fix: 补齐过期首帧素材定位与图库影响提示

This commit is contained in:
GouJ
2026-09-02 18:49:20 +08:00
parent f71d2bf0a4
commit 771b66cafc
11 changed files with 826 additions and 23 deletions
+44 -13
View File
@@ -12,7 +12,7 @@ import {
NProgress,
NSelect
} from 'naive-ui'
import { computed, ref, watch } from 'vue'
import { computed, inject, ref, watch } from 'vue'
import { ArrowLeft, CheckCircle2, CircleAlert, Film, Image, MessageSquareText, RefreshCw } from '@lucide/vue'
import { EmptyState, StatusBadge } from '../../components/ui'
import BeatShotDirectory from '../storyboard/components/BeatShotDirectory.vue'
@@ -22,6 +22,9 @@ import { useProduction } from './useProduction'
import ProductionReceipt from './components/ProductionReceipt.vue'
import ShotProductionAssets from './components/ShotProductionAssets.vue'
import AdvancedProduction from './components/AdvancedProduction.vue'
import StaleKeyframeNotice from './components/StaleKeyframeNotice.vue'
import { routeLocationKey } from 'vue-router'
import { queryText } from './asset-links'
/** 镜头生产页将项目批处理与单镜头资产管理放在同一条可核验链路中。 */
const {
@@ -49,6 +52,23 @@ const {
blocked,
run
} = useProduction()
const route = inject(routeLocationKey, undefined)
/** 从素材页返回时恢复到指定剧集与正式镜头,不按重复的 Shot 编号定位。 */
watch(
() => [route?.query.episodeNo, route?.query.shotId],
() => {
const episode = Number(queryText(route?.query.episodeNo))
selectedEpisode.value = Number.isSafeInteger(episode) && episode > 0 ? episode : undefined
selectedShot.value = queryText(route?.query.shotId)
},
{ immediate: true }
)
const linkedShotMissing = computed(
() =>
queryText(route?.query.shotId) &&
query.data.value &&
!shots.value.some(item => item.shotId === selectedShot.value)
)
const staleVideos = computed(() => query.data.value?.videos.stalePrimaryVideo ?? 0)
const stages = computed(() => {
const data = query.data.value
@@ -92,6 +112,12 @@ const stages = computed(() => {
const selectedIssues = computed(() =>
[promptItem.value, keyframeItem.value, videoItem.value].flatMap(item => item?.issues ?? [])
)
const remainingIssues = computed(() => selectedIssues.value.filter(issue => issue.code !== 'stale_keyframe'))
const selectedKeyframeStale = computed(
() =>
!!keyframeItem.value?.primaryKeyframeStale ||
selectedIssues.value.some(issue => issue.code === 'stale_keyframe')
)
const videoRunning = computed(
() =>
(query.data.value?.videoStatus.pending ?? 0) +
@@ -514,6 +540,9 @@ watch(
<article class="production-detail min-w-0">
<NScrollbar class="panel-scroll" content-class="p-5 lg:p-7">
<header class="mb-5 pb-5">
<NAlert v-if="linkedShotMissing" type="warning" :show-icon="false" class="mb-4"
>链接中的镜头已不存在或不属于该剧集,请在左侧重新选择。</NAlert
>
<div class="flex flex-wrap items-start justify-between gap-3">
<div>
<p class="eyebrow">BEAT {{ shot.beatNo }} / SHOT {{ shot.shotNo }}</p>
@@ -527,15 +556,17 @@ watch(
</div>
<p v-if="shot.description" class="mt-3 text-sm leading-7">{{ shot.description }}</p>
<p class="mt-3 break-all font-mono text-[10px] text-muted">Shot ID · {{ shot.shotId }}</p>
<NAlert
v-if="keyframeItem?.primaryKeyframeStale"
role="status"
type="info"
:show-icon="false"
class="mt-4 text-xs"
>
主首帧已过期:当前主体参考资产与生成该首帧时不一致。旧首帧会保留,但不能继续用于视频生成。
</NAlert>
<StaleKeyframeNotice
v-if="selectedKeyframeStale"
:key="shot.shotId"
:project-id="id"
:shot-id="shot.shotId"
:issues="selectedIssues"
:inconsistent="
keyframeItem?.primaryKeyframeStale === false &&
selectedIssues.some(issue => issue.code === 'stale_keyframe')
"
/>
<NAlert
v-if="videoItem?.primaryVideoStale"
role="status"
@@ -545,8 +576,8 @@ watch(
>
主视频已过期:当前主首帧或主体参考图与生成该视频时不一致。旧视频仍保留,但需要重新生成后才能作为当前有效成片。
</NAlert>
<ul v-if="selectedIssues.length" class="alert alert-error mt-4 space-y-1" role="alert">
<li v-for="(issue, index) in selectedIssues" :key="`${issue.code}-${index}`">
<ul v-if="remainingIssues.length" class="alert alert-error mt-4 space-y-1" role="alert">
<li v-for="(issue, index) in remainingIssues" :key="`${issue.code}-${index}`">
{{ issueLabel(issue.code) }}{{ issue.reason }}
</li>
</ul>
@@ -558,7 +589,7 @@ watch(
:prompt-readiness="promptItem"
:keyframe-readiness="keyframeItem"
:video-readiness="videoItem"
:disabled="blocked"
:disabled="blocked || !!linkedShotMissing"
@changed="refreshProject"
/>
</NScrollbar>