Pārlūkot izejas kodu

会员管理代码

wwh 2 nedēļas atpakaļ
vecāks
revīzija
c2e988ede9

+ 7 - 0
baqing-shop/src/main/java/com/ruoyi/web/modules/account/controller/MemberController.java

@@ -47,6 +47,13 @@ public class MemberController extends BaseController
47 47
         return success(memberId);
48 48
     }
49 49
 
50
+    @PreAuthorize("@ss.hasPermi('agri:member:list')")
51
+    @GetMapping("/levels")
52
+    public AjaxResult levels()
53
+    {
54
+        return success(memberService.selectMemberLevelList());
55
+    }
56
+
50 57
     @PreAuthorize("@ss.hasPermi('agri:member:query')")
51 58
     @GetMapping("/{memberId}")
52 59
     public AjaxResult getInfo(@PathVariable("memberId") Long memberId)

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

@@ -24,7 +24,7 @@ public class BizMember extends BaseEntity
24 24
 
25 25
     private String password;
26 26
 
27
-    /** 会员等级(字典 biz_member_level,选填) */
27
+    /** 会员等级(biz_member_level.level_no,选填) */
28 28
     private Integer memberLevel;
29 29
 
30 30
     private String status;

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

@@ -0,0 +1,112 @@
1
+package com.ruoyi.web.modules.account.domain;
2
+
3
+import com.ruoyi.common.core.domain.BaseEntity;
4
+
5
+/**
6
+ * 会员等级配置 biz_member_level
7
+ */
8
+public class BizMemberLevel extends BaseEntity
9
+{
10
+    private static final long serialVersionUID = 1L;
11
+
12
+    private Long levelId;
13
+
14
+    /** 等级序号,对应 biz_member.member_level */
15
+    private Integer levelNo;
16
+
17
+    /** 等级名称 */
18
+    private String levelName;
19
+
20
+    /** 等级图标 URL */
21
+    private String levelIcon;
22
+
23
+    /** 会员权益说明 */
24
+    private String benefits;
25
+
26
+    private Integer sortNo;
27
+
28
+    /** 0启用 1停用 */
29
+    private String status;
30
+
31
+    private String delFlag;
32
+
33
+    public Long getLevelId()
34
+    {
35
+        return levelId;
36
+    }
37
+
38
+    public void setLevelId(Long levelId)
39
+    {
40
+        this.levelId = levelId;
41
+    }
42
+
43
+    public Integer getLevelNo()
44
+    {
45
+        return levelNo;
46
+    }
47
+
48
+    public void setLevelNo(Integer levelNo)
49
+    {
50
+        this.levelNo = levelNo;
51
+    }
52
+
53
+    public String getLevelName()
54
+    {
55
+        return levelName;
56
+    }
57
+
58
+    public void setLevelName(String levelName)
59
+    {
60
+        this.levelName = levelName;
61
+    }
62
+
63
+    public String getLevelIcon()
64
+    {
65
+        return levelIcon;
66
+    }
67
+
68
+    public void setLevelIcon(String levelIcon)
69
+    {
70
+        this.levelIcon = levelIcon;
71
+    }
72
+
73
+    public String getBenefits()
74
+    {
75
+        return benefits;
76
+    }
77
+
78
+    public void setBenefits(String benefits)
79
+    {
80
+        this.benefits = benefits;
81
+    }
82
+
83
+    public Integer getSortNo()
84
+    {
85
+        return sortNo;
86
+    }
87
+
88
+    public void setSortNo(Integer sortNo)
89
+    {
90
+        this.sortNo = sortNo;
91
+    }
92
+
93
+    public String getStatus()
94
+    {
95
+        return status;
96
+    }
97
+
98
+    public void setStatus(String status)
99
+    {
100
+        this.status = status;
101
+    }
102
+
103
+    public String getDelFlag()
104
+    {
105
+        return delFlag;
106
+    }
107
+
108
+    public void setDelFlag(String delFlag)
109
+    {
110
+        this.delFlag = delFlag;
111
+    }
112
+}

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

@@ -0,0 +1,15 @@
1
+package com.ruoyi.web.modules.account.mapper;
2
+
3
+import java.util.List;
4
+import org.apache.ibatis.annotations.Param;
5
+import com.ruoyi.web.modules.account.domain.BizMemberLevel;
6
+
7
+/**
8
+ * 会员等级 Mapper
9
+ */
10
+public interface BizMemberLevelMapper
11
+{
12
+    List<BizMemberLevel> selectEnabledList();
13
+
14
+    BizMemberLevel selectByLevelNo(@Param("levelNo") Integer levelNo);
15
+}

+ 3 - 0
baqing-shop/src/main/java/com/ruoyi/web/modules/account/service/IMemberService.java

@@ -7,6 +7,7 @@ import com.ruoyi.web.modules.account.dto.MemberCreateDTO;
7 7
 import com.ruoyi.web.modules.account.dto.MemberOrderQueryDTO;
8 8
 import com.ruoyi.web.modules.account.dto.MemberStatusDTO;
9 9
 import com.ruoyi.web.modules.account.vo.MemberDetailVO;
10
+import com.ruoyi.web.modules.account.vo.MemberLevelVO;
10 11
 import com.ruoyi.web.modules.account.vo.MemberListVO;
11 12
 
12 13
 /**
@@ -25,4 +26,6 @@ public interface IMemberService
25 26
     TableDataInfo selectMemberOrders(Long memberId, MemberOrderQueryDTO query);
26 27
 
27 28
     Object selectMemberOrderDetail(Long memberId, Long orderId);
29
+
30
+    List<MemberLevelVO> selectMemberLevelList();
28 31
 }

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

@@ -1,7 +1,9 @@
1 1
 package com.ruoyi.web.modules.account.service.impl;
2 2
 
3 3
 import java.util.ArrayList;
4
+import java.util.HashMap;
4 5
 import java.util.List;
6
+import java.util.Map;
5 7
 import org.springframework.beans.factory.annotation.Autowired;
6 8
 import org.springframework.stereotype.Service;
7 9
 import com.ruoyi.common.core.page.TableDataInfo;
@@ -11,17 +13,20 @@ import com.ruoyi.common.utils.StringUtils;
11 13
 import com.ruoyi.web.modules.account.constant.MemberConstants;
12 14
 import com.ruoyi.web.modules.account.domain.BizMember;
13 15
 import com.ruoyi.web.modules.account.domain.BizMemberAddress;
16
+import com.ruoyi.web.modules.account.domain.BizMemberLevel;
14 17
 import com.ruoyi.web.modules.account.dto.MemberCreateDTO;
15 18
 import com.ruoyi.web.modules.account.dto.MemberOrderQueryDTO;
16 19
 import com.ruoyi.web.modules.account.dto.MemberStatusDTO;
17 20
 import com.ruoyi.web.modules.account.facade.IOrderFacade;
18 21
 import com.ruoyi.web.modules.account.mapper.BizMemberAddressMapper;
22
+import com.ruoyi.web.modules.account.mapper.BizMemberLevelMapper;
19 23
 import com.ruoyi.web.modules.account.mapper.BizMemberMapper;
20 24
 import com.ruoyi.web.modules.account.service.IMemberService;
21 25
 import com.ruoyi.web.modules.account.support.MemberRegistrationSupport;
22 26
 import com.ruoyi.web.modules.account.util.MemberMobileUtils;
23 27
 import com.ruoyi.web.modules.account.vo.MemberAddressVO;
24 28
 import com.ruoyi.web.modules.account.vo.MemberDetailVO;
29
+import com.ruoyi.web.modules.account.vo.MemberLevelVO;
25 30
 import com.ruoyi.web.modules.account.vo.MemberListVO;
26 31
 
27 32
 /**
@@ -33,6 +38,9 @@ public class MemberServiceImpl implements IMemberService
33 38
     @Autowired
34 39
     private BizMemberMapper memberMapper;
35 40
 
41
+    @Autowired
42
+    private BizMemberLevelMapper memberLevelMapper;
43
+
36 44
     @Autowired
37 45
     private BizMemberAddressMapper addressMapper;
38 46
 
@@ -51,10 +59,22 @@ public class MemberServiceImpl implements IMemberService
51 59
         }
52 60
         query.setMemberRoleKey(MemberConstants.MEMBER_ROLE_KEY);
53 61
         List<BizMember> list = memberMapper.selectList(query);
62
+        Map<Integer, BizMemberLevel> levelMap = buildLevelMap();
54 63
         List<MemberListVO> rows = new ArrayList<>();
55 64
         for (BizMember m : list)
56 65
         {
57
-            rows.add(toListVo(m, true));
66
+            rows.add(toListVo(m, true, levelMap));
67
+        }
68
+        return rows;
69
+    }
70
+
71
+    @Override
72
+    public List<MemberLevelVO> selectMemberLevelList()
73
+    {
74
+        List<MemberLevelVO> rows = new ArrayList<>();
75
+        for (BizMemberLevel level : memberLevelMapper.selectEnabledList())
76
+        {
77
+            rows.add(toLevelVo(level));
58 78
         }
59 79
         return rows;
60 80
     }
@@ -72,7 +92,7 @@ public class MemberServiceImpl implements IMemberService
72 92
         vo.setMemberCode(member.getMemberCode());
73 93
         vo.setNickName(member.getNickName());
74 94
         vo.setMobile(member.getMobile());
75
-        fillMemberLevel(vo, member);
95
+        fillMemberLevel(vo, member, buildLevelMap());
76 96
         vo.setStatus(member.getStatus());
77 97
         vo.setOrderCount(member.getOrderCount());
78 98
         vo.setTotalAmount(member.getTotalAmount());
@@ -148,14 +168,14 @@ public class MemberServiceImpl implements IMemberService
148 168
         }
149 169
     }
150 170
 
151
-    private MemberListVO toListVo(BizMember m, boolean maskMobile)
171
+    private MemberListVO toListVo(BizMember m, boolean maskMobile, Map<Integer, BizMemberLevel> levelMap)
152 172
     {
153 173
         MemberListVO vo = new MemberListVO();
154 174
         vo.setMemberId(m.getMemberId());
155 175
         vo.setMemberCode(m.getMemberCode());
156 176
         vo.setNickName(m.getNickName());
157 177
         vo.setMobile(maskMobile ? MemberMobileUtils.mask(m.getMobile()) : m.getMobile());
158
-        fillMemberLevel(vo, m);
178
+        fillMemberLevel(vo, m, levelMap);
159 179
         vo.setStatus(m.getStatus());
160 180
         String label = DictUtils.getDictLabel(MemberConstants.DICT_MEMBER_STATUS, m.getStatus());
161 181
         if (StringUtils.isEmpty(label))
@@ -169,26 +189,56 @@ public class MemberServiceImpl implements IMemberService
169 189
         return vo;
170 190
     }
171 191
 
172
-    private void fillMemberLevel(MemberListVO vo, BizMember m)
192
+    private Map<Integer, BizMemberLevel> buildLevelMap()
173 193
     {
174
-        vo.setMemberLevel(m.getMemberLevel());
175
-        if (m.getMemberLevel() != null)
194
+        Map<Integer, BizMemberLevel> map = new HashMap<>();
195
+        for (BizMemberLevel level : memberLevelMapper.selectEnabledList())
176 196
         {
177
-            String label = DictUtils.getDictLabel(MemberConstants.DICT_MEMBER_LEVEL,
178
-                    String.valueOf(m.getMemberLevel()));
179
-            vo.setMemberLevelLabel(StringUtils.isNotEmpty(label) ? label : String.valueOf(m.getMemberLevel()));
197
+            map.put(level.getLevelNo(), level);
180 198
         }
199
+        return map;
181 200
     }
182 201
 
183
-    private void fillMemberLevel(MemberDetailVO vo, BizMember m)
202
+    private MemberLevelVO toLevelVo(BizMemberLevel level)
203
+    {
204
+        MemberLevelVO vo = new MemberLevelVO();
205
+        vo.setLevelId(level.getLevelId());
206
+        vo.setLevelNo(level.getLevelNo());
207
+        vo.setLevelName(level.getLevelName());
208
+        vo.setLevelIcon(level.getLevelIcon());
209
+        vo.setBenefits(level.getBenefits());
210
+        vo.setSortNo(level.getSortNo());
211
+        return vo;
212
+    }
213
+
214
+    private void fillMemberLevel(MemberListVO vo, BizMember m, Map<Integer, BizMemberLevel> levelMap)
184 215
     {
185 216
         vo.setMemberLevel(m.getMemberLevel());
186
-        if (m.getMemberLevel() != null)
217
+        if (m.getMemberLevel() == null)
218
+        {
219
+            return;
220
+        }
221
+        BizMemberLevel level = levelMap.get(m.getMemberLevel());
222
+        if (level == null)
223
+        {
224
+            level = memberLevelMapper.selectByLevelNo(m.getMemberLevel());
225
+        }
226
+        if (level != null)
187 227
         {
188
-            String label = DictUtils.getDictLabel(MemberConstants.DICT_MEMBER_LEVEL,
189
-                    String.valueOf(m.getMemberLevel()));
190
-            vo.setMemberLevelLabel(StringUtils.isNotEmpty(label) ? label : String.valueOf(m.getMemberLevel()));
228
+            vo.setMemberLevelLabel(level.getLevelName());
191 229
         }
230
+        else
231
+        {
232
+            vo.setMemberLevelLabel(String.valueOf(m.getMemberLevel()));
233
+        }
234
+    }
235
+
236
+    private void fillMemberLevel(MemberDetailVO vo, BizMember m, Map<Integer, BizMemberLevel> levelMap)
237
+    {
238
+        MemberListVO temp = new MemberListVO();
239
+        fillMemberLevel(temp, m, levelMap);
240
+        vo.setMemberLevel(temp.getMemberLevel());
241
+        vo.setMemberLevelLabel(temp.getMemberLevelLabel());
192 242
     }
193 243
 
194 244
     private MemberAddressVO toAddressVo(BizMemberAddress addr)

+ 79 - 0
baqing-shop/src/main/java/com/ruoyi/web/modules/account/vo/MemberLevelVO.java

@@ -0,0 +1,79 @@
1
+package com.ruoyi.web.modules.account.vo;
2
+
3
+/**
4
+ * 会员等级(列表/选项)
5
+ */
6
+public class MemberLevelVO
7
+{
8
+    private Long levelId;
9
+
10
+    private Integer levelNo;
11
+
12
+    private String levelName;
13
+
14
+    private String levelIcon;
15
+
16
+    private String benefits;
17
+
18
+    private Integer sortNo;
19
+
20
+    public Long getLevelId()
21
+    {
22
+        return levelId;
23
+    }
24
+
25
+    public void setLevelId(Long levelId)
26
+    {
27
+        this.levelId = levelId;
28
+    }
29
+
30
+    public Integer getLevelNo()
31
+    {
32
+        return levelNo;
33
+    }
34
+
35
+    public void setLevelNo(Integer levelNo)
36
+    {
37
+        this.levelNo = levelNo;
38
+    }
39
+
40
+    public String getLevelName()
41
+    {
42
+        return levelName;
43
+    }
44
+
45
+    public void setLevelName(String levelName)
46
+    {
47
+        this.levelName = levelName;
48
+    }
49
+
50
+    public String getLevelIcon()
51
+    {
52
+        return levelIcon;
53
+    }
54
+
55
+    public void setLevelIcon(String levelIcon)
56
+    {
57
+        this.levelIcon = levelIcon;
58
+    }
59
+
60
+    public String getBenefits()
61
+    {
62
+        return benefits;
63
+    }
64
+
65
+    public void setBenefits(String benefits)
66
+    {
67
+        this.benefits = benefits;
68
+    }
69
+
70
+    public Integer getSortNo()
71
+    {
72
+        return sortNo;
73
+    }
74
+
75
+    public void setSortNo(Integer sortNo)
76
+    {
77
+        this.sortNo = sortNo;
78
+    }
79
+}

+ 39 - 0
baqing-shop/src/main/resources/mapper/account/BizMemberLevelMapper.xml

@@ -0,0 +1,39 @@
1
+<?xml version="1.0" encoding="UTF-8" ?>
2
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3
+<mapper namespace="com.ruoyi.web.modules.account.mapper.BizMemberLevelMapper">
4
+
5
+    <resultMap id="BizMemberLevelResult" type="com.ruoyi.web.modules.account.domain.BizMemberLevel">
6
+        <id property="levelId" column="level_id"/>
7
+        <result property="levelNo" column="level_no"/>
8
+        <result property="levelName" column="level_name"/>
9
+        <result property="levelIcon" column="level_icon"/>
10
+        <result property="benefits" column="benefits"/>
11
+        <result property="sortNo" column="sort_no"/>
12
+        <result property="status" column="status"/>
13
+        <result property="delFlag" column="del_flag"/>
14
+        <result property="createBy" column="create_by"/>
15
+        <result property="createTime" column="create_time"/>
16
+        <result property="updateBy" column="update_by"/>
17
+        <result property="updateTime" column="update_time"/>
18
+        <result property="remark" column="remark"/>
19
+    </resultMap>
20
+
21
+    <sql id="selectVo">
22
+        select level_id, level_no, level_name, level_icon, benefits, sort_no, status, del_flag,
23
+               create_by, create_time, update_by, update_time, remark
24
+        from biz_member_level
25
+    </sql>
26
+
27
+    <select id="selectEnabledList" resultMap="BizMemberLevelResult">
28
+        <include refid="selectVo"/>
29
+        where del_flag = '0' and status = '0'
30
+        order by sort_no asc, level_no asc
31
+    </select>
32
+
33
+    <select id="selectByLevelNo" resultMap="BizMemberLevelResult">
34
+        <include refid="selectVo"/>
35
+        where del_flag = '0' and level_no = #{levelNo}
36
+        limit 1
37
+    </select>
38
+
39
+</mapper>

+ 16 - 0
baqing-shop/src/test/java/com/ruoyi/web/modules/account/controller/MemberControllerTest.java

@@ -19,10 +19,12 @@ import org.springframework.http.MediaType;
19 19
 import org.springframework.test.web.servlet.MockMvc;
20 20
 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
21 21
 import com.fasterxml.jackson.databind.ObjectMapper;
22
+import java.util.Collections;
22 23
 import com.ruoyi.web.modules.account.dto.MemberCreateDTO;
23 24
 import com.ruoyi.web.modules.account.dto.MemberStatusDTO;
24 25
 import com.ruoyi.web.modules.account.service.IMemberService;
25 26
 import com.ruoyi.web.modules.account.vo.MemberDetailVO;
27
+import com.ruoyi.web.modules.account.vo.MemberLevelVO;
26 28
 
27 29
 @ExtendWith(MockitoExtension.class)
28 30
 class MemberControllerTest
@@ -45,6 +47,20 @@ class MemberControllerTest
45 47
         org.mockito.Mockito.lenient().doReturn("admin").when(controller).getUsername();
46 48
     }
47 49
 
50
+    @Test
51
+    void levels_returns200() throws Exception
52
+    {
53
+        MemberLevelVO level = new MemberLevelVO();
54
+        level.setLevelNo(0);
55
+        level.setLevelName("普通会员");
56
+        when(memberService.selectMemberLevelList()).thenReturn(Collections.singletonList(level));
57
+
58
+        mockMvc.perform(get("/agri/member/levels"))
59
+                .andExpect(status().isOk())
60
+                .andExpect(jsonPath("$.code").value(200))
61
+                .andExpect(jsonPath("$.data[0].levelName").value("普通会员"));
62
+    }
63
+
48 64
     @Test
49 65
     void getInfo_returns200() throws Exception
50 66
     {

+ 41 - 0
baqing-shop/src/test/java/com/ruoyi/web/modules/account/service/MemberServiceImplTest.java

@@ -1,5 +1,6 @@
1 1
 package com.ruoyi.web.modules.account.service;
2 2
 
3
+import static org.junit.jupiter.api.Assertions.assertEquals;
3 4
 import static org.junit.jupiter.api.Assertions.assertThrows;
4 5
 import static org.mockito.ArgumentMatchers.any;
5 6
 import static org.mockito.ArgumentMatchers.eq;
@@ -15,12 +16,16 @@ import com.ruoyi.common.core.page.TableDataInfo;
15 16
 import com.ruoyi.common.exception.ServiceException;
16 17
 import com.ruoyi.web.modules.account.constant.MemberConstants;
17 18
 import com.ruoyi.web.modules.account.domain.BizMember;
19
+import com.ruoyi.web.modules.account.domain.BizMemberLevel;
18 20
 import com.ruoyi.web.modules.account.dto.MemberOrderQueryDTO;
19 21
 import com.ruoyi.web.modules.account.dto.MemberStatusDTO;
20 22
 import com.ruoyi.web.modules.account.facade.IOrderFacade;
21 23
 import com.ruoyi.web.modules.account.mapper.BizMemberAddressMapper;
24
+import com.ruoyi.web.modules.account.mapper.BizMemberLevelMapper;
22 25
 import com.ruoyi.web.modules.account.mapper.BizMemberMapper;
23 26
 import com.ruoyi.web.modules.account.service.impl.MemberServiceImpl;
27
+import com.ruoyi.web.modules.account.vo.MemberDetailVO;
28
+import com.ruoyi.web.modules.account.vo.MemberListVO;
24 29
 
25 30
 @ExtendWith(MockitoExtension.class)
26 31
 class MemberServiceImplTest
@@ -28,6 +33,9 @@ class MemberServiceImplTest
28 33
     @Mock
29 34
     private BizMemberMapper memberMapper;
30 35
 
36
+    @Mock
37
+    private BizMemberLevelMapper memberLevelMapper;
38
+
31 39
     @Mock
32 40
     private BizMemberAddressMapper addressMapper;
33 41
 
@@ -71,4 +79,37 @@ class MemberServiceImplTest
71 79
         when(memberMapper.selectById(99L)).thenReturn(null);
72 80
         assertThrows(ServiceException.class, () -> memberService.selectMemberDetail(99L));
73 81
     }
82
+
83
+    @Test
84
+    void selectMemberDetail_usesBizMemberLevelName()
85
+    {
86
+        BizMember member = new BizMember();
87
+        member.setMemberId(1L);
88
+        member.setMemberCode("user01");
89
+        member.setMemberLevel(0);
90
+        member.setStatus(MemberConstants.STATUS_ENABLED);
91
+        when(memberMapper.selectById(1L)).thenReturn(member);
92
+        when(addressMapper.selectByMemberId(1L)).thenReturn(Collections.emptyList());
93
+
94
+        BizMemberLevel level = new BizMemberLevel();
95
+        level.setLevelNo(0);
96
+        level.setLevelName("普通会员");
97
+        when(memberLevelMapper.selectEnabledList()).thenReturn(Collections.singletonList(level));
98
+
99
+        MemberDetailVO vo = memberService.selectMemberDetail(1L);
100
+        assertEquals("普通会员", vo.getMemberLevelLabel());
101
+    }
102
+
103
+    @Test
104
+    void selectMemberLevelList_returnsEnabledLevels()
105
+    {
106
+        BizMemberLevel level = new BizMemberLevel();
107
+        level.setLevelId(1L);
108
+        level.setLevelNo(1);
109
+        level.setLevelName("黄金会员");
110
+        when(memberLevelMapper.selectEnabledList()).thenReturn(Collections.singletonList(level));
111
+
112
+        assertEquals(1, memberService.selectMemberLevelList().size());
113
+        assertEquals("黄金会员", memberService.selectMemberLevelList().get(0).getLevelName());
114
+    }
74 115
 }

+ 1 - 1
sql/biz_member.sql

@@ -6,7 +6,7 @@
6 6
 -- =============================================================================
7 7
 CREATE TABLE IF NOT EXISTS `biz_member` (
8 8
   `member_id` bigint(20) NOT NULL COMMENT '会员ID,与 sys_user.user_id 一致',
9
-  `member_level` tinyint(4) DEFAULT NULL COMMENT '会员等级(字典 biz_member_level,选填)',
9
+  `member_level` tinyint(4) DEFAULT NULL COMMENT '会员等级(biz_member_level.level_no,选填)',
10 10
   `order_count` int(11) NOT NULL DEFAULT '0' COMMENT '已完成订单笔数',
11 11
   `total_amount` decimal(12,2) NOT NULL DEFAULT '0.00' COMMENT '已完成实付合计(元)',
12 12
   `register_time` datetime NOT NULL COMMENT '注册时间',

+ 41 - 0
sql/biz_member_level.sql

@@ -0,0 +1,41 @@
1
+-- =============================================================================
2
+-- 会员等级配置 biz_member_level
3
+-- 用途:平台维护会员等级体系(等级、图标、名称、权益说明)
4
+-- 关联:biz_member.member_level = 本表 level_no(未删除且启用的等级)
5
+-- 说明:替代/补充原字典 biz_member_level;C 端与平台端展示等级信息时 JOIN 本表
6
+-- =============================================================================
7
+CREATE TABLE IF NOT EXISTS `biz_member_level` (
8
+  `level_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '等级ID,主键',
9
+  `level_no` tinyint(4) NOT NULL COMMENT '等级(序号;数值越大等级越高;与 biz_member.member_level 对应)',
10
+  `level_name` varchar(64) NOT NULL COMMENT '会员名称(等级展示名,如 普通会员、黄金会员)',
11
+  `level_icon` varchar(512) DEFAULT NULL COMMENT '会员图标URL',
12
+  `benefits` text COMMENT '会员权益(说明文案;可多行或富文本)',
13
+  `sort_no` int(11) NOT NULL DEFAULT '0' COMMENT '展示排序(升序)',
14
+  `status` char(1) NOT NULL DEFAULT '0' COMMENT '状态:0启用 1停用',
15
+  `del_flag` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志:0存在 2逻辑删除',
16
+  `create_by` varchar(64) DEFAULT '' COMMENT '创建者',
17
+  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
18
+  `update_by` varchar(64) DEFAULT '' COMMENT '更新者',
19
+  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
20
+  `remark` varchar(500) DEFAULT NULL COMMENT '备注',
21
+  PRIMARY KEY (`level_id`),
22
+  UNIQUE KEY `uk_level_no` (`level_no`, `del_flag`),
23
+  KEY `idx_status_sort` (`status`, `sort_no`, `del_flag`)
24
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='会员等级配置表';
25
+
26
+-- =============================================================================
27
+-- 初始等级(可选;若已存在同 level_no 则跳过)
28
+-- =============================================================================
29
+INSERT INTO `biz_member_level` (
30
+  `level_no`, `level_name`, `level_icon`, `benefits`, `sort_no`, `status`, `del_flag`, `create_by`, `create_time`, `remark`
31
+)
32
+SELECT 0, '普通会员', NULL, '享受平台基础购物服务', 0, '0', '0', 'admin', NOW(), '默认等级'
33
+FROM DUAL
34
+WHERE NOT EXISTS (SELECT 1 FROM `biz_member_level` WHERE `level_no` = 0 AND `del_flag` = '0');
35
+
36
+INSERT INTO `biz_member_level` (
37
+  `level_no`, `level_name`, `level_icon`, `benefits`, `sort_no`, `status`, `del_flag`, `create_by`, `create_time`, `remark`
38
+)
39
+SELECT 1, '黄金会员', NULL, '专属折扣、优先客服、会员活动', 1, '0', '0', 'admin', NOW(), NULL
40
+FROM DUAL
41
+WHERE NOT EXISTS (SELECT 1 FROM `biz_member_level` WHERE `level_no` = 1 AND `del_flag` = '0');