فهرست منبع

完成todo部分,优化环比同比数据的计算。

scholar 1 سال پیش
والد
کامیت
3afd2cba0c

+ 58 - 63
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsPerformanceServiceImpl.java

@@ -55,16 +55,15 @@ public class CrmStatisticsPerformanceServiceImpl implements CrmStatisticsPerform
     }
 
     /**
-     * 获得员工业绩数据
-     *
+     * 获得员工业绩数据,并通过如下方法拿到对应的lastYearCount,lastMonthCount
+     * 比如说,构造2024 年的CrmStatisticsPerformanceRespVO,获得 2023-01 到 2024-12的月统计数据即可
+     * 可以数据 group by 年-月,2023-01 到 2024-12的,然后聚合出 CrmStatisticsPerformanceRespVO
      * @param performanceReqVO  参数
      * @param performanceFunction 员工业绩统计方法
      * @return 员工业绩数据
      */
-    private List<CrmStatisticsPerformanceRespVO> getPerformance(CrmStatisticsPerformanceReqVO performanceReqVO, Function<CrmStatisticsPerformanceReqVO,
-            List<CrmStatisticsPerformanceRespVO>> performanceFunction) {
-
-        List<CrmStatisticsPerformanceRespVO> performanceRespVOList;
+    private List<CrmStatisticsPerformanceRespVO> getPerformance(CrmStatisticsPerformanceReqVO performanceReqVO,
+               Function<CrmStatisticsPerformanceReqVO, List<CrmStatisticsPerformanceRespVO>> performanceFunction) {
 
         // 1. 获得用户编号数组
         final List<Long> userIds = getUserIds(performanceReqVO);
@@ -72,75 +71,71 @@ public class CrmStatisticsPerformanceServiceImpl implements CrmStatisticsPerform
             return Collections.emptyList();
         }
         performanceReqVO.setUserIds(userIds);
+
         // 2. 获得业绩数据
-        List<CrmStatisticsPerformanceRespVO> performance = performanceFunction.apply(performanceReqVO);
+        List<CrmStatisticsPerformanceRespVO> performanceList = performanceFunction.apply(performanceReqVO);
 
         // 获取查询的年份
         String currentYear = LocalDateTimeUtil.format(performanceReqVO.getTimes()[0],"yyyy");
+        Map<Integer, CrmStatisticsPerformanceRespVO> currentYearMap = new TreeMap<>();//查询当年的map数据
+        Map<Integer, CrmStatisticsPerformanceRespVO> lastYearMap = new TreeMap<>();//前一年的map数据
 
-        // 构造查询当年和前一年,每年12个月的年月组合
-        List<String> allMonths = new ArrayList<>();
-        for (int year = Integer.parseInt(currentYear)-1; year <= Integer.parseInt(currentYear); year++) {
-            for (int month = 1; month <= 12; month++) {
-                allMonths.add(String.format("%d%02d", year, month));
-            }
-        }
+        for (int month = 1; month <= 12; month++) {
+            //根据数据库的月销售数据查询结果,构造查询当年的map数据
+            String currentYearKey = String.format("%d%02d", Integer.parseInt(currentYear), month);
+            buildYearMapData(performanceList, currentYearMap, currentYearKey);
 
-        List<CrmStatisticsPerformanceRespVO> computedList = new ArrayList<>();
-        List<CrmStatisticsPerformanceRespVO> respVOList = new ArrayList<>();
-
-        // 生成computedList基础数据
-        // 构造完整的2*12个月的数据,如果某月数据缺失,需要补上0,一年12个月不能有缺失
-        for (String month : allMonths) {
-            CrmStatisticsPerformanceRespVO foundData = performance.stream()
-                    .filter(data -> data.getTime().equals(month))
-                    .findFirst()
-                    .orElse(null);
-
-            if (foundData != null) {
-                computedList.add(foundData);
-            } else {
-                CrmStatisticsPerformanceRespVO missingData = new CrmStatisticsPerformanceRespVO();
-                missingData.setTime(month);
-                missingData.setCurrentMonthCount(BigDecimal.ZERO);
-                missingData.setLastMonthCount(BigDecimal.ZERO);
-                missingData.setLastYearCount(BigDecimal.ZERO);
-                computedList.add(missingData);
-            }
+            //根据数据库的月销售数据查询结果,构造查询前一年的map数据
+            String lastYearKey = String.format("%d%02d", Integer.parseInt(currentYear)-1, month);
+            buildYearMapData(performanceList, lastYearMap, lastYearKey);
         }
-        //根据查询年份和前一年的数据,计算查询年份的同比环比数据
-        for (CrmStatisticsPerformanceRespVO currentData : computedList) {
-            String currentMonth = currentData.getTime();
-
-            // 根据当年和前一年的月销售数据,计算currentYear的完整数据
-            if (currentMonth.startsWith(currentYear)) {
-                // 计算 LastMonthCount
-                int currentIndex = computedList.indexOf(currentData);
-                if (currentIndex > 0) {
-                    CrmStatisticsPerformanceRespVO lastMonthData = computedList.get(currentIndex - 1);
-                    currentData.setLastMonthCount(lastMonthData.getCurrentMonthCount());
-                } else {
-                    currentData.setLastMonthCount(BigDecimal.ZERO); // 第一个月的 LastMonthCount 设为0
-                }
-
-                // 计算 LastYearCount
-                String lastYearMonth = String.valueOf(Integer.parseInt(currentMonth) - 100);
-                CrmStatisticsPerformanceRespVO lastYearData = computedList.stream()
-                        .filter(data -> data.getTime().equals(lastYearMonth))
-                        .findFirst()
-                        .orElse(null);
-
-                if (lastYearData != null) {
-                    currentData.setLastYearCount(lastYearData.getCurrentMonthCount());
-                } else {
-                    currentData.setLastYearCount(BigDecimal.ZERO); // 如果去年同月数据不存在,设为0
-                }
-                respVOList.add(currentData);//给前端只需要返回查询当年的数据,不需要前一年数据
+        //根据构造好的map数据,计算查询当年的环比和同比数据,并构造好返回的respVOList
+        List<CrmStatisticsPerformanceRespVO> respVOList = new ArrayList<>();
+        for (int key : currentYearMap.keySet()) {
+            BigDecimal lastYearCount = lastYearMap.get(key-100).getCurrentMonthCount();
+            BigDecimal lastMonthCount;
+            if (key % 100 > 1) {//2-12月份的前一个月数据
+                lastMonthCount = currentYearMap.get(key-1).getCurrentMonthCount();
+            } else {//1月份的前一个月数据
+                lastMonthCount = lastYearMap.get(key-89).getCurrentMonthCount();
             }
+
+            currentYearMap.get(key).setLastYearCount(lastYearCount);
+            currentYearMap.get(key).setLastMonthCount(lastMonthCount);
+
+            respVOList.add(currentYearMap.get(key));
         }
+
         return respVOList;
     }
 
+    /**
+     * 根据mapKey,添加当年和前一年的月销售记录到对应的map结构中
+     * @param performanceList   数据库中查询到的月销售记录
+     * @param YearDataMap   将查询到的月销售记录put到对应的map中,如果月销售记录为null,置为0
+     * @param mapKey        对应的mapKey
+     */
+    private void buildYearMapData(List<CrmStatisticsPerformanceRespVO> performanceList,
+                                  Map<Integer, CrmStatisticsPerformanceRespVO> YearDataMap,
+                                  String mapKey)
+    {
+        CrmStatisticsPerformanceRespVO currentYearData = performanceList.stream()
+                .filter(data -> data.getTime().equals(mapKey))
+                .findFirst()
+                .orElse(null);
+
+        if(currentYearData != null) {
+            YearDataMap.put(Integer.parseInt(mapKey), currentYearData);
+        } else {
+            CrmStatisticsPerformanceRespVO defaultVO = new CrmStatisticsPerformanceRespVO();
+            defaultVO.setTime(mapKey);
+            defaultVO.setCurrentMonthCount(BigDecimal.ZERO);
+            defaultVO.setLastMonthCount(BigDecimal.ZERO);
+            defaultVO.setLastYearCount(BigDecimal.ZERO);
+            YearDataMap.put(Integer.parseInt(mapKey), defaultVO);
+        }
+    }
+
     /**
      * 获取用户编号数组。如果用户编号为空, 则获得部门下的用户编号数组,包括子部门的所有用户编号
      *