Commit c573585e75a292a9e35d5c73a4ec3bee015eedd2

Authored by puhui999
1 parent 5cf34c2b

CRM: 新增商机赢单转化率分析

yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsFunnelController.java
@@ -5,10 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; @@ -5,10 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.module.crm.controller.admin.business.CrmBusinessController; 6 import cn.iocoder.yudao.module.crm.controller.admin.business.CrmBusinessController;
7 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessRespVO; 7 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessRespVO;
8 -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByEndStatusRespVO;  
9 -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticFunnelSummaryRespVO;  
10 -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByDateRespVO;  
11 -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsFunnelReqVO; 8 +import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.*;
12 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 9 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
13 import cn.iocoder.yudao.module.crm.service.statistics.CrmStatisticsFunnelService; 10 import cn.iocoder.yudao.module.crm.service.statistics.CrmStatisticsFunnelService;
14 import io.swagger.v3.oas.annotations.Operation; 11 import io.swagger.v3.oas.annotations.Operation;
@@ -55,6 +52,13 @@ public class CrmStatisticsFunnelController { @@ -55,6 +52,13 @@ public class CrmStatisticsFunnelController {
55 return success(funnelService.getBusinessSummaryByDate(reqVO)); 52 return success(funnelService.getBusinessSummaryByDate(reqVO));
56 } 53 }
57 54
  55 + @GetMapping("/get-business-inversion-rate-summary-by-date")
  56 + @Operation(summary = "获取商机转化率分析(按日期)", description = "用于【销售漏斗】页面")
  57 + @PreAuthorize("@ss.hasPermission('crm:statistics-funnel:query')")
  58 + public CommonResult<List<CrmStatisticsBusinessInversionRateSummaryByDateRespVO>> getBusinessInversionRateSummaryByDate(@Valid CrmStatisticsFunnelReqVO reqVO) {
  59 + return success(funnelService.getBusinessInversionRateSummaryByDate(reqVO));
  60 + }
  61 +
58 @GetMapping("/get-business-page-by-date") 62 @GetMapping("/get-business-page-by-date")
59 @Operation(summary = "获得商机分页(按日期)", description = "用于【销售漏斗】页面的【新增商机分析】") 63 @Operation(summary = "获得商机分页(按日期)", description = "用于【销售漏斗】页面的【新增商机分析】")
60 @PreAuthorize("@ss.hasPermission('crm:business:query')") 64 @PreAuthorize("@ss.hasPermission('crm:business:query')")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/funnel/CrmStatisticsBusinessInversionRateSummaryByDateRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.math.BigDecimal;
  7 +
  8 +@Schema(description = "管理后台 - CRM 商机转化率分析(按日期) VO")
  9 +@Data
  10 +public class CrmStatisticsBusinessInversionRateSummaryByDateRespVO {
  11 +
  12 + @Schema(description = "时间轴", requiredMode = Schema.RequiredMode.REQUIRED, example = "202401")
  13 + private String time;
  14 +
  15 + @Schema(description = "商机数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  16 + private Long businessCount;
  17 +
  18 + @Schema(description = "赢单商机数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  19 + private Long businessWinCount;
  20 +
  21 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/funnel/CrmStatisticsBusinessSummaryByDateRespVO.java
@@ -13,7 +13,7 @@ public class CrmStatisticsBusinessSummaryByDateRespVO { @@ -13,7 +13,7 @@ public class CrmStatisticsBusinessSummaryByDateRespVO {
13 private String time; 13 private String time;
14 14
15 @Schema(description = "新增商机数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 15 @Schema(description = "新增商机数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
16 - private Integer businessCreateCount; 16 + private Long businessCreateCount;
17 17
18 @Schema(description = "新增商机金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 18 @Schema(description = "新增商机金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
19 private BigDecimal totalPrice; 19 private BigDecimal totalPrice;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsFunnelMapper.java
1 package cn.iocoder.yudao.module.crm.dal.mysql.statistics; 1 package cn.iocoder.yudao.module.crm.dal.mysql.statistics;
2 2
  3 +import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessInversionRateSummaryByDateRespVO;
3 import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByDateRespVO; 4 import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByDateRespVO;
4 import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByEndStatusRespVO; 5 import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByEndStatusRespVO;
5 import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsFunnelReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsFunnelReqVO;
@@ -24,4 +25,6 @@ public interface CrmStatisticsFunnelMapper { @@ -24,4 +25,6 @@ public interface CrmStatisticsFunnelMapper {
24 25
25 List<CrmStatisticsBusinessSummaryByDateRespVO> selectBusinessSummaryGroupByDate(CrmStatisticsFunnelReqVO reqVO); 26 List<CrmStatisticsBusinessSummaryByDateRespVO> selectBusinessSummaryGroupByDate(CrmStatisticsFunnelReqVO reqVO);
26 27
  28 + List<CrmStatisticsBusinessInversionRateSummaryByDateRespVO> selectBusinessInversionRateSummaryByDate(CrmStatisticsFunnelReqVO reqVO);
  29 +
27 } 30 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsFunnelService.java
1 package cn.iocoder.yudao.module.crm.service.statistics; 1 package cn.iocoder.yudao.module.crm.service.statistics;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByEndStatusRespVO;  
5 -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticFunnelSummaryRespVO;  
6 -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByDateRespVO;  
7 -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsFunnelReqVO; 4 +import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.*;
8 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 5 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
9 6
10 import java.util.List; 7 import java.util.List;
@@ -41,6 +38,14 @@ public interface CrmStatisticsFunnelService { @@ -41,6 +38,14 @@ public interface CrmStatisticsFunnelService {
41 List<CrmStatisticsBusinessSummaryByDateRespVO> getBusinessSummaryByDate(CrmStatisticsFunnelReqVO reqVO); 38 List<CrmStatisticsBusinessSummaryByDateRespVO> getBusinessSummaryByDate(CrmStatisticsFunnelReqVO reqVO);
42 39
43 /** 40 /**
  41 + * 获得商机转化率分析(按日期)
  42 + *
  43 + * @param reqVO 请求
  44 + * @return 商机转化率分析
  45 + */
  46 + List<CrmStatisticsBusinessInversionRateSummaryByDateRespVO> getBusinessInversionRateSummaryByDate(CrmStatisticsFunnelReqVO reqVO);
  47 +
  48 + /**
44 * 获得商机分页(按日期) 49 * 获得商机分页(按日期)
45 * 50 *
46 * @param pageVO 请求 51 * @param pageVO 请求
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsFunnelServiceImpl.java
@@ -4,10 +4,7 @@ import cn.hutool.core.collection.CollUtil; @@ -4,10 +4,7 @@ import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.util.ObjUtil; 4 import cn.hutool.core.util.ObjUtil;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; 6 import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
7 -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticFunnelSummaryRespVO;  
8 -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByDateRespVO;  
9 -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByEndStatusRespVO;  
10 -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsFunnelReqVO; 7 +import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.*;
11 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 8 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
12 import cn.iocoder.yudao.module.crm.dal.mysql.statistics.CrmStatisticsFunnelMapper; 9 import cn.iocoder.yudao.module.crm.dal.mysql.statistics.CrmStatisticsFunnelMapper;
13 import cn.iocoder.yudao.module.crm.enums.business.CrmBusinessEndStatusEnum; 10 import cn.iocoder.yudao.module.crm.enums.business.CrmBusinessEndStatusEnum;
@@ -85,9 +82,9 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic @@ -85,9 +82,9 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic
85 // 3. 按照日期间隔,合并数据 82 // 3. 按照日期间隔,合并数据
86 List<LocalDateTime[]> timeRanges = LocalDateTimeUtils.getDateRangeList(reqVO.getTimes()[0], reqVO.getTimes()[1], reqVO.getInterval()); 83 List<LocalDateTime[]> timeRanges = LocalDateTimeUtils.getDateRangeList(reqVO.getTimes()[0], reqVO.getTimes()[1], reqVO.getInterval());
87 return convertList(timeRanges, times -> { 84 return convertList(timeRanges, times -> {
88 - Integer businessCreateCount = businessSummaryList.stream() 85 + Long businessCreateCount = businessSummaryList.stream()
89 .filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getTime())) 86 .filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getTime()))
90 - .mapToInt(CrmStatisticsBusinessSummaryByDateRespVO::getBusinessCreateCount).sum(); 87 + .mapToLong(CrmStatisticsBusinessSummaryByDateRespVO::getBusinessCreateCount).sum();
91 BigDecimal businessDealCount = businessSummaryList.stream() 88 BigDecimal businessDealCount = businessSummaryList.stream()
92 .filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getTime())) 89 .filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getTime()))
93 .map(CrmStatisticsBusinessSummaryByDateRespVO::getTotalPrice) 90 .map(CrmStatisticsBusinessSummaryByDateRespVO::getTotalPrice)
@@ -99,6 +96,31 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic @@ -99,6 +96,31 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic
99 } 96 }
100 97
101 @Override 98 @Override
  99 + public List<CrmStatisticsBusinessInversionRateSummaryByDateRespVO> getBusinessInversionRateSummaryByDate(CrmStatisticsFunnelReqVO reqVO) {
  100 + // 1. 获得用户编号数组
  101 + reqVO.setUserIds(getUserIds(reqVO));
  102 + if (CollUtil.isEmpty(reqVO.getUserIds())) {
  103 + return Collections.emptyList();
  104 + }
  105 +
  106 + // 2. 按天统计,获取分项统计数据
  107 + List<CrmStatisticsBusinessInversionRateSummaryByDateRespVO> businessSummaryList = funnelMapper.selectBusinessInversionRateSummaryByDate(reqVO);
  108 + // 3. 按照日期间隔,合并数据
  109 + List<LocalDateTime[]> timeRanges = LocalDateTimeUtils.getDateRangeList(reqVO.getTimes()[0], reqVO.getTimes()[1], reqVO.getInterval());
  110 + return convertList(timeRanges, times -> {
  111 + Long businessCount = businessSummaryList.stream()
  112 + .filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getTime()))
  113 + .mapToLong(CrmStatisticsBusinessInversionRateSummaryByDateRespVO::getBusinessCount).sum();
  114 + Long businessWinCount = businessSummaryList.stream()
  115 + .filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getTime()))
  116 + .mapToLong(CrmStatisticsBusinessInversionRateSummaryByDateRespVO::getBusinessWinCount).sum();
  117 + return new CrmStatisticsBusinessInversionRateSummaryByDateRespVO()
  118 + .setTime(LocalDateTimeUtils.formatDateRange(times[0], times[1], reqVO.getInterval()))
  119 + .setBusinessCount(businessCount).setBusinessWinCount(businessWinCount);
  120 + });
  121 + }
  122 +
  123 + @Override
102 public PageResult<CrmBusinessDO> getBusinessPageByDate(CrmStatisticsFunnelReqVO pageVO) { 124 public PageResult<CrmBusinessDO> getBusinessPageByDate(CrmStatisticsFunnelReqVO pageVO) {
103 // 1. 获得用户编号数组 125 // 1. 获得用户编号数组
104 pageVO.setUserIds(getUserIds(pageVO)); 126 pageVO.setUserIds(getUserIds(pageVO));
yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsFunnelMapper.xml
@@ -60,4 +60,21 @@ @@ -60,4 +60,21 @@
60 GROUP BY time 60 GROUP BY time
61 </select> 61 </select>
62 62
  63 + <select id="selectBusinessInversionRateSummaryByDate"
  64 + resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessInversionRateSummaryByDateRespVO">
  65 + SELECT
  66 + DATE_FORMAT(create_time, '%Y-%m-%d') AS time,
  67 + COUNT(*) AS businessCount,
  68 + SUM(IF(end_status = 1, 1, 0)) AS businessWinCount
  69 + FROM crm_business
  70 + WHERE deleted = 0
  71 + AND owner_user_id IN
  72 + <foreach collection="userIds" item="userId" open="(" close=")" separator=",">
  73 + #{userId}
  74 + </foreach>
  75 + AND create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND
  76 + #{times[1],javaType=java.time.LocalDateTime}
  77 + GROUP BY time
  78 + </select>
  79 +
63 </mapper> 80 </mapper>