mirror of
https://gitcode.com/ageerle/ruoyi-ai.git
synced 2026-03-13 20:53:42 +08:00
feat: 全局格式化代码
This commit is contained in:
46
README.md
46
README.md
@@ -18,19 +18,20 @@
|
||||
|
||||
<img src="image/00.png" alt="RuoYi AI Logo" width="120" height="120">
|
||||
|
||||
|
||||
|
||||
### 企业级AI助手平台
|
||||
|
||||
*开箱即用的智能AI平台,深度集成 FastGPT、扣子(Coze)、DIFY 等主流AI平台,提供先进的RAG技术、知识图谱、数字人和AI流程编排能力*
|
||||
|
||||
**[🇺🇸 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.pandarobot.chat)** | *
|
||||
*[🚀 在线体验](https://web.pandarobot.chat)** | **[🐛 问题反馈](https://github.com/ageerle/ruoyi-ai/issues)** | *
|
||||
*[💡 功能建议](https://github.com/ageerle/ruoyi-ai/issues)**
|
||||
|
||||
</div>
|
||||
|
||||
## ✨ 核心亮点
|
||||
|
||||
### 智能AI引擎
|
||||
|
||||
- **多模型接入**:支持 OpenAI GPT-4、Azure、ChatGLM、通义千问、智谱AI 等主流模型
|
||||
- **AI平台集成**:深度集成 **FastGPT**、**扣子(Coze)**、**DIFY** 等主流AI应用平台
|
||||
- **Spring AI MCP 集成**:基于模型上下文协议,打造可扩展的AI工具生态系统
|
||||
@@ -38,60 +39,64 @@
|
||||
- **AI 编程助手**:内置智能代码分析和项目脚手架生成能力
|
||||
|
||||
### AI平台生态集成
|
||||
|
||||
- **FastGPT 深度集成**:原生支持 FastGPT API,包括知识库检索、工作流编排和上下文管理
|
||||
- **扣子(Coze) 官方SDK**:集成字节跳动扣子平台官方SDK,支持Bot对话和流式响应
|
||||
- **DIFY 完整兼容**:使用 DIFY Java Client,支持应用编排、工作流和知识库管理
|
||||
- **统一聊天接口**:提供统一的聊天服务接口,支持多平台无缝切换和负载均衡
|
||||
|
||||
### 本地化RAG方案
|
||||
|
||||
- **私有知识库**:基于 Langchain4j 框架 + BGE-large-zh-v1.5 中文向量模型
|
||||
- **多种向量库**:支持 Milvus、Weaviate、Qdrant 等主流向量数据库
|
||||
- **数据安全可控**:支持完全本地部署,保护企业数据隐私
|
||||
- **灵活模型部署**:兼容 Ollama、vLLM 等本地推理框架
|
||||
|
||||
### AI创作工具
|
||||
|
||||
- **AI 绘画创作**:深度集成 DALL·E-3、MidJourney、Stable Diffusion
|
||||
- **智能PPT生成**:一键将文本内容转换为精美演示文稿
|
||||
- **多模态理解**:支持文本、图片、文档等多种格式的智能处理
|
||||
|
||||
### 知识图谱与智能编排
|
||||
|
||||
- **知识图谱构建**:自动从文档和对话中提取实体关系,构建可视化知识网络
|
||||
- **AI 流程编排**:可视化工作流设计器,支持复杂AI任务的编排和自动化执行
|
||||
- **数字人交互**:集成数字人形象,提供更自然的人机交互体验
|
||||
- **智能推理引擎**:基于知识图谱的智能推理和问答能力
|
||||
|
||||
|
||||
|
||||
## 🚀 快速体验
|
||||
|
||||
### 在线演示
|
||||
|
||||
- **用户端体验**:[web.pandarobot.chat](https://web.pandarobot.chat) (账号:admin 密码:admin123)
|
||||
- **管理后台**:[admin.pandarobot.chat](https://admin.pandarobot.chat) (账号:admin 密码:admin123)
|
||||
|
||||
### 项目源码
|
||||
|
||||
| 项目模块 | GitHub 仓库 | Gitee 仓库 | GitCode 仓库 |
|
||||
|---------|------------|-----------|-------------|
|
||||
|----------|-------------------------------------------------------|------------------------------------------------------|--------------------------------------------------------|
|
||||
| 🔧 后端服务 | [ruoyi-ai](https://github.com/ageerle/ruoyi-ai) | [ruoyi-ai](https://gitee.com/ageerle/ruoyi-ai) | [ruoyi-ai](https://gitcode.com/ageerle/ruoyi-ai) |
|
||||
| 🎨 用户前端 | [ruoyi-web](https://github.com/ageerle/ruoyi-web) | [ruoyi-web](https://gitee.com/ageerle/ruoyi-web) | [ruoyi-web](https://gitcode.com/ageerle/ruoyi-web) |
|
||||
| 🛠️ 管理后台 | [ruoyi-admin](https://github.com/ageerle/ruoyi-admin) | [ruoyi-admin](https://gitee.com/ageerle/ruoyi-admin) | [ruoyi-admin](https://gitcode.com/ageerle/ruoyi-admin) |
|
||||
|
||||
### 合作项目
|
||||
|
||||
| 项目介绍 | GitHub 仓库 | Gitee 仓库 |
|
||||
|:--------:|:----------:|:----------:|
|
||||
|:-----:|:----------------------------------------------------------------------:|:----------------------------------------------------------------:|
|
||||
| 前端简化版 | [ruoyi-element-ai](https://github.com/element-plus-x/ruoyi-element-ai) | [ruoyi-element-ai](https://gitee.com/he-jiayue/ruoyi-element-ai) |
|
||||
|
||||
|
||||
|
||||
|
||||
## 🛠️ 技术架构
|
||||
|
||||
### 核心框架
|
||||
|
||||
- **后端架构**:Spring Boot 3.4 + Spring AI + Langchain4j
|
||||
- **数据存储**:MySQL 8.0 + Redis + 向量数据库(Milvus/Weaviate/Qdrant)
|
||||
- **前端技术**:Vue 3 + Vben Admin + Naive UI
|
||||
- **安全认证**:Sa-Token + JWT 双重保障
|
||||
|
||||
### 系统组件
|
||||
|
||||
- **文档处理**:PDF、Word、Excel 解析,图像智能分析
|
||||
- **实时通信**:WebSocket 实时通信,SSE 流式响应
|
||||
- **系统监控**:完善的日志体系、性能监控、服务健康检查
|
||||
@@ -107,6 +112,7 @@
|
||||
我们热烈欢迎社区贡献!无论您是资深开发者还是初学者,都可以为项目贡献力量 💪
|
||||
|
||||
### 贡献方式
|
||||
|
||||
1. **Fork** 项目到您的账户
|
||||
2. **创建分支** (`git checkout -b feature/新功能名称`)
|
||||
3. **提交代码** (`git commit -m '添加某某功能'`)
|
||||
@@ -123,7 +129,8 @@
|
||||
|
||||
感谢以下优秀的开源项目为本项目提供支持:
|
||||
|
||||
- [Spring AI Alibaba Copilot](https://github.com/springaialibaba/spring-ai-alibaba-copilot) - 基于spring-ai-alibaba 的智能编码助手
|
||||
- [Spring AI Alibaba Copilot](https://github.com/springaialibaba/spring-ai-alibaba-copilot) - 基于spring-ai-alibaba
|
||||
的智能编码助手
|
||||
- [Spring AI](https://spring.io/projects/spring-ai) - Spring 官方 AI 集成框架
|
||||
- [Langchain4j](https://github.com/langchain4j/langchain4j) - 强大的 Java LLM 开发框架
|
||||
- [RuoYi-Vue-Plus](https://gitee.com/dromara/RuoYi-Vue-Plus) - 成熟的企业级快速开发框架
|
||||
@@ -132,7 +139,8 @@
|
||||
|
||||
## 🌐 生态伙伴
|
||||
|
||||
- [PPIO 派欧云](https://ppinfra.com/user/register?invited_by=P8QTUY&utm_source=github_ruoyi-ai) - 提供高性价比的 GPU 算力和模型 API 服务
|
||||
- [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服务,秒级响应,按量计费,新客免费用。
|
||||
- [胜算云](https://www.shengsuanyun.com/?from=CH_3WG71ZOS) - AI模型算力聚合超市云服务。
|
||||
|
||||
@@ -162,20 +170,32 @@
|
||||
|
||||
<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.pandarobot.chat)**
|
||||
|
||||
*用 ❤️ 打造,由 RuoYi AI 开源社区维护*
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Badge Links -->
|
||||
|
||||
[contributors-shield]: https://img.shields.io/github/contributors/ageerle/ruoyi-ai.svg?style=flat-square
|
||||
|
||||
[contributors-url]: https://github.com/ageerle/ruoyi-ai/graphs/contributors
|
||||
|
||||
[forks-shield]: https://img.shields.io/github/forks/ageerle/ruoyi-ai.svg?style=flat-square
|
||||
|
||||
[forks-url]: https://github.com/ageerle/ruoyi-ai/network/members
|
||||
|
||||
[stars-shield]: https://img.shields.io/github/stars/ageerle/ruoyi-ai.svg?style=flat-square
|
||||
|
||||
[stars-url]: https://github.com/ageerle/ruoyi-ai/stargazers
|
||||
|
||||
[issues-shield]: https://img.shields.io/github/issues/ageerle/ruoyi-ai.svg?style=flat-square
|
||||
|
||||
[issues-url]: https://github.com/ageerle/ruoyi-ai/issues
|
||||
|
||||
[license-shield]: https://img.shields.io/github/license/ageerle/ruoyi-ai.svg?style=flat-square
|
||||
|
||||
[license-url]: https://github.com/ageerle/ruoyi-ai/blob/main/LICENSE
|
||||
|
||||
67
README_EN.md
67
README_EN.md
@@ -1,4 +1,3 @@
|
||||
|
||||
# RuoYi AI
|
||||
|
||||
<div align="center">
|
||||
@@ -13,16 +12,19 @@
|
||||
|
||||
### Enterprise-Grade AI Assistant Platform
|
||||
|
||||
*Production-ready AI platform with deep integration of FastGPT, Coze, DIFY, featuring advanced RAG technology, knowledge graphs, digital humans, and AI workflow orchestration*
|
||||
*Production-ready AI platform with deep integration of FastGPT, Coze, DIFY, featuring advanced RAG technology, knowledge
|
||||
graphs, digital humans, and AI workflow orchestration*
|
||||
|
||||
**[📖 中文文档](README.md)** | **[📚 Documentation](https://doc.pandarobot.chat)** | **[🚀 Live Demo](https://web.pandarobot.chat)** | **[🐛 Report Bug](https://github.com/ageerle/ruoyi-ai/issues)** | **[💡 Request Feature](https://github.com/ageerle/ruoyi-ai/issues)**
|
||||
**[📖 中文文档](README.md)** | **[📚 Documentation](https://doc.pandarobot.chat)** | *
|
||||
*[🚀 Live Demo](https://web.pandarobot.chat)** | **[🐛 Report Bug](https://github.com/ageerle/ruoyi-ai/issues)** | *
|
||||
*[💡 Request Feature](https://github.com/ageerle/ruoyi-ai/issues)**
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
## ✨ Key Features
|
||||
|
||||
### 🤖 Advanced AI Engine
|
||||
|
||||
- **Multi-Model Support**: OpenAI GPT-4, Azure, ChatGLM, Qwen, ZhipuAI
|
||||
- **AI Platform Integration**: Deep integration with **FastGPT**, **Coze**, **DIFY** and other leading AI platforms
|
||||
- **Spring AI MCP Integration**: Extensible tool ecosystem with Model Context Protocol
|
||||
@@ -30,58 +32,69 @@
|
||||
- **AI Copilot**: Intelligent code analysis and project scaffolding
|
||||
|
||||
### 🌟 AI Platform Ecosystem
|
||||
- **FastGPT Deep Integration**: Native FastGPT API support with knowledge base retrieval, workflow orchestration and context management
|
||||
- **Coze Official SDK**: Integration with ByteDance Coze platform official SDK, supporting Bot conversations and streaming responses
|
||||
|
||||
- **FastGPT Deep Integration**: Native FastGPT API support with knowledge base retrieval, workflow orchestration and
|
||||
context management
|
||||
- **Coze Official SDK**: Integration with ByteDance Coze platform official SDK, supporting Bot conversations and
|
||||
streaming responses
|
||||
- **DIFY Full Compatibility**: Using DIFY Java Client for app orchestration, workflows and knowledge base management
|
||||
- **Unified Chat Interface**: Standardized chat service interface supporting seamless platform switching and load balancing
|
||||
- **Unified Chat Interface**: Standardized chat service interface supporting seamless platform switching and load
|
||||
balancing
|
||||
|
||||
### 🧠 Enterprise RAG Solution
|
||||
|
||||
- **Local Knowledge Base**: Langchain4j + BGE-large-zh-v1.5 embeddings
|
||||
- **Vector Database Support**: Milvus, Weaviate, Qdrant
|
||||
- **Privacy-First**: On-premise deployment with local LLM support
|
||||
- **Ollama & vLLM Compatible**: Flexible model deployment options
|
||||
|
||||
### 🎨 Creative AI Tools
|
||||
|
||||
- **AI Art Generation**: DALL·E-3, MidJourney, Stable Diffusion integration
|
||||
- **PPT Creation**: Automated slide generation from text input
|
||||
- **Multi-Modal Processing**: Text, image, and document understanding
|
||||
|
||||
### 🧩 Knowledge Graph & Intelligent Orchestration
|
||||
- **Knowledge Graph Construction**: Automatically extract entities and relationships from documents and conversations to build visual knowledge networks
|
||||
- **AI Workflow Orchestration**: Visual workflow designer supporting complex AI task orchestration and automated execution
|
||||
|
||||
- **Knowledge Graph Construction**: Automatically extract entities and relationships from documents and conversations to
|
||||
build visual knowledge networks
|
||||
- **AI Workflow Orchestration**: Visual workflow designer supporting complex AI task orchestration and automated
|
||||
execution
|
||||
- **Digital Human Interaction**: Integrated digital human avatars for more natural human-computer interaction
|
||||
- **Intelligent Reasoning Engine**: Knowledge graph-based intelligent reasoning and Q&A capabilities
|
||||
|
||||
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### Live Demo
|
||||
|
||||
- **User Portal**: [web.pandarobot.chat](https://web.pandarobot.chat) (demo/demo123)
|
||||
- **Admin Panel**: [admin.pandarobot.chat](https://admin.pandarobot.chat) (admin/admin123)
|
||||
|
||||
### Source Code
|
||||
|
||||
| Component | GitHub | Gitee | GitCode |
|
||||
|-----------|--------|-------|---------|
|
||||
|----------------|-------------------------------------------------------|------------------------------------------------------|--------------------------------------------------------|
|
||||
| Backend API | [ruoyi-ai](https://github.com/ageerle/ruoyi-ai) | [ruoyi-ai](https://gitee.com/ageerle/ruoyi-ai) | [ruoyi-ai](https://gitcode.com/ageerle/ruoyi-ai) |
|
||||
| User Frontend | [ruoyi-web](https://github.com/ageerle/ruoyi-web) | [ruoyi-web](https://gitee.com/ageerle/ruoyi-web) | [ruoyi-web](https://gitcode.com/ageerle/ruoyi-web) |
|
||||
| Admin Frontend | [ruoyi-admin](https://github.com/ageerle/ruoyi-admin) | [ruoyi-admin](https://gitee.com/ageerle/ruoyi-admin) | [ruoyi-admin](https://gitcode.com/ageerle/ruoyi-admin) |
|
||||
|
||||
### Collaborative Projects
|
||||
| Project Description | GitHub Repository | Gitee Repository |
|
||||
|:-------------------:|:-----------------:|:----------------:|
|
||||
| Simplified Frontend | [ruoyi-element-ai](https://github.com/element-plus-x/ruoyi-element-ai) | [ruoyi-element-ai](https://gitee.com/he-jiayue/ruoyi-element-ai) |
|
||||
|
||||
| Project Description | GitHub Repository | Gitee Repository |
|
||||
|:-------------------:|:----------------------------------------------------------------------:|:----------------------------------------------------------------:|
|
||||
| Simplified Frontend | [ruoyi-element-ai](https://github.com/element-plus-x/ruoyi-element-ai) | [ruoyi-element-ai](https://gitee.com/he-jiayue/ruoyi-element-ai) |
|
||||
|
||||
## 🛠️ Tech Stack
|
||||
|
||||
### Core Framework
|
||||
|
||||
- **Backend**: Spring Boot 3.4, Spring AI, Langchain4j
|
||||
- **Database**: MySQL 8.0, Redis, Vector Databases (Milvus/Weaviate/Qdrant)
|
||||
- **Frontend**: Vue 3, Vben Admin, Naive UI
|
||||
- **Authentication**: Sa-Token, JWT
|
||||
|
||||
### System Components
|
||||
|
||||
- **File Processing**: PDF, Word, Excel parsing, intelligent image analysis
|
||||
- **Real-time Communication**: WebSocket real-time communication, SSE streaming
|
||||
- **System Monitoring**: Comprehensive logging, performance monitoring, health checks
|
||||
@@ -94,9 +107,11 @@ For detailed setup, configuration, and development guides, visit our comprehensi
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
We welcome contributions from developers of all skill levels! Whether you're fixing bugs, adding features, or improving documentation, your help is appreciated.
|
||||
We welcome contributions from developers of all skill levels! Whether you're fixing bugs, adding features, or improving
|
||||
documentation, your help is appreciated.
|
||||
|
||||
### How to Contribute
|
||||
|
||||
1. Fork the repository
|
||||
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
||||
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
||||
@@ -109,12 +124,12 @@ We welcome contributions from developers of all skill levels! Whether you're fix
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
||||
|
||||
|
||||
## 🙏 Acknowledgments
|
||||
|
||||
Special thanks to these amazing open source projects:
|
||||
|
||||
- [Spring AI Alibaba Copilot](https://github.com/springaialibaba/spring-ai-alibaba-copilot) - Intelligent coding assistant based on spring-ai-alibaba with MCP protocol integration for project analysis and code generation
|
||||
- [Spring AI Alibaba Copilot](https://github.com/springaialibaba/spring-ai-alibaba-copilot) - Intelligent coding
|
||||
assistant based on spring-ai-alibaba with MCP protocol integration for project analysis and code generation
|
||||
- [Spring AI](https://spring.io/projects/spring-ai) - Spring's AI integration framework
|
||||
- [Langchain4j](https://github.com/langchain4j/langchain4j) - Java LLM framework
|
||||
- [RuoYi-Vue-Plus](https://gitee.com/dromara/RuoYi-Vue-Plus) - Enterprise development framework
|
||||
@@ -123,7 +138,8 @@ Special thanks to these amazing open source projects:
|
||||
|
||||
## 🌐 Ecosystem Partners
|
||||
|
||||
- [PPIO Cloud](https://ppinfra.com/user/register?invited_by=P8QTUY&utm_source=github_ruoyi-ai) - Cost-effective GPU containers and model APIs
|
||||
- [PPIO Cloud](https://ppinfra.com/user/register?invited_by=P8QTUY&utm_source=github_ruoyi-ai) - Cost-effective GPU
|
||||
containers and model APIs
|
||||
|
||||
## 💬 Community
|
||||
|
||||
@@ -150,22 +166,33 @@ Special thanks to these amazing open source projects:
|
||||
|
||||
<div align="center">
|
||||
|
||||
**[⭐ Star this repo](https://github.com/ageerle/ruoyi-ai)** • **[🍴 Fork it](https://github.com/ageerle/ruoyi-ai/fork)** • **[📖 中文文档](README.md)** • **[📚 Documentation](https://doc.pandarobot.chat)**
|
||||
**[⭐ Star this repo](https://github.com/ageerle/ruoyi-ai)** • **[🍴 Fork it](https://github.com/ageerle/ruoyi-ai/fork)
|
||||
** • **[📖 中文文档](README.md)** • **[📚 Documentation](https://doc.pandarobot.chat)**
|
||||
|
||||
*Built with ❤️ by the RuoYi AI community*
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Badge Links -->
|
||||
|
||||
[contributors-shield]: https://img.shields.io/github/contributors/ageerle/ruoyi-ai.svg?style=flat-square
|
||||
|
||||
[contributors-url]: https://github.com/ageerle/ruoyi-ai/graphs/contributors
|
||||
|
||||
[forks-shield]: https://img.shields.io/github/forks/ageerle/ruoyi-ai.svg?style=flat-square
|
||||
|
||||
[forks-url]: https://github.com/ageerle/ruoyi-ai/network/members
|
||||
|
||||
[stars-shield]: https://img.shields.io/github/stars/ageerle/ruoyi-ai.svg?style=flat-square
|
||||
|
||||
[stars-url]: https://github.com/ageerle/ruoyi-ai/stargazers
|
||||
|
||||
[issues-shield]: https://img.shields.io/github/issues/ageerle/ruoyi-ai.svg?style=flat-square
|
||||
|
||||
[issues-url]: https://github.com/ageerle/ruoyi-ai/issues
|
||||
|
||||
[license-shield]: https://img.shields.io/github/license/ageerle/ruoyi-ai.svg?style=flat-square
|
||||
|
||||
[license-url]: https://github.com/ageerle/ruoyi-ai/blob/main/LICENSE
|
||||
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ ruoyi-admin/target/ruoyi-admin.jar
|
||||
### 五、上传 Jar 包至服务器
|
||||
|
||||
将生成的 `ruoyi-admin.jar` 上传到服务器 `/ruoyi-ai/deploy` 目录下。
|
||||
确保与 `Dockerfile` 同目录。
|
||||
确保与 `Dockerfile` 同目录。
|
||||
|
||||
------
|
||||
|
||||
@@ -195,7 +195,7 @@ source /docker-entrypoint-initdb.d/ruoyi-ai.sql;
|
||||
### 九、常用 Docker 命令
|
||||
|
||||
| 功能 | 命令 |
|
||||
| ----------------- | --------------------------------- |
|
||||
|-----------|-----------------------------------|
|
||||
| 查看容器状态 | `docker ps -a` |
|
||||
| 查看日志 | `docker logs -f <容器名>` |
|
||||
| 停止服务 | `docker compose down` |
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
## 概述
|
||||
|
||||
Ruoyi-AI 工作流模块是一个基于 LangGraph4j 的智能工作流引擎,支持可视化工作流设计、AI 模型集成、条件分支、人机交互等高级功能。该模块采用微服务架构,提供完整的 RESTful API 和流式响应支持。
|
||||
Ruoyi-AI 工作流模块是一个基于 LangGraph4j 的智能工作流引擎,支持可视化工作流设计、AI 模型集成、条件分支、人机交互等高级功能。该模块采用微服务架构,提供完整的
|
||||
RESTful API 和流式响应支持。
|
||||
|
||||
## 模块架构
|
||||
|
||||
@@ -48,12 +49,14 @@ ruoyi-ai/
|
||||
### 1. 工作流管理
|
||||
|
||||
#### 1.1 工作流定义
|
||||
|
||||
- **创建工作流**: 支持自定义标题、描述、公开性设置
|
||||
- **编辑工作流**: 可视化节点编辑、连接线配置
|
||||
- **版本控制**: 支持工作流的版本管理和回滚
|
||||
- **权限管理**: 支持公开/私有工作流设置
|
||||
|
||||
#### 1.2 工作流执行
|
||||
|
||||
- **流式执行**: 基于 SSE 的实时流式响应
|
||||
- **状态管理**: 完整的执行状态跟踪
|
||||
- **错误处理**: 详细的错误信息和异常处理
|
||||
@@ -62,26 +65,31 @@ ruoyi-ai/
|
||||
### 2. 节点类型
|
||||
|
||||
#### 2.1 基础节点
|
||||
|
||||
- **Start**: 开始节点,定义工作流入口
|
||||
- **End**: 结束节点,定义工作流出口
|
||||
|
||||
#### 2.2 AI 模型节点
|
||||
|
||||
- **Answer**: 大语言模型问答节点
|
||||
- **Dalle3**: DALL-E 3 图像生成
|
||||
- **Tongyiwanx**: 通义万相图像生成
|
||||
- **Classifier**: 内容分类节点
|
||||
|
||||
#### 2.3 数据处理节点
|
||||
|
||||
- **DocumentExtractor**: 文档信息提取
|
||||
- **KeywordExtractor**: 关键词提取
|
||||
- **FaqExtractor**: 常见问题提取
|
||||
- **KnowledgeRetrieval**: 知识库检索
|
||||
|
||||
#### 2.4 控制流节点
|
||||
|
||||
- **Switcher**: 条件分支节点
|
||||
- **HumanFeedback**: 人机交互节点
|
||||
|
||||
#### 2.5 外部集成节点
|
||||
|
||||
- **Google**: Google 搜索集成
|
||||
- **MailSend**: 邮件发送
|
||||
- **HttpRequest**: HTTP 请求
|
||||
@@ -90,6 +98,7 @@ ruoyi-ai/
|
||||
### 3. 数据流管理
|
||||
|
||||
#### 3.1 输入输出定义
|
||||
|
||||
```java
|
||||
// 节点输入输出数据结构
|
||||
public class NodeIOData {
|
||||
@@ -108,6 +117,7 @@ public enum WfIODataTypeEnum {
|
||||
```
|
||||
|
||||
#### 3.2 参数引用
|
||||
|
||||
- **节点间引用**: 支持上游节点输出作为下游节点输入
|
||||
- **参数映射**: 自动处理参数名称映射
|
||||
- **类型转换**: 自动进行数据类型转换
|
||||
@@ -117,6 +127,7 @@ public enum WfIODataTypeEnum {
|
||||
### 1. 核心表结构
|
||||
|
||||
#### 1.1 工作流定义表 (t_workflow)
|
||||
|
||||
```sql
|
||||
CREATE TABLE t_workflow (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
@@ -133,6 +144,7 @@ CREATE TABLE t_workflow (
|
||||
```
|
||||
|
||||
#### 1.2 工作流节点表 (t_workflow_node)
|
||||
|
||||
```sql
|
||||
CREATE TABLE t_workflow_node (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
@@ -153,6 +165,7 @@ CREATE TABLE t_workflow_node (
|
||||
```
|
||||
|
||||
#### 1.3 工作流边表 (t_workflow_edge)
|
||||
|
||||
```sql
|
||||
CREATE TABLE t_workflow_edge (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
@@ -168,6 +181,7 @@ CREATE TABLE t_workflow_edge (
|
||||
```
|
||||
|
||||
#### 1.4 工作流运行时表 (t_workflow_runtime)
|
||||
|
||||
```sql
|
||||
CREATE TABLE t_workflow_runtime (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
@@ -185,6 +199,7 @@ CREATE TABLE t_workflow_runtime (
|
||||
```
|
||||
|
||||
#### 1.5 工作流组件表 (t_workflow_component)
|
||||
|
||||
```sql
|
||||
CREATE TABLE t_workflow_component (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
@@ -205,6 +220,7 @@ CREATE TABLE t_workflow_component (
|
||||
### 1. 工作流管理接口
|
||||
|
||||
#### 1.1 基础操作
|
||||
|
||||
```http
|
||||
# 创建工作流
|
||||
POST /workflow/add
|
||||
@@ -232,6 +248,7 @@ POST /workflow/enable/{uuid}?enable=true
|
||||
```
|
||||
|
||||
#### 1.2 搜索和查询
|
||||
|
||||
```http
|
||||
# 搜索我的工作流
|
||||
GET /workflow/mine/search?keyword=关键词&isPublic=true¤tPage=1&pageSize=10
|
||||
@@ -246,6 +263,7 @@ GET /workflow/public/component/list
|
||||
### 2. 工作流执行接口
|
||||
|
||||
#### 2.1 流式执行
|
||||
|
||||
```http
|
||||
# 流式执行工作流
|
||||
POST /workflow/run
|
||||
@@ -266,6 +284,7 @@ Accept: text/event-stream
|
||||
```
|
||||
|
||||
#### 2.2 运行时管理
|
||||
|
||||
```http
|
||||
# 恢复中断的工作流
|
||||
POST /workflow/runtime/resume/{runtimeUuid}
|
||||
@@ -287,6 +306,7 @@ POST /workflow/runtime/clear?wfUuid=工作流UUID
|
||||
### 3. 管理端接口
|
||||
|
||||
#### 3.1 工作流管理
|
||||
|
||||
```http
|
||||
# 搜索所有工作流
|
||||
POST /admin/workflow/search
|
||||
@@ -306,6 +326,7 @@ POST /admin/workflow/enable?uuid=工作流UUID&isEnable=true
|
||||
### 1. 工作流引擎 (WorkflowEngine)
|
||||
|
||||
工作流引擎是整个模块的核心,负责:
|
||||
|
||||
- 工作流图的构建和编译
|
||||
- 节点执行调度
|
||||
- 状态管理和持久化
|
||||
@@ -399,7 +420,6 @@ public class WorkflowGraphBuilder {
|
||||
4. **状态更新**: 实时更新节点和工作流状态
|
||||
5. **错误处理**: 捕获并处理执行过程中的错误
|
||||
|
||||
|
||||
## 扩展开发
|
||||
|
||||
### 1. 自定义节点开发
|
||||
|
||||
4
pom.xml
4
pom.xml
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>ruoyi-ai</artifactId>
|
||||
|
||||
@@ -81,6 +81,7 @@ public class AuthController {
|
||||
|
||||
/**
|
||||
* 访客登录
|
||||
*
|
||||
* @param loginBody 登录信息
|
||||
* @return token信息
|
||||
*/
|
||||
|
||||
@@ -22,5 +22,4 @@ public class IndexController {
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
--- # 数据源配置
|
||||
spring:
|
||||
datasource:
|
||||
@@ -16,9 +15,9 @@ spring:
|
||||
master:
|
||||
type: ${spring.datasource.type}
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://127.0.0.1:3306/ruoyi-ai?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
||||
username: root
|
||||
password: root
|
||||
url: jdbc:mysql://47.112.190.27:3306/ruoyi-ai?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
||||
username: ruoyi-ai
|
||||
password: fc6jEZa77HHYZkw6
|
||||
|
||||
hikari:
|
||||
# 最大连接池数量
|
||||
|
||||
@@ -98,32 +98,32 @@
|
||||
</appender>
|
||||
|
||||
<!-- 整合 skywalking 控制台输出 tid -->
|
||||
<!-- <appender name="console" class="ch.qos.logback.core.ConsoleAppender">-->
|
||||
<!-- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">-->
|
||||
<!-- <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">-->
|
||||
<!-- <pattern>[%tid] ${console.log.pattern}</pattern>-->
|
||||
<!-- </layout>-->
|
||||
<!-- <charset>utf-8</charset>-->
|
||||
<!-- </encoder>-->
|
||||
<!-- </appender>-->
|
||||
<!-- <appender name="console" class="ch.qos.logback.core.ConsoleAppender">-->
|
||||
<!-- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">-->
|
||||
<!-- <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">-->
|
||||
<!-- <pattern>[%tid] ${console.log.pattern}</pattern>-->
|
||||
<!-- </layout>-->
|
||||
<!-- <charset>utf-8</charset>-->
|
||||
<!-- </encoder>-->
|
||||
<!-- </appender>-->
|
||||
|
||||
<!-- 整合 skywalking 推送采集日志 -->
|
||||
<!-- <appender name="sky_log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">-->
|
||||
<!-- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">-->
|
||||
<!-- <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">-->
|
||||
<!-- <pattern>[%tid] ${console.log.pattern}</pattern>-->
|
||||
<!-- </layout>-->
|
||||
<!-- <charset>utf-8</charset>-->
|
||||
<!-- </encoder>-->
|
||||
<!-- </appender>-->
|
||||
<!-- <appender name="sky_log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">-->
|
||||
<!-- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">-->
|
||||
<!-- <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">-->
|
||||
<!-- <pattern>[%tid] ${console.log.pattern}</pattern>-->
|
||||
<!-- </layout>-->
|
||||
<!-- <charset>utf-8</charset>-->
|
||||
<!-- </encoder>-->
|
||||
<!-- </appender>-->
|
||||
|
||||
<!--系统操作日志-->
|
||||
<root level="info">
|
||||
<appender-ref ref="console" />
|
||||
<appender-ref ref="async_info" />
|
||||
<appender-ref ref="async_error" />
|
||||
<appender-ref ref="file_console" />
|
||||
<!-- <appender-ref ref="sky_log"/>-->
|
||||
<appender-ref ref="console"/>
|
||||
<appender-ref ref="async_info"/>
|
||||
<appender-ref ref="async_error"/>
|
||||
<appender-ref ref="file_console"/>
|
||||
<!-- <appender-ref ref="sky_log"/>-->
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
|
||||
@@ -6,7 +6,6 @@ import cn.hutool.core.date.DateUnit;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* @date 2023-03-10
|
||||
*/
|
||||
@@ -16,16 +15,14 @@ public class LocalCache {
|
||||
* 缓存时长
|
||||
*/
|
||||
public static final long TIMEOUT = 30 * DateUnit.MINUTE.getMillis();
|
||||
/**
|
||||
* 清理间隔
|
||||
*/
|
||||
private static final long CLEAN_TIMEOUT = 30 * DateUnit.MINUTE.getMillis();
|
||||
|
||||
/**
|
||||
* 缓存对象
|
||||
*/
|
||||
public static final TimedCache<String, Object> CACHE = CacheUtil.newTimedCache(TIMEOUT);
|
||||
|
||||
/**
|
||||
* 清理间隔
|
||||
*/
|
||||
private static final long CLEAN_TIMEOUT = 30 * DateUnit.MINUTE.getMillis();
|
||||
|
||||
static {
|
||||
//启动定时任务
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.ruoyi.common.chat.constant;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* @since 2023-03-06
|
||||
*/
|
||||
|
||||
@@ -7,7 +7,6 @@ import lombok.Data;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* @since 2023-03-18
|
||||
*/
|
||||
|
||||
@@ -7,7 +7,6 @@ import lombok.Data;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* @since 2023-03-18
|
||||
*/
|
||||
|
||||
@@ -4,7 +4,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* @since 2023-04-08
|
||||
*/
|
||||
|
||||
@@ -12,7 +12,6 @@ import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* @since 1.1.2
|
||||
* 2023-03-02
|
||||
@@ -34,6 +33,7 @@ public class BaseMessage implements Serializable {
|
||||
|
||||
/**
|
||||
* The tool calls generated by the model, such as function calls.
|
||||
*
|
||||
* @since 1.1.2
|
||||
*/
|
||||
@JsonProperty("tool_calls")
|
||||
|
||||
@@ -7,7 +7,6 @@ import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* @since 2023-03-02
|
||||
*/
|
||||
|
||||
@@ -6,7 +6,6 @@ import lombok.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author https://www.unfbx.com
|
||||
* @since 1.1.2
|
||||
* 2023-11-10
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FastGPTAnswerResponse {
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.io.Serializable;
|
||||
* },
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* @since 2023-06-14
|
||||
*/
|
||||
|
||||
@@ -8,7 +8,6 @@ import lombok.NoArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author https://www.unfbx.com
|
||||
* 2023-11-10
|
||||
*/
|
||||
|
||||
@@ -10,8 +10,6 @@ import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* @since 2023-03-02
|
||||
*/
|
||||
@@ -24,10 +22,6 @@ public class Message extends BaseMessage implements Serializable {
|
||||
@JsonProperty("reasoning_content")
|
||||
private String reasoningContent;
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*
|
||||
@@ -57,6 +51,10 @@ public class Message extends BaseMessage implements Serializable {
|
||||
super.setToolCallId(builder.toolCallId);
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
private String role;
|
||||
private String content;
|
||||
|
||||
@@ -25,10 +25,6 @@ public class MessagePicture extends BaseMessage implements Serializable {
|
||||
private List<Content> content;
|
||||
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*
|
||||
@@ -58,6 +54,10 @@ public class MessagePicture extends BaseMessage implements Serializable {
|
||||
super.setToolCallId(builder.toolCallId);
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
private String role;
|
||||
private List<Content> content;
|
||||
|
||||
@@ -5,6 +5,7 @@ import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 方法参数类,扩展参数可以继承Parameters自己实现
|
||||
* 参考:
|
||||
@@ -21,6 +22,7 @@ import java.util.List;
|
||||
* "required": ["location"]
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* @since 2023-06-14
|
||||
*/
|
||||
|
||||
@@ -7,7 +7,6 @@ import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -6,8 +6,6 @@ import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -5,9 +5,8 @@ import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -7,8 +7,6 @@ import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -101,6 +101,7 @@ public class Completion implements Serializable {
|
||||
|
||||
/**
|
||||
* 获取当前参数的tokens数
|
||||
*
|
||||
* @return token数量
|
||||
*/
|
||||
// public long tokens() {
|
||||
|
||||
@@ -7,8 +7,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
@@ -35,7 +33,7 @@ public class Edit implements Serializable {
|
||||
|
||||
/**
|
||||
* 使用什么取样温度,0到2之间。较高的值(如0.8)将使输出更加随机,而较低的值(如0.2)将使输出更加集中和确定。
|
||||
*
|
||||
* <p>
|
||||
* We generally recommend altering this or but not both.top_p
|
||||
*/
|
||||
@Builder.Default
|
||||
@@ -43,7 +41,7 @@ public class Edit implements Serializable {
|
||||
|
||||
/**
|
||||
* 使用温度采样的替代方法称为核心采样,其中模型考虑具有top_p概率质量的令牌的结果。因此,0.1 意味着只考虑包含前 10% 概率质量的代币。
|
||||
*
|
||||
* <p>
|
||||
* 我们通常建议更改此设置,但不要同时更改两者。temperature
|
||||
*/
|
||||
@JsonProperty("top_p")
|
||||
@@ -90,6 +88,7 @@ public class Edit implements Serializable {
|
||||
public void setInstruction(String instruction) {
|
||||
this.instruction = instruction;
|
||||
}
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum Model {
|
||||
|
||||
@@ -9,8 +9,6 @@ import org.ruoyi.common.chat.entity.common.Usage;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -9,8 +9,6 @@ import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -8,8 +8,6 @@ import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -6,8 +6,6 @@ import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -6,8 +6,6 @@ import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -6,8 +6,6 @@ import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -30,6 +30,7 @@ public class FineTune implements Serializable {
|
||||
private String validationFile;
|
||||
/**
|
||||
* 参考
|
||||
*
|
||||
* @see Model
|
||||
*/
|
||||
private String model;
|
||||
@@ -101,7 +102,7 @@ public class FineTune implements Serializable {
|
||||
}
|
||||
|
||||
public void setSuffix(String suffix) {
|
||||
if(Objects.nonNull(suffix) && !"".equals(suffix) && suffix.length() > 40){
|
||||
if (Objects.nonNull(suffix) && !"".equals(suffix) && suffix.length() > 40) {
|
||||
log.error("后缀长度不能大于40");
|
||||
throw new BaseException(CommonError.PARAM_ERROR.msg());
|
||||
}
|
||||
|
||||
@@ -11,8 +11,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -11,8 +11,6 @@ import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
@@ -48,11 +46,11 @@ public class ImageEdit implements Serializable {
|
||||
private String user;
|
||||
|
||||
public ImageEdit setN(Integer n) {
|
||||
if(n < 1){
|
||||
if (n < 1) {
|
||||
log.warn("n最小值1");
|
||||
n = 1;
|
||||
}
|
||||
if(n > 10){
|
||||
if (n > 10) {
|
||||
log.warn("n最大值10");
|
||||
n = 10;
|
||||
}
|
||||
@@ -61,11 +59,11 @@ public class ImageEdit implements Serializable {
|
||||
}
|
||||
|
||||
public ImageEdit setPrompt(String prompt) {
|
||||
if(Objects.isNull(prompt) || "".equals(prompt)){
|
||||
if (Objects.isNull(prompt) || "".equals(prompt)) {
|
||||
log.error("参数异常");
|
||||
throw new BaseException(CommonError.PARAM_ERROR.msg());
|
||||
}
|
||||
if(prompt.length() > 1000){
|
||||
if (prompt.length() > 1000) {
|
||||
log.error("长度超过1000");
|
||||
throw new BaseException(CommonError.PARAM_ERROR.msg());
|
||||
}
|
||||
@@ -74,7 +72,7 @@ public class ImageEdit implements Serializable {
|
||||
}
|
||||
|
||||
public ImageEdit setSize(SizeEnum size) {
|
||||
if(Objects.isNull(size)){
|
||||
if (Objects.isNull(size)) {
|
||||
size = SizeEnum.size_512;
|
||||
}
|
||||
this.size = size.getName();
|
||||
@@ -82,7 +80,7 @@ public class ImageEdit implements Serializable {
|
||||
}
|
||||
|
||||
public ImageEdit setResponseFormat(ResponseFormat responseFormat) {
|
||||
if(Objects.isNull(responseFormat)){
|
||||
if (Objects.isNull(responseFormat)) {
|
||||
responseFormat = ResponseFormat.URL;
|
||||
}
|
||||
this.responseFormat = responseFormat.getName();
|
||||
|
||||
@@ -7,8 +7,6 @@ import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -12,8 +12,6 @@ import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -7,8 +7,6 @@ import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -6,8 +6,6 @@ import lombok.Getter;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -6,8 +6,6 @@ import lombok.Getter;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
package org.ruoyi.common.chat.entity.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
@@ -13,8 +14,8 @@ public class LocalModelsSearchResponse {
|
||||
private List<List<List<Double>>> topKEmbeddings; // 处理三层嵌套数组
|
||||
|
||||
// 默认构造函数
|
||||
public LocalModelsSearchResponse() {}
|
||||
|
||||
public LocalModelsSearchResponse() {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -8,8 +8,6 @@ import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -7,8 +7,6 @@ import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -7,8 +7,6 @@ import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -7,8 +7,6 @@ import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -8,8 +8,6 @@ import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -7,8 +7,6 @@ import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -7,8 +7,6 @@ import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-15
|
||||
*/
|
||||
|
||||
@@ -6,8 +6,6 @@ import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* @since 2023-03-02
|
||||
*/
|
||||
|
||||
@@ -47,7 +47,7 @@ public class PlusWebSocketHandler extends AbstractWebSocketHandler {
|
||||
if (StrUtil.isNotBlank(messageContext)) {
|
||||
messages = JSONUtil.toList(messageContext, Message.class);
|
||||
// 上下文长度
|
||||
int contextSize=10;
|
||||
int contextSize = 10;
|
||||
if (messages.size() >= contextSize) {
|
||||
messages = messages.subList(1, contextSize);
|
||||
}
|
||||
@@ -64,7 +64,7 @@ public class PlusWebSocketHandler extends AbstractWebSocketHandler {
|
||||
.temperature(0.2)
|
||||
.stream(true)
|
||||
.build();
|
||||
OpenAiStreamClient openAiStreamClient=(OpenAiStreamClient) SpringUtils.context().getBean("openAiStreamClient");
|
||||
OpenAiStreamClient openAiStreamClient = (OpenAiStreamClient) SpringUtils.context().getBean("openAiStreamClient");
|
||||
openAiStreamClient.streamChatCompletion(chatCompletion, eventSourceListener);
|
||||
LocalCache.CACHE.put(session.getId(), JSONUtil.toJsonStr(messages), LocalCache.TIMEOUT);
|
||||
}
|
||||
|
||||
@@ -22,12 +22,11 @@ import java.util.Objects;
|
||||
@Slf4j
|
||||
public class WebSocketEventListener extends EventSourceListener {
|
||||
|
||||
private WebSocketSession session;
|
||||
|
||||
/**
|
||||
* 消息结束标识
|
||||
*/
|
||||
private final String msgEnd = "[DONE]";
|
||||
private WebSocketSession session;
|
||||
|
||||
public WebSocketEventListener(WebSocketSession session) {
|
||||
this.session = session;
|
||||
@@ -59,8 +58,8 @@ public class WebSocketEventListener extends EventSourceListener {
|
||||
String delta = "";
|
||||
try {
|
||||
delta = mapper.writeValueAsString(completionResponse.getChoices().get(0).getDelta());
|
||||
}catch (Exception e){
|
||||
log.error("转换失败{}",e.getMessage());
|
||||
} catch (Exception e) {
|
||||
log.error("转换失败{}", e.getMessage());
|
||||
}
|
||||
session.sendMessage(new TextMessage(delta));
|
||||
}
|
||||
|
||||
@@ -100,15 +100,6 @@ public class OpenAiClient {
|
||||
@Getter
|
||||
private OpenAiAuthInterceptor authInterceptor;
|
||||
|
||||
/**
|
||||
* 构造器
|
||||
*
|
||||
* @return OpenAiClient.Builder
|
||||
*/
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
@@ -156,6 +147,14 @@ public class OpenAiClient {
|
||||
.build().create(OpenAiApi.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造器
|
||||
*
|
||||
* @return OpenAiClient.Builder
|
||||
*/
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建默认OkHttpClient
|
||||
@@ -681,7 +680,7 @@ public class OpenAiClient {
|
||||
RequestBody fileBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
|
||||
MultipartBody.Part multipartBody = MultipartBody.Part.createFormData("file", file.getName(), fileBody);
|
||||
//自定义参数
|
||||
Map<String, RequestBody> requestBodyMap = new HashMap<>(5,1L);
|
||||
Map<String, RequestBody> requestBodyMap = new HashMap<>(5, 1L);
|
||||
|
||||
if (StrUtil.isNotBlank(translations.getModel())) {
|
||||
requestBodyMap.put(Translations.Fields.model, RequestBody.create(MediaType.parse("multipart/form-data"), translations.getModel()));
|
||||
@@ -812,6 +811,7 @@ public class OpenAiClient {
|
||||
Single<Subscription> subscription = this.openAiApi.subscription();
|
||||
return subscription.blockingGet();
|
||||
}
|
||||
|
||||
/**
|
||||
* 账户调用接口消耗金额信息查询
|
||||
* 最多查询100天
|
||||
@@ -833,7 +833,6 @@ public class OpenAiClient {
|
||||
private @NotNull List<String> apiKey;
|
||||
/**
|
||||
* api请求地址,结尾处有斜杠
|
||||
*
|
||||
*/
|
||||
private String apiHost;
|
||||
/**
|
||||
|
||||
@@ -63,31 +63,27 @@ import java.util.concurrent.TimeUnit;
|
||||
@Setter
|
||||
public class OpenAiStreamClient {
|
||||
|
||||
private static final String DONE_SIGNAL = "[DONE]";
|
||||
@NotNull
|
||||
private List<String> apiKey;
|
||||
/**
|
||||
* 自定义api host使用builder的方式构造client
|
||||
*/
|
||||
private String apiHost;
|
||||
|
||||
/**
|
||||
* 自定义url 兼容多个平台
|
||||
*/
|
||||
private String apiUrl;
|
||||
|
||||
/**
|
||||
* 自定义的okHttpClient
|
||||
* 如果不自定义 ,就是用sdk默认的OkHttpClient实例
|
||||
*/
|
||||
private OkHttpClient okHttpClient;
|
||||
|
||||
/**
|
||||
* api key的获取策略
|
||||
*/
|
||||
private KeyStrategyFunction<List<String>, String> keyStrategy;
|
||||
|
||||
private OpenAiApi openAiApi;
|
||||
|
||||
/**
|
||||
* 自定义鉴权处理拦截器<br/>
|
||||
* 可以不设置,默认实现:DefaultOpenAiAuthInterceptor <br/>
|
||||
@@ -98,8 +94,6 @@ public class OpenAiStreamClient {
|
||||
*/
|
||||
private OpenAiAuthInterceptor authInterceptor;
|
||||
|
||||
private static final String DONE_SIGNAL = "[DONE]";
|
||||
|
||||
/**
|
||||
* 构造实例对象
|
||||
*
|
||||
@@ -155,6 +149,15 @@ public class OpenAiStreamClient {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建默认的OkHttpClient
|
||||
*/
|
||||
@@ -174,7 +177,6 @@ public class OpenAiStreamClient {
|
||||
return okHttpClient;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 流式输出,最新版的GPT-3.5 chat completion 更加贴近官方网站的问答模型
|
||||
*
|
||||
@@ -238,7 +240,6 @@ public class OpenAiStreamClient {
|
||||
this.streamChatCompletion(chatCompletion, pluginEventSourceListener);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 插件问答简易版
|
||||
* 默认取messages最后一个元素构建插件对话
|
||||
@@ -255,7 +256,6 @@ public class OpenAiStreamClient {
|
||||
this.streamChatCompletionWithPlugin(chatCompletion, eventSourceListener, pluginEventSourceListener, plugin);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 插件问答简易版
|
||||
* 默认取messages最后一个元素构建插件对话
|
||||
@@ -287,7 +287,6 @@ public class OpenAiStreamClient {
|
||||
this.streamChatCompletionWithPlugin(chatCompletion, eventSourceListener, plugin);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据描述生成图片
|
||||
*
|
||||
@@ -457,6 +456,7 @@ public class OpenAiStreamClient {
|
||||
Transcriptions transcriptions = Transcriptions.builder().build();
|
||||
return this.speechToTextTranscriptions(file, transcriptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文本转语音(异步)
|
||||
*
|
||||
@@ -475,12 +475,12 @@ public class OpenAiStreamClient {
|
||||
* @param textToSpeech 参数
|
||||
* @since 1.1.3
|
||||
*/
|
||||
public ResponseBody textToSpeech(TextToSpeech textToSpeech){
|
||||
public ResponseBody textToSpeech(TextToSpeech textToSpeech) {
|
||||
try {
|
||||
Call<ResponseBody> responseBody = this.openAiApi.textToSpeech(textToSpeech);
|
||||
return responseBody.execute().body();
|
||||
} catch (IOException e) {
|
||||
throw new BaseException("文本转语音(同步)失败: "+e.getMessage());
|
||||
throw new BaseException("文本转语音(同步)失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -514,7 +514,7 @@ public class OpenAiStreamClient {
|
||||
try {
|
||||
return client.newCall(request).execute().body();
|
||||
} catch (IOException e) {
|
||||
throw new BaseException("语音克隆失败!{}",e.getMessage());
|
||||
throw new BaseException("语音克隆失败!{}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -602,16 +602,6 @@ public class OpenAiStreamClient {
|
||||
return this.chatCompletionWithPlugin(chatCompletion, plugin);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
private @NotNull List<String> apiKey;
|
||||
/**
|
||||
|
||||
@@ -6,9 +6,14 @@ import java.io.IOException;
|
||||
|
||||
public class TestOpenAIAPI {
|
||||
|
||||
private final OkHttpClient client = new OkHttpClient();
|
||||
private static final String API_KEY = "sk-Waea254YSRYVg4FZVCz2CDz73B22xRpmKpJ41kbczVgpPxvg";
|
||||
private static final String URL = "https://api.gptgod.online/v1/chat/completions";
|
||||
private final OkHttpClient client = new OkHttpClient();
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
TestOpenAIAPI api = new TestOpenAIAPI();
|
||||
api.getChatGptResponse("Hello, how are you?");
|
||||
}
|
||||
|
||||
public void getChatGptResponse(String prompt) throws IOException {
|
||||
RequestBody body = RequestBody.create(MediaType.get("application/json; charset=utf-8"),
|
||||
@@ -24,9 +29,4 @@ public class TestOpenAIAPI {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
TestOpenAIAPI api = new TestOpenAIAPI();
|
||||
api.getChatGptResponse("Hello, how are you?");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ public enum CommonError implements IError {
|
||||
RETRY_ERROR(502, "请求异常,请重试~"),
|
||||
//官方的错误码列表:https://platform.openai.com/docs/guides/error-codes/api-errors
|
||||
OPENAI_AUTHENTICATION_ERROR(401, "身份验证无效/提供的 API 密钥不正确/您必须是组织的成员才能使用 API"),
|
||||
OPENAI_LIMIT_ERROR(429 , "达到请求的速率限制/您超出了当前配额,请检查您的计划和帐单详细信息/发动机当前过载,请稍后重试"),
|
||||
OPENAI_LIMIT_ERROR(429, "达到请求的速率限制/您超出了当前配额,请检查您的计划和帐单详细信息/发动机当前过载,请稍后重试"),
|
||||
OPENAI_SERVER_ERROR(500, "服务器在处理您的请求时出错"),
|
||||
;
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.ruoyi.common.chat.openai.exception;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* 2023-02-11
|
||||
*/
|
||||
|
||||
@@ -5,9 +5,9 @@ import java.util.function.Function;
|
||||
/**
|
||||
* key 的获取策略
|
||||
* jdk默认实现
|
||||
* @see Function
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* @see Function
|
||||
* @since 2023-04-03
|
||||
*/
|
||||
@FunctionalInterface
|
||||
|
||||
@@ -35,7 +35,6 @@ public class DynamicKeyOpenAiAuthInterceptor extends OpenAiAuthInterceptor {
|
||||
|
||||
/**
|
||||
* 请求头处理
|
||||
*
|
||||
*/
|
||||
public DynamicKeyOpenAiAuthInterceptor() {
|
||||
this.setWarringConfig(null);
|
||||
|
||||
@@ -69,6 +69,10 @@ public abstract class PluginAbstract<R extends PluginParam, T> {
|
||||
setParameters();
|
||||
}
|
||||
|
||||
public abstract T func(R args);
|
||||
|
||||
public abstract String content(T t);
|
||||
|
||||
@Data
|
||||
public static class Arg {
|
||||
private String name;
|
||||
@@ -81,8 +85,4 @@ public abstract class PluginAbstract<R extends PluginParam, T> {
|
||||
@JsonIgnore
|
||||
private boolean required;
|
||||
}
|
||||
|
||||
public abstract T func(R args);
|
||||
|
||||
public abstract String content(T t);
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author https:www.unfbx.com
|
||||
* @sine 2023-04-08
|
||||
*/
|
||||
@@ -18,15 +16,21 @@ public class Dall3Request {
|
||||
@NotEmpty(message = "提示词不能为空")
|
||||
private String prompt;
|
||||
|
||||
/** 图片大小 */
|
||||
/**
|
||||
* 图片大小
|
||||
*/
|
||||
@NotEmpty(message = "图片大小不能为空")
|
||||
private String size ;
|
||||
private String size;
|
||||
|
||||
/** 图片质量 */
|
||||
/**
|
||||
* 图片质量
|
||||
*/
|
||||
@NotEmpty(message = "图片质量不能为空")
|
||||
private String quality;
|
||||
|
||||
/** 图片风格 */
|
||||
/**
|
||||
* 图片风格
|
||||
*/
|
||||
@NotEmpty(message = "图片风格不能为空")
|
||||
private String style;
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ public class ConsoleEventSourceListener extends EventSourceListener {
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public void onFailure(EventSource eventSource, Throwable t, Response response) {
|
||||
if(Objects.isNull(response)){
|
||||
if (Objects.isNull(response)) {
|
||||
log.error("OpenAI sse连接异常:{}", t);
|
||||
eventSource.cancel();
|
||||
return;
|
||||
|
||||
@@ -30,21 +30,10 @@ public abstract class PluginListener<R extends PluginParam, T> extends EventSour
|
||||
* openAi插件构建的参数
|
||||
*/
|
||||
private String arguments = "";
|
||||
|
||||
/**
|
||||
* 获取openAi插件构建的参数
|
||||
*
|
||||
* @return arguments
|
||||
*/
|
||||
private String getArguments() {
|
||||
return this.arguments;
|
||||
}
|
||||
|
||||
private OpenAiStreamClient client;
|
||||
private EventSourceListener eventSourceListener;
|
||||
private PluginAbstract<R, T> plugin;
|
||||
private ChatCompletion chatCompletion;
|
||||
|
||||
/**
|
||||
* 构造方法必备四个元素
|
||||
*
|
||||
@@ -60,6 +49,15 @@ public abstract class PluginListener<R extends PluginParam, T> extends EventSour
|
||||
this.chatCompletion = chatCompletion;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取openAi插件构建的参数
|
||||
*
|
||||
* @return arguments
|
||||
*/
|
||||
private String getArguments() {
|
||||
return this.arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* sse关闭后处理,第二次请求方法
|
||||
*/
|
||||
|
||||
@@ -152,7 +152,7 @@ public class TikTokensUtil {
|
||||
}
|
||||
Encoding enc = getEncoding(modelName);
|
||||
if (Objects.isNull(enc)) {
|
||||
log.warn("[{}]模型不存在或者暂不支持计算tokens,直接返回tokens==0",modelName);
|
||||
log.warn("[{}]模型不存在或者暂不支持计算tokens,直接返回tokens==0", modelName);
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return enc.encode(text);
|
||||
@@ -192,17 +192,17 @@ public class TikTokensUtil {
|
||||
) {
|
||||
tokensPerMessage = 3;
|
||||
tokensPerName = 1;
|
||||
}else if(modelName.contains(ChatCompletion.Model.GPT_3_5_TURBO.getName())){
|
||||
} else if (modelName.contains(ChatCompletion.Model.GPT_3_5_TURBO.getName())) {
|
||||
//"gpt-3.5-turbo" in model:
|
||||
log.warn("Warning: gpt-3.5-turbo may update over time. Returning num tokens assuming gpt-3.5-turbo-0613.");
|
||||
tokensPerMessage = 3;
|
||||
tokensPerName = 1;
|
||||
}else if(modelName.contains(ChatCompletion.Model.GPT_4.getName())){
|
||||
} else if (modelName.contains(ChatCompletion.Model.GPT_4.getName())) {
|
||||
log.warn("Warning: gpt-4 may update over time. Returning num tokens assuming gpt-4-0613.");
|
||||
tokensPerMessage = 3;
|
||||
tokensPerName = 1;
|
||||
}else {
|
||||
log.warn("不支持的model {} 按gpt4计算tokens",modelName);
|
||||
} else {
|
||||
log.warn("不支持的model {} 按gpt4计算tokens", modelName);
|
||||
tokensPerMessage = 3;
|
||||
tokensPerName = 1;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
|
||||
@@ -16,31 +16,27 @@ import org.springframework.stereotype.Component;
|
||||
@ConfigurationProperties(prefix = "ruoyi")
|
||||
public class RuoYiConfig {
|
||||
|
||||
/**
|
||||
* 项目名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 版本
|
||||
*/
|
||||
private String version;
|
||||
|
||||
/**
|
||||
* 版权年份
|
||||
*/
|
||||
private String copyrightYear;
|
||||
|
||||
/**
|
||||
* 实例演示开关
|
||||
*/
|
||||
private boolean demoEnabled;
|
||||
|
||||
/**
|
||||
* 获取地址开关
|
||||
*/
|
||||
@Getter
|
||||
private static boolean addressEnabled;
|
||||
/**
|
||||
* 项目名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 版本
|
||||
*/
|
||||
private String version;
|
||||
/**
|
||||
* 版权年份
|
||||
*/
|
||||
private String copyrightYear;
|
||||
/**
|
||||
* 实例演示开关
|
||||
*/
|
||||
private boolean demoEnabled;
|
||||
|
||||
public void setAddressEnabled(boolean addressEnabled) {
|
||||
RuoYiConfig.addressEnabled = addressEnabled;
|
||||
|
||||
@@ -16,19 +16,16 @@ import java.io.Serializable;
|
||||
@NoArgsConstructor
|
||||
public class R<T> implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 成功
|
||||
*/
|
||||
public static final int SUCCESS = 200;
|
||||
|
||||
/**
|
||||
* 失败
|
||||
*/
|
||||
public static final int FAIL = 500;
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
private int code;
|
||||
|
||||
private String msg;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.ruoyi.common.core.exception;
|
||||
|
||||
public class AuthException extends RuntimeException{
|
||||
public class AuthException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
@@ -46,22 +46,22 @@ public final class ServiceException extends RuntimeException {
|
||||
return detailMessage;
|
||||
}
|
||||
|
||||
public ServiceException setDetailMessage(String detailMessage) {
|
||||
this.detailMessage = detailMessage;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public ServiceException setMessage(String message) {
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServiceException setDetailMessage(String detailMessage) {
|
||||
this.detailMessage = detailMessage;
|
||||
return this;
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.ruoyi.common.core.manager;
|
||||
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.ruoyi.common.core.utils.Threads;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
@@ -7,19 +7,20 @@ package org.ruoyi.common.core.service;
|
||||
public class BaseContext {
|
||||
private static ThreadLocal<String> threadLocal = new ThreadLocal<>();
|
||||
|
||||
/**
|
||||
* @description: 获取值
|
||||
* @author: yzm
|
||||
**/
|
||||
public static String getCurrentToken() {
|
||||
return threadLocal.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 设置值
|
||||
* @author: yzm
|
||||
* @param: [token] 线程token
|
||||
**/
|
||||
public static void setCurrentToken(String token){
|
||||
public static void setCurrentToken(String token) {
|
||||
threadLocal.set(token);
|
||||
}
|
||||
/**
|
||||
* @description: 获取值
|
||||
* @author: yzm
|
||||
**/
|
||||
public static String getCurrentToken(){
|
||||
return threadLocal.get();
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,7 @@ public interface ConfigService {
|
||||
* @param configKey
|
||||
* @return
|
||||
*/
|
||||
String getConfigValue(String category,String configKey);
|
||||
|
||||
String getConfigValue(String category, String configKey);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -12,16 +12,15 @@ import java.util.concurrent.TimeUnit;
|
||||
@Component
|
||||
public class OkHttpUtil {
|
||||
|
||||
@Setter
|
||||
private String apiHost;
|
||||
@Setter
|
||||
private String apiKey;
|
||||
|
||||
private final OkHttpClient client = new OkHttpClient.Builder()
|
||||
.connectTimeout(3000, TimeUnit.SECONDS)
|
||||
.writeTimeout(3000, TimeUnit.SECONDS)
|
||||
.readTimeout(3000, TimeUnit.SECONDS)
|
||||
.build();
|
||||
@Setter
|
||||
private String apiHost;
|
||||
@Setter
|
||||
private String apiKey;
|
||||
|
||||
public String executeRequest(Request request) {
|
||||
try (Response response = client.newCall(request).execute()) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
|
||||
@@ -56,7 +56,7 @@ public class SpringDocProperties {
|
||||
* </p>
|
||||
*
|
||||
* @see io.swagger.v3.oas.models.info.Info
|
||||
*
|
||||
* <p>
|
||||
* 为了 springboot 自动生产配置提示信息,所以这里复制一个类出来
|
||||
*/
|
||||
@Data
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
|
||||
@@ -61,7 +61,7 @@ public class MybatisDecryptInterceptor implements Interceptor {
|
||||
return;
|
||||
}
|
||||
if (sourceObject instanceof List<?> list) {
|
||||
if(CollUtil.isEmpty(list)) {
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return;
|
||||
}
|
||||
// 判断第一个元素是否含有注解。如果没有直接返回,提高效率
|
||||
|
||||
@@ -70,7 +70,7 @@ public class MybatisEncryptInterceptor implements Interceptor {
|
||||
return;
|
||||
}
|
||||
if (sourceObject instanceof List<?> list) {
|
||||
if(CollUtil.isEmpty(list)) {
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return;
|
||||
}
|
||||
// 判断第一个元素是否含有注解。如果没有直接返回,提高效率
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
|
||||
@@ -6,7 +6,7 @@ import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* excel 列单元格合并(合并列相同项)
|
||||
*
|
||||
* <p>
|
||||
* 需搭配 {@link CellMergeStrategy} 策略使用
|
||||
*
|
||||
* @author Lion Li
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
|
||||
@@ -15,17 +15,16 @@ import java.io.IOException;
|
||||
@JacksonStdImpl
|
||||
public class BigNumberSerializer extends NumberSerializer {
|
||||
|
||||
/**
|
||||
* 提供实例
|
||||
*/
|
||||
public static final BigNumberSerializer INSTANCE = new BigNumberSerializer(Number.class);
|
||||
/**
|
||||
* 根据 JS Number.MAX_SAFE_INTEGER 与 Number.MIN_SAFE_INTEGER 得来
|
||||
*/
|
||||
private static final long MAX_SAFE_INTEGER = 9007199254740991L;
|
||||
private static final long MIN_SAFE_INTEGER = -9007199254740991L;
|
||||
|
||||
/**
|
||||
* 提供实例
|
||||
*/
|
||||
public static final BigNumberSerializer INSTANCE = new BigNumberSerializer(Number.class);
|
||||
|
||||
public BigNumberSerializer(Class<? extends Number> rawType) {
|
||||
super(rawType);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
|
||||
@@ -42,7 +42,7 @@ public class LogAspect {
|
||||
/**
|
||||
* 排除敏感属性字段
|
||||
*/
|
||||
public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" };
|
||||
public static final String[] EXCLUDE_PROPERTIES = {"password", "oldPassword", "newPassword", "confirmPassword"};
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
|
||||
@@ -44,7 +44,7 @@ public class MailConfig {
|
||||
account.setConnectionTimeout(0);
|
||||
}
|
||||
|
||||
public String getKey(String key){
|
||||
public String getKey(String key) {
|
||||
return configService.getConfigValue("mail", key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,10 @@ public class Mail implements Builder<MimeMessage> {
|
||||
* 邮箱帐户信息以及一些客户端配置信息
|
||||
*/
|
||||
private final MailAccount mailAccount;
|
||||
/**
|
||||
* 正文、附件和图片的混合部分
|
||||
*/
|
||||
private final Multipart multipart = new MimeMultipart();
|
||||
/**
|
||||
* 收件人列表
|
||||
*/
|
||||
@@ -64,10 +68,6 @@ public class Mail implements Builder<MimeMessage> {
|
||||
* 是否为HTML
|
||||
*/
|
||||
private boolean isHtml;
|
||||
/**
|
||||
* 正文、附件和图片的混合部分
|
||||
*/
|
||||
private final Multipart multipart = new MimeMultipart();
|
||||
/**
|
||||
* 是否使用全局会话,默认为false
|
||||
*/
|
||||
@@ -78,6 +78,25 @@ public class Mail implements Builder<MimeMessage> {
|
||||
*/
|
||||
private PrintStream debugOutput;
|
||||
|
||||
/**
|
||||
* 构造,使用全局邮件帐户
|
||||
*/
|
||||
public Mail() {
|
||||
this(GlobalMailAccount.INSTANCE.getAccount());
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param mailAccount 邮件帐户,如果为null使用默认配置文件的全局邮件配置
|
||||
*/
|
||||
public Mail(MailAccount mailAccount) {
|
||||
mailAccount = (null != mailAccount) ? mailAccount : GlobalMailAccount.INSTANCE.getAccount();
|
||||
this.mailAccount = mailAccount.defaultIfEmpty();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------- Constructor start
|
||||
|
||||
/**
|
||||
* 创建邮件客户端
|
||||
*
|
||||
@@ -96,25 +115,6 @@ public class Mail implements Builder<MimeMessage> {
|
||||
public static Mail create() {
|
||||
return new Mail();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------- Constructor start
|
||||
|
||||
/**
|
||||
* 构造,使用全局邮件帐户
|
||||
*/
|
||||
public Mail() {
|
||||
this(GlobalMailAccount.INSTANCE.getAccount());
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param mailAccount 邮件帐户,如果为null使用默认配置文件的全局邮件配置
|
||||
*/
|
||||
public Mail(MailAccount mailAccount) {
|
||||
mailAccount = (null != mailAccount) ? mailAccount : GlobalMailAccount.INSTANCE.getAccount();
|
||||
this.mailAccount = mailAccount.defaultIfEmpty();
|
||||
}
|
||||
// --------------------------------------------------------------- Constructor end
|
||||
|
||||
// --------------------------------------------------------------- Getters and Setters start
|
||||
|
||||
@@ -18,9 +18,9 @@ import java.util.Properties;
|
||||
* @author Luxiaolei
|
||||
*/
|
||||
public class MailAccount implements Serializable {
|
||||
public static final String[] MAIL_SETTING_PATHS = new String[]{"config/mail.setting", "config/mailAccount.setting", "mail.setting"};
|
||||
@Serial
|
||||
private static final long serialVersionUID = -6937313421815719204L;
|
||||
|
||||
private static final String MAIL_PROTOCOL = "mail.transport.protocol";
|
||||
private static final String SMTP_HOST = "mail.smtp.host";
|
||||
private static final String SMTP_PORT = "mail.smtp.port";
|
||||
@@ -28,7 +28,6 @@ public class MailAccount implements Serializable {
|
||||
private static final String SMTP_TIMEOUT = "mail.smtp.timeout";
|
||||
private static final String SMTP_CONNECTION_TIMEOUT = "mail.smtp.connectiontimeout";
|
||||
private static final String SMTP_WRITE_TIMEOUT = "mail.smtp.writetimeout";
|
||||
|
||||
// SSL
|
||||
private static final String STARTTLS_ENABLE = "mail.smtp.starttls.enable";
|
||||
private static final String SSL_ENABLE = "mail.smtp.ssl.enable";
|
||||
@@ -36,17 +35,16 @@ public class MailAccount implements Serializable {
|
||||
private static final String SOCKET_FACTORY = "mail.smtp.socketFactory.class";
|
||||
private static final String SOCKET_FACTORY_FALLBACK = "mail.smtp.socketFactory.fallback";
|
||||
private static final String SOCKET_FACTORY_PORT = "smtp.socketFactory.port";
|
||||
|
||||
// System Properties
|
||||
private static final String SPLIT_LONG_PARAMS = "mail.mime.splitlongparameters";
|
||||
//private static final String ENCODE_FILE_NAME = "mail.mime.encodefilename";
|
||||
//private static final String CHARSET = "mail.mime.charset";
|
||||
|
||||
// System Properties
|
||||
private static final String SPLIT_LONG_PARAMS = "mail.mime.splitlongparameters";
|
||||
// 其他
|
||||
private static final String MAIL_DEBUG = "mail.debug";
|
||||
|
||||
public static final String[] MAIL_SETTING_PATHS = new String[]{"config/mail.setting", "config/mailAccount.setting", "mail.setting"};
|
||||
|
||||
/**
|
||||
* 自定义的其他属性,此自定义属性会覆盖默认属性
|
||||
*/
|
||||
private final Map<String, Object> customProperty = new HashMap<>();
|
||||
/**
|
||||
* SMTP服务器域名
|
||||
*/
|
||||
@@ -71,7 +69,6 @@ public class MailAccount implements Serializable {
|
||||
* 发送方,遵循RFC-822标准
|
||||
*/
|
||||
private String from;
|
||||
|
||||
/**
|
||||
* 是否打开调试模式,调试模式会显示与邮件服务器通信过程,默认不开启
|
||||
*/
|
||||
@@ -88,7 +85,6 @@ public class MailAccount implements Serializable {
|
||||
* 对于文件名是否使用{@link #charset}编码,默认为 {@code true}
|
||||
*/
|
||||
private boolean encodefilename = true;
|
||||
|
||||
/**
|
||||
* 使用 STARTTLS安全连接,STARTTLS是对纯文本通信协议的扩展。它将纯文本连接升级为加密连接(TLS或SSL), 而不是使用一个单独的加密通信端口。
|
||||
*/
|
||||
@@ -97,12 +93,10 @@ public class MailAccount implements Serializable {
|
||||
* 使用 SSL安全连接
|
||||
*/
|
||||
private Boolean sslEnable;
|
||||
|
||||
/**
|
||||
* SSL协议,多个协议用空格分隔
|
||||
*/
|
||||
private String sslProtocols;
|
||||
|
||||
/**
|
||||
* 指定实现javax.net.SocketFactory接口的类的名称,这个类将被用于创建SMTP的套接字
|
||||
*/
|
||||
@@ -115,7 +109,6 @@ public class MailAccount implements Serializable {
|
||||
* 指定的端口连接到在使用指定的套接字工厂。如果没有设置,将使用默认端口
|
||||
*/
|
||||
private int socketFactoryPort = 465;
|
||||
|
||||
/**
|
||||
* SMTP超时时长,单位毫秒,缺省值不超时
|
||||
*/
|
||||
@@ -129,11 +122,6 @@ public class MailAccount implements Serializable {
|
||||
*/
|
||||
private long writeTimeout;
|
||||
|
||||
/**
|
||||
* 自定义的其他属性,此自定义属性会覆盖默认属性
|
||||
*/
|
||||
private final Map<String, Object> customProperty = new HashMap<>();
|
||||
|
||||
// -------------------------------------------------------------- Constructor start
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
|
||||
@@ -23,38 +23,37 @@ import java.util.List;
|
||||
@Data
|
||||
public class PageQuery implements Serializable {
|
||||
|
||||
/**
|
||||
* 当前记录起始索引 默认值
|
||||
*/
|
||||
public static final int DEFAULT_PAGE_NUM = 1;
|
||||
/**
|
||||
* 每页显示记录数 默认值 默认查全部
|
||||
*/
|
||||
public static final int DEFAULT_PAGE_SIZE = Integer.MAX_VALUE;
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 分页大小
|
||||
*/
|
||||
private Integer pageSize;
|
||||
|
||||
/**
|
||||
* 当前页数
|
||||
*/
|
||||
private Integer pageNum;
|
||||
|
||||
/**
|
||||
* 排序列
|
||||
*/
|
||||
private String orderByColumn;
|
||||
|
||||
/**
|
||||
* 排序的方向desc或者asc
|
||||
*/
|
||||
private String isAsc;
|
||||
|
||||
/**
|
||||
* 当前记录起始索引 默认值
|
||||
*/
|
||||
public static final int DEFAULT_PAGE_NUM = 1;
|
||||
|
||||
/**
|
||||
* 每页显示记录数 默认值 默认查全部
|
||||
*/
|
||||
public static final int DEFAULT_PAGE_SIZE = Integer.MAX_VALUE;
|
||||
public PageQuery(Integer pageSize, Integer pageNum) {
|
||||
this.pageSize = pageSize;
|
||||
this.pageNum = pageNum;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建分页对象
|
||||
@@ -75,7 +74,7 @@ public class PageQuery implements Serializable {
|
||||
|
||||
/**
|
||||
* 构建排序
|
||||
*
|
||||
* <p>
|
||||
* 支持的用法如下:
|
||||
* {isAsc:"asc",orderByColumn:"id"} order by id asc
|
||||
* {isAsc:"asc",orderByColumn:"id,createTime"} order by id asc,create_time asc
|
||||
@@ -119,9 +118,4 @@ public class PageQuery implements Serializable {
|
||||
return (pageNum - 1) * pageSize;
|
||||
}
|
||||
|
||||
public PageQuery(Integer pageSize, Integer pageNum) {
|
||||
this.pageSize = pageSize;
|
||||
this.pageNum = pageNum;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
|
||||
@@ -28,7 +28,7 @@ public interface OssConstant {
|
||||
/**
|
||||
* 云服务商
|
||||
*/
|
||||
String[] CLOUD_SERVICE = new String[] {"aliyun", "qcloud", "qiniu", "obs"};
|
||||
String[] CLOUD_SERVICE = new String[]{"aliyun", "qcloud", "qiniu", "obs"};
|
||||
|
||||
/**
|
||||
* https 状态
|
||||
|
||||
@@ -77,6 +77,36 @@ public class OssClient {
|
||||
}
|
||||
}
|
||||
|
||||
private static String getPolicy(String bucketName, PolicyType policyType) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("{\n\"Statement\": [\n{\n\"Action\": [\n");
|
||||
builder.append(switch (policyType) {
|
||||
case WRITE -> "\"s3:GetBucketLocation\",\n\"s3:ListBucketMultipartUploads\"\n";
|
||||
case READ_WRITE -> "\"s3:GetBucketLocation\",\n\"s3:ListBucket\",\n\"s3:ListBucketMultipartUploads\"\n";
|
||||
default -> "\"s3:GetBucketLocation\"\n";
|
||||
});
|
||||
builder.append("],\n\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
|
||||
builder.append(bucketName);
|
||||
builder.append("\"\n},\n");
|
||||
if (policyType == PolicyType.READ) {
|
||||
builder.append("{\n\"Action\": [\n\"s3:ListBucket\"\n],\n\"Effect\": \"Deny\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
|
||||
builder.append(bucketName);
|
||||
builder.append("\"\n},\n");
|
||||
}
|
||||
builder.append("{\n\"Action\": ");
|
||||
builder.append(switch (policyType) {
|
||||
case WRITE ->
|
||||
"[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n";
|
||||
case READ_WRITE ->
|
||||
"[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:GetObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n";
|
||||
default -> "\"s3:GetObject\",\n";
|
||||
});
|
||||
builder.append("\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
|
||||
builder.append(bucketName);
|
||||
builder.append("/*\"\n}\n],\n\"Version\": \"2012-10-17\"\n}\n");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public void createBucket() {
|
||||
try {
|
||||
String bucketName = properties.getBucketName();
|
||||
@@ -178,7 +208,6 @@ public class OssClient {
|
||||
return path + suffix;
|
||||
}
|
||||
|
||||
|
||||
public String getConfigKey() {
|
||||
return configKey;
|
||||
}
|
||||
@@ -214,32 +243,4 @@ public class OssClient {
|
||||
return AccessPolicyType.getByType(properties.getAccessPolicy());
|
||||
}
|
||||
|
||||
private static String getPolicy(String bucketName, PolicyType policyType) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("{\n\"Statement\": [\n{\n\"Action\": [\n");
|
||||
builder.append(switch (policyType) {
|
||||
case WRITE -> "\"s3:GetBucketLocation\",\n\"s3:ListBucketMultipartUploads\"\n";
|
||||
case READ_WRITE -> "\"s3:GetBucketLocation\",\n\"s3:ListBucket\",\n\"s3:ListBucketMultipartUploads\"\n";
|
||||
default -> "\"s3:GetBucketLocation\"\n";
|
||||
});
|
||||
builder.append("],\n\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
|
||||
builder.append(bucketName);
|
||||
builder.append("\"\n},\n");
|
||||
if (policyType == PolicyType.READ) {
|
||||
builder.append("{\n\"Action\": [\n\"s3:ListBucket\"\n],\n\"Effect\": \"Deny\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
|
||||
builder.append(bucketName);
|
||||
builder.append("\"\n},\n");
|
||||
}
|
||||
builder.append("{\n\"Action\": ");
|
||||
builder.append(switch (policyType) {
|
||||
case WRITE -> "[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n";
|
||||
case READ_WRITE -> "[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:GetObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n";
|
||||
default -> "\"s3:GetObject\",\n";
|
||||
});
|
||||
builder.append("\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
|
||||
builder.append(bucketName);
|
||||
builder.append("/*\"\n}\n],\n\"Version\": \"2012-10-17\"\n}\n");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user