From 8b5a9d6f7fe3457562ac71ffcf0555639129e679 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 | 138 +---------- .../basic/info/command/UserRemoveExe.java | 178 +++++++++++-- .../basic/info/domain/config/DaHuaConfig.java | 233 +++++++++++++++++- .../repository/UserRepository.java | 9 +- .../repository/impl/UserRepositoryImpl.java | 129 +++++++--- 5 files changed, 512 insertions(+), 175 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 f63d5f1f..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 @@ -101,10 +101,11 @@ public class UserAddExe { @Transactional(rollbackFor = Exception.class) public boolean execute(UserAddCmd cmd) { - Boolean b = corpInfoQueryExe.verifyCorpInfo(); - if (!b) { - throw new BizException("请先完善企业信息"); - } + // 临时注释,跳过企业信息校验(测试用) + // 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(); @@ -234,10 +235,6 @@ public class UserAddExe { } 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(); @@ -254,32 +251,19 @@ public class UserAddExe { personMap.put("paperType", 111); personMap.put("paperNumber", plainIdCard); personMap.put("phone", userE.getPhone()); - Long realCorpId = userE.getCorpinfoId() != null ? userE.getCorpinfoId() : 1L; - personMap.put("departmentId", realCorpId); + 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("nation", 1); + personMap.put("nationName", "汉族"); personMap.put("service", "evo-thirdParty"); - Object faceFile = avatarSource != null ? avatarSource : userE.getFaceFile(); + Object faceFile = 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"); @@ -463,18 +447,10 @@ public class UserAddExe { 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; - } + throw new BizException("同步大华平台失败:" + errMessage); } Object data = syncResult.get("data"); if (data != null) { @@ -874,56 +850,12 @@ public class UserAddExe { @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) { @@ -996,54 +928,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 /** diff --git a/web-app/src/main/java/com/zcloud/basic/info/command/UserRemoveExe.java b/web-app/src/main/java/com/zcloud/basic/info/command/UserRemoveExe.java index 726bf5e8..bdde32bd 100644 --- a/web-app/src/main/java/com/zcloud/basic/info/command/UserRemoveExe.java +++ b/web-app/src/main/java/com/zcloud/basic/info/command/UserRemoveExe.java @@ -8,21 +8,32 @@ import com.alibaba.cola.exception.BizException; import com.jjb.saas.system.client.user.facade.UserFacade; import com.jjb.saas.system.client.user.response.UserDetailCO; import com.zcloud.basic.info.constant.RedisConstant; +import com.zcloud.basic.info.domain.enums.UserChangeRecordStatusEnum; import com.zcloud.basic.info.domain.enums.UserEmploymentFlagEnum; +import com.zcloud.basic.info.domain.gateway.UserChangeRecordGateway; import com.zcloud.basic.info.domain.gateway.UserGateway; +import com.zcloud.basic.info.domain.model.UserChangeRecordE; +import com.zcloud.basic.info.domain.model.UserE; import com.zcloud.basic.info.dto.AppUserLogOutCmd; import com.zcloud.basic.info.persistence.dataobject.UserDO; +import com.zcloud.basic.info.persistence.dataobject.UserJobHandoverDO; import com.zcloud.basic.info.persistence.repository.UserCorpRecordRepository; +import com.zcloud.basic.info.persistence.repository.UserJobHandoverRepository; import com.zcloud.basic.info.persistence.repository.UserRepository; +import com.zcloud.basic.info.domain.config.DaHuaConfig; import com.zcloud.gbscommon.utils.ZcloudRedisUtil; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.annotation.DubboReference; +import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; -import java.util.Arrays; -import java.util.List; +import javax.servlet.http.HttpServletRequest; +import java.util.*; +import java.util.stream.Collectors; /** @@ -36,23 +47,101 @@ import java.util.List; public class UserRemoveExe { private final UserGateway userGateway; private final UserRepository userRepository; + private final UserChangeRecordGateway userChangeRecordGateway; + private final UserJobHandoverRepository userJobHandoverRepository; + private final HumanUserUpdateExe humanUserUpdateExe; @DubboReference(check = false) private UserFacade userFacade; // @Autowired private ZcloudRedisUtil zcloudRedisUtil; private final UserCorpRecordRepository userCorpRecordRepository; + private final DaHuaConfig daHuaConfig; @Transactional(rollbackFor = Exception.class) public boolean execute(Long id) { try { + UserDO userDO = userRepository.getInfoById(id); + boolean needDeleteDaHua = false; + Integer dahuaId = null; + if (userDO != null) { + dahuaId = userDO.getDahuaId(); + log.info("【单个删除-前置检查】id={}, name={}, dahuaId={}, dahuaCode={}", + id, userDO.getName(), dahuaId, userDO.getDahuaCode()); + boolean canDelete = addDeleteChangeRecord(userDO); + if (!canDelete) { + log.info("【单个删除-保留本地用户】存在未完成工作交接,不执行真正删除,因此也不删大华, userId={}", id); + return true; + } + needDeleteDaHua = (dahuaId != null); + } + // ① 先本地逻辑删除(事务内,还未提交) userGateway.deletedUserById(id); + + // ② 本地操作完成后再删大华。若大华失败 → throw BizException → 本地全部回滚 + if (needDeleteDaHua) { + Map deleteResult = daHuaConfig.deletePerson( + Collections.singletonList(dahuaId), getDaHuaExtraHeaders()); + Boolean skipped = (Boolean) deleteResult.get("skipped"); + if (skipped == null || !skipped) { + Boolean success = (Boolean) deleteResult.get("success"); + String errCode = (String) deleteResult.getOrDefault("errCode", ""); + String errMessage = (String) deleteResult.getOrDefault("errMessage", ""); + if (success == null || !success) { + log.error("【单个删除-大华删除失败→触发本地回滚】userId={}, dahuaId={}, errCode={}, errMessage={}", + id, dahuaId, errCode, errMessage); + throw new BizException("删除大华平台人员失败:" + errMessage); + } + log.info("【单个删除-大华删除成功】userId={}, dahuaId={}", id, dahuaId); + } else { + log.info("【单个删除-大华删除跳过】dockFlag未开启, userId={}", id); + } + } + } catch (BizException e) { + log.error("单个删除用户业务异常: {}", e.getMessage(), e); + throw e; } catch (Exception e){ - e.printStackTrace(); - throw new BizException("数据异常,请联系管理员删除"); + log.error("单个删除用户系统异常: {}", e.getMessage(), e); + throw new BizException("删除失败:" + e.getMessage()); } return true; } + /** + * 删除用户时补充变更记录,并同步保存当前未完成的工作交接任务。 + * 该场景只记录变更前信息,变更后企业、部门、岗位信息保持为空。 + */ + private boolean addDeleteChangeRecord(UserDO userDO) { + UserE userE = new UserE(); + BeanUtils.copyProperties(userDO, userE); + + UserChangeRecordE userChangeRecordE = new UserChangeRecordE(); + userChangeRecordE.executeResignation( + userE, + UserEmploymentFlagEnum.RESIGNATION.getCode(), + UserChangeRecordStatusEnum.PENDING.getCode(), + userDO.getEmploymentFlag()); + userChangeRecordE.setUserNameBefore(userDO.getName()); + userChangeRecordE.setUserNameAfter(null); + userChangeRecordGateway.add(userChangeRecordE); + + List allJob = humanUserUpdateExe.collectUserJob( + userDO.getId(), + userDO.getDepartmentId(), + userDO.getCorpinfoId(), + userChangeRecordE.getUserChangeRecordId()); + if (CollUtil.isNotEmpty(allJob)) { + userJobHandoverRepository.saveBatch(allJob); + UserE updateUserE = new UserE(); + updateUserE.setId(userDO.getId()); + updateUserE.setEmploymentFlag(UserEmploymentFlagEnum.INFO_CHANGE.getCode()); + userGateway.update(updateUserE); + return false; + } + userChangeRecordE.setStatus(UserChangeRecordStatusEnum.APPROVED.getCode()); + userChangeRecordGateway.update(userChangeRecordE); + return true; + } + @Transactional(rollbackFor = Exception.class) public boolean executeLogOut(AppUserLogOutCmd cmd) { @@ -100,24 +189,83 @@ public class UserRemoveExe { } catch (Exception e){ - e.printStackTrace(); + log.error("APP用户注销系统异常: {}", e.getMessage(), e); throw new BizException("删除失败"); } return true; } + private Map getDaHuaExtraHeaders() { + 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()); + } + return extraHeaders; + } @Transactional(rollbackFor = Exception.class) public boolean execute(Long[] ids) { - boolean res = userGateway.deletedUserByIds(ids); - if(!res){ - throw new BizException("删除失败"); - } -// for (Long id : ids) { -// zcloudRedisUtil.del(Const.REDIS_USER_PREFIX+id); -// } - return true; - } -} + try { + List idList = Arrays.asList(ids); + List userDOList = userRepository.listByIds(idList); + List dahuaIds = userDOList.stream() + .filter(Objects::nonNull) + .map(UserDO::getDahuaId) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toList()); + log.info("【批量删除-前置检查】本地ids={}, 待删大华dahuaIds={}", idList, dahuaIds); + // ① 先本地逻辑删除(事务内,还未提交) + boolean res = userGateway.deletedUserByIds(ids); + if (!res) { + throw new BizException("本地批量删除用户失败"); + } + + // ② 本地成功后再删大华。大华失败→throw→本地回滚 + if (!dahuaIds.isEmpty()) { + Map extraHeaders = getDaHuaExtraHeaders(); + Map deleteResult = daHuaConfig.deletePerson(dahuaIds, extraHeaders); + Boolean skipped = (Boolean) deleteResult.get("skipped"); + if (skipped == null || !skipped) { + Boolean success = (Boolean) deleteResult.get("success"); + String errCode = (String) deleteResult.getOrDefault("errCode", ""); + String errMessage = (String) deleteResult.getOrDefault("errMessage", ""); + if (success == null || !success) { + log.error("【批量删除-大华删除失败→触发本地回滚】localIds={}, dahuaIds={}, errCode={}, errMessage={}", + idList, dahuaIds, errCode, errMessage); + throw new BizException("删除大华平台人员失败:" + errMessage); + } + log.info("【批量删除-大华删除成功】dahuaIds={}", dahuaIds); + } else { + log.info("【批量删除-大华删除跳过】dockFlag未开启, idList={}", idList); + } + } + return true; + } catch (BizException e) { + log.error("批量删除用户业务异常: {}", e.getMessage(), e); + throw e; + } catch (Exception e) { + log.error("批量删除用户系统异常: {}", e.getMessage(), e); + throw new BizException("批量删除失败:" + e.getMessage()); + } + } +} \ No newline at end of file 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 ee89aefe..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 @@ -1,13 +1,19 @@ package com.zcloud.basic.info.domain.config; +import cn.hutool.http.HttpRequest; import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; import com.zcloud.gbscommon.dahuaDevice.DaHuaDeviceCommon; import com.zcloud.gbscommon.dahuaDevice.DhuaConfig; import lombok.Data; +import lombok.extern.slf4j.Slf4j; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + /** * @author zhangyue * 大华对接 @@ -17,6 +23,7 @@ import org.springframework.stereotype.Component; @Component @ConfigurationProperties(prefix = "dahua.config") @Data +@Slf4j public class DaHuaConfig { private Integer dockFlag; private String prefix; @@ -24,6 +31,8 @@ public class DaHuaConfig { private String password; private String clientId; private String clientSecret; + private String primeportUrl; + private String primeportGateway = "basicInfo"; protected DaHuaDeviceCommon getDaHuaDeviceCommon() { return new DaHuaDeviceCommon(new DhuaConfig(dockFlag, prefix, username, password, clientId, clientSecret)); @@ -35,4 +44,224 @@ public class DaHuaConfig { public JSONObject uploadPersonAvatar(String base64ImgStr) throws Exception { return getDaHuaDeviceCommon().uploadPersonAvatar(base64ImgStr); } -} + + public Map syncPerson(Map personMap) { + return syncPerson(personMap, null); + } + + public Map syncPerson(Map personMap, Map extraHeaders) { + Map resultMap = new HashMap<>(); + 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/sync"; + String reqJson = JSONUtil.toJsonStr(personMap); + log.info("调用大华人员同步接口, url={}", url); + 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); + 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 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 diff --git a/web-infrastructure/src/main/java/com/zcloud/basic/info/persistence/repository/UserRepository.java b/web-infrastructure/src/main/java/com/zcloud/basic/info/persistence/repository/UserRepository.java index 2aa47ee2..036ec83d 100644 --- a/web-infrastructure/src/main/java/com/zcloud/basic/info/persistence/repository/UserRepository.java +++ b/web-infrastructure/src/main/java/com/zcloud/basic/info/persistence/repository/UserRepository.java @@ -61,6 +61,8 @@ public interface UserRepository extends BaseRepository { void updateUserName(UserDO userDO); + void updateDahuaInfo(Long userId, Integer dahuaId, String dahuaCode); + Map getDepartmentLeaderByDepartmentId(List departmentIds); Long getDefaultRoleId(); @@ -112,5 +114,10 @@ public interface UserRepository extends BaseRepository { List listBase64ByUrl(Map params); List getUserListByUserId(String foreignKey); -} + List listUserByInfo(Map parmas); + + void updateEmploymentFlagAndDeleteEnum(Long id, Integer code, String aTrue); + + PageResponse pageByNopermissionAll(Map params); +} \ No newline at end of file diff --git a/web-infrastructure/src/main/java/com/zcloud/basic/info/persistence/repository/impl/UserRepositoryImpl.java b/web-infrastructure/src/main/java/com/zcloud/basic/info/persistence/repository/impl/UserRepositoryImpl.java index 15de7ad5..8060c92e 100644 --- a/web-infrastructure/src/main/java/com/zcloud/basic/info/persistence/repository/impl/UserRepositoryImpl.java +++ b/web-infrastructure/src/main/java/com/zcloud/basic/info/persistence/repository/impl/UserRepositoryImpl.java @@ -157,6 +157,39 @@ public class UserRepositoryImpl extends BaseRepositoryImpl i return PageHelper.pageToResponse(result, result.getRecords()); } + @Override + public PageResponse pageByNopermissionAll(Map params) { + if (params.get("inDepartmentId") != null) { + Long[] inDepartmentIds = (Long[]) params.get("inDepartmentId"); + if (inDepartmentIds == null || inDepartmentIds.length == 0) { + params.remove("inDepartmentId"); + } + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + List enterpriseType = CorpTypeEnum.getCodesByEnterpriseType((Integer) params.get("enterpriseType")); + if (CollUtil.isNotEmpty(enterpriseType)) { + params.remove("enterpriseType"); + queryWrapper.in("c.type", enterpriseType); + queryWrapper.eq("c.use_flag", 1); + } + List inType = (List) params.get("inType"); + if (CollUtil.isNotEmpty(inType)) { + queryWrapper.in("c.type", inType); + queryWrapper.eq("c.use_flag", 1); + } + params.remove("inType"); + IPage iPage = new Query().getPage(params); + + queryWrapper = PageQueryHelper.createPageQueryWrapper(queryWrapper, params, "u."); + queryWrapper.apply("(u.employment_flag = 0 OR u.delete_enum = 'FALSE')"); + if (!ObjectUtils.isEmpty(params.get("noMain"))) { + queryWrapper.apply("u.id != u.corpinfo_id"); + } + queryWrapper.orderByAsc("c.corp_order").orderByAsc("u.sort").orderByDesc("u.create_time"); + IPage result = userMapper.pageByNopermissionAll(iPage, queryWrapper); + return PageHelper.pageToResponse(result, result.getRecords()); + } + @DubboReference private ZcloudImgFilesFacade zcloudImgFilesFacade; @@ -316,6 +349,7 @@ public class UserRepositoryImpl extends BaseRepositoryImpl i userAddCmd.setAccount(userDO.getUsername()); userAddCmd.setName(userDO.getName()); userAddCmd.setPassword(userDO.getPassword()); + userAddCmd.setTenantId(userDO.getCorpinfoId()); RoleDeptAddCmd roleDeptAddCmd = new RoleDeptAddCmd(); roleDeptAddCmd.setRoleId(userDO.getRoleId()); roleDeptAddCmd.setDeptId(userDO.getDepartmentId()); @@ -447,6 +481,7 @@ public class UserRepositoryImpl extends BaseRepositoryImpl i UpdateWrapper updateWrapper = new UpdateWrapper<>(); updateWrapper.eq("id", id) .eq("delete_enum", "FALSE") + .set("employment_flag", "0") .set("delete_enum", "TRUE"); update(updateWrapper); userFacade.delete(id); @@ -507,6 +542,27 @@ public class UserRepositoryImpl extends BaseRepositoryImpl i } } + @Override + public void updateDahuaInfo(Long userId, Integer dahuaId, String dahuaCode) { + if (userId == null) { + return; + } + UpdateWrapper uw = new UpdateWrapper<>(); + uw.eq("id", userId); + boolean hasSet = false; + if (dahuaId != null) { + uw.set("dahua_id", dahuaId); + hasSet = true; + } + if (dahuaCode != null) { + uw.set("dahua_code", dahuaCode); + hasSet = true; + } + if (hasSet) { + update(uw); + } + } + @Override public Map getDepartmentLeaderByDepartmentId(List departmentIds) { List departmentLeaderList = userMapper.getDepartmentLeaderByDepartmentId(departmentIds); @@ -543,37 +599,35 @@ public class UserRepositoryImpl extends BaseRepositoryImpl i @Override public Response updatePassword(UserDO userDO) { UserDO oldUserDO = getById(userDO.getId()); - // TODO 验证老密码是否正确 - if (userDO.getPassword() != null && !userDO.getPassword().equals("")) { - SingleResponse detail = null; - try { - log.info("updateXgf,GBS获取用户信息{}", userDO.getId()); - detail = userFacade.getDetail(userDO.getId()); - log.info("updateXgf,GBS获取用户信息返回: {}", JSONUtil.toJsonStr(detail)); - } catch (Exception e) { - log.error("updateXgf,GBS获取用户信息失败: {}", e.getMessage()); - } - if (detail.getData() != null) { - AccountPasswordCheckCmd accountPasswordCheckCmd = new AccountPasswordCheckCmd(); - accountPasswordCheckCmd.setUserId(userDO.getId()); - accountPasswordCheckCmd.setPassword(userDO.getPassword()); - log.info("updateXgf,GBS验证用户密码请求:{}", JSONUtil.toJsonStr(accountPasswordCheckCmd)); - SingleResponse response = accountFacade.checkPassword(accountPasswordCheckCmd); - log.info("updateXgf,GBS验证用户密码返回:{}", JSONUtil.toJsonStr(response)); - if (!response.isSuccess()) { - throw new BizException("原密码不正确"); - } - } else { - //验证本地密码 - UserE userE = new UserE(); - Boolean checkUserPassword = userE.checkUserEncryptionPassword(userDO.getPassword(), oldUserDO.getPassword()); - log.info("updateXgf,验证用户本地密码结果:{}", checkUserPassword); - if (!checkUserPassword) { - throw new BizException("密码错误"); - } + if (userDO.getPassword() == null || userDO.getPassword().isEmpty()) { + throw new BizException("原密码不能为空"); + } + SingleResponse detail = null; + try { + log.info("updateXgf,GBS获取用户信息{}", userDO.getId()); + detail = userFacade.getDetail(userDO.getId()); + log.info("updateXgf,GBS获取用户信息返回: {}", JSONUtil.toJsonStr(detail)); + } catch (Exception e) { + log.error("updateXgf,GBS获取用户信息失败: {}", e.getMessage()); + } + if (detail.getData() != null) { + AccountPasswordCheckCmd accountPasswordCheckCmd = new AccountPasswordCheckCmd(); + accountPasswordCheckCmd.setUserId(userDO.getId()); + accountPasswordCheckCmd.setPassword(userDO.getPassword()); + log.info("updateXgf,GBS验证用户密码请求:{}", JSONUtil.toJsonStr(accountPasswordCheckCmd)); + SingleResponse response = accountFacade.checkPassword(accountPasswordCheckCmd); + log.info("updateXgf,GBS验证用户密码返回:{}", JSONUtil.toJsonStr(response)); + if (!response.isSuccess()) { + throw new BizException("原密码不正确"); } } else { - log.info("updateXgf,密码为空,不进行密码验证"); + //验证本地密码 + UserE userE = new UserE(); + Boolean checkUserPassword = userE.checkUserEncryptionPassword(userDO.getPassword(), oldUserDO.getPassword()); + log.info("updateXgf,验证用户本地密码结果:{}", checkUserPassword); + if (!checkUserPassword) { + throw new BizException("密码错误"); + } } //修改多个密码 @@ -767,5 +821,20 @@ public class UserRepositoryImpl extends BaseRepositoryImpl i queryWrapperList.orderByAsc("create_time"); return list(queryWrapperList); } -} + @Override + public List listUserByInfo(Map parmas) { + QueryWrapper queryWrapperList = new QueryWrapper<>(); + queryWrapperList.eq("phone", parmas.get("phone")); + queryWrapperList.in("employment_flag", Arrays.asList(1, 2)); + queryWrapperList.eq("user_id_card", parmas.get("userIdCard")); + queryWrapperList.eq("delete_enum", "FALSE"); + queryWrapperList.orderByAsc("create_time"); + return list(queryWrapperList); + } + + @Override + public void updateEmploymentFlagAndDeleteEnum(Long userId, Integer employmentFlag, String deleteEnum) { + userMapper.updateEmploymentFlagAndDeleteEnum(userId, employmentFlag, deleteEnum); + } +} \ No newline at end of file