Просмотр исходного кода

优化,销售端营期加入课程营期数据,优化相关查询代码,修复套餐商品没有运费问题

yjwang 1 месяц назад
Родитель
Сommit
39758c1a04

+ 5 - 1
fs-admin/src/main/java/com/fs/course/controller/FsCourseWatchLogController.java

@@ -5,6 +5,7 @@ import java.util.List;
 import com.fs.common.core.domain.R;
 import com.fs.common.exception.CustomException;
 import com.fs.course.param.FsCourseOverParam;
+import com.fs.course.param.FsCourseSummaryDetailQueryParam;
 import com.fs.course.param.FsCourseWatchLogListParam;
 import com.fs.course.param.FsCourseWatchLogStatisticsListParam;
 import com.fs.course.service.IFsUserCoursePeriodDaysService;
@@ -249,7 +250,10 @@ public class FsCourseWatchLogController extends BaseController
         if (videoId == null || periodId == null) {
             return R.error("视频ID和营期ID不能为空");
         }
-        return R.ok().put("data", fsCourseWatchLogService.getCourseStatisticsDetail(videoId, periodId));
+        FsCourseSummaryDetailQueryParam param = new FsCourseSummaryDetailQueryParam();
+        param.setVideoId(videoId);
+        param.setPeriodId(periodId);
+        return R.ok().put("data", fsCourseWatchLogService.getCourseStatisticsDetail(param));
     }
 
     /**

+ 25 - 0
fs-company/src/main/java/com/fs/company/controller/course/FsCourseWatchLogController.java

@@ -4,6 +4,7 @@ import cn.hutool.core.util.ObjectUtil;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.ServletUtils;
@@ -382,4 +383,28 @@ public class FsCourseWatchLogController extends BaseController
     {
         return toAjax(fsCourseWatchLogService.deleteFsCourseWatchLogByLogIds(logIds));
     }
+
+    /**
+     * 查询课程小结详情总体数据
+     * @param videoId 视频ID
+     * @param periodId 营期ID
+     * @return 总体统计数据
+     */
+    @PreAuthorize("@ss.hasPermi('course:courseWatchLog:query')")
+    @GetMapping("/courseStatisticsDetail")
+    public R getCourseStatisticsDetail(@RequestParam("videoId") Long videoId, @RequestParam("periodId") Long periodId)
+    {
+        if (videoId == null || periodId == null) {
+            return R.error("视频ID和营期ID不能为空");
+        }
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        if(loginUser == null || loginUser.getCompany() == null || loginUser.getCompany().getCompanyId() == null){
+            return R.error("销售信息不存在!");
+        }
+        FsCourseSummaryDetailQueryParam param = new FsCourseSummaryDetailQueryParam();
+        param.setCompanyId(loginUser.getCompany().getCompanyId());
+        param.setVideoId(videoId);
+        param.setPeriodId(periodId);
+        return R.ok().put("data", fsCourseWatchLogService.getCourseStatisticsDetail(param));
+    }
 }

+ 8 - 2
fs-service/src/main/java/com/fs/course/mapper/FsCourseAnswerLogsMapper.java

@@ -154,6 +154,12 @@ public interface FsCourseAnswerLogsMapper
     FsCourseAnswerLogs selectRightLogByCourseVideoIsOpen(@Param("videoId") Long videoId,@Param("userId") Long userId);
 
     /** 统计指定视频+营期下去重答题人数 */
-    @Select("SELECT COUNT(DISTINCT user_id) FROM fs_course_answer_logs WHERE video_id = #{videoId} AND period_id = #{periodId}")
-    Long countDistinctUsersByVideoAndPeriod(@Param("videoId") Long videoId, @Param("periodId") Long periodId);
+    @Select("<script>" +
+            "SELECT COUNT(DISTINCT user_id) FROM fs_course_answer_logs " +
+            "WHERE video_id = #{videoId} AND period_id = #{periodId} " +
+            "<if test='companyId != null'>AND company_id = #{companyId}</if>" +
+            "</script>")
+    Long countDistinctUsersByVideoAndPeriod(@Param("videoId") Long videoId,
+                                            @Param("periodId") Long periodId,
+                                            @Param("companyId") Long companyId);
 }

+ 8 - 2
fs-service/src/main/java/com/fs/course/mapper/FsCourseRedPacketLogMapper.java

@@ -189,8 +189,14 @@ public interface FsCourseRedPacketLogMapper
     FsCourseRedPacketLog selectUserFsCourseRedPacketLog(@Param("videoId") Long videoId, @Param("userId")Long userId, @Param("periodId")Long periodId);
 
     /** 统计指定视频+营期下去重领红包人数 */
-    @Select("SELECT COUNT(DISTINCT user_id) FROM fs_course_red_packet_log WHERE video_id = #{videoId} AND period_id = #{periodId}")
-    Long countDistinctUsersByVideoAndPeriod(@Param("videoId") Long videoId, @Param("periodId") Long periodId);
+    @Select("<script>" +
+            "SELECT COUNT(DISTINCT user_id) FROM fs_course_red_packet_log " +
+            "WHERE video_id = #{videoId} AND period_id = #{periodId} " +
+            "<if test='companyId != null'>AND company_id = #{companyId}</if>" +
+            "</script>")
+    Long countDistinctUsersByVideoAndPeriod(@Param("videoId") Long videoId,
+                                            @Param("periodId") Long periodId,
+                                            @Param("companyId") Long companyId);
 
     @Select("SELECT * FROM fs_course_red_packet_log \n" +
             "WHERE create_time <= DATE_SUB(NOW(), INTERVAL 10 MINUTE)  -- 10 分钟前或更早\n" +

+ 18 - 6
fs-service/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java

@@ -773,8 +773,14 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
      * @param periodId 营期ID
      * @return 累计观看人数
      */
-    @Select("SELECT COUNT(DISTINCT user_id) FROM fs_course_watch_log WHERE video_id = #{videoId} AND period_id = #{periodId}")
-    Long countDistinctWatchUsers(@Param("videoId") Long videoId, @Param("periodId") Long periodId);
+    @Select("<script>" +
+            "SELECT COUNT(DISTINCT user_id) FROM fs_course_watch_log " +
+            "WHERE video_id = #{videoId} AND period_id = #{periodId} " +
+            "<if test='companyId != null'>AND company_id = #{companyId}</if>" +
+            "</script>")
+    Long countDistinctWatchUsers(@Param("videoId") Long videoId,
+                                 @Param("periodId") Long periodId,
+                                 @Param("companyId") Long companyId);
 
     /**
      * 统计累计完课人数(duration >= 1200秒,即20分钟,对userId去重)
@@ -782,8 +788,14 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
      * @param periodId 营期ID
      * @return 累计完课人数
      */
-    @Select("SELECT COUNT(DISTINCT user_id) FROM fs_course_watch_log WHERE video_id = #{videoId} AND period_id = #{periodId} AND duration >= 1200")
-    Long countDistinctCompleteUsers(@Param("videoId") Long videoId, @Param("periodId") Long periodId);
+    @Select("<script>" +
+            "SELECT COUNT(DISTINCT user_id) FROM fs_course_watch_log " +
+            "WHERE video_id = #{videoId} AND period_id = #{periodId} AND duration >= 1200 " +
+            "<if test='companyId != null'>AND company_id = #{companyId}</if>" +
+            "</script>")
+    Long countDistinctCompleteUsers(@Param("videoId") Long videoId,
+                                    @Param("periodId") Long periodId,
+                                    @Param("companyId") Long companyId);
 
     /**
      * 首次点播数据统计:观看人数、>=20分钟人数、>=30分钟人数
@@ -795,7 +807,7 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
      * @return Map: firstWatchCount, firstWatch20MinCount, firstWatch30MinCount
      */
     Map<String, Object> selectFirstPlaybackStats(@Param("videoId") Long videoId,
-                                                 @Param("periodId") Long periodId);
+                                                 @Param("periodId") Long periodId, @Param("companyId") Long companyId);
 
     /**
      * 第2-n次观看数据统计:view_start不在首次点播窗口内的观看记录
@@ -821,5 +833,5 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
     List<com.fs.course.vo.CourseStatisticsUserDetailVO> selectCourseStatisticsUserDetailExportList(
             @Param("param") com.fs.course.param.CourseStatisticsUserDetailParam param);
 
-    FSActualCompletionVO selectActualCompletionList(@Param("periodId") Long periodId, @Param("videoId") Long videoId);
+    FSActualCompletionVO selectActualCompletionList(@Param("periodId") Long periodId, @Param("videoId") Long videoId, @Param("companyId") Long companyId);
 }

+ 15 - 0
fs-service/src/main/java/com/fs/course/param/FsCourseSummaryDetailQueryParam.java

@@ -0,0 +1,15 @@
+package com.fs.course.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 查询实体类型信息
+ * **/
+@Data
+public class FsCourseSummaryDetailQueryParam implements Serializable {
+    private Long videoId;
+    private Long periodId;
+    private Long companyId;
+}

+ 2 - 3
fs-service/src/main/java/com/fs/course/service/IFsCourseWatchLogService.java

@@ -175,11 +175,10 @@ public interface IFsCourseWatchLogService extends IService<FsCourseWatchLog> {
 
     /**
      * 查询课程小结详情总体数据
-     * @param videoId 视频ID
-     * @param periodId 营期ID
+     * @param param 获取数据
      * @return 总体统计数据
      */
-    CourseStatisticsDetailVO getCourseStatisticsDetail(Long videoId, Long periodId);
+    CourseStatisticsDetailVO getCourseStatisticsDetail(FsCourseSummaryDetailQueryParam param);
 
     /**
      * 查询课程小结-用户详情列表(分页)

+ 13 - 9
fs-service/src/main/java/com/fs/course/service/impl/FsCourseWatchLogServiceImpl.java

@@ -1759,24 +1759,27 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
 
 
     @Override
-    public CourseStatisticsDetailVO getCourseStatisticsDetail(Long videoId, Long periodId) {
+    public CourseStatisticsDetailVO getCourseStatisticsDetail(FsCourseSummaryDetailQueryParam param) {
         CourseStatisticsDetailVO vo = new CourseStatisticsDetailVO();
+        Long videoId = param.getVideoId();
+        Long periodId = param.getPeriodId();
+        Long companyId = param.getCompanyId() != null ? param.getCompanyId() : null;
 
         // 总体数据
         
         // 1. 查询视频时长(只返回duration字段)
         FsUserCourseVideo fsUserCourseVideo = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId(videoId);
         vo.setVideoDuration(fsUserCourseVideo != null ? fsUserCourseVideo.getDuration() : 0L);
-
-        FsUserCoursePeriod fsUserCoursePeriod = fsUserCoursePeriodMapper.selectFsUserCoursePeriodById(periodId);
+//
+//        FsUserCoursePeriod fsUserCoursePeriod = fsUserCoursePeriodMapper.selectFsUserCoursePeriodById(periodId);
 
 
         // 2. 统计累计观看人数(对userId去重)
-        Long totalWatchCount = fsCourseWatchLogMapper.countDistinctWatchUsers(videoId, periodId);
+        Long totalWatchCount = fsCourseWatchLogMapper.countDistinctWatchUsers(videoId, periodId,companyId);
         vo.setTotalWatchCount(totalWatchCount != null ? totalWatchCount : 0L);
         
         // 3. 统计累计完课人数(duration >= 1200秒,即20分钟,对userId去重)
-        Long totalCompleteCount = fsCourseWatchLogMapper.countDistinctCompleteUsers(videoId, periodId);
+        Long totalCompleteCount = fsCourseWatchLogMapper.countDistinctCompleteUsers(videoId, periodId,companyId);
         vo.setTotalCompleteCount(totalCompleteCount != null ? totalCompleteCount : 0L);
         
         // 4. 计算到课完课率 = 累计完课人数 / 累计观看人数
@@ -1790,7 +1793,7 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
 
         // 首次点播数据:营期开始时间+视频时长内的观看记录,view_start=update_time-duration 或 finish_time-duration(SQL内联计算窗口)
         if (periodId != null && videoId != null) {
-            Map<String, Object> firstStats = fsCourseWatchLogMapper.selectFirstPlaybackStats(videoId, periodId);
+            Map<String, Object> firstStats = fsCourseWatchLogMapper.selectFirstPlaybackStats(videoId, periodId,companyId);
             if (firstStats != null && !firstStats.isEmpty()) {
                 Long firstWatch = getLongFromMap(firstStats, "firstWatchCount");
                 Long first20 = getLongFromMap(firstStats, "firstWatch20MinCount");
@@ -1828,7 +1831,7 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
 
         //实际看课数据
         if (periodId != null && videoId != null) {
-            vo.setFsActualCompletionVO(fsCourseWatchLogMapper.selectActualCompletionList(periodId,videoId));
+            vo.setFsActualCompletionVO(fsCourseWatchLogMapper.selectActualCompletionList(periodId,videoId,companyId));
         }
 
         // 订单数据:fs_store_order_scrm order_type=3,videoId+periodId 匹配,paid=1
@@ -1837,6 +1840,7 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
             orderQuery.setOrderType(3);
             orderQuery.setVideoId(videoId.intValue());
             orderQuery.setPeriodId(periodId.intValue());
+            orderQuery.setCompanyId(companyId);
             orderQuery.setPaid(1);
             List<FsStoreOrderScrm> orders = fsStoreOrderScrmMapper.selectFsStoreOrderList(orderQuery);
             List<FsStoreOrderScrm> paidOrders = orders != null ? orders.stream()
@@ -1867,10 +1871,10 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
                 vo.setCompleteRValue(gmv.divide(BigDecimal.valueOf(vo.getTotalCompleteCount()), 2, RoundingMode.HALF_UP));
             }
 
-            Long answerCount = fsCourseAnswerLogsMapper.countDistinctUsersByVideoAndPeriod(videoId, periodId);
+            Long answerCount = fsCourseAnswerLogsMapper.countDistinctUsersByVideoAndPeriod(videoId, periodId,companyId);
             vo.setAnswerUserCount(answerCount != null ? answerCount : 0L);
 
-            Long redCount = fsCourseRedPacketLogMapper.countDistinctUsersByVideoAndPeriod(videoId, periodId);
+            Long redCount = fsCourseRedPacketLogMapper.countDistinctUsersByVideoAndPeriod(videoId, periodId,companyId);
             vo.setRedPacketUserCount(redCount != null ? redCount : 0L);
 
             // 单品销量统计:从订单明细汇总

+ 3 - 1
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java

@@ -1848,7 +1848,9 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             storeOrder.setTotalPrice(storeProductPackage.getPayMoney());
             storeOrder.setTotalPostage(BigDecimal.ZERO);
 
-            storeOrder.setPayPostage(BigDecimal.ZERO);
+            if(storeOrder.getPayPostage() == null){
+                storeOrder.setPayPostage(BigDecimal.ZERO);
+            }
             storeOrder.setDeductionPrice(BigDecimal.ZERO);
             storeOrder.setPaid(0);
             storeOrder.setUseIntegral(BigDecimal.ZERO);

+ 31 - 24
fs-service/src/main/resources/mapper/course/FsCourseWatchLogMapper.xml

@@ -1374,6 +1374,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         WHERE l.video_id = #{videoId}
           AND l.period_id = #{periodId}
           AND l.user_id IS NOT NULL
+        <if test="companyId != null">
+            AND l.company_id = #{companyId}
+        </if>
           AND (
               (COALESCE(DATE_SUB(l.finish_time, INTERVAL COALESCE(l.duration, 0) SECOND), DATE_SUB(l.update_time, INTERVAL COALESCE(l.duration, 0) SECOND), l.create_time) &gt;= fcpd.start_date_time)
               AND
@@ -1497,30 +1500,34 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
     <select id="selectActualCompletionList" resultType="com.fs.course.vo.FSActualCompletionVO">
         SELECT
-            a.totalStudents,
-            a.completedCount,
-            ROUND((a.completedCount / a.totalStudents) * 100, 2) AS actualCompletionRate,
-            ROUND((a.totalViewingDuration / a.totalStudents) / 60, 2) AS avgWatchDurationMinutes,
-            ROUND((a.totalDurationOfCompleters/a.completedCount)/60,2) AS avgCompletedDuration,
-            ROUND(((a.totalDurationOfCompleters/a.completedCount)/a.duration) * 100,2) AS avgCompletionPlaybackRate
+        a.totalStudents,
+        a.completedCount,
+        ROUND((a.completedCount / a.totalStudents) * 100, 2) AS actualCompletionRate,
+        ROUND((a.totalViewingDuration / a.totalStudents) / 60, 2) AS avgWatchDurationMinutes,
+        ROUND((a.totalDurationOfCompleters/a.completedCount)/60,2) AS avgCompletedDuration,
+        ROUND(((a.totalDurationOfCompleters/a.completedCount)/a.duration) * 100,2) AS avgCompletionPlaybackRate
         FROM
-            (
-                SELECT
-                    COUNT(*) AS totalStudents,
-                    SUM(CASE WHEN wl.log_type = 2 THEN 1 ELSE 0 END) AS completedCount,
-                    SUM(wl.duration) AS totalViewingDuration,
-                    SUM(CASE WHEN wl.log_type = 2 THEN wl.duration ELSE 0 END) AS totalDurationOfCompleters,
-                    cv.duration
-                FROM
-                    fs_user_course_period_days pd
-                        INNER JOIN fs_course_watch_log wl ON pd.period_id = wl.period_id
-                        INNER JOIN fs_user_course_video cv ON pd.video_id = cv.video_id
-                        AND pd.video_id = wl.video_id
-                WHERE
-                    pd.period_id = #{periodId}
-                  AND pd.video_id = #{videoId}
-                GROUP BY
-                    pd.period_id
-            ) a
+        (
+        SELECT
+        COUNT(*) AS totalStudents,
+        SUM(CASE WHEN wl.log_type = 2 THEN 1 ELSE 0 END) AS completedCount,
+        SUM(wl.duration) AS totalViewingDuration,
+        SUM(CASE WHEN wl.log_type = 2 THEN wl.duration ELSE 0 END) AS totalDurationOfCompleters,
+        cv.duration
+        FROM
+        fs_user_course_period_days pd
+        INNER JOIN fs_course_watch_log wl ON pd.period_id = wl.period_id
+        INNER JOIN fs_user_course_video cv ON pd.video_id = cv.video_id
+        AND pd.video_id = wl.video_id
+        <where>
+            pd.period_id = #{periodId}
+            AND pd.video_id = #{videoId}
+            <if test="companyId != null">
+                AND wl.company_id = #{companyId}
+            </if>
+        </where>
+        GROUP BY
+        pd.period_id
+        ) a
     </select>
 </mapper>