diff --git a/honeycom-spdm/src/main/java/com/honeycombis/honeycom/spdm/controller/SpdmUserController.java b/honeycom-spdm/src/main/java/com/honeycombis/honeycom/spdm/controller/SpdmUserController.java index 8491531..9ccee27 100644 --- a/honeycom-spdm/src/main/java/com/honeycombis/honeycom/spdm/controller/SpdmUserController.java +++ b/honeycom-spdm/src/main/java/com/honeycombis/honeycom/spdm/controller/SpdmUserController.java @@ -30,6 +30,7 @@ import com.honeycombis.honeycom.spdm.feign.RemoteTenantServiceFeign; import com.honeycombis.honeycom.spdm.feign.RemoteUserServiceFeign; import com.honeycombis.honeycom.spdm.util.PageResult; import com.honeycombis.honeycom.spdm.util.ResponseR; +import com.honeycombis.honeycom.tenant.dto.SysDeptTreeAndListRequestDTO; import com.honeycombis.honeycom.tenant.entity.SysDeptEntity; import com.honeycombis.honeycom.tenant.entity.SysStaffEntity; import com.honeycombis.honeycom.tenant.vo.SysRoleVO; @@ -195,8 +196,8 @@ public class SpdmUserController { if (staffPage != null) { List userVOList = new ArrayList<>(); staffPage.getRecords().forEach(i -> { - R sysUserVO = remoteUserServiceFeign.getUserByUserId(Long.valueOf(i.getUserId()), SecurityConstants.FROM_IN, groupQueryDto.getTenantId()); - userVOList.add(sysUserVO.getData()); +// R sysUserVO = remoteUserServiceFeign.getUserByUserId(Long.valueOf(i.getUserId()), SecurityConstants.FROM_IN, groupQueryDto.getTenantId()); + userVOList.add(i.getUserInfo()); }); jsonObject.put("users", PageResult.of(staffPage.getTotal(), staffPage.getCurrent(), staffPage.getSize(), userVOList)); } @@ -204,6 +205,62 @@ public class SpdmUserController { return ResponseR.ok(jsonObject); } + @Operation(summary = "获取部门树") + @PostMapping(value = "/getDeptTree") + public ResponseR getDeptTree(@RequestBody GroupQueryDto groupQueryDto) { + SysDeptTreeAndListRequestDTO req = new SysDeptTreeAndListRequestDTO(); + req.setDeptName(groupQueryDto.getGroupName()); + req.setDeptCode(groupQueryDto.getGroupCode()); + R result = remoteTenantServiceFeign.getDeptTree(req, groupQueryDto.getTenantId()); + + if (result.isSuccess() && result.getData() != null) { + // Feign 反序列化后实际是 LinkedHashMap,需要手动转换 + @SuppressWarnings("unchecked") + List> deptList = (List>) result.getData(); + List groupResultDtoList = new ArrayList<>(deptList.size()); + for (Map deptMap : deptList) { + groupResultDtoList.add(convertMapToGroupResultDto(deptMap)); + } + return ResponseR.ok(groupResultDtoList); + } + return ResponseR.ok(); + } + + private static final java.time.ZoneId SYSTEM_ZONE_ID = java.time.ZoneId.systemDefault(); + + /** + * 递归将 Map 转换为 GroupResultDto + */ + @SuppressWarnings("unchecked") + private GroupResultDto convertMapToGroupResultDto(Map map) { + Long id = map.get("deptId") != null ? Long.valueOf(map.get("deptId").toString()) : null; + String groupCode = (String) map.get("deptCode"); + String groupName = (String) map.get("deptName"); +// LocalDateTime createTime = toLocalDateTime(map.get("createTime")); +// LocalDateTime updateTime = toLocalDateTime(map.get("updateTime")); + + List> childList = (List>) map.get("children"); + List children = null; + if (CollectionUtils.isNotEmpty(childList)) { + children = new ArrayList<>(childList.size()); + for (Map child : childList) { + children.add(convertMapToGroupResultDto(child)); + } + } + + return new GroupResultDto(id, groupCode, groupName, children); + } + + /** + * 时间戳转换为 LocalDateTime + */ + private LocalDateTime toLocalDateTime(Object timestamp) { + if (timestamp instanceof Number num) { + return java.time.Instant.ofEpochMilli(num.longValue()).atZone(SYSTEM_ZONE_ID).toLocalDateTime(); + } + return null; + } + @Operation(summary = "根据用户ids返回用户列表") @PostMapping(value = "/listUserByIds") public ResponseR listUserByIds(@RequestBody UserParamDto paramDto) { diff --git a/honeycom-spdm/src/main/java/com/honeycombis/honeycom/spdm/dto/GroupResultDto.java b/honeycom-spdm/src/main/java/com/honeycombis/honeycom/spdm/dto/GroupResultDto.java index f44df42..05ad11c 100644 --- a/honeycom-spdm/src/main/java/com/honeycombis/honeycom/spdm/dto/GroupResultDto.java +++ b/honeycom-spdm/src/main/java/com/honeycombis/honeycom/spdm/dto/GroupResultDto.java @@ -7,11 +7,10 @@ import lombok.Data; import lombok.NoArgsConstructor; import java.time.LocalDateTime; +import java.util.List; @Data @Schema(description = "用户组返回参数实体") -@NoArgsConstructor -@AllArgsConstructor public class GroupResultDto { @Schema(description = "用户组ID") private Long id; @@ -30,4 +29,33 @@ public class GroupResultDto { @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime updateTime; + @Schema(description = "子部门列表") + private List children; + + public GroupResultDto() { + } + + public GroupResultDto(Long id, String groupCode, String groupName, LocalDateTime createTime, LocalDateTime updateTime) { + this.id = id; + this.groupCode = groupCode; + this.groupName = groupName; + this.createTime = createTime; + this.updateTime = updateTime; + } + + public GroupResultDto(Long id, String groupCode, String groupName, LocalDateTime createTime, LocalDateTime updateTime, List children) { + this.id = id; + this.groupCode = groupCode; + this.groupName = groupName; + this.createTime = createTime; + this.updateTime = updateTime; + this.children = children; + } + + public GroupResultDto(Long id, String groupCode, String groupName, List children) { + this.id = id; + this.groupCode = groupCode; + this.groupName = groupName; + this.children = children; + } } diff --git a/honeycom-spdm/src/main/java/com/honeycombis/honeycom/spdm/feign/RemoteTenantServiceFeign.java b/honeycom-spdm/src/main/java/com/honeycombis/honeycom/spdm/feign/RemoteTenantServiceFeign.java index 291a84a..bda71e9 100644 --- a/honeycom-spdm/src/main/java/com/honeycombis/honeycom/spdm/feign/RemoteTenantServiceFeign.java +++ b/honeycom-spdm/src/main/java/com/honeycombis/honeycom/spdm/feign/RemoteTenantServiceFeign.java @@ -1,5 +1,6 @@ package com.honeycombis.honeycom.spdm.feign; +import cn.hutool.core.lang.tree.Tree; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.honeycombis.honeycom.common.core.constant.CommonConstants; import com.honeycombis.honeycom.common.core.constant.SecurityConstants; @@ -7,6 +8,7 @@ import com.honeycombis.honeycom.common.core.constant.ServiceNameConstants; import com.honeycombis.honeycom.common.core.util.R; import com.honeycombis.honeycom.common.feign.config.FeignConfig; import com.honeycombis.honeycom.spdm.dto.*; +import com.honeycombis.honeycom.tenant.dto.SysDeptTreeAndListRequestDTO; import com.honeycombis.honeycom.tenant.entity.SysDeptEntity; import com.honeycombis.honeycom.tenant.entity.SysPostEntity; import com.honeycombis.honeycom.tenant.entity.SysStaffEntity; @@ -41,6 +43,8 @@ public interface RemoteTenantServiceFeign { R> listDeptForPage(@SpringQueryMap GroupQueryDto pageQueryDto, @RequestHeader(CommonConstants.TENANT_ID) String tenantIdHeader); @GetMapping("/sysDept/{deptId}") R queryDeptById(@PathVariable("deptId" ) Long deptId, @RequestHeader(CommonConstants.TENANT_ID) String tenantIdHeader); + @PostMapping("/sysDept/tree") + R>> getDeptTree(@RequestBody SysDeptTreeAndListRequestDTO req, @RequestHeader(CommonConstants.TENANT_ID) String tenantIdHeader); @GetMapping("/sysStaff/findByDeptIds") R>> findByDeptIds(@RequestParam("deptIds") List deptIds, @RequestHeader(SecurityConstants.FROM) String from); diff --git a/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/controller/SysHrSyncController.java b/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/controller/SysHrSyncController.java index 19e46b1..2050f36 100644 --- a/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/controller/SysHrSyncController.java +++ b/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/controller/SysHrSyncController.java @@ -131,6 +131,39 @@ public class SysHrSyncController { return R.ok(); } + @Inner(value = false) + @PostMapping("/allSyncLyricUsers2") + public R allSyncLyricUsers2(@RequestBody List userDtoList) { + // 获取利元亨用户数据(带部门) + R> userListR = remoteSpdmService.queryUserList(null); + if (userListR.getData() != null) { + Map> userMapByWorkType = userListR.getData().stream().collect(Collectors.groupingBy(LyricUserDto::getWork_type_name)); + for (String workType : userMapByWorkType.keySet()) { + log.info("-------------------------开始同步{}的用户数据----------------------", workType); + try { + tkMoldService.allSyncLyricUsers2(userMapByWorkType.get(workType), workType); + } catch (Exception e) { + log.error("全量同步用户数据失败", e); + throw new HoneycomException(e.getMessage()); + } + } + } + return R.ok(); + } + /** + * 重新同步Lyric部门数据(仅更新部门和员工-部门关联,不删除用户) + */ + @Inner(value = false) + @PostMapping("/resyncLyricDept") + public R resyncLyricDept(@RequestBody List userDtoList) { + try { + tkMoldService.resyncLyricDept(userDtoList); + } catch (Exception e) { + log.error("重新同步部门数据失败", e); + throw new HoneycomException(e.getMessage()); + } + return R.ok(); + } } diff --git a/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/SysPostService.java b/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/SysPostService.java index 713012c..8d2008e 100644 --- a/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/SysPostService.java +++ b/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/SysPostService.java @@ -51,4 +51,11 @@ public interface SysPostService extends IService { Map> mapPostByStaffIdList(List staffIds); SysPostEntity getPostByHrId(Integer hrId); + + /** + * 根据岗位编码查询岗位 + * @param postCode 岗位编码 + * @return 岗位实体 + */ + SysPostEntity getByPostCode(String postCode); } \ No newline at end of file diff --git a/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/SysTKMoldService.java b/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/SysTKMoldService.java index 6b2635e..92b8905 100644 --- a/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/SysTKMoldService.java +++ b/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/SysTKMoldService.java @@ -14,4 +14,12 @@ public interface SysTKMoldService { void addSyncUsers(HrUserInfoAddDataVO hrUserInfoAddDataVO); void allSyncLyricUsers(List userDtoList, String workType); + + void allSyncLyricUsers2(List userDtoList, String workType); + + /** + * 重新同步Lyric部门数据(仅更新部门和员工-部门关联,不删除用户) + * @param userList 全量用户数据列表 + */ + void resyncLyricDept(List userList); } diff --git a/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/converter/TKMoldHrConverter.java b/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/converter/TKMoldHrConverter.java index d6a4ee4..f8400ea 100644 --- a/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/converter/TKMoldHrConverter.java +++ b/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/converter/TKMoldHrConverter.java @@ -21,8 +21,10 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ThreadLocalRandom; import java.util.stream.Collectors; @Component @@ -164,25 +166,121 @@ public class TKMoldHrConverter { return sysDeptEntities; } - public List lyricDeptToTenantDept(List depts, Map deptIdAndDeptIds,Long tenantId) { - List sysDeptEntities = new ArrayList<>(depts.size()); - depts.forEach(dept -> { - SysDeptEntity sysDeptEntity = new SysDeptEntity(); - sysDeptEntity.setTenantId(tenantId); - sysDeptEntity.setDeptCode(dept.getDept_grp_code1()); - sysDeptEntity.setDeptName(dept.getDept_grp_name1()); + /** + * 将Lyric用户数据转换为部门实体,构造4级部门父子层级关系 + *

+ * 部门层级: + * - 一级部门(dept_grp_code1/name1): parentId = 0L + * - 二级部门(dept_grp_code2/name2): parentId = 一级部门deptId + * - 三级部门(dept_grp_code3/name3): parentId = 二级部门deptId + * - 四级部门(dept_grp_code4/name4): parentId = 三级部门deptId (可选,有些用户只有3级) + *

+ * + * @param userList 用户列表(包含部门信息) + * @param deptIdAndDeptIds 用户当前部门编码(dept_code)与部门主键ID的映射(同时也包含数据库中已存在的部门) + * @param tenantId 租户ID + * @return 部门实体列表(已去重,包含父子层级关系) + */ + public List lyricDeptToTenantDept(List userList, Map deptIdAndDeptIds, Map existingDeptMap, Long tenantId) { + List sysDeptEntities = new ArrayList<>(); + + // 用于存储已创建的部门编码与部门ID的映射(用于构建父子关系) + Map createdDeptMap = new HashMap<>(); + + for (LyricUserDto user : userList) { + // 一级部门 + createDeptIfNotExists(createdDeptMap, existingDeptMap, sysDeptEntities, + user.getDept_grp_code1(), user.getDept_grp_name1(), + 0L, tenantId); + + // 二级部门 + if (StrUtil.isNotBlank(user.getDept_grp_code2()) && StrUtil.isNotBlank(user.getDept_grp_name2())) { + createDeptIfNotExists(createdDeptMap, existingDeptMap, sysDeptEntities, + user.getDept_grp_code2(), user.getDept_grp_name2(), + createdDeptMap.get(user.getDept_grp_code1()), tenantId); + } + + // 三级部门 + if (StrUtil.isNotBlank(user.getDept_grp_code3()) && StrUtil.isNotBlank(user.getDept_grp_name3())) { + Long parentId = createdDeptMap.get(user.getDept_grp_code2()); + if (parentId != null) { + createDeptIfNotExists(createdDeptMap, existingDeptMap, sysDeptEntities, + user.getDept_grp_code3(), user.getDept_grp_name3(), + parentId, tenantId); + } + } + + // 四级部门(可选,有些用户只有三级部门) + if (StrUtil.isNotBlank(user.getDept_grp_code4()) && StrUtil.isNotBlank(user.getDept_grp_name4())) { + Long parentId = createdDeptMap.get(user.getDept_grp_code3()); + if (parentId != null) { + createDeptIfNotExists(createdDeptMap, existingDeptMap, sysDeptEntities, + user.getDept_grp_code4(), user.getDept_grp_name4(), + parentId, tenantId); + } + } + + // 记录用户当前部门(dept_code)与部门主键ID的映射 + // dept_code可能是三级或四级部门编码 + if (StrUtil.isNotBlank(user.getDept_code())) { + Long currentDeptId = createdDeptMap.get(user.getDept_code()); + if (currentDeptId != null) { + deptIdAndDeptIds.put(user.getDept_code(), currentDeptId); + } + } + } - long id = IdWorker.getId(sysDeptEntity); - sysDeptEntity.setDeptId(id); - sysDeptEntity.setParentId(0L); - sysDeptEntity.setCreateBy(0L); - sysDeptEntity.setUpdateBy(0L); - deptIdAndDeptIds.put(dept.getDept_grp_code1(), id); - sysDeptEntities.add(sysDeptEntity); - }); return sysDeptEntities; } + /** + * 如果部门不存在则创建,存在则跳过 + * + * @param createdDeptMap 本次同步中已创建的部门映射(code -> deptId) + * @param existingDeptMap 数据库中已存在的部门映射(code -> deptId) + * @param deptList 部门实体列表 + * @param deptCode 部门编码 + * @param deptName 部门名称 + * @param parentId 父部门ID + * @param tenantId 租户ID + * @return true表示创建了新部门,false表示部门已存在跳过 + */ + private boolean createDeptIfNotExists(Map createdDeptMap, Map existingDeptMap, + List deptList, + String deptCode, String deptName, Long parentId, Long tenantId) { + // 如果部门编码为空,则跳过 + if (StrUtil.isBlank(deptCode)) { + return false; + } + + // 如果部门已存在于本次同步创建的部门中,则跳过 + if (createdDeptMap.containsKey(deptCode)) { + return false; + } + + // 如果部门已存在于数据库中,则跳过(从existingDeptMap获取ID用于构建父子关系) + if (existingDeptMap.containsKey(deptCode)) { + // 将已存在的部门ID也放入createdDeptMap,用于后续构建父子关系 + createdDeptMap.put(deptCode, existingDeptMap.get(deptCode)); + return false; + } + + SysDeptEntity sysDeptEntity = new SysDeptEntity(); + sysDeptEntity.setTenantId(tenantId); + sysDeptEntity.setDeptCode(deptCode); + sysDeptEntity.setDeptName(deptName); + sysDeptEntity.setParentId(parentId); + sysDeptEntity.setCreateBy(0L); + sysDeptEntity.setUpdateBy(0L); + + long id = IdWorker.getId(sysDeptEntity); + sysDeptEntity.setDeptId(id); + + createdDeptMap.put(deptCode, id); + deptList.add(sysDeptEntity); + return true; + } + public List lyricDeptToTenantDept2(String workType, Map deptIdAndDeptIds,Long tenantId) { List sysDeptEntities = new ArrayList<>(); SysDeptEntity sysDeptEntity = new SysDeptEntity(); @@ -208,6 +306,7 @@ public class TKMoldHrConverter { sysDeptEntity.setDeptCode("GROUP_06"); break; default: + sysDeptEntity.setDeptCode("GROUP_" + ThreadLocalRandom.current().nextInt(10, 100)); break; } @@ -273,9 +372,15 @@ public class TKMoldHrConverter { return sysPostEntities; } - public List lyricJobToPost(List jobs, Map jobIdAndPostIds,Long tenantId) { - List sysPostEntities = new ArrayList<>(jobs.size()); - jobs.forEach(job->{ + public List lyricJobToPost(List jobs, Map jobIdAndPostIds, Long tenantId) { + List sysPostEntities = new ArrayList<>(); + + for (LyricUserDto job : jobs) { + // 如果岗位编码已存在于映射中,则跳过 + if (jobIdAndPostIds.containsKey(job.getJob_code())) { + continue; + } + SysPostEntity sysPostEntity = new SysPostEntity(); sysPostEntity.setPostCode(job.getJob_code()); sysPostEntity.setPostName(job.getJob_name()); @@ -286,9 +391,10 @@ public class TKMoldHrConverter { sysPostEntity.setCreateBy(0L); sysPostEntity.setUpdateBy(0L); sysPostEntity.setSortOrder(0); - jobIdAndPostIds.put(job.getJob_code(),id); + jobIdAndPostIds.put(job.getJob_code(), id); sysPostEntities.add(sysPostEntity); - }); + } + return sysPostEntities; } diff --git a/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/impl/SysDeptServiceImpl.java b/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/impl/SysDeptServiceImpl.java index daae3fc..7bb0021 100644 --- a/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/impl/SysDeptServiceImpl.java +++ b/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/impl/SysDeptServiceImpl.java @@ -161,7 +161,7 @@ public class SysDeptServiceImpl extends ServiceImpl> selectTree(SysDeptTreeAndListRequestDTO req) { - // 查询全部部门 + // 查询部门列表 List deptAllList = this.deptList(req); if (CollectionUtils.isEmpty(deptAllList)) { return CollUtil.newArrayList(); @@ -174,12 +174,56 @@ public class SysDeptServiceImpl extends ServiceImpl deptIds = deptAllList.stream() + .map(SysDeptVO::getDeptId) + .collect(Collectors.toSet()); + + // 找出顶层部门 + List topLevelDepts = deptAllList.stream() + .filter(dept -> !deptIds.contains(dept.getParentId())) + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(topLevelDepts)) { + return CollUtil.newArrayList(); + } + + // 获取所有顶层部门的不同parentId,分别构建树然后合并 + Set parentIds = topLevelDepts.stream() + .map(SysDeptVO::getParentId) + .collect(Collectors.toSet()); + + List> result = new ArrayList<>(); + for (Long pid : parentIds) { + List> trees = TreeUtil.build(deptAllList, pid, nodeConfig, (item, tree) -> { + tree.setId(item.getDeptId()); + tree.setName(item.getDeptName()); + tree.setWeight(item.getSortOrder()); + tree.setParentId(item.getParentId()); + tree.putExtra("deptCode", item.getDeptCode()); + tree.putExtra("createBy", item.getCreateBy()); + tree.putExtra("createTime", item.getCreateTime()); + tree.putExtra("leaderId", item.getLeaderId()); + tree.putExtra("tenantId", item.getTenantId()); + tree.putExtra("updateBy", item.getUpdateBy()); + tree.putExtra("updateTime", item.getUpdateTime()); + }); + if (CollectionUtils.isNotEmpty(trees)) { + result.addAll(trees); + } + } + return result; + } + return TreeUtil.build(deptAllList, parentId == null ? 0 : parentId, nodeConfig, (item, tree) -> { tree.setId(item.getDeptId()); tree.setName(item.getDeptName()); @@ -419,7 +463,7 @@ public class SysDeptServiceImpl extends ServiceImpl query = Wrappers.lambdaQuery(SysPostEntity.class); + query.eq(SysPostEntity::getPostCode, postCode); + query.eq(SysPostEntity::getDelFlag, CommonConstants.STATUS_NORMAL); + return this.getOne(query); + } } \ No newline at end of file diff --git a/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/impl/SysStaffServiceImpl.java b/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/impl/SysStaffServiceImpl.java index a8cccd3..cffd303 100644 --- a/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/impl/SysStaffServiceImpl.java +++ b/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/impl/SysStaffServiceImpl.java @@ -346,6 +346,9 @@ public class SysStaffServiceImpl extends ServiceImpl listUserId = userR.getData().stream().map(SysUserNoSensitiveInfoVO::getUserId).toList(); + if (listUserId.isEmpty()) { + continue; + } LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.in(SysStaffEntity::getTenantId, tenantIds); queryWrapper.notIn(SysStaffEntity::getUserId, listUserId); diff --git a/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/impl/SysTKMoldServiceImpl.java b/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/impl/SysTKMoldServiceImpl.java index 8667778..12366f3 100644 --- a/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/impl/SysTKMoldServiceImpl.java +++ b/honeycom-tenant/honeycom-tenant-biz/src/main/java/com/honeycombis/honeycom/tenant/service/impl/SysTKMoldServiceImpl.java @@ -34,6 +34,8 @@ import org.springframework.transaction.annotation.Transactional; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import java.util.Set; +import java.util.HashSet; @Slf4j @@ -365,8 +367,162 @@ public class SysTKMoldServiceImpl implements SysTKMoldService { @Override @Transactional(rollbackFor = Exception.class) public void allSyncLyricUsers(List userList, String workType) { -// Long tenantId = 2001184963854700545L; - Long tenantId = 7244250568405852160L; +// Long tenantId = 1979091834410176514L; + Long tenantId = 2001184963854700545L; + + if (!userList.isEmpty()) { + // 筛选新用户 + userList = filerNewUserList(userList); + if (userList.size() > 0) { + log.info("开始同步,租户{}",tenantId); + StringBuilder message = new StringBuilder("全量同步:"); + + SysRoleVO sysRole = sysRoleService.getByRoleCodeAndTenantId(TenantConstants.ROLE_NORMAL_USER_CODE, tenantId); + if (sysRole != null) { + Map empIdAndUserIds = new HashMap<>(); + List tenantUserDtos = tkMoldHrConverter.lyricUserToTenantUserDto(userList, empIdAndUserIds); + List> lists = ListUtil.split(tenantUserDtos, 500); + int index = 0; + for (List tenantUserDtoList : lists) { + log.info("执行第{}到{}用户",index+1,index += tenantUserDtoList.size()); + //生成用户信息 + honeycomUserServiceFeign.hrBatchAdd(tenantUserDtoList, SecurityConstants.FROM_IN, new Request.Options(300, TimeUnit.SECONDS, 300, TimeUnit.SECONDS, true)); + } + message.append(String.format("新增用户%s;",tenantUserDtos.size())); + log.info("新增用户{}",tenantUserDtos.size()); + + // 生成部门信息 按工种分组 挂租户下面 + // 获取去重后的一级部门列表 +// List deptList = getDistinctDeptByDeptCode1(userList); + Map deptIdAndDeptIds = new HashMap<>(); + + // 收集所有需要的部门编码 + Set allDeptCodes = new HashSet<>(); + for (LyricUserDto user : userList) { + if (StrUtil.isNotBlank(user.getDept_grp_code1())) { + allDeptCodes.add(user.getDept_grp_code1()); + } + if (StrUtil.isNotBlank(user.getDept_grp_code2())) { + allDeptCodes.add(user.getDept_grp_code2()); + } + if (StrUtil.isNotBlank(user.getDept_grp_code3())) { + allDeptCodes.add(user.getDept_grp_code3()); + } + if (StrUtil.isNotBlank(user.getDept_grp_code4())) { + allDeptCodes.add(user.getDept_grp_code4()); + } + if (StrUtil.isNotBlank(user.getDept_code())) { + allDeptCodes.add(user.getDept_code()); + } + } + + // 查询已存在的部门 + List existingDepts = new ArrayList<>(); + for (String deptCode : allDeptCodes) { + SysDeptEntity existingDept = sysDeptService.getByDeptCode(deptCode); + if (existingDept != null) { + existingDepts.add(existingDept); + deptIdAndDeptIds.put(deptCode, existingDept.getDeptId()); + } + } + log.info("已存在部门数量: {}", existingDepts.size()); + + // 构建已存在部门映射(用于传递给转换方法) + Map existingDeptMap = new HashMap<>(); + for (SysDeptEntity dept : existingDepts) { + existingDeptMap.put(dept.getDeptCode(), dept.getDeptId()); + } + + // 转换新部门(只转换不存在的部门) + List sysDeptEntities = tkMoldHrConverter.lyricDeptToTenantDept(userList, deptIdAndDeptIds, existingDeptMap, tenantId); + if (CollUtil.isNotEmpty(sysDeptEntities)) { + sysDeptService.saveBatch(sysDeptEntities); + message.append(String.format("新增部门%s;", sysDeptEntities.size())); + log.info("新增部门{}", sysDeptEntities.size()); + } else { + message.append("部门全部已存在,无需新增;"); + log.info("部门全部已存在,无需新增"); + } + + //生成岗位信息 + List jobList = getDistinctJobByJobCode(userList); + Map jobIdAndPostIds = new HashMap<>(); + + // 收集所有需要的岗位编码 + Set allJobCodes = jobList.stream() + .map(LyricUserDto::getJob_code) + .filter(StrUtil::isNotBlank) + .collect(Collectors.toSet()); + + // 查询已存在的岗位 + List existingPosts = new ArrayList<>(); + for (String jobCode : allJobCodes) { + SysPostEntity existingPost = sysPostService.getByPostCode(jobCode); + if (existingPost != null) { + existingPosts.add(existingPost); + jobIdAndPostIds.put(jobCode, existingPost.getPostId()); + } + } + log.info("已存在岗位数量: {}", existingPosts.size()); + + // 转换新岗位(只转换不存在的岗位) + List sysPostEntities = tkMoldHrConverter.lyricJobToPost(jobList, jobIdAndPostIds, tenantId); + if (CollUtil.isNotEmpty(sysPostEntities)) { + sysPostService.saveBatch(sysPostEntities); + message.append(String.format("新增职位%s;", sysPostEntities.size())); + log.info("新增职位{}", sysPostEntities.size()); + } else { + message.append("岗位全部已存在,无需新增;"); + log.info("岗位全部已存在,无需新增"); + } + + //生成员工信息 + List sysStaffEntities = new ArrayList<>(userList.size()); + // cid部门id和员工id映射 + Map deptMap = new HashMap<>(); + Map postMap = new HashMap<>(); + List staffRoleList = new ArrayList<>(); + userList.forEach(emp -> { + SysStaffEntity sysStaffEntity = new SysStaffEntity(); + sysStaffEntity.setUserId(empIdAndUserIds.get(emp.getPsn_code())); + sysStaffEntity.setLoginDefault(CommonConstants.FALSE_S); + sysStaffEntity.setTenantId(tenantId); + // 用户状态默认正常 + sysStaffEntity.setStatus(CommonConstants.STATUS_NORMAL); + long staffId = IdWorker.getId(sysStaffEntity); + sysStaffEntity.setStaffId(staffId); + sysStaffEntity.setStaffCode(TenantConstants.STAFF_CODE_PREFIX + staffId); + sysStaffEntity.setCreateBy(0L); + sysStaffEntity.setUpdateBy(0L); +// deptMap.put(staffId, deptIdAndDeptIds.get(emp.getDept_grp_code1())); + // 使用用户当前部门编码(dept_code)获取部门ID + deptMap.put(staffId, deptIdAndDeptIds.get(emp.getDept_code())); + postMap.put(staffId, jobIdAndPostIds.get(emp.getJob_code())); + sysStaffEntities.add(sysStaffEntity); + SysStaffRoleEntity sysStaffRoleEntity = new SysStaffRoleEntity(); + sysStaffRoleEntity.setStaffId(staffId); + sysStaffRoleEntity.setRoleId(sysRole.getRoleId()); + staffRoleList.add(sysStaffRoleEntity); + }); + //保存员工信息 + sysStaffService.saveBatch(sysStaffEntities); + //处理员工关联关系 + List sysStaffDeptEntities = tkMoldHrConverter.convertStaffDept(deptMap); + List sysStaffPostEntities = tkMoldHrConverter.convertStaffPost(postMap); + sysStaffDeptService.saveBatch(sysStaffDeptEntities); + sysStaffPostService.saveBatch(sysStaffPostEntities); + sysStaffRoleService.saveBatch(staffRoleList); + } + } + } + } + + @Async("tenantAsyncTask") + @Override + @Transactional(rollbackFor = Exception.class) + public void allSyncLyricUsers2(List userList, String workType) { +// Long tenantId = 1979091834410176514L; + Long tenantId = 2001184963854700545L; if (!userList.isEmpty()) { // 筛选新用户 @@ -401,6 +557,24 @@ public class SysTKMoldServiceImpl implements SysTKMoldService { //生成岗位信息 List jobList = getDistinctJobByJobCode(userList); Map jobIdAndPostIds = new HashMap<>(); + + // 收集所有需要的岗位编码 + Set allJobCodes = jobList.stream() + .map(LyricUserDto::getJob_code) + .filter(StrUtil::isNotBlank) + .collect(Collectors.toSet()); + + // 查询已存在的岗位 + List existingPosts = new ArrayList<>(); + for (String jobCode : allJobCodes) { + SysPostEntity existingPost = sysPostService.getByPostCode(jobCode); + if (existingPost != null) { + existingPosts.add(existingPost); + jobIdAndPostIds.put(jobCode, existingPost.getPostId()); + } + } + log.info("已存在岗位数量: {}", existingPosts.size()); + List sysPostEntities = tkMoldHrConverter.lyricJobToPost(jobList, jobIdAndPostIds, tenantId); sysPostService.saveBatch(sysPostEntities); message.append(String.format("新增职位%s;",sysPostEntities.size())); @@ -495,5 +669,96 @@ public class SysTKMoldServiceImpl implements SysTKMoldService { )); return new ArrayList<>(jobMap.values()); } + + @Async("tenantAsyncTask") + @Override + @Transactional(rollbackFor = Exception.class) + public void resyncLyricDept(List userList) { + Long tenantId = 2001184963854700545L; +// Long tenantId = 1979091834410176514L; + + if (CollUtil.isEmpty(userList)) { + log.info("用户数据为空,跳过部门重新同步"); + return; + } + + log.info("开始重新同步部门数据,租户ID: {}, 用户数量: {}", tenantId, userList.size()); + + // 1. 查询该租户下所有员工,构建 username(psn_code) -> staffId 的映射 + List staffList = sysStaffService.findByTenantId(tenantId); + if (CollUtil.isEmpty(staffList)) { + log.warn("租户 {} 下没有找到员工数据", tenantId); + return; + } + + Map usernameToStaffIdMap = new HashMap<>(); + List staffIdList = new ArrayList<>(); + for (SysStaffDetailVO staff : staffList) { + staffIdList.add(staff.getStaffId()); + if (staff.getUserInfo() != null && StrUtil.isNotBlank(staff.getUserInfo().getUsername())) { + usernameToStaffIdMap.put(staff.getUserInfo().getUsername(), staff.getStaffId()); + } + } + log.info("查询到员工数量: {}", staffList.size()); + + // 2. 删除该租户下所有员工-部门关联关系 + if (CollUtil.isNotEmpty(staffIdList)) { + LambdaQueryWrapper staffDeptWrapper = new LambdaQueryWrapper<>(); + staffDeptWrapper.in(SysStaffDeptEntity::getStaffId, staffIdList); + sysStaffDeptService.remove(staffDeptWrapper); + log.info("已删除员工-部门关联关系数量: {}", staffIdList.size()); + } + + // 3. 删除该租户下所有部门 + LambdaQueryWrapper deptWrapper = new LambdaQueryWrapper<>(); + deptWrapper.eq(SysDeptEntity::getTenantId, tenantId); + sysDeptService.remove(deptWrapper); + log.info("已删除租户 {} 下的所有部门", tenantId); + + // 4. 使用新方法创建部门层级关系 + Map deptIdAndDeptIds = new HashMap<>(); + List sysDeptEntities = tkMoldHrConverter.lyricDeptToTenantDept(userList, deptIdAndDeptIds, new HashMap<>(), tenantId); + sysDeptService.saveBatch(sysDeptEntities); + log.info("新增部门数量: {}", sysDeptEntities.size()); + + // 5. 重新建立员工-部门关联关系 + List staffDeptEntities = new ArrayList<>(); + int matchedCount = 0; + int unmatchedCount = 0; + + for (LyricUserDto user : userList) { + String psnCode = user.getPsn_code(); + String deptCode = user.getDept_code(); + + if (StrUtil.isBlank(psnCode) || StrUtil.isBlank(deptCode)) { + continue; + } + + Long staffId = usernameToStaffIdMap.get(psnCode); + Long deptId = deptIdAndDeptIds.get(deptCode); + + if (staffId != null && deptId != null) { + SysStaffDeptEntity staffDeptEntity = new SysStaffDeptEntity(); + staffDeptEntity.setStaffId(staffId); + staffDeptEntity.setDeptId(deptId); + staffDeptEntities.add(staffDeptEntity); + matchedCount++; + } else { + unmatchedCount++; + if (staffId == null) { + log.debug("未找到员工映射,工号: {}", psnCode); + } + if (deptId == null) { + log.debug("未找到部门映射,部门编码: {}", deptCode); + } + } + } + + if (CollUtil.isNotEmpty(staffDeptEntities)) { + sysStaffDeptService.saveBatch(staffDeptEntities); + } + + log.info("部门重新同步完成,新增员工-部门关联: {}, 未匹配数量: {}", matchedCount, unmatchedCount); + } } diff --git a/honeycom-user/honeycom-user-biz/src/main/java/com/honeycombis/honeycom/user/service/impl/SysUserServiceImpl.java b/honeycom-user/honeycom-user-biz/src/main/java/com/honeycombis/honeycom/user/service/impl/SysUserServiceImpl.java index d543345..f7cdcc2 100644 --- a/honeycom-user/honeycom-user-biz/src/main/java/com/honeycombis/honeycom/user/service/impl/SysUserServiceImpl.java +++ b/honeycom-user/honeycom-user-biz/src/main/java/com/honeycombis/honeycom/user/service/impl/SysUserServiceImpl.java @@ -391,6 +391,7 @@ public class SysUserServiceImpl extends ServiceImpl queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.select(SysUserEntity::getUsername) + .eq(SysUserEntity::getDelFlag, CommonConstants.STATUS_NORMAL) .in(SysUserEntity::getUsername, usernameList); List existing = this.list(queryWrapper); return existing.stream()