接口修正、成就修正、学习记录修正

This commit is contained in:
2025-11-03 17:12:40 +08:00
parent 35aee59178
commit b95fff224b
28 changed files with 730 additions and 302 deletions

View File

@@ -134,6 +134,7 @@ const emit = defineEmits<{
'close': [];
'edit': [];
'back': [];
'videos-completed': []; // 所有视频播放完成事件
}>();
const router = useRouter();
@@ -324,17 +325,41 @@ async function loadLearningRecord(resourceID: string) {
}
}
// 生成学习记录的taskId当没有真实taskId时
function generateTaskId(resourceID: string, userID: string): string {
// 使用简短格式确保不超过50字符SA_{resourceID的hash}_{userID的hash}
// SA = Self-study Article
const resourceHash = hashString(resourceID).substring(0, 16);
const userHash = hashString(userID).substring(0, 16);
return `SA_${resourceHash}_${userHash}`; // 长度3 + 16 + 1 + 16 = 36字符
}
// 简单的字符串哈希函数
function hashString(str: string): string {
let hash = 0;
for (let i = 0; i < str.length; i++) {
const char = str.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32bit integer
}
// 转换为16进制字符串并确保长度一致
return Math.abs(hash).toString(16).padStart(8, '0') + str.substring(0, 8).replace(/[^a-zA-Z0-9]/g, '');
}
// 创建学习记录
async function createLearningRecord(resourceID: string) {
if (!userInfo.value?.id) return;
try {
const taskId = route.query.taskId as string;
// 如果没有taskId生成一个自学任务ID
const effectiveTaskId = taskId || generateTaskId(resourceID, userInfo.value.id!);
const res = await learningRecordApi.createRecord({
userID: userInfo.value.id,
resourceType: 1, // 资源类型:文章
resourceID: resourceID,
taskID: taskId || undefined,
taskID: effectiveTaskId,
duration: 0,
progress: 0,
isComplete: false
@@ -419,9 +444,12 @@ async function markArticleComplete() {
if (!userInfo.value?.id || !learningRecord.value) return;
try {
// 使用learningRecord中保存的taskID可能是真实任务ID或生成的自学ID
const taskId = learningRecord.value.taskID || (route.query.taskId as string);
await learningRecordApi.markComplete({
id: learningRecord.value.id,
taskID: route.query.taskId as string,
taskID: taskId,
userID: userInfo.value.id,
resourceType: 1,
resourceID: route.query.articleId as string,
@@ -497,8 +525,15 @@ function handleVideoEnded(videoIndex: number) {
if (!hasVideoCompleted.value) {
hasVideoCompleted.value = true;
ElMessage.success(`所有视频播放完成 (${totalVideos.value}/${totalVideos.value})`);
// 立即保存学习进度并标记完成
saveLearningProgress();
// 如果作为课程子组件使用没有learningRecord通知父组件
if (!learningRecord.value) {
console.log(' ArticleShow作为子组件使用通知父组件视频播放完成');
emit('videos-completed');
} else {
// 独立使用时,保存学习进度
saveLearningProgress();
}
}
} else {
ElMessage.info(`视频 ${videoIndex + 1} 播放完成 (${completedCount}/${totalVideos.value})`);
@@ -537,7 +572,7 @@ function startHistoryTimer() {
// 每30秒保存一次学习历史
historyTimer.value = window.setInterval(() => {
saveHistoryRecord();
}, 30000); // 30秒
}, 10000); // 30秒
}
// 停止学习历史计时