forked from zhongyidian/super_video
feat: 完善访谈与vlog模块页面,重组设备与图片公共资源,新增音频管理与一班对接工具
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
c4c9be9d35
commit
fc9633f371
159 files changed
+4823
-2535
No files matched your search
@@ -1,7 +1,7 @@
|
||||
<script lang="tsx" setup>
|
||||
import { getBackgroundImage, getStaticImage, IMAGE_PATHS } from '@/utils'
|
||||
import { GuideSteps, GuideStepsItem, type GuideStep } from '@/components/Guide'
|
||||
import { ref, computed } from 'vue'
|
||||
import { getBackgroundImage, getPublicPath, getStaticImage, IMAGE_PATHS } from '@/utils'
|
||||
import { GuideSteps } from '@/components/Guide'
|
||||
import { onBeforeUnmount, ref, computed } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ImgButton } from '@/components/Button'
|
||||
|
||||
@@ -11,39 +11,102 @@ const back = () => {
|
||||
// 跳转设备准备
|
||||
router.back()
|
||||
}
|
||||
const steps = [
|
||||
{ id: 'step1', content: '先认识 Vlog:点击右侧「1.vlog初识」继续' },
|
||||
{ id: 'step2', content: '这是主要内容区域的边框' }
|
||||
]
|
||||
const stepIndex = ref(0)
|
||||
const steps = ref([
|
||||
{
|
||||
id: 'step1',
|
||||
content:
|
||||
'设备准备妥当后,我们就该走进真实场景,开启实地取景的环节啦,一起去捕捉那些适合拍摄的画面吧!',
|
||||
audioSrc: getPublicPath('audio/py_2_013.MP3')
|
||||
}
|
||||
])
|
||||
|
||||
const showGuide = ref(false)
|
||||
const guideTriggered = ref(false)
|
||||
const guideTimer = ref<ReturnType<typeof setTimeout> | null>(null)
|
||||
const viewedMenuKeys = ref<Set<string>>(new Set())
|
||||
const hiddenbar = ref(false)
|
||||
const currentIndex = ref(0) // 当前显示的图片索引
|
||||
const selectedMenuIndex = ref(0) // 当前选中的菜单项索引
|
||||
|
||||
// 菜单项数据
|
||||
const menuItems = ref([
|
||||
{ id: 'phone', name: '手机', disabled: false },
|
||||
{ id: 'phone-stand', name: '手机支架', disabled: true },
|
||||
{ id: 'bluetooth-remote', name: '蓝牙遥控器', disabled: true },
|
||||
{ id: 'stabilizer', name: '稳定器', disabled: true },
|
||||
{ id: 'props', name: '常用道具', disabled: true },
|
||||
{ id: 'phone-lens', name: '手机辅助箱头', disabled: true }
|
||||
type EquipmentCategoryId = 'phone' | 'phone-stabilizer' | 'wireless-lavalier-mic'
|
||||
interface EquipmentProduct {
|
||||
img: string
|
||||
}
|
||||
interface EquipmentCategory {
|
||||
id: EquipmentCategoryId
|
||||
name: string
|
||||
disabled: boolean
|
||||
titleImg: string
|
||||
contentImg: string
|
||||
products: EquipmentProduct[]
|
||||
}
|
||||
|
||||
const categories = ref<EquipmentCategory[]>([
|
||||
{
|
||||
id: 'phone',
|
||||
name: '手机',
|
||||
disabled: false,
|
||||
titleImg: getStaticImage('equipment/标题-苹果.png'),
|
||||
contentImg: getStaticImage('equipment/内容-苹果.png'),
|
||||
products: [
|
||||
{ img: getStaticImage('equipment/设备-手机1.png') },
|
||||
{ img: getStaticImage('equipment/设备-手机2.png') }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'phone-stabilizer',
|
||||
name: '手机稳定器',
|
||||
disabled: false,
|
||||
titleImg: getStaticImage('equipment/手机稳定器标题.png'),
|
||||
contentImg: getStaticImage('equipment/手机稳定器图文.png'),
|
||||
products: [{ img: getStaticImage('equipment/手机稳定器.png') }]
|
||||
},
|
||||
{
|
||||
id: 'wireless-lavalier-mic',
|
||||
name: '无线领夹麦克风',
|
||||
disabled: false,
|
||||
titleImg: getStaticImage('equipment/无线领夹麦克风标题.png'),
|
||||
contentImg: getStaticImage('equipment/无线领夹麦克风图文.png'),
|
||||
products: [{ img: getStaticImage('equipment/无线领夹麦克风.png') }]
|
||||
}
|
||||
])
|
||||
|
||||
const phoneList = ref([
|
||||
{ phoneImg: getStaticImage('equipment/设备-手机1.png') },
|
||||
{ phoneImg: getStaticImage('equipment/设备-手机2.png') }
|
||||
])
|
||||
categories.value = categories.value.map(c => ({
|
||||
...c,
|
||||
disabled: (c.products?.length ?? 0) === 0
|
||||
}))
|
||||
|
||||
const platetitleList = ref([
|
||||
{ title: getStaticImage('equipment/标题-苹果.png') },
|
||||
{ title: getStaticImage('equipment/标题-安卓小米.png') }
|
||||
])
|
||||
// 默认选中的菜单也算作已查看
|
||||
if (categories.value[0] && !categories.value[0].disabled) {
|
||||
viewedMenuKeys.value.add(categories.value[0].id)
|
||||
}
|
||||
|
||||
const platetextList = ref([
|
||||
{ text: getStaticImage('equipment/内容-苹果.png') },
|
||||
{ text: getStaticImage('equipment/内容-安卓小米.png') }
|
||||
])
|
||||
const maybeTriggerGuide = () => {
|
||||
if (guideTriggered.value) return
|
||||
const enabledIds = categories.value.filter(c => !c.disabled).map(c => c.id)
|
||||
if (enabledIds.length === 0) return
|
||||
const allViewed = enabledIds.every(id => viewedMenuKeys.value.has(id))
|
||||
if (!allViewed) return
|
||||
guideTriggered.value = true
|
||||
guideTimer.value = setTimeout(() => {
|
||||
showGuide.value = true
|
||||
guideTimer.value = null
|
||||
}, 3000)
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (guideTimer.value) {
|
||||
clearTimeout(guideTimer.value)
|
||||
guideTimer.value = null
|
||||
}
|
||||
})
|
||||
|
||||
const currentCategory = computed(
|
||||
() => categories.value[selectedMenuIndex.value] ?? categories.value[0]
|
||||
)
|
||||
const currentProducts = computed(() => currentCategory.value?.products ?? [])
|
||||
const currentTitleImg = computed(() => currentCategory.value?.titleImg ?? '')
|
||||
const currentContentImg = computed(() => currentCategory.value?.contentImg ?? '')
|
||||
const hiddenbarclick = () => {
|
||||
hiddenbar.value = !hiddenbar.value
|
||||
}
|
||||
@@ -51,15 +114,17 @@ const hiddenbarclick = () => {
|
||||
// 选择菜单项
|
||||
const selectMenuItem = (index: number, item: { id: string; name: string; disabled: boolean }) => {
|
||||
if (item.disabled) {
|
||||
console.log(`菜单项 "${item.name}" 已被禁用`)
|
||||
return
|
||||
}
|
||||
selectedMenuIndex.value = index
|
||||
currentIndex.value = 0
|
||||
viewedMenuKeys.value.add(item.id)
|
||||
maybeTriggerGuide()
|
||||
}
|
||||
|
||||
// 下一张图片
|
||||
const nextPhone = () => {
|
||||
if (currentIndex.value < phoneList.value.length - 1) {
|
||||
if (currentIndex.value < currentProducts.value.length - 1) {
|
||||
currentIndex.value++
|
||||
}
|
||||
}
|
||||
@@ -70,17 +135,9 @@ const prevPhone = () => {
|
||||
currentIndex.value--
|
||||
}
|
||||
}
|
||||
|
||||
const handleStepChange = (_step: GuideStep | null, index: number) => {
|
||||
stepIndex.value = index
|
||||
}
|
||||
|
||||
const currentHighlight = computed(() =>
|
||||
stepIndex.value === 0 ? '.img-switch-item--vlog' : '.work-border'
|
||||
)
|
||||
</script>
|
||||
<template>
|
||||
<div class="equipment-index">
|
||||
<div class="equipment-index overflow-hidden">
|
||||
<!-- 背景图片 -->
|
||||
<div
|
||||
class="absolute inset-0 bg-cover bg-center bg-no-repeat equipment-bg"
|
||||
@@ -93,7 +150,7 @@ const currentHighlight = computed(() =>
|
||||
<div class="equipment-item" :hidden="hiddenbar">
|
||||
<div class="menu-list">
|
||||
<div
|
||||
v-for="(item, index) in menuItems"
|
||||
v-for="(item, index) in categories"
|
||||
:key="item.id"
|
||||
class="menu-item"
|
||||
:class="{
|
||||
@@ -118,7 +175,10 @@ const currentHighlight = computed(() =>
|
||||
<div class="equipment-bt">
|
||||
<img src="@/assets/images/equipment/按钮选中-设备准备.png" alt="" />
|
||||
</div>
|
||||
<div :class="hiddenbar ? 'equipment-unfold1' : 'equipment-unfold2'" @click="hiddenbarclick()">
|
||||
<div
|
||||
:class="['cursor-pointer', hiddenbar ? 'equipment-unfold1' : 'equipment-unfold2']"
|
||||
@click="hiddenbarclick()"
|
||||
>
|
||||
<img
|
||||
:src="
|
||||
hiddenbar
|
||||
@@ -139,12 +199,12 @@ const currentHighlight = computed(() =>
|
||||
<img src="@/assets/images/equipment/按钮-左滑.png" alt="" />
|
||||
</div>
|
||||
<div class="equipment-phoneImg">
|
||||
<img :src="phoneList[currentIndex].phoneImg" alt="" />
|
||||
<img :src="currentProducts[currentIndex]?.img" alt="" />
|
||||
</div>
|
||||
<div
|
||||
class="equipment-rightbutton"
|
||||
@click="nextPhone"
|
||||
:style="{ visibility: currentIndex < phoneList.length - 1 ? 'visible' : 'hidden' }"
|
||||
:style="{ visibility: currentIndex < currentProducts.length - 1 ? 'visible' : 'hidden' }"
|
||||
>
|
||||
<img src="@/assets/images/equipment/按钮-右滑.png" alt="" />
|
||||
</div>
|
||||
@@ -155,11 +215,11 @@ const currentHighlight = computed(() =>
|
||||
</div>
|
||||
|
||||
<div class="title">
|
||||
<img :src="platetitleList[currentIndex].title" alt="" />
|
||||
<img :src="currentTitleImg" alt="" />
|
||||
</div>
|
||||
<div class="plate-content">
|
||||
<div class="text">
|
||||
<img :src="platetextList[currentIndex].text" alt="" />
|
||||
<img :src="currentContentImg" alt="" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -175,17 +235,12 @@ const currentHighlight = computed(() =>
|
||||
|
||||
<!-- 引导步骤 -->
|
||||
<GuideSteps
|
||||
:visible="showGuide"
|
||||
:steps="steps"
|
||||
:highlight-selector="currentHighlight"
|
||||
:highlight-padding="12"
|
||||
:highlight-radius="20"
|
||||
@step-change="handleStepChange"
|
||||
position-offset-y="85%"
|
||||
>
|
||||
<GuideStepsItem>
|
||||
<img src="@/assets/images/equipment/设备准备引导1.png" alt="" />
|
||||
</GuideStepsItem>
|
||||
</GuideSteps>
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="less" scoped>
|
||||
|
||||
Reference in new issue
Block a user