From 9696e659c1ec3f080708536ef98c91775005247b Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Thu, 08 May 2025 14:24:33 +0800
Subject: [PATCH] feat(mall): 增加会员等级和分销等级设置功能 - 新增会员等级和分销等级设置页面 - 实现会员等级和分销等级的更新逻辑 - 优化会员列表页面,增加相关筛选条件 - 调整数据库查询以支持新的筛选条件

---
 src/main/java/cc/mrbird/febs/mall/controller/member/AdminMallMemberController.java |   13 ++
 src/main/resources/templates/febs/views/modules/mallMember/vip-level-setting.html  |   14 +-
 src/main/resources/mapper/modules/MallMemberMapper.xml                             |   31 +++---
 src/main/java/cc/mrbird/febs/mall/controller/member/ViewMallMemberController.java  |   15 ++
 src/main/resources/templates/febs/views/modules/mallMember/sale-level-setting.html |   92 ++++++++++++++++++
 src/main/java/cc/mrbird/febs/mall/service/impl/AdminMemberLevelServiceImpl.java    |    4 
 src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java       |    3 
 src/main/resources/templates/febs/views/modules/mallMember/mallMemberList.html     |  112 ++++++++++++++++++----
 8 files changed, 237 insertions(+), 47 deletions(-)

diff --git a/src/main/java/cc/mrbird/febs/mall/controller/member/AdminMallMemberController.java b/src/main/java/cc/mrbird/febs/mall/controller/member/AdminMallMemberController.java
index 800f122..19bd9af 100644
--- a/src/main/java/cc/mrbird/febs/mall/controller/member/AdminMallMemberController.java
+++ b/src/main/java/cc/mrbird/febs/mall/controller/member/AdminMallMemberController.java
@@ -631,8 +631,17 @@
 
     @PostMapping("vipLevelSetUpdate")
     public FebsResponse vipLevelSetUpdate(MallMember member) {
-        member.setVipLevelTime(new Date());
-        mallMemberService.updateById(member);
+        MallMember mallMember = mallMemberService.getBaseMapper().selectById(member.getId());
+        mallMember.setDirector(member.getDirector());
+        mallMemberService.updateById(mallMember);
+        return new FebsResponse().success().message("操作成功");
+    }
+
+    @PostMapping("saleLevelSetUpdate")
+    public FebsResponse saleLevelSetUpdate(MallMember member) {
+        MallMember mallMember = mallMemberService.getBaseMapper().selectById(member.getId());
+        mallMember.setStoreMaster(member.getStoreMaster());
+        mallMemberService.updateById(mallMember);
         return new FebsResponse().success().message("操作成功");
     }
 
diff --git a/src/main/java/cc/mrbird/febs/mall/controller/member/ViewMallMemberController.java b/src/main/java/cc/mrbird/febs/mall/controller/member/ViewMallMemberController.java
index 9d9aa36..0057351 100644
--- a/src/main/java/cc/mrbird/febs/mall/controller/member/ViewMallMemberController.java
+++ b/src/main/java/cc/mrbird/febs/mall/controller/member/ViewMallMemberController.java
@@ -403,16 +403,29 @@
     }
 
     @GetMapping("vipLevelSetting/{id}")
+    @RequiresPermissions("updateMemberLevel:update")
     public String vipLevelSetting(@PathVariable(value = "id") String id, Model model) {
         MallMember mallMember = mallMemberMapper.selectById(id);
 
         Map<String, Object> data = new HashMap<>();
         data.put("id", mallMember.getId());
-        data.put("level", mallMember.getLevel());
+        data.put("director", mallMember.getDirector());
         model.addAttribute("vipLevelSet", data);
         return FebsUtil.view("modules/mallMember/vip-level-setting");
     }
 
+    @GetMapping("saleLevelSetting/{id}")
+    @RequiresPermissions("updateSaleLevel:update")
+    public String updateSaleLevel(@PathVariable(value = "id") String id, Model model) {
+        MallMember mallMember = mallMemberMapper.selectById(id);
+
+        Map<String, Object> data = new HashMap<>();
+        data.put("id", mallMember.getId());
+        data.put("storeMaster", mallMember.getStoreMaster());
+        model.addAttribute("saleLevelSet", data);
+        return FebsUtil.view("modules/mallMember/sale-level-setting");
+    }
+
     @GetMapping("addCoupon/{id}")
     public String addCoupon(@PathVariable long id, Model model) {
 //        AdminAgentLevelSetInfoVo data = mallMemberService.getAgentLevelSetInfoByMemberId(id);
diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/AdminMemberLevelServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/AdminMemberLevelServiceImpl.java
index f0f1362..3022675 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/impl/AdminMemberLevelServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/impl/AdminMemberLevelServiceImpl.java
@@ -64,7 +64,7 @@
     public FebsResponse levelAll() {
         List<HappyMemberLevel> happyMemberLevels = happyMemberLevelMapper.selectList(
                 new LambdaQueryWrapper<HappyMemberLevel>()
-                        .select(HappyMemberLevel::getId, HappyMemberLevel::getName)
+                        .select(HappyMemberLevel::getCode, HappyMemberLevel::getName)
                         .orderByAsc(HappyMemberLevel::getId)
         );
         return new FebsResponse().success().data(happyMemberLevels);
@@ -102,7 +102,7 @@
     public FebsResponse saleLevelAll() {
         List<HappySaleLevel> happySaleLevels = happySaleLevelMapper.selectList(
                 new LambdaQueryWrapper<HappySaleLevel>()
-                        .select(HappySaleLevel::getId, HappySaleLevel::getName)
+                        .select(HappySaleLevel::getCode, HappySaleLevel::getName)
                         .orderByAsc(HappySaleLevel::getId)
         );
         return new FebsResponse().success().data(happySaleLevels);
diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java
index 3a4c4ab..d661368 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java
@@ -678,6 +678,9 @@
                     wallet.setMemberId(mallMember.getId());
                     mallMemberWalletMapper.insert(wallet);
                 } else {
+                    if (MallMember.ACCOUNT_STATUS_DISABLED.equals(mallMember.getAccountStatus())) {
+                        throw new FebsException("账号已停用");
+                    }
                     mallMember.setSessionKey(sessionKey);
                     this.baseMapper.updateById(mallMember);
                 }
diff --git a/src/main/resources/mapper/modules/MallMemberMapper.xml b/src/main/resources/mapper/modules/MallMemberMapper.xml
index 7cf3420..307315a 100644
--- a/src/main/resources/mapper/modules/MallMemberMapper.xml
+++ b/src/main/resources/mapper/modules/MallMemberMapper.xml
@@ -53,34 +53,35 @@
         <where>
             <if test="record != null" >
                 <if test="record.birthdayQuery!=null">
-                    and date_format(m.birthday, '%m-%d') = date_format(#{record.birthdayQuery}, '%m-%d')
+                    and date_format(a.birthday, '%m-%d') = date_format(#{record.birthdayQuery}, '%m-%d')
                 </if>
                 <if test="record.name!=null and record.name!=''">
-                    and m.name like concat('%',  #{record.name},'%')
+                    and a.name like concat('%',  #{record.name},'%')
                 </if>
-                <if test="record.account!=null and record.account!=''">
-                    and (
-                    m.phone like concat('%',  #{record.account},'%')
-                    or m.email like concat('%',  #{record.account},'%')
-                    or m.bind_phone like concat('%',  #{record.account},'%')
-                    or m.invite_id like concat('%',  #{record.account},'%')
-                    )
+                <if test="record.phone!=null and record.phone!=''">
+                    and a.phone like concat('%',  #{record.phone},'%')
                 </if>
                 <if test="record.accountStatus!=null">
-                    and m.account_status = #{record.accountStatus}
+                    and a.account_status = #{record.accountStatus}
+                </if>
+                <if test="record.director!=null">
+                    and a.director = #{record.director}
+                </if>
+                <if test="record.storeMaster!=null">
+                    and a.store_master = #{record.storeMaster}
                 </if>
                 <if test="record.accountType != null" >
-                    and m.account_type = #{record.accountType}
+                    and a.account_type = #{record.accountType}
                 </if>
                 <if test="record.level!=null and record.level!=''">
-                    and m.level=#{record.level}
+                    and a.level=#{record.level}
                 </if>
-                <if test="record.isSale!=null and record.isSale!=''">
-                    and m.is_sale=#{record.isSale}
+                <if test="record.checkOrder!=null">
+                    and a.check_order=#{record.checkOrder}
                 </if>
             </if>
         </where>
-        GROUP BY m.id order by m.CREATED_TIME desc
+        GROUP BY a.id order by a.CREATED_TIME desc
     </select>
 
     <select id="getMallMemberInfoById" resultType="cc.mrbird.febs.mall.vo.MallMemberVo">
diff --git a/src/main/resources/templates/febs/views/modules/mallMember/mallMemberList.html b/src/main/resources/templates/febs/views/modules/mallMember/mallMemberList.html
index 1197007..4890e74 100644
--- a/src/main/resources/templates/febs/views/modules/mallMember/mallMemberList.html
+++ b/src/main/resources/templates/febs/views/modules/mallMember/mallMemberList.html
@@ -8,15 +8,43 @@
                             <div class="layui-col-md10">
                                 <div class="layui-form-item">
                                     <div class="layui-inline">
-                                        <label class="layui-form-label layui-form-label-sm">用户昵称</label>
+                                        <label class="layui-form-label layui-form-label-sm">用户名</label>
                                         <div class="layui-input-inline">
-                                            <input type="text" placeholder="用户昵称" name="name" autocomplete="off" class="layui-input">
+                                            <input type="text" placeholder="用户名" name="name" autocomplete="off" class="layui-input">
                                         </div>
                                     </div>
                                     <div class="layui-inline">
-                                        <label class="layui-form-label layui-form-label-sm">手机号码</label>
+                                        <label class="layui-form-label layui-form-label-sm">联系方式</label>
                                         <div class="layui-input-inline">
-                                            <input type="text" placeholder="手机号码" name="phone" autocomplete="off" class="layui-input">
+                                            <input type="text" placeholder="联系方式" name="phone" autocomplete="off" class="layui-input">
+                                        </div>
+                                    </div>
+
+                                    <div class="layui-inline">
+                                        <label class="layui-form-label layui-form-label-sm">会员等级</label>
+                                        <div class="layui-input-inline">
+                                            <select name="director" class="director-type">
+                                                <option value="">请选择</option>
+                                            </select>
+                                        </div>
+                                    </div>
+
+                                    <div class="layui-inline">
+                                        <label class="layui-form-label layui-form-label-sm">分销等级</label>
+                                        <div class="layui-input-inline">
+                                            <select name="storeMaster" class="storeMaster-type">
+                                                <option value="">请选择</option>
+                                            </select>
+                                        </div>
+                                    </div>
+                                    <div class="layui-inline">
+                                        <label class="layui-form-label layui-form-label-sm">状态</label>
+                                        <div class="layui-input-inline">
+                                            <select name="accountStatus">
+                                                <option value="">请选择</option>
+                                                <option value="1">启用</option>
+                                                <option value="2">停用</option>
+                                            </select>
                                         </div>
                                     </div>
                                     <div class="layui-inline">
@@ -61,11 +89,11 @@
     <a lay-event="edit" shiro:hasPermission="user:update"><i
             class="layui-icon febs-edit-area febs-blue">&#xe7a5;</i></a>
 </script>
-<script type="text/html" id="switchStatus">
+<script type="text/html" id="accountStatusSwitch">
     {{# if(d.accountStatus === 1) { }}
-    <input type="checkbox" value={{d.id}} lay-text="正常|禁用" checked lay-skin="switch" lay-filter="switchStatus">
+    <input type="checkbox" value={{d.id}} lay-text="启用|停用" checked lay-skin="switch" lay-filter="accountStatusSwitch">
     {{# } else { }}
-    <input type="checkbox" value={{d.id}} lay-text="正常|禁用" lay-skin="switch" lay-filter="switchStatus">
+    <input type="checkbox" value={{d.id}} lay-text="启用|停用" lay-skin="switch" lay-filter="accountStatusSwitch">
     {{# } }}
 </script>
 <script type="text/html" id="switchStoreMaster">
@@ -111,10 +139,11 @@
         background-color: #5FB878 !important;
     }
 </style>
-<script type="text/html" id="toolbar">
+<script type="text/html" id="memberToolbar">
     <div class="layui-btn-container">
 <!--        <button class="layui-btn layui-btn-normal layui-btn-sm" type="button" lay-event="updateReferer">修改推荐人</button>-->
-<!--        <button class="layui-btn layui-btn-normal layui-btn-sm" type="button" lay-event="updateVipLevel">修改会员等级</button>-->
+        <button class="layui-btn layui-btn-normal layui-btn-sm" type="button" shiro:hasPermission="updateMemberLevel:update" lay-event="updateMemberLevel">修改会员等级</button>
+        <button class="layui-btn layui-btn-normal layui-btn-sm" type="button" shiro:hasPermission="updateSaleLevel:update" lay-event="updateSaleLevel">修改分销等级</button>
 <!--        <button class="layui-btn layui-btn-normal layui-btn-sm" type="button" lay-event="addCoupon">优惠券派送</button>-->
     </div>
 </script>
@@ -144,9 +173,33 @@
             elem: '#febs-member-benefits-list-birthday-start',
             format:'MM-dd'
         });
+        //(下拉框)
+        $.get(ctx + 'admin/level/levelAll', function (res) {
+            var data = res.data;
+            for (let k in data)
+            {
+                $(".director-type").append("<option value='" + data[k].code + "'>" + data[k].name + "</option>");
+            }
+            layui.use('form', function () {
+                var form = layui.form;
+                form.render();
+            });
+        });
+        //(下拉框)
+        $.get(ctx + 'admin/level/saleLevelAll', function (res) {
+            var data = res.data;
+            for (let k in data)
+            {
+                $(".storeMaster-type").append("<option value='" + data[k].code + "'>" + data[k].name + "</option>");
+            }
+            layui.use('form', function () {
+                var form = layui.form;
+                form.render();
+            });
+        });
 
         // 表格初始化
-        initTable();
+        initMemberListTable();
 
         // 初始化表格操作栏各个按钮功能
         table.on('tool(userTable)', function (obj) {
@@ -223,13 +276,13 @@
         }
         function closeAccount(id) {
             febs.get(ctx + 'admin/mallMember/closeAccount/' + id, null, function () {
-                febs.alert.success('禁用成功');
+                febs.alert.success('操作成功');
                 $query.click();
             });
         }
         function openAccount(id) {
             febs.get(ctx + 'admin/mallMember/openAccount/' + id, null, function () {
-                febs.alert.success('开启成功');
+                febs.alert.success('操作成功');
                 $query.click();
             });
         }
@@ -318,12 +371,12 @@
             tableIns.reload({where: getQueryParams(), page: {curr: 1}, initSort: sortObject});
         });
 
-        function initTable() {
+        function initMemberListTable() {
             tableIns = febs.table.init({
                 elem: $view.find('table'),
                 id: 'userTable',
                 url: ctx + 'admin/mallMember/getMallMemberList',
-                toolbar:"#toolbar",
+                toolbar:"#memberToolbar",
                 defaultToolbar:[],
                 cols: [[
                     {type: 'checkbox'},
@@ -332,7 +385,10 @@
                     {field: 'name', title: '用户名', minWidth: 100,align:'left'},
                     {field: 'realName', title: '真实姓名', minWidth: 100,align:'left'},
                     {field: 'phone', title: '联系方式', minWidth: 150,align:'left'},
+                    {field: 'directorName', title: '会员等级', minWidth: 150,align:'left'},
+                    {field: 'storeMasterName', title: '分销等级', minWidth: 150,align:'left'},
                     {field: 'inviteId', title: '邀请码', minWidth: 100,align:'left'},
+                    {field: 'checkOrder', title: '状态', templet: '#accountStatusSwitch', minWidth: 100,align:'center'},
                     {field: 'checkOrder', title: '核销员', templet: '#checkOrderSwitch', minWidth: 100,align:'center'},
                     {field: 'createdTime', title: '注册时间', minWidth: 180,align:'center'},
                 ]]
@@ -379,16 +435,29 @@
                 });
             }
 
-            if (layEvent === 'updateVipLevel') {
+            if (layEvent === 'updateSaleLevel') {
                 var checkData = table.checkStatus('userTable').data;
                 if (checkData.length > 1) {
                     febs.alert.warn('每次只能修改一个用户');
                     return;
                 }
-                // var idList = [];
-                // for (var i = 0; i < checkData.length; i++) {
-                //     idList.push(checkData[i].id);
-                // }
+                febs.modal.open('设置分销等级', 'modules/mallMember/saleLevelSetting/' + checkData[0].id, {
+                    btn: ['确认', '取消'],
+                    yes: function (index, layero) {
+                        $('#sale-level-set').find('#submit').trigger('click');
+                    },
+                    btn2: function () {
+                        layer.closeAll();
+                    }
+                });
+            }
+
+            if (layEvent === 'updateMemberLevel') {
+                var checkData = table.checkStatus('userTable').data;
+                if (checkData.length > 1) {
+                    febs.alert.warn('每次只能修改一个用户');
+                    return;
+                }
                 febs.modal.open('设置会员等级', 'modules/mallMember/vipLevelSetting/' + checkData[0].id, {
                     btn: ['确认', '取消'],
                     yes: function (index, layero) {
@@ -485,10 +554,13 @@
                 name: $searchForm.find('input[name="name"]').val().trim(),
                 phone: $searchForm.find('input[name="phone"]').val().trim(),
                 checkOrder: $searchForm.find("select[name='checkOrder']").val(),
+                accountStatus: $searchForm.find("select[name='accountStatus']").val(),
+                director: $searchForm.find("select[name='director']").val(),
+                storeMaster: $searchForm.find("select[name='storeMaster']").val(),
             };
         }
 
-        form.on('switch(switchStatus)', function (data) {
+        form.on('switch(accountStatusSwitch)', function (data) {
             if (data.elem.checked) {
                 openAccount(data.value);
             } else {
diff --git a/src/main/resources/templates/febs/views/modules/mallMember/sale-level-setting.html b/src/main/resources/templates/febs/views/modules/mallMember/sale-level-setting.html
new file mode 100644
index 0000000..c82254c
--- /dev/null
+++ b/src/main/resources/templates/febs/views/modules/mallMember/sale-level-setting.html
@@ -0,0 +1,92 @@
+<style>
+    #sale-level-set {
+        padding: 20px 25px 25px 0;
+    }
+
+    #sale-level-set .layui-treeSelect .ztree li a, .ztree li span {
+        margin: 0 0 2px 3px !important;
+    }
+    #sale-level-set #data-permission-tree-block {
+        border: 1px solid #eee;
+        border-radius: 2px;
+        padding: 3px 0;
+    }
+    #sale-level-set .layui-treeSelect .ztree li span.button.switch {
+        top: 1px;
+        left: 3px;
+    }
+
+</style>
+<div class="layui-fluid" id="sale-level-set">
+    <form class="layui-form" action="" lay-filter="sale-level-set-form">
+        <div class="layui-form-item febs-hide">
+            <label class="layui-form-label febs-form-item-require">id:</label>
+            <div class="layui-input-block">
+                <input type="text" name="id">
+            </div>
+        </div>
+        <div class="layui-form-item">
+            <div class="layui-inline">
+                <label class="layui-form-label">分销等级:</label>
+                <div class="layui-input-inline">
+                    <select lay-verify="required" name="storeMaster" class="sale-level-set-level" id="saleLevelSet">
+                        <option value="">请选择</option>
+                    </select>
+                </div>
+            </div>
+        </div>
+        <div class="layui-form-item febs-hide">
+            <button class="layui-btn" lay-submit="" lay-filter="sale-level-set-form-submit" id="submit"></button>
+        </div>
+    </form>
+</div>
+
+<script data-th-inline="javascript">
+    layui.use(['febs', 'form', 'formSelects', 'validate', 'treeSelect', 'eleTree'], function () {
+        var $ = layui.jquery,
+            febs = layui.febs,
+            layer = layui.layer,
+            formSelects = layui.formSelects,
+            treeSelect = layui.treeSelect,
+            form = layui.form,
+            eleTree = layui.eleTree,
+            saleLevelSet = [[${saleLevelSet}]],
+            $view = $('#sale-level-set'),
+            validate = layui.validate,
+            _deptTree;
+
+        form.render();
+
+        initMemberLevel();
+
+        function initMemberLevel() {
+            form.val("sale-level-set-form", {
+                "id": saleLevelSet.id,
+                "storeMaster": saleLevelSet.storeMaster
+            });
+        }
+
+        //(下拉框)
+        $.get(ctx + 'admin/level/saleLevelAll', function (res) {
+            var data = res.data;
+            for (var k in data)
+            {
+                $(".sale-level-set-level").append("<option value='" + data[k].code + "'>" + data[k].name + "</option>");
+            }
+            layui.use('form', function () {
+                var form = layui.form;
+                $("#saleLevelSet").val(saleLevelSet.storeMaster)
+                form.render();
+            });
+        });
+
+        form.on('submit(sale-level-set-form-submit)', function (data) {
+            febs.post(ctx + 'admin/mallMember/saleLevelSetUpdate', data.field, function () {
+                layer.closeAll();
+                febs.alert.success('操作成功');
+                $('#febs-member-list').find('#query').click();
+            });
+            return false;
+        });
+    });
+</script>
\ No newline at end of file
diff --git a/src/main/resources/templates/febs/views/modules/mallMember/vip-level-setting.html b/src/main/resources/templates/febs/views/modules/mallMember/vip-level-setting.html
index 434c406..22b5a96 100644
--- a/src/main/resources/templates/febs/views/modules/mallMember/vip-level-setting.html
+++ b/src/main/resources/templates/febs/views/modules/mallMember/vip-level-setting.html
@@ -29,7 +29,7 @@
             <div class="layui-inline">
                 <label class="layui-form-label">会员等级:</label>
                 <div class="layui-input-inline">
-                    <select lay-verify="required" name="level" class="vip-level-set-level" id="levelSet">
+                    <select lay-verify="required" name="director" class="vip-level-set-level" id="levelSet">
                         <option value="">请选择</option>
                     </select>
                 </div>
@@ -57,17 +57,17 @@
 
         form.render();
 
-        initUserValue();
+        initMemberLevel();
 
-        function initUserValue() {
+        function initMemberLevel() {
             form.val("vip-level-set-form", {
                 "id": vipLevelSet.id,
-                "level": vipLevelSet.level
+                "director": vipLevelSet.director
             });
         }
 
         //(下拉框)
-        $.get(ctx + 'admin/vip/config/allList', function (res) {
+        $.get(ctx + 'admin/level/levelAll', function (res) {
             var data = res.data;
             for (var k in data)
             {
@@ -75,7 +75,7 @@
             }
             layui.use('form', function () {
                 var form = layui.form;
-                $("#levelSet").val(vipLevelSet.level)
+                $("#levelSet").val(vipLevelSet.director)
                 form.render();
             });
         });
@@ -84,7 +84,7 @@
             febs.post(ctx + 'admin/mallMember/vipLevelSetUpdate', data.field, function () {
                 layer.closeAll();
                 febs.alert.success('操作成功');
-                $('#febs-member-list').find('#reset').click();
+                $('#febs-member-list').find('#query').click();
             });
             return false;
         });

--
Gitblit v1.9.1