feat: 同步精简接口并统一表单校验
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import AppForm from '../../components/ui/AppForm.vue'
|
||||
import { NFormItem } from 'naive-ui'
|
||||
import { integerRule, sizeRules } from '../../lib/form-rules'
|
||||
import WorkspacePage from '../../components/ui/WorkspacePage.vue'
|
||||
import WorkspaceTools from '../../components/ui/WorkspaceTools.vue'
|
||||
import {
|
||||
@@ -164,6 +167,21 @@ watch(
|
||||
if (receipt) toolsOpen.value = true
|
||||
}
|
||||
)
|
||||
const batchModel = computed(() => ({ concurrency: concurrency.value }))
|
||||
const batchRules = { concurrency: integerRule('批量并发') }
|
||||
const keyframeModel = computed(() => ({
|
||||
keyframeLimit: keyframeLimit.value,
|
||||
keyframeWidth: keyframeWidth.value,
|
||||
keyframeHeight: keyframeHeight.value
|
||||
}))
|
||||
const dimensionRules = sizeRules(() => ({ width: keyframeWidth.value, height: keyframeHeight.value }))
|
||||
const keyframeRules = {
|
||||
keyframeLimit: integerRule('本批上限', 1, true),
|
||||
keyframeWidth: dimensionRules.width,
|
||||
keyframeHeight: dimensionRules.height
|
||||
}
|
||||
const videoModel = computed(() => ({ videoLimit: videoLimit.value, videoRepairAttempts: videoRepairAttempts.value }))
|
||||
const videoRules = { videoLimit: integerRule('本批镜头上限'), videoRepairAttempts: integerRule('每镜最多自动修复') }
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -219,25 +237,31 @@ watch(
|
||||
</RouterLink>
|
||||
</div>
|
||||
<section class="mt-3" aria-label="项目生产配置">
|
||||
<div class="production-controls">
|
||||
<label>
|
||||
<span class="field-label">批量并发</span>
|
||||
<NInputNumber
|
||||
<AppForm
|
||||
:model="batchModel"
|
||||
:rules="batchRules"
|
||||
:disabled="operation.pending"
|
||||
validate-on-change
|
||||
>
|
||||
<div class="form-controls production-controls">
|
||||
<NFormItem path="concurrency" label="批量并发">
|
||||
<NInputNumber
|
||||
:input-props="{ 'aria-label': '批量并发' }"
|
||||
:disabled="operation.pending"
|
||||
:value="typeof concurrency === 'number' ? concurrency : null"
|
||||
@update:value="concurrency = $event ?? 0"
|
||||
:min="1"
|
||||
:step="1"
|
||||
></NInputNumber>
|
||||
</NFormItem>
|
||||
<NCheckbox
|
||||
v-model:checked="force"
|
||||
:disabled="operation.pending"
|
||||
:value="typeof concurrency === 'number' ? concurrency : null"
|
||||
@update:value="concurrency = $event ?? 0"
|
||||
:min="1"
|
||||
:step="1"
|
||||
></NInputNumber>
|
||||
<span v-if="!batchValid" class="mt-1 block text-xs text-danger">请输入正整数</span>
|
||||
</label>
|
||||
<NCheckbox
|
||||
v-model:checked="force"
|
||||
:disabled="operation.pending"
|
||||
class="control-row-checkbox text-xs"
|
||||
>覆盖模式:重写提示词/新增图视频候选
|
||||
</NCheckbox>
|
||||
</div>
|
||||
class="control-row-checkbox text-xs"
|
||||
>覆盖模式:重写提示词/新增图视频候选
|
||||
</NCheckbox>
|
||||
</div>
|
||||
</AppForm>
|
||||
<DetailDisclosure title="处理范围与覆盖规则" class="mt-3"
|
||||
><p class="text-xs leading-6 text-muted">
|
||||
提示词与视频就绪检查面向全项目;视频实际提交受本批镜头上限控制,并使用严格质量流水线。首帧默认补当前剧集,存在过期主首帧时优先更新全项目过期项,覆盖模式处理全项目;过期首帧成功后会自动接替旧主图,其余新增候选。图片模型、视频模型与视觉校验均可能产生费用。
|
||||
@@ -393,63 +417,69 @@ watch(
|
||||
:primary="stage.key === 'videos'"
|
||||
@confirm="run(stage.key)"
|
||||
/>
|
||||
<div v-if="stage.key === 'keyframes'" class="mt-4 grid gap-3">
|
||||
<label
|
||||
><span class="field-label">本批上限(可选)</span
|
||||
<AppForm
|
||||
v-if="stage.key === 'keyframes'"
|
||||
:model="keyframeModel"
|
||||
:rules="keyframeRules"
|
||||
:disabled="operation.pending"
|
||||
validate-on-change
|
||||
class="mt-4 grid gap-3"
|
||||
>
|
||||
<NFormItem path="keyframeLimit" label="本批上限(可选)"
|
||||
><NInputNumber
|
||||
:input-props="{ 'aria-label': '本批上限(可选)' }"
|
||||
:value="keyframeLimit === '' ? null : keyframeLimit"
|
||||
@update:value="keyframeLimit = $event ?? ''"
|
||||
:min="1"
|
||||
:precision="0"
|
||||
:disabled="operation.pending"
|
||||
placeholder="留空不限制"
|
||||
/></label>
|
||||
/></NFormItem>
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<label
|
||||
><span class="field-label">宽度(像素)</span
|
||||
<NFormItem path="keyframeWidth" label="宽度(像素)"
|
||||
><NInputNumber
|
||||
:input-props="{ 'aria-label': '宽度(像素)' }"
|
||||
:value="keyframeWidth === '' ? null : keyframeWidth"
|
||||
@update:value="keyframeWidth = $event ?? ''"
|
||||
:min="1"
|
||||
:disabled="operation.pending"
|
||||
placeholder="默认" /></label
|
||||
><label
|
||||
><span class="field-label">高度(像素)</span
|
||||
placeholder="默认" /></NFormItem
|
||||
><NFormItem path="keyframeHeight" label="高度(像素)"
|
||||
><NInputNumber
|
||||
:input-props="{ 'aria-label': '高度(像素)' }"
|
||||
:value="keyframeHeight === '' ? null : keyframeHeight"
|
||||
@update:value="keyframeHeight = $event ?? ''"
|
||||
:min="1"
|
||||
:disabled="operation.pending"
|
||||
placeholder="默认"
|
||||
/></label>
|
||||
/></NFormItem>
|
||||
</div>
|
||||
<p v-if="!keyframeValid" class="text-xs text-danger">
|
||||
上限须为正整数;宽高须同时留空或填写正整数。
|
||||
</p>
|
||||
</div>
|
||||
<div v-if="stage.key === 'videos'" class="mt-4 grid gap-3">
|
||||
<label
|
||||
><span class="field-label">本批镜头上限</span
|
||||
</AppForm>
|
||||
<AppForm
|
||||
v-if="stage.key === 'videos'"
|
||||
:model="videoModel"
|
||||
:rules="videoRules"
|
||||
:disabled="operation.pending"
|
||||
validate-on-change
|
||||
class="mt-4 grid gap-3"
|
||||
>
|
||||
<NFormItem path="videoLimit" label="本批镜头上限"
|
||||
><NInputNumber
|
||||
v-model:value="videoLimit"
|
||||
:min="1"
|
||||
:precision="0"
|
||||
:disabled="operation.pending"
|
||||
:input-props="{ 'aria-label': '视频质量任务镜头上限' }"
|
||||
/></label>
|
||||
<label
|
||||
><span class="field-label">每镜最多自动修复</span
|
||||
/></NFormItem>
|
||||
<NFormItem path="videoRepairAttempts" label="每镜最多自动修复"
|
||||
><NInputNumber
|
||||
v-model:value="videoRepairAttempts"
|
||||
:min="1"
|
||||
:precision="0"
|
||||
:disabled="operation.pending"
|
||||
:input-props="{ 'aria-label': '视频自动修复次数' }"
|
||||
/></label>
|
||||
<p v-if="!videoQualityValid" class="text-xs text-danger">
|
||||
本批上限和自动修复次数都必须是正整数。
|
||||
</p>
|
||||
</div>
|
||||
/></NFormItem>
|
||||
</AppForm>
|
||||
</article>
|
||||
</div>
|
||||
<div v-if="query.data.value" class="panel mt-4 p-5">
|
||||
@@ -466,7 +496,7 @@ watch(
|
||||
blocked || !batchValid || !query.data.value.videoStatus.failed
|
||||
"
|
||||
acknowledgement
|
||||
description="为当前最近一次状态为失败的镜头重新创建视频模型任务。成功镜头和进行中的镜头不会处理。"
|
||||
description="仅重新提交后端判定可重试的失败视频;不可重试项会跳过,并在回执中显示数量。"
|
||||
@confirm="run('retry-videos')"
|
||||
/>
|
||||
</div>
|
||||
@@ -591,6 +621,18 @@ 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="videoStatusItem?.status === 'failed'"
|
||||
type="error"
|
||||
:show-icon="false"
|
||||
class="mt-3"
|
||||
>
|
||||
{{ videoStatusItem.error || '最近一次视频任务失败' }}
|
||||
<p v-if="videoStatusItem.retryable === false" class="mt-2">
|
||||
此失败不支持普通重试,请先处理失败原因。
|
||||
</p>
|
||||
<p v-else-if="videoStatusItem.retryable === true" class="mt-2">后端允许重试此任务。</p>
|
||||
</NAlert>
|
||||
<StaleKeyframeNotice
|
||||
v-if="selectedKeyframeStale"
|
||||
:key="shot.shotId"
|
||||
|
||||
Reference in New Issue
Block a user