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 e47e20e5..6328e2c7 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 @@ -33,7 +33,6 @@ import com.zcloud.basic.info.persistence.dataobject.*; import com.zcloud.basic.info.persistence.repository.*; import com.zcloud.gbscommon.utils.*; import lombok.AllArgsConstructor; -import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.annotation.DubboReference; import org.springframework.beans.BeanUtils; @@ -65,11 +64,6 @@ 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; @@ -106,22 +100,31 @@ public class UserAddExe { // if (!b) { // throw new BizException("请先完善企业信息"); // } - log.info("开始新增用户,name: {}, corpinfoId: {}, phone: {}", cmd.getName(), cmd.getCorpinfoId(), cmd.getPhone()); + log.info("========== 开始新增用户,请求参数 name: {}, corpinfoId: {}, phone: {}, 请求体 JSON: {}", cmd.getName(), cmd.getCorpinfoId(), cmd.getPhone(), JSONUtil.toJsonStr(cmd)); try { ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if (attrs != null) { HttpServletRequest req = attrs.getRequest(); + Enumeration headerNames = req.getHeaderNames(); + Map headerMap = new HashMap<>(); + while (headerNames.hasMoreElements()) { + String h = headerNames.nextElement(); + headerMap.put(h, req.getHeader(h)); + } + log.info("========== 请求头信息: {}", JSONUtil.toJsonStr(headerMap)); String orgidHeader = req.getHeader("orgid"); + log.info("========== 从请求头获取 orgid: {}", orgidHeader); if (orgidHeader != null && cmd.getCorpinfoId() == null) { try { cmd.setCorpinfoId(Long.parseLong(orgidHeader.trim())); + log.info("========== 用请求头 orgid 设置 cmd.corpinfoId: {}", cmd.getCorpinfoId()); } catch (Exception e) { - log.warn("orgid 转 Long 失败: {}", orgidHeader); + log.warn("========== orgid 转 Long 失败: {}", orgidHeader); } } } } catch (Exception e) { - log.warn("获取请求头异常: {}", e.getMessage()); + log.warn("========== 获取请求头异常: {}", e.getMessage()); } Long tenantId = null; SSOUser ssoUser = AuthContext.getCurrentUser(); @@ -182,59 +185,38 @@ public class UserAddExe { userE.setRoleId(roleId); } try { + log.info("========== 企业类型 type: {}", corpInfoDO.getType()); userE.setUserType(CorpTypeEnum.getUserTypeByCode(corpInfoDO.getType())); userE.resetPassword(corpInfoDO.getType()); - // ① 先本地落库 + 底座GBS新增。GBS失败抛 RuntimeException,整个事务回滚 + //先同步大华人脸平台,成功后再保存本地 + log.info("========== 开始调用大华同步接口"); + syncDaHuaPerson(userE); + log.info("========== 大华同步成功,开始保存本地用户"); res = userGateway.add(userE); + log.info("========== 本地保存结果: {}", res); if (corpInfoDO != null && !ObjectUtils.isEmpty(corpInfoDO.getCorpName())) { corpName = corpInfoDO.getCorpName(); } userEmploymentLogE.initAdd(userEmploymentLogE, corpName, userE.getId()); - try { - userEmploymentLogGateway.add(userEmploymentLogE); - } catch (Exception e) { - log.error("用户就业日志保存失败(不影响用户主体), userId: {}, error: {}", userE.getId(), e.getMessage(), e); - } - try { - addUserChangeRecordForSave(userE, corpInfoDO); - } 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()); - } - } + userEmploymentLogGateway.add(userEmploymentLogE); + addUserChangeRecordForSave(userE, corpInfoDO); + log.info("========== 用户就业日志保存成功"); } catch (BizException e) { - log.error("新增用户业务异常: {}", e.getMessage(), e); + log.error("========== 业务异常: {}", e.getMessage(), e); throw e; } catch (Exception e) { - log.error("新增用户系统异常: {}", e.getMessage(), e); + log.error("========== 系统异常: {}", e.getMessage(), e); throw new RuntimeException(e); } if (!res) { throw new BizException("保存失败"); } - cmd.setId(userE.getId()); - cmd.setUsername(userE.getUsername()); - log.info("新增用户完成, userId: {}, username: {}", userE.getId(), userE.getUsername()); + log.info("========== 新增用户完成"); return true; } - private DaHuaSyncResult syncDaHuaPerson(UserE userE) { + private void syncDaHuaPerson(UserE userE) { Map personMap = new HashMap<>(); personMap.put("name", userE.getName()); String idCard = userE.getUserIdCard(); @@ -259,34 +241,67 @@ public class UserAddExe { personMap.put("service", "evo-thirdParty"); Object faceFile = userE.getFaceFile(); + log.info("========== 大华图片调试开始 =========="); + log.info("faceFile原始类型: {}, faceFile原始值(截取前500字符): {}", + faceFile == null ? "null" : faceFile.getClass().getName(), + faceFile == null ? "null" : (faceFile.toString().length() > 500 ? faceFile.toString().substring(0, 500) + "..." : faceFile.toString())); + log.info("userE.getUserAvatarUrl()值(截取前500字符): {}", + userE.getUserAvatarUrl() == null ? "null" : (userE.getUserAvatarUrl().length() > 500 ? userE.getUserAvatarUrl().substring(0, 500) + "..." : userE.getUserAvatarUrl())); java.util.function.Function extractThumbFromSingle = (singleObj) -> { if (singleObj == null) { + log.debug("单个图片对象为null"); return null; } + log.info("从单个对象提取thumbUrl,对象类型: {}", singleObj.getClass().getName()); if (singleObj instanceof Map) { Map faceFileMap = (Map) singleObj; + log.info("单个对象是Map类型,所有key: {}", faceFileMap.keySet()); + for (Map.Entry entry : faceFileMap.entrySet()) { + Object v = entry.getValue(); + String vStr = v == null ? "null" : (v.toString().length() > 200 ? v.toString().substring(0, 200) + "..." : v.toString()); + log.info("单个对象 key={}, value类型={}, value={}", entry.getKey(), v == null ? "null" : v.getClass().getName(), vStr); + } Object thumbUrlObj = faceFileMap.get("thumbUrl"); if (thumbUrlObj != null) { - return thumbUrlObj.toString(); + String res = thumbUrlObj.toString(); + log.info("从Map提取到thumbUrl,长度={}", res.length()); + return res; } } else if (singleObj instanceof cn.hutool.json.JSONObject) { cn.hutool.json.JSONObject faceJson = (cn.hutool.json.JSONObject) singleObj; + log.info("单个对象是JSONObject类型,所有key: {}", faceJson.keySet()); + for (String key : faceJson.keySet()) { + Object v = faceJson.get(key); + String vStr = v == null ? "null" : (v.toString().length() > 200 ? v.toString().substring(0, 200) + "..." : v.toString()); + log.info("单个对象 key={}, value类型={}, value={}", key, v == null ? "null" : v.getClass().getName(), vStr); + } Object thumbUrlObj = faceJson.get("thumbUrl"); if (thumbUrlObj != null) { - return thumbUrlObj.toString(); + String res = thumbUrlObj.toString(); + log.info("从JSONObject提取到thumbUrl,长度={}", res.length()); + return res; } } else { try { cn.hutool.json.JSONObject faceJson = cn.hutool.json.JSONUtil.parseObj(singleObj); + log.info("单个对象解析为JSONObject后,所有key: {}", faceJson.keySet()); + for (String key : faceJson.keySet()) { + Object v = faceJson.get(key); + String vStr = v == null ? "null" : (v.toString().length() > 200 ? v.toString().substring(0, 200) + "..." : v.toString()); + log.info("单个对象 key={}, value类型={}, value={}", key, v == null ? "null" : v.getClass().getName(), vStr); + } Object thumbUrlObj = faceJson.get("thumbUrl"); if (thumbUrlObj != null) { - return thumbUrlObj.toString(); + String res = thumbUrlObj.toString(); + log.info("从解析后的JSONObject提取到thumbUrl,长度={}", res.length()); + return res; } } catch (Exception e) { - log.warn("解析单个图片对象为JSON失败: {}", e.getMessage()); + log.warn("解析单个图片对象为JSON失败: {}, 错误: {}", singleObj, e.getMessage()); } } + log.warn("单个对象中未找到thumbUrl字段"); return null; }; @@ -297,39 +312,56 @@ public class UserAddExe { if (faceFile instanceof java.util.Collection) { isArray = true; java.util.Collection coll = (java.util.Collection) faceFile; + log.info("faceFile是Collection/List类型,size={}", coll.size()); if (!coll.isEmpty()) { firstElement = coll.iterator().next(); + log.info("取Collection第一个元素,类型: {}", firstElement == null ? "null" : firstElement.getClass().getName()); + } else { + log.warn("faceFile是空数组,无元素可取"); } } else if (faceFile.getClass().isArray()) { isArray = true; Object[] arr = (Object[]) faceFile; + log.info("faceFile是原生数组类型,length={}", arr.length); if (arr.length > 0) { firstElement = arr[0]; + log.info("取数组第0个元素,类型: {}", firstElement == null ? "null" : firstElement.getClass().getName()); + } else { + log.warn("faceFile是空原生数组,无元素可取"); } } else if (faceFile instanceof cn.hutool.json.JSONArray) { isArray = true; cn.hutool.json.JSONArray jsonArr = (cn.hutool.json.JSONArray) faceFile; + log.info("faceFile是JSONArray类型,size={}", jsonArr.size()); if (!jsonArr.isEmpty()) { firstElement = jsonArr.get(0); + log.info("取JSONArray第0个元素,类型: {}", firstElement == null ? "null" : firstElement.getClass().getName()); + } else { + log.warn("faceFile是空JSONArray,无元素可取"); } } if (isArray) { + log.info("faceFile是数组/集合类型,从第一个元素中提取thumbUrl"); if (firstElement != null) { thumbUrl = extractThumbFromSingle.apply(firstElement); + } else { + log.warn("数组第一个元素是null,无法提取thumbUrl"); } } else { + log.info("faceFile是单个对象类型,直接提取thumbUrl"); thumbUrl = extractThumbFromSingle.apply(faceFile); } } - + log.info("从faceFile提取thumbUrl结果(截取前500字符): {}", + thumbUrl == null ? "null" : (thumbUrl.length() > 500 ? thumbUrl.substring(0, 500) + "..." : thumbUrl)); if (thumbUrl != null && !thumbUrl.trim().isEmpty()) { String trimmedThumb = thumbUrl.trim(); + boolean startsWithDataImage = trimmedThumb.startsWith("data:image"); boolean startsWithHttp = trimmedThumb.startsWith("http://") || trimmedThumb.startsWith("https://"); boolean containsComma = trimmedThumb.contains(","); - boolean startsWithDataImage = trimmedThumb.startsWith("data:image"); String cleanBase64; if (containsComma && startsWithDataImage) { @@ -337,25 +369,46 @@ public class UserAddExe { String bodyPart = trimmedThumb.substring(trimmedThumb.indexOf(",") + 1); String cleanBody = bodyPart.replaceAll("\\s+", ""); cleanBase64 = prefixPart + cleanBody; + log.info("已保留data:image前缀(严格对齐大华文档示例), 前缀={}, 仅清洗主体中的空白字符", prefixPart.length() > 80 ? prefixPart.substring(0, 80) + "..." : prefixPart); } else { String pureBody = trimmedThumb.replaceAll("\\s+", ""); cleanBase64 = "data:image/jpeg;base64," + pureBody; + log.info("原始thumbUrl无标准data:image前缀,已自动补齐(data:image/jpeg;base64,)以对齐大华文档示例"); } int commaIdx = cleanBase64.indexOf(","); String base64BodyOnly = commaIdx >= 0 ? cleanBase64.substring(commaIdx + 1) : cleanBase64; boolean isLikelyBase64 = base64BodyOnly.matches("^[A-Za-z0-9+/=]+$"); + int totalLen = cleanBase64.length(); int bodyLen = base64BodyOnly.length(); boolean finalHasPrefix = cleanBase64.startsWith("data:image"); + log.info("========== 图片格式判断结果(严格对齐大华文档示例) =========="); + log.info("原始thumbUrl总长度: {}", trimmedThumb.length()); + log.info("最终结果是否带data:image前缀(文档示例:true): {}", finalHasPrefix); + log.info("是否是http/https URL(文档要求:false): {}", startsWithHttp); + log.info("最终整体长度(含前缀): {}", totalLen); + log.info("base64主体长度(去掉前缀逗号后): {}", bodyLen); + log.info("base64主体是否匹配纯base64字符集(A-Za-z0-9+/=): {}", isLikelyBase64); if (startsWithHttp) { - log.error("同步大华人员失败:人脸图片传的是HTTP/HTTPS URL,要求必须传带data:image前缀的base64图片"); + log.error("===== 严重错误:传的是HTTP/HTTPS URL(或文件路径)!大华文档personBiosignatures要求必须传【带data:image前缀的base64图片】,不是URL ====="); + System.out.println("===== 大华图片错误:HTTP URL无效, 前200: " + (trimmedThumb.length() > 200 ? trimmedThumb.substring(0, 200) : trimmedThumb)); } else if (!finalHasPrefix) { - log.error("同步大华人员失败:人脸图片最终无data:image前缀,代码补齐逻辑失效"); + log.error("===== 最终结果竟然没有data:image前缀(代码补齐逻辑失效) ====="); + System.out.println("===== 大华图片错误:无data:image前缀, 前100: " + (cleanBase64.length() > 100 ? cleanBase64.substring(0, 100) : cleanBase64)); } else if (!isLikelyBase64) { - log.error("同步大华人员失败:人脸图片base64主体含非base64非法字符"); + log.error("===== base64主体部分含非base64非法字符!前200: {}", base64BodyOnly.length() > 200 ? base64BodyOnly.substring(0, 200) : base64BodyOnly); + System.out.println("===== 大华图片错误:主体非base64字符, 前200: " + (base64BodyOnly.length() > 200 ? base64BodyOnly.substring(0, 200) : base64BodyOnly)); } else if (bodyLen < 1000) { - log.error("同步大华人员失败:人脸图片base64主体长度过短({}),缩略图可能损坏", bodyLen); + log.error("===== base64主体长度过短({}),缩略图太小/损坏!正常300KB JPEG→主体约40万字符 =====", bodyLen); + System.out.println("===== 大华图片错误:主体过短=" + bodyLen); + } else { + log.info("===== ✅ 完全符合大华文档personBiosignatures格式:带data:image前缀 + 纯base64主体 + 长度正常 ====="); } + log.info("【最终传给大华base64Data(严格对齐文档)】前150字符: {}", cleanBase64.length() > 150 ? cleanBase64.substring(0, 150) : cleanBase64); + log.info("【最终传给大华base64Data】后150字符: {}", cleanBase64.length() > 150 ? cleanBase64.substring(cleanBase64.length() - 150) : cleanBase64); + System.out.println("===== 最终带前缀完整base64Data 前200: " + (cleanBase64.length() > 200 ? cleanBase64.substring(0, 200) : cleanBase64)); + System.out.println("===== 最终带前缀完整base64Data 后200: " + (cleanBase64.length() > 200 ? cleanBase64.substring(cleanBase64.length() - 200) : cleanBase64)); + System.out.println("===== 是否按文档带data:image前缀=" + finalHasPrefix + " / 最终总长度=" + totalLen + " / 主体长度=" + bodyLen); List> personBiosignatures = new ArrayList<>(); Map biosignature = new java.util.LinkedHashMap<>(); @@ -364,9 +417,15 @@ public class UserAddExe { biosignature.put("base64Data", cleanBase64); personBiosignatures.add(biosignature); personMap.put("personBiosignatures", personBiosignatures); + log.info("组装personBiosignatures成功(严格按文档顺序type→index→base64Data,LinkedHashMap有序)"); + String biosigJson = JSONUtil.toJsonStr(personBiosignatures); + log.info("personBiosignatures JSON(截取前500字符): {}", biosigJson.length() > 500 ? biosigJson.substring(0, 500) + "..." : biosigJson); + System.out.println("===== 传给大华personBiosignatures完整JSON前500字符: " + (biosigJson.length() > 500 ? biosigJson.substring(0, 500) + "..." : biosigJson)); } else { log.warn("未获取到人脸图片thumbUrl,personBiosignatures将不传递"); + System.out.println("===== 警告:未从faceFile中获取到有效的thumbUrl,personBiosignatures不会传给大华!"); } + log.info("========== 大华图片调试结束 =========="); Integer age = null; Integer sex = null; @@ -431,6 +490,7 @@ public class UserAddExe { if (tenantId != null && !tenantId.trim().isEmpty()) { extraHeaders.put("tenantId", tenantId); } + log.info("收集到需要透传的请求头: {}", extraHeaders); } } catch (Exception e) { log.warn("获取当前请求头异常: {}", e.getMessage()); @@ -438,20 +498,17 @@ 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 result; - } - String maskedIdCard = plainIdCard; - if (plainIdCard != null && plainIdCard.length() >= 14) { - maskedIdCard = plainIdCard.substring(0, 6) + "********" + plainIdCard.substring(plainIdCard.length() - 4); + return; } if (success == null || !success) { String errCode = (String) syncResult.getOrDefault("errCode", ""); String errMessage = (String) syncResult.getOrDefault("errMessage", "大华人员同步失败"); + log.error("同步大华人员失败, errCode={}, errMessage={}, name={}, idCard={}", errCode, errMessage, userE.getName(), plainIdCard); throw new BizException("同步大华平台失败:" + errMessage); } + log.info("同步大华人员成功, name={}, idCard={}", userE.getName(), plainIdCard); + System.out.println("同步大华人员成功, name=" + userE.getName() + ", idCard=" + plainIdCard); Object data = syncResult.get("data"); if (data != null) { if (data instanceof Map) { @@ -460,7 +517,6 @@ 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) { @@ -473,7 +529,6 @@ 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) { @@ -483,7 +538,7 @@ public class UserAddExe { } } userE.setDahuaCode(plainIdCard); - return result; + log.info("设置大华dahuaCode成功, dahuaCode={}", plainIdCard); } @Transactional(rollbackFor = Exception.class) @@ -843,7 +898,7 @@ public class UserAddExe { sendParams.put("code", phoneCode); messageSendCmd.setParams(sendParams); SingleResponse d = messageFacade.send(messageSendCmd); - log.info("短信发送结果: {}, phone: {}", d, phone); + System.out.println( d.toString()); return d == null ? false : d.getData(); } 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 58fe9ce3..2fd661e5 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 @@ -11,7 +11,6 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.util.HashMap; -import java.util.List; import java.util.Map; /** @@ -68,7 +67,9 @@ public class DaHuaConfig { String gw = (primeportGateway == null || primeportGateway.trim().isEmpty()) ? "basicInfo" : primeportGateway.trim(); String url = baseUrl + "/" + gw + "/dahua/person/sync"; String reqJson = JSONUtil.toJsonStr(personMap); - log.info("调用大华人员同步接口, url={}", url); + log.info("调用大华人员同步接口, url={}, 请求参数={}", url, reqJson); + System.out.println("调用大华人员同步接口, url=" + url); + System.out.println("请求参数: " + reqJson); try { HttpRequest request = HttpRequest.post(url) .header("Content-Type", "application/json;charset=UTF-8") @@ -78,12 +79,14 @@ public class DaHuaConfig { extraHeaders.forEach((k, v) -> { if (k != null && v != null) { request.header(k, v); + System.out.println("透传请求头: " + k + "=" + v); } }); log.info("透传请求头: {}", extraHeaders); } String respBody = request.execute().body(); log.info("大华人员同步接口返回: {}", respBody); + System.out.println("大华人员同步接口返回: " + respBody); if (respBody == null || respBody.trim().isEmpty()) { resultMap.put("success", false); resultMap.put("errCode", "EMPTY_RESPONSE"); @@ -108,160 +111,4 @@ public class DaHuaConfig { return resultMap; } } - - public Map updatePerson(Map personMap) { - return updatePerson(personMap, null); - } - - public Map updatePerson(Map personMap, Map extraHeaders) { - Map resultMap = new HashMap<>(); - log.info("========== 大华人员(更新)调用开始 =========="); - log.info("dockFlag配置值={}, primeportUrl={}, primeportGateway={}", dockFlag, primeportUrl, primeportGateway); - if (dockFlag == null || dockFlag != 1) { - log.info("大华对接未开启(dockFlag={}), 跳过更新大华人员", dockFlag); - 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/update"; - log.info("【实际请求URL】method=PUT, url={}", url); - log.info("【对比-新增sync的URL】method=POST, {}/{}/dahua/person/sync", baseUrl, gw); - - String reqJson = JSONUtil.toJsonStr(personMap); - log.info("【传给大华的请求体(JSON)】{}", reqJson); - log.info("【personMap关键字段】id={}, code={}, name={}, paperNumber={}, phone={}, departmentId={}, paperType={}, service={}, personBiosignatures是否有值={}", - personMap.get("id"), personMap.get("code"), personMap.get("name"), - personMap.get("paperNumber"), personMap.get("phone"), - personMap.get("departmentId"), personMap.get("paperType"), - personMap.get("service"), - personMap.get("personBiosignatures") == null ? "null" : - (personMap.get("personBiosignatures") instanceof List - ? "List-size=" + ((List) personMap.get("personBiosignatures")).size() - : personMap.get("personBiosignatures").getClass().getName())); - try { - HttpRequest request = HttpRequest.put(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; - } - } - - 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