Browse Source

会员管理代码

wwh 2 weeks ago
parent
commit
22efecaffd

+ 2 - 2
baqing-shop/src/main/java/com/ruoyi/web/modules/account/constant/MemberConstants.java

@@ -30,8 +30,8 @@ public final class MemberConstants
30 30
 
31 31
     public static final String DICT_MEMBER_LEVEL = "biz_member_level";
32 32
 
33
-    /** C 端会员角色 role_key */
34
-    public static final String MEMBER_ROLE_KEY = "102";
33
+    /** C 端会员角色 role_key(权限字符 member) */
34
+    public static final String MEMBER_ROLE_KEY = "member";
35 35
 
36 36
     public static final String REDIS_SMS_PREFIX = "member:sms:";
37 37
 

+ 15 - 0
baqing-shop/src/main/java/com/ruoyi/web/modules/account/domain/BizMember.java

@@ -3,6 +3,7 @@ package com.ruoyi.web.modules.account.domain;
3 3
 import java.math.BigDecimal;
4 4
 import java.util.Date;
5 5
 import com.fasterxml.jackson.annotation.JsonFormat;
6
+import com.fasterxml.jackson.annotation.JsonIgnore;
6 7
 import com.ruoyi.common.core.domain.BaseEntity;
7 8
 
8 9
 /**
@@ -42,6 +43,10 @@ public class BizMember extends BaseEntity
42 43
     /** 列表检索:会员名称、昵称或手机号模糊 */
43 44
     private String keyword;
44 45
 
46
+    /** 内部查询:会员角色 role_key(列表仅查 member 角色) */
47
+    @JsonIgnore
48
+    private String memberRoleKey;
49
+
45 50
     public Long getMemberId()
46 51
     {
47 52
         return memberId;
@@ -171,4 +176,14 @@ public class BizMember extends BaseEntity
171 176
     {
172 177
         this.keyword = keyword;
173 178
     }
179
+
180
+    public String getMemberRoleKey()
181
+    {
182
+        return memberRoleKey;
183
+    }
184
+
185
+    public void setMemberRoleKey(String memberRoleKey)
186
+    {
187
+        this.memberRoleKey = memberRoleKey;
188
+    }
174 189
 }

+ 13 - 0
baqing-shop/src/main/java/com/ruoyi/web/modules/account/dto/MemberCreateDTO.java

@@ -17,6 +17,9 @@ public class MemberCreateDTO
17 17
     /** 昵称(选填,未填则同会员名称) */
18 18
     private String nickName;
19 19
 
20
+    /** 头像 URL(选填,写入 sys_user.avatar) */
21
+    private String avatar;
22
+
20 23
     /** 会员等级(选填) */
21 24
     private Integer memberLevel;
22 25
 
@@ -66,6 +69,16 @@ public class MemberCreateDTO
66 69
         this.nickName = nickName;
67 70
     }
68 71
 
72
+    public String getAvatar()
73
+    {
74
+        return avatar;
75
+    }
76
+
77
+    public void setAvatar(String avatar)
78
+    {
79
+        this.avatar = avatar;
80
+    }
81
+
69 82
     public Integer getMemberLevel()
70 83
     {
71 84
         return memberLevel;

+ 5 - 0
baqing-shop/src/main/java/com/ruoyi/web/modules/account/service/impl/MemberServiceImpl.java

@@ -45,6 +45,11 @@ public class MemberServiceImpl implements IMemberService
45 45
     @Override
46 46
     public List<MemberListVO> selectMemberList(BizMember query)
47 47
     {
48
+        if (query == null)
49
+        {
50
+            query = new BizMember();
51
+        }
52
+        query.setMemberRoleKey(MemberConstants.MEMBER_ROLE_KEY);
48 53
         List<BizMember> list = memberMapper.selectList(query);
49 54
         List<MemberListVO> rows = new ArrayList<>();
50 55
         for (BizMember m : list)

+ 2 - 1
baqing-shop/src/main/java/com/ruoyi/web/modules/account/support/MemberRegistrationSupport.java

@@ -17,7 +17,7 @@ import com.ruoyi.web.modules.account.mapper.BizMemberMapper;
17 17
 import com.ruoyi.web.modules.account.util.UserNameGenerator;
18 18
 
19 19
 /**
20
- * 会员注册/创建(C 端与平台端共用:先 sys_user 角色 102,再 biz_member)
20
+ * 会员注册/创建(C 端与平台端共用:先 sys_user + 角色 member,再 biz_member)
21 21
  */
22 22
 @Component
23 23
 public class MemberRegistrationSupport
@@ -54,6 +54,7 @@ public class MemberRegistrationSupport
54 54
         sysUser.setNickName(nickName);
55 55
         sysUser.setPhonenumber(dto.getMobile());
56 56
         sysUser.setPassword(SecurityUtils.encryptPassword(dto.getPassword()));
57
+        sysUser.setAvatar(dto.getAvatar());
57 58
         sysUser.setStatus(status);
58 59
         sysUser.setCreateBy(operator);
59 60
         Long memberRoleId = memberSysUserSupport.resolveMemberRoleId();

+ 1 - 1
baqing-shop/src/main/java/com/ruoyi/web/modules/account/support/MemberSysUserSupport.java

@@ -13,7 +13,7 @@ import com.ruoyi.web.modules.account.constant.MemberConstants;
13 13
 import com.ruoyi.web.modules.merchant.mapper.MerchantBindMapper;
14 14
 
15 15
 /**
16
- * 会员与 sys_user 复用:角色 102、追加角色等
16
+ * 会员与 sys_user 复用:角色 member、追加角色等
17 17
  */
18 18
 @Component
19 19
 public class MemberSysUserSupport

+ 2 - 2
baqing-shop/src/main/java/com/ruoyi/web/modules/merchant/constant/MerchantBindConstants.java

@@ -15,8 +15,8 @@ public final class MerchantBindConstants
15 15
     /** 绑定 C 端会员(biz_member) */
16 16
     public static final String BIND_MEMBER = "MEMBER";
17 17
 
18
-    /** 商户经营端角色 role_key */
19
-    public static final String MERCHANT_ADMIN_ROLE_KEY = "100";
18
+    /** 商户经营端角色 role_key(权限字符 merchant) */
19
+    public static final String MERCHANT_ADMIN_ROLE_KEY = "merchant";
20 20
 
21 21
     public static final String MSG_BIND_REQUIRED = "请选择并绑定管理员账号或会员账号";
22 22
 

+ 1 - 2
baqing-shop/src/main/java/com/ruoyi/web/modules/merchant/service/impl/MerchantAccountBindServiceImpl.java

@@ -101,12 +101,11 @@ public class MerchantAccountBindServiceImpl implements IMerchantAccountBindServi
101 101
         {
102 102
             throw new ServiceException("会员账号不存在,无法绑定经营账号");
103 103
         }
104
-        memberSysUserSupport.grantRoleIfAbsent(memberId, MerchantBindConstants.MERCHANT_ADMIN_ROLE_KEY);
105
-
106 104
         if (merchantBindMapper.countUserHasRole(memberId, MemberConstants.MEMBER_ROLE_KEY) <= 0)
107 105
         {
108 106
             throw new ServiceException("所选用户不是会员账号");
109 107
         }
108
+        memberSysUserSupport.grantRoleIfAbsent(memberId, MerchantBindConstants.MERCHANT_ADMIN_ROLE_KEY);
110 109
 
111 110
         String loginName = member.getMemberCode();
112 111
         if (StringUtils.isEmpty(loginName))

+ 3 - 3
baqing-shop/src/main/resources/mapper/account/BizMemberMapper.xml

@@ -44,13 +44,13 @@
44 44
         inner join sys_user u on m.member_id = u.user_id
45 45
     </sql>
46 46
 
47
-    <sql id="memberRole102Exists">
47
+    <sql id="memberRoleExists">
48 48
         and exists (
49 49
             select 1
50 50
             from sys_user_role ur
51 51
             inner join sys_role r on ur.role_id = r.role_id and r.del_flag = '0' and r.status = '0'
52 52
             where ur.user_id = u.user_id
53
-              and (r.role_key = '102' or cast(r.role_id as char) = '102')
53
+              and r.role_key = #{memberRoleKey}
54 54
         )
55 55
     </sql>
56 56
 
@@ -67,7 +67,7 @@
67 67
     <select id="selectList" resultMap="BizMemberResult">
68 68
         <include refid="selectVo"/>
69 69
         where u.del_flag = '0'
70
-        <include refid="memberRole102Exists"/>
70
+        <include refid="memberRoleExists"/>
71 71
         <if test="status != null and status != ''">
72 72
             and u.status = #{status}
73 73
         </if>

+ 4 - 5
baqing-shop/src/main/resources/mapper/merchant/MerchantBindMapper.xml

@@ -11,11 +11,10 @@
11 11
         inner join sys_user_role ur on u.user_id = ur.user_id
12 12
         inner join sys_role r on ur.role_id = r.role_id and r.del_flag = '0' and r.status = '0'
13 13
         where u.del_flag = '0' and u.status = '0'
14
-          and (r.role_key = #{roleKey} or cast(r.role_id as char) = #{roleKey})
14
+          and r.role_key = #{roleKey}
15 15
         <if test="keyword != null and keyword != ''">
16 16
             and (
17 17
                 u.user_name like concat('%', #{keyword}, '%')
18
-                or u.nick_name like concat('%', #{keyword}, '%')
19 18
                 or u.phonenumber like concat('%', #{keyword}, '%')
20 19
             )
21 20
         </if>
@@ -32,7 +31,7 @@
32 31
         inner join sys_user_role ur on u.user_id = ur.user_id
33 32
         inner join sys_role r on ur.role_id = r.role_id and r.del_flag = '0' and r.status = '0'
34 33
         where u.del_flag = '0' and u.status = '0'
35
-          and (r.role_key = #{roleKey} or cast(r.role_id as char) = #{roleKey})
34
+          and r.role_key = #{roleKey}
36 35
         <if test="keyword != null and keyword != ''">
37 36
             and (
38 37
                 u.user_name like concat('%', #{keyword}, '%')
@@ -46,8 +45,8 @@
46 45
     <select id="countUserHasRole" resultType="int">
47 46
         select count(1)
48 47
         from sys_user_role ur
49
-        inner join sys_role r on ur.role_id = r.role_id and r.del_flag = '0'
48
+        inner join sys_role r on ur.role_id = r.role_id and r.del_flag = '0' and r.status = '0'
50 49
         where ur.user_id = #{userId}
51
-          and (r.role_key = #{roleKey} or cast(r.role_id as char) = #{roleKey})
50
+          and r.role_key = #{roleKey}
52 51
     </select>
53 52
 </mapper>

+ 5 - 5
doc/农资商城web/会员管理/会员管理技术方案.md

@@ -15,7 +15,7 @@
15 15
 | 数据库 | **MySQL 5.7.39** |
16 16
 | ORM / 权限 / 响应 | MyBatis;`@PreAuthorize`;`AjaxResult` / `TableDataInfo` |
17 17
 | 密码 | C 端 `SecurityUtils.encryptPassword`(BCrypt);存于 **`sys_user.password`** |
18
-| 账号 | **与 `sys_user` 复用**:`member_id = user_id`;会员角色 **role_key=102** |
18
+| 账号 | **与 `sys_user` 复用**:`member_id = user_id`;会员角色 **role_key=member** |
19 19
 | 脱敏 | 列表手机号中间 4 位 `*`(如 `177****9136`) |
20 20
 | 日志 | 启用状态变更 `@Log` |
21 21
 
@@ -52,7 +52,7 @@ sys_user(账号:user_name/phonenumber/nick_name/password/avatar/status)
52 52
 | 头像 | avatar | avatar |
53 53
 | 状态 | status(0正常 1停用) | status |
54 54
 
55
-**注册(事务):** `insertUser`(角色 **102**)→ `insert biz_member`(`member_id = userId`)。
55
+**注册(事务):** `insertUser`(角色 **member**)→ `insert biz_member`(`member_id = userId`)。
56 56
 
57 57
 | 模块 | 表/职责 |
58 58
 |------|---------|
@@ -126,7 +126,7 @@ sys_user(账号:user_name/phonenumber/nick_name/password/avatar/status)
126 126
 | password | BCrypt |
127 127
 | avatar | 头像 URL |
128 128
 | status | 0 启用 1 禁用 |
129
-| 角色 | 注册时分配 **role_key=102** |
129
+| 角色 | 注册时分配 **role_key=member** |
130 130
 
131 131
 ### 2.4 `biz_member_address`
132 132
 
@@ -240,7 +240,7 @@ CREATE TABLE `biz_member_address` (
240 240
 | status | 选填;默认 `0` 启用 |
241 241
 | remark | 选填 |
242 242
 
243
-**流程:** 同事务 `insertUser`(角色 **102**)→ `insert biz_member`(`member_id=user_id`)。  
243
+**流程:** 同事务 `insertUser`(角色 **member**)→ `insert biz_member`(`member_id=user_id`)。  
244 244
 **成功:** 返回 `memberId`。
245 245
 
246 246
 ### 3.2 列表 `GET /list`
@@ -251,7 +251,7 @@ CREATE TABLE `biz_member_address` (
251 251
 | keyword | 可选;**会员名称、昵称或手机号** 模糊(M11) |
252 252
 | status | 可选;0/1 |
253 253
 
254
-**过滤:** `del_flag='0'`;且 `sys_user` 须拥有 **会员角色 role_key=102**(排除仅平台/商户角色账号)。  
254
+**过滤:** `del_flag='0'`;且 `sys_user` 须拥有 **会员角色 role_key=member**(排除仅平台/商户角色账号)。  
255 255
 **排序:** 默认 `register_time DESC`(可扩展 `orderBy=total_amount`)。
256 256
 
257 257
 **rows:**

+ 1 - 1
doc/农资商城web/组织管理/商户管理/商户管理功能需求.md

@@ -200,7 +200,7 @@
200 200
 | 未选绑定类型 | 请选择并绑定管理员账号或会员账号 |
201 201
 | 选管理员但未选人 | 请选择平台管理员账号 |
202 202
 | 选会员但未选人 | 请选择会员账号 |
203
-| 用户无角色 100 | 所选用户未分配商户经营角色 |
203
+| 用户无 merchant 角色 | 所选用户未分配商户经营角色 |
204 204
 | 登录名已占用 | 经营账号登录名已存在 |
205 205
 | 会员无昵称 | 会员昵称不能为空,无法作为经营账号管理员姓名 |
206 206
 | 会员无名称 | 会员名称不能为空,无法作为经营账号登录名 |

+ 8 - 8
doc/农资商城web/组织管理/商户管理/商户管理技术方案.md

@@ -136,7 +136,7 @@ biz_merchant(商户)
136 136
 | GET | `/list` | 分页列表 |
137 137
 | GET | `/{merchantId}` | 详情 |
138 138
 | POST | `/` | 新增(主体资质 + 绑定账号,`MerchantCreateDTO`) |
139
-| GET | `/adminUserOptions` | 入驻可选平台管理员(角色 100) |
139
+| GET | `/adminUserOptions` | 入驻可选平台管理员(role_key=merchant) |
140 140
 | GET | `/memberOptions` | 入驻可选会员 |
141 141
 | PUT | `/` | 编辑 |
142 142
 | PUT | `/{merchantId}/certStatus` | 改认证状态(支持两步 confirm) |
@@ -190,7 +190,7 @@ biz_merchant(商户)
190 190
 
191 191
 | 响应 data[] | 说明 |
192 192
 |-------------|------|
193
-| userId, userName, nickName, phonenumber | 仅含 `sys_user` 且拥有 **角色 100** 的用户;最多 50 条 |
193
+| userId, userName, nickName, phonenumber | 仅含 `sys_user` 且拥有 **role_key=merchant** 的用户;最多 50 条 |
194 194
 
195 195
 权限:`agri:merchant:add`
196 196
 
@@ -202,7 +202,7 @@ biz_merchant(商户)
202 202
 
203 203
 | 响应 data[] | 说明 |
204 204
 |-------------|------|
205
-| memberId, memberCode, nickName, mobile | `sys_user` 且拥有 **角色 102**;`memberId=userId`;mobile 脱敏;最多 50 条 |
205
+| memberId, memberCode, nickName, mobile | `sys_user` 且拥有 **角色 member**;`memberId=userId`;mobile 脱敏;最多 50 条 |
206 206
 
207 207
 权限:`agri:merchant:add`
208 208
 
@@ -266,7 +266,7 @@ biz_merchant(商户)
266 266
 | R1 | **不设** 店铺数量上限;`shop_count` 仅统计;selectList / openShopCheck **不校验** 店数 |
267 267
 | R2 | `MerchantAccountBindServiceImpl`;`MerchantBindMapper` |
268 268
 | R12 | `BIND_SYS_USER`:`login_name=user_name`,`admin_name=nick_name` |
269
-| R13 | `BIND_MEMBER`:追加角色 100 + `biz_merchant_account`;见 §9.8 |
269
+| R13 | `BIND_MEMBER`:追加 role_key=merchant + `biz_merchant_account`;见 §9.8 |
270 270
 | R3 | insert `cert_status=0` + `cert_time` |
271 271
 | R4 | update 忽略 `merchantType` |
272 272
 | R5 | `certStatus` 仅 `PUT .../certStatus` |
@@ -443,7 +443,7 @@ biz_merchant(商户)
443 443
 | 批量删除失败 | 部分商户不满足删除条件,操作已取消 |
444 444
 | 状态不允许 | 不允许的认证状态变更 |
445 445
 | 未选绑定 | 请选择并绑定管理员账号或会员账号 |
446
-| 用户无角色 100 | 所选用户未分配商户经营角色 |
446
+| 用户无 merchant 角色 | 所选用户未分配商户经营角色 |
447 447
 | 登录名重复 | 经营账号登录名已存在 |
448 448
 | 会员无昵称 | 会员昵称不能为空,无法作为经营账号管理员姓名 |
449 449
 | 会员无名称 | 会员名称不能为空,无法作为经营账号登录名 |
@@ -453,8 +453,8 @@ biz_merchant(商户)
453 453
 | 字段 | 类型 | 必填 | 说明 |
454 454
 |------|------|:----:|------|
455 455
 | bindType | String | ✓ | `SYS_USER` 或 `MEMBER` |
456
-| bindUserId | Long | SYS_USER 时 ✓ | `sys_user.user_id`(角色 100) |
457
-| bindMemberId | Long | MEMBER 时 ✓ | `member_id = sys_user.user_id`(角色 102) |
456
+| bindUserId | Long | SYS_USER 时 ✓ | `sys_user.user_id`(role_key=merchant) |
457
+| bindMemberId | Long | MEMBER 时 ✓ | `member_id = sys_user.user_id`(角色 member) |
458 458
 
459 459
 **`BIND_SYS_USER` 落库 `biz_merchant_account`**
460 460
 
@@ -466,7 +466,7 @@ biz_merchant(商户)
466 466
 
467 467
 **`BIND_MEMBER`**
468 468
 
469
-1. `grantRoleIfAbsent(userId, 100)` → `sys_user_role` 追加角色 100  
469
+1. `grantRoleIfAbsent(userId, merchant)` → `sys_user_role` 追加 **role_key=merchant** 的角色  
470 470
 2. `login_name` = 会员名称(`user_name`,必填)  
471 471
 3. `admin_name` = 会员昵称(`nick_name`,必填)  
472 472
 4. `insert biz_merchant_account`;`password` 复制会员 `sys_user.password`  

+ 1 - 0
sql/biz_member.sql

@@ -2,7 +2,7 @@
2 2
 -- C 端会员 biz_member(与 sys_user 复用)
3 3
 -- 映射:member_id = user_id;手机号=phonenumber;会员名称=user_name;昵称=nick_name;
4 4
 --       密码=password;头像=avatar;状态=status
5
+-- 注册:先 insert sys_user(分配 role_key=member),再 insert biz_member(member_id = user_id)
5 6
 -- =============================================================================
6 7
 CREATE TABLE IF NOT EXISTS `biz_member` (
7 8
   `member_id` bigint(20) NOT NULL COMMENT '会员ID,与 sys_user.user_id 一致',

+ 0 - 1
sql/biz_merchant.sql

@@ -79,12 +79,3 @@ CREATE TABLE IF NOT EXISTS `biz_merchant` (
79 79
   KEY `idx_cert_status` (`cert_status`,`del_flag`),
80 80
   KEY `idx_create_time` (`create_time`)
81 81
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商户表(主体资质+经营信息+认证)';
82
-

+ 2 - 3
sql/biz_shop.sql

@@ -7,8 +7,8 @@
7 7
 CREATE TABLE IF NOT EXISTS `biz_merchant_account` (
8 8
   `account_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '经营账号ID,主键',
9 9
   `merchant_id` bigint(20) NOT NULL COMMENT '所属商户ID(biz_merchant.merchant_id);一商户一条(del_flag=0)',
10
-  `login_name` varchar(20) NOT NULL COMMENT '登录名(商家端);绑定管理员=sys_user.user_name;绑定会员=会员昵称',
11
-  `admin_name` varchar(64) NOT NULL COMMENT '管理员姓名(展示用);绑定管理员=sys_user.nick_name;绑定会员=会员名称(user_name)+会员ID',
10
+  `login_name` varchar(20) NOT NULL COMMENT '登录名(商家端);绑定管理员=sys_user.user_name;绑定会员=会员名称(user_name)',
11
+  `admin_name` varchar(64) NOT NULL COMMENT '管理员姓名(展示用);绑定管理员=sys_user.nick_name;绑定会员=会员昵称(nick_name)',
12 12
   `password` varchar(100) NOT NULL COMMENT '密码(BCrypt哈希);绑定管理员可复用 sys_user 密码;绑定会员可复用会员密码',
13 13
   `del_flag` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志:0存在 2逻辑删除(末店删除后一般仍保留)',
14 14
   `create_by` varchar(64) DEFAULT '' COMMENT '创建者',
@@ -43,9 +43,3 @@ CREATE TABLE IF NOT EXISTS `biz_shop` (
43 43
   KEY `idx_shop_status` (`shop_status`,`del_flag`),
44 44
   KEY `idx_create_time` (`create_time`)
45 45
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='店铺(不含经营账号,账号见 biz_merchant_account)';
46
-