Explorar el Código

会员管理代码

wwh hace 1 semana
padre
commit
6f41c32ac4

+ 38 - 0
baqing-shop/src/main/java/com/ruoyi/web/modules/merchant/service/impl/MerchantServiceImpl.java

@@ -27,6 +27,8 @@ import com.ruoyi.web.modules.merchant.facade.IMerchantOrderFacade;
27 27
 import com.ruoyi.web.modules.merchant.facade.IMerchantShopFacade;
28 28
 import com.ruoyi.web.modules.merchant.mapper.BizMerchantMapper;
29 29
 import com.ruoyi.web.modules.merchant.service.IMerchantService;
30
+import com.ruoyi.web.modules.store.mapper.BizMerchantAccountMapper;
31
+import com.ruoyi.web.modules.store.vo.MerchantAccountUserVO;
30 32
 import com.ruoyi.web.modules.merchant.support.BizCompleteEvaluator;
31 33
 import com.ruoyi.web.modules.merchant.support.CertStatusTransition;
32 34
 import com.ruoyi.web.modules.merchant.support.MerchantDisplayUtils;
@@ -55,6 +57,9 @@ public class MerchantServiceImpl implements IMerchantService
55 57
     @Autowired
56 58
     private MerchantBindMapper merchantBindMapper;
57 59
 
60
+    @Autowired
61
+    private BizMerchantAccountMapper merchantAccountMapper;
62
+
58 63
     @Override
59 64
     public List<MerchantListVO> selectMerchantList(BizMerchant query)
60 65
     {
@@ -70,6 +75,7 @@ public class MerchantServiceImpl implements IMerchantService
70 75
             vo.setCanDelete(check.isCanDelete());
71 76
             rows.add(vo);
72 77
         }
78
+        fillAdminNames(rows);
73 79
         return rows;
74 80
     }
75 81
 
@@ -417,6 +423,38 @@ public class MerchantServiceImpl implements IMerchantService
417 423
         return m;
418 424
     }
419 425
 
426
+    private void fillAdminNames(List<MerchantListVO> rows)
427
+    {
428
+        if (rows == null || rows.isEmpty())
429
+        {
430
+            return;
431
+        }
432
+        List<Long> merchantIds = new ArrayList<>(rows.size());
433
+        for (MerchantListVO row : rows)
434
+        {
435
+            if (row.getMerchantId() != null)
436
+            {
437
+                merchantIds.add(row.getMerchantId());
438
+            }
439
+        }
440
+        if (merchantIds.isEmpty())
441
+        {
442
+            return;
443
+        }
444
+        Map<Long, String> adminNameByMerchantId = new HashMap<>();
445
+        for (MerchantAccountUserVO account : merchantAccountMapper.selectMerchantAdminNamesByMerchantIds(merchantIds))
446
+        {
447
+            if (account.getMerchantId() != null && StringUtils.isNotEmpty(account.getAdminName()))
448
+            {
449
+                adminNameByMerchantId.putIfAbsent(account.getMerchantId(), account.getAdminName());
450
+            }
451
+        }
452
+        for (MerchantListVO row : rows)
453
+        {
454
+            row.setAdminName(adminNameByMerchantId.get(row.getMerchantId()));
455
+        }
456
+    }
457
+
420 458
     private MerchantListVO toListVo(BizMerchant m)
421 459
     {
422 460
         MerchantListVO vo = new MerchantListVO();

+ 13 - 0
baqing-shop/src/main/java/com/ruoyi/web/modules/merchant/vo/MerchantListVO.java

@@ -16,6 +16,9 @@ public class MerchantListVO
16 16
 
17 17
     private String merchantName;
18 18
 
19
+    /** 商户管理员姓名(sys_user.nick_name,shop_id 为空的首条经营账号) */
20
+    private String adminName;
21
+
19 22
     private String contactName;
20 23
 
21 24
     private String contactPhone;
@@ -73,6 +76,16 @@ public class MerchantListVO
73 76
         this.merchantName = merchantName;
74 77
     }
75 78
 
79
+    public String getAdminName()
80
+    {
81
+        return adminName;
82
+    }
83
+
84
+    public void setAdminName(String adminName)
85
+    {
86
+        this.adminName = adminName;
87
+    }
88
+
76 89
     public String getContactName()
77 90
     {
78 91
         return contactName;

+ 4 - 0
baqing-shop/src/main/java/com/ruoyi/web/modules/store/mapper/BizMerchantAccountMapper.java

@@ -1,5 +1,6 @@
1 1
 package com.ruoyi.web.modules.store.mapper;
2 2
 
3
+import java.util.List;
3 4
 import org.apache.ibatis.annotations.Param;
4 5
 import com.ruoyi.web.modules.store.domain.BizMerchantAccount;
5 6
 import com.ruoyi.web.modules.store.vo.MerchantAccountUserVO;
@@ -18,6 +19,9 @@ public interface BizMerchantAccountMapper
18 19
 
19 20
     MerchantAccountUserVO selectMerchantAdminWithUser(@Param("merchantId") Long merchantId);
20 21
 
22
+    List<MerchantAccountUserVO> selectMerchantAdminNamesByMerchantIds(
23
+            @Param("merchantIds") List<Long> merchantIds);
24
+
21 25
     int countByAccountId(@Param("accountId") Long accountId);
22 26
 
23 27
     int insert(BizMerchantAccount account);

+ 10 - 0
baqing-shop/src/main/resources/mapper/store/BizMerchantAccountMapper.xml

@@ -45,6 +45,16 @@
45 45
         where a.merchant_id = #{merchantId} and a.shop_id is null and a.del_flag = '0'
46 46
     </select>
47 47
 
48
+    <select id="selectMerchantAdminNamesByMerchantIds"
49
+            resultType="com.ruoyi.web.modules.store.vo.MerchantAccountUserVO">
50
+        select a.merchant_id as merchantId, u.nick_name as adminName
51
+        from biz_merchant_account a
52
+        inner join sys_user u on a.account_id = u.user_id and u.del_flag = '0'
53
+        where a.shop_id is null and a.del_flag = '0'
54
+          and a.merchant_id in
55
+        <foreach collection="merchantIds" item="id" open="(" separator="," close=")">#{id}</foreach>
56
+    </select>
57
+
48 58
     <select id="countByAccountId" resultType="int">
49 59
         select count(1) from biz_merchant_account
50 60
         where account_id = #{accountId} and del_flag = '0'

+ 32 - 0
baqing-shop/src/test/java/com/ruoyi/web/modules/merchant/service/MerchantServiceImplTest.java

@@ -5,9 +5,12 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
5 5
 import static org.junit.jupiter.api.Assertions.assertTrue;
6 6
 import static org.mockito.ArgumentMatchers.any;
7 7
 import static org.mockito.ArgumentMatchers.eq;
8
+import static org.mockito.ArgumentMatchers.anyList;
8 9
 import static org.mockito.Mockito.never;
9 10
 import static org.mockito.Mockito.verify;
10 11
 import static org.mockito.Mockito.when;
12
+import java.util.Collections;
13
+import java.util.List;
11 14
 import java.util.Map;
12 15
 import org.junit.jupiter.api.Test;
13 16
 import com.ruoyi.web.modules.merchant.vo.OpenShopCheckVO;
@@ -26,6 +29,9 @@ import com.ruoyi.web.modules.merchant.facade.IMerchantOrderFacade;
26 29
 import com.ruoyi.web.modules.merchant.facade.IMerchantShopFacade;
27 30
 import com.ruoyi.web.modules.merchant.mapper.BizMerchantMapper;
28 31
 import com.ruoyi.web.modules.merchant.service.impl.MerchantServiceImpl;
32
+import com.ruoyi.web.modules.merchant.vo.MerchantListVO;
33
+import com.ruoyi.web.modules.store.mapper.BizMerchantAccountMapper;
34
+import com.ruoyi.web.modules.store.vo.MerchantAccountUserVO;
29 35
 
30 36
 @ExtendWith(MockitoExtension.class)
31 37
 class MerchantServiceImplTest
@@ -42,9 +48,35 @@ class MerchantServiceImplTest
42 48
     @Mock
43 49
     private IMerchantAccountBindService accountBindService;
44 50
 
51
+    @Mock
52
+    private BizMerchantAccountMapper merchantAccountMapper;
53
+
45 54
     @InjectMocks
46 55
     private MerchantServiceImpl merchantService;
47 56
 
57
+    @Test
58
+    void selectMerchantList_fillsAdminName()
59
+    {
60
+        BizMerchant merchant = new BizMerchant();
61
+        merchant.setMerchantId(1L);
62
+        merchant.setMerchantType(MerchantConstants.TYPE_PERSON);
63
+        merchant.setPersonName("张三");
64
+        merchant.setShopCount(0);
65
+        when(merchantMapper.selectList(any())).thenReturn(Collections.singletonList(merchant));
66
+        when(orderFacade.hasUnfinishedOrdersByMerchant(1L)).thenReturn(false);
67
+
68
+        MerchantAccountUserVO admin = new MerchantAccountUserVO();
69
+        admin.setMerchantId(1L);
70
+        admin.setAdminName("张管理员");
71
+        when(merchantAccountMapper.selectMerchantAdminNamesByMerchantIds(anyList()))
72
+                .thenReturn(Collections.singletonList(admin));
73
+
74
+        List<MerchantListVO> rows = merchantService.selectMerchantList(new BizMerchant());
75
+
76
+        assertEquals(1, rows.size());
77
+        assertEquals("张管理员", rows.get(0).getAdminName());
78
+    }
79
+
48 80
     @Test
49 81
     void insert_setsCertNormalAndBizComplete_whenBizFieldsComplete()
50 82
     {

+ 10 - 50
ruoyi-ui/src/views/agri/org/merchant/index.vue

@@ -100,7 +100,7 @@
100 100
                 </el-col>
101 101
                 <el-col :span="12">
102 102
                   <el-form-item label="证件号码" prop="idCardNo">
103
-                    <el-input v-model="form.idCardNo" maxlength="18" :disabled="!!form.merchantId" :placeholder="form.merchantId ? '选填' : '必填'" />
103
+                    <el-input v-model="form.idCardNo" maxlength="18" :disabled="!!form.merchantId" placeholder="选填" />
104 104
                   </el-form-item>
105 105
                 </el-col>
106 106
                 <el-col :span="12">
@@ -206,7 +206,7 @@
206 206
                 <el-col :span="12"><el-form-item label="企业名称" prop="companyName"><el-input v-model="form.companyName" maxlength="128" /></el-form-item></el-col>
207 207
                 <el-col :span="12">
208 208
                   <el-form-item label="统一社会信用代码" prop="creditCode">
209
-                    <el-input v-model="form.creditCode" maxlength="18" :disabled="!!form.merchantId" :placeholder="form.merchantId ? '选填' : '必填'" />
209
+                    <el-input v-model="form.creditCode" maxlength="18" :disabled="!!form.merchantId" placeholder="选填" />
210 210
                   </el-form-item>
211 211
                 </el-col>
212 212
                 <el-col :span="24">
@@ -247,8 +247,8 @@
247 247
             </template>
248 248
           </el-tab-pane>
249 249
 
250
-          <!-- 经营信息 -->
251
-          <el-tab-pane label="商户经营信息" name="biz">
250
+          <!-- 经营信息(仅编辑) -->
251
+          <el-tab-pane v-if="form.merchantId" label="商户经营信息" name="biz">
252 252
             <el-row :gutter="16">
253 253
               <el-col :span="12"><el-form-item label="商户名称" prop="merchantName"><el-input v-model="form.merchantName" maxlength="128" /></el-form-item></el-col>
254 254
               <el-col :span="12"><el-form-item label="客服电话" prop="servicePhone"><el-input v-model="form.servicePhone" maxlength="20" /></el-form-item></el-col>
@@ -372,7 +372,7 @@ export default {
372 372
     }
373 373
   },
374 374
   computed: {
375
-    /** 表单校验:新增须完整主体+经营信息;编辑经营信息在 biz 页签校验 */
375
+    /** 表单校验:新增个人仅姓名必填;新增企业仅法人姓名+企业名称必填;绑定仅新增时校验 */
376 376
     formRules() {
377 377
       const rules = {
378 378
         merchantType: [{ required: true, message: "请选择主体类型", trigger: "change" }]
@@ -380,41 +380,11 @@ export default {
380 380
       const isAdd = !this.form.merchantId
381 381
       if (this.form.merchantType === "1") {
382 382
         rules.personName = [{ required: true, message: "请输入姓名", trigger: "blur" }]
383
-        if (isAdd) {
384
-          rules.idCardNo = [{ required: true, message: "请输入证件号码", trigger: "blur" }]
385
-        }
386 383
       } else {
387 384
         rules.legalName = [{ required: true, message: "请输入法人姓名", trigger: "blur" }]
388 385
         rules.companyName = [{ required: true, message: "请输入企业名称", trigger: "blur" }]
389
-        if (isAdd) {
390
-          rules.creditCode = [{ required: true, message: "请输入统一社会信用代码", trigger: "blur" }]
391
-        }
392 386
       }
393 387
       if (isAdd) {
394
-        rules.merchantName = [{ required: true, message: "请输入商户名称", trigger: "blur" }]
395
-        rules.servicePhone = [{ required: true, message: "请输入客服电话", trigger: "blur" }]
396
-        rules.bizRegionCascader = [{
397
-          required: true,
398
-          validator: (rule, value, callback) => {
399
-            if (!value || value.length === 0) {
400
-              callback(new Error("请选择经营地区"))
401
-            } else {
402
-              callback()
403
-            }
404
-          },
405
-          trigger: "change"
406
-        }]
407
-        rules.bizDetailAddress = [{ required: true, message: "请输入经营详细地址", trigger: "blur" }]
408
-        rules.contactName = [{ required: true, message: "请输入联系人姓名", trigger: "blur" }]
409
-        rules.contactPhone = [{ required: true, message: "请输入联系人手机", trigger: "blur" }]
410
-        rules.contactEmail = [{ required: true, message: "请输入联系人邮箱", trigger: "blur" }]
411
-        rules.bankName = [{ required: true, message: "请输入开户银行", trigger: "blur" }]
412
-        rules.bankBranch = [{ required: true, message: "请输入支行名称", trigger: "blur" }]
413
-        rules.bankAccount = [{ required: true, message: "请输入银行账号", trigger: "blur" }]
414
-        if (this.form.merchantType === "2") {
415
-          rules.businessLicense = [{ required: true, message: "请上传营业执照电子版", trigger: "change" }]
416
-          rules.accountPermit = [{ required: true, message: "请上传开户许可证", trigger: "change" }]
417
-        }
418 388
         rules.bindType = [{ required: true, message: "请选择绑定类型", trigger: "change" }]
419 389
         if (this.form.bindType === "SYS_USER") {
420 390
           rules.bindUserId = [{ required: true, message: "请选择平台管理员", trigger: "change" }]
@@ -495,19 +465,6 @@ export default {
495 465
         bindType: "SYS_USER",
496 466
         bindUserId: undefined,
497 467
         bindMemberId: undefined,
498
-        merchantName: undefined,
499
-        servicePhone: undefined,
500
-        bizRegionCode: undefined,
501
-        bizRegionName: undefined,
502
-        bizDetailAddress: undefined,
503
-        contactName: undefined,
504
-        contactPhone: undefined,
505
-        contactEmail: undefined,
506
-        bankName: undefined,
507
-        bankBranch: undefined,
508
-        bankAccount: undefined,
509
-        businessLicense: undefined,
510
-        accountPermit: undefined,
511 468
         bizRegionCascader: []
512 469
       }
513 470
       this.activeTab = "subject"
@@ -664,10 +621,13 @@ export default {
664 621
         const payload = this.buildSubmitPayload()
665 622
         const submitFn = payload.merchantId ? updateMerchant : addMerchant
666 623
         submitFn(payload).then(response => {
667
-          let msg = response.msg || (payload.merchantId ? "修改成功" : "保存成功,已可开设店铺")
668
-          if (payload.merchantId && response.data && response.data.bizCompleteChanged) {
624
+          let msg = payload.merchantId ? "修改成功" : "新增成功"
625
+          if (response.data && response.data.bizCompleteChanged) {
669 626
             msg = "保存成功,已可开设店铺"
670 627
           }
628
+          if (!payload.merchantId) {
629
+            msg = "请尽快在编辑中完善商户经营信息后再开设店铺"
630
+          }
671 631
           if (response.data && response.data.warnExpired) {
672 632
             this.$modal.msgWarning("证件或营业期限已过期,请注意风险")
673 633
           }