统一引导提示的持久化控制,补充学习进度入口与模块资源,避免用户返回页面时重复触发提示。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
141 lines
4.3 KiB
Vue
141 lines
4.3 KiB
Vue
<script lang="ts" setup>
|
||
import { useRouter } from 'vue-router'
|
||
import { Video } from '@/components'
|
||
import { ImgButton } from '@/components/Button'
|
||
import { StarRating } from '@/components/Rating'
|
||
import { IMAGE_PATHS, getBackgroundImage, getPublicPath } from '@/utils'
|
||
import { Overlay } from '@/components/Overlay'
|
||
import { ref } from 'vue'
|
||
import { GuideSteps, GuideStepsItem } from '@/components/Guide'
|
||
import { useFilmStore } from '@/stores/modules/film'
|
||
const router = useRouter()
|
||
const filmStore = useFilmStore()
|
||
const guideKey = 'film-practice-video-rating'
|
||
const showGuide = ref(!filmStore.guideShown[guideKey])
|
||
|
||
if (showGuide.value) {
|
||
filmStore.markGuideShown(guideKey)
|
||
}
|
||
|
||
const props = defineProps({
|
||
path: {
|
||
type: String,
|
||
required: true
|
||
}
|
||
})
|
||
|
||
interface EvaluationItem {
|
||
/** 标题 */
|
||
title: string
|
||
/** 描述 */
|
||
description: string
|
||
/** 评分 */
|
||
score: number
|
||
}
|
||
|
||
/** 评估项目列表 */
|
||
const evaluationItems = ref<EvaluationItem[]>([
|
||
{
|
||
title: '主题与内容',
|
||
description: '主题明确聚焦"身边美好",内容真实、有感染力,能让观众感受到日常闪光',
|
||
score: 3
|
||
},
|
||
{
|
||
title: '拍摄技巧',
|
||
description: '运镜自然、光线运用合理、画面清晰饱和度、能辅助主题表达(至少1种运镜+1种光线)',
|
||
score: 4
|
||
},
|
||
{
|
||
title: '剪辑与包装',
|
||
description: '素材拼接流畅,调色/滤镜适配、字幕清晰、音乐不盖人声、整体风格统一',
|
||
score: 5
|
||
},
|
||
{
|
||
title: '创意与独特性',
|
||
description: '视角新颖、有个人观察,或用特殊细节/情节展现“美好”,避免平淡复刻',
|
||
score: 4
|
||
},
|
||
{
|
||
title: '综合感受',
|
||
description: '视角新颖、有个人观察,或用特殊细节/情节展现“美好”避免平淡复刻',
|
||
score: 5
|
||
}
|
||
])
|
||
|
||
/** 保存弹窗 */
|
||
const showModal = ref<boolean>(false)
|
||
|
||
/** 返回上一页 */
|
||
const handleBack = (): void => {
|
||
router.back()
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<div class="relative h-full">
|
||
<ImgButton
|
||
class="absolute right-0 top-0 z-50"
|
||
:image="IMAGE_PATHS.COMPONENTS.BACK"
|
||
@click="handleBack"
|
||
/>
|
||
<ImgButton
|
||
class="absolute right-0 bottom-10 z-50 btn-1"
|
||
image="vlog/practice/评分"
|
||
@click="showModal = true"
|
||
/>
|
||
<Video
|
||
:src="getPublicPath(decodeURIComponent(props.path))"
|
||
:volume="1"
|
||
:muted="false"
|
||
:controls="true"
|
||
:loop="false"
|
||
/>
|
||
|
||
<!-- 保存图片弹窗 -->
|
||
<Overlay :visible="showModal" :clickable="false">
|
||
<div
|
||
class="w-[1795px] h-[987px] bg-no-repeat bg-cover p-10 pt-[80px]"
|
||
:style="{ backgroundImage: getBackgroundImage('vlog/practice/评分底板') }"
|
||
>
|
||
<ImgButton
|
||
class="absolute -top-8 -right-14 z-10"
|
||
:image="IMAGE_PATHS.COMPONENTS.CLOSE"
|
||
@click="showModal = false"
|
||
/>
|
||
|
||
<div class="relative h-full overflow-y-scroll px-8">
|
||
<div
|
||
class="w-full bg-no-repeat bg-cover bg-left py-44"
|
||
:style="{ backgroundImage: getBackgroundImage('vlog/practice/滑动表内文字') }"
|
||
>
|
||
<div class="pl-10 space-y-16">
|
||
<div
|
||
v-for="(item, index) in evaluationItems"
|
||
:key="index"
|
||
class="relative w-full h-[182px] bg-no-repeat bg-cover px-12 py-3 flex justify-between"
|
||
:style="{ backgroundImage: getBackgroundImage('vlog/practice/评分条') }"
|
||
>
|
||
<div class="pr-8 space-y-10">
|
||
<h4 class="text-3xl font-bold text-white mb-3">
|
||
{{ `0${index + 1}` }} {{ item.title }}
|
||
</h4>
|
||
<p class="text-3xl text-gray-800 font-bold leading-relaxed">
|
||
{{ item.description }}
|
||
</p>
|
||
</div>
|
||
<StarRating class="absolute -bottom-5 right-10" :score="item.score" size="lg" />
|
||
</div>
|
||
<div class="w-full flex justify-center">
|
||
<ImgButton image="vlog/practice/保存" @click="showModal = false" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</Overlay>
|
||
<GuideSteps :visible="showGuide" :highlight-selector="'.btn-1'" position-offset-y="60%">
|
||
<GuideStepsItem>点击这里可以给作品评分噢~</GuideStepsItem>
|
||
</GuideSteps>
|
||
</div>
|
||
</template>
|