feat:同步利元亨用户部门数据

This commit is contained in:
2026-01-27 09:05:48 +08:00
parent 1c86473c15
commit 3819057382
10 changed files with 381 additions and 0 deletions

View File

@@ -84,6 +84,12 @@
<artifactId>hutool-all</artifactId>
<version>5.8.38</version>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.50</version>
</dependency>
<!--必备: 操作数据源相关-->
<!-- <dependency>-->
<!-- <groupId>com.honeycombis</groupId>-->

View File

@@ -19,9 +19,11 @@
package com.honeycombis.honeycom.spdm.controller;
import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.honeycombis.honeycom.common.core.util.R;
import com.honeycombis.honeycom.spdm.dto.LyricUserDto;
import com.honeycombis.honeycom.spdm.dto.TenantPageQueryDto;
import com.honeycombis.honeycom.spdm.feign.RemoteTenantServiceFeign;
import com.honeycombis.honeycom.spdm.feign.SpdmServiceFeignClient;
@@ -35,8 +37,10 @@ import jakarta.annotation.Resource;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@@ -88,4 +92,18 @@ public class SpdmTenantController {
log.info("[initNewTenant] tenantId:{}, responseR:{}", tenantId, responseR);
}
@PostMapping("/queryUserList")
public R<List<LyricUserDto>> queryUserList(@RequestParam String workType) {
ResponseR sdmResponse = spdmServiceFeignClient.queryUserList(workType);
log.info("[queryUserList] sdmResponse:{}", sdmResponse);
if (sdmResponse.isSuccess() && sdmResponse.getData() != null) {
JSONArray jsonArray = (JSONArray) sdmResponse.getData();
List<LyricUserDto> userToDmList = jsonArray.toJavaList(LyricUserDto.class);
return R.ok(userToDmList);
} else {
return R.ok(new ArrayList<LyricUserDto>());
}
}
}

View File

@@ -0,0 +1,67 @@
package com.honeycombis.honeycom.spdm.dto;
import lombok.Data;
@Data
public class LyricUserDto {
/**
* 部门编码
*/
private String dept_code;
/**
* 三级部门编码
*/
private String dept_grp_code3;
/**
* 四级部门编码
*/
private String dept_grp_code4;
/**
* 部门名称
*/
private String dept_name;
/**
* 一级部门编码
*/
private String dept_grp_code1;
/**
* 二级部门编码
*/
private String dept_grp_code2;
/**
* 人员姓名
*/
private String psn_name;
/**
* 人员编码
*/
private String psn_code;
/**
* 完整部门名称
*/
private String full_dept_name;
/**
* 工种名称
*/
private String work_type_name;
/**
* 岗位名称
*/
private String job_name;
/**
* 四级部门名称
*/
private String dept_grp_name4;
/**
* 三级部门名称
*/
private String dept_grp_name3;
/**
* 二级部门名称
*/
private String dept_grp_name2;
/**
* 一级部门名称
*/
private String dept_grp_name1;
}

View File

@@ -22,4 +22,7 @@ public interface SpdmServiceFeignClient {
@PostMapping("/tenant/initNewTenant")
ResponseR initNewTenant(@RequestParam Long tenantId);
@PostMapping("/lyricUser/queryUserList")
ResponseR queryUserList(@RequestParam String workType);
}

View File

@@ -1,10 +1,13 @@
package com.honeycombis.honeycom.tenant.feign;
import com.honeycombis.honeycom.common.core.constant.ServiceNameConstants;
import com.honeycombis.honeycom.common.core.util.R;
import com.honeycombis.honeycom.tenant.vo.lyric.LyricUserDto;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@FeignClient(contextId = "remoteSpdmTenantService", value = ServiceNameConstants.SPDM_SERVICE)
@@ -12,4 +15,8 @@ public interface RemoteSpdmService {
@PostMapping("/honeycom-spdm/spdm-tenant/initNewTenant")
void initNewTenant(@RequestParam Long tenantId);
@PostMapping("/honeycom-spdm/spdm-tenant/queryUserList")
R<List<LyricUserDto>> queryUserList(@RequestParam String workType);
}

View File

@@ -0,0 +1,67 @@
package com.honeycombis.honeycom.tenant.vo.lyric;
import lombok.Data;
@Data
public class LyricUserDto {
/**
* 部门编码
*/
private String dept_code;
/**
* 三级部门编码
*/
private String dept_grp_code3;
/**
* 四级部门编码
*/
private String dept_grp_code4;
/**
* 部门名称
*/
private String dept_name;
/**
* 一级部门编码
*/
private String dept_grp_code1;
/**
* 二级部门编码
*/
private String dept_grp_code2;
/**
* 人员姓名
*/
private String psn_name;
/**
* 人员编码
*/
private String psn_code;
/**
* 完整部门名称
*/
private String full_dept_name;
/**
* 工种名称
*/
private String work_type_name;
/**
* 岗位名称
*/
private String job_name;
/**
* 四级部门名称
*/
private String dept_grp_name4;
/**
* 三级部门名称
*/
private String dept_grp_name3;
/**
* 二级部门名称
*/
private String dept_grp_name2;
/**
* 一级部门名称
*/
private String dept_grp_name1;
}

View File

@@ -15,6 +15,7 @@ import com.honeycombis.honeycom.tenant.service.SysHrSyncLogService;
import com.honeycombis.honeycom.tenant.service.SysTKMoldService;
import com.honeycombis.honeycom.tenant.vo.hr.HrUserInfoAddDataVO;
import com.honeycombis.honeycom.tenant.vo.hr.HrUserInfoAllDataVO;
import com.honeycombis.honeycom.tenant.vo.lyric.LyricUserDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -24,6 +25,7 @@ import org.springdoc.core.annotations.ParameterObject;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -37,6 +39,10 @@ public class SysHrSyncController {
private final SysTKMoldService tkMoldService;
private final SysHrSyncLogService sysHrSyncLogService;
public static final List<String> WORK_TYPES = Arrays.asList(
"设计", "仿真", "产品工艺", "方案", "程序", "激光"
);
/**
* 分页查询
* @param page 分页对象
@@ -99,6 +105,23 @@ public class SysHrSyncController {
}
/**
* 全量同步用户数据
*/
@Inner(value = false)
@PostMapping("/allSyncLyricUsers")
public R<Boolean> allSyncLyricUsers(@RequestBody List<LyricUserDto> userDtoList) {
for (String workType : WORK_TYPES) {
try {
tkMoldService.allSyncLyricUsers(userDtoList, workType);
} catch (Exception e) {
log.error("全量同步用户数据失败", e);
throw new HoneycomException(e.getMessage());
}
}
return R.ok();
}
}

View File

@@ -3,6 +3,7 @@ package com.honeycombis.honeycom.tenant.service;
import com.honeycombis.honeycom.tenant.vo.hr.HrUserInfoAddDataVO;
import com.honeycombis.honeycom.tenant.vo.hr.HrUserInfoAllDataVO;
import com.honeycombis.honeycom.tenant.vo.hr.HrUserInfoVO;
import com.honeycombis.honeycom.tenant.vo.lyric.LyricUserDto;
import java.util.List;
@@ -11,4 +12,6 @@ public interface SysTKMoldService {
void allSyncUsers(HrUserInfoAllDataVO hrUserInfoAllDataVO);
void addSyncUsers(HrUserInfoAddDataVO hrUserInfoAddDataVO);
void allSyncLyricUsers(List<LyricUserDto> userDtoList, String workType);
}

View File

@@ -13,6 +13,7 @@ import com.honeycombis.honeycom.tenant.vo.hr.HrDeptVO;
import com.honeycombis.honeycom.tenant.vo.hr.HrEDetailVO;
import com.honeycombis.honeycom.tenant.vo.hr.HrEmpVO;
import com.honeycombis.honeycom.tenant.vo.hr.HrJobVO;
import com.honeycombis.honeycom.tenant.vo.lyric.LyricUserDto;
import com.honeycombis.honeycom.user.dto.TenantUserDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -67,6 +68,26 @@ public class TKMoldHrConverter {
}
return tenantUserDtos;
}
public List<TenantUserDto> lyricUserToTenantUserDto(List<LyricUserDto> lyricUserList, Map<String,Long> empIdAndUserIds) {
List<TenantUserDto> tenantUserDtos = new ArrayList<>();
for (LyricUserDto lyricUser : lyricUserList) {
TenantUserDto tenantUserDto = new TenantUserDto();
long userId = IdWorker.getId();
// 工号与cid userId映射关系
empIdAndUserIds.put(lyricUser.getPsn_code(), userId);
tenantUserDto.setUserId(userId);
tenantUserDto.setUsername(lyricUser.getPsn_code());
tenantUserDto.setNickname(lyricUser.getPsn_name());
// 初始化手机号
String format = StrUtil.padPre(lyricUser.getPsn_code(), 6, '9');
String iphone = "199"+RandomUtil.randomNumbers(2)+format;
tenantUserDto.setPhone(iphone);
tenantUserDtos.add(tenantUserDto);
}
return tenantUserDtos;
}
/**
* 转换成单个用户信息
* @param emp
@@ -143,6 +164,63 @@ public class TKMoldHrConverter {
return sysDeptEntities;
}
public List<SysDeptEntity> lyricDeptToTenantDept(List<LyricUserDto> depts, Map<String,Long> deptIdAndDeptIds,Long tenantId) {
List<SysDeptEntity> 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());
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;
}
public List<SysDeptEntity> lyricDeptToTenantDept2(String workType, Map<String,Long> deptIdAndDeptIds,Long tenantId) {
List<SysDeptEntity> sysDeptEntities = new ArrayList<>();
SysDeptEntity sysDeptEntity = new SysDeptEntity();
sysDeptEntity.setTenantId(tenantId);
sysDeptEntity.setDeptName(workType + "");
switch (workType) {
case "设计":
sysDeptEntity.setDeptCode("GROUP_01");
break;
case "仿真":
sysDeptEntity.setDeptCode("GROUP_02");
break;
case "产品工艺":
sysDeptEntity.setDeptCode("GROUP_03");
break;
case "方案":
sysDeptEntity.setDeptCode("GROUP_04");
break;
case "程序":
sysDeptEntity.setDeptCode("GROUP_05");
break;
case "激光":
sysDeptEntity.setDeptCode("GROUP_06");
break;
default:
break;
}
long id = IdWorker.getId(sysDeptEntity);
sysDeptEntity.setDeptId(id);
sysDeptEntity.setParentId(0L);
sysDeptEntity.setCreateBy(0L);
sysDeptEntity.setUpdateBy(0L);
deptIdAndDeptIds.put(workType, id);
sysDeptEntities.add(sysDeptEntity);
return sysDeptEntities;
}
/**
* 返回单个部门信息
* @param dept
@@ -239,6 +317,17 @@ public class TKMoldHrConverter {
return sysStaffDeptEntities;
}
public List<SysStaffDeptEntity> convertStaffDept(Map<Long,Long> deptMap){
List<SysStaffDeptEntity> sysStaffDeptEntities = new ArrayList<>();
deptMap.forEach((staffId,deptId) -> {
SysStaffDeptEntity sysStaffDeptEntity = new SysStaffDeptEntity();
sysStaffDeptEntity.setStaffId(staffId);
sysStaffDeptEntity.setDeptId(deptId);
sysStaffDeptEntities.add(sysStaffDeptEntity);
});
return sysStaffDeptEntities;
}
public List<SysStaffPostEntity> converterStaffPost(Map<Integer,Long> postDept, Map<Integer,Long> jobIdAndPostIds){
List<SysStaffPostEntity> sysStaffDeptEntities = new ArrayList<>();

View File

@@ -13,10 +13,12 @@ import com.honeycombis.honeycom.common.core.util.R;
import com.honeycombis.honeycom.tenant.constants.TenantConstants;
import com.honeycombis.honeycom.tenant.entity.*;
import com.honeycombis.honeycom.tenant.enums.HrTableEnum;
import com.honeycombis.honeycom.tenant.feign.RemoteSpdmService;
import com.honeycombis.honeycom.tenant.service.*;
import com.honeycombis.honeycom.tenant.service.converter.TKMoldHrConverter;
import com.honeycombis.honeycom.tenant.vo.*;
import com.honeycombis.honeycom.tenant.vo.hr.*;
import com.honeycombis.honeycom.tenant.vo.lyric.LyricUserDto;
import com.honeycombis.honeycom.tenant.vo.tenant.SysTenantVO;
import com.honeycombis.honeycom.user.dto.TenantUserDto;
import com.honeycombis.honeycom.user.entity.SysUserEntity;
@@ -53,6 +55,7 @@ public class SysTKMoldServiceImpl implements SysTKMoldService {
private final SysHrSyncLogService sysHrSyncLogService;
private final SysRoleService sysRoleService;
private final SysStaffRoleService sysStaffRoleService;
private final RemoteSpdmService remoteSpdmService;
@Async("tenantAsyncTask")
@Override
@@ -361,5 +364,100 @@ public class SysTKMoldServiceImpl implements SysTKMoldService {
sysHrSyncLogEntity.setHrEndId(hrUserInfoAddDataVO.getSyncEndId());
sysHrSyncLogService.save(sysHrSyncLogEntity);
}
// @Async("tenantAsyncTask")
@Override
@Transactional(rollbackFor = Exception.class)
public void allSyncLyricUsers(List<LyricUserDto> userList, String workType) {
// Long tenantId = 2001184963854700545L;
Long tenantId = 7244250568405852160L;
// 获取利元亨用户数据(带部门)
// R<List<LyricUserDto>> userListR = remoteSpdmService.queryUserList(workType);
// List<LyricUserDto> userList = userListR.getData();
if (!userList.isEmpty()) {
log.info("开始同步,租户{}",tenantId);
StringBuilder message = new StringBuilder("全量同步:");
SysRoleVO sysRole = sysRoleService.getByRoleCodeAndTenantId(TenantConstants.ROLE_NORMAL_USER_CODE, tenantId);
if (sysRole != null) {
Map<String,Long> empIdAndUserIds = new HashMap<>();
List<TenantUserDto> tenantUserDtos = tkMoldHrConverter.lyricUserToTenantUserDto(userList, empIdAndUserIds);
List<List<TenantUserDto>> lists = ListUtil.split(tenantUserDtos, 500);
int index = 0;
for (List<TenantUserDto> 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<LyricUserDto> deptList = getDistinctDeptByDeptCode1(userList);
Map<String,Long> deptIdAndDeptIds = new HashMap<>();
List<SysDeptEntity> sysDeptEntities = tkMoldHrConverter.lyricDeptToTenantDept2(workType, deptIdAndDeptIds, tenantId);
sysDeptService.saveBatch(sysDeptEntities);
message.append(String.format("新增部门%s;",sysDeptEntities.size()));
log.info("新增部门{}",sysDeptEntities.size());
//生成员工信息
List<SysStaffEntity> sysStaffEntities = new ArrayList<>(userList.size());
// cid部门id和员工id映射
Map<Long,Long> deptMap = new HashMap<>();
Map<Integer,Long> postMap = new HashMap<>();
List<SysStaffRoleEntity> 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()));
deptMap.put(staffId, deptIdAndDeptIds.get(workType));
// postMap.put(emp.getJobId(),staffId);
sysStaffEntities.add(sysStaffEntity);
SysStaffRoleEntity sysStaffRoleEntity = new SysStaffRoleEntity();
sysStaffRoleEntity.setStaffId(staffId);
sysStaffRoleEntity.setRoleId(sysRole.getRoleId());
staffRoleList.add(sysStaffRoleEntity);
});
//保存员工信息
sysStaffService.saveBatch(sysStaffEntities);
//处理员工关联关系
List<SysStaffDeptEntity> sysStaffDeptEntities = tkMoldHrConverter.convertStaffDept(deptMap);
// List<SysStaffPostEntity> sysStaffPostEntities = tkMoldHrConverter.converterStaffPost(postMap, jobIdAndPostIds);
sysStaffDeptService.saveBatch(sysStaffDeptEntities);
// sysStaffPostService.saveBatch(sysStaffPostEntities);
sysStaffRoleService.saveBatch(staffRoleList);
}
}
}
private List<LyricUserDto> getDistinctDeptByDeptCode1(List<LyricUserDto> originalList) {
// 核心用HashMap底层实现去重key是dept_grp_code1value是DTO
Map<String, LyricUserDto> deptMap = originalList.stream()
// 过滤掉code1为空的无效数据避免空指针提升效率
.filter(dto -> dto.getDept_grp_code1() != null && !dto.getDept_grp_code1().isEmpty())
.collect(Collectors.toMap(
LyricUserDto::getDept_grp_code1, // 按code1作为唯一key
dto -> {
// 只保留需要的两个字段,减少内存占用
LyricUserDto newDto = new LyricUserDto();
newDto.setDept_grp_code1(dto.getDept_grp_code1());
newDto.setDept_grp_name1(dto.getDept_grp_name1());
return newDto;
},
(existing, replacement) -> existing // 重复时保留第一个,避免覆盖
));
// 转成列表HashMap.values()遍历效率极高)
return new ArrayList<>(deptMap.values());
}
}