feat: 生产页展示过期首帧状态

This commit is contained in:
GouJ
2026-09-01 14:49:33 +08:00
parent 5d26387b03
commit 16e67b563e
+20 -4
View File
@@ -52,7 +52,7 @@ const stages = computed(() => {
icon: Image,
data: data?.keyframes,
done: data?.keyframes.skipped ?? 0,
action: force.value ? '为全部镜头新增首帧' : '补齐主首帧'
action: force.value ? '为全部镜头新增首帧' : '补齐 / 更新主首帧'
},
{
key: 'videos' as const,
@@ -81,6 +81,7 @@ const identityBlocked = computed(
(query.data.value?.keyframes.missingIdentityAnchor ?? 0) +
(query.data.value?.keyframes.identityUnlocked ?? 0)
)
const staleKeyframes = computed(() => query.data.value?.keyframes.stalePrimaryKeyframe ?? 0)
/** 父页查询包含整个项目的就绪统计,单镜头变更后立即刷新。 */
function refreshProject() {
@@ -100,7 +101,7 @@ function refreshProject() {
</RouterLink>
</div>
<p class="alert mt-5 text-xs">
每一步都按后端就绪检查执行覆盖只会新增首帧视频候选不会替换当前主资产重新生成上游内容后也不会自动更新已有下游结果
每一步都按后端就绪检查执行覆盖只会新增首帧视频候选不会替换当前主资产上游参考资产变化后下游过期结果会被标记并阻止继续使用需要重新生成后才能恢复就绪
</p>
<section class="panel mt-5 p-5" aria-label="项目生产配置">
@@ -160,6 +161,9 @@ function refreshProject() {
Identity确认演员母版并锁定后首帧才能就绪
<RouterLink :to="`/projects/${id}/subject-identity`" class="text-button ml-2">前往角色选角 </RouterLink>
</p>
<p v-if="staleKeyframes" class="alert mt-4" role="status">
当前有 {{ staleKeyframes }} 个主首帧已过期它们使用的主体参考资产已经变化视频阶段会被阻止可在下方逐镜重新生成或使用补齐 / 更新主首帧批量处理
</p>
<ProductionReceipt v-if="session.receipt" :receipt="session.receipt" />
<div v-if="query.data.value" class="production-pipeline mt-5">
@@ -202,6 +206,9 @@ function refreshProject() {
<dd>{{ stage.data?.blocked ?? 0 }}</dd>
</div>
</dl>
<p v-if="stage.key === 'keyframes' && staleKeyframes" class="mt-3 text-[11px] leading-5">
已过期 {{ staleKeyframes }} · 会按当前主体参考资产重新生成
</p>
<p v-if="stage.key === 'keyframes' && identityBlocked" class="mt-3 text-[11px] leading-5 text-danger">
身份缺失 {{ query.data.value?.keyframes.missingIdentity ?? 0 }} · 母版缺失
{{ query.data.value?.keyframes.missingIdentityAnchor ?? 0 }} · 未锁定
@@ -216,7 +223,7 @@ function refreshProject() {
stage.key === 'videos'
? '只为当前就绪镜头创建 Seedance 异步任务。创建成功不代表视频已经完成,任务会在后台继续运行。'
: stage.key === 'keyframes'
? '只为当前就绪镜头调用 Seedream。覆盖模式新增候选,不替换已有主首帧。'
? '处理缺失主首帧和参考资产已变化的过期主首帧。过期镜头会按当前主体参考资产重新生成并恢复为可用于视频的主首帧;覆盖模式新增候选。'
: '只处理通过视频提示词就绪检查的镜头;覆盖模式会重写已有提示词。'
"
:primary="stage.key === 'videos'"
@@ -281,7 +288,13 @@ function refreshProject() {
>
<span class="font-mono text-[10px] text-muted">B{{ item.beatNo }} / S{{ item.shotNo }}</span>
<span class="mt-1 block truncate text-xs font-medium">{{ item.title }}</span>
<span class="mt-2 flex items-center gap-2 text-[10px] text-muted">
<span
v-if="query.data.value?.keyframes.items.find(row => row.shotId === item.shotId)?.primaryKeyframeStale"
class="mt-2 flex items-center gap-2 text-[10px]"
>
<CircleAlert :size="12" />主首帧已过期
</span>
<span v-else class="mt-2 flex items-center gap-2 text-[10px] text-muted">
<CheckCircle2
v-if="
query.data.value?.videos.items.find(row => row.shotId === item.shotId)?.status ===
@@ -320,6 +333,9 @@ function refreshProject() {
</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>
<p v-if="keyframeItem?.primaryKeyframeStale" class="alert mt-4 text-xs" role="status">
主首帧已过期:当前主体参考资产与生成该首帧时不一致。旧首帧会保留,但不能继续用于视频生成。
</p>
<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}`">
{{ issueLabel(issue.code) }}{{ issue.reason }}