diff --git a/start/src/main/java/com/zcloud/basic/info/config/LocalDevFilterConfig.java b/start/src/main/java/com/zcloud/basic/info/config/LocalDevFilterConfig.java new file mode 100644 index 00000000..a4870b65 --- /dev/null +++ b/start/src/main/java/com/zcloud/basic/info/config/LocalDevFilterConfig.java @@ -0,0 +1,20 @@ +package com.zcloud.basic.info.config; + +import com.jjb.saas.framework.auth.filter.AuthenticationFilter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@Slf4j +public class LocalDevFilterConfig { + + @Bean + public FilterRegistrationBean disableAuthenticationFilter(AuthenticationFilter authenticationFilter) { + log.info("========== 本地开发环境:禁用 AuthenticationFilter 过滤器 =========="); + FilterRegistrationBean registration = new FilterRegistrationBean<>(authenticationFilter); + registration.setEnabled(false); + return registration; + } +} \ No newline at end of file diff --git a/start/src/main/resources/application.yml b/start/src/main/resources/application.yml new file mode 100644 index 00000000..1a98197b --- /dev/null +++ b/start/src/main/resources/application.yml @@ -0,0 +1,11 @@ +common: + mysql: + host: nlb-kd2xz70qhllfet2koj.cn-beijing.nlb.aliyuncsslb.com + port: 33068 + username: root + password: 5tS3owZ7w8Uk1egv +dahua: + config: + dockFlag: 1 + primeportUrl: https://gbs-gateway.qhdsafety.com + primeportGateway: primeport \ No newline at end of file diff --git a/start/src/main/resources/bootstrap.yml b/start/src/main/resources/bootstrap.yml index ea7eb2ef..f467a2cb 100644 --- a/start/src/main/resources/bootstrap.yml +++ b/start/src/main/resources/bootstrap.yml @@ -3,8 +3,8 @@ spring: import: # - classpath:nacos.yml # - classpath:sdk.yml -# - classpath:nacos-prod.yml -# - classpath:sdk-prod.yml - - classpath:nacos-prod2.yml - - classpath:sdk-prod2.yml + - classpath:nacos-prod.yml + - classpath:sdk-prod.yml +# - classpath:nacos-prod2.yml +# - classpath:sdk-prod2.yml - classpath:swagger.yml diff --git a/start/src/main/resources/nacos.yml b/start/src/main/resources/nacos.yml index 6ba057e8..e22017e6 100644 --- a/start/src/main/resources/nacos.yml +++ b/start/src/main/resources/nacos.yml @@ -35,4 +35,4 @@ spring: - config-flyway.yml discovery: server-addr: ${spring.cloud.nacos.config.server-addr} - namespace: ${spring.cloud.nacos.config.namespace} + namespace: ${spring.cloud.nacos.config.namespace} \ No newline at end of file diff --git a/start/src/main/resources/nacos/config-common.yml b/start/src/main/resources/nacos/config-common.yml index 810ccf57..db97b17b 100644 --- a/start/src/main/resources/nacos/config-common.yml +++ b/start/src/main/resources/nacos/config-common.yml @@ -1,9 +1,9 @@ common: mysql: - host: 192.168.2.166 - port: 3306 + host: nlb-kd2xz70qhllfet2koj.cn-beijing.nlb.aliyuncsslb.com + port: 33068 username: root - password: root + password: 5tS3owZ7w8Uk1egv redis: host: 10.43.253.4 password: jjb123456 diff --git a/web-adapter/src/main/java/com/zcloud/basic/info/facade/ZcloudUserFacadeImpl.java b/web-adapter/src/main/java/com/zcloud/basic/info/facade/ZcloudUserFacadeImpl.java index cf1488ce..125bb239 100644 --- a/web-adapter/src/main/java/com/zcloud/basic/info/facade/ZcloudUserFacadeImpl.java +++ b/web-adapter/src/main/java/com/zcloud/basic/info/facade/ZcloudUserFacadeImpl.java @@ -1,10 +1,15 @@ package com.zcloud.basic.info.facade; import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import cn.hutool.json.JSONUtil; import com.alibaba.cola.dto.MultiResponse; import com.alibaba.cola.dto.SingleResponse; +import com.alibaba.cola.exception.BizException; import com.zcloud.basic.info.api.UserServiceI; import com.zcloud.basic.info.command.convertor.UserCoConvertor; +import com.zcloud.basic.info.dto.UserAddCmd; +import com.zcloud.basic.info.dto.UserUpdateCmd; import com.zcloud.basic.info.dto.clientobject.UserCO; import com.zcloud.basic.info.persistence.dataobject.UserDO; import com.zcloud.basic.info.persistence.dataobject.UserImgDO; @@ -14,7 +19,9 @@ import com.zcloud.gbscommon.zclouduser.facade.ZcloudUserFacade; import com.zcloud.gbscommon.zclouduser.request.*; import com.zcloud.gbscommon.zclouduser.response.ZcloudUserCo; import com.zcloud.gbscommon.zclouduser.response.ZcloudUserImgBase64Co; +import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.annotation.DubboService; +import org.springframework.util.StringUtils; import javax.annotation.Resource; import java.util.ArrayList; @@ -25,6 +32,7 @@ import java.util.Map; /** * @author lin */ +@Slf4j @DubboService public class ZcloudUserFacadeImpl implements ZcloudUserFacade { @Resource @@ -97,18 +105,97 @@ public class ZcloudUserFacadeImpl implements ZcloudUserFacade { } @Override - public SingleResponse addHumanUser(ZcloudUserAddCmd zcloudUserAddCmd) { - return null; + public SingleResponse addHumanUser(ZcloudUserAddCmd cmd) { + UserAddCmd userAddCmd = new UserAddCmd(); + BeanUtil.copyProperties(cmd, userAddCmd); + return userServiceI.addHumanUser(userAddCmd); } + /** + * 人资用户变更 Dubbo 入口。 + * 这里负责把外部系统的更新命令转换为本系统命令对象, + * 并在查到原用户时先回填老数据,再将非空的新值覆盖进去, + * 最终统一交给 humanUserUpdateExe 按新增、离职、跨企业变更、企业内修改四种场景处理。 + */ @Override public SingleResponse updateHumanUser(ZcloudUserUpdateCmd zcloudUserUpdateCmd) { - return null; + if (zcloudUserUpdateCmd == null) { + throw new BizException("用户更新参数不能为空"); + } + log.info("接收人资用户变更请求参数: {}", JSONUtil.toJsonStr(zcloudUserUpdateCmd)); + + UserUpdateCmd userUpdateCmd = new UserUpdateCmd(); + UserDO userDO = null; + if (zcloudUserUpdateCmd.getId() != null) { + userDO = userRepository.getInfoById(zcloudUserUpdateCmd.getId()); + if (userDO != null) { + userUpdateCmd = BeanUtil.toBean(userDO, UserUpdateCmd.class); + } + } + + BeanUtil.copyProperties(zcloudUserUpdateCmd, userUpdateCmd, CopyOptions.create().ignoreNullValue()); + fillHumanUserUpdateCmd(userUpdateCmd, userDO, zcloudUserUpdateCmd); + return userServiceI.updateHumanUser(userUpdateCmd); } @Override public MultiResponse listUserByInfo(ZcloudUserInfoQry zcloudUserInfoQry) { - return null; + Map parmas = PageQueryHelper.toHashMap(zcloudUserInfoQry); + List userList = userRepository.listUserByInfo(parmas); + List zcloudUserCos = userCoConvertor.converDOsToDubboCOs(userList); + return MultiResponse.of(zcloudUserCos); } + /** + * 补齐人资更新入口需要的关键字段。 + * 这样在外部系统做局部更新时,可以避免 userId、手机号、账号等关键值丢失。 + * 但如果企业、部门、岗位 id 已发生变化,则需要主动清空旧名称, + * 让下游按变更后的 id 重新解析名称,避免跨企业变更时 after 名称仍然写成旧值。 + */ + private void fillHumanUserUpdateCmd(UserUpdateCmd userUpdateCmd, UserDO userDO, ZcloudUserUpdateCmd zcloudUserUpdateCmd) { + if (userDO != null && !StringUtils.hasText(userUpdateCmd.getUserId())) { + userUpdateCmd.setUserId(userDO.getUserId()); + } + if (userDO != null && !StringUtils.hasText(userUpdateCmd.getName())) { + userUpdateCmd.setName(userDO.getName()); + } + if (userDO != null && !StringUtils.hasText(userUpdateCmd.getPhone())) { + userUpdateCmd.setPhone(userDO.getPhone()); + } + if (!StringUtils.hasText(userUpdateCmd.getUsername())) { + if (StringUtils.hasText(zcloudUserUpdateCmd.getPhone()) + && (userDO == null || !StringUtils.hasText(userDO.getUsername()) || userDO.getUsername().equals(userDO.getPhone()))) { + userUpdateCmd.setUsername(zcloudUserUpdateCmd.getPhone()); + } else if (userDO != null) { + userUpdateCmd.setUsername(userDO.getUsername()); + } + } + if (userDO != null + && userUpdateCmd.getCorpinfoId() != null + && !userUpdateCmd.getCorpinfoId().equals(userDO.getCorpinfoId())) { + userUpdateCmd.setCorpinfoName(null); + } + if (userDO != null + && userUpdateCmd.getDepartmentId() != null + && !userUpdateCmd.getDepartmentId().equals(userDO.getDepartmentId())) { + userUpdateCmd.setDepartmentName(null); + } + if (userDO != null && !StringUtils.hasText(userUpdateCmd.getDepartmentName())) { + userUpdateCmd.setDepartmentName(userDO.getDepartmentName()); + } + if (userDO != null + && userUpdateCmd.getPostId() != null + && !userUpdateCmd.getPostId().equals(userDO.getPostId())) { + userUpdateCmd.setPostName(null); + } + if (userDO != null && !StringUtils.hasText(userUpdateCmd.getPostName())) { + userUpdateCmd.setPostName(userDO.getPostName()); + } + } + + //人员 + + + + } 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 cb377ce9..bb71d100 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 @@ -41,18 +41,9 @@ import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.ObjectUtils; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; - -import javax.servlet.http.HttpServletRequest; import java.util.*; import java.util.stream.Collectors; -import java.nio.charset.StandardCharsets; -import java.time.LocalDate; -import java.time.Period; -import java.time.format.DateTimeFormatter; -import java.util.Base64; /** @@ -65,11 +56,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; @@ -97,56 +83,17 @@ public class UserAddExe { private final CodeConfig codeConfig; private final UserExpandInfoRepository userExpandInfoRepository; private final ImgFilesRepository imgFilesRepository; - private final DaHuaConfig daHuaConfig; @Transactional(rollbackFor = Exception.class) public boolean execute(UserAddCmd cmd) { - Boolean b = corpInfoQueryExe.verifyCorpInfo(); - if (!b) { - throw new BizException("请先完善企业信息"); - } - log.info("开始新增用户,name: {}, corpinfoId: {}, phone: {}", cmd.getName(), cmd.getCorpinfoId(), cmd.getPhone()); - try { - ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); - if (attrs != null) { - HttpServletRequest req = attrs.getRequest(); - String orgidHeader = req.getHeader("orgid"); - if (orgidHeader != null && cmd.getCorpinfoId() == null) { - try { - cmd.setCorpinfoId(Long.parseLong(orgidHeader.trim())); - } catch (Exception e) { - log.warn("orgid 转 Long 失败: {}", orgidHeader); - } - } - } - } catch (Exception e) { - log.warn("获取请求头异常: {}", e.getMessage()); + Boolean b = corpInfoQueryExe.verifyCorpInfo(); + if (!b) { + throw new BizException("请先完善企业信息"); } - Long tenantId = null; SSOUser ssoUser = AuthContext.getCurrentUser(); - if (ssoUser != null) { - tenantId = ssoUser.getTenantId(); - } + Long tenantId = ssoUser.getTenantId(); UserE userE = new UserE(); BeanUtils.copyProperties(cmd, userE); - // tenantId 优先级:cmd 传值 -> AuthContext 上下文 -> ssoUser - if (!ObjectUtils.isEmpty(userE.getTenantId())) { - tenantId = userE.getTenantId(); - } else if (!ObjectUtils.isEmpty(userE.getCorpinfoId())) { - tenantId = userE.getCorpinfoId(); - } else { - try { - Long ctxTenantId = AuthContext.getTenantId(); - if (ctxTenantId != null) { - tenantId = ctxTenantId; - } - } catch (Exception e) { - log.warn("从 AuthContext 获取 tenantId 失败: {}", e.getMessage()); - } - } - if (tenantId == null && ObjectUtils.isEmpty(userE.getCorpinfoId())) { - throw new BizException("无法获取租户信息,请登录后重试或在请求中指定 corpinfoId"); - } userE.initAdd(tenantId, userE); //校验身份证是否存在 List userDOList = userRepository.getByIdCard(userE.getUserIdCard(), null); @@ -162,13 +109,7 @@ public class UserAddExe { userE.checkPhone(userEList); } - if (userE.getCorpinfoId() == null) { - throw new BizException("企业ID不能为空"); - } CorpInfoDO corpInfoDO = corpInfoRepository.getById(userE.getCorpinfoId()); - if (corpInfoDO == null) { - throw new BizException("企业信息不存在,corpinfoId=" + userE.getCorpinfoId()); - } String corpName = null; UserEmploymentLogE userEmploymentLogE = new UserEmploymentLogE(); BeanUtils.copyProperties(userE, userEmploymentLogE); @@ -184,331 +125,22 @@ public class UserAddExe { userE.setUserType(CorpTypeEnum.getUserTypeByCode(corpInfoDO.getType())); userE.resetPassword(corpInfoDO.getType()); - // ① 先本地落库 + 底座GBS新增。GBS失败抛 RuntimeException,整个事务回滚 res = userGateway.add(userE); 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()); - } - } - } catch (BizException e) { - log.error("新增用户业务异常: {}", e.getMessage(), e); - throw e; + userEmploymentLogGateway.add(userEmploymentLogE); + addUserChangeRecordForSave(userE, corpInfoDO); } catch (Exception 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()); return true; } - private DaHuaSyncResult syncDaHuaPerson(UserE userE) { - return syncDaHuaPerson(userE, userE.getFaceFile(), true); - } - - private DaHuaSyncResult syncDaHuaPerson(UserE userE, Object avatarSource, boolean throwOnFail) { - Map personMap = new HashMap<>(); - personMap.put("name", userE.getName()); - String idCard = userE.getUserIdCard(); - String plainIdCard = idCard; - if (idCard != null && !idCard.trim().isEmpty()) { - try { - byte[] decodedBytes = Base64.getDecoder().decode(idCard.trim()); - plainIdCard = new String(decodedBytes, StandardCharsets.UTF_8); - } catch (Exception e) { - log.warn("身份证号非Base64格式,按原值处理: {}", idCard); - } - } - personMap.put("code", plainIdCard); - personMap.put("paperType", 111); - personMap.put("paperNumber", plainIdCard); - personMap.put("phone", userE.getPhone()); - personMap.put("departmentId", 1L); - personMap.put("departmentType", 2); - personMap.put("type", 3); - if (userE.getNation() != null && !userE.getNation().trim().isEmpty()) { - try { - personMap.put("nation", Integer.valueOf(userE.getNation().trim())); - } catch (Exception e) { - log.warn("用户民族编码转Integer失败,用默认值1,nation={}", userE.getNation()); - personMap.put("nation", 1); - } - } else { - personMap.put("nation", 1); - } - personMap.put("nationName", (userE.getNationName() != null && !userE.getNationName().trim().isEmpty()) ? userE.getNationName().trim() : "汉族"); - personMap.put("service", "evo-thirdParty"); - - Object faceFile = avatarSource != null ? avatarSource : userE.getFaceFile(); - - java.util.function.Function extractThumbFromSingle = (singleObj) -> { - if (singleObj == null) { - return null; - } - if (singleObj instanceof String) { - return singleObj.toString(); - } - if (singleObj instanceof Map) { - Map faceFileMap = (Map) singleObj; - Object thumbUrlObj = faceFileMap.get("thumbUrl"); - if (thumbUrlObj != null) { - return thumbUrlObj.toString(); - } - } else if (singleObj instanceof cn.hutool.json.JSONObject) { - cn.hutool.json.JSONObject faceJson = (cn.hutool.json.JSONObject) singleObj; - Object thumbUrlObj = faceJson.get("thumbUrl"); - if (thumbUrlObj != null) { - return thumbUrlObj.toString(); - } - } else { - try { - cn.hutool.json.JSONObject faceJson = cn.hutool.json.JSONUtil.parseObj(singleObj); - Object thumbUrlObj = faceJson.get("thumbUrl"); - if (thumbUrlObj != null) { - return thumbUrlObj.toString(); - } - } catch (Exception e) { - log.warn("解析单个图片对象为JSON失败: {}", e.getMessage()); - } - } - return null; - }; - - String thumbUrl = null; - if (faceFile != null) { - boolean isArray = false; - Object firstElement = null; - if (faceFile instanceof java.util.Collection) { - isArray = true; - java.util.Collection coll = (java.util.Collection) faceFile; - if (!coll.isEmpty()) { - firstElement = coll.iterator().next(); - } - } else if (faceFile.getClass().isArray()) { - isArray = true; - Object[] arr = (Object[]) faceFile; - if (arr.length > 0) { - firstElement = arr[0]; - } - } else if (faceFile instanceof cn.hutool.json.JSONArray) { - isArray = true; - cn.hutool.json.JSONArray jsonArr = (cn.hutool.json.JSONArray) faceFile; - if (!jsonArr.isEmpty()) { - firstElement = jsonArr.get(0); - } - } - - if (isArray) { - if (firstElement != null) { - thumbUrl = extractThumbFromSingle.apply(firstElement); - } - } else { - thumbUrl = extractThumbFromSingle.apply(faceFile); - } - } - - - - if (thumbUrl != null && !thumbUrl.trim().isEmpty()) { - String trimmedThumb = thumbUrl.trim(); - boolean startsWithHttp = trimmedThumb.startsWith("http://") || trimmedThumb.startsWith("https://"); - boolean containsComma = trimmedThumb.contains(","); - boolean startsWithDataImage = trimmedThumb.startsWith("data:image"); - - String cleanBase64; - if (containsComma && startsWithDataImage) { - String prefixPart = trimmedThumb.substring(0, trimmedThumb.indexOf(",") + 1); - String bodyPart = trimmedThumb.substring(trimmedThumb.indexOf(",") + 1); - String cleanBody = bodyPart.replaceAll("\\s+", ""); - cleanBase64 = prefixPart + cleanBody; - } else { - String pureBody = trimmedThumb.replaceAll("\\s+", ""); - cleanBase64 = "data:image/jpeg;base64," + pureBody; - } - int commaIdx = cleanBase64.indexOf(","); - String base64BodyOnly = commaIdx >= 0 ? cleanBase64.substring(commaIdx + 1) : cleanBase64; - boolean isLikelyBase64 = base64BodyOnly.matches("^[A-Za-z0-9+/=]+$"); - int bodyLen = base64BodyOnly.length(); - boolean finalHasPrefix = cleanBase64.startsWith("data:image"); - - if (startsWithHttp) { - log.error("同步大华人员失败:人脸图片传的是HTTP/HTTPS URL,要求必须传带data:image前缀的base64图片"); - } else if (!finalHasPrefix) { - log.error("同步大华人员失败:人脸图片最终无data:image前缀,代码补齐逻辑失效"); - } else if (!isLikelyBase64) { - log.error("同步大华人员失败:人脸图片base64主体含非base64非法字符"); - } else if (bodyLen < 1000) { - log.error("同步大华人员失败:人脸图片base64主体长度过短({}),缩略图可能损坏", bodyLen); - } - - List> personBiosignatures = new ArrayList<>(); - Map biosignature = new java.util.LinkedHashMap<>(); - biosignature.put("type", 3); - biosignature.put("index", 1); - biosignature.put("base64Data", cleanBase64); - personBiosignatures.add(biosignature); - personMap.put("personBiosignatures", personBiosignatures); - } else { - log.warn("未获取到人脸图片thumbUrl,personBiosignatures将不传递"); - } - - Integer age = null; - Integer sex = null; - if (plainIdCard != null && plainIdCard.length() == 18) { - try { - String birthStr = plainIdCard.substring(6, 14); - LocalDate birthDate = LocalDate.parse(birthStr, DateTimeFormatter.ofPattern("yyyyMMdd")); - age = Period.between(birthDate, LocalDate.now()).getYears(); - char sexChar = plainIdCard.charAt(16); - int sexNum = Integer.parseInt(String.valueOf(sexChar)); - sex = (sexNum % 2 == 1) ? 1 : 2; - } catch (Exception e) { - log.warn("解析身份证号获取年龄性别失败: {}, error={}", plainIdCard, e.getMessage()); - } - } - if (age == null) { - if (userE.getBirthday() != null && !userE.getBirthday().trim().isEmpty()) { - try { - String birthdayStr = userE.getBirthday().trim(); - LocalDate birthDate = null; - if (birthdayStr.length() == 8 && birthdayStr.matches("\\d{8}")) { - birthDate = LocalDate.parse(birthdayStr, DateTimeFormatter.ofPattern("yyyyMMdd")); - } else if (birthdayStr.contains("-")) { - birthDate = LocalDate.parse(birthdayStr, DateTimeFormatter.ofPattern("yyyy-MM-dd")); - } else if (birthdayStr.contains("/")) { - birthDate = LocalDate.parse(birthdayStr, DateTimeFormatter.ofPattern("yyyy/MM/dd")); - } - if (birthDate != null) { - age = Period.between(birthDate, LocalDate.now()).getYears(); - } - } catch (Exception ignored) {} - } - } - if (age == null) { - age = 23; - } - if (sex == null) { - if ("1".equals(userE.getSex()) || "男".equals(userE.getSex())) { - sex = 1; - } else if ("2".equals(userE.getSex()) || "女".equals(userE.getSex())) { - sex = 2; - } else { - sex = 1; - } - } - personMap.put("age", age); - personMap.put("sex", sex); - Map extraHeaders = new HashMap<>(); - try { - ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); - if (attrs != null) { - HttpServletRequest req = attrs.getRequest(); - String token = req.getHeader("token"); - String orgid = req.getHeader("orgid"); - String tenantId = req.getHeader("tenantId"); - if (token != null && !token.trim().isEmpty()) { - extraHeaders.put("token", token); - } - if (orgid != null && !orgid.trim().isEmpty()) { - extraHeaders.put("orgid", orgid); - } - if (tenantId != null && !tenantId.trim().isEmpty()) { - extraHeaders.put("tenantId", tenantId); - } - } - } catch (Exception e) { - log.warn("获取当前请求头异常: {}", e.getMessage()); - } - 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); - } - result.setDahuaCode(plainIdCard); - userE.setDahuaCode(plainIdCard); - if (success == null || !success) { - String errCode = (String) syncResult.getOrDefault("errCode", ""); - String errMessage = (String) syncResult.getOrDefault("errMessage", "大华人员同步失败"); - if (throwOnFail) { - throw new BizException("同步大华平台失败:" + errMessage); - } else { - log.warn("同步大华平台未成功(重复信息或其他原因,不影响本地数据保存): errCode={}, errMessage={}, userId={}, idCardMask={}", - errCode, errMessage, userE.getId(), maskedIdCard); - return result; - } - } - Object data = syncResult.get("data"); - if (data != null) { - if (data instanceof Map) { - Map dataMap = (Map) data; - Object idObj = dataMap.get("id"); - if (idObj != null) { - try { - Integer dahuaId = Integer.valueOf(idObj.toString()); - result.setDahuaId(dahuaId); - userE.setDahuaId(dahuaId); - log.info("设置大华dahuaId成功, dahuaId={}", dahuaId); - } catch (Exception e) { - log.warn("转换大华返回id为Integer失败, idObj={}", idObj); - } - } - } else if (data instanceof cn.hutool.json.JSONObject) { - cn.hutool.json.JSONObject dataJson = (cn.hutool.json.JSONObject) data; - Object idObj = dataJson.get("id"); - if (idObj != null) { - try { - Integer dahuaId = Integer.valueOf(idObj.toString()); - result.setDahuaId(dahuaId); - userE.setDahuaId(dahuaId); - log.info("设置大华dahuaId成功, dahuaId={}", dahuaId); - } catch (Exception e) { - log.warn("转换大华返回id为Integer失败, idObj={}", idObj); - } - } - } - } - userE.setDahuaCode(plainIdCard); - return result; - } - @Transactional(rollbackFor = Exception.class) public boolean executeRegister(AppUserRegisterCmd cmd) { @@ -866,63 +498,19 @@ 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(); } @Transactional(rollbackFor = Exception.class) public boolean executeXgf(UserXgfAddCmd cmd) { - log.info("开始新增相关方用户,name: {}, corpinfoId: {}, phone: {}", cmd.getName(), cmd.getCorpinfoId(), cmd.getPhone()); - try { - ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); - if (attrs != null) { - HttpServletRequest req = attrs.getRequest(); - String orgidHeader = req.getHeader("orgid"); - if (orgidHeader != null && cmd.getCorpinfoId() == null) { - try { - cmd.setCorpinfoId(Long.parseLong(orgidHeader.trim())); - } catch (Exception e) { - log.warn("orgid 转 Long 失败: {}", orgidHeader); - } - } - } - } catch (Exception e) { - log.warn("获取请求头异常: {}", e.getMessage()); - } - Long tenantId = null; SSOUser ssoUser = AuthContext.getCurrentUser(); - if (ssoUser != null) { - tenantId = ssoUser.getTenantId(); - } + Long tenantId = ssoUser.getTenantId(); UserE userE = new UserE(); BeanUtils.copyProperties(cmd, userE); - // tenantId 优先级:cmd 传值 -> AuthContext 上下文 -> ssoUser - if (!ObjectUtils.isEmpty(userE.getTenantId())) { - tenantId = userE.getTenantId(); - } else if (!ObjectUtils.isEmpty(userE.getCorpinfoId())) { - tenantId = userE.getCorpinfoId(); - } else { - try { - Long ctxTenantId = AuthContext.getTenantId(); - if (ctxTenantId != null) { - tenantId = ctxTenantId; - } - } catch (Exception e) { - log.warn("从 AuthContext 获取 tenantId 失败: {}", e.getMessage()); - } - } - if (tenantId == null && ObjectUtils.isEmpty(userE.getCorpinfoId())) { - throw new BizException("无法获取租户信息,请登录后重试或在请求中指定 corpinfoId"); - } - if (ObjectUtils.isEmpty(userE.getCorpinfoId())) { - userE.setCorpinfoId(tenantId); - } userE.initAdd(tenantId, userE); CorpInfoDO corpInfoDO = corpInfoRepository.getById(userE.getCorpinfoId()); - if (corpInfoDO == null) { - throw new BizException("企业信息不存在,corpinfoId=" + userE.getCorpinfoId()); - } userE.setUserType(CorpTypeEnum.getUserTypeByCode(corpInfoDO.getType())); Long roleId = userRepository.getDefaultRoleId(); if (roleId == null) { @@ -995,54 +583,6 @@ public class UserAddExe { userExpandInfoRepository.updateByPhone(userE.getPhone(),userE.getFlowFlag()); } - // ========== 相关方用户同步大华(统一用 /person/sync;重复信息返回false直接跳过不影响本地)========== - Long xgfUserId = addFlag ? userE.getId() : userDOUpdate.getId(); - if (xgfUserId == null) { - log.warn("相关方用户保存后未获取到userId,跳过大华同步及dahua信息写回, addFlag={}", addFlag); - } else { - Object xgfAvatarSource = cmd.getUserImg(); - if (xgfAvatarSource == null) { - xgfAvatarSource = cmd.getUserAvatarUrl(); - } - DaHuaSyncResult xgfSyncResult = null; - try { - xgfSyncResult = syncDaHuaPerson(userE, xgfAvatarSource, false); - } catch (Exception e) { - log.error("相关方用户同步大华异常(不影响本地保存,继续执行写回身份证号为dahuaCode), userId={}, addFlag={}, error={}", - xgfUserId, addFlag, e.getMessage(), e); - } - // 无论大华同步成功/失败/返回false/抛异常,都尝试写回dahuaId/dahuaCode: - // dahuaId = 大华返回的id(成功时才有,失败/异常/重复时为null) - // dahuaCode = 前端传的身份证号(经过Base64解码的明文,syncDaHuaPerson里即使失败也已经set到result了) - Integer xgfDahuaId = xgfSyncResult != null ? xgfSyncResult.dahuaId : null; - String xgfDahuaCode = xgfSyncResult != null ? xgfSyncResult.dahuaCode : null; - // 如果xgfSyncResult异常或dahuaCode为空兜底:直接把userE.getUserIdCard()做一次Base64解码写入dahuaCode,保证100%写回 - if ((xgfDahuaCode == null || xgfDahuaCode.trim().isEmpty()) && userE.getUserIdCard() != null && !userE.getUserIdCard().trim().isEmpty()) { - String idCardRaw = userE.getUserIdCard().trim(); - try { - xgfDahuaCode = new String(java.util.Base64.getDecoder().decode(idCardRaw), java.nio.charset.StandardCharsets.UTF_8); - } catch (Exception e) { - xgfDahuaCode = idCardRaw; - } - } - if (xgfDahuaId != null || (xgfDahuaCode != null && !xgfDahuaCode.trim().isEmpty())) { - try { - UserE updateDahua = new UserE(); - updateDahua.setId(xgfUserId); - updateDahua.setDahuaId(xgfDahuaId); - updateDahua.setDahuaCode(xgfDahuaCode); - userRepository.updateDahuaInfo(updateDahua.getId(), updateDahua.getDahuaId(), updateDahua.getDahuaCode()); - log.info("相关方用户写回dahuaId/dahuaCode成功, userId={}, addFlag={}, dahuaId={}, dahuaCode={}", - xgfUserId, addFlag, xgfDahuaId, xgfDahuaCode); - } catch (Exception e) { - log.error("相关方用户写回dahuaId/dahuaCode失败, userId={}, addFlag={}, dahuaId={}, dahuaCode={}", - xgfUserId, addFlag, xgfDahuaId, xgfDahuaCode, e); - } - } else { - log.warn("相关方用户既无dahuaId也无dahuaCode可写回,跳过update, userId={}, addFlag={}", xgfUserId, addFlag); - } - } - // ========================================================================= //页面相关保存user_corp /** @@ -1181,4 +721,5 @@ public class UserAddExe { userChangeRecordE.initUserAdd(userE, corpName, departmentName); userChangeRecordGateway.add(userChangeRecordE); } -} \ No newline at end of file +} + diff --git a/web-app/src/main/java/com/zcloud/basic/info/command/UserImportExe.java b/web-app/src/main/java/com/zcloud/basic/info/command/UserImportExe.java index d5274dcf..c1488097 100644 --- a/web-app/src/main/java/com/zcloud/basic/info/command/UserImportExe.java +++ b/web-app/src/main/java/com/zcloud/basic/info/command/UserImportExe.java @@ -415,9 +415,9 @@ public class UserImportExe { user.setPostId(postId); user.setCorpinfoId(corpinfoId); user.setName(importEntity.getName()); - user.setUserIdCard(encodeBase64IdCard(importEntity.getUserIdCard())); + user.setUserIdCard(null); user.setPersonnelType(importEntity.getPersonnelType()); - user.setPersonnelTypeName(importEntity.getPersonnelTypeName()); + user.setPersonnelTypeName(importEntity.getPersonnelType()); user.resetPassword(corpInfoDO.getType()); userGateway.add(user); String corpName = null; @@ -444,5 +444,4 @@ public class UserImportExe { return userIdCard.trim(); } } -} - +} \ No newline at end of file diff --git a/web-client/src/main/java/com/zcloud/basic/info/dto/UserAddCmd.java b/web-client/src/main/java/com/zcloud/basic/info/dto/UserAddCmd.java index 13a25bcf..16a4b44a 100644 --- a/web-client/src/main/java/com/zcloud/basic/info/dto/UserAddCmd.java +++ b/web-client/src/main/java/com/zcloud/basic/info/dto/UserAddCmd.java @@ -80,6 +80,9 @@ public class UserAddCmd extends Command { @ApiModelProperty(value = "人脸头像url", name = "userAvatarUrl") private String userAvatarUrl; + @ApiModelProperty(value = "人脸图片文件(取thumbUrl字段作为base64传大华)") + private Object faceFile; + @ApiModelProperty(value = "现住址", name = "currentAddress") private String currentAddress; @@ -159,5 +162,10 @@ public class UserAddCmd extends Command { @ApiModelProperty(value = "是否缴纳其他人身伤害保险") private Integer isBf; -} + private Integer rzFlag; + + @ApiModelProperty(value = "该人员在大华口门对应的id") + private Integer dahuaId; + @ApiModelProperty(value = "该人员在大华口门对应的code") + private String dahuaCode; diff --git a/web-client/src/main/java/com/zcloud/basic/info/dto/clientobject/UserCO.java b/web-client/src/main/java/com/zcloud/basic/info/dto/clientobject/UserCO.java index a419d504..43bba875 100644 --- a/web-client/src/main/java/com/zcloud/basic/info/dto/clientobject/UserCO.java +++ b/web-client/src/main/java/com/zcloud/basic/info/dto/clientobject/UserCO.java @@ -194,6 +194,10 @@ public class UserCO extends ClientObject { @ApiModelProperty(value = "微信openid") private String openId; + @ApiModelProperty(value = "该人员在大华口门对应的id") + private Integer dahuaId; + @ApiModelProperty(value = "该人员在大华口门对应的code") + private String dahuaCode; @ApiModelProperty(value = "是否特殊工种") private Integer isSpecialJob; @@ -221,5 +225,4 @@ public class UserCO extends ClientObject { @ApiModelProperty(value = "是否九公司人员") private Boolean nineCompanyFlag; -} - +} \ No newline at end of file diff --git a/web-domain/src/main/java/com/zcloud/basic/info/domain/model/UserE.java b/web-domain/src/main/java/com/zcloud/basic/info/domain/model/UserE.java index d023270d..139d4092 100644 --- a/web-domain/src/main/java/com/zcloud/basic/info/domain/model/UserE.java +++ b/web-domain/src/main/java/com/zcloud/basic/info/domain/model/UserE.java @@ -21,6 +21,7 @@ import com.zcloud.gbscommon.utils.Sm2Util; import com.zcloud.gbscommon.utils.Tools; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.springframework.util.ObjectUtils; import org.springframework.web.multipart.MultipartFile; @@ -42,6 +43,7 @@ import java.util.stream.Collectors; * @Date 2025-11-04 14:07:34 */ @Data +@Slf4j public class UserE extends BaseE { //GBS用户id private Long id; @@ -155,6 +157,12 @@ public class UserE extends BaseE { // 入职状态 private Integer flowFlag; private Integer rzFlag; + // 人脸图片文件 + private Object faceFile; + // 该人员在大华口门对应的id + private Integer dahuaId; + // 该人员在大华口门对应的code + private String dahuaCode; // 父级租户id private final Long parentTenantId = 1989259383784415232L; // 默认密码 @@ -358,10 +366,19 @@ public class UserE extends BaseE { if (CollUtil.isEmpty(userEList)) { return; } - //判断AuthContext.gettenantId在userList中是否存在 + //优先用当前对象自身的 corpinfoId,否则回退到 AuthContext + Long currentCorpId = this.getCorpinfoId(); + if (currentCorpId == null) { + try { + currentCorpId = AuthContext.getTenantId(); + } catch (Exception e) { + log.warn("checkPhone: 从 AuthContext 获取 tenantId 失败,无法按企业维度校验手机号"); + } + } if (CollUtil.isNotEmpty(userEList)) { //判断是否有当前企业 - boolean flag = userEList.stream().anyMatch(userE -> userE.getCorpinfoId().equals(AuthContext.getTenantId())); + final Long finalCorpId = currentCorpId; + boolean flag = finalCorpId != null && userEList.stream().anyMatch(userE -> finalCorpId.equals(userE.getCorpinfoId())); if (flag) { //需要修改,不是提示 throw new BizException("当前手机号当前企业已存在,请联系管理员"); @@ -416,5 +433,4 @@ public class UserE extends BaseE { } -} - +} \ No newline at end of file diff --git a/web-infrastructure/src/main/java/com/zcloud/basic/info/persistence/dataobject/UserDO.java b/web-infrastructure/src/main/java/com/zcloud/basic/info/persistence/dataobject/UserDO.java index e81102f5..fe4acdcc 100644 --- a/web-infrastructure/src/main/java/com/zcloud/basic/info/persistence/dataobject/UserDO.java +++ b/web-infrastructure/src/main/java/com/zcloud/basic/info/persistence/dataobject/UserDO.java @@ -164,7 +164,10 @@ public class UserDO extends BaseDO { @ApiModelProperty(value = "微信openid") private String openId; - + @ApiModelProperty(value = "该人员在大华口门对应的id") + private Integer dahuaId; + @ApiModelProperty(value = "该人员在大华口门对应的code") + private String dahuaCode; @@ -206,5 +209,4 @@ public class UserDO extends BaseDO { this.userId = userId; } -} - +} \ No newline at end of file