瀏覽代碼

1、增加Menduner用户相关

rayson 1 年之前
父節點
當前提交
884442e878

+ 4 - 4
citu-module-system/citu-module-system-api/src/main/java/com/citu/module/system/enums/sms/SmsSceneEnum.java

@@ -23,10 +23,10 @@ public enum SmsSceneEnum implements IntArrayValuable {
 
     ADMIN_MEMBER_LOGIN(21, "admin-sms-login", "后台用户 - 手机号登录"),
 
-    MENDUNER_LOGIN(30, "menduner-user-sms-login", "手机号登陆"),
-    MENDUNER_UPDATE_MOBILE(31, "menduner-user-update-mobile", "求职者 - 修改手机"),
-    MENDUNER_UPDATE_PASSWORD(32, "menduner-user-update-password", "求职者 - 修改密码"),
-    MENDUNER_RESET_PASSWORD(33, "menduner-user-reset-password", "求职者 - 忘记密码");
+    MENDUNER_LOGIN(30, "menduner-user-sms-login", "menduner - 手机号登陆"),
+    MENDUNER_UPDATE_MOBILE(31, "menduner-user-update-mobile", "修改手机"),
+    MENDUNER_UPDATE_PASSWORD(32, "menduner-user-update-password", "menduner - 修改密码"),
+    MENDUNER_RESET_PASSWORD(33, "menduner-user-reset-password", "menduner - 忘记密码");
 
     public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SmsSceneEnum::getScene).toArray();
 

+ 49 - 11
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/user/MdeUserController.java

@@ -7,9 +7,8 @@ import com.citu.framework.common.pojo.PageParam;
 import com.citu.framework.common.pojo.PageResult;
 import com.citu.framework.common.util.object.BeanUtils;
 import com.citu.framework.excel.core.util.ExcelUtils;
-import com.citu.module.menduner.system.controller.admin.user.vo.MdeUserPageReqVO;
-import com.citu.module.menduner.system.controller.admin.user.vo.MdeUserRespVO;
-import com.citu.module.menduner.system.controller.admin.user.vo.MdeUserSaveReqVO;
+import com.citu.framework.security.core.annotations.PreAuthenticated;
+import com.citu.module.menduner.system.controller.admin.user.vo.*;
 import com.citu.module.menduner.system.dal.dataobject.user.MdeUserDO;
 import com.citu.module.menduner.system.service.user.MdeUserService;
 import io.swagger.v3.oas.annotations.Operation;
@@ -27,8 +26,9 @@ import java.util.List;
 
 import static com.citu.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static com.citu.framework.common.pojo.CommonResult.success;
+import static com.citu.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 
-@Tag(name = "管理后台 - 门墩儿-用户信息")
+@Tag(name = "管理后台 - 用户信息")
 @RestController
 @RequestMapping("/menduner/system/mde-user")
 @Validated
@@ -38,14 +38,14 @@ public class MdeUserController {
     private MdeUserService mdeUserService;
 
     @PostMapping("/create")
-    @Operation(summary = "创建门墩儿-用户信息")
+    @Operation(summary = "创建用户信息")
     @PreAuthorize("@ss.hasPermission('menduner:system:mde-user:create')")
     public CommonResult<Long> createMdeUser(@Valid @RequestBody MdeUserSaveReqVO createReqVO) {
         return success(mdeUserService.createMdeUser(createReqVO));
     }
 
     @PutMapping("/update")
-    @Operation(summary = "更新门墩儿-用户信息")
+    @Operation(summary = "更新用户信息")
     @PreAuthorize("@ss.hasPermission('menduner:system:mde-user:update')")
     public CommonResult<Boolean> updateMdeUser(@Valid @RequestBody MdeUserSaveReqVO updateReqVO) {
         mdeUserService.updateMdeUser(updateReqVO);
@@ -53,7 +53,7 @@ public class MdeUserController {
     }
 
     @DeleteMapping("/delete")
-    @Operation(summary = "删除门墩儿-用户信息")
+    @Operation(summary = "删除用户信息")
     @Parameter(name = "id", description = "编号", required = true)
     @PreAuthorize("@ss.hasPermission('menduner:system:mde-user:delete')")
     public CommonResult<Boolean> deleteMdeUser(@RequestParam("id") Long id) {
@@ -62,7 +62,7 @@ public class MdeUserController {
     }
 
     @GetMapping("/get")
-    @Operation(summary = "获得门墩儿-用户信息")
+    @Operation(summary = "获得用户信息")
     @Parameter(name = "id", description = "编号", required = true, example = "1024")
     @PreAuthorize("@ss.hasPermission('menduner:system:mde-user:query')")
     public CommonResult<MdeUserRespVO> getMdeUser(@RequestParam("id") Long id) {
@@ -71,7 +71,7 @@ public class MdeUserController {
     }
 
     @GetMapping("/page")
-    @Operation(summary = "获得门墩儿-用户信息分页")
+    @Operation(summary = "获得用户信息分页")
     @PreAuthorize("@ss.hasPermission('menduner:system:mde-user:query')")
     public CommonResult<PageResult<MdeUserRespVO>> getMdeUserPage(@Valid MdeUserPageReqVO pageReqVO) {
         PageResult<MdeUserDO> pageResult = mdeUserService.getMdeUserPage(pageReqVO);
@@ -79,7 +79,7 @@ public class MdeUserController {
     }
 
     @GetMapping("/export-excel")
-    @Operation(summary = "导出门墩儿-用户信息 Excel")
+    @Operation(summary = "导出用户信息 Excel")
     @PreAuthorize("@ss.hasPermission('menduner:system:mde-user:export')")
     @ApiAccessLog(operateType = EXPORT)
     public void exportMdeUserExcel(@Valid MdeUserPageReqVO pageReqVO,
@@ -87,8 +87,46 @@ public class MdeUserController {
         pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
         List<MdeUserDO> list = mdeUserService.getMdeUserPage(pageReqVO).getList();
         // 导出 Excel
-        ExcelUtils.write(response, "门墩儿-用户信息.xls", "数据", MdeUserRespVO.class,
+        ExcelUtils.write(response, "用户信息.xls", "数据", MdeUserRespVO.class,
                 BeanUtils.toBean(list, MdeUserRespVO.class));
     }
 
+    @PutMapping("/update-phone")
+    @Operation(summary = "修改用户手机")
+    @PreAuthenticated
+    public CommonResult<Boolean> updateUserPhone(@RequestBody @Valid MdeUserUpdatePhoneReqVO reqVO) {
+        mdeUserService.updateUserPhone(getLoginUserId(), reqVO);
+        return success(true);
+    }
+
+    @PutMapping("/update-mobile-by-weixin")
+    @Operation(summary = "基于微信小程序的授权码,修改用户手机")
+    @PreAuthenticated
+    public CommonResult<Boolean> updateUserMobileByWeixin(@RequestBody @Valid MdeUserUpdatePhoneByWeixinReqVO reqVO) {
+        mdeUserService.updateUserMobileByWeixin(getLoginUserId(), reqVO);
+        return success(true);
+    }
+
+    @PutMapping("/update-password")
+    @Operation(summary = "修改用户密码", description = "用户修改密码时使用")
+    @PreAuthenticated
+    public CommonResult<Boolean> updateUserPassword(@RequestBody @Valid MdeUserUpdatePasswordReqVO reqVO) {
+        mdeUserService.updateUserPassword(getLoginUserId(), reqVO);
+        return success(true);
+    }
+
+    @PutMapping("/reset-password")
+    @Operation(summary = "重置密码", description = "用户忘记密码时使用")
+    public CommonResult<Boolean> resetUserPassword(@RequestBody @Valid MdeUserResetPasswordReqVO reqVO) {
+        mdeUserService.resetUserPassword(reqVO);
+        return success(true);
+    }
+
+    @PostMapping("/create/h5")
+    @Operation(summary = "基于手机号创建用户(H5)", description = "网页注册时使用")
+    public CommonResult<Boolean> createUserIfAbsentH5(@RequestBody @Valid MdeUserCreatePhonePCReqVO reqVO) {
+        mdeUserService.createUserIfAbsentH5(reqVO);
+        return success(true);
+    }
+
 }

+ 24 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/user/vo/MdeUserCreatePhonePCReqVO.java

@@ -0,0 +1,24 @@
+package com.citu.module.menduner.system.controller.admin.user.vo;
+
+import com.citu.framework.common.validation.Mobile;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotBlank;
+
+@Schema(description = "门墩儿-用户 - 基于网页pc注册 Request VO")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class MdeUserCreatePhonePCReqVO {
+
+    @Schema(description = "手机号",requiredMode = Schema.RequiredMode.REQUIRED,example = "15878962356")
+    @NotBlank(message = "手机号不能为空")
+    @Mobile
+    private String phone;
+
+}

+ 38 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/user/vo/MdeUserResetPasswordReqVO.java

@@ -0,0 +1,38 @@
+package com.citu.module.menduner.system.controller.admin.user.vo;
+
+import com.citu.framework.common.validation.Mobile;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.Pattern;
+
+@Schema(description = "门墩儿-用户 - 重置密码 Request VO")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class MdeUserResetPasswordReqVO {
+
+    @Schema(description = "新密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "buzhidao")
+    @NotEmpty(message = "新密码不能为空")
+    @Length(min = 4, max = 16, message = "密码长度为 4-16 位")
+    private String password;
+
+    @Schema(description = "手机验证码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    @NotEmpty(message = "手机验证码不能为空")
+    @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位")
+    @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字")
+    private String code;
+
+    @Schema(description = "手机号",requiredMode = Schema.RequiredMode.REQUIRED,example = "15878962356")
+    @NotBlank(message = "手机号不能为空")
+    @Mobile
+    private String phone;
+
+}

+ 31 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/user/vo/MdeUserUpdatePasswordReqVO.java

@@ -0,0 +1,31 @@
+package com.citu.module.menduner.system.controller.admin.user.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.Pattern;
+
+@Schema(description = "门墩儿-用户 - 修改密码 Request VO")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class MdeUserUpdatePasswordReqVO {
+
+    @Schema(description = "新密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "buzhidao")
+    @NotEmpty(message = "新密码不能为空")
+    @Length(min = 4, max = 16, message = "密码长度为 4-16 位")
+    private String password;
+
+    @Schema(description = "手机验证码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    @NotEmpty(message = "手机验证码不能为空")
+    @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位")
+    @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字")
+    private String code;
+
+}

+ 17 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/user/vo/MdeUserUpdatePhoneByWeixinReqVO.java

@@ -0,0 +1,17 @@
+package com.citu.module.menduner.system.controller.admin.user.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+
+@Schema(description = "门墩儿-用户 - 基于微信小程序的授权码,修改手机 Request VO")
+@Data
+public class MdeUserUpdatePhoneByWeixinReqVO {
+
+    @Schema(description = "手机 code,小程序通过 wx.getPhoneNumber 方法获得",
+            requiredMode = Schema.RequiredMode.REQUIRED, example = "hello")
+    @NotEmpty(message = "手机 code 不能为空")
+    private String code;
+
+}

+ 33 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/user/vo/MdeUserUpdatePhoneReqVO.java

@@ -0,0 +1,33 @@
+package com.citu.module.menduner.system.controller.admin.user.vo;
+
+import com.citu.framework.common.validation.Mobile;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.Pattern;
+
+@Schema(description = "门墩儿-用户 - 修改手机 Request VO")
+@Data
+public class MdeUserUpdatePhoneReqVO {
+
+    @Schema(description = "手机验证码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    @NotEmpty(message = "手机验证码不能为空")
+    @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位")
+    @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字")
+    private String code;
+
+    @Schema(description = "手机号",requiredMode = Schema.RequiredMode.REQUIRED, example = "15823654487")
+    @NotBlank(message = "手机号不能为空")
+    @Length(min = 8, max = 11, message = "手机号码长度为 8-11 位")
+    @Mobile
+    private String phone;
+
+    @Schema(description = "原手机验证码", example = "1024")
+    @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位")
+    @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字")
+    private String oldCode;
+
+}

+ 3 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/convert/MdeAuthConvert.java

@@ -2,12 +2,14 @@ package com.citu.module.menduner.system.convert;
 
 
 import com.citu.module.menduner.system.controller.admin.auth.vo.*;
+import com.citu.module.menduner.system.controller.admin.user.vo.MdeUserResetPasswordReqVO;
 import com.citu.module.system.api.oauth2.dto.OAuth2AccessTokenRespDTO;
 import com.citu.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
 import com.citu.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
 import com.citu.module.system.api.sms.dto.code.SmsCodeValidateReqDTO;
 import com.citu.module.system.api.social.dto.SocialUserBindReqDTO;
 import com.citu.module.system.api.social.dto.SocialWxJsapiSignatureRespDTO;
+import com.citu.module.system.enums.sms.SmsSceneEnum;
 import org.mapstruct.Mapper;
 import org.mapstruct.factory.Mappers;
 
@@ -20,6 +22,7 @@ public interface MdeAuthConvert {
 
     SmsCodeSendReqDTO convert(MdeAuthSmsSendReqVO reqVO);
 
+    SmsCodeUseReqDTO convert(MdeUserResetPasswordReqVO reqVO, SmsSceneEnum scene, String usedIp);
     SmsCodeUseReqDTO convert(MdeAuthSmsLoginReqVO reqVO, Integer scene, String usedIp);
 
     MdeAuthLoginRespVO convert(OAuth2AccessTokenRespDTO bean, String openid);

+ 44 - 2
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/user/MdeUserService.java

@@ -4,8 +4,7 @@ package com.citu.module.menduner.system.service.user;
 import com.citu.framework.common.enums.TerminalEnum;
 import com.citu.framework.common.pojo.PageResult;
 import com.citu.framework.common.validation.Mobile;
-import com.citu.module.menduner.system.controller.admin.user.vo.MdeUserPageReqVO;
-import com.citu.module.menduner.system.controller.admin.user.vo.MdeUserSaveReqVO;
+import com.citu.module.menduner.system.controller.admin.user.vo.*;
 import com.citu.module.menduner.system.dal.dataobject.user.MdeUserDO;
 
 import javax.validation.Valid;
@@ -82,6 +81,17 @@ public interface MdeUserService {
      */
     MdeUserDO createUserIfAbsent(@Mobile String phone, String registerIp, Integer terminal);
 
+
+    /**
+     * 基于手机号创建用户。
+     * 如果用户已经存在,则直接进行返回
+     *
+     * @param reqVO
+     * @return 用户对象
+     */
+    MdeUserDO createUserIfAbsentH5(MdeUserCreatePhonePCReqVO reqVO);
+
+
     /**
      * 创建用户
      * 目的:三方登录时,如果未绑定用户时,自动创建对应用户
@@ -104,4 +114,36 @@ public interface MdeUserService {
     boolean isPasswordMatch(String rawPassword, String encodedPassword);
 
 
+    /**
+     * 修改手机,基于手机验证码
+     *
+     * @param userId 用户编号
+     * @param reqVO  请求信息
+     */
+    void updateUserPhone(Long userId, MdeUserUpdatePhoneReqVO reqVO);
+
+    /**
+     * 修改手机,基于微信小程序的授权码
+     *
+     * @param userId 用户编号
+     * @param reqVO 请求信息
+     */
+    void updateUserMobileByWeixin(Long userId, MdeUserUpdatePhoneByWeixinReqVO reqVO);
+
+    /**
+     * 修改密码
+     *
+     * @param userId 用户编号
+     * @param reqVO  请求信息
+     */
+    void updateUserPassword(Long userId, MdeUserUpdatePasswordReqVO reqVO);
+
+    /**
+     * 忘记密码
+     *
+     * @param reqVO 请求信息
+     */
+    void resetUserPassword(MdeUserResetPasswordReqVO reqVO);
+
+
 }

+ 136 - 3
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/user/MdeUserServiceImpl.java

@@ -1,14 +1,24 @@
 package com.citu.module.menduner.system.service.user;
 
 
+import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.StrUtil;
 import com.citu.framework.common.enums.CommonStatusEnum;
+import com.citu.framework.common.enums.TerminalEnum;
+import com.citu.framework.common.enums.UserTypeEnum;
 import com.citu.framework.common.pojo.PageResult;
 import com.citu.framework.common.util.object.BeanUtils;
-import com.citu.module.menduner.system.controller.admin.user.vo.MdeUserPageReqVO;
-import com.citu.module.menduner.system.controller.admin.user.vo.MdeUserSaveReqVO;
+import com.citu.module.menduner.system.controller.admin.user.vo.*;
+import com.citu.module.menduner.system.convert.MdeAuthConvert;
 import com.citu.module.menduner.system.dal.dataobject.user.MdeUserDO;
 import com.citu.module.menduner.system.dal.mysql.user.MdeUserMapper;
+import com.citu.module.system.api.sms.SmsCodeApi;
+import com.citu.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
+import com.citu.module.system.api.social.SocialClientApi;
+import com.citu.module.system.api.social.dto.SocialWxPhoneNumberInfoRespDTO;
+import com.citu.module.system.enums.sms.SmsSceneEnum;
+import com.google.common.annotations.VisibleForTesting;
 import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -18,7 +28,8 @@ import javax.annotation.Resource;
 import java.time.LocalDateTime;
 
 import static com.citu.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static com.citu.module.menduner.system.enums.ErrorCodeConstants.MDE_USER_NOT_EXISTS;
+import static com.citu.framework.common.util.servlet.ServletUtils.getClientIP;
+import static com.citu.module.menduner.system.enums.ErrorCodeConstants.*;
 
 /**
  * 门墩儿-用户登录 Service 实现类
@@ -35,7 +46,14 @@ public class MdeUserServiceImpl implements MdeUserService {
     @Resource
     private PasswordEncoder passwordEncoder;
 
+    @Resource
+    private SmsCodeApi smsCodeApi;
+
+    @Resource
+    private SocialClientApi socialClientApi;
+
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public Long createMdeUser(MdeUserSaveReqVO createReqVO) {
         // 插入
         MdeUserDO mdeUser = BeanUtils.toBean(createReqVO, MdeUserDO.class);
@@ -45,6 +63,7 @@ public class MdeUserServiceImpl implements MdeUserService {
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void updateMdeUser(MdeUserSaveReqVO updateReqVO) {
         // 校验存在
         validateMdeUserExists(updateReqVO.getId());
@@ -54,6 +73,7 @@ public class MdeUserServiceImpl implements MdeUserService {
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void deleteMdeUser(Long id) {
         // 校验存在
         validateMdeUserExists(id);
@@ -78,6 +98,7 @@ public class MdeUserServiceImpl implements MdeUserService {
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void updateUserLogin(Long id, String loginIp) {
         mdeUserMapper.updateById(new MdeUserDO().setId(id)
                 .setLoginIp(loginIp).setLoginDate(LocalDateTime.now()));
@@ -102,6 +123,7 @@ public class MdeUserServiceImpl implements MdeUserService {
 
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public MdeUserDO createUser(String avtar, String registerIp, Integer terminal) {
         return createUser(null, avtar, registerIp, terminal);
     }
@@ -138,4 +160,115 @@ public class MdeUserServiceImpl implements MdeUserService {
     private String encodePassword(String password) {
         return passwordEncoder.encode(password);
     }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public MdeUserDO createUserIfAbsentH5(MdeUserCreatePhonePCReqVO reqVO) {
+        // 用户已经存在
+        MdeUserDO user = mdeUserMapper.selectByPhone(reqVO.getPhone());
+        if (user != null) {
+            return user;
+        }
+        // 用户不存在,则进行创建
+        return createUser(reqVO.getPhone(), null, getClientIP(), TerminalEnum.H5.getTerminal());
+    }
+
+    @VisibleForTesting
+    MdeUserDO validateUserExists(Long id) {
+        if (id == null) {
+            return null;
+        }
+        MdeUserDO user = mdeUserMapper.selectById(id);
+        if (user == null) {
+            throw exception(MDE_USER_NOT_EXISTS);
+        }
+        return user;
+    }
+
+    @VisibleForTesting
+    void validatePhoneUnique(Long id, String phone) {
+        if (StrUtil.isBlank(phone)) {
+            return;
+        }
+        MdeUserDO user = mdeUserMapper.selectByPhone(phone);
+        if (user == null) {
+            return;
+        }
+        // 如果 id 为空,说明不用比较是否为相同 id 的用户
+        if (id == null) {
+            throw exception(MDE_USER_MOBILE_USED, phone);
+        }
+        if (!user.getId().equals(id)) {
+            throw exception(MDE_USER_MOBILE_USED, phone);
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateUserPhone(Long userId, MdeUserUpdatePhoneReqVO reqVO) {
+        // 1.1 检测用户是否存在
+        MdeUserDO user = validateUserExists(userId);
+        // 1.2 校验新手机是否已经被绑定
+        validatePhoneUnique(null, reqVO.getPhone());
+
+        // 2.1 校验旧手机和旧验证码
+        if (StrUtil.isNotEmpty(reqVO.getOldCode())) {
+            smsCodeApi.useSmsCode(new SmsCodeUseReqDTO().setMobile(user.getPhone()).setCode(reqVO.getOldCode())
+                    .setScene(SmsSceneEnum.MENDUNER_UPDATE_MOBILE.getScene()).setUsedIp(getClientIP())).getCheckedData();
+        }
+        // 2.2 使用新验证码
+        smsCodeApi.useSmsCode(new SmsCodeUseReqDTO().setMobile(reqVO.getPhone()).setCode(reqVO.getCode())
+                .setScene(SmsSceneEnum.MENDUNER_UPDATE_MOBILE.getScene()).setUsedIp(getClientIP())).getCheckedData();
+
+        // 3. 更新用户手机
+        mdeUserMapper.updateById(MdeUserDO.builder().id(userId).phone(reqVO.getPhone()).build());
+    }
+
+    @Override
+    public void updateUserMobileByWeixin(Long userId, MdeUserUpdatePhoneByWeixinReqVO reqVO) {
+        // 1.1 获得对应的手机号信息
+        SocialWxPhoneNumberInfoRespDTO phoneNumberInfo = socialClientApi.getWxMaPhoneNumberInfo(
+                UserTypeEnum.MEMBER.getValue(), reqVO.getCode()).getCheckedData();
+        Assert.notNull(phoneNumberInfo, "获得手机信息失败,结果为空");
+        // 1.2 校验新手机是否已经被绑定
+        validatePhoneUnique(userId, phoneNumberInfo.getPhoneNumber());
+
+        // 2. 更新用户手机
+        mdeUserMapper.updateById(MdeUserDO.builder().id(userId).phone(phoneNumberInfo.getPhoneNumber()).build());
+    }
+
+    @Override
+    public void updateUserPassword(Long userId, MdeUserUpdatePasswordReqVO reqVO) {
+        // 检测用户是否存在
+        MdeUserDO user = validateUserExists(userId);
+        // 校验验证码
+        smsCodeApi.useSmsCode(new SmsCodeUseReqDTO().setMobile(user.getPhone()).setCode(reqVO.getCode())
+                .setScene(SmsSceneEnum.MEMBER_UPDATE_PASSWORD.getScene()).setUsedIp(getClientIP())).getCheckedData();
+
+        // 更新用户密码
+        mdeUserMapper.updateById(MdeUserDO.builder().id(userId)
+                .password(passwordEncoder.encode(reqVO.getPassword())).build());
+    }
+
+    private MdeUserDO validateUserExists(String mobile) {
+        MdeUserDO user = mdeUserMapper.selectByPhone(mobile);
+        if (user == null) {
+            throw exception(MDE_USER_MOBILE_NOT_EXISTS);
+        }
+        return user;
+    }
+
+    @Override
+    public void resetUserPassword(MdeUserResetPasswordReqVO reqVO) {
+        // 检验用户是否存在
+        MdeUserDO user = validateUserExists(reqVO.getPhone());
+
+        // 使用验证码
+        smsCodeApi.useSmsCode(MdeAuthConvert.INSTANCE.convert(reqVO, SmsSceneEnum.MENDUNER_RESET_PASSWORD,
+                getClientIP())).getCheckedData();
+
+        // 更新密码
+        mdeUserMapper.updateById(MdeUserDO.builder().id(user.getId())
+                .password(passwordEncoder.encode(reqVO.getPassword())).build());
+    }
 }