Browse Source

✨ CRM:优化客户的 backlog 逻辑

YunaiV 1 year ago
parent
commit
4b41c3c692

+ 7 - 8
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java

@@ -174,15 +174,15 @@ public class CrmCustomerController {
         return success(customerService.getPutPoolRemindCustomerCount(getLoginUserId()));
     }
 
-    @GetMapping("/today-customer-count")
+    @GetMapping("/today-contact-count")
     @Operation(summary = "获得今日需联系客户数量")
     @PreAuthorize("@ss.hasPermission('crm:customer:query')")
-    public CommonResult<Long> getTodayCustomerCount() {
-        return success(customerService.getTodayCustomerCount(getLoginUserId()));
+    public CommonResult<Long> getTodayContactCustomerCount() {
+        return success(customerService.getTodayContactCustomerCount(getLoginUserId()));
     }
 
-    @GetMapping("/follow-customer-count")
-    @Operation(summary = "获得分配给我的客户数量")
+    @GetMapping("/follow-count")
+    @Operation(summary = "获得分配给我、待跟进的线索数量的客户数量")
     @PreAuthorize("@ss.hasPermission('crm:customer:query')")
     public CommonResult<Long> getFollowCustomerCount() {
         return success(customerService.getFollowCustomerCount(getLoginUserId()));
@@ -222,9 +222,9 @@ public class CrmCustomerController {
         });
     }
 
-    @GetMapping(value = "/list-all-simple")
+    @GetMapping(value = "/simple-list")
     @Operation(summary = "获取客户精简信息列表", description = "只包含有读权限的客户,主要用于前端的下拉选项")
-    public CommonResult<List<CrmCustomerRespVO>> getSimpleDeptList() {
+    public CommonResult<List<CrmCustomerRespVO>> getCustomerSimpleList() {
         CrmCustomerPageReqVO reqVO = new CrmCustomerPageReqVO();
         reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页
         List<CrmCustomerDO> list = customerService.getCustomerPage(reqVO, getLoginUserId()).getList();
@@ -232,7 +232,6 @@ public class CrmCustomerController {
                 new CrmCustomerRespVO().setId(customer.getId()).setName(customer.getName())));
     }
 
-    // TODO @puhui999:公海的导出,前端可以接下
     @GetMapping("/export-excel")
     @Operation(summary = "导出客户 Excel")
     @PreAuthorize("@ss.hasPermission('crm:customer:export')")

+ 12 - 12
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java

@@ -49,11 +49,11 @@ public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> {
                 .set(CrmCustomerDO::getOwnerUserId, ownerUserId));
     }
 
-    default PageResult<CrmCustomerDO> selectPage(CrmCustomerPageReqVO pageReqVO, Long userId) {
+    default PageResult<CrmCustomerDO> selectPage(CrmCustomerPageReqVO pageReqVO, Long ownerUserId) {
         MPJLambdaWrapperX<CrmCustomerDO> query = new MPJLambdaWrapperX<>();
         // 拼接数据权限的查询条件
         CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(),
-                CrmCustomerDO::getId, userId, pageReqVO.getSceneType(), pageReqVO.getPool());
+                CrmCustomerDO::getId, ownerUserId, pageReqVO.getSceneType(), pageReqVO.getPool());
         // 拼接自身的查询条件
         query.selectAll(CrmCustomerDO.class)
                 .likeIfPresent(CrmCustomerDO::getName, pageReqVO.getName())
@@ -81,10 +81,10 @@ public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> {
         return selectJoinPage(pageReqVO, CrmCustomerDO.class, query);
     }
 
-    default List<CrmCustomerDO> selectBatchIds(Collection<Long> ids, Long userId) {
+    default List<CrmCustomerDO> selectBatchIds(Collection<Long> ids, Long ownerUserId) {
         MPJLambdaWrapperX<CrmCustomerDO> query = new MPJLambdaWrapperX<>();
         // 拼接数据权限的查询条件
-        CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), ids, userId);
+        CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), ids, ownerUserId);
         // 拼接自身的查询条件
         query.selectAll(CrmCustomerDO.class).in(CrmCustomerDO::getId, ids).orderByDesc(CrmCustomerDO::getId);
         return selectJoinList(CrmCustomerDO.class, query);
@@ -96,8 +96,8 @@ public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> {
 
     default PageResult<CrmCustomerDO> selectPutPoolRemindCustomerPage(CrmCustomerPageReqVO pageReqVO,
                                                                       CrmCustomerPoolConfigDO poolConfig,
-                                                                      Long userId) {
-        final MPJLambdaWrapperX<CrmCustomerDO> query = buildPutPoolRemindCustomerQuery(pageReqVO, poolConfig, userId);
+                                                                      Long ownerUserId) {
+        final MPJLambdaWrapperX<CrmCustomerDO> query = buildPutPoolRemindCustomerQuery(pageReqVO, poolConfig, ownerUserId);
         return selectJoinPage(pageReqVO, CrmCustomerDO.class, query.selectAll(CrmCustomerDO.class));
     }
 
@@ -110,11 +110,11 @@ public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> {
 
     private static MPJLambdaWrapperX<CrmCustomerDO> buildPutPoolRemindCustomerQuery(CrmCustomerPageReqVO pageReqVO,
                                                                                     CrmCustomerPoolConfigDO poolConfig,
-                                                                                    Long userId) {
+                                                                                    Long ownerUserId) {
         MPJLambdaWrapperX<CrmCustomerDO> query = new MPJLambdaWrapperX<>();
         // 拼接数据权限的查询条件
         CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(),
-                CrmCustomerDO::getId, userId, pageReqVO.getSceneType(), null);
+                CrmCustomerDO::getId, ownerUserId, pageReqVO.getSceneType(), null);
 
         // 未锁定 + 未成交
         query.eq(CrmCustomerDO::getLockStatus, false).eq(CrmCustomerDO::getDealStatus, false);
@@ -164,11 +164,11 @@ public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> {
         return selectList(query);
     }
 
-    default Long selectTodayCustomerCount(Long userId) {
+    default Long selectCountByTodayContact(Long ownerUserId) {
         MPJLambdaWrapperX<CrmCustomerDO> query = new MPJLambdaWrapperX<>();
         // 我负责的 + 非公海
         CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(),
-                CrmCustomerDO::getId, userId, CrmSceneTypeEnum.OWNER.getType(), Boolean.FALSE);
+                CrmCustomerDO::getId, ownerUserId, CrmSceneTypeEnum.OWNER.getType(), Boolean.FALSE);
         // 今天需联系
         LocalDateTime beginOfToday = LocalDateTimeUtil.beginOfDay(LocalDateTime.now());
         LocalDateTime endOfToday = LocalDateTimeUtil.endOfDay(LocalDateTime.now());
@@ -176,11 +176,11 @@ public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> {
         return selectCount(query);
     }
 
-    default Long selectFollowCustomerCount(Long userId) {
+    default Long selectCountByFollow(Long ownerUserId) {
         MPJLambdaWrapperX<CrmCustomerDO> query = new MPJLambdaWrapperX<>();
         // 我负责的 + 非公海
         CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(),
-                CrmCustomerDO::getId, userId, CrmSceneTypeEnum.OWNER.getType(), Boolean.FALSE);
+                CrmCustomerDO::getId, ownerUserId, CrmSceneTypeEnum.OWNER.getType(), Boolean.FALSE);
         // 未跟进
         query.eq(CrmClueDO::getFollowUpStatus, false);
         return selectCount(query);

+ 17 - 17
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java

@@ -113,6 +113,22 @@ public interface CrmCustomerService {
      */
     Long getPutPoolRemindCustomerCount(Long userId);
 
+    /**
+     * 获得今日需联系客户数量
+     *
+     * @param userId 用户编号
+     * @return 提醒数量
+     */
+    Long getTodayContactCustomerCount(Long userId);
+
+    /**
+     * 获得分配给我的客户数量
+     *
+     * @param userId 用户编号
+     * @return 提醒数量
+     */
+    Long getFollowCustomerCount(Long userId);
+
     /**
      * 校验客户是否存在
      *
@@ -168,7 +184,7 @@ public interface CrmCustomerService {
      *
      * @param ids         要领取的客户编号数组
      * @param ownerUserId 负责人
-     * @param isReceive   是/否领取
+     * @param isReceive   是/否领取;true - 领取;false - 分配
      */
     void receiveCustomer(List<Long> ids, Long ownerUserId, Boolean isReceive);
 
@@ -179,20 +195,4 @@ public interface CrmCustomerService {
      */
     int autoPutCustomerPool();
 
-    /**
-     * 获得今日需联系客户数量
-     *
-     * @param userId 用户编号
-     * @return 提醒数量
-     */
-    Long getTodayCustomerCount(Long userId);
-
-    /**
-     * 获得分配给我的客户数量
-     *
-     * @param userId 用户编号
-     * @return 提醒数量
-     */
-    Long getFollowCustomerCount(Long userId);
-
 }

+ 29 - 34
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java

@@ -18,7 +18,6 @@ import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
 import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
 import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission;
-import cn.iocoder.yudao.module.crm.framework.permission.core.util.CrmPermissionUtils;
 import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;
 import cn.iocoder.yudao.module.crm.service.contact.CrmContactService;
 import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
@@ -191,23 +190,6 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
         LogRecordContext.putVariable("customerName", customer.getName());
     }
 
-    /**
-     * 校验客户是否被引用
-     *
-     * @param id 客户编号
-     */
-    private void validateCustomerReference(Long id) {
-        if (contactService.getContactCountByCustomerId(id) > 0) {
-            throw exception(CUSTOMER_DELETE_FAIL_HAVE_REFERENCE, CrmBizTypeEnum.CRM_CONTACT.getName());
-        }
-        if (businessService.getBusinessCountByCustomerId(id) > 0) {
-            throw exception(CUSTOMER_DELETE_FAIL_HAVE_REFERENCE, CrmBizTypeEnum.CRM_BUSINESS.getName());
-        }
-        if (contractService.getContractCountByCustomerId(id) > 0) {
-            throw exception(CUSTOMER_DELETE_FAIL_HAVE_REFERENCE, CrmBizTypeEnum.CRM_CONTRACT.getName());
-        }
-    }
-
     @Override
     @Transactional(rollbackFor = Exception.class)
     @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.id}}",
@@ -336,13 +318,6 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
         LogRecordContext.putVariable("isUpdate", isUpdate);
     }
 
-    private void validateCustomerForCreate(CrmCustomerImportExcelVO importCustomer) {
-        // 校验客户名称不能为空
-        if (StrUtil.isEmptyIfStr(importCustomer.getName())) {
-            throw exception(CUSTOMER_CREATE_NAME_NOT_NULL);
-        }
-    }
-
     // ==================== 公海相关操作 ====================
 
     @Override
@@ -371,18 +346,14 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void receiveCustomer(List<Long> ids, Long ownerUserId, Boolean isReceive) {
-        if (!isReceive && !CrmPermissionUtils.isCrmAdmin()) { // 只有管理员可以分配
-            throw exception(CRM_PERMISSION_DENIED, CrmBizTypeEnum.CRM_CUSTOMER.getName());
-        }
-
         // 1.1 校验存在
         List<CrmCustomerDO> customers = customerMapper.selectBatchIds(ids);
         if (customers.size() != ids.size()) {
             throw exception(CUSTOMER_NOT_EXISTS);
         }
-        // 1.2. 校验负责人是否存在
+        // 1.2 校验负责人是否存在
         adminUserApi.validateUserList(singletonList(ownerUserId));
-        // 1.3. 校验状态
+        // 1.3 校验状态
         customers.forEach(customer -> {
             // 校验是否已有负责人
             validateCustomerOwnerExists(customer, false);
@@ -513,17 +484,41 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
     }
 
     @Override
-    public Long getTodayCustomerCount(Long userId) {
-        return customerMapper.selectTodayCustomerCount(userId);
+    public Long getTodayContactCustomerCount(Long userId) {
+        return customerMapper.selectCountByTodayContact(userId);
     }
 
     @Override
     public Long getFollowCustomerCount(Long userId) {
-        return customerMapper.selectFollowCustomerCount(userId);
+        return customerMapper.selectCountByFollow(userId);
     }
 
     // ======================= 校验相关 =======================
 
+    private void validateCustomerForCreate(CrmCustomerImportExcelVO importCustomer) {
+        // 校验客户名称不能为空
+        if (StrUtil.isEmptyIfStr(importCustomer.getName())) {
+            throw exception(CUSTOMER_CREATE_NAME_NOT_NULL);
+        }
+    }
+
+    /**
+     * 校验客户是否被引用
+     *
+     * @param id 客户编号
+     */
+    private void validateCustomerReference(Long id) {
+        if (contactService.getContactCountByCustomerId(id) > 0) {
+            throw exception(CUSTOMER_DELETE_FAIL_HAVE_REFERENCE, CrmBizTypeEnum.CRM_CONTACT.getName());
+        }
+        if (businessService.getBusinessCountByCustomerId(id) > 0) {
+            throw exception(CUSTOMER_DELETE_FAIL_HAVE_REFERENCE, CrmBizTypeEnum.CRM_BUSINESS.getName());
+        }
+        if (contractService.getContractCountByCustomerId(id) > 0) {
+            throw exception(CUSTOMER_DELETE_FAIL_HAVE_REFERENCE, CrmBizTypeEnum.CRM_CONTRACT.getName());
+        }
+    }
+
     /**
      * 校验客户是否存在
      *