You've already forked DataMate
核心功能: - G6 v5 力导向图,支持交互式缩放、平移、拖拽 - 5 种布局模式:force, circular, grid, radial, concentric - 双击展开节点邻居到图中(增量探索) - 全文搜索,类型过滤,结果高亮(变暗/高亮状态) - 节点详情抽屉:实体属性、别名、置信度、关系列表(可导航) - 关系详情抽屉:类型、源/目标、权重、置信度、属性 - 查询构建器:最短路径/全路径查询,可配置 maxDepth/maxPaths - 基于 UUID 的图加载(输入或 URL 参数 ?graphId=...) - 大图性能优化(200 节点阈值,超过时禁用动画) 新增文件(13 个): - knowledge-graph.model.ts - TypeScript 接口,匹配 Java DTOs - knowledge-graph.api.ts - API 服务,包含所有 KG REST 端点 - knowledge-graph.const.ts - 实体类型颜色、关系类型标签、中文显示名称 - graphTransform.ts - 后端数据 → G6 节点/边格式转换 + 合并工具 - graphConfig.ts - G6 v5 图配置(节点/边样式、行为、布局) - hooks/useGraphData.ts - 数据钩子:加载子图、展开节点、搜索、合并 - hooks/useGraphLayout.ts - 布局钩子:5 种布局类型 - components/GraphCanvas.tsx - G6 v5 画布,力导向布局,缩放/平移/拖拽 - components/SearchPanel.tsx - 全文实体搜索,类型过滤 - components/NodeDetail.tsx - 实体详情抽屉 - components/RelationDetail.tsx - 关系详情抽屉 - components/QueryBuilder.tsx - 路径查询构建器 - Home/KnowledgeGraphPage.tsx - 主页面,整合所有组件 修改文件(5 个): - package.json - 添加 @antv/g6 v5 依赖 - vite.config.ts - 添加 /knowledge-graph 代理规则 - auth/permissions.ts - 添加 knowledgeGraphRead/knowledgeGraphWrite - pages/Layout/menu.tsx - 添加知识图谱菜单项(Network 图标) - routes/routes.ts - 添加 /data/knowledge-graph 路由 新增文档(10 个): - docs/knowledge-graph/ - 完整的知识图谱设计文档 Bug 修复(Codex 审查后修复): - P1: 详情抽屉状态与选中状态不一致(显示旧数据) - P1: 查询构建器未实现(最短路径/多路径查询) - P2: 实体类型映射 Organization → Org(匹配后端) - P2: getSubgraph depth 参数无效(改用正确端点) - P2: AllPathsVO 字段名不一致(totalPaths → pathCount) - P2: 搜索取消逻辑无效(传递 AbortController.signal) - P2: 大图性能优化(动画降级) - P3: 移除未使用的类型导入 构建验证: - tsc --noEmit ✅ clean - eslint ✅ 0 errors/warnings - vite build ✅ successful
83 lines
3.8 KiB
TypeScript
83 lines
3.8 KiB
TypeScript
export const PermissionCodes = {
|
|
dataManagementRead: "module:data-management:read",
|
|
dataManagementWrite: "module:data-management:write",
|
|
dataAnnotationRead: "module:data-annotation:read",
|
|
dataAnnotationWrite: "module:data-annotation:write",
|
|
dataCollectionRead: "module:data-collection:read",
|
|
dataCollectionWrite: "module:data-collection:write",
|
|
dataEvaluationRead: "module:data-evaluation:read",
|
|
dataEvaluationWrite: "module:data-evaluation:write",
|
|
dataSynthesisRead: "module:data-synthesis:read",
|
|
dataSynthesisWrite: "module:data-synthesis:write",
|
|
knowledgeManagementRead: "module:knowledge-management:read",
|
|
knowledgeManagementWrite: "module:knowledge-management:write",
|
|
knowledgeBaseRead: "module:knowledge-base:read",
|
|
knowledgeBaseWrite: "module:knowledge-base:write",
|
|
operatorMarketRead: "module:operator-market:read",
|
|
operatorMarketWrite: "module:operator-market:write",
|
|
orchestrationRead: "module:orchestration:read",
|
|
orchestrationWrite: "module:orchestration:write",
|
|
taskCoordinationRead: "module:task-coordination:read",
|
|
taskCoordinationWrite: "module:task-coordination:write",
|
|
taskCoordinationAssign: "module:task-coordination:assign",
|
|
contentGenerationUse: "module:content-generation:use",
|
|
agentUse: "module:agent:use",
|
|
knowledgeGraphRead: "module:knowledge-graph:read",
|
|
knowledgeGraphWrite: "module:knowledge-graph:write",
|
|
userManage: "system:user:manage",
|
|
roleManage: "system:role:manage",
|
|
permissionManage: "system:permission:manage",
|
|
} as const;
|
|
|
|
const routePermissionRules: Array<{ prefix: string; permission: string }> = [
|
|
{ prefix: "/data/management", permission: PermissionCodes.dataManagementRead },
|
|
{ prefix: "/data/annotation", permission: PermissionCodes.dataAnnotationRead },
|
|
{ prefix: "/data/collection", permission: PermissionCodes.dataCollectionRead },
|
|
{ prefix: "/data/evaluation", permission: PermissionCodes.dataEvaluationRead },
|
|
{ prefix: "/data/synthesis", permission: PermissionCodes.dataSynthesisRead },
|
|
{ prefix: "/data/knowledge-management", permission: PermissionCodes.knowledgeManagementRead },
|
|
{ prefix: "/data/knowledge-base", permission: PermissionCodes.knowledgeBaseRead },
|
|
{ prefix: "/data/operator-market", permission: PermissionCodes.operatorMarketRead },
|
|
{ prefix: "/data/orchestration", permission: PermissionCodes.orchestrationRead },
|
|
{ prefix: "/data/task-coordination", permission: PermissionCodes.taskCoordinationRead },
|
|
{ prefix: "/data/content-generation", permission: PermissionCodes.contentGenerationUse },
|
|
{ prefix: "/data/knowledge-graph", permission: PermissionCodes.knowledgeGraphRead },
|
|
{ prefix: "/chat", permission: PermissionCodes.agentUse },
|
|
];
|
|
|
|
const defaultRouteCandidates: Array<{ path: string; permission: string }> = [
|
|
{ path: "/data/management", permission: PermissionCodes.dataManagementRead },
|
|
{ path: "/data/annotation", permission: PermissionCodes.dataAnnotationRead },
|
|
{ path: "/data/knowledge-management", permission: PermissionCodes.knowledgeManagementRead },
|
|
{ path: "/data/knowledge-base", permission: PermissionCodes.knowledgeBaseRead },
|
|
{ path: "/chat", permission: PermissionCodes.agentUse },
|
|
];
|
|
|
|
export function hasPermission(
|
|
userPermissions: string[] | undefined,
|
|
requiredPermission?: string | null
|
|
): boolean {
|
|
if (!requiredPermission) {
|
|
return true;
|
|
}
|
|
return (userPermissions ?? []).includes(requiredPermission);
|
|
}
|
|
|
|
export function resolveRequiredPermissionByPath(pathname: string): string | null {
|
|
if (pathname === "/403") {
|
|
return null;
|
|
}
|
|
const matchedRule = routePermissionRules.find((rule) =>
|
|
pathname.startsWith(rule.prefix)
|
|
);
|
|
return matchedRule?.permission ?? null;
|
|
}
|
|
|
|
export function resolveDefaultAuthorizedPath(userPermissions: string[]): string {
|
|
const matchedPath = defaultRouteCandidates.find((candidate) =>
|
|
hasPermission(userPermissions, candidate.permission)
|
|
)?.path;
|
|
return matchedPath ?? "/403";
|
|
}
|
|
|