From 3cb996a045eed15c039391863c813ddcaec74174 Mon Sep 17 00:00:00 2001 From: haoxr <1490493387@qq.com> Date: Fri, 3 Mar 2023 18:28:02 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E7=94=A8=E6=88=B7=E5=AF=BC?= =?UTF-8?q?=E5=85=A5=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/listener/UserImportListener.java | 128 ++++++++++-------- .../youlai/system/pojo/vo/UserImportVO.java | 5 +- .../excel-templates/用户导入模板.xlsx | Bin 12414 -> 12438 bytes 3 files changed, 76 insertions(+), 57 deletions(-) diff --git a/src/main/java/com/youlai/system/listener/UserImportListener.java b/src/main/java/com/youlai/system/listener/UserImportListener.java index c17d382a..305264d8 100644 --- a/src/main/java/com/youlai/system/listener/UserImportListener.java +++ b/src/main/java/com/youlai/system/listener/UserImportListener.java @@ -1,24 +1,31 @@ package com.youlai.system.listener; +import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.lang.Validator; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.spring.SpringUtil; import cn.hutool.json.JSONUtil; import com.alibaba.excel.context.AnalysisContext; -import com.alibaba.excel.util.ListUtils; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.youlai.system.common.base.IBaseEnum; import com.youlai.system.common.constant.SystemConstants; import com.youlai.system.common.enums.GenderEnum; +import com.youlai.system.common.enums.StatusEnum; import com.youlai.system.converter.UserConverter; import com.youlai.system.framework.easyexcel.MyAnalysisEventListener; +import com.youlai.system.pojo.entity.SysRole; import com.youlai.system.pojo.entity.SysUser; +import com.youlai.system.pojo.entity.SysUserRole; import com.youlai.system.pojo.vo.UserImportVO; +import com.youlai.system.service.SysRoleService; +import com.youlai.system.service.SysUserRoleService; import com.youlai.system.service.SysUserService; import lombok.extern.slf4j.Slf4j; import org.springframework.security.crypto.password.PasswordEncoder; import java.util.List; +import java.util.stream.Collectors; + /** * 用户导入监听器 @@ -31,28 +38,17 @@ import java.util.List; @Slf4j public class UserImportListener extends MyAnalysisEventListener { - /** - * 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收 - */ - private static final int BATCH_COUNT = 100; + // 有效条数 private int validCount; + // 无效条数 private int invalidCount; - private int currentIndex; - + // 导入返回信息 StringBuilder msg = new StringBuilder(); - - /** - * 缓存的数据 - */ - private List cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); - - /** - * 部门ID - */ + // 部门ID private final Long deptId; private final SysUserService userService; @@ -61,76 +57,102 @@ public class UserImportListener extends MyAnalysisEventListener { private final UserConverter userConverter; + private final SysRoleService roleService; + + private final SysUserRoleService userRoleService; + public UserImportListener(Long deptId) { this.deptId = deptId; this.userService = SpringUtil.getBean(SysUserService.class); this.passwordEncoder = SpringUtil.getBean(PasswordEncoder.class); + this.roleService = SpringUtil.getBean(SysRoleService.class); + this.userRoleService = SpringUtil.getBean(SysUserRoleService.class); this.userConverter = SpringUtil.getBean(UserConverter.class); } /** * 每一条数据解析都会来调用 + *

+ * 1. 数据校验;全字段校验 + * 2. 数据持久化; * - * @param userImportVO 一行数据,类似于 {@link AnalysisContext#readRowHolder()} + * @param userImportVO 一行数据,类似于 {@link AnalysisContext#readRowHolder()} * @param analysisContext */ @Override public void invoke(UserImportVO userImportVO, AnalysisContext analysisContext) { log.info("解析到一条用户数据:{}", JSONUtil.toJsonStr(userImportVO)); - currentIndex++; - StringBuilder rowMsg = new StringBuilder(); - boolean rowFlag = true; // 校验数据 + StringBuilder validationMsg = new StringBuilder(); String username = userImportVO.getUsername(); if (StrUtil.isBlank(username)) { - rowFlag = false; - rowMsg.append("用户名为空;"); + validationMsg.append("用户名为空;"); } else { long count = userService.count(new LambdaQueryWrapper().eq(SysUser::getUsername, username)); if (count > 0) { - rowFlag = false; - rowMsg.append("用户名已存在;"); + validationMsg.append("用户名已存在;"); } } String nickname = userImportVO.getNickname(); if (StrUtil.isBlank(nickname)) { - rowFlag = false; - rowMsg.append("用户昵称为空;"); + validationMsg.append("用户昵称为空;"); } - String mobile = userImportVO.getMobile(); if (StrUtil.isBlank(mobile)) { - rowFlag = false; - rowMsg.append("手机号码为空;"); + validationMsg.append("手机号码为空;"); } else { if (!Validator.isMobile(mobile)) { - rowFlag = false; - rowMsg.append("手机号码不正确;"); + validationMsg.append("手机号码不正确;"); } } - if (rowFlag) { - validCount++; + if (validationMsg.length() == 0) { + // 校验通过,持久化至数据库 SysUser entity = userConverter.importVo2Entity(userImportVO); - // 默认密码 - entity.setPassword(passwordEncoder.encode(SystemConstants.DEFAULT_PASSWORD)); - // 性别转换 - Integer gender = (Integer) IBaseEnum.getValueByLabel(userImportVO.getGender(), GenderEnum.class); - entity.setGender(gender); - entity.setDeptId(deptId); + entity.setDeptId(deptId); // 部门 + entity.setPassword(passwordEncoder.encode(SystemConstants.DEFAULT_PASSWORD)); // 默认密码 + // 性别翻译 + String genderLabel = userImportVO.getGender(); + if (StrUtil.isNotBlank(genderLabel)) { + Integer genderValue = (Integer) IBaseEnum.getValueByLabel(genderLabel, GenderEnum.class); + entity.setGender(genderValue); + } - cachedDataList.add(entity); + // 角色解析 + String roleCodes = userImportVO.getRoleCodes(); + List roleIds = null; + if (StrUtil.isNotBlank(roleCodes)) { + roleIds = roleService.list( + new LambdaQueryWrapper() + .in(SysRole::getCode, roleCodes.split(",")) + .eq(SysRole::getStatus, StatusEnum.ENABLE.getValue()) + .select(SysRole::getId) + ).stream() + .map(role -> role.getId()) + .collect(Collectors.toList()); + } + + + boolean saveResult = userService.save(entity); + if (saveResult) { + validCount++; + // 保存用户角色关联 + if (CollectionUtil.isNotEmpty(roleIds)) { + List userRoles = roleIds.stream() + .map(roleId -> new SysUserRole(entity.getId(), roleId)) + .collect(Collectors.toList()); + userRoleService.saveBatch(userRoles); + } + } else { + invalidCount++; + msg.append("第" + (validCount + invalidCount) + "行数据保存失败;
"); + } } else { invalidCount++; - msg.append("第" + currentIndex + "行数据校验失败:").append(rowMsg + "
"); - } - - if (cachedDataList.size() > BATCH_COUNT) { - saveData(); - cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); + msg.append("第" + (validCount + invalidCount) + "行数据校验失败:").append(validationMsg + "
"); } } @@ -142,20 +164,14 @@ public class UserImportListener extends MyAnalysisEventListener { */ @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { - // 这里也要保存数据,确保最后遗留的数据也存储到数据库 - saveData(); - msg = new StringBuilder("导入用户结束:成功" + validCount + "条;失败" + invalidCount + "条
").append(msg); + } - /** - * 存储数据库 - */ - private void saveData() { - userService.saveBatch(cachedDataList); - } @Override public String getMsg() { - return this.msg.toString(); + // 总结信息 + String summaryMsg = StrUtil.format("导入用户结束:成功{}条,失败{}条;
{}", validCount, invalidCount, msg); + return summaryMsg; } } diff --git a/src/main/java/com/youlai/system/pojo/vo/UserImportVO.java b/src/main/java/com/youlai/system/pojo/vo/UserImportVO.java index f47a43c9..67c27f69 100644 --- a/src/main/java/com/youlai/system/pojo/vo/UserImportVO.java +++ b/src/main/java/com/youlai/system/pojo/vo/UserImportVO.java @@ -15,7 +15,7 @@ public class UserImportVO { @ExcelProperty(value = "用户名") private String username; - @ExcelProperty(value = "用户昵称") + @ExcelProperty(value = "昵称") private String nickname; @ExcelProperty(value = "性别") @@ -27,4 +27,7 @@ public class UserImportVO { @ExcelProperty(value = "邮箱") private String email; + @ExcelProperty("角色") + private String roleCodes; + } diff --git a/src/main/resources/excel-templates/用户导入模板.xlsx b/src/main/resources/excel-templates/用户导入模板.xlsx index 36a208cc11024cb47601bf33be5568c0f80b30fe..7ece1403061fd34e6e4467907c0630813059446b 100644 GIT binary patch delta 3105 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 delta 3044 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 X**kqw>d|~+`7=Y1MKF*ge((J+WPN8q