Commit 87e5b2bed13cc6558e538739914ffb81dc82fcc4
1 parent
41533315
1. 会员用户的修改手机 API 的优化
Showing
10 changed files
with
90 additions
and
29 deletions
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java
| @@ -12,6 +12,7 @@ public interface ErrorCodeConstants { | @@ -12,6 +12,7 @@ public interface ErrorCodeConstants { | ||
| 12 | // ========== 用户相关 1004001000============ | 12 | // ========== 用户相关 1004001000============ |
| 13 | ErrorCode USER_NOT_EXISTS = new ErrorCode(1004001000, "用户不存在"); | 13 | ErrorCode USER_NOT_EXISTS = new ErrorCode(1004001000, "用户不存在"); |
| 14 | ErrorCode USER_PASSWORD_FAILED = new ErrorCode(1004001001, "密码校验失败"); | 14 | ErrorCode USER_PASSWORD_FAILED = new ErrorCode(1004001001, "密码校验失败"); |
| 15 | + ErrorCode USER_MOBILE_USED = new ErrorCode(1004001002, "修改手机失败,该手机号({})已经被使用"); | ||
| 15 | 16 | ||
| 16 | // ========== AUTH 模块 1004003000 ========== | 17 | // ========== AUTH 模块 1004003000 ========== |
| 17 | ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1004003000, "登录失败,账号密码不正确"); | 18 | ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1004003000, "登录失败,账号密码不正确"); |
| @@ -19,6 +20,7 @@ public interface ErrorCodeConstants { | @@ -19,6 +20,7 @@ public interface ErrorCodeConstants { | ||
| 19 | ErrorCode AUTH_TOKEN_EXPIRED = new ErrorCode(1004003004, "Token 已经过期"); | 20 | ErrorCode AUTH_TOKEN_EXPIRED = new ErrorCode(1004003004, "Token 已经过期"); |
| 20 | ErrorCode AUTH_THIRD_LOGIN_NOT_BIND = new ErrorCode(1004003005, "未绑定账号,需要进行绑定"); | 21 | ErrorCode AUTH_THIRD_LOGIN_NOT_BIND = new ErrorCode(1004003005, "未绑定账号,需要进行绑定"); |
| 21 | ErrorCode AUTH_WEIXIN_MINI_APP_PHONE_CODE_ERROR = new ErrorCode(1004003006, "获得手机号失败"); | 22 | ErrorCode AUTH_WEIXIN_MINI_APP_PHONE_CODE_ERROR = new ErrorCode(1004003006, "获得手机号失败"); |
| 23 | + ErrorCode AUTH_MOBILE_USED = new ErrorCode(1004003007, "手机号已经被使用"); | ||
| 22 | 24 | ||
| 23 | // ========== 用户收件地址 1004004000 ========== | 25 | // ========== 用户收件地址 1004004000 ========== |
| 24 | ErrorCode ADDRESS_NOT_EXISTS = new ErrorCode(1004004000, "用户收件地址不存在"); | 26 | ErrorCode ADDRESS_NOT_EXISTS = new ErrorCode(1004004000, "用户收件地址不存在"); |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java
| @@ -77,6 +77,13 @@ public class AppAuthController { | @@ -77,6 +77,13 @@ public class AppAuthController { | ||
| 77 | return success(true); | 77 | return success(true); |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | + @PostMapping("/validate-sms-code") | ||
| 81 | + @Operation(summary = "校验手机验证码") | ||
| 82 | + public CommonResult<Boolean> validateSmsCode(@RequestBody @Valid AppAuthSmsValidateReqVO reqVO) { | ||
| 83 | + authService.validateSmsCode(getLoginUserId(), reqVO); | ||
| 84 | + return success(true); | ||
| 85 | + } | ||
| 86 | + | ||
| 80 | @PostMapping("/reset-password") | 87 | @PostMapping("/reset-password") |
| 81 | @Operation(summary = "重置密码", description = "用户忘记密码时使用") | 88 | @Operation(summary = "重置密码", description = "用户忘记密码时使用") |
| 82 | @PreAuthenticated | 89 | @PreAuthenticated |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsValidateReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.member.controller.app.auth.vo; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | ||
| 4 | +import cn.iocoder.yudao.framework.common.validation.Mobile; | ||
| 5 | +import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; | ||
| 6 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 7 | +import lombok.Data; | ||
| 8 | +import lombok.experimental.Accessors; | ||
| 9 | +import org.hibernate.validator.constraints.Length; | ||
| 10 | + | ||
| 11 | +import javax.validation.constraints.NotEmpty; | ||
| 12 | +import javax.validation.constraints.NotNull; | ||
| 13 | +import javax.validation.constraints.Pattern; | ||
| 14 | + | ||
| 15 | +@Schema(description = "用户 APP - 校验手机验证码 Request VO") | ||
| 16 | +@Data | ||
| 17 | +@Accessors(chain = true) | ||
| 18 | +public class AppAuthSmsValidateReqVO { | ||
| 19 | + | ||
| 20 | + @Schema(description = "手机号", example = "15601691234") | ||
| 21 | + @Mobile | ||
| 22 | + private String mobile; | ||
| 23 | + | ||
| 24 | + @Schema(description = "发送场景,对应 SmsSceneEnum 枚举", example = "1") | ||
| 25 | + @NotNull(message = "发送场景不能为空") | ||
| 26 | + @InEnum(SmsSceneEnum.class) | ||
| 27 | + private Integer scene; | ||
| 28 | + | ||
| 29 | + @Schema(description = "手机验证码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | ||
| 30 | + @NotEmpty(message = "手机验证码不能为空") | ||
| 31 | + @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") | ||
| 32 | + @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") | ||
| 33 | + private String code; | ||
| 34 | + | ||
| 35 | +} |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppMemberUserController.java
| @@ -30,14 +30,6 @@ public class AppMemberUserController { | @@ -30,14 +30,6 @@ public class AppMemberUserController { | ||
| 30 | @Resource | 30 | @Resource |
| 31 | private MemberUserService userService; | 31 | private MemberUserService userService; |
| 32 | 32 | ||
| 33 | - @PutMapping("/update") | ||
| 34 | - @Operation(summary = "修改基本信息") | ||
| 35 | - @PreAuthenticated | ||
| 36 | - public CommonResult<Boolean> updateUser(@RequestBody @Valid AppMemberUserUpdateReqVO reqVO) { | ||
| 37 | - userService.updateUser(getLoginUserId(), reqVO); | ||
| 38 | - return success(true); | ||
| 39 | - } | ||
| 40 | - | ||
| 41 | @GetMapping("/get") | 33 | @GetMapping("/get") |
| 42 | @Operation(summary = "获得基本信息") | 34 | @Operation(summary = "获得基本信息") |
| 43 | @PreAuthenticated | 35 | @PreAuthenticated |
| @@ -46,10 +38,18 @@ public class AppMemberUserController { | @@ -46,10 +38,18 @@ public class AppMemberUserController { | ||
| 46 | return success(MemberUserConvert.INSTANCE.convert(user)); | 38 | return success(MemberUserConvert.INSTANCE.convert(user)); |
| 47 | } | 39 | } |
| 48 | 40 | ||
| 49 | - @PostMapping("/update-mobile") | 41 | + @PutMapping("/update") |
| 42 | + @Operation(summary = "修改基本信息") | ||
| 43 | + @PreAuthenticated | ||
| 44 | + public CommonResult<Boolean> updateUser(@RequestBody @Valid AppMemberUserUpdateReqVO reqVO) { | ||
| 45 | + userService.updateUser(getLoginUserId(), reqVO); | ||
| 46 | + return success(true); | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + @PutMapping("/update-mobile") | ||
| 50 | @Operation(summary = "修改用户手机") | 50 | @Operation(summary = "修改用户手机") |
| 51 | @PreAuthenticated | 51 | @PreAuthenticated |
| 52 | - public CommonResult<Boolean> updateMobile(@RequestBody @Valid AppUserUpdateMobileReqVO reqVO) { | 52 | + public CommonResult<Boolean> updateUserMobile(@RequestBody @Valid AppUserUpdateMobileReqVO reqVO) { |
| 53 | userService.updateUserMobile(getLoginUserId(), reqVO); | 53 | userService.updateUserMobile(getLoginUserId(), reqVO); |
| 54 | return success(true); | 54 | return success(true); |
| 55 | } | 55 | } |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserUpdateMobileReqVO.java
| @@ -37,12 +37,4 @@ public class AppUserUpdateMobileReqVO { | @@ -37,12 +37,4 @@ public class AppUserUpdateMobileReqVO { | ||
| 37 | @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") | 37 | @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") |
| 38 | private String oldCode; | 38 | private String oldCode; |
| 39 | 39 | ||
| 40 | - // TODO @芋艿:oldMobile 应该不用传递 | ||
| 41 | - | ||
| 42 | - @Schema(description = "原手机号",requiredMode = Schema.RequiredMode.REQUIRED,example = "15823654487") | ||
| 43 | - @NotBlank(message = "手机号不能为空") | ||
| 44 | - @Length(min = 8, max = 11, message = "手机号码长度为 8-11 位") | ||
| 45 | - @Mobile | ||
| 46 | - private String oldMobile; | ||
| 47 | - | ||
| 48 | } | 40 | } |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java
| @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.member.controller.app.social.vo.AppSocialUserUnbi | @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.member.controller.app.social.vo.AppSocialUserUnbi | ||
| 5 | import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenRespDTO; | 5 | import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenRespDTO; |
| 6 | import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO; | 6 | import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO; |
| 7 | import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; | 7 | import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; |
| 8 | +import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeValidateReqDTO; | ||
| 8 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; | 9 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; |
| 9 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserUnbindReqDTO; | 10 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserUnbindReqDTO; |
| 10 | import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; | 11 | import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; |
| @@ -25,4 +26,6 @@ public interface AuthConvert { | @@ -25,4 +26,6 @@ public interface AuthConvert { | ||
| 25 | 26 | ||
| 26 | AppAuthLoginRespVO convert(OAuth2AccessTokenRespDTO bean); | 27 | AppAuthLoginRespVO convert(OAuth2AccessTokenRespDTO bean); |
| 27 | 28 | ||
| 29 | + SmsCodeValidateReqDTO convert(AppAuthSmsValidateReqVO bean); | ||
| 30 | + | ||
| 28 | } | 31 | } |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthService.java
| @@ -83,6 +83,14 @@ public interface MemberAuthService { | @@ -83,6 +83,14 @@ public interface MemberAuthService { | ||
| 83 | void sendSmsCode(Long userId, AppAuthSmsSendReqVO reqVO); | 83 | void sendSmsCode(Long userId, AppAuthSmsSendReqVO reqVO); |
| 84 | 84 | ||
| 85 | /** | 85 | /** |
| 86 | + * 校验短信验证码是否正确 | ||
| 87 | + * | ||
| 88 | + * @param userId 用户编号 | ||
| 89 | + * @param reqVO 校验信息 | ||
| 90 | + */ | ||
| 91 | + void validateSmsCode(Long userId, AppAuthSmsValidateReqVO reqVO); | ||
| 92 | + | ||
| 93 | + /** | ||
| 86 | * 刷新访问令牌 | 94 | * 刷新访问令牌 |
| 87 | * | 95 | * |
| 88 | * @param refreshToken 刷新令牌 | 96 | * @param refreshToken 刷新令牌 |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java
| @@ -236,13 +236,27 @@ public class MemberAuthServiceImpl implements MemberAuthService { | @@ -236,13 +236,27 @@ public class MemberAuthServiceImpl implements MemberAuthService { | ||
| 236 | 236 | ||
| 237 | @Override | 237 | @Override |
| 238 | public void sendSmsCode(Long userId, AppAuthSmsSendReqVO reqVO) { | 238 | public void sendSmsCode(Long userId, AppAuthSmsSendReqVO reqVO) { |
| 239 | - // TODO 要根据不同的场景,校验是否有用户 | 239 | + // 如果是修改手机场景,需要校验新手机号是否已经注册,说明不能使用该手机了 |
| 240 | + if (Objects.equals(reqVO.getScene(), SmsSceneEnum.MEMBER_UPDATE_MOBILE.getScene())) { | ||
| 241 | + MemberUserDO user = userMapper.selectByMobile(reqVO.getMobile()); | ||
| 242 | + if (user != null && !Objects.equals(user.getId(), userId)) { | ||
| 243 | + throw exception(AUTH_MOBILE_USED); | ||
| 244 | + } | ||
| 245 | + } | ||
| 246 | + | ||
| 247 | + // 执行发送 | ||
| 240 | smsCodeApi.sendSmsCode(AuthConvert.INSTANCE.convert(reqVO).setCreateIp(getClientIP())); | 248 | smsCodeApi.sendSmsCode(AuthConvert.INSTANCE.convert(reqVO).setCreateIp(getClientIP())); |
| 241 | } | 249 | } |
| 242 | 250 | ||
| 243 | @Override | 251 | @Override |
| 252 | + public void validateSmsCode(Long userId, AppAuthSmsValidateReqVO reqVO) { | ||
| 253 | + smsCodeApi.validateSmsCode(AuthConvert.INSTANCE.convert(reqVO)); | ||
| 254 | + } | ||
| 255 | + | ||
| 256 | + @Override | ||
| 244 | public AppAuthLoginRespVO refreshToken(String refreshToken) { | 257 | public AppAuthLoginRespVO refreshToken(String refreshToken) { |
| 245 | - OAuth2AccessTokenRespDTO accessTokenDO = oauth2TokenApi.refreshAccessToken(refreshToken, OAuth2ClientConstants.CLIENT_ID_DEFAULT); | 258 | + OAuth2AccessTokenRespDTO accessTokenDO = oauth2TokenApi.refreshAccessToken(refreshToken, |
| 259 | + OAuth2ClientConstants.CLIENT_ID_DEFAULT); | ||
| 246 | return AuthConvert.INSTANCE.convert(accessTokenDO); | 260 | return AuthConvert.INSTANCE.convert(accessTokenDO); |
| 247 | } | 261 | } |
| 248 | 262 |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java
| @@ -29,8 +29,7 @@ import java.util.List; | @@ -29,8 +29,7 @@ import java.util.List; | ||
| 29 | 29 | ||
| 30 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 30 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 31 | import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; | 31 | import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; |
| 32 | -import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.USER_NOT_EXISTS; | ||
| 33 | -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_MOBILE_EXISTS; | 32 | +import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*; |
| 34 | 33 | ||
| 35 | /** | 34 | /** |
| 36 | * 会员 User Service 实现类 | 35 | * 会员 User Service 实现类 |
| @@ -113,11 +112,12 @@ public class MemberUserServiceImpl implements MemberUserService { | @@ -113,11 +112,12 @@ public class MemberUserServiceImpl implements MemberUserService { | ||
| 113 | @Transactional(rollbackFor = Exception.class) | 112 | @Transactional(rollbackFor = Exception.class) |
| 114 | public void updateUserMobile(Long userId, AppUserUpdateMobileReqVO reqVO) { | 113 | public void updateUserMobile(Long userId, AppUserUpdateMobileReqVO reqVO) { |
| 115 | // 检测用户是否存在 | 114 | // 检测用户是否存在 |
| 116 | - validateUserExists(userId); | ||
| 117 | - // TODO 芋艿:oldMobile 应该不用传递 | 115 | + MemberUserDO user = validateUserExists(userId); |
| 116 | + // 校验新手机是否已经被绑定 | ||
| 117 | + validateMobileUnique(null, reqVO.getMobile()); | ||
| 118 | 118 | ||
| 119 | // 校验旧手机和旧验证码 | 119 | // 校验旧手机和旧验证码 |
| 120 | - smsCodeApi.useSmsCode(new SmsCodeUseReqDTO().setMobile(reqVO.getOldMobile()).setCode(reqVO.getOldCode()) | 120 | + smsCodeApi.useSmsCode(new SmsCodeUseReqDTO().setMobile(user.getMobile()).setCode(reqVO.getOldCode()) |
| 121 | .setScene(SmsSceneEnum.MEMBER_UPDATE_MOBILE.getScene()).setUsedIp(getClientIP())); | 121 | .setScene(SmsSceneEnum.MEMBER_UPDATE_MOBILE.getScene()).setUsedIp(getClientIP())); |
| 122 | // 使用新验证码 | 122 | // 使用新验证码 |
| 123 | smsCodeApi.useSmsCode(new SmsCodeUseReqDTO().setMobile(reqVO.getMobile()).setCode(reqVO.getCode()) | 123 | smsCodeApi.useSmsCode(new SmsCodeUseReqDTO().setMobile(reqVO.getMobile()).setCode(reqVO.getCode()) |
| @@ -177,10 +177,10 @@ public class MemberUserServiceImpl implements MemberUserService { | @@ -177,10 +177,10 @@ public class MemberUserServiceImpl implements MemberUserService { | ||
| 177 | } | 177 | } |
| 178 | // 如果 id 为空,说明不用比较是否为相同 id 的用户 | 178 | // 如果 id 为空,说明不用比较是否为相同 id 的用户 |
| 179 | if (id == null) { | 179 | if (id == null) { |
| 180 | - throw exception(USER_MOBILE_EXISTS); | 180 | + throw exception(USER_MOBILE_USED); |
| 181 | } | 181 | } |
| 182 | if (!user.getId().equals(id)) { | 182 | if (!user.getId().equals(id)) { |
| 183 | - throw exception(USER_MOBILE_EXISTS); | 183 | + throw exception(USER_MOBILE_USED); |
| 184 | } | 184 | } |
| 185 | } | 185 | } |
| 186 | 186 |
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsSceneEnum.java
| @@ -17,8 +17,8 @@ import java.util.Arrays; | @@ -17,8 +17,8 @@ import java.util.Arrays; | ||
| 17 | public enum SmsSceneEnum implements IntArrayValuable { | 17 | public enum SmsSceneEnum implements IntArrayValuable { |
| 18 | 18 | ||
| 19 | MEMBER_LOGIN(1, "user-sms-login", "会员用户 - 手机号登陆"), | 19 | MEMBER_LOGIN(1, "user-sms-login", "会员用户 - 手机号登陆"), |
| 20 | - MEMBER_UPDATE_MOBILE(2, "user-sms-reset-password", "会员用户 - 修改手机"), | ||
| 21 | - MEMBER_FORGET_PASSWORD(3, "user-sms-update-mobile", "会员用户 - 忘记密码"), | 20 | + MEMBER_UPDATE_MOBILE(2, "user-sms-update-mobile", "会员用户 - 修改手机"), |
| 21 | + MEMBER_FORGET_PASSWORD(3, "user-sms-forget-password", "会员用户 - 忘记密码"), | ||
| 22 | 22 | ||
| 23 | ADMIN_MEMBER_LOGIN(21, "admin-sms-login", "后台用户 - 手机号登录"); | 23 | ADMIN_MEMBER_LOGIN(21, "admin-sms-login", "后台用户 - 手机号登录"); |
| 24 | 24 |