From 94b093e9d41034feb5d0dadf09eda16818a8d02b Mon Sep 17 00:00:00 2001 From: King <1306086303@qq.com> Date: Thu, 20 Mar 2025 02:43:21 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=B3=A8=E5=86=8C=EF=BC=8C=E5=BF=98=E8=AE=B0=E5=AF=86=E7=A0=81?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=EF=BC=8C=E4=BF=AE=E5=A4=8D=E7=AC=AC=E4=B8=89?= =?UTF-8?q?=E6=96=B9=E6=B3=A8=E5=86=8C=E9=BB=98=E8=AE=A4=E6=9D=83=E9=99=90?= =?UTF-8?q?=E5=92=8C=E5=88=A0=E9=99=A4=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/properties/CaptchaProperties.java | 5 ++ .../admin/common/constant/SysConstants.java | 5 ++ .../auth/handler/AccountLoginHandler.java | 1 + .../admin/auth/handler/EmailLoginHandler.java | 23 +++++-- .../admin/auth/handler/PhoneLoginHandler.java | 24 ++++++-- .../auth/handler/SocialLoginHandler.java | 3 +- .../admin/auth/model/req/PhoneLoginReq.java | 4 +- .../admin/system/mapper/user/UserMapper.java | 2 +- .../system/mapper/user/UserSocialMapper.java | 1 + .../model/req/user/UserPasswordUpdateReq.java | 29 +++++++++ .../model/req/user/UserPhoneUpdateReq.java | 4 +- .../admin/system/model/req/user/UserReq.java | 15 ++++- .../system/service/UserSocialService.java | 7 +++ .../system/service/impl/UserServiceImpl.java | 19 ++++-- .../service/impl/UserSocialServiceImpl.java | 4 ++ .../admin/ContiNewAdminApplication.java | 2 + .../controller/system/UserController.java | 60 +++++++++++++++++-- .../main/resources/config/application-dev.yml | 8 ++- .../db/changelog/mysql/main_data.sql | 5 +- .../db/changelog/postgresql/main_data.sql | 5 +- 20 files changed, 193 insertions(+), 33 deletions(-) diff --git a/continew-common/src/main/java/top/continew/admin/common/config/properties/CaptchaProperties.java b/continew-common/src/main/java/top/continew/admin/common/config/properties/CaptchaProperties.java index 51870c56..65e39ef3 100644 --- a/continew-common/src/main/java/top/continew/admin/common/config/properties/CaptchaProperties.java +++ b/continew-common/src/main/java/top/continew/admin/common/config/properties/CaptchaProperties.java @@ -74,6 +74,11 @@ public class CaptchaProperties { */ @Data public static class CaptchaSms { + /** + * 万能验证码 + */ + private String code; + /** * 内容长度 */ diff --git a/continew-common/src/main/java/top/continew/admin/common/constant/SysConstants.java b/continew-common/src/main/java/top/continew/admin/common/constant/SysConstants.java index 509be74d..c25eb7ce 100644 --- a/continew-common/src/main/java/top/continew/admin/common/constant/SysConstants.java +++ b/continew-common/src/main/java/top/continew/admin/common/constant/SysConstants.java @@ -54,6 +54,11 @@ public class SysConstants { */ public static final String SUPER_ROLE_CODE = "admin"; + /** + * 普通角色编码 + */ + public static final String GENERAL_ROLE_CODE = "general"; + /** * 超管角色 ID */ diff --git a/continew-module-system/src/main/java/top/continew/admin/auth/handler/AccountLoginHandler.java b/continew-module-system/src/main/java/top/continew/admin/auth/handler/AccountLoginHandler.java index 04d2f1b3..2da02545 100644 --- a/continew-module-system/src/main/java/top/continew/admin/auth/handler/AccountLoginHandler.java +++ b/continew-module-system/src/main/java/top/continew/admin/auth/handler/AccountLoginHandler.java @@ -60,6 +60,7 @@ public class AccountLoginHandler extends AbstractLoginHandler { // 验证用户名密码 String username = req.getUsername(); UserDO user = userService.getByUsername(username); + ValidationUtils.throwIfNull(user, "用户不存在"); boolean isError = ObjectUtil.isNull(user) || !passwordEncoder.matches(rawPassword, user.getPassword()); // 检查账号锁定状态 this.checkUserLocked(req.getUsername(), request, isError); diff --git a/continew-module-system/src/main/java/top/continew/admin/auth/handler/EmailLoginHandler.java b/continew-module-system/src/main/java/top/continew/admin/auth/handler/EmailLoginHandler.java index f1f74990..5b1027d7 100644 --- a/continew-module-system/src/main/java/top/continew/admin/auth/handler/EmailLoginHandler.java +++ b/continew-module-system/src/main/java/top/continew/admin/auth/handler/EmailLoginHandler.java @@ -17,11 +17,14 @@ package top.continew.admin.auth.handler; import jakarta.servlet.http.HttpServletRequest; +import jodd.util.StringUtil; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import top.continew.admin.auth.AbstractLoginHandler; import top.continew.admin.auth.enums.AuthTypeEnum; import top.continew.admin.auth.model.req.EmailLoginReq; import top.continew.admin.auth.model.resp.LoginResp; +import top.continew.admin.common.config.properties.CaptchaProperties; import top.continew.admin.common.constant.CacheConstants; import top.continew.admin.system.model.entity.user.UserDO; import top.continew.admin.system.model.resp.ClientResp; @@ -36,7 +39,9 @@ import top.continew.starter.core.validation.ValidationUtils; * @since 2024/12/22 14:58 */ @Component +@RequiredArgsConstructor public class EmailLoginHandler extends AbstractLoginHandler { + private final CaptchaProperties captchaProperties; @Override public LoginResp login(EmailLoginReq req, ClientResp client, HttpServletRequest request) { @@ -53,11 +58,19 @@ public class EmailLoginHandler extends AbstractLoginHandler { @Override public void preLogin(EmailLoginReq req, ClientResp client, HttpServletRequest request) { String email = req.getEmail(); - String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + email; - String captcha = RedisUtils.get(captchaKey); - ValidationUtils.throwIfBlank(captcha, CAPTCHA_EXPIRED); - ValidationUtils.throwIfNotEqualIgnoreCase(req.getCaptcha(), captcha, CAPTCHA_ERROR); - RedisUtils.delete(captchaKey); + // String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + email; + // String captcha = RedisUtils.get(captchaKey); + // ValidationUtils.throwIfBlank(captcha, CAPTCHA_EXPIRED); + // ValidationUtils.throwIfNotEqualIgnoreCase(req.getCaptcha(), captcha, CAPTCHA_ERROR); + // RedisUtils.delete(captchaKey); + String captcha = req.getCaptcha(); + if (!StringUtil.equals(captcha, captchaProperties.getSms().getCode())) { + String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + email; + String captcha1 = RedisUtils.get(captchaKey); + ValidationUtils.throwIfBlank(captcha, CAPTCHA_EXPIRED); + ValidationUtils.throwIfNotEqualIgnoreCase(captcha1, captcha, CAPTCHA_ERROR); + RedisUtils.delete(captchaKey); + } } @Override diff --git a/continew-module-system/src/main/java/top/continew/admin/auth/handler/PhoneLoginHandler.java b/continew-module-system/src/main/java/top/continew/admin/auth/handler/PhoneLoginHandler.java index 7f9e673f..0139e8c4 100644 --- a/continew-module-system/src/main/java/top/continew/admin/auth/handler/PhoneLoginHandler.java +++ b/continew-module-system/src/main/java/top/continew/admin/auth/handler/PhoneLoginHandler.java @@ -17,11 +17,14 @@ package top.continew.admin.auth.handler; import jakarta.servlet.http.HttpServletRequest; +import jodd.util.StringUtil; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import top.continew.admin.auth.AbstractLoginHandler; import top.continew.admin.auth.enums.AuthTypeEnum; import top.continew.admin.auth.model.req.PhoneLoginReq; import top.continew.admin.auth.model.resp.LoginResp; +import top.continew.admin.common.config.properties.CaptchaProperties; import top.continew.admin.common.constant.CacheConstants; import top.continew.admin.system.model.entity.user.UserDO; import top.continew.admin.system.model.resp.ClientResp; @@ -36,8 +39,11 @@ import top.continew.starter.core.validation.ValidationUtils; * @since 2024/12/22 14:59 */ @Component +@RequiredArgsConstructor public class PhoneLoginHandler extends AbstractLoginHandler { + private final CaptchaProperties captchaProperties; + @Override public LoginResp login(PhoneLoginReq req, ClientResp client, HttpServletRequest request) { // 验证手机号 @@ -53,11 +59,19 @@ public class PhoneLoginHandler extends AbstractLoginHandler { @Override public void preLogin(PhoneLoginReq req, ClientResp client, HttpServletRequest request) { String phone = req.getPhone(); - String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + phone; - String captcha = RedisUtils.get(captchaKey); - ValidationUtils.throwIfBlank(captcha, CAPTCHA_EXPIRED); - ValidationUtils.throwIfNotEqualIgnoreCase(req.getCaptcha(), captcha, CAPTCHA_ERROR); - RedisUtils.delete(captchaKey); + // String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + phone; + // String captcha = RedisUtils.get(captchaKey); + // ValidationUtils.throwIfBlank(captcha, CAPTCHA_EXPIRED); + // ValidationUtils.throwIfNotEqualIgnoreCase(req.getCaptcha(), captcha, CAPTCHA_ERROR); + // RedisUtils.delete(captchaKey); + String captcha = req.getCaptcha(); + if (!StringUtil.equals(captcha, captchaProperties.getSms().getCode())) { + String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + phone; + String captcha1 = RedisUtils.get(captchaKey); + ValidationUtils.throwIfBlank(captcha1, CAPTCHA_EXPIRED); + ValidationUtils.throwIfNotEqualIgnoreCase(captcha, captcha1, CAPTCHA_ERROR); + RedisUtils.delete(captchaKey); + } } @Override diff --git a/continew-module-system/src/main/java/top/continew/admin/auth/handler/SocialLoginHandler.java b/continew-module-system/src/main/java/top/continew/admin/auth/handler/SocialLoginHandler.java index c7e33b6d..3b6864c8 100644 --- a/continew-module-system/src/main/java/top/continew/admin/auth/handler/SocialLoginHandler.java +++ b/continew-module-system/src/main/java/top/continew/admin/auth/handler/SocialLoginHandler.java @@ -110,7 +110,8 @@ public class SocialLoginHandler extends AbstractLoginHandler { user.setStatus(DisEnableStatusEnum.ENABLE); userService.save(user); Long userId = user.getId(); - RoleDO role = roleService.getByCode(SysConstants.SUPER_ROLE_CODE); +// RoleDO role = roleService.getByCode(SysConstants.SUPER_ROLE_CODE); + RoleDO role = roleService.getByCode(SysConstants.GENERAL_ROLE_CODE); userRoleService.assignRolesToUser(Collections.singletonList(role.getId()), userId); userSocial = new UserSocialDO(); userSocial.setUserId(userId); diff --git a/continew-module-system/src/main/java/top/continew/admin/auth/model/req/PhoneLoginReq.java b/continew-module-system/src/main/java/top/continew/admin/auth/model/req/PhoneLoginReq.java index 260cec22..1aa299dd 100644 --- a/continew-module-system/src/main/java/top/continew/admin/auth/model/req/PhoneLoginReq.java +++ b/continew-module-system/src/main/java/top/continew/admin/auth/model/req/PhoneLoginReq.java @@ -49,8 +49,8 @@ public class PhoneLoginReq extends LoginReq { /** * 验证码 */ - @Schema(description = "验证码", example = "8888") + @Schema(description = "验证码", example = "888888") @NotBlank(message = "验证码不能为空") - @Length(max = 4, message = "验证码非法") + @Length(max = 6, message = "验证码非法") private String captcha; } diff --git a/continew-module-system/src/main/java/top/continew/admin/system/mapper/user/UserMapper.java b/continew-module-system/src/main/java/top/continew/admin/system/mapper/user/UserMapper.java index 8bf487bb..66379253 100644 --- a/continew-module-system/src/main/java/top/continew/admin/system/mapper/user/UserMapper.java +++ b/continew-module-system/src/main/java/top/continew/admin/system/mapper/user/UserMapper.java @@ -63,7 +63,7 @@ public interface UserMapper extends DataPermissionMapper { * @param username 用户名 * @return 用户信息 */ - @Select("SELECT * FROM sys_user WHERE username = #{username}") + @Select("SELECT * FROM sys_user WHERE username =#{username} OR nickname = #{username}") UserDO selectByUsername(@Param("username") String username); /** diff --git a/continew-module-system/src/main/java/top/continew/admin/system/mapper/user/UserSocialMapper.java b/continew-module-system/src/main/java/top/continew/admin/system/mapper/user/UserSocialMapper.java index 954c0204..8ae3d12a 100644 --- a/continew-module-system/src/main/java/top/continew/admin/system/mapper/user/UserSocialMapper.java +++ b/continew-module-system/src/main/java/top/continew/admin/system/mapper/user/UserSocialMapper.java @@ -16,6 +16,7 @@ package top.continew.admin.system.mapper.user; +import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import top.continew.admin.system.model.entity.user.UserSocialDO; import top.continew.starter.data.mp.base.BaseMapper; diff --git a/continew-module-system/src/main/java/top/continew/admin/system/model/req/user/UserPasswordUpdateReq.java b/continew-module-system/src/main/java/top/continew/admin/system/model/req/user/UserPasswordUpdateReq.java index d2acdf1f..d2688e8a 100644 --- a/continew-module-system/src/main/java/top/continew/admin/system/model/req/user/UserPasswordUpdateReq.java +++ b/continew-module-system/src/main/java/top/continew/admin/system/model/req/user/UserPasswordUpdateReq.java @@ -16,9 +16,13 @@ package top.continew.admin.system.model.req.user; +import cn.hutool.core.lang.RegexPool; +import org.hibernate.validator.constraints.Length; +import top.continew.admin.common.constant.RegexConstants; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import lombok.Data; +import jakarta.validation.constraints.Pattern; import java.io.Serial; import java.io.Serializable; @@ -36,10 +40,35 @@ public class UserPasswordUpdateReq implements Serializable { @Serial private static final long serialVersionUID = 1L; + /** + * 用户名 + */ + @Schema(description = "用户名", example = "zhangsan") + // @NotBlank(message = "用户名不能为空") + @Pattern(regexp = RegexConstants.GENERAL_NAME, message = "用户名长度为 2-30 个字符,支持中文、字母、数字、下划线,短横线") + private String username; + + /** + * 邮箱 + */ + @Schema(description = "邮箱", example = "123456789@qq.com") + // @NotBlank(message = "邮箱不能为空") + @Pattern(regexp = RegexPool.EMAIL, message = "邮箱格式错误") + private String email; + + /** + * 验证码 + */ + @Schema(description = "验证码", example = "888888") + // @NotBlank(message = "验证码不能为空") + @Length(max = 6, message = "验证码非法") + private String captcha; + /** * 当前密码(加密) */ @Schema(description = "当前密码(加密)", example = "E7c72TH+LDxKTwavjM99W1MdI9Lljh79aPKiv3XB9MXcplhm7qJ1BJCj28yaflbdVbfc366klMtjLIWQGqb0qw==") +// @NotBlank(message = "当前密码不能为空") private String oldPassword; /** diff --git a/continew-module-system/src/main/java/top/continew/admin/system/model/req/user/UserPhoneUpdateReq.java b/continew-module-system/src/main/java/top/continew/admin/system/model/req/user/UserPhoneUpdateReq.java index c27b1184..5593d6e9 100644 --- a/continew-module-system/src/main/java/top/continew/admin/system/model/req/user/UserPhoneUpdateReq.java +++ b/continew-module-system/src/main/java/top/continew/admin/system/model/req/user/UserPhoneUpdateReq.java @@ -50,9 +50,9 @@ public class UserPhoneUpdateReq implements Serializable { /** * 验证码 */ - @Schema(description = "验证码", example = "8888") + @Schema(description = "验证码", example = "888888") @NotBlank(message = "验证码不能为空") - @Length(max = 4, message = "验证码非法") + @Length(max = 6, message = "验证码非法") private String captcha; /** diff --git a/continew-module-system/src/main/java/top/continew/admin/system/model/req/user/UserReq.java b/continew-module-system/src/main/java/top/continew/admin/system/model/req/user/UserReq.java index be7134c6..6756445b 100644 --- a/continew-module-system/src/main/java/top/continew/admin/system/model/req/user/UserReq.java +++ b/continew-module-system/src/main/java/top/continew/admin/system/model/req/user/UserReq.java @@ -48,7 +48,8 @@ public class UserReq implements Serializable { */ @Schema(description = "用户名", example = "zhangsan") @NotBlank(message = "用户名不能为空") - @Pattern(regexp = RegexConstants.USERNAME, message = "用户名长度为 4-64 个字符,支持大小写字母、数字、下划线,以字母开头") + // @Pattern(regexp = RegexConstants.USERNAME, message = "用户名长度为 4-64 个字符,支持大小写字母、数字、下划线,以字母开头") + @Pattern(regexp = RegexConstants.GENERAL_NAME, message = "用户名长度为 2-30 个字符,支持中文、字母、数字、下划线,短横线") private String username; /** @@ -115,4 +116,16 @@ public class UserReq implements Serializable { */ @Schema(description = "状态", example = "1") private DisEnableStatusEnum status; + + /** + * 验证码 + */ + @Schema(description = "验证码", example = "ABCD") + private String captcha; + + /** + * 验证码标识 + */ + @Schema(description = "验证码标识", example = "090b9a2c-1691-4fca-99db-e4ed0cff362f") + private String uuid; } diff --git a/continew-module-system/src/main/java/top/continew/admin/system/service/UserSocialService.java b/continew-module-system/src/main/java/top/continew/admin/system/service/UserSocialService.java index 86b41a19..a21a1f83 100644 --- a/continew-module-system/src/main/java/top/continew/admin/system/service/UserSocialService.java +++ b/continew-module-system/src/main/java/top/continew/admin/system/service/UserSocialService.java @@ -61,6 +61,13 @@ public interface UserSocialService { */ void bind(AuthUser authUser, Long userId); + /** + * 根据用户 ID 删除 + * + * @param userIds 用户 ID 列表 + */ + void deleteByUserIds(List userIds); + /** * 根据来源和用户 ID 删除 * diff --git a/continew-module-system/src/main/java/top/continew/admin/system/service/impl/UserServiceImpl.java b/continew-module-system/src/main/java/top/continew/admin/system/service/impl/UserServiceImpl.java index a0e036be..476f8dc6 100644 --- a/continew-module-system/src/main/java/top/continew/admin/system/service/impl/UserServiceImpl.java +++ b/continew-module-system/src/main/java/top/continew/admin/system/service/impl/UserServiceImpl.java @@ -116,6 +116,7 @@ public class UserServiceImpl extends BaseServiceImpl userIds) { + baseMapper.lambdaUpdate().in(UserSocialDO::getUserId, userIds).remove(); + } + @Override public void deleteBySourceAndUserId(String source, Long userId) { baseMapper.lambdaUpdate().eq(UserSocialDO::getSource, source).eq(UserSocialDO::getUserId, userId).remove(); diff --git a/continew-webapi/src/main/java/top/continew/admin/ContiNewAdminApplication.java b/continew-webapi/src/main/java/top/continew/admin/ContiNewAdminApplication.java index 99c5a9cd..b7c50ae7 100644 --- a/continew-webapi/src/main/java/top/continew/admin/ContiNewAdminApplication.java +++ b/continew-webapi/src/main/java/top/continew/admin/ContiNewAdminApplication.java @@ -26,6 +26,7 @@ import io.swagger.v3.oas.annotations.Hidden; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dromara.x.file.storage.spring.EnableFileStorage; +import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.boot.SpringApplication; @@ -52,6 +53,7 @@ import top.continew.starter.web.model.R; @RestController @SpringBootApplication @RequiredArgsConstructor +@MapperScan("top.continew.admin.system.mapper") public class ContiNewAdminApplication implements ApplicationRunner { private final ProjectProperties projectProperties; diff --git a/continew-webapi/src/main/java/top/continew/admin/controller/system/UserController.java b/continew-webapi/src/main/java/top/continew/admin/controller/system/UserController.java index 23b26c13..a5fdc37c 100644 --- a/continew-webapi/src/main/java/top/continew/admin/controller/system/UserController.java +++ b/continew-webapi/src/main/java/top/continew/admin/controller/system/UserController.java @@ -24,24 +24,26 @@ import io.swagger.v3.oas.annotations.enums.ParameterIn; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.constraints.NotNull; +import jodd.util.StringUtil; import lombok.RequiredArgsConstructor; import org.springframework.http.MediaType; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import top.continew.admin.common.config.properties.CaptchaProperties; +import top.continew.admin.common.constant.CacheConstants; import top.continew.admin.common.controller.BaseController; import top.continew.admin.common.constant.RegexConstants; import top.continew.admin.common.util.SecureUtils; +import top.continew.admin.system.model.entity.UserDO; import top.continew.admin.system.model.query.UserQuery; -import top.continew.admin.system.model.req.user.UserImportReq; -import top.continew.admin.system.model.req.user.UserPasswordResetReq; -import top.continew.admin.system.model.req.user.UserReq; -import top.continew.admin.system.model.req.user.UserRoleUpdateReq; +import top.continew.admin.system.model.req.user.*; import top.continew.admin.system.model.resp.user.UserDetailResp; import top.continew.admin.system.model.resp.user.UserImportParseResp; import top.continew.admin.system.model.resp.user.UserImportResp; import top.continew.admin.system.model.resp.user.UserResp; import top.continew.admin.system.service.UserService; +import top.continew.starter.cache.redisson.util.RedisUtils; import top.continew.starter.core.util.ExceptionUtils; import top.continew.starter.core.validation.ValidationUtils; import top.continew.starter.extension.crud.annotation.CrudRequestMapping; @@ -65,6 +67,56 @@ import java.io.IOException; Api.EXPORT}) public class UserController extends BaseController { + private final UserService userService; + private final CaptchaProperties captchaProperties; + + @Operation(summary = "用户注册", description = "用户注册") + @PostMapping(value = "/signup") + public BaseIdResp signup(@Validated(CrudValidationGroup.Add.class) @RequestBody UserReq req) { + String captcha = req.getCaptcha(); + if (!StringUtil.equals(captcha, captchaProperties.getSms().getCode())) { + String key = StringUtil.isNotBlank(req.getUuid()) + ? req.getUuid() + : StringUtil.isNotBlank(req.getPhone()) + ? req.getPhone() + : StringUtil.isNotBlank(req.getEmail()) ? req.getEmail() : ""; + ValidationUtils.throwIfBlank(captcha, "验证码不能为空"); + ValidationUtils.throwIfBlank(key, "验证码标识不能为空"); + String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + key; + String captcha1 = RedisUtils.get(captchaKey); + ValidationUtils.throwIfBlank(captcha1, "验证码已失效"); + ValidationUtils.throwIfNotEqualIgnoreCase(captcha, captcha1, "验证码错误"); + // RedisUtils.delete(captchaKey); + } + String rawPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(req.getPassword())); + ValidationUtils.throwIfNull(rawPassword, "密码解密失败"); + ValidationUtils.throwIf(!ReUtil + .isMatch(RegexConstants.PASSWORD, rawPassword), "密码长度为 8-32 个字符,支持大小写字母、数字、特殊字符,至少包含字母和数字"); + req.setPassword(rawPassword); + return super.add(req); + } + + @Operation(summary = "修改密码", description = "修改用户登录密码") + @PostMapping("/password") + public void updatePassword(@Validated @RequestBody UserPasswordUpdateReq updateReq) { + String captcha = updateReq.getCaptcha(); + if (!StringUtil.equals(captcha, captchaProperties.getSms().getCode())) { + String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + updateReq.getEmail(); + String captcha1 = RedisUtils.get(captchaKey); + ValidationUtils.throwIfBlank(captcha1, "验证码已失效"); + ValidationUtils.throwIfNotEqualIgnoreCase(captcha, captcha1, "验证码错误"); + RedisUtils.delete(captchaKey); + } + String newPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updateReq + .getNewPassword())); + ValidationUtils.throwIfNull(newPassword, "新密码解密失败"); + ValidationUtils.throwIf(!ReUtil + .isMatch(RegexConstants.PASSWORD, newPassword), "密码长度为 8-32 个字符,支持大小写字母、数字、特殊字符,至少包含字母和数字"); + UserDO user = userService.getByUsername(updateReq.getUsername()); + ValidationUtils.throwIfEmpty(user, "用户名错误或不存在"); + userService.updatePassword("", newPassword, user.getId()); + } + @Override @Operation(summary = "新增数据", description = "新增数据") public BaseIdResp add(@Validated(CrudValidationGroup.Add.class) @RequestBody UserReq req) { diff --git a/continew-webapi/src/main/resources/config/application-dev.yml b/continew-webapi/src/main/resources/config/application-dev.yml index 4cfb76e0..6387d601 100644 --- a/continew-webapi/src/main/resources/config/application-dev.yml +++ b/continew-webapi/src/main/resources/config/application-dev.yml @@ -12,7 +12,7 @@ server: spring.datasource: type: com.zaxxer.hikari.HikariDataSource # 请务必提前创建好名为 continew_admin 的数据库,如果使用其他数据库名请注意同步修改 DB_NAME 配置 - url: jdbc:p6spy:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:continew_admin}?serverTimezone=Asia/Shanghai&useSSL=true&useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&autoReconnect=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true + url: jdbc:p6spy:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:continew_admin}?serverTimezone=Asia/Shanghai&useSSL=true&useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&autoReconnect=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&maxReconnects=10&failOverReadOnly=false username: ${DB_USER:root} password: ${DB_PWD:123456} driver-class-name: com.p6spy.engine.spy.P6SpyDriver @@ -126,8 +126,10 @@ captcha: templatePath: mail/captcha.ftl ## 短信验证码配置 sms: + # 万能验证码(限调试时使用) + code: 111111 # 内容长度 - length: 4 + length: 6 # 过期时间 expirationInMinutes: 5 # 模板 ID @@ -232,6 +234,8 @@ sa-token.extension: - /swagger-ui/** - /swagger-resources/** - /*/api-docs/** + - /system/user/signup + - /system/user/password # 本地存储资源 - /file/** diff --git a/continew-webapi/src/main/resources/db/changelog/mysql/main_data.sql b/continew-webapi/src/main/resources/db/changelog/mysql/main_data.sql index 1737f462..15121136 100644 --- a/continew-webapi/src/main/resources/db/changelog/mysql/main_data.sql +++ b/continew-webapi/src/main/resources/db/changelog/mysql/main_data.sql @@ -156,8 +156,9 @@ INSERT INTO `sys_role` (`id`, `name`, `code`, `data_scope`, `description`, `sort`, `is_system`, `create_user`, `create_time`) VALUES (1, '系统管理员', 'admin', 1, '系统初始角色', 1, b'1', 1, NOW()), -(547888897925840927, '测试人员', 'tester', 5, NULL, 2, b'0', 1, NOW()), -(547888897925840928, '研发人员', 'developer', 4, NULL, 3, b'0', 1, NOW()); +(2, '普通用户', 'general', 4, '系统初始角色', 2, b'0', 1, NOW()), +(547888897925840927, '测试人员', 'tester', 5, NULL, 3, b'0', 1, NOW()), +(547888897925840928, '研发人员', 'developer', 4, NULL, 4, b'0', 1, NOW()); -- 初始化默认用户:admin/admin123;test/test123 INSERT INTO `sys_user` diff --git a/continew-webapi/src/main/resources/db/changelog/postgresql/main_data.sql b/continew-webapi/src/main/resources/db/changelog/postgresql/main_data.sql index 30aa9b70..d807e599 100644 --- a/continew-webapi/src/main/resources/db/changelog/postgresql/main_data.sql +++ b/continew-webapi/src/main/resources/db/changelog/postgresql/main_data.sql @@ -156,8 +156,9 @@ INSERT INTO "sys_role" ("id", "name", "code", "data_scope", "description", "sort", "is_system", "create_user", "create_time") VALUES (1, '系统管理员', 'admin', 1, '系统初始角色', 1, true, 1, NOW()), -(547888897925840927, '测试人员', 'tester', 5, NULL, 2, false, 1, NOW()), -(547888897925840928, '研发人员', 'developer', 4, NULL, 3, false, 1, NOW()); +(2, '普通用户', 'general', 4, '系统初始角色', 2, false, 1, NOW()), +(547888897925840927, '测试人员', 'tester', 5, NULL, 3, false, 1, NOW()), +(547888897925840928, '研发人员', 'developer', 4, NULL, 4, false, 1, NOW()); -- 初始化默认用户:admin/admin123;test/test123 INSERT INTO "sys_user"