mirror of
https://gitcode.com/ageerle/ruoyi-ai.git
synced 2026-04-14 12:23:39 +00:00
Compare commits
2 Commits
accac603cf
...
003c066361
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
003c066361 | ||
|
|
a5e7c59fd4 |
15
README.md
15
README.md
@@ -31,14 +31,13 @@
|
||||
|
||||
## ✨ 核心亮点
|
||||
|
||||
| 模块 | 现有能力 | 扩展方向 |
|
||||
|:---:|---|---|
|
||||
| **模型管理** | 多模型接入(OpenAI/DeepSeek/通义/智谱)、多模态理解、Coze/DIFY/FastGPT平台集成 | 自动模式、容错机制 |
|
||||
| **知识库** | 本地RAG + 向量库(Milvus/Weaviate) + 知识图谱 + 文档解析 +重排序 | 音频视频解析、知识出处 |
|
||||
| **工具管理** | Mcp协议集成、Skills能力 + 可扩展工具生态 | 工具插件市场、toolAgent自动加载工具 |
|
||||
| **流程编排** | 可视化工作流设计器、节点拖拽编排、SSE流式执行,目前已经支持模型调用,邮件发送,人工审核等节点 | 更多节点类型 |
|
||||
| **多智能体** | 基于Langchain4j的Agent框架、Supervisor模式编排,支持多种决策模型 | 智能体可配置 |
|
||||
| **AI编程** | 智能代码分析、项目脚手架生成、Copilot助手 | 代码生成优化 |
|
||||
| 模块 | 现有能力 | 扩展方向 |
|
||||
|:----------:|---|------------------------|
|
||||
| **模型管理** | 多模型接入(OpenAI/DeepSeek/通义/智谱)、多模态理解、Coze/DIFY/FastGPT平台集成 | 自动模式、容错机制、计费管理 |
|
||||
| **知识管理** | 本地RAG + 向量库(Milvus/Weaviate) + 文档解析 | 多模态、知识出处、知识图谱、重排序 |
|
||||
| **工具管理** | Mcp协议集成、Skills能力 + 可扩展工具生态 | 工具插件市场、 |
|
||||
| **流程编排** | 可视化工作流设计器、节点拖拽编排、SSE流式执行,目前已经支持模型调用,邮件发送,人工审核等节点 | 更多节点类型 |
|
||||
| **多智能体** | 基于Langchain4j的Agent框架、Supervisor模式编排,支持多种决策模型 | 智能体可配置 |
|
||||
|
||||
## 🚀 快速体验
|
||||
|
||||
|
||||
@@ -11,42 +11,12 @@
|
||||
Target Server Version : 80045 (8.0.45)
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 14/03/2026 14:15:08
|
||||
Date: 15/03/2026 23:56:19
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for chat_config
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `chat_config`;
|
||||
CREATE TABLE `chat_config` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`category` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '配置类型',
|
||||
`config_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '配置名称',
|
||||
`config_value` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '配置值',
|
||||
`config_dict` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '说明',
|
||||
`create_dept` bigint NULL DEFAULT NULL COMMENT '创建部门',
|
||||
`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
|
||||
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
|
||||
`version` int NULL DEFAULT NULL COMMENT '版本',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 1代表删除)',
|
||||
`update_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '更新IP',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户Id',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `unique_category_key`(`category` ASC, `config_name` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2030620372623781891 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '配置信息表' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of chat_config
|
||||
-- ----------------------------
|
||||
INSERT INTO `chat_config` VALUES (2030620372556673026, 'wechat', 'appid', 'xx', 'appid', 103, '2026-03-08 20:23:19', '1', '1', '2026-03-08 20:23:19', NULL, NULL, '0', NULL, 0);
|
||||
INSERT INTO `chat_config` VALUES (2030620372623781890, 'wechat', 'secret', 'xx', 'secret', 103, '2026-03-08 20:23:19', '1', '1', '2026-03-08 20:23:19', NULL, NULL, '0', NULL, 0);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for chat_message
|
||||
-- ----------------------------
|
||||
@@ -57,10 +27,8 @@ CREATE TABLE `chat_message` (
|
||||
`user_id` bigint NOT NULL COMMENT '用户id',
|
||||
`content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '消息内容',
|
||||
`role` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '对话角色',
|
||||
`deduct_cost` double(20, 2) NULL DEFAULT 0.00 COMMENT '扣除金额',
|
||||
`total_tokens` int NULL DEFAULT 0 COMMENT '累计 Tokens',
|
||||
`model_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '模型名称',
|
||||
`billing_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '计费类型(1-token计费,2-次数计费)',
|
||||
`create_dept` bigint NULL DEFAULT NULL COMMENT '创建部门',
|
||||
`create_by` bigint NULL DEFAULT NULL COMMENT '创建者',
|
||||
`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
|
||||
@@ -85,11 +53,8 @@ CREATE TABLE `chat_model` (
|
||||
`model_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '模型名称',
|
||||
`provider_code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '模型供应商',
|
||||
`model_describe` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '模型描述',
|
||||
`model_price` double NULL DEFAULT NULL COMMENT '模型价格',
|
||||
`model_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '计费类型',
|
||||
`model_dimension` int NULL DEFAULT NULL COMMENT '模型维度',
|
||||
`model_show` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否显示',
|
||||
`model_free` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否免费',
|
||||
`priority` int NULL DEFAULT 1 COMMENT '模型优先级(值越大优先级越高)',
|
||||
`api_host` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '请求地址',
|
||||
`api_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '密钥',
|
||||
`create_dept` bigint NULL DEFAULT NULL COMMENT '创建部门',
|
||||
@@ -105,8 +70,8 @@ CREATE TABLE `chat_model` (
|
||||
-- ----------------------------
|
||||
-- Records of chat_model
|
||||
-- ----------------------------
|
||||
INSERT INTO `chat_model` VALUES (2000585866022060033, 'chat', 'deepseek/deepseek-v3.2', 'ppio', 'deepseek', 1, '1', 'Y', 'Y', 1, 'https://api.ppinfra.com/openai', 'sk_xx', 103, 1, '2025-12-15 23:16:54', 1, '2026-02-25 21:46:08', 'DeepSeek-V3.2 是一款在高效推理、复杂推理能力与智能体场景中表现突出的领先模型。其基于 DeepSeek Sparse Attention(DSA)稀疏注意力机制,在显著降低计算开销的同时优化长上下文性能;通过可扩展强化学习框架,整体能力达到 GPT-5 同级,高算力版本 V3.2-Speciale 更在推理表现上接近 Gemini-3.0-Pro;同时,模型依托大型智能体任务合成管线,具备更强的工具调用与多步骤决策能力,并在 2025 年 IMO 与 IOI 中取得金牌级表现。作为 MaaS 平台,我们已对 DeepSeek-V3.2 完成深度适配,通过动态调度、批处理加速、低延迟推理与企业级 SLA 保障,进一步增强其在企业生产环境中的稳定性、性价比与可控性,适用于搜索、问答、智能体、代码、数据处理等多类高价值场景。', 0);
|
||||
INSERT INTO `chat_model` VALUES (2007528268536287233, 'vector', 'baai/bge-m3', 'ppio', 'bge-m3', 0, '1', 'N', 'Y', 1, 'https://api.ppinfra.com/openai', 'sk_xx', 103, 1, '2026-01-04 03:03:32', 1, '2026-02-25 21:15:14', 'bge-large-zh-v1.5', 0);
|
||||
INSERT INTO `chat_model` VALUES (2000585866022060033, 'chat', 'deepseek/deepseek-v3.2', 'ppio', 'deepseek', NULL, 'Y', 'https://api.ppinfra.com/openai', 'sk_xx', 103, 1, '2025-12-15 23:16:54', 1, '2026-03-15 19:18:48', 'DeepSeek-V3.2 是一款在高效推理、复杂推理能力与智能体场景中表现突出的领先模型。其基于 DeepSeek Sparse Attention(DSA)稀疏注意力机制,在显著降低计算开销的同时优化长上下文性能;通过可扩展强化学习框架,整体能力达到 GPT-5 同级,高算力版本 V3.2-Speciale 更在推理表现上接近 Gemini-3.0-Pro;同时,模型依托大型智能体任务合成管线,具备更强的工具调用与多步骤决策能力,并在 2025 年 IMO 与 IOI 中取得金牌级表现。作为 MaaS 平台,我们已对 DeepSeek-V3.2 完成深度适配,通过动态调度、批处理加速、低延迟推理与企业级 SLA 保障,进一步增强其在企业生产环境中的稳定性、性价比与可控性,适用于搜索、问答、智能体、代码、数据处理等多类高价值场景。', 0);
|
||||
INSERT INTO `chat_model` VALUES (2007528268536287233, 'vector', 'baai/bge-m3', 'ppio', 'bge-m3', 1024, 'N', 'https://api.ppinfra.com/openai', 'sk_xx', 103, 1, '2026-01-04 03:03:32', 1, '2026-03-15 19:18:51', 'BGE-M3 是一款具备多维度能力的文本嵌入模型,可同时实现密集检索、多向量检索和稀疏检索三大核心功能。该模型设计上兼容超过100种语言,并支持从短句到长达8192词元的长文本等多种输入形式。在跨语言检索任务中,BGE-M3展现出显著优势,其性能在MIRACL、MKQA等国际基准测试中位居前列。此外,针对长文档检索场景,该模型在MLDR、NarritiveQA等数据集上的表现同样达到行业领先水平。', 0);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for chat_provider
|
||||
@@ -1101,171 +1066,6 @@ INSERT INTO `gen_table_column` VALUES (2018961776721399811, 2018961776515878913,
|
||||
INSERT INTO `gen_table_column` VALUES (2018961776721399812, 2018961776515878913, 'open_id', '微信用户标识', 'varchar(100)', 'String', 'openId', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 22, 103, 1, '2026-02-04 16:16:13', 1, '2026-02-04 16:20:23');
|
||||
INSERT INTO `gen_table_column` VALUES (2018961776721399813, 2018961776515878913, 'user_balance', '账户余额', 'double(20,2)', 'Long', 'userBalance', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 23, 103, 1, '2026-02-04 16:16:13', 1, '2026-02-04 16:20:23');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for graph_build_task
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `graph_build_task`;
|
||||
CREATE TABLE `graph_build_task` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`task_uuid` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '任务UUID',
|
||||
`graph_uuid` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '图谱UUID',
|
||||
`knowledge_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '知识库ID',
|
||||
`doc_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '文档ID(可选,null表示全量构建)',
|
||||
`task_type` tinyint NULL DEFAULT 1 COMMENT '任务类型:1全量构建、2增量更新、3重建',
|
||||
`task_status` tinyint NULL DEFAULT 1 COMMENT '任务状态:1待执行、2执行中、3成功、4失败',
|
||||
`progress` int NULL DEFAULT 0 COMMENT '进度百分比(0-100)',
|
||||
`total_docs` int NULL DEFAULT 0 COMMENT '总文档数',
|
||||
`processed_docs` int NULL DEFAULT 0 COMMENT '已处理文档数',
|
||||
`extracted_entities` int NULL DEFAULT 0 COMMENT '提取的实体数',
|
||||
`extracted_relations` int NULL DEFAULT 0 COMMENT '提取的关系数',
|
||||
`error_message` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '错误信息',
|
||||
`result_summary` json NULL COMMENT '结果摘要(JSON格式)',
|
||||
`start_time` datetime NULL DEFAULT NULL COMMENT '开始时间',
|
||||
`end_time` datetime NULL DEFAULT NULL COMMENT '结束时间',
|
||||
`create_dept` bigint NULL DEFAULT NULL COMMENT '创建部门',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uk_task_uuid`(`task_uuid` ASC) USING BTREE,
|
||||
INDEX `idx_graph_uuid`(`graph_uuid` ASC) USING BTREE,
|
||||
INDEX `idx_knowledge_id`(`knowledge_id` ASC) USING BTREE,
|
||||
INDEX `idx_task_status`(`task_status` ASC) USING BTREE,
|
||||
INDEX `idx_create_time`(`create_time` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '图谱构建任务表' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of graph_build_task
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for graph_entity_type
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `graph_entity_type`;
|
||||
CREATE TABLE `graph_entity_type` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`type_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '实体类型名称',
|
||||
`type_code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '类型编码',
|
||||
`description` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '描述',
|
||||
`color` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '#1890ff' COMMENT '可视化颜色',
|
||||
`icon` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '图标',
|
||||
`sort` int NULL DEFAULT 0 COMMENT '显示顺序',
|
||||
`is_enable` tinyint(1) NULL DEFAULT 1 COMMENT '是否启用(0否 1是)',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uk_type_code`(`type_code` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '图谱实体类型定义表' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of graph_entity_type
|
||||
-- ----------------------------
|
||||
INSERT INTO `graph_entity_type` VALUES (1, '人物', 'PERSON', '人物实体,包括真实人物和虚拟角色', '#1890ff', 'user', 1, 1, '', '2025-11-07 16:33:37', '', '2025-11-07 16:33:37', NULL);
|
||||
INSERT INTO `graph_entity_type` VALUES (2, '机构', 'ORGANIZATION', '组织机构,包括公司、政府机构等', '#52c41a', 'bank', 2, 1, '', '2025-11-07 16:33:37', '', '2025-11-07 16:33:37', NULL);
|
||||
INSERT INTO `graph_entity_type` VALUES (3, '地点', 'LOCATION', '地理位置,包括国家、城市、地址等', '#fa8c16', 'environment', 3, 1, '', '2025-11-07 16:33:37', '', '2025-11-07 16:33:37', NULL);
|
||||
INSERT INTO `graph_entity_type` VALUES (4, '概念', 'CONCEPT', '抽象概念,包括理论、方法等', '#722ed1', 'bulb', 4, 1, '', '2025-11-07 16:33:37', '', '2025-11-07 16:33:37', NULL);
|
||||
INSERT INTO `graph_entity_type` VALUES (5, '事件', 'EVENT', '事件记录,包括历史事件、活动等', '#eb2f96', 'calendar', 5, 1, '', '2025-11-07 16:33:37', '', '2025-11-07 16:33:37', NULL);
|
||||
INSERT INTO `graph_entity_type` VALUES (6, '产品', 'PRODUCT', '产品或服务', '#13c2c2', 'shopping', 6, 1, '', '2025-11-07 16:33:37', '', '2025-11-07 16:33:37', NULL);
|
||||
INSERT INTO `graph_entity_type` VALUES (7, '技术', 'TECHNOLOGY', '技术或工具', '#2f54eb', 'tool', 7, 1, '', '2025-11-07 16:33:37', '', '2025-11-07 16:33:37', NULL);
|
||||
INSERT INTO `graph_entity_type` VALUES (8, '文档', 'DOCUMENT', '文档或资料', '#faad14', 'file-text', 8, 1, '', '2025-11-07 16:33:37', '', '2025-11-07 16:33:37', NULL);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for graph_query_history
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `graph_query_history`;
|
||||
CREATE TABLE `graph_query_history` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`query_uuid` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '查询UUID',
|
||||
`user_id` bigint NOT NULL COMMENT '用户ID',
|
||||
`knowledge_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '知识库ID',
|
||||
`graph_uuid` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '图谱UUID',
|
||||
`query_text` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '查询文本',
|
||||
`query_type` tinyint NULL DEFAULT 1 COMMENT '查询类型:1实体查询、2关系查询、3路径查询、4混合查询',
|
||||
`cypher_query` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '生成的Cypher查询',
|
||||
`result_count` int NULL DEFAULT 0 COMMENT '结果数量',
|
||||
`response_time` int NULL DEFAULT 0 COMMENT '响应时间(ms)',
|
||||
`is_success` tinyint(1) NULL DEFAULT 1 COMMENT '是否成功(0否 1是)',
|
||||
`error_message` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '错误信息',
|
||||
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uk_query_uuid`(`query_uuid` ASC) USING BTREE,
|
||||
INDEX `idx_user_id`(`user_id` ASC) USING BTREE,
|
||||
INDEX `idx_knowledge_id`(`knowledge_id` ASC) USING BTREE,
|
||||
INDEX `idx_create_time`(`create_time` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '图谱查询历史表' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of graph_query_history
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for graph_relation_type
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `graph_relation_type`;
|
||||
CREATE TABLE `graph_relation_type` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`relation_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '关系名称',
|
||||
`relation_code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '关系编码',
|
||||
`description` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '描述',
|
||||
`direction` tinyint(1) NULL DEFAULT 1 COMMENT '关系方向:0双向、1单向',
|
||||
`style` json NULL COMMENT '可视化样式(JSON格式)',
|
||||
`sort` int NULL DEFAULT 0 COMMENT '显示顺序',
|
||||
`is_enable` tinyint(1) NULL DEFAULT 1 COMMENT '是否启用(0否 1是)',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uk_relation_code`(`relation_code` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 14 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '图谱关系类型定义表' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of graph_relation_type
|
||||
-- ----------------------------
|
||||
INSERT INTO `graph_relation_type` VALUES (1, '属于', 'BELONGS_TO', '隶属关系,表示从属或归属', 1, NULL, 1, 1, '', '2025-11-07 16:33:37', '', '2025-11-07 16:33:37', NULL);
|
||||
INSERT INTO `graph_relation_type` VALUES (2, '位于', 'LOCATED_IN', '地理位置关系', 1, NULL, 2, 1, '', '2025-11-07 16:33:37', '', '2025-11-07 16:33:37', NULL);
|
||||
INSERT INTO `graph_relation_type` VALUES (3, '相关', 'RELATED_TO', '一般关联关系', 0, NULL, 3, 1, '', '2025-11-07 16:33:37', '', '2025-11-07 16:33:37', NULL);
|
||||
INSERT INTO `graph_relation_type` VALUES (4, '导致', 'CAUSES', '因果关系', 1, NULL, 4, 1, '', '2025-11-07 16:33:37', '', '2025-11-07 16:33:37', NULL);
|
||||
INSERT INTO `graph_relation_type` VALUES (5, '包含', 'CONTAINS', '包含关系', 1, NULL, 5, 1, '', '2025-11-07 16:33:37', '', '2025-11-07 16:33:37', NULL);
|
||||
INSERT INTO `graph_relation_type` VALUES (6, '提及', 'MENTIONS', '文档提及实体的关系', 1, NULL, 6, 1, '', '2025-11-07 16:33:37', '', '2025-11-07 16:33:37', NULL);
|
||||
INSERT INTO `graph_relation_type` VALUES (7, '部分', 'PART_OF', '部分关系', 1, NULL, 7, 1, '', '2025-11-07 16:33:37', '', '2025-11-07 16:33:37', NULL);
|
||||
INSERT INTO `graph_relation_type` VALUES (8, '实例', 'INSTANCE_OF', '实例关系', 1, NULL, 8, 1, '', '2025-11-07 16:33:37', '', '2025-11-07 16:33:37', NULL);
|
||||
INSERT INTO `graph_relation_type` VALUES (9, '相似', 'SIMILAR_TO', '相似关系', 0, NULL, 9, 1, '', '2025-11-07 16:33:37', '', '2025-11-07 16:33:37', NULL);
|
||||
INSERT INTO `graph_relation_type` VALUES (10, '前序', 'PRECEDES', '时序关系', 1, NULL, 10, 1, '', '2025-11-07 16:33:37', '', '2025-11-07 16:33:37', NULL);
|
||||
INSERT INTO `graph_relation_type` VALUES (11, '工作于', 'WORKS_AT', '人物与机构的工作关系', 1, NULL, 11, 1, '', '2025-11-07 16:33:37', '', '2025-11-07 16:33:37', NULL);
|
||||
INSERT INTO `graph_relation_type` VALUES (12, '创建', 'CREATED_BY', '创建关系', 1, NULL, 12, 1, '', '2025-11-07 16:33:37', '', '2025-11-07 16:33:37', NULL);
|
||||
INSERT INTO `graph_relation_type` VALUES (13, '使用', 'USES', '使用关系', 1, NULL, 13, 1, '', '2025-11-07 16:33:37', '', '2025-11-07 16:33:37', NULL);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for graph_statistics
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `graph_statistics`;
|
||||
CREATE TABLE `graph_statistics` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`graph_uuid` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '图谱UUID',
|
||||
`stat_date` date NOT NULL COMMENT '统计日期',
|
||||
`total_nodes` int NULL DEFAULT 0 COMMENT '总节点数',
|
||||
`total_relationships` int NULL DEFAULT 0 COMMENT '总关系数',
|
||||
`node_type_distribution` json NULL COMMENT '节点类型分布(JSON格式)',
|
||||
`relation_type_distribution` json NULL COMMENT '关系类型分布(JSON格式)',
|
||||
`query_count` int NULL DEFAULT 0 COMMENT '查询次数',
|
||||
`avg_query_time` int NULL DEFAULT 0 COMMENT '平均查询时间(ms)',
|
||||
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uk_graph_date`(`graph_uuid` ASC, `stat_date` ASC) USING BTREE,
|
||||
INDEX `idx_stat_date`(`stat_date` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '图谱统计信息表' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of graph_statistics
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for knowledge_attach
|
||||
-- ----------------------------
|
||||
@@ -1286,7 +1086,7 @@ CREATE TABLE `knowledge_attach` (
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户Id',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `idx_kname`(`knowledge_id` ASC, `name` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2016797369199366146 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '知识库附件' ROW_FORMAT = DYNAMIC;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2033199209203183619 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '知识库附件' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of knowledge_attach
|
||||
@@ -1309,81 +1109,12 @@ CREATE TABLE `knowledge_fragment` (
|
||||
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户Id',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2016797369027399683 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '知识片段' ROW_FORMAT = DYNAMIC;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2033199209131880451 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '知识片段' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of knowledge_fragment
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for knowledge_graph_instance
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `knowledge_graph_instance`;
|
||||
CREATE TABLE `knowledge_graph_instance` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`graph_uuid` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '图谱UUID',
|
||||
`knowledge_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '关联knowledge_info.kid',
|
||||
`graph_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '图谱名称',
|
||||
`graph_status` tinyint NULL DEFAULT 10 COMMENT '构建状态:10构建中、20已完成、30失败',
|
||||
`node_count` int NULL DEFAULT 0 COMMENT '节点数量',
|
||||
`relationship_count` int NULL DEFAULT 0 COMMENT '关系数量',
|
||||
`config` json NULL COMMENT '图谱配置(JSON格式)',
|
||||
`model_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'LLM模型名称',
|
||||
`entity_types` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '实体类型(逗号分隔)',
|
||||
`relation_types` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '关系类型(逗号分隔)',
|
||||
`error_message` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '错误信息',
|
||||
`create_dept` bigint NULL DEFAULT NULL COMMENT '创建部门',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 1代表删除)',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uk_graph_uuid`(`graph_uuid` ASC) USING BTREE,
|
||||
INDEX `idx_knowledge_id`(`knowledge_id` ASC) USING BTREE,
|
||||
INDEX `idx_graph_status`(`graph_status` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '知识图谱实例表' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of knowledge_graph_instance
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for knowledge_graph_segment
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `knowledge_graph_segment`;
|
||||
CREATE TABLE `knowledge_graph_segment` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`uuid` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '片段UUID',
|
||||
`kb_uuid` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '知识库UUID',
|
||||
`kb_item_uuid` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '知识库条目UUID',
|
||||
`doc_uuid` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '文档UUID',
|
||||
`segment_text` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '片段文本内容',
|
||||
`chunk_index` int NULL DEFAULT 0 COMMENT '片段索引(第几个片段)',
|
||||
`total_chunks` int NULL DEFAULT 1 COMMENT '总片段数',
|
||||
`extraction_status` tinyint NULL DEFAULT 0 COMMENT '抽取状态:0-待处理 1-处理中 2-已完成 3-失败',
|
||||
`entity_count` int NULL DEFAULT 0 COMMENT '抽取的实体数量',
|
||||
`relation_count` int NULL DEFAULT 0 COMMENT '抽取的关系数量',
|
||||
`token_used` int NULL DEFAULT 0 COMMENT '消耗的token数',
|
||||
`error_message` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '错误信息',
|
||||
`user_id` bigint NULL DEFAULT NULL COMMENT '用户ID',
|
||||
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uk_uuid`(`uuid` ASC) USING BTREE,
|
||||
INDEX `idx_kb_uuid`(`kb_uuid` ASC) USING BTREE,
|
||||
INDEX `idx_kb_item_uuid`(`kb_item_uuid` ASC) USING BTREE,
|
||||
INDEX `idx_doc_uuid`(`doc_uuid` ASC) USING BTREE,
|
||||
INDEX `idx_user_id`(`user_id` ASC) USING BTREE,
|
||||
INDEX `idx_create_time`(`create_time` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '知识图谱片段表' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of knowledge_graph_segment
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for knowledge_info
|
||||
-- ----------------------------
|
||||
@@ -1408,7 +1139,7 @@ CREATE TABLE `knowledge_info` (
|
||||
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户Id',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2018245281372573699 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '知识库' ROW_FORMAT = DYNAMIC;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2033198818050781187 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '知识库' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of knowledge_info
|
||||
@@ -2639,6 +2370,21 @@ INSERT INTO `sys_logininfor` VALUES (2026654082020204546, '000000', 'admin', 'pc
|
||||
INSERT INTO `sys_logininfor` VALUES (2026654455514587138, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-25 21:44:10');
|
||||
INSERT INTO `sys_logininfor` VALUES (2027260957187186689, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-27 13:54:12');
|
||||
INSERT INTO `sys_logininfor` VALUES (2030617171346399233, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-08 20:10:35');
|
||||
INSERT INTO `sys_logininfor` VALUES (2033083137191841794, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 15:29:27');
|
||||
INSERT INTO `sys_logininfor` VALUES (2033102367094214657, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 16:45:52');
|
||||
INSERT INTO `sys_logininfor` VALUES (2033116897354551298, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 17:43:36');
|
||||
INSERT INTO `sys_logininfor` VALUES (2033133175565836289, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 18:48:17');
|
||||
INSERT INTO `sys_logininfor` VALUES (2033167392953675778, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 21:04:16');
|
||||
INSERT INTO `sys_logininfor` VALUES (2033168637663719425, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 21:09:12');
|
||||
INSERT INTO `sys_logininfor` VALUES (2033170263812157441, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '退出成功', '2026-03-15 21:15:40');
|
||||
INSERT INTO `sys_logininfor` VALUES (2033170654197002242, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 21:17:13');
|
||||
INSERT INTO `sys_logininfor` VALUES (2033170805703651330, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '退出成功', '2026-03-15 21:17:49');
|
||||
INSERT INTO `sys_logininfor` VALUES (2033170821767835650, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 21:17:53');
|
||||
INSERT INTO `sys_logininfor` VALUES (2033170964009267201, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 21:18:27');
|
||||
INSERT INTO `sys_logininfor` VALUES (2033197762549985282, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 23:04:56');
|
||||
INSERT INTO `sys_logininfor` VALUES (2033200372921217025, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '1', '密码输入错误1次', '2026-03-15 23:15:19');
|
||||
INSERT INTO `sys_logininfor` VALUES (2033200386498179073, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 23:15:22');
|
||||
INSERT INTO `sys_logininfor` VALUES (2033210457315696642, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 23:55:23');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_menu
|
||||
@@ -2831,31 +2577,19 @@ INSERT INTO `sys_menu` VALUES (2000210913846157316, '模型管理新增', 200021
|
||||
INSERT INTO `sys_menu` VALUES (2000210913846157317, '模型管理修改', 2000210913846157314, 3, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:model:edit', '#', 103, 1, '2025-12-14 22:27:59', NULL, NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2000210913846157318, '模型管理删除', 2000210913846157314, 4, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:model:remove', '#', 103, 1, '2025-12-14 22:27:59', NULL, NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2000210913846157319, '模型管理导出', 2000210913846157314, 5, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:model:export', '#', 103, 1, '2025-12-14 22:28:00', NULL, NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2000210914299142145, '聊天配置', 2000209300188356609, 1, 'config', 'chat/config/index', NULL, 1, 0, 'C', '0', '0', 'system:config:list', 'tdesign:task-setting', 103, 1, '2025-12-14 22:27:46', 1, '2025-12-15 00:59:48', '配置信息菜单');
|
||||
INSERT INTO `sys_menu` VALUES (2000210914299142146, '配置信息查询', 2000210914299142145, 1, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:config:query', '#', 103, 1, '2025-12-14 22:27:46', NULL, NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2000210914299142147, '配置信息新增', 2000210914299142145, 2, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:config:add', '#', 103, 1, '2025-12-14 22:27:46', NULL, NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2000210914299142148, '配置信息修改', 2000210914299142145, 3, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:config:edit', '#', 103, 1, '2025-12-14 22:27:46', NULL, NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2000210914299142149, '配置信息删除', 2000210914299142145, 4, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:config:remove', '#', 103, 1, '2025-12-14 22:27:46', NULL, NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2000210914299142150, '配置信息导出', 2000210914299142145, 5, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:config:export', '#', 103, 1, '2025-12-14 22:27:46', NULL, NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2000210914680823809, '聊天消息', 2000209300188356609, 1, 'message', 'chat/message/index', NULL, 1, 0, 'C', '0', '0', 'system:message:list', 'system-uicons:message', 103, 1, '2025-12-14 22:27:54', 1, '2025-12-15 00:53:47', '聊天消息菜单');
|
||||
INSERT INTO `sys_menu` VALUES (2000210914680823810, '聊天消息查询', 2000210914680823809, 1, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:message:query', '#', 103, 1, '2025-12-14 22:27:54', NULL, NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2000210914680823811, '聊天消息新增', 2000210914680823809, 2, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:message:add', '#', 103, 1, '2025-12-14 22:27:54', NULL, NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2000210914680823812, '聊天消息修改', 2000210914680823809, 3, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:message:edit', '#', 103, 1, '2025-12-14 22:27:54', NULL, NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2000210914680823813, '聊天消息删除', 2000210914680823809, 4, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:message:remove', '#', 103, 1, '2025-12-14 22:27:54', NULL, NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2000210914680823814, '聊天消息导出', 2000210914680823809, 5, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:message:export', '#', 103, 1, '2025-12-14 22:27:54', NULL, NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2006681261898813441, '知识库', 2006683336984580098, 1, 'info', 'knowledge/info/index', NULL, 1, 0, 'C', '0', '0', 'knowledge:info:list', 'solar:book-line-duotone', 103, 1, '2026-01-01 18:59:05', 1, '2026-01-01 19:08:03', '知识库菜单');
|
||||
INSERT INTO `sys_menu` VALUES (2006681261898813441, '知识管理', 2000209300188356609, 1, 'info', 'knowledge/info/index', NULL, 1, 0, 'C', '0', '0', 'knowledge:info:list', 'solar:book-line-duotone', 103, 1, '2026-01-01 18:59:05', 1, '2026-03-15 21:07:50', '知识库菜单');
|
||||
INSERT INTO `sys_menu` VALUES (2006681261898813442, '知识库查询', 2006681261898813441, 1, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:info:query', '#', 103, 1, '2026-01-01 18:59:05', NULL, NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2006681261898813443, '知识库新增', 2006681261898813441, 2, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:info:add', '#', 103, 1, '2026-01-01 18:59:05', NULL, NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2006681261898813444, '知识库修改', 2006681261898813441, 3, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:info:edit', '#', 103, 1, '2026-01-01 18:59:05', NULL, NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2006681261898813445, '知识库删除', 2006681261898813441, 4, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:info:remove', '#', 103, 1, '2026-01-01 18:59:06', NULL, NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2006681261898813446, '知识库导出', 2006681261898813441, 5, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:info:export', '#', 103, 1, '2026-01-01 18:59:06', NULL, NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2006683336984580098, '知识管理', 0, 2, 'knowledge', '', NULL, 1, 0, 'M', '0', '0', NULL, 'bx:book', 103, 1, '2026-01-01 19:06:05', 1, '2026-01-01 19:06:05', '');
|
||||
INSERT INTO `sys_menu` VALUES (2019464280262905857, '图谱实例', 2019464531388469250, 1, 'graphInstance', 'graph/graphInstance/index', NULL, 1, 0, 'C', '0', '0', 'operator:graph:list', 'ant-design:node-index-outlined', 103, 1, '2026-02-06 01:32:59', 1, '2026-02-06 01:40:06', '');
|
||||
INSERT INTO `sys_menu` VALUES (2019464531388469250, '知识图谱', 2006683336984580098, 15, 'graph', '', NULL, 1, 0, 'M', '0', '0', NULL, 'carbon:chart-relationship', 103, 1, '2026-02-06 01:33:59', 1, '2026-02-06 01:33:59', '');
|
||||
INSERT INTO `sys_menu` VALUES (2019464779217309697, '图谱可视化', 2019464531388469250, 2, 'graphVisualization', 'graph/graphVisualization/index', NULL, 1, 0, 'C', '0', '0', 'operator:graph:view', 'carbon:chart-network', 103, 1, '2026-02-06 01:34:58', 1, '2026-02-06 01:40:14', '');
|
||||
INSERT INTO `sys_menu` VALUES (2019464917407043585, '图谱检索', 2019464531388469250, 3, 'graphRAG', 'graph/graphRAG/index', NULL, 1, 0, 'C', '0', '0', 'operator:graph:retrieve', 'carbon:search-advanced', 103, 1, '2026-02-06 01:35:31', 1, '2026-02-06 01:40:19', '');
|
||||
INSERT INTO `sys_menu` VALUES (2031360871412346881, '流程编排', 0, 2, 'aiflow', '', NULL, 1, 0, 'M', '0', '0', NULL, 'fluent:flow-dot-16-filled', 103, 1, '2026-03-10 21:25:47', 1, '2026-03-10 21:25:47', '');
|
||||
INSERT INTO `sys_menu` VALUES (2031361596464902145, '编排管理', 2031360871412346881, 1, 'aiflow', 'aiflow/index', NULL, 1, 0, 'C', '0', '0', NULL, 'carbon:flow', 103, 1, '2026-03-10 21:28:40', 1, '2026-03-10 21:29:40', '');
|
||||
INSERT INTO `sys_menu` VALUES (2031361596464902145, '编排管理', 2000209300188356609, 1, 'aiflow', 'aiflow/index', NULL, 1, 0, 'C', '0', '0', NULL, 'carbon:flow', 103, 1, '2026-03-10 21:28:40', 1, '2026-03-15 21:06:01', '');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_notice
|
||||
@@ -2946,6 +2680,12 @@ INSERT INTO `sys_oss` VALUES (2026640515967557633, '000000', '2026/02/25/afecabe
|
||||
INSERT INTO `sys_oss` VALUES (2026640548213366785, '000000', '2026/02/25/e16429a462e54e14a1d36673146b9e3c.png', 'ppio-color.png', '.png', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/e16429a462e54e14a1d36673146b9e3c.png', '{\"fileSize\":\"7382\",\"contentType\":\"image/png\"}', 103, '2026-02-25 20:48:55', 1, '2026-02-25 20:48:55', 1, 'qcloud');
|
||||
INSERT INTO `sys_oss` VALUES (2026640572443860993, '000000', '2026/02/25/049bb6a507174f73bba4b8d8b9e55b8a.png', 'ppio-color.png', '.png', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/049bb6a507174f73bba4b8d8b9e55b8a.png', '{\"fileSize\":\"7382\",\"contentType\":\"image/png\"}', 103, '2026-02-25 20:49:00', 1, '2026-02-25 20:49:00', 1, 'qcloud');
|
||||
INSERT INTO `sys_oss` VALUES (2026640621945036802, '000000', '2026/02/25/de2aa7e649de44f3ba5c6380ac6acd04.png', 'bailian-color.png', '.png', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/de2aa7e649de44f3ba5c6380ac6acd04.png', '{\"fileSize\":\"5901\",\"contentType\":\"image/png\"}', 103, '2026-02-25 20:49:12', 1, '2026-02-25 20:49:12', 1, 'qcloud');
|
||||
INSERT INTO `sys_oss` VALUES (2033120065673043969, '000000', '2026/03/15/68c4d853814e444982c2517ffabac0f3.jpg', '9b75e600b2df6160261a507055eabfdf.jpg', '.jpg', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/03/15/68c4d853814e444982c2517ffabac0f3.jpg', '{\"fileSize\":\"28027\",\"contentType\":\"image/jpeg\"}', 103, '2026-03-15 17:56:12', 1, '2026-03-15 17:56:12', 1, 'qcloud');
|
||||
INSERT INTO `sys_oss` VALUES (2033169884118593537, '000000', '2026/03/15/4b7e93a72bf04805ae59985cc0845ef1.png', 'logo.png', '.png', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/03/15/4b7e93a72bf04805ae59985cc0845ef1.png', '{\"fileSize\":\"61537\",\"contentType\":\"image/png\"}', 103, '2026-03-15 21:14:10', 1, '2026-03-15 21:14:10', 1, 'qcloud');
|
||||
INSERT INTO `sys_oss` VALUES (2033198191581147137, '000000', '2026/03/15/66d9e6d216c74652bb466a13d24f4440.txt', 'ruoyi-ai介绍.txt', '.txt', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/03/15/66d9e6d216c74652bb466a13d24f4440.txt', '{\"fileSize\":\"1166\",\"contentType\":\"text/plain\"}', 103, '2026-03-15 23:06:39', 1, '2026-03-15 23:06:39', 1, 'qcloud');
|
||||
INSERT INTO `sys_oss` VALUES (2033198447232364546, '000000', '2026/03/15/ae1b1e0d363e4bc1b3321d696453fdbf.txt', 'ruoyi-ai介绍.txt', '.txt', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/03/15/ae1b1e0d363e4bc1b3321d696453fdbf.txt', '{\"fileSize\":\"1166\",\"contentType\":\"text/plain\"}', 103, '2026-03-15 23:07:39', 1, '2026-03-15 23:07:39', 1, 'qcloud');
|
||||
INSERT INTO `sys_oss` VALUES (2033198841211727874, '000000', '2026/03/15/83564059b4f643b69a1e0ea727d17364.txt', 'ruoyi-ai介绍.txt', '.txt', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/03/15/83564059b4f643b69a1e0ea727d17364.txt', '{\"fileSize\":\"1166\",\"contentType\":\"text/plain\"}', 103, '2026-03-15 23:09:13', 1, '2026-03-15 23:09:13', 1, 'qcloud');
|
||||
INSERT INTO `sys_oss` VALUES (2033199209064771586, '000000', '2026/03/15/695360eb380d43d6af34e8a308c09696.txt', 'ruoyi-ai介绍.txt', '.txt', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/03/15/695360eb380d43d6af34e8a308c09696.txt', '{\"fileSize\":\"1166\",\"contentType\":\"text/plain\"}', 103, '2026-03-15 23:10:41', 1, '2026-03-15 23:10:41', 1, 'qcloud');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_oss_config
|
||||
@@ -2981,7 +2721,7 @@ CREATE TABLE `sys_oss_config` (
|
||||
INSERT INTO `sys_oss_config` VALUES (1, '000000', 'minio', 'ruoyi', 'ruoyi123', 'ruoyi', '', '127.0.0.1:9000', '', 'N', '', '1', '1', '', 103, 1, '2026-02-03 05:14:52', 1, '2026-02-25 15:44:13', NULL);
|
||||
INSERT INTO `sys_oss_config` VALUES (2, '000000', 'qiniu', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 's3-cn-north-1.qiniucs.com', '', 'N', '', '1', '1', '', 103, 1, '2026-02-03 05:14:52', 1, '2026-02-03 05:14:52', NULL);
|
||||
INSERT INTO `sys_oss_config` VALUES (3, '000000', 'aliyun', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'oss-cn-beijing.aliyuncs.com', '', 'N', '', '1', '1', '', 103, 1, '2026-02-03 05:14:52', 1, '2026-02-03 05:14:52', NULL);
|
||||
INSERT INTO `sys_oss_config` VALUES (4, '000000', 'qcloud', 'xx', 'xx', 'ruoyiai-1254149996', '', 'cos.ap-guangzhou.myqcloud.com', '', 'Y', 'ap-guangzhou', '1', '0', '', 103, 1, '2026-02-03 05:14:52', 1, '2026-02-25 16:51:41', '');
|
||||
INSERT INTO `sys_oss_config` VALUES (4, '000000', 'qcloud', 'xx', 'xx', 'ruoyiai-1254149996', '', 'cos.ap-guangzhou.myqcloud.com', '', 'Y', 'ap-guangzhou', '1', '0', '', 103, 1, '2026-02-03 05:14:52', 1, '2026-03-15 17:56:06', '');
|
||||
INSERT INTO `sys_oss_config` VALUES (5, '000000', 'image', 'ruoyi', 'ruoyi123', 'ruoyi', 'image', '127.0.0.1:9000', '', 'N', '', '1', '1', '', 103, 1, '2026-02-03 05:14:53', 1, '2026-02-03 05:14:53', NULL);
|
||||
|
||||
-- ----------------------------
|
||||
@@ -3428,7 +3168,7 @@ CREATE TABLE `sys_user` (
|
||||
-- ----------------------------
|
||||
-- Records of sys_user
|
||||
-- ----------------------------
|
||||
INSERT INTO `sys_user` VALUES (1, '000000', 103, 'admin', 'admin', 'sys_user', 'ageerle@163.com', '15888888888', '1', NULL, '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', '2026-03-08 20:10:35', 103, 1, '2026-02-05 09:22:12', -1, '2026-03-08 20:10:35', '管理员', NULL, 0.00);
|
||||
INSERT INTO `sys_user` VALUES (1, '000000', 103, 'admin', 'admin', 'sys_user', 'ageerle@163.com', '15888888888', '1', NULL, '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', '2026-03-15 23:55:23', 103, 1, '2026-02-05 09:22:12', -1, '2026-03-15 23:55:23', '管理员', NULL, 0.00);
|
||||
INSERT INTO `sys_user` VALUES (3, '000000', 108, 'test', '本部门及以下 密码666666', 'sys_user', '', '', '0', NULL, '$2a$10$b8yUzN0C71sbz.PhNOCgJe.Tu1yWC3RNrTyjSQ8p1W0.aaUXUJ.Ne', '0', '0', '127.0.0.1', '2026-02-05 09:22:12', 103, 1, '2026-02-05 09:22:12', 3, '2026-02-05 09:22:12', NULL, NULL, 0.00);
|
||||
INSERT INTO `sys_user` VALUES (4, '000000', 102, 'test1', '仅本人 密码666666', 'sys_user', '', '', '0', NULL, '$2a$10$b8yUzN0C71sbz.PhNOCgJe.Tu1yWC3RNrTyjSQ8p1W0.aaUXUJ.Ne', '0', '0', '127.0.0.1', '2026-02-05 09:22:12', 103, 1, '2026-02-05 09:22:12', 4, '2026-02-05 09:22:12', NULL, NULL, 0.00);
|
||||
|
||||
|
||||
37
pom.xml
37
pom.xml
@@ -59,6 +59,8 @@
|
||||
<langgraph4j.version>1.5.3</langgraph4j.version>
|
||||
<weaviate.version>1.19.6</weaviate.version>
|
||||
<dify.version>1.0.7</dify.version>
|
||||
<!-- gRPC 版本 - 解决 Milvus SDK 依赖冲突 -->
|
||||
<grpc.version>1.62.2</grpc.version>
|
||||
<!-- Apache Commons Compress - 用于POI处理ZIP格式 -->
|
||||
<commons-compress.version>1.27.1</commons-compress.version>
|
||||
|
||||
@@ -129,6 +131,15 @@
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- gRPC BOM - 解决 Milvus SDK 依赖冲突,强制统一版本 -->
|
||||
<dependency>
|
||||
<groupId>io.grpc</groupId>
|
||||
<artifactId>grpc-bom</artifactId>
|
||||
<version>${grpc.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- hutool 的依赖配置-->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
@@ -352,24 +363,12 @@
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>ruoyi-job</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>ruoyi-generator</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>ruoyi-demo</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>ruoyi-chat</artifactId>
|
||||
@@ -383,13 +382,6 @@
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 微信模块 -->
|
||||
<dependency>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>ruoyi-wechat</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- AI流程编排模块 -->
|
||||
<dependency>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
@@ -397,13 +389,6 @@
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 企业微信SDK -->
|
||||
<dependency>
|
||||
<groupId>com.github.binarywang</groupId>
|
||||
<artifactId>weixin-java-cp</artifactId>
|
||||
<version>${weixin-java-cp.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Jackson XML -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
|
||||
@@ -70,23 +70,12 @@
|
||||
<artifactId>ruoyi-system</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>ruoyi-job</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 代码生成-->
|
||||
<dependency>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>ruoyi-generator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- demo模块 -->
|
||||
<dependency>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>ruoyi-demo</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>ruoyi-chat</artifactId>
|
||||
@@ -98,12 +87,6 @@
|
||||
<artifactId>ruoyi-workflow</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 微信模块 -->
|
||||
<dependency>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>ruoyi-wechat</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- AI流程编排模块 -->
|
||||
<dependency>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
|
||||
@@ -125,9 +125,6 @@ security:
|
||||
- /*/api-docs/**
|
||||
- /warm-flow-ui/config
|
||||
- /workflow/run
|
||||
- /user/qrcode
|
||||
- /user/login/qrcode
|
||||
- /weixin/check
|
||||
# 多租户配置
|
||||
tenant:
|
||||
# 是否开启
|
||||
@@ -206,6 +203,7 @@ springdoc:
|
||||
name: ageerle
|
||||
email: ageerle@163.com
|
||||
url: https://gitee.com/ageerle/ruoyi-ai
|
||||
|
||||
#这里定义了两个分组,可定义多个,也可以不定义
|
||||
group-configs:
|
||||
- group: 1.演示模块
|
||||
@@ -247,12 +245,6 @@ management:
|
||||
show-details: ALWAYS
|
||||
logfile:
|
||||
external-file: ./logs/sys-console.log
|
||||
health:
|
||||
# ⚠️ 禁用 Neo4j 健康检查
|
||||
# Spring Boot Actuator 会自动为 Neo4j 创建健康检查器
|
||||
# 这会导致应用在启动时尝试连接到 Neo4j
|
||||
neo4j:
|
||||
enabled: false
|
||||
|
||||
--- # 默认/推荐使用sse推送
|
||||
sse:
|
||||
@@ -285,7 +277,7 @@ warm-flow:
|
||||
vector-store:
|
||||
# 向量存储类型 可选(weaviate/milvus)
|
||||
# 如需修改向量库类型,请修改此配置值!
|
||||
type: weaviate
|
||||
type: milvus
|
||||
# Weaviate配置
|
||||
weaviate:
|
||||
protocol: http
|
||||
@@ -295,81 +287,3 @@ vector-store:
|
||||
milvus:
|
||||
url: http://localhost:19530
|
||||
collectionname: LocalKnowledge
|
||||
|
||||
chat:
|
||||
memory:
|
||||
enabled: true
|
||||
maxMessages: 20
|
||||
persistenceEnabled: true
|
||||
|
||||
# 企业微信应用
|
||||
wechat:
|
||||
cp:
|
||||
corpId:
|
||||
appConfigs:
|
||||
- agentId:
|
||||
secret: ''
|
||||
token: ''
|
||||
aesKey: ''
|
||||
|
||||
--- # Neo4j 知识图谱配置
|
||||
neo4j:
|
||||
uri: bolt://117.72.192.162:7687
|
||||
username: neo4j
|
||||
password: MySecurePass123!
|
||||
database: neo4j
|
||||
max-connection-pool-size: 50
|
||||
connection-timeout-seconds: 30
|
||||
|
||||
# 知识图谱配置
|
||||
knowledge:
|
||||
graph:
|
||||
# 是否启用知识图谱功能
|
||||
enabled: false
|
||||
# 图数据库类型: neo4j 或 apache-age
|
||||
database-type: neo4j
|
||||
# 是否自动创建索引
|
||||
auto-create-index: true
|
||||
# 批量处理大小
|
||||
batch-size: 1000
|
||||
# 最大重试次数
|
||||
max-retry-count: 3
|
||||
|
||||
# 实体抽取配置
|
||||
extraction:
|
||||
# 置信度阈值(低于此值的实体将被过滤)
|
||||
confidence-threshold: 0.7
|
||||
# 最大实体数量(每个文档)
|
||||
max-entities-per-doc: 100
|
||||
# 最大关系数量(每个文档)
|
||||
max-relations-per-doc: 200
|
||||
# 文本分片大小(用于长文档)
|
||||
chunk-size: 2000
|
||||
# 分片重叠大小
|
||||
chunk-overlap: 200
|
||||
|
||||
# 查询配置
|
||||
query:
|
||||
# 默认查询限制数量
|
||||
default-limit: 100
|
||||
# 最大查询限制数量
|
||||
max-limit: 1000
|
||||
# 路径查询最大深度
|
||||
max-path-depth: 5
|
||||
# 查询超时时间(秒)
|
||||
timeout-seconds: 30
|
||||
# 是否启用查询缓存
|
||||
cache-enabled: true
|
||||
# 缓存过期时间(分钟)
|
||||
cache-expire-minutes: 60
|
||||
|
||||
--- # MCP 模块配置
|
||||
app:
|
||||
mcp:
|
||||
client:
|
||||
# 请求超时时间(秒)
|
||||
request-timeout: 30
|
||||
# 连接超时时间(秒)
|
||||
connection-timeout: 10
|
||||
# 最大重试次数
|
||||
max-retries: 3
|
||||
|
||||
@@ -48,11 +48,6 @@ public class ChatMessageBo extends BaseEntity {
|
||||
*/
|
||||
private String role;
|
||||
|
||||
/**
|
||||
* 扣除金额
|
||||
*/
|
||||
private Long deductCost;
|
||||
|
||||
/**
|
||||
* 累计 Tokens
|
||||
*/
|
||||
@@ -63,11 +58,6 @@ public class ChatMessageBo extends BaseEntity {
|
||||
*/
|
||||
private String modelName;
|
||||
|
||||
/**
|
||||
* 计费类型(1-token计费,2-次数计费)
|
||||
*/
|
||||
private String billingType;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
|
||||
@@ -45,30 +45,15 @@ public class ChatModelBo extends BaseEntity {
|
||||
*/
|
||||
private String modelDescribe;
|
||||
|
||||
/**
|
||||
* 模型价格
|
||||
*/
|
||||
private Long modelPrice;
|
||||
|
||||
/**
|
||||
* 计费类型
|
||||
*/
|
||||
private String modelType;
|
||||
|
||||
/**
|
||||
* 是否显示
|
||||
*/
|
||||
private String modelShow;
|
||||
|
||||
/**
|
||||
* 是否免费
|
||||
* 向量维度
|
||||
*/
|
||||
private String modelFree;
|
||||
|
||||
/**
|
||||
* 模型优先级(值越大优先级越高)
|
||||
*/
|
||||
private Long priority;
|
||||
private Integer modelDimension;
|
||||
|
||||
/**
|
||||
* 请求地址
|
||||
|
||||
@@ -56,12 +56,6 @@ public class ChatMessageVo implements Serializable {
|
||||
@ExcelProperty(value = "对话角色")
|
||||
private String role;
|
||||
|
||||
/**
|
||||
* 扣除金额
|
||||
*/
|
||||
@ExcelProperty(value = "扣除金额")
|
||||
private Long deductCost;
|
||||
|
||||
/**
|
||||
* 累计 Tokens
|
||||
*/
|
||||
@@ -74,12 +68,6 @@ public class ChatMessageVo implements Serializable {
|
||||
@ExcelProperty(value = "模型名称")
|
||||
private String modelName;
|
||||
|
||||
/**
|
||||
* 计费类型(1-token计费,2-次数计费)
|
||||
*/
|
||||
@ExcelProperty(value = "计费类型", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(readConverterExp = "1=-token计费,2-次数计费")
|
||||
private String billingType;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
|
||||
@@ -54,17 +54,6 @@ public class ChatModelVo implements Serializable {
|
||||
@ExcelProperty(value = "模型描述")
|
||||
private String modelDescribe;
|
||||
|
||||
/**
|
||||
* 模型价格
|
||||
*/
|
||||
@ExcelProperty(value = "模型价格")
|
||||
private Long modelPrice;
|
||||
|
||||
/**
|
||||
* 计费类型
|
||||
*/
|
||||
@ExcelProperty(value = "计费类型")
|
||||
private String modelType;
|
||||
|
||||
/**
|
||||
* 是否显示
|
||||
@@ -73,16 +62,10 @@ public class ChatModelVo implements Serializable {
|
||||
private String modelShow;
|
||||
|
||||
/**
|
||||
* 是否免费
|
||||
* 向量维度
|
||||
*/
|
||||
@ExcelProperty(value = "是否免费")
|
||||
private String modelFree;
|
||||
|
||||
/**
|
||||
* 模型优先级(值越大优先级越高)
|
||||
*/
|
||||
@ExcelProperty(value = "模型优先级(值越大优先级越高)")
|
||||
private Long priority;
|
||||
@ExcelProperty(value = "向量维度")
|
||||
private Integer modelDimension;
|
||||
|
||||
/**
|
||||
* 请求地址
|
||||
@@ -102,11 +85,5 @@ public class ChatModelVo implements Serializable {
|
||||
@ExcelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 模型维度
|
||||
*/
|
||||
private Integer dimension;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -48,10 +48,6 @@ public class ChatMessage extends TenantEntity {
|
||||
*/
|
||||
private String role;
|
||||
|
||||
/**
|
||||
* 扣除金额
|
||||
*/
|
||||
private Long deductCost;
|
||||
|
||||
/**
|
||||
* 累计 Tokens
|
||||
@@ -63,11 +59,6 @@ public class ChatMessage extends TenantEntity {
|
||||
*/
|
||||
private String modelName;
|
||||
|
||||
/**
|
||||
* 计费类型(1-token计费,2-次数计费)
|
||||
*/
|
||||
private String billingType;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
|
||||
@@ -48,15 +48,6 @@ public class ChatModel extends TenantEntity {
|
||||
*/
|
||||
private String modelDescribe;
|
||||
|
||||
/**
|
||||
* 模型价格
|
||||
*/
|
||||
private Long modelPrice;
|
||||
|
||||
/**
|
||||
* 计费类型
|
||||
*/
|
||||
private String modelType;
|
||||
|
||||
/**
|
||||
* 是否显示
|
||||
@@ -64,14 +55,9 @@ public class ChatModel extends TenantEntity {
|
||||
private String modelShow;
|
||||
|
||||
/**
|
||||
* 是否免费
|
||||
* 向量维度
|
||||
*/
|
||||
private String modelFree;
|
||||
|
||||
/**
|
||||
* 模型优先级(值越大优先级越高)
|
||||
*/
|
||||
private Long priority;
|
||||
private Integer modelDimension;
|
||||
|
||||
/**
|
||||
* 请求地址
|
||||
|
||||
@@ -41,7 +41,6 @@ public abstract class AbstractChatMessageService {
|
||||
messageBO.setContent(content);
|
||||
messageBO.setRole(role);
|
||||
messageBO.setModelName(chatRequest.getModel());
|
||||
messageBO.setBillingType(chatModelVo.getModelType());
|
||||
messageBO.setRemark(null);
|
||||
|
||||
chatMessageService.insertByBo(messageBO);
|
||||
|
||||
@@ -12,11 +12,8 @@
|
||||
<modules>
|
||||
<module>ruoyi-aiflow</module>
|
||||
<module>ruoyi-chat</module>
|
||||
<module>ruoyi-demo</module>
|
||||
<module>ruoyi-generator</module>
|
||||
<module>ruoyi-job</module>
|
||||
<module>ruoyi-system</module>
|
||||
<module>ruoyi-wechat</module>
|
||||
<module>ruoyi-workflow</module>
|
||||
</modules>
|
||||
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
package org.ruoyi.config;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
/**
|
||||
* 图谱构建异步任务配置
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-10-11
|
||||
*/
|
||||
@Slf4j
|
||||
@EnableAsync
|
||||
@Configuration
|
||||
@ConditionalOnProperty(prefix = "knowledge.graph", name = "enabled", havingValue = "true")
|
||||
public class GraphAsyncConfig {
|
||||
|
||||
/**
|
||||
* 图谱构建专用线程池
|
||||
* 用于执行图谱构建任务,避免阻塞主线程池
|
||||
*/
|
||||
@Bean("graphBuildExecutor")
|
||||
public Executor graphBuildExecutor() {
|
||||
log.info("初始化图谱构建线程池...");
|
||||
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
|
||||
// 核心线程数:CPU核心数
|
||||
int processors = Runtime.getRuntime().availableProcessors();
|
||||
executor.setCorePoolSize(processors);
|
||||
|
||||
// 最大线程数:CPU核心数 * 2
|
||||
executor.setMaxPoolSize(processors * 2);
|
||||
|
||||
// 队列容量:100个任务
|
||||
executor.setQueueCapacity(100);
|
||||
|
||||
// 线程空闲时间:60秒
|
||||
executor.setKeepAliveSeconds(60);
|
||||
|
||||
// 线程名称前缀
|
||||
executor.setThreadNamePrefix("graph-build-");
|
||||
|
||||
// 拒绝策略:由调用线程处理
|
||||
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
|
||||
// 等待所有任务完成后关闭线程池
|
||||
executor.setWaitForTasksToCompleteOnShutdown(true);
|
||||
|
||||
// 等待时间:60秒
|
||||
executor.setAwaitTerminationSeconds(60);
|
||||
|
||||
// 初始化
|
||||
executor.initialize();
|
||||
|
||||
log.info("图谱构建线程池初始化完成: corePoolSize={}, maxPoolSize={}, queueCapacity={}",
|
||||
processors, processors * 2, 100);
|
||||
|
||||
return executor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,175 +0,0 @@
|
||||
package org.ruoyi.config;
|
||||
|
||||
|
||||
import org.ruoyi.constant.GraphConstants;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 图谱实体关系抽取提示词
|
||||
* 参考 Microsoft GraphRAG 项目
|
||||
* https://github.com/microsoft/graphrag/blob/main/graphrag/index/graph/extractors/graph/prompts.py
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
public class GraphExtractPrompt {
|
||||
|
||||
/**
|
||||
* 中文实体关系抽取提示词
|
||||
*/
|
||||
public static final String GRAPH_EXTRACTION_PROMPT_CN = """
|
||||
-目标-
|
||||
给定一个可能与此活动相关的文本文档以及实体类型列表,从文本中识别出所有这些类型的实体以及识别出的实体之间的所有关系。
|
||||
|
||||
-步骤-
|
||||
1. 识别所有实体。对于每个识别出的实体,提取以下信息:
|
||||
- entity_name:实体的名称,首字母大写
|
||||
- entity_type:以下类型之一:[{entity_types}]
|
||||
- entity_description:实体的属性和活动的全面描述
|
||||
将每个实体格式化为 ("entity"{tuple_delimiter}<entity_name>{tuple_delimiter}<entity_type>{tuple_delimiter}<entity_description>)
|
||||
|
||||
2. 从步骤1中识别出的实体中,识别出所有明确相关的 (source_entity, target_entity) 对。
|
||||
对于每对相关的实体,提取以下信息:
|
||||
- source_entity:在步骤1中识别的源实体的名称
|
||||
- target_entity:在步骤1中识别的目标实体的名称
|
||||
- relationship_description:解释你认为源实体和目标实体之间相关的原因
|
||||
- relationship_strength:一个表示源实体和目标实体之间关系强度的数字分数(0-10)
|
||||
将每个关系格式化为 ("relationship"{tuple_delimiter}<source_entity>{tuple_delimiter}<target_entity>{tuple_delimiter}<relationship_description>{tuple_delimiter}<relationship_strength>)
|
||||
|
||||
3. 以英文返回输出,作为所有在步骤1和步骤2中识别的实体和关系的列表。使用 **{record_delimiter}** 作为列表分隔符。
|
||||
|
||||
4. 完成时,输出 {completion_delimiter}
|
||||
|
||||
######################
|
||||
-示例-
|
||||
######################
|
||||
示例 1:
|
||||
Entity_types: ORGANIZATION,PERSON
|
||||
文本:
|
||||
The Verdantis's Central Institution is scheduled to meet on Monday and Thursday, with the institution planning to release its latest policy decision on Thursday at 1:30 p.m. PDT, followed by a press conference where Central Institution Chair Martin Smith will take questions. Investors expect the Market Strategy Committee to hold its benchmark interest rate steady in a range of 3.5%-3.75%.
|
||||
######################
|
||||
输出:
|
||||
("entity"{tuple_delimiter}CENTRAL INSTITUTION{tuple_delimiter}ORGANIZATION{tuple_delimiter}The Central Institution is the Federal Reserve of Verdantis, which is setting interest rates on Monday and Thursday)
|
||||
{record_delimiter}
|
||||
("entity"{tuple_delimiter}MARTIN SMITH{tuple_delimiter}PERSON{tuple_delimiter}Martin Smith is the chair of the Central Institution)
|
||||
{record_delimiter}
|
||||
("entity"{tuple_delimiter}MARKET STRATEGY COMMITTEE{tuple_delimiter}ORGANIZATION{tuple_delimiter}The Central Institution committee makes key decisions about interest rates and the growth of Verdantis's money supply)
|
||||
{record_delimiter}
|
||||
("relationship"{tuple_delimiter}MARTIN SMITH{tuple_delimiter}CENTRAL INSTITUTION{tuple_delimiter}Martin Smith is the Chair of the Central Institution and will answer questions at a press conference{tuple_delimiter}9)
|
||||
{completion_delimiter}
|
||||
|
||||
######################
|
||||
示例 2:
|
||||
Entity_types: ORGANIZATION
|
||||
文本:
|
||||
TechGlobal's (TG) stock skyrocketed in its opening day on the Global Exchange Thursday. But IPO experts warn that the semiconductor corporation's debut on the public markets isn't indicative of how other newly listed companies may perform.
|
||||
|
||||
TechGlobal, a formerly public company, was taken private by Vision Holdings in 2014. The well-established chip designer says it powers 85% of premium smartphones.
|
||||
######################
|
||||
输出:
|
||||
("entity"{tuple_delimiter}TECHGLOBAL{tuple_delimiter}ORGANIZATION{tuple_delimiter}TechGlobal is a stock now listed on the Global Exchange which powers 85% of premium smartphones)
|
||||
{record_delimiter}
|
||||
("entity"{tuple_delimiter}VISION HOLDINGS{tuple_delimiter}ORGANIZATION{tuple_delimiter}Vision Holdings is a firm that previously owned TechGlobal)
|
||||
{record_delimiter}
|
||||
("relationship"{tuple_delimiter}TECHGLOBAL{tuple_delimiter}VISION HOLDINGS{tuple_delimiter}Vision Holdings formerly owned TechGlobal from 2014 until present{tuple_delimiter}5)
|
||||
{completion_delimiter}
|
||||
|
||||
######################
|
||||
示例 3:
|
||||
Entity_types: ORGANIZATION,LOCATION,PERSON
|
||||
文本:
|
||||
Five Aurelians jailed for 8 years in Firuzabad and widely regarded as hostages are on their way home to Aurelia.
|
||||
|
||||
The swap orchestrated by Quintara was finalized when $8bn of Firuzi funds were transferred to financial institutions in Krohaara, the capital of Quintara.
|
||||
|
||||
The exchange initiated in Firuzabad's capital, Tiruzia, led to the four men and one woman, who are also Firuzi nationals, boarding a chartered flight to Krohaara.
|
||||
|
||||
They were welcomed by senior Aurelian officials and are now on their way to Aurelia's capital, Cashion.
|
||||
|
||||
The Aurelians include 39-year-old businessman Samuel Namara, who has been held in Tiruzia's Alhamia Prison, as well as journalist Durke Bataglani, 59, and environmentalist Meggie Tazbah, 53, who also holds Bratinas nationality.
|
||||
######################
|
||||
输出:
|
||||
("entity"{tuple_delimiter}FIRUZABAD{tuple_delimiter}LOCATION{tuple_delimiter}Firuzabad held Aurelians as hostages)
|
||||
{record_delimiter}
|
||||
("entity"{tuple_delimiter}AURELIA{tuple_delimiter}LOCATION{tuple_delimiter}Country seeking to release hostages)
|
||||
{record_delimiter}
|
||||
("entity"{tuple_delimiter}QUINTARA{tuple_delimiter}LOCATION{tuple_delimiter}Country that negotiated a swap of money in exchange for hostages)
|
||||
{record_delimiter}
|
||||
("entity"{tuple_delimiter}TIRUZIA{tuple_delimiter}LOCATION{tuple_delimiter}Capital of Firuzabad where the Aurelians were being held)
|
||||
{record_delimiter}
|
||||
("entity"{tuple_delimiter}KROHAARA{tuple_delimiter}LOCATION{tuple_delimiter}Capital city in Quintara)
|
||||
{record_delimiter}
|
||||
("entity"{tuple_delimiter}CASHION{tuple_delimiter}LOCATION{tuple_delimiter}Capital city in Aurelia)
|
||||
{record_delimiter}
|
||||
("entity"{tuple_delimiter}SAMUEL NAMARA{tuple_delimiter}PERSON{tuple_delimiter}Aurelian who spent time in Tiruzia's Alhamia Prison)
|
||||
{record_delimiter}
|
||||
("entity"{tuple_delimiter}ALHAMIA PRISON{tuple_delimiter}LOCATION{tuple_delimiter}Prison in Tiruzia)
|
||||
{record_delimiter}
|
||||
("entity"{tuple_delimiter}DURKE BATAGLANI{tuple_delimiter}PERSON{tuple_delimiter}Aurelian journalist who was held hostage)
|
||||
{record_delimiter}
|
||||
("entity"{tuple_delimiter}MEGGIE TAZBAH{tuple_delimiter}PERSON{tuple_delimiter}Bratinas national and environmentalist who was held hostage)
|
||||
{record_delimiter}
|
||||
("relationship"{tuple_delimiter}FIRUZABAD{tuple_delimiter}AURELIA{tuple_delimiter}Firuzabad negotiated a hostage exchange with Aurelia{tuple_delimiter}2)
|
||||
{record_delimiter}
|
||||
("relationship"{tuple_delimiter}QUINTARA{tuple_delimiter}AURELIA{tuple_delimiter}Quintara brokered the hostage exchange between Firuzabad and Aurelia{tuple_delimiter}2)
|
||||
{record_delimiter}
|
||||
("relationship"{tuple_delimiter}SAMUEL NAMARA{tuple_delimiter}ALHAMIA PRISON{tuple_delimiter}Samuel Namara was a prisoner at Alhamia prison{tuple_delimiter}8)
|
||||
{record_delimiter}
|
||||
("relationship"{tuple_delimiter}SAMUEL NAMARA{tuple_delimiter}MEGGIE TAZBAH{tuple_delimiter}Samuel Namara and Meggie Tazbah were exchanged in the same hostage release{tuple_delimiter}2)
|
||||
{completion_delimiter}
|
||||
|
||||
######################
|
||||
-真实数据-
|
||||
######################
|
||||
Entity_types: {entity_types}
|
||||
文本: {input_text}
|
||||
######################
|
||||
输出:
|
||||
""".replace("{tuple_delimiter}", GraphConstants.GRAPH_TUPLE_DELIMITER)
|
||||
.replace("{entity_types}", Arrays.stream(GraphConstants.DEFAULT_ENTITY_TYPES).collect(Collectors.joining(",")))
|
||||
.replace("{completion_delimiter}", GraphConstants.GRAPH_COMPLETION_DELIMITER)
|
||||
.replace("{record_delimiter}", GraphConstants.GRAPH_RECORD_DELIMITER);
|
||||
|
||||
/**
|
||||
* 继续抽取提示词(当第一次抽取遗漏实体时使用)
|
||||
*/
|
||||
public static final String CONTINUE_PROMPT = """
|
||||
在上一次抽取中遗漏了许多实体和关系。
|
||||
请记住只提取与之前提取的类型匹配的实体。
|
||||
使用相同的格式在下面添加它们:
|
||||
""";
|
||||
|
||||
/**
|
||||
* 循环检查提示词
|
||||
*/
|
||||
public static final String LOOP_PROMPT = """
|
||||
似乎仍然可能遗漏了一些实体和关系。
|
||||
如果还有需要添加的实体或关系,请回答 YES | NO。
|
||||
""";
|
||||
|
||||
/**
|
||||
* 生成提取提示词
|
||||
*
|
||||
* @param inputText 输入文本
|
||||
* @return 完整的提示词
|
||||
*/
|
||||
public static String buildExtractionPrompt(String inputText) {
|
||||
return GRAPH_EXTRACTION_PROMPT_CN.replace("{input_text}", inputText);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成提取提示词(自定义实体类型)
|
||||
*
|
||||
* @param inputText 输入文本
|
||||
* @param entityTypes 实体类型列表
|
||||
* @return 完整的提示词
|
||||
*/
|
||||
public static String buildExtractionPrompt(String inputText, String[] entityTypes) {
|
||||
String entityTypesStr = Arrays.stream(entityTypes).collect(Collectors.joining(","));
|
||||
return GRAPH_EXTRACTION_PROMPT_CN
|
||||
.replace("{input_text}", inputText)
|
||||
.replace(Arrays.stream(GraphConstants.DEFAULT_ENTITY_TYPES).collect(Collectors.joining(",")), entityTypesStr);
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
package org.ruoyi.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 知识图谱配置属性
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "knowledge.graph")
|
||||
public class GraphProperties {
|
||||
|
||||
/**
|
||||
* 是否启用知识图谱功能
|
||||
*/
|
||||
private Boolean enabled = false;
|
||||
|
||||
/**
|
||||
* 图数据库类型: neo4j 或 apache-age
|
||||
*/
|
||||
private String databaseType = "neo4j";
|
||||
|
||||
/**
|
||||
* 是否自动创建索引
|
||||
*/
|
||||
private Boolean autoCreateIndex = true;
|
||||
|
||||
/**
|
||||
* 批量处理大小
|
||||
*/
|
||||
private Integer batchSize = 1000;
|
||||
|
||||
/**
|
||||
* 最大重试次数
|
||||
*/
|
||||
private Integer maxRetryCount = 3;
|
||||
|
||||
/**
|
||||
* 实体抽取配置
|
||||
*/
|
||||
private ExtractionConfig extraction = new ExtractionConfig();
|
||||
|
||||
/**
|
||||
* 查询配置
|
||||
*/
|
||||
private QueryConfig query = new QueryConfig();
|
||||
|
||||
@Data
|
||||
public static class ExtractionConfig {
|
||||
/**
|
||||
* 置信度阈值(低于此值的实体将被过滤)
|
||||
*/
|
||||
private Double confidenceThreshold = 0.7;
|
||||
|
||||
/**
|
||||
* 最大实体数量(每个文档)
|
||||
*/
|
||||
private Integer maxEntitiesPerDoc = 100;
|
||||
|
||||
/**
|
||||
* 最大关系数量(每个文档)
|
||||
*/
|
||||
private Integer maxRelationsPerDoc = 200;
|
||||
|
||||
/**
|
||||
* 文本分片大小(用于长文档)
|
||||
*/
|
||||
private Integer chunkSize = 2000;
|
||||
|
||||
/**
|
||||
* 分片重叠大小
|
||||
*/
|
||||
private Integer chunkOverlap = 200;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class QueryConfig {
|
||||
/**
|
||||
* 默认查询限制数量
|
||||
*/
|
||||
private Integer defaultLimit = 100;
|
||||
|
||||
/**
|
||||
* 最大查询限制数量
|
||||
*/
|
||||
private Integer maxLimit = 1000;
|
||||
|
||||
/**
|
||||
* 路径查询最大深度
|
||||
*/
|
||||
private Integer maxPathDepth = 5;
|
||||
|
||||
/**
|
||||
* 查询超时时间(秒)
|
||||
*/
|
||||
private Integer timeoutSeconds = 30;
|
||||
|
||||
/**
|
||||
* 是否启用查询缓存
|
||||
*/
|
||||
private Boolean cacheEnabled = true;
|
||||
|
||||
/**
|
||||
* 缓存过期时间(分钟)
|
||||
*/
|
||||
private Integer cacheExpireMinutes = 60;
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package org.ruoyi.config;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.neo4j.driver.AuthTokens;
|
||||
import org.neo4j.driver.Driver;
|
||||
import org.neo4j.driver.GraphDatabase;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Neo4j配置类
|
||||
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(Neo4jProperties.class)
|
||||
public class Neo4jConfig {
|
||||
|
||||
public Neo4jConfig() {
|
||||
log.warn("========== Neo4jConfig 已激活 ==========");
|
||||
log.warn("知识图谱功能(Neo4j): 已启用");
|
||||
log.warn("========================================");
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Neo4j Driver Bean
|
||||
*
|
||||
* @param neo4jProperties Neo4j 配置属性
|
||||
* @return Neo4j Driver
|
||||
*/
|
||||
@Bean
|
||||
public Driver neo4jDriver(Neo4jProperties neo4jProperties) {
|
||||
log.info("========== 正在初始化 Neo4j Driver ==========");
|
||||
log.info("Neo4j 连接地址: {}", neo4jProperties.getUri());
|
||||
log.info("Neo4j 用户名: {}", neo4jProperties.getUsername());
|
||||
log.info("Neo4j 数据库: {}", neo4jProperties.getDatabase());
|
||||
log.info("最大连接池大小: {}", neo4jProperties.getMaxConnectionPoolSize());
|
||||
log.info("连接超时时间: {} 秒", neo4jProperties.getConnectionTimeoutSeconds());
|
||||
|
||||
try {
|
||||
Driver driver = GraphDatabase.driver(
|
||||
neo4jProperties.getUri(),
|
||||
AuthTokens.basic(neo4jProperties.getUsername(), neo4jProperties.getPassword()),
|
||||
org.neo4j.driver.Config.builder()
|
||||
.withMaxConnectionPoolSize(neo4jProperties.getMaxConnectionPoolSize())
|
||||
.withConnectionTimeout(neo4jProperties.getConnectionTimeoutSeconds(), java.util.concurrent.TimeUnit.SECONDS)
|
||||
.build()
|
||||
);
|
||||
log.info("========== Neo4j Driver 初始化完成 ==========");
|
||||
return driver;
|
||||
} catch (Exception e) {
|
||||
log.error("Neo4j Driver 初始化失败", e);
|
||||
throw new RuntimeException("Failed to initialize Neo4j Driver", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
package org.ruoyi.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
|
||||
/**
|
||||
* Neo4j 配置属性
|
||||
*
|
||||
* 分离 @ConfigurationProperties 避免与 @ConditionalOnProperty 冲突
|
||||
* 不使用 @Component,而是在 Neo4jConfig 中通过 @EnableConfigurationProperties 启用
|
||||
* 参考: https://github.com/spring-projects/spring-boot/issues/26251
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties(prefix = "neo4j")
|
||||
public class Neo4jProperties {
|
||||
|
||||
/**
|
||||
* Neo4j连接URI
|
||||
* 例如: bolt://localhost:7687
|
||||
*/
|
||||
private String uri;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 数据库名称(Neo4j 4.0+支持多数据库)
|
||||
* 默认: neo4j
|
||||
*/
|
||||
private String database = "neo4j";
|
||||
|
||||
/**
|
||||
* 最大连接池大小
|
||||
*/
|
||||
private Integer maxConnectionPoolSize = 50;
|
||||
|
||||
/**
|
||||
* 连接超时时间(秒)
|
||||
*/
|
||||
private Integer connectionTimeoutSeconds = 30;
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
package org.ruoyi.constant;
|
||||
|
||||
/**
|
||||
* 知识图谱常量
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
public class GraphConstants {
|
||||
|
||||
/**
|
||||
* 图谱记录分隔符
|
||||
*/
|
||||
public static final String GRAPH_RECORD_DELIMITER = "##";
|
||||
|
||||
/**
|
||||
* 图谱元组分隔符
|
||||
*/
|
||||
public static final String GRAPH_TUPLE_DELIMITER = "<|>";
|
||||
|
||||
/**
|
||||
* 图谱完成标记
|
||||
*/
|
||||
public static final String GRAPH_COMPLETION_DELIMITER = "<|COMPLETE|>";
|
||||
|
||||
/**
|
||||
* 实体类型:人物
|
||||
*/
|
||||
public static final String ENTITY_TYPE_PERSON = "PERSON";
|
||||
|
||||
/**
|
||||
* 实体类型:组织机构
|
||||
*/
|
||||
public static final String ENTITY_TYPE_ORGANIZATION = "ORGANIZATION";
|
||||
|
||||
/**
|
||||
* 实体类型:地点
|
||||
*/
|
||||
public static final String ENTITY_TYPE_LOCATION = "LOCATION";
|
||||
|
||||
/**
|
||||
* 实体类型:概念
|
||||
*/
|
||||
public static final String ENTITY_TYPE_CONCEPT = "CONCEPT";
|
||||
|
||||
/**
|
||||
* 实体类型:事件
|
||||
*/
|
||||
public static final String ENTITY_TYPE_EVENT = "EVENT";
|
||||
|
||||
/**
|
||||
* 实体类型:产品
|
||||
*/
|
||||
public static final String ENTITY_TYPE_PRODUCT = "PRODUCT";
|
||||
|
||||
/**
|
||||
* 实体类型:技术
|
||||
*/
|
||||
public static final String ENTITY_TYPE_TECHNOLOGY = "TECHNOLOGY";
|
||||
|
||||
/**
|
||||
* 默认实体抽取类型列表
|
||||
*/
|
||||
public static final String[] DEFAULT_ENTITY_TYPES = {
|
||||
ENTITY_TYPE_PERSON,
|
||||
ENTITY_TYPE_ORGANIZATION,
|
||||
ENTITY_TYPE_LOCATION,
|
||||
ENTITY_TYPE_CONCEPT,
|
||||
ENTITY_TYPE_EVENT,
|
||||
ENTITY_TYPE_PRODUCT,
|
||||
ENTITY_TYPE_TECHNOLOGY
|
||||
};
|
||||
|
||||
/**
|
||||
* 元数据键:知识库UUID
|
||||
*/
|
||||
public static final String METADATA_KB_UUID = "kb_uuid";
|
||||
|
||||
/**
|
||||
* 元数据键:知识库条目UUID
|
||||
*/
|
||||
public static final String METADATA_KB_ITEM_UUID = "kb_item_uuid";
|
||||
|
||||
/**
|
||||
* 元数据键:文档UUID
|
||||
*/
|
||||
public static final String METADATA_DOC_UUID = "doc_uuid";
|
||||
|
||||
/**
|
||||
* 元数据键:片段UUID
|
||||
*/
|
||||
public static final String METADATA_SEGMENT_UUID = "segment_uuid";
|
||||
|
||||
/**
|
||||
* RAG最大片段大小(token数)
|
||||
*/
|
||||
public static final int RAG_MAX_SEGMENT_SIZE_IN_TOKENS = 512;
|
||||
|
||||
/**
|
||||
* RAG片段重叠大小(token数)
|
||||
*/
|
||||
public static final int RAG_SEGMENT_OVERLAP_IN_TOKENS = 50;
|
||||
}
|
||||
@@ -1,418 +0,0 @@
|
||||
package org.ruoyi.controller.graph;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.ruoyi.common.core.domain.R;
|
||||
import org.ruoyi.common.web.core.BaseController;
|
||||
import org.ruoyi.domain.bo.graph.GraphBuildTask;
|
||||
import org.ruoyi.domain.bo.graph.GraphInstance;
|
||||
import org.ruoyi.enums.GraphStatusEnum;
|
||||
import org.ruoyi.service.graph.IGraphBuildTaskService;
|
||||
import org.ruoyi.service.graph.IGraphInstanceService;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 图谱实例管理控制器
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/graph/instance")
|
||||
@Tag(name = "图谱实例管理", description = "知识图谱实例的创建、查询、更新、删除")
|
||||
@ConditionalOnProperty(prefix = "knowledge.graph", name = "enabled", havingValue = "true")
|
||||
public class GraphInstanceController extends BaseController {
|
||||
|
||||
private final IGraphInstanceService graphInstanceService;
|
||||
private final IGraphBuildTaskService buildTaskService;
|
||||
|
||||
/**
|
||||
* 辅助方法:根据ID或UUID获取图谱实例
|
||||
*/
|
||||
private GraphInstance getInstanceByIdOrUuid(String id) {
|
||||
GraphInstance instance = null;
|
||||
|
||||
// 尝试作为数字ID查询
|
||||
try {
|
||||
Long numericId = Long.parseLong(id);
|
||||
instance = graphInstanceService.getById(numericId);
|
||||
} catch (NumberFormatException e) {
|
||||
// 不是数字,尝试作为UUID查询
|
||||
instance = graphInstanceService.getByUuid(id);
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建图谱实例
|
||||
*/
|
||||
@Operation(summary = "创建图谱实例")
|
||||
@PostMapping
|
||||
public R<GraphInstance> createInstance(@RequestBody GraphInstance graphInstance) {
|
||||
try {
|
||||
if (graphInstance.getKnowledgeId() == null || graphInstance.getKnowledgeId().trim().isEmpty()) {
|
||||
return R.fail("知识库ID不能为空");
|
||||
}
|
||||
if (graphInstance.getInstanceName() == null || graphInstance.getInstanceName().trim().isEmpty()) {
|
||||
return R.fail("图谱名称不能为空");
|
||||
}
|
||||
|
||||
// 创建基础实例
|
||||
GraphInstance instance = graphInstanceService.createInstance(
|
||||
graphInstance.getKnowledgeId(),
|
||||
graphInstance.getInstanceName(),
|
||||
graphInstance.getConfig()
|
||||
);
|
||||
|
||||
// 设置扩展属性
|
||||
boolean needUpdate = false;
|
||||
if (graphInstance.getModelName() != null) {
|
||||
instance.setModelName(graphInstance.getModelName());
|
||||
needUpdate = true;
|
||||
}
|
||||
if (graphInstance.getEntityTypes() != null) {
|
||||
instance.setEntityTypes(graphInstance.getEntityTypes());
|
||||
needUpdate = true;
|
||||
}
|
||||
if (graphInstance.getRelationTypes() != null) {
|
||||
instance.setRelationTypes(graphInstance.getRelationTypes());
|
||||
needUpdate = true;
|
||||
}
|
||||
if (graphInstance.getRemark() != null) {
|
||||
instance.setRemark(graphInstance.getRemark());
|
||||
needUpdate = true;
|
||||
}
|
||||
|
||||
// 如果有扩展属性,更新到数据库
|
||||
if (needUpdate) {
|
||||
graphInstanceService.updateInstance(instance);
|
||||
}
|
||||
|
||||
return R.ok(instance);
|
||||
} catch (Exception e) {
|
||||
return R.fail("创建图谱实例失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新图谱实例
|
||||
*/
|
||||
@Operation(summary = "更新图谱实例")
|
||||
@PutMapping
|
||||
public R<GraphInstance> updateInstance(@RequestBody GraphInstance graphInstance) {
|
||||
try {
|
||||
if (graphInstance.getId() == null && (graphInstance.getGraphUuid() == null || graphInstance.getGraphUuid().trim().isEmpty())) {
|
||||
return R.fail("图谱ID不能为空");
|
||||
}
|
||||
|
||||
// 如果有 instanceName,更新基本信息
|
||||
if (graphInstance.getInstanceName() != null) {
|
||||
// 这里可以添加更新实例名称的逻辑
|
||||
}
|
||||
|
||||
// 更新配置
|
||||
if (graphInstance.getConfig() != null) {
|
||||
graphInstanceService.updateConfig(graphInstance.getGraphUuid(), graphInstance.getConfig());
|
||||
}
|
||||
|
||||
// 更新模型名称、实体类型、关系类型等
|
||||
// 注意:这里需要在 Service 层实现完整的更新逻辑
|
||||
|
||||
GraphInstance instance = graphInstanceService.getByUuid(graphInstance.getGraphUuid());
|
||||
return R.ok(instance);
|
||||
} catch (Exception e) {
|
||||
return R.fail("更新图谱实例失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ID或UUID获取图谱实例
|
||||
*/
|
||||
@Operation(summary = "获取图谱实例")
|
||||
@GetMapping("/{id}")
|
||||
public R<GraphInstance> getByUuid(@PathVariable String id) {
|
||||
try {
|
||||
GraphInstance instance = getInstanceByIdOrUuid(id);
|
||||
|
||||
if (instance == null) {
|
||||
return R.fail("图谱实例不存在");
|
||||
}
|
||||
return R.ok(instance);
|
||||
} catch (Exception e) {
|
||||
return R.fail("获取图谱实例失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取图谱实例列表(支持分页和条件查询)
|
||||
*/
|
||||
@Operation(summary = "获取图谱实例列表")
|
||||
@GetMapping("/list")
|
||||
public R<Map<String, Object>> list(
|
||||
@RequestParam(required = false) String instanceName,
|
||||
@RequestParam(required = false) String knowledgeId,
|
||||
@RequestParam(required = false) String status,
|
||||
@RequestParam(required = false, defaultValue = "1") Integer pageNum,
|
||||
@RequestParam(required = false, defaultValue = "10") Integer pageSize) {
|
||||
try {
|
||||
// 使用枚举转换前端状态字符串为数字状态码
|
||||
Integer graphStatus = GraphStatusEnum.getCodeByStatusKey(status);
|
||||
|
||||
// 创建分页对象
|
||||
Page<GraphInstance> page = new Page<>(pageNum, pageSize);
|
||||
|
||||
// 调用 Service 层分页查询
|
||||
Page<GraphInstance> result = graphInstanceService.queryPage(page, instanceName, knowledgeId, graphStatus);
|
||||
|
||||
// 构造返回结果
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("rows", result.getRecords());
|
||||
data.put("total", result.getTotal());
|
||||
|
||||
return R.ok(data);
|
||||
} catch (Exception e) {
|
||||
return R.fail("获取图谱列表失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据知识库ID获取图谱列表
|
||||
*/
|
||||
@Operation(summary = "获取知识库的图谱列表")
|
||||
@GetMapping("/knowledge/{knowledgeId}")
|
||||
public R<List<GraphInstance>> listByKnowledge(@PathVariable String knowledgeId) {
|
||||
try {
|
||||
List<GraphInstance> instances = graphInstanceService.listByKnowledgeId(knowledgeId);
|
||||
return R.ok(instances);
|
||||
} catch (Exception e) {
|
||||
return R.fail("获取图谱列表失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新图谱状态
|
||||
*/
|
||||
@Operation(summary = "更新图谱状态")
|
||||
@PutMapping("/status/{graphUuid}")
|
||||
public R<Void> updateStatus(
|
||||
@PathVariable String graphUuid,
|
||||
@RequestParam Integer status) {
|
||||
try {
|
||||
boolean success = graphInstanceService.updateStatus(graphUuid, status);
|
||||
return success ? R.ok() : R.fail("更新状态失败");
|
||||
} catch (Exception e) {
|
||||
return R.fail("更新状态失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新图谱统计信息
|
||||
*/
|
||||
@Operation(summary = "更新图谱统计")
|
||||
@PutMapping("/counts/{graphUuid}")
|
||||
public R<Void> updateCounts(
|
||||
@PathVariable String graphUuid,
|
||||
@RequestParam Integer nodeCount,
|
||||
@RequestParam Integer relationshipCount) {
|
||||
try {
|
||||
boolean success = graphInstanceService.updateCounts(graphUuid, nodeCount, relationshipCount);
|
||||
return success ? R.ok() : R.fail("更新统计失败");
|
||||
} catch (Exception e) {
|
||||
return R.fail("更新统计失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新图谱配置
|
||||
*/
|
||||
@Operation(summary = "更新图谱配置")
|
||||
@PutMapping("/config/{graphUuid}")
|
||||
public R<Void> updateConfig(
|
||||
@PathVariable String graphUuid,
|
||||
@RequestBody Map<String, String> request) {
|
||||
try {
|
||||
String config = request.get("config");
|
||||
boolean success = graphInstanceService.updateConfig(graphUuid, config);
|
||||
return success ? R.ok() : R.fail("更新配置失败");
|
||||
} catch (Exception e) {
|
||||
return R.fail("更新配置失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除图谱实例(软删除)
|
||||
*/
|
||||
@Operation(summary = "删除图谱实例")
|
||||
@DeleteMapping("/{id}")
|
||||
public R<Void> deleteInstance(@PathVariable String id) {
|
||||
try {
|
||||
// 获取图谱实例
|
||||
GraphInstance instance = getInstanceByIdOrUuid(id);
|
||||
if (instance == null) {
|
||||
return R.fail("图谱实例不存在");
|
||||
}
|
||||
|
||||
boolean success = graphInstanceService.deleteInstance(instance.getGraphUuid());
|
||||
return success ? R.ok() : R.fail("删除失败");
|
||||
} catch (Exception e) {
|
||||
return R.fail("删除图谱实例失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 物理删除图谱实例及其数据
|
||||
*/
|
||||
@Operation(summary = "彻底删除图谱")
|
||||
@DeleteMapping("/permanent/{graphUuid}")
|
||||
public R<Void> deleteInstanceAndData(@PathVariable String graphUuid) {
|
||||
try {
|
||||
boolean success = graphInstanceService.deleteInstanceAndData(graphUuid);
|
||||
return success ? R.ok() : R.fail("删除失败");
|
||||
} catch (Exception e) {
|
||||
return R.fail("彻底删除图谱失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取图谱统计信息
|
||||
*/
|
||||
@Operation(summary = "获取图谱统计")
|
||||
@GetMapping("/stats/{graphUuid}")
|
||||
public R<Map<String, Object>> getStatistics(@PathVariable String graphUuid) {
|
||||
try {
|
||||
Map<String, Object> stats = graphInstanceService.getStatistics(graphUuid);
|
||||
return R.ok(stats);
|
||||
} catch (Exception e) {
|
||||
return R.fail("获取统计信息失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建图谱(全量构建知识库)
|
||||
*/
|
||||
@Operation(summary = "构建图谱")
|
||||
@PostMapping("/build/{id}")
|
||||
public R<GraphBuildTask> buildGraph(@PathVariable String id) {
|
||||
try {
|
||||
// 获取图谱实例
|
||||
GraphInstance instance = getInstanceByIdOrUuid(id);
|
||||
|
||||
if (instance == null) {
|
||||
return R.fail("图谱实例不存在");
|
||||
}
|
||||
|
||||
// 更新状态为构建中
|
||||
graphInstanceService.updateStatus(instance.getGraphUuid(), 10); // 10=构建中
|
||||
|
||||
// 创建构建任务(全量构建)
|
||||
GraphBuildTask task = buildTaskService.createTask(
|
||||
instance.getGraphUuid(),
|
||||
instance.getKnowledgeId(),
|
||||
null, // docId=null 表示全量构建
|
||||
1 // taskType=1 全量构建
|
||||
);
|
||||
|
||||
// 异步启动任务
|
||||
buildTaskService.startTask(task.getTaskUuid());
|
||||
|
||||
return R.ok(task);
|
||||
} catch (Exception e) {
|
||||
return R.fail("启动构建任务失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重建图谱(清空后重新构建)
|
||||
*/
|
||||
@Operation(summary = "重建图谱")
|
||||
@PostMapping("/rebuild/{id}")
|
||||
public R<GraphBuildTask> rebuildGraph(@PathVariable String id) {
|
||||
try {
|
||||
// 获取图谱实例
|
||||
GraphInstance instance = getInstanceByIdOrUuid(id);
|
||||
|
||||
if (instance == null) {
|
||||
return R.fail("图谱实例不存在");
|
||||
}
|
||||
|
||||
// 更新状态为构建中
|
||||
graphInstanceService.updateStatus(instance.getGraphUuid(), 10); // 10=构建中
|
||||
|
||||
// 创建重建任务
|
||||
GraphBuildTask task = buildTaskService.createTask(
|
||||
instance.getGraphUuid(),
|
||||
instance.getKnowledgeId(),
|
||||
null, // docId=null 表示全量
|
||||
2 // taskType=2 重建
|
||||
);
|
||||
|
||||
// 异步启动任务
|
||||
buildTaskService.startTask(task.getTaskUuid());
|
||||
|
||||
return R.ok(task);
|
||||
} catch (Exception e) {
|
||||
return R.fail("启动重建任务失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取构建状态
|
||||
*/
|
||||
@Operation(summary = "获取构建状态")
|
||||
@GetMapping("/status/{id}")
|
||||
public R<Map<String, Object>> getBuildStatus(@PathVariable String id) {
|
||||
try {
|
||||
// 获取图谱实例
|
||||
GraphInstance instance = getInstanceByIdOrUuid(id);
|
||||
|
||||
if (instance == null) {
|
||||
return R.fail("图谱实例不存在");
|
||||
}
|
||||
|
||||
// 获取最新的构建任务
|
||||
GraphBuildTask latestTask = buildTaskService.getLatestTask(instance.getGraphUuid());
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("graphStatus", instance.getGraphStatus());
|
||||
result.put("nodeCount", instance.getNodeCount());
|
||||
result.put("relationshipCount", instance.getRelationshipCount());
|
||||
|
||||
if (latestTask != null) {
|
||||
result.put("taskStatus", latestTask.getTaskStatus());
|
||||
// ⭐ 确保 progress 不为 null,前端期望是 number 类型
|
||||
Integer progress = latestTask.getProgress();
|
||||
result.put("progress", progress != null ? progress : 0);
|
||||
result.put("errorMessage", latestTask.getErrorMessage());
|
||||
|
||||
// 转换状态字符串(兼容前端)
|
||||
String status = "NOT_BUILT";
|
||||
if (instance.getGraphStatus() == 10) status = "BUILDING";
|
||||
else if (instance.getGraphStatus() == 20) status = "COMPLETED";
|
||||
else if (instance.getGraphStatus() == 30) status = "FAILED";
|
||||
|
||||
result.put("status", status);
|
||||
} else {
|
||||
// ⭐ 如果没有任务,也返回默认值
|
||||
result.put("taskStatus", null);
|
||||
result.put("progress", 0);
|
||||
result.put("errorMessage", null);
|
||||
result.put("status", "NOT_BUILT");
|
||||
}
|
||||
|
||||
return R.ok(result);
|
||||
} catch (Exception e) {
|
||||
return R.fail("获取构建状态失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,228 +0,0 @@
|
||||
package org.ruoyi.controller.graph;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.ruoyi.common.core.domain.R;
|
||||
import org.ruoyi.common.web.core.BaseController;
|
||||
|
||||
import org.ruoyi.domain.bo.graph.GraphEdge;
|
||||
import org.ruoyi.domain.bo.graph.GraphVertex;
|
||||
import org.ruoyi.domain.dto.GraphExtractionResult;
|
||||
import org.ruoyi.service.graph.IGraphExtractionService;
|
||||
import org.ruoyi.service.graph.IGraphRAGService;
|
||||
import org.ruoyi.service.graph.IGraphStoreService;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 图谱查询控制器
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/graph/query")
|
||||
@Tag(name = "图谱查询", description = "知识图谱查询相关接口")
|
||||
@ConditionalOnProperty(prefix = "knowledge.graph", name = "enabled", havingValue = "true")
|
||||
public class GraphQueryController extends BaseController {
|
||||
|
||||
private final IGraphStoreService graphStoreService;
|
||||
private final IGraphExtractionService graphExtractionService;
|
||||
private final IGraphRAGService graphRAGService;
|
||||
|
||||
/**
|
||||
* 获取知识库的图谱数据
|
||||
*/
|
||||
@Operation(summary = "获取知识库图谱")
|
||||
@GetMapping("/knowledge/{knowledgeId}")
|
||||
public R<Map<String, Object>> getGraphByKnowledge(
|
||||
@PathVariable String knowledgeId,
|
||||
@RequestParam(defaultValue = "100") Integer limit) {
|
||||
|
||||
try {
|
||||
// 查询节点
|
||||
List<GraphVertex> vertices = graphStoreService.queryVerticesByKnowledgeId(knowledgeId, limit);
|
||||
|
||||
// 查询关系
|
||||
List<GraphEdge> edges = graphStoreService.queryEdgesByKnowledgeId(knowledgeId, limit);
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("vertices", vertices);
|
||||
result.put("edges", edges);
|
||||
result.put("vertexCount", vertices.size());
|
||||
result.put("edgeCount", edges.size());
|
||||
|
||||
return R.ok(result);
|
||||
} catch (Exception e) {
|
||||
return R.fail("获取图谱数据失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索实体节点
|
||||
*/
|
||||
@Operation(summary = "搜索实体")
|
||||
@GetMapping("/search/entity")
|
||||
public R<List<GraphVertex>> searchEntity(
|
||||
@RequestParam String keyword,
|
||||
@RequestParam(required = false) String knowledgeId,
|
||||
@RequestParam(defaultValue = "20") Integer limit) {
|
||||
|
||||
try {
|
||||
List<GraphVertex> vertices = graphStoreService.searchVerticesByName(keyword, knowledgeId, limit);
|
||||
return R.ok(vertices);
|
||||
} catch (Exception e) {
|
||||
return R.fail("搜索实体失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询实体的邻居节点
|
||||
*/
|
||||
@Operation(summary = "查询邻居节点")
|
||||
@GetMapping("/neighbors/{nodeId}")
|
||||
public R<List<GraphVertex>> getNeighbors(
|
||||
@PathVariable String nodeId,
|
||||
@RequestParam(required = false) String knowledgeId,
|
||||
@RequestParam(defaultValue = "20") Integer limit) {
|
||||
|
||||
try {
|
||||
List<GraphVertex> neighbors = graphStoreService.getNeighbors(nodeId, knowledgeId, limit);
|
||||
return R.ok(neighbors);
|
||||
} catch (Exception e) {
|
||||
return R.fail("查询邻居节点失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询两个实体之间的路径
|
||||
*/
|
||||
@Operation(summary = "查询实体路径")
|
||||
@GetMapping("/path")
|
||||
public R<List<List<GraphVertex>>> findPath(
|
||||
@RequestParam String startNodeId,
|
||||
@RequestParam String endNodeId,
|
||||
@RequestParam(defaultValue = "5") Integer maxDepth) {
|
||||
|
||||
try {
|
||||
List<List<GraphVertex>> paths = graphStoreService.findPaths(startNodeId, endNodeId, maxDepth);
|
||||
return R.ok(paths);
|
||||
} catch (Exception e) {
|
||||
return R.fail("查询路径失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从文本抽取实体和关系(测试用)
|
||||
*/
|
||||
@Operation(summary = "文本实体抽取")
|
||||
@PostMapping("/extract")
|
||||
public R<GraphExtractionResult> extractFromText(@RequestBody Map<String, String> request) {
|
||||
try {
|
||||
String text = request.get("text");
|
||||
if (text == null || text.trim().isEmpty()) {
|
||||
return R.fail("文本不能为空");
|
||||
}
|
||||
|
||||
String modelName = request.get("modelName");
|
||||
GraphExtractionResult result;
|
||||
|
||||
if (modelName != null && !modelName.trim().isEmpty()) {
|
||||
result = graphExtractionService.extractFromTextWithModel(text, modelName);
|
||||
} else {
|
||||
result = graphExtractionService.extractFromText(text);
|
||||
}
|
||||
|
||||
return R.ok(result);
|
||||
} catch (Exception e) {
|
||||
return R.fail("实体抽取失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将文本入库到图谱
|
||||
*/
|
||||
@Operation(summary = "文本入库")
|
||||
@PostMapping("/ingest")
|
||||
public R<GraphExtractionResult> ingestText(@RequestBody Map<String, Object> request) {
|
||||
try {
|
||||
String text = (String) request.get("text");
|
||||
String knowledgeId = (String) request.get("knowledgeId");
|
||||
String modelName = (String) request.get("modelName");
|
||||
|
||||
if (text == null || text.trim().isEmpty()) {
|
||||
return R.fail("文本不能为空");
|
||||
}
|
||||
if (knowledgeId == null || knowledgeId.trim().isEmpty()) {
|
||||
return R.fail("知识库ID不能为空");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> metadata = (Map<String, Object>) request.get("metadata");
|
||||
|
||||
GraphExtractionResult result;
|
||||
if (modelName != null && !modelName.trim().isEmpty()) {
|
||||
result = graphRAGService.ingestTextWithModel(text, knowledgeId, metadata, modelName);
|
||||
} else {
|
||||
result = graphRAGService.ingestText(text, knowledgeId, metadata);
|
||||
}
|
||||
return R.ok(result);
|
||||
} catch (Exception e) {
|
||||
return R.fail("文本入库失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 基于图谱检索
|
||||
*/
|
||||
@Operation(summary = "图谱检索")
|
||||
@GetMapping("/retrieve")
|
||||
public R<String> retrieveFromGraph(
|
||||
@RequestParam String query,
|
||||
@RequestParam String knowledgeId,
|
||||
@RequestParam(defaultValue = "10") Integer maxResults) {
|
||||
|
||||
try {
|
||||
String result = graphRAGService.retrieveFromGraph(query, knowledgeId, maxResults);
|
||||
return R.ok(result);
|
||||
} catch (Exception e) {
|
||||
return R.fail("图谱检索失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除知识库的图谱数据
|
||||
*/
|
||||
@Operation(summary = "删除图谱数据")
|
||||
@DeleteMapping("/knowledge/{knowledgeId}")
|
||||
public R<Void> deleteGraphData(@PathVariable String knowledgeId) {
|
||||
try {
|
||||
boolean success = graphRAGService.deleteGraphData(knowledgeId);
|
||||
return success ? R.ok() : R.fail("删除失败");
|
||||
} catch (Exception e) {
|
||||
return R.fail("删除图谱数据失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取图谱统计信息
|
||||
*/
|
||||
@Operation(summary = "图谱统计")
|
||||
@GetMapping("/stats/{knowledgeId}")
|
||||
public R<Map<String, Object>> getGraphStats(@PathVariable String knowledgeId) {
|
||||
try {
|
||||
Map<String, Object> stats = graphStoreService.getStatistics(knowledgeId);
|
||||
return R.ok(stats);
|
||||
} catch (Exception e) {
|
||||
return R.fail("获取统计信息失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
package org.ruoyi.controller.graph;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.ruoyi.common.core.domain.R;
|
||||
import org.ruoyi.config.GraphProperties;
|
||||
import org.ruoyi.config.Neo4jProperties;
|
||||
import org.ruoyi.util.Neo4jTestUtil;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Neo4j测试控制器
|
||||
* 仅用于开发环境测试Neo4j连接
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/graph/test")
|
||||
@RequiredArgsConstructor
|
||||
@ConditionalOnProperty(prefix = "knowledge.graph", name = "enabled", havingValue = "true")
|
||||
public class Neo4jTestController {
|
||||
|
||||
private final Neo4jTestUtil neo4jTestUtil;
|
||||
private final Neo4jProperties neo4jProperties;
|
||||
private final GraphProperties graphProperties;
|
||||
|
||||
|
||||
@GetMapping("/connection")
|
||||
public R<Map<String, Object>> testConnection() {
|
||||
Map<String, Object> result = neo4jTestUtil.testConnection();
|
||||
|
||||
if ("SUCCESS".equals(result.get("connection"))) {
|
||||
return R.ok("Neo4j连接成功", result);
|
||||
} else {
|
||||
return R.fail(result.get("error").toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/config")
|
||||
public R<Map<String, Object>> getConfig() {
|
||||
Map<String, Object> config = new HashMap<>();
|
||||
config.put("neo4j", Map.of(
|
||||
"uri", neo4jProperties.getUri(),
|
||||
"username", neo4jProperties.getUsername(),
|
||||
"database", neo4jProperties.getDatabase(),
|
||||
"maxConnectionPoolSize", neo4jProperties.getMaxConnectionPoolSize()
|
||||
));
|
||||
config.put("graph", Map.of(
|
||||
"enabled", graphProperties.getEnabled(),
|
||||
"databaseType", graphProperties.getDatabaseType(),
|
||||
"batchSize", graphProperties.getBatchSize(),
|
||||
"extraction", graphProperties.getExtraction(),
|
||||
"query", graphProperties.getQuery()
|
||||
));
|
||||
return R.ok(config);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/node")
|
||||
public R<Map<String, Object>> createTestNode(@RequestParam String name) {
|
||||
Map<String, Object> result = neo4jTestUtil.createTestNode(name);
|
||||
|
||||
if (Boolean.TRUE.equals(result.get("success"))) {
|
||||
return R.ok("测试节点创建成功", result);
|
||||
} else {
|
||||
return R.fail(result.get("error").toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/node/{name}")
|
||||
public R<Map<String, Object>> queryTestNode(@PathVariable String name) {
|
||||
Map<String, Object> result = neo4jTestUtil.queryTestNode(name);
|
||||
|
||||
if (Boolean.TRUE.equals(result.get("found"))) {
|
||||
return R.ok("节点查询成功", result);
|
||||
} else {
|
||||
return R.ok("未找到节点", result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/relationship")
|
||||
public R<Map<String, Object>> createTestRelationship(
|
||||
@RequestParam String source,
|
||||
@RequestParam String target) {
|
||||
|
||||
Map<String, Object> result = neo4jTestUtil.createTestRelationship(source, target);
|
||||
|
||||
if (Boolean.TRUE.equals(result.get("success"))) {
|
||||
return R.ok("测试关系创建成功", result);
|
||||
} else {
|
||||
return R.fail(result.get("error").toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@DeleteMapping("/nodes")
|
||||
public R<Map<String, Object>> deleteAllTestNodes() {
|
||||
Map<String, Object> result = neo4jTestUtil.deleteAllTestNodes();
|
||||
|
||||
if (Boolean.TRUE.equals(result.get("success"))) {
|
||||
return R.ok("测试节点清理完成", result);
|
||||
} else {
|
||||
return R.fail(result.get("error").toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/statistics")
|
||||
public R<Map<String, Object>> getStatistics() {
|
||||
Map<String, Object> result = neo4jTestUtil.getStatistics();
|
||||
|
||||
if (result.containsKey("error")) {
|
||||
return R.fail(result.get("error").toString());
|
||||
}
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/health")
|
||||
public R<String> health() {
|
||||
Map<String, Object> result = neo4jTestUtil.testConnection();
|
||||
|
||||
if ("SUCCESS".equals(result.get("connection"))) {
|
||||
return R.ok("Neo4j服务正常");
|
||||
} else {
|
||||
return R.fail("Neo4j服务异常: " + result.get("error"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 调试关系查询 - 查看指定知识库的所有关系
|
||||
*/
|
||||
@GetMapping("/debug/relationships/{knowledgeId}")
|
||||
public R<Map<String, Object>> debugRelationships(@PathVariable String knowledgeId) {
|
||||
Map<String, Object> result = neo4jTestUtil.debugRelationships(knowledgeId);
|
||||
return R.ok(result);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package org.ruoyi.controller.tripartite;
|
||||
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Tag(name = "任务查询")
|
||||
@RestController
|
||||
@RequestMapping("/mj/task")
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class TaskController {
|
||||
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
package org.ruoyi.domain.bo.graph;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 图谱构建任务对象 graph_build_task
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
@Data
|
||||
@TableName("graph_build_task")
|
||||
public class GraphBuildTask extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 任务UUID
|
||||
*/
|
||||
private String taskUuid;
|
||||
|
||||
/**
|
||||
* 图谱UUID
|
||||
*/
|
||||
private String graphUuid;
|
||||
|
||||
/**
|
||||
* 知识库ID
|
||||
*/
|
||||
private String knowledgeId;
|
||||
|
||||
/**
|
||||
* 文档ID(可选,null表示全量构建)
|
||||
*/
|
||||
private String docId;
|
||||
|
||||
/**
|
||||
* 任务类型:1全量构建、2增量更新、3重建
|
||||
*/
|
||||
private Integer taskType;
|
||||
|
||||
/**
|
||||
* 任务状态:1待执行、2执行中、3成功、4失败
|
||||
*/
|
||||
private Integer taskStatus;
|
||||
|
||||
/**
|
||||
* 进度百分比(0-100)
|
||||
*/
|
||||
private Integer progress;
|
||||
|
||||
/**
|
||||
* 总文档数
|
||||
*/
|
||||
private Integer totalDocs;
|
||||
|
||||
/**
|
||||
* 已处理文档数
|
||||
*/
|
||||
private Integer processedDocs;
|
||||
|
||||
/**
|
||||
* 提取的实体数
|
||||
*/
|
||||
private Integer extractedEntities;
|
||||
|
||||
/**
|
||||
* 提取的关系数
|
||||
*/
|
||||
private Integer extractedRelations;
|
||||
|
||||
/**
|
||||
* 错误信息
|
||||
*/
|
||||
private String errorMessage;
|
||||
|
||||
/**
|
||||
* 结果摘要(JSON格式)
|
||||
*/
|
||||
private String resultSummary;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date startTime;
|
||||
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date endTime;
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
package org.ruoyi.domain.bo.graph;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 图关系实体
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@TableName("graph_edge")
|
||||
public class GraphEdge implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 图谱UUID
|
||||
*/
|
||||
private String graphUuid;
|
||||
|
||||
/**
|
||||
* 关系唯一标识(Neo4j中的关系ID)
|
||||
*/
|
||||
private String edgeId;
|
||||
|
||||
/**
|
||||
* 关系标签(类型)
|
||||
*/
|
||||
private String label;
|
||||
|
||||
/**
|
||||
* 源节点ID
|
||||
*/
|
||||
private String sourceNodeId;
|
||||
|
||||
/**
|
||||
* 源节点名称
|
||||
*/
|
||||
private String sourceName;
|
||||
|
||||
/**
|
||||
* 目标节点ID
|
||||
*/
|
||||
private String targetNodeId;
|
||||
|
||||
/**
|
||||
* 目标节点名称
|
||||
*/
|
||||
private String targetName;
|
||||
|
||||
/**
|
||||
* 关系类型编码
|
||||
*/
|
||||
private String relationType;
|
||||
|
||||
/**
|
||||
* 关系描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 关系权重(0.0-1.0)
|
||||
*/
|
||||
private Double weight;
|
||||
|
||||
/**
|
||||
* 置信度(0.0-1.0)
|
||||
*/
|
||||
private Double confidence;
|
||||
|
||||
/**
|
||||
* 来源知识库ID
|
||||
*/
|
||||
private String knowledgeId;
|
||||
|
||||
/**
|
||||
* 来源文档ID列表(JSON格式)
|
||||
*/
|
||||
private String docIds;
|
||||
|
||||
/**
|
||||
* 来源片段ID列表(JSON格式)
|
||||
*/
|
||||
private String fragmentIds;
|
||||
|
||||
/**
|
||||
* 文本段ID(关联到具体的文本段)
|
||||
*/
|
||||
@JsonProperty("text_segment_id")
|
||||
private String textSegmentId;
|
||||
|
||||
/**
|
||||
* 其他属性(JSON格式)
|
||||
*/
|
||||
private String properties;
|
||||
|
||||
/**
|
||||
* 元数据(JSON格式)
|
||||
*/
|
||||
private Map<String, Object> metadata;
|
||||
|
||||
/**
|
||||
* 源节点元数据
|
||||
*/
|
||||
private Map<String, Object> sourceMetadata;
|
||||
|
||||
/**
|
||||
* 目标节点元数据
|
||||
*/
|
||||
private Map<String, Object> targetMetadata;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package org.ruoyi.domain.bo.graph;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 图谱实体类型定义对象 graph_entity_type
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("graph_entity_type")
|
||||
public class GraphEntityType extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 实体类型名称
|
||||
*/
|
||||
private String typeName;
|
||||
|
||||
/**
|
||||
* 类型编码
|
||||
*/
|
||||
private String typeCode;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 可视化颜色
|
||||
*/
|
||||
private String color;
|
||||
|
||||
/**
|
||||
* 图标
|
||||
*/
|
||||
private String icon;
|
||||
|
||||
/**
|
||||
* 显示顺序
|
||||
*/
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 是否启用(0否 1是)
|
||||
*/
|
||||
private Integer isEnable;
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
package org.ruoyi.domain.bo.graph;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 知识图谱实例对象 knowledge_graph_instance
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("knowledge_graph_instance")
|
||||
public class GraphInstance extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 图谱UUID
|
||||
*/
|
||||
private String graphUuid;
|
||||
|
||||
/**
|
||||
* 关联knowledge_info.kid
|
||||
*/
|
||||
private String knowledgeId;
|
||||
|
||||
/**
|
||||
* 图谱名称
|
||||
*/
|
||||
private String graphName;
|
||||
|
||||
/**
|
||||
* 图谱实例名称(前端使用,不映射到数据库)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String instanceName;
|
||||
|
||||
/**
|
||||
* 构建状态:10构建中、20已完成、30失败
|
||||
*/
|
||||
private Integer graphStatus;
|
||||
|
||||
/**
|
||||
* 节点数量
|
||||
*/
|
||||
private Integer nodeCount;
|
||||
|
||||
/**
|
||||
* 关系数量
|
||||
*/
|
||||
private Integer relationshipCount;
|
||||
|
||||
/**
|
||||
* 图谱配置(JSON格式)
|
||||
*/
|
||||
private String config;
|
||||
|
||||
/**
|
||||
* LLM模型名称
|
||||
*/
|
||||
private String modelName;
|
||||
|
||||
/**
|
||||
* 实体类型(逗号分隔)
|
||||
*/
|
||||
private String entityTypes;
|
||||
|
||||
/**
|
||||
* 关系类型(逗号分隔)
|
||||
*/
|
||||
private String relationTypes;
|
||||
|
||||
/**
|
||||
* 错误信息
|
||||
*/
|
||||
private String errorMessage;
|
||||
|
||||
/**
|
||||
* 删除标志(0代表存在 1代表删除)
|
||||
*/
|
||||
private String delFlag;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 获取实例名称(兼容前端)
|
||||
*/
|
||||
public String getInstanceName() {
|
||||
return instanceName != null ? instanceName : graphName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置实例名称(同步到graphName)
|
||||
*/
|
||||
public void setInstanceName(String instanceName) {
|
||||
this.instanceName = instanceName;
|
||||
this.graphName = instanceName;
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package org.ruoyi.domain.bo.graph;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 图谱关系类型定义对象 graph_relation_type
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("graph_relation_type")
|
||||
public class GraphRelationType extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 关系名称
|
||||
*/
|
||||
private String relationName;
|
||||
|
||||
/**
|
||||
* 关系编码
|
||||
*/
|
||||
private String relationCode;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 关系方向:0双向、1单向
|
||||
*/
|
||||
private Integer direction;
|
||||
|
||||
/**
|
||||
* 可视化样式(JSON格式)
|
||||
*/
|
||||
private String style;
|
||||
|
||||
/**
|
||||
* 显示顺序
|
||||
*/
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 是否启用(0否 1是)
|
||||
*/
|
||||
private Integer isEnable;
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
package org.ruoyi.domain.bo.graph;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 图节点实体
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@TableName("graph_vertex")
|
||||
public class GraphVertex implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 图谱UUID
|
||||
*/
|
||||
private String graphUuid;
|
||||
|
||||
/**
|
||||
* 节点唯一标识(Neo4j中的节点ID)
|
||||
*/
|
||||
private String nodeId;
|
||||
|
||||
/**
|
||||
* 节点名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 节点标签(类型)
|
||||
*/
|
||||
private String label;
|
||||
|
||||
/**
|
||||
* 节点类型编码
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 描述信息
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 置信度(0.0-1.0)
|
||||
*/
|
||||
private Double confidence;
|
||||
|
||||
/**
|
||||
* 来源知识库ID
|
||||
*/
|
||||
private String knowledgeId;
|
||||
|
||||
/**
|
||||
* 来源文档ID列表(JSON格式)
|
||||
*/
|
||||
private String docIds;
|
||||
|
||||
/**
|
||||
* 来源片段ID列表(JSON格式)
|
||||
*/
|
||||
private String fragmentIds;
|
||||
|
||||
/**
|
||||
* 文本段ID(关联到具体的文本段)
|
||||
*/
|
||||
@JsonProperty("text_segment_id")
|
||||
private String textSegmentId;
|
||||
|
||||
/**
|
||||
* 别名列表(JSON格式)
|
||||
*/
|
||||
private String aliases;
|
||||
|
||||
/**
|
||||
* 其他属性(JSON格式)
|
||||
*/
|
||||
private String properties;
|
||||
|
||||
/**
|
||||
* 元数据(JSON格式)
|
||||
*/
|
||||
private Map<String, Object> metadata;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
package org.ruoyi.domain.bo.graph;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 知识图谱片段实体
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("knowledge_base_graph_segment")
|
||||
public class KnowledgeBaseGraphSegment extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 片段UUID
|
||||
*/
|
||||
private String uuid;
|
||||
|
||||
/**
|
||||
* 知识库UUID
|
||||
*/
|
||||
private String kbUuid;
|
||||
|
||||
/**
|
||||
* 知识库条目UUID
|
||||
*/
|
||||
private String kbItemUuid;
|
||||
|
||||
/**
|
||||
* 文档UUID
|
||||
*/
|
||||
private String docUuid;
|
||||
|
||||
/**
|
||||
* 片段文本内容
|
||||
*/
|
||||
private String segmentText;
|
||||
|
||||
/**
|
||||
* 片段索引(第几个片段)
|
||||
*/
|
||||
private Integer chunkIndex;
|
||||
|
||||
/**
|
||||
* 总片段数
|
||||
*/
|
||||
private Integer totalChunks;
|
||||
|
||||
/**
|
||||
* 抽取状态:0-待处理 1-处理中 2-已完成 3-失败
|
||||
*/
|
||||
private Integer extractionStatus;
|
||||
|
||||
/**
|
||||
* 抽取的实体数量
|
||||
*/
|
||||
private Integer entityCount;
|
||||
|
||||
/**
|
||||
* 抽取的关系数量
|
||||
*/
|
||||
private Integer relationCount;
|
||||
|
||||
/**
|
||||
* 消耗的token数
|
||||
*/
|
||||
private Integer tokenUsed;
|
||||
|
||||
/**
|
||||
* 错误信息
|
||||
*/
|
||||
private String errorMessage;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
}
|
||||
@@ -14,7 +14,8 @@ public enum ChatModeType {
|
||||
ZHI_PU("zhipu", "智谱清言"),
|
||||
DEEP_SEEK("deepseek", "深度求索"),
|
||||
QIAN_WEN("qianwen", "通义千问"),
|
||||
OPEN_AI("openai", "openai");
|
||||
OPEN_AI("openai", "openai"),
|
||||
PPIO("ppio", "ppio");
|
||||
private final String code;
|
||||
private final String description;
|
||||
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
package org.ruoyi.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 图谱构建状态枚举
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
@Getter
|
||||
public enum GraphStatusEnum {
|
||||
|
||||
/**
|
||||
* 未构建
|
||||
*/
|
||||
NOT_BUILT(0, "未构建", "NOT_BUILT"),
|
||||
|
||||
/**
|
||||
* 构建中
|
||||
*/
|
||||
BUILDING(10, "构建中", "BUILDING"),
|
||||
|
||||
/**
|
||||
* 已完成
|
||||
*/
|
||||
COMPLETED(20, "已完成", "COMPLETED"),
|
||||
|
||||
/**
|
||||
* 失败
|
||||
*/
|
||||
FAILED(30, "失败", "FAILED");
|
||||
|
||||
private final Integer code;
|
||||
private final String description;
|
||||
private final String statusKey;
|
||||
|
||||
GraphStatusEnum(Integer code, String description, String statusKey) {
|
||||
this.code = code;
|
||||
this.description = description;
|
||||
this.statusKey = statusKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据code获取枚举
|
||||
*/
|
||||
public static GraphStatusEnum getByCode(Integer code) {
|
||||
for (GraphStatusEnum status : values()) {
|
||||
if (status.getCode().equals(code)) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据前端状态字符串获取状态码
|
||||
*/
|
||||
public static Integer getCodeByStatusKey(String statusKey) {
|
||||
if (statusKey == null || statusKey.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
for (GraphStatusEnum status : values()) {
|
||||
if (status.getStatusKey().equals(statusKey)) {
|
||||
return status.getCode();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据状态码获取前端状态字符串
|
||||
*/
|
||||
public static String getStatusKeyByCode(Integer code) {
|
||||
GraphStatusEnum status = getByCode(code);
|
||||
return status != null ? status.getStatusKey() : "NOT_BUILT";
|
||||
}
|
||||
}
|
||||
@@ -36,17 +36,14 @@ public class EmbeddingModelFactory {
|
||||
* 如果模型已存在于缓存中,则直接返回;否则创建新的实例
|
||||
*
|
||||
* @param embeddingModelName 嵌入模型名称
|
||||
* @param dimension 模型维度大小
|
||||
*/
|
||||
public BaseEmbedModelService createModel(String embeddingModelName, Integer dimension) {
|
||||
public BaseEmbedModelService createModel(String embeddingModelName) {
|
||||
return modelCache.computeIfAbsent(embeddingModelName, name -> {
|
||||
ChatModelVo modelConfig = chatModelService.selectModelByName(embeddingModelName);
|
||||
|
||||
if (modelConfig == null) {
|
||||
throw new IllegalArgumentException("未找到模型配置,name=" + name);
|
||||
}
|
||||
if (modelConfig.getDimension() != null) {
|
||||
modelConfig.setDimension(dimension);
|
||||
}
|
||||
return createModelInstance(modelConfig.getProviderCode(), modelConfig);
|
||||
});
|
||||
}
|
||||
@@ -58,7 +55,7 @@ public class EmbeddingModelFactory {
|
||||
* @return boolean 如果模型支持多模态则返回true,否则返回false
|
||||
*/
|
||||
public boolean isMultimodalModel(String embeddingModelName) {
|
||||
return createModel(embeddingModelName, null) instanceof MultiModalEmbedModelService;
|
||||
return createModel(embeddingModelName) instanceof MultiModalEmbedModelService;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,7 +66,7 @@ public class EmbeddingModelFactory {
|
||||
* @throws IllegalArgumentException 当模型不支持多模态时抛出
|
||||
*/
|
||||
public MultiModalEmbedModelService createMultimodalModel(String embeddingModelName) {
|
||||
BaseEmbedModelService model = createModel(embeddingModelName, null);
|
||||
BaseEmbedModelService model = createModel(embeddingModelName);
|
||||
if (model instanceof MultiModalEmbedModelService) {
|
||||
return (MultiModalEmbedModelService) model;
|
||||
}
|
||||
@@ -113,7 +110,6 @@ public class EmbeddingModelFactory {
|
||||
// 配置模型参数
|
||||
model.configure(config);
|
||||
log.info("成功创建嵌入模型: factory={}, modelId={}", config.getProviderCode(), config.getId());
|
||||
|
||||
return model;
|
||||
} catch (NoSuchBeanDefinitionException e) {
|
||||
throw new IllegalArgumentException("获取不到嵌入模型: " + factory, e);
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
package org.ruoyi.factory;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.ruoyi.service.graph.IGraphLLMService;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 图谱LLM服务工厂类
|
||||
* 参考 ruoyi-chat 的 ChatServiceFactory 设计
|
||||
* 根据模型类别自动选择对应的LLM服务实现
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-10-11
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class GraphLLMServiceFactory implements ApplicationContextAware {
|
||||
|
||||
private final Map<String, IGraphLLMService> llmServiceMap = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
// 初始化时收集所有 IGraphLLMService 的实现
|
||||
Map<String, IGraphLLMService> serviceMap = applicationContext.getBeansOfType(IGraphLLMService.class);
|
||||
|
||||
for (IGraphLLMService service : serviceMap.values()) {
|
||||
if (service != null) {
|
||||
String category = service.getCategory();
|
||||
llmServiceMap.put(category, service);
|
||||
log.info("注册图谱LLM服务: category={}, service={}",
|
||||
category, service.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
log.info("图谱LLM服务工厂初始化完成,共注册 {} 个服务", llmServiceMap.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据模型类别获取对应的LLM服务实现
|
||||
*
|
||||
* @param category 模型类别(如: openai, qwen, zhipu)
|
||||
* @return LLM服务实现
|
||||
* @throws IllegalArgumentException 如果不支持该类别
|
||||
*/
|
||||
public IGraphLLMService getLLMService(String category) {
|
||||
IGraphLLMService service = llmServiceMap.get(category);
|
||||
|
||||
if (service == null) {
|
||||
log.error("不支持的模型类别: {}, 可用类别: {}", category, llmServiceMap.keySet());
|
||||
throw new IllegalArgumentException("不支持的模型类别: " + category +
|
||||
", 可用类别: " + llmServiceMap.keySet());
|
||||
}
|
||||
|
||||
return service;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有支持的模型类别
|
||||
*
|
||||
* @return 模型类别集合
|
||||
*/
|
||||
public java.util.Set<String> getSupportedCategories() {
|
||||
return llmServiceMap.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否支持指定的模型类别
|
||||
*
|
||||
* @param category 模型类别
|
||||
* @return 是否支持
|
||||
*/
|
||||
public boolean isSupported(String category) {
|
||||
return llmServiceMap.containsKey(category);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
package org.ruoyi.listener;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import dev.langchain4j.model.openai.internal.chat.ChatCompletionResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.sse.EventSource;
|
||||
import okhttp3.sse.EventSourceListener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* 图谱抽取LLM响应监听器
|
||||
* 用于收集完整的LLM响应(非流式)
|
||||
*
|
||||
* @author ruoyi-ai
|
||||
*/
|
||||
@Slf4j
|
||||
public class GraphExtractionListener extends EventSourceListener {
|
||||
|
||||
private final StringBuilder responseBuilder = new StringBuilder();
|
||||
private final CompletableFuture<String> responseFuture;
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
public GraphExtractionListener(CompletableFuture<String> responseFuture) {
|
||||
this.responseFuture = responseFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(@NotNull EventSource eventSource, @NotNull Response response) {
|
||||
log.debug("LLM连接已建立");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(@NotNull EventSource eventSource, String id, String type, @NotNull String data) {
|
||||
try {
|
||||
if ("[DONE]".equals(data)) {
|
||||
// 响应完成,返回完整内容
|
||||
responseFuture.complete(responseBuilder.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
// 解析响应
|
||||
ChatCompletionResponse completionResponse = objectMapper.readValue(data, ChatCompletionResponse.class);
|
||||
if (completionResponse != null && !completionResponse.choices().isEmpty()) {
|
||||
Object content = completionResponse.choices().get(0).delta().content();
|
||||
if (content != null) {
|
||||
responseBuilder.append(content);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("解析LLM响应失败: {}", e.getMessage(), e);
|
||||
responseFuture.completeExceptionally(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClosed(@NotNull EventSource eventSource) {
|
||||
log.debug("LLM连接已关闭");
|
||||
// 如果还没有完成,就用当前内容完成
|
||||
if (!responseFuture.isDone()) {
|
||||
responseFuture.complete(responseBuilder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NotNull EventSource eventSource, Throwable t, Response response) {
|
||||
String errorMsg = "LLM调用失败";
|
||||
if (response != null && response.body() != null) {
|
||||
try {
|
||||
errorMsg = response.body().string();
|
||||
} catch (Exception e) {
|
||||
errorMsg = response.toString();
|
||||
}
|
||||
}
|
||||
log.error("LLM调用失败: {}", errorMsg, t);
|
||||
responseFuture.completeExceptionally(
|
||||
new RuntimeException(errorMsg, t)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package org.ruoyi.mapper.graph;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.ruoyi.domain.bo.graph.GraphBuildTask;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 图谱构建任务Mapper接口
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
public interface GraphBuildTaskMapper extends BaseMapper<GraphBuildTask> {
|
||||
|
||||
/**
|
||||
* 根据任务UUID查询
|
||||
*
|
||||
* @param taskUuid 任务UUID
|
||||
* @return 构建任务
|
||||
*/
|
||||
GraphBuildTask selectByTaskUuid(String taskUuid);
|
||||
|
||||
/**
|
||||
* 根据图谱UUID查询任务列表
|
||||
*
|
||||
* @param graphUuid 图谱UUID
|
||||
* @return 任务列表
|
||||
*/
|
||||
List<GraphBuildTask> selectByGraphUuid(String graphUuid);
|
||||
|
||||
/**
|
||||
* 根据知识库ID查询任务列表
|
||||
*
|
||||
* @param knowledgeId 知识库ID
|
||||
* @return 任务列表
|
||||
*/
|
||||
List<GraphBuildTask> selectByKnowledgeId(String knowledgeId);
|
||||
|
||||
/**
|
||||
* 查询待执行和执行中的任务
|
||||
*
|
||||
* @return 任务列表
|
||||
*/
|
||||
List<GraphBuildTask> selectPendingAndRunningTasks();
|
||||
|
||||
/**
|
||||
* 更新任务进度
|
||||
*
|
||||
* @param taskUuid 任务UUID
|
||||
* @param progress 进度
|
||||
* @param processedDocs 已处理文档数
|
||||
* @return 影响行数
|
||||
*/
|
||||
int updateProgress(String taskUuid, Integer progress, Integer processedDocs);
|
||||
|
||||
/**
|
||||
* 更新任务状态
|
||||
*
|
||||
* @param taskUuid 任务UUID
|
||||
* @param status 状态
|
||||
* @return 影响行数
|
||||
*/
|
||||
int updateStatus(String taskUuid, Integer status);
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package org.ruoyi.mapper.graph;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.ruoyi.domain.bo.graph.GraphEntityType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 图谱实体类型Mapper接口
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
public interface GraphEntityTypeMapper extends BaseMapper<GraphEntityType> {
|
||||
|
||||
/**
|
||||
* 根据类型编码查询
|
||||
*
|
||||
* @param typeCode 类型编码
|
||||
* @return 实体类型
|
||||
*/
|
||||
GraphEntityType selectByTypeCode(String typeCode);
|
||||
|
||||
/**
|
||||
* 查询所有启用的实体类型
|
||||
*
|
||||
* @return 实体类型列表
|
||||
*/
|
||||
List<GraphEntityType> selectEnabledTypes();
|
||||
|
||||
/**
|
||||
* 批量查询实体类型
|
||||
*
|
||||
* @param typeCodes 类型编码列表
|
||||
* @return 实体类型列表
|
||||
*/
|
||||
List<GraphEntityType> selectByTypeCodes(List<String> typeCodes);
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package org.ruoyi.mapper.graph;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.ruoyi.domain.bo.graph.GraphInstance;
|
||||
|
||||
/**
|
||||
* 知识图谱实例Mapper接口
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
public interface GraphInstanceMapper extends BaseMapper<GraphInstance> {
|
||||
|
||||
/**
|
||||
* 根据图谱UUID查询
|
||||
*
|
||||
* @param graphUuid 图谱UUID
|
||||
* @return 图谱实例
|
||||
*/
|
||||
GraphInstance selectByGraphUuid(String graphUuid);
|
||||
|
||||
/**
|
||||
* 根据知识库ID查询图谱列表
|
||||
*
|
||||
* @param knowledgeId 知识库ID
|
||||
* @return 图谱实例列表
|
||||
*/
|
||||
java.util.List<GraphInstance> selectByKnowledgeId(String knowledgeId);
|
||||
|
||||
/**
|
||||
* 更新节点和关系数量
|
||||
*
|
||||
* @param graphUuid 图谱UUID
|
||||
* @param nodeCount 节点数量
|
||||
* @param relationshipCount 关系数量
|
||||
* @return 影响行数
|
||||
*/
|
||||
int updateCounts(String graphUuid, Integer nodeCount, Integer relationshipCount);
|
||||
|
||||
/**
|
||||
* 更新图谱状态
|
||||
*
|
||||
* @param graphUuid 图谱UUID
|
||||
* @param status 状态
|
||||
* @return 影响行数
|
||||
*/
|
||||
int updateStatus(String graphUuid, Integer status);
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package org.ruoyi.mapper.graph;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.ruoyi.domain.bo.graph.GraphRelationType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 图谱关系类型Mapper接口
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
public interface GraphRelationTypeMapper extends BaseMapper<GraphRelationType> {
|
||||
|
||||
/**
|
||||
* 根据关系编码查询
|
||||
*
|
||||
* @param relationCode 关系编码
|
||||
* @return 关系类型
|
||||
*/
|
||||
GraphRelationType selectByRelationCode(String relationCode);
|
||||
|
||||
/**
|
||||
* 查询所有启用的关系类型
|
||||
*
|
||||
* @return 关系类型列表
|
||||
*/
|
||||
List<GraphRelationType> selectEnabledTypes();
|
||||
|
||||
/**
|
||||
* 批量查询关系类型
|
||||
*
|
||||
* @param relationCodes 关系编码列表
|
||||
* @return 关系类型列表
|
||||
*/
|
||||
List<GraphRelationType> selectByRelationCodes(List<String> relationCodes);
|
||||
}
|
||||
@@ -148,7 +148,6 @@ public class AgentChatHandler implements ChatHandler {
|
||||
messageBO.setContent(content);
|
||||
messageBO.setRole(role);
|
||||
messageBO.setModelName(chatRequest.getModel());
|
||||
messageBO.setBillingType(chatModelVo.getModelType());
|
||||
messageBO.setRemark(null);
|
||||
|
||||
chatMessageService.insertByBo(messageBO);
|
||||
|
||||
@@ -79,10 +79,8 @@ public class ChatMessageServiceImpl implements IChatMessageService {
|
||||
lqw.eq(bo.getUserId() != null, ChatMessage::getUserId, bo.getUserId());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getContent()), ChatMessage::getContent, bo.getContent());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getRole()), ChatMessage::getRole, bo.getRole());
|
||||
lqw.eq(bo.getDeductCost() != null, ChatMessage::getDeductCost, bo.getDeductCost());
|
||||
lqw.eq(bo.getTotalTokens() != null, ChatMessage::getTotalTokens, bo.getTotalTokens());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getModelName()), ChatMessage::getModelName, bo.getModelName());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getBillingType()), ChatMessage::getBillingType, bo.getBillingType());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
|
||||
@@ -92,11 +92,7 @@ public class ChatModelServiceImpl implements IChatModelService {
|
||||
lqw.like(StringUtils.isNotBlank(bo.getModelName()), ChatModel::getModelName, bo.getModelName());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getProviderCode()), ChatModel::getProviderCode, bo.getProviderCode());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getModelDescribe()), ChatModel::getModelDescribe, bo.getModelDescribe());
|
||||
lqw.eq(bo.getModelPrice() != null, ChatModel::getModelPrice, bo.getModelPrice());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getModelType()), ChatModel::getModelType, bo.getModelType());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getModelShow()), ChatModel::getModelShow, bo.getModelShow());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getModelFree()), ChatModel::getModelFree, bo.getModelFree());
|
||||
lqw.eq(bo.getPriority() != null, ChatModel::getPriority, bo.getPriority());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getApiHost()), ChatModel::getApiHost, bo.getApiHost());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getApiKey()), ChatModel::getApiKey, bo.getApiKey());
|
||||
return lqw;
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package org.ruoyi.service.chat.impl.provider;
|
||||
|
||||
|
||||
import dev.langchain4j.data.message.ChatMessage;
|
||||
import dev.langchain4j.model.chat.StreamingChatModel;
|
||||
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
|
||||
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.ruoyi.common.chat.domain.dto.request.ChatRequest;
|
||||
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
|
||||
import org.ruoyi.enums.ChatModeType;
|
||||
import org.ruoyi.service.chat.impl.AbstractStreamingChatService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* OPENAI服务调用
|
||||
*
|
||||
* @author ageerle@163.com
|
||||
* @date 2025/12/13
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class PPIOServiceImpl extends AbstractStreamingChatService {
|
||||
|
||||
@Override
|
||||
public StreamingChatModel buildStreamingChatModel(ChatModelVo chatModelVo, ChatRequest chatRequest) {
|
||||
return OpenAiStreamingChatModel.builder()
|
||||
.baseUrl(chatModelVo.getApiHost())
|
||||
.apiKey(chatModelVo.getApiKey())
|
||||
.modelName(chatModelVo.getModelName())
|
||||
.returnThinking(chatRequest.getEnableThinking())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doChat(ChatModelVo chatModelVo, ChatRequest chatRequest, List<ChatMessage> messagesWithMemory, StreamingChatResponseHandler handler) {
|
||||
StreamingChatModel streamingChatModel = buildStreamingChatModel(chatModelVo, chatRequest);
|
||||
streamingChatModel.chat(messagesWithMemory, handler);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getProviderName() {
|
||||
return ChatModeType.PPIO.getCode();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -38,7 +38,7 @@ public class AliBaiLianBaseEmbedProvider extends OpenAiEmbeddingProvider {
|
||||
return QwenEmbeddingModel.builder()
|
||||
.apiKey(chatModelVo.getApiKey())
|
||||
.modelName(chatModelVo.getModelName())
|
||||
.dimension(1024)
|
||||
.dimension(chatModelVo.getModelDimension())
|
||||
.build()
|
||||
.embedAll(textSegments);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class OpenAiEmbeddingProvider implements BaseEmbedModelService {
|
||||
.baseUrl(chatModelVo.getApiHost())
|
||||
.apiKey(chatModelVo.getApiKey())
|
||||
.modelName(chatModelVo.getModelName())
|
||||
.dimensions(chatModelVo.getDimension())
|
||||
.dimensions(chatModelVo.getModelDimension())
|
||||
.build()
|
||||
.embedAll(textSegments);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.ruoyi.service.embed.impl;
|
||||
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @Author: Robust_H
|
||||
* @Date: 2025-09-30-下午3:59
|
||||
* @Description: 硅基流动(兼容 OpenAi)
|
||||
*/
|
||||
@Component("ppio")
|
||||
public class PPIOEmbeddingProvider extends OpenAiEmbeddingProvider {
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
//package org.ruoyi.service.embed.impl;
|
||||
//
|
||||
//import dev.langchain4j.community.model.zhipu.ZhipuAiEmbeddingModel;
|
||||
//import dev.langchain4j.data.embedding.Embedding;
|
||||
//import dev.langchain4j.data.segment.TextSegment;
|
||||
//import dev.langchain4j.model.output.Response;
|
||||
//import org.ruoyi.domain.vo.chat.ChatModelVo;
|
||||
//import org.ruoyi.enums.ModalityType;
|
||||
//import org.ruoyi.service.embed.BaseEmbedModelService;
|
||||
//import org.springframework.stereotype.Component;
|
||||
//
|
||||
//import java.util.List;
|
||||
//import java.util.Set;
|
||||
//
|
||||
///**
|
||||
// * @Author: Robust_H
|
||||
// * @Date: 2025-09-30-下午4:02
|
||||
// * @Description: 智谱AI
|
||||
// */
|
||||
//@Component("zhipu")
|
||||
//public class ZhiPuAiEmbeddingProvider implements BaseEmbedModelService {
|
||||
// private ChatModelVo chatModelVo;
|
||||
//
|
||||
// @Override
|
||||
// public void configure(ChatModelVo config) {
|
||||
// this.chatModelVo = config;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Set<ModalityType> getSupportedModalities() {
|
||||
// return Set.of();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Response<List<Embedding>> embedAll(List<TextSegment> textSegments) {
|
||||
// return ZhipuAiEmbeddingModel.builder()
|
||||
// .baseUrl(chatModelVo.getApiHost())
|
||||
// .apiKey(chatModelVo.getApiKey())
|
||||
// .model(chatModelVo.getModelName())
|
||||
// .dimensions(chatModelVo.getDimension())
|
||||
// .build()
|
||||
// .embedAll(textSegments);
|
||||
// }
|
||||
//}
|
||||
@@ -1,136 +0,0 @@
|
||||
package org.ruoyi.service.graph;
|
||||
|
||||
|
||||
import org.ruoyi.domain.bo.graph.GraphBuildTask;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 图谱构建任务服务接口
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
public interface IGraphBuildTaskService {
|
||||
|
||||
/**
|
||||
* 创建构建任务
|
||||
*
|
||||
* @param graphUuid 图谱UUID
|
||||
* @param knowledgeId 知识库ID
|
||||
* @param docId 文档ID(可选)
|
||||
* @param taskType 任务类型
|
||||
* @return 任务信息
|
||||
*/
|
||||
GraphBuildTask createTask(String graphUuid, String knowledgeId, String docId, Integer taskType);
|
||||
|
||||
/**
|
||||
* 启动构建任务(异步)
|
||||
*
|
||||
* @param taskUuid 任务UUID
|
||||
* @return 异步结果
|
||||
*/
|
||||
void startTask(String taskUuid);
|
||||
|
||||
/**
|
||||
* 根据UUID获取任务
|
||||
*
|
||||
* @param taskUuid 任务UUID
|
||||
* @return 任务信息
|
||||
*/
|
||||
GraphBuildTask getByUuid(String taskUuid);
|
||||
|
||||
/**
|
||||
* 根据图谱UUID获取任务列表
|
||||
*
|
||||
* @param graphUuid 图谱UUID
|
||||
* @return 任务列表
|
||||
*/
|
||||
List<GraphBuildTask> listByGraphUuid(String graphUuid);
|
||||
|
||||
/**
|
||||
* 获取图谱的最新构建任务
|
||||
*
|
||||
* @param graphUuid 图谱UUID
|
||||
* @return 最新任务
|
||||
*/
|
||||
GraphBuildTask getLatestTask(String graphUuid);
|
||||
|
||||
/**
|
||||
* 根据知识库ID获取任务列表
|
||||
*
|
||||
* @param knowledgeId 知识库ID
|
||||
* @return 任务列表
|
||||
*/
|
||||
List<GraphBuildTask> listByKnowledgeId(String knowledgeId);
|
||||
|
||||
/**
|
||||
* 获取待执行和执行中的任务
|
||||
*
|
||||
* @return 任务列表
|
||||
*/
|
||||
List<GraphBuildTask> getPendingAndRunningTasks();
|
||||
|
||||
/**
|
||||
* 更新任务进度
|
||||
*
|
||||
* @param taskUuid 任务UUID
|
||||
* @param progress 进度百分比
|
||||
* @param processedDocs 已处理文档数
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean updateProgress(String taskUuid, Integer progress, Integer processedDocs);
|
||||
|
||||
/**
|
||||
* 更新任务状态
|
||||
*
|
||||
* @param taskUuid 任务UUID
|
||||
* @param status 状态
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean updateStatus(String taskUuid, Integer status);
|
||||
|
||||
/**
|
||||
* 更新提取统计信息
|
||||
*
|
||||
* @param taskUuid 任务UUID
|
||||
* @param extractedEntities 提取的实体数
|
||||
* @param extractedRelations 提取的关系数
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean updateExtractionStats(String taskUuid, Integer extractedEntities, Integer extractedRelations);
|
||||
|
||||
/**
|
||||
* 标记任务为成功
|
||||
*
|
||||
* @param taskUuid 任务UUID
|
||||
* @param resultSummary 结果摘要
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean markSuccess(String taskUuid, String resultSummary);
|
||||
|
||||
/**
|
||||
* 标记任务为失败
|
||||
*
|
||||
* @param taskUuid 任务UUID
|
||||
* @param errorMessage 错误信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean markFailed(String taskUuid, String errorMessage);
|
||||
|
||||
/**
|
||||
* 取消任务
|
||||
*
|
||||
* @param taskUuid 任务UUID
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean cancelTask(String taskUuid);
|
||||
|
||||
/**
|
||||
* 重试失败的任务
|
||||
*
|
||||
* @param taskUuid 任务UUID
|
||||
* @return 新任务UUID
|
||||
*/
|
||||
String retryTask(String taskUuid);
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package org.ruoyi.service.graph;
|
||||
|
||||
|
||||
import org.ruoyi.domain.dto.GraphExtractionResult;
|
||||
|
||||
/**
|
||||
* 图谱实体关系抽取服务接口
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
public interface IGraphExtractionService {
|
||||
|
||||
/**
|
||||
* 从文本中抽取实体和关系
|
||||
*
|
||||
* @param text 输入文本
|
||||
* @return 抽取结果
|
||||
*/
|
||||
GraphExtractionResult extractFromText(String text);
|
||||
|
||||
/**
|
||||
* 从文本中抽取实体和关系(自定义实体类型)
|
||||
*
|
||||
* @param text 输入文本
|
||||
* @param entityTypes 实体类型列表
|
||||
* @return 抽取结果
|
||||
*/
|
||||
GraphExtractionResult extractFromText(String text, String[] entityTypes);
|
||||
|
||||
/**
|
||||
* 从文本中抽取实体和关系(使用指定的LLM模型)
|
||||
*
|
||||
* @param text 输入文本
|
||||
* @param modelName LLM模型名称
|
||||
* @return 抽取结果
|
||||
*/
|
||||
GraphExtractionResult extractFromTextWithModel(String text, String modelName);
|
||||
|
||||
/**
|
||||
* 解析LLM响应为实体和关系
|
||||
*
|
||||
* @param response LLM响应文本
|
||||
* @return 抽取结果
|
||||
*/
|
||||
GraphExtractionResult parseGraphResponse(String response);
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
package org.ruoyi.service.graph;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.ruoyi.domain.bo.graph.GraphInstance;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 图谱实例服务接口
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-30
|
||||
*/
|
||||
public interface IGraphInstanceService {
|
||||
|
||||
/**
|
||||
* 创建图谱实例
|
||||
*
|
||||
* @param knowledgeId 知识库ID
|
||||
* @param graphName 图谱名称
|
||||
* @param config 配置信息
|
||||
* @return 图谱实例
|
||||
*/
|
||||
GraphInstance createInstance(String knowledgeId, String graphName, String config);
|
||||
|
||||
/**
|
||||
* 根据主键ID获取图谱实例
|
||||
*
|
||||
* @param id 主键ID
|
||||
* @return 图谱实例
|
||||
*/
|
||||
GraphInstance getById(Long id);
|
||||
|
||||
/**
|
||||
* 根据UUID获取图谱实例
|
||||
*
|
||||
* @param graphUuid 图谱UUID
|
||||
* @return 图谱实例
|
||||
*/
|
||||
GraphInstance getByUuid(String graphUuid);
|
||||
|
||||
/**
|
||||
* 更新图谱实例
|
||||
*
|
||||
* @param instance 图谱实例
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean updateInstance(GraphInstance instance);
|
||||
|
||||
/**
|
||||
* 根据知识库ID获取图谱列表
|
||||
*
|
||||
* @param knowledgeId 知识库ID
|
||||
* @return 图谱实例列表
|
||||
*/
|
||||
List<GraphInstance> listByKnowledgeId(String knowledgeId);
|
||||
|
||||
/**
|
||||
* 条件查询图谱实例列表(分页)
|
||||
*
|
||||
* @param page 分页对象
|
||||
* @param instanceName 图谱名称(模糊查询)
|
||||
* @param knowledgeId 知识库ID
|
||||
* @param graphStatus 图谱状态码
|
||||
* @return 分页结果
|
||||
*/
|
||||
Page<GraphInstance> queryPage(Page<GraphInstance> page, String instanceName, String knowledgeId, Integer graphStatus);
|
||||
|
||||
/**
|
||||
* 更新图谱状态
|
||||
*
|
||||
* @param graphUuid 图谱UUID
|
||||
* @param status 状态
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean updateStatus(String graphUuid, Integer status);
|
||||
|
||||
/**
|
||||
* 更新图谱统计信息
|
||||
*
|
||||
* @param graphUuid 图谱UUID
|
||||
* @param nodeCount 节点数量
|
||||
* @param relationshipCount 关系数量
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean updateCounts(String graphUuid, Integer nodeCount, Integer relationshipCount);
|
||||
|
||||
/**
|
||||
* 更新图谱配置
|
||||
*
|
||||
* @param graphUuid 图谱UUID
|
||||
* @param config 配置信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean updateConfig(String graphUuid, String config);
|
||||
|
||||
/**
|
||||
* 删除图谱实例(软删除)
|
||||
*
|
||||
* @param graphUuid 图谱UUID
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean deleteInstance(String graphUuid);
|
||||
|
||||
/**
|
||||
* 物理删除图谱实例及其数据
|
||||
*
|
||||
* @param graphUuid 图谱UUID
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean deleteInstanceAndData(String graphUuid);
|
||||
|
||||
/**
|
||||
* 获取图谱统计信息
|
||||
*
|
||||
* @param graphUuid 图谱UUID
|
||||
* @return 统计信息
|
||||
*/
|
||||
java.util.Map<String, Object> getStatistics(String graphUuid);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user