diff --git a/web-app/src/main/java/com/zcloud/basic/info/command/UserImportExe.java b/web-app/src/main/java/com/zcloud/basic/info/command/UserImportExe.java new file mode 100644 index 0000000..b14eb72 --- /dev/null +++ b/web-app/src/main/java/com/zcloud/basic/info/command/UserImportExe.java @@ -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 roleCOMultiResponse = roleFacade.listRoles(); + if (roleCOMultiResponse == null || CollUtil.isEmpty(roleCOMultiResponse.getData())) { + throw new BizException("未创建默认通用角色,请联系管理员"); + } + // 部门数据 + List departmentDOList = departmentRepository.listByCorpInfoId(corpinfoId); + // 岗位数据 + List postDOList = postRepository.listByCorpInfoId(corpinfoId); + // 用户名数据 + List userDOList = userRepository.listByCorpInfoId(corpinfoId); + + List 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 departmentDOList, List postDOList, + List userDOList, List 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 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 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 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 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 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 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 roleList) { + if(StringUtils.isBlank(importEntity.getRoleName())){ + throw new BizException("角色名称不能为空"); + } + Map 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 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); + } +} + diff --git a/web-domain/src/main/java/com/zcloud/basic/info/domain/model/UserE.java b/web-domain/src/main/java/com/zcloud/basic/info/domain/model/UserE.java index f2d99b6..75b67f0 100644 --- a/web-domain/src/main/java/com/zcloud/basic/info/domain/model/UserE.java +++ b/web-domain/src/main/java/com/zcloud/basic/info/domain/model/UserE.java @@ -6,6 +6,7 @@ import com.alibaba.cola.exception.BizException; import com.baomidou.mybatisplus.annotation.TableField; import com.jjb.saas.framework.domain.model.BaseE; 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.UserExcelImportEntity; import com.zcloud.gbscommon.utils.ExcelUtils; @@ -18,6 +19,7 @@ import org.apache.commons.lang.StringUtils; import org.springframework.util.ObjectUtils; import org.springframework.web.multipart.MultipartFile; +import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.time.LocalDateTime; import java.util.ArrayList; @@ -196,151 +198,6 @@ public class UserE extends BaseE { } } - // 导入 - public List parseImportTemplateData(MultipartFile file, - List departmentList, - List postList, - List userList, - Map roleMap, - Map dictMap) { - List 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 departmentEMap = departmentList.stream().collect(Collectors.toMap(DepartmentE::getName, DepartmentE -> DepartmentE)); - - - Map userEMap = new HashMap<>(); - if (CollUtil.isNotEmpty(userList)) { - userEMap = userList.stream().collect(Collectors.toMap(UserE::getUsername, UserE -> UserE)); - } - - Map usernameMap = new HashMap<>(); - - - // 错误消息集合 - List 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 postListByDepartId = postList.stream().filter(post -> post.getDepartmentId().equals(departmentE.getId())).collect(Collectors.toList()); - if (CollUtil.isEmpty(postListByDepartId)) { - errList.add("第" + (i + 2) + "行所属部门下不存在岗位信息。"); - } else { - Map 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 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 postListByDepartId = postList.stream().filter(post -> post.getDepartmentId().equals(departmentId)).collect(Collectors.toList()); - Map 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) { this.setId(corpInfoId); this.setName(examTypeE.getCorpName());