feat(platform): 插件协议系统 - 支持声明式渠道、工作流与参考媒体映射

This commit is contained in:
ddCat
2026-08-26 13:11:10 +08:00
parent 054e3bbbff
commit 2f3a813ccb
58 changed files with 2074 additions and 706 deletions

View File

@@ -1,5 +1,5 @@
import { CanvasNodeContextMenu } from "@/components/canvas/canvas-context-menu";
import { CanvasNodeType, type CanvasNodeData, type CanvasWorkspaceMode, type ContextMenuState, type Position } from "@/types/canvas";
import { CanvasNodeType, type CanvasNodeData, type CanvasNodeTypeId, type CanvasWorkspaceMode, type ContextMenuState, type Position } from "@/types/canvas";
type CanvasAssetCategory = NonNullable<NonNullable<CanvasNodeData["metadata"]>["assetCategory"]>;
@@ -13,7 +13,7 @@ type CanvasProjectContextMenuProps = {
canPaste: boolean;
screenToCanvas: (clientX: number, clientY: number) => Position;
onClose: () => void;
onAddNode: (type: CanvasNodeType, position: Position) => void;
onAddNode: (type: CanvasNodeTypeId, position: Position) => void;
onAddFolder: (position: Position) => void;
onChooseStyle: () => void;
onOpenDirector: (position?: Position) => void;

View File

@@ -926,6 +926,7 @@ function InfiniteCanvasPage() {
setContextMenu(null);
setHoveredNodeId(null);
setToolbarNodeId(null);
setDialogNodeId(null);
}, []);
const { alignmentGuides, cancelSelectionBox, deselectCanvas, dragPreview, frameDropTargetId, handleCanvasMouseDown, handleNodeMouseDown, isNodeDragging, nodeDraggingRef, selectionBoundsElementRef, selectionBox } = useCanvasSelectionController({

View File

@@ -32,7 +32,7 @@ import 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";
import { CanvasNodeType, type CanvasConnection, type CanvasNodeData } from "@/types/canvas";
import { CanvasNodeType, type CanvasConnection, type CanvasNodeData, type CanvasNodeTypeId } from "@/types/canvas";
type UseCanvasGenerationRetryOptions = {
projectId: string;
@@ -387,7 +387,7 @@ export function useCanvasGenerationRetry({
}
// 生成类型必须由明确的节点契约决定,未知节点不能降级成图片任务。
function retryModeForNode(type: CanvasNodeType): CanvasNodeGenerationMode | null {
function retryModeForNode(type: CanvasNodeTypeId): CanvasNodeGenerationMode | null {
if (type === CanvasNodeType.Text) return "text";
if (type === CanvasNodeType.Image) return "image";
if (type === CanvasNodeType.Video) return "video";

View File

@@ -8,7 +8,7 @@ import { FOLDER_COLLAPSED_HEIGHT, FOLDER_COLLAPSED_WIDTH, FRAME_HEADER_HEIGHT, g
import { alignCanvasNodes, layoutCanvasFlow, layoutCanvasNodes, nextCanvasVersionLabel, type CanvasAlignmentMode } from "@/lib/canvas/canvas-layout";
import { createCanvasNode, isHiddenBatchChild, removeCanvasNodes } from "@/lib/canvas/canvas-project-domain";
import { isolateCopiedNodeMetadata } from "@/lib/canvas/canvas-node-copy";
import { CanvasNodeType, type CanvasConnection, type CanvasFolderStyle, type CanvasFolderTheme, type CanvasNodeData, type ContextMenuState, type Position } from "@/types/canvas";
import { CanvasNodeType, type CanvasConnection, type CanvasFolderStyle, type CanvasFolderTheme, type CanvasNodeData, type CanvasNodeTypeId, type ContextMenuState, type Position } from "@/types/canvas";
import { cloneCanvasDrawing } from "@/lib/canvas/canvas-drawing-storage";
import { isDrawingEngineAvailable, type CanvasDrawingEngine } from "@/lib/canvas/canvas-drawing-engine";
import { useUserStore } from "@/stores/use-user-store";
@@ -122,7 +122,7 @@ export function useCanvasNodeOperations({
setSelectedConnectionId(null);
}, [selectedNodeIdsRef, setSelectedConnectionId, setSelectedNodeIds]);
const createNode = useCallback((type: CanvasNodeType, position?: Position) => {
const createNode = useCallback((type: CanvasNodeTypeId, position?: Position) => {
if (type === CanvasNodeType.Drawing && !isDrawingEngineAvailable(defaultDrawingEngine, tldrawLicenseKey)) {
message.error("当前生产构建未配置 tldraw License Key,不能创建 tldraw 绘图");
return;

View File

@@ -571,7 +571,7 @@ export function useCanvasUpload({
|| (targetNode.type === CanvasNodeType.Image && file.type.startsWith("image/"))
|| (targetNode.type === CanvasNodeType.Video && file.type.startsWith("video/"))
|| (targetNode.type === CanvasNodeType.Audio && isAudioFile(file))
|| ![CanvasNodeType.Image, CanvasNodeType.Video, CanvasNodeType.Audio].includes(targetNode.type);
|| (targetNode.type !== CanvasNodeType.Image && targetNode.type !== CanvasNodeType.Video && targetNode.type !== CanvasNodeType.Audio);
if (!compatible) {
message.warning("请选择与当前节点相同类型的媒体文件");
return;