diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkSyncProcessorImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkSyncProcessorImpl.java index 50c1bd92..a32be23a 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkSyncProcessorImpl.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkSyncProcessorImpl.java @@ -13,8 +13,11 @@ import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkHrUs import com.zt.plat.module.system.controller.admin.user.vo.user.UserSaveReqVO; import com.zt.plat.module.system.dal.dataobject.dept.DeptDO; import com.zt.plat.module.system.dal.dataobject.dept.PostDO; +import com.zt.plat.module.system.dal.dataobject.dept.UserPostDO; import com.zt.plat.module.system.dal.dataobject.user.AdminUserDO; +import com.zt.plat.module.system.dal.dataobject.userdept.UserDeptDO; import com.zt.plat.module.system.dal.mysql.dept.PostMapper; +import com.zt.plat.module.system.dal.mysql.dept.UserPostMapper; import com.zt.plat.module.system.dal.mysql.user.AdminUserMapper; import com.zt.plat.module.system.enums.common.SexEnum; import com.zt.plat.module.system.enums.dept.DeptSourceEnum; @@ -24,6 +27,7 @@ import com.zt.plat.module.system.service.dept.DeptService; import com.zt.plat.module.system.service.dept.PostService; import com.zt.plat.module.system.service.integration.iwork.IWorkSyncProcessor; import com.zt.plat.module.system.service.user.AdminUserService; +import com.zt.plat.module.system.service.userdept.UserDeptService; import com.zt.plat.module.system.util.sync.SyncVerifyUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -33,6 +37,7 @@ import org.springframework.util.DigestUtils; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; @Slf4j @Service @@ -47,8 +52,10 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor { private final DeptService deptService; private final PostService postService; private final PostMapper postMapper; + private final UserPostMapper userPostMapper; private final AdminUserService adminUserService; private final AdminUserMapper adminUserMapper; + private final UserDeptService userDeptService; private final Map postCache = new ConcurrentHashMap<>(); @@ -531,11 +538,16 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor { String externalPassword) { UserSaveReqVO req = buildUserSaveReq(source, username, deptId, postId, status); req.setId(existing.getId()); + Long iworkDeptId = resolveIWorkDeptId(deptId); + req.setDeptIds(null); + req.setPostIds(null); boolean disabledChanged = CommonStatusEnum.isDisable(status.getStatus()) && CommonStatusEnum.isEnable(existing.getStatus()); boolean infoChanged = isUserInfoChanged(existing, req); boolean passwordChanged = isPasswordChanged(existing, externalPassword); + boolean deptChanged = syncIWorkUserDeptRelations(existing.getId(), iworkDeptId); + boolean postChanged = syncIWorkUserPostRelations(existing.getId(), postId); - if (!infoChanged && !passwordChanged) { + if (!infoChanged && !passwordChanged && !deptChanged && !postChanged) { return new UserSyncOutcome(SyncAction.SKIPPED, false, existing.getId()); } @@ -619,8 +631,9 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor { req.setWorkcode(resolveWorkcode(source)); req.setNickname(limitLength(StrUtil.blankToDefault(source.getLastname(), username), 30)); req.setRemark(buildUserRemark(source)); - if (deptId != null) { - req.setDeptIds(singletonSet(deptId)); + Long iworkDeptId = resolveIWorkDeptId(deptId); + if (iworkDeptId != null) { + req.setDeptIds(singletonSet(iworkDeptId)); } if (postId != null) { req.setPostIds(singletonSet(postId)); @@ -635,6 +648,74 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor { return req; } + private boolean syncIWorkUserDeptRelations(Long userId, Long iworkDeptId) { + if (userId == null) { + return false; + } + List relations = userDeptService.getValidUserDeptListByUserIds(Collections.singleton(userId)); + Set existingDeptIds = relations.stream() + .map(UserDeptDO::getDeptId) + .filter(Objects::nonNull) + .collect(Collectors.toCollection(LinkedHashSet::new)); + Set existingIworkDeptIds = new LinkedHashSet<>(); + if (CollUtil.isNotEmpty(existingDeptIds)) { + Map deptMap = deptService.getDeptMap(existingDeptIds); + existingIworkDeptIds = deptMap.values().stream() + .filter(this::isIWorkDept) + .map(DeptDO::getId) + .filter(Objects::nonNull) + .collect(Collectors.toCollection(LinkedHashSet::new)); + } + Set desiredIworkDeptIds = iworkDeptId == null + ? Collections.emptySet() + : Collections.singleton(iworkDeptId); + if (existingIworkDeptIds.equals(desiredIworkDeptIds)) { + return false; + } + Collection toDelete = CollUtil.subtract(existingIworkDeptIds, desiredIworkDeptIds); + Collection toAdd = CollUtil.subtract(desiredIworkDeptIds, existingIworkDeptIds); + if (CollUtil.isNotEmpty(toDelete)) { + userDeptService.deleteUserDeptByUserIdAndDeptIds(userId, toDelete); + } + if (CollUtil.isNotEmpty(toAdd)) { + userDeptService.batchCreateUserDept(Collections.singletonList( + new UserDeptDO().setUserId(userId).setDeptId(iworkDeptId))); + } + return true; + } + + private boolean syncIWorkUserPostRelations(Long userId, Long postId) { + if (userId == null || postId == null) { + return false; + } + List relations = userPostMapper.selectListByUserId(userId); + Set existingPostIds = relations.stream() + .map(UserPostDO::getPostId) + .filter(Objects::nonNull) + .collect(Collectors.toCollection(LinkedHashSet::new)); + if (existingPostIds.contains(postId)) { + return false; + } + userPostMapper.insertBatch(Collections.singletonList( + new UserPostDO().setUserId(userId).setPostId(postId))); + return true; + } + + private Long resolveIWorkDeptId(Long deptId) { + if (deptId == null) { + return null; + } + DeptDO dept = deptService.getDept(deptId); + return isIWorkDept(dept) ? deptId : null; + } + + private boolean isIWorkDept(DeptDO dept) { + if (dept == null) { + return false; + } + return Objects.equals(dept.getDeptSource(), DeptSourceEnum.IWORK.getSource()); + } + private void mergeDeptDefaults(DeptSaveReqVO target, DeptDO existing) { target.setCode(StrUtil.blankToDefault(target.getCode(), existing.getCode())); target.setShortName(StrUtil.blankToDefault(target.getShortName(), existing.getShortName())); diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/userdept/UserDeptService.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/userdept/UserDeptService.java index 26c728b7..7a4e027c 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/userdept/UserDeptService.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/userdept/UserDeptService.java @@ -70,6 +70,13 @@ public interface UserDeptService { */ void deleteUserDeptByUserId(Long userId); + /** + * 根据用户ID与部门ID集合删除用户与部门关系 + * @param userId 用户ID + * @param deptIds 部门ID集合 + */ + void deleteUserDeptByUserIdAndDeptIds(Long userId, Collection deptIds); + /** * 批量创建用户与部门关系 * @param createReqVOList 创建信息列表 diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/userdept/UserDeptServiceImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/userdept/UserDeptServiceImpl.java index 8c71a020..bbc78645 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/userdept/UserDeptServiceImpl.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/userdept/UserDeptServiceImpl.java @@ -3,6 +3,7 @@ package com.zt.plat.module.system.service.userdept; import cn.hutool.core.collection.CollUtil; import com.zt.plat.framework.common.util.object.BeanUtils; import com.zt.plat.framework.security.core.LoginUser; +import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX; import com.zt.plat.module.system.dal.dataobject.userdept.UserDeptDO; import com.zt.plat.module.system.dal.mysql.userdept.UserDeptMapper; import jakarta.annotation.Resource; @@ -128,10 +129,20 @@ public class UserDeptServiceImpl implements UserDeptService { @Override public void deleteUserDeptByUserId(Long userId) { if (userId == null) return; - userDeptMapper.delete(new com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX() + userDeptMapper.delete(new LambdaQueryWrapperX() .eq(UserDeptDO::getUserId, userId)); } + @Override + public void deleteUserDeptByUserIdAndDeptIds(Long userId, Collection deptIds) { + if (userId == null || CollUtil.isEmpty(deptIds)) { + return; + } + userDeptMapper.delete(new LambdaQueryWrapperX() + .eq(UserDeptDO::getUserId, userId) + .in(UserDeptDO::getDeptId, deptIds)); + } + @Override @Transactional(rollbackFor = Exception.class) public void batchCreateUserDept(List createReqVOList) {