diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 00000000..251341d2
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,41 @@
+---
+name: 漏洞报告
+about: 报告项目中的Bug或安全问题
+title: '[Bug] '
+labels: 'bug'
+assignees: ''
+---
+
+## 问题描述
+
+简要描述遇到的问题:
+
+## 复现步骤
+
+1.
+2.
+3.
+
+## 期望行为
+
+描述你期望发生的情况:
+
+## 实际行为
+
+描述实际发生的情况:
+
+## 环境信息
+
+| 项目 | 信息 |
+|:---|:---|
+| 操作系统 | |
+| JDK版本 | |
+| 项目版本 | |
+
+## 截图/日志
+
+如有相关信息,请在此粘贴:
+
+## 补充说明
+
+其他补充信息:
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 00000000..0086358d
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1 @@
+blank_issues_enabled: true
diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md
new file mode 100644
index 00000000..af6ecc3e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/custom.md
@@ -0,0 +1,15 @@
+---
+name: 自定义
+about: 其他问题或讨论
+title: ''
+labels: ''
+assignees: ''
+---
+
+## 描述
+
+请详细描述你的问题或需求:
+
+## 补充信息
+
+如有其他补充,请在此填写:
diff --git a/.github/ISSUE_TEMPLATE/enterprise-collaboration.md b/.github/ISSUE_TEMPLATE/enterprise-collaboration.md
new file mode 100644
index 00000000..21e8e335
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/enterprise-collaboration.md
@@ -0,0 +1,57 @@
+---
+name: 企业AI应用合作登记
+about: 登记企业信息与合作意向,获取免费技术支持
+title: '[合作登记] 企业AI应用需求登记'
+labels: '合作登记'
+assignees: ''
+---
+
+## 登记说明
+
+感谢您关注 RuoYi AI!我们团队今年的重点是帮助企业落地AI应用,如果贵公司符合要求,我们可以提供**免费的技术支持**。
+
+请在下方评论中填写登记信息,格式如下:
+
+---
+
+## 登记格式预览
+
+| 字段 | 内容 |
+|:---|:---|
+| 公司名称 | (必填) |
+| 公司Logo地址 | (可选) |
+| 所属行业 | (必填) |
+| 公司所在地 | (必填) |
+| 项目名称 | (必填) |
+| 项目Logo地址 | (可选) |
+| 项目简介 | (必填) |
+| 当前AI应用状态 | □ 尚未开始 □ 规划中 □ 已有初步应用 □ 已有成熟应用 |
+| 计划落地时间 | □ 1个月内 □ 1-3个月 □ 3-6个月 □ 6个月以上 |
+| 当前痛点或挑战 | (可选) |
+| 公司简介 | (可选) |
+
+---
+
+## 可复制格式
+
+复制下方内容并在评论中填写:
+
+```
+| 字段 | 内容 |
+|:---|:---|
+| 公司名称 | |
+| 公司Logo地址 | |
+| 所属行业 | |
+| 公司所在地 | |
+| 项目名称 | |
+| 项目Logo地址 | |
+| 项目简介 | |
+| 当前AI应用状态 | |
+| 计划落地时间 | |
+| 当前痛点或挑战 | |
+| 公司简介 | |
+```
+
+---
+
+> **温馨提示**:提交的信息仅用于合作沟通,不会对外公开。
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 00000000..403ca8c9
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,31 @@
+---
+name: 想法建议
+about: 提出新功能建议或改进想法
+title: '[Feature] '
+labels: 'enhancement'
+assignees: ''
+---
+
+## 建议类型
+
+□ 新功能 □ 功能改进 □ 文档完善 □ 其他
+
+## 建议描述
+
+清晰描述你的建议内容:
+
+## 使用场景
+
+描述这个功能在什么场景下会用到:
+
+## 期望效果
+
+描述你期望的效果:
+
+## 参考示例
+
+如有类似的参考实现或产品,请提供链接:
+
+## 补充说明
+
+其他补充信息:
diff --git a/.gitignore b/.gitignore
index c23b47ce..e204fe12 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,10 +21,13 @@ target/
### IntelliJ IDEA ###
.idea
+.claude
+.github
*.iws
*.iml
*.ipr
+
### JRebel ###
rebel.xml
@@ -48,3 +51,4 @@ data/
!*/build/*.xml
.flattened-pom.xml
+/.claude/settings.local.json
diff --git a/README.md b/README.md
index 90ebdeed..bb8c4859 100644
--- a/README.md
+++ b/README.md
@@ -17,12 +17,9 @@
-## 功能建议&bug提交:【腾讯文档】
-https://docs.qq.com/sheet/DR3hoR3FVVkpJcnVm
-
### 企业级AI助手平台
-*开箱即用的全栈AI平台,集成Coze、DIFY等主流AI平台,提供先进的RAG技术、知识图谱、数字人和AI流程编排能力*
+*开箱即用的全栈AI平台,支持多智能体协同、Supervisor模式编排、多种决策模型,提供先进的RAG技术和可视化流程编排能力*
**[English](README_EN.md)** | **[📖 使用文档](https://doc.pandarobot.chat)** |
**[🚀 在线体验](https://web.pandarobot.chat)** | **[🐛 问题反馈](https://github.com/ageerle/ruoyi-ai/issues)** | **[💡 功能建议](https://github.com/ageerle/ruoyi-ai/issues)**
@@ -34,34 +31,23 @@ https://docs.qq.com/sheet/DR3hoR3FVVkpJcnVm
## ✨ 核心亮点
-### 智能AI引擎
-- **多模型接入**:支持 OpenAI、DeepSeek、通义千问、智谱AI 等主流厂商的模型
-- **多模态理解**:支持文本、图片、文档等多种格式的智能处理
-- **AI平台集成**:集成了 **扣子(Coze)**、**DIFY**、**FastGPT** 等主流AI应用平台
-- **MCP能力集成**:基于模型上下文协议,打造可扩展的AI工具生态系统
-- **AI编程助手**:内置智能代码分析和项目脚手架生成能力
-
-### 本地化RAG方案
-- **私有知识库**:基于 Langchain4j 框架 + BGE-large-zh-v1.5 中文向量模型实现本地私有知识库
-- **多种向量库**:支持 Milvus、Weaviate、Qdrant 等主流向量数据库
-- **数据安全可控**:支持完全本地部署,保护企业数据隐私
-- **灵活模型部署**:兼容 Ollama、vLLM 等本地推理框架
-
-### AI创作工具
-- **AI 绘画创作**: 集成 MidJourney、GPT-4o-image
-- **智能PPT生成**:一键将文本内容转换为精美演示文稿
-
-### 知识图谱与智能编排
-- **知识图谱构建**:自动从文档和对话中提取实体关系,构建可视化知识网络
-- **AI 流程编排**:可视化工作流设计器,支持复杂AI任务的编排和自动化执行
-- **数字人交互**:集成数字人形象,提供更自然的人机交互体验
+| 模块 | 现有能力 | 扩展方向 |
+|:---:|---|---|
+| **模型管理** | 多模型接入(OpenAI/DeepSeek/通义/智谱)、多模态理解、Coze/DIFY/FastGPT平台集成 | 自动模式、容错机制 |
+| **知识库** | 本地RAG + 向量库(Milvus/Weaviate) + 知识图谱 + 文档解析 +重排序 | 音频视频解析、知识出处 |
+| **工具管理** | Mcp协议集成、Skills能力 + 可扩展工具生态 | 工具插件市场、toolAgent自动加载工具 |
+| **流程编排** | 可视化工作流设计器、节点拖拽编排、SSE流式执行,目前已经支持模型调用,邮件发送,人工审核等节点 | 更多节点类型 |
+| **多智能体** | 基于Langchain4j的Agent框架、Supervisor模式编排,支持多种决策模型 | 智能体可配置 |
+| **AI编程** | 智能代码分析、项目脚手架生成、Copilot助手 | 代码生成优化 |
## 🚀 快速体验
### 在线演示
-- **用户端体验**:[web.pandarobot.chat](https://web.pandarobot.chat) (账号:admin 密码:admin123)
-- **管理后台**:[admin.pandarobot.chat](https://admin.pandarobot.chat) (账号:admin 密码:admin123)
+| 平台 | 地址 | 账号 |
+|:------:|---|---|
+| 用户端 | [web.pandarobot.chat](https://web.pandarobot.chat) | admin / admin123 |
+| 管理后台 | [admin.pandarobot.chat](https://admin.pandarobot.chat) | admin / admin123 |
### 项目源码
@@ -71,18 +57,19 @@ https://docs.qq.com/sheet/DR3hoR3FVVkpJcnVm
| 🎨 用户前端 | [ruoyi-web](https://github.com/ageerle/ruoyi-web) | [ruoyi-web](https://gitee.com/ageerle/ruoyi-web) | [ruoyi-web](https://gitcode.com/ageerle/ruoyi-web) |
| 🛠️ 管理后台 | [ruoyi-admin](https://github.com/ageerle/ruoyi-admin) | [ruoyi-admin](https://gitee.com/ageerle/ruoyi-admin) | [ruoyi-admin](https://gitcode.com/ageerle/ruoyi-admin) |
+### 合作项目
+| 项目名称 | GitHub 仓库 | Gitee 仓库
+|----------------|-------------------------------------------------------|------------------------------------------------------|
+| element-plus-x | [element-plus-x](https://github.com/element-plus-x/Element-Plus-X) | [element-plus-x](https://gitee.com/he-jiayue/element-plus-x) |
+
## 🛠️ 技术架构
### 核心框架
-- **后端架构**:Spring Boot 3.5 + Langchain4j
-- **数据存储**:MySQL 8.0 + Redis + 向量数据库(Milvus/Weaviate/Qdrant)
-- **前端技术**:Vue 3 + Vben Admin + Element UI
+- **后端架构**:Spring Boot 4.0 + Spring ai 2.0 + Langchain4j
+- **数据存储**:MySQL 8.0 + Redis + 向量数据库(Milvus/Weaviate)
+- **前端技术**:Vue 3 + Vben Admin + element-plus-x
- **安全认证**:Sa-Token + JWT 双重保障
-### 系统组件
-- **文档处理**:PDF、Word、Excel 解析,图像智能分析
-- **实时通信**:WebSocket 实时通信,SSE 流式响应
-- **系统监控**:完善的日志体系、性能监控、服务健康检查
## 📚 使用文档
@@ -150,6 +137,29 @@ https://docs.qq.com/sheet/DR3hoR3FVVkpJcnVm
---
+
+## 📺 视频教程
+
+
**[⭐ 点个Star支持一下](https://github.com/ageerle/ruoyi-ai)** • **[ Fork 开始贡献](https://github.com/ageerle/ruoyi-ai/fork)** • **[📚 English](README_EN.md)** • **[📖 查看完整文档](https://doc.pandarobot.chat)**
diff --git a/README_EN.md b/README_EN.md
index 16e3dcd4..20e4a54e 100644
--- a/README_EN.md
+++ b/README_EN.md
@@ -1,3 +1,4 @@
+
# RuoYi AI
@@ -19,64 +20,57 @@
### Enterprise-Grade AI Assistant Platform
-*An out-of-the-box intelligent AI platform that integrates mainstream AI platforms such as Coze and DIFY, providing advanced RAG technology, knowledge graphs, digital humans, and AI workflow orchestration capabilities*
+*An out-of-the-box full-stack AI platform supporting multi-agent collaboration, Supervisor mode orchestration, and multiple decision models, with advanced RAG technology and visual workflow orchestration capabilities*
**[中文](README.md)** | **[📖 Documentation](https://doc.pandarobot.chat)** |
**[🚀 Live Demo](https://web.pandarobot.chat)** | **[🐛 Report Issues](https://github.com/ageerle/ruoyi-ai/issues)** | **[💡 Feature Requests](https://github.com/ageerle/ruoyi-ai/issues)**
+
+
+
## ✨ Core Features
-### Intelligent AI Engine
-- **Multi-Model Integration**: Supports mainstream LLM providers including OpenAI, DeepSeek, Alibaba's Tongyi Qianwen, and Zhipu AI
-- **Multi-Modal Understanding**: Intelligently processes multiple formats including text, images, and documents
-- **AI Platform Integration**: Integrates mainstream AI application platforms like **Coze**, **DIFY**, and **FastGPT**
-- **MCP Capability Integration**: Build an extensible AI toolkit ecosystem based on the Model Context Protocol
-- **AI Coding Assistant**: Built-in intelligent code analysis and project scaffolding generation capabilities
-
-### Local RAG Solution
-- **Private Knowledge Base**: Implements local private knowledge base based on Langchain4j framework + BGE-large-zh-v1.5 Chinese vector model
-- **Multiple Vector Databases**: Supports mainstream vector databases including Milvus, Weaviate, and Qdrant
-- **Data Security & Privacy**: Supports fully local deployment to protect enterprise data privacy
-- **Flexible Model Deployment**: Compatible with local inference frameworks like Ollama and vLLM
-
-### AI Creative Tools
-- **AI Image Generation**: Integrates MidJourney and GPT-4o-image
-- **Intelligent PPT Generation**: Convert text content to beautiful presentations with one click
-
-### Knowledge Graph & Intelligent Orchestration
-- **Knowledge Graph Construction**: Automatically extract entity relationships from documents and conversations, build visualized knowledge networks
-- **AI Workflow Orchestration**: Visual workflow designer supporting complex AI task orchestration and automated execution
-- **Digital Human Interaction**: Integrated digital avatars providing more natural human-machine interaction experience
+| Module | Current Capabilities | Extension Direction |
+|:---:|---|---|
+| **Model Management** | Multi-model integration (OpenAI/DeepSeek/Tongyi/Zhipu), multi-modal understanding, Coze/DIFY/FastGPT platform integration | Auto mode, fault tolerance |
+| **Knowledge Base** | Local RAG + Vector DB (Milvus/Weaviate) + Knowledge Graph + Document parsing + Reranking | Audio/video parsing, knowledge source |
+| **Tool Management** | MCP protocol integration, Skills capability + Extensible tool ecosystem | Tool plugin marketplace, toolAgent auto-loading |
+| **Workflow Orchestration** | Visual workflow designer, drag-and-drop node orchestration, SSE streaming execution, currently supports model (with RAG) calls, email sending, manual review nodes | More node types |
+| **Multi-Agent** | Agent framework based on Langchain4j, Supervisor mode orchestration, supports multiple decision models | Configurable agents |
+| **AI Coding** | Intelligent code analysis, project scaffolding generation, Copilot assistant | Code generation optimization |
## 🚀 Quick Start
### Live Demo
-- **User Experience**: [web.pandarobot.chat](https://web.pandarobot.chat) (Username: admin, Password: admin123)
-- **Admin Dashboard**: [admin.pandarobot.chat](https://admin.pandarobot.chat) (Username: admin, Password: admin123)
+| Platform | URL | Account |
+|:------:|---|---|
+| User Frontend | [web.pandarobot.chat](https://web.pandarobot.chat) | admin / admin123 |
+| Admin Panel | [admin.pandarobot.chat](https://admin.pandarobot.chat) | admin / admin123 |
### Project Repositories
-| Module | GitHub Repository | Gitee Repository | GitCode Repository |
-|------------------|-------------------------------------------------------|------------------------------------------------------|--------------------------------------------------------|
-| 🔧 Backend | [ruoyi-ai](https://github.com/ageerle/ruoyi-ai) | [ruoyi-ai](https://gitee.com/ageerle/ruoyi-ai) | [ruoyi-ai](https://gitcode.com/ageerle/ruoyi-ai) |
-| 🎨 User Frontend | [ruoyi-web](https://github.com/ageerle/ruoyi-web) | [ruoyi-web](https://gitee.com/ageerle/ruoyi-web) | [ruoyi-web](https://gitcode.com/ageerle/ruoyi-web) |
-| 🛠️ Admin Panel | [ruoyi-admin](https://github.com/ageerle/ruoyi-admin) | [ruoyi-admin](https://gitee.com/ageerle/ruoyi-admin) | [ruoyi-admin](https://gitcode.com/ageerle/ruoyi-admin) |
+| Module | GitHub Repository | Gitee Repository | GitCode Repository |
+|----------|-------------------------------------------------------|------------------------------------------------------|--------------------------------------------------------|
+| 🔧 Backend | [ruoyi-ai](https://github.com/ageerle/ruoyi-ai) | [ruoyi-ai](https://gitee.com/ageerle/ruoyi-ai) | [ruoyi-ai](https://gitcode.com/ageerle/ruoyi-ai) |
+| 🎨 User Frontend | [ruoyi-web](https://github.com/ageerle/ruoyi-web) | [ruoyi-web](https://gitee.com/ageerle/ruoyi-web) | [ruoyi-web](https://gitcode.com/ageerle/ruoyi-web) |
+| 🛠️ Admin Panel | [ruoyi-admin](https://github.com/ageerle/ruoyi-admin) | [ruoyi-admin](https://gitee.com/ageerle/ruoyi-admin) | [ruoyi-admin](https://gitcode.com/ageerle/ruoyi-admin) |
+
+### Partner Projects
+| Project Name | GitHub Repository | Gitee Repository
+|----------------|-------------------------------------------------------|------------------------------------------------------|
+| element-plus-x | [element-plus-x](https://github.com/element-plus-x/Element-Plus-X) | [element-plus-x](https://gitee.com/he-jiayue/element-plus-x) |
## 🛠️ Technical Architecture
### Core Framework
-- **Backend**: Spring Boot 3.5 + Langchain4j
-- **Data Storage**: MySQL 8.0 + Redis + Vector Databases (Milvus/Weaviate/Qdrant)
-- **Frontend**: Vue 3 + Vben Admin + Element UI
+- **Backend**: Spring Boot 4.0 + Spring AI 2.0 + Langchain4j
+- **Data Storage**: MySQL 8.0 + Redis + Vector Databases (Milvus/Weaviate)
+- **Frontend**: Vue 3 + Vben Admin + element-plus-x
- **Security**: Sa-Token + JWT dual-layer security
-### System Components
-- **Document Processing**: PDF, Word, and Excel parsing with intelligent image analysis
-- **Real-Time Communication**: WebSocket real-time communication with SSE streaming responses
-- **System Monitoring**: Comprehensive logging system, performance monitoring, and service health checks
## 📚 Documentation
@@ -122,21 +116,7 @@ Thanks to the following excellent open-source projects for their support:
-
-
-
-
-Scan to Add Author's WeChat
-Invitation to join the group
- |
-
-
-QQ Technical Discussion Group
-Technical discussions
- |
-
-
-
+**[📱 Join Telegram Group](https://t.me/+LqooQAc5HxRmYmE1)**
@@ -170,4 +150,4 @@ Thanks to the following excellent open-source projects for their support:
[license-shield]: https://img.shields.io/github/license/ageerle/ruoyi-ai.svg?style=flat-square
-[license-url]: https://github.com/ageerle/ruoyi-ai/blob/main/LICENSE
\ No newline at end of file
+[license-url]: https://github.com/ageerle/ruoyi-ai/blob/main/LICENSE
diff --git a/docs/image/bibi.png b/docs/image/bibi.png
new file mode 100644
index 00000000..bafba054
Binary files /dev/null and b/docs/image/bibi.png differ
diff --git a/docs/image/dy.png b/docs/image/dy.png
new file mode 100644
index 00000000..c303e76a
Binary files /dev/null and b/docs/image/dy.png differ
diff --git a/docs/script/sql/ruoyi-ai-v3_mysql8.sql b/docs/script/sql/ruoyi-ai-v3_mysql8.sql
index 0f957597..87ef9ecc 100644
--- a/docs/script/sql/ruoyi-ai-v3_mysql8.sql
+++ b/docs/script/sql/ruoyi-ai-v3_mysql8.sql
@@ -105,8 +105,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', 'openai', 'deepseek', 1, '1', 'Y', 'Y', 1, 'https://api.ppinfra.com/openai', 'sk_xx', 103, 1, '2025-12-15 23:16:54', 1, '2026-02-06 01:02:31', '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', 'openai', '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-06 01:02:35', 'bge-large-zh-v1.5', 0);
-- ----------------------------
-- Table structure for chat_provider
@@ -139,11 +139,11 @@ CREATE TABLE `chat_provider` (
-- ----------------------------
-- Records of chat_provider
-- ----------------------------
-INSERT INTO `chat_provider` VALUES (1, 'OpenAI', 'openai', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/01091be272334383a1efd9bc22b73ee6.png', 'OpenAI官方API服务商', 'https://api.openai.com', '0', 1, NULL, '2025-12-14 21:48:11', '1', '1', '2026-02-25 20:46:59', 'OpenAI厂商', NULL, '0', NULL, 0);
-INSERT INTO `chat_provider` VALUES (2, '阿里云百炼', 'qianwen', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/de2aa7e649de44f3ba5c6380ac6acd04.png', '阿里云百炼大模型服务', 'https://dashscope.aliyuncs.com', '0', 2, NULL, '2025-12-14 21:48:11', '1', '1', '2026-02-25 20:49:13', '阿里云厂商', NULL, '0', NULL, 0);
+INSERT INTO `chat_provider` VALUES (1, 'OpenAI', 'openai', 'https://ruoyi-ai-1254149996.cos.ap-guangzhou.myqcloud.com/2025/12/15/9d944a6abfcd46e2bd6e364f07202589.png', 'OpenAI官方API服务商', 'https://api.openai.com', '0', 1, NULL, '2025-12-14 21:48:11', '1', '1', '2026-01-22 15:05:55', 'OpenAI厂商', NULL, '0', NULL, 0);
+INSERT INTO `chat_provider` VALUES (2, '阿里云百炼', 'qianwen', 'https://ruoyi-ai-1254149996.cos.ap-guangzhou.myqcloud.com/2025/12/15/039ad13f690649f0ade139f8c803727b.png', '阿里云百炼大模型服务', 'https://dashscope.aliyuncs.com', '0', 2, NULL, '2025-12-14 21:48:11', '1', '1', '2026-02-06 00:58:22', '阿里云厂商', NULL, '0', NULL, 0);
INSERT INTO `chat_provider` VALUES (3, '智谱AI', 'zhipu', 'https://ruoyi-ai-1254149996.cos.ap-guangzhou.myqcloud.com/2025/12/15/a43e98fb7b3b4861b8caa6184e6fa40a.png', '智谱AI大模型服务', 'https://open.bigmodel.cn', '0', 3, NULL, '2025-12-14 21:48:11', '1', '1', '2026-02-06 00:49:14', '智谱AI厂商', NULL, '1', NULL, 0);
-INSERT INTO `chat_provider` VALUES (5, 'ollama', 'ollama', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/afecabebc8014d80b0f06b4796a74c5d.png', 'ollama大模型', 'http://127.0.0.1:11434', '0', 5, NULL, '2025-12-14 21:48:11', '1', '1', '2026-02-25 20:48:48', 'ollama厂商', NULL, '0', NULL, 0);
-INSERT INTO `chat_provider` VALUES (2000585060904435714, 'PPIO', 'ppio', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/049bb6a507174f73bba4b8d8b9e55b8a.png', 'api聚合厂商', 'https://api.ppinfra.com/openai', '0', 5, 103, '2025-12-15 23:13:42', '1', '1', '2026-02-25 20:49:01', 'api聚合厂商', NULL, '0', NULL, 0);
+INSERT INTO `chat_provider` VALUES (5, 'ollama', 'ollama', 'https://ruoyi-ai-1254149996.cos.ap-guangzhou.myqcloud.com/2025/12/15/2ff984bc9e4249df992733b31959056b.png', 'ollama大模型', 'http://127.0.0.1:11434', '0', 5, NULL, '2025-12-14 21:48:11', '1', '1', '2025-12-15 00:49:05', 'ollama厂商', NULL, '0', NULL, 0);
+INSERT INTO `chat_provider` VALUES (2000585060904435714, 'PPIO', 'ppio', 'https://ruoyi-ai-1254149996.cos.ap-guangzhou.myqcloud.com/2025/12/15/c4f8e304ce7740029b0024934d4625bc.png', 'api聚合厂商', 'https://api.ppinfra.com/openai', '0', 5, 103, '2025-12-15 23:13:42', '1', '1', '2026-01-02 00:54:45', 'api聚合厂商', NULL, '0', NULL, 0);
-- ----------------------------
-- Table structure for chat_session
@@ -1414,90 +1414,6 @@ CREATE TABLE `knowledge_info` (
-- Records of knowledge_info
-- ----------------------------
--- ----------------------------
--- Table structure for mcp_market_info
--- ----------------------------
-DROP TABLE IF EXISTS `mcp_market_info`;
-CREATE TABLE `mcp_market_info` (
- `id` bigint NOT NULL AUTO_INCREMENT COMMENT '市场ID',
- `name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '市场名称',
- `url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '市场URL',
- `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '市场描述',
- `auth_config` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '认证配置(JSON格式)',
- `status` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT 'ENABLED' COMMENT '状态:ENABLED-启用, DISABLED-禁用',
- `tenant_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '000000' COMMENT '租户编号',
- `create_dept` bigint NULL DEFAULT NULL COMMENT '创建部门',
- `create_by` bigint NULL DEFAULT NULL COMMENT '创建者',
- `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
- `update_by` bigint NULL DEFAULT NULL COMMENT '更新者',
- `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
- `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
- PRIMARY KEY (`id`) USING BTREE,
- INDEX `idx_name`(`name` ASC) USING BTREE,
- INDEX `idx_status`(`status` ASC) USING BTREE,
- INDEX `idx_tenant_id`(`tenant_id` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'MCP市场表' ROW_FORMAT = Dynamic;
-
--- ----------------------------
--- Records of mcp_market_info
--- ----------------------------
-
--- ----------------------------
--- Table structure for mcp_market_tool
--- ----------------------------
-DROP TABLE IF EXISTS `mcp_market_tool`;
-CREATE TABLE `mcp_market_tool` (
- `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
- `market_id` bigint NOT NULL COMMENT '市场ID',
- `tool_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '工具名称',
- `tool_description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '工具描述',
- `tool_version` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '工具版本',
- `tool_metadata` json NULL COMMENT '工具元数据(JSON格式)',
- `is_loaded` tinyint(1) NULL DEFAULT 0 COMMENT '是否已加载到本地',
- `local_tool_id` bigint NULL DEFAULT NULL COMMENT '关联的本地工具ID',
- `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
- PRIMARY KEY (`id`) USING BTREE,
- INDEX `idx_market_id`(`market_id` ASC) USING BTREE,
- INDEX `idx_tool_name`(`tool_name` ASC) USING BTREE,
- INDEX `idx_is_loaded`(`is_loaded` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'MCP市场工具关联表' ROW_FORMAT = Dynamic;
-
--- ----------------------------
--- Records of mcp_market_tool
--- ----------------------------
-
--- ----------------------------
--- Table structure for mcp_tool_info
--- ----------------------------
-DROP TABLE IF EXISTS `mcp_tool_info`;
-CREATE TABLE `mcp_tool_info` (
- `id` bigint NOT NULL AUTO_INCREMENT COMMENT '工具ID',
- `name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '工具名称',
- `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '工具描述',
- `type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT 'LOCAL' COMMENT '工具类型:LOCAL-本地, REMOTE-远程, BUILTIN-内置',
- `status` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT 'ENABLED' COMMENT '状态:ENABLED-启用, DISABLED-禁用',
- `config_json` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '配置信息(JSON格式)',
- `tenant_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '000000' COMMENT '租户编号',
- `create_dept` bigint NULL DEFAULT NULL COMMENT '创建部门',
- `create_by` bigint NULL DEFAULT NULL COMMENT '创建者',
- `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
- `update_by` bigint NULL DEFAULT NULL COMMENT '更新者',
- `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
- `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
- PRIMARY KEY (`id`) USING BTREE,
- INDEX `idx_name`(`name` ASC) USING BTREE,
- INDEX `idx_type`(`type` ASC) USING BTREE,
- INDEX `idx_status`(`status` ASC) USING BTREE,
- INDEX `idx_tenant_id`(`tenant_id` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'MCP工具表' ROW_FORMAT = Dynamic;
-
--- ----------------------------
--- Records of mcp_tool_info
--- ----------------------------
-INSERT INTO `mcp_tool_info` VALUES (1, 'edit_file', 'Edits a file by applying a diff. Use this tool when you need to make specific changes to a file. The tool will show the diff before applying changes. Use absolute paths within the workspace directory.', 'BUILTIN', 'ENABLED', NULL, '000000', -1, -1, '2026-02-24 20:19:41', -1, '2026-02-24 20:19:41', '0');
-INSERT INTO `mcp_tool_info` VALUES (2, 'list_directory', 'Lists files and directories in the specified path. Supports recursive listing and filtering. Shows file sizes, modification times, and types. Use absolute paths within the workspace directory.', 'BUILTIN', 'ENABLED', NULL, '000000', -1, -1, '2026-02-24 20:19:41', -1, '2026-02-24 20:19:41', '0');
-INSERT INTO `mcp_tool_info` VALUES (3, 'read_file', 'Reads the contents of a file. Use absolute paths within the workspace directory. Returns the complete file content as a string.', 'BUILTIN', 'ENABLED', NULL, '000000', -1, -1, '2026-02-24 20:19:41', -1, '2026-02-24 20:19:41', '0');
-
-- ----------------------------
-- Table structure for sj_distributed_lock
-- ----------------------------
@@ -1510,7 +1426,7 @@ CREATE TABLE `sj_distributed_lock` (
`create_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`name`) USING BTREE
-) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '锁定表' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '锁定表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_distributed_lock
@@ -1535,7 +1451,7 @@ CREATE TABLE `sj_group_config` (
`update_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_namespace_id_group_name`(`namespace_id` ASC, `group_name` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '组配置' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '组配置' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_group_config
@@ -1581,7 +1497,7 @@ CREATE TABLE `sj_job` (
INDEX `idx_namespace_id_group_name`(`namespace_id` ASC, `group_name` ASC) USING BTREE,
INDEX `idx_job_status_bucket_index`(`job_status` ASC, `bucket_index` ASC) USING BTREE,
INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务信息' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务信息' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_job
@@ -1603,7 +1519,7 @@ CREATE TABLE `sj_job_executor` (
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_namespace_id_group_name`(`namespace_id` ASC, `group_name` ASC) USING BTREE,
INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务执行器信息' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务执行器信息' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_job_executor
@@ -1629,7 +1545,7 @@ CREATE TABLE `sj_job_log_message` (
INDEX `idx_task_batch_id_task_id`(`task_batch_id` ASC, `task_id` ASC) USING BTREE,
INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE,
INDEX `idx_namespace_id_group_name`(`namespace_id` ASC, `group_name` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '调度日志' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '调度日志' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_job_log_message
@@ -1658,7 +1574,7 @@ CREATE TABLE `sj_job_summary` (
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_trigger_at_system_task_type_business_id`(`trigger_at` ASC, `system_task_type` ASC, `business_id` ASC) USING BTREE,
INDEX `idx_namespace_id_group_name_business_id`(`namespace_id` ASC, `group_name` ASC, `business_id` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'DashBoard_Job' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'DashBoard_Job' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_job_summary
@@ -1692,7 +1608,7 @@ CREATE TABLE `sj_job_task` (
INDEX `idx_task_batch_id_task_status`(`task_batch_id` ASC, `task_status` ASC) USING BTREE,
INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE,
INDEX `idx_namespace_id_group_name`(`namespace_id` ASC, `group_name` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务实例' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务实例' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_job_task
@@ -1724,7 +1640,7 @@ CREATE TABLE `sj_job_task_batch` (
INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE,
INDEX `idx_namespace_id_group_name`(`namespace_id` ASC, `group_name` ASC) USING BTREE,
INDEX `idx_workflow_task_batch_id_workflow_node_id`(`workflow_task_batch_id` ASC, `workflow_node_id` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务批次' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务批次' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_job_task_batch
@@ -1745,7 +1661,7 @@ CREATE TABLE `sj_namespace` (
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_unique_id`(`unique_id` ASC) USING BTREE,
INDEX `idx_name`(`name` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '命名空间' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '命名空间' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_namespace
@@ -1774,7 +1690,7 @@ CREATE TABLE `sj_notify_config` (
`update_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_namespace_id_group_name_scene_name`(`namespace_id` ASC, `group_name` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '通知配置' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '通知配置' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_notify_config
@@ -1795,7 +1711,7 @@ CREATE TABLE `sj_notify_recipient` (
`update_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_namespace_id`(`namespace_id` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '告警通知接收人' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '告警通知接收人' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_notify_recipient
@@ -1834,7 +1750,7 @@ CREATE TABLE `sj_retry` (
INDEX `idx_retry_status_bucket_index`(`retry_status` ASC, `bucket_index` ASC) USING BTREE,
INDEX `idx_parent_id`(`parent_id` ASC) USING BTREE,
INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '重试信息表' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '重试信息表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_retry
@@ -1863,7 +1779,7 @@ CREATE TABLE `sj_retry_dead_letter` (
INDEX `idx_idempotent_id`(`idempotent_id` ASC) USING BTREE,
INDEX `idx_biz_no`(`biz_no` ASC) USING BTREE,
INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '死信队列表' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '死信队列表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_retry_dead_letter
@@ -1898,7 +1814,7 @@ CREATE TABLE `sj_retry_scene_config` (
`update_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_namespace_id_group_name_scene_name`(`namespace_id` ASC, `group_name` ASC, `scene_name` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '场景配置' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '场景配置' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_retry_scene_config
@@ -1923,7 +1839,7 @@ CREATE TABLE `sj_retry_summary` (
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_scene_name_trigger_at`(`namespace_id` ASC, `group_name` ASC, `scene_name` ASC, `trigger_at` ASC) USING BTREE,
INDEX `idx_trigger_at`(`trigger_at` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'DashBoard_Retry' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'DashBoard_Retry' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_retry_summary
@@ -1951,7 +1867,7 @@ CREATE TABLE `sj_retry_task` (
INDEX `task_status`(`task_status` ASC) USING BTREE,
INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE,
INDEX `idx_retry_id`(`retry_id` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '重试任务表' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '重试任务表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_retry_task
@@ -1974,7 +1890,7 @@ CREATE TABLE `sj_retry_task_log_message` (
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_namespace_id_group_name_retry_task_id`(`namespace_id` ASC, `group_name` ASC, `retry_task_id` ASC) USING BTREE,
INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务调度日志信息记录表' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务调度日志信息记录表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_retry_task_log_message
@@ -2001,7 +1917,7 @@ CREATE TABLE `sj_server_node` (
UNIQUE INDEX `uk_host_id_host_ip`(`host_id` ASC, `host_ip` ASC) USING BTREE,
INDEX `idx_namespace_id_group_name`(`namespace_id` ASC, `group_name` ASC) USING BTREE,
INDEX `idx_expire_at_node_type`(`expire_at` ASC, `node_type` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '服务器节点' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '服务器节点' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_server_node
@@ -2020,7 +1936,7 @@ CREATE TABLE `sj_system_user` (
`update_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_username`(`username` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统用户表' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统用户表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_system_user
@@ -2040,7 +1956,7 @@ CREATE TABLE `sj_system_user_permission` (
`update_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_namespace_id_group_name_system_user_id`(`namespace_id` ASC, `group_name` ASC, `system_user_id` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统用户权限表' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统用户权限表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_system_user_permission
@@ -2075,7 +1991,7 @@ CREATE TABLE `sj_workflow` (
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE,
INDEX `idx_namespace_id_group_name`(`namespace_id` ASC, `group_name` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '工作流' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '工作流' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_workflow
@@ -2106,7 +2022,7 @@ CREATE TABLE `sj_workflow_node` (
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE,
INDEX `idx_namespace_id_group_name`(`namespace_id` ASC, `group_name` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '工作流节点' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '工作流节点' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_workflow_node
@@ -2135,7 +2051,7 @@ CREATE TABLE `sj_workflow_task_batch` (
INDEX `idx_job_id_task_batch_status`(`workflow_id` ASC, `task_batch_status` ASC) USING BTREE,
INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE,
INDEX `idx_namespace_id_group_name`(`namespace_id` ASC, `group_name` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '工作流批次' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '工作流批次' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sj_workflow_task_batch
@@ -2338,11 +2254,6 @@ INSERT INTO `sys_dict_data` VALUES (2018858143757504522, '154726', 0, 'PC', 'pc'
INSERT INTO `sys_dict_data` VALUES (2018858143761698817, '154726', 0, '安卓', 'android', 'sys_device_type', '', 'default', 'N', 103, 1, '2026-02-04 09:24:25', 1, '2026-02-04 09:24:25', '安卓');
INSERT INTO `sys_dict_data` VALUES (2018858143761698818, '154726', 0, 'iOS', 'ios', 'sys_device_type', '', 'default', 'N', 103, 1, '2026-02-04 09:24:25', 1, '2026-02-04 09:24:25', 'iOS');
INSERT INTO `sys_dict_data` VALUES (2018858143761698819, '154726', 0, '小程序', 'xcx', 'sys_device_type', '', 'default', 'N', 103, 1, '2026-02-04 09:24:25', 1, '2026-02-04 09:24:25', '小程序');
-INSERT INTO `sys_dict_data` VALUES (2026642472673288194, '000000', 0, '对话', 'chat', 'chat_model_category', NULL, 'cyan', 'N', 103, 1, '2026-02-25 20:56:33', 1, '2026-02-25 21:01:42', NULL);
-INSERT INTO `sys_dict_data` VALUES (2026642525081116674, '000000', 1, '图像', 'image', 'chat_model_category', NULL, 'success', 'N', 103, 1, '2026-02-25 20:56:46', 1, '2026-02-25 21:01:37', NULL);
-INSERT INTO `sys_dict_data` VALUES (2026643983713247233, '000000', 1, '次数计费', '1', 'sys_model_billing', NULL, 'green', 'N', 103, 1, '2026-02-25 21:02:34', 1, '2026-02-25 21:02:56', NULL);
-INSERT INTO `sys_dict_data` VALUES (2026644058522853378, '000000', 2, 'token计费', '2', 'sys_model_billing', NULL, 'primary', 'N', 103, 1, '2026-02-25 21:02:51', 1, '2026-02-25 21:02:51', NULL);
-INSERT INTO `sys_dict_data` VALUES (2027261114955931650, '000000', 2, '向量', 'vector', 'chat_model_category', NULL, 'default', 'N', 103, 1, '2026-02-27 13:54:49', 1, '2026-02-27 13:54:54', NULL);
-- ----------------------------
-- Table structure for sys_dict_type
@@ -2386,8 +2297,6 @@ INSERT INTO `sys_dict_type` VALUES (2018858143723950085, '154726', '操作类型
INSERT INTO `sys_dict_type` VALUES (2018858143723950086, '154726', '系统状态', 'sys_common_status', 103, 1, '2026-02-04 09:24:25', 1, '2026-02-04 09:24:25', '登录状态列表');
INSERT INTO `sys_dict_type` VALUES (2018858143723950087, '154726', '授权类型', 'sys_grant_type', 103, 1, '2026-02-04 09:24:25', 1, '2026-02-04 09:24:25', '认证授权类型');
INSERT INTO `sys_dict_type` VALUES (2018858143723950088, '154726', '设备类型', 'sys_device_type', 103, 1, '2026-02-04 09:24:25', 1, '2026-02-04 09:24:25', '客户端设备类型');
-INSERT INTO `sys_dict_type` VALUES (2026642112982360066, '000000', '模型分类', 'chat_model_category', 103, 1, '2026-02-25 20:55:08', 1, '2026-02-25 20:55:08', '模型分类');
-INSERT INTO `sys_dict_type` VALUES (2026642183606050817, '000000', '计费方式', 'sys_model_billing', 103, 1, '2026-02-25 20:55:24', 1, '2026-02-25 20:55:24', '计费方式');
-- ----------------------------
-- Table structure for sys_logininfor
@@ -2626,15 +2535,6 @@ INSERT INTO `sys_logininfor` VALUES (2019224998575153153, '000000', 'admin', 'pc
INSERT INTO `sys_logininfor` VALUES (2019225059417726977, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-05 09:42:24');
INSERT INTO `sys_logininfor` VALUES (2019240817392693249, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-05 10:45:01');
INSERT INTO `sys_logininfor` VALUES (2019447979716972545, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-06 00:28:13');
-INSERT INTO `sys_logininfor` VALUES (2026536636865163265, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-25 13:56:00');
-INSERT INTO `sys_logininfor` VALUES (2026556949535502337, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-25 15:16:43');
-INSERT INTO `sys_logininfor` VALUES (2026578433112911874, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-25 16:42:05');
-INSERT INTO `sys_logininfor` VALUES (2026638437400518657, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-25 20:40:31');
-INSERT INTO `sys_logininfor` VALUES (2026647463072952321, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-25 21:16:23');
-INSERT INTO `sys_logininfor` VALUES (2026653919016968194, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '退出成功', '2026-02-25 21:42:02');
-INSERT INTO `sys_logininfor` VALUES (2026654082020204546, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-25 21:42:41');
-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');
-- ----------------------------
-- Table structure for sys_menu
@@ -2670,7 +2570,7 @@ CREATE TABLE `sys_menu` (
INSERT INTO `sys_menu` VALUES (1, '系统管理', 0, 3, 'system', '', '', 1, 0, 'M', '0', '0', '', 'eos-icons:system-group', 103, 1, '2025-12-14 16:11:49', 1, '2026-01-01 19:06:19', '系统管理目录');
INSERT INTO `sys_menu` VALUES (2, '系统监控', 0, 3, 'monitor', '', '', 1, 0, 'M', '0', '0', '', 'solar:monitor-camera-outline', 103, 1, '2025-12-14 16:11:49', 1, '2025-12-14 17:56:44', '系统监控目录');
INSERT INTO `sys_menu` VALUES (3, '系统工具', 0, 4, 'tool', NULL, '', 1, 0, 'M', '0', '0', '', 'ant-design:tool-outlined', 103, 1, '2025-12-14 16:11:49', NULL, NULL, '系统工具目录');
-INSERT INTO `sys_menu` VALUES (6, '租户管理', 0, 8, 'tenant', '', '', 1, 0, 'M', '0', '0', '', 'ph:users-light', 103, 1, '2025-12-14 16:11:49', 1, '2026-02-25 20:42:14', '租户管理目录');
+INSERT INTO `sys_menu` VALUES (6, '租户管理', 0, 2, 'tenant', NULL, '', 1, 0, 'M', '0', '0', '', 'ph:users-light', 103, 1, '2025-12-14 16:11:49', NULL, NULL, '租户管理目录');
INSERT INTO `sys_menu` VALUES (100, '用户管理', 1, 1, 'user', 'system/user/index', '', 1, 0, 'C', '0', '0', 'system:user:list', 'ant-design:user-outlined', 103, 1, '2025-12-14 16:11:49', NULL, NULL, '用户管理菜单');
INSERT INTO `sys_menu` VALUES (101, '角色管理', 1, 2, 'role', 'system/role/index', '', 1, 0, 'C', '0', '0', 'system:role:list', 'eos-icons:role-binding-outlined', 103, 1, '2025-12-14 16:11:49', NULL, NULL, '角色管理菜单');
INSERT INTO `sys_menu` VALUES (102, '菜单管理', 1, 3, 'menu', 'system/menu/index', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'ic:sharp-menu', 103, 1, '2025-12-14 16:11:49', NULL, NULL, '菜单管理菜单');
@@ -2774,22 +2674,6 @@ INSERT INTO `sys_menu` VALUES (1620, '配置列表', 118, 5, '#', '', '', 1, 0,
INSERT INTO `sys_menu` VALUES (1621, '配置添加', 118, 6, '#', '', '', 1, 0, 'F', '0', '0', 'system:ossConfig:add', '#', 103, 1, '2025-12-14 16:11:49', NULL, NULL, '');
INSERT INTO `sys_menu` VALUES (1622, '配置编辑', 118, 6, '#', '', '', 1, 0, 'F', '0', '0', 'system:ossConfig:edit', '#', 103, 1, '2025-12-14 16:11:49', NULL, NULL, '');
INSERT INTO `sys_menu` VALUES (1623, '配置删除', 118, 6, '#', '', '', 1, 0, 'F', '0', '0', 'system:ossConfig:remove', '#', 103, 1, '2025-12-14 16:11:49', NULL, NULL, '');
-INSERT INTO `sys_menu` VALUES (2000, 'MCP管理', 0, 2, 'mcp', '', '', 1, 0, 'M', '0', '0', '', 'mdi:robot-industrial', 103, 1, '2026-02-24 20:02:47', 1, '2026-02-25 20:41:54', 'MCP模块管理菜单');
-INSERT INTO `sys_menu` VALUES (2001, 'MCP工具管理', 2000, 1, 'tool', 'mcp/tool/index', '', 1, 0, 'C', '0', '0', 'mcp:tool:list', 'octicon:tools-24', 103, 1, '2026-02-24 20:02:47', 1, '2026-02-25 20:41:27', 'MCP工具管理菜单');
-INSERT INTO `sys_menu` VALUES (2002, 'MCP工具查询', 2001, 1, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:tool:query', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, '');
-INSERT INTO `sys_menu` VALUES (2003, 'MCP工具新增', 2001, 2, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:tool:add', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, '');
-INSERT INTO `sys_menu` VALUES (2004, 'MCP工具修改', 2001, 3, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:tool:edit', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, '');
-INSERT INTO `sys_menu` VALUES (2005, 'MCP工具删除', 2001, 4, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:tool:remove', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, '');
-INSERT INTO `sys_menu` VALUES (2006, 'MCP工具测试', 2001, 5, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:tool:test', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, '');
-INSERT INTO `sys_menu` VALUES (2007, 'MCP工具导出', 2001, 6, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:tool:export', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, '');
-INSERT INTO `sys_menu` VALUES (2010, 'MCP市场管理', 2000, 2, 'market', 'mcp/market/index', '', 1, 0, 'C', '0', '0', 'mcp:market:list', 'mdi:storefront-outline', 103, 1, '2026-02-24 20:02:47', NULL, NULL, 'MCP市场管理菜单');
-INSERT INTO `sys_menu` VALUES (2011, 'MCP市场查询', 2010, 1, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:market:query', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, '');
-INSERT INTO `sys_menu` VALUES (2012, 'MCP市场新增', 2010, 2, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:market:add', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, '');
-INSERT INTO `sys_menu` VALUES (2013, 'MCP市场修改', 2010, 3, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:market:edit', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, '');
-INSERT INTO `sys_menu` VALUES (2014, 'MCP市场删除', 2010, 4, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:market:remove', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, '');
-INSERT INTO `sys_menu` VALUES (2015, 'MCP市场刷新', 2010, 5, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:market:refresh', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, '');
-INSERT INTO `sys_menu` VALUES (2016, 'MCP工具加载', 2010, 6, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:market:load', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, '');
-INSERT INTO `sys_menu` VALUES (2017, 'MCP市场导出', 2010, 7, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:market:export', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, '');
INSERT INTO `sys_menu` VALUES (11616, '工作流', 0, 6, 'workflow', '', '', 1, 0, 'M', '0', '0', '', 'mdi:workflow-outline', 103, 1, '2026-01-05 14:39:33', 1, '2026-01-05 14:56:07', '');
INSERT INTO `sys_menu` VALUES (11618, '我的任务', 0, 7, 'task', '', '', 1, 0, 'M', '0', '0', '', 'carbon:task-approved', 103, 1, '2026-01-05 14:39:33', NULL, NULL, '');
INSERT INTO `sys_menu` VALUES (11619, '我的待办', 11618, 2, 'taskWaiting', 'workflow/task/taskWaiting', '', 1, 1, 'C', '0', '0', '', 'ri:todo-line', 103, 1, '2026-01-05 14:39:33', NULL, NULL, '');
@@ -2814,6 +2698,13 @@ INSERT INTO `sys_menu` VALUES (11803, '流程达式定义新增', 11801, 2, '#',
INSERT INTO `sys_menu` VALUES (11804, '流程达式定义修改', 11801, 3, '#', '', NULL, 1, 0, 'F', '0', '0', 'workflow:spel:edit', '#', 103, 1, '2026-01-05 14:39:33', NULL, NULL, '');
INSERT INTO `sys_menu` VALUES (11805, '流程达式定义删除', 11801, 4, '#', '', NULL, 1, 0, 'F', '0', '0', 'workflow:spel:remove', '#', 103, 1, '2026-01-05 14:39:33', NULL, NULL, '');
INSERT INTO `sys_menu` VALUES (11806, '流程达式定义导出', 11801, 5, '#', '', NULL, 1, 0, 'F', '0', '0', 'workflow:spel:export', '#', 103, 1, '2026-01-05 14:39:33', NULL, NULL, '');
+INSERT INTO `sys_menu` VALUES (1971546066781597696, '数字人体验', 2019459914910994434, 10, 'aihumanPublish', 'aihuman/aihumanPublish/index', NULL, 1, 0, 'C', '0', '0', '', 'mdi:human-child', 103, 1, '2026-02-06 01:13:22', 1, '2026-02-06 01:29:34', '数字人信息管理菜单');
+INSERT INTO `sys_menu` VALUES (1971546066781597697, '数字人信息管理查询', 1971546066781597696, 1, '#', '', NULL, 1, 0, 'F', '0', '0', 'aihuman:aihumanInfo:query', '#', 103, 1, '2026-02-06 01:13:22', NULL, NULL, '');
+INSERT INTO `sys_menu` VALUES (1971546066781597698, '数字人信息管理新增', 1971546066781597696, 2, '#', '', NULL, 1, 0, 'F', '0', '0', 'aihuman:aihumanInfo:add', '#', 103, 1, '2026-02-06 01:13:22', NULL, NULL, '');
+INSERT INTO `sys_menu` VALUES (1971546066781597699, '数字人信息管理修改', 1971546066781597696, 3, '#', '', NULL, 1, 0, 'F', '0', '0', 'aihuman:aihumanInfo:edit', '#', 103, 1, '2026-02-06 01:13:22', NULL, NULL, '');
+INSERT INTO `sys_menu` VALUES (1971546066781597700, '数字人信息管理删除', 1971546066781597696, 4, '#', '', NULL, 1, 0, 'F', '0', '0', 'aihuman:aihumanInfo:remove', '#', 103, 1, '2026-02-06 01:13:22', NULL, NULL, '');
+INSERT INTO `sys_menu` VALUES (1971546066781597701, '数字人信息管理导出', 1971546066781597696, 5, '#', '', NULL, 1, 0, 'F', '0', '0', 'aihuman:aihumanInfo:export', '#', 103, 1, '2026-02-06 01:13:22', NULL, NULL, '');
+INSERT INTO `sys_menu` VALUES (1980480880138051584, '数字人配置', 2019459914910994434, 1, 'aihumanConfig', 'aihuman/aihumanConfig/index', NULL, 1, 0, 'C', '0', '0', 'aihuman:aihumanConfig:list', 'mdi:human-child', 103, 1, '2026-02-06 01:13:35', 1, '2026-02-06 01:28:12', '');
INSERT INTO `sys_menu` VALUES (2000209300188356609, '对话管理', 0, 0, 'chat', '', NULL, 1, 0, 'M', '0', '0', NULL, 'material-symbols:chat-outline', 103, 1, '2025-12-14 22:20:34', 1, '2025-12-14 22:21:24', '');
INSERT INTO `sys_menu` VALUES (2000210913451892738, '厂商管理', 2000209300188356609, 1, 'provider', 'chat/provider/index', NULL, 1, 0, 'C', '0', '0', 'system:provider:list', 'tabler:cube-spark', 103, 1, '2025-12-14 22:28:05', 1, '2025-12-14 23:42:55', '厂商管理菜单');
INSERT INTO `sys_menu` VALUES (2000210913451892739, '厂商管理查询', 2000210913451892738, 1, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:provider:query', '#', 103, 1, '2025-12-14 22:28:05', NULL, NULL, '');
@@ -2846,6 +2737,7 @@ INSERT INTO `sys_menu` VALUES (2006681261898813444, '知识库修改', 200668126
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 (2019459914910994434, '数字人管理', 0, 2, 'human', '', NULL, 1, 0, 'M', '0', '0', NULL, 'tdesign:user', 103, 1, '2026-02-06 01:15:38', 1, '2026-02-06 01:16:58', '');
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', '');
@@ -2934,12 +2826,6 @@ CREATE TABLE `sys_oss` (
-- ----------------------------
-- Records of sys_oss
-- ----------------------------
-INSERT INTO `sys_oss` VALUES (2026580908423340033, '000000', '2026/02/25/9219d6d71a6d45e19192014609d92dc9.png', 'logo.png', '.png', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/9219d6d71a6d45e19192014609d92dc9.png', '{\"fileSize\":\"183613\",\"contentType\":\"image/png\"}', 103, '2026-02-25 16:51:55', 1, '2026-02-25 16:51:55', 1, 'qcloud');
-INSERT INTO `sys_oss` VALUES (2026640059920883713, '000000', '2026/02/25/01091be272334383a1efd9bc22b73ee6.png', 'openai.png', '.png', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/01091be272334383a1efd9bc22b73ee6.png', '{\"fileSize\":\"11297\",\"contentType\":\"image/png\"}', 103, '2026-02-25 20:46:58', 1, '2026-02-25 20:46:58', 1, 'qcloud');
-INSERT INTO `sys_oss` VALUES (2026640515967557633, '000000', '2026/02/25/afecabebc8014d80b0f06b4796a74c5d.png', 'ollama.png', '.png', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/afecabebc8014d80b0f06b4796a74c5d.png', '{\"fileSize\":\"8746\",\"contentType\":\"image/png\"}', 103, '2026-02-25 20:48:47', 1, '2026-02-25 20:48:47', 1, 'qcloud');
-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');
-- ----------------------------
-- Table structure for sys_oss_config
@@ -2972,10 +2858,10 @@ CREATE TABLE `sys_oss_config` (
-- ----------------------------
-- Records of 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 (1, '000000', 'minio', 'ruoyi', 'ruoyi123', 'ruoyi', '', '127.0.0.1:9000', '', 'N', '', '1', '0', '', 103, 1, '2026-02-03 05:14:52', 1, '2026-02-03 05:14:52', 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', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi-1240000000', '', 'cos.ap-beijing.myqcloud.com', '', 'N', 'ap-beijing', '1', '1', '', 103, 1, '2026-02-03 05:14:52', 1, '2026-02-03 05:14:52', NULL);
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);
-- ----------------------------
@@ -3422,7 +3308,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-02-27 13:54:12', 103, 1, '2026-02-05 09:22:12', -1, '2026-02-27 13:54:12', '管理员', 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-02-06 00:28:13', 103, 1, '2026-02-05 09:22:12', -1, '2026-02-06 00:28:13', '管理员', 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);
@@ -3501,7 +3387,7 @@ CREATE TABLE `t_workflow_component` (
`tenant_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '000000' COMMENT '租户编号',
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_display_order`(`display_order` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 37 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '工作流组件库 | Workflow Component' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB AUTO_INCREMENT = 20 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '工作流组件库 | Workflow Component' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of t_workflow_component
@@ -3509,9 +3395,6 @@ CREATE TABLE `t_workflow_component` (
INSERT INTO `t_workflow_component` VALUES (17, '5cd68dccbbb411f0bb7840c2ba9a7fbc', 'Start', '开始', '流程由此开始', 0, 1, '2025-11-07 16:32:49', '2025-11-07 16:32:49', 0, '000000');
INSERT INTO `t_workflow_component` VALUES (18, '5cd6ac69bbb411f0bb7840c2ba9a7fbc', 'End', '结束', '流程由此结束', 0, 1, '2025-11-07 16:32:49', '2025-11-07 16:32:49', 0, '000000');
INSERT INTO `t_workflow_component` VALUES (19, '5cd6c8eabbb411f0bb7840c2ba9a7fbc', 'Answer', '生成回答', '调用大语言模型回答问题', 0, 1, '2025-11-07 16:32:49', '2025-11-07 16:32:49', 0, '000000');
-INSERT INTO `t_workflow_component` VALUES (25, '0b4369bb60dc46d6bd84ceb4e36184dc', 'KeywordExtractor', '关键词提取', '从文本中提取关键词', 0, 1, '2025-12-26 16:30:05', '2025-12-26 16:30:05', 0, '000000');
-INSERT INTO `t_workflow_component` VALUES (26, 'bb00fc2f52c74fec82ee3f99725b56bb', 'Switcher', '条件分支', '根据条件执行不同分支', 0, 1, '2025-12-26 16:30:46', '2025-12-26 16:30:46', 0, '000000');
-INSERT INTO `t_workflow_component` VALUES (36, 'f37dbcb8f0d5464d90fbb22774490a56', 'HumanFeedback', '人类', '人机沟通', 0, 1, '2025-12-30 17:37:14', '2025-12-30 17:37:14', 0, '000000');
-- ----------------------------
-- Table structure for t_workflow_edge
@@ -3731,25 +3614,161 @@ INSERT INTO `test_tree` VALUES (13, '000000', 10, 108, 3, '子节点99', 0, 103,
SET FOREIGN_KEY_CHECKS = 1;
-INSERT INTO `t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (17, '5cd68dccbbb411f0bb7840c2ba9a7fbc', 'Start', '开始', '流程由此开始', 0, 1, '2025-11-07 16:32:49', '2025-11-07 16:32:49', 0, '000000');
-INSERT INTO `t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (18, '5cd6ac69bbb411f0bb7840c2ba9a7fbc', 'End', '结束', '流程由此结束', 0, 1, '2025-11-07 16:32:49', '2025-11-07 16:32:49', 0, '000000');
-INSERT INTO `t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (19, '5cd6c8eabbb411f0bb7840c2ba9a7fbc', 'Answer', '生成回答', '调用大语言模型回答问题', 0, 1, '2025-11-07 16:32:49', '2025-11-07 16:32:49', 0, '000000');
-INSERT INTO `t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (20, '0b4369bb60dc46d6bd84ceb4e36184dc', 'KeywordExtractor', '关键词提取', '从文本中提取关键词', 0, 1, '2025-12-26 16:30:05', '2025-12-26 16:30:05', 0, '000000');
-INSERT INTO `t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (21, 'bb00fc2f52c74fec82ee3f99725b56bb', 'Switcher', '条件分支', '根据条件执行不同分支', 0, 1, '2025-12-26 16:30:46', '2025-12-26 16:30:46', 0, '000000');
-INSERT INTO `t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (22, 'f37dbcb8f0d5464d90fbb22774490a56', 'HumanFeedback', '人类', '人机沟通', 0, 1, '2025-12-30 17:37:14', '2025-12-30 17:37:14', 0, '000000');
-INSERT INTO `t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (23, 'af9d6d7b9c9b47f990ad25ec84912b73', 'Tongyiwanx', '阿里图像生成', '使用通义万相生成图像', 0, 1, '2025-12-26 16:32:25', '2025-12-26 16:32:25', 0, '000000');
-INSERT INTO `t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (24, 'a1e2c9d4b8f04e1a9c3d6f8e2a7b1c9d', 'MailSend', '发送邮箱', '发送邮箱', 0, 1, '2025-12-30 17:37:14', '2025-12-30 17:37:14', 0, '000000');
-INSERT INTO `t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (25, 'f1e2d3c4b5a67890f1e2d3c4b5a6f1e2', 'HttpRequest', '请求节点', '请求节点', 0, 1, '2025-12-30 17:37:14', '2025-12-30 17:37:14', 0, '000000');
-INSERT INTO `chat_model` (`id`, `category`, `model_name`, `provider_code`, `model_describe`, `model_price`, `model_type`, `model_show`, `model_free`, `priority`, `api_host`, `api_key`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`, `tenant_id`) VALUES (2022565766560468994, 'image', 'wan2.5-t2i-preview', 'Tongyiwanx', 'wan2.5-t2i-preview', 1, '1', 'Y', 'Y', 1, 'https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation', 'skxxxx', 103, 1, '2026-02-14 14:57:11', 1, '2026-02-14 14:57:11', '通义万相文生图', 0);
-INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query_param`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2021046920636690433, '流程管理', 0, 0, 'flow', '', NULL, 1, 0, 'M', '0', '0', NULL, 'ph:user-fill', 103, 1, '2026-02-10 10:21:50', 1, '2026-02-10 15:59:28', '');
-INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query_param`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2021047050391678978, '工作流编排', 2021046920636690433, 0, 'aiflowengine', 'aiflow/index', NULL, 1, 0, 'C', '0', '0', '', 'ph:user-fill', 103, 1, '2026-02-10 10:22:21', 1, '2026-02-10 16:04:41', '');
-INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2027192921483309058, '000000', 'HTTP请求节点响应模板', 'node.httpRequest.template', '✅ HTTP请求节点:结束响应 - ', 'Y', 103, 1, '2026-02-27 09:23:51', 1, '2026-02-27 09:31:41', NULL);
-INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2027193296990957569, '000000', '文生图节点响应模板', 'node.image.template', '🎨 文生图节点:结束响应 - 图片URL: ', 'Y', 103, 1, '2026-02-27 09:25:20', 1, '2026-02-27 09:31:52', NULL);
-INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2027193820393959425, '000000', '发送邮箱节点响应模板', 'node.mailsend.template', '📧 发送邮箱节点:结束响应 - ', 'Y', 103, 1, '2026-02-27 09:27:25', 1, '2026-02-27 09:32:05', NULL);
-INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2027194134438277122, '000000', '结束节点响应模板', 'node.end.template', '🔚 流程已执行完毕,如果您有其他需求,请随时重新发起请求。', 'Y', 103, 1, '2026-02-27 09:28:40', 1, '2026-02-27 09:32:53', NULL);
-INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2027206492573335554, '000000', '人机交互节点响应模板', 'node.humanFeedback.template', '👤 人机交互节点:等待用户操作 - ', 'Y', 103, 1, '2026-02-27 10:17:46', 1, '2026-02-27 10:17:46', NULL);
-INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2027208880369647617, '000000', '条件分支节点响应模板', 'node.switch.template', '🔀 条件分支节点:触发 -> 跳转到节点 ', 'Y', 103, 1, '2026-02-27 10:27:15', 1, '2026-02-27 10:35:54', NULL);
-INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2027213914603995137, '000000', '大模型回答节点响应模板', 'node.llmAnswer.template', '🤖 LLM 节点 生成回答:', 'Y', 103, 1, '2026-02-27 10:47:16', 1, '2026-02-27 10:52:40', NULL);
-INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2027214387000066050, '000000', '关键词提取响应模板', 'node.keywordExtractor.template', '🔑 关键词提取节点 处理完成 : ', 'Y', 103, 1, '2026-02-27 10:49:08', 1, '2026-02-27 10:52:08', NULL);
-INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2027217577397391361, '000000', '工作流异常响应模板', 'node.exception.template', '🛑 工作流发生异常:', 'N', 103, 1, '2026-02-27 11:01:49', 1, '2026-02-27 11:02:01', NULL);
+
+-- MCP 模块数据库表结构
+-- 版本: V3.0.0
+-- 描述: MCP 工具管理和 MCP 市场管理表
+
+-- ----------------------------
+-- MCP 工具表
+-- ----------------------------
+DROP TABLE IF EXISTS `mcp_tool_info`;
+CREATE TABLE `mcp_tool_info`
+(
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT '工具ID',
+ `name` varchar(200) NOT NULL COMMENT '工具名称',
+ `description` text COMMENT '工具描述',
+ `type` varchar(20) DEFAULT 'LOCAL' COMMENT '工具类型:LOCAL-本地, REMOTE-远程, BUILTIN-内置',
+ `status` varchar(20) DEFAULT 'ENABLED' COMMENT '状态:ENABLED-启用, DISABLED-禁用',
+ `config_json` text COMMENT '配置信息(JSON格式)',
+ `tenant_id` varchar(20) DEFAULT '000000' COMMENT '租户编号',
+ `create_dept` bigint DEFAULT NULL COMMENT '创建部门',
+ `create_by` bigint DEFAULT NULL COMMENT '创建者',
+ `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+ `update_by` bigint DEFAULT NULL COMMENT '更新者',
+ `update_time` datetime DEFAULT NULL COMMENT '更新时间',
+ `del_flag` char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
+ PRIMARY KEY (`id`),
+ KEY `idx_name` (`name`),
+ KEY `idx_type` (`type`),
+ KEY `idx_status` (`status`),
+ KEY `idx_tenant_id` (`tenant_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='MCP工具表';
+
+-- ----------------------------
+-- MCP 市场表
+-- ----------------------------
+DROP TABLE IF EXISTS `mcp_market_info`;
+CREATE TABLE `mcp_market_info`
+(
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT '市场ID',
+ `name` varchar(200) NOT NULL COMMENT '市场名称',
+ `url` varchar(500) NOT NULL COMMENT '市场URL',
+ `description` text COMMENT '市场描述',
+ `auth_config` text COMMENT '认证配置(JSON格式)',
+ `status` varchar(20) DEFAULT 'ENABLED' COMMENT '状态:ENABLED-启用, DISABLED-禁用',
+ `tenant_id` varchar(20) DEFAULT '000000' COMMENT '租户编号',
+ `create_dept` bigint DEFAULT NULL COMMENT '创建部门',
+ `create_by` bigint DEFAULT NULL COMMENT '创建者',
+ `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+ `update_by` bigint DEFAULT NULL COMMENT '更新者',
+ `update_time` datetime DEFAULT NULL COMMENT '更新时间',
+ `del_flag` char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
+ PRIMARY KEY (`id`),
+ KEY `idx_name` (`name`),
+ KEY `idx_status` (`status`),
+ KEY `idx_tenant_id` (`tenant_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='MCP市场表';
+
+-- ----------------------------
+-- MCP 市场工具关联表
+-- ----------------------------
+DROP TABLE IF EXISTS `mcp_market_tool`;
+CREATE TABLE `mcp_market_tool`
+(
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
+ `market_id` bigint NOT NULL COMMENT '市场ID',
+ `tool_name` varchar(200) NOT NULL COMMENT '工具名称',
+ `tool_description` text COMMENT '工具描述',
+ `tool_version` varchar(50) COMMENT '工具版本',
+ `tool_metadata` json COMMENT '工具元数据(JSON格式)',
+ `is_loaded` tinyint(1) DEFAULT 0 COMMENT '是否已加载到本地',
+ `local_tool_id` bigint COMMENT '关联的本地工具ID',
+ `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+ PRIMARY KEY (`id`),
+ KEY `idx_market_id` (`market_id`),
+ KEY `idx_tool_name` (`tool_name`),
+ KEY `idx_is_loaded` (`is_loaded`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='MCP市场工具关联表';
+
+
+
+-- MCP 模块菜单权限 SQL
+-- 版本: V3.0.1
+-- 描述: MCP 工具管理和 MCP 市场管理菜单权限
+-- 菜单 ID 规划: 2000-2199
+
+-- ----------------------------
+-- MCP 主菜单
+-- ----------------------------
+INSERT INTO sys_menu
+VALUES (2000, 'MCP管理', 0, 5, 'mcp', '', '', 1, 0, 'M', '0', '0', '',
+ 'mdi:robot-industrial', 103, 1, NOW(), NULL, NULL, 'MCP模块管理菜单');
+
+-- ----------------------------
+-- MCP 工具管理
+-- ----------------------------
+INSERT INTO sys_menu
+VALUES (2001, 'MCP工具管理', 2000, 1, 'tool', 'mcp/tool/index', '', 1, 0, 'C', '0',
+ '0', 'mcp:tool:list', 'material-symbols:tools-hammer-outline', 103, 1, NOW(), NULL,
+ NULL, 'MCP工具管理菜单');
+
+-- MCP 工具管理按钮权限
+INSERT INTO sys_menu
+VALUES (2002, 'MCP工具查询', 2001, 1, '#', '', '', 1, 0, 'F', '0', '0',
+ 'mcp:tool:query', '#', 103, 1, NOW(), NULL, NULL, '');
+INSERT INTO sys_menu
+VALUES (2003, 'MCP工具新增', 2001, 2, '#', '', '', 1, 0, 'F', '0', '0',
+ 'mcp:tool:add', '#', 103, 1, NOW(), NULL, NULL, '');
+INSERT INTO sys_menu
+VALUES (2004, 'MCP工具修改', 2001, 3, '#', '', '', 1, 0, 'F', '0', '0',
+ 'mcp:tool:edit', '#', 103, 1, NOW(), NULL, NULL, '');
+INSERT INTO sys_menu
+VALUES (2005, 'MCP工具删除', 2001, 4, '#', '', '', 1, 0, 'F', '0', '0',
+ 'mcp:tool:remove', '#', 103, 1, NOW(), NULL, NULL, '');
+INSERT INTO sys_menu
+VALUES (2006, 'MCP工具测试', 2001, 5, '#', '', '', 1, 0, 'F', '0', '0',
+ 'mcp:tool:test', '#', 103, 1, NOW(), NULL, NULL, '');
+INSERT INTO sys_menu
+VALUES (2007, 'MCP工具导出', 2001, 6, '#', '', '', 1, 0, 'F', '0', '0',
+ 'mcp:tool:export', '#', 103, 1, NOW(), NULL, NULL, '');
+
+-- ----------------------------
+-- MCP 市场管理
+-- ----------------------------
+INSERT INTO sys_menu
+VALUES (2010, 'MCP市场管理', 2000, 2, 'market', 'mcp/market/index', '', 1, 0, 'C', '0',
+ '0', 'mcp:market:list', 'mdi:storefront-outline', 103, 1, NOW(), NULL, NULL,
+ 'MCP市场管理菜单');
+
+-- MCP 市场管理按钮权限
+INSERT INTO sys_menu
+VALUES (2011, 'MCP市场查询', 2010, 1, '#', '', '', 1, 0, 'F', '0', '0',
+ 'mcp:market:query', '#', 103, 1, NOW(), NULL, NULL, '');
+INSERT INTO sys_menu
+VALUES (2012, 'MCP市场新增', 2010, 2, '#', '', '', 1, 0, 'F', '0', '0',
+ 'mcp:market:add', '#', 103, 1, NOW(), NULL, NULL, '');
+INSERT INTO sys_menu
+VALUES (2013, 'MCP市场修改', 2010, 3, '#', '', '', 1, 0, 'F', '0', '0',
+ 'mcp:market:edit', '#', 103, 1, NOW(), NULL, NULL, '');
+INSERT INTO sys_menu
+VALUES (2014, 'MCP市场删除', 2010, 4, '#', '', '', 1, 0, 'F', '0', '0',
+ 'mcp:market:remove', '#', 103, 1, NOW(), NULL, NULL, '');
+INSERT INTO sys_menu
+VALUES (2015, 'MCP市场刷新', 2010, 5, '#', '', '', 1, 0, 'F', '0', '0',
+ 'mcp:market:refresh', '#', 103, 1, NOW(), NULL, NULL, '');
+INSERT INTO sys_menu
+VALUES (2016, 'MCP工具加载', 2010, 6, '#', '', '', 1, 0, 'F', '0', '0',
+ 'mcp:market:load', '#', 103, 1, NOW(), NULL, NULL, '');
+INSERT INTO sys_menu
+VALUES (2017, 'MCP市场导出', 2010, 7, '#', '', '', 1, 0, 'F', '0', '0',
+ 'mcp:market:export', '#', 103, 1, NOW(), NULL, NULL, '');
+
+-- ----------------------------
+-- MCP 配置管理 (可选,预留扩展)
+-- ----------------------------
+-- INSERT INTO sys_menu VALUES (2020, 'MCP配置管理', 2000, 3, 'config', 'mcp/config/index', '', 1, 0, 'C', '0',
+-- '0', 'mcp:config:list', 'ant-design:setting-outlined', 103, 1, NOW(), NULL, NULL,
+-- 'MCP配置管理菜单');
+
diff --git a/pom.xml b/pom.xml
index 372c2770..8771fb18 100644
--- a/pom.xml
+++ b/pom.xml
@@ -50,16 +50,17 @@
1.8.2
-
4.4.0
+
4.6.0
-
2.20.1
+
2.18.2
1.11.0
1.11.0-beta19
-
1.1.0-beta7
1.5.3
1.19.6
1.0.7
+
+
1.27.1
1.1.0
@@ -410,6 +411,13 @@
${jackson-dataformat-xml.version}
+
+
+ org.apache.commons
+ commons-compress
+ ${commons-compress.version}
+
+
diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml
index 4675462c..49750f04 100644
--- a/ruoyi-admin/pom.xml
+++ b/ruoyi-admin/pom.xml
@@ -110,6 +110,7 @@
ruoyi-aiflow
+
de.codecentric
spring-boot-admin-starter-client
diff --git a/ruoyi-admin/src/main/java/org/ruoyi/config/MapperConflictResolver.java b/ruoyi-admin/src/main/java/org/ruoyi/config/MapperConflictResolver.java
new file mode 100644
index 00000000..467c96db
--- /dev/null
+++ b/ruoyi-admin/src/main/java/org/ruoyi/config/MapperConflictResolver.java
@@ -0,0 +1,48 @@
+package org.ruoyi.config;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * BeanDefinitionRegistry后置处理器
+ * 解决 MapStruct Plus 生成的 mapper 冲突问题
+ *
+ * @author ruoyi team
+ */
+@Configuration
+public class MapperConflictResolver implements BeanDefinitionRegistryPostProcessor {
+
+ private static final Logger log = LoggerFactory.getLogger(MapperConflictResolver.class);
+
+ @Override
+ public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
+ String[] beanNames = registry.getBeanDefinitionNames();
+
+ // 查找冲突的 mapper bean
+ for (String beanName : beanNames) {
+ if (beanName.equals("chatMessageBoToChatMessageMapperImpl")) {
+ BeanDefinition beanDefinition = registry.getBeanDefinition(beanName);
+ String beanClassName = beanDefinition.getBeanClassName();
+
+ log.info("Found mapper bean: {} -> {}", beanName, beanClassName);
+
+ // 如果是 org.ruoyi.domain.bo.chat 包下的(冲突的),移除它
+ if (beanClassName != null && beanClassName.startsWith("org.ruoyi.domain.bo.chat")) {
+ log.warn("Removing conflicting bean definition: {} ({})", beanName, beanClassName);
+ registry.removeBeanDefinition(beanName);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+ // 不需要实现
+ }
+}
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index 2a17ad30..5743c299 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -125,7 +125,9 @@ security:
- /*/api-docs/**
- /warm-flow-ui/config
- /workflow/run
-
+ - /user/qrcode
+ - /user/login/qrcode
+ - /weixin/check
# 多租户配置
tenant:
# 是否开启
@@ -216,6 +218,8 @@ springdoc:
packages-to-scan: org.ruoyi.generator
- group: 5.工作流模块
packages-to-scan: org.ruoyi.workflow
+ - group: 6.MCP模块
+ packages-to-scan: org.ruoyi.mcp
# 防止XSS攻击
xss:
@@ -307,6 +311,7 @@ wechat:
secret: ''
token: ''
aesKey: ''
+
--- # Neo4j 知识图谱配置
neo4j:
uri: bolt://117.72.192.162:7687
@@ -357,3 +362,14 @@ knowledge:
cache-enabled: true
# 缓存过期时间(分钟)
cache-expire-minutes: 60
+
+--- # MCP 模块配置
+app:
+ mcp:
+ client:
+ # 请求超时时间(秒)
+ request-timeout: 30
+ # 连接超时时间(秒)
+ connection-timeout: 10
+ # 最大重试次数
+ max-retries: 3
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/service/ConfigService.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/service/ConfigService.java
index 7a5cf5b5..c2ebc98b 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/service/ConfigService.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/service/ConfigService.java
@@ -15,4 +15,13 @@ public interface ConfigService {
*/
String getConfigValue(String configKey);
+ /**
+ * 根据配置类型和配置key获取值
+ *
+ * @param category 配置类型
+ * @param configKey 配置key
+ * @return 配置属性
+ */
+ String getConfigValue(String category, String configKey);
+
}
diff --git a/ruoyi-common/ruoyi-common-excel/pom.xml b/ruoyi-common/ruoyi-common-excel/pom.xml
index 51a34a08..e48189f9 100644
--- a/ruoyi-common/ruoyi-common-excel/pom.xml
+++ b/ruoyi-common/ruoyi-common-excel/pom.xml
@@ -25,6 +25,12 @@
cn.idev.excel
fastexcel
+
+
+
+ org.apache.commons
+ commons-compress
+
diff --git a/ruoyi-common/ruoyi-common-sse/src/main/java/org/ruoyi/common/sse/utils/SseMessageUtils.java b/ruoyi-common/ruoyi-common-sse/src/main/java/org/ruoyi/common/sse/utils/SseMessageUtils.java
index ec4e95ca..b4c224d5 100644
--- a/ruoyi-common/ruoyi-common-sse/src/main/java/org/ruoyi/common/sse/utils/SseMessageUtils.java
+++ b/ruoyi-common/ruoyi-common-sse/src/main/java/org/ruoyi/common/sse/utils/SseMessageUtils.java
@@ -6,9 +6,6 @@ import lombok.extern.slf4j.Slf4j;
import org.ruoyi.common.core.utils.SpringUtils;
import org.ruoyi.common.sse.core.SseEmitterManager;
import org.ruoyi.common.sse.dto.SseMessageDto;
-import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
-
-import java.io.IOException;
/**
* SSE工具类
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/handler/GlobalExceptionHandler.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/handler/GlobalExceptionHandler.java
index 03a682db..3d81e0d0 100644
--- a/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/handler/GlobalExceptionHandler.java
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/handler/GlobalExceptionHandler.java
@@ -121,16 +121,23 @@ public class GlobalExceptionHandler {
/**
* 拦截未知的运行时异常
+ * 注意:对于文件下载/导出等场景,IOException 可能是正常流程的一部分,
+ * 需要排除 export/download 等路径,避免干扰文件导出
*/
- @ResponseStatus(org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(IOException.class)
- public void handleIoException(IOException e, HttpServletRequest request) {
+ public R
handleIoException(IOException e, HttpServletRequest request) {
String requestURI = request.getRequestURI();
if (requestURI.contains("sse")) {
// sse 经常性连接中断 例如关闭浏览器 直接屏蔽
- return;
+ return null;
+ }
+ // 排除文件下载/导出相关的 IOException,让异常正常传播以便上层处理
+ if (requestURI.contains("/export") || requestURI.contains("/download")) {
+ // 重新抛出,让调用方处理
+ throw new RuntimeException("文件导出/下载IO异常: " + e.getMessage(), e);
}
log.error("请求地址'{}',连接中断", requestURI, e);
+ return R.fail(e.getMessage());
}
/**
@@ -146,6 +153,13 @@ public class GlobalExceptionHandler {
@ExceptionHandler(RuntimeException.class)
public R handleRuntimeException(RuntimeException e, HttpServletRequest request) {
String requestURI = request.getRequestURI();
+ // 对于文件导出相关异常,不进行封装处理,让原始异常信息传播
+ Throwable cause = e.getCause();
+ if (requestURI.contains("/export") || requestURI.contains("/download")) {
+ log.error("请求地址'{}',文件导出/下载异常.", requestURI, e);
+ // 对于文件导出,直接返回异常信息,不进行额外封装
+ return R.fail(cause != null ? cause.getMessage() : e.getMessage());
+ }
log.error("请求地址'{}',发生未知异常.", requestURI, e);
return R.fail(e.getMessage());
}
diff --git a/ruoyi-modules/ruoyi-chat/docs/frontend-guide.md b/ruoyi-modules/ruoyi-chat/docs/frontend-guide.md
new file mode 100644
index 00000000..05cb5b9f
--- /dev/null
+++ b/ruoyi-modules/ruoyi-chat/docs/frontend-guide.md
@@ -0,0 +1,244 @@
+# MCP工具管理前端开发指南
+
+## 前置条件
+
+- Node.js >= 16.0
+- Vue 3
+- Element Plus
+- ECharts (用于图表展示)
+- Axios (用于HTTP请求)
+
+## 安装依赖
+
+```bash
+npm install element-plus echarts axios
+```
+
+## 项目结构
+
+```
+ruoyi-ui/
+├── src/
+│ ├── api/
+│ │ └── mcp/
+│ │ └── tool.js # API接口
+│ ├── views/
+│ │ └── mcp/
+│ │ ├── tool/
+│ │ │ └── index.vue # 工具管理页面
+│ │ ├── market/
+│ │ │ └── index.vue # 市场管理页面
+│ │ └── log/
+│ │ └── index.vue # 调用日志页面
+│ └── utils/
+│ └── request.js # Axios封装
+```
+
+## 菜单配置
+
+在系统菜单管理中添加以下菜单:
+
+### 1. MCP工具管理
+
+| 字段 | 值 |
+|------|-----|
+| 菜单名称 | MCP工具管理 |
+| 菜单类型 | 目录 |
+| 显示顺序 | 1 |
+| 路由地址 | mcp |
+| 组件路径 | |
+
+#### 子菜单:工具列表
+
+| 字段 | 值 |
+|------|-----|
+| 菜单名称 | 工具列表 |
+| 菜单类型 | 菜单 |
+| 显示顺序 | 1 |
+| 路由地址 | tool |
+| 组件路径 | mcp/tool/index |
+| 权限标识 | mcp:tool:list |
+
+#### 子菜单:市场管理
+
+| 字段 | 值 |
+|------|-----|
+| 菜单名称 | 市场管理 |
+| 菜单类型 | 菜单 |
+| 显示顺序 | 2 |
+| 路由地址 | market |
+| 组件路径 | mcp/market/index |
+| 权限标识 | mcp:market:list |
+
+#### 子菜单:调用日志
+
+| 字段 | 值 |
+|------|-----|
+| 菜单名称 | 调用日志 |
+| 菜单类型 | 菜单 |
+| 显示顺序 | 3 |
+| 路由地址 | log |
+| 组件路径 | mcp/log/index |
+| 权限标识 | mcp:tool:query |
+
+## 权限配置
+
+| 权限标识 | 权限名称 | 说明 |
+|----------|----------|------|
+| mcp:tool:list | 工具列表 | 查看工具列表 |
+| mcp:tool:query | 工具查询 | 查看工具详情 |
+| mcp:tool:add | 工具新增 | 新增工具 |
+| mcp:tool:edit | 工具修改 | 修改工具 |
+| mcp:tool:remove | 工具删除 | 删除工具 |
+| mcp:tool:export | 工具导出 | 导出工具数据 |
+| mcp:market:list | 市场列表 | 查看市场列表 |
+| mcp:market:query | 市场查询 | 查看市场详情 |
+| mcp:market:add | 市场新增 | 新增市场 |
+| mcp:market:edit | 市场修改 | 修改市场 |
+| mcp:market:remove | 市场删除 | 删除市场 |
+
+## 路由配置
+
+在路由配置文件中添加:
+
+```javascript
+{
+ path: '/mcp',
+ component: Layout,
+ redirect: '/mcp/tool',
+ name: 'Mcp',
+ meta: { title: 'MCP工具管理', icon: 'tools' },
+ children: [
+ {
+ path: 'tool',
+ name: 'McpTool',
+ component: () => import('@/views/mcp/tool/index'),
+ meta: { title: '工具列表', icon: 'tool' }
+ },
+ {
+ path: 'market',
+ name: 'McpMarket',
+ component: () => import('@/views/mcp/market/index'),
+ meta: { title: '市场管理', icon: 'shop' }
+ },
+ {
+ path: 'log',
+ name: 'McpLog',
+ component: () => import('@/views/mcp/log/index'),
+ meta: { title: '调用日志', icon: 'document' }
+ }
+ ]
+}
+```
+
+## API请求配置
+
+确保Axios请求拦截器正确配置:
+
+```javascript
+// src/utils/request.js
+import axios from 'axios'
+import { ElMessage } from 'element-plus'
+
+const service = axios.create({
+ baseURL: process.env.VUE_APP_BASE_API,
+ timeout: 30000
+})
+
+// 请求拦截器
+service.interceptors.request.use(
+ config => {
+ // 添加token
+ const token = localStorage.getItem('Admin-Token')
+ if (token) {
+ config.headers['Authorization'] = 'Bearer ' + token
+ }
+ return config
+ },
+ error => {
+ return Promise.reject(error)
+ }
+)
+
+// 响应拦截器
+service.interceptors.response.use(
+ response => {
+ const res = response.data
+ if (res.code !== 200) {
+ ElMessage.error(res.msg || '请求失败')
+ return Promise.reject(new Error(res.msg || '请求失败'))
+ }
+ return res
+ },
+ error => {
+ ElMessage.error(error.message)
+ return Promise.reject(error)
+ }
+)
+
+export default service
+```
+
+## 开发步骤
+
+1. **复制代码文件**
+ - 将 `tool.js` 复制到 `src/api/mcp/` 目录
+ - 将 `*.vue` 文件复制到对应的视图目录
+
+2. **安装依赖**
+ ```bash
+ npm install element-plus echarts
+ ```
+
+3. **配置路由**
+ - 在路由配置中添加MCP相关路由
+
+4. **配置菜单**
+ - 在系统管理中添加菜单
+
+5. **配置权限**
+ - 在系统管理中添加权限标识
+
+6. **测试功能**
+ - 启动开发服务器
+ - 测试各项功能
+
+## 注意事项
+
+1. **工具类型说明**
+ - BUILTIN: 内置工具(系统自带,不可编辑)
+ - LOCAL: 本地STDIO工具(通过命令行启动)
+ - REMOTE: 远程HTTP工具(通过网络连接)
+
+2. **配置JSON格式**
+ - LOCAL类型: `{"command": "npx", "args": ["-y", "@example/tool"], "env": {}}`
+ - REMOTE类型: `{"baseUrl": "http://localhost:8080/mcp"}`
+
+3. **错误处理**
+ - 工具连接测试可能超时,请合理设置超时时间
+ - 删除工具前请确认没有正在运行的Agent使用该工具
+
+4. **性能优化**
+ - 调用日志数据量大时,建议使用分页加载
+ - 图表数据建议缓存处理,避免频繁请求
+
+## 常见问题
+
+### 1. 跨域问题
+在 `vue.config.js` 中配置代理:
+```javascript
+devServer: {
+ proxy: {
+ '/api': {
+ target: 'http://localhost:8080',
+ changeOrigin: true
+ }
+ }
+}
+```
+
+### 2. 图表不显示
+确保ECharts容器有固定高度,并在数据加载后初始化图表。
+
+### 3. 权限不生效
+检查菜单权限配置和后端接口权限注解是否一致。
diff --git a/ruoyi-modules/ruoyi-chat/docs/mcp-api-spec.md b/ruoyi-modules/ruoyi-chat/docs/mcp-api-spec.md
new file mode 100644
index 00000000..9d8460b7
--- /dev/null
+++ b/ruoyi-modules/ruoyi-chat/docs/mcp-api-spec.md
@@ -0,0 +1,336 @@
+# MCP工具管理模块 - API接口文档
+
+## 概述
+
+本文档描述了MCP工具管理模块的REST API接口,供前端开发人员参考。
+
+## 基础信息
+
+- **Base URL**: `/api/mcp`
+- **认证方式**: Bearer Token (SaToken)
+- **响应格式**: JSON
+
+---
+
+## 1. MCP工具管理
+
+### 1.1 查询工具列表(分页)
+
+**接口**: `GET /tool/list`
+
+**权限**: `mcp:tool:list`
+
+**请求参数**:
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| name | String | 否 | 工具名称(模糊查询) |
+| description | String | 否 | 工具描述(模糊查询) |
+| type | String | 否 | 工具类型:LOCAL/REMOTE/BUILTIN |
+| status | String | 否 | 状态:0-启用, 1-禁用 |
+| pageNum | Integer | 是 | 页码,默认1 |
+| pageSize | Integer | 是 | 每页数量,默认10 |
+
+**响应示例**:
+```json
+{
+ "rows": [
+ {
+ "id": 1,
+ "name": "ReadFileTool",
+ "description": "读取文件内容工具",
+ "type": "BUILTIN",
+ "status": "0",
+ "configJson": null,
+ "createTime": "2026-03-08 10:00:00",
+ "updateTime": "2026-03-08 10:00:00"
+ }
+ ],
+ "total": 1
+}
+```
+
+### 1.2 查询工具列表(不分页)
+
+**接口**: `GET /tool/all`
+
+**权限**: `mcp:tool:list`
+
+**请求参数**:
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| keyword | String | 否 | 关键词 |
+| type | String | 否 | 工具类型 |
+| status | String | 否 | 状态 |
+
+**响应示例**:
+```json
+{
+ "tools": [
+ {
+ "id": 1,
+ "name": "ReadFileTool",
+ "description": "读取文件内容工具",
+ "type": "BUILTIN",
+ "status": "0"
+ }
+ ],
+ "total": 1
+}
+```
+
+### 1.3 获取工具详情
+
+**接口**: `GET /tool/{id}`
+
+**权限**: `mcp:tool:query`
+
+**路径参数**:
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| id | Long | 是 | 工具ID |
+
+### 1.4 新增工具
+
+**接口**: `POST /tool`
+
+**权限**: `mcp:tool:add`
+
+**请求体**:
+```json
+{
+ "name": "MyMcpTool",
+ "description": "我的MCP工具",
+ "type": "REMOTE",
+ "status": "0",
+ "configJson": "{\"baseUrl\": \"http://localhost:8080/mcp\"}"
+}
+```
+
+### 1.5 修改工具
+
+**接口**: `PUT /tool`
+
+**权限**: `mcp:tool:edit`
+
+**请求体**: 同新增工具
+
+### 1.6 删除工具
+
+**接口**: `DELETE /tool/{ids}`
+
+**权限**: `mcp:tool:remove`
+
+**路径参数**:
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| ids | String | 是 | 工具ID,多个用逗号分隔 |
+
+### 1.7 更新工具状态
+
+**接口**: `PUT /tool/{id}/status`
+
+**权限**: `mcp:tool:edit`
+
+**路径参数**:
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| id | Long | 是 | 工具ID |
+
+**请求参数**:
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| status | String | 是 | 状态:0-启用, 1-禁用 |
+
+### 1.8 测试工具连接
+
+**接口**: `POST /tool/{id}/test`
+
+**权限**: `mcp:tool:query`
+
+**响应示例**:
+```json
+{
+ "success": true,
+ "message": "连接测试成功",
+ "toolCount": 5,
+ "tools": ["tool1", "tool2", "tool3", "tool4", "tool5"]
+}
+```
+
+---
+
+## 2. MCP市场管理
+
+### 2.1 查询市场列表
+
+**接口**: `GET /market/list`
+
+**权限**: `mcp:market:list`
+
+**请求参数**:
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| name | String | 否 | 市场名称 |
+| description | String | 否 | 市场描述 |
+| status | String | 否 | 状态 |
+| pageNum | Integer | 是 | 页码 |
+| pageSize | Integer | 是 | 每页数量 |
+
+### 2.2 获取市场工具列表
+
+**接口**: `GET /market/{marketId}/tools`
+
+**权限**: `mcp:market:query`
+
+**路径参数**:
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| marketId | Long | 是 | 市场ID |
+
+**请求参数**:
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| page | Integer | 否 | 页码,默认1 |
+| size | Integer | 否 | 每页数量,默认10 |
+
+### 2.3 刷新市场工具
+
+**接口**: `POST /market/{marketId}/refresh`
+
+**权限**: `mcp:market:edit`
+
+**响应示例**:
+```json
+{
+ "success": true,
+ "message": "刷新成功",
+ "addedCount": 3,
+ "updatedCount": 5
+}
+```
+
+### 2.4 加载工具到本地
+
+**接口**: `POST /market/tool/{toolId}/load`
+
+**权限**: `mcp:market:edit`
+
+**路径参数**:
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| toolId | Long | 是 | 市场工具ID |
+
+### 2.5 批量加载工具
+
+**接口**: `POST /market/tools/batchLoad`
+
+**权限**: `mcp:market:edit`
+
+**请求体**:
+```json
+{
+ "toolIds": [1, 2, 3]
+}
+```
+
+---
+
+## 3. 工具调用日志
+
+### 3.1 查询调用日志
+
+**接口**: `GET /tool/callLog`
+
+**权限**: `mcp:tool:query`
+
+**请求参数**:
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| toolId | Long | 否 | 工具ID |
+| sessionId | Long | 否 | 会话ID |
+| startDate | Date | 否 | 开始日期 |
+| endDate | Date | 否 | 结束日期 |
+| pageNum | Integer | 是 | 页码 |
+| pageSize | Integer | 是 | 每页数量 |
+
+### 3.2 获取工具统计
+
+**接口**: `GET /tool/{toolId}/metrics`
+
+**权限**: `mcp:tool:query`
+
+**响应示例**:
+```json
+{
+ "toolId": 1,
+ "toolName": "ReadFileTool",
+ "today": {
+ "callCount": 100,
+ "successCount": 95,
+ "failureCount": 5,
+ "avgDurationMs": 150,
+ "successRate": 95.0
+ },
+ "week": {
+ "callCount": 500,
+ "successCount": 475,
+ "failureCount": 25,
+ "avgDurationMs": 160,
+ "successRate": 95.0
+ }
+}
+```
+
+---
+
+## 4. 状态码说明
+
+| 状态码 | 说明 |
+|--------|------|
+| 200 | 请求成功 |
+| 401 | 未认证 |
+| 403 | 无权限 |
+| 404 | 资源不存在 |
+| 500 | 服务器错误 |
+
+---
+
+## 5. 前端页面需求
+
+### 5.1 MCP工具管理页面 (`/mcp/tool`)
+
+**功能**:
+- 工具列表展示(分页)
+- 工具搜索和筛选
+- 新增/编辑/删除工具
+- 工具状态切换
+- 工具连接测试
+
+**表格列**:
+- 工具名称
+- 工具描述
+- 工具类型(标签显示)
+- 状态(开关)
+- 创建时间
+- 操作(编辑、删除、测试)
+
+### 5.2 MCP市场管理页面 (`/mcp/market`)
+
+**功能**:
+- 市场列表展示
+- 市场工具浏览
+- 刷新市场工具
+- 加载工具到本地
+
+### 5.3 工具调用日志页面 (`/mcp/log`)
+
+**功能**:
+- 调用日志列表
+- 按工具/日期筛选
+- 成功率统计
+- 响应时间统计
+
+**图表**:
+- 每日调用次数趋势图
+- 工具调用成功率饼图
+- 平均响应时间柱状图
diff --git a/ruoyi-modules/ruoyi-chat/pom.xml b/ruoyi-modules/ruoyi-chat/pom.xml
index 35a3535f..f0a95fe5 100644
--- a/ruoyi-modules/ruoyi-chat/pom.xml
+++ b/ruoyi-modules/ruoyi-chat/pom.xml
@@ -51,15 +51,9 @@
dev.langchain4j
langchain4j-community-zhipu-ai
- ${langchain4j.community.zhipu.ai.version}
+ ${langchain4j.community.version}
-
-
-
-
-
-
com.zaxxer
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/ChartGenerationAgent.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/ChartGenerationAgent.java
index 2de1fcea..ab61ee62 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/ChartGenerationAgent.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/ChartGenerationAgent.java
@@ -6,7 +6,7 @@ import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
-public interface ChartGenerationAgent {
+public interface ChartGenerationAgent extends Agent {
@SystemMessage("""
You are a chart generation specialist. Your only task is to generate Apache ECharts
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/McpAgent.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/McpAgent.java
index 1f5d0c6a..7bef6b4a 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/McpAgent.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/McpAgent.java
@@ -5,42 +5,38 @@ import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
-public interface McpAgent {
+public interface McpAgent extends Agent {
+
/**
- * 系统提示词:定义智能体身份、核心职责、强制遵守的规则
- * 适配SSE流式特性,明确工具全来自远端MCP服务,仅做代理调用和结果整理
+ * 系统提示词:通用工具调用智能体
+ * 不限定具体工具类型,让 LangChain4j 自动传递工具描述给 LLM
*/
@SystemMessage("""
- 你是专业的MCP服务工具代理智能体,核心能力是通过HTTP SSE流式传输协议,调用本地http://localhost:8085/sse地址上MCP服务端注册的所有工具。
- 你的核心工作职责:
- 1. 准确理解用户的自然语言请求,判断需要调用MCP服务端的哪一个/哪些工具;
- 2. 通过绑定的工具提供者,向MCP服务端发起工具调用请求,传递完整的工具执行参数;
- 3. 实时接收MCP服务端通过SSE流式返回的工具执行结果,保证结果片段的完整性;
- 4. 将流式结果按原始顺序整理为清晰、易懂的自然语言答案,返回给用户。
+ 你是一个AI助手,可以通过调用各种工具来帮助用户完成不同的任务。
- 【强制遵守的核心规则 - 无例外】
- 1. 所有工具调用必须通过远端MCP服务执行,严禁尝试本地执行任何业务逻辑;
- 2. 处理SSE流式结果时,严格保留结果片段的返回顺序,不得打乱或遗漏;
- 3. 若MCP服务返回错误(如工具未找到、参数错误、执行失败),直接将错误信息友好反馈给用户,无需额外推理;
- 4. 工具执行结果若为结构化数据(如JSON、表格),需格式化后返回,提升可读性。
+ 【工具使用规则】
+ 1. 根据用户的请求,判断需要使用哪些工具
+ 2. 仔细阅读每个工具的描述,确保理解工具的功能和参数要求
+ 3. 使用正确的参数调用工具
+ 4. 如果工具执行失败,向用户友好地说明错误原因,并尝试提供替代方案
+ 5. 对于复杂任务,可以分步骤使用多个工具完成
+ 6. 将工具执行结果以清晰易懂的方式呈现给用户
+
+ 【响应格式】
+ - 直接回答用户的问题
+ - 如果使用了工具,说明使用了什么工具以及结果
+ - 如果遇到错误,提供友好的错误信息和解决建议
""")
- /**
- * 用户消息模板:{{query}}为参数占位符,与方法入参的@V("query")绑定
- */
@UserMessage("""
- 请通过调用MCP服务端的工具,处理用户的以下请求:
{{query}}
""")
+
+ @Agent("通用工具调用智能体")
/**
- * 智能体标识:用于日志打印、监控追踪、多智能体协作时的身份识别
- */
- @Agent("MCP服务SSE流式代理智能体-连接本地8085端口")
- /**
- * 智能体对外调用入口方法
- * @param query 用户的自然语言请求(如:生成订单数据柱状图、查询今日天气)
- * @V("query") 将方法入参值绑定到@UserMessage的{{query}}占位符中
- * @return 整理后的MCP工具执行结果(流式结果会自动拼接为完整字符串)
+ * 智能体对外调用入口
+ * @param query 用户的自然语言请求
+ * @return 处理结果
*/
String callMcpTool(@V("query") String query);
}
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/SqlAgent.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/SqlAgent.java
index 99e1ff05..77b8e1ab 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/SqlAgent.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/SqlAgent.java
@@ -2,7 +2,6 @@ package org.ruoyi.agent;
import dev.langchain4j.agentic.Agent;
import dev.langchain4j.service.SystemMessage;
-import dev.langchain4j.service.TokenStream;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
@@ -12,7 +11,7 @@ import dev.langchain4j.service.V;
* and returning relevant data and analysis results.
*
*/
-public interface SqlAgent {
+public interface SqlAgent extends Agent {
@SystemMessage("""
This agent is designed for MySQL 5.7
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/StreamingCreativeWriter.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/StreamingCreativeWriter.java
deleted file mode 100644
index 9486b853..00000000
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/StreamingCreativeWriter.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.ruoyi.agent;
-
-import dev.langchain4j.agentic.Agent;
-import dev.langchain4j.service.TokenStream;
-import dev.langchain4j.service.UserMessage;
-import dev.langchain4j.service.V;
-
-public interface StreamingCreativeWriter {
- @UserMessage("""
- You are a creative writer.
- Generate a draft of a story no more than
- 3 sentences long around the given topic.
- Return only the story and nothing else.
- The topic is {{topic}}.
- """)
- @Agent("Generates a story based on the given topic")
- TokenStream generateStory(@V("topic") String topic);
-}
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/WebSearchAgent.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/WebSearchAgent.java
index 33f8737e..970e3a2b 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/WebSearchAgent.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/WebSearchAgent.java
@@ -10,7 +10,7 @@ import dev.langchain4j.service.V;
* A web search assistant that answers natural language questions by searching the internet
* and returning relevant information from web pages.
*/
-public interface WebSearchAgent {
+public interface WebSearchAgent extends Agent {
@SystemMessage("""
You are a web search assistant. Answer questions by searching and retrieving web content.
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/manager/TableSchemaManager.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/manager/TableSchemaManager.java
index a02eb78d..7366acc8 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/manager/TableSchemaManager.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/manager/TableSchemaManager.java
@@ -40,7 +40,7 @@ import lombok.extern.slf4j.Slf4j;
@Component
@DS("agent")
public class TableSchemaManager {
-
+
@Autowired(required = false)
private DataSource agentDataSource;
@@ -77,7 +77,7 @@ public class TableSchemaManager {
loadAllowedTableSchemas();
initialized = true;
log.info("Schema cache initialized with {} tables", schemaCache.size());
-
+
} catch (Exception e) {
log.error("Failed to initialize schema cache", e);
}
@@ -87,7 +87,7 @@ public class TableSchemaManager {
/**
* 加载所有允许的表的结构信息
*/
- private void loadAllowedTableSchemas() throws SQLException {
+ private void loadAllowedTableSchemas() {
List allowedTables = getAllowedTableNames();
for (String tableName : allowedTables) {
try {
@@ -191,10 +191,7 @@ public class TableSchemaManager {
}
List allowedTables = getAllowedTableNames();
- return allowedTables.stream()
- .map(schemaCache::get)
- .filter(Objects::nonNull)
- .collect(Collectors.toList());
+ return allowedTables.stream().map(schemaCache::get).filter(Objects::nonNull).collect(Collectors.toList());
}
/**
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/ExecuteSqlQueryTool.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/ExecuteSqlQueryTool.java
index 2cc33a67..7fb56ad6 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/ExecuteSqlQueryTool.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/ExecuteSqlQueryTool.java
@@ -11,13 +11,14 @@ import java.util.Map;
import javax.sql.DataSource;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.ruoyi.common.core.utils.SpringUtils;
import org.springframework.stereotype.Component;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import dev.langchain4j.agent.tool.Tool;
import lombok.extern.slf4j.Slf4j;
+import org.ruoyi.mcp.service.core.BuiltinToolProvider;
/**
* 执行 SQL 查询的 Tool
@@ -25,10 +26,12 @@ import lombok.extern.slf4j.Slf4j;
*/
@Slf4j
@Component
-public class ExecuteSqlQueryTool {
+public class ExecuteSqlQueryTool implements BuiltinToolProvider {
- @Autowired(required = false)
- private DataSource dataSource;
+ // 使用延迟初始化,避免在构造函数中调用 SpringUtils.getBean()
+ private DataSource getDataSource() {
+ return SpringUtils.getBean(DataSource.class);
+ }
/**
* 执行 SELECT SQL 查询
@@ -52,6 +55,7 @@ public class ExecuteSqlQueryTool {
}
try {
+ DataSource dataSource = getDataSource();
if (dataSource == null) {
return "Error: Database datasource not configured";
}
@@ -177,4 +181,19 @@ public class ExecuteSqlQueryTool {
}
return str;
}
+
+ @Override
+ public String getToolName() {
+ return "execute_sql_query";
+ }
+
+ @Override
+ public String getDisplayName() {
+ return "执行SQL查询";
+ }
+
+ @Override
+ public String getDescription() {
+ return "Execute a SELECT SQL query and return the results. Example: SELECT * FROM sys_user";
+ }
}
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/QueryAllTablesTool.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/QueryAllTablesTool.java
index d9ed0666..9fd6637c 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/QueryAllTablesTool.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/QueryAllTablesTool.java
@@ -4,11 +4,12 @@ import java.util.List;
import org.ruoyi.agent.domain.TableStructure;
import org.ruoyi.agent.manager.TableSchemaManager;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.ruoyi.common.core.utils.SpringUtils;
import org.springframework.stereotype.Component;
import dev.langchain4j.agent.tool.Tool;
import lombok.extern.slf4j.Slf4j;
+import org.ruoyi.mcp.service.core.BuiltinToolProvider;
/**
* 查询数据库所有表的 Tool
@@ -16,11 +17,13 @@ import lombok.extern.slf4j.Slf4j;
*/
@Slf4j
@Component
-public class QueryAllTablesTool {
+public class QueryAllTablesTool implements BuiltinToolProvider {
+
+ // 使用延迟初始化,避免在构造函数中调用 SpringUtils.getBean()
+ private TableSchemaManager getTableSchemaManager() {
+ return SpringUtils.getBean(TableSchemaManager.class);
+ }
-
- @Autowired
- private TableSchemaManager tableSchemaManager; // 注入管理器
/**
* 查询数据库中所有表
* 返回数据库中存在的所有表的列表
@@ -30,36 +33,49 @@ public class QueryAllTablesTool {
@Tool("Query all tables in the database and return table names and basic information")
public String queryAllTables() {
try {
- // 1. 从管理器获取所有允许的表结构信息(内部已包含初始化/缓存逻辑)
- List tableSchemas = tableSchemaManager.getAllowedTableSchemas();
-
- if (tableSchemas == null || tableSchemas.isEmpty()) {
- return "No tables found in database or cache is empty.";
- }
-
- // 2. 格式化结果
- StringBuilder result = new StringBuilder();
- result.append("Found ").append(tableSchemas.size()).append(" tables in cache:\n");
-
- for (TableStructure schema : tableSchemas) {
- String tableName = schema.getTableName();
- String tableType = schema.getTableType() != null ? schema.getTableType() : "TABLE";
- String tableComment = schema.getTableComment();
-
- result.append(String.format("- %s (%s) - %s\n",
- tableName,
- tableType,
- tableComment != null ? tableComment : "No comment"));
- }
-
- log.info("Successfully retrieved {} tables from schema cache", tableSchemas.size());
- return result.toString();
-
- } catch (Exception e) {
- log.error("Error retrieving tables from cache", e);
- return "Error: " + e.getMessage();
+ // 1. 从管理器获取所有允许的表结构信息(内部已包含初始化/缓存逻辑)
+ List tableSchemas = getTableSchemaManager().getAllowedTableSchemas();
+
+ if (tableSchemas == null || tableSchemas.isEmpty()) {
+ return "No tables found in database or cache is empty.";
}
-
-
+
+ // 2. 格式化结果
+ StringBuilder result = new StringBuilder();
+ result.append("Found ").append(tableSchemas.size()).append(" tables in cache:\n");
+
+ for (TableStructure schema : tableSchemas) {
+ String tableName = schema.getTableName();
+ String tableType = schema.getTableType() != null ? schema.getTableType() : "TABLE";
+ String tableComment = schema.getTableComment();
+
+ result.append(String.format("- %s (%s) - %s\n",
+ tableName,
+ tableType,
+ tableComment != null ? tableComment : "No comment"));
+ }
+
+ log.info("Successfully retrieved {} tables from schema cache", tableSchemas.size());
+ return result.toString();
+
+ } catch (Exception e) {
+ log.error("Error retrieving tables from cache", e);
+ return "Error: " + e.getMessage();
+ }
+ }
+
+ @Override
+ public String getToolName() {
+ return "query_all_tables";
+ }
+
+ @Override
+ public String getDisplayName() {
+ return "查询所有表";
+ }
+
+ @Override
+ public String getDescription() {
+ return "Query all tables in the database and return table names and basic information";
}
}
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/QueryTableSchemaTool.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/QueryTableSchemaTool.java
index 33d06b27..73a62670 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/QueryTableSchemaTool.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/QueryTableSchemaTool.java
@@ -6,20 +6,23 @@ import java.sql.ResultSet;
import javax.sql.DataSource;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.ruoyi.common.core.utils.SpringUtils;
import org.springframework.stereotype.Component;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import dev.langchain4j.agent.tool.Tool;
import lombok.extern.slf4j.Slf4j;
+import org.ruoyi.mcp.service.core.BuiltinToolProvider;
@Component
@Slf4j
-public class QueryTableSchemaTool {
+public class QueryTableSchemaTool implements BuiltinToolProvider {
- @Autowired(required = false)
- private DataSource dataSource;
+ // 使用延迟初始化,避免在构造函数中调用 SpringUtils.getBean()
+ private DataSource getDataSource() {
+ return SpringUtils.getBean(DataSource.class);
+ }
@Tool("Query the CREATE TABLE statement (DDL) for a specific table by table name")
public String queryTableSchema(String tableName) {
@@ -35,7 +38,7 @@ public class QueryTableSchemaTool {
String sql = "SHOW CREATE TABLE `" + tableName + "`";
- try (Connection connection = dataSource.getConnection();
+ try (Connection connection = getDataSource().getConnection();
PreparedStatement ps = connection.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
@@ -54,4 +57,19 @@ public class QueryTableSchemaTool {
DynamicDataSourceContextHolder.clear();
}
}
+
+ @Override
+ public String getToolName() {
+ return "query_table_schema";
+ }
+
+ @Override
+ public String getDisplayName() {
+ return "查询表结构";
+ }
+
+ @Override
+ public String getDescription() {
+ return "Query the CREATE TABLE statement (DDL) for a specific table by table name";
+ }
}
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/config/mcp/SystemToolInitializer.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/config/mcp/SystemToolInitializer.java
new file mode 100644
index 00000000..8426db52
--- /dev/null
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/config/mcp/SystemToolInitializer.java
@@ -0,0 +1,93 @@
+package org.ruoyi.config.mcp;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.ruoyi.domain.entity.mcp.McpTool;
+import org.ruoyi.enums.McpToolStatus;
+import org.ruoyi.mapper.mcp.McpToolMapper;
+import org.ruoyi.mcp.service.core.BuiltinToolDefinition;
+import org.ruoyi.mcp.service.core.BuiltinToolRegistry;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * 系统工具初始化器
+ * 在应用启动时,将系统内置工具同步到数据库
+ * 这样可以统一管理所有工具,支持动态启用/禁用
+ *
+ * @author ruoyi team
+ */
+@Slf4j
+@Component
+@Order(999) // 确保在其他初始化器之后执行
+@RequiredArgsConstructor
+public class SystemToolInitializer implements ApplicationRunner {
+
+ private final McpToolMapper mcpToolMapper;
+ private final BuiltinToolRegistry builtinToolRegistry;
+
+ @Override
+ @Transactional
+ public void run(ApplicationArguments args) {
+ log.info("开始同步系统内置工具到数据库...");
+
+ int addedCount = 0;
+ int existingCount = 0;
+
+ for (BuiltinToolDefinition tool : builtinToolRegistry.getAllBuiltinTools()) {
+ try {
+ boolean added = syncBuiltinTool(tool);
+ if (added) {
+ addedCount++;
+ } else {
+ existingCount++;
+ }
+ } catch (Exception e) {
+ log.error("同步内置工具失败: {}", tool.name(), e);
+ }
+ }
+
+ log.info("系统内置工具同步完成: 新增 {} 个, 已存在 {} 个", addedCount, existingCount);
+ }
+
+ /**
+ * 同步单个内置工具到数据库
+ *
+ * @param tool 工具定义
+ * @return 是否新增(true=新增, false=已存在)
+ */
+ private boolean syncBuiltinTool(BuiltinToolDefinition tool) {
+ // 检查是否已存在
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(McpTool::getName, tool.name())
+ .eq(McpTool::getType, BuiltinToolRegistry.TYPE_BUILTIN);
+
+ McpTool existing = mcpToolMapper.selectOne(wrapper);
+
+ if (existing != null) {
+ // 已存在,更新描述信息(保留状态不变)
+ if (!tool.description().equals(existing.getDescription())) {
+ existing.setDescription(tool.description());
+ mcpToolMapper.updateById(existing);
+ log.debug("更新内置工具描述: {}", tool.name());
+ }
+ return false;
+ }
+
+ // 新增
+ McpTool newTool = new McpTool();
+ newTool.setName(tool.name());
+ newTool.setDescription(tool.description());
+ newTool.setType(BuiltinToolRegistry.TYPE_BUILTIN);
+ newTool.setStatus(McpToolStatus.ENABLED.getValue()); // 默认启用
+ newTool.setConfigJson(null); // 内置工具不需要配置
+ mcpToolMapper.insert(newTool);
+
+ log.info("新增内置工具: {} ({})", tool.name(), tool.displayName());
+ return true;
+ }
+}
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/controller/mcp/McpMarketController.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/controller/mcp/McpMarketController.java
new file mode 100644
index 00000000..3f840425
--- /dev/null
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/controller/mcp/McpMarketController.java
@@ -0,0 +1,172 @@
+package org.ruoyi.controller.mcp;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import org.ruoyi.common.core.domain.R;
+import org.ruoyi.common.excel.utils.ExcelUtil;
+import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
+import org.ruoyi.common.log.annotation.Log;
+import org.ruoyi.common.log.enums.BusinessType;
+import org.ruoyi.common.mybatis.core.page.PageQuery;
+import org.ruoyi.common.mybatis.core.page.TableDataInfo;
+import org.ruoyi.common.web.core.BaseController;
+import org.ruoyi.domain.bo.mcp.McpMarketBo;
+import org.ruoyi.domain.dto.mcp.McpMarketListResult;
+import org.ruoyi.domain.dto.mcp.McpMarketRefreshResult;
+import org.ruoyi.domain.dto.mcp.McpMarketToolListResult;
+import org.ruoyi.domain.vo.mcp.McpMarketVo;
+import org.ruoyi.service.mcp.IMcpMarketService;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * MCP 市场管理 Controller
+ *
+ * @author ruoyi team
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/mcp/market")
+public class McpMarketController extends BaseController {
+
+ private final IMcpMarketService mcpMarketService;
+
+ /**
+ * 查询市场列表
+ */
+ @SaCheckPermission("mcp:market:list")
+ @GetMapping("/list")
+ public TableDataInfo list(McpMarketBo bo, PageQuery pageQuery) {
+ return mcpMarketService.selectPageList(bo, pageQuery);
+ }
+
+ /**
+ * 查询市场列表(不分页)
+ */
+ @SaCheckPermission("mcp:market:list")
+ @GetMapping("/all")
+ public McpMarketListResult listAll(
+ @RequestParam(required = false) String keyword,
+ @RequestParam(required = false) String status) {
+ return mcpMarketService.listMarkets(keyword, status);
+ }
+
+ /**
+ * 导出 MCP 市场列表
+ */
+ @SaCheckPermission("mcp:market:export")
+ @Log(title = "MCP市场管理", businessType = BusinessType.EXPORT)
+ @PostMapping("/export")
+ public void export(McpMarketBo bo, HttpServletResponse response) {
+ List list = mcpMarketService.queryList(bo);
+ ExcelUtil.exportExcel(list, "MCP市场", McpMarketVo.class, response);
+ }
+
+ /**
+ * 根据市场ID获取详细信息
+ *
+ * @param id 市场ID
+ */
+ @SaCheckPermission("mcp:market:query")
+ @GetMapping("/{id}")
+ public R getInfo(@PathVariable Long id) {
+ return R.ok(mcpMarketService.selectById(id));
+ }
+
+ /**
+ * 新增市场
+ */
+ @SaCheckPermission("mcp:market:add")
+ @Log(title = "MCP市场管理", businessType = BusinessType.INSERT)
+ @RepeatSubmit()
+ @PostMapping
+ public R add(@Validated @RequestBody McpMarketBo bo) {
+ mcpMarketService.insert(bo);
+ return R.ok();
+ }
+
+ /**
+ * 修改市场
+ */
+ @SaCheckPermission("mcp:market:edit")
+ @Log(title = "MCP市场管理", businessType = BusinessType.UPDATE)
+ @RepeatSubmit()
+ @PutMapping
+ public R edit(@Validated @RequestBody McpMarketBo bo) {
+ mcpMarketService.update(bo);
+ return R.ok();
+ }
+
+ /**
+ * 删除市场
+ *
+ * @param ids 市场ID串
+ */
+ @SaCheckPermission("mcp:market:remove")
+ @Log(title = "MCP市场管理", businessType = BusinessType.DELETE)
+ @DeleteMapping("/{ids}")
+ public R remove(@PathVariable Long[] ids) {
+ mcpMarketService.deleteByIds(List.of(ids));
+ return R.ok();
+ }
+
+ /**
+ * 更新市场状态
+ */
+ @SaCheckPermission("mcp:market:edit")
+ @Log(title = "MCP市场管理", businessType = BusinessType.UPDATE)
+ @PutMapping("/{id}/status")
+ public R updateStatus(@PathVariable Long id, @RequestParam String status) {
+ mcpMarketService.updateStatus(id, status);
+ return R.ok();
+ }
+
+ /**
+ * 获取市场工具列表(分页)
+ */
+ @SaCheckPermission("mcp:market:query")
+ @GetMapping("/{marketId}/tools")
+ public McpMarketToolListResult getMarketTools(
+ @PathVariable Long marketId,
+ @RequestParam(defaultValue = "1") int page,
+ @RequestParam(defaultValue = "10") int size) {
+ return mcpMarketService.getMarketTools(marketId, page, size);
+ }
+
+ /**
+ * 刷新市场工具列表
+ */
+ @SaCheckPermission("mcp:market:edit")
+ @Log(title = "MCP市场管理", businessType = BusinessType.UPDATE)
+ @PostMapping("/{marketId}/refresh")
+ public R refreshMarketTools(@PathVariable Long marketId) {
+ return R.ok(mcpMarketService.refreshMarketTools(marketId));
+ }
+
+ /**
+ * 加载单个工具到本地
+ */
+ @SaCheckPermission("mcp:market:add")
+ @Log(title = "MCP市场管理", businessType = BusinessType.INSERT)
+ @PostMapping("/tools/{toolId}/load")
+ public R loadToolToLocal(@PathVariable Long toolId) {
+ mcpMarketService.loadToolToLocal(toolId);
+ return R.ok();
+ }
+
+ /**
+ * 批量加载工具到本地
+ */
+ @SaCheckPermission("mcp:market:add")
+ @Log(title = "MCP市场管理", businessType = BusinessType.INSERT)
+ @PostMapping("/tools/batch-load")
+ public R