Pārlūkot izejas kodu

小程序看课统计红包领取数 金额优化

wangxy 2 nedēļas atpakaļ
vecāks
revīzija
004768ed94

+ 19 - 0
fs-service/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java

@@ -832,6 +832,25 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
      */
     List<WatchLogReportVO> selectRedPacketStats(@Param("logIds") List<Long> logIds);
 
+    /**
+     * 按销售维度统计红包数据
+     * @param companyUserIds 销售ID列表
+     * @param param 查询参数
+     * @return 红包统计
+     */
+    List<WatchLogReportVO> selectRedPacketStatsByCompanyUserIds(@Param("companyUserIds") List<Long> companyUserIds, @Param("startDate") String startDate, @Param("endDate") String endDate, @Param("periodId") String periodId, @Param("trainingCampId") String trainingCampId);
+
+    /**
+     * 按部门维度统计红包数据
+     * @param deptIds 部门ID列表
+     * @param startDate 开始日期
+     * @param endDate 结束日期
+     * @param periodId 营期ID
+     * @param trainingCampId 训练营ID
+     * @return 红包统计
+     */
+    List<WatchLogReportVO> selectRedPacketStatsByDeptIds(@Param("deptIds") List<Long> deptIds, @Param("startDate") String startDate, @Param("endDate") String endDate, @Param("periodId") String periodId, @Param("trainingCampId") String trainingCampId);
+
     /**
      * 订单
      * @param userIds

+ 80 - 5
fs-service/src/main/java/com/fs/course/service/impl/FsCourseWatchLogServiceImpl.java

@@ -2084,11 +2084,8 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
     private List<WatchLogReportVO> assembleStatisticsData(List<WatchLogReportVO> baseData, FsCourseWatchLogStatisticsListParam param) {
         String dimension = param.getDimension();
         
-        // 只有 user 维度需要单独查询红包和答题数据
-        // sales 和 company 维度已经在基础数据 SQL 中计算了
         if ("user".equals(dimension)) {
             List<Long> logIds = baseData.stream().map(WatchLogReportVO::getLogId).collect(Collectors.toList());
-            List<Long> userIds = baseData.stream().map(WatchLogReportVO::getUserId).collect(Collectors.toList());
 
             Map<Long, WatchLogReportVO> redPacketMap = convertRedPacketToMap(
                     fsCourseWatchLogMapper.selectRedPacketStats(logIds)
@@ -2109,6 +2106,54 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
                 }
             }
         }
+        else if ("sales".equals(dimension)) {
+            List<Long> companyUserIds = baseData.stream().map(WatchLogReportVO::getCompanyUserId).distinct().collect(Collectors.toList());
+            
+            if (!companyUserIds.isEmpty()) {
+                Map<Long, WatchLogReportVO> redPacketMap = convertRedPacketToMapByCompanyUserId(
+                        fsCourseWatchLogMapper.selectRedPacketStatsByCompanyUserIds(
+                                companyUserIds, 
+                                param.getStartDate(), 
+                                param.getEndDate(), 
+                                param.getPeriodId() != null ? String.valueOf(param.getPeriodId()) : null,
+                                param.getTrainingCampId() != null ? String.valueOf(param.getTrainingCampId()) : null
+                        )
+                );
+
+                for (WatchLogReportVO item : baseData) {
+                    WatchLogReportVO redPacketStats = redPacketMap.getOrDefault(item.getCompanyUserId(), null);
+                    if (redPacketStats != null) {
+                        item.setRedPacketAmount(redPacketStats.getRedPacketAmount());
+                        item.setRedPacketCount(redPacketStats.getRedPacketCount());
+                    }
+                    item.setCompletionRate(calculateCompletionRate(item));
+                }
+            }
+        }
+        else if ("company".equals(dimension)) {
+            List<Long> deptIds = baseData.stream().map(WatchLogReportVO::getDeptId).distinct().collect(Collectors.toList());
+            
+            if (!deptIds.isEmpty()) {
+                Map<Long, WatchLogReportVO> redPacketMap = convertRedPacketToMapByDeptId(
+                        fsCourseWatchLogMapper.selectRedPacketStatsByDeptIds(
+                                deptIds, 
+                                param.getStartDate(), 
+                                param.getEndDate(), 
+                                param.getPeriodId() != null ? String.valueOf(param.getPeriodId()) : null,
+                                param.getTrainingCampId() != null ? String.valueOf(param.getTrainingCampId()) : null
+                        )
+                );
+
+                for (WatchLogReportVO item : baseData) {
+                    WatchLogReportVO redPacketStats = redPacketMap.getOrDefault(item.getDeptId(), null);
+                    if (redPacketStats != null) {
+                        item.setRedPacketAmount(redPacketStats.getRedPacketAmount());
+                        item.setRedPacketCount(redPacketStats.getRedPacketCount());
+                    }
+                    item.setCompletionRate(calculateCompletionRate(item));
+                }
+            }
+        }
 
         // 订单数据(所有维度都需要)
         List<Long> userIds = baseData.stream().map(WatchLogReportVO::getUserId).distinct().collect(Collectors.toList());
@@ -2121,7 +2166,7 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
                 if (order != null) {
                     item.setHistoryOrderCount(order.getHistoryOrderCount());
                 }
-                if (!"user".equals(dimension)) {
+                if (!"user".equals(dimension) && !"sales".equals(dimension) && !"company".equals(dimension)) {
                     item.setCompletionRate(calculateCompletionRate(item));
                 }
             }
@@ -2189,7 +2234,37 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
                 .collect(Collectors.toMap(
                         WatchLogReportVO::getLogId,
                         Function.identity(),
-                        (existing, replacement) -> existing // 当出现重复键时,保留第一个值
+                        (existing, replacement) -> existing
+                ));
+    }
+
+    /**
+     * 红包数据转Map(按销售ID)
+     */
+    public Map<Long, WatchLogReportVO> convertRedPacketToMapByCompanyUserId(List<WatchLogReportVO> list) {
+        if (list == null || list.isEmpty()) {
+            return new HashMap<>();
+        }
+        return list.stream()
+                .collect(Collectors.toMap(
+                        WatchLogReportVO::getCompanyUserId,
+                        Function.identity(),
+                        (existing, replacement) -> existing
+                ));
+    }
+
+    /**
+     * 红包数据转Map(按部门ID)
+     */
+    public Map<Long, WatchLogReportVO> convertRedPacketToMapByDeptId(List<WatchLogReportVO> list) {
+        if (list == null || list.isEmpty()) {
+            return new HashMap<>();
+        }
+        return list.stream()
+                .collect(Collectors.toMap(
+                        WatchLogReportVO::getDeptId,
+                        Function.identity(),
+                        (existing, replacement) -> existing
                 ));
     }
 

+ 72 - 30
fs-service/src/main/resources/mapper/course/FsCourseWatchLogMapper.xml

@@ -1278,9 +1278,7 @@ FROM
         COUNT(DISTINCT CASE WHEN log.log_type = '2' THEN log.log_id END) AS finishedCount,
         COUNT(DISTINCT CASE WHEN log.log_type IN ('1', '3', '4') THEN log.log_id END) AS unfinishedCount,
         COUNT(DISTINCT log.log_id)-COUNT(DISTINCT log.user_id) AS notWatchedCount,
-        COUNT(DISTINCT log.log_id) - COUNT(DISTINCT a.watch_log_id) AS notAnsweredCount,
-        COALESCE(SUM(rp.amount), 0) AS redPacketAmount,
-        COUNT(rp.log_id) AS redPacketCount
+        COUNT(DISTINCT log.log_id) - COUNT(DISTINCT a.watch_log_id) AS notAnsweredCount
         FROM
         fs_course_watch_log log
         <if test="orderSTime != null and orderETime != null">
@@ -1291,7 +1289,6 @@ FROM
         LEFT JOIN company_dept d ON cu.dept_id = d.dept_id
         LEFT JOIN company c ON d.company_id = c.company_id
         LEFT JOIN fs_course_answer_logs a ON a.watch_log_id = log.log_id
-        LEFT JOIN fs_course_red_packet_log rp ON rp.watch_log_id = log.log_id
         WHERE log.send_type =1 and log.watch_type =2
         <if test="startDate != null and startDate != '' and endDate != null and endDate != ''">
             AND log.create_time &gt;= #{startDate} AND log.create_time &lt; DATE_ADD(#{endDate}, INTERVAL 1 DAY)
@@ -1333,27 +1330,27 @@ FROM
         GROUP BY cu.user_id
 
     </select>
-    <select id="selectCompanyBaseData" resultType="com.fs.his.vo.WatchLogReportVO">
-        SELECT
-        log.user_id userId,
-        log.period_id periodId,
-        log.log_id logId,
-        log.create_time courseTime,
-        d.dept_id AS deptId,
-        d.dept_name AS salesDept,
-        c.company_name AS salesCompany,
-        COUNT(DISTINCT cu.user_id) AS salesCount,
-        COUNT(DISTINCT u.user_id) AS userCount,
-        COUNT(DISTINCT CASE WHEN u.STATUS = 1 THEN u.user_id END) AS onlineUserCount,
-        cv.title videoTitle,
-        COUNT(DISTINCT log.log_id) AS totalLogCount,
-        COUNT(DISTINCT CASE WHEN log.log_type = '2' THEN log.log_id END) AS finishedCount,
-        COUNT(DISTINCT CASE WHEN log.log_type IN ('1', '3', '4') THEN log.log_id END) AS unfinishedCount,
-        COUNT(DISTINCT log.user_id) - COUNT(DISTINCT CASE WHEN log.log_type = '2' THEN log.user_id END) AS notWatchedCount
-        FROM fs_course_watch_log log
-        <if test="orderSTime != null and orderETime != null">
-            LEFT JOIN fs_package_order po ON po.user_id = log.user_id
-        </if>
+        <select id="selectCompanyBaseData" resultType="com.fs.his.vo.WatchLogReportVO">
+            SELECT
+            log.user_id userId,
+            log.period_id periodId,
+            log.log_id logId,
+            log.create_time courseTime,
+            d.dept_id AS deptId,
+            d.dept_name AS salesDept,
+            c.company_name AS salesCompany,
+            COUNT(DISTINCT cu.user_id) AS salesCount,
+            COUNT(DISTINCT u.user_id) AS userCount,
+            COUNT(DISTINCT CASE WHEN u.STATUS = 1 THEN u.user_id END) AS onlineUserCount,
+            cv.title videoTitle,
+            COUNT(DISTINCT log.log_id) AS totalLogCount,
+            COUNT(DISTINCT CASE WHEN log.log_type = '2' THEN log.log_id END) AS finishedCount,
+            COUNT(DISTINCT CASE WHEN log.log_type IN ('1', '3', '4') THEN log.log_id END) AS unfinishedCount,
+            COUNT(DISTINCT log.user_id) - COUNT(DISTINCT CASE WHEN log.log_type = '2' THEN log.user_id END) AS notWatchedCount
+            FROM fs_course_watch_log log
+            <if test="orderSTime != null and orderETime != null">
+                LEFT JOIN fs_package_order po ON po.user_id = log.user_id
+            </if>
         LEFT JOIN company_user cu ON log.company_user_id = cu.user_id
         LEFT JOIN fs_user u on log.user_id= u.user_id
         LEFT JOIN company_dept d ON cu.dept_id = d.dept_id
@@ -1467,6 +1464,54 @@ FROM
         </foreach>
         GROUP BY rp.watch_log_id
     </select>
+
+    <select id="selectRedPacketStatsByCompanyUserIds" resultType="com.fs.his.vo.WatchLogReportVO">
+        SELECT
+        w.company_user_id AS companyUserId,
+        SUM(rp.amount) AS redPacketAmount,
+        COUNT(rp.log_id) AS redPacketCount
+        FROM fs_course_red_packet_log rp
+        INNER JOIN fs_course_watch_log w ON rp.watch_log_id = w.log_id
+        WHERE w.company_user_id IN
+        <foreach collection="companyUserIds" item="companyUserId" open="(" separator="," close=")">
+            #{companyUserId}
+        </foreach>
+        <if test="startDate != null and startDate != '' and endDate != null and endDate != ''">
+            AND w.create_time &gt;= #{startDate} AND w.create_time &lt; DATE_ADD(#{endDate}, INTERVAL 1 DAY)
+        </if>
+        <if test="periodId != null and periodId != ''">
+            AND w.period_id = #{periodId}
+        </if>
+        <if test="trainingCampId != null and trainingCampId != ''">
+            AND w.period_id IN (SELECT period_id FROM fs_user_course_period WHERE training_camp_id = #{trainingCampId})
+        </if>
+        GROUP BY w.company_user_id
+    </select>
+
+    <select id="selectRedPacketStatsByDeptIds" resultType="com.fs.his.vo.WatchLogReportVO">
+        SELECT
+        cu.dept_id AS deptId,
+        SUM(rp.amount) AS redPacketAmount,
+        COUNT(rp.log_id) AS redPacketCount
+        FROM fs_course_red_packet_log rp
+        INNER JOIN fs_course_watch_log w ON rp.watch_log_id = w.log_id
+        INNER JOIN company_user cu ON w.company_user_id = cu.user_id
+        WHERE cu.dept_id IN
+        <foreach collection="deptIds" item="deptId" open="(" separator="," close=")">
+            #{deptId}
+        </foreach>
+        <if test="startDate != null and startDate != '' and endDate != null and endDate != ''">
+            AND w.create_time &gt;= #{startDate} AND w.create_time &lt; DATE_ADD(#{endDate}, INTERVAL 1 DAY)
+        </if>
+        <if test="periodId != null and periodId != ''">
+            AND w.period_id = #{periodId}
+        </if>
+        <if test="trainingCampId != null and trainingCampId != ''">
+            AND w.period_id IN (SELECT period_id FROM fs_user_course_period WHERE training_camp_id = #{trainingCampId})
+        </if>
+        GROUP BY cu.dept_id
+    </select>
+
     <select id="selectOrderStats" resultType="com.fs.his.vo.WatchLogReportVO">
         SELECT
         user_id AS userId,
@@ -1835,16 +1880,13 @@ FROM
             COUNT(DISTINCT CASE WHEN log.log_type = '2' THEN log.log_id END) AS finishedCount,
             COUNT(DISTINCT CASE WHEN log.log_type IN ('1', '3', '4') THEN log.log_id END) AS unfinishedCount,
             COUNT(DISTINCT log.user_id) - COUNT(DISTINCT CASE WHEN log.log_type = '2' THEN log.user_id END) AS notWatchedCount,
-            COUNT(DISTINCT log.log_id) - COUNT(DISTINCT a.watch_log_id) AS notAnsweredCount,
-            COALESCE(SUM(rp.amount), 0) AS redPacketAmount,
-            COUNT(rp.log_id) AS redPacketCount
+            COUNT(DISTINCT log.log_id) - COUNT(DISTINCT a.watch_log_id) AS notAnsweredCount
         FROM fs_course_watch_log log
         LEFT JOIN company_user cu ON log.company_user_id = cu.user_id
         LEFT JOIN fs_user u ON log.user_id = u.user_id
         LEFT JOIN company_dept d ON cu.dept_id = d.dept_id
         LEFT JOIN company c ON d.company_id = c.company_id
         LEFT JOIN fs_course_answer_logs a ON a.watch_log_id = log.log_id
-        LEFT JOIN fs_course_red_packet_log rp ON rp.watch_log_id = log.log_id
         WHERE log.send_type = 1 AND log.watch_type = 2
         <if test="startDate != null and startDate != '' and endDate != null and endDate != ''">
             AND log.create_time &gt;= #{startDate} AND log.create_time &lt; DATE_ADD(#{endDate}, INTERVAL 1 DAY)
@@ -2114,7 +2156,7 @@ FROM
         SELECT
         log.user_id userId,
         u.nick_name AS nickName,
-        u.source loginChannel,
+        u.app_create_time loginChannel,
         cu.nick_name AS salesName,
         c.company_name AS salesCompany,
         cd.dept_name AS salesDept,