feat: 完善视频学习进度缓存
完善新手导航和三大创作模块的视频完成缓存、未完成提示与学习进度计算,确保进度按实际学习资源完成情况更新。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
1f8723aabd
commit
6f289959be
63 files changed
+3139
-1126
No files matched your search
@@ -1,19 +1,37 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue'
|
||||
import { computed, onBeforeUnmount, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { getBackgroundImage, IMAGE_PATHS } from '@/utils'
|
||||
import { ImgButton } from '@/components/Button'
|
||||
import PracticeRatingModal, {
|
||||
type PracticeRatingItem,
|
||||
} from '@/components/PracticeRatingModal'
|
||||
import { useInterviewStore } from '@/stores/modules/interview'
|
||||
|
||||
const router = useRouter()
|
||||
const store = useInterviewStore()
|
||||
|
||||
type PracticeRatingScores = Record<string, number>
|
||||
|
||||
const applyScores = (
|
||||
items: PracticeRatingItem[],
|
||||
scores: PracticeRatingScores,
|
||||
): PracticeRatingItem[] =>
|
||||
items.map((item) => ({
|
||||
...item,
|
||||
score: scores[item.title] ?? item.score,
|
||||
}))
|
||||
|
||||
const toScores = (items: PracticeRatingItem[]): PracticeRatingScores =>
|
||||
Object.fromEntries(items.map((item) => [item.title, item.score]))
|
||||
|
||||
/** 笔记内容 */
|
||||
const noteContent = ref<string>('')
|
||||
const noteContent = ref<string>(store.practiceNoteContent)
|
||||
|
||||
/** 保存弹窗 */
|
||||
const showModal = ref<boolean>(false)
|
||||
const showSuccess = ref<boolean>(false)
|
||||
let successTimer: number | undefined
|
||||
|
||||
/** 返回上一页 */
|
||||
const handleBack = (): void => {
|
||||
@@ -23,7 +41,7 @@ const handleBack = (): void => {
|
||||
const disabled = computed<boolean>(() => noteContent.value.trim() === '')
|
||||
|
||||
/** 评估项目列表 */
|
||||
const evaluationItems = ref<PracticeRatingItem[]>([
|
||||
const defaultEvaluationItems: PracticeRatingItem[] = [
|
||||
{
|
||||
title: '人物表达',
|
||||
description: '能清晰介绍人物身份、特点或故事,让观众认识人物',
|
||||
@@ -54,11 +72,28 @@ const evaluationItems = ref<PracticeRatingItem[]>([
|
||||
description: '作品完整,有真实感与感染力,具备观看吸引力',
|
||||
score: 5,
|
||||
},
|
||||
])
|
||||
]
|
||||
|
||||
const evaluationItems = ref<PracticeRatingItem[]>(
|
||||
applyScores(defaultEvaluationItems, store.practiceSelfEvaluationScores),
|
||||
)
|
||||
|
||||
const handleSave = (): void => {
|
||||
console.log('保存笔记')
|
||||
handleBack()
|
||||
store.setPracticeNoteContent(noteContent.value)
|
||||
showSuccess.value = true
|
||||
window.clearTimeout(successTimer)
|
||||
successTimer = window.setTimeout(() => {
|
||||
showSuccess.value = false
|
||||
}, 1500)
|
||||
}
|
||||
|
||||
const handleSaveEvaluation = (items: PracticeRatingItem[]): void => {
|
||||
store.setPracticeSelfEvaluationScores(toScores(items))
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.clearTimeout(successTimer)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -81,6 +116,13 @@ const handleSave = (): void => {
|
||||
placeholder="点击输入创作笔记"
|
||||
></textarea>
|
||||
|
||||
<div
|
||||
v-if="showSuccess"
|
||||
class="absolute left-1/2 top-1/2 z-[100] -translate-x-1/2 -translate-y-1/2 rounded-2xl bg-black/70 px-16 py-8 text-5xl font-bold text-white"
|
||||
>
|
||||
提交成功
|
||||
</div>
|
||||
|
||||
<div class="absolute bottom-24 left-1/2 -translate-x-1/2 flex gap-60">
|
||||
<ImgButton
|
||||
image="vlog/practice/保存"
|
||||
@@ -95,10 +137,11 @@ const handleSave = (): void => {
|
||||
|
||||
<PracticeRatingModal
|
||||
:visible="showModal"
|
||||
:items="evaluationItems"
|
||||
v-model:items="evaluationItems"
|
||||
background-image="interview/practice/人物访谈短片创作-作品评分表"
|
||||
top-tip="评分时要关注6个维度哦~分别是人物表达、素材拍摄、镜头语言、剪辑结构、音画关系、综合观感每个维度满分5分,能打1-5分,记得对照作品表现来打分呀~"
|
||||
bottom-tip="己评价的实战作品,从封面入口就能直接看到具体评分!打了多少分一目了然,不用再点进详情页翻找啦~"
|
||||
@save="handleSaveEvaluation"
|
||||
@close="showModal = false"
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user