✨ Member:增加使用微信小程序 code 绑定手机号
This commit is contained in:
parent
5de6a8bd23
commit
2f5afdb5c9
@ -15,11 +15,11 @@ import jakarta.validation.constraints.NotEmpty;
|
|||||||
@Builder
|
@Builder
|
||||||
public class AppAuthWeixinMiniAppLoginReqVO {
|
public class AppAuthWeixinMiniAppLoginReqVO {
|
||||||
|
|
||||||
@Schema(description = "手机 code,小程序通过 wx.getPhoneNumber 方法获得", requiredMode = Schema.RequiredMode.REQUIRED, example = "hello")
|
@Schema(description = "手机 code,小程序通过 wx.getPhoneNumber 方法获得", requiredMode = Schema.RequiredMode.REQUIRED, example = "hello")
|
||||||
@NotEmpty(message = "手机 code 不能为空")
|
@NotEmpty(message = "手机 code 不能为空")
|
||||||
private String phoneCode;
|
private String phoneCode;
|
||||||
|
|
||||||
@Schema(description = "登录 code,小程序通过 wx.login 方法获得", requiredMode = Schema.RequiredMode.REQUIRED, example = "word")
|
@Schema(description = "登录 code,小程序通过 wx.login 方法获得", requiredMode = Schema.RequiredMode.REQUIRED, example = "word")
|
||||||
@NotEmpty(message = "登录 code 不能为空")
|
@NotEmpty(message = "登录 code 不能为空")
|
||||||
private String loginCode;
|
private String loginCode;
|
||||||
|
|
||||||
|
@ -57,6 +57,14 @@ public class AppMemberUserController {
|
|||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PutMapping("/update-mobile-by-weixin")
|
||||||
|
@Operation(summary = "基于微信小程序的授权码,修改用户手机")
|
||||||
|
@PreAuthenticated
|
||||||
|
public CommonResult<Boolean> updateUserMobileByWeixin(@RequestBody @Valid AppMemberUserUpdateMobileByWeixinReqVO reqVO) {
|
||||||
|
userService.updateUserMobileByWeixin(getLoginUserId(), reqVO);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
@PutMapping("/update-password")
|
@PutMapping("/update-password")
|
||||||
@Operation(summary = "修改用户密码", description = "用户修改密码时使用")
|
@Operation(summary = "修改用户密码", description = "用户修改密码时使用")
|
||||||
@PreAuthenticated
|
@PreAuthenticated
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
package cn.iocoder.yudao.module.member.controller.app.user.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Schema(description = "用户 APP - 基于微信小程序的授权码,修改手机 Request VO")
|
||||||
|
@Data
|
||||||
|
public class AppMemberUserUpdateMobileByWeixinReqVO {
|
||||||
|
|
||||||
|
@Schema(description = "手机 code,小程序通过 wx.getPhoneNumber 方法获得",
|
||||||
|
requiredMode = Schema.RequiredMode.REQUIRED, example = "hello")
|
||||||
|
@NotEmpty(message = "手机 code 不能为空")
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
}
|
@ -14,9 +14,6 @@ import jakarta.validation.constraints.Pattern;
|
|||||||
|
|
||||||
@Schema(description = "用户 APP - 修改手机 Request VO")
|
@Schema(description = "用户 APP - 修改手机 Request VO")
|
||||||
@Data
|
@Data
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
@Builder
|
|
||||||
public class AppMemberUserUpdateMobileReqVO {
|
public class AppMemberUserUpdateMobileReqVO {
|
||||||
|
|
||||||
@Schema(description = "手机验证码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
@Schema(description = "手机验证码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
@ -31,8 +28,7 @@ public class AppMemberUserUpdateMobileReqVO {
|
|||||||
@Mobile
|
@Mobile
|
||||||
private String mobile;
|
private String mobile;
|
||||||
|
|
||||||
@Schema(description = "原手机验证码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
@Schema(description = "原手机验证码", example = "1024")
|
||||||
@NotEmpty(message = "原手机验证码不能为空")
|
|
||||||
@Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位")
|
@Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位")
|
||||||
@Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字")
|
@Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字")
|
||||||
private String oldCode;
|
private String oldCode;
|
||||||
|
@ -5,10 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|||||||
import cn.iocoder.yudao.framework.common.validation.Mobile;
|
import cn.iocoder.yudao.framework.common.validation.Mobile;
|
||||||
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserPageReqVO;
|
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserPageReqVO;
|
||||||
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateReqVO;
|
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateReqVO;
|
||||||
import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserResetPasswordReqVO;
|
import cn.iocoder.yudao.module.member.controller.app.user.vo.*;
|
||||||
import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserUpdateMobileReqVO;
|
|
||||||
import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserUpdatePasswordReqVO;
|
|
||||||
import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserUpdateReqVO;
|
|
||||||
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
|
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
|
||||||
|
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
@ -94,13 +91,21 @@ public interface MemberUserService {
|
|||||||
void updateUser(Long userId, AppMemberUserUpdateReqVO reqVO);
|
void updateUser(Long userId, AppMemberUserUpdateReqVO reqVO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 【会员】修改手机
|
* 【会员】修改手机,基于手机验证码
|
||||||
*
|
*
|
||||||
* @param userId 用户编号
|
* @param userId 用户编号
|
||||||
* @param reqVO 请求信息
|
* @param reqVO 请求信息
|
||||||
*/
|
*/
|
||||||
void updateUserMobile(Long userId, AppMemberUserUpdateMobileReqVO reqVO);
|
void updateUserMobile(Long userId, AppMemberUserUpdateMobileReqVO reqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【会员】修改手机,基于微信小程序的授权码
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @param reqVO 请求信息
|
||||||
|
*/
|
||||||
|
void updateUserMobileByWeixin(Long userId, AppMemberUserUpdateMobileByWeixinReqVO reqVO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 【会员】修改密码
|
* 【会员】修改密码
|
||||||
*
|
*
|
||||||
@ -181,4 +186,5 @@ public interface MemberUserService {
|
|||||||
* @return 更新结果
|
* @return 更新结果
|
||||||
*/
|
*/
|
||||||
boolean updateUserPoint(Long userId, Integer point);
|
boolean updateUserPoint(Long userId, Integer point);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,16 +2,15 @@ package cn.iocoder.yudao.module.member.service.user;
|
|||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.collection.ListUtil;
|
import cn.hutool.core.collection.ListUtil;
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.util.*;
|
import cn.hutool.core.util.*;
|
||||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
|
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserPageReqVO;
|
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserPageReqVO;
|
||||||
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateReqVO;
|
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateReqVO;
|
||||||
import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserResetPasswordReqVO;
|
import cn.iocoder.yudao.module.member.controller.app.user.vo.*;
|
||||||
import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserUpdateMobileReqVO;
|
|
||||||
import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserUpdatePasswordReqVO;
|
|
||||||
import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserUpdateReqVO;
|
|
||||||
import cn.iocoder.yudao.module.member.convert.auth.AuthConvert;
|
import cn.iocoder.yudao.module.member.convert.auth.AuthConvert;
|
||||||
import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert;
|
import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert;
|
||||||
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
|
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
|
||||||
@ -19,6 +18,8 @@ import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
|
|||||||
import cn.iocoder.yudao.module.member.mq.producer.user.MemberUserProducer;
|
import cn.iocoder.yudao.module.member.mq.producer.user.MemberUserProducer;
|
||||||
import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
|
import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
|
||||||
import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
|
import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
|
||||||
|
import cn.iocoder.yudao.module.system.api.social.SocialClientApi;
|
||||||
|
import cn.iocoder.yudao.module.system.api.social.dto.SocialWxPhoneNumberInfoRespDTO;
|
||||||
import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
|
import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -54,6 +55,9 @@ public class MemberUserServiceImpl implements MemberUserService {
|
|||||||
@Resource
|
@Resource
|
||||||
private SmsCodeApi smsCodeApi;
|
private SmsCodeApi smsCodeApi;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SocialClientApi socialClientApi;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private PasswordEncoder passwordEncoder;
|
private PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
@ -145,22 +149,38 @@ public class MemberUserServiceImpl implements MemberUserService {
|
|||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void updateUserMobile(Long userId, AppMemberUserUpdateMobileReqVO reqVO) {
|
public void updateUserMobile(Long userId, AppMemberUserUpdateMobileReqVO reqVO) {
|
||||||
// 检测用户是否存在
|
// 1.1 检测用户是否存在
|
||||||
MemberUserDO user = validateUserExists(userId);
|
MemberUserDO user = validateUserExists(userId);
|
||||||
// 校验新手机是否已经被绑定
|
// 1.2 校验新手机是否已经被绑定
|
||||||
validateMobileUnique(null, reqVO.getMobile());
|
validateMobileUnique(null, reqVO.getMobile());
|
||||||
|
|
||||||
// 校验旧手机和旧验证码
|
// 2.1 校验旧手机和旧验证码
|
||||||
|
// 补充说明:从安全性来说,老手机也校验 oldCode 验证码会更安全。但是由于 uni-app 商城界面暂时没做,所以这里不强制校验
|
||||||
|
if (StrUtil.isNotEmpty(reqVO.getOldCode())) {
|
||||||
smsCodeApi.useSmsCode(new SmsCodeUseReqDTO().setMobile(user.getMobile()).setCode(reqVO.getOldCode())
|
smsCodeApi.useSmsCode(new SmsCodeUseReqDTO().setMobile(user.getMobile()).setCode(reqVO.getOldCode())
|
||||||
.setScene(SmsSceneEnum.MEMBER_UPDATE_MOBILE.getScene()).setUsedIp(getClientIP()));
|
.setScene(SmsSceneEnum.MEMBER_UPDATE_MOBILE.getScene()).setUsedIp(getClientIP()));
|
||||||
// 使用新验证码
|
}
|
||||||
|
// 2.2 使用新验证码
|
||||||
smsCodeApi.useSmsCode(new SmsCodeUseReqDTO().setMobile(reqVO.getMobile()).setCode(reqVO.getCode())
|
smsCodeApi.useSmsCode(new SmsCodeUseReqDTO().setMobile(reqVO.getMobile()).setCode(reqVO.getCode())
|
||||||
.setScene(SmsSceneEnum.MEMBER_UPDATE_MOBILE.getScene()).setUsedIp(getClientIP()));
|
.setScene(SmsSceneEnum.MEMBER_UPDATE_MOBILE.getScene()).setUsedIp(getClientIP()));
|
||||||
|
|
||||||
// 更新用户手机
|
// 3. 更新用户手机
|
||||||
memberUserMapper.updateById(MemberUserDO.builder().id(userId).mobile(reqVO.getMobile()).build());
|
memberUserMapper.updateById(MemberUserDO.builder().id(userId).mobile(reqVO.getMobile()).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateUserMobileByWeixin(Long userId, AppMemberUserUpdateMobileByWeixinReqVO reqVO) {
|
||||||
|
// 1.1 获得对应的手机号信息
|
||||||
|
SocialWxPhoneNumberInfoRespDTO phoneNumberInfo = socialClientApi.getWxMaPhoneNumberInfo(
|
||||||
|
UserTypeEnum.MEMBER.getValue(), reqVO.getCode());
|
||||||
|
Assert.notNull(phoneNumberInfo, "获得手机信息失败,结果为空");
|
||||||
|
// 1.2 校验新手机是否已经被绑定
|
||||||
|
validateMobileUnique(userId, phoneNumberInfo.getPhoneNumber());
|
||||||
|
|
||||||
|
// 2. 更新用户手机
|
||||||
|
memberUserMapper.updateById(MemberUserDO.builder().id(userId).mobile(phoneNumberInfo.getPhoneNumber()).build());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateUserPassword(Long userId, AppMemberUserUpdatePasswordReqVO reqVO) {
|
public void updateUserPassword(Long userId, AppMemberUserUpdatePasswordReqVO reqVO) {
|
||||||
// 检测用户是否存在
|
// 检测用户是否存在
|
||||||
|
Loading…
Reference in New Issue
Block a user