73 lines
2.8 KiB
TypeScript
73 lines
2.8 KiB
TypeScript
import { reactive } from 'vue'
|
|
import type { ProductionIssueCode, ProductionSession, ShotKeyframe, ShotVideo } from './types'
|
|
|
|
/** 按项目隔离生产回执,切换页面后仍能查看上一次批量操作结果。 */
|
|
const sessions = reactive<Record<string, ProductionSession>>({})
|
|
|
|
/** 取得项目的生产页会话容器。 */
|
|
export function getProductionSession(projectId: string): ProductionSession {
|
|
return (sessions[projectId] ??= { receipt: null })
|
|
}
|
|
|
|
/** 生成规格尺寸必须成对留空或成对填写正整数。 */
|
|
export function validOptionalSize(width: number | '', height: number | ''): boolean {
|
|
if (width === '' && height === '') return true
|
|
return (
|
|
Number.isSafeInteger(width) &&
|
|
Number.isSafeInteger(height) &&
|
|
typeof width === 'number' &&
|
|
typeof height === 'number' &&
|
|
width > 0 &&
|
|
height > 0
|
|
)
|
|
}
|
|
|
|
/** 返回当前成功主首帧;异常的重复主图只取最新列表中的第一条。 */
|
|
export function primaryKeyframe(items: ShotKeyframe[]): ShotKeyframe | undefined {
|
|
return items.find(item => item.isPrimary && item.status === 'completed' && item.imageUrl)
|
|
}
|
|
|
|
/** 返回当前成功主视频。 */
|
|
export function primaryVideo(items: ShotVideo[]): ShotVideo | undefined {
|
|
return items.find(item => item.isPrimary && item.status === 'completed' && item.videoUrl)
|
|
}
|
|
|
|
/** 活动视频状态与后端重复任务保护保持一致。 */
|
|
export function isActiveVideo(item: ShotVideo): boolean {
|
|
return ['pending', 'queued', 'running'].includes(item.status)
|
|
}
|
|
|
|
/** 就绪问题转为短标签,后端详细 reason 仍在页面原样显示。 */
|
|
export function issueLabel(code: ProductionIssueCode): string {
|
|
const labels: Record<ProductionIssueCode, string> = {
|
|
invalid_generation_spec: '生成规格不完整',
|
|
missing_visual_style: '缺少视觉风格',
|
|
missing_reference: '缺少主体参考图',
|
|
missing_identity: '缺少角色身份',
|
|
missing_identity_anchor: '缺少演员母版',
|
|
identity_unlocked: '演员身份未锁定',
|
|
missing_prompt: '缺少视频提示词',
|
|
missing_keyframe: '缺少主首帧',
|
|
stale_keyframe: '主首帧已过期'
|
|
}
|
|
return labels[code]
|
|
}
|
|
|
|
/** 生产状态中文标签,未知值由状态组件回退显示原文。 */
|
|
export function productionStatusLabel(status: string): string {
|
|
const labels: Record<string, string> = {
|
|
ready: '已就绪',
|
|
skipped: '已有结果',
|
|
in_progress: '任务进行中',
|
|
blocked: '前置条件不足',
|
|
pending: '等待提交',
|
|
queued: '排队中',
|
|
running: '生成中',
|
|
completed: '已完成',
|
|
failed: '失败',
|
|
cancelled: '已取消',
|
|
not_started: '未开始'
|
|
}
|
|
return labels[status] ?? status
|
|
}
|