feat: 生产页展示过期主视频

This commit is contained in:
GouJ
2026-09-01 15:55:21 +08:00
parent d5ea2aaa98
commit c9201ce22c
+33 -32
View File
@@ -31,6 +31,8 @@ const {
blocked, blocked,
run run
} = useProduction() } = useProduction()
const staleKeyframes = computed(() => query.data.value?.keyframes.stalePrimaryKeyframe ?? 0)
const staleVideos = computed(() => query.data.value?.videos.stalePrimaryVideo ?? 0)
const stages = computed(() => { const stages = computed(() => {
const data = query.data.value const data = query.data.value
return [ return [
@@ -62,7 +64,11 @@ const stages = computed(() => {
icon: Film, icon: Film,
data: data?.videos, data: data?.videos,
done: data?.videoStatus.completed ?? 0, done: data?.videoStatus.completed ?? 0,
action: force.value ? '为全部就绪镜头新增视频' : '提交就绪视频任务' action: force.value
? '为全部就绪镜头新增视频'
: staleVideos.value > 0
? `更新 ${staleVideos.value} 个过期主视频`
: '提交就绪视频任务'
} }
] ]
}) })
@@ -81,7 +87,6 @@ const identityBlocked = computed(
(query.data.value?.keyframes.missingIdentityAnchor ?? 0) + (query.data.value?.keyframes.missingIdentityAnchor ?? 0) +
(query.data.value?.keyframes.identityUnlocked ?? 0) (query.data.value?.keyframes.identityUnlocked ?? 0)
) )
const staleKeyframes = computed(() => query.data.value?.keyframes.stalePrimaryKeyframe ?? 0)
/** 父页查询包含整个项目的就绪统计,单镜头变更后立即刷新。 */ /** 父页查询包含整个项目的就绪统计,单镜头变更后立即刷新。 */
function refreshProject() { function refreshProject() {
@@ -164,6 +169,9 @@ function refreshProject() {
<p v-if="staleKeyframes" class="alert mt-4" role="status"> <p v-if="staleKeyframes" class="alert mt-4" role="status">
当前有 {{ staleKeyframes }} 个主首帧已过期它们使用的主体参考资产已经变化视频阶段会被阻止可在下方逐镜重新生成或使用补齐 / 更新主首帧批量处理 当前有 {{ staleKeyframes }} 个主首帧已过期它们使用的主体参考资产已经变化视频阶段会被阻止可在下方逐镜重新生成或使用补齐 / 更新主首帧批量处理
</p> </p>
<p v-if="staleVideos" class="alert mt-4" role="status">
当前有 {{ staleVideos }} 个主视频已过期它们使用的主首帧或主体参考图已经变化非覆盖模式批量生成时会只重建这些过期主视频
</p>
<ProductionReceipt v-if="session.receipt" :receipt="session.receipt" /> <ProductionReceipt v-if="session.receipt" :receipt="session.receipt" />
<div v-if="query.data.value" class="production-pipeline mt-5"> <div v-if="query.data.value" class="production-pipeline mt-5">
@@ -209,6 +217,9 @@ function refreshProject() {
<p v-if="stage.key === 'keyframes' && staleKeyframes" class="mt-3 text-[11px] leading-5"> <p v-if="stage.key === 'keyframes' && staleKeyframes" class="mt-3 text-[11px] leading-5">
已过期 {{ staleKeyframes }} · 会按当前主体参考资产重新生成 已过期 {{ staleKeyframes }} · 会按当前主体参考资产重新生成
</p> </p>
<p v-if="stage.key === 'videos' && staleVideos" class="mt-3 text-[11px] leading-5">
主视频已过期 {{ staleVideos }} · 会按当前主首帧与参考资产重新生成
</p>
<p v-if="stage.key === 'keyframes' && identityBlocked" class="mt-3 text-[11px] leading-5 text-danger"> <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.missingIdentity ?? 0 }} · 母版缺失
{{ query.data.value?.keyframes.missingIdentityAnchor ?? 0 }} · 未锁定 {{ query.data.value?.keyframes.missingIdentityAnchor ?? 0 }} · 未锁定
@@ -221,7 +232,9 @@ function refreshProject() {
acknowledgement acknowledgement
:description=" :description="
stage.key === 'videos' stage.key === 'videos'
? '只为当前就绪镜头创建 Seedance 异步任务。创建成功不代表视频已经完成,任务会在后台继续运行。' ? staleVideos
? '当前存在过期主视频,非覆盖模式只会为这些镜头创建新的 Seedance 任务;新视频完成后会自动接替过期主视频。'
: '只为当前就绪镜头创建 Seedance 异步任务。创建成功不代表视频已经完成,任务会在后台继续运行。'
: stage.key === 'keyframes' : stage.key === 'keyframes'
? '处理缺失主首帧和参考资产已变化的过期主首帧。过期镜头会按当前主体参考资产重新生成并恢复为可用于视频的主首帧;覆盖模式只新增候选。' ? '处理缺失主首帧和参考资产已变化的过期主首帧。过期镜头会按当前主体参考资产重新生成并恢复为可用于视频的主首帧;覆盖模式只新增候选。'
: '只处理通过视频提示词就绪检查的镜头;覆盖模式会重写已有提示词。' : '只处理通过视频提示词就绪检查的镜头;覆盖模式会重写已有提示词。'
@@ -246,26 +259,11 @@ function refreshProject() {
/> />
</div> </div>
<dl class="production-status-grid mt-4"> <dl class="production-status-grid mt-4">
<div> <div><dt>完成</dt><dd>{{ query.data.value.videoStatus.completed }}</dd></div>
<dt></dt> <div><dt>排队</dt><dd>{{ videoRunning }}</dd></div>
<dd>{{ query.data.value.videoStatus.completed }}</dd> <div><dt>失败</dt><dd>{{ query.data.value.videoStatus.failed }}</dd></div>
</div> <div><dt>取消</dt><dd>{{ query.data.value.videoStatus.cancelled }}</dd></div>
<div> <div><dt>未开始</dt><dd>{{ query.data.value.videoStatus.notStarted }}</dd></div>
<dt>排队生成</dt>
<dd>{{ videoRunning }}</dd>
</div>
<div>
<dt>失败</dt>
<dd>{{ query.data.value.videoStatus.failed }}</dd>
</div>
<div>
<dt>取消</dt>
<dd>{{ query.data.value.videoStatus.cancelled }}</dd>
</div>
<div>
<dt>未开始</dt>
<dd>{{ query.data.value.videoStatus.notStarted }}</dd>
</div>
</dl> </dl>
</div> </div>
@@ -294,19 +292,19 @@ function refreshProject() {
> >
<CircleAlert :size="12" />主首帧已过期 <CircleAlert :size="12" />主首帧已过期
</span> </span>
<span
v-else-if="query.data.value?.videos.items.find(row => row.shotId === item.shotId)?.primaryVideoStale"
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"> <span v-else class="mt-2 flex items-center gap-2 text-[10px] text-muted">
<CheckCircle2 <CheckCircle2
v-if=" v-if="query.data.value?.videos.items.find(row => row.shotId === item.shotId)?.status === 'skipped'"
query.data.value?.videos.items.find(row => row.shotId === item.shotId)?.status ===
'skipped'
"
:size="12" :size="12"
/> />
<CircleAlert <CircleAlert
v-else-if=" v-else-if="query.data.value?.videos.items.find(row => row.shotId === item.shotId)?.status === 'blocked'"
query.data.value?.videos.items.find(row => row.shotId === item.shotId)?.status ===
'blocked'
"
:size="12" :size="12"
/> />
{{ {{
@@ -336,6 +334,9 @@ function refreshProject() {
<p v-if="keyframeItem?.primaryKeyframeStale" class="alert mt-4 text-xs" role="status"> <p v-if="keyframeItem?.primaryKeyframeStale" class="alert mt-4 text-xs" role="status">
主首帧已过期当前主体参考资产与生成该首帧时不一致旧首帧会保留但不能继续用于视频生成 主首帧已过期当前主体参考资产与生成该首帧时不一致旧首帧会保留但不能继续用于视频生成
</p> </p>
<p v-if="videoItem?.primaryVideoStale" 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"> <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}`"> <li v-for="(issue, index) in selectedIssues" :key="`${issue.code}-${index}`">
{{ issueLabel(issue.code) }}{{ issue.reason }} {{ issueLabel(issue.code) }}{{ issue.reason }}
@@ -365,4 +366,4 @@ function refreshProject() {
正在检查全项目生产就绪状态 正在检查全项目生产就绪状态
</p> </p>
</section> </section>
</template> </template>