Commit e44011754c583ad7d6b397a53382e6b511f26a7c
1 parent
fe4a774c
feat(member): 会员增加 email 字段
Showing
10 changed files
with
61 additions
and
2 deletions
yudao-module-member/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/MemberUserRespDTO.java
yudao-module-member/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/vo/MemberUserBaseVO.java
| ... | ... | @@ -5,7 +5,9 @@ import lombok.Data; |
| 5 | 5 | import org.hibernate.validator.constraints.URL; |
| 6 | 6 | import org.springframework.format.annotation.DateTimeFormat; |
| 7 | 7 | |
| 8 | +import jakarta.validation.constraints.Email; | |
| 8 | 9 | import jakarta.validation.constraints.NotNull; |
| 10 | +import jakarta.validation.constraints.Size; | |
| 9 | 11 | import java.time.LocalDateTime; |
| 10 | 12 | import java.util.List; |
| 11 | 13 | |
| ... | ... | @@ -26,6 +28,11 @@ public class MemberUserBaseVO { |
| 26 | 28 | @NotNull(message = "状态不能为空") |
| 27 | 29 | private Byte status; |
| 28 | 30 | |
| 31 | + @Schema(description = "邮箱", example = "member@iocoder.cn") | |
| 32 | + @Email(message = "邮箱格式不正确") | |
| 33 | + @Size(max = 50, message = "邮箱长度不能超过 50 个字符") | |
| 34 | + private String email; | |
| 35 | + | |
| 29 | 36 | @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") |
| 30 | 37 | @NotNull(message = "用户昵称不能为空") |
| 31 | 38 | private String nickname; | ... | ... |
yudao-module-member/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/vo/MemberUserPageReqVO.java
| ... | ... | @@ -21,6 +21,9 @@ public class MemberUserPageReqVO extends PageParam { |
| 21 | 21 | @Schema(description = "手机号", example = "15601691300") |
| 22 | 22 | private String mobile; |
| 23 | 23 | |
| 24 | + @Schema(description = "邮箱", example = "member@iocoder.cn") | |
| 25 | + private String email; | |
| 26 | + | |
| 24 | 27 | @Schema(description = "用户昵称", example = "李四") |
| 25 | 28 | private String nickname; |
| 26 | 29 | ... | ... |
yudao-module-member/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppMemberUserInfoRespVO.java
| ... | ... | @@ -23,6 +23,9 @@ public class AppMemberUserInfoRespVO { |
| 23 | 23 | @Schema(description = "用户手机号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15601691300") |
| 24 | 24 | private String mobile; |
| 25 | 25 | |
| 26 | + @Schema(description = "邮箱", example = "member@iocoder.cn") | |
| 27 | + private String email; | |
| 28 | + | |
| 26 | 29 | @Schema(description = "用户性别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 27 | 30 | private Integer sex; |
| 28 | 31 | ... | ... |
yudao-module-member/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppMemberUserUpdateReqVO.java
| 1 | 1 | package cn.iocoder.yudao.module.member.controller.app.user.vo; |
| 2 | 2 | |
| 3 | -import cn.iocoder.yudao.framework.common.validation.InEnum; | |
| 4 | -import cn.iocoder.yudao.module.system.enums.common.SexEnum; | |
| 5 | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | +import jakarta.validation.constraints.Email; | |
| 5 | +import jakarta.validation.constraints.Size; | |
| 6 | 6 | import lombok.Data; |
| 7 | 7 | import org.hibernate.validator.constraints.URL; |
| 8 | 8 | |
| ... | ... | @@ -17,6 +17,11 @@ public class AppMemberUserUpdateReqVO { |
| 17 | 17 | @URL(message = "头像必须是 URL 格式") |
| 18 | 18 | private String avatar; |
| 19 | 19 | |
| 20 | + @Schema(description = "邮箱", example = "member@iocoder.cn") | |
| 21 | + @Email(message = "邮箱格式不正确") | |
| 22 | + @Size(max = 50, message = "邮箱长度不能超过 50 个字符") | |
| 23 | + private String email; | |
| 24 | + | |
| 20 | 25 | @Schema(description = "性别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 21 | 26 | private Integer sex; |
| 22 | 27 | ... | ... |
yudao-module-member/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/user/MemberUserDO.java
yudao-module-member/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/user/MemberUserMapper.java
| ... | ... | @@ -26,6 +26,10 @@ public interface MemberUserMapper extends BaseMapperX<MemberUserDO> { |
| 26 | 26 | return selectOne(MemberUserDO::getMobile, mobile); |
| 27 | 27 | } |
| 28 | 28 | |
| 29 | + default MemberUserDO selectByEmail(String email) { | |
| 30 | + return selectOne(MemberUserDO::getEmail, email); | |
| 31 | + } | |
| 32 | + | |
| 29 | 33 | default List<MemberUserDO> selectListByNicknameLike(String nickname) { |
| 30 | 34 | return selectList(new LambdaQueryWrapperX<MemberUserDO>() |
| 31 | 35 | .likeIfPresent(MemberUserDO::getNickname, nickname)); |
| ... | ... | @@ -42,6 +46,7 @@ public interface MemberUserMapper extends BaseMapperX<MemberUserDO> { |
| 42 | 46 | // 分页查询 |
| 43 | 47 | return selectPage(reqVO, new LambdaQueryWrapperX<MemberUserDO>() |
| 44 | 48 | .likeIfPresent(MemberUserDO::getMobile, reqVO.getMobile()) |
| 49 | + .likeIfPresent(MemberUserDO::getEmail, reqVO.getEmail()) | |
| 45 | 50 | .betweenIfPresent(MemberUserDO::getLoginDate, reqVO.getLoginDate()) |
| 46 | 51 | .likeIfPresent(MemberUserDO::getNickname, reqVO.getNickname()) |
| 47 | 52 | .betweenIfPresent(MemberUserDO::getCreateTime, reqVO.getCreateTime()) | ... | ... |
yudao-module-member/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java
| ... | ... | @@ -14,6 +14,7 @@ public interface ErrorCodeConstants { |
| 14 | 14 | ErrorCode USER_MOBILE_NOT_EXISTS = new ErrorCode(1_004_001_001, "手机号未注册用户"); |
| 15 | 15 | ErrorCode USER_MOBILE_USED = new ErrorCode(1_004_001_002, "修改手机失败,该手机号({})已经被使用"); |
| 16 | 16 | ErrorCode USER_POINT_NOT_ENOUGH = new ErrorCode(1_004_001_003, "用户积分余额不足"); |
| 17 | + ErrorCode USER_EMAIL_USED = new ErrorCode(1_004_001_004, "修改邮箱失败,该邮箱({})已经被使用"); | |
| 17 | 18 | |
| 18 | 19 | // ========== AUTH 模块 1-004-003-000 ========== |
| 19 | 20 | ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1_004_003_000, "登录失败,账号密码不正确"); | ... | ... |
yudao-module-member/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java
| ... | ... | @@ -142,6 +142,12 @@ public class MemberUserServiceImpl implements MemberUserService { |
| 142 | 142 | |
| 143 | 143 | @Override |
| 144 | 144 | public void updateUser(Long userId, AppMemberUserUpdateReqVO reqVO) { |
| 145 | + // 1.1 检测用户是否存在 | |
| 146 | + validateUserExists(userId); | |
| 147 | + // 1.2 校验手机是否已经被绑定 | |
| 148 | + validateEmailUnique(userId, reqVO.getEmail()); | |
| 149 | + | |
| 150 | + // 2. 更新用户 | |
| 145 | 151 | MemberUserDO updateObj = BeanUtils.toBean(reqVO, MemberUserDO.class).setId(userId); |
| 146 | 152 | memberUserMapper.updateById(updateObj); |
| 147 | 153 | } |
| ... | ... | @@ -238,6 +244,8 @@ public class MemberUserServiceImpl implements MemberUserService { |
| 238 | 244 | validateUserExists(updateReqVO.getId()); |
| 239 | 245 | // 校验手机唯一 |
| 240 | 246 | validateMobileUnique(updateReqVO.getId(), updateReqVO.getMobile()); |
| 247 | + // 校验邮箱唯一 | |
| 248 | + validateEmailUnique(updateReqVO.getId(), updateReqVO.getEmail()); | |
| 241 | 249 | |
| 242 | 250 | // 更新 |
| 243 | 251 | MemberUserDO updateObj = MemberUserConvert.INSTANCE.convert(updateReqVO); |
| ... | ... | @@ -274,6 +282,24 @@ public class MemberUserServiceImpl implements MemberUserService { |
| 274 | 282 | } |
| 275 | 283 | } |
| 276 | 284 | |
| 285 | + @VisibleForTesting | |
| 286 | + void validateEmailUnique(Long id, String email) { | |
| 287 | + if (StrUtil.isBlank(email)) { | |
| 288 | + return; | |
| 289 | + } | |
| 290 | + MemberUserDO user = memberUserMapper.selectByEmail(email); | |
| 291 | + if (user == null) { | |
| 292 | + return; | |
| 293 | + } | |
| 294 | + // 如果 id 为空,说明不用比较是否为相同 id 的用户 | |
| 295 | + if (id == null) { | |
| 296 | + throw exception(USER_EMAIL_USED, email); | |
| 297 | + } | |
| 298 | + if (!user.getId().equals(id)) { | |
| 299 | + throw exception(USER_EMAIL_USED, email); | |
| 300 | + } | |
| 301 | + } | |
| 302 | + | |
| 277 | 303 | @Override |
| 278 | 304 | public PageResult<MemberUserDO> getUserPage(MemberUserPageReqVO pageReqVO) { |
| 279 | 305 | return memberUserMapper.selectPage(pageReqVO); | ... | ... |
yudao-module-member/src/test/resources/sql/create_tables.sql
| ... | ... | @@ -11,6 +11,7 @@ CREATE TABLE IF NOT EXISTS "member_user" |
| 11 | 11 | "avatar" varchar(255) NOT NULL DEFAULT '' COMMENT '头像', |
| 12 | 12 | "status" tinyint NOT NULL COMMENT '状态', |
| 13 | 13 | "mobile" varchar(11) NOT NULL COMMENT '手机号', |
| 14 | + "email" varchar(50) NULL COMMENT '邮箱', | |
| 14 | 15 | "password" varchar(100) NOT NULL DEFAULT '' COMMENT '密码', |
| 15 | 16 | "register_ip" varchar(32) NOT NULL COMMENT '注册 IP', |
| 16 | 17 | "login_ip" varchar(50) NULL DEFAULT '' COMMENT '最后登录IP', | ... | ... |