From d23dfd4276716dfbcefded0b6ed980ceac180777 Mon Sep 17 00:00:00 2001 From: dhb52 Date: Sun, 18 Feb 2024 00:03:11 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20CRM/backlog=20=E6=8F=90=E9=86=92?= =?UTF-8?q?=E6=95=B0=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/clue/CrmClueController.java | 7 ++ .../admin/contract/CrmContractController.java | 15 +++ .../admin/customer/CrmCustomerController.java | 36 ++++++ .../receivable/CrmReceivableController.java | 8 ++ .../CrmReceivablePlanController.java | 8 ++ .../crm/dal/mysql/clue/CrmClueMapper.java | 14 +++ .../dal/mysql/contract/CrmContractMapper.java | 30 +++++ .../dal/mysql/customer/CrmCustomerMapper.java | 105 ++++++++++++------ .../mysql/receivable/CrmReceivableMapper.java | 16 +++ .../receivable/CrmReceivablePlanMapper.java | 16 +++ .../crm/service/clue/CrmClueService.java | 8 ++ .../crm/service/clue/CrmClueServiceImpl.java | 5 + .../service/contract/CrmContractService.java | 17 +++ .../contract/CrmContractServiceImpl.java | 11 ++ .../service/customer/CrmCustomerService.java | 38 ++++++- .../customer/CrmCustomerServiceImpl.java | 18 +++ .../receivable/CrmReceivablePlanService.java | 7 ++ .../CrmReceivablePlanServiceImpl.java | 6 +- .../receivable/CrmReceivableService.java | 8 ++ .../receivable/CrmReceivableServiceImpl.java | 6 +- 20 files changed, 343 insertions(+), 36 deletions(-) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java index 8be62ae26..a3acd04f6 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java @@ -104,4 +104,11 @@ public class CrmClueController { return success(Boolean.TRUE); } + @GetMapping("/follow-leads-count") + @Operation(summary = "获得分配给我的线索数量") + @PreAuthorize("@ss.hasPermission('crm:clue:query')") + public CommonResult getFollowLeadsCount() { + return success(clueService.getFollowLeadsCount(getLoginUserId())); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java index aaaccbd81..8de96587e 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java @@ -192,4 +192,19 @@ public class CrmContractController { return success(true); } + @GetMapping("/check-contract-count") + @Operation(summary = "获得待审核合同数量") + @PreAuthorize("@ss.hasPermission('crm:contract:query')") + public CommonResult getCheckContractCount() { + return success(contractService.getCheckContractCount(getLoginUserId())); + } + + + @GetMapping("/end-contract-count") + @Operation(summary = "获得即将到期的合同数量") + @PreAuthorize("@ss.hasPermission('crm:contract:query')") + public CommonResult getEndContractCount() { + return success(contractService.getEndContractCount(getLoginUserId())); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java index a2420bc81..83e6274a0 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java @@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*; import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerPoolConfigDO; +import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum; import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerPoolConfigService; import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; @@ -149,6 +150,41 @@ public class CrmCustomerController { return success(CrmCustomerConvert.INSTANCE.convertPage(pageResult, userMap, deptMap, poolDayMap)); } + @GetMapping("/put-in-pool-remind-count") + @Operation(summary = "获得待进入公海客户数量") + @PreAuthorize("@ss.hasPermission('crm:customer:query')") + public CommonResult getPutInPoolRemindCustomerCount() { + // 获取公海配置 TODO @dbh52:合并到 getPutInPoolRemindCustomerPage 会更合适哈; + CrmCustomerPoolConfigDO poolConfigDO = customerPoolConfigService.getCustomerPoolConfig(); + if (ObjUtil.isNull(poolConfigDO) + || Boolean.FALSE.equals(poolConfigDO.getEnabled()) + || Boolean.FALSE.equals(poolConfigDO.getNotifyEnabled())) { + throw exception(CUSTOMER_POOL_CONFIG_NOT_EXISTS_OR_DISABLED); + } + + CrmCustomerPageReqVO pageVO = new CrmCustomerPageReqVO(); + pageVO.setPool(null); + pageVO.setContactStatus(CrmCustomerPageReqVO.CONTACT_TODAY); + pageVO.setSceneType(CrmSceneTypeEnum.OWNER.getType()); + + return success(customerService.getPutInPoolRemindCustomerCount(pageVO, poolConfigDO, getLoginUserId())); + } + + @GetMapping("/today-customer-count") + @Operation(summary = "获得今日需联系客户数量") + @PreAuthorize("@ss.hasPermission('crm:customer:query')") + public CommonResult getTodayCustomerCount() { + return success(customerService.getTodayCustomerCount(getLoginUserId())); + } + + @GetMapping("/follow-customer-count") + @Operation(summary = "获得分配给我的客户数量") + @PreAuthorize("@ss.hasPermission('crm:customer:query')") + public CommonResult getFollowCustomerCount() { + return success(customerService.getFollowCustomerCount(getLoginUserId())); + } + + /** * 获取距离进入公海的时间 * diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java index 8516ebd66..f29bc5139 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java @@ -144,4 +144,12 @@ public class CrmReceivableController { return CrmReceivableConvert.INSTANCE.convertPage(pageResult, userMap, customerList, contractList); } + + @GetMapping("/check-receivables-count") + @Operation(summary = "获得待审核回款数量") + @PreAuthorize("@ss.hasPermission('crm:receivable:query')") + public CommonResult getCheckReceivablesCount() { + return success(receivableService.getCheckReceivablesCount(getLoginUserId())); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java index 252d714f4..6144ae6d3 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java @@ -153,4 +153,12 @@ public class CrmReceivablePlanController { return CrmReceivablePlanConvert.INSTANCE.convertPage(pageResult, userMap, customerList, contractList, receivableList); } + + @GetMapping("/remind-receivable-plan-count") + @Operation(summary = "获得待回款提醒数量") + @PreAuthorize("@ss.hasPermission('crm:receivable-plan:query')") + public CommonResult getRemindReceivablesCount() { + return success(receivablePlanService.getRemindReceivablePlanCount(getLoginUserId())); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/clue/CrmClueMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/clue/CrmClueMapper.java index cab4c4662..a60ecdbcc 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/clue/CrmClueMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/clue/CrmClueMapper.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; +import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum; import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; @@ -53,4 +54,17 @@ public interface CrmClueMapper extends BaseMapperX { return selectJoinList(CrmClueDO.class, query); } + default Long getFollowLeadsCount(Long userId) { + MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); + + // 我负责的, 非公海 + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_LEADS.getType(), + CrmClueDO::getId, userId, CrmSceneTypeEnum.OWNER.getType(), Boolean.FALSE); + + // 未跟进, 未转化 + query.ne(CrmClueDO::getFollowUpStatus, true) + .ne(CrmClueDO::getTransformStatus, true); + + return selectCount(query); + } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java index d553962ee..3f27400d1 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java @@ -9,6 +9,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageR import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; +import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum; import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; @@ -90,4 +91,33 @@ public interface CrmContractMapper extends BaseMapperX { return selectCount(CrmContractDO::getBusinessId, businessId); } + default Long getCheckContractCount(Long userId) { + MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); + + // 我负责的, 非公海 + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTRACT.getType(), + CrmContractDO::getId, userId, CrmSceneTypeEnum.OWNER.getType(), Boolean.FALSE); + + // 未提交 or 审核不通过 + query.in(CrmContractDO::getAuditStatus, CrmAuditStatusEnum.DRAFT.getStatus(), CrmAuditStatusEnum.REJECT.getStatus()); + + return selectCount(query); + } + + default Long getEndContractCount(Long userId) { + MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); + + // 我负责的, 非公海 + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTRACT.getType(), + CrmContractDO::getId, userId, CrmSceneTypeEnum.OWNER.getType(), Boolean.FALSE); + + // 即将到期 + LocalDateTime beginOfToday = LocalDateTimeUtil.beginOfDay(LocalDateTime.now()); + LocalDateTime endOfToday = LocalDateTimeUtil.endOfDay(LocalDateTime.now()); + int REMIND_DAYS = 20; + query.eq(CrmContractDO::getAuditStatus, CrmAuditStatusEnum.APPROVE.getStatus()) + .between(CrmContractDO::getEndTime, beginOfToday, endOfToday.plusDays(REMIND_DAYS)); + + return selectCount(query); + } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java index da2ea92f3..8bfd9cb44 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java @@ -7,9 +7,11 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO; +import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerPoolConfigDO; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; +import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum; import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; @@ -29,6 +31,40 @@ import java.util.List; @Mapper public interface CrmCustomerMapper extends BaseMapperX { + private static MPJLambdaWrapperX buildPutInPoolRemindCustomerWrapper(CrmCustomerPageReqVO pageReqVO, CrmCustomerPoolConfigDO poolConfigDO, Long userId) { + MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); + // 拼接数据权限的查询条件 + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), + CrmCustomerDO::getId, userId, pageReqVO.getSceneType(), null); + + // 锁定状态不需要提醒 + query.ne(CrmCustomerDO::getLockStatus, true); + + // 情况一:未成交提醒日期区间 + Integer dealExpireDays = poolConfigDO.getDealExpireDays(); + LocalDateTime startDealRemindDate = LocalDateTimeUtil.beginOfDay(LocalDateTime.now()) + .minusDays(dealExpireDays); + LocalDateTime endDealRemindDate = LocalDateTimeUtil.endOfDay(LocalDateTime.now()) + .minusDays(Math.max(dealExpireDays - poolConfigDO.getNotifyDays(), 0)); + // 情况二:未跟进提醒日期区间 + Integer contactExpireDays = poolConfigDO.getContactExpireDays(); + LocalDateTime startContactRemindDate = LocalDateTimeUtil.beginOfDay(LocalDateTime.now()) + .minusDays(contactExpireDays); + LocalDateTime endContactRemindDate = LocalDateTimeUtil.endOfDay(LocalDateTime.now()) + .minusDays(Math.max(contactExpireDays - poolConfigDO.getNotifyDays(), 0)); + query + // 情况一:1. 未成交放入公海提醒 + .eq(CrmCustomerDO::getDealStatus, false) + .between(CrmCustomerDO::getCreateTime, startDealRemindDate, endDealRemindDate) + // 情况二:未跟进放入公海提醒 + .or() // 2.1 contactLastTime 为空 TODO 芋艿:这个要不要搞个默认值; + .isNull(CrmCustomerDO::getContactLastTime) + .between(CrmCustomerDO::getCreateTime, startContactRemindDate, endContactRemindDate) + .or() // 2.2 ContactLastTime 不为空 + .between(CrmCustomerDO::getContactLastTime, startContactRemindDate, endContactRemindDate); + return query; + } + default Long selectCountByLockStatusAndOwnerUserId(Boolean lockStatus, Long ownerUserId) { return selectCount(new LambdaUpdateWrapper() .eq(CrmCustomerDO::getLockStatus, lockStatus) @@ -102,39 +138,42 @@ public interface CrmCustomerMapper extends BaseMapperX { default PageResult selectPutInPoolRemindCustomerPage(CrmCustomerPageReqVO pageReqVO, CrmCustomerPoolConfigDO poolConfigDO, Long userId) { - MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); - // 拼接数据权限的查询条件 - CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), - CrmCustomerDO::getId, userId, pageReqVO.getSceneType(), null); - - // 锁定状态不需要提醒 - query.ne(CrmCustomerDO::getLockStatus, true); - - // 拼接自身的查询条件 - query.selectAll(CrmCustomerDO.class); - // 情况一:未成交提醒日期区间 - Integer dealExpireDays = poolConfigDO.getDealExpireDays(); - LocalDateTime startDealRemindDate = LocalDateTimeUtil.beginOfDay(LocalDateTime.now()) - .minusDays(dealExpireDays); - LocalDateTime endDealRemindDate = LocalDateTimeUtil.endOfDay(LocalDateTime.now()) - .minusDays(Math.max(dealExpireDays - poolConfigDO.getNotifyDays(), 0)); - // 情况二:未跟进提醒日期区间 - Integer contactExpireDays = poolConfigDO.getContactExpireDays(); - LocalDateTime startContactRemindDate = LocalDateTimeUtil.beginOfDay(LocalDateTime.now()) - .minusDays(contactExpireDays); - LocalDateTime endContactRemindDate = LocalDateTimeUtil.endOfDay(LocalDateTime.now()) - .minusDays(Math.max(contactExpireDays - poolConfigDO.getNotifyDays(), 0)); - query - // 情况一:1. 未成交放入公海提醒 - .eq(CrmCustomerDO::getDealStatus, false) - .between(CrmCustomerDO::getCreateTime, startDealRemindDate, endDealRemindDate) - // 情况二:未跟进放入公海提醒 - .or() // 2.1 contactLastTime 为空 TODO 芋艿:这个要不要搞个默认值; - .isNull(CrmCustomerDO::getContactLastTime) - .between(CrmCustomerDO::getCreateTime, startContactRemindDate, endContactRemindDate) - .or() // 2.2 ContactLastTime 不为空 - .between(CrmCustomerDO::getContactLastTime, startContactRemindDate, endContactRemindDate); - return selectJoinPage(pageReqVO, CrmCustomerDO.class, query); + final MPJLambdaWrapperX query = buildPutInPoolRemindCustomerWrapper(pageReqVO, poolConfigDO, userId); + return selectJoinPage(pageReqVO, CrmCustomerDO.class, query.selectAll(CrmCustomerDO.class)); } + default Long selectPutInPoolRemindCustomerCount(CrmCustomerPageReqVO pageReqVO, + CrmCustomerPoolConfigDO poolConfigDO, + Long userId) { + final MPJLambdaWrapperX query = buildPutInPoolRemindCustomerWrapper(pageReqVO, poolConfigDO, userId); + return selectCount(query); + } + + default Long getTodayCustomerCount(Long userId) { + MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); + + // 我负责的, 非公海 + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), + CrmCustomerDO::getId, userId, CrmSceneTypeEnum.OWNER.getType(), Boolean.FALSE); + + // 今天需联系 + LocalDateTime beginOfToday = LocalDateTimeUtil.beginOfDay(LocalDateTime.now()); + LocalDateTime endOfToday = LocalDateTimeUtil.endOfDay(LocalDateTime.now()); + query.between(CrmCustomerDO::getContactNextTime, beginOfToday, endOfToday); + + return selectCount(query); + } + + default Long getFollowCustomerCount(Long userId) { + MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); + + // 我负责的, 非公海 + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), + CrmCustomerDO::getId, userId, CrmSceneTypeEnum.OWNER.getType(), Boolean.FALSE); + + // 未跟进 + query.ne(CrmClueDO::getFollowUpStatus, true); + + return selectCount(query); + } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivableMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivableMapper.java index 28b2298ec..36345f01f 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivableMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivableMapper.java @@ -5,8 +5,11 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO; +import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO; +import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; +import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum; import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; @@ -59,4 +62,17 @@ public interface CrmReceivableMapper extends BaseMapperX { return selectJoinList(CrmReceivableDO.class, query); } + default Long getCheckReceivablesCount(Long userId) { + MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); + + // 我负责的, 非公海 + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE.getType(), + CrmReceivableDO::getId, userId, CrmSceneTypeEnum.OWNER.getType(), Boolean.FALSE); + + // 未提交 or 审核不通过 + query.in(CrmContractDO::getAuditStatus, CrmAuditStatusEnum.DRAFT.getStatus(), CrmAuditStatusEnum.REJECT.getStatus()); + + return selectCount(query); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivablePlanMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivablePlanMapper.java index 618a95750..780d611cb 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivablePlanMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivablePlanMapper.java @@ -8,6 +8,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanPageReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; +import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum; import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; @@ -80,4 +81,19 @@ public interface CrmReceivablePlanMapper extends BaseMapperX query = new MPJLambdaWrapperX<>(); + + // 我负责的, 非公海 + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType(), + CrmReceivablePlanDO::getId, userId, CrmSceneTypeEnum.OWNER.getType(), Boolean.FALSE); + + // 待回款 + LocalDateTime beginOfToday = LocalDateTimeUtil.beginOfDay(LocalDateTime.now()); + query.isNull(CrmReceivablePlanDO::getReceivableId) + .gt(CrmReceivablePlanDO::getReturnTime, beginOfToday) + .apply("to_days(return_time) <= to_days(now())+ remind_days"); + + return selectCount(query); + } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueService.java index 1472bf02f..6c37305c7 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueService.java @@ -90,4 +90,12 @@ public interface CrmClueService { */ void translateCustomer(CrmClueTranslateReqVO reqVO, Long userId); + /** + * 获得分配给我的线索数量 + * + * @param userId 用户编号 + * @return 提醒数量 + */ + Long getFollowLeadsCount(Long userId); + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java index dfb044f50..209b54fbc 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java @@ -276,4 +276,9 @@ public class CrmClueServiceImpl implements CrmClueService { return SpringUtil.getBean(getClass()); } + @Override + public Long getFollowLeadsCount(Long userId) { + return clueMapper.getFollowLeadsCount(userId); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java index 3e79b73ed..919cc293c 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java @@ -134,4 +134,21 @@ public interface CrmContractService { */ Long getContractCountByBusinessId(Long businessId); + + /** + * 获得待审核合同数量 + * + * @param userId 用户编号 + * @return 提醒数量 + */ + Long getCheckContractCount(Long userId); + + /** + * 获得即将到期的合同数量 + * + * @param userId 用户编号 + * @return 提醒数量 + */ + Long getEndContractCount(Long userId); + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java index 4af609edd..4c7feb4a9 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java @@ -314,4 +314,15 @@ public class CrmContractServiceImpl implements CrmContractService { return contractMapper.selectCountByBusinessId(businessId); } // TODO @合同待定:需要新增一个 ContractConfigDO 表,合同配置,重点是到期提醒; + + @Override + public Long getCheckContractCount(Long userId) { + return contractMapper.getCheckContractCount(userId); + } + + @Override + public Long getEndContractCount(Long userId) { + return contractMapper.getEndContractCount(userId); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java index 259812e4b..31553f9c0 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java @@ -141,7 +141,43 @@ public interface CrmCustomerService { */ int autoPutCustomerPool(); + /** + * 获得放入公海提醒的客户分页数据 + * + * @param pageVO 分页查询 + * @param poolConfigDO 公海配置 + * @param userId 用户编号 + * @return 客户分页 + */ PageResult getPutInPoolRemindCustomerPage(CrmCustomerPageReqVO pageVO, CrmCustomerPoolConfigDO poolConfigDO, - Long loginUserId); + Long userId); + + /** + * 获得今日需联系客户数量 + * + * @param userId 用户编号 + * @return 提醒数量 + */ + Long getTodayCustomerCount(Long userId); + + /** + * 获得待进入公海的客户数量 + * + * @param pageVO 分页查询 + * @param poolConfigDO 公海配置 + * @param userId 用户编号 + * @return 提醒数量 + */ + Long getPutInPoolRemindCustomerCount(CrmCustomerPageReqVO pageVO, + CrmCustomerPoolConfigDO poolConfigDO, + Long userId); + + /** + * 获得分配给我的客户数量 + * + * @param userId 用户编号 + * @return 提醒数量 + */ + Long getFollowCustomerCount(Long userId); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java index eeea1efdf..26d144ea7 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java @@ -465,12 +465,30 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { return customerMapper.selectPage(pageReqVO, userId); } + @Override public PageResult getPutInPoolRemindCustomerPage(CrmCustomerPageReqVO pageReqVO, CrmCustomerPoolConfigDO poolConfigDO, Long userId) { return customerMapper.selectPutInPoolRemindCustomerPage(pageReqVO, poolConfigDO, userId); } + @Override + public Long getPutInPoolRemindCustomerCount(CrmCustomerPageReqVO pageReqVO, + CrmCustomerPoolConfigDO poolConfigDO, + Long userId) { + return customerMapper.selectPutInPoolRemindCustomerCount(pageReqVO, poolConfigDO, userId); + } + + @Override + public Long getTodayCustomerCount(Long userId) { + return customerMapper.getTodayCustomerCount(userId); + } + + @Override + public Long getFollowCustomerCount(Long userId) { + return customerMapper.getFollowCustomerCount(userId); + } + // ======================= 校验相关 ======================= /** diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanService.java index ded059b28..ebc80f25c 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanService.java @@ -77,4 +77,11 @@ public interface CrmReceivablePlanService { */ PageResult getReceivablePlanPageByCustomerId(CrmReceivablePlanPageReqVO pageReqVO); + /** + * 获得待回款提醒数量 + * + * @param userId 用户编号 + * @return 提醒数量 + */ + Long getRemindReceivablePlanCount(Long userId); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java index 9ac2e7f43..88ba22e14 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java @@ -24,7 +24,6 @@ import com.mzt.logapi.context.LogRecordContext; import com.mzt.logapi.service.impl.DiffParseFunction; import com.mzt.logapi.starter.annotation.LogRecord; import jakarta.annotation.Resource; -import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -163,4 +162,9 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService { return receivablePlanMapper.selectPageByCustomerId(pageReqVO); } + @Override + public Long getRemindReceivablePlanCount(Long userId) { + return receivablePlanMapper.getRemindReceivablePlanCount(userId); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java index 8e9cfa0ea..f92db6a4d 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java @@ -78,4 +78,12 @@ public interface CrmReceivableService { */ PageResult getReceivablePageByCustomerId(CrmReceivablePageReqVO pageReqVO); + /** + * 获得待审核回款数量 + * + * @param userId 用户编号 + * @return 提醒数量 + */ + Long getCheckReceivablesCount(Long userId); + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java index effe0d720..e931286d7 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java @@ -27,7 +27,6 @@ import com.mzt.logapi.context.LogRecordContext; import com.mzt.logapi.service.impl.DiffParseFunction; import com.mzt.logapi.starter.annotation.LogRecord; import jakarta.annotation.Resource; -import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -183,4 +182,9 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { return receivableMapper.selectPageByCustomerId(pageReqVO); } + @Override + public Long getCheckReceivablesCount(Long userId) { + return receivableMapper.getCheckReceivablesCount(userId); + } + }