feat: 完善模块引导与学习进度体验
统一引导提示的持久化控制,补充学习进度入口与模块资源,避免用户返回页面时重复触发提示。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
fc9633f371
commit
6f8252472f
114 files changed
+2758
-1798
No files matched your search
@@ -188,18 +188,6 @@ const prevPhone = () => {
|
||||
<button @click="disableAllMenuItems" class="debug-btn">禁用全部</button>
|
||||
<button @click="toggleMenuItem('bluetooth-remote')" class="debug-btn">切换蓝牙遥控器</button>
|
||||
</div> -->
|
||||
|
||||
<!-- 引导步骤 -->
|
||||
<GuideSteps
|
||||
:steps="steps"
|
||||
:highlight-padding="12"
|
||||
:highlight-radius="20"
|
||||
position-offset-y="85%"
|
||||
>
|
||||
<GuideStepsItem>
|
||||
<img src="@/assets/images/equipment/设备准备引导1.png" alt="" />
|
||||
</GuideStepsItem>
|
||||
</GuideSteps>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="less" scoped>
|
||||
|
||||
@@ -10,17 +10,19 @@ const playing = ref(false)
|
||||
const showStepNavigation = ref(false)
|
||||
const currentVideoIndex = ref(0)
|
||||
|
||||
const navigationSteps = [
|
||||
const navigationSteps = ref([
|
||||
{
|
||||
id: 'q1-shoot-material',
|
||||
label: '中期拍摄',
|
||||
content: '素材怎么拍',
|
||||
videoUrl: getPublicPath('video/interview/on-site/ftmk_sczmp_batch.mp4'),
|
||||
type: 'shooting' as const
|
||||
},
|
||||
{
|
||||
id: 'q1-required-shots',
|
||||
label: '中期拍摄',
|
||||
content: '必拍镜头有哪些',
|
||||
videoUrl: getPublicPath('video/interview/on-site/ftmk_bpjtynx_batch.mp4'),
|
||||
type: 'shooting' as const
|
||||
},
|
||||
{
|
||||
@@ -35,16 +37,9 @@ const navigationSteps = [
|
||||
content: '特写镜头的作用',
|
||||
type: 'shooting' as const
|
||||
}
|
||||
]
|
||||
])
|
||||
|
||||
const videoList = [
|
||||
getPublicPath('video/on-site/dygmk_mmps_batch.mp4'),
|
||||
getPublicPath('video/on-site/dygmk_hgydjt_batch.mp4'),
|
||||
getPublicPath('video/on-site/dygmk_jzxjj_batch.mp4'),
|
||||
getPublicPath('video/on-site/dygmk_czsjx_batch.mp4')
|
||||
]
|
||||
|
||||
const currentVideo = computed(() => videoList[currentVideoIndex.value])
|
||||
const currentVideo = computed(() => navigationSteps.value[currentVideoIndex.value].videoUrl)
|
||||
|
||||
const back = () => {
|
||||
router.back()
|
||||
@@ -63,7 +58,7 @@ const handleStepNavigationClose = () => {
|
||||
}
|
||||
|
||||
const handleEnded = () => {
|
||||
if (currentVideoIndex.value >= videoList.length - 1) {
|
||||
if (currentVideoIndex.value >= navigationSteps.value.length - 1) {
|
||||
playing.value = false
|
||||
return
|
||||
}
|
||||
|
||||
@@ -156,9 +156,12 @@ const capturePhoto = async () => {
|
||||
<div class="w-full h-full">
|
||||
<div
|
||||
class="relative w-full h-full bg-cover bg-center bg-no-repeat shooting-bg"
|
||||
:style="{ backgroundImage: getBackgroundImage('shooting/取景地模糊背景.png') }"
|
||||
:style="{ backgroundImage: getBackgroundImage('interview/shooting/操场-模糊.png') }"
|
||||
>
|
||||
<ImgButton image="shooting/标题-取景地a.png" class="title-button absolute left-0" />
|
||||
<ImgButton
|
||||
image="interview/shooting/操场-侧边标题.png"
|
||||
class="title-button absolute left-0"
|
||||
/>
|
||||
<ImgButton image="shooting/返回.png" class="back-button absolute right-0" @click="back" />
|
||||
|
||||
<StartOverlay v-if="!start" @start="start = true" />
|
||||
@@ -186,7 +189,7 @@ const capturePhoto = async () => {
|
||||
'cursor-grabbing': isDragging
|
||||
}"
|
||||
:style="{ transform: getTransform() }"
|
||||
src="@/assets/images/shooting/取景大图.png"
|
||||
src="@/assets/images/interview/shooting/操场-清晰.png"
|
||||
alt=""
|
||||
crossorigin="anonymous"
|
||||
@mousedown="startDrag"
|
||||
|
||||
@@ -101,12 +101,15 @@ const handleComplete = () => {
|
||||
class="relative w-full h-full bg-cover bg-center bg-no-repeat shooting-bg"
|
||||
:style="{
|
||||
backgroundImage: start
|
||||
? getBackgroundImage('shooting/取景大图.png')
|
||||
: getBackgroundImage('shooting/取景地模糊背景.png')
|
||||
? getBackgroundImage('interview/shooting/教学楼-清晰.png')
|
||||
: getBackgroundImage('interview/shooting/教学楼-模糊.png')
|
||||
}"
|
||||
>
|
||||
<!-- 标题 -->
|
||||
<ImgButton image="shooting/标题-取景地b.png" class="title-button absolute left-0" />
|
||||
<ImgButton
|
||||
image="interview/shooting/教学楼-侧边标题.png"
|
||||
class="title-button absolute left-0"
|
||||
/>
|
||||
|
||||
<!-- 返回按钮 -->
|
||||
<ImgButton
|
||||
@@ -123,7 +126,7 @@ const handleComplete = () => {
|
||||
<img
|
||||
ref="backgroundImage"
|
||||
class="absolute inset-0 w-full h-full object-cover pointer-events-none opacity-0"
|
||||
src="@/assets/images/shooting/取景大图.png"
|
||||
src="@/assets/images/interview/shooting/教学楼-清晰.png"
|
||||
alt=""
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
|
||||
@@ -4,10 +4,11 @@ import { useRouter } from 'vue-router'
|
||||
import { GuideSteps, GuideStepsItem } from '@/components/Guide'
|
||||
import { Overlay } from '@/components/Overlay'
|
||||
import { ImgButton } from '@/components/Button'
|
||||
import { getBackgroundImage, IMAGE_PATHS } from '@/utils'
|
||||
import { getBackgroundImage, getPublicPath, IMAGE_PATHS } from '@/utils'
|
||||
import shootingtitle from '@/assets/images/shooting/标题-实地取景.png'
|
||||
import videoSrc from '/video/xinshou_jiuzhonggoutufa.mp4'
|
||||
import KnowledgeCard from '@/components/KnowledgeCard/KnowledgeCard.vue'
|
||||
import { useInterviewStore } from '@/stores/modules/interview'
|
||||
|
||||
type Btn = {
|
||||
key: string
|
||||
@@ -18,6 +19,13 @@ type Btn = {
|
||||
}
|
||||
|
||||
const router = useRouter()
|
||||
const interviewStore = useInterviewStore()
|
||||
const guideKey = 'interview-shooting-intro'
|
||||
const showIntroGuide = ref(!interviewStore.guideShown[guideKey])
|
||||
|
||||
if (showIntroGuide.value) {
|
||||
interviewStore.markGuideShown(guideKey)
|
||||
}
|
||||
|
||||
const showModal = ref(false)
|
||||
|
||||
@@ -87,7 +95,7 @@ const back = () => {
|
||||
<!-- 背景图片 -->
|
||||
<div
|
||||
class="absolute inset-0 bg-cover bg-center bg-no-repeat shooting-bg"
|
||||
:style="{ backgroundImage: getBackgroundImage(IMAGE_PATHS.SHOOTING.BG) }"
|
||||
:style="{ backgroundImage: getBackgroundImage('interview/shooting/实地取景底图') }"
|
||||
>
|
||||
<div class="shooting-title">
|
||||
<img :src="shootingtitle" alt="" />
|
||||
@@ -95,25 +103,28 @@ const back = () => {
|
||||
<div class="shooting-return">
|
||||
<ImgButton image="shooting/返回.png" @click="back" />
|
||||
</div>
|
||||
<div class="shooting-left">
|
||||
<ImgButton image="shooting/按钮-取景地A.png" @click="handleClickA" />
|
||||
<div class="absolute left-[12%] top-1/2 -translate-y-[calc(50%-70px)]">
|
||||
<ImgButton image="interview/shooting/操场-入口.png" @click="handleClickA" />
|
||||
</div>
|
||||
<div class="shooting-right">
|
||||
<ImgButton image="shooting/按钮-取景地B.png" @click="handleClickB" />
|
||||
<div class="absolute right-[12%] top-1/2 -translate-y-[calc(50%-70px)]">
|
||||
<ImgButton image="interview/shooting/教学楼-入口.png" @click="handleClickB" />
|
||||
</div>
|
||||
<div class="shooting-composition">
|
||||
<ImgButton image="shooting/构图指南.png" @click="showModal = true" />
|
||||
<ImgButton class="mybutton" image="shooting/构图指南.png" @click="showModal = true" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 引导步骤 -->
|
||||
<GuideSteps
|
||||
v-if="showIntroGuide"
|
||||
:highlight-selector="'.mybutton'"
|
||||
:highlight-padding="12"
|
||||
:highlight-radius="20"
|
||||
position-offset-y="85%"
|
||||
position-offset-y="30%"
|
||||
>
|
||||
<GuideStepsItem> 在走进拍摄场景之前,我们先来查看一下构图指南。 </GuideStepsItem>
|
||||
<GuideStepsItem :audio-src="getPublicPath('audio/py_3_009.MP3')">
|
||||
同一个地点,站位不同、构图不同,画面质感就完全不同。
|
||||
</GuideStepsItem>
|
||||
</GuideSteps>
|
||||
|
||||
<!-- 保存图片弹窗 -->
|
||||
|
||||
Reference in new issue
Block a user