mirror of
				https://github.com/continew-org/continew-admin.git
				synced 2025-10-31 00:57:13 +08:00 
			
		
		
		
	优化:优化部分校验类型(业务验证迁移到 Service 层,使用 CheckUtils 来验证)
This commit is contained in:
		| @@ -226,6 +226,7 @@ continew-admin  # 全局通用项目配置及依赖版本管理 | |||||||
|   │                │  ├─ dto          # 公共 DTO(Data Transfer Object) |   │                │  ├─ dto          # 公共 DTO(Data Transfer Object) | ||||||
|   │                │  ├─ entity       # 公共实体对象 |   │                │  ├─ entity       # 公共实体对象 | ||||||
|   │                │  ├─ query        # 公共查询条件 |   │                │  ├─ query        # 公共查询条件 | ||||||
|  |   │                │  ├─ request      # 公共请求对象 | ||||||
|   │                │  └─ vo           # 公共 VO(View Object) |   │                │  └─ vo           # 公共 VO(View Object) | ||||||
|   │                └─ util         # 公共工具类 |   │                └─ util         # 公共工具类 | ||||||
|   │                  ├─ helper        # 公共 Helper(助手) |   │                  ├─ helper        # 公共 Helper(助手) | ||||||
|   | |||||||
| @@ -33,6 +33,7 @@ import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum; | |||||||
|  * @since 2023/1/24 19:51 |  * @since 2023/1/24 19:51 | ||||||
|  */ |  */ | ||||||
| @Data | @Data | ||||||
|  | @Schema(description = "修改状态信息") | ||||||
| public class UpdateStatusRequest implements Serializable { | public class UpdateStatusRequest implements Serializable { | ||||||
|  |  | ||||||
|     private static final long serialVersionUID = 1L; |     private static final long serialVersionUID = 1L; | ||||||
| @@ -40,7 +41,7 @@ public class UpdateStatusRequest implements Serializable { | |||||||
|     /** |     /** | ||||||
|      * 状态(1启用 2禁用) |      * 状态(1启用 2禁用) | ||||||
|      */ |      */ | ||||||
|     @Schema(description = "状态(1启用 2禁用)") |     @Schema(description = "状态(1启用 2禁用)", type = "Integer", allowableValues = {"1", "2"}) | ||||||
|     @NotNull(message = "状态非法") |     @NotNull(message = "状态非法") | ||||||
|     private DisEnableStatusEnum status; |     private DisEnableStatusEnum status; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ import lombok.extern.slf4j.Slf4j; | |||||||
| import top.charles7c.cnadmin.common.exception.ServiceException; | import top.charles7c.cnadmin.common.exception.ServiceException; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 业务检查工具类(抛出 500 ServiceException) |  * 业务参数校验工具类(抛出 500 ServiceException) | ||||||
|  * |  * | ||||||
|  * @author Charles7c |  * @author Charles7c | ||||||
|  * @see ServiceException |  * @see ServiceException | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ import lombok.extern.slf4j.Slf4j; | |||||||
| import top.charles7c.cnadmin.common.exception.BadRequestException; | import top.charles7c.cnadmin.common.exception.BadRequestException; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 校验工具类(抛出 400 BadRequestException) |  * 基本参数校验工具类(抛出 400 BadRequestException) | ||||||
|  * |  * | ||||||
|  * @author Charles7c |  * @author Charles7c | ||||||
|  * @since 2022/12/21 20:56 |  * @since 2022/12/21 20:56 | ||||||
|   | |||||||
| @@ -38,7 +38,7 @@ import top.charles7c.cnadmin.common.model.vo.PageInfo; | |||||||
| import top.charles7c.cnadmin.common.util.ExceptionUtils; | import top.charles7c.cnadmin.common.util.ExceptionUtils; | ||||||
| import top.charles7c.cnadmin.common.util.ReflectUtils; | import top.charles7c.cnadmin.common.util.ReflectUtils; | ||||||
| import top.charles7c.cnadmin.common.util.helper.QueryHelper; | import top.charles7c.cnadmin.common.util.helper.QueryHelper; | ||||||
| import top.charles7c.cnadmin.common.util.validate.ValidationUtils; | import top.charles7c.cnadmin.common.util.validate.CheckUtils; | ||||||
| import top.charles7c.cnadmin.monitor.mapper.LogMapper; | import top.charles7c.cnadmin.monitor.mapper.LogMapper; | ||||||
| import top.charles7c.cnadmin.monitor.model.entity.SysLog; | import top.charles7c.cnadmin.monitor.model.entity.SysLog; | ||||||
| import top.charles7c.cnadmin.monitor.model.query.LoginLogQuery; | import top.charles7c.cnadmin.monitor.model.query.LoginLogQuery; | ||||||
| @@ -135,7 +135,7 @@ public class LogServiceImpl implements LogService { | |||||||
|     @Override |     @Override | ||||||
|     public SystemLogDetailVO detail(Long logId) { |     public SystemLogDetailVO detail(Long logId) { | ||||||
|         SysLog sysLog = logMapper.selectById(logId); |         SysLog sysLog = logMapper.selectById(logId); | ||||||
|         ValidationUtils.throwIfNull(sysLog, String.format("ID为 [%s] 的日志已不存在", logId)); |         CheckUtils.throwIfNull(sysLog, String.format("ID为 [%s] 的日志已不存在", logId)); | ||||||
|  |  | ||||||
|         SystemLogDetailVO detailVO = BeanUtil.copyProperties(sysLog, SystemLogDetailVO.class); |         SystemLogDetailVO detailVO = BeanUtil.copyProperties(sysLog, SystemLogDetailVO.class); | ||||||
|         this.fill(detailVO); |         this.fill(detailVO); | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum; | |||||||
| import top.charles7c.cnadmin.common.model.dto.LoginUser; | import top.charles7c.cnadmin.common.model.dto.LoginUser; | ||||||
| import top.charles7c.cnadmin.common.util.SecureUtils; | import top.charles7c.cnadmin.common.util.SecureUtils; | ||||||
| import top.charles7c.cnadmin.common.util.helper.LoginHelper; | import top.charles7c.cnadmin.common.util.helper.LoginHelper; | ||||||
| import top.charles7c.cnadmin.common.util.validate.ValidationUtils; | import top.charles7c.cnadmin.common.util.validate.CheckUtils; | ||||||
| import top.charles7c.cnadmin.system.model.entity.SysUser; | import top.charles7c.cnadmin.system.model.entity.SysUser; | ||||||
| import top.charles7c.cnadmin.system.service.UserService; | import top.charles7c.cnadmin.system.service.UserService; | ||||||
|  |  | ||||||
| @@ -46,15 +46,11 @@ public class LoginServiceImpl implements LoginService { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public String login(String username, String password) { |     public String login(String username, String password) { | ||||||
|         // 查询用户 |  | ||||||
|         SysUser sysUser = userService.getByUsername(username); |         SysUser sysUser = userService.getByUsername(username); | ||||||
|  |         CheckUtils.throwIfNull(sysUser, "用户名或密码错误"); | ||||||
|         // 校验 |  | ||||||
|         ValidationUtils.throwIfNull(sysUser, "用户名或密码错误"); |  | ||||||
|         Long userId = sysUser.getUserId(); |         Long userId = sysUser.getUserId(); | ||||||
|         ValidationUtils.throwIfNotEqual(SecureUtils.md5Salt(password, userId.toString()), sysUser.getPassword(), |         CheckUtils.throwIfNotEqual(SecureUtils.md5Salt(password, userId.toString()), sysUser.getPassword(), "用户名或密码错误"); | ||||||
|             "用户名或密码错误"); |         CheckUtils.throwIfEqual(DisEnableStatusEnum.DISABLE, sysUser.getStatus(), "此账号已被禁用,如有疑问,请联系管理员"); | ||||||
|         ValidationUtils.throwIfEqual(DisEnableStatusEnum.DISABLE, sysUser.getStatus(), "此账号已被禁用,如有疑问,请联系管理员"); |  | ||||||
|  |  | ||||||
|         // 登录 |         // 登录 | ||||||
|         LoginUser loginUser = BeanUtil.copyProperties(sysUser, LoginUser.class); |         LoginUser loginUser = BeanUtil.copyProperties(sysUser, LoginUser.class); | ||||||
|   | |||||||
| @@ -19,12 +19,13 @@ package top.charles7c.cnadmin.system.model.request; | |||||||
| import java.io.Serializable; | import java.io.Serializable; | ||||||
|  |  | ||||||
| import javax.validation.constraints.NotBlank; | import javax.validation.constraints.NotBlank; | ||||||
| import javax.validation.constraints.Size; |  | ||||||
|  |  | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
|  |  | ||||||
| import io.swagger.v3.oas.annotations.media.Schema; | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
|  |  | ||||||
|  | import org.hibernate.validator.constraints.Length; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 创建部门信息 |  * 创建部门信息 | ||||||
|  * |  * | ||||||
| @@ -60,6 +61,6 @@ public class CreateDeptRequest implements Serializable { | |||||||
|      * 描述 |      * 描述 | ||||||
|      */ |      */ | ||||||
|     @Schema(description = "描述") |     @Schema(description = "描述") | ||||||
|     @Size(max = 200, message = "描述长度不能超过 200 个字符") |     @Length(max = 200, message = "描述长度不能超过 200 个字符") | ||||||
|     private String description; |     private String description; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -20,12 +20,13 @@ import java.io.Serializable; | |||||||
|  |  | ||||||
| import javax.validation.constraints.NotBlank; | import javax.validation.constraints.NotBlank; | ||||||
| import javax.validation.constraints.NotNull; | import javax.validation.constraints.NotNull; | ||||||
| import javax.validation.constraints.Size; |  | ||||||
|  |  | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
|  |  | ||||||
| import io.swagger.v3.oas.annotations.media.Schema; | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
|  |  | ||||||
|  | import org.hibernate.validator.constraints.Length; | ||||||
|  |  | ||||||
| import top.charles7c.cnadmin.common.enums.GenderEnum; | import top.charles7c.cnadmin.common.enums.GenderEnum; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -45,7 +46,7 @@ public class UpdateBasicInfoRequest implements Serializable { | |||||||
|      */ |      */ | ||||||
|     @Schema(description = "昵称") |     @Schema(description = "昵称") | ||||||
|     @NotBlank(message = "昵称不能为空") |     @NotBlank(message = "昵称不能为空") | ||||||
|     @Size(max = 32, message = "昵称长度不能超过 32 个字符") |     @Length(max = 32, message = "昵称长度不能超过 32 个字符") | ||||||
|     private String nickname; |     private String nickname; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|   | |||||||
| @@ -37,6 +37,7 @@ import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum; | |||||||
| import top.charles7c.cnadmin.common.util.ExceptionUtils; | import top.charles7c.cnadmin.common.util.ExceptionUtils; | ||||||
| import top.charles7c.cnadmin.common.util.TreeUtils; | import top.charles7c.cnadmin.common.util.TreeUtils; | ||||||
| import top.charles7c.cnadmin.common.util.helper.QueryHelper; | import top.charles7c.cnadmin.common.util.helper.QueryHelper; | ||||||
|  | import top.charles7c.cnadmin.common.util.validate.CheckUtils; | ||||||
| import top.charles7c.cnadmin.system.mapper.DeptMapper; | import top.charles7c.cnadmin.system.mapper.DeptMapper; | ||||||
| import top.charles7c.cnadmin.system.model.entity.SysDept; | import top.charles7c.cnadmin.system.model.entity.SysDept; | ||||||
| import top.charles7c.cnadmin.system.model.query.DeptQuery; | import top.charles7c.cnadmin.system.model.query.DeptQuery; | ||||||
| @@ -75,7 +76,7 @@ public class DeptServiceImpl implements DeptService { | |||||||
|             return new ArrayList<>(); |             return new ArrayList<>(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // 去重 |         // 去除重复子部门列表 | ||||||
|         List<DeptVO> deDuplicationDeptList = deDuplication(list); |         List<DeptVO> deDuplicationDeptList = deDuplication(list); | ||||||
|         return deDuplicationDeptList.stream().map(d -> d.setChildren(this.getChildren(d, list))) |         return deDuplicationDeptList.stream().map(d -> d.setChildren(this.getChildren(d, list))) | ||||||
|             .collect(Collectors.toList()); |             .collect(Collectors.toList()); | ||||||
| @@ -134,6 +135,11 @@ public class DeptServiceImpl implements DeptService { | |||||||
|     @Override |     @Override | ||||||
|     @Transactional(rollbackFor = Exception.class) |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public Long create(CreateDeptRequest request) { |     public Long create(CreateDeptRequest request) { | ||||||
|  |         String deptName = request.getDeptName(); | ||||||
|  |         boolean isExist = this.checkDeptNameExist(deptName, request.getParentId(), null); | ||||||
|  |         CheckUtils.throwIf(() -> isExist, String.format("新增失败,'%s'已存在", deptName)); | ||||||
|  |  | ||||||
|  |         // 保存部门信息 | ||||||
|         SysDept sysDept = BeanUtil.copyProperties(request, SysDept.class); |         SysDept sysDept = BeanUtil.copyProperties(request, SysDept.class); | ||||||
|         sysDept.setStatus(DisEnableStatusEnum.ENABLE); |         sysDept.setStatus(DisEnableStatusEnum.ENABLE); | ||||||
|         deptMapper.insert(sysDept); |         deptMapper.insert(sysDept); | ||||||
|   | |||||||
| @@ -30,15 +30,16 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||||||
|  |  | ||||||
| import cn.hutool.core.bean.BeanUtil; | import cn.hutool.core.bean.BeanUtil; | ||||||
| import cn.hutool.core.io.FileUtil; | import cn.hutool.core.io.FileUtil; | ||||||
|  | import cn.hutool.core.io.file.FileNameUtil; | ||||||
| import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||||
|  |  | ||||||
| import top.charles7c.cnadmin.common.config.properties.LocalStorageProperties; | import top.charles7c.cnadmin.common.config.properties.LocalStorageProperties; | ||||||
|  | import top.charles7c.cnadmin.common.consts.FileConstants; | ||||||
| import top.charles7c.cnadmin.common.model.dto.LoginUser; | import top.charles7c.cnadmin.common.model.dto.LoginUser; | ||||||
| import top.charles7c.cnadmin.common.util.FileUtils; | import top.charles7c.cnadmin.common.util.FileUtils; | ||||||
| import top.charles7c.cnadmin.common.util.SecureUtils; | import top.charles7c.cnadmin.common.util.SecureUtils; | ||||||
| import top.charles7c.cnadmin.common.util.helper.LoginHelper; | import top.charles7c.cnadmin.common.util.helper.LoginHelper; | ||||||
| import top.charles7c.cnadmin.common.util.validate.CheckUtils; | import top.charles7c.cnadmin.common.util.validate.CheckUtils; | ||||||
| import top.charles7c.cnadmin.common.util.validate.ValidationUtils; |  | ||||||
| import top.charles7c.cnadmin.system.mapper.UserMapper; | import top.charles7c.cnadmin.system.mapper.UserMapper; | ||||||
| import top.charles7c.cnadmin.system.model.entity.SysUser; | import top.charles7c.cnadmin.system.model.entity.SysUser; | ||||||
| import top.charles7c.cnadmin.system.service.UserService; | import top.charles7c.cnadmin.system.service.UserService; | ||||||
| @@ -64,6 +65,14 @@ public class UserServiceImpl implements UserService { | |||||||
|     @Override |     @Override | ||||||
|     @Transactional(rollbackFor = Exception.class) |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public String uploadAvatar(MultipartFile avatarFile, Long userId) { |     public String uploadAvatar(MultipartFile avatarFile, Long userId) { | ||||||
|  |         Long avatarMaxSizeInMb = localStorageProperties.getAvatarMaxSizeInMb(); | ||||||
|  |         CheckUtils.throwIf(() -> avatarFile.getSize() > avatarMaxSizeInMb * 1024 * 1024, | ||||||
|  |             String.format("请上传小于 %s MB 的图片", avatarMaxSizeInMb)); | ||||||
|  |         String avatarImageType = FileNameUtil.extName(avatarFile.getOriginalFilename()); | ||||||
|  |         String[] avatarSupportImgTypes = FileConstants.AVATAR_SUPPORTED_IMG_TYPES; | ||||||
|  |         CheckUtils.throwIf(() -> !StrUtil.equalsAnyIgnoreCase(avatarImageType, avatarSupportImgTypes), | ||||||
|  |             String.format("头像仅支持 %s 格式的图片", String.join(",", avatarSupportImgTypes))); | ||||||
|  |  | ||||||
|         // 上传新头像 |         // 上传新头像 | ||||||
|         String avatarPath = localStorageProperties.getPath().getAvatar(); |         String avatarPath = localStorageProperties.getPath().getAvatar(); | ||||||
|         File newAvatarFile = FileUtils.upload(avatarFile, avatarPath, false); |         File newAvatarFile = FileUtils.upload(avatarFile, avatarPath, false); | ||||||
| @@ -103,8 +112,9 @@ public class UserServiceImpl implements UserService { | |||||||
|     @Override |     @Override | ||||||
|     @Transactional(rollbackFor = Exception.class) |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public void updatePassword(String oldPassword, String newPassword, Long userId) { |     public void updatePassword(String oldPassword, String newPassword, Long userId) { | ||||||
|  |         CheckUtils.throwIfEqual(newPassword, oldPassword, "新密码不能与当前密码相同"); | ||||||
|         SysUser sysUser = this.getById(userId); |         SysUser sysUser = this.getById(userId); | ||||||
|         ValidationUtils.throwIfNotEqual(SecureUtils.md5Salt(oldPassword, userId.toString()), sysUser.getPassword(), |         CheckUtils.throwIfNotEqual(SecureUtils.md5Salt(oldPassword, userId.toString()), sysUser.getPassword(), | ||||||
|             "当前密码错误"); |             "当前密码错误"); | ||||||
|  |  | ||||||
|         // 更新密码和密码重置时间 |         // 更新密码和密码重置时间 | ||||||
| @@ -123,13 +133,12 @@ public class UserServiceImpl implements UserService { | |||||||
|     @Override |     @Override | ||||||
|     @Transactional(rollbackFor = Exception.class) |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public void updateEmail(String newEmail, String currentPassword, Long userId) { |     public void updateEmail(String newEmail, String currentPassword, Long userId) { | ||||||
|         // 校验 |  | ||||||
|         SysUser sysUser = this.getById(userId); |         SysUser sysUser = this.getById(userId); | ||||||
|         ValidationUtils.throwIfNotEqual(SecureUtils.md5Salt(currentPassword, userId.toString()), sysUser.getPassword(), |         CheckUtils.throwIfNotEqual(SecureUtils.md5Salt(currentPassword, userId.toString()), sysUser.getPassword(), | ||||||
|             "当前密码错误"); |             "当前密码错误"); | ||||||
|         Long count = userMapper.selectCount(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getEmail, newEmail)); |         Long count = userMapper.selectCount(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getEmail, newEmail)); | ||||||
|         ValidationUtils.throwIf(() -> count > 0, "邮箱已绑定其他账号,请更换其他邮箱"); |         CheckUtils.throwIf(() -> count > 0, "邮箱已绑定其他账号,请更换其他邮箱"); | ||||||
|         ValidationUtils.throwIfEqual(newEmail, sysUser.getEmail(), "新邮箱不能与当前邮箱相同"); |         CheckUtils.throwIfEqual(newEmail, sysUser.getEmail(), "新邮箱不能与当前邮箱相同"); | ||||||
|  |  | ||||||
|         // 更新邮箱 |         // 更新邮箱 | ||||||
|         userMapper.update(null, |         userMapper.update(null, | ||||||
| @@ -143,9 +152,8 @@ public class UserServiceImpl implements UserService { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public SysUser getById(Long userId) { |     public SysUser getById(Long userId) { | ||||||
|         ValidationUtils.throwIfNull(userId, "用户不存在"); |  | ||||||
|         SysUser sysUser = userMapper.selectById(userId); |         SysUser sysUser = userMapper.selectById(userId); | ||||||
|         ValidationUtils.throwIfNull(sysUser, String.format("ID为 [%s] 的用户已不存在", userId)); |         CheckUtils.throwIfNull(sysUser, String.format("ID为 [%s] 的用户已不存在", userId)); | ||||||
|         return sysUser; |         return sysUser; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -35,7 +35,6 @@ import top.charles7c.cnadmin.auth.model.request.LoginRequest; | |||||||
| import top.charles7c.cnadmin.auth.model.vo.LoginVO; | import top.charles7c.cnadmin.auth.model.vo.LoginVO; | ||||||
| import top.charles7c.cnadmin.auth.model.vo.UserInfoVO; | import top.charles7c.cnadmin.auth.model.vo.UserInfoVO; | ||||||
| import top.charles7c.cnadmin.auth.service.LoginService; | import top.charles7c.cnadmin.auth.service.LoginService; | ||||||
| import top.charles7c.cnadmin.common.config.properties.CaptchaProperties; |  | ||||||
| import top.charles7c.cnadmin.common.consts.CacheConstants; | import top.charles7c.cnadmin.common.consts.CacheConstants; | ||||||
| import top.charles7c.cnadmin.common.model.dto.LoginUser; | import top.charles7c.cnadmin.common.model.dto.LoginUser; | ||||||
| import top.charles7c.cnadmin.common.model.vo.R; | import top.charles7c.cnadmin.common.model.vo.R; | ||||||
| @@ -58,7 +57,6 @@ import top.charles7c.cnadmin.common.util.validate.ValidationUtils; | |||||||
| public class LoginController { | public class LoginController { | ||||||
|  |  | ||||||
|     private final LoginService loginService; |     private final LoginService loginService; | ||||||
|     private final CaptchaProperties captchaProperties; |  | ||||||
|  |  | ||||||
|     @SaIgnore |     @SaIgnore | ||||||
|     @Operation(summary = "用户登录", description = "根据用户名和密码进行登录认证") |     @Operation(summary = "用户登录", description = "根据用户名和密码进行登录认证") | ||||||
|   | |||||||
| @@ -47,7 +47,7 @@ import top.charles7c.cnadmin.common.consts.CacheConstants; | |||||||
| import top.charles7c.cnadmin.common.model.vo.CaptchaVO; | import top.charles7c.cnadmin.common.model.vo.CaptchaVO; | ||||||
| import top.charles7c.cnadmin.common.model.vo.R; | import top.charles7c.cnadmin.common.model.vo.R; | ||||||
| import top.charles7c.cnadmin.common.util.*; | import top.charles7c.cnadmin.common.util.*; | ||||||
| import top.charles7c.cnadmin.common.util.validate.ValidationUtils; | import top.charles7c.cnadmin.common.util.validate.CheckUtils; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 验证码 API |  * 验证码 API | ||||||
| @@ -89,12 +89,11 @@ public class CaptchaController { | |||||||
|     public R getMailCaptcha( |     public R getMailCaptcha( | ||||||
|         @NotBlank(message = "邮箱不能为空") @Pattern(regexp = RegexPool.EMAIL, message = "邮箱格式错误") String email) |         @NotBlank(message = "邮箱不能为空") @Pattern(regexp = RegexPool.EMAIL, message = "邮箱格式错误") String email) | ||||||
|         throws MessagingException { |         throws MessagingException { | ||||||
|         // 校验 |  | ||||||
|         String limitCacheKey = CacheConstants.LIMIT_CACHE_KEY; |         String limitCacheKey = CacheConstants.LIMIT_CACHE_KEY; | ||||||
|         String captchaCacheKey = CacheConstants.CAPTCHA_CACHE_KEY; |         String captchaCacheKey = CacheConstants.CAPTCHA_CACHE_KEY; | ||||||
|         String limitCaptchaKey = RedisUtils.formatKey(limitCacheKey, captchaCacheKey, email); |         String limitCaptchaKey = RedisUtils.formatKey(limitCacheKey, captchaCacheKey, email); | ||||||
|         long limitTimeInMillisecond = RedisUtils.getTimeToLive(limitCaptchaKey); |         long limitTimeInMillisecond = RedisUtils.getTimeToLive(limitCaptchaKey); | ||||||
|         ValidationUtils.throwIf(() -> limitTimeInMillisecond > 0, |         CheckUtils.throwIf(() -> limitTimeInMillisecond > 0, | ||||||
|             String.format("发送邮箱验证码过于频繁,请您 %ds 后再试", limitTimeInMillisecond / 1000)); |             String.format("发送邮箱验证码过于频繁,请您 %ds 后再试", limitTimeInMillisecond / 1000)); | ||||||
|  |  | ||||||
|         // 生成验证码 |         // 生成验证码 | ||||||
|   | |||||||
| @@ -43,7 +43,6 @@ import top.charles7c.cnadmin.system.service.DeptService; | |||||||
|  * @since 2023/1/22 21:48 |  * @since 2023/1/22 21:48 | ||||||
|  */ |  */ | ||||||
| @Tag(name = "公共 API") | @Tag(name = "公共 API") | ||||||
| @Validated |  | ||||||
| @RestController | @RestController | ||||||
| @RequiredArgsConstructor | @RequiredArgsConstructor | ||||||
| @RequestMapping(value = "/common", produces = MediaType.APPLICATION_JSON_VALUE) | @RequestMapping(value = "/common", produces = MediaType.APPLICATION_JSON_VALUE) | ||||||
| @@ -51,7 +50,7 @@ public class CommonController { | |||||||
|  |  | ||||||
|     private final DeptService deptService; |     private final DeptService deptService; | ||||||
|  |  | ||||||
|     @Operation(summary = "查询部门树") |     @Operation(summary = "查询部门树", description = "查询树结构的部门列表") | ||||||
|     @GetMapping("/tree/dept") |     @GetMapping("/tree/dept") | ||||||
|     public R<List<Tree<Long>>> deptTree(@Validated DeptQuery query) { |     public R<List<Tree<Long>>> deptTree(@Validated DeptQuery query) { | ||||||
|         List<DeptVO> list = deptService.list(query); |         List<DeptVO> list = deptService.list(query); | ||||||
|   | |||||||
| @@ -47,7 +47,6 @@ import top.charles7c.cnadmin.monitor.service.LogService; | |||||||
|  * @since 2023/1/18 23:55 |  * @since 2023/1/18 23:55 | ||||||
|  */ |  */ | ||||||
| @Tag(name = "日志管理 API") | @Tag(name = "日志管理 API") | ||||||
| @Validated |  | ||||||
| @RestController | @RestController | ||||||
| @RequiredArgsConstructor | @RequiredArgsConstructor | ||||||
| @RequestMapping(value = "/monitor/log", produces = MediaType.APPLICATION_JSON_VALUE) | @RequestMapping(value = "/monitor/log", produces = MediaType.APPLICATION_JSON_VALUE) | ||||||
|   | |||||||
| @@ -43,7 +43,7 @@ import top.charles7c.cnadmin.common.model.dto.LoginUser; | |||||||
| import top.charles7c.cnadmin.common.model.query.PageQuery; | import top.charles7c.cnadmin.common.model.query.PageQuery; | ||||||
| import top.charles7c.cnadmin.common.model.vo.PageInfo; | import top.charles7c.cnadmin.common.model.vo.PageInfo; | ||||||
| import top.charles7c.cnadmin.common.model.vo.R; | import top.charles7c.cnadmin.common.model.vo.R; | ||||||
| import top.charles7c.cnadmin.common.util.validate.ValidationUtils; | import top.charles7c.cnadmin.common.util.validate.CheckUtils; | ||||||
| import top.charles7c.cnadmin.monitor.model.query.OnlineUserQuery; | import top.charles7c.cnadmin.monitor.model.query.OnlineUserQuery; | ||||||
| import top.charles7c.cnadmin.monitor.model.vo.*; | import top.charles7c.cnadmin.monitor.model.vo.*; | ||||||
|  |  | ||||||
| @@ -54,7 +54,6 @@ import top.charles7c.cnadmin.monitor.model.vo.*; | |||||||
|  * @since 2023/1/20 21:51 |  * @since 2023/1/20 21:51 | ||||||
|  */ |  */ | ||||||
| @Tag(name = "在线用户 API") | @Tag(name = "在线用户 API") | ||||||
| @Validated |  | ||||||
| @RestController | @RestController | ||||||
| @RequiredArgsConstructor | @RequiredArgsConstructor | ||||||
| @RequestMapping(value = "/monitor/online/user", produces = MediaType.APPLICATION_JSON_VALUE) | @RequestMapping(value = "/monitor/online/user", produces = MediaType.APPLICATION_JSON_VALUE) | ||||||
| @@ -67,7 +66,7 @@ public class OnlineUserController { | |||||||
|         List<String> tokenKeyList = StpUtil.searchTokenValue("", 0, -1, false); |         List<String> tokenKeyList = StpUtil.searchTokenValue("", 0, -1, false); | ||||||
|         for (String tokenKey : tokenKeyList) { |         for (String tokenKey : tokenKeyList) { | ||||||
|             String token = StrUtil.subAfter(tokenKey, ":", true); |             String token = StrUtil.subAfter(tokenKey, ":", true); | ||||||
|             // 忽略已过期或失效 token |             // 忽略已过期或失效 Token | ||||||
|             if (StpUtil.stpLogic.getTokenActivityTimeoutByToken(token) < SaTokenDao.NEVER_EXPIRE) { |             if (StpUtil.stpLogic.getTokenActivityTimeoutByToken(token) < SaTokenDao.NEVER_EXPIRE) { | ||||||
|                 continue; |                 continue; | ||||||
|             } |             } | ||||||
| @@ -118,7 +117,7 @@ public class OnlineUserController { | |||||||
|     @DeleteMapping("/{token}") |     @DeleteMapping("/{token}") | ||||||
|     public R kickout(@PathVariable String token) { |     public R kickout(@PathVariable String token) { | ||||||
|         String currentToken = StpUtil.getTokenValue(); |         String currentToken = StpUtil.getTokenValue(); | ||||||
|         ValidationUtils.throwIfEqual(token, currentToken, "不能强退当前登录"); |         CheckUtils.throwIfEqual(token, currentToken, "不能强退当前登录"); | ||||||
|  |  | ||||||
|         StpUtil.kickoutByTokenValue(token); |         StpUtil.kickoutByTokenValue(token); | ||||||
|         return R.ok("强退成功"); |         return R.ok("强退成功"); | ||||||
|   | |||||||
| @@ -43,7 +43,6 @@ import top.charles7c.cnadmin.system.service.DeptService; | |||||||
|  * @since 2023/1/22 17:50 |  * @since 2023/1/22 17:50 | ||||||
|  */ |  */ | ||||||
| @Tag(name = "部门管理 API") | @Tag(name = "部门管理 API") | ||||||
| @Validated |  | ||||||
| @RestController | @RestController | ||||||
| @RequiredArgsConstructor | @RequiredArgsConstructor | ||||||
| @RequestMapping(value = "/system/dept", produces = MediaType.APPLICATION_JSON_VALUE) | @RequestMapping(value = "/system/dept", produces = MediaType.APPLICATION_JSON_VALUE) | ||||||
| @@ -61,17 +60,12 @@ public class DeptController { | |||||||
|     @Operation(summary = "新增部门") |     @Operation(summary = "新增部门") | ||||||
|     @PostMapping |     @PostMapping | ||||||
|     public R<Long> create(@Validated @RequestBody CreateDeptRequest request) { |     public R<Long> create(@Validated @RequestBody CreateDeptRequest request) { | ||||||
|         // 校验 |         Long id = deptService.create(request); | ||||||
|         String deptName = request.getDeptName(); |         return R.ok("新增成功", id); | ||||||
|         boolean isExist = deptService.checkDeptNameExist(deptName, request.getParentId(), null); |  | ||||||
|         if (isExist) { |  | ||||||
|             return R.fail(String.format("新增失败,'%s'已存在", deptName)); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return R.ok("新增成功", deptService.create(request)); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Operation(summary = "修改部门状态") |     @Operation(summary = "修改部门状态") | ||||||
|  |     @Parameter(name = "ids", description = "ID 列表", in = ParameterIn.PATH) | ||||||
|     @PatchMapping("/{ids}") |     @PatchMapping("/{ids}") | ||||||
|     public R updateStatus(@PathVariable List<Long> ids, @Validated @RequestBody UpdateStatusRequest request) { |     public R updateStatus(@PathVariable List<Long> ids, @Validated @RequestBody UpdateStatusRequest request) { | ||||||
|         deptService.updateStatus(ids, request.getStatus()); |         deptService.updateStatus(ids, request.getStatus()); | ||||||
|   | |||||||
| @@ -29,13 +29,9 @@ import org.springframework.web.bind.annotation.*; | |||||||
| import org.springframework.web.multipart.MultipartFile; | import org.springframework.web.multipart.MultipartFile; | ||||||
|  |  | ||||||
| import cn.hutool.core.bean.BeanUtil; | import cn.hutool.core.bean.BeanUtil; | ||||||
| import cn.hutool.core.io.file.FileNameUtil; |  | ||||||
| import cn.hutool.core.util.ReUtil; | import cn.hutool.core.util.ReUtil; | ||||||
| import cn.hutool.core.util.StrUtil; |  | ||||||
|  |  | ||||||
| import top.charles7c.cnadmin.common.config.properties.LocalStorageProperties; |  | ||||||
| import top.charles7c.cnadmin.common.consts.CacheConstants; | import top.charles7c.cnadmin.common.consts.CacheConstants; | ||||||
| import top.charles7c.cnadmin.common.consts.FileConstants; |  | ||||||
| import top.charles7c.cnadmin.common.consts.RegExpConstants; | import top.charles7c.cnadmin.common.consts.RegExpConstants; | ||||||
| import top.charles7c.cnadmin.common.model.vo.R; | import top.charles7c.cnadmin.common.model.vo.R; | ||||||
| import top.charles7c.cnadmin.common.util.ExceptionUtils; | import top.charles7c.cnadmin.common.util.ExceptionUtils; | ||||||
| @@ -64,20 +60,11 @@ import top.charles7c.cnadmin.system.service.UserService; | |||||||
| public class UserCenterController { | public class UserCenterController { | ||||||
|  |  | ||||||
|     private final UserService userService; |     private final UserService userService; | ||||||
|     private final LocalStorageProperties localStorageProperties; |  | ||||||
|  |  | ||||||
|     @Operation(summary = "上传头像", description = "用户上传个人头像") |     @Operation(summary = "上传头像", description = "用户上传个人头像") | ||||||
|     @PostMapping("/avatar") |     @PostMapping("/avatar") | ||||||
|     public R<AvatarVO> uploadAvatar(@NotNull(message = "头像不能为空") MultipartFile avatarFile) { |     public R<AvatarVO> uploadAvatar(@NotNull(message = "头像不能为空") MultipartFile avatarFile) { | ||||||
|         // 校验 |  | ||||||
|         ValidationUtils.throwIf(avatarFile::isEmpty, "头像不能为空"); |         ValidationUtils.throwIf(avatarFile::isEmpty, "头像不能为空"); | ||||||
|         Long avatarMaxSizeInMb = localStorageProperties.getAvatarMaxSizeInMb(); |  | ||||||
|         ValidationUtils.throwIf(() -> avatarFile.getSize() > avatarMaxSizeInMb * 1024 * 1024, |  | ||||||
|             String.format("请上传小于 %s MB 的图片", avatarMaxSizeInMb)); |  | ||||||
|         String avatarImageType = FileNameUtil.extName(avatarFile.getOriginalFilename()); |  | ||||||
|         String[] avatarSupportImgTypes = FileConstants.AVATAR_SUPPORTED_IMG_TYPES; |  | ||||||
|         ValidationUtils.throwIf(() -> !StrUtil.equalsAnyIgnoreCase(avatarImageType, avatarSupportImgTypes), |  | ||||||
|             String.format("头像仅支持 %s 格式的图片", String.join(",", avatarSupportImgTypes))); |  | ||||||
|  |  | ||||||
|         // 上传头像 |         // 上传头像 | ||||||
|         String newAvatar = userService.uploadAvatar(avatarFile, LoginHelper.getUserId()); |         String newAvatar = userService.uploadAvatar(avatarFile, LoginHelper.getUserId()); | ||||||
| @@ -97,18 +84,14 @@ public class UserCenterController { | |||||||
|     @Operation(summary = "修改密码", description = "修改用户登录密码") |     @Operation(summary = "修改密码", description = "修改用户登录密码") | ||||||
|     @PatchMapping("/password") |     @PatchMapping("/password") | ||||||
|     public R updatePassword(@Validated @RequestBody UpdatePasswordRequest updatePasswordRequest) { |     public R updatePassword(@Validated @RequestBody UpdatePasswordRequest updatePasswordRequest) { | ||||||
|         // 解密 |  | ||||||
|         String rawOldPassword = |         String rawOldPassword = | ||||||
|             ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updatePasswordRequest.getOldPassword())); |             ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updatePasswordRequest.getOldPassword())); | ||||||
|         ValidationUtils.throwIfBlank(rawOldPassword, "当前密码解密失败"); |         ValidationUtils.throwIfBlank(rawOldPassword, "当前密码解密失败"); | ||||||
|         String rawNewPassword = |         String rawNewPassword = | ||||||
|             ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updatePasswordRequest.getNewPassword())); |             ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updatePasswordRequest.getNewPassword())); | ||||||
|         ValidationUtils.throwIfBlank(rawNewPassword, "新密码解密失败"); |         ValidationUtils.throwIfBlank(rawNewPassword, "新密码解密失败"); | ||||||
|  |  | ||||||
|         // 校验 |  | ||||||
|         ValidationUtils.throwIf(() -> !ReUtil.isMatch(RegExpConstants.PASSWORD, rawNewPassword), |         ValidationUtils.throwIf(() -> !ReUtil.isMatch(RegExpConstants.PASSWORD, rawNewPassword), | ||||||
|             "密码长度 6 到 32 位,同时包含数字和字母"); |             "密码长度 6 到 32 位,同时包含数字和字母"); | ||||||
|         ValidationUtils.throwIfEqual(rawNewPassword, rawOldPassword, "新密码不能与当前密码相同"); |  | ||||||
|  |  | ||||||
|         // 修改密码 |         // 修改密码 | ||||||
|         userService.updatePassword(rawOldPassword, rawNewPassword, LoginHelper.getUserId()); |         userService.updatePassword(rawOldPassword, rawNewPassword, LoginHelper.getUserId()); | ||||||
| @@ -118,12 +101,11 @@ public class UserCenterController { | |||||||
|     @Operation(summary = "修改邮箱", description = "修改用户邮箱") |     @Operation(summary = "修改邮箱", description = "修改用户邮箱") | ||||||
|     @PatchMapping("/email") |     @PatchMapping("/email") | ||||||
|     public R updateEmail(@Validated @RequestBody UpdateEmailRequest updateEmailRequest) { |     public R updateEmail(@Validated @RequestBody UpdateEmailRequest updateEmailRequest) { | ||||||
|         // 解密 |  | ||||||
|         String rawCurrentPassword = |         String rawCurrentPassword = | ||||||
|             ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updateEmailRequest.getCurrentPassword())); |             ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updateEmailRequest.getCurrentPassword())); | ||||||
|         ValidationUtils.throwIfBlank(rawCurrentPassword, "当前密码解密失败"); |         ValidationUtils.throwIfBlank(rawCurrentPassword, "当前密码解密失败"); | ||||||
|  |  | ||||||
|         // 校验 |         // 校验验证码 | ||||||
|         String captchaKey = RedisUtils.formatKey(CacheConstants.CAPTCHA_CACHE_KEY, updateEmailRequest.getNewEmail()); |         String captchaKey = RedisUtils.formatKey(CacheConstants.CAPTCHA_CACHE_KEY, updateEmailRequest.getNewEmail()); | ||||||
|         String captcha = RedisUtils.getCacheObject(captchaKey); |         String captcha = RedisUtils.getCacheObject(captchaKey); | ||||||
|         ValidationUtils.throwIfBlank(captcha, "验证码已失效"); |         ValidationUtils.throwIfBlank(captcha, "验证码已失效"); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user