feat: 单镜头展示过期主视频
This commit is contained in:
@@ -67,6 +67,7 @@ const canGenerateVideo = computed(
|
|||||||
!assetBlocked.value && !activeVideo.value && !!props.videoReadiness && props.videoReadiness.issues.length === 0
|
!assetBlocked.value && !activeVideo.value && !!props.videoReadiness && props.videoReadiness.issues.length === 0
|
||||||
)
|
)
|
||||||
const keyframeStale = computed(() => !!props.keyframeReadiness?.primaryKeyframeStale)
|
const keyframeStale = computed(() => !!props.keyframeReadiness?.primaryKeyframeStale)
|
||||||
|
const videoStale = computed(() => !!props.videoReadiness?.primaryVideoStale)
|
||||||
|
|
||||||
watch(key, () => {
|
watch(key, () => {
|
||||||
confirmingKeyframe.value = ''
|
confirmingKeyframe.value = ''
|
||||||
@@ -265,9 +266,7 @@ async function inspectSpecs() {
|
|||||||
<StatusBadge :status="item.status" :label="productionStatusLabel(item.status)" />
|
<StatusBadge :status="item.status" :label="productionStatusLabel(item.status)" />
|
||||||
<span v-if="item.isPrimary" class="tag">主首帧</span>
|
<span v-if="item.isPrimary" class="tag">主首帧</span>
|
||||||
<span v-if="item.isPrimary && keyframeStale" class="tag">已过期</span>
|
<span v-if="item.isPrimary && keyframeStale" class="tag">已过期</span>
|
||||||
<span class="text-[10px] text-muted"
|
<span class="text-[10px] text-muted">{{ item.width || '—' }} × {{ item.height || '—' }}</span>
|
||||||
>{{ item.width || '—' }} × {{ item.height || '—' }}</span
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
<p v-if="item.error" class="mt-2 line-clamp-3 text-xs text-danger">{{ item.error }}</p>
|
<p v-if="item.error" class="mt-2 line-clamp-3 text-xs text-danger">{{ item.error }}</p>
|
||||||
<p class="mt-2 text-[10px] text-muted">{{ formatDate(item.createdAt) }}</p>
|
<p class="mt-2 text-[10px] text-muted">{{ formatDate(item.createdAt) }}</p>
|
||||||
@@ -304,9 +303,12 @@ async function inspectSpecs() {
|
|||||||
<StatusBadge
|
<StatusBadge
|
||||||
v-if="videoReadiness"
|
v-if="videoReadiness"
|
||||||
:status="videoReadiness.status"
|
:status="videoReadiness.status"
|
||||||
:label="productionStatusLabel(videoReadiness.status)"
|
:label="videoStale ? '主视频已过期' : productionStatusLabel(videoReadiness.status)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<p v-if="videoStale" class="alert mt-3 text-xs" role="status">
|
||||||
|
当前主视频使用的主首帧或主体参考图已经变化。旧视频仍保留;重新生成完成后,新视频会自动接替过期主视频。
|
||||||
|
</p>
|
||||||
<ul v-if="videoReadiness?.issues.length" class="mt-3 space-y-2 text-xs text-danger">
|
<ul v-if="videoReadiness?.issues.length" class="mt-3 space-y-2 text-xs text-danger">
|
||||||
<li v-for="issue in videoReadiness.issues" :key="issue.code">
|
<li v-for="issue in videoReadiness.issues" :key="issue.code">
|
||||||
{{ issueLabel(issue.code) }}:{{ issue.reason }}
|
{{ issueLabel(issue.code) }}:{{ issue.reason }}
|
||||||
@@ -325,9 +327,8 @@ async function inspectSpecs() {
|
|||||||
<div class="flex flex-wrap items-center gap-2">
|
<div class="flex flex-wrap items-center gap-2">
|
||||||
<StatusBadge :status="item.status" :label="productionStatusLabel(item.status)" />
|
<StatusBadge :status="item.status" :label="productionStatusLabel(item.status)" />
|
||||||
<span v-if="item.isPrimary" class="tag">主视频</span>
|
<span v-if="item.isPrimary" class="tag">主视频</span>
|
||||||
<span class="text-[10px] text-muted"
|
<span v-if="item.isPrimary && videoStale" class="tag">已过期</span>
|
||||||
>{{ item.durationSeconds || shot.durationSeconds || '—' }}s</span
|
<span class="text-[10px] text-muted">{{ item.durationSeconds || shot.durationSeconds || '—' }}s</span>
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
<p v-if="item.error" class="alert alert-error mt-3" role="alert">{{ item.error }}</p>
|
<p v-if="item.error" class="alert alert-error mt-3" role="alert">{{ item.error }}</p>
|
||||||
<p class="mt-3 break-all text-[10px] text-muted">
|
<p class="mt-3 break-all text-[10px] text-muted">
|
||||||
@@ -340,8 +341,8 @@ async function inspectSpecs() {
|
|||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
class="text-button"
|
class="text-button"
|
||||||
>打开视频<ExternalLink :size="12"
|
>打开视频<ExternalLink :size="12" /></a
|
||||||
/></a>
|
>
|
||||||
<button
|
<button
|
||||||
v-if="item.status === 'completed' && item.videoUrl && !item.isPrimary"
|
v-if="item.status === 'completed' && item.videoUrl && !item.isPrimary"
|
||||||
class="text-button"
|
class="text-button"
|
||||||
@@ -364,13 +365,15 @@ async function inspectSpecs() {
|
|||||||
<p v-else class="mt-4 text-xs text-muted">尚无视频任务记录。</p>
|
<p v-else class="mt-4 text-xs text-muted">尚无视频任务记录。</p>
|
||||||
<div class="mt-4 flex flex-wrap gap-3">
|
<div class="mt-4 flex flex-wrap gap-3">
|
||||||
<ConfirmAction
|
<ConfirmAction
|
||||||
:label="currentVideo ? '再生成一个视频候选' : '提交本镜视频任务'"
|
:label="videoStale ? '重新生成主视频' : currentVideo ? '再生成一个视频候选' : '提交本镜视频任务'"
|
||||||
:disabled="!canGenerateVideo"
|
:disabled="!canGenerateVideo"
|
||||||
acknowledgement
|
acknowledgement
|
||||||
:description="
|
:description="
|
||||||
currentVideo
|
videoStale
|
||||||
? '使用当前视频提示词、主首帧和主体参考图新增一个 Seedance 视频候选,不自动替换主视频。'
|
? '使用当前视频提示词、主首帧和主体参考图重新创建 Seedance 任务;完成后会自动接替当前过期主视频。'
|
||||||
: '使用当前视频提示词、主首帧和主体参考图创建 Seedance 任务;任务会在后台继续运行。'
|
: currentVideo
|
||||||
|
? '使用当前视频提示词、主首帧和主体参考图新增一个 Seedance 视频候选,不自动替换主视频。'
|
||||||
|
: '使用当前视频提示词、主首帧和主体参考图创建 Seedance 任务;任务会在后台继续运行。'
|
||||||
"
|
"
|
||||||
primary
|
primary
|
||||||
@confirm="generateVideo"
|
@confirm="generateVideo"
|
||||||
@@ -425,4 +428,4 @@ async function inspectSpecs() {
|
|||||||
@generate="generateKeyframe"
|
@generate="generateKeyframe"
|
||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
Reference in New Issue
Block a user