celery 容灾升级

This commit is contained in:
2026-07-22 14:48:29 +08:00
parent 3f1c4063b0
commit 69e7dec807
67 changed files with 6161 additions and 1958 deletions
@@ -0,0 +1,181 @@
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();
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';
};
const firstMatching = (values: string[], keys: Set<string>): string => (
values.find((value) => keys.has(value)) || ''
);
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);
let effectiveKey = '';
if (failureKey) {
effectiveKey = failureKey;
} else if (deletedKey) {
effectiveKey = deletedKey;
} else if (ACTIVE_PIPELINE_STAGES.has(pipelineStage)) {
effectiveKey = pipelineStage;
} else if (successKey) {
effectiveKey = successKey;
} else if (pipelineStage) {
effectiveKey = pipelineStage;
} else {
effectiveKey = 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;
@@ -0,0 +1,77 @@
export interface ShotStatusLike {
status?: string | null;
analysisStatus?: string | null;
analysis_status?: string | null;
splitStatus?: string | null;
split_status?: string | null;
moduleProjectStatus?: string | null;
module_project_status?: string | null;
}
export interface ShotStatusMeta {
key: string;
label: string;
color: string;
active: boolean;
terminal: boolean;
failure: boolean;
}
const ANALYSIS_META: Record<string, Omit<ShotStatusMeta, 'key'>> = {
not_required: { label: '无需单独分析', color: 'default', active: false, terminal: true, failure: false },
pending: { label: '等待分析', color: 'default', active: true, terminal: false, failure: false },
processing: { label: '分析中', color: 'processing', active: true, terminal: false, failure: false },
completed: { label: '分析完成', color: 'success', active: false, terminal: true, failure: false },
failed: { label: '分析失败', color: 'error', active: false, terminal: true, failure: true },
};
const SPLIT_META: Record<string, Omit<ShotStatusMeta, 'key'>> = {
pending: { label: '等待切割', color: 'default', active: true, terminal: false, failure: false },
processing: { label: '切割中', color: 'processing', active: true, terminal: false, failure: false },
retry_waiting: { label: '等待切割重试', color: 'warning', active: true, terminal: false, failure: false },
completed: { label: '切割完成', color: 'success', active: false, terminal: true, failure: false },
failed: { label: '切割失败', color: 'error', active: false, terminal: true, failure: true },
};
const TASK_META: Record<string, Omit<ShotStatusMeta, 'key'>> = {
pending_analysis: { label: '等待分析', color: 'default', active: true, terminal: false, failure: false },
analyzing: { label: '分析中', color: 'processing', active: true, terminal: false, failure: false },
analysis_completed: { label: '分析完成', color: 'blue', active: false, terminal: false, failure: false },
analysis_failed: { label: '分析失败', color: 'error', active: false, terminal: true, failure: true },
splitting: { label: '拆镜中', color: 'processing', active: true, terminal: false, failure: false },
split_completed: { label: '拆镜完成', color: 'success', active: false, terminal: true, failure: false },
partial_failed: { label: '部分失败', color: 'warning', active: false, terminal: true, failure: true },
failed: { label: '失败', color: 'error', active: false, terminal: true, failure: true },
deleted: { label: '已删除', color: 'default', active: false, terminal: true, failure: false },
};
const MODULE_ACTIVE = new Set(['pending', 'waiting_user', 'processing']);
const normalize = (value?: string | null): string => String(value || '').trim().toLowerCase();
const buildMeta = (key: string, map: Record<string, Omit<ShotStatusMeta, 'key'>>, fallback: string): ShotStatusMeta => ({
key,
...(map[key] || { label: key || fallback, color: 'default', active: false, terminal: false, failure: false }),
});
export const getShotAnalysisStatusMeta = (status?: string | null): ShotStatusMeta => {
const key = normalize(status);
return buildMeta(key, ANALYSIS_META, '未知分析状态');
};
export const getShotSplitStatusMeta = (status?: string | null): ShotStatusMeta => {
const key = normalize(status);
return buildMeta(key, SPLIT_META, '未知切割状态');
};
export const getShotTaskStatusMeta = (status?: string | null): ShotStatusMeta => {
const key = normalize(status);
return buildMeta(key, TASK_META, '未知任务状态');
};
export const isShotSegmentActive = (item: ShotStatusLike): boolean => {
const analysisStatus = normalize(item.analysisStatus || item.analysis_status);
const splitStatus = normalize(item.splitStatus || item.split_status);
const moduleStatus = normalize(item.moduleProjectStatus || item.module_project_status);
return getShotAnalysisStatusMeta(analysisStatus).active
|| getShotSplitStatusMeta(splitStatus).active
|| MODULE_ACTIVE.has(moduleStatus);
};