一、代碼?
@PostMapping("/import")@Operation(summary = "導入用戶")@Parameters({@Parameter(name = "file", description = "Excel 文件", required = true),@Parameter(name = "updateSupport", description = "是否支持更新,默認為 false", example = "true")})@PreAuthorize("@ss.hasPermission('system:user:import')")public CommonResult<UserImportRespVO> importExcel(@RequestParam("file") MultipartFile file,@RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception {List<UserImportExcelVO> list = ExcelUtils.read(file, UserImportExcelVO.class);return success(userService.importUserList(list, updateSupport));}
@Override@Transactional(rollbackFor = Exception.class) // 添加事務,異常則回滾所有導入public UserImportRespVO importUserList(List<UserImportExcelVO> importUsers, boolean isUpdateSupport) {// 1.1 參數校驗if (CollUtil.isEmpty(importUsers)) {throw exception(USER_IMPORT_LIST_IS_EMPTY);}// 1.2 初始化密碼不能為空String initPassword = configApi.getConfigValueByKey(USER_INIT_PASSWORD_KEY).getCheckedData();if (StrUtil.isEmpty(initPassword)) {throw exception(USER_IMPORT_INIT_PASSWORD);}// 2. 遍歷,逐個創建 or 更新UserImportRespVO respVO = UserImportRespVO.builder().createUsernames(new ArrayList<>()).updateUsernames(new ArrayList<>()).failureUsernames(new LinkedHashMap<>()).build();importUsers.forEach(importUser -> {// 2.1.1 校驗字段是否符合要求try {ValidationUtils.validate(BeanUtils.toBean(importUser, UserSaveReqVO.class).setPassword(initPassword));} catch (ConstraintViolationException ex){respVO.getFailureUsernames().put(importUser.getUsername(), ex.getMessage());return;}// 2.1.2 校驗,判斷是否有不符合的原因try {validateUserForCreateOrUpdate(null, null, importUser.getMobile(), importUser.getEmail(),importUser.getDeptId(), null);} catch (ServiceException ex) {respVO.getFailureUsernames().put(importUser.getUsername(), ex.getMessage());return;}// 2.2.1 判斷如果不存在,在進行插入AdminUserDO existUser = userMapper.selectByUsername(importUser.getUsername());if (existUser == null) {userMapper.insert(BeanUtils.toBean(importUser, AdminUserDO.class).setPassword(encodePassword(initPassword)).setPostIds(new HashSet<>())); // 設置默認密碼及空崗位編號數組respVO.getCreateUsernames().add(importUser.getUsername());return;}// 2.2.2 如果存在,判斷是否允許更新if (!isUpdateSupport) {respVO.getFailureUsernames().put(importUser.getUsername(), USER_USERNAME_EXISTS.getMsg());return;}AdminUserDO updateUser = BeanUtils.toBean(importUser, AdminUserDO.class);updateUser.setId(existUser.getId());userMapper.updateById(updateUser);respVO.getUpdateUsernames().add(importUser.getUsername());});return respVO;}
二、密碼判斷?
? 1.
configApi.getConfigValueByKey(...)
這是調用 配置中心 API(
configApi
)的方法,去根據配置項的 key 獲取對應的值。
USER_INIT_PASSWORD_KEY
是常量,通常定義為字符串"sys.user.init-password"
(或者類似的 key)。意思是:去配置系統里找“用戶初始密碼”的配置。
? 2.
.getCheckedData()
這是對配置結果的 封裝處理,用于確保該配置值是存在并有效的。
如果配置項未設置或值為空,它可能會拋出異常(提示配置缺失),避免后面使用 null 值。
所以這是一個 帶校驗的安全獲取配置值方式。
三、校驗數據 (加注解)
?
當執行 validate(userSaveReqVO)
時,如果 username
是空,或者 email
格式不對,或者 password
長度不合適,都會被檢測出來,然后拋出異常。
?
字段名 | 校驗規則 | 說明 |
---|---|---|
username | @NotBlank 、@Pattern 、@Size(4~30) | 用戶賬號不能為空,且只能是字母數字,長度4~30 |
nickname | @Size(max=30) | 用戶昵稱最長30個字符 |
email | @Email 、@Size(max=50) | 必須是合法郵箱,最長50字符 |
mobile | @Mobile (自定義手機校驗注解) | 手機號格式校驗 |
password | @Length(4~16) + @AssertTrue(isPasswordValid) | 新增用戶時密碼不能為空且長度4~16 |
?