Commit af610c621fce097a24f844889cc51fa3e6f44dc9

Authored by 芋道源码
Committed by Gitee
2 parents 488c4607 9e6474a1

!952 CRM员工业绩统计完善及bug修复

Merge pull request !952 from scholarli/develop
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsPerformanceServiceImpl.java
1 package cn.iocoder.yudao.module.crm.service.statistics; 1 package cn.iocoder.yudao.module.crm.service.statistics;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.date.LocalDateTimeUtil;
4 import cn.hutool.core.util.ObjUtil; 5 import cn.hutool.core.util.ObjUtil;
5 import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceReqVO;
6 import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceRespVO; 7 import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceRespVO;
@@ -13,8 +14,9 @@ import org.springframework.stereotype.Service; @@ -13,8 +14,9 @@ import org.springframework.stereotype.Service;
13 import org.springframework.validation.annotation.Validated; 14 import org.springframework.validation.annotation.Validated;
14 15
15 import jakarta.annotation.Resource; 16 import jakarta.annotation.Resource;
16 -import java.util.Collections;  
17 -import java.util.List; 17 +
  18 +import java.math.BigDecimal;
  19 +import java.util.*;
18 import java.util.function.Function; 20 import java.util.function.Function;
19 21
20 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; 22 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
@@ -59,24 +61,87 @@ public class CrmStatisticsPerformanceServiceImpl implements CrmStatisticsPerform @@ -59,24 +61,87 @@ public class CrmStatisticsPerformanceServiceImpl implements CrmStatisticsPerform
59 * 获得员工业绩数据 61 * 获得员工业绩数据
60 * 62 *
61 * @param performanceReqVO 参数 63 * @param performanceReqVO 参数
62 - * @param performanceFunction 排行榜方法  
63 - * @return 排行版数据 64 + * @param performanceFunction 员工业绩统计方法
  65 + * @return 员工业绩数据
64 */ 66 */
65 private List<CrmStatisticsPerformanceRespVO> getPerformance(CrmStatisticsPerformanceReqVO performanceReqVO, Function<CrmStatisticsPerformanceReqVO, 67 private List<CrmStatisticsPerformanceRespVO> getPerformance(CrmStatisticsPerformanceReqVO performanceReqVO, Function<CrmStatisticsPerformanceReqVO,
66 List<CrmStatisticsPerformanceRespVO>> performanceFunction) { 68 List<CrmStatisticsPerformanceRespVO>> performanceFunction) {
67 69
  70 + List<CrmStatisticsPerformanceRespVO> performanceRespVOList;
  71 +
68 // 1. 获得用户编号数组 72 // 1. 获得用户编号数组
69 final List<Long> userIds = getUserIds(performanceReqVO); 73 final List<Long> userIds = getUserIds(performanceReqVO);
70 if (CollUtil.isEmpty(userIds)) { 74 if (CollUtil.isEmpty(userIds)) {
71 return Collections.emptyList(); 75 return Collections.emptyList();
72 } 76 }
73 performanceReqVO.setUserIds(userIds); 77 performanceReqVO.setUserIds(userIds);
74 - // 2. 获得排行数据 78 + // 2. 获得业绩数据
75 List<CrmStatisticsPerformanceRespVO> performance = performanceFunction.apply(performanceReqVO); 79 List<CrmStatisticsPerformanceRespVO> performance = performanceFunction.apply(performanceReqVO);
76 - if (CollUtil.isEmpty(performance)) {  
77 - return Collections.emptyList(); 80 +
  81 + // 获取查询的年份
  82 + String currentYear = LocalDateTimeUtil.format(performanceReqVO.getTimes()[0],"yyyy");
  83 +
  84 + // 构造查询当年和前一年,每年12个月的年月组合
  85 + List<String> allMonths = new ArrayList<>();
  86 + for (int year = Integer.parseInt(currentYear)-1; year <= Integer.parseInt(currentYear); year++) {
  87 + for (int month = 1; month <= 12; month++) {
  88 + allMonths.add(String.format("%d%02d", year, month));
  89 + }
  90 + }
  91 +
  92 + List<CrmStatisticsPerformanceRespVO> computedList = new ArrayList<>();
  93 + List<CrmStatisticsPerformanceRespVO> respVOList = new ArrayList<>();
  94 +
  95 + // 生成computedList基础数据
  96 + // 构造完整的2*12个月的数据,如果某月数据缺失,需要补上0,一年12个月不能有缺失
  97 + for (String month : allMonths) {
  98 + CrmStatisticsPerformanceRespVO foundData = performance.stream()
  99 + .filter(data -> data.getTime().equals(month))
  100 + .findFirst()
  101 + .orElse(null);
  102 +
  103 + if (foundData != null) {
  104 + computedList.add(foundData);
  105 + } else {
  106 + CrmStatisticsPerformanceRespVO missingData = new CrmStatisticsPerformanceRespVO();
  107 + missingData.setTime(month);
  108 + missingData.setCurrentMonthCount(BigDecimal.ZERO);
  109 + missingData.setLastMonthCount(BigDecimal.ZERO);
  110 + missingData.setLastYearCount(BigDecimal.ZERO);
  111 + computedList.add(missingData);
  112 + }
  113 + }
  114 + //根据查询年份和前一年的数据,计算查询年份的同比环比数据
  115 + for (CrmStatisticsPerformanceRespVO currentData : computedList) {
  116 + String currentMonth = currentData.getTime();
  117 +
  118 + // 根据当年和前一年的月销售数据,计算currentYear的完整数据
  119 + if (currentMonth.startsWith(currentYear)) {
  120 + // 计算 LastMonthCount
  121 + int currentIndex = computedList.indexOf(currentData);
  122 + if (currentIndex > 0) {
  123 + CrmStatisticsPerformanceRespVO lastMonthData = computedList.get(currentIndex - 1);
  124 + currentData.setLastMonthCount(lastMonthData.getCurrentMonthCount());
  125 + } else {
  126 + currentData.setLastMonthCount(BigDecimal.ZERO); // 第一个月的 LastMonthCount 设为0
  127 + }
  128 +
  129 + // 计算 LastYearCount
  130 + String lastYearMonth = String.valueOf(Integer.parseInt(currentMonth) - 100);
  131 + CrmStatisticsPerformanceRespVO lastYearData = computedList.stream()
  132 + .filter(data -> data.getTime().equals(lastYearMonth))
  133 + .findFirst()
  134 + .orElse(null);
  135 +
  136 + if (lastYearData != null) {
  137 + currentData.setLastYearCount(lastYearData.getCurrentMonthCount());
  138 + } else {
  139 + currentData.setLastYearCount(BigDecimal.ZERO); // 如果去年同月数据不存在,设为0
  140 + }
  141 + respVOList.add(currentData);//给前端只需要返回查询当年的数据,不需要前一年数据
  142 + }
78 } 143 }
79 - return performance; 144 + return respVOList;
80 } 145 }
81 146
82 /** 147 /**
yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsPerformanceMapper.xml
@@ -5,27 +5,8 @@ @@ -5,27 +5,8 @@
5 <select id="selectContractCountPerformance" 5 <select id="selectContractCountPerformance"
6 resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceRespVO"> 6 resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceRespVO">
7 SELECT 7 SELECT
8 - t.time as time,  
9 - COALESCE(t.currentMonthCount,0) as currentMonthCount,  
10 - COALESCE(y.lastMonthCount,0) as lastMonthCount,  
11 - COALESCE(z.lastYearCount,0) as lastYearCount  
12 - FROM  
13 - (SELECT  
14 - COUNT(1) AS currentMonthCount,  
15 - DATE_FORMAT(order_date, '%Y-%m') AS time  
16 - FROM crm_contract  
17 - WHERE deleted = 0  
18 - AND audit_status = 20  
19 - AND owner_user_id in  
20 - <foreach collection="userIds" item="userId" open="(" close=")" separator=",">  
21 - #{userId}  
22 - </foreach>  
23 - AND DATE_FORMAT(order_date, '%Y') = DATE_FORMAT(#{times[0],javaType=java.time.LocalDateTime},'%Y')  
24 - GROUP BY time)t  
25 - LEFT JOIN  
26 - (SELECT  
27 - COUNT(1) AS lastMonthCount,  
28 - DATE_FORMAT(DATE_ADD(order_date,INTERVAL 1 MONTH), '%Y-%m') AS time 8 + DATE_FORMAT(order_date, '%Y%m') AS time,
  9 + COUNT(1) AS currentMonthCount
29 FROM crm_contract 10 FROM crm_contract
30 WHERE deleted = 0 11 WHERE deleted = 0
31 AND audit_status = 20 12 AND audit_status = 20
@@ -35,45 +16,14 @@ @@ -35,45 +16,14 @@
35 </foreach> 16 </foreach>
36 AND (DATE_FORMAT(order_date, '%Y') = DATE_FORMAT(#{times[0],javaType=java.time.LocalDateTime},'%Y') 17 AND (DATE_FORMAT(order_date, '%Y') = DATE_FORMAT(#{times[0],javaType=java.time.LocalDateTime},'%Y')
37 or DATE_FORMAT(order_date, '%Y') = DATE_FORMAT(#{times[0],javaType=java.time.LocalDateTime},'%Y')-1) 18 or DATE_FORMAT(order_date, '%Y') = DATE_FORMAT(#{times[0],javaType=java.time.LocalDateTime},'%Y')-1)
38 - GROUP BY time)y ON t.time = y.time  
39 - LEFT JOIN  
40 - (SELECT  
41 - COUNT(1) AS lastYearCount,  
42 - DATE_FORMAT(DATE_ADD(order_date,INTERVAL 1 YEAR), '%Y-%m') AS time  
43 - FROM crm_contract  
44 - WHERE deleted = 0  
45 - AND audit_status = 20  
46 - AND owner_user_id in  
47 - <foreach collection="userIds" item="userId" open="(" close=")" separator=",">  
48 - #{userId}  
49 - </foreach>  
50 - AND DATE_FORMAT(order_date, '%Y') = DATE_FORMAT(#{times[0],javaType=java.time.LocalDateTime},'%Y')-1  
51 - GROUP BY time)z ON t.time = z.time 19 + GROUP BY time
52 </select> 20 </select>
  21 +
53 <select id="selectContractPricePerformance" 22 <select id="selectContractPricePerformance"
54 resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceRespVO"> 23 resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceRespVO">
55 SELECT 24 SELECT
56 - t.time as time,  
57 - COALESCE(t.currentMonthCount,0) as currentMonthCount,  
58 - COALESCE(y.lastMonthCount,0) as lastMonthCount,  
59 - COALESCE(z.lastYearCount,0) as lastYearCount  
60 - FROM  
61 - (SELECT  
62 - IFNULL(SUM(total_price), 0) AS currentMonthCount,  
63 - DATE_FORMAT(order_date, '%Y-%m') AS time  
64 - FROM crm_contract  
65 - WHERE deleted = 0  
66 - AND audit_status = 20  
67 - AND owner_user_id in  
68 - <foreach collection="userIds" item="userId" open="(" close=")" separator=",">  
69 - #{userId}  
70 - </foreach>  
71 - AND DATE_FORMAT(order_date, '%Y') = DATE_FORMAT(#{times[0],javaType=java.time.LocalDateTime},'%Y')  
72 - GROUP BY time)t  
73 - LEFT JOIN  
74 - (SELECT  
75 - IFNULL(SUM(total_price), 0) AS lastMonthCount,  
76 - DATE_FORMAT(DATE_ADD(order_date,INTERVAL 1 MONTH), '%Y-%m') AS time 25 + DATE_FORMAT(order_date, '%Y%m') AS time,
  26 + IFNULL(SUM(total_price), 0) AS currentMonthCount
77 FROM crm_contract 27 FROM crm_contract
78 WHERE deleted = 0 28 WHERE deleted = 0
79 AND audit_status = 20 29 AND audit_status = 20
@@ -83,46 +33,14 @@ @@ -83,46 +33,14 @@
83 </foreach> 33 </foreach>
84 AND (DATE_FORMAT(order_date, '%Y') = DATE_FORMAT(#{times[0],javaType=java.time.LocalDateTime},'%Y') 34 AND (DATE_FORMAT(order_date, '%Y') = DATE_FORMAT(#{times[0],javaType=java.time.LocalDateTime},'%Y')
85 or DATE_FORMAT(order_date, '%Y') = DATE_FORMAT(#{times[0],javaType=java.time.LocalDateTime},'%Y')-1) 35 or DATE_FORMAT(order_date, '%Y') = DATE_FORMAT(#{times[0],javaType=java.time.LocalDateTime},'%Y')-1)
86 - GROUP BY time)y ON t.time = y.time  
87 - LEFT JOIN  
88 - (SELECT  
89 - IFNULL(SUM(total_price), 0) AS lastYearCount,  
90 - DATE_FORMAT(DATE_ADD(order_date,INTERVAL 1 YEAR), '%Y-%m') AS time  
91 - FROM crm_contract  
92 - WHERE deleted = 0  
93 - AND audit_status = 20  
94 - AND owner_user_id in  
95 - <foreach collection="userIds" item="userId" open="(" close=")" separator=",">  
96 - #{userId}  
97 - </foreach>  
98 - AND DATE_FORMAT(order_date, '%Y') = DATE_FORMAT(#{times[0],javaType=java.time.LocalDateTime},'%Y')-1  
99 - GROUP BY time)z ON t.time = z.time 36 + GROUP BY time
100 </select> 37 </select>
101 38
102 <select id="selectReceivablePricePerformance" 39 <select id="selectReceivablePricePerformance"
103 resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceRespVO"> 40 resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceRespVO">
104 SELECT 41 SELECT
105 - t.time as time,  
106 - COALESCE(t.currentMonthCount,0) as currentMonthCount,  
107 - COALESCE(y.lastMonthCount,0) as lastMonthCount,  
108 - COALESCE(z.lastYearCount,0) as lastYearCount  
109 - FROM  
110 - (SELECT  
111 - IFNULL(SUM(price), 0) AS currentMonthCount,  
112 - DATE_FORMAT(return_time, '%Y-%m') AS time  
113 - FROM crm_receivable  
114 - WHERE deleted = 0  
115 - AND audit_status = 20  
116 - AND owner_user_id in  
117 - <foreach collection="userIds" item="userId" open="(" close=")" separator=",">  
118 - #{userId}  
119 - </foreach>  
120 - AND DATE_FORMAT(return_time, '%Y') = DATE_FORMAT(#{times[0],javaType=java.time.LocalDateTime},'%Y')  
121 - GROUP BY time)t  
122 - LEFT JOIN  
123 - (SELECT  
124 - IFNULL(SUM(price), 0) AS lastMonthCount,  
125 - DATE_FORMAT(DATE_ADD(return_time,INTERVAL 1 MONTH), '%Y-%m') AS time 42 + DATE_FORMAT(return_time, '%Y%m') AS time,
  43 + IFNULL(SUM(price), 0) AS currentMonthCount
126 FROM crm_receivable 44 FROM crm_receivable
127 WHERE deleted = 0 45 WHERE deleted = 0
128 AND audit_status = 20 46 AND audit_status = 20
@@ -132,21 +50,7 @@ @@ -132,21 +50,7 @@
132 </foreach> 50 </foreach>
133 AND (DATE_FORMAT(return_time, '%Y') = DATE_FORMAT(#{times[0],javaType=java.time.LocalDateTime},'%Y') 51 AND (DATE_FORMAT(return_time, '%Y') = DATE_FORMAT(#{times[0],javaType=java.time.LocalDateTime},'%Y')
134 or DATE_FORMAT(return_time, '%Y') = DATE_FORMAT(#{times[0],javaType=java.time.LocalDateTime},'%Y')-1) 52 or DATE_FORMAT(return_time, '%Y') = DATE_FORMAT(#{times[0],javaType=java.time.LocalDateTime},'%Y')-1)
135 - GROUP BY time)y ON t.time = y.time  
136 - LEFT JOIN  
137 - (SELECT  
138 - IFNULL(SUM(price), 0) AS lastYearCount,  
139 - DATE_FORMAT(DATE_ADD(return_time,INTERVAL 1 YEAR), '%Y-%m') AS time  
140 - FROM crm_receivable  
141 - WHERE deleted = 0  
142 - AND audit_status = 20  
143 - AND owner_user_id in  
144 - <foreach collection="userIds" item="userId" open="(" close=")" separator=",">  
145 - #{userId}  
146 - </foreach>  
147 - AND DATE_FORMAT(return_time, '%Y') = DATE_FORMAT(#{times[0],javaType=java.time.LocalDateTime},'%Y')-1  
148 - GROUP BY time)z ON t.time = z.time 53 + GROUP BY time
149 </select> 54 </select>
150 55
151 -  
152 </mapper> 56 </mapper>