个人学习记录
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
package org.xyzh.api.study.record;
|
||||
|
||||
import org.xyzh.common.core.domain.ResultDomain;
|
||||
import org.xyzh.common.core.page.PageRequest;
|
||||
import org.xyzh.common.dto.study.TbLearningRecord;
|
||||
import org.xyzh.common.vo.LearningStatisticsDetailVO;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
@@ -129,4 +131,23 @@ public interface LearningRecordService {
|
||||
* @since 2025-10-30
|
||||
*/
|
||||
ResultDomain<Map<String, Object>> getStudyRecordsRankings();
|
||||
|
||||
/**
|
||||
* @description 获取时间范围内每天的学习时长
|
||||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @return ResultDomain<Map<String, Object>> 用户学习记录统计
|
||||
* @author yslg
|
||||
* @since 2025-10-30
|
||||
*/
|
||||
ResultDomain<Map<String, Object>> getUserRecordRange(String startTime, String endTime);
|
||||
|
||||
/**
|
||||
* @description 获取用户学习记录统计
|
||||
* @param learningRecord 学习记录
|
||||
* @return ResultDomain<Map<String, Object>> 用户学习记录统计
|
||||
* @author yslg
|
||||
* @since 2025-10-30
|
||||
*/
|
||||
ResultDomain<LearningStatisticsDetailVO> getUserRecordRangePage(PageRequest<TbLearningRecord> learningRecord);
|
||||
}
|
||||
|
||||
@@ -6,10 +6,9 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.xyzh.api.study.record.LearningRecordService;
|
||||
import org.xyzh.common.core.domain.ResultDomain;
|
||||
import org.xyzh.common.core.page.PageRequest;
|
||||
import org.xyzh.common.dto.study.TbLearningRecord;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.xyzh.common.vo.LearningStatisticsDetailVO;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -92,4 +91,28 @@ public class LearningRecordController {
|
||||
public ResultDomain<Map<String, Object>> getStudyRecordsRankings() {
|
||||
return learningRecordService.getStudyRecordsRankings();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户学习记录统计
|
||||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @return 用户学习记录统计
|
||||
*/
|
||||
@GetMapping("/user/record/range")
|
||||
public ResultDomain<Map<String, Object>> getUserRecordRange(@RequestParam("startTime") String startTime, @RequestParam("endTime") String endTime) {
|
||||
return learningRecordService.getUserRecordRange(startTime, endTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户学习记录统计
|
||||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @return 用户学习记录统计
|
||||
*/
|
||||
@PostMapping("/user/record/range")
|
||||
public ResultDomain<LearningStatisticsDetailVO> getUserRecordRangePage(@RequestBody PageRequest<TbLearningRecord> learningRecord) {
|
||||
return learningRecordService.getUserRecordRangePage(learningRecord);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.apache.ibatis.annotations.Param;
|
||||
import org.xyzh.common.core.page.PageParam;
|
||||
import org.xyzh.common.dto.study.TbLearningRecord;
|
||||
import org.xyzh.common.dto.study.TbLearningTask;
|
||||
import org.xyzh.common.vo.LearningStatisticsDetailVO;
|
||||
import org.xyzh.common.vo.UserDeptRoleVO;
|
||||
|
||||
import java.util.List;
|
||||
@@ -138,7 +139,7 @@ public interface LearningRecordMapper extends BaseMapper<TbLearningRecord> {
|
||||
* @author yslg
|
||||
* @since 2025-10-15
|
||||
*/
|
||||
List<TbLearningRecord> selectLearningRecordsPage(@Param("filter") TbLearningRecord filter, @Param("pageParam") PageParam pageParam);
|
||||
List<LearningStatisticsDetailVO> selectLearningRecordsPage(@Param("filter") TbLearningRecord filter, @Param("pageParam") PageParam pageParam);
|
||||
|
||||
/**
|
||||
* @description 统计学习记录总数
|
||||
@@ -195,4 +196,16 @@ public interface LearningRecordMapper extends BaseMapper<TbLearningRecord> {
|
||||
* @since 2025-10-30
|
||||
*/
|
||||
List<Map<String, Object>> getWeeklyTaskCompletionRanking(@Param("userDeptRoles") List<UserDeptRoleVO> userDeptRoles);
|
||||
|
||||
/**
|
||||
* @description 获取用户时间范围内每天的学习时长
|
||||
* @param userId 用户ID
|
||||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @return List<Map<String, Object>> 每天学习时长数据
|
||||
* @author yslg
|
||||
* @since 2025-11-17
|
||||
*/
|
||||
List<Map<String, Object>> getUserDailyDuration(@Param("userId") String userId, @Param("startTime") String startTime, @Param("endTime") String endTime);
|
||||
|
||||
}
|
||||
|
||||
@@ -13,11 +13,15 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.xyzh.common.core.domain.ResultDomain;
|
||||
import org.xyzh.common.core.enums.TaskItemType;
|
||||
import org.xyzh.common.core.page.PageRequest;
|
||||
import org.xyzh.common.core.page.PageParam;
|
||||
import org.xyzh.common.core.page.PageDomain;
|
||||
import org.xyzh.common.dto.study.TbLearningRecord;
|
||||
import org.xyzh.common.dto.study.TbLearningTask;
|
||||
import org.xyzh.common.dto.study.TbTaskItem;
|
||||
import org.xyzh.common.dto.study.TbTaskUser;
|
||||
import org.xyzh.common.dto.user.TbSysUser;
|
||||
import org.xyzh.common.vo.LearningStatisticsDetailVO;
|
||||
import org.xyzh.common.vo.TaskItemVO;
|
||||
import org.xyzh.common.vo.UserDeptRoleVO;
|
||||
import org.xyzh.api.study.record.LearningRecordService;
|
||||
@@ -328,4 +332,71 @@ public class SCLearningRecordServiceImpl implements LearningRecordService {
|
||||
}
|
||||
return resultDomain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<Map<String, Object>> getUserRecordRange(String startTime, String endTime) {
|
||||
ResultDomain<Map<String, Object>> resultDomain = new ResultDomain<>();
|
||||
try {
|
||||
// 获取当前用户ID
|
||||
String userId = LoginUtil.getCurrentUserId();
|
||||
if (userId == null) {
|
||||
resultDomain.fail("用户未登录");
|
||||
return resultDomain;
|
||||
}
|
||||
|
||||
// 查询时间范围内每天的学习时长
|
||||
List<Map<String, Object>> dailyData = learningRecordMapper.getUserDailyDuration(userId, startTime, endTime);
|
||||
|
||||
Map<String, Object> chartData = new HashMap<>();
|
||||
chartData.put("dailyDuration", dailyData);
|
||||
|
||||
resultDomain.success("获取学习时长统计成功", chartData);
|
||||
} catch (Exception e) {
|
||||
logger.error("获取学习时长统计失败", e);
|
||||
resultDomain.fail("获取学习时长统计失败:" + e.getMessage());
|
||||
}
|
||||
return resultDomain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<LearningStatisticsDetailVO> getUserRecordRangePage(PageRequest<TbLearningRecord> pageRequest) {
|
||||
ResultDomain<LearningStatisticsDetailVO> resultDomain = new ResultDomain<>();
|
||||
try {
|
||||
// 获取当前用户ID
|
||||
String userId = LoginUtil.getCurrentUserId();
|
||||
if (userId == null) {
|
||||
resultDomain.fail("用户未登录");
|
||||
return resultDomain;
|
||||
}
|
||||
|
||||
TbLearningRecord filter = pageRequest.getFilter();
|
||||
if (filter == null) {
|
||||
filter = new TbLearningRecord();
|
||||
}
|
||||
|
||||
PageParam pageParam = pageRequest.getPageParam();
|
||||
if (pageParam == null) {
|
||||
pageParam = new PageParam();
|
||||
}
|
||||
// 设置当前用户ID用于筛选
|
||||
filter.setUserID(userId);
|
||||
|
||||
// 查询分页数据
|
||||
List<LearningStatisticsDetailVO> list = learningRecordMapper.selectLearningRecordsPage(filter, pageParam);
|
||||
long total = learningRecordMapper.countLearningRecords(filter);
|
||||
|
||||
// 构建分页结果
|
||||
PageDomain<LearningStatisticsDetailVO> pageDomain = new PageDomain<>();
|
||||
pageDomain.setDataList(list);
|
||||
pageParam.setTotalElements((int) total);
|
||||
pageParam.setTotalPages((int) Math.ceil((double) total / pageParam.getPageSize()));
|
||||
pageDomain.setPageParam(pageParam);
|
||||
|
||||
resultDomain.success("查询学习记录成功", pageDomain);
|
||||
} catch (Exception e) {
|
||||
logger.error("查询学习记录失败", e);
|
||||
resultDomain.fail("查询学习记录失败:" + e.getMessage());
|
||||
}
|
||||
return resultDomain;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,6 +156,9 @@
|
||||
<if test="updateTime != null">
|
||||
update_time = #{updateTime},
|
||||
</if>
|
||||
<if test="startTime != null and endTime != null">
|
||||
create_time BETWEEN #{startTime} AND #{endTime}
|
||||
</if>
|
||||
</set>
|
||||
WHERE id = #{id}
|
||||
</update>
|
||||
@@ -187,21 +190,87 @@
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<!-- 分页查询学习记录 -->
|
||||
<select id="selectLearningRecordsPage" resultMap="BaseResultMap">
|
||||
<!-- LearningStatisticsDetailVO结果映射 -->
|
||||
<resultMap id="StatisticsDetailResultMap" type="org.xyzh.common.vo.LearningStatisticsDetailVO">
|
||||
<result column="stat_date" property="statDate" jdbcType="TIMESTAMP"/>
|
||||
<result column="resource_type" property="resourceType" jdbcType="INTEGER"/>
|
||||
<result column="resource_type_name" property="resourceTypeName" jdbcType="VARCHAR"/>
|
||||
<result column="resource_id" property="resourceID" jdbcType="VARCHAR"/>
|
||||
<result column="resource_title" property="resourceTitle" jdbcType="VARCHAR"/>
|
||||
<result column="course_id" property="courseID" jdbcType="VARCHAR"/>
|
||||
<result column="course_name" property="courseName" jdbcType="VARCHAR"/>
|
||||
<result column="chapter_id" property="chapterID" jdbcType="VARCHAR"/>
|
||||
<result column="chapter_name" property="chapterName" jdbcType="VARCHAR"/>
|
||||
<result column="total_duration" property="totalDuration" jdbcType="INTEGER"/>
|
||||
<result column="total_duration_formatted" property="totalDurationFormatted" jdbcType="VARCHAR"/>
|
||||
<result column="learn_count" property="learnCount" jdbcType="INTEGER"/>
|
||||
<result column="is_complete" property="isComplete" jdbcType="BOOLEAN"/>
|
||||
<result column="complete_time" property="completeTime" jdbcType="TIMESTAMP"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 分页查询学习记录详情 -->
|
||||
<select id="selectLearningRecordsPage" resultMap="StatisticsDetailResultMap">
|
||||
SELECT
|
||||
<include refid="Base_Column_List" />
|
||||
FROM tb_learning_record
|
||||
<include refid="Where_Clause" />
|
||||
ORDER BY last_learn_time DESC, create_time DESC
|
||||
COALESCE(lr.last_learn_time, lr.update_time, lr.create_time) AS stat_date,
|
||||
lr.resource_type AS resource_type,
|
||||
CASE lr.resource_type
|
||||
WHEN 1 THEN '文章'
|
||||
WHEN 2 THEN '课程'
|
||||
WHEN 3 THEN '章节'
|
||||
ELSE '未知'
|
||||
END AS resource_type_name,
|
||||
lr.resource_id AS resource_id,
|
||||
CASE
|
||||
WHEN lr.resource_type = 1 THEN COALESCE(r.title, CONCAT('文章-', lr.resource_id))
|
||||
WHEN lr.resource_type = 2 THEN COALESCE(c.name, CONCAT('课程-', lr.course_id))
|
||||
WHEN lr.resource_type = 3 THEN COALESCE(ch.name, CONCAT('章节-', lr.chapter_id))
|
||||
ELSE '未知资源'
|
||||
END AS resource_title,
|
||||
COALESCE(lr.course_id, '') AS course_id,
|
||||
COALESCE(c.name, '') AS course_name,
|
||||
COALESCE(lr.chapter_id, '') AS chapter_id,
|
||||
COALESCE(ch.name, '') AS chapter_name,
|
||||
COALESCE(lr.duration, 0) AS total_duration,
|
||||
'' AS total_duration_formatted,
|
||||
1 AS learn_count,
|
||||
COALESCE(lr.is_complete, 0) AS is_complete,
|
||||
lr.complete_time AS complete_time
|
||||
FROM tb_learning_record lr
|
||||
LEFT JOIN tb_resource r ON lr.resource_type = 1 AND lr.resource_id = r.resource_id
|
||||
LEFT JOIN tb_course c ON lr.resource_type = 2 AND lr.course_id = c.id
|
||||
LEFT JOIN tb_course_chapter ch ON lr.resource_type = 3 AND lr.chapter_id = ch.id
|
||||
<where>
|
||||
<if test="filter.userID != null and filter.userID != ''">
|
||||
AND lr.user_id = #{filter.userID}
|
||||
</if>
|
||||
<if test="filter.resourceType != null">
|
||||
AND lr.resource_type = #{filter.resourceType}
|
||||
</if>
|
||||
<if test="filter.isComplete != null">
|
||||
AND lr.is_complete = #{filter.isComplete}
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY lr.last_learn_time DESC, lr.create_time DESC
|
||||
LIMIT #{pageParam.pageSize} OFFSET #{pageParam.offset}
|
||||
</select>
|
||||
|
||||
<!-- 统计学习记录总数 -->
|
||||
<select id="countLearningRecords" resultType="long">
|
||||
SELECT COUNT(1)
|
||||
FROM tb_learning_record
|
||||
<include refid="Where_Clause" />
|
||||
FROM tb_learning_record lr
|
||||
<where>
|
||||
<if test="filter != null">
|
||||
<if test="filter.userID != null and filter.userID != ''">
|
||||
AND lr.user_id = #{filter.userID}
|
||||
</if>
|
||||
<if test="filter.resourceType != null">
|
||||
AND lr.resource_type = #{filter.resourceType}
|
||||
</if>
|
||||
<if test="filter.isComplete != null">
|
||||
AND lr.is_complete = #{filter.isComplete}
|
||||
</if>
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<!-- 获取本周课程和文章的总学习时长统计 -->
|
||||
@@ -362,4 +431,30 @@
|
||||
<select id="getTaskStaticByTag">
|
||||
|
||||
</select>
|
||||
|
||||
<!-- 获取用户时间范围内每天的学习时长 -->
|
||||
<select id="getUserDailyDuration" resultType="java.util.Map">
|
||||
WITH RECURSIVE date_range AS (
|
||||
-- 生成起始日期
|
||||
SELECT DATE(#{startTime}) AS date
|
||||
UNION ALL
|
||||
-- 递归生成后续日期
|
||||
SELECT DATE_ADD(date, INTERVAL 1 DAY)
|
||||
FROM date_range
|
||||
WHERE date < DATE(#{endTime})
|
||||
)
|
||||
SELECT
|
||||
dr.date AS date,
|
||||
DATE_FORMAT(dr.date, '%Y-%m-%d') AS statDate,
|
||||
COALESCE(SUM(lr.duration), 0) AS duration,
|
||||
COALESCE(SUM(lr.duration), 0) AS totalDuration,
|
||||
COUNT(lr.id) AS count
|
||||
FROM date_range dr
|
||||
LEFT JOIN tb_learning_record lr
|
||||
ON DATE(lr.update_time) = dr.date
|
||||
AND lr.user_id = #{userId}
|
||||
GROUP BY dr.date
|
||||
ORDER BY dr.date ASC
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
Reference in New Issue
Block a user