diff --git a/schoolNewsServ/api/api-study/src/main/java/org/xyzh/api/study/record/LearningRecordService.java b/schoolNewsServ/api/api-study/src/main/java/org/xyzh/api/study/record/LearningRecordService.java index d6c2612..5731b00 100644 --- a/schoolNewsServ/api/api-study/src/main/java/org/xyzh/api/study/record/LearningRecordService.java +++ b/schoolNewsServ/api/api-study/src/main/java/org/xyzh/api/study/record/LearningRecordService.java @@ -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> getStudyRecordsRankings(); + + /** + * @description 获取时间范围内每天的学习时长 + * @param startTime 开始时间 + * @param endTime 结束时间 + * @return ResultDomain> 用户学习记录统计 + * @author yslg + * @since 2025-10-30 + */ + ResultDomain> getUserRecordRange(String startTime, String endTime); + + /** + * @description 获取用户学习记录统计 + * @param learningRecord 学习记录 + * @return ResultDomain> 用户学习记录统计 + * @author yslg + * @since 2025-10-30 + */ + ResultDomain getUserRecordRangePage(PageRequest learningRecord); } diff --git a/schoolNewsServ/study/src/main/java/org/xyzh/study/controller/LearningRecordController.java b/schoolNewsServ/study/src/main/java/org/xyzh/study/controller/LearningRecordController.java index e279863..692bade 100644 --- a/schoolNewsServ/study/src/main/java/org/xyzh/study/controller/LearningRecordController.java +++ b/schoolNewsServ/study/src/main/java/org/xyzh/study/controller/LearningRecordController.java @@ -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> getStudyRecordsRankings() { return learningRecordService.getStudyRecordsRankings(); } + + /** + * 获取用户学习记录统计 + * @param startTime 开始时间 + * @param endTime 结束时间 + * @return 用户学习记录统计 + */ + @GetMapping("/user/record/range") + public ResultDomain> 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 getUserRecordRangePage(@RequestBody PageRequest learningRecord) { + return learningRecordService.getUserRecordRangePage(learningRecord); + } + + } diff --git a/schoolNewsServ/study/src/main/java/org/xyzh/study/mapper/LearningRecordMapper.java b/schoolNewsServ/study/src/main/java/org/xyzh/study/mapper/LearningRecordMapper.java index 81082b4..5d92561 100644 --- a/schoolNewsServ/study/src/main/java/org/xyzh/study/mapper/LearningRecordMapper.java +++ b/schoolNewsServ/study/src/main/java/org/xyzh/study/mapper/LearningRecordMapper.java @@ -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 { * @author yslg * @since 2025-10-15 */ - List selectLearningRecordsPage(@Param("filter") TbLearningRecord filter, @Param("pageParam") PageParam pageParam); + List selectLearningRecordsPage(@Param("filter") TbLearningRecord filter, @Param("pageParam") PageParam pageParam); /** * @description 统计学习记录总数 @@ -195,4 +196,16 @@ public interface LearningRecordMapper extends BaseMapper { * @since 2025-10-30 */ List> getWeeklyTaskCompletionRanking(@Param("userDeptRoles") List userDeptRoles); + + /** + * @description 获取用户时间范围内每天的学习时长 + * @param userId 用户ID + * @param startTime 开始时间 + * @param endTime 结束时间 + * @return List> 每天学习时长数据 + * @author yslg + * @since 2025-11-17 + */ + List> getUserDailyDuration(@Param("userId") String userId, @Param("startTime") String startTime, @Param("endTime") String endTime); + } diff --git a/schoolNewsServ/study/src/main/java/org/xyzh/study/service/impl/SCLearningRecordServiceImpl.java b/schoolNewsServ/study/src/main/java/org/xyzh/study/service/impl/SCLearningRecordServiceImpl.java index 39043ce..442d76c 100644 --- a/schoolNewsServ/study/src/main/java/org/xyzh/study/service/impl/SCLearningRecordServiceImpl.java +++ b/schoolNewsServ/study/src/main/java/org/xyzh/study/service/impl/SCLearningRecordServiceImpl.java @@ -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> getUserRecordRange(String startTime, String endTime) { + ResultDomain> resultDomain = new ResultDomain<>(); + try { + // 获取当前用户ID + String userId = LoginUtil.getCurrentUserId(); + if (userId == null) { + resultDomain.fail("用户未登录"); + return resultDomain; + } + + // 查询时间范围内每天的学习时长 + List> dailyData = learningRecordMapper.getUserDailyDuration(userId, startTime, endTime); + + Map 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 getUserRecordRangePage(PageRequest pageRequest) { + ResultDomain 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 list = learningRecordMapper.selectLearningRecordsPage(filter, pageParam); + long total = learningRecordMapper.countLearningRecords(filter); + + // 构建分页结果 + PageDomain 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; + } } diff --git a/schoolNewsServ/study/src/main/resources/mapper/LearningRecordMapper.xml b/schoolNewsServ/study/src/main/resources/mapper/LearningRecordMapper.xml index 76f1a08..732b510 100644 --- a/schoolNewsServ/study/src/main/resources/mapper/LearningRecordMapper.xml +++ b/schoolNewsServ/study/src/main/resources/mapper/LearningRecordMapper.xml @@ -156,6 +156,9 @@ update_time = #{updateTime}, + + create_time BETWEEN #{startTime} AND #{endTime} + WHERE id = #{id} @@ -187,21 +190,87 @@ - - SELECT - - FROM tb_learning_record - - 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 + + + AND lr.user_id = #{filter.userID} + + + AND lr.resource_type = #{filter.resourceType} + + + AND lr.is_complete = #{filter.isComplete} + + + ORDER BY lr.last_learn_time DESC, lr.create_time DESC LIMIT #{pageParam.pageSize} OFFSET #{pageParam.offset} @@ -362,4 +431,30 @@ + + + + diff --git a/schoolNewsWeb/src/apis/study/learning-record.ts b/schoolNewsWeb/src/apis/study/learning-record.ts index cd5ac52..1a8a3c4 100644 --- a/schoolNewsWeb/src/apis/study/learning-record.ts +++ b/schoolNewsWeb/src/apis/study/learning-record.ts @@ -92,4 +92,25 @@ export const learningRecordApi = { const response = await api.get('/study/records/statistics/rankings'); return response.data; }, + + /** + * 获取用户时间范围内的学习时长统计(用于图表) + * @param startTime 开始时间 + * @param endTime 结束时间 + * @returns Promise> 每天学习时长数据 + */ + async getUserRecordRange(startTime: string, endTime: string): Promise> { + const response = await api.get(`/study/records/user/record/range?startTime=${startTime}&endTime=${endTime}`); + return response.data; + }, + + /** + * 分页查询用户学习记录详情 + * @param pageRequest 分页请求参数 + * @returns Promise> 分页记录数据 + */ + async getUserRecordRangePage(pageRequest: any): Promise> { + const response = await api.post('/study/records/user/record/range', pageRequest); + return response.data; + }, }; diff --git a/schoolNewsWeb/src/views/user/user-center/LearningRecordsView.vue b/schoolNewsWeb/src/views/user/user-center/LearningRecordsView.vue index 1d15921..4aa59bf 100644 --- a/schoolNewsWeb/src/views/user/user-center/LearningRecordsView.vue +++ b/schoolNewsWeb/src/views/user/user-center/LearningRecordsView.vue @@ -7,26 +7,46 @@ end-placeholder="结束日期" @change="handleDateChange" /> -
-
-
- -
-
-

{{ record.title }}

-

{{ record.description }}

-
- {{ record.typeName }} - 学习时长:{{ record.duration }}分钟 - {{ record.learnDate }} -
-
-
-
- {{ record.progress }}% -
-
-
+ +
+

学习时长统计

+
+
+ + +
+

学习记录明细

+ + + + + + + + + + + + + + + +
@@ -34,18 +54,203 @@