feat: 完善课程引导与实战评价体验

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
zhongyidianandClaude Opus 4.7 committed 2026-05-09 09:53:06 +08:00
1 parent 6f8252472f
commit 1f8723aabd
122 files changed
+2595 -1325

No files matched your search

+54 -31
View File
@@ -16,61 +16,62 @@ const category = ref([
{
label: '前期准备',
value: 1,
icon: getStaticImage('midterm/准备图标.png')
icon: getStaticImage('midterm/准备图标.png'),
},
{
label: '中期拍摄',
value: 2,
icon: getStaticImage('midterm/拍摄图标.png')
icon: getStaticImage('midterm/拍摄图标.png'),
},
{
label: '后期剪辑',
value: 3,
icon: getStaticImage('midterm/剪辑图标.png')
}
icon: getStaticImage('midterm/剪辑图标.png'),
},
])
const menuItems = ref([
{
label: '资源筹备',
routeName: 'InterviewResource',
parentValue: 1,
disabled: false
disabled: false,
},
{
label: '创意构想',
routeName: 'InterviewCreative',
parentValue: 1,
disabled: false
disabled: false,
},
{
label: '脚本撰写',
routeName: 'InterviewScriptWriting',
parentValue: 1,
disabled: false
disabled: false,
},
{
label: '分镜制作',
routeName: 'InterviewStoryboard',
parentValue: 1,
disabled: false
disabled: false,
},
{
label: '设备准备',
routeName: 'InterviewEquipment',
parentValue: 2,
disabled: false
disabled: false,
},
{
label: '实地取景',
routeName: 'InterviewShooting',
parentValue: 2,
disabled: false
disabled: false,
},
{
label: '现场拍摄',
routeName: 'InterviewOnsiteShooting',
parentValue: 2,
disabled: false
disabled: false,
},
// {
// label: '素材管理',
@@ -82,26 +83,26 @@ const menuItems = ref([
label: '剪辑',
routeName: 'InterviewEditing',
parentValue: 3,
disabled: false
disabled: false,
},
{
label: '调色',
routeName: 'InterviewColor',
parentValue: 3,
disabled: false
disabled: false,
},
{
label: '音频',
routeName: 'InterviewAudio',
parentValue: 3,
disabled: false
disabled: false,
},
{
label: '导出发布',
routeName: 'InterviewExportPublish',
parentValue: 3,
disabled: false
}
disabled: false,
},
])
const props = defineProps<{
@@ -119,28 +120,36 @@ const currentParentValue = computed<number>(() => {
return props.currentStep
}) // 当前选中的父级菜单项
const currentItemValue = computed<string>(() => {
return router.currentRoute.value.name?.toString() ?? ''
})
const currentItemValue = ref<string>('') // 当前选中的子级菜单项
const getMenuItems = computed(() => {
return menuItems.value.filter(item => item.parentValue === currentParentValue.value)
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 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="" />
<img
class="filter-blue"
:src="category[currentParentValue - 1].icon"
alt=""
/>
</div>
<!-- 背景图片 -->
<div
@@ -148,12 +157,17 @@ const handleItemClick = (item: { routeName: string; disabled: boolean }) => {
: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">
<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'
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)"
@@ -161,13 +175,22 @@ const handleItemClick = (item: { routeName: string; disabled: boolean }) => {
<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') }"
:style="{
backgroundImage: getBackgroundImage('components/menu-hover.png'),
}"
></div>
<span class="flex items-center gap-2" :class="[!item.disabled ? 'menu-glow-text' : '']">
<span
class="flex items-center gap-2"
:class="[!item.disabled ? 'menu-glow-text' : '']"
>
<span>{{ item.label }}</span>
<img
:class="['w-10', isViewed(item.routeName) ? 'brightness-90' : 'brightness-50']"
src="@/assets/images/midterm/完成.png"
class="w-10"
:src="
isViewed(item.routeName)
? '/src/assets/images/midterm/完成.png'
: '/src/assets/images/midterm/未完成.png'
"
alt=""
/>
</span>
@@ -179,8 +202,8 @@ const handleItemClick = (item: { routeName: string; disabled: boolean }) => {
<style scoped>
.filter-blue {
filter: brightness(0) saturate(100%) invert(79%) sepia(29%) saturate(1190%) hue-rotate(330deg)
brightness(102%) contrast(98%);
filter: brightness(0) saturate(100%) invert(79%) sepia(29%) saturate(1190%)
hue-rotate(330deg) brightness(102%) contrast(98%);
}
.menu-glow-text {