Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
215 lines
5.3 KiB
Vue
215 lines
5.3 KiB
Vue
<script lang="tsx" setup>
|
|
import { getStaticImage } from '@/utils'
|
|
import { computed, ref } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import { getBackgroundImage } from '@/utils'
|
|
import { useInterviewStore } from '@/stores'
|
|
defineOptions({ name: 'InterviewMenu' })
|
|
|
|
/**
|
|
* 菜单项 (前期准备、中期拍摄、后期剪辑)
|
|
* 前期准备-资源筹备、创意构想、脚本撰写、分镜制作
|
|
* 中期拍摄-设备准备、实地取景、现场拍摄
|
|
* 后期剪辑-素材管理、剪辑、调色、导出发布
|
|
*/
|
|
const category = ref([
|
|
{
|
|
label: '前期准备',
|
|
value: 1,
|
|
icon: getStaticImage('midterm/准备图标.png'),
|
|
},
|
|
{
|
|
label: '中期拍摄',
|
|
value: 2,
|
|
icon: getStaticImage('midterm/拍摄图标.png'),
|
|
},
|
|
{
|
|
label: '后期剪辑',
|
|
value: 3,
|
|
icon: getStaticImage('midterm/剪辑图标.png'),
|
|
},
|
|
])
|
|
|
|
const menuItems = ref([
|
|
{
|
|
label: '资源筹备',
|
|
routeName: 'InterviewResource',
|
|
parentValue: 1,
|
|
disabled: false,
|
|
},
|
|
{
|
|
label: '创意构想',
|
|
routeName: 'InterviewCreative',
|
|
parentValue: 1,
|
|
disabled: false,
|
|
},
|
|
{
|
|
label: '脚本撰写',
|
|
routeName: 'InterviewScriptWriting',
|
|
parentValue: 1,
|
|
disabled: false,
|
|
},
|
|
{
|
|
label: '分镜制作',
|
|
routeName: 'InterviewStoryboard',
|
|
parentValue: 1,
|
|
disabled: false,
|
|
},
|
|
{
|
|
label: '设备准备',
|
|
routeName: 'InterviewEquipment',
|
|
parentValue: 2,
|
|
disabled: false,
|
|
},
|
|
{
|
|
label: '实地取景',
|
|
routeName: 'InterviewShooting',
|
|
parentValue: 2,
|
|
disabled: false,
|
|
},
|
|
{
|
|
label: '现场拍摄',
|
|
routeName: 'InterviewOnsiteShooting',
|
|
parentValue: 2,
|
|
disabled: false,
|
|
},
|
|
// {
|
|
// label: '素材管理',
|
|
// routeName: 'Interview素材管理',
|
|
// parentValue: 3,
|
|
// disabled: true
|
|
// },
|
|
{
|
|
label: '剪辑',
|
|
routeName: 'InterviewEditing',
|
|
parentValue: 3,
|
|
disabled: false,
|
|
},
|
|
{
|
|
label: '调色',
|
|
routeName: 'InterviewColor',
|
|
parentValue: 3,
|
|
disabled: false,
|
|
},
|
|
{
|
|
label: '音频',
|
|
routeName: 'InterviewAudio',
|
|
parentValue: 3,
|
|
disabled: false,
|
|
},
|
|
{
|
|
label: '导出发布',
|
|
routeName: 'InterviewExportPublish',
|
|
parentValue: 3,
|
|
disabled: false,
|
|
},
|
|
])
|
|
|
|
const props = defineProps<{
|
|
currentStep: number
|
|
}>()
|
|
|
|
const router = useRouter()
|
|
const interview = useInterviewStore()
|
|
|
|
const isViewed = (routeName: string) => {
|
|
return interview.viewed?.[routeName] === true
|
|
}
|
|
|
|
const currentParentValue = computed<number>(() => {
|
|
return props.currentStep
|
|
}) // 当前选中的父级菜单项
|
|
|
|
const currentItemValue = ref<string>('') // 当前选中的子级菜单项
|
|
|
|
const getMenuItems = computed(() => {
|
|
return menuItems.value.filter(
|
|
(item) => item.parentValue === currentParentValue.value,
|
|
)
|
|
})
|
|
|
|
const handleItemClick = (item: { routeName: string; disabled: boolean }) => {
|
|
if (item.disabled) return
|
|
currentItemValue.value = item.routeName
|
|
router.push({ name: item.routeName })
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
class="absolute left-20 top-0 bottom-0 w-[520px] pt-28"
|
|
v-if="currentStep"
|
|
>
|
|
<!-- 分类名称 -->
|
|
<div class="absolute top-3 left-24 flex items-center space-x-2">
|
|
<span class="text-4xl text-[#fbbf24] font-black">
|
|
{{ category[currentParentValue - 1].label }}
|
|
</span>
|
|
<img
|
|
class="filter-blue"
|
|
:src="category[currentParentValue - 1].icon"
|
|
alt=""
|
|
/>
|
|
</div>
|
|
<!-- 背景图片 -->
|
|
<div
|
|
class="absolute inset-0 bg-cover bg-left bg-no-repeat -z-10"
|
|
:style="{ backgroundImage: getBackgroundImage('components/menu-bg.png') }"
|
|
></div>
|
|
<div class="flex items-center flex-col pl-[60px]">
|
|
<template
|
|
v-for="(item, index) in getMenuItems"
|
|
:key="item.routeName"
|
|
>
|
|
<div
|
|
class="relative w-[373px] h-[143px] pl-14 flex items-center justify-center group text-4xl font-black transition-colors"
|
|
:class="[
|
|
currentItemValue === item.routeName
|
|
? 'text-blue-400'
|
|
: 'text-white',
|
|
item.disabled ? 'opacity-20 cursor-not-allowed' : 'cursor-pointer',
|
|
]"
|
|
:style="{ marginLeft: -index * 40 + 'px' }"
|
|
@click="handleItemClick(item)"
|
|
>
|
|
<div
|
|
v-if="!item.disabled"
|
|
class="absolute inset-0 bg-cover bg-center bg-no-repeat opacity-0 group-hover:opacity-100 transition-opacity duration-300"
|
|
:style="{
|
|
backgroundImage: getBackgroundImage('components/menu-hover.png'),
|
|
}"
|
|
></div>
|
|
<span
|
|
class="flex items-center gap-2"
|
|
:class="[!item.disabled ? 'menu-glow-text' : '']"
|
|
>
|
|
<span>{{ item.label }}</span>
|
|
<img
|
|
class="w-10"
|
|
:src="
|
|
isViewed(item.routeName)
|
|
? '/src/assets/images/midterm/完成.png'
|
|
: '/src/assets/images/midterm/未完成.png'
|
|
"
|
|
alt=""
|
|
/>
|
|
</span>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.filter-blue {
|
|
filter: brightness(0) saturate(100%) invert(79%) sepia(29%) saturate(1190%)
|
|
hue-rotate(330deg) brightness(102%) contrast(98%);
|
|
}
|
|
|
|
.menu-glow-text {
|
|
text-shadow:
|
|
0 0 40px rgba(0, 180, 255, 0.9),
|
|
0 0 20px rgba(0, 180, 255, 0.7);
|
|
}
|
|
</style>
|