Files
video-gen/video-gen-admin/src/utils/generationTaskStatus.ts
T
2026-07-22 14:53:03 +08:00

134 lines
5.3 KiB
TypeScript

export interface GenerationStatusLike {
status?: string | null;
displayStatus?: string | null;
pipelineStage?: string | null;
}
export type GenerationUiColor = 'default' | 'processing' | 'warning' | 'success' | 'error' | 'blue' | 'orange' | 'purple';
export interface GenerationUiState {
status: string;
displayStatus: string;
pipelineStage: string;
effectiveKey: string;
label: string;
color: GenerationUiColor;
isActive: boolean;
isSuccess: boolean;
isFailure: boolean;
isTerminal: boolean;
}
const ACTIVE_STATUS_KEYS = new Set(['pending', 'optimizing', 'prompt_optimized', 'generating']);
const ACTIVE_PIPELINE_STAGES = new Set([
'queued', 'preparing', 'creating_provider_task', 'provider_result_staged',
'waiting_remote', 'polling', 'result_ready', 'download_queued', 'downloading',
'retry_waiting', 'upscale_queued', 'upscale_processing', 'upscale_polling',
'upscale_downloading', 'upscale_finalizing', 'upscale_retry_waiting',
]);
const SUCCESS_KEYS = new Set(['completed', 'done']);
const FAILURE_KEYS = new Set(['failed', 'timeout', 'download_failed', 'upscale_failed']);
const TERMINAL_KEYS = new Set([...SUCCESS_KEYS, ...FAILURE_KEYS, 'deleted']);
const LABELS: Record<string, string> = {
pending: '待处理',
optimizing: '优化中',
prompt_optimized: '待生成',
generating: '生成中',
queued: '已入队',
preparing: '准备中',
creating_provider_task: '创建供应商任务',
provider_result_staged: '供应商结果已暂存',
waiting_remote: '等待供应商结果',
polling: '轮询供应商结果',
result_ready: '远程结果已就绪',
download_queued: '下载已入队',
downloading: '下载中',
retry_waiting: '下载等待重试',
upscale_queued: '超分已入队',
upscale_processing: '本地超分处理中',
upscale_polling: '轮询远程超分',
upscale_downloading: '下载超分结果',
upscale_finalizing: '超分结果最终化',
upscale_retry_waiting: '超分等待重试',
completed: '已完成',
done: '已完成',
timeout: '任务超时',
download_failed: '下载失败',
upscale_failed: '超分失败',
failed: '失败',
deleted: '已删除',
};
const COLOR_MAP: Record<string, GenerationUiColor> = {
pending: 'default', optimizing: 'processing', prompt_optimized: 'processing', generating: 'warning',
queued: 'processing', preparing: 'processing', creating_provider_task: 'processing',
provider_result_staged: 'processing', waiting_remote: 'processing', polling: 'processing',
result_ready: 'processing', download_queued: 'processing', downloading: 'processing',
retry_waiting: 'orange', upscale_queued: 'purple', upscale_processing: 'purple',
upscale_polling: 'purple', upscale_downloading: 'purple', upscale_finalizing: 'purple',
upscale_retry_waiting: 'orange', completed: 'success', done: 'success', failed: 'error',
timeout: 'error', download_failed: 'error', upscale_failed: 'error', deleted: 'default',
};
const normalize = (value?: string | null): string => String(value || '').trim().toLowerCase();
const firstMatching = (values: string[], keys: Set<string>): string => values.find((value) => keys.has(value)) || '';
export const getGenerationStageLabel = (key?: string | null): string => {
const normalized = normalize(key);
return LABELS[normalized] || normalized || '未知状态';
};
export const getGenerationStatusColor = (key?: string | null): GenerationUiColor => {
const normalized = normalize(key);
return COLOR_MAP[normalized] || 'default';
};
export const resolveGenerationUiState = (value: GenerationStatusLike): GenerationUiState => {
const status = normalize(value.status);
const displayStatus = normalize(value.displayStatus);
const pipelineStage = normalize(value.pipelineStage);
const values = [displayStatus, status, pipelineStage].filter(Boolean);
const failureKey = FAILURE_KEYS.has(pipelineStage)
? pipelineStage
: firstMatching([displayStatus, status], FAILURE_KEYS);
const deletedKey = firstMatching(values, new Set(['deleted']));
const successKey = firstMatching(values, SUCCESS_KEYS);
const effectiveKey = failureKey
|| deletedKey
|| (ACTIVE_PIPELINE_STAGES.has(pipelineStage) ? pipelineStage : '')
|| successKey
|| pipelineStage
|| displayStatus
|| status
|| 'pending';
const isFailure = FAILURE_KEYS.has(effectiveKey);
const isSuccess = SUCCESS_KEYS.has(effectiveKey);
const isActive = !isFailure && !isSuccess && effectiveKey !== 'deleted' && (
ACTIVE_PIPELINE_STAGES.has(pipelineStage)
|| ACTIVE_STATUS_KEYS.has(displayStatus)
|| ACTIVE_STATUS_KEYS.has(status)
|| ACTIVE_PIPELINE_STAGES.has(effectiveKey)
);
return {
status,
displayStatus,
pipelineStage,
effectiveKey,
label: getGenerationStageLabel(effectiveKey),
color: getGenerationStatusColor(effectiveKey),
isActive,
isSuccess,
isFailure,
isTerminal: TERMINAL_KEYS.has(effectiveKey),
};
};
export const isGenerationActive = (value: GenerationStatusLike): boolean => resolveGenerationUiState(value).isActive;
export const isGenerationSuccess = (value: GenerationStatusLike): boolean => resolveGenerationUiState(value).isSuccess;
export const isGenerationFailure = (value: GenerationStatusLike): boolean => resolveGenerationUiState(value).isFailure;
export const isGenerationTerminal = (value: GenerationStatusLike): boolean => resolveGenerationUiState(value).isTerminal;