From 92ed2c31776ef2f5e76bf9d0c6ede9d5a407ccdd Mon Sep 17 00:00:00 2001 From: zhangxiongfeng Date: Tue, 28 Jul 2026 16:58:06 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=A7=E5=8D=8E=E5=8F=A3=E9=97=A8=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit bcb9d32b9542d24444e1ce44708d278f936a9569) --- .../zcloud/basic/info/command/UserAddExe.java | 34 ++++++++- .../basic/info/domain/config/DaHuaConfig.java | 76 +++++++++++++++++++ 2 files changed, 106 insertions(+), 4 deletions(-) diff --git a/web-app/src/main/java/com/zcloud/basic/info/command/UserAddExe.java b/web-app/src/main/java/com/zcloud/basic/info/command/UserAddExe.java index 6413d864..e47e20e5 100644 --- a/web-app/src/main/java/com/zcloud/basic/info/command/UserAddExe.java +++ b/web-app/src/main/java/com/zcloud/basic/info/command/UserAddExe.java @@ -65,6 +65,11 @@ import java.util.Base64; @AllArgsConstructor @Slf4j public class UserAddExe { + @Data + public static class DaHuaSyncResult { + private Integer dahuaId; + private String dahuaCode; + } private final UserGateway userGateway; private final UserExpandInfoGateway userExpandInfoGateway; private UserCoConvertor userCoConvertor; @@ -180,8 +185,7 @@ public class UserAddExe { userE.setUserType(CorpTypeEnum.getUserTypeByCode(corpInfoDO.getType())); userE.resetPassword(corpInfoDO.getType()); - //先同步大华人脸平台,成功后再保存本地 - syncDaHuaPerson(userE); + // ① 先本地落库 + 底座GBS新增。GBS失败抛 RuntimeException,整个事务回滚 res = userGateway.add(userE); if (corpInfoDO != null && !ObjectUtils.isEmpty(corpInfoDO.getCorpName())) { corpName = corpInfoDO.getCorpName(); @@ -197,6 +201,23 @@ public class UserAddExe { } catch (Exception e) { log.error("用户变更记录保存失败(不影响用户主体), userId: {}, error: {}", userE.getId(), e.getMessage(), e); } + // ② 本地和底座都成功后,最后才同步大华。失败→抛异常→回滚本地+GBS(避免留下"大华人成功但本地没数据") + DaHuaSyncResult syncResult = syncDaHuaPerson(userE); + if (syncResult.dahuaId != null || (syncResult.dahuaCode != null && !syncResult.dahuaCode.trim().isEmpty())) { + try { + UserE updateDahua = new UserE(); + updateDahua.setId(userE.getId()); + updateDahua.setDahuaId(syncResult.dahuaId); + updateDahua.setDahuaCode(syncResult.dahuaCode); + userRepository.updateDahuaInfo(updateDahua.getId(), updateDahua.getDahuaId(), updateDahua.getDahuaCode()); + log.info("写回dahuaId/dahuaCode成功, userId={}, dahuaId={}, dahuaCode={}", + userE.getId(), syncResult.dahuaId, syncResult.dahuaCode); + } catch (Exception e) { + log.error("写回dahuaId/dahuaCode失败, userId={}, dahuaId={}, dahuaCode={}", + userE.getId(), syncResult.dahuaId, syncResult.dahuaCode, e); + throw new BizException("写回大华信息到本地失败:" + e.getMessage()); + } + } } catch (BizException e) { log.error("新增用户业务异常: {}", e.getMessage(), e); throw e; @@ -213,7 +234,7 @@ public class UserAddExe { return true; } - private void syncDaHuaPerson(UserE userE) { + private DaHuaSyncResult syncDaHuaPerson(UserE userE) { Map personMap = new HashMap<>(); personMap.put("name", userE.getName()); String idCard = userE.getUserIdCard(); @@ -417,8 +438,10 @@ public class UserAddExe { Map syncResult = daHuaConfig.syncPerson(personMap, extraHeaders); Boolean success = (Boolean) syncResult.get("success"); Boolean skipped = (Boolean) syncResult.get("skipped"); + DaHuaSyncResult result = new DaHuaSyncResult(); + result.setDahuaCode(plainIdCard); if (skipped != null && skipped) { - return; + return result; } String maskedIdCard = plainIdCard; if (plainIdCard != null && plainIdCard.length() >= 14) { @@ -437,6 +460,7 @@ public class UserAddExe { if (idObj != null) { try { Integer dahuaId = Integer.valueOf(idObj.toString()); + result.setDahuaId(dahuaId); userE.setDahuaId(dahuaId); log.info("设置大华dahuaId成功, dahuaId={}", dahuaId); } catch (Exception e) { @@ -449,6 +473,7 @@ public class UserAddExe { if (idObj != null) { try { Integer dahuaId = Integer.valueOf(idObj.toString()); + result.setDahuaId(dahuaId); userE.setDahuaId(dahuaId); log.info("设置大华dahuaId成功, dahuaId={}", dahuaId); } catch (Exception e) { @@ -458,6 +483,7 @@ public class UserAddExe { } } userE.setDahuaCode(plainIdCard); + return result; } @Transactional(rollbackFor = Exception.class) diff --git a/web-domain/src/main/java/com/zcloud/basic/info/domain/config/DaHuaConfig.java b/web-domain/src/main/java/com/zcloud/basic/info/domain/config/DaHuaConfig.java index d5aad7a2..58fe9ce3 100644 --- a/web-domain/src/main/java/com/zcloud/basic/info/domain/config/DaHuaConfig.java +++ b/web-domain/src/main/java/com/zcloud/basic/info/domain/config/DaHuaConfig.java @@ -188,4 +188,80 @@ public class DaHuaConfig { return resultMap; } } + + public Map deletePerson(List ids) { + return deletePerson(ids, null); + } + + public Map deletePerson(List ids, Map extraHeaders) { + Map resultMap = new HashMap<>(); + log.info("========== 大华人员(删除)调用开始 =========="); + log.info("dockFlag配置值={}, primeportUrl={}, primeportGateway={}, ids={}", dockFlag, primeportUrl, primeportGateway, ids); + if (dockFlag == null || dockFlag != 1) { + log.info("大华对接未开启(dockFlag={}), 跳过删除大华人员", dockFlag); + resultMap.put("success", true); + resultMap.put("skipped", true); + return resultMap; + } + if (ids == null || ids.isEmpty()) { + log.info("待删除大华ids为空, 跳过删除"); + resultMap.put("success", true); + resultMap.put("skipped", true); + return resultMap; + } + String baseUrl = primeportUrl; + if (baseUrl == null || baseUrl.trim().isEmpty()) { + throw new RuntimeException("大华对接网关地址未配置(dahua.config.primeportUrl)"); + } + baseUrl = baseUrl.trim(); + if (baseUrl.endsWith("/")) { + baseUrl = baseUrl.substring(0, baseUrl.length() - 1); + } + String gw = (primeportGateway == null || primeportGateway.trim().isEmpty()) ? "basicInfo" : primeportGateway.trim(); + String url = baseUrl + "/" + gw + "/dahua/person/delete"; + Map reqMap = new HashMap<>(); + reqMap.put("ids", ids); + String reqJson = JSONUtil.toJsonStr(reqMap); + log.info("【实际请求URL】method=POST, url={}", url); + log.info("【传给大华的请求体(JSON)】{}", reqJson); + try { + HttpRequest request = HttpRequest.post(url) + .header("Content-Type", "application/json;charset=UTF-8") + .timeout(30000) + .body(reqJson); + if (extraHeaders != null && !extraHeaders.isEmpty()) { + extraHeaders.forEach((k, v) -> { + if (k != null && v != null) { + request.header(k, v); + } + }); + log.info("【透传请求头】{}", extraHeaders); + } + String respBody = request.execute().body(); + log.info("【大华接口原始返回】{}", respBody); + if (respBody == null || respBody.trim().isEmpty()) { + resultMap.put("success", false); + resultMap.put("errCode", "EMPTY_RESPONSE"); + resultMap.put("errMessage", "大华人员删除接口返回为空"); + return resultMap; + } + JSONObject respJson = JSONUtil.parseObj(respBody); + Boolean success = respJson.getBool("success", false); + String errCode = respJson.getStr("errCode", ""); + String errMessage = respJson.getStr("errMessage", ""); + Object data = respJson.get("data"); + resultMap.put("success", success); + resultMap.put("errCode", errCode); + resultMap.put("errMessage", errMessage); + resultMap.put("data", data); + log.info("【解析后返回】success={}, errCode={}, errMessage={}, data={}", success, errCode, errMessage, data); + return resultMap; + } catch (Exception e) { + log.error("调用大华人员删除接口异常: {}", e.getMessage(), e); + resultMap.put("success", false); + resultMap.put("errCode", "HTTP_EXCEPTION"); + resultMap.put("errMessage", "调用大华人员删除接口异常: " + e.getMessage()); + return resultMap; + } + } } \ No newline at end of file