Commit e8c1bdde3de9edc6b45bc1f4261174b32eb9fc9c

Authored by YunaiV
1 parent 61fbb990

会员中心:会员管理 50%

Showing 15 changed files with 348 additions and 43 deletions
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java
@@ -23,6 +23,8 @@ public class DateUtils { @@ -23,6 +23,8 @@ public class DateUtils {
23 */ 23 */
24 public static final long SECOND_MILLIS = 1000; 24 public static final long SECOND_MILLIS = 1000;
25 25
  26 + public static final String FORMAT_YEAR_MONTH_DAY = "yyyy-MM-dd";
  27 +
26 public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss"; 28 public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss";
27 29
28 public static final String FORMAT_HOUR_MINUTE_SECOND = "HH:mm:ss"; 30 public static final String FORMAT_HOUR_MINUTE_SECOND = "HH:mm:ss";
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/index.vue.vm
@@ -120,7 +120,6 @@ @@ -120,7 +120,6 @@
120 <!-- 列表 --> 120 <!-- 列表 -->
121 <ContentWrap> 121 <ContentWrap>
122 <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"> 122 <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
123 - <el-table-column label="序号" type="index" width="70px" />  
124 #foreach($column in $columns) 123 #foreach($column in $columns)
125 #if ($column.listOperationResult) 124 #if ($column.listOperationResult)
126 #set ($dictType=$column.dictType) 125 #set ($dictType=$column.dictType)
@@ -142,7 +141,7 @@ @@ -142,7 +141,7 @@
142 </template> 141 </template>
143 </el-table-column> 142 </el-table-column>
144 #else 143 #else
145 - <el-table-column label="${comment}" align="center" prop="${javaField}" width="150px"/> 144 + <el-table-column label="${comment}" align="center" prop="${javaField}" width="150px" />
146 #end 145 #end
147 #end 146 #end
148 #end 147 #end
@@ -180,7 +179,7 @@ @@ -180,7 +179,7 @@
180 <${simpleClassName}Form ref="formRef" @success="getList" /> 179 <${simpleClassName}Form ref="formRef" @success="getList" />
181 </template> 180 </template>
182 181
183 -<script setup lang="ts" name="${table.className}"> 182 +<script setup lang="ts">
184 #if ($dictMethods.size() > 0) 183 #if ($dictMethods.size() > 0)
185 import { DICT_TYPE#foreach ($dictMethod in $dictMethods), ${dictMethod}#end } from '@/utils/dict' 184 import { DICT_TYPE#foreach ($dictMethod in $dictMethods), ${dictMethod}#end } from '@/utils/dict'
186 #end 185 #end
@@ -193,6 +192,9 @@ import { dateFormatter } from &#39;@/utils/formatTime&#39; @@ -193,6 +192,9 @@ import { dateFormatter } from &#39;@/utils/formatTime&#39;
193 import download from '@/utils/download' 192 import download from '@/utils/download'
194 import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${classNameVar}' 193 import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${classNameVar}'
195 import ${simpleClassName}Form from './${simpleClassName}Form.vue' 194 import ${simpleClassName}Form from './${simpleClassName}Form.vue'
  195 +
  196 +defineOptions({ name: '${table.className}' })
  197 +
196 const message = useMessage() // 消息弹窗 198 const message = useMessage() // 消息弹窗
197 const { t } = useI18n() // 国际化 199 const { t } = useI18n() // 国际化
198 200
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApiImpl.java
1 package cn.iocoder.yudao.module.member.api.user; 1 package cn.iocoder.yudao.module.member.api.user;
2 2
3 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; 3 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
4 -import cn.iocoder.yudao.module.member.convert.user.UserConvert; 4 +import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert;
5 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; 5 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
6 import cn.iocoder.yudao.module.member.service.user.MemberUserService; 6 import cn.iocoder.yudao.module.member.service.user.MemberUserService;
7 import org.springframework.stereotype.Service; 7 import org.springframework.stereotype.Service;
@@ -26,22 +26,22 @@ public class MemberUserApiImpl implements MemberUserApi { @@ -26,22 +26,22 @@ public class MemberUserApiImpl implements MemberUserApi {
26 @Override 26 @Override
27 public MemberUserRespDTO getUser(Long id) { 27 public MemberUserRespDTO getUser(Long id) {
28 MemberUserDO user = userService.getUser(id); 28 MemberUserDO user = userService.getUser(id);
29 - return UserConvert.INSTANCE.convert2(user); 29 + return MemberUserConvert.INSTANCE.convert2(user);
30 } 30 }
31 31
32 @Override 32 @Override
33 public List<MemberUserRespDTO> getUserList(Collection<Long> ids) { 33 public List<MemberUserRespDTO> getUserList(Collection<Long> ids) {
34 - return UserConvert.INSTANCE.convertList2(userService.getUserList(ids)); 34 + return MemberUserConvert.INSTANCE.convertList2(userService.getUserList(ids));
35 } 35 }
36 36
37 @Override 37 @Override
38 public List<MemberUserRespDTO> getUserListByNickname(String nickname) { 38 public List<MemberUserRespDTO> getUserListByNickname(String nickname) {
39 - return UserConvert.INSTANCE.convertList2(userService.getUserListByNickname(nickname)); 39 + return MemberUserConvert.INSTANCE.convertList2(userService.getUserListByNickname(nickname));
40 } 40 }
41 41
42 @Override 42 @Override
43 public MemberUserRespDTO getUserByMobile(String mobile) { 43 public MemberUserRespDTO getUserByMobile(String mobile) {
44 - return UserConvert.INSTANCE.convert2(userService.getUserByMobile(mobile)); 44 + return MemberUserConvert.INSTANCE.convert2(userService.getUserByMobile(mobile));
45 } 45 }
46 46
47 } 47 }
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/MemberUserController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.member.controller.admin.user;
  2 +
  3 +import org.springframework.web.bind.annotation.*;
  4 +import javax.annotation.Resource;
  5 +import org.springframework.validation.annotation.Validated;
  6 +import org.springframework.security.access.prepost.PreAuthorize;
  7 +import io.swagger.v3.oas.annotations.tags.Tag;
  8 +import io.swagger.v3.oas.annotations.Parameter;
  9 +import io.swagger.v3.oas.annotations.Operation;
  10 +
  11 +import javax.validation.*;
  12 +
  13 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  14 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  15 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  16 +
  17 +import cn.iocoder.yudao.module.member.controller.admin.user.vo.*;
  18 +import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
  19 +import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert;
  20 +import cn.iocoder.yudao.module.member.service.user.MemberUserService;
  21 +
  22 +@Tag(name = "管理后台 - 会员用户")
  23 +@RestController
  24 +@RequestMapping("/member/user")
  25 +@Validated
  26 +public class MemberUserController {
  27 +
  28 + @Resource
  29 + private MemberUserService memberUserService;
  30 +
  31 + @PutMapping("/update")
  32 + @Operation(summary = "更新会员用户")
  33 + @PreAuthorize("@ss.hasPermission('member:user:update')")
  34 + public CommonResult<Boolean> updateUser(@Valid @RequestBody MemberUserUpdateReqVO updateReqVO) {
  35 + memberUserService.updateUser(updateReqVO);
  36 + return success(true);
  37 + }
  38 +
  39 + @GetMapping("/get")
  40 + @Operation(summary = "获得会员用户")
  41 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  42 + @PreAuthorize("@ss.hasPermission('member:user:query')")
  43 + public CommonResult<MemberUserRespVO> getUser(@RequestParam("id") Long id) {
  44 + MemberUserDO user = memberUserService.getUser(id);
  45 + return success(MemberUserConvert.INSTANCE.convert03(user));
  46 + }
  47 +
  48 + @GetMapping("/page")
  49 + @Operation(summary = "获得会员用户分页")
  50 + @PreAuthorize("@ss.hasPermission('member:user:query')")
  51 + public CommonResult<PageResult<MemberUserRespVO>> getUserPage(@Valid MemberUserPageReqVO pageVO) {
  52 + PageResult<MemberUserDO> pageResult = memberUserService.getUserPage(pageVO);
  53 + return success(MemberUserConvert.INSTANCE.convertPage(pageResult));
  54 + }
  55 +
  56 +}
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/package-info.java deleted
1 -package cn.iocoder.yudao.module.member.controller.admin.user;  
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/vo/MemberUserBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.member.controller.admin.user.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import org.springframework.format.annotation.DateTimeFormat;
  6 +
  7 +import javax.validation.constraints.NotNull;
  8 +import java.time.LocalDateTime;
  9 +
  10 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
  11 +
  12 +/**
  13 + * 会员用户 Base VO,提供给添加、修改、详细的子 VO 使用
  14 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  15 + */
  16 +@Data
  17 +public class MemberUserBaseVO {
  18 +
  19 + @Schema(description = "手机号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15601691300")
  20 + @NotNull(message = "手机号不能为空")
  21 + private String mobile;
  22 +
  23 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  24 + @NotNull(message = "状态不能为空")
  25 + private Byte status;
  26 +
  27 + @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
  28 + @NotNull(message = "用户昵称不能为空")
  29 + private String nickname;
  30 +
  31 + @Schema(description = "用户昵称", example = "李四")
  32 + private String name;
  33 +
  34 + @Schema(description = "用户性别", example = "1")
  35 + private Byte sex;
  36 +
  37 + @Schema(description = "所在地", example = "4371")
  38 + private Long areaId;
  39 +
  40 + @Schema(description = "出生日期", example = "2023-03-12")
  41 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
  42 + private LocalDateTime birthday;
  43 +
  44 + @Schema(description = "会员备注", example = "我是小备注")
  45 + private String mark;
  46 +
  47 +}
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/vo/MemberUserPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.member.controller.admin.user.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +import org.springframework.format.annotation.DateTimeFormat;
  9 +
  10 +import java.time.LocalDateTime;
  11 +
  12 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  13 +
  14 +@Schema(description = "管理后台 - 会员用户分页 Request VO")
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +@ToString(callSuper = true)
  18 +public class MemberUserPageReqVO extends PageParam {
  19 +
  20 + @Schema(description = "手机号", example = "15601691300")
  21 + private String mobile;
  22 +
  23 + @Schema(description = "用户昵称", example = "李四")
  24 + private String nickname;
  25 +
  26 + @Schema(description = "最后登录时间")
  27 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  28 + private LocalDateTime[] loginDate;
  29 +
  30 + @Schema(description = "创建时间")
  31 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  32 + private LocalDateTime[] createTime;
  33 +
  34 +}
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/vo/MemberUserRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.member.controller.admin.user.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.*;
  5 +
  6 +import javax.validation.constraints.NotNull;
  7 +import java.time.LocalDateTime;
  8 +
  9 +@Schema(description = "管理后台 - 会员用户 Response VO")
  10 +@Data
  11 +@EqualsAndHashCode(callSuper = true)
  12 +@ToString(callSuper = true)
  13 +public class MemberUserRespVO extends MemberUserBaseVO {
  14 +
  15 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23788")
  16 + private Long id;
  17 +
  18 + @Schema(description = "注册 IP", requiredMode = Schema.RequiredMode.REQUIRED, example = "127.0.0.1")
  19 + private String registerIp;
  20 +
  21 + @Schema(description = "最后登录IP", requiredMode = Schema.RequiredMode.REQUIRED, example = "127.0.0.1")
  22 + private String loginIp;
  23 +
  24 + @Schema(description = "最后登录时间", requiredMode = Schema.RequiredMode.REQUIRED)
  25 + private LocalDateTime loginDate;
  26 +
  27 + @Schema(description = "头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/x.png")
  28 + @NotNull(message = "头像不能为空")
  29 + private String avatar;
  30 +
  31 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  32 + private LocalDateTime createTime;
  33 +
  34 +}
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/vo/MemberUserUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.member.controller.admin.user.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +import javax.validation.constraints.NotNull;
  9 +
  10 +@Schema(description = "管理后台 - 会员用户更新 Request VO")
  11 +@Data
  12 +@EqualsAndHashCode(callSuper = true)
  13 +@ToString(callSuper = true)
  14 +public class MemberUserUpdateReqVO extends MemberUserBaseVO {
  15 +
  16 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23788")
  17 + @NotNull(message = "编号不能为空")
  18 + private Long id;
  19 +
  20 +}
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppUserController.java
@@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; @@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; 4 import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
5 import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserInfoRespVO; 5 import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserInfoRespVO;
6 import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserUpdateMobileReqVO; 6 import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserUpdateMobileReqVO;
7 -import cn.iocoder.yudao.module.member.convert.user.UserConvert; 7 +import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert;
8 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; 8 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
9 import cn.iocoder.yudao.module.member.service.user.MemberUserService; 9 import cn.iocoder.yudao.module.member.service.user.MemberUserService;
10 import io.swagger.v3.oas.annotations.tags.Tag; 10 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -56,7 +56,7 @@ public class AppUserController { @@ -56,7 +56,7 @@ public class AppUserController {
56 @PreAuthenticated 56 @PreAuthenticated
57 public CommonResult<AppUserInfoRespVO> getUserInfo() { 57 public CommonResult<AppUserInfoRespVO> getUserInfo() {
58 MemberUserDO user = userService.getUser(getLoginUserId()); 58 MemberUserDO user = userService.getUser(getLoginUserId());
59 - return success(UserConvert.INSTANCE.convert(user)); 59 + return success(MemberUserConvert.INSTANCE.convert(user));
60 } 60 }
61 61
62 @PostMapping("/update-mobile") 62 @PostMapping("/update-mobile")
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/user/UserConvert.java renamed to yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/user/MemberUserConvert.java
1 package cn.iocoder.yudao.module.member.convert.user; 1 package cn.iocoder.yudao.module.member.convert.user;
2 2
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
3 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; 4 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
  5 +import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserRespVO;
  6 +import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateReqVO;
4 import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserInfoRespVO; 7 import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserInfoRespVO;
5 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; 8 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
6 import org.mapstruct.Mapper; 9 import org.mapstruct.Mapper;
@@ -9,9 +12,9 @@ import org.mapstruct.factory.Mappers; @@ -9,9 +12,9 @@ import org.mapstruct.factory.Mappers;
9 import java.util.List; 12 import java.util.List;
10 13
11 @Mapper 14 @Mapper
12 -public interface UserConvert { 15 +public interface MemberUserConvert {
13 16
14 - UserConvert INSTANCE = Mappers.getMapper(UserConvert.class); 17 + MemberUserConvert INSTANCE = Mappers.getMapper(MemberUserConvert.class);
15 18
16 AppUserInfoRespVO convert(MemberUserDO bean); 19 AppUserInfoRespVO convert(MemberUserDO bean);
17 20
@@ -19,4 +22,10 @@ public interface UserConvert { @@ -19,4 +22,10 @@ public interface UserConvert {
19 22
20 List<MemberUserRespDTO> convertList2(List<MemberUserDO> list); 23 List<MemberUserRespDTO> convertList2(List<MemberUserDO> list);
21 24
  25 + MemberUserDO convert(MemberUserUpdateReqVO bean);
  26 +
  27 + PageResult<MemberUserRespVO> convertPage(PageResult<MemberUserDO> page);
  28 +
  29 + MemberUserRespVO convert03(MemberUserDO bean);
  30 +
22 } 31 }
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/user/MemberUserDO.java
1 package cn.iocoder.yudao.module.member.dal.dataobject.user; 1 package cn.iocoder.yudao.module.member.dal.dataobject.user;
2 2
3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.ip.core.Area;
4 import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; 5 import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
  6 +import cn.iocoder.yudao.module.system.enums.common.SexEnum;
5 import com.baomidou.mybatisplus.annotation.KeySequence; 7 import com.baomidou.mybatisplus.annotation.KeySequence;
6 import com.baomidou.mybatisplus.annotation.TableId; 8 import com.baomidou.mybatisplus.annotation.TableId;
7 import com.baomidou.mybatisplus.annotation.TableName; 9 import com.baomidou.mybatisplus.annotation.TableName;
@@ -26,27 +28,14 @@ import java.time.LocalDateTime; @@ -26,27 +28,14 @@ import java.time.LocalDateTime;
26 @AllArgsConstructor 28 @AllArgsConstructor
27 public class MemberUserDO extends TenantBaseDO { 29 public class MemberUserDO extends TenantBaseDO {
28 30
  31 + // ========== 账号信息 ==========
  32 +
29 /** 33 /**
30 * 用户ID 34 * 用户ID
31 */ 35 */
32 @TableId 36 @TableId
33 private Long id; 37 private Long id;
34 /** 38 /**
35 - * 用户昵称  
36 - */  
37 - private String nickname;  
38 - /**  
39 - * 用户头像  
40 - */  
41 - private String avatar;  
42 - /**  
43 - * 帐号状态  
44 - *  
45 - * 枚举 {@link CommonStatusEnum}  
46 - */  
47 - private Integer status;  
48 -  
49 - /**  
50 * 手机 39 * 手机
51 */ 40 */
52 private String mobile; 41 private String mobile;
@@ -57,6 +46,12 @@ public class MemberUserDO extends TenantBaseDO { @@ -57,6 +46,12 @@ public class MemberUserDO extends TenantBaseDO {
57 */ 46 */
58 private String password; 47 private String password;
59 /** 48 /**
  49 + * 帐号状态
  50 + *
  51 + * 枚举 {@link CommonStatusEnum}
  52 + */
  53 + private Integer status;
  54 + /**
60 * 注册 IP 55 * 注册 IP
61 */ 56 */
62 private String registerIp; 57 private String registerIp;
@@ -69,10 +64,44 @@ public class MemberUserDO extends TenantBaseDO { @@ -69,10 +64,44 @@ public class MemberUserDO extends TenantBaseDO {
69 */ 64 */
70 private LocalDateTime loginDate; 65 private LocalDateTime loginDate;
71 66
72 - // TODO 芋艿:name 真实名字;  
73 - // TODO 芋艿:email 邮箱;  
74 - // TODO 芋艿:gender 性别;  
75 - // TODO 芋艿:score 积分;  
76 - // TODO 芋艿:payPassword 支付密码; 67 + // ========== 基础信息 ==========
  68 +
  69 + /**
  70 + * 用户昵称
  71 + */
  72 + private String nickname;
  73 + /**
  74 + * 用户头像
  75 + */
  76 + private String avatar;
  77 +
  78 + /**
  79 + * 真实名字
  80 + */
  81 + private String name;
  82 + /**
  83 + * 性别
  84 + *
  85 + * 枚举 {@link SexEnum}
  86 + */
  87 + private Integer sex;
  88 + /**
  89 + * 出生日期
  90 + */
  91 + private LocalDateTime birthday;
  92 + /**
  93 + * 所在地
  94 + *
  95 + * 关联 {@link Area#getId()} 字段
  96 + */
  97 + private Integer areaId;
  98 + /**
  99 + * 用户备注
  100 + */
  101 + private String mark;
  102 +
  103 + // ========== 其它信息 ==========
  104 +
  105 + // TODO 积分、成长值、会员等级等等
77 106
78 } 107 }
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/user/MemberUserMapper.java
1 package cn.iocoder.yudao.module.member.dal.mysql.user; 1 package cn.iocoder.yudao.module.member.dal.mysql.user;
2 2
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
3 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
4 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserPageReqVO;
5 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; 7 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
6 import org.apache.ibatis.annotations.Mapper; 8 import org.apache.ibatis.annotations.Mapper;
7 9
@@ -24,4 +26,13 @@ public interface MemberUserMapper extends BaseMapperX&lt;MemberUserDO&gt; { @@ -24,4 +26,13 @@ public interface MemberUserMapper extends BaseMapperX&lt;MemberUserDO&gt; {
24 .likeIfPresent(MemberUserDO::getNickname, nickname)); 26 .likeIfPresent(MemberUserDO::getNickname, nickname));
25 } 27 }
26 28
  29 + default PageResult<MemberUserDO> selectPage(MemberUserPageReqVO reqVO) {
  30 + return selectPage(reqVO, new LambdaQueryWrapperX<MemberUserDO>()
  31 + .likeIfPresent(MemberUserDO::getMobile, reqVO.getMobile())
  32 + .betweenIfPresent(MemberUserDO::getLoginDate, reqVO.getLoginDate())
  33 + .likeIfPresent(MemberUserDO::getNickname, reqVO.getNickname())
  34 + .betweenIfPresent(MemberUserDO::getCreateTime, reqVO.getCreateTime())
  35 + .orderByDesc(MemberUserDO::getId));
  36 + }
  37 +
27 } 38 }
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserService.java
1 package cn.iocoder.yudao.module.member.service.user; 1 package cn.iocoder.yudao.module.member.service.user;
2 2
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
3 import cn.iocoder.yudao.framework.common.validation.Mobile; 4 import cn.iocoder.yudao.framework.common.validation.Mobile;
  5 +import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserPageReqVO;
  6 +import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateReqVO;
4 import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserUpdateMobileReqVO; 7 import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserUpdateMobileReqVO;
5 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; 8 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
6 9
  10 +import javax.validation.Valid;
7 import java.io.InputStream; 11 import java.io.InputStream;
8 import java.util.Collection; 12 import java.util.Collection;
9 import java.util.List; 13 import java.util.List;
@@ -66,14 +70,16 @@ public interface MemberUserService { @@ -66,14 +70,16 @@ public interface MemberUserService {
66 List<MemberUserDO> getUserList(Collection<Long> ids); 70 List<MemberUserDO> getUserList(Collection<Long> ids);
67 71
68 /** 72 /**
69 - * 修改用户昵称 73 + * 【会员】修改用户昵称
  74 + *
70 * @param userId 用户id 75 * @param userId 用户id
71 * @param nickname 用户新昵称 76 * @param nickname 用户新昵称
72 */ 77 */
73 void updateUserNickname(Long userId, String nickname); 78 void updateUserNickname(Long userId, String nickname);
74 79
75 /** 80 /**
76 - * 修改用户头像 81 + * 【会员】修改用户头像
  82 + *
77 * @param userId 用户id 83 * @param userId 用户id
78 * @param inputStream 头像文件 84 * @param inputStream 头像文件
79 * @return 头像url 85 * @return 头像url
@@ -81,7 +87,8 @@ public interface MemberUserService { @@ -81,7 +87,8 @@ public interface MemberUserService {
81 String updateUserAvatar(Long userId, InputStream inputStream) throws Exception; 87 String updateUserAvatar(Long userId, InputStream inputStream) throws Exception;
82 88
83 /** 89 /**
84 - * 修改手机 90 + * 【会员】修改手机
  91 + *
85 * @param userId 用户id 92 * @param userId 用户id
86 * @param reqVO 请求实体 93 * @param reqVO 请求实体
87 */ 94 */
@@ -96,4 +103,19 @@ public interface MemberUserService { @@ -96,4 +103,19 @@ public interface MemberUserService {
96 */ 103 */
97 boolean isPasswordMatch(String rawPassword, String encodedPassword); 104 boolean isPasswordMatch(String rawPassword, String encodedPassword);
98 105
  106 + /**
  107 + * 【管理员】更新会员用户
  108 + *
  109 + * @param updateReqVO 更新信息
  110 + */
  111 + void updateUser(@Valid MemberUserUpdateReqVO updateReqVO);
  112 +
  113 + /**
  114 + * 【管理员】获得会员用户分页
  115 + *
  116 + * @param pageReqVO 分页查询
  117 + * @return 会员用户分页
  118 + */
  119 + PageResult<MemberUserDO> getUserPage(MemberUserPageReqVO pageReqVO);
  120 +
99 } 121 }
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java
@@ -2,9 +2,14 @@ package cn.iocoder.yudao.module.member.service.user; @@ -2,9 +2,14 @@ package cn.iocoder.yudao.module.member.service.user;
2 2
3 import cn.hutool.core.io.IoUtil; 3 import cn.hutool.core.io.IoUtil;
4 import cn.hutool.core.util.IdUtil; 4 import cn.hutool.core.util.IdUtil;
  5 +import cn.hutool.core.util.StrUtil;
5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 6 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  7 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.module.infra.api.file.FileApi; 8 import cn.iocoder.yudao.module.infra.api.file.FileApi;
  9 +import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserPageReqVO;
  10 +import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateReqVO;
7 import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserUpdateMobileReqVO; 11 import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserUpdateMobileReqVO;
  12 +import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert;
8 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; 13 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
9 import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper; 14 import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
10 import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; 15 import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
@@ -19,14 +24,14 @@ import org.springframework.transaction.annotation.Transactional; @@ -19,14 +24,14 @@ import org.springframework.transaction.annotation.Transactional;
19 import javax.annotation.Resource; 24 import javax.annotation.Resource;
20 import javax.validation.Valid; 25 import javax.validation.Valid;
21 import java.io.InputStream; 26 import java.io.InputStream;
  27 +import java.time.LocalDateTime;
22 import java.util.Collection; 28 import java.util.Collection;
23 -import java.util.Date;  
24 import java.util.List; 29 import java.util.List;
25 -import java.time.LocalDateTime;  
26 30
27 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 31 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
28 import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; 32 import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
29 import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.USER_NOT_EXISTS; 33 import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.USER_NOT_EXISTS;
  34 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_MOBILE_EXISTS;
30 35
31 /** 36 /**
32 * 会员 User Service 实现类 37 * 会员 User Service 实现类
@@ -101,7 +106,7 @@ public class MemberUserServiceImpl implements MemberUserService { @@ -101,7 +106,7 @@ public class MemberUserServiceImpl implements MemberUserService {
101 106
102 @Override 107 @Override
103 public void updateUserNickname(Long userId, String nickname) { 108 public void updateUserNickname(Long userId, String nickname) {
104 - MemberUserDO user = this.checkUserExists(userId); 109 + MemberUserDO user = this.validateUserExists(userId);
105 // 仅当新昵称不等于旧昵称时进行修改 110 // 仅当新昵称不等于旧昵称时进行修改
106 if (nickname.equals(user.getNickname())){ 111 if (nickname.equals(user.getNickname())){
107 return; 112 return;
@@ -113,8 +118,8 @@ public class MemberUserServiceImpl implements MemberUserService { @@ -113,8 +118,8 @@ public class MemberUserServiceImpl implements MemberUserService {
113 } 118 }
114 119
115 @Override 120 @Override
116 - public String updateUserAvatar(Long userId, InputStream avatarFile) throws Exception {  
117 - this.checkUserExists(userId); 121 + public String updateUserAvatar(Long userId, InputStream avatarFile) {
  122 + validateUserExists(userId);
118 // 创建文件 123 // 创建文件
119 String avatar = fileApi.createFile(IoUtil.readBytes(avatarFile)); 124 String avatar = fileApi.createFile(IoUtil.readBytes(avatarFile));
120 // 更新头像路径 125 // 更新头像路径
@@ -126,7 +131,7 @@ public class MemberUserServiceImpl implements MemberUserService { @@ -126,7 +131,7 @@ public class MemberUserServiceImpl implements MemberUserService {
126 @Transactional(rollbackFor = Exception.class) 131 @Transactional(rollbackFor = Exception.class)
127 public void updateUserMobile(Long userId, AppUserUpdateMobileReqVO reqVO) { 132 public void updateUserMobile(Long userId, AppUserUpdateMobileReqVO reqVO) {
128 // 检测用户是否存在 133 // 检测用户是否存在
129 - checkUserExists(userId); 134 + validateUserExists(userId);
130 // TODO 芋艿:oldMobile 应该不用传递 135 // TODO 芋艿:oldMobile 应该不用传递
131 136
132 // 校验旧手机和旧验证码 137 // 校验旧手机和旧验证码
@@ -155,8 +160,20 @@ public class MemberUserServiceImpl implements MemberUserService { @@ -155,8 +160,20 @@ public class MemberUserServiceImpl implements MemberUserService {
155 return passwordEncoder.encode(password); 160 return passwordEncoder.encode(password);
156 } 161 }
157 162
  163 + @Override
  164 + public void updateUser(MemberUserUpdateReqVO updateReqVO) {
  165 + // 校验存在
  166 + validateUserExists(updateReqVO.getId());
  167 + // 校验手机唯一
  168 + validateMobileUnique(updateReqVO.getId(), updateReqVO.getMobile());
  169 +
  170 + // 更新
  171 + MemberUserDO updateObj = MemberUserConvert.INSTANCE.convert(updateReqVO);
  172 + memberUserMapper.updateById(updateObj);
  173 + }
  174 +
158 @VisibleForTesting 175 @VisibleForTesting
159 - public MemberUserDO checkUserExists(Long id) { 176 + MemberUserDO validateUserExists(Long id) {
160 if (id == null) { 177 if (id == null) {
161 return null; 178 return null;
162 } 179 }
@@ -167,4 +184,27 @@ public class MemberUserServiceImpl implements MemberUserService { @@ -167,4 +184,27 @@ public class MemberUserServiceImpl implements MemberUserService {
167 return user; 184 return user;
168 } 185 }
169 186
  187 + @VisibleForTesting
  188 + void validateMobileUnique(Long id, String mobile) {
  189 + if (StrUtil.isBlank(mobile)) {
  190 + return;
  191 + }
  192 + MemberUserDO user = memberUserMapper.selectByMobile(mobile);
  193 + if (user == null) {
  194 + return;
  195 + }
  196 + // 如果 id 为空,说明不用比较是否为相同 id 的用户
  197 + if (id == null) {
  198 + throw exception(USER_MOBILE_EXISTS);
  199 + }
  200 + if (!user.getId().equals(id)) {
  201 + throw exception(USER_MOBILE_EXISTS);
  202 + }
  203 + }
  204 +
  205 + @Override
  206 + public PageResult<MemberUserDO> getUserPage(MemberUserPageReqVO pageReqVO) {
  207 + return memberUserMapper.selectPage(pageReqVO);
  208 + }
  209 +
170 } 210 }