dev:人员导入(部门岗位反哺版)

main
SondonYong 2025-11-28 15:39:12 +08:00
parent f2b527d32a
commit eac75ce415
2 changed files with 384 additions and 145 deletions

View File

@ -0,0 +1,382 @@
package com.zcloud.basic.info.command;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.cola.dto.MultiResponse;
import com.alibaba.cola.exception.BizException;
import com.jjb.saas.config.client.dicttree.facade.ConfDictTreeFacade;
import com.jjb.saas.config.client.dicttree.response.ConfDictTreeCO;
import com.jjb.saas.framework.auth.model.SSOUser;
import com.jjb.saas.framework.auth.utils.AuthContext;
import com.jjb.saas.system.client.role.facade.RoleFacade;
import com.jjb.saas.system.client.role.response.RoleCO;
import com.zcloud.basic.info.command.convertor.UserCoConvertor;
import com.zcloud.basic.info.domain.gateway.DepartmentGateway;
import com.zcloud.basic.info.domain.gateway.PostGateway;
import com.zcloud.basic.info.domain.gateway.UserEmploymentLogGateway;
import com.zcloud.basic.info.domain.gateway.UserGateway;
import com.zcloud.basic.info.domain.model.DepartmentE;
import com.zcloud.basic.info.domain.model.PostE;
import com.zcloud.basic.info.domain.model.UserE;
import com.zcloud.basic.info.domain.model.UserEmploymentLogE;
import com.zcloud.basic.info.dto.CorpInfoAddCmd;
import com.zcloud.basic.info.dto.UserAddCmd;
import com.zcloud.basic.info.dto.UserXgfAddCmd;
import com.zcloud.basic.info.persistence.dataobject.CorpInfoDO;
import com.zcloud.basic.info.persistence.dataobject.DepartmentDO;
import com.zcloud.basic.info.persistence.dataobject.PostDO;
import com.zcloud.basic.info.persistence.dataobject.UserDO;
import com.zcloud.basic.info.persistence.repository.CorpInfoRepository;
import com.zcloud.basic.info.persistence.repository.DepartmentRepository;
import com.zcloud.basic.info.persistence.repository.PostRepository;
import com.zcloud.basic.info.persistence.repository.UserRepository;
import com.zcloud.gbscommon.excelEntity.UserExcelImportEntity;
import com.zcloud.gbscommon.utils.ExcelUtils;
import lombok.AllArgsConstructor;
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.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* web-app
* @Author zhangyue
* @Date 2025-11-04 14:07:21
*/
@Component
@AllArgsConstructor
public class UserImportExe {
private final UserGateway userGateway;
private final UserEmploymentLogGateway userEmploymentLogGateway;
private final CorpInfoRepository corpInfoRepository;
private final DepartmentRepository departmentRepository;
private final PostRepository postRepository;
private final PostGateway postGateway;
private final UserRepository userRepository;
private final DepartmentGateway departmentGateway;
@DubboReference
private ConfDictTreeFacade confDictTreeFacade;
@DubboReference
private RoleFacade roleFacade;
@Transactional(rollbackFor = Exception.class)
public void importUserTable(MultipartFile file) {
Long corpinfoId = AuthContext.getTenantId();
CorpInfoDO corpInfoDO = corpInfoRepository.getById(corpinfoId);
// 角色数据
MultiResponse<RoleCO> roleCOMultiResponse = roleFacade.listRoles();
if (roleCOMultiResponse == null || CollUtil.isEmpty(roleCOMultiResponse.getData())) {
throw new BizException("未创建默认通用角色,请联系管理员");
}
// 部门数据
List<DepartmentDO> departmentDOList = departmentRepository.listByCorpInfoId(corpinfoId);
// 岗位数据
List<PostDO> postDOList = postRepository.listByCorpInfoId(corpinfoId);
// 用户名数据
List<UserDO> userDOList = userRepository.listByCorpInfoId(corpinfoId);
List<UserExcelImportEntity> list = new ArrayList<>();
try {
ExcelUtils.readBatch(file, UserExcelImportEntity.class, list);
if (list.isEmpty()) {
throw new BizException("文件为空");
}
} catch (Exception e) {
throw new BizException("文件解析失败");
}
// 开始处理导入逻辑
for (UserExcelImportEntity importEntity : list) {
try {
processSingleUser(importEntity, corpinfoId, corpInfoDO, departmentDOList, postDOList, userDOList, roleCOMultiResponse.getData());
} catch (Exception e) {
System.out.println("导入用户失败: " + importEntity.getUsername());
throw new BizException("导入用户失败: " + importEntity.getUsername() + ", 原因: " + e.getMessage());
}
}
}
/**
*
*/
private void processSingleUser(UserExcelImportEntity importEntity, Long corpinfoId,
CorpInfoDO corpInfoDO,
List<DepartmentDO> departmentDOList, List<PostDO> postDOList,
List<UserDO> userDOList, List<RoleCO> roleList) {
// 1. 处理部门层级获取最终部门ID
Long departmentId = processDepartmentHierarchy(importEntity, corpinfoId, departmentDOList);
// 2. 处理岗位获取岗位ID
Long postId = processPost(importEntity, corpinfoId, corpInfoDO, departmentId, postDOList);
// 3. 处理角色信息
Long roleId = processRoleInfo(importEntity, roleList);
// 4. 处理用户信息
processUserInfo(importEntity, corpinfoId, corpInfoDO, departmentId, postId, userDOList, roleId);
}
/**
*
*/
private Long processDepartmentHierarchy(UserExcelImportEntity importEntity, Long corpinfoId,
List<DepartmentDO> allDepartments) {
if(StringUtils.isEmpty(importEntity.getDepartmentName1())
&& StringUtils.isEmpty(importEntity.getDepartmentName2())
&& StringUtils.isEmpty(importEntity.getDepartmentName3())
&& StringUtils.isEmpty(importEntity.getDepartmentName4())
&& StringUtils.isEmpty(importEntity.getDepartmentName5())){
throw new BizException("部门层级不能为空。");
}
String[] deptLevels = {
importEntity.getDepartmentName1(),
importEntity.getDepartmentName2(),
importEntity.getDepartmentName3(),
importEntity.getDepartmentName4(),
importEntity.getDepartmentName5()
};
// 首先获取或创建固定的一级部门(公司同名部门)
DepartmentDO rootDept = getOrCreateRootDepartment(corpinfoId, allDepartments);
// 验证一级部门名称是否与Excel中的部门1匹配
if (StringUtils.isNotBlank(importEntity.getDepartmentName1()) &&
!importEntity.getDepartmentName1().equals(rootDept.getName())) {
throw new BizException("一级部门名称与公司名称不一致: Excel中的" + importEntity.getDepartmentName1() + " vs 系统中的" + rootDept.getName());
}
Long currentParentId = rootDept.getId(); // 从一级部门开始
DepartmentDO currentDept = rootDept;
// 从一级部门开始处理(但一级部门已经存在,所以从二级开始创建)
for (int level = 0; level < deptLevels.length; level++) {
String deptName = deptLevels[level];
// 如果当前层级部门名为空,则停止处理
if (StringUtils.isBlank(deptName)) {
break;
}
deptName = deptName.trim();
// 一级部门已经存在,跳过创建
if (level == 0) {
// 一级部门使用现有的根部门,继续处理下级
continue;
}
// 查找或创建部门(从二级部门开始)
currentDept = findOrCreateDepartment(deptName, currentParentId, level + 1, corpinfoId, allDepartments);
if (currentDept == null) {
throw new BizException("创建部门失败: " + deptName + " (层级: " + (level + 1) + ")");
}
// 当前部门作为下一级的父部门
currentParentId = currentDept.getId();
}
// 返回最终的部门ID
// 如果没有下级部门则返回一级部门ID否则返回最后创建的部门ID
return currentDept != null ? currentDept.getId() : rootDept.getId();
}
/**
*
*/
private DepartmentDO getOrCreateRootDepartment(Long corpinfoId, List<DepartmentDO> allDepartments) {
// 先从现有部门中查找一级部门父ID为0
DepartmentDO rootDept = allDepartments.stream()
.filter(dept -> dept.getParentId() != null && dept.getParentId() == 0L)
.findFirst()
.orElse(null);
if (rootDept != null) {
return rootDept;
}
// 如果根部门不存在,需要创建(根据你的业务需求决定)
// 这里保持你的原有逻辑,抛出异常
throw new BizException("所属部门1不存在该部门无法手动创建");
}
/**
* 使
*/
private DepartmentDO findOrCreateDepartment(String deptName, Long parentId, int level,
Long corpinfoId, List<DepartmentDO> allDepartments) {
// 在现有部门中查找
DepartmentDO existingDept = findDepartmentInList(allDepartments, parentId, deptName);
if (existingDept != null) {
return existingDept;
}
// 不存在则创建新部门
DepartmentDO newDept = createNewDepartment(deptName, parentId, level, corpinfoId);
// 将新部门添加到列表中
allDepartments.add(newDept);
return newDept;
}
/**
*
*/
private DepartmentDO findDepartmentInList(List<DepartmentDO> departments, Long parentId, String name) {
return departments.stream()
.filter(dept -> {
// 根部门的父ID是0不是null
boolean parentMatch = (parentId == null && dept.getParentId() == 0L) ||
(parentId != null && parentId.equals(dept.getParentId()));
return parentMatch && name.equals(dept.getName());
})
.findFirst()
.orElse(null);
}
/**
*
*/
private DepartmentDO createNewDepartment(String name, Long parentId, int level, Long corpinfoId) {
DepartmentE department = new DepartmentE();
department.setName(name);
department.setParentId(parentId);
department.setCorpinfoId(corpinfoId);
department.setDepOrder(9999);
Long departmentId = departmentGateway.add(department);
DepartmentDO departmentDO = new DepartmentDO();
BeanUtils.copyProperties(department, departmentDO);
departmentDO.setId(departmentId);
return departmentDO;
}
/**
*
*/
private Long processPost(UserExcelImportEntity importEntity, Long corpinfoId,
CorpInfoDO corpInfoDO,
Long departmentId, List<PostDO> allPosts) {
if (StringUtils.isBlank(importEntity.getPostName())) {
throw new BizException("岗位名称不能为空");
}
String postName = importEntity.getPostName().trim();
// 查找该部门下是否存在该岗位
PostDO existingPost = findPostInList(allPosts, departmentId, postName);
if (existingPost != null) {
return existingPost.getId();
}
// 不存在则创建新岗位
PostDO newPost = createNewPost(postName, departmentId, corpinfoId, corpInfoDO);
// 将新岗位添加到列表中
allPosts.add(newPost);
return newPost.getId();
}
/**
*
*/
private PostDO findPostInList(List<PostDO> posts, Long departmentId, String name) {
return posts.stream()
.filter(post -> departmentId.equals(post.getDepartmentId()) && name.equals(post.getPostName()))
.findFirst()
.orElse(null);
}
/**
*
*/
private PostDO createNewPost(String name, Long departmentId, Long corpinfoId, CorpInfoDO corpInfoDO) {
PostDO post = new PostDO();
post.setPostName(name);
post.setDepartmentId(departmentId);
post.setCorpinfoId(corpinfoId);
post.setCorpinfoName(corpInfoDO.getCorpName());
PostE postE = new PostE();
BeanUtils.copyProperties(post, postE);
Long postId = postGateway.add(postE);
post.setId(postId);
return post;
}
/**
*
*/
private Long processRoleInfo(UserExcelImportEntity importEntity, List<RoleCO> roleList) {
if(StringUtils.isBlank(importEntity.getRoleName())){
throw new BizException("角色名称不能为空");
}
Map<String, RoleCO> roleCOMap = roleList.stream().collect(Collectors.toMap(RoleCO::getRoleName, role -> role));
String roleName = importEntity.getRoleName();
if(roleCOMap.get(roleName) == null){
throw new BizException("角色不存在: " + roleName);
}
return roleCOMap.get(roleName).getId();
}
/**
*
*/
private void processUserInfo(UserExcelImportEntity importEntity, Long corpinfoId,
CorpInfoDO corpInfoDO,
Long departmentId, Long postId, List<UserDO> allUsers,
Long roleId) {
// 检查用户名是否已存在
boolean usernameExists = allUsers.stream()
.anyMatch(user -> importEntity.getUsername().equals(user.getUsername()));
if (usernameExists) {
throw new BizException("用户名已存在: " + importEntity.getUsername());
}
// 创建用户
UserE user = new UserE();
user.setUsername(importEntity.getUsername());
user.setRoleId(roleId);
user.setDepartmentId(departmentId);
user.setPostId(postId);
user.setCorpinfoId(corpinfoId);
user.setName(importEntity.getName());
userGateway.add(user);
String corpName = null;
if(corpInfoDO != null && !ObjectUtils.isEmpty(corpInfoDO.getCorpName())){
corpName = corpInfoDO.getCorpName();
}
UserEmploymentLogE userEmploymentLogE = new UserEmploymentLogE();
userEmploymentLogE.initAdd(userEmploymentLogE, corpName, user.getId());
userEmploymentLogGateway.add(userEmploymentLogE);
// 将新用户添加到列表中
UserDO userDO = new UserDO();
BeanUtils.copyProperties(user, userDO);
allUsers.add(userDO);
}
}

View File

@ -6,6 +6,7 @@ import com.alibaba.cola.exception.BizException;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.jjb.saas.framework.domain.model.BaseE; import com.jjb.saas.framework.domain.model.BaseE;
import com.zcloud.basic.info.domain.enums.CorpTypeEnum; import com.zcloud.basic.info.domain.enums.CorpTypeEnum;
import com.zcloud.basic.info.domain.gateway.DepartmentGateway;
import com.zcloud.gbscommon.excelEntity.UserExcelExportEntity; import com.zcloud.gbscommon.excelEntity.UserExcelExportEntity;
import com.zcloud.gbscommon.excelEntity.UserExcelImportEntity; import com.zcloud.gbscommon.excelEntity.UserExcelImportEntity;
import com.zcloud.gbscommon.utils.ExcelUtils; import com.zcloud.gbscommon.utils.ExcelUtils;
@ -18,6 +19,7 @@ import org.apache.commons.lang.StringUtils;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
@ -196,151 +198,6 @@ public class UserE extends BaseE {
} }
} }
// 导入
public List<UserE> parseImportTemplateData(MultipartFile file,
List<DepartmentE> departmentList,
List<PostE> postList,
List<UserE> userList,
Map<String, Long> roleMap,
Map<String, String> dictMap) {
List<UserExcelImportEntity> list = new ArrayList<>();
try {
ExcelUtils.readBatch(file, UserExcelImportEntity.class, list);
if (list.isEmpty()) {
throw new BizException("文件为空");
}
} catch (Exception e) {
throw new BizException("文件解析失败");
}
if (CollUtil.isEmpty(departmentList)) {
throw new BizException("该企业暂未存在部门信息,请添加部门后重新导入");
}
// if(CollUtil.isEmpty(postList)){
// throw new BizException("该企业暂未存在岗位信息,请添加岗位后重新导入");
// }
Map<String, DepartmentE> departmentEMap = departmentList.stream().collect(Collectors.toMap(DepartmentE::getName, DepartmentE -> DepartmentE));
Map<String, UserE> userEMap = new HashMap<>();
if (CollUtil.isNotEmpty(userList)) {
userEMap = userList.stream().collect(Collectors.toMap(UserE::getUsername, UserE -> UserE));
}
Map<String, String> usernameMap = new HashMap<>();
// 错误消息集合
List<String> errList = new ArrayList<>();
// 校验
for (int i = 0; i < list.size(); i++) {
UserExcelImportEntity entity = list.get(i);
if (entity == null) {
errList.add("第" + (i + 2) + "行数据不能为空。");
continue;
}
if (StringUtils.isEmpty(entity.getRoleName())) {
errList.add("第" + (i + 2) + "行用户角色不能为空。");
}
if(!roleMap.containsKey(entity.getRoleName())){
errList.add("第" + (i + 2) + "行用户角色不存在。");
}
if (StringUtils.isEmpty(entity.getDepartmentName())) {
errList.add("第" + (i + 2) + "行所属部门不能为空。");
} else {
if (departmentEMap.get(entity.getDepartmentName()) == null) {
errList.add("第" + (i + 2) + "行所属部门不存在。");
}
}
// 岗位
if (StringUtils.isNotEmpty(entity.getPostName())) {
if (CollUtil.isEmpty(postList)) {
throw new BizException("该企业暂未存在岗位信息,请添加岗位后重新导入");
}
DepartmentE departmentE = departmentEMap.get(entity.getDepartmentName());
if (departmentE != null) {
List<PostE> postListByDepartId = postList.stream().filter(post -> post.getDepartmentId().equals(departmentE.getId())).collect(Collectors.toList());
if (CollUtil.isEmpty(postListByDepartId)) {
errList.add("第" + (i + 2) + "行所属部门下不存在岗位信息。");
} else {
Map<String, PostE> postEMap = postListByDepartId.stream().collect(Collectors.toMap(PostE::getPostName, PostE -> PostE));
if (postEMap.get(entity.getPostName()) == null) {
errList.add("第" + (i + 2) + "行所属岗位信息与所属部门信息不匹配。");
}
}
}
}
// if(StringUtils.isEmpty(entity.getPostName())){
// errList.add("第" + (i+2) + "行所属岗位不能为空。");
// }else{
//
//
// }
// 用户名
if (StringUtils.isEmpty(entity.getUsername())) {
errList.add("第" + (i + 2) + "行用户名不能为空。");
} else {
if (CollUtil.isNotEmpty(userEMap)) {
if (userEMap.get(entity.getUsername()) != null) {
errList.add("第" + (i + 2) + "行用户名重复。");
}
}
if (usernameMap.get(entity.getUsername()) != null) {
errList.add("第" + (i + 2) + "行用户名重复。");
} else {
usernameMap.put(entity.getUsername(), entity.getUsername());
}
}
if (StringUtils.isEmpty(entity.getName())) {
errList.add("第" + (i + 2) + "行姓名不能为空。");
}
if (StringUtils.isEmpty(entity.getPersonnelTypeName())) {
errList.add("第" + (i + 2) + "行人员类型不能为空。");
} else {
if (StringUtils.isEmpty(dictMap.get(entity.getPersonnelTypeName()))) {
errList.add("第" + (i + 2) + "行人员类型与系统不匹配。");
}
}
}
if (CollUtil.isNotEmpty(errList)) {
throw new BizException("导入信息有误,请检查后重新导入。错误信息:" + String.join("", errList));
}
// 映射
List<UserE> userEList = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
UserExcelImportEntity entity = list.get(i);
UserE userE = new UserE();
// 部门
Long departmentId = departmentEMap.get(entity.getDepartmentName()).getId();
userE.setDepartmentId(departmentId);
userE.setDepartmentName(entity.getDepartmentName());
// 岗位
if (StringUtils.isNotEmpty(entity.getPostName())) {
List<PostE> postListByDepartId = postList.stream().filter(post -> post.getDepartmentId().equals(departmentId)).collect(Collectors.toList());
Map<String, PostE> postEMap = postListByDepartId.stream().collect(Collectors.toMap(PostE::getPostName, PostE -> PostE));
userE.setPostId(postEMap.get(entity.getPostName()).getId());
userE.setPostName(entity.getPostName());
}
userE.setRoleId(roleMap.get(entity.getRoleName()));
// 用户名
userE.setUsername(entity.getUsername());
// 姓名
userE.setName(entity.getName());
// 人员类型
userE.setPersonnelType(dictMap.get(entity.getPersonnelTypeName()));
userE.setPersonnelTypeName(entity.getPersonnelTypeName());
userEList.add(userE);
}
return userEList;
}
public void initCorpInfo(CorpInfoE examTypeE, Long departmentId, Long corpInfoId) { public void initCorpInfo(CorpInfoE examTypeE, Long departmentId, Long corpInfoId) {
this.setId(corpInfoId); this.setId(corpInfoId);
this.setName(examTypeE.getCorpName()); this.setName(examTypeE.getCorpName());