| | |
| | | import cn.iocoder.yudao.module.system.dal.mysql.dept.UserPostMapper; |
| | | import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper; |
| | | import cn.iocoder.yudao.module.system.mq.producer.user.AdminUserProducer; |
| | | import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO; |
| | | import cn.iocoder.yudao.module.system.service.dept.DeptService; |
| | | import cn.iocoder.yudao.module.system.service.dept.PostService; |
| | | import cn.iocoder.yudao.module.system.service.oauth2.OAuth2TokenService; |
| | |
| | | if (StrUtil.isEmpty(initPassword)) { |
| | | throw exception(USER_IMPORT_INIT_PASSWORD); |
| | | } |
| | | // 1.3 预加载部门:名称 -> 部门,编号 -> 部门,供两种写法解析 |
| | | List<DeptDO> allDepts = deptService.getDeptList(new DeptListReqVO()); |
| | | Map<String, DeptDO> deptByName = new HashMap<>(allDepts.size()); |
| | | for (DeptDO dept : allDepts) { |
| | | deptByName.put(dept.getName().trim(), dept); |
| | | } |
| | | |
| | | // 2. 遍历,逐个创建 or 更新 |
| | | UserImportRespVO respVO = UserImportRespVO.builder().createUsernames(new ArrayList<>()) |
| | |
| | | AtomicInteger index = new AtomicInteger(1); |
| | | importUsers.forEach(importUser -> { |
| | | int currentIndex = index.getAndIncrement(); |
| | | // 2.1.1 校验字段是否符合要求 |
| | | try { |
| | | ValidationUtils.validate(BeanUtils.toBean(importUser, UserSaveReqVO.class).setPassword(initPassword)); |
| | | } catch (ConstraintViolationException ex) { |
| | | String key = StrUtil.blankToDefault(importUser.getUsername(), "第 " + currentIndex + " 行"); |
| | | respVO.getFailureUsernames().put(key, ex.getMessage()); |
| | | // 用于报错的定位 key:优先登录名,否则「第 N 行」 |
| | | String rowKey = StrUtil.blankToDefault(importUser.getUsername(), "第 " + currentIndex + " 行"); |
| | | |
| | | // 2.1 解析部门:优先按名称,兼容历史模板填的部门编号 |
| | | DeptDO dept = resolveImportDept(importUser.getDeptName(), deptByName); |
| | | if (dept == null && StrUtil.isNotBlank(importUser.getDeptName())) { |
| | | respVO.getFailureUsernames().put(rowKey, |
| | | "部门「" + importUser.getDeptName().trim() + "」不存在,请填写部门管理中的完整部门名称"); |
| | | return; |
| | | } |
| | | // 2.1.2 校验,判断是否有不符合的原因 |
| | | Long deptId = dept != null ? dept.getId() : null; |
| | | importUser.setDeptName(dept != null ? dept.getName() : importUser.getDeptName()); |
| | | |
| | | // 2.2 校验字段是否符合要求 |
| | | try { |
| | | validateUserForCreateOrUpdate(null, null, importUser.getMobile(), importUser.getEmail(), |
| | | importUser.getDeptId(), null); |
| | | ValidationUtils.validate(BeanUtils.toBean(importUser, UserSaveReqVO.class) |
| | | .setPassword(initPassword).setDeptId(deptId)); |
| | | } catch (ConstraintViolationException ex) { |
| | | respVO.getFailureUsernames().put(rowKey, ex.getMessage()); |
| | | return; |
| | | } |
| | | // 2.3 校验业务约束(手机号/邮箱/部门是否存在) |
| | | try { |
| | | validateUserForCreateOrUpdate(null, null, importUser.getMobile(), importUser.getEmail(), deptId, null); |
| | | } catch (ServiceException ex) { |
| | | respVO.getFailureUsernames().put(importUser.getUsername(), ex.getMessage()); |
| | | respVO.getFailureUsernames().put(rowKey, ex.getMessage()); |
| | | return; |
| | | } |
| | | |
| | | // 2.2.1 判断如果不存在,在进行插入 |
| | | // 2.4 判断如果不存在,在进行插入 |
| | | AdminUserDO existUser = userMapper.selectByUsername(importUser.getUsername()); |
| | | if (existUser == null) { |
| | | userMapper.insert(BeanUtils.toBean(importUser, AdminUserDO.class) |
| | | .setPassword(encodePassword(initPassword)).setPostIds(new HashSet<>())); // 设置默认密码及空岗位编号数组 |
| | | AdminUserDO newUser = BeanUtils.toBean(importUser, AdminUserDO.class); |
| | | newUser.setDeptId(deptId); |
| | | newUser.setPassword(encodePassword(initPassword)).setPostIds(new HashSet<>()); // 默认密码及空岗位 |
| | | userMapper.insert(newUser); |
| | | respVO.getCreateUsernames().add(importUser.getUsername()); |
| | | return; |
| | | } |
| | | // 2.2.2 如果存在,判断是否允许更新 |
| | | // 2.5 如果存在,判断是否允许更新 |
| | | if (!isUpdateSupport) { |
| | | respVO.getFailureUsernames().put(importUser.getUsername(), USER_USERNAME_EXISTS.getMsg()); |
| | | respVO.getFailureUsernames().put(rowKey, USER_USERNAME_EXISTS.getMsg()); |
| | | return; |
| | | } |
| | | AdminUserDO updateUser = BeanUtils.toBean(importUser, AdminUserDO.class); |
| | | updateUser.setId(existUser.getId()); |
| | | updateUser.setDeptId(deptId); |
| | | userMapper.updateById(updateUser); |
| | | respVO.getUpdateUsernames().add(importUser.getUsername()); |
| | | }); |
| | |
| | | return respVO; |
| | | } |
| | | |
| | | /** |
| | | * 解析导入行里的部门 |
| | | * |
| | | * 优先按部门名称精确匹配;若填写的是纯数字,再按部门编号匹配(兼容历史模板)。 |
| | | * |
| | | * @param raw 导入填写的部门文本 |
| | | * @param byName 部门名称 -> 部门 |
| | | * @param byId 部门编号 -> 部门 |
| | | * @return 匹配到的部门,未填写返回 null,填了但匹配不到也返回 null |
| | | */ |
| | | /** |
| | | * 解析导入行里的部门名称 |
| | | * |
| | | * 只按部门名称精确匹配(不再兼容数字编号,避免使用者填错列导致静默错配)。 |
| | | * |
| | | * @param raw 导入填写的部门名称 |
| | | * @param byName 部门名称 -> 部门 |
| | | * @return 匹配到的部门;未填写或匹配不到返回 null |
| | | */ |
| | | private DeptDO resolveImportDept(String raw, Map<String, DeptDO> byName) { |
| | | if (StrUtil.isBlank(raw)) { |
| | | return null; |
| | | } |
| | | return byName.get(raw.trim()); |
| | | } |
| | | |
| | | @Override |
| | | public List<AdminUserDO> getUserListByStatus(Integer status) { |
| | | return userMapper.selectListByStatus(status); |