serv\web-学习历史修改

This commit is contained in:
2025-10-27 13:42:34 +08:00
parent 74880b429e
commit e50de4a277
31 changed files with 3997 additions and 64 deletions

View File

@@ -221,11 +221,11 @@ import {
} from '@element-plus/icons-vue';
import { ArticleShowView } from '@/views/article';
import { courseApi } from '@/apis/study';
import { learningRecordApi } from '@/apis/study';
import { learningRecordApi, learningHistoryApi } from '@/apis/study';
import { resourceApi } from '@/apis/resource';
import { useStore } from 'vuex';
import { FILE_DOWNLOAD_URL } from '@/config';
import type { CourseVO, LearningRecord } from '@/types';
import type { CourseVO, LearningRecord, TbLearningHistory } from '@/types';
interface Props {
courseId: string;
@@ -269,6 +269,11 @@ const previousNodeKey = ref<string | null>(null);
const totalRichTextVideos = ref(0);
const completedRichTextVideos = ref<Set<number>>(new Set());
// 学习历史记录
const learningHistory = ref<TbLearningHistory | null>(null);
const historyStartTime = ref<number>(0);
const historyTimer = ref<number | null>(null);
// 当前节点
const currentNode = computed(() => {
if (!courseVO.value || !courseVO.value.courseChapters) return null;
@@ -346,9 +351,18 @@ watch(() => [props.chapterIndex, props.nodeIndex], () => {
loadNodeContent();
}, { immediate: true });
watch(currentNode, () => {
watch(currentNode, async () => {
// 保存上一个节点的学习历史记录
if (learningHistory.value) {
await saveHistoryRecord();
stopHistoryTimer();
}
if (currentNode.value) {
loadNodeContent();
// 为新节点创建学习历史记录
await createHistoryRecord();
}
});
@@ -359,6 +373,12 @@ onMounted(() => {
onBeforeUnmount(() => {
stopLearningTimer();
saveLearningProgress();
// 保存学习历史记录
if (learningHistory.value) {
saveHistoryRecord();
}
stopHistoryTimer();
});
// 加载课程
@@ -807,9 +827,97 @@ function toggleSidebar() {
}
// 返回
// ==================== 学习历史记录功能 ====================
// 创建学习历史记录
async function createHistoryRecord() {
if (!userInfo.value?.id || !courseVO.value || !currentNode.value) return;
try {
const chapterVO = courseVO.value.courseChapters[currentChapterIndex.value];
const chapter = chapterVO?.chapter;
const node = currentNode.value;
const res = await learningHistoryApi.recordCourseLearn(
userInfo.value.id,
props.courseId,
chapter?.chapterID,
node.nodeID,
0 // 初始时长为0
);
if (res.success && res.data) {
learningHistory.value = res.data;
console.log('✅ 课程学习历史记录创建成功:', learningHistory.value);
// 开始计时
startHistoryTimer();
}
} catch (error) {
console.error('❌ 创建课程学习历史记录失败:', error);
}
}
// 开始学习历史计时
function startHistoryTimer() {
historyStartTime.value = Date.now();
// 每30秒保存一次学习历史
historyTimer.value = window.setInterval(() => {
saveHistoryRecord();
}, 30000); // 30秒
}
// 停止学习历史计时
function stopHistoryTimer() {
if (historyTimer.value) {
clearInterval(historyTimer.value);
historyTimer.value = null;
}
}
// 保存学习历史记录
async function saveHistoryRecord() {
if (!userInfo.value?.id || !learningHistory.value) return;
const currentTime = Date.now();
const duration = Math.floor((currentTime - historyStartTime.value) / 1000); // 秒
// 如果时长太短小于1秒不保存
if (duration < 1) return;
try {
const updatedHistory: TbLearningHistory = {
...learningHistory.value,
duration: (learningHistory.value.duration || 0) + duration,
endTime: new Date().toISOString()
};
// 调用API更新学习历史
const res = await learningHistoryApi.recordLearningHistory(updatedHistory);
if (res.success && res.data) {
learningHistory.value = res.data;
console.log(`💾 课程学习历史已保存 - 累计时长: ${learningHistory.value.duration}秒 - 节点: ${currentNode.value?.name}`);
}
// 重置开始时间
historyStartTime.value = currentTime;
} catch (error) {
console.error('❌ 保存课程学习历史失败:', error);
}
}
function handleBack() {
stopLearningTimer();
saveLearningProgress();
// 保存学习历史记录
if (learningHistory.value) {
saveHistoryRecord();
}
stopHistoryTimer();
emit('back');
}
</script>