Procházet zdrojové kódy

1.学习行为分析相关统计功能
2.其他完善

honorfire před 5 měsíci
rodič
revize
11f8ca460d

+ 164 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/controller/StudyBehaviorProgressController.java

@@ -0,0 +1,164 @@
+package vip.xiaonuo.disk.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import com.github.xiaoymin.knife4j.annotations.ApiSupport;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+import vip.xiaonuo.common.pojo.CommonResult;
+import vip.xiaonuo.disk.service.StudyBehaviorProgressService;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 统计-学习行为分析控制器
+ *
+ * @author honorfire
+ * @date  2025/06/18 14:16
+ */
+@Api(tags = "统计-学习行为分析控制器")
+@ApiSupport(author = "SNOWY_TEAM", order = 1)
+@RestController
+@Validated
+public class StudyBehaviorProgressController {
+
+    @Resource
+    private StudyBehaviorProgressService studyBehaviorProgressService;
+
+    /**
+     * 学习行为分析-课程访问统计
+     *
+     * @author honorfire
+     * @date  2025/07/11 18:52
+     */
+    @ApiOperationSupport(order = 1)
+    @ApiOperation("学习行为分析-课程访问统计")
+    @GetMapping("/disk/studyBehavior/courseVisitProgress")
+    public CommonResult<Map<String,Object>> courseVisitProgress(HttpServletRequest req) {
+        Map param =new HashMap();
+        param.put("courseId", req.getParameter("courseId"));
+        param.put("startTime", req.getParameter("startTime"));
+        param.put("endTime", req.getParameter("endTime"));
+
+        Map<String,Object> result=studyBehaviorProgressService.getCourseVisitProgress(param);
+        return CommonResult.data(result);
+    }
+
+    /**
+     * 学习行为分析-用户登录统计
+     *
+     * @author honorfire
+     * @date  2025/07/11 18:52
+     */
+    @ApiOperationSupport(order = 1)
+    @ApiOperation("学习行为分析-用户登录统计")
+    @GetMapping("/disk/studyBehavior/userLoginProgress")
+    public CommonResult<Map<String,Object>> userLoginProgress(HttpServletRequest req) {
+        Map param =new HashMap();
+        param.put("courseId", req.getParameter("courseId"));
+        param.put("startTime", req.getParameter("startTime"));
+        param.put("endTime", req.getParameter("endTime"));
+
+        Map<String,Object> result=studyBehaviorProgressService.getUserLoginProgress(param);
+        return CommonResult.data(result);
+    }
+
+    /**
+     * 学习行为分析-观看时长统计
+     *
+     * @author honorfire
+     * @date  2025/07/11 18:52
+     */
+    @ApiOperationSupport(order = 1)
+    @ApiOperation("学习行为分析-观看时长统计")
+    @GetMapping("/disk/studyBehavior/watchDurationProgress")
+    public CommonResult<Map<String,Object>> watchDurationProgress(HttpServletRequest req) {
+        Map param =new HashMap();
+        param.put("courseId", req.getParameter("courseId"));
+        param.put("startTime", req.getParameter("startTime"));
+        param.put("endTime", req.getParameter("endTime"));
+
+        Map<String,Object> result=studyBehaviorProgressService.getWatchDurationProgress(param);
+        return CommonResult.data(result);
+    }
+
+    /**
+     * 学习行为分析-用户登录时段分布
+     *
+     * @author honorfire
+     * @date  2025/07/11 18:52
+     */
+    @ApiOperationSupport(order = 1)
+    @ApiOperation("学习行为分析-用户登录时段分布")
+    @GetMapping("/disk/studyBehavior/loginFrameDistribution")
+    public CommonResult<Page<Map<String,Object>>> loginFrameDistribution(HttpServletRequest req) {
+        Map param =new HashMap();
+        param.put("courseId", req.getParameter("courseId"));
+        param.put("startTime", req.getParameter("startTime"));
+        param.put("endTime", req.getParameter("endTime"));
+        Page<Map<String,Object>> list=studyBehaviorProgressService.getLoginFrameDistribution(param);
+        return CommonResult.data(list);
+    }
+
+    /**
+     * 学习行为分析-课程访问热度排行
+     *
+     * @author honorfire
+     * @date  2025/07/11 18:52
+     */
+    @ApiOperationSupport(order = 1)
+    @ApiOperation("学习行为分析-课程访问热度排行")
+    @GetMapping("/disk/studyBehavior/courseVisitHeatRank")
+    public CommonResult<Page<Map<String,Object>>> courseVisitHeatRank(HttpServletRequest req) {
+        Map param =new HashMap();
+        param.put("courseId", req.getParameter("courseId"));
+        param.put("startTime", req.getParameter("startTime"));
+        param.put("endTime", req.getParameter("endTime"));
+        Page<Map<String,Object>> list=studyBehaviorProgressService.getCourseVisitHeatRank(param);
+        return CommonResult.data(list);
+    }
+
+    /**
+     * 学习行为分析-学院课程详细统计
+     *
+     * @author honorfire
+     * @date  2025/07/11 18:52
+     */
+    @ApiOperationSupport(order = 1)
+    @ApiOperation("学习行为分析-学院课程详细统计")
+    @GetMapping("/disk/studyBehavior/collegeCourseDetailProgress")
+    public CommonResult<Page<Map<String,Object>>> collegeCourseDetailProgress(HttpServletRequest req) {
+        Map param =new HashMap();
+        param.put("courseId", req.getParameter("courseId"));
+        param.put("startTime", req.getParameter("startTime"));
+        param.put("endTime", req.getParameter("endTime"));
+        Page<Map<String,Object>> list=studyBehaviorProgressService.getCollegeCourseDetailProgress(param);
+        return CommonResult.data(list);
+    }
+
+    /**
+     * 学习行为分析-学员维度分析
+     *
+     * @author honorfire
+     * @date  2025/07/11 18:52
+     */
+    @ApiOperationSupport(order = 1)
+    @ApiOperation("学习行为分析-学员维度分析")
+    @GetMapping("/disk/studyBehavior/studentAnalyse")
+    public CommonResult<Page<Map<String,Object>>> studentAnalyse(HttpServletRequest req) {
+        Map param =new HashMap();
+        param.put("courseId", req.getParameter("courseId"));
+        param.put("startTime", req.getParameter("startTime"));
+        param.put("endTime", req.getParameter("endTime"));
+        Page<Map<String,Object>> list=studyBehaviorProgressService.getStudentAnalyse(param);
+        return CommonResult.data(list);
+    }
+
+
+}

+ 121 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/StudyBehaviorProgressMapper.java

@@ -0,0 +1,121 @@
+package vip.xiaonuo.disk.mapper;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+public interface StudyBehaviorProgressMapper {
+
+    /**
+     * 学习行为分析-课程访问统计-总课程数
+     */
+    String getAllCourseCount(Map param);
+
+    /**
+     * 学习行为分析-课程访问统计-活跃课程数
+     */
+    String getActiveCourseCount(Map param);
+
+    /**
+     * 学习行为分析-课程访问统计-课程访问数
+     */
+    String getCourseVisitCount(Map param);
+
+    /**
+     * 学习行为分析-用户登录统计-总登录数
+     */
+    String getAllLoginCount(Map param);
+
+    /**
+     * 学习行为分析-用户登录统计-独立用户数
+     */
+    String getUserCount(Map param);
+
+    /**
+     * 学习行为分析-用户登录统计-人均登录次数
+     */
+    String getAvgLoginCount(Map param);
+
+    /**
+     * 学习行为分析-观看时长统计-总观看时长
+     */
+    String getUserAllStayTime(Map param);
+
+    /**
+     * 学习行为分析-观看时长统计-平均观看时长
+     */
+    String getAvgStayTime(Map param);
+
+    /**
+     * 学习行为分析-观看时长统计-峰值观看人数
+     */
+    String getPeakWatchUserCount(Map param);
+
+    /**
+     * 学习行为分析-用户登录时段分布
+     */
+    Page<Map<String,Object>> getLoginFrameDistribution(@Param("param") Map param, @Param("page") Page<Object> page);
+
+    /**
+     * 学习行为分析-课程访问热度排行
+     */
+    Page<Map<String,Object>> getCourseVisitHeatRank(@Param("param") Map param, @Param("page") Page<Object> page);
+
+    /**
+     * 学习行为分析-课程访问热度排行-获取学院列表
+     */
+    Page<Map<String,Object>> getCollegeList(@Param("param") Map param, @Param("page") Page<Object> page);
+
+    /**
+     * 学习行为分析-课程访问热度排行-获取课程数量
+     */
+    List<Map<String,Object>> getCourseCountListCollegeCourse(Map param);
+
+    /**
+     * 学习行为分析-课程访问热度排行-获取总访问量
+     */
+    List<Map<String,Object>> getWatchCountListCollegeCourse(Map param);
+
+    /**
+     * 学习行为分析-课程访问热度排行-获取平均完成值
+     */
+    List<Map<String,Object>> getCompleteRateListCollegeCourse(Map param);
+
+    /**
+     * 学习行为分析-课程访问热度排行-获取作业提交率
+     */
+    List<Map<String,Object>> getHomeworkFinishRateCollegeCourse(Map param);
+
+    /**
+     * 学习行为分析-学员维度分析-查询学生列表
+     */
+    Page<Map<String,Object>> getUserList(@Param("param") Map param, @Param("page") Page<Object> page);
+
+    /**
+     * 学习行为分析-学员维度分析-获取这些学生的汇总课程列表
+     */
+    List<Map<String,Object>> getCourseListStudentAnalyse(Map param);
+
+    /**
+     * 学习行为分析-学员维度分析-获取这些学生的汇总课程列表-查询课程对应学习进度
+     */
+    List<Map<String,Object>> getFinishRateListStudentAnalyse(Map param);
+
+    /**
+     * 学习行为分析-学员维度分析-获取这些学生的汇总课程列表-获取作业完成情况
+     */
+    List<Map<String,Object>> getWorkCountListStudentAnalyse(Map param);
+
+    /**
+     * 学习行为分析-学员维度分析-获取这些学生的汇总课程列表-获取讨论参与数
+     */
+    List<Map<String,Object>> getPostCountListStudentAnalyse(Map param);
+
+    /**
+     * 学习行为分析-学员维度分析-获取这些学生的汇总课程列表-获取提问次数
+     */
+    List<Map<String,Object>> getAnswerCountListStudentAnalyse(Map param);
+
+}

+ 1159 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/mapping/StudyBehaviorProgressMapper.xml

@@ -0,0 +1,1159 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="vip.xiaonuo.disk.mapper.StudyBehaviorProgressMapper">
+
+    <select id="getAllCourseCount" resultType="java.lang.String">
+        SELECT
+            COUNT(ci.COURSE_ID) AS allCourseCount
+        FROM COURSE_INFO ci
+        WHERE ci.DELETE_FLAG ='NOT_DELETE'
+    </select>
+    <select id="getActiveCourseCount" resultType="java.lang.String">
+        SELECT
+            COUNT(z1.courseId) AS activeCourseCount
+        FROM(
+            SELECT
+                --		t1.hourId AS hourId,
+                --		t1.chapterId AS chapterId,
+                --		t1.courseId AS courseId,
+                --		csb.USER_ID AS userId
+                t1.courseId AS courseId
+            FROM (
+                SELECT
+                    cop.ID AS copId,
+                    stu.ID AS userId,
+                    cch.ID AS hourId,
+                    cc.ID AS chapterId,
+                    ci.COURSE_ID AS courseId
+                FROM COURSE_INFO ci
+                LEFT JOIN COURSE_OPEN cop ON ci.COURSE_ID =cop.COURSE_ID AND cop.DELETE_FLAG='NOT_DELETE'
+                LEFT JOIN SYS_USER stu ON stu.GRADES_ID =cop.GRADES_ID AND stu.DELETE_FLAG='NOT_DELETE'
+                LEFT JOIN COURSE_CHAPTER cc ON ci.COURSE_ID =cc.COURSE_ID AND cc.DELETE_FLAG ='NOT_DELETE'
+                LEFT JOIN COURSE_CLASSHOUR cch ON cc.ID=cch.CHAPTER_ID AND cch.DELETE_FLAG ='NOT_DELETE'
+                WHERE ci.DELETE_FLAG ='NOT_DELETE'
+                AND cch.ID IS NOT NULL
+                AND cc.ID IS NOT NULL
+                AND ci.COURSE_ID IS NOT NULL
+                AND stu.ID IS NOT NULL
+                --		AND csb.USER_ID='1948586504800468993'
+            )t1
+            JOIN (
+                SELECT
+                    csb1.USER_ID,
+                    csb1.HOUR_ID
+                FROM COURSE_STUDENT_BURIALPOINT csb1
+                WHERE csb1.DELETE_FLAG ='NOT_DELETE'
+                AND csb1.FUNC_TYPE='1'
+                AND csb1.TYPE='1'
+                --		AND csb1.CREATE_TIME &gt; ='2025-09-01 00:00:00'
+                --		AND csb1.CREATE_TIME &lt; ='2025-09-30 23:59:59'
+                GROUP BY csb1.USER_ID,csb1.HOUR_ID
+            ) csb ON csb.HOUR_ID =t1.hourId AND csb.USER_ID=t1.userId
+            WHERE 1=1
+            GROUP BY t1.courseId
+        )z1
+    </select>
+    <select id="getCourseVisitCount" resultType="java.lang.String">
+        SELECT
+            CASE
+            when z1.courseAllCount=0 or z1.courseAllCount is NULL OR z1.activeCourseCount=0 OR z1.activeCourseCount IS null then 0
+            else TRUNC(z1.activeCourseCount * 1.0 / z1.courseAllCount, 2)
+            END AS courseVisitRate
+        FROM(
+            SELECT
+                (
+                    SELECT COUNT(ci1.COURSE_ID)
+                    FROM COURSE_INFO ci1
+                    WHERE ci1.DELETE_FLAG='NOT_DELETE'
+                ) AS courseAllCount,
+                (
+                    SELECT
+                        COUNT(z1.courseId)
+                    FROM(
+                        SELECT
+                            --		t1.hourId AS hourId,
+                            --		t1.chapterId AS chapterId,
+                            --		t1.courseId AS courseId,
+                            --		csb.USER_ID AS userId
+                            t1.courseId AS courseId
+                        FROM (
+                            SELECT
+                                cop.ID AS copId,
+                                stu.ID AS userId,
+                                cch.ID AS hourId,
+                                cc.ID AS chapterId,
+                                ci.COURSE_ID AS courseId
+                            FROM COURSE_INFO ci
+                            LEFT JOIN COURSE_OPEN cop ON ci.COURSE_ID =cop.COURSE_ID AND cop.DELETE_FLAG='NOT_DELETE'
+                            LEFT JOIN SYS_USER stu ON stu.GRADES_ID =cop.GRADES_ID AND stu.DELETE_FLAG='NOT_DELETE'
+                            LEFT JOIN COURSE_CHAPTER cc ON ci.COURSE_ID =cc.COURSE_ID AND cc.DELETE_FLAG ='NOT_DELETE'
+                            LEFT JOIN COURSE_CLASSHOUR cch ON cc.ID=cch.CHAPTER_ID AND cch.DELETE_FLAG ='NOT_DELETE'
+                            WHERE ci.DELETE_FLAG ='NOT_DELETE'
+                            AND cch.ID IS NOT NULL
+                            AND cc.ID IS NOT NULL
+                            AND ci.COURSE_ID IS NOT NULL
+                            AND stu.ID IS NOT NULL
+                            --		AND csb.USER_ID='1948586504800468993'
+                        )t1
+                        JOIN (
+                            SELECT
+                                csb1.USER_ID,
+                                csb1.HOUR_ID
+                            FROM COURSE_STUDENT_BURIALPOINT csb1
+                            WHERE csb1.DELETE_FLAG ='NOT_DELETE'
+                            AND csb1.FUNC_TYPE='1'
+                            AND csb1.TYPE='1'
+                            --		AND csb1.CREATE_TIME &gt;='2025-09-01 00:00:00'
+                            --		AND csb1.CREATE_TIME &lt;='2025-09-30 23:59:59'
+                            GROUP BY csb1.USER_ID,csb1.HOUR_ID
+                        ) csb ON csb.HOUR_ID =t1.hourId AND csb.USER_ID=t1.userId
+                        WHERE 1=1
+                        GROUP BY t1.courseId
+                    )z1
+                )AS activeCourseCount
+            FROM DUAL
+        )z1
+    </select>
+    <select id="getAllLoginCount" resultType="java.lang.String">
+        SELECT
+            ifnull(COUNT(dl.ID),0) AS allloginCount
+        FROM DEV_LOG dl
+        WHERE dl.CATEGORY='LOGIN'
+        AND dl.EXE_STATUS='SUCCESS'
+    </select>
+    <select id="getUserCount" resultType="java.lang.String">
+        SELECT
+            ifnull(COUNT(su.ID),0) AS userCount
+        FROM SYS_USER su
+        WHERE su.DELETE_FLAG ='NOT_DELETE'
+    </select>
+    <select id="getAvgLoginCount" resultType="java.lang.String">
+        SELECT
+            ifnull(TRUNC(AVG(t1.userLoginCount), 2) ,0) AS avgLoginCount
+        FROM(
+            SELECT
+                dl.OP_USER AS opUser,
+                COUNT(dl.ID) AS userLoginCount
+            FROM DEV_LOG dl
+            WHERE dl.CATEGORY='LOGIN'
+            AND dl.EXE_STATUS='SUCCESS'
+            GROUP BY dl.OP_USER
+        )t1
+    </select>
+    <select id="getUserAllStayTime" resultType="java.lang.String">
+        SELECT
+            LPAD(FLOOR(tt1.userAllStayTIme / 3600000), 5, '0') || '小时' ||
+            LPAD(FLOOR((tt1.userAllStayTIme % 3600000) / 60000), 2, '0') || '分钟' AS userAllStayTime
+        FROM(
+            SELECT
+                --	t1.hourId AS hourId,
+                --	t1.chapterId AS chapterId,
+                --	t1.courseId AS courseId,
+                --	t1.userId AS userId,
+                --	IFNULL(csb.STAY_TIME,0) AS stayTime
+                IFNULL(SUM(csb.STAY_TIME),0) AS userAllStayTIme
+            FROM (
+                SELECT
+                    cop.ID AS copId,
+                    stu.ID AS userId,
+                    cch.ID AS hourId,
+                    cc.ID AS chapterId,
+                    ci.COURSE_ID AS courseId
+                FROM COURSE_INFO ci
+                LEFT JOIN COURSE_OPEN cop ON ci.COURSE_ID =cop.COURSE_ID AND cop.DELETE_FLAG='NOT_DELETE'
+                LEFT JOIN SYS_USER stu ON stu.GRADES_ID =cop.GRADES_ID AND stu.DELETE_FLAG='NOT_DELETE'
+                LEFT JOIN COURSE_CHAPTER cc ON ci.COURSE_ID =cc.COURSE_ID AND cc.DELETE_FLAG ='NOT_DELETE'
+                LEFT JOIN COURSE_CLASSHOUR cch ON cc.ID=cch.CHAPTER_ID AND cch.DELETE_FLAG ='NOT_DELETE'
+                WHERE ci.DELETE_FLAG ='NOT_DELETE'
+                AND cch.ID IS NOT NULL
+                AND cc.ID IS NOT NULL
+                AND ci.COURSE_ID IS NOT NULL
+                AND stu.ID IS NOT NULL
+                --		AND csb.USER_ID='1948586504800468993'
+            )t1
+            LEFT JOIN (SELECT csb1.USER_ID,csb1.HOUR_ID,csb1.STAY_TIME FROM COURSE_STUDENT_BURIALPOINT csb1 WHERE csb1.DELETE_FLAG ='NOT_DELETE' AND csb1.FUNC_TYPE='1' AND csb1.TYPE='1') csb ON csb.HOUR_ID =t1.hourId AND csb.USER_ID=t1.userId
+            WHERE 1=1
+            --	AND t1.courseId='1954728193252552705'
+        )tt1
+    </select>
+    <select id="getAvgStayTime" resultType="java.lang.String">
+        SELECT
+            LPAD(FLOOR(tt1.avgStayTime / 3600000), 5, '0') || '小时' ||
+            LPAD(FLOOR((tt1.avgStayTime % 3600000) / 60000), 2, '0') || '分钟' AS avgStayTime
+        FROM(
+            SELECT
+                TRUNC(IFNULL(AVG(z1.userAllStayTIme),0), 2) AS avgStayTime
+            FROM(
+                SELECT
+                    --	t1.hourId AS hourId,
+                    --	t1.chapterId AS chapterId,
+                    --	t1.courseId AS courseId,
+                    --	t1.userId AS userId,
+                    --	IFNULL(csb.STAY_TIME,0) AS stayTime
+                    t1.userId AS userId,
+                    IFNULL(SUM(csb.STAY_TIME),0) AS userAllStayTIme
+                FROM (
+                    SELECT
+                        cop.ID AS copId,
+                        stu.ID AS userId,
+                        cch.ID AS hourId,
+                        cc.ID AS chapterId,
+                        ci.COURSE_ID AS courseId
+                    FROM COURSE_INFO ci
+                    LEFT JOIN COURSE_OPEN cop ON ci.COURSE_ID =cop.COURSE_ID AND cop.DELETE_FLAG='NOT_DELETE'
+                    LEFT JOIN SYS_USER stu ON stu.GRADES_ID =cop.GRADES_ID AND stu.DELETE_FLAG='NOT_DELETE'
+                    LEFT JOIN COURSE_CHAPTER cc ON ci.COURSE_ID =cc.COURSE_ID AND cc.DELETE_FLAG ='NOT_DELETE'
+                    LEFT JOIN COURSE_CLASSHOUR cch ON cc.ID=cch.CHAPTER_ID AND cch.DELETE_FLAG ='NOT_DELETE'
+                    WHERE ci.DELETE_FLAG ='NOT_DELETE'
+                    AND cch.ID IS NOT NULL
+                    AND cc.ID IS NOT NULL
+                    AND ci.COURSE_ID IS NOT NULL
+                    AND stu.ID IS NOT NULL
+                    --		AND csb.USER_ID='1948586504800468993'
+                )t1
+                LEFT JOIN (SELECT csb1.USER_ID,csb1.HOUR_ID,csb1.STAY_TIME FROM COURSE_STUDENT_BURIALPOINT csb1 WHERE csb1.DELETE_FLAG ='NOT_DELETE' AND csb1.FUNC_TYPE='1' AND csb1.TYPE='1') csb ON csb.HOUR_ID =t1.hourId AND csb.USER_ID=t1.userId
+                WHERE 1=1
+                --	AND t1.courseId='1954728193252552705'
+                GROUP BY t1.userId
+            )z1
+        )tt1
+    </select>
+    <select id="getPeakWatchUserCount" resultType="java.lang.String">
+        SELECT
+            IFNULL(zz1.watchCount,0)AS peakWatchUserCount
+        FROM(
+            SELECT
+                --	z1.csbCreateTime AS csbCreateTime,
+                z1.watchCount AS watchCount
+            FROM(
+                SELECT
+                    tt1.csbCreateTime AS csbCreateTime,
+                    count(csbId) AS watchCount
+                FROM (
+                    SELECT
+                        t1.hourId AS hourId,
+                        t1.chapterId AS chapterId,
+                        t1.courseId AS courseId,
+                        t1.userId AS userId,
+                        DATE_FORMAT(csb.CREATE_TIME, '%Y-%m-%d') AS csbCreateTime,
+                        csb.ID AS csbId
+                    FROM (
+                        SELECT
+                            stu.ID AS userId,
+                            cch.ID AS hourId,
+                            cc.ID AS chapterId,
+                            ci.COURSE_ID AS courseId
+                        FROM COURSE_INFO ci
+                        LEFT JOIN COURSE_OPEN cop ON ci.COURSE_ID =cop.COURSE_ID AND cop.DELETE_FLAG='NOT_DELETE'
+                        LEFT JOIN SYS_USER stu ON stu.GRADES_ID =cop.GRADES_ID AND stu.DELETE_FLAG='NOT_DELETE'
+                        LEFT JOIN COURSE_CHAPTER cc ON ci.COURSE_ID =cc.COURSE_ID AND cc.DELETE_FLAG ='NOT_DELETE'
+                        LEFT JOIN COURSE_CLASSHOUR cch ON cc.ID=cch.CHAPTER_ID AND cch.DELETE_FLAG ='NOT_DELETE'
+                        WHERE ci.DELETE_FLAG ='NOT_DELETE'
+                        AND cch.ID IS NOT NULL
+                        AND cc.ID IS NOT NULL
+                        AND ci.COURSE_ID IS NOT NULL
+                        AND stu.ID IS NOT NULL
+                        --		AND csb.USER_ID='1948586504800468993'
+                    )t1
+                    LEFT JOIN (SELECT csb1.ID,csb1.USER_ID,csb1.HOUR_ID,csb1.CREATE_TIME FROM COURSE_STUDENT_BURIALPOINT csb1 WHERE csb1.DELETE_FLAG ='NOT_DELETE' AND csb1.FUNC_TYPE='1' AND csb1.TYPE='1') csb ON csb.HOUR_ID =t1.hourId AND csb.USER_ID=t1.userId
+                    WHERE 1=1
+                    --	AND t1.courseId='1954728193252552705'
+                )tt1
+                GROUP BY tt1.csbCreateTime
+            )z1
+            ORDER BY z1.watchCount DESC
+            LIMIT 1
+        )zz1
+    </select>
+    <select id="getLoginFrameDistribution" resultType="java.util.Map">
+        SELECT
+            t1.createTime AS createTime,
+            COUNT(t1.createTime) AS count
+        FROM(
+            SELECT
+                DATE_FORMAT(dl.CREATE_TIME, '%H') || ':00' AS createTime
+            FROM DEV_LOG dl
+            WHERE dl.CATEGORY='LOGIN'
+            AND dl.EXE_STATUS='SUCCESS'
+        )t1
+        GROUP by t1.createTime
+    </select>
+    <select id="getCourseVisitHeatRank" resultType="java.util.Map">
+        SELECT
+            ci.courseId AS courseId,
+            IFNULL(ci.courseName,'') AS courseName,
+            IFNULL(finalTwo.watchCount,0) AS watchCount
+        FROM(SELECT ci1.COURSE_ID AS courseId, IFNULL(ci1.COURSE_NAME,'') AS courseName FROM COURSE_INFO ci1 LEFT JOIN COURSE_OPEN cop ON ci1.COURSE_ID =cop.COURSE_ID AND cop.DELETE_FLAG='NOT_DELETE' WHERE ci1.DELETE_FLAG='NOT_DELETE' GROUP BY ci1.COURSE_ID,ci1.COURSE_NAME)ci
+        LEFT JOIN(
+            SELECT
+                --		z1.courseId AS courseId,
+                --		z1.hourId AS hourId,
+                --		z1.csbId AS csbId
+                --		z1.userId AS userId
+                z1.courseId AS courseId,
+                IFNULL(count(z1.userId),0) AS watchCount
+            FROM(
+                SELECT
+                    --	#比对每个人应上的所有课程对应课时中,所有看过的记录
+                    --	t1.courseId AS courseId,
+                    --	t1.hourId AS hourId,
+                    --	csb.USER_ID AS userId
+                    t1.hourId AS hourId,
+                    t1.courseId AS courseId,
+                    t1.userId AS userId,
+                    csb.ID AS csbId
+                FROM(
+                    --  #先查出,每个人应该上的所有课程和对应课时
+                    SELECT
+                        stu.ID AS userId,
+                        cch.ID AS hourId,
+                        cc.ID AS chapterId,
+                        ci.COURSE_ID AS courseId
+                    FROM COURSE_INFO ci
+                    LEFT JOIN COURSE_OPEN cop ON ci.COURSE_ID =cop.COURSE_ID AND cop.DELETE_FLAG='NOT_DELETE'
+                    LEFT JOIN SYS_USER stu ON stu.GRADES_ID =cop.GRADES_ID AND stu.DELETE_FLAG='NOT_DELETE'
+                    LEFT JOIN COURSE_CHAPTER cc ON ci.COURSE_ID =cc.COURSE_ID       AND cc.DELETE_FLAG ='NOT_DELETE'
+                    LEFT JOIN COURSE_CLASSHOUR cch ON cc.ID=cch.CHAPTER_ID AND cch.DELETE_FLAG ='NOT_DELETE'
+                    WHERE ci.DELETE_FLAG ='NOT_DELETE'
+                    AND cch.ID IS NOT NULL
+                    AND cc.ID IS NOT NULL
+                    AND ci.COURSE_ID IS NOT NULL
+                    AND stu.ID IS NOT NULL
+                    GROUP BY stu.ID,cch.ID,cc.ID,ci.COURSE_ID
+                )t1
+                JOIN (SELECT csb1.ID,csb1.USER_ID,csb1.HOUR_ID FROM COURSE_STUDENT_BURIALPOINT csb1 WHERE csb1.DELETE_FLAG ='NOT_DELETE' AND csb1.FUNC_TYPE='1' AND csb1.TYPE='1') csb ON csb.HOUR_ID =t1.hourId AND csb.USER_ID=t1.userId
+                WHERE 1=1
+                GROUP BY t1.courseId,t1.userId,t1.hourId,csb.ID
+            )z1
+            GROUP BY z1.courseId
+        )finalTwo ON ci.courseId =finalTwo.courseId
+        ORDER BY watchCount desc
+    </select>
+    <select id="getCollegeList" resultType="java.util.Map">
+        SELECT
+               so.ID as collegeId,
+               so.NAME as collegeIdName
+        FROM SYS_ORG so
+        WHERE so.DELETE_FLAG ='NOT_DELETE'
+        AND so."CATEGORY" ='COLLEGE'
+    </select>
+    <select id="getCourseCountListCollegeCourse" resultType="java.util.Map">
+        SELECT
+            so.ID AS collegeId,
+            IFNULL(finalOne.courseCount,0) AS courseCount
+        FROM (
+            SELECT so.ID
+            FROM SYS_ORG so
+            WHERE so.DELETE_FLAG ='NOT_DELETE'
+            AND so."CATEGORY" ='COLLEGE'
+            <if test="collegeIdList !=null and collegeIdList.size()>0">
+                and so.ID in
+                <foreach collection=" collegeIdList" close=")" index="index" item="item" open="(" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+        ) so
+        LEFT JOIN(
+            SELECT
+                t1.orgId AS orgId,
+                count(t1.courseId) AS courseCount
+            FROM(
+                SELECT
+                    --		so.ID AS orgId,
+                    --		gr.grades_id AS gradesId,
+                    --		ci.COURSE_ID AS courseId
+                    so.ID AS orgId,
+                    ci.COURSE_ID AS courseId
+                FROM SYS_ORG so
+                LEFT JOIN "grades" gr  ON gr.college_id=so.ID AND gr.DELETE_FLAG='NOT_DELETE'
+                LEFT JOIN COURSE_OPEN cop ON cop.GRADES_ID =gr.grades_id AND cop.DELETE_FLAG='NOT_DELETE'
+                LEFT JOIN COURSE_INFO ci ON cop.COURSE_ID =ci.COURSE_ID
+                WHERE so.DELETE_FLAG='NOT_DELETE'
+                AND gr.grades_id IS NOT NULL
+                AND ci.COURSE_ID IS NOT NULL
+                <if test="collegeIdList !=null and collegeIdList.size()>0">
+                    and so.ID in
+                    <foreach collection=" collegeIdList" close=")" index="index" item="item" open="(" separator=",">
+                        #{item}
+                    </foreach>
+                </if>
+                GROUP BY so.ID,ci.COURSE_ID
+            )t1
+            GROUP BY t1.orgId
+        )finalOne ON so.ID =finalOne.orgId
+    </select>
+    <select id="getWatchCountListCollegeCourse" resultType="java.util.Map">
+        SELECT
+            so.ID AS collegeId,
+            IFNULL(finalTwo.watchCount,0) AS watchCount
+        FROM (
+            SELECT so.ID
+            FROM SYS_ORG so
+            WHERE so.DELETE_FLAG ='NOT_DELETE'
+            AND so."CATEGORY" ='COLLEGE'
+            <if test="collegeIdList !=null and collegeIdList.size()>0">
+                and so.ID in
+                <foreach collection=" collegeIdList" close=")" index="index" item="item" open="(" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+        ) so
+        LEFT JOIN(
+            SELECT
+                --	t1.orgId AS orgId,
+                --	t1.courseId AS courseId,
+                --	t1.hourId AS hourId,
+                --	csb.ID AS csbId,
+                --	csb.USER_ID AS csbUserId
+                t1.orgId AS orgId,
+                COUNT(csb.ID) AS watchCount
+            FROM(
+                --  #先查出,每个人应该上的所有课程和对应课时,以及这些课程对应所属班级和对应院系(另外院系得以自身为维度,和开课班级之类的关联,统计的是对应课程的院系,而不是学生的院系)
+                SELECT
+                    stu.ID AS userId,
+                    cch.ID AS hourId,
+                    cc.ID AS chapterId,
+                    z1.orgId AS orgId,
+                    z1.gradesId AS gradesId,
+                    z1.courseId AS courseId
+                FROM (
+                    --	#查出每个院系对应每个班级以及对应课程,因为一个院系,可能会有多个班级,多个班级对应的多个开课,可能就会导致某个课程对于一个院系重复,所以需要提前分组
+                    SELECT
+                        so.ID AS orgId,
+                        gr.grades_id AS gradesId,
+                        ci.COURSE_ID AS courseId
+                    FROM SYS_ORG so
+                    LEFT JOIN "grades" gr  ON gr.college_id=so.ID AND gr.DELETE_FLAG='NOT_DELETE'
+                    LEFT JOIN COURSE_OPEN cop ON cop.GRADES_ID =gr.grades_id AND cop.DELETE_FLAG='NOT_DELETE'
+                    LEFT JOIN COURSE_INFO ci ON cop.COURSE_ID =ci.COURSE_ID
+                    WHERE so.DELETE_FLAG='NOT_DELETE'
+                    AND gr.grades_id IS NOT NULL
+                    AND ci.COURSE_ID IS NOT NULL
+                    <if test="collegeIdList !=null and collegeIdList.size()>0">
+                        and so.ID in
+                        <foreach collection=" collegeIdList" close=")" index="index" item="item" open="(" separator=",">
+                            #{item}
+                        </foreach>
+                    </if>
+                    GROUP BY so.ID,ci.COURSE_ID,gr.grades_id
+                )z1
+                LEFT JOIN SYS_USER stu ON stu.GRADES_ID =z1.gradesId AND stu.DELETE_FLAG='NOT_DELETE'
+                LEFT JOIN COURSE_CHAPTER cc ON z1.courseId =cc.COURSE_ID AND cc.DELETE_FLAG ='NOT_DELETE'
+                LEFT JOIN COURSE_CLASSHOUR cch ON cc.ID=cch.CHAPTER_ID AND cch.DELETE_FLAG ='NOT_DELETE'
+                WHERE 1=1
+                AND cch.ID IS NOT NULL
+                AND cc.ID IS NOT NULL
+                AND stu.ID IS NOT NULL
+                GROUP BY stu.ID,cch.ID,cc.ID,z1.orgId,z1.gradesId,z1.courseId
+            )t1
+            JOIN (SELECT csb1.ID,csb1.USER_ID,csb1.HOUR_ID FROM COURSE_STUDENT_BURIALPOINT csb1 WHERE csb1.DELETE_FLAG ='NOT_DELETE' AND csb1.FUNC_TYPE='1' AND csb1.TYPE='1') csb ON csb.HOUR_ID =t1.hourId AND csb.USER_ID=t1.userId
+            WHERE 1=1
+            GROUP BY t1.orgId
+        )finalTwo ON so.ID =finalTwo.orgId
+    </select>
+    <select id="getCompleteRateListCollegeCourse" resultType="java.util.Map">
+        SELECT
+            so.ID AS collegeId,
+            IFNULL(finalThree.completeRate,0) AS completeRate
+        FROM (
+            SELECT so.ID
+            FROM SYS_ORG so
+            WHERE so.DELETE_FLAG ='NOT_DELETE'
+            AND so."CATEGORY" ='COLLEGE'
+            <if test="collegeIdList !=null and collegeIdList.size()>0">
+                and so.ID in
+                <foreach collection=" collegeIdList" close=")" index="index" item="item" open="(" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+        ) so
+        LEFT JOIN(
+            SELECT
+                tt2.orgId AS orgId,
+                CASE
+                when tt2.allUserCount=0 or tt2.allUserCount is NULL OR tt2.completeWatchUserCount=0 OR tt2.completeWatchUserCount IS null then 0
+                else TRUNC(tt2.completeWatchUserCount * 1.0 / tt2.allUserCount, 2)
+                END AS completeRate
+            FROM(
+                SELECT
+                    --	#这门专业,完成观看的人和应该观看的总人数(专业下,目前对应人员的对应课程,对应人员只要看过任何一门就算完成观看,如果未来要求全部完成才算完成观看,只需要finishRate=1即可)
+                    tt1.orgId,
+                    IFNULL(count( CASE WHEN tt1.finishRate>0 THEN 1 ELSE NULL END ),0) AS completeWatchUserCount,
+                    IFNULL(count(tt1.userId),0) AS allUserCount
+                from(
+                    --	#查询每个专业每个人完成率(每个人,应该上的课程,的完成率)
+                    SELECT
+                        IFNULL(z1.alreadyCount,0) AS alreadyCount,
+                        IFNULL(z2.allCount,0) AS allCount,
+                        z2.orgId AS orgId,
+                        z2.userId AS userId,
+                        CASE
+                        when z2.allCount=0 or z2.allCount is NULL OR z1.alreadyCount=0 OR z1.alreadyCount IS null then 0
+                        else TRUNC(z1.alreadyCount * 1.0 / z2.allCount, 2)
+                        END AS finishRate
+                    FROM (
+                        --	#根据开课查询每个课程,每个人员,对应的课时总数量,最后按院系维度统计,院系每个人应该看的总数量
+                        SELECT
+                            t2.orgId,
+                            t2.userId,
+                            IFNULL(COUNT(t2.userId),0) AS allCount
+                        FROM (
+                            SELECT
+                                stu.ID AS userId,
+                                cch.ID AS hourId,
+                                cc.ID AS chapterId,
+                                z1.orgId AS orgId,
+                                z1.gradesId AS gradesId,
+                                z1.courseId AS courseId
+                            FROM (
+                                --	#查出每个院系对应每个班级以及对应课程,因为一个院系,可能会有多个班级,多个班级对应的多个开课,可能就会导致某个课程对于一个院系重复,所以需要提前分组
+                                SELECT
+                                    so.ID AS orgId,
+                                    gr.grades_id AS gradesId,
+                                    ci.COURSE_ID AS courseId
+                                FROM SYS_ORG so
+                                LEFT JOIN "grades" gr  ON gr.college_id=so.ID AND gr.DELETE_FLAG='NOT_DELETE'
+                                LEFT JOIN COURSE_OPEN cop ON cop.GRADES_ID =gr.grades_id AND cop.DELETE_FLAG='NOT_DELETE'
+                                LEFT JOIN COURSE_INFO ci ON cop.COURSE_ID =ci.COURSE_ID
+                                WHERE so.DELETE_FLAG='NOT_DELETE'
+                                AND gr.grades_id IS NOT NULL
+                                AND ci.COURSE_ID IS NOT NULL
+                                <if test="collegeIdList !=null and collegeIdList.size()>0">
+                                    and so.ID in
+                                    <foreach collection=" collegeIdList" close=")" index="index" item="item" open="(" separator=",">
+                                        #{item}
+                                    </foreach>
+                                </if>
+                                GROUP BY so.ID,ci.COURSE_ID,gr.grades_id
+                            )z1
+                            LEFT JOIN SYS_USER stu ON stu.GRADES_ID =z1.gradesId AND stu.DELETE_FLAG='NOT_DELETE'
+                            LEFT JOIN COURSE_CHAPTER cc ON z1.courseId =cc.COURSE_ID AND cc.DELETE_FLAG ='NOT_DELETE'
+                            LEFT JOIN COURSE_CLASSHOUR cch ON cc.ID=cch.CHAPTER_ID AND cch.DELETE_FLAG ='NOT_DELETE'
+                            WHERE 1=1
+                            AND cch.ID IS NOT NULL
+                            AND cc.ID IS NOT NULL
+                            AND stu.ID IS NOT NULL
+                            GROUP BY stu.ID,cch.ID,cc.ID,z1.orgId,z1.gradesId,z1.courseId
+                        )t2
+                        WHERE 1=1
+                        --	AND t2.courseId='1954728193252552705'
+                        GROUP BY t2.orgId,t2.userId
+                    )z2
+                    LEFT JOIN(
+                        --	#根据开课查询每个课程,对应的课时的对应人员,其中已经看完的部分,最后按院系维度统计,院系每个人已看完的数量
+                        SELECT
+                            --				t1.hourId AS hourId,
+                            --				t1.chapterId AS chapterId,
+                            --				t1.courseId AS courseId,
+                            --				t1.gradesId AS gradesId,
+                            --				t1.orgId AS orgId,
+                            --				t1.userId AS needWatchUserId,
+                            --				csb.USER_ID AS alreadyWatchUserId
+                            t1.orgId AS orgId,
+                            t1.userId AS userId,
+                            IFNULL(COUNT(csb.USER_ID),0) AS alreadyCount
+                        FROM (
+                            SELECT
+                                stu.ID AS userId,
+                                cch.ID AS hourId,
+                                cc.ID AS chapterId,
+                                zz1.orgId AS orgId,
+                                zz1.gradesId AS gradesId,
+                                zz1.courseId AS courseId
+                            FROM (
+                                --	#查出每个院系对应每个班级以及对应课程,因为一个院系,可能会有多个班级,多个班级对应的多个开课,可能就会导致某个课程对于一个院系重复,所以需要提前分组
+                                SELECT
+                                    so.ID AS orgId,
+                                    gr.grades_id AS gradesId,
+                                    ci.COURSE_ID AS courseId
+                                FROM SYS_ORG so
+                                LEFT JOIN "grades" gr  ON gr.college_id=so.ID AND gr.DELETE_FLAG='NOT_DELETE'
+                                LEFT JOIN COURSE_OPEN cop ON cop.GRADES_ID =gr.grades_id AND cop.DELETE_FLAG='NOT_DELETE'
+                                LEFT JOIN COURSE_INFO ci ON cop.COURSE_ID =ci.COURSE_ID
+                                WHERE so.DELETE_FLAG='NOT_DELETE'
+                                AND gr.grades_id IS NOT NULL
+                                AND ci.COURSE_ID IS NOT NULL
+                                <if test="collegeIdList !=null and collegeIdList.size()>0">
+                                    and so.ID in
+                                    <foreach collection=" collegeIdList" close=")" index="index" item="item" open="(" separator=",">
+                                        #{item}
+                                    </foreach>
+                                </if>
+                                GROUP BY so.ID,ci.COURSE_ID,gr.grades_id
+                            )zz1
+                            LEFT JOIN SYS_USER stu ON stu.GRADES_ID =zz1.gradesId AND stu.DELETE_FLAG='NOT_DELETE'
+                            LEFT JOIN COURSE_CHAPTER cc ON zz1.courseId =cc.COURSE_ID AND cc.DELETE_FLAG ='NOT_DELETE'
+                            LEFT JOIN COURSE_CLASSHOUR cch ON cc.ID=cch.CHAPTER_ID AND cch.DELETE_FLAG ='NOT_DELETE'
+                            WHERE 1=1
+                            AND cch.ID IS NOT NULL
+                            AND cc.ID IS NOT NULL
+                            AND stu.ID IS NOT NULL
+                            GROUP BY stu.ID,cch.ID,cc.ID,zz1.orgId,zz1.gradesId,zz1.courseId
+                        )t1
+                        JOIN (SELECT csb1.USER_ID,csb1.HOUR_ID FROM COURSE_STUDENT_BURIALPOINT csb1 WHERE csb1.DELETE_FLAG ='NOT_DELETE' AND csb1.FUNC_TYPE='1' AND csb1.TYPE='1' GROUP BY csb1.USER_ID,csb1.HOUR_ID) csb ON csb.HOUR_ID =t1.hourId AND csb.USER_ID=t1.userId
+                        WHERE 1=1
+                        --	AND t1.courseId='1954728193252552705'
+                        GROUP BY t1.orgId,t1.userId
+                    )z1 ON z1.userId=z2.userId AND z1.orgId=z2.orgId
+                )tt1
+                GROUP BY tt1.orgId
+            )tt2
+        )finalThree ON so.ID =finalThree.orgId
+    </select>
+    <select id="getHomeworkFinishRateCollegeCourse" resultType="java.util.Map">
+        SELECT
+            so.ID AS collegeId,
+            IFNULL(finalfour.homeworkFinishRate,0) AS homeworkFinishRate
+        FROM (
+            SELECT so.ID
+            FROM SYS_ORG so
+            WHERE so.DELETE_FLAG ='NOT_DELETE'
+            AND so."CATEGORY" ='COLLEGE'
+            <if test="collegeIdList !=null and collegeIdList.size()>0">
+                and so.ID in
+                <foreach collection=" collegeIdList" close=")" index="index" item="item" open="(" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+        ) so
+        LEFT JOIN(
+            SELECT
+                tt1.orgId AS orgId,
+                CASE
+                when tt1.allCount=0 or tt1.allCount is NULL OR tt1.alreadyCount=0 OR tt1.alreadyCount IS null then 0
+                else TRUNC(tt1.alreadyCount * 1.0 / tt1.allCount, 2)
+                END AS homeworkFinishRate
+            from(
+                --	#查询每个专业每个人完成率(每个人,应该上的课程,的完成率)
+                SELECT
+                    z2.orgId AS orgId,
+                    IFNULL(count( CASE WHEN z2.tepaId IS NOT NULL THEN 1 ELSE NULL END ),0) AS alreadyCount,
+                    IFNULL(count(z2.orgId),0) AS allCount
+                FROM (
+                    --	#根据开课查询每个课程,每个人员,对应的课时总数量,最后按院系维度统计,院系每个人应该看的总数量
+                    SELECT
+                        t2.orgId AS orgId,
+                        t2.hourId AS hourId,
+                        t2.userId AS userId,
+                        t2.tepId AS tepId,
+                        tepa.id AS tepaId
+                    --				IFNULL(COUNT(t2.userId),0) AS allCount
+                    FROM (
+                        SELECT
+                            stu.ID AS userId,
+                            z1.orgId AS orgId,
+                            cch.ID AS hourId,
+                            tep.id AS tepId
+                        FROM (
+                            --	#查出每个院系对应每个班级以及对应课程,因为一个院系,可能会有多个班级,多个班级对应的多个开课,可能就会导致某个课程对于一个院系重复,所以需要提前分组
+                            SELECT
+                                so.ID AS orgId,
+                                gr.grades_id AS gradesId,
+                                ci.COURSE_ID AS courseId
+                            FROM SYS_ORG so
+                            LEFT JOIN "grades" gr  ON gr.college_id=so.ID AND gr.DELETE_FLAG='NOT_DELETE'
+                            LEFT JOIN COURSE_OPEN cop ON cop.GRADES_ID =gr.grades_id AND cop.DELETE_FLAG='NOT_DELETE'
+                            LEFT JOIN COURSE_INFO ci ON cop.COURSE_ID =ci.COURSE_ID
+                            WHERE so.DELETE_FLAG='NOT_DELETE'
+                            AND gr.grades_id IS NOT NULL
+                            AND ci.COURSE_ID IS NOT NULL
+                            <if test="collegeIdList !=null and collegeIdList.size()>0">
+                                and so.ID in
+                                <foreach collection=" collegeIdList" close=")" index="index" item="item" open="(" separator=",">
+                                    #{item}
+                                </foreach>
+                            </if>
+                            GROUP BY so.ID,ci.COURSE_ID,gr.grades_id
+                        )z1
+                        LEFT JOIN SYS_USER stu ON stu.GRADES_ID =z1.gradesId AND stu.DELETE_FLAG='NOT_DELETE'
+                        LEFT JOIN COURSE_CHAPTER cc ON z1.courseId =cc.COURSE_ID AND cc.DELETE_FLAG ='NOT_DELETE'
+                        LEFT JOIN COURSE_CLASSHOUR cch ON cc.ID=cch.CHAPTER_ID AND cch.DELETE_FLAG ='NOT_DELETE'
+                        JOIN COURSE_RELATE cr ON cr.MAIN_ID =cch.ID AND cr.FUNC_TYPE ='4' AND cr.INFO_TYPE ='0' AND cr.CHAPTERHOUR_TYPE ='1' AND cr.DELETE_FLAG ='NOT_DELETE'
+                        JOIN "t_exam_paper" tep ON tep.id=cr.RELATE_ID AND tep.deleted='0'
+                        WHERE 1=1
+                        AND cch.ID IS NOT NULL
+                        AND cc.ID IS NOT NULL
+                        AND stu.ID IS NOT NULL
+                        GROUP BY stu.ID,z1.orgId,z1.gradesId,cch.ID,tep.id
+                    )t2
+                    --	#直接查询考试答卷表,查询该人员该试卷是否有对应答案
+                    LEFT JOIN t_exam_paper_answer tepa ON tepa.create_user=t2.userId AND tepa.exam_paper_id=t2.tepId
+                    WHERE 1=1
+                    --	AND t2.courseId='1954728193252552705'
+                    GROUP BY t2.orgId,t2.hourId,t2.userId,t2.tepId,tepa.id
+                )z2
+                GROUP BY z2.orgId
+            )tt1
+        )finalFour ON so.ID =finalFour.orgId
+    </select>
+    <select id="getUserList" resultType="java.util.Map">
+        SELECT
+            su.ID AS userId,
+            IFNULL(su.NAME,'') AS userIdName,
+            IFNULL(su.STUDENT_NUM,'') AS studentNum,
+            IFNULL(su.ORG_ID,'') AS orgId,
+            IFNULL(so.NAME,'') AS orgIdName,
+            IFNULL(su.MAJOR_ID,'') AS majorId,
+            IFNULL(ma."major_name",'') AS majorIdName,
+            IFNULL(su.GRADES_ID,'') AS gradesId,
+            IFNULL(gr."grades_name",'') AS gradesIdName,
+            IFNULL(finalThree.finishRate,0) AS finishRate
+        FROM SYS_USER su
+        LEFT JOIN SYS_ORG so ON su.ORG_ID = so.ID AND so.DELETE_FLAG ='NOT_DELETE'
+        LEFT JOIN "major" ma ON su.MAJOR_ID = ma."id" AND ma.DELETE_FLAG ='NOT_DELETE'
+        LEFT JOIN "grades" gr ON su.GRADES_ID = gr."grades_id" AND gr.DELETE_FLAG ='NOT_DELETE'
+        LEFT JOIN (
+            SELECT
+                --	z1.courseId AS courseId,
+                --	z1.alreadyCount AS alreadyCount,
+                --	z2.allCount AS allCount
+                z2.userId AS userId,
+                CASE
+                when z2.allCount=0 or z2.allCount is NULL OR z1.alreadyCount=0 OR z1.alreadyCount IS null then 0
+                else TRUNC(z1.alreadyCount * 1.0 / z2.allCount, 2)
+                END AS finishRate
+            FROM (
+                SELECT
+                    t2.userId,
+                    IFNULL(COUNT(t2.hourId AS hourId),0) AS allCount
+                FROM (
+                    SELECT
+                        cop.ID AS copId,
+                        cch.ID AS hourId,
+                        cc.ID AS chapterId,
+                        ci.COURSE_ID AS courseId,
+                        stu.ID AS userId
+                    FROM COURSE_INFO ci
+                    LEFT JOIN COURSE_OPEN cop ON ci.COURSE_ID =cop.COURSE_ID AND cop.DELETE_FLAG='NOT_DELETE'
+                    LEFT JOIN SYS_USER stu ON stu.GRADES_ID =cop.GRADES_ID AND stu.DELETE_FLAG='NOT_DELETE'
+                    LEFT JOIN COURSE_CHAPTER cc ON ci.COURSE_ID =cc.COURSE_ID AND cc.DELETE_FLAG ='NOT_DELETE'
+                    LEFT JOIN COURSE_CLASSHOUR cch ON cc.ID=cch.CHAPTER_ID AND cch.DELETE_FLAG ='NOT_DELETE'
+                    WHERE ci.DELETE_FLAG ='NOT_DELETE'
+                    AND cch.ID IS NOT NULL
+                    AND cc.ID IS NOT NULL
+                    AND ci.COURSE_ID IS NOT NULL
+                    AND stu.ID IS NOT NULL
+                )t2
+                WHERE 1=1
+                --	AND t2.courseId='1954728193252552705'
+                GROUP BY t2.userId
+            )z2
+            LEFT JOIN(
+                SELECT
+                    --		t1.hourId AS hourId,
+                    --		t1.chapterId AS chapterId,
+                    --		csb.USER_ID AS userId
+                    t1.userId AS userId,
+                    IFNULL(COUNT(csb.HOUR_ID AS hourId),0) AS alreadyCount
+                FROM (
+                    SELECT
+                        cop.ID AS copId,
+                        stu.ID AS userId,
+                        cch.ID AS hourId,
+                        cc.ID AS chapterId,
+                        ci.COURSE_ID AS courseId
+                    FROM COURSE_INFO ci
+                    LEFT JOIN COURSE_OPEN cop ON ci.COURSE_ID =cop.COURSE_ID AND cop.DELETE_FLAG='NOT_DELETE'
+                    LEFT JOIN SYS_USER stu ON stu.GRADES_ID =cop.GRADES_ID AND stu.DELETE_FLAG='NOT_DELETE'
+                    LEFT JOIN COURSE_CHAPTER cc ON ci.COURSE_ID =cc.COURSE_ID AND cc.DELETE_FLAG ='NOT_DELETE'
+                    LEFT JOIN COURSE_CLASSHOUR cch ON cc.ID=cch.CHAPTER_ID AND cch.DELETE_FLAG ='NOT_DELETE'
+                    WHERE ci.DELETE_FLAG ='NOT_DELETE'
+                    AND cch.ID IS NOT NULL
+                    AND cc.ID IS NOT NULL
+                    AND ci.COURSE_ID IS NOT NULL
+                    AND stu.ID IS NOT NULL
+                    --		AND csb.USER_ID='1948586504800468993'
+                )t1
+                LEFT JOIN (SELECT csb1.USER_ID,csb1.HOUR_ID FROM COURSE_STUDENT_BURIALPOINT csb1 WHERE csb1.DELETE_FLAG ='NOT_DELETE' AND csb1.FUNC_TYPE='1' AND csb1.TYPE='1' GROUP BY csb1.USER_ID,csb1.HOUR_ID) csb ON csb.HOUR_ID =t1.hourId AND csb.USER_ID=t1.userId
+                WHERE 1=1
+                --	AND t1.courseId='1954728193252552705'
+                GROUP BY t1.userId
+            )z1 ON z1.userId=z2.userId
+        )finalThree ON su.ID =finalThree.userId
+        WHERE su.DELETE_FLAG ='NOT_DELETE'
+        AND su.EDU_IDENTITY ='2'
+    </select>
+    <select id="getCourseListStudentAnalyse" resultType="java.util.Map">
+        SELECT
+               su.ID AS userId,
+               ci1.COURSE_ID AS courseId,
+               IFNULL(ci1.COURSE_NAME,'') AS courseName
+        FROM (SELECT su1.ID,su1.NAME,su1.GRADES_ID FROM SYS_USER su1 WHERE su1.DELETE_FLAG='NOT_DELETE' AND su1.EDU_IDENTITY='2')su
+        LEFT JOIN COURSE_OPEN cop ON su.GRADES_ID=cop.GRADES_ID AND cop.DELETE_FLAG='NOT_DELETE'
+        LEFT JOIN COURSE_INFO ci1 ON ci1.COURSE_ID =cop.COURSE_ID AND cop.DELETE_FLAG='NOT_DELETE'
+        WHERE ci1.DELETE_FLAG='NOT_DELETE'
+        GROUP BY su.ID,ci1.COURSE_ID,ci1.COURSE_NAME
+    </select>
+    <select id="getFinishRateListStudentAnalyse" resultType="java.util.Map">
+        SELECT
+            userCourse.userId AS userId,
+            userCourse.courseId AS courseId,
+            IFNULL(finalOne.finishRate,0) AS finishRate
+        FROM(
+            SELECT su.ID AS userId,ci1.COURSE_ID AS courseId, IFNULL(ci1.COURSE_NAME,'') AS courseName
+            FROM (SELECT su1.ID,su1.NAME,su1.GRADES_ID FROM SYS_USER su1 WHERE su1.DELETE_FLAG='NOT_DELETE' AND su1.EDU_IDENTITY='2')su
+            LEFT JOIN COURSE_OPEN cop ON su.GRADES_ID=cop.GRADES_ID AND cop.DELETE_FLAG='NOT_DELETE'
+            LEFT JOIN COURSE_INFO ci1 ON ci1.COURSE_ID =cop.COURSE_ID AND cop.DELETE_FLAG='NOT_DELETE'
+            WHERE ci1.DELETE_FLAG='NOT_DELETE'
+            <if test="userIdList !=null and userIdList.size()>0">
+                and su.ID in
+                <foreach collection=" userIdList" close=")" index="index" item="item" open="(" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="courseIdList !=null and courseIdList.size()>0">
+                and ci1.COURSE_ID in
+                <foreach collection=" courseIdList" close=")" index="index" item="item" open="(" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+            GROUP BY su.ID,ci1.COURSE_ID,ci1.COURSE_NAME
+        )userCourse
+        LEFT JOIN(
+            SELECT
+                IFNULL(z1.alreadyCount,0) AS alreadyCount,
+                IFNULL(z2.allCount,0) AS allCount,
+                z2.courseId AS courseId,
+                z2.userId AS userId,
+                CASE
+                when z2.allCount=0 or z2.allCount is NULL OR z1.alreadyCount=0 OR z1.alreadyCount IS null then 0
+                else TRUNC(z1.alreadyCount * 1.0 / z2.allCount, 2)
+                END AS finishRate
+            FROM (
+                --	#根据开课查询每个课程,每个人员,对应的课时总数量
+                SELECT
+                    t2.courseId,
+                    t2.userId,
+                    IFNULL(COUNT(t2.userId),0) AS allCount
+                FROM (
+                    SELECT
+                        -- cop.ID AS copId,
+                        -- cop.GRADES_ID AS gradesId,
+                        cch.ID AS hourId,
+                        cc.ID AS chapterId,
+                        ci.COURSE_ID AS courseId,
+                        stu.ID AS userId
+                    FROM COURSE_INFO ci
+                    LEFT JOIN COURSE_OPEN cop ON ci.COURSE_ID =cop.COURSE_ID AND cop.DELETE_FLAG='NOT_DELETE'
+                    LEFT JOIN SYS_USER stu ON stu.GRADES_ID =cop.GRADES_ID AND stu.DELETE_FLAG='NOT_DELETE'
+                    LEFT JOIN COURSE_CHAPTER cc ON ci.COURSE_ID =cc.COURSE_ID AND cc.DELETE_FLAG ='NOT_DELETE'
+                    LEFT JOIN COURSE_CLASSHOUR cch ON cc.ID=cch.CHAPTER_ID AND cch.DELETE_FLAG ='NOT_DELETE'
+                    WHERE ci.DELETE_FLAG ='NOT_DELETE'
+                    AND cch.ID IS NOT NULL
+                    AND cc.ID IS NOT NULL
+                    AND ci.COURSE_ID IS NOT NULL
+                    AND stu.ID IS NOT NULL
+                    <if test="userIdList !=null and userIdList.size()>0">
+                        and stu.ID in
+                        <foreach collection=" userIdList" close=")" index="index" item="item" open="(" separator=",">
+                            #{item}
+                        </foreach>
+                    </if>
+                    <if test="courseIdList !=null and courseIdList.size()>0">
+                        and ci.COURSE_ID in
+                        <foreach collection=" courseIdList" close=")" index="index" item="item" open="(" separator=",">
+                            #{item}
+                        </foreach>
+                    </if>
+                    GROUP BY cch.ID,cc.ID,ci.COURSE_ID,stu.ID
+                )t2
+                WHERE 1=1
+                --	AND t2.courseId='1954728193252552705'
+                GROUP BY t2.courseId,t2.userId
+            )z2
+            LEFT JOIN(
+                --	#根据开课查询每个课程,对应的课时的对应人员,其中已经看完的部分
+                SELECT
+                    --			t1.hourId AS hourId,
+                    --			t1.chapterId AS chapterId,
+                    --			t1.courseId AS courseId,
+                    --			t1.userId AS needWatchUserId,
+                    --			csb.USER_ID AS alreadyWatchUserId
+                    t1.courseId AS courseId,
+                    t1.userId AS userId,
+                    IFNULL(COUNT(csb.USER_ID AS hourId),0) AS alreadyCount
+                FROM (
+                    SELECT
+                        cop.ID AS copId,
+                        stu.ID AS userId,
+                        cch.ID AS hourId,
+                        cc.ID AS chapterId,
+                        ci.COURSE_ID AS courseId
+                    FROM COURSE_INFO ci
+                    LEFT JOIN COURSE_OPEN cop ON ci.COURSE_ID =cop.COURSE_ID AND cop.DELETE_FLAG='NOT_DELETE'
+                    LEFT JOIN SYS_USER stu ON stu.GRADES_ID =cop.GRADES_ID AND stu.DELETE_FLAG='NOT_DELETE'
+                    LEFT JOIN COURSE_CHAPTER cc ON ci.COURSE_ID =cc.COURSE_ID AND cc.DELETE_FLAG ='NOT_DELETE'
+                    LEFT JOIN COURSE_CLASSHOUR cch ON cc.ID=cch.CHAPTER_ID AND cch.DELETE_FLAG ='NOT_DELETE'
+                    WHERE ci.DELETE_FLAG ='NOT_DELETE'
+                    AND cch.ID IS NOT NULL
+                    AND cc.ID IS NOT NULL
+                    AND ci.COURSE_ID IS NOT NULL
+                    AND stu.ID IS NOT NULL
+                    --		AND csb.USER_ID='1948586504800468993'
+                    <if test="userIdList !=null and userIdList.size()>0">
+                        and stu.ID in
+                        <foreach collection=" userIdList" close=")" index="index" item="item" open="(" separator=",">
+                            #{item}
+                        </foreach>
+                    </if>
+                    <if test="courseIdList !=null and courseIdList.size()>0">
+                        and ci.COURSE_ID in
+                        <foreach collection=" courseIdList" close=")" index="index" item="item" open="(" separator=",">
+                            #{item}
+                        </foreach>
+                    </if>
+                )t1
+                JOIN (SELECT csb1.USER_ID,csb1.HOUR_ID FROM COURSE_STUDENT_BURIALPOINT csb1 WHERE csb1.DELETE_FLAG ='NOT_DELETE' AND csb1.FUNC_TYPE='1' AND csb1.TYPE='1' GROUP BY csb1.USER_ID,csb1.HOUR_ID) csb ON csb.HOUR_ID =t1.hourId AND csb.USER_ID=t1.userId
+                WHERE 1=1
+                --	AND t1.courseId='1954728193252552705'
+                GROUP BY t1.courseId,t1.userId
+            )z1 ON z1.userId=z2.userId AND z1.courseId=z2.courseId
+        )finalOne ON finalOne.userId=userCourse.userId AND finalOne.courseId=userCourse.courseId
+    </select>
+    <select id="getWorkCountListStudentAnalyse" resultType="java.util.Map">
+        SELECT
+            userCourse.userId AS userId,
+            userCourse.courseId AS courseId,
+            IFNULL(finalTwo.workRate,'0/0') AS workRate
+        FROM(
+            SELECT su.ID AS userId,ci1.COURSE_ID AS courseId, IFNULL(ci1.COURSE_NAME,'') AS courseName
+            FROM (SELECT su1.ID,su1.NAME,su1.GRADES_ID FROM SYS_USER su1 WHERE su1.DELETE_FLAG='NOT_DELETE' AND su1.EDU_IDENTITY='2')su
+            LEFT JOIN COURSE_OPEN cop ON su.GRADES_ID=cop.GRADES_ID AND cop.DELETE_FLAG='NOT_DELETE'
+            LEFT JOIN COURSE_INFO ci1 ON ci1.COURSE_ID =cop.COURSE_ID AND cop.DELETE_FLAG='NOT_DELETE'
+            WHERE ci1.DELETE_FLAG='NOT_DELETE'
+            <if test="userIdList !=null and userIdList.size()>0">
+                and su.ID in
+                <foreach collection=" userIdList" close=")" index="index" item="item" open="(" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="courseIdList !=null and courseIdList.size()>0">
+                and ci1.COURSE_ID in
+                <foreach collection=" courseIdList" close=")" index="index" item="item" open="(" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+            GROUP BY su.ID,ci1.COURSE_ID,ci1.COURSE_NAME
+        )userCourse
+        LEFT JOIN(
+            SELECT
+                tt1.courseId AS courseId,
+                tt1.userId AS userId,
+                tt1.alreadyWorkCount || '/' ||
+                tt1.allWorkount AS workRate
+            from(
+                SELECT
+                    z2.courseId AS courseId,
+                    z2.userId AS userId,
+                    IFNULL(count( CASE WHEN z2.tepaId IS NOT NULL THEN 1 ELSE NULL END ),0) AS alreadyWorkCount,
+                    IFNULL(count(z2.tepId),0) AS allWorkount
+                FROM (
+                    --	#根据开课查询每个课程,每个人员,对应的课时,下的卷子的总数量
+                    SELECT
+                        t2.hourId AS hourId,
+                        t2.courseId AS courseId,
+                        t2.userId AS userId,
+                        t2.tepId AS tepId,
+                        tepa.id AS tepaId
+                        --				IFNULL(COUNT(t2.userId),0) AS allCount
+                    FROM (
+                        SELECT
+                            --				cop.ID AS copId,
+                            stu.ID AS userId,
+                            cch.ID AS hourId,
+                            cc.ID AS chapterId,
+                            ci.COURSE_ID AS courseId,
+                            tep.id AS tepId
+                        FROM COURSE_INFO ci
+                        LEFT JOIN COURSE_OPEN cop ON ci.COURSE_ID =cop.COURSE_ID AND cop.DELETE_FLAG='NOT_DELETE'
+                        LEFT JOIN SYS_USER stu ON stu.GRADES_ID =cop.GRADES_ID AND stu.DELETE_FLAG='NOT_DELETE'
+                        LEFT JOIN COURSE_CHAPTER cc ON ci.COURSE_ID =cc.COURSE_ID AND cc.DELETE_FLAG ='NOT_DELETE'
+                        LEFT JOIN COURSE_CLASSHOUR cch ON cc.ID=cch.CHAPTER_ID AND cch.DELETE_FLAG ='NOT_DELETE'
+                        JOIN COURSE_RELATE cr ON cr.MAIN_ID =cch.ID AND cr.FUNC_TYPE ='4' AND cr.INFO_TYPE ='0' AND cr.CHAPTERHOUR_TYPE ='1' AND cr.DELETE_FLAG ='NOT_DELETE'
+                        JOIN "t_exam_paper" tep ON tep.id=cr.RELATE_ID AND tep.deleted='0'
+                        WHERE 1=1
+                        AND cch.ID IS NOT NULL
+                        AND cc.ID IS NOT NULL
+                        AND ci.COURSE_ID IS NOT NULL
+                        AND stu.ID IS NOT NULL
+                        <if test="userIdList !=null and userIdList.size()>0">
+                            and stu.ID in
+                            <foreach collection=" userIdList" close=")" index="index" item="item" open="(" separator=",">
+                                #{item}
+                            </foreach>
+                        </if>
+                        <if test="courseIdList !=null and courseIdList.size()>0">
+                            and ci.COURSE_ID in
+                            <foreach collection=" courseIdList" close=")" index="index" item="item" open="(" separator=",">
+                                #{item}
+                            </foreach>
+                        </if>
+                        GROUP BY stu.ID,cch.ID,cc.ID,ci.COURSE_ID,tep.id
+                    )t2
+                    --	#直接查询考试答卷表,查询该人员该试卷是否有对应答案
+                    LEFT JOIN t_exam_paper_answer tepa ON tepa.create_user=t2.userId AND tepa.exam_paper_id=t2.tepId
+                    WHERE 1=1
+                    --	AND t2.courseId='1954728193252552705'
+                    GROUP BY t2.hourId,t2.courseId,t2.userId,t2.tepId,tepa.id
+                )z2
+                GROUP BY z2.courseId,z2.userId
+            )tt1
+        )finalTwo ON finalTwo.userId=userCourse.userId AND finalTwo.courseId=userCourse.courseId
+    </select>
+    <select id="getPostCountListStudentAnalyse" resultType="java.util.Map">
+        SELECT
+            userCourse.userId AS userId,
+            userCourse.courseId AS courseId,
+            IFNULL(finalThree.postCount,0) AS postCount
+        FROM(
+            SELECT su.ID AS userId,ci1.COURSE_ID AS courseId, IFNULL(ci1.COURSE_NAME,'') AS courseName
+            FROM (SELECT su1.ID,su1.NAME,su1.GRADES_ID FROM SYS_USER su1 WHERE su1.DELETE_FLAG='NOT_DELETE' AND su1.EDU_IDENTITY='2')su
+            LEFT JOIN COURSE_OPEN cop ON su.GRADES_ID=cop.GRADES_ID AND cop.DELETE_FLAG='NOT_DELETE'
+            LEFT JOIN COURSE_INFO ci1 ON ci1.COURSE_ID =cop.COURSE_ID AND cop.DELETE_FLAG='NOT_DELETE'
+            WHERE ci1.DELETE_FLAG='NOT_DELETE'
+            <if test="userIdList !=null and userIdList.size()>0">
+                and su.ID in
+                <foreach collection=" userIdList" close=")" index="index" item="item" open="(" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="courseIdList !=null and courseIdList.size()>0">
+                and ci1.COURSE_ID in
+                <foreach collection=" courseIdList" close=")" index="index" item="item" open="(" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+            GROUP BY su.ID,ci1.COURSE_ID,ci1.COURSE_NAME
+        )userCourse
+        LEFT join(
+            SELECT
+                --	t1.userId AS userId,
+                --	t1.chapterId AS chapterId,
+                --	t1.courseId AS courseId,
+                --	t2.replyId AS replyId
+                t1.courseId AS courseId,
+                t1.userId AS userId,
+                IFNULL(count(t2.replyId),0) postCount
+            from(
+                SELECT
+                    stu.ID AS userId,
+                    cc.ID AS chapterId,
+                    ci.COURSE_ID AS courseId
+                FROM COURSE_INFO ci
+                LEFT JOIN COURSE_OPEN cop ON ci.COURSE_ID =cop.COURSE_ID AND cop.DELETE_FLAG='NOT_DELETE'
+                LEFT JOIN SYS_USER stu ON stu.GRADES_ID =cop.GRADES_ID AND stu.DELETE_FLAG='NOT_DELETE'
+                LEFT JOIN COURSE_CHAPTER cc ON ci.COURSE_ID =cc.COURSE_ID AND cc.DELETE_FLAG ='NOT_DELETE'
+                WHERE ci.DELETE_FLAG ='NOT_DELETE'
+                AND cc.ID IS NOT NULL
+                AND ci.COURSE_ID IS NOT NULL
+                AND stu.ID IS NOT NULL
+                <if test="userIdList !=null and userIdList.size()>0">
+                    and stu.ID in
+                    <foreach collection=" userIdList" close=")" index="index" item="item" open="(" separator=",">
+                        #{item}
+                    </foreach>
+                </if>
+                <if test="courseIdList !=null and courseIdList.size()>0">
+                    and ci.COURSE_ID in
+                    <foreach collection=" courseIdList" close=")" index="index" item="item" open="(" separator=",">
+                        #{item}
+                    </foreach>
+                </if>
+                GROUP BY stu.ID,cc.ID,ci.COURSE_ID
+            )t1
+            JOIN (
+                select
+                    reply.REPLY_ID AS replyId,
+                    reply.USER_ID AS userId,
+                    chapter.DISCUSSION_ID AS discussionId,
+                    chapter.CHAPTER_ID AS chapterId
+                from FORUM_POST_REPLY as reply
+                left join FORUM_CHAPTER_DISCUSSION as chapter on reply.POST_ID = chapter.POST_ID
+                where
+                reply.POST_TYPE = 3
+                <if test="userIdList !=null and userIdList.size()>0">
+                    and reply.USER_ID in
+                    <foreach collection=" userIdList" close=")" index="index" item="item" open="(" separator=",">
+                        #{item}
+                    </foreach>
+                </if>
+            )t2 ON t1.chapterId=t2.chapterId AND t1.userId=t2.userId
+            WHERE 1=1
+            GROUP BY t1.courseId,t1.userId
+        )finalThree ON finalThree.userId=userCourse.userId AND finalThree.courseId=userCourse.courseId
+    </select>
+    <select id="getAnswerCountListStudentAnalyse" resultType="java.util.Map">
+        SELECT
+            userCourse.userId AS userId,
+            userCourse.courseId AS courseId,
+            IFNULL(finalFour.answerCount,0) AS answerCount
+        FROM(
+            SELECT su.ID AS userId,ci1.COURSE_ID AS courseId, IFNULL(ci1.COURSE_NAME,'') AS courseName
+            FROM (SELECT su1.ID,su1.NAME,su1.GRADES_ID FROM SYS_USER su1 WHERE su1.DELETE_FLAG='NOT_DELETE' AND su1.EDU_IDENTITY='2')su
+            LEFT JOIN COURSE_OPEN cop ON su.GRADES_ID=cop.GRADES_ID AND cop.DELETE_FLAG='NOT_DELETE'
+            LEFT JOIN COURSE_INFO ci1 ON ci1.COURSE_ID =cop.COURSE_ID AND cop.DELETE_FLAG='NOT_DELETE'
+            WHERE ci1.DELETE_FLAG='NOT_DELETE'
+            <if test="userIdList !=null and userIdList.size()>0">
+                and su.ID in
+                <foreach collection=" userIdList" close=")" index="index" item="item" open="(" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="courseIdList !=null and courseIdList.size()>0">
+                and ci1.COURSE_ID in
+                <foreach collection=" courseIdList" close=")" index="index" item="item" open="(" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+            GROUP BY su.ID,ci1.COURSE_ID,ci1.COURSE_NAME
+        )userCourse
+        LEFT JOIN(
+            SELECT
+                --		t1.hourId AS hourId,
+                --		t1.chapterId AS chapterId,
+                --		t1.courseId AS courseId,
+                --		t2.userId AS userId,
+                --		t2.cqaId AS cqaId
+                t1.userId AS userId,
+                t1.courseId AS courseId,
+                COUNT(t2.cqaId) answerCount
+            FROM (
+                SELECT
+--                     cop.ID AS copId,
+                    stu.ID AS userId,
+                    cch.ID AS hourId,
+                    cc.ID AS chapterId,
+                    ci.COURSE_ID AS courseId
+                FROM COURSE_INFO ci
+                LEFT JOIN COURSE_OPEN cop ON ci.COURSE_ID =cop.COURSE_ID AND cop.DELETE_FLAG='NOT_DELETE'
+                LEFT JOIN SYS_USER stu ON stu.GRADES_ID =cop.GRADES_ID AND stu.DELETE_FLAG='NOT_DELETE'
+                LEFT JOIN COURSE_CHAPTER cc ON ci.COURSE_ID =cc.COURSE_ID AND cc.DELETE_FLAG ='NOT_DELETE'
+                LEFT JOIN COURSE_CLASSHOUR cch ON cc.ID=cch.CHAPTER_ID AND cch.DELETE_FLAG ='NOT_DELETE'
+                WHERE ci.DELETE_FLAG ='NOT_DELETE'
+                AND cch.ID IS NOT NULL
+                AND cc.ID IS NOT NULL
+                AND ci.COURSE_ID IS NOT NULL
+                AND stu.ID IS NOT NULL
+                --		AND csb.USER_ID='1948586504800468993'
+                <if test="userIdList !=null and userIdList.size()>0">
+                    and stu.ID in
+                    <foreach collection=" userIdList" close=")" index="index" item="item" open="(" separator=",">
+                        #{item}
+                    </foreach>
+                </if>
+                GROUP BY cch.ID,cc.ID,ci.COURSE_ID,stu.ID
+            )t1
+            LEFT JOIN(
+                SELECT
+                    cqa.ID AS cqaId,
+                    cr.ID AS crId,
+                    cr.MAIN_ID AS hourId,
+                    cqa.USER_ID AS userId
+                FROM (SELECT cqa1.* FROM COURSE_QUESTION_ANSWER cqa1 WHERE cqa1.DELETE_FLAG ='NOT_DELETE' AND cqa1.PID IS null) cqa
+                JOIN COURSE_RELATE cr ON cqa.ID=cr.RELATE_ID  AND cr.DELETE_FLAG ='NOT_DELETE' and cr.CHAPTERHOUR_TYPE ='1' AND cr.INFO_TYPE ='1' AND FUNC_TYPE ='7'
+                WHERE 1=1
+            )t2 ON t1.hourId=t2.hourId AND t1.userId=t2.userId
+            GROUP BY t1.userId,t1.courseId
+        )finalFour ON finalFour.userId=userCourse.userId AND finalFour.courseId=userCourse.courseId
+    </select>
+</mapper>

+ 49 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/StudyBehaviorProgressService.java

@@ -0,0 +1,49 @@
+package vip.xiaonuo.disk.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+import java.util.Map;
+
+/**
+ * 统计-学习行为分析控制器service
+ *
+ * @author honorfire
+ * @date  2025/06/18 14:16
+ */
+public interface StudyBehaviorProgressService {
+
+    /**
+     * 学习行为分析-课程访问统计
+     */
+    Map<String,Object> getCourseVisitProgress(Map param);
+
+    /**
+     * 学习行为分析-用户登录统计
+     */
+    Map<String,Object> getUserLoginProgress(Map param);
+
+    /**
+     * 学习行为分析-观看时长统计
+     */
+    Map<String,Object> getWatchDurationProgress(Map param);
+
+    /**
+     *  学习行为分析-用户登录时段分布
+     */
+    Page<Map<String,Object>> getLoginFrameDistribution(Map param);
+
+    /**
+     *  学习行为分析-课程访问热度排行
+     */
+    Page<Map<String,Object>> getCourseVisitHeatRank(Map param);
+
+    /**
+     *  学习行为分析-学院课程详细统计
+     */
+    Page<Map<String,Object>> getCollegeCourseDetailProgress(Map param);
+
+    /**
+     *  学习行为分析-学员维度分析
+     */
+    Page<Map<String,Object>> getStudentAnalyse(Map param);
+}

+ 275 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/impl/StudyBehaviorProgressServiceImpl.java

@@ -0,0 +1,275 @@
+package vip.xiaonuo.disk.service.impl;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.poi.ss.formula.functions.T;
+import org.springframework.stereotype.Service;
+import vip.xiaonuo.common.page.CommonPageRequest;
+import vip.xiaonuo.disk.mapper.StudyBehaviorProgressMapper;
+import vip.xiaonuo.disk.service.StudyBehaviorProgressService;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Service
+public class StudyBehaviorProgressServiceImpl implements StudyBehaviorProgressService {
+
+    @Resource
+    private StudyBehaviorProgressMapper studyBehaviorProgressMapper;
+
+    /**
+     * 学习行为分析-课程访问统计
+     */
+    @Override
+    public Map<String,Object> getCourseVisitProgress(Map param)
+    {
+        Map result=new HashMap();
+        //总课程数
+        String allCourseCount=studyBehaviorProgressMapper.getAllCourseCount(param);
+        //活跃课程数
+        String activeCourseCount=studyBehaviorProgressMapper.getActiveCourseCount(param);
+        //课程访问数
+        String courseVisitCount=studyBehaviorProgressMapper.getCourseVisitCount(param);
+
+        result.put("allCourseCount",allCourseCount);
+        result.put("activeCourseCount",activeCourseCount);
+        result.put("courseVisitCount",courseVisitCount);
+        return result;
+    }
+
+    /**
+     * 学习行为分析-用户登录统计
+     */
+    @Override
+    public Map<String,Object> getUserLoginProgress(Map param)
+    {
+        Map result=new HashMap();
+        //总登录数
+        String allLoginCount=studyBehaviorProgressMapper.getAllLoginCount(param);
+        //独立用户数
+        String userCount=studyBehaviorProgressMapper.getUserCount(param);
+        //人均登录次数
+        String avgLoginCount=studyBehaviorProgressMapper.getAvgLoginCount(param);
+
+        result.put("allLoginCount",allLoginCount);
+        result.put("userCount",userCount);
+        result.put("avgLoginCount",avgLoginCount);
+        return result;
+    }
+
+    /**
+     * 学习行为分析-观看时长统计
+     */
+    @Override
+    public Map<String,Object> getWatchDurationProgress(Map param){
+        Map result=new HashMap();
+        //总观看时长
+        String userAllStayTime=studyBehaviorProgressMapper.getUserAllStayTime(param);
+        //平均观看时长
+        String avgStayTime=studyBehaviorProgressMapper.getAvgStayTime(param);
+        //峰值观看人数
+        String peakWatchUserCount=studyBehaviorProgressMapper.getPeakWatchUserCount(param);
+
+        result.put("userAllStayTime",userAllStayTime);
+        result.put("avgStayTime",avgStayTime);
+        result.put("peakWatchUserCount",peakWatchUserCount);
+        return result;
+    }
+
+    /**
+     *  学习行为分析-用户登录时段分布
+     */
+    @Override
+    public Page<Map<String,Object>> getLoginFrameDistribution(Map param)
+    {
+        return studyBehaviorProgressMapper.getLoginFrameDistribution(param, CommonPageRequest.defaultPage());
+    }
+
+    /**
+     *  学习行为分析-课程访问热度排行
+     */
+    @Override
+    public Page<Map<String,Object>> getCourseVisitHeatRank(Map param)
+    {
+        Page<Object> objectPage = CommonPageRequest.defaultPage();
+//        Page<Object> objectPage = new Page<>(1, 8);
+        return studyBehaviorProgressMapper.getCourseVisitHeatRank(param, objectPage);
+    }
+
+    /**
+     *  学习行为分析-学院课程详细统计
+     */
+    @Override
+    public Page<Map<String,Object>> getCollegeCourseDetailProgress(Map param)
+    {
+        //为了考虑效率问题,改成不通过大sql一起查回,通过后台组装数据
+        //1.获取院系基准信息,同时带上课程章节信息
+        Page<Map<String,Object>> page=studyBehaviorProgressMapper.getCollegeList(param, CommonPageRequest.defaultPage());
+        List<Map<String,Object>> collegeList=page.getRecords();
+        //获取院系id集合
+        List<String> collegeIdList = collegeList.stream().map(map -> (String) map.get("collegeId")).collect(Collectors.toList());
+        param.put("collegeIdList",collegeIdList);
+        //2.获取课程数量
+        List<Map<String,Object>> courseCountList=studyBehaviorProgressMapper.getCourseCountListCollegeCourse(param);
+        //3.获取总访问量
+        List<Map<String,Object>> watchCountList=studyBehaviorProgressMapper.getWatchCountListCollegeCourse(param);
+        //4.获取平均完成值
+        List<Map<String,Object>> completeRateList=studyBehaviorProgressMapper.getCompleteRateListCollegeCourse(param);
+        //5.获取作业提交率
+        List<Map<String,Object>> homeworkFinishRate=studyBehaviorProgressMapper.getHomeworkFinishRateCollegeCourse(param);
+
+        //数据匹配
+        //采取倒叙安全删除方法,提升效率
+        for (Map<String,Object> college : collegeList)
+        {
+            //匹配2.获取课程数量
+            for (int i = courseCountList.size() - 1; i >= 0; i--)
+            {
+                Map<String,Object> courseCount = courseCountList.get(i);
+                if (courseCount == null || courseCount.get("collegeId") == null) continue;
+
+                if (college.get("collegeId").equals(courseCount.get("collegeId")))
+                {
+                    college.put("courseCount",courseCount.get("courseCount"));
+                    courseCountList.remove(i);          // 从原列表删除(安全操作)
+                }
+            }
+            //匹配3.获取总访问量
+            for (int i = watchCountList.size() - 1; i >= 0; i--)
+            {
+                Map<String,Object> watchCount = watchCountList.get(i);
+                if (watchCount == null || watchCount.get("collegeId") == null) continue;
+                if (college.get("collegeId").equals(watchCount.get("collegeId")))
+                {
+                    college.put("watchCount",watchCount.get("watchCount"));
+                    watchCountList.remove(i);          // 从原列表删除(安全操作)
+                }
+            }
+            //匹配4.获取平均完成值
+            for (int i = completeRateList.size() - 1; i >= 0; i--)
+            {
+                Map<String,Object> completeRate = completeRateList.get(i);
+                if (completeRate == null || completeRate.get("collegeId") == null) continue;
+
+                if (college.get("collegeId").equals(completeRate.get("collegeId")))
+                {
+                    college.put("completeRate",completeRate.get("completeRate"));
+                    completeRateList.remove(i);          // 从原列表删除(安全操作)
+                }
+            }
+            //匹配5.获取作业提交率
+            for (int i = homeworkFinishRate.size() - 1; i >= 0; i--)
+            {
+                Map<String,Object> homeworkFinishRateMap = homeworkFinishRate.get(i);
+                if (homeworkFinishRateMap == null || homeworkFinishRateMap.get("collegeId") == null) continue;
+
+                if (college.get("collegeId").equals(homeworkFinishRateMap.get("collegeId")))
+                {
+                    college.put("homeworkFinishRate",homeworkFinishRateMap.get("homeworkFinishRate"));
+                    homeworkFinishRate.remove(i);          // 从原列表删除(安全操作)
+                }
+            }
+        }
+        return page;
+    }
+
+    /**
+     *  学习行为分析-学员维度分析
+     */
+    @Override
+    public Page<Map<String,Object>> getStudentAnalyse(Map param)
+    {
+        //避免数据量大查询缓慢,采取后台组装
+        //1.查询学生相关信息列表
+        Page<Map<String,Object>> page=studyBehaviorProgressMapper.getUserList(param, CommonPageRequest.defaultPage());
+        List<Map<String,Object>> userList=page.getRecords();
+        //用户id集合
+        List<String> userIdList = userList.stream().map(map -> (String) map.get("userId")).collect(Collectors.toList());
+        param.put("userIdList",userIdList);
+        //2.获取这些学生的汇总课程列表
+        List<Map<String,Object>> courseList=studyBehaviorProgressMapper.getCourseListStudentAnalyse(param);
+        //课程id集合
+        List<String> courseIdList = courseList.stream().map(map -> (String) map.get("courseId")).collect(Collectors.toList());
+        param.put("courseIdList",courseIdList);
+        //2-1.获取课程对应学习进度
+        List<Map<String,Object>> finishRateList=studyBehaviorProgressMapper.getFinishRateListStudentAnalyse(param);
+        //2-2.获取作业完成情况
+        List<Map<String,Object>> workCountList=studyBehaviorProgressMapper.getWorkCountListStudentAnalyse(param);
+        //2-3.获取讨论参与数
+        List<Map<String,Object>> postCountList=studyBehaviorProgressMapper.getPostCountListStudentAnalyse(param);
+        //2-4.获取提问次数
+        List<Map<String,Object>> answerCountList=studyBehaviorProgressMapper.getAnswerCountListStudentAnalyse(param);
+
+
+        //给所有学生的课程信息,匹配对应关联数据
+        for (Map<String,Object> course : courseList)
+        {
+            //匹配2-1.获取课程对应学习进度
+            for (int i = finishRateList.size() - 1; i >= 0; i--)
+            {
+                Map<String,Object> finishRate = finishRateList.get(i);
+                if (finishRate == null || finishRate.get("courseId") == null) continue;
+                if (course.get("courseId").equals(finishRate.get("courseId"))&&course.get("userId").equals(finishRate.get("userId")))
+                {
+                    course.put("finishRate",finishRate.get("finishRate"));
+                    finishRateList.remove(i);          // 从原列表删除(安全操作)
+                }
+            }
+            //匹配2-2.获取作业完成情况
+            for (int i = workCountList.size() - 1; i >= 0; i--)
+            {
+                Map<String,Object> workCount = workCountList.get(i);
+                if (workCount == null || workCount.get("courseId") == null) continue;
+                if (course.get("courseId").equals(workCount.get("courseId"))&&course.get("userId").equals(workCount.get("userId")))
+                {
+                    course.put("workRate",workCount.get("workRate"));
+                    workCountList.remove(i);          // 从原列表删除(安全操作)
+                }
+            }
+            //匹配2-3.获取讨论参与数
+            for (int i = postCountList.size() - 1; i >= 0; i--)
+            {
+                Map<String,Object> postCount = postCountList.get(i);
+                if (postCount == null || postCount.get("courseId") == null) continue;
+                if (course.get("courseId").equals(postCount.get("courseId"))&& course.get("userId").equals(postCount.get("userId")))
+                {
+                    course.put("postCount",postCount.get("postCount"));
+                    postCountList.remove(i);          // 从原列表删除(安全操作)
+                }
+            }
+            //匹配2-4.获取提问次数
+            for (int i = answerCountList.size() - 1; i >= 0; i--)
+            {
+                Map<String,Object> answerCount = answerCountList.get(i);
+                if (answerCount == null || answerCount.get("courseId") == null) continue;
+                if (course.get("courseId").equals(answerCount.get("courseId"))&& course.get("userId").equals(answerCount.get("userId")))
+                {
+                    course.put("answerCount",answerCount.get("answerCount"));
+                    answerCountList.remove(i);          // 从原列表删除(安全操作)
+                }
+            }
+        }
+        //将学生匹配各自对应课程信息
+        for (Map<String,Object> user : userList)
+        {
+            List<Map<String,Object>> userCourseList=new ArrayList<>();
+            for (int i = courseList.size() - 1; i >= 0; i--)
+            {
+                Map<String,Object> course = courseList.get(i);
+                if (course == null || course.get("userId") == null) continue;
+                if (user.get("userId").equals(course.get("userId")))
+                {
+                    userCourseList.add(course);
+                    courseList.remove(i);          // 从原列表删除(安全操作)
+                }
+            }
+            user.put("courseList",userCourseList);
+        }
+
+        return page;
+    }
+
+}

+ 8 - 8
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/impl/VideoAnalysisProgressServiceImpl.java

@@ -199,7 +199,7 @@ public class VideoAnalysisProgressServiceImpl implements VideoAnalysisProgressSe
                 if (user.get("userId").equals(postCount.get("userId")))
                 {
                     user.put("postCount",postCount.get("postCount"));
-                    postCountList.remove(i);          // 从原列表
+                    postCountList.remove(i);          // 从原列表删除(安全操作)
                 }
             }
             //匹配8.获取回帖数
@@ -211,7 +211,7 @@ public class VideoAnalysisProgressServiceImpl implements VideoAnalysisProgressSe
                 if (user.get("userId").equals(replyCount.get("userId")))
                 {
                     user.put("replyCount",replyCount.get("replyCount"));
-                    replyCountList.remove(i);          // 从原列表
+                    replyCountList.remove(i);          // 从原列表删除(安全操作)
                 }
             }
 
@@ -263,7 +263,7 @@ public class VideoAnalysisProgressServiceImpl implements VideoAnalysisProgressSe
                 if (hour.get("hourId").equals(replyCount.get("hourId")))
                 {
                     hour.put("allStayTime",replyCount.get("allStayTime"));
-                    allStayTimeList.remove(i);          // 从原列表
+                    allStayTimeList.remove(i);          // 从原列表删除(安全操作)
                 }
             }
             //匹配3.获取观看人数
@@ -275,7 +275,7 @@ public class VideoAnalysisProgressServiceImpl implements VideoAnalysisProgressSe
                 if (hour.get("hourId").equals(watchUserCount.get("hourId")))
                 {
                     hour.put("watchUserCount",watchUserCount.get("watchUserCount"));
-                    watchUserCountList.remove(i);          // 从原列表
+                    watchUserCountList.remove(i);          // 从原列表删除(安全操作)
                 }
             }
             //匹配4.获取完成人数
@@ -287,7 +287,7 @@ public class VideoAnalysisProgressServiceImpl implements VideoAnalysisProgressSe
                 if (hour.get("hourId").equals(completeWatchUserCount.get("hourId")))
                 {
                     hour.put("completeWatchUserCount",completeWatchUserCount.get("completeWatchUserCount"));
-                    completeWatchUserCountList.remove(i);          // 从原列表
+                    completeWatchUserCountList.remove(i);          // 从原列表删除(安全操作)
                 }
             }
             //匹配5.获取完成率
@@ -298,7 +298,7 @@ public class VideoAnalysisProgressServiceImpl implements VideoAnalysisProgressSe
                 if (hour.get("hourId").equals(completeRate.get("hourId")))
                 {
                     hour.put("completeRate",completeRate.get("completeRate"));
-                    completeRateList.remove(i);          // 从原列表
+                    completeRateList.remove(i);          // 从原列表删除(安全操作)
                 }
             }
             //匹配6.获取平均观看时长
@@ -309,7 +309,7 @@ public class VideoAnalysisProgressServiceImpl implements VideoAnalysisProgressSe
                 if (hour.get("hourId").equals(avgStayTime.get("hourId")))
                 {
                     hour.put("avgStayTime",avgStayTime.get("avgStayTime"));
-                    avgStayTimeList.remove(i);          // 从原列表
+                    avgStayTimeList.remove(i);          // 从原列表删除(安全操作)
                 }
             }
             //匹配7.获取跳出率
@@ -319,7 +319,7 @@ public class VideoAnalysisProgressServiceImpl implements VideoAnalysisProgressSe
                 if (hour.get("hourId").equals(jumpOutRate.get("hourId")))
                 {
                     hour.put("jumpOutRate",jumpOutRate.get("jumpOutRate"));
-                    jumpOutRateList.remove(i);          // 从原列表
+                    jumpOutRateList.remove(i);          // 从原列表删除(安全操作)
                 }
             }
             //匹配8.获取下载数(笔记数)