33 Commits

Author SHA1 Message Date
ageerle@163.com
7aa67cfc2f docs: 移除赞助商区块引用样式及多余换行
- 去掉 blockquote 引用块样式消除左侧竖线
- 去掉多余 <br> 避免链接文字断行

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-10 18:19:04 +08:00
ageerle@163.com
6d38e2bf25 docs: 赞助商图片改用本地路径并新增火山引擎 CodingPlan
- Atlas Cloud 图片从远程链接改为 docs/image/sponsor/ 本地路径
- 新增火山引擎 CodingPlan 开发者计划赞助商(中英文 README 同步)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-10 18:14:46 +08:00
ageerle@163.com
8ed5e61f63 docs: 添加微信技术交流群二维码
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 10:25:18 +08:00
ageerle@163.com
c3c89f8cc8 docs: 调整中文版赞助商图标大小
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 11:44:42 +08:00
ageerle@163.com
a3a6bdbc55 docs: 调整英文版赞助商图标大小与中文版一致
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 11:43:37 +08:00
ageerle@163.com
07d9fc1f45 docs: 同步英文版 README 与中文版保持一致
- 移除英文版 Quick Start/Live Demo 章节
- 移除 Ecosystem Partners 章节,合并到 Sponsors
- 更新赞助商格式为图片横幅样式
- 社区交流改为微信/QQ 二维码(替换 Telegram)
- 移除 Acknowledgments 中的 Spring AI Alibaba Copilot
- 修复 Technical Architecture 多余空行
- 更新文档链接域名(pandarobot -> ruoyiai)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 11:38:48 +08:00
ageerle@163.com
73a60e3591 docs: 更新 Atlas Cloud 赞助链接添加推荐参数
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 14:37:14 +08:00
ageerle@163.com
c79848c654 feat: 替换 PPIO 为 Atlas Cloud 并增强知识库功能
- 将 PPIO 服务提供商替换为 Atlas Cloud
- 更新 README 赞助商信息
- 删除 PPIOEmbeddingProvider 和相关测试
- 知识库新增重排序、混合检索、相似度阈值等字段
- 更新 SQL 初始化脚本

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 11:18:59 +08:00
ageerle@163.com
ec092a11c3 docs: 添加 web coding 快速部署说明
在 README 中新增使用 web coding 急速部署的章节,包含在线体验链接和部署截图展示

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 17:45:16 +08:00
ageerle
9a7b727413 Merge pull request #293 from RobustH/main
升级RAG模块
2026-04-23 09:15:02 +08:00
RobustH
b8d16b7669 feat(rag): 对接用户端用户知识库对话,集成知识库配置应用 2026-04-23 00:52:53 +08:00
RobustH
058a4aee2a feat(rag): 新增测试配置应用的功能 2026-04-21 22:54:11 +08:00
RobustH
1b50c7f9f1 fix(rag): 修复合并重复,重排模型新增硅基流动供应商 2026-04-21 22:41:00 +08:00
RobustH
e7f53fd55f Merge remote-tracking branch 'origin/main'
# Conflicts:
#	ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/bo/knowledge/KnowledgeInfoBo.java
#	ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/entity/knowledge/KnowledgeInfo.java
#	ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/vo/knowledge/KnowledgeInfoVo.java
#	ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/service/chat/impl/ChatServiceFacade.java
2026-04-21 21:41:51 +08:00
ageerle
07bdc5e585 Merge pull request #292 from yangzhen233/feature/rerank-model
Feature/rerank model
2026-04-20 21:06:27 +08:00
yangzhen
e1b8a5f011 新增千问3重排序模型,并附带新增sql文件 2026-04-20 16:07:02 +08:00
杨振
80ca76ea37 添加重排序功能 2026-04-20 01:02:09 +08:00
wangle
2c6ff66830 fix: 修正application.yml演示模式message缩进
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 13:42:39 +08:00
wangle
4f79a66559 feat: 添加小米MiMo、DeepSeek、自定义厂商等provider支持
- 新增小米MiMo服务实现类(MiMoServiceImpl)
- ChatModeType添加XIAOMI枚举
- 更新SQL初始化脚本,新增多家厂商(provider)和模型数据
- 添加2026-04-19数据库更新脚本
- application.yml演示模式排除路径增加attach/fragment/info接口
- 删除独立的minimax_provider.sql(数据已合并到主SQL)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 13:42:05 +08:00
wangle
22883b4334 Merge branch pr-280: 添加MiniMax作为LLM提供商
解决冲突:
- README: 保留Qdrant向量库信息 + 合并MiniMax模型接入
- pom.xml: 保留spring-boot-starter-test + 添加MiniMax测试依赖
- ChatModeType: 保留CUSTOM_API + 新增MINIMAX枚举
- MinimaxServiceImpl: 保留MyChatModelListener监听器

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 11:47:04 +08:00
wangle
081da6d18d feat: 添加MiniMax作为LLM提供商,合并PR#280并补充监听
合并PR#280的MiniMax provider实现,解决与main分支的冲突,
并在MinimaxServiceImpl中补充MyChatModelListener监听,
与其他provider保持一致。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-17 18:31:53 +08:00
ageerle
74eb5b2530 Merge pull request #290 from yangzhen233/feature/zhipu-embedding
添加智谱向量模型实现
2026-04-17 18:24:24 +08:00
ageerle
b0328fe0ef Merge pull request #291 from xiaonieli7/main
fate:增加自定义模型,调整前端模型选择下拉框
2026-04-17 18:16:59 +08:00
Administrator
2ee0aae57e fate:增加自定义模型,调整前端模型选择下拉框 2026-04-17 08:31:40 +08:00
杨振
d9c3de660a 添加智谱向量模型实现 2026-04-16 21:18:11 +08:00
RobustH
ccbf5c9520 feat(rag): 知识库检索测试新增混合检索 2026-04-14 23:18:29 +08:00
ageerle
c4f7c1f5d0 Merge pull request #283 from MrWws/fix/docker-compose-all.yaml
fix: 修复运行docker-compose-all.yaml报错的问题
2026-04-14 14:36:14 +08:00
RobustH
1208c46cca feat(rag): 集成硅基流动、阿里百炼重排模型并全方位增强检索测试体验 2026-04-14 01:40:28 +08:00
RobustH
06a63c377e feat: 新增检索测试相关接口
- 实现向量 L2 归一化,统一 Milvus/Qdrant/Weaviate 检索评分为 [0, 1] 空间
2026-04-13 23:33:56 +08:00
RobustH
0fa25032a3 feat(knowledge): 优化知识库文件状态枚举为"未解析,解析中,解析成功,解析失败",支持异步线程池解析文档 2026-04-13 00:15:01 +08:00
RobustH
28ad29d6ed feat(knowledge): 完善知识库及附件统计功能并修复分块数统计问题 2026-04-12 18:38:32 +08:00
MrWws
b9097b4989 fix: 修复运行docker-compose-all.yaml报错的问题 2026-03-31 22:59:26 +08:00
octopus
5d14eb20af feat: add MiniMax as first-class LLM provider
Add MiniMax AI as the 7th LLM provider, supporting chat (M2.7, M2.5,
M2.5-highspeed) and embedding (embo-01) models via OpenAI-compatible API.

Changes:
- Add MINIMAX enum to ChatModeType
- Add MinimaxServiceImpl chat provider (OpenAI-compat streaming)
- Add MinimaxEmbeddingProvider for vector embeddings
- Add SQL migration for provider and model registration
- Add 14 unit tests + 3 integration tests
- Update README/README_EN with MiniMax in provider list
2026-03-21 16:14:19 +08:00
81 changed files with 3339 additions and 1005 deletions

View File

@@ -21,8 +21,8 @@
*开箱即用的全栈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)**
**[English](README_EN.md)** | **[📖 使用文档](https://doc.ruoyiai.chat/)** |
**[🚀 在线体验](https://web.ruoyiai.chat/)** | **[🐛 问题反馈](https://github.com/ageerle/ruoyi-ai/issues)** | **[💡 功能建议](https://github.com/ageerle/ruoyi-ai/issues)**
</div>
@@ -31,20 +31,12 @@
| 模块 | 现有能力
|:----------:|---
| **模型管理** | 多模型接入(OpenAI/DeepSeek/通义/智谱)、多模态理解、Coze/DIFY/FastGPT平台集成
| **模型管理** | 多模型接入(OpenAI/DeepSeek/通义/智谱/MiniMax)、多模态理解、Coze/DIFY/FastGPT平台集成
| **知识管理** | 本地RAG + 向量库(Milvus/Weaviate/Qdrant) + 文档解析
| **工具管理** | Mcp协议集成、Skills能力 + 可扩展工具生态
| **流程编排** | 可视化工作流设计器、节点拖拽编排、SSE流式执行,目前已经支持模型调用,邮件发送,人工审核等节点
| **多智能体** | 基于Langchain4j的Agent框架、Supervisor模式编排,支持多种决策模型
## 🚀 快速体验
### 在线演示
| 平台 | 地址 | 账号 |
|:------:|---|---|
| 用户端 | [web.pandarobot.chat](https://web.pandarobot.chat) | admin / admin123 |
| 管理后台 | [admin.pandarobot.chat](https://admin.pandarobot.chat) | admin / admin123 |
### 项目源码
@@ -66,8 +58,6 @@
- **数据存储**MySQL 8.0 + Redis + 向量数据库Milvus/Weaviate/Qdrant
- **前端技术**Vue 3 + Vben Admin + element-plus-x
- **安全认证**Sa-Token + JWT 双重保障
- **文档处理**PDF、Word、Excel 解析,图像智能分析
- **实时通信**WebSocket 实时通信SSE 流式响应
- **系统监控**:完善的日志体系、性能监控、服务健康检查
@@ -187,7 +177,7 @@ docker-compose -f docker-compose-all.yaml restart [服务名]
想要深入了解安装部署、功能配置和二次开发?
**👉 [完整使用文档](https://doc.pandarobot.chat)**
**👉 [完整使用文档](https://doc.ruoyiai.chat/)**
## 🤝 参与贡献
@@ -210,17 +200,29 @@ docker-compose -f docker-compose-all.yaml restart [服务名]
## 🙏 特别鸣谢
感谢以下优秀的开源项目为本项目提供支持:
- [Spring AI Alibaba Copilot](https://github.com/spring-ai-alibaba/copilot) - 基于spring-ai-alibaba
的智能编码助手
- [Langchain4j](https://github.com/langchain4j/langchain4j) - 强大的 Java LLM 开发框架
- [RuoYi-Vue-Plus](https://gitee.com/dromara/RuoYi-Vue-Plus) - 成熟的企业级快速开发框架
- [Vben Admin](https://github.com/vbenjs/vue-vben-admin) - 现代化的 Vue 后台管理模板
## 🌐 生态伙伴
- [PPIO 派欧云](https://ppinfra.com/user/register?invited_by=P8QTUY&utm_source=github_ruoyi-ai) - 提供高性价比的 GPU
算力和模型 API 服务
- [优云智算](https://www.compshare.cn/?ytag=GPU_YY-gh_ruoyi) - 万卡RTX40系GPU+海内外主流模型API服务秒级响应按量计费新客免费用。
## 💎 赞助商
**感谢以下赞助商对本项目的支持:**
<a href="https://www.atlascloud.ai?ref=89F97E">
<img src="docs/image/sponsor/atlascloud_banner.png" alt="Atlas Cloud" width="160" height="80">
</a>
[访问Atlas Cloud官网](https://www.atlascloud.ai?ref=89F97E) · [编程计划优惠](https://www.atlascloud.ai/console/coding-plan)
全模态 AI 推理平台,为开发者提供统一的 AI API支持视频生成、图像生成和大语言模型。一次接入即可访问 **300+ 精选模型**
<a href="https://www.volcengine.com/activity/codingplan?utm_campaign=hw&utm_content=hw&utm_medium=devrel_tool_web&utm_source=OWO&utm_term=ageerle-ruoyi-ai">
<img src="docs/image/sponsor/huoshan.png" alt="火山引擎 CodingPlan" width="160" height="80">
</a>
[火山引擎 CodingPlan 开发者计划](https://www.volcengine.com/activity/codingplan?utm_campaign=hw&utm_content=hw&utm_medium=devrel_tool_web&utm_source=OWO&utm_term=ageerle-ruoyi-ai)
火山引擎是字节跳动旗下的云与 AI 服务平台火山方舟提供豆包大模型、DeepSeek 等多种模型的 API 接入,为开发者提供一站式 AI 开发与推理服务。
## 💬 社区交流
@@ -234,6 +236,11 @@ docker-compose -f docker-compose-all.yaml restart [服务名]
<em>邀请进群学习</em>
</td>
<td align="center">
<img src="docs/image/wx06.png" alt="微信二维码" width="200" height="200"><br>
<strong>微信技术交流群</strong><br>
<em>技术讨论</em>
</td>
<td align="center">
<img src="docs/image/qq.png" alt="QQ群二维码" width="200" height="200"><br>
<strong>QQ技术交流群</strong><br>
<em>技术讨论</em>
@@ -247,7 +254,7 @@ docker-compose -f docker-compose-all.yaml restart [服务名]
---
<div align="center">
**[⭐ 点个Star支持一下](https://github.com/ageerle/ruoyi-ai)** • **[ Fork 开始贡献](https://github.com/ageerle/ruoyi-ai/fork)** • **[📚 English](README_EN.md)** • **[📖 查看完整文档](https://doc.pandarobot.chat)**
**[⭐ 点个Star支持一下](https://github.com/ageerle/ruoyi-ai)** • **[ Fork 开始贡献](https://github.com/ageerle/ruoyi-ai/fork)** • **[📚 English](README_EN.md)** • **[📖 查看完整文档](https://doc.ruoyiai.chat/)**
*用 ❤️ 打造,由 RuoYi AI 开源社区维护*

View File

@@ -22,8 +22,8 @@
*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)**
**[中文](README.md)** | **[📖 Documentation](https://doc.ruoyiai.chat/)** |
**[🚀 Live Demo](https://web.ruoyiai.chat/)** | **[🐛 Report Issues](https://github.com/ageerle/ruoyi-ai/issues)** | **[💡 Feature Requests](https://github.com/ageerle/ruoyi-ai/issues)**
</div>
@@ -34,21 +34,12 @@
| Module | Current Capabilities |
|:---:|---|
| **Model Management** | Multi-model integration (OpenAI/DeepSeek/Tongyi/Zhipu), multi-modal understanding, Coze/DIFY/FastGPT platform integration |
| **Model Management** | Multi-model integration (OpenAI/DeepSeek/Tongyi/Zhipu/MiniMax), multi-modal understanding, Coze/DIFY/FastGPT platform integration |
| **Knowledge Base** | Local RAG + Vector DB (Milvus/Weaviate/Qdrant) + Document parsing |
| **Tool Management** | MCP protocol integration, Skills capability + Extensible tool ecosystem |
| **Workflow Orchestration** | Visual workflow designer, drag-and-drop node orchestration, SSE streaming execution, currently supports model calls, email sending, manual review nodes |
| **Multi-Agent** | Agent framework based on Langchain4j, Supervisor mode orchestration, supports multiple decision models |
## 🚀 Quick Start
### Live Demo
| 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 |
@@ -69,8 +60,6 @@
- **Data Storage**: MySQL 8.0 + Redis + Vector Databases (Milvus/Weaviate/Qdrant)
- **Frontend**: Vue 3 + Vben Admin + element-plus-x
- **Security**: Sa-Token + JWT dual-layer security
- **Document Processing**: PDF, Word, Excel parsing, intelligent image analysis
- **Real-time Communication**: WebSocket real-time communication, SSE streaming response
- **System Monitoring**: Comprehensive logging system, performance monitoring, service health checks
@@ -190,7 +179,7 @@ docker-compose -f docker-compose-all.yaml restart [service-name]
Want to learn more about installation, deployment, configuration, and secondary development?
**👉 [Complete Documentation](https://doc.pandarobot.chat)**
**👉 [Complete Documentation](https://doc.ruoyiai.chat/)**
## 🤝 Contributing
@@ -213,23 +202,47 @@ This project is licensed under the **MIT License**. See the [LICENSE](LICENSE) f
## 🙏 Acknowledgments
Thanks to the following excellent open-source projects for their support:
- [Spring AI Alibaba Copilot](https://github.com/spring-ai-alibaba/copilot) - Intelligent coding assistant based on spring-ai-alibaba
- [Langchain4j](https://github.com/langchain4j/langchain4j) - Powerful Java LLM development framework
- [RuoYi-Vue-Plus](https://gitee.com/dromara/RuoYi-Vue-Plus) - Mature enterprise-level rapid development framework
- [Vben Admin](https://github.com/vbenjs/vue-vben-admin) - Modern Vue admin template
## 🌐 Ecosystem Partners
## 💎 Sponsors
- [PPIO Cloud](https://ppinfra.com/user/register?invited_by=P8QTUY&utm_source=github_ruoyi-ai) - Provides cost-effective GPU computing and model API services
- [Youyun Intelligent Computing](https://www.compshare.cn/?ytag=GPU_YY-gh_ruoyi) - Thousands of RTX40 series GPUs + mainstream models API services, second-level response, pay-per-use, free for new customers.
**Thanks to the following sponsors for supporting this project:**
<a href="https://www.atlascloud.ai?ref=89F97E">
<img src="docs/image/sponsor/atlascloud_banner.png" alt="Atlas Cloud" width="160" height="80">
</a>
[Visit Atlas Cloud](https://www.atlascloud.ai?ref=89F97E) · [Coding Plan Promotion](https://www.atlascloud.ai/console/coding-plan)
A full-modal AI inference platform that gives developers a unified AI API, supporting video generation, image generation, and LLMs. Connect once to access **300+ curated models**.
<a href="https://www.volcengine.com/activity/codingplan?utm_campaign=hw&utm_content=hw&utm_medium=devrel_tool_web&utm_source=OWO&utm_term=ageerle-ruoyi-ai">
<img src="docs/image/sponsor/huoshan.png" alt="Volcengine CodingPlan" width="160" height="80">
</a>
[Volcengine CodingPlan Developer Program](https://www.volcengine.com/activity/codingplan?utm_campaign=hw&utm_content=hw&utm_medium=devrel_tool_web&utm_source=OWO&utm_term=ageerle-ruoyi-ai)
Volcengine is ByteDance's cloud and AI service platform. Volcengine Ark provides API access to Doubao LLM, DeepSeek, and more — a one-stop AI development and inference platform for developers.
## 💬 Community Chat
<div align="center">
**[📱 Join Telegram Group](
https://t.me/+LqooQAc5HxRmYmE1)**
<table>
<tr>
<td align="center">
<img src="docs/image/wx.png" alt="WeChat QR Code" width="200" height="200"><br>
<strong>Scan to add author on WeChat</strong><br>
<em>Join group for learning</em>
</td>
<td align="center">
<img src="docs/image/qq.png" alt="QQ Group QR Code" width="200" height="200"><br>
<strong>QQ Tech Exchange Group</strong><br>
<em>Technical discussion</em>
</td>
</tr>
</table>
</div>
@@ -237,7 +250,7 @@ https://t.me/+LqooQAc5HxRmYmE1)**
<div align="center">
**[⭐ Star to Support](https://github.com/ageerle/ruoyi-ai)** • **[Fork to Contribute](https://github.com/ageerle/ruoyi-ai/fork)** • **[📚 中文](README.md)** • **[📖 Complete Documentation](https://doc.pandarobot.chat)**
**[⭐ Star to Support](https://github.com/ageerle/ruoyi-ai)** • **[Fork to Contribute](https://github.com/ageerle/ruoyi-ai/fork)** • **[📚 中文](README.md)** • **[📖 Complete Documentation](https://doc.ruoyiai.chat/)**
*Built with ❤️, maintained by the RuoYi AI open-source community*

View File

@@ -65,7 +65,7 @@ services:
- "28080:8080"
environment:
QUERY_DEFAULTS_LIMIT: 25
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: true
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: "true"
PERSISTENCE_DATA_PATH: /var/lib/weaviate
DEFAULT_VECTORIZER_MODULE: none
ENABLE_MODULES: text2vec-cohere,text2vec-huggingface,text2vec-palm,text2vec-openai,generative-openai,generative-cohere,generative-palm,ref2vec-centroid,reranker-cohere,qna-openai

BIN
docs/image/01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

BIN
docs/image/02.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

BIN
docs/image/03.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

BIN
docs/image/wx06.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

View File

@@ -1,7 +1,7 @@
/*
Navicat MySQL Dump SQL
Navicat Premium Dump SQL
Source Server : 本地
Source Server : localhost_3306
Source Server Type : MySQL
Source Server Version : 80045 (8.0.45)
Source Host : localhost:3306
@@ -11,13 +11,11 @@
Target Server Version : 80045 (8.0.45)
File Encoding : 65001
Date: 15/03/2026 23:56:19
Date: 21/05/2026 11:03:49
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- 忽略所有错误,继续执行
SET sql_mode = '';
-- ----------------------------
-- Table structure for chat_message
@@ -72,8 +70,9 @@ CREATE TABLE `chat_model` (
-- ----------------------------
-- Records of chat_model
-- ----------------------------
INSERT INTO `chat_model` VALUES (2000585866022060033, 'chat', 'deepseek/deepseek-v3.2', 'ppio', 'deepseek', NULL, 'Y', 'https://api.ppinfra.com/openai', 'sk_xx', 103, 1, '2025-12-15 23:16:54', 1, '2026-03-15 19:18:48', 'DeepSeek-V3.2 是一款在高效推理、复杂推理能力与智能体场景中表现突出的领先模型。其基于 DeepSeek Sparse AttentionDSA稀疏注意力机制在显著降低计算开销的同时优化长上下文性能通过可扩展强化学习框架整体能力达到 GPT-5 同级,高算力版本 V3.2-Speciale 更在推理表现上接近 Gemini-3.0-Pro同时模型依托大型智能体任务合成管线具备更强的工具调用与多步骤决策能力并在 2025 年 IMO 与 IOI 中取得金牌级表现。作为 MaaS 平台,我们已对 DeepSeek-V3.2 完成深度适配,通过动态调度、批处理加速、低延迟推理与企业级 SLA 保障,进一步增强其在企业生产环境中的稳定性、性价比与可控性,适用于搜索、问答、智能体、代码、数据处理等多类高价值场景。', 0);
INSERT INTO `chat_model` VALUES (2007528268536287233, 'vector', 'baai/bge-m3', 'ppio', 'bge-m3', 1024, 'N', 'https://api.ppinfra.com/openai', 'sk_xx', 103, 1, '2026-01-04 03:03:32', 1, '2026-03-15 19:18:51', 'BGE-M3 是一款具备多维度能力的文本嵌入模型可同时实现密集检索、多向量检索和稀疏检索三大核心功能。该模型设计上兼容超过100种语言并支持从短句到长达8192词元的长文本等多种输入形式。在跨语言检索任务中BGE-M3展现出显著优势其性能在MIRACL、MKQA等国际基准测试中位居前列。此外针对长文档检索场景该模型在MLDR、NarritiveQA等数据集上的表现同样达到行业领先水平。', 0);
INSERT INTO `chat_model` (`id`, `category`, `model_name`, `provider_code`, `model_describe`, `model_dimension`, `model_show`, `api_host`, `api_key`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`, `tenant_id`) VALUES (2000585866022060033, 'chat', 'zai-org/glm-5.1', 'atlas', 'zai-org/glm-5.1', NULL, 'Y', 'https://api.atlascloud.ai/v1', 'sk_xx', 103, 1, '2025-12-15 23:16:54', 1, '2026-03-15 19:18:48', '对话模型', 0);
INSERT INTO `chat_model` (`id`, `category`, `model_name`, `provider_code`, `model_describe`, `model_dimension`, `model_show`, `api_host`, `api_key`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`, `tenant_id`) VALUES (2007528268536287233, 'vector', 'embedding-3', 'zhipu', 'embedding-3', 2048, 'N', 'https://open.bigmodel.cn', 'sk_xx', 103, 1, '2026-01-04 03:03:32', 1, '2026-03-15 19:18:51', '向量模型', 0);
INSERT INTO `chat_model` (`id`, `category`, `model_name`, `provider_code`, `model_describe`, `model_dimension`, `model_show`, `api_host`, `api_key`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`, `tenant_id`) VALUES (2045071617578237953, 'rerank', 'rerank', 'zhipu', 'rerank', NULL, 'N', 'https://open.bigmodel.cn', 'sk_xx', 103, 1, '2026-04-17 17:27:24', 1, '2026-04-20 15:21:48', '重排序模型', 0);
-- ----------------------------
-- Table structure for chat_provider
@@ -95,22 +94,25 @@ CREATE TABLE `chat_provider` (
`update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
`version` int NULL DEFAULT NULL COMMENT '版本',
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '删除标志0代表存在 1代表删除',
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '删除标志',
`update_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '更新IP',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户Id',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `unique_provider_code`(`provider_code` ASC, `tenant_id` ASC) USING BTREE,
UNIQUE INDEX `unique_provider_code`(`provider_code` ASC, `tenant_id` ASC, `del_flag` ASC) USING BTREE,
INDEX `idx_status`(`status` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2008460994477690882 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '厂商管理表' ROW_FORMAT = DYNAMIC;
) ENGINE = InnoDB AUTO_INCREMENT = 2045727230803255298 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '厂商管理表' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- 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 (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 (11, '深度求索', 'deepseek', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/04/19/5ba8c30f153246898a4d7dc7b846de8d.png', 'DeepSeek官方API', 'https://api.deepseek.com', '0', 0, 103, '2026-04-19 12:52:34', '1', '1', '2026-04-19 13:13:25', 'DeepSeek官方API', NULL, '0', NULL, 0);
INSERT INTO `chat_provider` VALUES (12, '智谱AI', 'zhipu', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/04/19/da071783c9284fdd9ed1ce1b57b3c75c.png', '智谱AI大模型服务', 'https://open.bigmodel.cn', '0', 4, 103, '2025-12-14 21:48:11', '1', '1', '2026-04-19 13:14:00', '智谱AI厂商', NULL, '0', NULL, 0);
INSERT INTO `chat_provider` VALUES (13, '小米MIMO', 'xiaomi', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/04/19/18dd39365ce244e3ae5e030da036760e.png', '小米官方API', 'https://api.xiaomimimo.com/v1', '0', 3, 103, '2026-04-19 12:48:24', '1', '1', '2026-04-19 13:14:22', '小米官方API', NULL, '0', NULL, 0);
INSERT INTO `chat_provider` VALUES (14, '阿里云百炼', 'qianwen', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/de2aa7e649de44f3ba5c6380ac6acd04.png', '阿里云百炼大模型服务', 'https://dashscope.aliyuncs.com', '0', 2, 103, '2025-12-14 21:48:11', '1', '1', '2026-02-25 20:49:13', '阿里云厂商', NULL, '0', NULL, 0);
INSERT INTO `chat_provider` VALUES (15, 'Atlas Cloud', 'atlas', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/04/19/atlascloud.png', '全模态AI推理平台', 'https://api.atlascloud.ai/v1', '0', 5, 103, '2025-12-15 23:13:42', '1', '1', '2026-02-25 20:49:01', 'Atlas Cloud AI平台', NULL, '0', NULL, 0);
INSERT INTO `chat_provider` VALUES (16, 'MiniMax', 'minimax', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/04/19/fdc712e90e0e4d78b05862ad230884e5.png', 'MiniMax大模型服务支持M2.7、M2.5等模型', 'https://api.minimax.io/v1', '0', 6, 103, '2026-04-19 12:50:12', '1', '1', '2026-04-19 13:14:59', 'MiniMax厂商', NULL, '0', NULL, 0);
INSERT INTO `chat_provider` VALUES (17, 'ollama', 'ollama', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/afecabebc8014d80b0f06b4796a74c5d.png', 'ollama大模型', 'http://127.0.0.1:11434', '0', 7, 103, '2025-12-14 21:48:11', '1', '1', '2026-02-25 20:48:48', 'ollama厂商', NULL, '0', NULL, 0);
INSERT INTO `chat_provider` VALUES (18, '自定义厂商', 'custom_api', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/04/19/c1a8e122510f4e2f90deb36958af710b.png', 'OPENAI兼容格式', '自定义', '0', 8, 103, '2026-04-19 12:35:57', '1', '1', '2026-04-19 13:17:20', 'OPENAI兼容格式', NULL, '0', NULL, 0);
-- ----------------------------
-- Table structure for chat_session
@@ -1086,6 +1088,7 @@ CREATE TABLE `knowledge_attach` (
`update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户Id',
`status` tinyint NULL DEFAULT 0 COMMENT '解析状态: 0待解析, 1解析中, 2已解析, 3解析失败',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `idx_kname`(`knowledge_id` ASC, `name` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2033199209203183619 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '知识库附件' ROW_FORMAT = DYNAMIC;
@@ -1110,7 +1113,9 @@ CREATE TABLE `knowledge_fragment` (
`update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户Id',
PRIMARY KEY (`id`) USING BTREE
`knowledge_id` bigint NULL DEFAULT NULL COMMENT '知识库ID',
PRIMARY KEY (`id`) USING BTREE,
FULLTEXT INDEX `ft_content`(`content`) WITH PARSER `ngram`
) ENGINE = InnoDB AUTO_INCREMENT = 2033199209131880451 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '知识片段' ROW_FORMAT = DYNAMIC;
-- ----------------------------
@@ -1130,6 +1135,7 @@ CREATE TABLE `knowledge_info` (
`separator` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '知识分隔符',
`overlap_char` int NULL DEFAULT NULL COMMENT '重叠字符数',
`retrieve_limit` int NULL DEFAULT NULL COMMENT '知识库中检索的条数',
`similarity_threshold` double NULL DEFAULT 0.5 COMMENT '相似度阈值',
`text_block_size` int NULL DEFAULT NULL COMMENT '文本块大小',
`vector_model` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '向量库',
`embedding_model` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '向量模型',
@@ -1140,6 +1146,13 @@ CREATE TABLE `knowledge_info` (
`update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户Id',
`enable_rerank` tinyint NULL DEFAULT 0 COMMENT '是否启用重排序0否 1是',
`rerank_score_threshold` double NULL DEFAULT NULL COMMENT '重排序相关性分数阈值',
`rerank_top_n` int NULL DEFAULT NULL COMMENT '重排序后返回的文档数量',
`rerank_model` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '重排序模型名称',
`enable_hybrid` tinyint(1) NULL DEFAULT 0 COMMENT '是否启用混合检索',
`hybrid_alpha` double NULL DEFAULT 0.5 COMMENT '混合检索权重比例 (0.0=纯向量, 1.0=纯关键词)',
`system_prompt` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '系统提示词',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2033198818050781187 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '知识库' ROW_FORMAT = DYNAMIC;
@@ -1169,7 +1182,7 @@ CREATE TABLE `mcp_market_info` (
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;
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'MCP市场表' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of mcp_market_info
@@ -1193,7 +1206,7 @@ CREATE TABLE `mcp_market_tool` (
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;
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'MCP市场工具关联表' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of mcp_market_tool
@@ -1222,7 +1235,7 @@ CREATE TABLE `mcp_tool_info` (
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 = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'MCP工具表' ROW_FORMAT = Dynamic;
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'MCP工具表' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of mcp_tool_info
@@ -2080,6 +2093,7 @@ INSERT INTO `sys_dict_data` VALUES (2026642525081116674, '000000', 1, '图像',
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);
INSERT INTO `sys_dict_data` VALUES (2045070879435259905, '000000', 4, '重排序', 'rerank', 'chat_model_category', NULL, '#000000', 'N', 103, 1, '2026-04-17 17:24:28', 1, '2026-04-19 01:02:20', '重排序模型');
-- ----------------------------
-- Table structure for sys_dict_type
@@ -2151,243 +2165,6 @@ CREATE TABLE `sys_logininfor` (
-- ----------------------------
-- Records of sys_logininfor
-- ----------------------------
INSERT INTO `sys_logininfor` VALUES (2018437160497668098, '000000', 'admin', 'web', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 05:31:34');
INSERT INTO `sys_logininfor` VALUES (2018489328494317570, '000000', 'admin', 'web', 'pc', '58.56.198.114', '中国|山东省|泰安市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 08:58:52');
INSERT INTO `sys_logininfor` VALUES (2018490223370047490, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 09:02:26');
INSERT INTO `sys_logininfor` VALUES (2018494821124149250, '000000', 'admin', 'web', 'pc', '180.165.21.147', '中国|上海|上海市|电信', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 09:20:42');
INSERT INTO `sys_logininfor` VALUES (2018495323429801985, '000000', 'admin', 'web', 'pc', '218.1.209.117', '中国|上海|上海市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 09:22:42');
INSERT INTO `sys_logininfor` VALUES (2018496463106084866, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 09:27:13');
INSERT INTO `sys_logininfor` VALUES (2018506873276338177, '000000', 'admin', 'web', 'pc', '14.155.110.230', '中国|广东省|深圳市|电信', 'Chrome', 'OSX', '0', 'Login successful', '2026-02-03 10:08:35');
INSERT INTO `sys_logininfor` VALUES (2018507142684872705, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'OSX', '0', '登录成功', '2026-02-03 10:09:40');
INSERT INTO `sys_logininfor` VALUES (2018507255759114241, '000000', 'admin', 'web', 'pc', '27.156.68.14', '中国|福建省|福州市|电信', 'Chrome', 'OSX', '0', 'Login successful', '2026-02-03 10:10:06');
INSERT INTO `sys_logininfor` VALUES (2018507799294775297, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 10:12:16');
INSERT INTO `sys_logininfor` VALUES (2018507878344822786, '000000', 'admin', 'web', 'pc', '39.78.246.253', '中国|山东省|济南市|联通', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 10:12:35');
INSERT INTO `sys_logininfor` VALUES (2018508087959359489, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 10:13:25');
INSERT INTO `sys_logininfor` VALUES (2018513467045187586, '000000', 'admin', 'web', 'pc', '111.175.56.210', '中国|湖北省|武汉市|电信', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 10:34:47');
INSERT INTO `sys_logininfor` VALUES (2018515864068952066, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 10:44:19');
INSERT INTO `sys_logininfor` VALUES (2018516837059399682, '000000', 'admin', 'web', 'pc', '115.236.45.35', '中国|浙江省|杭州市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 10:48:11');
INSERT INTO `sys_logininfor` VALUES (2018517630747545602, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 10:51:20');
INSERT INTO `sys_logininfor` VALUES (2018530038144700418, '000000', 'admin', 'web', 'pc', '116.128.248.194', '中国|湖南省|长沙市|联通', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 11:40:38');
INSERT INTO `sys_logininfor` VALUES (2018531663223590914, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 11:47:06');
INSERT INTO `sys_logininfor` VALUES (2018534417249734658, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 11:58:02');
INSERT INTO `sys_logininfor` VALUES (2018537768200835074, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 12:11:21');
INSERT INTO `sys_logininfor` VALUES (2018537900388519937, '000000', 'admin', 'web', 'pc', '183.54.238.100', '中国|广东省|广州市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 12:11:53');
INSERT INTO `sys_logininfor` VALUES (2018549455184334849, '000000', 'admin', 'web', 'pc', '13.212.58.4', '美国|康涅狄格|亚马逊', 'Chrome', 'OSX', '0', 'Login successful', '2026-02-03 12:57:48');
INSERT INTO `sys_logininfor` VALUES (2018554371911061506, '000000', 'admin', 'web', 'pc', '61.182.224.157', '中国|河北省|石家庄市|联通', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 13:17:20');
INSERT INTO `sys_logininfor` VALUES (2018560767549378562, '000000', 'admin', 'web', 'pc', '106.39.125.218', '中国|北京|北京市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 13:42:45');
INSERT INTO `sys_logininfor` VALUES (2018567861803552769, '000000', 'admin', 'web', 'pc', '58.16.14.89', '中国|贵州省|贵阳市|联通', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 14:10:56');
INSERT INTO `sys_logininfor` VALUES (2018568178360258561, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 14:12:12');
INSERT INTO `sys_logininfor` VALUES (2018571219020943362, '000000', 'admin', 'web', 'pc', '116.169.71.139', '中国|辽宁省|威瑞森', 'Chrome', 'OSX', '0', 'Login successful', '2026-02-03 14:24:17');
INSERT INTO `sys_logininfor` VALUES (2018574610824564737, '000000', 'admin', 'web', 'pc', '113.13.108.124', '中国|广西|柳州市|电信', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 14:37:45');
INSERT INTO `sys_logininfor` VALUES (2018574668861149186, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 14:37:59');
INSERT INTO `sys_logininfor` VALUES (2018577941697531906, '000000', 'admin', 'web', 'pc', '36.110.12.226', '中国|北京|北京市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 14:50:59');
INSERT INTO `sys_logininfor` VALUES (2018578431793565697, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'OSX', '0', '登录成功', '2026-02-03 14:52:56');
INSERT INTO `sys_logininfor` VALUES (2018582006717775874, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 15:07:08');
INSERT INTO `sys_logininfor` VALUES (2018582568484605953, '000000', 'admin', 'web', 'pc', '223.104.43.1', '中国|北京|北京市|移动', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 15:09:22');
INSERT INTO `sys_logininfor` VALUES (2018585018155274242, '000000', 'admin', 'web', 'pc', '116.169.127.68', '中国|辽宁省|威瑞森', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 15:19:06');
INSERT INTO `sys_logininfor` VALUES (2018586528248791041, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 15:25:07');
INSERT INTO `sys_logininfor` VALUES (2018586925091393537, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 15:26:41');
INSERT INTO `sys_logininfor` VALUES (2018587111276548097, '000000', 'admin', 'web', 'pc', '117.159.171.116', '中国|河南省|焦作市|移动', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 15:27:26');
INSERT INTO `sys_logininfor` VALUES (2018588210859479041, '000000', 'admin', 'web', 'pc', '61.169.93.182', '中国|上海|上海市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 15:31:48');
INSERT INTO `sys_logininfor` VALUES (2018588453218947074, '000000', 'admin', 'web', 'pc', '61.133.210.59', '中国|宁夏|银川市|电信', 'MSEdge', 'Windows 10 or Windows Server 2016', '1', 'Password input error 1 times', '2026-02-03 15:32:45');
INSERT INTO `sys_logininfor` VALUES (2018588518431985666, '000000', 'admin', 'web', 'pc', '61.133.210.59', '中国|宁夏|银川市|电信', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 15:33:01');
INSERT INTO `sys_logininfor` VALUES (2018588841208844289, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 15:34:18');
INSERT INTO `sys_logininfor` VALUES (2018589986920730625, '000000', 'admin', 'web', 'pc', '115.236.69.226', '中国|浙江省|杭州市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 15:38:51');
INSERT INTO `sys_logininfor` VALUES (2018590616590618625, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 15:41:21');
INSERT INTO `sys_logininfor` VALUES (2018593068400381953, '000000', 'admin', 'web', 'pc', '180.123.251.84', '中国|江苏省|徐州市|电信', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 15:51:06');
INSERT INTO `sys_logininfor` VALUES (2018594019760803842, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 15:54:53');
INSERT INTO `sys_logininfor` VALUES (2018595653618372609, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 16:01:22');
INSERT INTO `sys_logininfor` VALUES (2018596016505360386, '000000', 'admin', 'web', 'pc', '114.242.16.161', '中国|北京|北京市|联通', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 16:02:49');
INSERT INTO `sys_logininfor` VALUES (2018596170675392513, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 16:03:25');
INSERT INTO `sys_logininfor` VALUES (2018599719354372098, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 16:17:32');
INSERT INTO `sys_logininfor` VALUES (2018599739910656001, '000000', 'admin', 'web', 'pc', '42.235.239.253', '中国|河南省|新乡市|联通', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 16:17:36');
INSERT INTO `sys_logininfor` VALUES (2018600606151872513, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 16:21:03');
INSERT INTO `sys_logininfor` VALUES (2018600933580214274, '000000', 'admin', 'web', 'pc', '219.142.141.194', '中国|北京|北京市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 16:22:21');
INSERT INTO `sys_logininfor` VALUES (2018602589315272705, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'OSX', '0', '登录成功', '2026-02-03 16:28:56');
INSERT INTO `sys_logininfor` VALUES (2018605159794479105, '000000', 'admin', 'web', 'pc', '222.168.89.242', '中国|吉林省|长春市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 16:39:09');
INSERT INTO `sys_logininfor` VALUES (2018609628598898690, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'OSX', '0', '登录成功', '2026-02-03 16:56:54');
INSERT INTO `sys_logininfor` VALUES (2018609656977559553, '000000', 'admin', 'web', 'pc', '121.35.46.195', '中国|广东省|深圳市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 16:57:01');
INSERT INTO `sys_logininfor` VALUES (2018610104228777985, '000000', 'admin', 'web', 'pc', '115.236.69.226', '中国|浙江省|杭州市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 16:58:47');
INSERT INTO `sys_logininfor` VALUES (2018610284827119618, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 16:59:31');
INSERT INTO `sys_logininfor` VALUES (2018611513854660610, '000000', 'admin ', 'web', 'pc', '222.90.12.243', '中国|陕西省|西安市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '1', 'Password input error 1 times', '2026-02-03 17:04:24');
INSERT INTO `sys_logininfor` VALUES (2018611519181426690, '000000', 'admin ', 'web', 'pc', '222.90.12.243', '中国|陕西省|西安市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '1', 'Password input error 2 times', '2026-02-03 17:04:25');
INSERT INTO `sys_logininfor` VALUES (2018611644431732738, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 17:04:55');
INSERT INTO `sys_logininfor` VALUES (2018611724014456833, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 17:05:14');
INSERT INTO `sys_logininfor` VALUES (2018612993819021314, '000000', 'admin', 'web', 'pc', '223.160.130.33', '中国|北京|北京市|广电', 'Chrome', 'OSX', '0', 'Login successful', '2026-02-03 17:10:16');
INSERT INTO `sys_logininfor` VALUES (2018614987845668866, '000000', 'admin ', 'web', 'pc', '222.90.12.243', '中国|陕西省|西安市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '1', 'Password input error 1 times', '2026-02-03 17:18:12');
INSERT INTO `sys_logininfor` VALUES (2018615005365276674, '000000', 'admin', 'web', 'pc', '222.90.12.243', '中国|陕西省|西安市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 17:18:16');
INSERT INTO `sys_logininfor` VALUES (2018615245262688258, '000000', 'admin', 'web', 'pc', '61.184.94.104', '中国|湖北省|十堰市|电信', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 17:19:13');
INSERT INTO `sys_logininfor` VALUES (2018615451685359617, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 17:20:02');
INSERT INTO `sys_logininfor` VALUES (2018615588662939650, '000000', 'admin', 'web', 'pc', '183.241.255.169', '中国|北京|北京市|移动', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 17:20:35');
INSERT INTO `sys_logininfor` VALUES (2018615733957824514, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 17:21:10');
INSERT INTO `sys_logininfor` VALUES (2018618361873829889, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 17:31:36');
INSERT INTO `sys_logininfor` VALUES (2018619606214774785, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 17:36:33');
INSERT INTO `sys_logininfor` VALUES (2018621042193469441, '000000', 'admin', 'web', 'pc', '27.227.167.177', '中国|甘肃省|兰州市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 17:42:15');
INSERT INTO `sys_logininfor` VALUES (2018623610328059905, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 17:52:28');
INSERT INTO `sys_logininfor` VALUES (2018623677315289089, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'OSX', '0', '登录成功', '2026-02-03 17:52:44');
INSERT INTO `sys_logininfor` VALUES (2018623870995664897, '000000', 'admin', 'web', 'pc', '59.57.134.162', '中国|福建省|厦门市|电信', 'Chrome', 'OSX', '0', 'Login successful', '2026-02-03 17:53:30');
INSERT INTO `sys_logininfor` VALUES (2018624044400775169, '000000', 'admin', 'web', 'pc', '39.162.49.29', '中国|河南省|郑州市|移动', 'Chrome', 'Windows 10 or Windows Server 2016', '1', 'Password input error 1 times', '2026-02-03 17:54:11');
INSERT INTO `sys_logininfor` VALUES (2018624054987198465, '000000', 'admin', 'web', 'pc', '39.162.49.29', '中国|河南省|郑州市|移动', 'Chrome', 'Windows 10 or Windows Server 2016', '1', 'Password input error 2 times', '2026-02-03 17:54:14');
INSERT INTO `sys_logininfor` VALUES (2018624077900681218, '000000', 'admin', 'web', 'pc', '39.162.49.29', '中国|河南省|郑州市|移动', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 17:54:19');
INSERT INTO `sys_logininfor` VALUES (2018625637493903362, '000000', 'admin', 'web', 'pc', '114.253.10.114', '中国|北京|北京市|联通', 'Chrome', 'OSX', '0', 'Login successful', '2026-02-03 18:00:31');
INSERT INTO `sys_logininfor` VALUES (2018625743718846465, '000000', 'admin', 'web', 'pc', '111.198.137.189', '中国|北京|北京市|联通', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 18:00:56');
INSERT INTO `sys_logininfor` VALUES (2018625749372768258, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'OSX', '0', '登录成功', '2026-02-03 18:00:58');
INSERT INTO `sys_logininfor` VALUES (2018625771480944641, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 18:01:03');
INSERT INTO `sys_logininfor` VALUES (2018625852410040321, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'OSX', '0', '退出成功', '2026-02-03 18:01:22');
INSERT INTO `sys_logininfor` VALUES (2018625877240320002, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'OSX', '0', '登录成功', '2026-02-03 18:01:28');
INSERT INTO `sys_logininfor` VALUES (2018627882260238337, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 18:09:26');
INSERT INTO `sys_logininfor` VALUES (2018628150670528513, '000000', 'admin', 'web', 'pc', '114.253.10.114', '中国|北京|北京市|联通', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 18:10:30');
INSERT INTO `sys_logininfor` VALUES (2018672955786137601, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 21:08:32');
INSERT INTO `sys_logininfor` VALUES (2018689142062452738, '000000', 'admin ', 'web', 'pc', '221.205.106.23', '中国|山西省|太原市|联通', 'Chrome', 'Windows 10 or Windows Server 2016', '1', 'Password input error 1 times', '2026-02-03 22:12:52');
INSERT INTO `sys_logininfor` VALUES (2018689178624200706, '000000', 'admin', 'web', 'pc', '221.205.106.23', '中国|山西省|太原市|联通', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 22:13:00');
INSERT INTO `sys_logininfor` VALUES (2018689429430996993, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 22:14:00');
INSERT INTO `sys_logininfor` VALUES (2018693323410247681, '000000', 'admin', 'web', 'pc', '140.206.143.69', '中国|上海|上海市|联通', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 22:29:28');
INSERT INTO `sys_logininfor` VALUES (2018694798878314498, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'OSX', '0', '登录成功', '2026-02-03 22:35:20');
INSERT INTO `sys_logininfor` VALUES (2018710386166075394, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 23:37:17');
INSERT INTO `sys_logininfor` VALUES (2018715692476534785, '000000', 'admin', 'web', 'pc', '113.248.49.12', '中国|重庆|重庆市|电信', 'Firefox', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-03 23:58:22');
INSERT INTO `sys_logininfor` VALUES (2018715768049504257, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Firefox', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-03 23:58:40');
INSERT INTO `sys_logininfor` VALUES (2018745408302485505, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 01:56:26');
INSERT INTO `sys_logininfor` VALUES (2018745476409593857, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '退出成功', '2026-02-04 01:56:43');
INSERT INTO `sys_logininfor` VALUES (2018852568944480258, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'OSX', '0', '登录成功', '2026-02-04 09:02:16');
INSERT INTO `sys_logininfor` VALUES (2018852760607395842, '000000', 'admin', 'web', 'pc', '39.170.0.61', '中国|浙江省|杭州市|移动', 'Chrome', 'OSX', '0', 'Login successful', '2026-02-04 09:03:01');
INSERT INTO `sys_logininfor` VALUES (2018855559080579073, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 09:14:08');
INSERT INTO `sys_logininfor` VALUES (2018856680327090177, '000000', 'admin', 'web', 'pc', '180.201.162.34', '中国|山东省|青岛市|教育网', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 09:18:36');
INSERT INTO `sys_logininfor` VALUES (2018856825580032001, '000000', 'admin', 'web', 'pc', '60.10.20.65', '中国|河北省|廊坊市|联通', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 09:19:10');
INSERT INTO `sys_logininfor` VALUES (2018857125414047745, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 09:20:22');
INSERT INTO `sys_logininfor` VALUES (2018857183823925249, '000000', 'admin', 'web', 'pc', '114.253.10.114', '中国|北京|北京市|联通', 'Chrome', 'OSX', '0', 'Login successful', '2026-02-04 09:20:36');
INSERT INTO `sys_logininfor` VALUES (2018857493854294017, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'OSX', '0', '登录成功', '2026-02-04 09:21:50');
INSERT INTO `sys_logininfor` VALUES (2018860201030062082, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 09:32:35');
INSERT INTO `sys_logininfor` VALUES (2018860399353532418, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 09:33:22');
INSERT INTO `sys_logininfor` VALUES (2018860419058372609, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 09:33:27');
INSERT INTO `sys_logininfor` VALUES (2018862938719391745, '000000', 'admin', 'web', 'pc', '113.65.15.168', '中国|广东省|广州市|电信', 'Firefox', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 09:43:28');
INSERT INTO `sys_logininfor` VALUES (2018863017278705665, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Firefox', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 09:43:47');
INSERT INTO `sys_logininfor` VALUES (2018863424306548737, '000000', 'admin', 'web', 'pc', '114.253.10.114', '中国|北京|北京市|联通', 'Chrome', 'OSX', '0', 'Login successful', '2026-02-04 09:45:24');
INSERT INTO `sys_logininfor` VALUES (2018864538947031042, '000000', 'admin', 'web', 'pc', '114.224.36.132', '中国|江苏省|无锡市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 09:49:49');
INSERT INTO `sys_logininfor` VALUES (2018864646790975490, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 09:50:15');
INSERT INTO `sys_logininfor` VALUES (2018864913326411777, '000000', 'admin', 'web', 'pc', '14.220.151.192', '中国|广东省|东莞市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 09:51:19');
INSERT INTO `sys_logininfor` VALUES (2018865224053035009, '000000', 'admin', 'web', 'pc', '8.220.210.62', '中国|阿里巴巴', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 09:52:33');
INSERT INTO `sys_logininfor` VALUES (2018865354428780546, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 09:53:04');
INSERT INTO `sys_logininfor` VALUES (2018865432400891905, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 09:53:22');
INSERT INTO `sys_logininfor` VALUES (2018865469902163970, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '退出成功', '2026-02-04 09:53:31');
INSERT INTO `sys_logininfor` VALUES (2018865485031018498, '154726', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 09:53:35');
INSERT INTO `sys_logininfor` VALUES (2018865600516984833, '154726', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '退出成功', '2026-02-04 09:54:03');
INSERT INTO `sys_logininfor` VALUES (2018865826023739394, '000000', 'admin', 'web', 'pc', '113.104.237.0', '中国|广东省|深圳市|电信', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 09:54:56');
INSERT INTO `sys_logininfor` VALUES (2018865939207032834, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 09:55:23');
INSERT INTO `sys_logininfor` VALUES (2018868158258089986, '000000', 'admin', 'web', 'pc', '39.170.71.231', '中国|浙江省|杭州市|移动', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 10:04:12');
INSERT INTO `sys_logininfor` VALUES (2018868610617970690, '000000', 'admin', 'web', 'pc', '219.152.39.216', '中国|重庆|重庆市|电信', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 10:06:00');
INSERT INTO `sys_logininfor` VALUES (2018870568124813313, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 10:13:47');
INSERT INTO `sys_logininfor` VALUES (2018882173784952834, '000000', 'admin', 'web', 'pc', '220.196.184.73', '中国|上海|上海市|联通', 'Chrome', 'Windows 10 or Windows Server 2016', '1', 'Password input error 1 times', '2026-02-04 10:59:54');
INSERT INTO `sys_logininfor` VALUES (2018882179346599938, '000000', 'admin', 'web', 'pc', '220.196.184.73', '中国|上海|上海市|联通', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 10:59:55');
INSERT INTO `sys_logininfor` VALUES (2018882457076633602, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 11:01:01');
INSERT INTO `sys_logininfor` VALUES (2018882886007132162, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 11:02:44');
INSERT INTO `sys_logininfor` VALUES (2018883626641526786, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Firefox', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 11:05:40');
INSERT INTO `sys_logininfor` VALUES (2018885851870793730, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 11:14:31');
INSERT INTO `sys_logininfor` VALUES (2018887170559971330, '000000', 'admin', 'web', 'pc', '114.222.24.76', '中国|江苏省|南京市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 11:19:45');
INSERT INTO `sys_logininfor` VALUES (2018887913358626817, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 11:22:42');
INSERT INTO `sys_logininfor` VALUES (2018889490362404865, '000000', 'admin', 'web', 'pc', '124.165.224.106', '中国|山西省|吕梁市|联通', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 11:28:58');
INSERT INTO `sys_logininfor` VALUES (2018891240427360257, '000000', 'admin', 'web', 'pc', '163.142.243.239', '中国|广东省|佛山市|联通', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 11:35:56');
INSERT INTO `sys_logininfor` VALUES (2018895246847512578, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 11:51:51');
INSERT INTO `sys_logininfor` VALUES (2018897167293485058, '000000', 'admin', 'web', 'pc', '113.57.48.151', '中国|湖北省|武汉市|联通', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 11:59:29');
INSERT INTO `sys_logininfor` VALUES (2018898894247825410, '000000', 'admin', 'web', 'pc', '114.254.1.2', '中国|北京|北京市|联通', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 12:06:20');
INSERT INTO `sys_logininfor` VALUES (2018899094601338882, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 12:07:08');
INSERT INTO `sys_logininfor` VALUES (2018916480444403714, '000000', 'admin', 'web', 'pc', '219.143.206.106', '中国|北京|北京市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 13:16:13');
INSERT INTO `sys_logininfor` VALUES (2018916794622939137, '000000', 'admin', 'web', 'pc', '116.252.72.152', '中国|广西|南宁市|电信', 'Chrome', 'OSX', '0', 'Login successful', '2026-02-04 13:17:28');
INSERT INTO `sys_logininfor` VALUES (2018917938204119041, '000000', 'admin', 'web', 'pc', '219.143.206.106', '中国|北京|北京市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 13:22:01');
INSERT INTO `sys_logininfor` VALUES (2018918018160136193, '000000', 'admin', 'web', 'pc', '218.240.181.5', '中国|北京|北京市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 13:22:20');
INSERT INTO `sys_logininfor` VALUES (2018918326378565634, '000000', 'admin', 'web', 'pc', '218.240.181.5', '中国|北京|北京市|电信', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 13:23:33');
INSERT INTO `sys_logininfor` VALUES (2018920804255928322, '000000', 'admin', 'web', 'pc', '219.143.206.106', '中国|北京|北京市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 13:33:24');
INSERT INTO `sys_logininfor` VALUES (2018921548166074369, '000000', 'admin', 'web', 'pc', '219.143.206.106', '中国|北京|北京市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 13:36:21');
INSERT INTO `sys_logininfor` VALUES (2018922995012210690, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Quark', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 13:42:06');
INSERT INTO `sys_logininfor` VALUES (2018926354117038082, '000000', 'admin', 'web', 'pc', '8.220.210.62', '中国|阿里巴巴', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 13:55:27');
INSERT INTO `sys_logininfor` VALUES (2018927011129593858, '000000', 'admin', 'web', 'pc', '60.190.252.115', '中国|浙江省|杭州市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 13:58:04');
INSERT INTO `sys_logininfor` VALUES (2018927468619108353, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 13:59:53');
INSERT INTO `sys_logininfor` VALUES (2018927515784056834, '000000', 'admin', 'web', 'pc', '14.111.243.245', '中国|重庆|重庆市|电信', 'MSEdge', 'Windows 10 or Windows Server 2016', '1', 'Password input error 1 times', '2026-02-04 14:00:04');
INSERT INTO `sys_logininfor` VALUES (2018927562521186305, '000000', 'admin', 'web', 'pc', '14.111.243.245', '中国|重庆|重庆市|电信', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 14:00:15');
INSERT INTO `sys_logininfor` VALUES (2018929485043339265, '000000', 'admin', 'web', 'pc', '124.114.150.254', '中国|陕西省|西安市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 14:07:54');
INSERT INTO `sys_logininfor` VALUES (2018931277877612545, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 14:15:01');
INSERT INTO `sys_logininfor` VALUES (2018933698284621826, '000000', 'admin', 'web', 'pc', '222.35.11.50', '中国|北京|北京市|铁通', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 14:24:38');
INSERT INTO `sys_logininfor` VALUES (2018933723182010369, '000000', 'admin', 'web', 'pc', '183.162.217.80', '中国|安徽省|蚌埠市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 14:24:44');
INSERT INTO `sys_logininfor` VALUES (2018933918011625473, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 14:25:31');
INSERT INTO `sys_logininfor` VALUES (2018935595993272322, '000000', 'admin', 'web', 'pc', '122.225.239.202', '中国|浙江省|嘉兴市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 14:32:11');
INSERT INTO `sys_logininfor` VALUES (2018937821423865857, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 14:41:01');
INSERT INTO `sys_logininfor` VALUES (2018938936521527298, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 14:45:27');
INSERT INTO `sys_logininfor` VALUES (2018946088032145409, '000000', 'admin', 'web', 'pc', '223.104.202.88', '中国|陕西省|咸阳市|移动', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 15:13:52');
INSERT INTO `sys_logininfor` VALUES (2018946463766286337, '000000', 'admin', 'web', 'pc', '114.139.48.241', '中国|贵州省|遵义市|电信', 'Chrome', 'OSX', '0', 'Login successful', '2026-02-04 15:15:22');
INSERT INTO `sys_logininfor` VALUES (2018948323336130562, '000000', 'admin', 'web', 'pc', '113.207.43.98', '中国|重庆|重庆市|联通', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 15:22:45');
INSERT INTO `sys_logininfor` VALUES (2018948839856279554, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 15:24:48');
INSERT INTO `sys_logininfor` VALUES (2018950286861799426, '000000', 'admin', 'web', 'pc', '112.224.162.237', '中国|山东省|联通', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 15:30:33');
INSERT INTO `sys_logininfor` VALUES (2018950904724721665, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 15:33:01');
INSERT INTO `sys_logininfor` VALUES (2018950963323342849, '000000', 'admin', 'web', 'pc', '182.132.201.232', '中国|四川省|眉山市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 15:33:15');
INSERT INTO `sys_logininfor` VALUES (2018950986727559170, '000000', 'admin', 'web', 'pc', '111.8.48.211', '中国|湖南省|长沙市|移动', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 15:33:20');
INSERT INTO `sys_logininfor` VALUES (2018951848111771650, '000000', 'admin', 'web', 'pc', '219.138.228.254', '中国|湖北省|鄂州市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 15:36:46');
INSERT INTO `sys_logininfor` VALUES (2018952415047454722, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 15:39:01');
INSERT INTO `sys_logininfor` VALUES (2018954681871634433, '000000', 'admin', 'web', 'pc', '123.235.153.115', '中国|山东省|青岛市|联通', 'MicroMessenger', 'OSX', '0', 'Login successful', '2026-02-04 15:48:01');
INSERT INTO `sys_logininfor` VALUES (2018959635684397057, '000000', 'admin', 'web', 'pc', '58.56.198.114', '中国|山东省|泰安市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 16:07:42');
INSERT INTO `sys_logininfor` VALUES (2018961274495438849, '000000', 'admin', 'web', 'pc', '120.197.21.117', '中国|广东省|广州市|移动', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 16:14:13');
INSERT INTO `sys_logininfor` VALUES (2018961365956431873, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 16:14:35');
INSERT INTO `sys_logininfor` VALUES (2018961449058177025, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 16:14:55');
INSERT INTO `sys_logininfor` VALUES (2018961841162686465, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 16:16:28');
INSERT INTO `sys_logininfor` VALUES (2018961976873586689, '000000', 'admin', 'web', 'pc', '36.112.184.220', '中国|北京|北京市|电信', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 16:17:00');
INSERT INTO `sys_logininfor` VALUES (2018962175272554497, '000000', 'admin', 'web', 'pc', '39.144.212.209', '中国|移动', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 16:17:48');
INSERT INTO `sys_logininfor` VALUES (2018962369447858177, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 16:18:34');
INSERT INTO `sys_logininfor` VALUES (2018963149303189505, '000000', 'admin', 'web', 'pc', '112.97.202.126', '中国|广东省|东莞市|联通', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 16:21:40');
INSERT INTO `sys_logininfor` VALUES (2018963440199143425, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 16:22:49');
INSERT INTO `sys_logininfor` VALUES (2018966187199827970, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '退出成功', '2026-02-04 16:33:44');
INSERT INTO `sys_logininfor` VALUES (2018966195156422657, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 16:33:46');
INSERT INTO `sys_logininfor` VALUES (2018967272132055041, '000000', 'admin', 'web', 'pc', '121.8.154.218', '中国|广东省|广州市|电信', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 16:38:03');
INSERT INTO `sys_logininfor` VALUES (2018967970655637505, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 16:40:49');
INSERT INTO `sys_logininfor` VALUES (2018968030697099265, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 16:41:04');
INSERT INTO `sys_logininfor` VALUES (2018970160656945154, '000000', 'admin', 'web', 'pc', '183.209.146.73', '中国|江苏省|南京市|移动', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 16:49:32');
INSERT INTO `sys_logininfor` VALUES (2018970873374052354, '000000', 'admin', 'web', 'pc', '60.1.71.196', '中国|河北省|石家庄市|联通', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 16:52:22');
INSERT INTO `sys_logininfor` VALUES (2018970947504181249, '000000', 'admin', 'web', 'pc', '223.88.78.216', '中国|河南省|郑州市|移动', 'Chrome', 'Windows 10 or Windows Server 2016', '0', 'Login successful', '2026-02-04 16:52:39');
INSERT INTO `sys_logininfor` VALUES (2018971098872418305, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 16:53:15');
INSERT INTO `sys_logininfor` VALUES (2018978580902580226, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 17:22:59');
INSERT INTO `sys_logininfor` VALUES (2018978998839808002, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 17:24:39');
INSERT INTO `sys_logininfor` VALUES (2018984098123616257, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 17:44:55');
INSERT INTO `sys_logininfor` VALUES (2018988627267293186, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 18:02:54');
INSERT INTO `sys_logininfor` VALUES (2018990733382520834, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 18:11:17');
INSERT INTO `sys_logininfor` VALUES (2019029939576246274, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 20:47:04');
INSERT INTO `sys_logininfor` VALUES (2019040366678904834, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 21:28:30');
INSERT INTO `sys_logininfor` VALUES (2019057692774109186, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 22:37:21');
INSERT INTO `sys_logininfor` VALUES (2019057715637260289, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-04 22:37:26');
INSERT INTO `sys_logininfor` VALUES (2019113073072279553, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'OSX', '0', '登录成功', '2026-02-05 02:17:25');
INSERT INTO `sys_logininfor` VALUES (2019203832710565889, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-05 08:18:03');
INSERT INTO `sys_logininfor` VALUES (2019210865128116226, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'OSX', '0', '登录成功', '2026-02-05 08:46:00');
INSERT INTO `sys_logininfor` VALUES (2019213517912150018, '154726', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-05 08:56:33');
INSERT INTO `sys_logininfor` VALUES (2019217038615121921, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-05 09:10:32');
INSERT INTO `sys_logininfor` VALUES (2019219134710157314, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Linux', '0', '登录成功', '2026-02-05 09:18:52');
INSERT INTO `sys_logininfor` VALUES (2019222079201157121, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-05 09:30:34');
INSERT INTO `sys_logininfor` VALUES (2019223047400198146, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'OSX', '0', '登录成功', '2026-02-05 09:34:25');
INSERT INTO `sys_logininfor` VALUES (2019224288503140354, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'Chrome', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-05 09:39:20');
INSERT INTO `sys_logininfor` VALUES (2019224998575153153, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '退出成功', '2026-02-05 09:42:10');
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');
INSERT INTO `sys_logininfor` VALUES (2030617171346399233, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-08 20:10:35');
INSERT INTO `sys_logininfor` VALUES (2033083137191841794, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 15:29:27');
INSERT INTO `sys_logininfor` VALUES (2033102367094214657, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 16:45:52');
INSERT INTO `sys_logininfor` VALUES (2033116897354551298, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 17:43:36');
INSERT INTO `sys_logininfor` VALUES (2033133175565836289, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 18:48:17');
INSERT INTO `sys_logininfor` VALUES (2033167392953675778, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 21:04:16');
INSERT INTO `sys_logininfor` VALUES (2033168637663719425, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 21:09:12');
INSERT INTO `sys_logininfor` VALUES (2033170263812157441, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '退出成功', '2026-03-15 21:15:40');
INSERT INTO `sys_logininfor` VALUES (2033170654197002242, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 21:17:13');
INSERT INTO `sys_logininfor` VALUES (2033170805703651330, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '退出成功', '2026-03-15 21:17:49');
INSERT INTO `sys_logininfor` VALUES (2033170821767835650, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 21:17:53');
INSERT INTO `sys_logininfor` VALUES (2033170964009267201, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 21:18:27');
INSERT INTO `sys_logininfor` VALUES (2033197762549985282, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 23:04:56');
INSERT INTO `sys_logininfor` VALUES (2033200372921217025, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '1', '密码输入错误1次', '2026-03-15 23:15:19');
INSERT INTO `sys_logininfor` VALUES (2033200386498179073, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 23:15:22');
INSERT INTO `sys_logininfor` VALUES (2033210457315696642, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-03-15 23:55:23');
-- ----------------------------
-- Table structure for sys_menu
@@ -3171,7 +2948,7 @@ CREATE TABLE `sys_user` (
-- ----------------------------
-- Records of sys_user
-- ----------------------------
INSERT INTO `sys_user` VALUES (1, '000000', 103, 'admin', 'admin', 'sys_user', 'ageerle@163.com', '15888888888', '1', NULL, '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', '2026-03-15 23:55:23', 103, 1, '2026-02-05 09:22:12', -1, '2026-03-15 23:55:23', '管理员', NULL, 0.00);
INSERT INTO `sys_user` VALUES (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-05-19 23:16:57', 103, 1, '2026-02-05 09:22:12', -1, '2026-05-19 23:16:57', '管理员', 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);

View File

@@ -0,0 +1,92 @@
/*
Navicat Premium Dump SQL
Source Server : localhost-mysql
Source Server Type : MySQL
Source Server Version : 80045 (8.0.45)
Source Host : localhost:3306
Source Schema : ruoyi-ai
Target Server Type : MySQL
Target Server Version : 80045 (8.0.45)
File Encoding : 65001
Date: 19/04/2026 13:36:41
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for chat_model
-- ----------------------------
DROP TABLE IF EXISTS `chat_model`;
CREATE TABLE `chat_model` (
`id` bigint NOT NULL COMMENT '主键',
`category` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '模型分类',
`model_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '模型名称',
`provider_code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '模型供应商',
`model_describe` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '模型描述',
`model_dimension` int NULL DEFAULT NULL COMMENT '模型维度',
`model_show` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否显示',
`api_host` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '请求地址',
`api_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '密钥',
`create_dept` bigint NULL DEFAULT NULL COMMENT '创建部门',
`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 '更新时间',
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户Id',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '模型管理' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of chat_model
-- ----------------------------
INSERT INTO `chat_model` VALUES (2000585866022060033, 'chat', 'zai-org/glm-5', 'ppio', 'zai-org/glm-5', NULL, 'Y', 'https://api.ppio.com/openai', 'sk_xx', 103, 1, '2025-12-15 23:16:54', 1, '2026-03-15 19:18:48', 'DeepSeek-V3.2 是一款在高效推理、复杂推理能力与智能体场景中表现突出的领先模型。其基于 DeepSeek Sparse AttentionDSA稀疏注意力机制在显著降低计算开销的同时优化长上下文性能通过可扩展强化学习框架整体能力达到 GPT-5 同级,高算力版本 V3.2-Speciale 更在推理表现上接近 Gemini-3.0-Pro同时模型依托大型智能体任务合成管线具备更强的工具调用与多步骤决策能力并在 2025 年 IMO 与 IOI 中取得金牌级表现。作为 MaaS 平台,我们已对 DeepSeek-V3.2 完成深度适配,通过动态调度、批处理加速、低延迟推理与企业级 SLA 保障,进一步增强其在企业生产环境中的稳定性、性价比与可控性,适用于搜索、问答、智能体、代码、数据处理等多类高价值场景。', 0);
INSERT INTO `chat_model` VALUES (2007528268536287233, 'vector', 'baai/bge-m3', 'ppio', 'bge-m3', 1024, 'N', 'https://api.ppio.com/openai', 'sk_xx', 103, 1, '2026-01-04 03:03:32', 1, '2026-03-15 19:18:51', 'BGE-M3 是一款具备多维度能力的文本嵌入模型可同时实现密集检索、多向量检索和稀疏检索三大核心功能。该模型设计上兼容超过100种语言并支持从短句到长达8192词元的长文本等多种输入形式。在跨语言检索任务中BGE-M3展现出显著优势其性能在MIRACL、MKQA等国际基准测试中位居前列。此外针对长文档检索场景该模型在MLDR、NarritiveQA等数据集上的表现同样达到行业领先水平。', 0);
INSERT INTO `chat_model` VALUES (2045735140488847361, 'chat', 'deepseek-chat', 'custom_api', 'deepseek-chat', NULL, NULL, 'https://api.deepseek.com', 'sk_xx', 103, 1, '2026-04-19 13:24:00', 1, '2026-04-19 13:24:00', 'deepseek对话模型', 0);
-- ----------------------------
-- Table structure for chat_provider
-- ----------------------------
DROP TABLE IF EXISTS `chat_provider`;
CREATE TABLE `chat_provider` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`provider_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '厂商名称',
`provider_code` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '厂商编码',
`provider_icon` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '厂商图标',
`provider_desc` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '厂商描述',
`api_host` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'API地址',
`status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '状态0正常 1停用',
`sort_order` int NULL DEFAULT 0 COMMENT '排序',
`create_dept` bigint NULL DEFAULT NULL COMMENT '创建部门',
`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
`version` int NULL DEFAULT NULL COMMENT '版本',
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '删除标志',
`update_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '更新IP',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户Id',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `unique_provider_code`(`provider_code` ASC, `tenant_id` ASC, `del_flag` ASC) USING BTREE,
INDEX `idx_status`(`status` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2045727230803255298 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '厂商管理表' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- 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, 103, '2025-12-14 21:48:11', '1', '1', '2026-02-25 20:46:59', 'OpenAI厂商', NULL, '0', NULL, 0);
INSERT INTO `chat_provider` VALUES (11, '深度求索', 'deepseek', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/04/19/5ba8c30f153246898a4d7dc7b846de8d.png', 'DeepSeek官方API', 'https://api.deepseek.com', '0', 0, 103, '2026-04-19 12:52:34', '1', '1', '2026-04-19 13:13:25', 'DeepSeek官方API', NULL, '0', NULL, 0);
INSERT INTO `chat_provider` VALUES (12, '智谱AI', 'zhipu', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/04/19/da071783c9284fdd9ed1ce1b57b3c75c.png', '智谱AI大模型服务', 'https://open.bigmodel.cn', '0', 4, 103, '2025-12-14 21:48:11', '1', '1', '2026-04-19 13:14:00', '智谱AI厂商', NULL, '0', NULL, 0);
INSERT INTO `chat_provider` VALUES (13, '小米MIMO', 'xiaomi', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/04/19/18dd39365ce244e3ae5e030da036760e.png', '小米官方API', 'https://api.xiaomimimo.com/anthropic/v1/messages', '0', 3, 103, '2026-04-19 12:48:24', '1', '1', '2026-04-19 13:14:22', '小米官方API', NULL, '0', NULL, 0);
INSERT INTO `chat_provider` VALUES (14, '阿里云百炼', 'qianwen', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/de2aa7e649de44f3ba5c6380ac6acd04.png', '阿里云百炼大模型服务', 'https://dashscope.aliyuncs.com', '0', 2, 103, '2025-12-14 21:48:11', '1', '1', '2026-02-25 20:49:13', '阿里云厂商', NULL, '0', NULL, 0);
INSERT INTO `chat_provider` VALUES (15, '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 (16, 'MiniMax', 'minimax', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/04/19/fdc712e90e0e4d78b05862ad230884e5.png', 'MiniMax大模型服务支持M2.7、M2.5等模型', 'https://api.minimax.io/v1', '0', 6, 103, '2026-04-19 12:50:12', '1', '1', '2026-04-19 13:14:59', 'MiniMax厂商', NULL, '0', NULL, 0);
INSERT INTO `chat_provider` VALUES (17, 'ollama', 'ollama', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/afecabebc8014d80b0f06b4796a74c5d.png', 'ollama大模型', 'http://127.0.0.1:11434', '0', 7, 103, '2025-12-14 21:48:11', '1', '1', '2026-02-25 20:48:48', 'ollama厂商', NULL, '0', NULL, 0);
INSERT INTO `chat_provider` VALUES (18, '自定义厂商', 'custom_api', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/04/19/c1a8e122510f4e2f90deb36958af710b.png', 'OPENAI兼容格式', '自定义', '0', 8, 103, '2026-04-19 12:35:57', '1', '1', '2026-04-19 13:17:20', 'OPENAI兼容格式', NULL, '0', NULL, 0);
SET FOREIGN_KEY_CHECKS = 1;

View File

@@ -0,0 +1,46 @@
/*
Navicat Premium Dump SQL
Source Server : localhost-mysql
Source Server Type : MySQL
Source Server Version : 80045 (8.0.45)
Source Host : localhost:3306
Source Schema : ruoyi-ai
Target Server Type : MySQL
Target Server Version : 80045 (8.0.45)
File Encoding : 65001
Date: 20/04/2026 15:30:00
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- 新增重排序模型chat_model
-- ----------------------------
INSERT INTO `chat_model`
(id, category, model_name, provider_code, model_describe, model_dimension, model_show, api_host, api_key, create_dept, create_by, create_time, update_by, update_time, remark, tenant_id)
VALUES(2045071617578237953, 'rerank', 'rerank', 'zhipu', '智谱重排序', NULL, 'Y', 'https://open.bigmodel.cn', 'e9xx', 103, 1, '2026-04-17 17:27:24', 1, '2026-04-20 15:21:48', '智谱重排序', 0);
INSERT INTO `chat_model`
(id, category, model_name, provider_code, model_describe, model_dimension, model_show, api_host, api_key, create_dept, create_by, create_time, update_by, update_time, remark, tenant_id)
VALUES(2046119803482902530, 'rerank', 'qwen3-rerank', 'qianwen', '千问3重排序', NULL, NULL, 'https://dashscope.aliyuncs.com', 'sk-xx', 103, 1, '2026-04-20 14:52:31', 1, '2026-04-20 15:03:13', '千问3文本重排序', 0);
-- ----------------------------
-- 新增:字典类型 - 重排序模型分类
-- ----------------------------
INSERT INTO `sys_dict_data`
(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark)
VALUES(2045070879435259905, '000000', 4, '重排序', 'rerank', 'chat_model_category', NULL, '#000000', 'N', 103, 1, '2026-04-17 17:24:28', 1, '2026-04-19 01:02:20', '重排序模型');
-- ----------------------------
-- 修改表knowledge_info 增加重排序相关字段
-- ----------------------------
ALTER TABLE `knowledge_info` ADD COLUMN `enable_rerank` tinyint DEFAULT 0 NULL COMMENT '是否启用重排序0否 1是';
ALTER TABLE `knowledge_info` ADD COLUMN `rerank_score_threshold` double NULL COMMENT '重排序相关性分数阈值';
ALTER TABLE `knowledge_info` ADD COLUMN `rerank_top_n` int NULL COMMENT '重排序后返回的文档数量';
ALTER TABLE `knowledge_info` ADD COLUMN `rerank_model` varchar(100) NULL COMMENT '重排序模型名称';
SET FOREIGN_KEY_CHECKS = 1;

View File

@@ -0,0 +1,14 @@
-- 为知识库信息表新增检索配置字段 (剔除了已存在的重排字段)
ALTER TABLE knowledge_info
ADD COLUMN similarity_threshold DOUBLE DEFAULT 0.5 COMMENT '相似度阈值'
AFTER retrieve_limit;
ALTER TABLE knowledge_info ADD COLUMN enable_hybrid tinyint(1) DEFAULT 0 COMMENT '是否启用混合检索';
ALTER TABLE knowledge_info ADD COLUMN hybrid_alpha double DEFAULT 0.5 COMMENT '混合检索权重比例 (0.0=纯向量, 1.0=纯关键词)';
-- 为知识片段表增加全文索引及关联ID
ALTER TABLE knowledge_fragment ADD COLUMN knowledge_id bigint COMMENT '知识库ID';
ALTER TABLE knowledge_fragment ADD FULLTEXT INDEX ft_content (content) WITH PARSER ngram;
-- 为知识库附件表增加解析状态字段
ALTER TABLE `knowledge_attach` ADD COLUMN `status` TINYINT DEFAULT 0 COMMENT '解析状态: 0待解析, 1解析中, 2已解析, 3解析失败';

View File

@@ -265,7 +265,7 @@ demo:
# 是否开启演示模式(开启后所有写操作将被拦截)
enabled: false
# 提示消息
message: "演示模式,不允许进行写操作"
message: "演示模式,不允许操作"
# 排除的路径(这些路径不受演示模式限制)
excludes:
- /login
@@ -276,7 +276,9 @@ demo:
- /chat/send
- /system/session/**
- /system/message/**
- /system/attach/**
- /system/fragment/**
- /system/info/**
--- # warm-flow工作流配置
warm-flow:
# 是否开启工作流默认true

View File

@@ -10,6 +10,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Bean;
import org.springframework.core.task.VirtualThreadTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.*;
/**
@@ -22,6 +23,12 @@ import java.util.concurrent.*;
@EnableConfigurationProperties(ThreadPoolProperties.class)
public class ThreadPoolConfig {
private final ThreadPoolProperties properties;
public ThreadPoolConfig(ThreadPoolProperties properties) {
this.properties = properties;
}
/**
* 核心线程数 = cpu 核心数 + 1
*/
@@ -54,6 +61,22 @@ public class ThreadPoolConfig {
return scheduledThreadPoolExecutor;
}
/**
* 知识库解析专用异步线程池
*/
@Bean(name = "knowledgeParseExecutor")
public ThreadPoolTaskExecutor knowledgeParseExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(core);
executor.setMaxPoolSize(core * 2);
executor.setQueueCapacity(properties.getQueueCapacity());
executor.setKeepAliveSeconds(properties.getKeepAliveSeconds());
executor.setThreadNamePrefix("knowledge-parse-pool-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
/**
* 销毁事件
* 停止线程池

View File

@@ -174,6 +174,23 @@
<scope>test</scope>
</dependency>
<!-- Test dependencies -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -9,6 +9,7 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
import org.ruoyi.common.chat.service.chat.IChatModelService;
import org.ruoyi.common.chat.domain.bo.chat.ChatModelBo;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.ruoyi.enums.ChatModeType;
import org.ruoyi.enums.ModelType;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
@@ -23,6 +24,8 @@ import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import java.util.LinkedHashMap;
/**
* 模型管理
*
@@ -55,6 +58,21 @@ public class ChatModelController extends BaseController {
return R.ok(chatModelService.queryList(bo));
}
/**
* 获取模型供应商枚举
*/
@GetMapping("/providerOptions")
public R<List<LinkedHashMap<String, String>>> providerOptions() {
List<LinkedHashMap<String, String>> options = new java.util.ArrayList<>();
for (ChatModeType type : ChatModeType.values()) {
LinkedHashMap<String, String> item = new LinkedHashMap<>();
item.put("label", type.getDescription());
item.put("value", type.getCode());
options.add(item);
}
return R.ok(options);
}
/**
* 导出模型管理列表
*/

View File

@@ -110,6 +110,17 @@ public class KnowledgeAttachController extends BaseController {
@PostMapping(value = "/upload")
public R<String> upload(KnowledgeInfoUploadBo bo){
knowledgeAttachService.upload(bo);
return R.ok("上传知识库附件成功!");
return R.ok("上传成功!");
}
/**
* 手动解析附件内容
*
* @param id 附件ID
*/
@PostMapping("/parse/{id}")
public R<Void> parse(@PathVariable Long id) {
knowledgeAttachService.parse(id);
return R.ok();
}
}

View File

@@ -8,6 +8,7 @@ import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.ruoyi.domain.bo.knowledge.KnowledgeFragmentBo;
import org.ruoyi.domain.vo.knowledge.KnowledgeFragmentVo;
import org.ruoyi.domain.vo.knowledge.KnowledgeRetrievalVo;
import org.ruoyi.service.knowledge.IKnowledgeFragmentService;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
@@ -102,4 +103,12 @@ public class KnowledgeFragmentController extends BaseController {
@PathVariable Long[] ids) {
return toAjax(knowledgeFragmentService.deleteWithValidByIds(List.of(ids), true));
}
/**
* 检索测试
*/
@PostMapping("/retrieval")
public R<List<KnowledgeRetrievalVo>> retrieval(@RequestBody KnowledgeFragmentBo bo) {
return R.ok(knowledgeFragmentService.retrieval(bo));
}
}

View File

@@ -1,105 +0,0 @@
package org.ruoyi.controller.knowledge;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.ruoyi.domain.bo.knowledge.KnowledgeGraphInstanceBo;
import org.ruoyi.domain.vo.knowledge.KnowledgeGraphInstanceVo;
import org.ruoyi.service.knowledge.IKnowledgeGraphInstanceService;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.core.domain.R;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
/**
* 知识图谱实例
*
* @author ageerle
* @date 2025-12-17
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/graphInstance")
public class KnowledgeGraphInstanceController extends BaseController {
private final IKnowledgeGraphInstanceService knowledgeGraphInstanceService;
/**
* 查询知识图谱实例列表
*/
@SaCheckPermission("system:graphInstance:list")
@GetMapping("/list")
public TableDataInfo<KnowledgeGraphInstanceVo> list(KnowledgeGraphInstanceBo bo, PageQuery pageQuery) {
return knowledgeGraphInstanceService.queryPageList(bo, pageQuery);
}
/**
* 导出知识图谱实例列表
*/
@SaCheckPermission("system:graphInstance:export")
@Log(title = "知识图谱实例", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(KnowledgeGraphInstanceBo bo, HttpServletResponse response) {
List<KnowledgeGraphInstanceVo> list = knowledgeGraphInstanceService.queryList(bo);
ExcelUtil.exportExcel(list, "知识图谱实例", KnowledgeGraphInstanceVo.class, response);
}
/**
* 获取知识图谱实例详细信息
*
* @param id 主键
*/
@SaCheckPermission("system:graphInstance:query")
@GetMapping("/{id}")
public R<KnowledgeGraphInstanceVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(knowledgeGraphInstanceService.queryById(id));
}
/**
* 新增知识图谱实例
*/
@SaCheckPermission("system:graphInstance:add")
@Log(title = "知识图谱实例", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody KnowledgeGraphInstanceBo bo) {
return toAjax(knowledgeGraphInstanceService.insertByBo(bo));
}
/**
* 修改知识图谱实例
*/
@SaCheckPermission("system:graphInstance:edit")
@Log(title = "知识图谱实例", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody KnowledgeGraphInstanceBo bo) {
return toAjax(knowledgeGraphInstanceService.updateByBo(bo));
}
/**
* 删除知识图谱实例
*
* @param ids 主键串
*/
@SaCheckPermission("system:graphInstance:remove")
@Log(title = "知识图谱实例", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(knowledgeGraphInstanceService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@@ -1,105 +0,0 @@
package org.ruoyi.controller.knowledge;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.ruoyi.domain.bo.knowledge.KnowledgeGraphSegmentBo;
import org.ruoyi.domain.vo.knowledge.KnowledgeGraphSegmentVo;
import org.ruoyi.service.knowledge.IKnowledgeGraphSegmentService;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.core.domain.R;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
/**
* 知识图谱片段
*
* @author ageerle
* @date 2025-12-17
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/graphSegment")
public class KnowledgeGraphSegmentController extends BaseController {
private final IKnowledgeGraphSegmentService knowledgeGraphSegmentService;
/**
* 查询知识图谱片段列表
*/
@SaCheckPermission("system:graphSegment:list")
@GetMapping("/list")
public TableDataInfo<KnowledgeGraphSegmentVo> list(KnowledgeGraphSegmentBo bo, PageQuery pageQuery) {
return knowledgeGraphSegmentService.queryPageList(bo, pageQuery);
}
/**
* 导出知识图谱片段列表
*/
@SaCheckPermission("system:graphSegment:export")
@Log(title = "知识图谱片段", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(KnowledgeGraphSegmentBo bo, HttpServletResponse response) {
List<KnowledgeGraphSegmentVo> list = knowledgeGraphSegmentService.queryList(bo);
ExcelUtil.exportExcel(list, "知识图谱片段", KnowledgeGraphSegmentVo.class, response);
}
/**
* 获取知识图谱片段详细信息
*
* @param id 主键
*/
@SaCheckPermission("system:graphSegment:query")
@GetMapping("/{id}")
public R<KnowledgeGraphSegmentVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(knowledgeGraphSegmentService.queryById(id));
}
/**
* 新增知识图谱片段
*/
@SaCheckPermission("system:graphSegment:add")
@Log(title = "知识图谱片段", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody KnowledgeGraphSegmentBo bo) {
return toAjax(knowledgeGraphSegmentService.insertByBo(bo));
}
/**
* 修改知识图谱片段
*/
@SaCheckPermission("system:graphSegment:edit")
@Log(title = "知识图谱片段", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody KnowledgeGraphSegmentBo bo) {
return toAjax(knowledgeGraphSegmentService.updateByBo(bo));
}
/**
* 删除知识图谱片段
*
* @param ids 主键串
*/
@SaCheckPermission("system:graphSegment:remove")
@Log(title = "知识图谱片段", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(knowledgeGraphSegmentService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@@ -49,5 +49,44 @@ public class KnowledgeFragmentBo extends BaseEntity {
*/
private String remark;
/**
* 知识库ID
*/
private Long knowledgeId;
/**
* 检索内容
*/
private String query;
/**
* 返回条数
*/
private Integer topK;
/**
* 相似度阈值
*/
private Double threshold;
/**
* 是否启用重排
*/
private Boolean enableRerank;
/**
* 重排模型名称
*/
private String rerankModel;
/**
* 是否启用混合检索
*/
private Boolean enableHybrid;
/**
* 混合检索权重 (0.0-1.0)
*/
private Double hybridAlpha;
}

View File

@@ -62,6 +62,11 @@ public class KnowledgeInfoBo extends BaseEntity {
*/
private Long retrieveLimit;
/**
* 相似度阈值
*/
private Double similarityThreshold;
/**
* 文本块大小
*/
@@ -77,10 +82,40 @@ public class KnowledgeInfoBo extends BaseEntity {
*/
private String embeddingModel;
/**
* 是否启用重排序0 否 1是
*/
private Integer enableRerank;
/**
* 重排序模型名称
*/
private String rerankModel;
/**
* 重排序后返回的文档数量
*/
private Integer rerankTopN;
/**
* 重排序相关性分数阈值
*/
private Double rerankScoreThreshold;
/**
* 是否启用混合检索0 否 1是
*/
private Integer enableHybrid;
/**
* 混合检索权重 (0.0-1.0)
*/
private Double hybridAlpha;
/**
* 备注
*/
private String remark;
}

View File

@@ -16,6 +16,11 @@ public class KnowledgeInfoUploadBo {
private MultipartFile file;
/**
* 是否自动解析 (true: 立即解析, false: 仅上传)
*/
private Boolean autoParse;
/**
* 生效时间, 为空则立即生效
*/

View File

@@ -0,0 +1,44 @@
package org.ruoyi.domain.bo.rerank;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* 重排序请求参数
*
* @author yang
* @date 2026-04-19
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RerankRequest {
/**
* 查询文本
*/
private String query;
/**
* 候选文档列表
*/
private List<String> documents;
/**
* 返回的文档数量topN
* 如果不指定,默认返回所有文档
*/
private Integer topN;
/**
* 是否返回原始文档内容
* 默认为 true
*/
@Builder.Default
private Boolean returnDocuments = true;
}

View File

@@ -0,0 +1,72 @@
package org.ruoyi.domain.bo.rerank;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* 重排序结果
*
* @author yang
* @date 2026-04-19
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RerankResult {
/**
* 重排序后的文档结果列表
*/
private List<RerankDocument> documents;
/**
* 原始请求中的文档总数
*/
private Integer totalDocuments;
/**
* 重排序耗时(毫秒)
*/
private Long durationMs;
/**
* 单个重排序文档结果
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class RerankDocument {
/**
* 文档在原始列表中的索引位置
*/
private Integer index;
/**
* 相关性分数(通常 0-1 之间,越高越相关)
*/
private Double relevanceScore;
/**
* 文档内容
*/
private String document;
}
/**
* 创建空结果
*/
public static RerankResult empty() {
return RerankResult.builder()
.documents(List.of())
.totalDocuments(0)
.durationMs(0L)
.build();
}
}

View File

@@ -51,4 +51,48 @@ public class QueryVectorBo {
*/
private String baseUrl;
// ========== 重排序相关参数 ==========
/**
* 是否启用重排序
* 默认为 false
*/
private Boolean enableRerank = false;
/**
* 重排序模型名称
*/
private String rerankModelName;
/**
* 重排序后返回的文档数量topN
* 如果不指定,默认与 maxResults 相同
*/
private Integer rerankTopN;
/**
* 重排序相关性分数阈值
* 低于此阈值的文档将被过滤
*/
private Double rerankScoreThreshold;
// ========== 混合检索与阈值相关参数 ==========
/**
* 相似度阈值 (0.0-1.0)
* 应用于向量搜索阶段
*/
private Double similarityThreshold;
/**
* 是否启用混合检索
*/
private Boolean enableHybrid = false;
/**
* 混合检索权重 (0.0-1.0)
*/
private Double hybridAlpha;
}

View File

@@ -0,0 +1,55 @@
package org.ruoyi.domain.dto.request;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
/**
* 阿里百炼重排序请求DTOOpenAI兼容格式
*
* @author yang
* @date 2026-04-20
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public record AliBaiLianRerankRequest(
String model,
List<String> documents,
String query,
@JsonProperty("top_n")
Integer topN,
String instruct,
@JsonProperty("return_documents")
Boolean returnDocuments
) {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
/**
* 创建文本重排序请求
*/
public static AliBaiLianRerankRequest create(String modelName, String query,
List<String> documents, Integer topN,
Boolean returnDocuments) {
return new AliBaiLianRerankRequest(
modelName,
documents,
query,
topN != null ? topN : documents.size(),
null,
returnDocuments != null ? returnDocuments : true
);
}
/**
* 转换为JSON字符串
*/
public String toJson() {
try {
return OBJECT_MAPPER.writeValueAsString(this);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException("序列化阿里百炼重排序请求失败", e);
}
}
}

View File

@@ -0,0 +1,48 @@
package org.ruoyi.domain.dto.request;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
/**
* 智谱AI重排序请求DTO
*
* @author yang
* @date 2026-04-19
*/
public record ZhipuRerankRequest(
String model,
String query,
List<String> documents,
Integer top_n,
Boolean return_documents
) {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
/**
* 创建智谱重排序请求
*/
public static ZhipuRerankRequest create(String modelName, String query,
List<String> documents, Integer topN,
Boolean returnDocuments) {
return new ZhipuRerankRequest(
modelName,
query,
documents,
topN != null ? topN : documents.size(),
returnDocuments != null ? returnDocuments : true
);
}
/**
* 转换为JSON字符串
*/
public String toJson() {
try {
return OBJECT_MAPPER.writeValueAsString(this);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException("序列化智谱重排序请求失败", e);
}
}
}

View File

@@ -0,0 +1,81 @@
package org.ruoyi.domain.dto.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.ruoyi.domain.bo.rerank.RerankResult;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 阿里百炼重排序响应DTOOpenAI兼容格式
*
* @author yang
* @date 2026-04-20
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public record AliBaiLianRerankResponse(
String id,
String object,
List<ResultItem> results,
UsageInfo usage
) {
/**
* 单个重排序结果项
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public record ResultItem(
Integer index,
@JsonProperty("relevance_score")
Double relevanceScore,
Object document
) {
/**
* 获取文档文本内容
*/
public String getDocumentText() {
if (document == null) return null;
if (document instanceof String) return (String) document;
if (document instanceof Map) {
Object text = ((Map<?, ?>) document).get("text");
return text != null ? text.toString() : null;
}
return document.toString();
}
}
/**
* Token使用信息
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public record UsageInfo(
@JsonProperty("total_tokens")
Integer totalTokens,
@JsonProperty("prompt_tokens")
Integer promptTokens
) {}
/**
* 转换为通用RerankResult
*/
public RerankResult toRerankResult(int totalDocs, long durationMs) {
if (results == null || results.isEmpty()) {
return RerankResult.empty();
}
List<RerankResult.RerankDocument> documents = results.stream()
.map(item -> RerankResult.RerankDocument.builder()
.index(item.index())
.relevanceScore(item.relevanceScore())
.document(item.getDocumentText())
.build())
.collect(Collectors.toList());
return RerankResult.builder()
.documents(documents)
.totalDocuments(totalDocs)
.durationMs(durationMs)
.build();
}
}

View File

@@ -0,0 +1,68 @@
package org.ruoyi.domain.dto.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.ruoyi.domain.bo.rerank.RerankResult;
import java.util.List;
import java.util.stream.Collectors;
/**
* 智谱AI重排序响应DTO
*
* @author yang
* @date 2026-04-19
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public record ZhipuRerankResponse(
String model,
String object,
List<ResultItem> results,
UsageInfo usage
) {
/**
* 单个重排序结果项
*/
public record ResultItem(
Integer index,
@JsonProperty("relevance_score")
Double relevanceScore,
String document
) {}
/**
* Token使用信息
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public record UsageInfo(
@JsonProperty("total_tokens")
Integer totalTokens,
@JsonProperty("input_tokens")
Integer inputTokens,
@JsonProperty("output_tokens")
Integer outputTokens
) {}
/**
* 转换为通用RerankResult
*/
public RerankResult toRerankResult(int totalDocs, long durationMs) {
if (results == null || results.isEmpty()) {
return RerankResult.empty();
}
List<RerankResult.RerankDocument> documents = results.stream()
.map(item -> RerankResult.RerankDocument.builder()
.index(item.index())
.relevanceScore(item.relevanceScore())
.document(item.document())
.build())
.collect(Collectors.toList());
return RerankResult.builder()
.documents(documents)
.totalDocuments(totalDocs)
.durationMs(durationMs)
.build();
}
}

View File

@@ -57,5 +57,10 @@ public class KnowledgeAttach extends BaseEntity {
*/
private String remark;
/**
* 解析状态: 0待解析, 1解析中, 2已解析, 3解析失败
*/
private Integer status;
}

View File

@@ -47,5 +47,10 @@ public class KnowledgeFragment extends BaseEntity {
*/
private String remark;
/**
* 知识库ID
*/
private Long knowledgeId;
}

View File

@@ -63,6 +63,11 @@ public class KnowledgeInfo extends BaseEntity {
*/
private Long retrieveLimit;
/**
* 相似度阈值
*/
private Double similarityThreshold;
/**
* 文本块大小
*/
@@ -78,6 +83,36 @@ public class KnowledgeInfo extends BaseEntity {
*/
private String embeddingModel;
/**
* 是否启用重排序0 否 1是
*/
private Integer enableRerank;
/**
* 重排序模型名称
*/
private String rerankModel;
/**
* 重排序后返回的文档数量
*/
private Integer rerankTopN;
/**
* 重排序相关性分数阈值
*/
private Double rerankScoreThreshold;
/**
* 是否启用混合检索0 否 1是
*/
private Integer enableHybrid;
/**
* 混合检索权重 (0.0-1.0)
*/
private Double hybridAlpha;
/**
* 备注
*/

View File

@@ -0,0 +1,20 @@
package org.ruoyi.domain.vo.knowledge;
import lombok.Data;
/**
* 文档分块数统计 VO用于 GROUP BY 查询结果接收)
*/
@Data
public class DocFragmentCountVo {
/**
* 文档ID关联 knowledge_attach.doc_id
*/
private String docId;
/**
* 该文档下的分块数量
*/
private Integer fragmentCount;
}

View File

@@ -8,6 +8,7 @@ import org.ruoyi.domain.entity.knowledge.KnowledgeAttach;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
@@ -68,5 +69,22 @@ public class KnowledgeAttachVo implements Serializable {
@ExcelProperty(value = "备注")
private String remark;
/**
* 上传时间(来自 BaseEntity.createTime
*/
@ExcelProperty(value = "上传时间")
private Date createTime;
/**
* 解析状态: 0待解析, 1解析中, 2已解析, 3解析失败
*/
@ExcelProperty(value = "解析状态")
private Integer status;
/**
* 分块数(统计字段,非数据库列)
*/
private Integer fragmentCount;
}

View File

@@ -39,7 +39,7 @@ public class KnowledgeFragmentVo implements Serializable {
* 片段索引下标
*/
@ExcelProperty(value = "片段索引下标")
private Long idx;
private Integer idx;
/**
* 文档内容
@@ -53,5 +53,10 @@ public class KnowledgeFragmentVo implements Serializable {
@ExcelProperty(value = "备注")
private String remark;
/**
* 知识库ID
*/
private Long knowledgeId;
}

View File

@@ -76,6 +76,12 @@ public class KnowledgeInfoVo implements Serializable {
@ExcelProperty(value = "知识库中检索的条数")
private Integer retrieveLimit;
/**
* 相似度阈值
*/
@ExcelProperty(value = "相似度阈值")
private Double similarityThreshold;
/**
* 文本块大小
*/
@@ -94,6 +100,48 @@ public class KnowledgeInfoVo implements Serializable {
@ExcelProperty(value = "向量模型")
private String embeddingModel;
/**
* 是否启用重排序0 否 1是
*/
@ExcelProperty(value = "是否启用重排序")
private Integer enableRerank;
/**
* 重排序模型名称
*/
@ExcelProperty(value = "重排序模型")
private String rerankModel;
/**
* 重排序后返回的文档数量
*/
@ExcelProperty(value = "重排序返回数量")
private Integer rerankTopN;
/**
* 重排序相关性分数阈值
*/
@ExcelProperty(value = "重排序分数阈值")
private Double rerankScoreThreshold;
/**
* 是否启用混合检索0 否 1是
*/
@ExcelProperty(value = "是否启用混合检索")
private Integer enableHybrid;
/**
* 混合检索权重 (0.0-1.0)
*/
@ExcelProperty(value = "混合检索权重")
private Double hybridAlpha;
/**
* 文档数量
*/
@ExcelProperty(value = "文档数量")
private Integer documentCount;
/**
* 备注
*/

View File

@@ -0,0 +1,69 @@
package org.ruoyi.domain.vo.knowledge;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
/**
* 知识检索测试结果视图对象
*
* @author RobustH
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class KnowledgeRetrievalVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 片段ID
*/
private String id;
/**
* 文档ID
*/
private String docId;
/**
* 知识库ID
*/
private Long knowledgeId;
/**
* 分片索引
*/
private Integer idx;
/**
* 片段内容
*/
private String content;
/**
* 相似度得分
*/
private Double score;
/**
* 原始检索排名 (重排前)
*/
private Integer originalIndex;
/**
* 原始检索得分 (重排前)
*/
private Double rawScore;
/**
* 来源文档名称
*/
private String sourceName;
}

View File

@@ -15,7 +15,10 @@ public enum ChatModeType {
DEEP_SEEK("deepseek", "深度求索"),
QIAN_WEN("qianwen", "通义千问"),
OPEN_AI("openai", "openai"),
PPIO("ppio", "ppio");
ATLAS("atlas", "Atlas Cloud"),
CUSTOM_API("custom_api", "自定义API"),
MINIMAX("minimax", "MiniMax"),
XIAOMI("xiaomi", "小米MiMo");
private final String code;
private final String description;

View File

@@ -0,0 +1,38 @@
package org.ruoyi.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 知识库附件解析状态枚举
*
* @author RobustH
*/
@Getter
@AllArgsConstructor
public enum KnowledgeAttachStatus {
/**
* 待解析
*/
WAITING(0, "待解析"),
/**
* 解析中
*/
PARSING(1, "解析中"),
/**
* 已解析
*/
COMPLETED(2, "已解析"),
/**
* 解析失败
*/
FAILED(3, "解析失败");
private final Integer code;
private final String info;
}

View File

@@ -0,0 +1,106 @@
package org.ruoyi.factory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.ruoyi.common.chat.service.chat.IChatModelService;
import org.ruoyi.service.rerank.RerankModelService;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 重排序模型工厂服务类
* 参考设计模式EmbeddingModelFactory
* 负责创建和管理重排序模型实例
*
* @author yang
* @date 2026-04-19
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class RerankModelFactory {
private final ApplicationContext applicationContext;
private final IChatModelService chatModelService;
/**
* 模型缓存使用ConcurrentHashMap保证线程安全
*/
private final Map<String, RerankModelService> modelCache = new ConcurrentHashMap<>();
/**
* 创建重排序模型实例
* 如果模型已存在于缓存中,则直接返回;否则创建新的实例
*
* @param rerankModelName 重排序模型名称
*/
public RerankModelService createModel(String rerankModelName) {
return modelCache.computeIfAbsent(rerankModelName, name -> {
ChatModelVo modelConfig = chatModelService.selectModelByName(rerankModelName);
if (modelConfig == null) {
throw new IllegalArgumentException("未找到重排序模型配置name=" + name);
}
return createModelInstance(modelConfig.getProviderCode(), modelConfig);
});
}
/**
* 刷新模型缓存
* 根据给定的模型ID从缓存中移除对应的模型
*
* @param modelId 模型的唯一标识ID
*/
public void refreshModel(Long modelId) {
modelCache.remove(modelId);
}
/**
* 获取所有支持模型工厂的列表
*
* @return 支持的模型工厂名称列表
*/
public List<String> getSupportedFactories() {
return new ArrayList<>(applicationContext.getBeansOfType(RerankModelService.class)
.keySet());
}
/**
* 创建具体的模型实例
* 根据提供的工厂名称和配置信息创建并配置模型实例
*
* @param factory 工厂名称用于标识模型类型providerCode
* @param config 模型配置信息
* @return RerankModelService 配置好的模型实例
* @throws IllegalArgumentException 当无法获取指定的模型实例时抛出
*/
private RerankModelService createModelInstance(String factory, ChatModelVo config) {
try {
// 优先尝试使用 providerCode + "Rerank" 作为 Bean 名称
// 例如zhipu -> zhipuRerankjina -> jinaRerank
String rerankBeanName = factory + "Rerank";
RerankModelService model = applicationContext.getBean(rerankBeanName, RerankModelService.class);
model.configure(config);
log.info("成功创建重排序模型: factory={}, modelName={}", rerankBeanName, config.getModelName());
return model;
} catch (NoSuchBeanDefinitionException e) {
// 如果找不到,尝试使用原始的 providerCode
try {
RerankModelService model = applicationContext.getBean(factory, RerankModelService.class);
model.configure(config);
log.info("成功创建重排序模型: factory={}, modelName={}", factory, config.getModelName());
return model;
} catch (NoSuchBeanDefinitionException ex) {
throw new IllegalArgumentException("获取不到重排序模型: " + factory + "" + factory + "Rerank", ex);
}
}
}
}

View File

@@ -1,5 +1,8 @@
package org.ruoyi.mapper.knowledge;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.ruoyi.domain.entity.knowledge.KnowledgeAttach;
import org.ruoyi.domain.vo.knowledge.KnowledgeAttachVo;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
@@ -10,6 +13,12 @@ import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
* @author ageerle
* @date 2025-12-17
*/
@Mapper
public interface KnowledgeAttachMapper extends BaseMapperPlus<KnowledgeAttach, KnowledgeAttachVo> {
/**
* 统计指定知识库下的文档数量
*/
@Select("SELECT COUNT(*) FROM knowledge_attach WHERE knowledge_id = #{knowledgeId}")
int countByKnowledgeId(@Param("knowledgeId") Long knowledgeId);
}

View File

@@ -1,15 +1,45 @@
package org.ruoyi.mapper.knowledge;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.ruoyi.domain.entity.knowledge.KnowledgeFragment;
import org.ruoyi.domain.vo.knowledge.DocFragmentCountVo;
import org.ruoyi.domain.vo.knowledge.KnowledgeFragmentVo;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import java.util.List;
/**
* 知识片段Mapper接口
*
* @author ageerle
* @date 2025-12-17
*/
@Mapper
public interface KnowledgeFragmentMapper extends BaseMapperPlus<KnowledgeFragment, KnowledgeFragmentVo> {
/**
* 批量统计各文档的分块数(强类型接收,避免 Map key 大小写问题)
*
* @param docIds 文档 ID 列表
* @return 每个 docId 对应的分块数列表
*/
@Select("<script>" +
"SELECT doc_id AS docId, COUNT(*) AS fragmentCount " +
"FROM knowledge_fragment " +
"WHERE doc_id IN " +
"<foreach collection='docIds' item='id' open='(' separator=',' close=')'>#{id}</foreach> " +
"GROUP BY doc_id" +
"</script>")
List<DocFragmentCountVo> selectFragmentCountByDocIds(@Param("docIds") List<String> docIds);
@Select("<script>" +
"SELECT id, doc_id AS docId, content, idx, knowledge_id AS knowledgeId " +
"FROM knowledge_fragment " +
"WHERE knowledge_id = #{knowledgeId} " +
"AND MATCH (content) AGAINST (#{query} IN NATURAL LANGUAGE MODE) " +
"ORDER BY MATCH (content) AGAINST (#{query} IN NATURAL LANGUAGE MODE) DESC " +
"LIMIT #{limit}" +
"</script>")
List<KnowledgeFragmentVo> searchByKeyword(@Param("knowledgeId") Long knowledgeId, @Param("query") String query, @Param("limit") Integer limit);
}

View File

@@ -1,9 +1,13 @@
package org.ruoyi.service.chat;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import org.ruoyi.common.chat.domain.dto.request.ChatRequest;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import java.time.Duration;
/**
* 聊天消息Service接口
*
@@ -21,6 +25,23 @@ public interface AbstractChatService {
*/
StreamingChatModel buildStreamingChatModel(ChatModelVo chatModelVo, ChatRequest chatRequest);
/**
* 创建同步聊天模型(供 Agent/SupervisorAgent 使用)
* 默认实现使用 OpenAI 兼容协议,适用于 OpenAI、DeepSeek、Atlas Cloud 等兼容接口的 provider。
* ZhiPu、QianWen、Ollama 等需覆盖此方法使用各自 SDK。
*
* @param chatModelVo 模型配置
* @return 同步聊天模型实例
*/
default ChatModel buildChatModel(ChatModelVo chatModelVo) {
return OpenAiChatModel.builder()
.baseUrl(chatModelVo.getApiHost())
.apiKey(chatModelVo.getApiKey())
.modelName(chatModelVo.getModelName())
.timeout(Duration.ofSeconds(120))
.build();
}
/**
* 获取服务提供商名称
*/

View File

@@ -20,6 +20,11 @@ import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.tool.ToolProvider;
import dev.langchain4j.skills.shell.ShellSkills;
import dev.langchain4j.rag.AugmentationRequest;
import dev.langchain4j.rag.AugmentationResult;
import dev.langchain4j.rag.DefaultRetrievalAugmentor;
import dev.langchain4j.rag.RetrievalAugmentor;
import dev.langchain4j.rag.query.Metadata;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
@@ -54,6 +59,8 @@ import org.ruoyi.service.chat.AbstractChatService;
import org.ruoyi.service.chat.IChatMessageService;
import org.ruoyi.service.chat.impl.memory.PersistentChatMemoryStore;
import org.ruoyi.service.knowledge.IKnowledgeInfoService;
import org.ruoyi.service.retrieval.KnowledgeRetrievalService;
import org.ruoyi.service.knowledge.retriever.CustomVectorRetriever;
import org.ruoyi.service.vector.VectorStoreService;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
@@ -89,6 +96,8 @@ public class ChatServiceFacade implements IChatService {
private final VectorStoreService vectorStoreService;
private final KnowledgeRetrievalService knowledgeRetrievalService;
private final SseEmitterManager sseEmitterManager;
private final IChatMessageService chatMessageService;
@@ -409,7 +418,6 @@ public class ChatServiceFacade implements IChatService {
/**
* 构建上下文消息列表
* 消息顺序:历史消息 → 当前用户消息(确保 AI 正确理解对话上下文)
*
* @param chatRequest 聊天请求
@@ -418,7 +426,41 @@ public class ChatServiceFacade implements IChatService {
private List<ChatMessage> buildContextMessages(ChatRequest chatRequest) {
List<ChatMessage> messages = new ArrayList<>();
// 从数据库查询历史对话消息(放在前面)
// 1. 初始化当前用户消息
UserMessage userMessage = UserMessage.userMessage(chatRequest.getContent());
// 2. 知识库检索增强 (RAG)
if (chatRequest.getKnowledgeId() != null) {
KnowledgeInfoVo knowledgeInfoVo = knowledgeInfoService.queryById(Long.valueOf(chatRequest.getKnowledgeId()));
if (knowledgeInfoVo != null) {
ChatModelVo chatModel = chatModelService.selectModelByName(knowledgeInfoVo.getEmbeddingModel());
if (chatModel != null) {
log.info("执行高级 RAG 流程: kid={}", chatRequest.getKnowledgeId());
// 构建自定义检索器
CustomVectorRetriever retriever = new CustomVectorRetriever(
knowledgeRetrievalService, knowledgeInfoVo, chatModel);
// 构建增强流水线
RetrievalAugmentor augmentor = DefaultRetrievalAugmentor.builder()
.contentRetriever(retriever)
.build();
// 执行增强:编织上下文到 UserMessage
Metadata metadata = Metadata.from(userMessage, chatRequest.getSessionId(), new ArrayList<>());
AugmentationRequest augmentationRequest = new AugmentationRequest(userMessage, metadata);
AugmentationResult result = augmentor.augment(augmentationRequest);
ChatMessage augmented = result.chatMessage();
if (augmented instanceof UserMessage) {
userMessage = (UserMessage) augmented;
log.debug("RAG 增强完成UserMessage 已注入背景知识");
}
}
}
}
// 3. 从数据库查询历史对话消息(放在前面)
if (chatRequest.getSessionId() != null) {
MessageWindowChatMemory memory = createChatMemory(chatRequest.getSessionId());
if (memory != null) {
@@ -430,38 +472,7 @@ public class ChatServiceFacade implements IChatService {
}
}
// 从向量库查询相关历史消息(知识库内容作为上下文
if (chatRequest.getKnowledgeId() != null) {
// 查询知识库信息
KnowledgeInfoVo knowledgeInfoVo = knowledgeInfoService.queryById(Long.valueOf(chatRequest.getKnowledgeId()));
if (knowledgeInfoVo == null) {
log.warn("知识库信息不存在kid: {}", chatRequest.getKnowledgeId());
// 继续添加当前用户消息
messages.add(UserMessage.userMessage(chatRequest.getContent()));
return messages;
}
// 查询向量模型配置信息
ChatModelVo chatModel = chatModelService.selectModelByName(knowledgeInfoVo.getEmbeddingModel());
if (chatModel == null) {
log.warn("向量模型配置不存在,模型名称: {}", knowledgeInfoVo.getEmbeddingModel());
messages.add(UserMessage.userMessage(chatRequest.getContent()));
return messages;
}
// 构建向量查询参数
QueryVectorBo queryVectorBo = buildQueryVectorBo(chatRequest, knowledgeInfoVo, chatModel);
// 获取向量查询结果(知识库内容作为系统上下文,放在历史消息之后)
List<String> nearestList = vectorStoreService.getQueryVector(queryVectorBo);
for (String prompt : nearestList) {
// 知识库内容作为系统上下文添加
messages.add(new AiMessage(prompt));
}
}
// 构建当前用户消息(放在最后)
UserMessage userMessage = UserMessage.userMessage(chatRequest.getContent());
// 4. 添加经过增强的用户消息(放在最后
messages.add(userMessage);
return messages;
@@ -480,6 +491,13 @@ public class ChatServiceFacade implements IChatService {
queryVectorBo.setVectorModelName(knowledgeInfoVo.getVectorModel());
queryVectorBo.setEmbeddingModelName(knowledgeInfoVo.getEmbeddingModel());
queryVectorBo.setMaxResults(knowledgeInfoVo.getRetrieveLimit());
// 设置重排序参数
queryVectorBo.setEnableRerank(knowledgeInfoVo.getEnableRerank() != null && knowledgeInfoVo.getEnableRerank() == 1);
queryVectorBo.setRerankModelName(knowledgeInfoVo.getRerankModel());
queryVectorBo.setRerankTopN(knowledgeInfoVo.getRerankTopN());
queryVectorBo.setRerankScoreThreshold(knowledgeInfoVo.getRerankScoreThreshold());
return queryVectorBo;
}

View File

@@ -15,7 +15,7 @@ import org.springframework.stereotype.Service;
import java.util.List;
/**
* PPIO服务调用
* Atlas Cloud服务调用
*
* @author ageerle@163.com
* @date 2025/12/13
@@ -23,7 +23,7 @@ import java.util.List;
@Service
@Slf4j
@RequiredArgsConstructor
public class PPIOServiceImpl implements AbstractChatService {
public class AtlaServiceImpl implements AbstractChatService {
@Override
public StreamingChatModel buildStreamingChatModel(ChatModelVo chatModelVo, ChatRequest chatRequest) {
@@ -38,7 +38,7 @@ public class PPIOServiceImpl implements AbstractChatService {
@Override
public String getProviderName() {
return ChatModeType.PPIO.getCode();
return ChatModeType.ATLAS.getCode();
}
}

View File

@@ -0,0 +1,72 @@
package org.ruoyi.service.chat.impl.provider;
import cn.hutool.core.util.StrUtil;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.common.chat.domain.dto.request.ChatRequest;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.ruoyi.enums.ChatModeType;
import org.ruoyi.observability.MyChatModelListener;
import org.ruoyi.service.chat.AbstractChatService;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.util.List;
/**
* 自定义 API 服务调用
*
* 适用于 OpenAI 兼容接口或仅通过通用 HTTP 协议接入的第三方大模型服务。
* 通过模型配置中的 apiHost / apiKey / modelName 即可复用,不需要再写死具体供应商。
*
* @author better
*/
@Service
@Slf4j
@RequiredArgsConstructor
public class CustomApiServiceImpl implements AbstractChatService {
private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(180);
@Override
public StreamingChatModel buildStreamingChatModel(ChatModelVo chatModelVo, ChatRequest chatRequest) {
return OpenAiStreamingChatModel.builder()
.baseUrl(normalizeBaseUrl(chatModelVo.getApiHost()))
.apiKey(defaultIfBlank(chatModelVo.getApiKey(), "EMPTY"))
.modelName(chatModelVo.getModelName())
.timeout(DEFAULT_TIMEOUT)
.listeners(List.of(new MyChatModelListener()))
.returnThinking(chatRequest.getEnableThinking())
.build();
}
@Override
public ChatModel buildChatModel(ChatModelVo chatModelVo) {
return OpenAiChatModel.builder()
.baseUrl(normalizeBaseUrl(chatModelVo.getApiHost()))
.apiKey(defaultIfBlank(chatModelVo.getApiKey(), "EMPTY"))
.modelName(chatModelVo.getModelName())
.timeout(DEFAULT_TIMEOUT)
.build();
}
@Override
public String getProviderName() {
return ChatModeType.CUSTOM_API.getCode();
}
private String normalizeBaseUrl(String baseUrl) {
if (StrUtil.isBlank(baseUrl)) {
throw new IllegalArgumentException("自定义API的请求地址(apiHost)不能为空");
}
return baseUrl.endsWith("/") ? baseUrl.substring(0, baseUrl.length() - 1) : baseUrl;
}
private String defaultIfBlank(String value, String defaultValue) {
return StrUtil.isBlank(value) ? defaultValue : value;
}
}

View File

@@ -0,0 +1,47 @@
package org.ruoyi.service.chat.impl.provider;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.common.chat.domain.dto.request.ChatRequest;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.ruoyi.enums.ChatModeType;
import org.ruoyi.observability.MyChatModelListener;
import org.ruoyi.service.chat.AbstractChatService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 小米MiMo服务调用
* <p>
* 小米提供OpenAI兼容的API接口支持MiMo等模型。
*
* @author ageerle
* @date 2026/4/19
*/
@Service
@Slf4j
@RequiredArgsConstructor
public class MiMoServiceImpl implements AbstractChatService {
@Override
public StreamingChatModel buildStreamingChatModel(ChatModelVo chatModelVo, ChatRequest chatRequest) {
return OpenAiStreamingChatModel.builder()
.baseUrl(chatModelVo.getApiHost())
.apiKey(chatModelVo.getApiKey())
.modelName(chatModelVo.getModelName())
.listeners(List.of(new MyChatModelListener()))
.returnThinking(chatRequest.getEnableThinking())
.build();
}
@Override
public String getProviderName() {
return ChatModeType.XIAOMI.getCode();
}
}

View File

@@ -0,0 +1,44 @@
package org.ruoyi.service.chat.impl.provider;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.common.chat.domain.dto.request.ChatRequest;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.ruoyi.enums.ChatModeType;
import org.ruoyi.observability.MyChatModelListener;
import org.ruoyi.service.chat.AbstractChatService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* MiniMax服务调用
* <p>
* MiniMax提供OpenAI兼容的API接口支持MiniMax-M2.7、MiniMax-M2.5等模型。
* API地址https://api.minimax.io/v1
*
* @author octopus
* @date 2026/3/21
*/
@Service
@Slf4j
public class MinimaxServiceImpl implements AbstractChatService {
@Override
public StreamingChatModel buildStreamingChatModel(ChatModelVo chatModelVo, ChatRequest chatRequest) {
return OpenAiStreamingChatModel.builder()
.baseUrl(chatModelVo.getApiHost())
.apiKey(chatModelVo.getApiKey())
.modelName(chatModelVo.getModelName())
.listeners(List.of(new MyChatModelListener()))
.returnThinking(chatRequest.getEnableThinking())
.build();
}
@Override
public String getProviderName() {
return ChatModeType.MINIMAX.getCode();
}
}

Some files were not shown because too many files have changed in this diff Show More