feat(media): 作品保存恢复 - 按原任务重试交付并避免重复生成计费

This commit is contained in:
ddCat
2026-09-22 15:47:24 +08:00
parent acbb354e97
commit 48a82ded74
49 changed files with 1710 additions and 50 deletions

View File

@@ -30,7 +30,7 @@ import { modelCapabilityConfigFor } from "@/lib/model-capabilities";
import { navigateToSettings } from "@/lib/settings-navigation";
import type { Skill } from "@/services/api/skills";
import { skillRuntime, type SkillRuntimeMetadata } from "@/services/skill-runtime";
import type { GenerationTask } from "@/services/api/task-center";
import { queryGenerationTask, recoverGenerationTaskMedia, waitForGenerationTask, type GenerationTask } from "@/services/api/task-center";
import { resolveImageUrl } from "@/services/image-storage";
import { resolveModelRequestConfig, useConfigStore, useEffectiveConfig } from "@/stores/use-config-store";
import type { Asset } from "@/stores/use-asset-store";
@@ -75,6 +75,35 @@ export function useCanvasGenerationRetry({
return useCallback(
async (node: CanvasNodeData) => {
// Canvas caches may predate the failure. Consult the original task
// before deciding to submit another paid generation.
let sourceTask: GenerationTask | undefined;
if (node.metadata?.taskId) {
try {
sourceTask = await queryGenerationTask(node.metadata.taskId);
} catch (error) {
message.error(error instanceof Error ? error.message : "无法核对原任务,请稍后重试");
return;
}
}
if (sourceTask?.mediaStage && sourceTask.status !== "cancelled") {
const controller = startGenerationRequest(node.id, node.id, node.id);
try {
const initialTask = sourceTask.status === "failed" ? await recoverGenerationTaskMedia(sourceTask.id) : sourceTask;
if (controller.signal.aborted) return;
bindGenerationTask(node.id, initialTask);
const completed = await waitForGenerationTask(initialTask.id, {
initialTask, signal: controller.signal, timeoutMs: 25 * 60_000,
onTaskUpdate: (task) => bindGenerationTask(node.id, task),
});
await applyGenerationTaskResult(node.id, completed);
} catch (error) {
if (!controller.signal.aborted) message.error(error instanceof Error ? error.message : "恢复作品保存失败");
} finally {
finishGenerationRequest(node.id, controller);
}
return;
}
const retryMode = retryModeForNode(node.type);
if (!retryMode) {
message.warning("当前节点不能使用通用生成重试");