109 lines
6.1 KiB
Vue
109 lines
6.1 KiB
Vue
<script setup lang="ts">
|
||
import { NAlert, NButton, NCollapse, NCollapseItem } from 'naive-ui'
|
||
import { computed, ref, watch } from 'vue'
|
||
import ConfirmAction from '../../workflows/ConfirmAction.vue'
|
||
import { downloadText, formatDate } from '../../../lib/format'
|
||
import { useAdvancedProduction } from '../useAdvancedProduction'
|
||
|
||
/** 高级入口明确真实流程边界,默认折叠且不在挂载时触发预检或生成。 */
|
||
const { id, operation, session, checking, error, check, blocked, preflight, start } = useAdvancedProduction()
|
||
const receipt = computed(() => session.value.pipelineReceipt)
|
||
const expanded = ref<string[]>([])
|
||
watch(
|
||
receipt,
|
||
value => {
|
||
if (value) expanded.value = ['advanced']
|
||
},
|
||
{ immediate: true }
|
||
)
|
||
const rows = computed(() => [
|
||
{ name: '形态正式提示词', result: receipt.value?.visualPromptResult },
|
||
{ name: '形态参考图', result: receipt.value?.subjectImageResult },
|
||
{ name: '视频提示词', result: receipt.value?.videoPromptResult }
|
||
])
|
||
/** 导出实际后端回执,不把流程完成转换为视频完成。 */
|
||
function exportReceipt() {
|
||
if (receipt.value)
|
||
downloadText(`project-${id.value}-pipeline.json`, JSON.stringify(receipt.value, null, 2), 'application/json')
|
||
}
|
||
</script>
|
||
<template>
|
||
<NCollapse v-model:expanded-names="expanded" class="mt-5"
|
||
><NCollapseItem name="advanced" title="高级:串联生产(全项目)">
|
||
<NAlert type="warning" :show-icon="false"
|
||
>依次补齐形态提示词、形态参考图、视频提示词并提交视频任务。不会生成视觉风格、身份母版、导演设计、即时状态或首帧。请先在各阶段完成验收。</NAlert
|
||
>
|
||
<p class="mt-3 text-xs leading-6 text-muted">
|
||
范围固定为全项目,跳过已有结果;不使用上方并发、覆盖、数量上限和尺寸配置。后端固定文字并发
|
||
3、图片和视频并发 2,可能产生模型费用。此流程没有持久运行锁或恢复
|
||
checkpoint;请确认其他页面/终端没有任务。断网后先查资产,勿直接重试。
|
||
</p>
|
||
<div class="mt-4 flex flex-wrap items-center gap-3">
|
||
<NButton :disabled="blocked || checking" :loading="checking" @click="preflight"
|
||
>检查串联生产条件</NButton
|
||
>
|
||
<ConfirmAction
|
||
label="启动串联生产"
|
||
:disabled="blocked || checking || !check || !!check.issues.length"
|
||
acknowledgement
|
||
:description="`项目 ${id}:全项目串联生产,不生成首帧,也不等待视频完成。确认后会重新检查前置条件;可能产生文字、图片和视频模型费用。`"
|
||
@confirm="start"
|
||
/>
|
||
</div>
|
||
<NAlert v-if="error" type="error" class="mt-3" :show-icon="false">{{ error }}</NAlert>
|
||
<NAlert
|
||
v-if="operation.label === '高级串联生产' && operation.error"
|
||
type="error"
|
||
class="mt-3"
|
||
:show-icon="false"
|
||
>{{ operation.error }}</NAlert
|
||
>
|
||
<div v-if="check" class="surface-inset mt-3 p-4">
|
||
<p class="text-xs text-muted">{{ formatDate(check.checkedAt) }} · 检查 {{ check.shotCount }} 镜</p>
|
||
<ul v-if="check.issues.length" class="mt-2 space-y-2 text-xs text-danger">
|
||
<li v-for="issue in check.issues" :key="issue">{{ issue }}</li>
|
||
</ul>
|
||
<p v-else class="mt-2 text-sm">前置检查通过,提交前仍会再次校验。</p>
|
||
</div>
|
||
<p v-if="operation.pending && operation.label === '高级串联生产'" role="status" class="mt-3 text-sm">
|
||
请求进行中;关闭面板不会取消后端任务,请勿重复提交。
|
||
</p>
|
||
<section v-if="receipt" aria-label="串联生产回执" class="surface-inset mt-4 p-4">
|
||
<div class="flex items-center justify-between gap-3">
|
||
<h3 class="text-sm font-semibold">
|
||
串联生产回执 ·
|
||
{{
|
||
receipt.needsManualReview ? '需要人工处理' : receipt.completed ? '流程已返回' : '流程未完成'
|
||
}}
|
||
</h3>
|
||
<NButton text size="small" @click="exportReceipt">导出回执</NButton>
|
||
</div>
|
||
<p class="mt-3 text-xs text-muted">
|
||
流程返回不等于成片完成。已保存结果不会回滚,最终结果以各资产页为准。
|
||
</p>
|
||
<p v-for="row in rows" :key="row.name" class="mt-2 text-xs">
|
||
{{ row.name }}:<template v-if="row.result"
|
||
>共 {{ row.result.total }} · 生成 {{ row.result.generated }} · 跳过 {{ row.result.skipped }} ·
|
||
失败 {{ row.result.failed }}</template
|
||
><template v-else>未执行或未返回</template>
|
||
</p>
|
||
<p class="mt-2 text-xs">
|
||
视频任务:<template v-if="receipt.videoGenerationResult"
|
||
>共 {{ receipt.videoGenerationResult.total }} · 已提交
|
||
{{ receipt.videoGenerationResult.created }} · 跳过 {{ receipt.videoGenerationResult.skipped }} ·
|
||
提交失败 {{ receipt.videoGenerationResult.failed }}</template
|
||
><template v-else>未执行或未返回</template>
|
||
</p>
|
||
<NAlert
|
||
v-if="receipt.stopReason || receipt.errors.length"
|
||
type="warning"
|
||
:show-icon="false"
|
||
class="mt-3"
|
||
><p>{{ receipt.stopReason }}</p>
|
||
<p v-for="(item, index) in receipt.errors" :key="index" class="mt-2">{{ item }}</p></NAlert
|
||
>
|
||
</section>
|
||
</NCollapseItem></NCollapse
|
||
>
|
||
</template>
|