feat: 提示词

This commit is contained in:
zhongyidian committed 2025-12-31 17:46:53 +08:00
1 parent b980f2993b
commit 6090abf955
15 files changed
+330 -54

No files matched your search

+36 -1
View File
@@ -1,19 +1,26 @@
<script lang="tsx" setup>
import { getBackgroundImage, IMAGE_PATHS } from '@/utils'
import { getBackgroundImage, getStaticImage, IMAGE_PATHS } from '@/utils'
import { ImgButton } from '@/components/Button'
import { computed, onMounted, ref } from 'vue'
import { ProgressBar, Overlay } from '@/components'
import { useRouter } from 'vue-router'
import { useFilmStore } from '@/stores'
import { GuideSteps, GuideStepsItem } from '@/components/Guide'
import FilmMenu from './components/menu.vue'
const router = useRouter()
const film = useFilmStore()
const visible = ref(false)
const status = ref(true)
const currentStep = computed(() => film.FilmUnlockProgress)
const progress = computed(() => {
return Math.round((currentStep.value / 4) * 100)
})
const handleComplete = () => {
// console.log('完成前置条件')
// 处理完成逻辑
@@ -51,6 +58,16 @@ onMounted(() => {
:style="{ backgroundImage: getBackgroundImage('film/电影模块背景') }"
></div>
<!-- 进度数据 -->
<div class="absolute top-[140px] left-[calc(50%)] -translate-x-1/2">
<div
class="flex items-center justify-center text-white [font-family:DingTalkJinBuTi] font-[1000] [text-shadow:_6px_6px_4px_#2b80c1,_6px_6px_4px_#2b80c1,_6px_6px_4px_#2b80c1,_6px_6px_4px_#2b80c1]"
>
<span class="text-6xl">学习进度:</span>
<span class="text-7xl">{{ progress }}%</span>
</div>
</div>
<!-- 关闭 -->
<ImgButton
class="absolute right-0 top-0 z-20"
@@ -112,5 +129,23 @@ onMounted(() => {
@step-change="handleStepChange"
/>
</div>
<GuideSteps
v-if="status"
highlight-selector=""
highlight-mode="gradient"
position-offset-y="85%"
@complete="() => {}"
>
<GuideStepsItem>
<div class="flex items-center justify-start">
请点击<img
class="w-20"
:src="getStaticImage('film/icon')"
alt=""
/>进入任务取景框开始学习!
</div>
</GuideStepsItem>
</GuideSteps>
</div>
</template>
@@ -154,7 +154,7 @@ const handleComplete = () => {
<img
ref="backgroundImage"
class="absolute inset-0 w-full h-full object-cover pointer-events-none opacity-0"
:src="getStaticImage('film/shooting/龙美术馆清晰图.png')"
:src="getStaticImage('film/shooting/油罐艺术公园清晰底图.png')"
alt=""
crossorigin="anonymous"
/>
+70 -20
View File
@@ -2,9 +2,9 @@
import { computed, nextTick, onMounted, ref } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import ImgButton from '@/components/Button/ImgButton.vue'
import { GuideSteps, StepNavigation } from '@/components/Guide'
import { GuideSteps, GuideStepsItem, StepNavigation } from '@/components/Guide'
import { Video, QuestionQuiz, type Question } from '@/components'
import { getStaticImage, IMAGE_PATHS } from '@/utils'
import { getPublicPath, getStaticImage, IMAGE_PATHS } from '@/utils'
import second from '/video/vlog_renwuqujing_jichujingbieyunyong.mp4'
import third from '/video/vlog_renwuqujing_huamiangoutu.mp4'
import fourth from '/video/vlog_renwuqujing_jiaobencehua.mp4'
@@ -17,6 +17,10 @@ const route = useRoute()
const film = useFilmStore()
const visibleGuide = ref(true)
const visibleGuide2 = ref(true)
// 受控播放开关(用于切换到下一个视频时自动播放)
const playing = ref(false)
const status = ref(false)
@@ -34,43 +38,43 @@ const steps = ref([
const navigationSteps = ref([
{
id: 'step1',
label: '',
label: '后期制作',
content: '遮幅',
type: 'shooting' as const
type: 'post' as const
},
{
id: 'step2',
label: '',
label: '拍摄执行',
content: '光线',
type: 'shooting' as const
type: 'post' as const
},
{
id: 'step3',
label: '',
label: '拍摄执行',
content: '虚实',
type: 'planning' as const
},
{
id: 'step4',
label: '',
content: '特写镜头',
type: 'shooting' as const
},
{
id: 'step4',
label: '拍摄执行',
content: '特写镜头',
type: 'post' as const
},
{
id: 'step5',
label: '',
label: '拍摄执行',
content: '分镜头',
type: 'post' as const
},
{
id: 'step5',
label: '',
label: '后期制作',
content: '滤镜',
type: 'post' as const
},
{
id: 'step5',
label: '',
label: '拍摄执行',
content: '同期声',
type: 'post' as const
}
@@ -140,7 +144,7 @@ const getQuestionsForVideo = (index: number): Question[] => {
//按顺序播放
const currentVideo = computed(() => videoList[currentVideoIndex.value])
const resolvedSrc = computed(() => {
if (key.value === 'case') return '/video/anlishangxi_meishi_xiaoyuanzi.mp4'
if (key.value === 'case') return getPublicPath('video/anlishangxi_meishi_xiaoyuanzi.mp4')
if (key.value === 'profession') return currentVideo.value
return ''
})
@@ -248,11 +252,11 @@ onMounted(() => {
<!-- 步骤导航按钮 -->
<button
v-if="key === 'profession'"
class="absolute right-4 top-1/2 z-10 -translate-y-1/2 w-12 h-12 bg-blue-500/80 hover:bg-blue-500 rounded-full flex items-center justify-center text-white transition-all duration-200"
class="absolute right-4 top-1/2 z-10 -translate-y-1/2 w-20 h-20 bg-blue-500/80 hover:bg-blue-500 rounded-full flex items-center justify-center text-white transition-all duration-200"
@click="showStepNavigation = true"
title="步骤导航"
>
<svg width="20" height="20" viewBox="0 0 20 20" fill="none">
<svg width="35" height="35" viewBox="0 0 20 20" fill="none">
<path
d="M3 4H17M3 8H17M3 12H17M3 16H17"
stroke="currentColor"
@@ -293,7 +297,7 @@ onMounted(() => {
</div>
<!-- 引导与高亮 -->
<GuideSteps v-if="status" :steps="steps" position-offset-y="85%" @complete="handleComplete" />
<!-- <GuideSteps v-if="status" :steps="steps" position-offset-y="85%" @complete="handleComplete" /> -->
<!-- 步骤导航抽屉 -->
<StepNavigation
@@ -304,6 +308,52 @@ onMounted(() => {
@step-click="handleStepClick"
@close="handleStepNavigationClose"
/>
<!-- 引导与高亮 -->
<GuideSteps
highlight-selector=""
v-if="visibleGuide && key === 'profession'"
position-offset-y="85%"
>
<GuideStepsItem>
从刚才的案例可以看出,电影感画面自带一种独特的艺术魅力——或大气恢弘,扑朔迷离或充满故事感。
</GuideStepsItem>
<GuideStepsItem>
作为短视频创作者,我们可以借助这些方法,在拍摄与剪辑中打造更有质感的画面。
</GuideStepsItem>
<GuideStepsItem>
<div class="flex flex-wrap items-center justify-start">
<div>接下来,让我们一起看看打造电影感的几种关键技巧吧。</div>
<div class="text-yellow-400">
点击<button
class="w-10 h-10 bg-blue-500/80 hover:bg-blue-500 rounded-full inline-flex items-center justify-center text-white transition-all duration-200"
title="步骤导航"
>
<svg width="20" height="20" viewBox="0 0 20 20" fill="none">
<path
d="M3 4H17M3 8H17M3 12H17M3 16H17"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
/>
</svg>
</button>
可以切换不同的学习内容!
</div>
</div>
</GuideStepsItem>
</GuideSteps>
<!-- 引导与高亮 -->
<GuideSteps highlight-selector="" v-if="visibleGuide2 && key === 'idea'" position-offset-y="85%">
<GuideStepsItem>
一个好镜头,既要好看,又要好懂 ——
既有视觉吸引力,又能把信息清晰地传达出来。当这些条件被满足,一个镜头就有了“高级感”。
</GuideStepsItem>
<GuideStepsItem>
而优秀的短视频,就是靠无数这样的好镜头累积而成的。接下来,我们就以徐汇滨江为例,一起动手练习如何拍出属于它的意义与故事吧!
</GuideStepsItem>
</GuideSteps>
</template>
<style scoped>
+30 -12
View File
@@ -4,7 +4,7 @@ import { ref, computed } from 'vue'
import { getBackgroundImage, IMAGE_PATHS, getStaticImage } from '@/utils'
import { ImgButton } from '@/components/Button'
import WorkSideSwitcher from './components/WorkSideSwitcher.vue'
import { GuideSteps } from '@/components/Guide'
import { GuideSteps, GuideStepsItem } from '@/components/Guide'
import { useRouter } from 'vue-router'
import { useScale } from '@/composables/useScale'
import { ImagePreview } from '@/components'
@@ -23,15 +23,6 @@ const workSideSwitcherRef = ref<InstanceType<typeof WorkSideSwitcher>>()
const isGuideFilmTask = computed(() => film.isGuideFilmTask)
const isFilmUnlock = computed(() => film.isFilmUnlock)
//引导步骤
const steps = [
{
id: 'step1',
content: '经常听到有人赞叹:“这个镜头真高级。”'
},
{ id: 'step2', content: '那么什么样的镜头才算是好镜头?又是什么让画面显得更高级?' }
]
//切换图片
const sideSwitcherItems = ref([
{
@@ -152,6 +143,21 @@ function openImages(urls: string[], startIndex = 0) {
:src="getStaticImage(currentItem?.image || '')"
alt=""
/>
<!-- <div class="absolute inset-0 flex items-center justify-center pointer-events-none z-10">
<div
class="w-40 h-40 pointer-events-auto rounded-full bg-black/50 backdrop-blur-sm flex items-center justify-center cursor-pointer hover:bg-black/70 transition-colors"
>
<svg
class="w-22 h-22 text-white ml-1"
fill="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M8 5v14l11-7z" />
</svg>
</div>
</div> -->
</div>
<!-- 左侧选项切换 -->
@@ -174,7 +180,6 @@ function openImages(urls: string[], startIndex = 0) {
<!-- 引导与高亮 -->
<GuideSteps
v-if="isGuideFilmTask"
:steps="steps"
:highlight-selector="currentHighlight"
:highlight-padding="12"
:highlight-radius="20"
@@ -182,7 +187,20 @@ function openImages(urls: string[], startIndex = 0) {
@complete="handleGuideComplete"
@skip="handleGuideComplete"
position-offset-y="85%"
/>
>
<GuideStepsItem>
点击右侧【案例赏析】、【专业剖析】、【思路提点】,可以切换不同内容
</GuideStepsItem>
<GuideStepsItem>
<div class="flex items-center justify-start">
请点击 &nbsp;<img
class="w-16"
:src="getStaticImage('film/sx')"
alt=""
/>&nbsp;,进入案例赏析!
</div>
</GuideStepsItem>
</GuideSteps>
<!-- 引导词按钮 -->
<ImgButton
+71 -3
View File
@@ -1,10 +1,23 @@
<script lang="ts" setup>
defineOptions({
name: 'Action'
})
import { getBackgroundImage, IMAGE_PATHS, getStaticImage } from '@/utils'
import { ImgButton } from '@/components/Button'
import { ModuleSwitcher } from './components/ModuleSwitcher'
import { computed, ref, onMounted, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import { useUserStore } from '@/stores'
import { GuideSteps, GuideStepsItem } from '@/components/Guide'
//点击电视机按钮引导状态
const status = ref(false)
//点击新手导航节点引导状态
const status2 = ref(true)
const handleComplete = () => {
status.value = false
}
const router = useRouter()
const user = useUserStore()
@@ -46,6 +59,7 @@ const handleCloseGuide = () => {
}
const handleModuleChange = (module: 'vlog' | 'film' | 'interview') => {
status.value = true
if (selectedModule.value === module) return
isImageLoading.value = true
@@ -58,7 +72,8 @@ const handleModuleChange = (module: 'vlog' | 'film' | 'interview') => {
}
const handleClick = () => {
console.log(selectedModule.value.charAt(0).toUpperCase() + selectedModule.value.slice(1))
if (selectedModule.value === 'interview') return
// console.log(selectedModule.value.charAt(0).toUpperCase() + selectedModule.value.slice(1))
router.push({
//首字母大写
name: selectedModule.value.charAt(0).toUpperCase() + selectedModule.value.slice(1)
@@ -173,7 +188,7 @@ onUnmounted(() => {
<!-- 电视机 -->
<div
class="absolute w-[765px] h-[768px] right-0 top-0 z-[5] transition-all duration-300 hover:scale-105 hover:brightness-110 cursor-pointer"
class="absolute w-[765px] h-[768px] right-0 top-0 z-[5] transition-all duration-300 hover:scale-105 hover:brightness-110 cursor-pointer tvGuide"
:class="{ 'opacity-50': isImageLoading }"
:style="{ backgroundImage: selectedImage }"
@click.stop="handleClick"
@@ -197,7 +212,7 @@ onUnmounted(() => {
v-if="!guideShow"
>
<div
class="absolute bottom-20 right-[calc(50%-20px)] translate-x-1/2 w-20 h-20 cursor-pointer pointer-events-auto"
class="absolute bottom-20 right-[calc(50%-20px)] translate-x-1/2 w-20 h-20 cursor-pointer pointer-events-auto newUserGuide"
@click="handleOpenGuide"
></div>
</div>
@@ -329,5 +344,58 @@ onUnmounted(() => {
</div>
</div>
</div>
<!-- 引导与高亮 -->
<GuideSteps
v-if="status"
highlight-mode="gradient"
highlight-selector=".tvGuide"
position-offset-y="85%"
@complete="handleComplete"
>
<GuideStepsItem>
<div
class="flex items-center justify-start"
v-if="selectedModule === 'interview' || selectedModule === 'vlog'"
>
[{{
selectedModule == 'interview'
? '访谈-聆听与对话'
: selectedModule == 'vlog'
? 'vlog-创作与表达'
: ''
}}]模块建设中...
</div>
<div class="flex items-center justify-start" v-else>
请点击<img
class="w-20"
:src="getStaticImage(imageMap[selectedModule])"
alt=""
/>,继续学习[{{
selectedModule == 'film'
? '电影-创作与表达'
: selectedModule == 'vlog'
? 'vlog-创作与表达'
: ''
}}]模块!
</div>
</GuideStepsItem>
</GuideSteps>
<GuideSteps
v-if="status2"
highlight-mode="gradient"
highlight-selector=".newUserGuide"
position-offset-y="50%"
@complete="handleComplete"
>
<GuideStepsItem>
<div class="flex items-center justify-start">
欢迎来到《短视频达人养成记》课程,请点击下方
<img class="w-20" :src="getStaticImage('home/action/top')" alt="" />
开始学习!
</div>
</GuideStepsItem>
</GuideSteps>
</div>
</template>
+2 -2
View File
@@ -4,7 +4,7 @@ import { useRouter, useRoute } from 'vue-router'
import ImgButton from '@/components/Button/ImgButton.vue'
import { GuideSteps, StepNavigation } from '@/components/Guide'
import { Video } from '@/components'
import { getBackgroundImage, getStaticImage, IMAGE_PATHS } from '@/utils'
import { getBackgroundImage, getPublicPath, getStaticImage, IMAGE_PATHS } from '@/utils'
import second from '/video/vlog_renwuqujing_jichujingbieyunyong.mp4'
import third from '/video/vlog_renwuqujing_huamiangoutu.mp4'
import fourth from '/video/vlog_renwuqujing_jiaobencehua.mp4'
@@ -74,7 +74,7 @@ const currentVideoIndex = ref(0)
//按顺序播放
const currentVideo = computed(() => videoList[currentVideoIndex.value])
const resolvedSrc = computed(() => {
if (key.value === 'case') return '/video/anlishangxi_meishi_xiaoyuanzi.mp4'
if (key.value === 'case') return getPublicPath('video/anlishangxi_meishi_xiaoyuanzi.mp4')
if (key.value === 'profession') return currentVideo.value
return ''
})