43 Commits

Author SHA1 Message Date
ageer
5476a4b0b7 fix: 公众号登录功能同步 2025-04-30 19:34:09 +08:00
ageerle
cd490aa0e5 feat: 新增wechat模块 2025-04-30 11:29:23 +08:00
ageerle
b1ff44df4b feat: sse对话样式优化 2025-04-29 11:44:47 +08:00
ageerle
dc6d00f0fc feat: 查询gpts无需登录 2025-04-29 11:00:34 +08:00
ageerle
990da8da6f feat: 增加工具调用超时时间配置 2025-04-24 17:09:52 +08:00
ageerle
8fc7ad0359 feat: mcp开启后才执行工具调用 2025-04-24 10:31:58 +08:00
ageer
8a89d9eb9c fix: 1.合并知识库对话接口 2.修复web无法查询套餐信息 2025-04-23 23:10:31 +08:00
ageer
abfa9ae97b fix: 1.合并知识库对话接口 2.修复web无法查询套餐信息 2025-04-23 23:09:56 +08:00
ageer
bde2e8ff8e fix: 1.合并知识库对话接口 2.修复web无法查询套餐信息 2025-04-23 23:09:22 +08:00
ageer
4d8eb1850f feat: 附件上传逻辑调整 2025-04-22 21:43:40 +08:00
ageer
5aaa3a5662 fix: 1. 修复No static resource tool/gen/list. 2. 修复新增数据库校验异常 2025-04-22 21:24:00 +08:00
ageerle
8fec96f5b2 feat: 默认关闭mcp功能 2025-04-22 18:01:40 +08:00
ageerle
15c306eca2 fix: 根据不同的模型构建对话客户端 2025-04-22 11:28:10 +08:00
ageerle
620ea1fc76 fix: 系统提示词非必填 2025-04-22 11:06:38 +08:00
ageerle
c5c375dc6d fix: 扣费时无法获取用户id 2025-04-22 10:43:54 +08:00
ageerle
1b793e822a fix: 扣费时无法获取用户id 2025-04-22 10:40:36 +08:00
ageerle
6281840f36 fix: 修复后台管理系统登录异常 2025-04-22 09:12:56 +08:00
ageer
f5daa7eb78 feat: 设置server-filesystem默认路径为D盘 防止启动报错 2025-04-21 20:34:05 +08:00
ageer
52cb563383 fix(1.修复/store/appList404 2.修复无法查询数据库 3.修复请求地址'/chat/config/configKey/logoImage',发生系统异常): 2025-04-21 20:16:53 +08:00
ageerle
69efc3261e Merge branch 'dev' 2025-04-21 09:44:09 +08:00
ageerle
fb19fb29cc feat: 移除文件 2025-04-21 09:43:09 +08:00
ageer
9f257cf712 feat: mcp升级依赖 2025-04-20 22:52:09 +08:00
ageer
4af26fe4b4 feat: mcp升级依赖 2025-04-20 22:52:00 +08:00
ageerle
ab2a118ee9 feat: 更新项目说明 2025-04-18 11:11:48 +08:00
ageerle
9cd97a4dc5 feat: mcp支持远程调用 2025-04-18 10:55:42 +08:00
ageerle
788b372e32 feat: mcp支持远程调用 2025-04-17 16:23:32 +08:00
lh
744f9b6c7f 更新readme.md 2025-04-17 11:09:00 +08:00
ageer
761d954ef1 feat: mcp 1.0.0 2025-04-16 21:56:05 +08:00
ageerle
d1006f50ad feat: mcp-1.0.0 2025-04-16 10:25:10 +08:00
ageerle
f24ff5bbdd feat: mcp 测试版本 2025-04-15 17:34:21 +08:00
ageer
a4314dbbde feat: mcp测试版 2025-04-14 23:10:17 +08:00
ageerle
188dc1e55e feat: mcp 测试版本 2025-04-14 17:23:33 +08:00
ageer
731352fd04 feat: mcp测试版 2025-04-14 00:22:21 +08:00
ageer
4b53939002 feat: mcp支持,模块重构 2025-04-12 15:18:16 +08:00
lh
b50c15755d 更新readme.md 2025-04-12 14:19:51 +08:00
ageer
0dc6262b39 feat: mcp支持 2025-04-12 10:09:01 +08:00
ageer
9b32e3b3b2 feat: mcp支持 2025-04-12 10:08:51 +08:00
ageerle
37a8b7dad3 feat: 对话模块重构 2025-04-11 15:47:05 +08:00
ageerle
efeb0bd6fb fix: ollama兼容联网查询 知识库检索 2025-04-11 12:05:13 +08:00
ageerle
af33040117 fix: 语音功能无法使用 2025-04-11 10:45:02 +08:00
ageerle
ac4c037634 feat: 重构模块 2025-04-11 09:51:23 +08:00
ageerle
9734ec53f7 feat: 重构模块 2025-04-11 09:34:37 +08:00
lh
09abc0b5af 新增讨论群信息 2025-04-08 14:05:05 +08:00
922 changed files with 167142 additions and 4946 deletions

142
README.md
View File

@@ -36,48 +36,85 @@
## 目录
- [系统体验](#系统体验)
- [源码地址](#源码地址)
- [特色功能](#特色功能)
- [配套文档](#项目文档)
- [核心功能](#核心功能)
- [项目演示](#项目演示)
- [后台管理](#后台管理)
- [管理](#管理)
- [用户端](#用户端)
- [小程序端](#小程序端)
- [开发前的配置要求](#开发前的配置要求)
- [文件目录说明](#文件目录说明)
- [使用到的框架](#使用到的框架)
- [开发环境](#开发环境)
- [项目结构](#项目结构)
- [ruoyi-ai](#ruoyi-ai)
- [注意事项](#注意事项)
- [vben模板](#vben模板)
- [贡献者](#贡献者)
- [如何参与开源项目](#如何参与开源项目)
- [版本控制](#版本控制)
- [作者](#作者)
- [鸣谢](#鸣谢)
- [技术讨论群](#技术讨论群)
### 系统体验
- 用户端https://web.pandarobot.chat
- 管理端https://admin.pandarobot.chat
用户名: admin 密码admin123
### 源码地址
- 项目文档: https://doc.pandarobot.chat
- 前端-后台管理: https://github.com/ageerle/ruoyi-admin
- 前端-用户端: https://github.com/ageerle/ruoyi-web
- 小程序端: https://github.com/ageerle/ruoyi-uniapp
- 演示地址: https://web.pandarobot.chat
- 后台管理: https://admin.pandarobot.chat
- 用户名: admin 密码admin123
### gitcode源码地址
- https://gitcode.com/ageerle/ruoyi-ai
- https://gitcode.com/ageerle/ruoyi-web
- https://gitcode.com/ageerle/ruoyi-admin
- https://gitcode.com/ageerle/ruoyi-uniapp
[1]gitee
- 前端服务-用户端: https://gitee.com/ageerle/ruoyi-web
- 前端服务-管理端: https://gitee.com/ageerle/ruoyi-admin
- 前端服务-小程序端: https://gitee.com/ageerle/ruoyi-uniapp
- 后端服务:https://gitee.com/ageerle/ruoyi-ai
### 特色功能
[2]github
- 前端服务-用户端: https://github.com/ageerle/ruoyi-web
- 前端服务-管理端: https://github.com/ageerle/ruoyi-admin
- 前端服务-小程序端: https://github.com/ageerle/ruoyi-uniapp
- 后端服务https://github.com/ageerle/ruoyi-ai
[3]gitcode
- 前端服务-用户端https://gitcode.com/ageerle/ruoyi-web
- 前端服务-管理端: https://gitcode.com/ageerle/ruoyi-admin
- 前端服务-小程序端: https://gitcode.com/ageerle/ruoyi-uniapp
- 后端服务https://gitcode.com/ageerle/ruoyi-ai
### 配套文档
- 配套文档: https://doc.pandarobot.chat
- 项目部署文档https://doc.pandarobot.chat/guide/introduction/
### 核心功能
1. 全套开源系统提供完整的前端应用、后台管理以及小程序应用基于MIT协议开箱即用。
2. 本地RAG方案集成Milvus/Weaviate向量库、本地向量化模型与Ollama实现本地化RAG
2. 本地RAG方案集成Milvus/Weaviate向量库、本地向量化模型与Ollama实现本地化RAG
3. 丰富插件功能支持联网、SQL查询插件及Text2API插件扩展系统能力与应用场景。
4. 内置SSE、websocket等网络协议支持对接多种大语言模型同时还集成了MidJourney和DALLE AI绘画功能
5. 强大的多媒体功能支持AI翻译、PPT制作、语音克隆和翻唱等
6. 扩展功能:支持将大模型接入个人或企业微信
7. 支付功能:支持易支付、微信支付等多种支付方式
4. 内置SSE、websocket等网络协议支持对接多种大语言模型同时还集成了MidJourney和DALLE AI绘画功能
5. 强大的多媒体功能支持AI翻译、PPT制作、语音克隆和翻唱等
6. 扩展功能:支持将大模型接入个人或企业微信
7. 支付功能:支持易支付、微信支付等多种支付方式
### 项目演示
#### 后台管理
#### mcp支持
### 如何使用
1. ruoyi-admin\src\main\resources\application.yml中mcp.client.enabled改为true
2. application.yml中配置openai api-key(用于推理使用那个工具,并构建工具所需参数)
3. 启动[ruoyi-mcp-server]
4. [mcp-server.json]中配置fileSystem.command(npx本地安装路径)
5. 指定fileSystem操作目录(本地必须存在指定的目录)
6. 配置search1api.env.SEARCH1API_KEY 申请地址https://www.search1api.com/
7. 详情教程https://blog.csdn.net/weixin_42416319/article/details/147385808
<div style="display: flex; flex-wrap: wrap; gap: 20px; justify-content: center;">
<img src="image/mcp-01.png" alt="drawing" style="width: 600px; height: 300px; border: 2px solid #ddd; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);"/>
<img src="image/mcp-02.png" alt="drawing" style="width: 600px; height: 300px; border: 2px solid #ddd; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);"/>
<img src="image/mcp-03.png" alt="drawing" style="width: 600px; height: 300px; border: 2px solid #ddd; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);"/>
<img src="image/mcp-04.png" alt="drawing" style="width: 600px; height: 300px; border: 2px solid #ddd; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);"/>
</div>
#### 管理端
<div style="display: flex; flex-wrap: wrap; gap: 20px; justify-content: center;">
<img src="image/02.png" alt="drawing" style="width: 600px; height: 300px; border: 2px solid #ddd; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);"/>
<img src="image/03.png" alt="drawing" style="width: 600px; height: 300px; border: 2px solid #ddd; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);"/>
@@ -100,7 +137,7 @@
<img src="image/07.png" alt="drawing" style="width: 320px; height: 600px; border: 2px solid #ddd; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);"/>
</div>
### 开发前的配置要求
### 开发环境
1. jdk 17
2. mysql 5.7、8.0
@@ -108,8 +145,14 @@
4. maven 3.8+
5. nodejs 20+ & pnpm
### 文件目录说明
RuoYi-AI
- 附-部署配套视频https://www.bilibili.com/video/BV1jDXkYWEba
<div>
<img src="image/教程搭建.png" alt="drawing" width="600px" height="300px"/>
</div>
### 项目结构
- RuoYi-AI
```
├─ ruoyi-admin // 管理模块
@@ -158,6 +201,14 @@ RuoYi-AI
```
### 注意事项
- vben模板
Qvben5 的模板默认是没有的吗?
Avben模板是收费的 请联系vben-vue-plus作者获取。
### 版本控制
该项目使用Git进行版本管理。您可以在repository参看当前可用版本。
@@ -170,20 +221,16 @@ RuoYi-AI
### 项目现状
目前项目还处于早期阶段距离成熟还有很长的路要走。由于个人精力有限项目的发展速度受到了一定的限制。为了加快项目的进度我真诚地希望更多人能够参与到项目中来。无论是经验丰富的开发者还是刚刚入门的小白我都热烈欢迎你们提交Pull RequestPR。即使代码修改得很少或者存在一些错误都没有关系。我会认真审核每一位贡献者的代码并和大家一起完善项目。
目前项目还处于早期阶段距离成熟还有很长的路要走。由于个人精力有限项目的发展速度受到了一定的限制。为了加快项目的进度我真诚地希望更多人能够参与到项目中来。无论是经验丰富的开发者还是刚刚入门的小白我都热烈欢迎你们提交Pull RequestPR👏👏👏。即使代码修改得很少,或者存在一些错误,都没有关系。我会认真审核每一位贡献者的代码,并和大家一起完善项目⛽️⛽️⛽️
### 开发计划
- 智能体管理
| 主题 | 方向 | 时间节点 |
| --- |-----------------------------------|--------|
| 前端简化版 | 与element-plus-x框架合作推出基于该框架的前端简化版 | 2025.5 |
| agent2agent | Agent2Agent协议支持 | 2025.6 |
| 流程编排 | 通过可视化界面和灵活的配置方式快速构建AI应用 | 2025.7 |
通过设置提示词、插件、知识库等用户可以快速构建一个AI应用。这将极大地简化AI应用的开发流程降低开发门槛使更多企业能够轻松地利用AI技术。
<div>
<img src="image/13.png" alt="drawing" width="600px" height="300px"/>
</div>
- 流程编排
通过流程编排功能,用户可以将不同的模型按照业务逻辑进行有序连接。这将解决单一模型能力不足的问题,充分发挥多个模型的协同作用,从而更好地满足企业的复杂业务需求。
- 感谢
@@ -193,7 +240,7 @@ RuoYi-AI
#### 如何参与开源项目
贡献使开源社区成为一个学习、激励和创造的绝佳场所。你所作的任何贡献都是**非常感谢**的。
贡献使开源社区成为一个学习、激励和创造的绝佳场所。你所作的任何贡献,我们都非常感谢!🙏
1. Fork 这个项目
2. 创建你的功能分支 (`git checkout -b feature/dev`)
@@ -231,4 +278,23 @@ RuoYi-AI
[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=flat-square&logo=linkedin&colorB=555
### 附:技术讨论群
#### 全面开放,欢迎加入
🏠 wxruoyi-ai加人备注ruoyi-ai
🏠 qq1603234088 加人备注ruoyi-ai
👏👏👏 ruoyi-ai官方交流1群qq区1034554687
<div style="display: flex; flex-wrap: wrap; gap: 20px; justify-content: center;">
<img src="image/QQ区-官方交流1群.png" alt="drawing" style="width: 400px; height: 400px; border: 2px solid #ddd; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);"/>
</div>
👏👏👏 ruoyi-ai官方交流4群微信区
<div style="display: flex; flex-wrap: wrap; gap: 20px; justify-content: center;">
<img src="image/WX区-官方交流4群.jpg" alt="drawing" style="width: 400px; height: 400px; border: 2px solid #ddd; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);"/>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 KiB

BIN
image/mcp-01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

BIN
image/mcp-02.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 KiB

BIN
image/mcp-03.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

BIN
image/mcp-04.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

BIN
image/qq-msg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 KiB

BIN
image/wx-msg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

BIN
image/wx-msg2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

BIN
image/教程搭建.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 KiB

52
pom.xml
View File

@@ -14,26 +14,26 @@
<properties>
<revision>1.0.0</revision>
<spring-boot.version>3.0.6</spring-boot.version>
<spring-boot.version>3.4.4</spring-boot.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>17</java.version>
<mysql.version>8.0.33</mysql.version>
<spring-boot.mybatis>3.0.1</spring-boot.mybatis>
<mybatis.version>3.5.16</mybatis.version>
<springdoc.version>2.1.0</springdoc.version>
<therapi-javadoc.version>0.15.0</therapi-javadoc.version>
<poi.version>5.2.3</poi.version>
<easyexcel.version>3.2.1</easyexcel.version>
<velocity.version>2.3</velocity.version>
<satoken.version>1.34.0</satoken.version>
<mybatis-plus.version>3.5.3.1</mybatis-plus.version>
<mybatis-plus.version>3.5.11</mybatis-plus.version>
<p6spy.version>3.9.1</p6spy.version>
<hutool.version>5.8.18</hutool.version>
<hutool.version>5.8.35</hutool.version>
<okhttp.version>4.10.0</okhttp.version>
<dynamic-ds.version>4.3.1</dynamic-ds.version>
<spring-boot-admin.version>3.0.3</spring-boot-admin.version>
<redisson.version>3.20.1</redisson.version>
<lock4j.version>2.2.4</lock4j.version>
<dynamic-ds.version>3.6.1</dynamic-ds.version>
<alibaba-ttl.version>2.14.2</alibaba-ttl.version>
<xxl-job.version>2.4.0</xxl-job.version>
<mapstruct-plus.version>1.2.1</mapstruct-plus.version>
@@ -42,10 +42,6 @@
<bouncycastle.version>1.72</bouncycastle.version>
<!-- 离线IP地址定位库 -->
<ip2region.version>2.7.0</ip2region.version>
<!-- 临时修复 snakeyaml 漏洞 -->
<snakeyaml.version>1.33</snakeyaml.version>
<!-- OSS 配置 -->
<aws-java-sdk-s3.version>1.12.400</aws-java-sdk-s3.version>
<!-- SMS 配置 -->
@@ -202,22 +198,22 @@
<version>${satoken.version}</version>
</dependency>
<!-- dynamic-datasource 多数据源-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>${dynamic-ds.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${spring-boot.mybatis}</version>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-jsqlparser</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
@@ -227,6 +223,13 @@
<version>${mybatis-plus.version}</version>
</dependency>
<!-- dynamic-datasource 多数据源-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
<version>${dynamic-ds.version}</version>
</dependency>
<!-- sql性能分析插件 -->
<dependency>
<groupId>p6spy</groupId>
@@ -277,13 +280,6 @@
<version>${alibaba-ttl.version}</version>
</dependency>
<!-- 临时修复 snakeyaml 漏洞 -->
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>${snakeyaml.version}</version>
</dependency>
<!-- 加密包引入 -->
<dependency>
<groupId>org.bouncycastle</groupId>
@@ -343,7 +339,7 @@
<dependency>
<groupId>org.ruoyi</groupId>
<artifactId>ruoyi-demo</artifactId>
<artifactId>ruoyi-wechat</artifactId>
<version>${revision}</version>
</dependency>
@@ -354,6 +350,8 @@
<module>ruoyi-common</module>
<module>ruoyi-modules</module>
<module>ruoyi-modules-api</module>
<module>ruoyi-admin</module>
<module>ruoyi-extend</module>
</modules>
<packaging>pom</packaging>

99
ruoyi-admin/pom.xml Normal file
View File

@@ -0,0 +1,99 @@
<?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"
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>
<groupId>org.ruoyi</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>ruoyi-admin</artifactId>
<description>
web服务入口
</description>
<dependencies>
<!-- Mysql驱动包 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!-- Oracle -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
</dependency>
<!-- PostgreSql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<!-- SqlServer -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.ruoyi</groupId>
<artifactId>ruoyi-system</artifactId>
</dependency>
<dependency>
<groupId>org.ruoyi</groupId>
<artifactId>ruoyi-chat</artifactId>
</dependency>
<dependency>
<groupId>org.ruoyi</groupId>
<artifactId>ruoyi-generator</artifactId>
</dependency>
<dependency>
<groupId>org.ruoyi</groupId>
<artifactId>ruoyi-wechat</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>${maven-jar-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${maven-war-plugin.version}</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<warName>${project.artifactId}</warName>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -1,4 +1,4 @@
package org.ruoyi.system;
package org.ruoyi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

View File

@@ -1,4 +1,4 @@
package org.ruoyi.system;
package org.ruoyi;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

View File

@@ -1,17 +1,22 @@
package org.ruoyi.system.controller.system;
package org.ruoyi.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.collection.CollUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.ruoyi.common.core.constant.Constants;
import org.ruoyi.common.core.domain.R;
import org.ruoyi.common.core.domain.model.*;
import org.ruoyi.common.core.domain.model.EmailLoginBody;
import org.ruoyi.common.core.domain.model.LoginBody;
import org.ruoyi.common.core.domain.model.RegisterBody;
import org.ruoyi.common.core.domain.model.SmsLoginBody;
import org.ruoyi.common.core.domain.model.VisitorLoginBody;
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StreamUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.satoken.utils.LoginHelper;
import org.ruoyi.common.tenant.helper.TenantHelper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.ruoyi.system.domain.bo.SysTenantBo;
import org.ruoyi.system.domain.vo.LoginTenantVo;
import org.ruoyi.system.domain.vo.LoginVo;
@@ -42,15 +47,6 @@ public class AuthController {
private final SysRegisterService registerService;
private final ISysTenantService tenantService;
// @PostMapping("/xcxLogin")
// public R<LoginVo> login(@Validated @RequestBody String xcxCode) throws WxErrorException {
//
// String openidFromCode = loginService.getOpenidFromCode((String) JSONUtil.parseObj(xcxCode).get("xcxCode"));
// LoginVo loginVo = loginService.mpLogin(openidFromCode);
// return R.ok(loginVo);
// }
/**
* 登录方法
*
@@ -67,6 +63,7 @@ public class AuthController {
body.getUsername(), body.getPassword(),
body.getCode(), body.getUuid());
loginVo.setToken(token);
// 兼容后台管理登录
loginVo.setAccess_token(token);
loginVo.setUserInfo(LoginHelper.getLoginUser());
return R.ok(loginVo);
@@ -89,7 +86,6 @@ public class AuthController {
/**
* 访客登录
*
* @param loginBody 登录信息
* @return token信息
*/
@@ -128,7 +124,7 @@ public class AuthController {
*/
@PostMapping("/register")
public R<Void> register(@Validated @RequestBody RegisterBody user, HttpServletRequest request) {
String domainName = request.getServerName();
String domainName = request.getServerName();
user.setDomainName(domainName);
registerService.register(user);
return R.ok();

View File

@@ -1,14 +1,10 @@
package org.ruoyi.system.controller.system;
package org.ruoyi.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.captcha.AbstractCaptcha;
import cn.hutool.captcha.generator.CodeGenerator;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.common.core.constant.Constants;
import org.ruoyi.common.core.constant.GlobalConstants;
import org.ruoyi.common.core.domain.R;
@@ -26,6 +22,10 @@ import org.ruoyi.common.web.config.properties.CaptchaProperties;
import org.ruoyi.common.web.enums.CaptchaType;
import org.ruoyi.system.domain.request.EmailRequest;
import org.ruoyi.system.domain.vo.CaptchaVo;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
@@ -36,8 +36,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.*;
/**
* 验证码操作处理
@@ -95,6 +94,7 @@ public class CaptchaController {
String suffix = configService.getConfigValue("mail", "suffix");
String prompt = configService.getConfigValue("mail", "prompt");
if(StringUtils.isNotEmpty(suffix)){
// 动态的域名列表
String[] invalidDomains = suffix.split(",");
for (String domain : invalidDomains) {
if (emailRequest.getUsername().endsWith(domain)) {
@@ -107,7 +107,7 @@ public class CaptchaController {
String mailTitle = configService.getConfigValue("mail", "mailTitle");
String replacedModel = model.replace("{code}", code);
try {
MailUtils.sendHtml(emailRequest.getUsername(), mailTitle, replacedModel);
MailUtils.sendHtml(emailRequest.getUsername(), mailTitle, replacedModel);
} catch (Exception e) {
log.error("邮箱验证码发送异常 => {}", e.getMessage());
return R.fail(e.getMessage());

View File

@@ -1,7 +1,8 @@
package org.ruoyi.system.controller.system;
package org.ruoyi.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -11,7 +12,6 @@ import org.springframework.web.bind.annotation.RestController;
* @author Lion Li
*/
@SaIgnore
@RequiredArgsConstructor
@RestController
public class IndexController {
@@ -20,7 +20,9 @@ public class IndexController {
*/
@GetMapping("/")
public String index() {
return "RuoYi-AI 启动成功";
return "RuoYi AI启动成功";
}
}

View File

@@ -25,10 +25,9 @@ spring:
master:
type: ${spring.datasource.type}
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://43.139.70.230:3306/ruoyi-ai?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
username: ruoyi-ai
password: ruoyi-ai
url: jdbc:mysql://127.0.0.1:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
username: ry-vue
password: xx
hikari:
# 最大连接池数量
@@ -61,9 +60,6 @@ spring.data:
# password: 123456
# 连接超时时间
timeout: 10S
# 是否开启ssl
ssl: false
redisson:
# redis key前缀
keyPrefix:
@@ -97,3 +93,4 @@ sms:
signName: 测试
# 腾讯专用
sdkAppId:

View File

@@ -49,8 +49,10 @@ server:
# 日志配置
logging:
level:
org.ruoyi: @logging.level@
org.dromara: @logging.level@
org.springframework: warn
org.mybatis.spring.mapper: error
org.apache.fury: warn
config: classpath:logback-plus.xml
# 用户配置
@@ -318,5 +320,20 @@ wechat:
token: ''
aesKey: ''
spring:
ai:
openai:
api-key: sk-xx
base-url: https://api.pandarobot.chat/
mcp:
client:
enabled: false
name: ruoyi-ai-mcp
sse:
connections:
server:
url: http://127.0.0.1:8081
stdio:
servers-configuration: classpath:mcp-server.json
request-timeout: 300s

View File

@@ -0,0 +1,22 @@
{
"mcpServers": {
"fileSystem": {
"command": "C:\\Program Files\\nodejs\\npx.cmd",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"D:\\"
]
},
"search1api": {
"command": "C:\\Program Files\\nodejs\\npx.cmd",
"args": [
"-y",
"search1api-mcp"
],
"env": {
"SEARCH1API_KEY": "xx"
}
}
}
}

View File

@@ -39,6 +39,9 @@
<module>ruoyi-common-encrypt</module>
<module>ruoyi-common-tenant</module>
<module>ruoyi-common-chat</module>
<module>ruoyi-common-wechat</module>
<module>ruoyi-common-pay</module>
<module>ruoyi-common-live</module>
</modules>
</project>

View File

@@ -466,8 +466,8 @@ public class OpenAiStreamClient {
* @since 1.1.3
*/
public ResponseBody textToSpeech(TextToSpeech textToSpeech){
Call<ResponseBody> responseBody = this.openAiApi.textToSpeech(textToSpeech);
try {
Call<ResponseBody> responseBody = this.openAiApi.textToSpeech(textToSpeech);
return responseBody.execute().body();
} catch (IOException e) {
throw new BaseException("文本转语音(同步)失败: "+e.getMessage());
@@ -593,11 +593,6 @@ public class OpenAiStreamClient {
}
/**
* 构造
*

View File

@@ -26,6 +26,11 @@ public class ChatRequest {
*/
private String prompt;
/**
* 系统提示词
*/
private String sysPrompt;
/**
* 是否开启流式对话
*/
@@ -36,6 +41,11 @@ public class ChatRequest {
*/
private Boolean search = Boolean.FALSE;
/**
* 是否开启mcp
*/
private Boolean isMcp = Boolean.FALSE;
/**
* 知识库id
*/
@@ -44,7 +54,7 @@ public class ChatRequest {
/**
* 用户id
*/
private String userId;
private Long userId;
/**
* 应用ID

View File

@@ -109,16 +109,19 @@
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${okhttp.version}</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp-sse</artifactId>
<version>${okhttp.version}</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>logging-interceptor</artifactId>
<version>${okhttp.version}</version>
</dependency>
</dependencies>

View File

@@ -0,0 +1,59 @@
package org.ruoyi.common.core.constant;
import cn.hutool.core.lang.RegexPool;
/**
* 常用正则表达式字符串
* <p>
* 常用正则表达式集合,更多正则见: https://any86.github.io/any-rule/
*
* @author Feng
*/
public interface RegexConstants extends RegexPool {
/**
* 字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)
*/
String DICTIONARY_TYPE = "^[a-z][a-z0-9_]*$";
/**
* 权限标识必须符合以下格式:
* 1. 标准格式xxx:yyy:zzz
* - 第一部分xxx只能包含字母、数字和下划线_不能使用 `*`
* - 第二部分yyy可以包含字母、数字、下划线_和 `*`
* - 第三部分zzz可以包含字母、数字、下划线_和 `*`
* 2. 允许空字符串(""),表示没有权限标识
*/
String PERMISSION_STRING = "^$|^[a-zA-Z0-9_]+:[a-zA-Z0-9_*]+:[a-zA-Z0-9_*]+$";
/**
* 身份证号码后6位
*/
String ID_CARD_LAST_6 = "^(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$";
/**
* QQ号码
*/
String QQ_NUMBER = "^[1-9][0-9]\\d{4,9}$";
/**
* 邮政编码
*/
String POSTAL_CODE = "^[1-9]\\d{5}$";
/**
* 注册账号
*/
String ACCOUNT = "^[a-zA-Z][a-zA-Z0-9_]{4,15}$";
/**
* 密码包含至少8个字符包括大写字母、小写字母、数字和特殊字符
*/
String PASSWORD = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$";
/**
* 通用状态0表示正常1表示停用
*/
String STATUS = "^[01]$";
}

View File

@@ -0,0 +1,80 @@
package org.ruoyi.common.core.constant;
/**
* 系统常量信息
*
* @author Lion Li
*/
public interface SystemConstants {
/**
* 正常状态
*/
String NORMAL = "0";
/**
* 异常状态
*/
String DISABLE = "1";
/**
* 是否为系统默认(是)
*/
String YES = "Y";
/**
* 是否为系统默认(否)
*/
String NO = "N";
/**
* 是否菜单外链(是)
*/
String YES_FRAME = "0";
/**
* 是否菜单外链(否)
*/
String NO_FRAME = "1";
/**
* 菜单类型(目录)
*/
String TYPE_DIR = "M";
/**
* 菜单类型(菜单)
*/
String TYPE_MENU = "C";
/**
* 菜单类型(按钮)
*/
String TYPE_BUTTON = "F";
/**
* Layout组件标识
*/
String LAYOUT = "Layout";
/**
* ParentView组件标识
*/
String PARENT_VIEW = "ParentView";
/**
* InnerLink组件标识
*/
String INNER_LINK = "InnerLink";
/**
* 超级管理员ID
*/
Long SUPER_ADMIN_ID = 1L;
/**
* 根部门祖级列表
*/
String ROOT_DEPT_ANCESTORS = "0";
}

View File

@@ -0,0 +1,53 @@
package org.ruoyi.common.core.factory;
import cn.hutool.core.lang.PatternPool;
import org.ruoyi.common.core.constant.RegexConstants;
import java.util.regex.Pattern;
/**
* 正则表达式模式池工厂
* <p>初始化的时候将正则表达式加入缓存池当中</p>
* <p>提高正则表达式的性能,避免重复编译相同的正则表达式</p>
*
* @author 21001
*/
public class RegexPatternPoolFactory extends PatternPool {
/**
* 字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)
*/
public static final Pattern DICTIONARY_TYPE = get(RegexConstants.DICTIONARY_TYPE);
/**
* 身份证号码后6位
*/
public static final Pattern ID_CARD_LAST_6 = get(RegexConstants.ID_CARD_LAST_6);
/**
* QQ号码
*/
public static final Pattern QQ_NUMBER = get(RegexConstants.QQ_NUMBER);
/**
* 邮政编码
*/
public static final Pattern POSTAL_CODE = get(RegexConstants.POSTAL_CODE);
/**
* 注册账号
*/
public static final Pattern ACCOUNT = get(RegexConstants.ACCOUNT);
/**
* 密码包含至少8个字符包括大写字母、小写字母、数字和特殊字符
*/
public static final Pattern PASSWORD = get(RegexConstants.PASSWORD);
/**
* 通用状态0表示正常1表示停用
*/
public static final Pattern STATUS = get(RegexConstants.STATUS);
}

View File

@@ -0,0 +1,32 @@
package org.ruoyi.common.core.factory;
import org.ruoyi.common.core.utils.StringUtils;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;
import java.io.IOException;
/**
* yml 配置源工厂
*
* @author Lion Li
*/
public class YmlPropertySourceFactory extends DefaultPropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
String sourceName = resource.getResource().getFilename();
if (StringUtils.isNotBlank(sourceName) && StringUtils.endsWithAny(sourceName, ".yml", ".yaml")) {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(resource.getResource());
factory.afterPropertiesSet();
return new PropertiesPropertySource(sourceName, factory.getObject());
}
return super.createPropertySource(name, resource);
}
}

View File

@@ -0,0 +1,60 @@
package org.ruoyi.common.core.utils;
import cn.hutool.core.util.ObjectUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.util.function.Function;
/**
* 对象工具类
*
* @author 秋辞未寒
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ObjectUtils extends ObjectUtil {
/**
* 如果对象不为空,则获取对象中的某个字段 ObjectUtils.notNullGetter(user, User::getName);
*
* @param obj 对象
* @param func 获取方法
* @return 对象字段
*/
public static <T, E> E notNullGetter(T obj, Function<T, E> func) {
if (isNotNull(obj) && isNotNull(func)) {
return func.apply(obj);
}
return null;
}
/**
* 如果对象不为空,则获取对象中的某个字段,否则返回默认值
*
* @param obj 对象
* @param func 获取方法
* @param defaultValue 默认值
* @return 对象字段
*/
public static <T, E> E notNullGetter(T obj, Function<T, E> func, E defaultValue) {
if (isNotNull(obj) && isNotNull(func)) {
return func.apply(obj);
}
return defaultValue;
}
/**
* 如果值不为空,则返回值,否则返回默认值
*
* @param obj 对象
* @param defaultValue 默认值
* @return 对象字段
*/
public static <T> T notNull(T obj, T defaultValue) {
if (isNotNull(obj)) {
return obj;
}
return defaultValue;
}
}

View File

@@ -1,9 +1,10 @@
package org.ruoyi.common.core.utils;
import cn.hutool.extra.spring.SpringUtil;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.boot.autoconfigure.thread.Threading;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
/**
@@ -48,7 +49,7 @@ public final class SpringUtils extends SpringUtil {
*/
@SuppressWarnings("unchecked")
public static <T> T getAopProxy(T invoker) {
return (T) AopContext.currentProxy();
return (T) getBean(invoker.getClass());
}
@@ -59,4 +60,8 @@ public final class SpringUtils extends SpringUtil {
return getApplicationContext();
}
public static boolean isVirtual() {
return Threading.VIRTUAL.isActive(getBean(Environment.class));
}
}

View File

@@ -23,11 +23,6 @@
<artifactId>ruoyi-common-core</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15to18</artifactId>
@@ -38,6 +33,23 @@
<artifactId>hutool-crypto</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,49 @@
<!--
~ MIT License
~
~ Copyright (c) 2023 OrdinaryRoad
~
~ Permission is hereby granted, free of charge, to any person obtaining a copy
~ of this software and associated documentation files (the "Software"), to deal
~ in the Software without restriction, including without limitation the rights
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
~ copies of the Software, and to permit persons to whom the Software is
~ furnished to do so, subject to the following conditions:
~
~ The above copyright notice and this permission notice shall be included in all
~ copies or substantial portions of the Software.
~
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
~ SOFTWARE.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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>
<groupId>org.ruoyi</groupId>
<artifactId>live-chat-client-commons</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>live-chat-client-commons-base</artifactId>
<name>ordinaryroad-live-chat-client-commons-base</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,32 @@
/*
* MIT License
*
* Copyright (c) 2023 OrdinaryRoad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package tech.ordinaryroad.live.chat.client.commons.base.constant;
/**
* @author mjz
* @date 2023/8/26
*/
public class Constants {
}

View File

@@ -0,0 +1,51 @@
/*
* MIT License
*
* Copyright (c) 2023 OrdinaryRoad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package tech.ordinaryroad.live.chat.client.commons.base.exception;
/**
* @author mjz
* @date 2023/9/5
*/
public class BaseException extends RuntimeException {
public BaseException() {
}
public BaseException(String message) {
super(message);
}
public BaseException(String message, Throwable cause) {
super(message, cause);
}
public BaseException(Throwable cause) {
super(cause);
}
public BaseException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View File

@@ -0,0 +1,60 @@
/*
* MIT License
*
* Copyright (c) 2023 OrdinaryRoad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package tech.ordinaryroad.live.chat.client.commons.base.listener;
/**
* 连接回调
*
* @author mjz
* @date 2023/8/26
*/
public interface IBaseConnectionListener<T> {
/**
* 连接建立成功
*/
default void onConnected(T t) {
// ignore
}
/**
* 连接建立失败
*
* @param t
*/
default void onConnectFailed(T t) {
// ignore
}
/**
* 连接断开
*
* @param t
*/
default void onDisconnected(T t) {
// ignore
}
}

View File

@@ -0,0 +1,149 @@
/*
* MIT License
*
* Copyright (c) 2023 OrdinaryRoad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package tech.ordinaryroad.live.chat.client.commons.base.listener;
import tech.ordinaryroad.live.chat.client.commons.base.msg.BaseCmdMsg;
import tech.ordinaryroad.live.chat.client.commons.base.msg.BaseMsg;
import tech.ordinaryroad.live.chat.client.commons.base.msg.ICmdMsg;
import tech.ordinaryroad.live.chat.client.commons.base.msg.IMsg;
/**
* Base消息回调
*
* @author mjz
* @date 2023/8/26
*/
public interface IBaseMsgListener<T, CmdEnum extends Enum<CmdEnum>> {
/**
* 收到消息(所有消息)
*
* @param msg IMsg
*/
default void onMsg(T t, IMsg msg) {
this.onMsg(msg);
}
default void onMsg(IMsg msg) {
// ignore
}
/**
* 收到cmd消息所有cmd
*
* @param cmd CmdEnum
* @param cmdMsg BaseCmdMsg
*/
default void onCmdMsg(T t, CmdEnum cmd, ICmdMsg<CmdEnum> cmdMsg) {
this.onCmdMsg(cmd, cmdMsg);
}
default void onCmdMsg(CmdEnum cmd, ICmdMsg<CmdEnum> cmdMsg) {
// ignore
}
/**
* 收到其他cmd消息存在Enum但Listener没有对应的回调
*
* @param cmd CmdEnum
* @param cmdMsg BaseCmdMsg
*/
default void onOtherCmdMsg(T t, CmdEnum cmd, ICmdMsg<CmdEnum> cmdMsg) {
this.onOtherCmdMsg(cmd, cmdMsg);
}
default void onOtherCmdMsg(CmdEnum cmd, ICmdMsg<CmdEnum> cmdMsg) {
// ignore
}
/**
* 收到未知cmd消息
*
* @param cmdString 实际收到的cmd字符串
* @param msg BaseMsg
*/
default void onUnknownCmd(T t, String cmdString, IMsg msg) {
this.onUnknownCmd(cmdString, msg);
}
default void onUnknownCmd(String cmdString, IMsg msg) {
// ignore
}
/**
* 收到cmd消息所有cmd
*
* @param cmd CmdEnum
* @param cmdMsg BaseCmdMsg
* @deprecated use {@link #onCmdMsg(T, Enum, ICmdMsg)}
*/
default void onCmdMsg(T t, CmdEnum cmd, BaseCmdMsg<CmdEnum> cmdMsg) {
this.onCmdMsg(cmd, cmdMsg);
}
/**
* @deprecated use {@link #onCmdMsg(Enum, ICmdMsg)}
*/
default void onCmdMsg(CmdEnum cmd, BaseCmdMsg<CmdEnum> cmdMsg) {
// ignore
}
/**
* 收到其他cmd消息存在Enum但Listener没有对应的回调
*
* @param cmd CmdEnum
* @param cmdMsg BaseCmdMsg
* @deprecated use {@link #onOtherCmdMsg(T, Enum, ICmdMsg)}
*/
default void onOtherCmdMsg(T t, CmdEnum cmd, BaseCmdMsg<CmdEnum> cmdMsg) {
this.onOtherCmdMsg(cmd, cmdMsg);
}
/**
* @deprecated use {@link #onOtherCmdMsg(Enum, ICmdMsg)}
*/
default void onOtherCmdMsg(CmdEnum cmd, BaseCmdMsg<CmdEnum> cmdMsg) {
// ignore
}
/**
* 收到未知cmd消息
*
* @param cmdString 实际收到的cmd字符串
* @param msg BaseMsg
* @deprecated use {@link #onUnknownCmd(T, String, IMsg)}
*/
default void onUnknownCmd(T t, String cmdString, BaseMsg msg) {
this.onUnknownCmd(cmdString, msg);
}
/**
* @deprecated use {@link #onUnknownCmd(String, IMsg)}
*/
default void onUnknownCmd(String cmdString, BaseMsg msg) {
// ignore
}
}

View File

@@ -0,0 +1,46 @@
/*
* MIT License
*
* Copyright (c) 2023 OrdinaryRoad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package tech.ordinaryroad.live.chat.client.commons.base.listener;
/**
* 弹幕消息回调
*
* @author mjz
* @since 0.0.6
*/
public interface IDanmuMsgListener<T, DanmuMsg> {
/**
* 收到弹幕
*/
default void onDanmuMsg(T t, DanmuMsg msg) {
this.onDanmuMsg(msg);
}
default void onDanmuMsg(DanmuMsg msg) {
// ignore
}
}

View File

@@ -0,0 +1,47 @@
/*
* MIT License
*
* Copyright (c) 2023 OrdinaryRoad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package tech.ordinaryroad.live.chat.client.commons.base.listener;
/**
* 进入房间消息回调
*
* @author mjz
* @date 2023/12/14
* @since 0.0.16
*/
public interface IEnterRoomMsgListener<T, EnterRoomMsg> {
/**
* 用户进入房间
*/
default void onEnterRoomMsg(T t, EnterRoomMsg msg) {
this.onEnterRoomMsg(msg);
}
default void onEnterRoomMsg(EnterRoomMsg msg) {
// ignore
}
}

View File

@@ -0,0 +1,47 @@
/*
* MIT License
*
* Copyright (c) 2023 OrdinaryRoad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package tech.ordinaryroad.live.chat.client.commons.base.listener;
/**
* 礼物消息回调
*
* @author mjz
* @since 0.0.8
*/
public interface IGiftMsgListener<T, GiftMsg> {
/**
* 收到礼物
*/
default void onGiftMsg(T t, GiftMsg msg) {
this.onGiftMsg(msg);
}
default void onGiftMsg(GiftMsg msg) {
// ignore
}
}

View File

@@ -0,0 +1,46 @@
/*
* MIT License
*
* Copyright (c) 2023 OrdinaryRoad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package tech.ordinaryroad.live.chat.client.commons.base.listener;
/**
* 点赞消息回调
*
* @author mjz
* @since 0.2.0
*/
public interface ILikeMsgListener<T, LikeMsg> {
/**
* 收到点赞
*/
default void onLikeMsg(T t, LikeMsg msg) {
this.onLikeMsg(msg);
}
default void onLikeMsg(LikeMsg msg) {
// ignore
}
}

View File

@@ -0,0 +1,47 @@
/*
* MIT License
*
* Copyright (c) 2023 OrdinaryRoad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package tech.ordinaryroad.live.chat.client.commons.base.listener;
/**
* 醒目留言消息回调
*
* @author mjz
* @date 2023/9/24
* @since 0.0.11
*/
public interface ISuperChatMsgListener<T, SuperChatMsg> {
/**
* 收到醒目留言
*/
default void onSuperChatMsg(T t, SuperChatMsg msg) {
this.onSuperChatMsg(msg);
}
default void onSuperChatMsg(SuperChatMsg msg) {
// ignore
}
}

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