/** * useGraphEditor — 图谱编辑器 composable * * 封装编辑会话管理、diff 计算和 API 调用逻辑。 * 在任意使用图谱的视图中引入此 composable,即可获得完整的编辑能力。 * * 使用方式: * ```ts * const editor = useGraphEditor({ * onSaveSuccess: (stats) => { ElMessage.success(...) }, * onSaveError: (err) => { ElMessage.error(...) } * }) * * // 进入编辑 * editor.enterEditMode(nodes, edges) * * // 用户点击保存 * await editor.save() * * // 用户取消 * editor.cancelEdit() * * // 暴露给模板的响应式状态 * editor.isEditing // 是否处于编辑模式 * editor.hasChanges // 是否有未保存的变更 * editor.isSaving // 是否正在保存 * ``` */ import { type Ref } from 'vue'; import type { GraphNode, GraphEdge } from '../@types'; export interface GraphEditorOptions { /** * 保存时合并进批量请求(如 file_source、userId、project), * 便于新增节点/边归属到某上传文件,Obsidian 导出可带上编辑结果。 */ batchExtra?: () => Partial>; /** 保存成功后回调(参数为后端返回的统计信息) */ onSaveSuccess?: (stats: { added_nodes: number; added_edges: number; updated_nodes: number; updated_edges: number; deleted_nodes: number; deleted_edges: number; }) => void; /** 保存失败后回调 */ onSaveError?: (error: Error) => void; /** API 请求函数,默认使用 fetch */ api?: { batchUpdate: (request: BatchUpdateRequest) => Promise; }; } export interface BatchUpdateRequest { add_nodes?: GraphNodeInput[]; add_edges?: GraphEdgeInput[]; update_nodes?: { id: string; [key: string]: any; }[]; update_edges?: { id: string; [key: string]: any; }[]; delete_node_ids?: string[]; delete_edge_ids?: string[]; userId?: string; project?: string; file_source?: string; } export interface GraphNodeInput { id?: string; label: string; type?: string; size?: number; x?: number; y?: number; style?: Record; } export interface GraphEdgeInput { id?: string; source: string; target: string; label?: string; relation_type?: string; style?: Record; } export interface BatchUpdateResponse { success: boolean; message?: string; stats?: { added_nodes: number; added_edges: number; updated_nodes: number; updated_edges: number; deleted_nodes: number; deleted_edges: number; }; } /** * GraphVisualization 暴露给 editor 的接口 */ export interface GraphVisualizationRef { getEditData: () => { nodes: GraphNode[]; edges: GraphEdge[]; }; applyEditData: (nodes: GraphNode[], edges: GraphEdge[]) => void; promptAddNodeAtCenter: () => Promise; hintHowToAddRelation: () => void; } export declare function useGraphEditor(options?: GraphEditorOptions): { isEditing: Readonly>; hasChanges: Readonly>; isSaving: Readonly>; graphRef: null; setGraphRef: (ref: GraphVisualizationRef | null) => void; enterEditMode: (nodes: GraphNode[], edges: GraphEdge[]) => void; updateCurrentData: (nodes: GraphNode[], edges: GraphEdge[]) => void; calculateDiff: () => { addedNodes: GraphNode[]; addedEdges: GraphEdge[]; updatedNodes: { id: string; [key: string]: any; }[]; updatedEdges: { id: string; [key: string]: any; }[]; deletedNodeIds: string[]; deletedEdgeIds: string[]; }; checkHasChanges: () => boolean; markChanged: () => void; cancelEdit: (applyToGraph?: boolean) => { nodes: any; edges: any; }; save: (applyToGraph?: boolean) => Promise<{ nodes: GraphNode[]; edges: GraphEdge[]; } | null>; getEditData: () => { nodes: GraphNode[]; edges: GraphEdge[]; }; }; export type GraphEditor = ReturnType;