From d83ec033bb2275f7ea114bd54ec5c59e924e66fc Mon Sep 17 00:00:00 2001 From: ahyang <53590964+zAhYAng@users.noreply.github.com> Date: Mon, 3 Aug 2026 21:38:04 +0800 Subject: [PATCH] =?UTF-8?q?feat(canvas):=20=E7=BB=98=E5=9B=BE=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E6=94=AF=E6=8C=81=E8=87=AA=E5=AE=9A=E4=B9=89=20tldraw?= =?UTF-8?q?=20License=20Key=20(#100)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(canvas): 绘图工具 - 支持自定义 tldraw License Key * docs(canvas): 绘图工具 - 添加 License Key 页面截图 --- assets/tldraw-license-key-settings.png | Bin 0 -> 91713 bytes backend/internal/repository/repository.go | 11 +++ backend/internal/service/drawing_engine.go | 69 ++++++++++++++---- .../internal/service/drawing_engine_test.go | 62 +++++++++++++++- .../canvas/canvas-drawing-editor-modal.tsx | 4 +- .../canvas/canvas-drawing-tldraw-editor.tsx | 7 +- web/src/lib/canvas/canvas-drawing-engine.ts | 11 ++- .../settings/drawing-engine-settings-page.tsx | 53 ++++++++------ .../use-canvas-connection-controller.ts | 6 +- .../canvas/use-canvas-node-operations.ts | 6 +- web/src/services/api/auth.ts | 4 +- 11 files changed, 186 insertions(+), 47 deletions(-) create mode 100644 assets/tldraw-license-key-settings.png diff --git a/assets/tldraw-license-key-settings.png b/assets/tldraw-license-key-settings.png new file mode 100644 index 0000000000000000000000000000000000000000..9b875279e6f19aaa314674c0b43273cb6f0ad15b GIT binary patch literal 91713 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 Rf`6gY*3>_gd(h^8{|Bu>6@dT% literal 0 HcmV?d00001 diff --git a/backend/internal/repository/repository.go b/backend/internal/repository/repository.go index 3e2ca3aae..c9c21898b 100644 --- a/backend/internal/repository/repository.go +++ b/backend/internal/repository/repository.go @@ -590,6 +590,17 @@ func (r *Repository) SaveSystemSetting(setting *model.SystemSetting) error { return r.db.Save(setting).Error } +func (r *Repository) SaveSystemSettings(settings ...*model.SystemSetting) error { + return r.db.Transaction(func(tx *gorm.DB) error { + for _, setting := range settings { + if err := tx.Save(setting).Error; err != nil { + return err + } + } + return nil + }) +} + func (r *Repository) DeleteSystemSetting(key string) error { return r.db.Delete(&model.SystemSetting{}, "key = ?", key).Error } diff --git a/backend/internal/service/drawing_engine.go b/backend/internal/service/drawing_engine.go index c15c0f021..0d2a1d072 100644 --- a/backend/internal/service/drawing_engine.go +++ b/backend/internal/service/drawing_engine.go @@ -11,7 +11,10 @@ import ( "gorm.io/gorm" ) -const drawingEngineSettingKey = "drawing_engine" +const ( + drawingEngineSettingKey = "drawing_engine" + tldrawLicenseKeySettingKey = "tldraw_license_key" +) const ( DrawingEngineTldraw = "tldraw" @@ -19,7 +22,8 @@ const ( ) type DrawingEngineSetting struct { - DefaultEngine string `json:"defaultEngine"` + DefaultEngine string `json:"defaultEngine"` + TldrawLicenseKey string `json:"tldrawLicenseKey"` } type PublicDrawingEngineSetting struct { @@ -57,11 +61,22 @@ func (s *Service) UpdateDrawingEngineSetting(actor *model.User, value DrawingEng if err := validateDrawingEngineSetting(value); err != nil { return nil, err } + value.TldrawLicenseKey = strings.TrimSpace(value.TldrawLicenseKey) current, before, err := s.readDrawingEngineSetting() if err != nil { return nil, err } - encoded, err := json.Marshal(value) + currentLicenseSetting, _, err := s.readTldrawLicenseKey() + if err != nil { + return nil, err + } + encoded, err := json.Marshal(struct { + DefaultEngine string `json:"defaultEngine"` + }{DefaultEngine: value.DefaultEngine}) + if err != nil { + return nil, err + } + encodedLicenseKey, err := json.Marshal(value.TldrawLicenseKey) if err != nil { return nil, err } @@ -69,10 +84,14 @@ func (s *Service) UpdateDrawingEngineSetting(actor *model.User, value DrawingEng if current != nil { setting.CreatedAt = current.CreatedAt } - if err := s.repo.SaveSystemSetting(&setting); err != nil { + licenseSetting := model.SystemSetting{Key: tldrawLicenseKeySettingKey, ValueJSON: string(encodedLicenseKey), UpdatedBy: actor.ID} + if currentLicenseSetting != nil { + licenseSetting.CreatedAt = currentLicenseSetting.CreatedAt + } + if err := s.repo.SaveSystemSettings(&setting, &licenseSetting); err != nil { return nil, err } - if err := s.appendAdminAudit(actor, "drawing_engine.update", "system_setting", drawingEngineSettingKey, "更新默认绘图工具", map[string]any{"before": before, "after": value}); err != nil { + if err := s.appendAdminAudit(actor, "drawing_engine.update", "system_setting", drawingEngineSettingKey, "更新绘图工具配置", map[string]any{"before": drawingEngineAuditValue(before), "after": drawingEngineAuditValue(value)}); err != nil { return nil, err } return publicDrawingEngineSetting(&setting, value), nil @@ -80,22 +99,42 @@ func (s *Service) UpdateDrawingEngineSetting(actor *model.User, value DrawingEng func (s *Service) readDrawingEngineSetting() (*model.SystemSetting, DrawingEngineSetting, error) { setting, err := s.repo.SystemSetting(drawingEngineSettingKey) + value := defaultDrawingEngineSetting() if errors.Is(err, gorm.ErrRecordNotFound) { - return nil, defaultDrawingEngineSetting(), nil + setting = nil + } else if err != nil { + return nil, DrawingEngineSetting{}, err + } else { + if strings.TrimSpace(setting.ValueJSON) == "" || json.Unmarshal([]byte(setting.ValueJSON), &value) != nil { + return nil, DrawingEngineSetting{}, errors.New("绘图工具配置格式无效") + } + if err := validateDrawingEngineSetting(value); err != nil { + return nil, DrawingEngineSetting{}, err + } } + _, licenseKey, err := s.readTldrawLicenseKey() if err != nil { return nil, DrawingEngineSetting{}, err } - value := DrawingEngineSetting{} - if strings.TrimSpace(setting.ValueJSON) == "" || json.Unmarshal([]byte(setting.ValueJSON), &value) != nil { - return nil, DrawingEngineSetting{}, errors.New("绘图工具配置格式无效") - } - if err := validateDrawingEngineSetting(value); err != nil { - return nil, DrawingEngineSetting{}, err - } + value.TldrawLicenseKey = licenseKey return setting, value, nil } +func (s *Service) readTldrawLicenseKey() (*model.SystemSetting, string, error) { + setting, err := s.repo.SystemSetting(tldrawLicenseKeySettingKey) + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, "", nil + } + if err != nil { + return nil, "", err + } + var value string + if strings.TrimSpace(setting.ValueJSON) == "" || json.Unmarshal([]byte(setting.ValueJSON), &value) != nil { + return nil, "", errors.New("tldraw License Key 配置格式无效") + } + return setting, strings.TrimSpace(value), nil +} + func validateDrawingEngineSetting(value DrawingEngineSetting) error { if value.DefaultEngine != DrawingEngineTldraw && value.DefaultEngine != DrawingEngineExcalidraw { return BadAuthRequest("默认绘图工具必须是 tldraw 或 Excalidraw") @@ -103,6 +142,10 @@ func validateDrawingEngineSetting(value DrawingEngineSetting) error { return nil } +func drawingEngineAuditValue(value DrawingEngineSetting) map[string]any { + return map[string]any{"defaultEngine": value.DefaultEngine, "hasTldrawLicenseKey": strings.TrimSpace(value.TldrawLicenseKey) != ""} +} + func publicDrawingEngineSetting(setting *model.SystemSetting, value DrawingEngineSetting) *PublicDrawingEngineSetting { result := &PublicDrawingEngineSetting{DrawingEngineSetting: value, Configured: setting != nil} if setting != nil { diff --git a/backend/internal/service/drawing_engine_test.go b/backend/internal/service/drawing_engine_test.go index 643020be0..986f878ff 100644 --- a/backend/internal/service/drawing_engine_test.go +++ b/backend/internal/service/drawing_engine_test.go @@ -1,6 +1,16 @@ package service -import "testing" +import ( + "encoding/json" + "strings" + "testing" + + "infinite-canvas/backend/internal/model" + "infinite-canvas/backend/internal/repository" + + "gorm.io/driver/sqlite" + "gorm.io/gorm" +) func TestDefaultDrawingEngineUsesExcalidraw(t *testing.T) { setting := defaultDrawingEngineSetting() @@ -19,3 +29,53 @@ func TestValidateDrawingEngineSetting(t *testing.T) { t.Fatal("validate unknown engine = nil") } } + +func TestUpdateDrawingEngineSettingKeepsDefaultEngineAndStoresTldrawLicenseSeparately(t *testing.T) { + db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) + if err != nil { + t.Fatal(err) + } + if sqlDB, err := db.DB(); err == nil { + sqlDB.SetMaxOpenConns(1) + } + if err := db.AutoMigrate(&model.SystemSetting{}, &model.AdminAuditEvent{}); err != nil { + t.Fatal(err) + } + repo := repository.New(db) + svc := New(repo, t.TempDir()) + actor := &model.User{ID: "admin-1", Role: model.UserRoleAdmin} + + setting, err := svc.UpdateDrawingEngineSetting(actor, DrawingEngineSetting{ + DefaultEngine: DrawingEngineExcalidraw, + TldrawLicenseKey: "license-key-for-test", + }) + if err != nil { + t.Fatal(err) + } + if setting.DefaultEngine != DrawingEngineExcalidraw { + t.Fatalf("default engine = %q, want %q", setting.DefaultEngine, DrawingEngineExcalidraw) + } + if setting.TldrawLicenseKey != "license-key-for-test" { + t.Fatalf("license key = %q", setting.TldrawLicenseKey) + } + + licenseSetting, err := repo.SystemSetting(tldrawLicenseKeySettingKey) + if err != nil { + t.Fatal(err) + } + var savedLicenseKey string + if err := json.Unmarshal([]byte(licenseSetting.ValueJSON), &savedLicenseKey); err != nil { + t.Fatal(err) + } + if savedLicenseKey != "license-key-for-test" { + t.Fatalf("stored license key = %q", savedLicenseKey) + } + + engineSetting, err := repo.SystemSetting(drawingEngineSettingKey) + if err != nil { + t.Fatal(err) + } + if strings.Contains(engineSetting.ValueJSON, "license-key-for-test") { + t.Fatalf("drawing engine setting must not contain the license key: %s", engineSetting.ValueJSON) + } +} diff --git a/web/src/components/canvas/canvas-drawing-editor-modal.tsx b/web/src/components/canvas/canvas-drawing-editor-modal.tsx index efb9615ed..1cf579805 100644 --- a/web/src/components/canvas/canvas-drawing-editor-modal.tsx +++ b/web/src/components/canvas/canvas-drawing-editor-modal.tsx @@ -6,6 +6,7 @@ import type { CanvasDrawingEditorHandle } from "@/components/canvas/canvas-drawi import { drawingEngineForNode, drawingEngineLabel, isDrawingEngineAvailable } from "@/lib/canvas/canvas-drawing-engine"; import { loadCanvasDrawing, saveCanvasDrawing, type CanvasDrawingSnapshot } from "@/lib/canvas/canvas-drawing-storage"; import { useThemeStore } from "@/stores/use-theme-store"; +import { useUserStore } from "@/stores/use-user-store"; import type { CanvasNodeData } from "@/types/canvas"; const CanvasDrawingTldrawEditor = lazy(() => import("@/components/canvas/canvas-drawing-tldraw-editor").then((module) => ({ default: module.CanvasDrawingTldrawEditor }))); @@ -22,6 +23,7 @@ type CanvasDrawingEditorModalProps = { export function CanvasDrawingEditorModal({ open, projectId, node, onClose, onSaved }: CanvasDrawingEditorModalProps) { const { message } = App.useApp(); const colorScheme = useThemeStore((state) => state.theme); + const tldrawLicenseKey = useUserStore((state) => state.drawingEngine.tldrawLicenseKey); const engine = drawingEngineForNode(node); const currentRef = useRef(null); const editorRef = useRef(null); @@ -76,7 +78,7 @@ export function CanvasDrawingEditorModal({ open, projectId, node, onClose, onSav onClose(); }; - const unavailable = !isDrawingEngineAvailable(engine); + const unavailable = !isDrawingEngineAvailable(engine, tldrawLicenseKey); return ( void handleClose()} footer={null} closable={false} destroyOnHidden width="100vw" centered styles={{ body: { padding: 0 }, container: { padding: 0, overflow: "hidden" } }} className="canvas-drawing-editor-modal">
diff --git a/web/src/components/canvas/canvas-drawing-tldraw-editor.tsx b/web/src/components/canvas/canvas-drawing-tldraw-editor.tsx index b11e5ebef..b293d9886 100644 --- a/web/src/components/canvas/canvas-drawing-tldraw-editor.tsx +++ b/web/src/components/canvas/canvas-drawing-tldraw-editor.tsx @@ -4,12 +4,15 @@ import type { Editor } from "tldraw"; import "tldraw/tldraw.css"; import type { CanvasDrawingEditorHandle, CanvasDrawingEditorProps } from "@/components/canvas/canvas-drawing-editor-types"; +import { resolveTldrawLicenseKey } from "@/lib/canvas/canvas-drawing-engine"; +import { useUserStore } from "@/stores/use-user-store"; const SINGLE_PAGE_OPTIONS = { maxPages: 1 } as const; const DRAWING_RENDER_MAX_DIMENSION = 2048; const DRAWING_RENDER_PADDING = 24; export const CanvasDrawingTldrawEditor = forwardRef(function CanvasDrawingTldrawEditor({ snapshot, colorScheme, onReady }, ref) { + const tldrawLicenseKey = useUserStore((state) => state.drawingEngine.tldrawLicenseKey); const store = useMemo(() => { const next = createTLStore(); if (snapshot) loadSnapshot(next, snapshot as never); @@ -46,7 +49,7 @@ export const CanvasDrawingTldrawEditor = forwardRef { editorRef.current = editor; // 绘图节点只保留单页,避免预览和生成引用出现页选择歧义。 @@ -61,4 +64,4 @@ export const CanvasDrawingTldrawEditor = forwardRef ); -}); +}); \ No newline at end of file diff --git a/web/src/lib/canvas/canvas-drawing-engine.ts b/web/src/lib/canvas/canvas-drawing-engine.ts index ab431e073..8a5cc761e 100644 --- a/web/src/lib/canvas/canvas-drawing-engine.ts +++ b/web/src/lib/canvas/canvas-drawing-engine.ts @@ -4,6 +4,7 @@ export type CanvasDrawingEngine = "tldraw" | "excalidraw"; export type CanvasDrawingEngineSetting = { defaultEngine: CanvasDrawingEngine; + tldrawLicenseKey?: string; configured?: boolean; updatedBy?: string; createdAt?: string; @@ -17,10 +18,14 @@ export function drawingEngineForNode(node?: Pick | n return node?.metadata?.drawingEngine === "excalidraw" ? "excalidraw" : "tldraw"; } -export function isDrawingEngineAvailable(engine: CanvasDrawingEngine) { - return engine === "excalidraw" || import.meta.env.DEV || Boolean(import.meta.env.VITE_TLDRAW_LICENSE_KEY); +export function resolveTldrawLicenseKey(configuredLicenseKey?: string) { + return configuredLicenseKey?.trim() || import.meta.env.VITE_TLDRAW_LICENSE_KEY?.trim() || undefined; +} + +export function isDrawingEngineAvailable(engine: CanvasDrawingEngine, configuredLicenseKey?: string) { + return engine === "excalidraw" || Boolean(resolveTldrawLicenseKey(configuredLicenseKey)); } export function drawingEngineLabel(engine: CanvasDrawingEngine) { return engine === "excalidraw" ? "Excalidraw" : "tldraw"; -} +} \ No newline at end of file diff --git a/web/src/pages/admin/settings/drawing-engine-settings-page.tsx b/web/src/pages/admin/settings/drawing-engine-settings-page.tsx index fc774cd1c..9fa9db54e 100644 --- a/web/src/pages/admin/settings/drawing-engine-settings-page.tsx +++ b/web/src/pages/admin/settings/drawing-engine-settings-page.tsx @@ -1,4 +1,4 @@ -import { App, Button, Segmented, Tag } from "antd"; +import { App, Button, Input, Segmented, Tag } from "antd"; import { Brush, Save } from "lucide-react"; import { useEffect, useState } from "react"; @@ -13,6 +13,7 @@ export default function DrawingEngineSettingsPage() { const current = useUserStore((state) => state.drawingEngine); const setDrawingEngine = useUserStore((state) => state.setDrawingEngine); const [engine, setEngine] = useState(current.defaultEngine); + const [tldrawLicenseKey, setTldrawLicenseKey] = useState(current.tldrawLicenseKey || ""); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); @@ -22,6 +23,7 @@ export default function DrawingEngineSettingsPage() { if (cancelled) return; setDrawingEngine(setting); setEngine(setting.defaultEngine); + setTldrawLicenseKey(setting.tldrawLicenseKey || ""); }).catch((error) => { if (!cancelled) message.error(error instanceof Error ? error.message : "读取绘图工具配置失败"); }).finally(() => { @@ -30,17 +32,19 @@ export default function DrawingEngineSettingsPage() { return () => { cancelled = true; }; }, [message, setDrawingEngine]); + const tldrawAvailable = isDrawingEngineAvailable("tldraw", tldrawLicenseKey); const save = async () => { - if (!isDrawingEngineAvailable(engine)) { - message.error("当前生产构建未配置 tldraw License Key"); + if (!isDrawingEngineAvailable(engine, tldrawLicenseKey)) { + message.error("请先配置有效的 tldraw License Key"); return; } setSaving(true); try { - const { setting } = await updateAdminDrawingEngineSetting(engine); + const { setting } = await updateAdminDrawingEngineSetting({ defaultEngine: engine, tldrawLicenseKey }); setDrawingEngine(setting); setEngine(setting.defaultEngine); - message.success("默认绘图工具已更新"); + setTldrawLicenseKey(setting.tldrawLicenseKey || ""); + message.success("绘图工具配置已更新"); } catch (error) { message.error(error instanceof Error ? error.message : "保存绘图工具配置失败"); } finally { @@ -48,28 +52,35 @@ export default function DrawingEngineSettingsPage() { } }; - const dirty = engine !== current.defaultEngine; + const dirty = engine !== current.defaultEngine || tldrawLicenseKey !== (current.tldrawLicenseKey || ""); return (
} title="默认绘图引擎" description="已有绘图保持原引擎,仅新建绘图使用这里的选择。" status={{drawingEngineLabel(current.defaultEngine)}}> -
- - block - className="w-full sm:max-w-md" - disabled={loading || saving} - value={engine} - onChange={setEngine} - options={[ - { label: "Excalidraw", value: "excalidraw" }, - { label: "tldraw", value: "tldraw", disabled: !isDrawingEngineAvailable("tldraw") }, - ]} - /> - +
+
+ + setTldrawLicenseKey(event.target.value)} placeholder="输入 tldraw License Key" disabled={loading || saving} autoComplete="off" /> +

填入有效的 License Key 后保存,即可解锁 tldraw 选项。

+
+
+ + block + className="w-full sm:max-w-md" + disabled={loading || saving} + value={engine} + onChange={setEngine} + options={[ + { label: "Excalidraw", value: "excalidraw" }, + { label: "tldraw", value: "tldraw", disabled: !tldrawAvailable }, + ]} + /> + +
- {!isDrawingEngineAvailable("tldraw") ?
当前生产构建没有 tldraw License Key,不能将其设为新建默认值。
: null} + {!tldrawAvailable ?
当前未配置 tldraw License Key,不能将其设为新建默认值。
: null}
); -} +} \ No newline at end of file diff --git a/web/src/pages/canvas/use-canvas-connection-controller.ts b/web/src/pages/canvas/use-canvas-connection-controller.ts index a93eb4b50..068790b63 100644 --- a/web/src/pages/canvas/use-canvas-connection-controller.ts +++ b/web/src/pages/canvas/use-canvas-connection-controller.ts @@ -8,6 +8,7 @@ import { attachNodeToStoryboardRow, createCanvasNode, getConnectionTargetAnchor, import { createCanvasDrawingFromImage } from "@/lib/canvas/canvas-drawing-storage"; import { isDrawingEngineAvailable, type CanvasDrawingEngine } from "@/lib/canvas/canvas-drawing-engine"; import { isFrameNode, isNodeHiddenByCollapsedFrame } from "@/lib/canvas/canvas-frame"; +import { useUserStore } from "@/stores/use-user-store"; import { CanvasNodeType, type CanvasConnection, type CanvasNodeData, type ConnectionHandle, type ContextMenuState, type Position, type ViewportTransform } from "@/types/canvas"; type UseCanvasConnectionControllerOptions = { @@ -55,6 +56,7 @@ export function useCanvasConnectionController({ setDrawingNodeId, }: UseCanvasConnectionControllerOptions) { const { message } = App.useApp(); + const tldrawLicenseKey = useUserStore((state) => state.drawingEngine.tldrawLicenseKey); const [connectingParams, setConnectingParams] = useState(null); const [connectionTargetNodeId, setConnectionTargetNodeId] = useState(null); const [connectionTargetAnchorRatio, setConnectionTargetAnchorRatio] = useState(); @@ -114,7 +116,7 @@ export function useCanvasConnectionController({ }, [connectionsRef, message, nodesRef, setConnections, setContextMenu, setNodes]); const createConnectedNode = useCallback(async (type: CanvasNodeType.Image | CanvasNodeType.Text | CanvasNodeType.Script | CanvasNodeType.Video | CanvasNodeType.Audio | CanvasNodeType.Drawing, pending: PendingConnectionCreate) => { - if (type === CanvasNodeType.Drawing && !isDrawingEngineAvailable(defaultDrawingEngine)) { + if (type === CanvasNodeType.Drawing && !isDrawingEngineAvailable(defaultDrawingEngine, tldrawLicenseKey)) { message.error("当前生产构建未配置 tldraw License Key,不能创建 tldraw 绘图"); return; } @@ -190,7 +192,7 @@ export function useCanvasConnectionController({ else if (type !== CanvasNodeType.Text && type !== CanvasNodeType.Script && type !== CanvasNodeType.Audio) setDialogNodeId(newNode.id); closeConnectionCreateMenu(); setConnecting(null); - }, [closeConnectionCreateMenu, defaultDrawingEngine, message, nodesRef, projectId, setConnecting, setConnections, setDialogNodeId, setDrawingNodeId, setNodes, setSelectedConnectionId, setSelectedNodeIds]); + }, [closeConnectionCreateMenu, defaultDrawingEngine, message, nodesRef, projectId, setConnecting, setConnections, setDialogNodeId, setDrawingNodeId, setNodes, setSelectedConnectionId, setSelectedNodeIds, tldrawLicenseKey]); const getConnectionDropTarget = useCallback((clientX: number, clientY: number, current: ConnectionHandle): ConnectionDropTarget => { const world = screenToCanvas(clientX, clientY); diff --git a/web/src/pages/canvas/use-canvas-node-operations.ts b/web/src/pages/canvas/use-canvas-node-operations.ts index 1f6f3a9fc..4a511a4fc 100644 --- a/web/src/pages/canvas/use-canvas-node-operations.ts +++ b/web/src/pages/canvas/use-canvas-node-operations.ts @@ -10,6 +10,7 @@ import { isolateCopiedNodeMetadata } from "@/lib/canvas/canvas-node-copy"; import { CanvasNodeType, type CanvasConnection, type CanvasNodeData, 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"; type CanvasClipboard = { nodes: CanvasNodeData[]; @@ -52,6 +53,7 @@ export function useCanvasNodeOperations({ onNodesDeleted, }: UseCanvasNodeOperationsOptions) { const { message } = App.useApp(); + const tldrawLicenseKey = useUserStore((state) => state.drawingEngine.tldrawLicenseKey); const clipboardRef = useRef(null); const preferCopiedNodesRef = useRef(false); const markerWritePendingRef = useRef(false); @@ -120,7 +122,7 @@ export function useCanvasNodeOperations({ }, [selectedNodeIdsRef, setSelectedConnectionId, setSelectedNodeIds]); const createNode = useCallback((type: CanvasNodeType, position?: Position) => { - if (type === CanvasNodeType.Drawing && !isDrawingEngineAvailable(defaultDrawingEngine)) { + if (type === CanvasNodeType.Drawing && !isDrawingEngineAvailable(defaultDrawingEngine, tldrawLicenseKey)) { message.error("当前生产构建未配置 tldraw License Key,不能创建 tldraw 绘图"); return; } @@ -128,7 +130,7 @@ export function useCanvasNodeOperations({ commitNodes([...nodesRef.current, node]); selectNodes(new Set([node.id])); if (type !== CanvasNodeType.Text && type !== CanvasNodeType.Script && type !== CanvasNodeType.Audio && type !== CanvasNodeType.Frame && type !== CanvasNodeType.Drawing) setDialogNodeId(node.id); - }, [commitNodes, defaultDrawingEngine, getCanvasCenter, message, nodesRef, selectNodes, setDialogNodeId]); + }, [commitNodes, defaultDrawingEngine, getCanvasCenter, message, nodesRef, selectNodes, setDialogNodeId, tldrawLicenseKey]); const arrangeSelectedNodes = useCallback((mode: "row" | "column" | "grid" | "flow") => { const selected = nodesRef.current.filter((node) => selectedNodeIdsRef.current.has(node.id) && !node.metadata?.locked && !isFrameNode(node)); diff --git a/web/src/services/api/auth.ts b/web/src/services/api/auth.ts index dac454200..5e0dbc70d 100644 --- a/web/src/services/api/auth.ts +++ b/web/src/services/api/auth.ts @@ -437,8 +437,8 @@ export function getAdminDrawingEngineSetting() { return request<{ setting: CanvasDrawingEngineSetting }>(api.get("/admin/settings/drawing-engine")); } -export function updateAdminDrawingEngineSetting(defaultEngine: CanvasDrawingEngineSetting["defaultEngine"]) { - return request<{ setting: CanvasDrawingEngineSetting }>(api.patch("/admin/settings/drawing-engine", { defaultEngine })); +export function updateAdminDrawingEngineSetting(input: Pick) { + return request<{ setting: CanvasDrawingEngineSetting }>(api.patch("/admin/settings/drawing-engine", input)); } export function listAdminApiLogs(params: AdminListParams = {}) {