Commit c573585e75a292a9e35d5c73a4ec3bee015eedd2
1 parent
5cf34c2b
CRM: 新增商机赢单转化率分析
Showing
7 changed files
with
87 additions
and
15 deletions
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> |