fix(canvas): 画布与素材同步 - 修复批量缩略图、远程资源回退与重命名同步

This commit is contained in:
ddCat committed 2026-09-18 23:27:34 +08:00
1 parent 1a79005d25
commit 262540ea36
19 files changed
+635 -513

No files matched your search

@@ -9,7 +9,7 @@ import { resolveCanvasGenerationModel } from "@/lib/canvas/canvas-project-genera
import { clampPromptEditorModalSize, PROMPT_EDITOR_VIEWPORT_MARGIN } from "@/lib/canvas/canvas-prompt-editor-size";
import { CreditSymbol, requestCreditCost } from "@/constant/credits";
import { canvasThemes } from "@/lib/canvas-theme";
import { modelQuoteRequest } from "@/lib/model-pricing";
import { modelQuoteDescription, modelQuoteRequest } from "@/lib/model-pricing";
import { normalizeVideoDuration, normalizeVideoResolution } from "@/lib/video-generation-options";
import { modelRequestOptions, resolveCompatibleModel, resolveModelGenerationDefaults, defaultImageParamsForModel, type ModelRequirements } from "@/lib/model-selection";
import { navigateToSettings } from "@/lib/settings-navigation";
@@ -30,7 +30,7 @@ import { promptOptimizerPlugin, PROMPT_OPTIMIZER_PLUGIN_ID } from "@/lib/plugins
import { createPluginHostContext } from "@/services/plugin-host";
import { usePluginStore } from "@/stores/use-plugin-store";
import { useResolvedCanvasResourceReferences } from "./use-resolved-canvas-resource-references";
import { quoteLogicalModel } from "@/services/api/logical-models";
import { quoteModel, type LogicalModelQuote } from "@/services/api/logical-models";
export type CanvasNodeGenerationMode = CanvasGenerationMode;
@@ -146,8 +146,8 @@ export function CanvasNodePromptPanel({ projectId, node, isRunning, onPromptChan
});
const quoteRequest = modelQuoteRequest(config, config.model, mode, resolvedRequirements);
const quoteRequestKey = JSON.stringify(quoteRequest || null);
const [quotedCredits, setQuotedCredits] = useState<number | null>(null);
const credits = quotedCredits ?? configuredCredits;
const [routeQuote, setRouteQuote] = useState<LogicalModelQuote | null>(null);
const credits = routeQuote ? routeQuote.amountMicrocredits / 1_000_000 : configuredCredits;
const activeReferenceCount = activeReferences.length;
const videoFrameOptions = resolvedMentionReferences.filter((item) => item.active && item.kind === "image").map((item) => ({ nodeId: item.nodeId, label: item.label, title: item.title, previewUrl: item.previewUrl }));
const hasVideoPromptTools = mode === "video" && !simpleMode && videoFrameOptions.length > 0;
@@ -210,15 +210,15 @@ export function CanvasNodePromptPanel({ projectId, node, isRunning, onPromptChan
useEffect(() => {
if (!creditsEnabled || !quoteRequest) {
setQuotedCredits(null);
setRouteQuote(null);
return;
}
const controller = new AbortController();
setQuotedCredits(null);
quoteLogicalModel(quoteRequest.logicalModelID, quoteRequest.intent, controller.signal)
.then(({ quote }) => setQuotedCredits(quote.amountMicrocredits / 1_000_000))
setRouteQuote(null);
quoteModel(quoteRequest, controller.signal)
.then(({ quote }) => setRouteQuote(quote))
.catch(() => {
if (!controller.signal.aborted) setQuotedCredits(null);
if (!controller.signal.aborted) setRouteQuote(null);
});
return () => controller.abort();
// quoteRequestKey captures the full normalized request without retriggering on object identity.
@@ -352,12 +352,12 @@ export function CanvasNodePromptPanel({ projectId, node, isRunning, onPromptChan
}
onClick={() => (expanded ? submitExpandedPrompt() : submit())}
aria-label={actionLabel}
title={actionLabel}
title={routeQuote ? modelQuoteDescription(routeQuote) : actionLabel}
>
{showCost ? (
<span className="canvas-node-composer-submit-cost">
<CreditSymbol />
<span>{formattedCredits}</span>
<span>{routeQuote?.estimated ? "预计 " : ""}{formattedCredits}</span>
</span>
) : null}
<span className="canvas-node-composer-submit-action" aria-hidden>