feat: 同步精简接口并统一表单校验

This commit is contained in:
GJ
2026-09-10 22:34:47 +08:00
parent 82d7bde631
commit 2eea0ea72e
66 changed files with 1611 additions and 1100 deletions
+7 -48
View File
@@ -1,10 +1,12 @@
import { reactive } from 'vue'
import { validOptionalSize } from './model'
import type { KeyframeReadiness } from './types'
import type { QualityInput, QualityReceipt, QualityTarget, VisualValidation } from './quality.types'
import type { QualityInput, QualityReceipt, QualityTarget, VisualValidation, VideoValidation } from './quality.types'
/** 未返回的操作不显示上次成功结论;网络失败不会自动重发。 */
const sessions = reactive<Record<string, { receipt: QualityReceipt | null; error: string }>>({})
const sessions = reactive<
Record<string, { receipt: QualityReceipt | null; error: string; videoValidation?: VideoValidation }>
>({})
/** 正式 ID 与目标类型共同隔离会话结果,批量回执按剧集隔离。 */
export function qualityKey(projectId: string, target: QualityTarget | null) {
@@ -83,50 +85,7 @@ export function isVisualValidation(value: unknown): value is VisualValidation {
)
}
/** 读取视频已保存的抽样校验,不为查看历史再次调用视觉模型。 */
export function savedVideoValidation(rawJson?: string | null): VisualValidation | null {
try {
const value: unknown = JSON.parse(rawJson || '{}').videoValidation
return isVisualValidation(value) ? value : null
} catch {
return null
}
}
/** 识别后端修复候选标记,避免未复检候选通过普通主视频按钮绕过校验。 */
export function videoRepairInfo(rawJson?: string | null): { attempt: number } | null {
try {
const repair: unknown = JSON.parse(rawJson || '{}').repair
if (!repair || typeof repair !== 'object' || Array.isArray(repair)) return null
const attempt = (repair as { attempt?: unknown }).attempt
return { attempt: typeof attempt === 'number' && Number.isSafeInteger(attempt) && attempt >= 0 ? attempt : 0 }
} catch {
return null
}
}
/** 识别严格质量候选及其自动修复配置,防止未通过候选被手动绕过校验设为主视频。 */
export function videoQualityInfo(
rawJson?: string | null
): { allowedTexts: string[]; maxRepairAttempts: number } | null {
try {
const snapshot: unknown = JSON.parse(rawJson || '{}')
if (!snapshot || typeof snapshot !== 'object' || Array.isArray(snapshot)) return null
const record = snapshot as Record<string, unknown>
if (record.qualityCandidate !== true) return null
const pipeline = record.qualityPipeline
if (!pipeline || typeof pipeline !== 'object' || Array.isArray(pipeline)) return null
const config = pipeline as Record<string, unknown>
const maxRepairAttempts = config.maxRepairAttempts
if (typeof maxRepairAttempts !== 'number' || !Number.isSafeInteger(maxRepairAttempts) || maxRepairAttempts <= 0)
return null
return {
allowedTexts: Array.isArray(config.allowedTexts)
? config.allowedTexts.filter((item): item is string => typeof item === 'string')
: [],
maxRepairAttempts
}
} catch {
return null
}
/** 公开视频 DTO 不含质量历史,只使用本会话真实收到的校验回执。 */
export function sessionVideoValidation(projectId: string, shotId: string, assetId: string): VideoValidation | null {
return qualitySession(qualityKey(projectId, { kind: 'video', shotId, assetId, title: '' })).videoValidation ?? null
}