Commit 613eef375805e282ee90b3c25ff0ec977c4deb8d

Authored by franky
2 parents 1bc812fd 2b9b3023

Merge remote-tracking branch 'origin/feature/1.8.0-uniapp' into feature/1.8.0-uniapp

Showing 210 changed files with 2275 additions and 2308 deletions

Too many changes.

To preserve performance only 100 of 210 files are displayed.

README.md
... ... @@ -157,27 +157,27 @@ ps:核心功能已经实现,正在对接微信小程序中...
157 157  
158 158 | 框架 | 说明 | 版本 | 学习指南 |
159 159 |---------------------------------------------------------------------------------------------|------------------|----------|----------------------------------------------------------------|
160   -| [Spring Boot](https://spring.io/projects/spring-boot) | 应用开发框架 | 2.5.12 | [文档](https://github.com/YunaiV/SpringBoot-Labs) |
  160 +| [Spring Boot](https://spring.io/projects/spring-boot) | 应用开发框架 | 2.6.8 | [文档](https://github.com/YunaiV/SpringBoot-Labs) |
161 161 | [MySQL](https://www.mysql.com/cn/) | 数据库服务器 | 5.7 | |
162 162 | [Druid](https://github.com/alibaba/druid) | JDBC 连接池、监控组件 | 1.2.8 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) |
163   -| [MyBatis Plus](https://mp.baomidou.com/) | MyBatis 增强工具包 | 3.5.1 | [文档](http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao) |
  163 +| [MyBatis Plus](https://mp.baomidou.com/) | MyBatis 增强工具包 | 3.5.2 | [文档](http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao) |
164 164 | [Dynamic Datasource](https://dynamic-datasource.com/) | 动态数据源 | 3.5.0 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) |
165 165 | [Redis](https://redis.io/) | key-value 数据库 | 5.0 | |
166   -| [Redisson](https://github.com/redisson/redisson) | Redis 客户端 | 3.16.8 | [文档](http://www.iocoder.cn/Spring-Boot/Redis/?yudao) |
167   -| [Spring MVC](https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc) | MVC 框架 | 5.3.16 | [文档](http://www.iocoder.cn/SpringMVC/MVC/?yudao) |
168   -| [Spring Security](https://github.com/spring-projects/spring-security) | Spring 安全框架 | 5.5.5 | [文档](http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao) |
169   -| [Hibernate Validator](https://github.com/hibernate/hibernate-validator) | 参数校验组件 | 6.2.2 | [文档](http://www.iocoder.cn/Spring-Boot/Validation/?yudao) |
  166 +| [Redisson](https://github.com/redisson/redisson) | Redis 客户端 | 3.17.3 | [文档](http://www.iocoder.cn/Spring-Boot/Redis/?yudao) |
  167 +| [Spring MVC](https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc) | MVC 框架 | 5.3.20 | [文档](http://www.iocoder.cn/SpringMVC/MVC/?yudao) |
  168 +| [Spring Security](https://github.com/spring-projects/spring-security) | Spring 安全框架 | 5.6.5 | [文档](http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao) |
  169 +| [Hibernate Validator](https://github.com/hibernate/hibernate-validator) | 参数校验组件 | 6.2.3 | [文档](http://www.iocoder.cn/Spring-Boot/Validation/?yudao) |
170 170 | [Activiti](https://github.com/Activiti/Activiti) | 工作流引擎 | 7.1.0.M6 | [文档](TODO) |
171 171 | [Quartz](https://github.com/quartz-scheduler) | 任务调度组件 | 2.3.2 | [文档](http://www.iocoder.cn/Spring-Boot/Job/?yudao) |
172   -| [Knife4j](https://gitee.com/xiaoym/knife4j) | Swagger 增强 UI 实现 | 3.0.2 | [文档](http://www.iocoder.cn/Spring-Boot/Swagger/?yudao) |
173   -| [Resilience4j](https://github.com/resilience4j/resilience4j) | 服务保障组件 | 1.7.0 | [文档](http://www.iocoder.cn/Spring-Boot/Resilience4j/?yudao) |
  172 +| [Knife4j](https://gitee.com/xiaoym/knife4j) | Swagger 增强 UI 实现 | 3.0.3 | [文档](http://www.iocoder.cn/Spring-Boot/Swagger/?yudao) |
  173 +| [Resilience4j](https://github.com/resilience4j/resilience4j) | 服务保障组件 | 1.7.1 | [文档](http://www.iocoder.cn/Spring-Boot/Resilience4j/?yudao) |
174 174 | [SkyWalking](https://skywalking.apache.org/) | 分布式应用追踪系统 | 8.5.0 | [文档](http://www.iocoder.cn/Spring-Boot/SkyWalking/?yudao) |
175   -| [Spring Boot Admin](https://github.com/codecentric/spring-boot-admin) | Spring Boot 监控平台 | 2.4.2 | [文档](http://www.iocoder.cn/Spring-Boot/Admin/?yudao) |
176   -| [Jackson](https://github.com/FasterXML/jackson) | JSON 工具库 | 2.12.6 | |
  175 +| [Spring Boot Admin](https://github.com/codecentric/spring-boot-admin) | Spring Boot 监控平台 | 2.6.7 | [文档](http://www.iocoder.cn/Spring-Boot/Admin/?yudao) |
  176 +| [Jackson](https://github.com/FasterXML/jackson) | JSON 工具库 | 2.13.3 | |
177 177 | [MapStruct](https://mapstruct.org/) | Java Bean 转换 | 1.4.1 | [文档](http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao) |
178 178 | [Lombok](https://projectlombok.org/) | 消除冗长的 Java 代码 | 1.16.14 | [文档](http://www.iocoder.cn/Spring-Boot/Lombok/?yudao) |
179   -| [JUnit](https://junit.org/junit5/) | Java 单元测试框架 | 5.7.2 | - |
180   -| [Mockito](https://github.com/mockito/mockito) | Java Mock 框架 | 3.9.0 | - |
  179 +| [JUnit](https://junit.org/junit5/) | Java 单元测试框架 | 5.8.2 | - |
  180 +| [Mockito](https://github.com/mockito/mockito) | Java Mock 框架 | 4.0.0 | - |
181 181  
182 182 ### 前端
183 183  
... ... @@ -192,42 +192,41 @@ ps:核心功能已经实现,正在对接微信小程序中...
192 192  
193 193 | 模块 | biu | biu | biu |
194 194 |----------|--------------------------------------------------------------------|------------------------------------------------------------------|------------------------------------------------------------------|
195   -| 登录 & 首页 | ![登录](https://static.iocoder.cn/images/ruoyi-vue-pro/登录.jpg) | ![首页](https://static.iocoder.cn/images/ruoyi-vue-pro/首页.jpg) | ![个人中心](https://static.iocoder.cn/images/ruoyi-vue-pro/个人中心.jpg) |
196   -| 用户 | ![用户管理](https://static.iocoder.cn/images/ruoyi-vue-pro/用户管理.jpg) | ![在线用户](https://static.iocoder.cn/images/ruoyi-vue-pro/在线用户.jpg) | - |
197   -| 租户 & 套餐 | ![租户管理](https://static.iocoder.cn/images/ruoyi-vue-pro/租户管理.jpg) | ![租户套餐](https://static.iocoder.cn/images/ruoyi-vue-pro/租户套餐.png) | - |
198   -| 部门 & 岗位 | ![部门管理](https://static.iocoder.cn/images/ruoyi-vue-pro/部门管理.jpg) | ![岗位管理](https://static.iocoder.cn/images/ruoyi-vue-pro/岗位管理.jpg) | - |
199   -| 菜单 & 角色 | ![菜单管理](https://static.iocoder.cn/images/ruoyi-vue-pro/菜单管理.jpg) | ![角色管理](https://static.iocoder.cn/images/ruoyi-vue-pro/角色管理.jpg) | - |
200   -| 审计日志 | ![操作日志](https://static.iocoder.cn/images/ruoyi-vue-pro/操作日志.jpg) | ![登录日志](https://static.iocoder.cn/images/ruoyi-vue-pro/登录日志.jpg) | - |
201   -| 短信 | ![短信渠道](https://static.iocoder.cn/images/ruoyi-vue-pro/短信渠道.jpg) | ![短信模板](https://static.iocoder.cn/images/ruoyi-vue-pro/短信模板.jpg) | ![短信日志](https://static.iocoder.cn/images/ruoyi-vue-pro/短信日志.jpg) |
202   -| 字典 | ![字典类型](https://static.iocoder.cn/images/ruoyi-vue-pro/字典类型.jpg) | ![字典数据](https://static.iocoder.cn/images/ruoyi-vue-pro/字典数据.jpg) | - |
203   -| 错误码 & 通知 | ![错误码管理](https://static.iocoder.cn/images/ruoyi-vue-pro/错误码管理.jpg) | ![通知公告](https://static.iocoder.cn/images/ruoyi-vue-pro/通知公告.jpg) | - |
  195 +| 登录 & 首页 | ![登录](https://static.iocoder.cn/images/ruoyi-vue-pro/登录.jpg?imageView2/2/format/webp/w/1280) | ![首页](https://static.iocoder.cn/images/ruoyi-vue-pro/首页.jpg?imageView2/2/format/webp/w/1280) | ![个人中心](https://static.iocoder.cn/images/ruoyi-vue-pro/个人中心.jpg?imageView2/2/format/webp/w/1280) |
  196 +| 用户 | ![用户管理](https://static.iocoder.cn/images/ruoyi-vue-pro/用户管理.jpg?imageView2/2/format/webp/w/1280) | ![在线用户](https://static.iocoder.cn/images/ruoyi-vue-pro/在线用户.jpg?imageView2/2/format/webp/w/1280) | - |
  197 +| 租户 & 套餐 | ![租户管理](https://static.iocoder.cn/images/ruoyi-vue-pro/租户管理.jpg?imageView2/2/format/webp/w/1280) | ![租户套餐](https://static.iocoder.cn/images/ruoyi-vue-pro/租户套餐.png) | - |
  198 +| 部门 & 岗位 | ![部门管理](https://static.iocoder.cn/images/ruoyi-vue-pro/部门管理.jpg?imageView2/2/format/webp/w/1280) | ![岗位管理](https://static.iocoder.cn/images/ruoyi-vue-pro/岗位管理.jpg?imageView2/2/format/webp/w/1280) | - |
  199 +| 菜单 & 角色 | ![菜单管理](https://static.iocoder.cn/images/ruoyi-vue-pro/菜单管理.jpg?imageView2/2/format/webp/w/1280) | ![角色管理](https://static.iocoder.cn/images/ruoyi-vue-pro/角色管理.jpg?imageView2/2/format/webp/w/1280) | - |
  200 +| 审计日志 | ![操作日志](https://static.iocoder.cn/images/ruoyi-vue-pro/操作日志.jpg?imageView2/2/format/webp/w/1280) | ![登录日志](https://static.iocoder.cn/images/ruoyi-vue-pro/登录日志.jpg?imageView2/2/format/webp/w/1280) | - |
  201 +| 短信 | ![短信渠道](https://static.iocoder.cn/images/ruoyi-vue-pro/短信渠道.jpg?imageView2/2/format/webp/w/1280) | ![短信模板](https://static.iocoder.cn/images/ruoyi-vue-pro/短信模板.jpg?imageView2/2/format/webp/w/1280) | ![短信日志](https://static.iocoder.cn/images/ruoyi-vue-pro/短信日志.jpg?imageView2/2/format/webp/w/1280) |
  202 +| 字典 | ![字典类型](https://static.iocoder.cn/images/ruoyi-vue-pro/字典类型.jpg?imageView2/2/format/webp/w/1280) | ![字典数据](https://static.iocoder.cn/images/ruoyi-vue-pro/字典数据.jpg?imageView2/2/format/webp/w/1280) | - |
  203 +| 错误码 & 通知 | ![错误码管理](https://static.iocoder.cn/images/ruoyi-vue-pro/错误码管理.jpg?imageView2/2/format/webp/w/1280) | ![通知公告](https://static.iocoder.cn/images/ruoyi-vue-pro/通知公告.jpg?imageView2/2/format/webp/w/1280) | - |
204 204  
205 205 ### 工作流程
206 206  
207 207 | 模块 | biu | biu | biu |
208 208 |---------|------------------------------------------------------------------------|------------------------------------------------------------------------|------------------------------------------------------------------------|
209   -| 流程模型 | ![流程模型-列表](https://static.iocoder.cn/images/ruoyi-vue-pro/流程模型-列表.jpg) | ![流程模型-设计](https://static.iocoder.cn/images/ruoyi-vue-pro/流程模型-设计.jpg) | ![流程模型-定义](https://static.iocoder.cn/images/ruoyi-vue-pro/流程模型-定义.jpg) |
210   -| 表单 & 分组 | ![流程表单](https://static.iocoder.cn/images/ruoyi-vue-pro/流程表单.jpg) | ![用户分组](https://static.iocoder.cn/images/ruoyi-vue-pro/用户分组.jpg) | - |
211   -| 我的流程 | ![我的流程-列表](https://static.iocoder.cn/images/ruoyi-vue-pro/我的流程-列表.jpg) | ![我的流程-发起](https://static.iocoder.cn/images/ruoyi-vue-pro/我的流程-发起.jpg) | ![我的流程-详情](https://static.iocoder.cn/images/ruoyi-vue-pro/我的流程-详情.jpg) |
212   -| 待办 & 已办 | ![任务列表-审批](https://static.iocoder.cn/images/ruoyi-vue-pro/任务列表-审批.jpg) | ![任务列表-待办](https://static.iocoder.cn/images/ruoyi-vue-pro/任务列表-待办.jpg) | ![任务列表-已办](https://static.iocoder.cn/images/ruoyi-vue-pro/任务列表-已办.jpg) |
213   -| OA 请假 | ![OA请假-列表](https://static.iocoder.cn/images/ruoyi-vue-pro/OA请假-列表.jpg) | ![OA请假-发起](https://static.iocoder.cn/images/ruoyi-vue-pro/OA请假-发起.jpg) | ![OA请假-详情](https://static.iocoder.cn/images/ruoyi-vue-pro/OA请假-详情.jpg) |
214   -
215   -### 支付系统
216   -
217   -| 模块 | biu | biu | biu |
218   -|---------|------------------------------------------------------------------|------------------------------------------------------------------------|------------------------------------------------------------------------|
219   -| 商家 & 应用 | ![商户信息](https://static.iocoder.cn/images/ruoyi-vue-pro/商户信息.jpg) | ![应用信息-列表](https://static.iocoder.cn/images/ruoyi-vue-pro/应用信息-列表.jpg) | ![应用信息-编辑](https://static.iocoder.cn/images/ruoyi-vue-pro/应用信息-编辑.jpg) |
220   -| 支付 & 退款 | ![支付订单](https://static.iocoder.cn/images/ruoyi-vue-pro/支付订单.jpg) | ![退款订单](https://static.iocoder.cn/images/ruoyi-vue-pro/退款订单.jpg) | --- |
  209 +| 流程模型 | ![流程模型-列表](https://static.iocoder.cn/images/ruoyi-vue-pro/流程模型-列表.jpg?imageView2/2/format/webp/w/1280) | ![流程模型-设计](https://static.iocoder.cn/images/ruoyi-vue-pro/流程模型-设计.jpg?imageView2/2/format/webp/w/1280) | ![流程模型-定义](https://static.iocoder.cn/images/ruoyi-vue-pro/流程模型-定义.jpg?imageView2/2/format/webp/w/1280) |
  210 +| 表单 & 分组 | ![流程表单](https://static.iocoder.cn/images/ruoyi-vue-pro/流程表单.jpg?imageView2/2/format/webp/w/1280) | ![用户分组](https://static.iocoder.cn/images/ruoyi-vue-pro/用户分组.jpg?imageView2/2/format/webp/w/1280) | - |
  211 +| 我的流程 | ![我的流程-列表](https://static.iocoder.cn/images/ruoyi-vue-pro/我的流程-列表.jpg?imageView2/2/format/webp/w/1280) | ![我的流程-发起](https://static.iocoder.cn/images/ruoyi-vue-pro/我的流程-发起.jpg?imageView2/2/format/webp/w/1280) | ![我的流程-详情](https://static.iocoder.cn/images/ruoyi-vue-pro/我的流程-详情.jpg?imageView2/2/format/webp/w/1280) |
  212 +| 待办 & 已办 | ![任务列表-审批](https://static.iocoder.cn/images/ruoyi-vue-pro/任务列表-审批.jpg?imageView2/2/format/webp/w/1280) | ![任务列表-待办](https://static.iocoder.cn/images/ruoyi-vue-pro/任务列表-待办.jpg?imageView2/2/format/webp/w/1280) | ![任务列表-已办](https://static.iocoder.cn/images/ruoyi-vue-pro/任务列表-已办.jpg?imageView2/2/format/webp/w/1280) |
  213 +| OA 请假 | ![OA请假-列表](https://static.iocoder.cn/images/ruoyi-vue-pro/OA请假-列表.jpg?imageView2/2/format/webp/w/1280) | ![OA请假-发起](https://static.iocoder.cn/images/ruoyi-vue-pro/OA请假-发起.jpg?imageView2/2/format/webp/w/1280) | ![OA请假-详情](https://static.iocoder.cn/images/ruoyi-vue-pro/OA请假-详情.jpg?imageView2/2/format/webp/w/1280) |
221 214  
222 215 ### 基础设施
223 216  
224 217 | 模块 | biu | biu | biu |
225 218 |---------------|----------------------------------------------------------------------|--------------------------------------------------------------------|------------------------------------------------------------------|
226   -| 代码生成 | ![代码生成](https://static.iocoder.cn/images/ruoyi-vue-pro/代码生成.jpg) | ![生成效果](https://static.iocoder.cn/images/ruoyi-vue-pro/生成效果.jpg) | - |
227   -| 文档 | ![系统接口](https://static.iocoder.cn/images/ruoyi-vue-pro/系统接口.jpg) | ![数据库文档](https://static.iocoder.cn/images/ruoyi-vue-pro/数据库文档.jpg) | - |
228   -| 文件 & 配置 | ![文件配置](https://static.iocoder.cn/images/ruoyi-vue-pro/文件配置.jpg) | ![文件管理](https://static.iocoder.cn/images/ruoyi-vue-pro/文件管理2.jpg) | ![配置管理](https://static.iocoder.cn/images/ruoyi-vue-pro/配置管理.jpg) |
229   -| 定时任务 | ![定时任务](https://static.iocoder.cn/images/ruoyi-vue-pro/定时任务.jpg) | ![任务日志](https://static.iocoder.cn/images/ruoyi-vue-pro/任务日志.jpg) | - |
230   -| API 日志 | ![访问日志](https://static.iocoder.cn/images/ruoyi-vue-pro/访问日志.jpg) | ![错误日志](https://static.iocoder.cn/images/ruoyi-vue-pro/错误日志.jpg) | - |
231   -| MySQL & Redis | ![MySQL](https://static.iocoder.cn/images/ruoyi-vue-pro/MySQL.jpg) | ![Redis](https://static.iocoder.cn/images/ruoyi-vue-pro/Redis.jpg) | - |
232   -| 监控平台 | ![Java监控](https://static.iocoder.cn/images/ruoyi-vue-pro/Java监控.jpg) | ![链路追踪](https://static.iocoder.cn/images/ruoyi-vue-pro/链路追踪.jpg) | ![日志中心](https://static.iocoder.cn/images/ruoyi-vue-pro/日志中心.jpg) |
  219 +| 代码生成 | ![代码生成](https://static.iocoder.cn/images/ruoyi-vue-pro/代码生成.jpg?imageView2/2/format/webp/w/1280) | ![生成效果](https://static.iocoder.cn/images/ruoyi-vue-pro/生成效果.jpg?imageView2/2/format/webp/w/1280) | - |
  220 +| 文档 | ![系统接口](https://static.iocoder.cn/images/ruoyi-vue-pro/系统接口.jpg?imageView2/2/format/webp/w/1280) | ![数据库文档](https://static.iocoder.cn/images/ruoyi-vue-pro/数据库文档.jpg?imageView2/2/format/webp/w/1280) | - |
  221 +| 文件 & 配置 | ![文件配置](https://static.iocoder.cn/images/ruoyi-vue-pro/文件配置.jpg?imageView2/2/format/webp/w/1280) | ![文件管理](https://static.iocoder.cn/images/ruoyi-vue-pro/文件管理2.jpg?imageView2/2/format/webp/w/1280) | ![配置管理](https://static.iocoder.cn/images/ruoyi-vue-pro/配置管理.jpg?imageView2/2/format/webp/w/1280) |
  222 +| 定时任务 | ![定时任务](https://static.iocoder.cn/images/ruoyi-vue-pro/定时任务.jpg?imageView2/2/format/webp/w/1280) | ![任务日志](https://static.iocoder.cn/images/ruoyi-vue-pro/任务日志.jpg?imageView2/2/format/webp/w/1280) | - |
  223 +| API 日志 | ![访问日志](https://static.iocoder.cn/images/ruoyi-vue-pro/访问日志.jpg?imageView2/2/format/webp/w/1280) | ![错误日志](https://static.iocoder.cn/images/ruoyi-vue-pro/错误日志.jpg?imageView2/2/format/webp/w/1280) | - |
  224 +| MySQL & Redis | ![MySQL](https://static.iocoder.cn/images/ruoyi-vue-pro/MySQL.jpg?imageView2/2/format/webp/w/1280) | ![Redis](https://static.iocoder.cn/images/ruoyi-vue-pro/Redis.jpg?imageView2/2/format/webp/w/1280) | - |
  225 +| 监控平台 | ![Java监控](https://static.iocoder.cn/images/ruoyi-vue-pro/Java监控.jpg?imageView2/2/format/webp/w/1280) | ![链路追踪](https://static.iocoder.cn/images/ruoyi-vue-pro/链路追踪.jpg?imageView2/2/format/webp/w/1280) | ![日志中心](https://static.iocoder.cn/images/ruoyi-vue-pro/日志中心.jpg?imageView2/2/format/webp/w/1280) |
233 226  
  227 +### 支付系统
  228 +
  229 +| 模块 | biu | biu | biu |
  230 +|---------|------------------------------------------------------------------|------------------------------------------------------------------------|------------------------------------------------------------------------|
  231 +| 商家 & 应用 | ![商户信息](https://static.iocoder.cn/images/ruoyi-vue-pro/商户信息.jpg?imageView2/2/format/webp/w/1280) | ![应用信息-列表](https://static.iocoder.cn/images/ruoyi-vue-pro/应用信息-列表.jpg?imageView2/2/format/webp/w/1280) | ![应用信息-编辑](https://static.iocoder.cn/images/ruoyi-vue-pro/应用信息-编辑.jpg?imageView2/2/format/webp/w/1280) |
  232 +| 支付 & 退款 | ![支付订单](https://static.iocoder.cn/images/ruoyi-vue-pro/支付订单.jpg?imageView2/2/format/webp/w/1280) | ![退款订单](https://static.iocoder.cn/images/ruoyi-vue-pro/退款订单.jpg?imageView2/2/format/webp/w/1280) | --- |
... ...
http-client.env.json
... ... @@ -7,5 +7,14 @@
7 7 "appApi": "http://127.0.0.1:48080/app-api",
8 8 "appToken": "test1",
9 9 "appTenentId": "1"
  10 + },
  11 + "gateway": {
  12 + "baseUrl": "http://127.0.0.1:8888/admin-api",
  13 + "token": "test1",
  14 + "adminTenentId": "1",
  15 +
  16 + "appApi": "http://127.0.0.1:8888/app-api",
  17 + "appToken": "test1",
  18 + "appTenentId": "1"
10 19 }
11 20 }
... ...
sql/mysql/ruoyi-vue-pro.sql
... ... @@ -11,7 +11,7 @@
11 11 Target Server Version : 80026
12 12 File Encoding : 65001
13 13  
14   - Date: 25/05/2022 23:28:25
  14 + Date: 15/06/2022 08:11:25
15 15 */
16 16  
17 17 SET NAMES utf8mb4;
... ... @@ -300,7 +300,7 @@ CREATE TABLE `bpm_form` (
300 300 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
301 301 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
302 302 PRIMARY KEY (`id`) USING BTREE
303   -) ENGINE = InnoDB AUTO_INCREMENT = 17 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '工作流的表单定义';
  303 +) ENGINE = InnoDB AUTO_INCREMENT = 18 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '工作流的表单定义';
304 304  
305 305 -- ----------------------------
306 306 -- Records of bpm_form
... ... @@ -359,7 +359,7 @@ CREATE TABLE `bpm_process_definition_ext` (
359 359 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
360 360 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
361 361 PRIMARY KEY (`id`) USING BTREE
362   -) ENGINE = InnoDB AUTO_INCREMENT = 104 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'Bpm 流程定义的拓展表\n';
  362 +) ENGINE = InnoDB AUTO_INCREMENT = 119 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'Bpm 流程定义的拓展表\n';
363 363  
364 364 -- ----------------------------
365 365 -- Records of bpm_process_definition_ext
... ... @@ -389,7 +389,7 @@ CREATE TABLE `bpm_process_instance_ext` (
389 389 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
390 390 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
391 391 PRIMARY KEY (`id`) USING BTREE
392   -) ENGINE = InnoDB AUTO_INCREMENT = 204 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '工作流的流程实例的拓展';
  392 +) ENGINE = InnoDB AUTO_INCREMENT = 256 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '工作流的流程实例的拓展';
393 393  
394 394 -- ----------------------------
395 395 -- Records of bpm_process_instance_ext
... ... @@ -415,7 +415,7 @@ CREATE TABLE `bpm_task_assign_rule` (
415 415 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
416 416 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
417 417 PRIMARY KEY (`id`) USING BTREE
418   -) ENGINE = InnoDB AUTO_INCREMENT = 201 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'Bpm 任务规则表';
  418 +) ENGINE = InnoDB AUTO_INCREMENT = 225 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'Bpm 任务规则表';
419 419  
420 420 -- ----------------------------
421 421 -- Records of bpm_task_assign_rule
... ... @@ -431,6 +431,7 @@ CREATE TABLE `bpm_task_ext` (
431 431 `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
432 432 `assignee_user_id` bigint NULL DEFAULT NULL COMMENT '任务的审批人',
433 433 `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '任务的名字',
  434 + `task_def_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '流程任务key',
434 435 `task_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '任务的编号',
435 436 `result` tinyint NOT NULL COMMENT '任务的结果',
436 437 `reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '审批建议',
... ... @@ -444,7 +445,7 @@ CREATE TABLE `bpm_task_ext` (
444 445 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
445 446 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
446 447 PRIMARY KEY (`id`) USING BTREE
447   -) ENGINE = InnoDB AUTO_INCREMENT = 217 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '工作流的流程任务的拓展表';
  448 +) ENGINE = InnoDB AUTO_INCREMENT = 295 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '工作流的流程任务的拓展表';
448 449  
449 450 -- ----------------------------
450 451 -- Records of bpm_task_ext
... ... @@ -504,7 +505,7 @@ CREATE TABLE `infra_api_access_log` (
504 505 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
505 506 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
506 507 PRIMARY KEY (`id`) USING BTREE
507   -) ENGINE = InnoDB AUTO_INCREMENT = 33232 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'API 访问日志表';
  508 +) ENGINE = InnoDB AUTO_INCREMENT = 35150 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'API 访问日志表';
508 509  
509 510 -- ----------------------------
510 511 -- Records of infra_api_access_log
... ... @@ -546,7 +547,7 @@ CREATE TABLE `infra_api_error_log` (
546 547 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
547 548 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
548 549 PRIMARY KEY (`id`) USING BTREE
549   -) ENGINE = InnoDB AUTO_INCREMENT = 454 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志';
  550 +) ENGINE = InnoDB AUTO_INCREMENT = 627 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志';
550 551  
551 552 -- ----------------------------
552 553 -- Records of infra_api_error_log
... ... @@ -688,6 +689,7 @@ DROP TABLE IF EXISTS `infra_file`;
688 689 CREATE TABLE `infra_file` (
689 690 `id` bigint NOT NULL AUTO_INCREMENT COMMENT '文件编号',
690 691 `config_id` bigint NULL DEFAULT NULL COMMENT '配置编号',
  692 + `name` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '文件名',
691 693 `path` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '文件路径',
692 694 `url` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '文件 URL',
693 695 `type` varchar(63) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '文件类型',
... ... @@ -698,7 +700,7 @@ CREATE TABLE `infra_file` (
698 700 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
699 701 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
700 702 PRIMARY KEY (`id`) USING BTREE
701   -) ENGINE = InnoDB AUTO_INCREMENT = 83 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
  703 +) ENGINE = InnoDB AUTO_INCREMENT = 85 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
702 704  
703 705 -- ----------------------------
704 706 -- Records of infra_file
... ... @@ -723,7 +725,7 @@ CREATE TABLE `infra_file_config` (
723 725 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
724 726 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
725 727 PRIMARY KEY (`id`) USING BTREE
726   -) ENGINE = InnoDB AUTO_INCREMENT = 15 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件配置表';
  728 +) ENGINE = InnoDB AUTO_INCREMENT = 18 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件配置表';
727 729  
728 730 -- ----------------------------
729 731 -- Records of infra_file_config
... ... @@ -732,6 +734,9 @@ BEGIN;
732 734 INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4, '数据库', 1, '我是数据库', b'0', '{\"@class\":\"cn.iocoder.yudao.framework.file.core.client.db.DBFileClientConfig\",\"domain\":\"http://127.0.0.1:48080\"}', '1', '2022-03-15 23:56:24', '1', '2022-03-26 21:39:26', b'0');
733 735 INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5, '本地磁盘', 10, '测试下本地存储', b'0', '{\"@class\":\"cn.iocoder.yudao.framework.file.core.client.local.LocalFileClientConfig\",\"basePath\":\"/Users/yunai/file_test\",\"domain\":\"http://127.0.0.1:48080\"}', '1', '2022-03-15 23:57:00', '1', '2022-03-26 21:39:26', b'0');
734 736 INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (11, 'S3 - 七牛云', 20, NULL, b'1', '{\"@class\":\"cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"s3-cn-south-1.qiniucs.com\",\"domain\":\"http://test.yudao.iocoder.cn\",\"bucket\":\"ruoyi-vue-pro\",\"accessKey\":\"b7yvuhBSAGjmtPhMFcn9iMOxUOY_I06cA_p0ZUx8\",\"accessSecret\":\"kXM1l5ia1RvSX3QaOEcwI3RLz3Y2rmNszWonKZtP\"}', '1', '2022-03-19 18:00:03', '1', '2022-03-26 21:39:26', b'0');
  737 +INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (15, 'S3 - 七牛云', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"s3-cn-south-1.qiniucs.com\",\"domain\":\"http://test.yudao.iocoder.cn\",\"bucket\":\"ruoyi-vue-pro\",\"accessKey\":\"b7yvuhBSAGjmtPhMFcn9iMOxUOY_I06cA_p0ZUx8\",\"accessSecret\":\"kXM1l5ia1RvSX3QaOEcwI3RLz3Y2rmNszWonKZtP\"}', '1', '2022-06-10 20:50:41', '1', '2022-06-10 20:50:41', b'0');
  738 +INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (16, 'S3 - 七牛云', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"s3-cn-south-1.qiniucs.com\",\"domain\":\"http://test.yudao.iocoder.cn\",\"bucket\":\"ruoyi-vue-pro\",\"accessKey\":\"b7yvuhBSAGjmtPhMFcn9iMOxUOY_I06cA_p0ZUx8\",\"accessSecret\":\"kXM1l5ia1RvSX3QaOEcwI3RLz3Y2rmNszWonKZtP\"}', '1', '2022-06-11 20:32:08', '1', '2022-06-11 20:32:08', b'0');
  739 +INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (17, 'S3 - 七牛云', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"s3-cn-south-1.qiniucs.com\",\"domain\":\"http://test.yudao.iocoder.cn\",\"bucket\":\"ruoyi-vue-pro\",\"accessKey\":\"b7yvuhBSAGjmtPhMFcn9iMOxUOY_I06cA_p0ZUx8\",\"accessSecret\":\"kXM1l5ia1RvSX3QaOEcwI3RLz3Y2rmNszWonKZtP\"}', '1', '2022-06-11 20:32:47', '1', '2022-06-11 20:32:47', b'0');
735 740 COMMIT;
736 741  
737 742 -- ----------------------------
... ... @@ -862,7 +867,7 @@ CREATE TABLE `member_user` (
862 867 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
863 868 PRIMARY KEY (`id`) USING BTREE,
864 869 UNIQUE INDEX `uk_mobile`(`mobile` ASC) USING BTREE COMMENT '手机号'
865   -) ENGINE = InnoDB AUTO_INCREMENT = 247 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户';
  870 +) ENGINE = InnoDB AUTO_INCREMENT = 248 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户';
866 871  
867 872 -- ----------------------------
868 873 -- Records of member_user
... ... @@ -1258,7 +1263,6 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
1258 1263 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (79, 2, '手动编辑', '2', 'system_error_code_type', 0, 'primary', '', NULL, '1', '2021-04-21 00:07:14', '1', '2022-02-16 13:57:24', b'0');
1259 1264 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (80, 100, '账号登录', '100', 'system_login_type', 0, 'primary', '', '账号登录', '1', '2021-10-06 00:52:02', '1', '2022-02-16 13:11:34', b'0');
1260 1265 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (81, 101, '社交登录', '101', 'system_login_type', 0, 'info', '', '社交登录', '1', '2021-10-06 00:52:17', '1', '2022-02-16 13:11:40', b'0');
1261   -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (82, 102, 'Mock 登录', '102', 'system_login_type', 0, 'danger', '', 'Mock 登录', '1', '2021-10-06 00:52:32', '1', '2022-02-16 13:11:44', b'0');
1262 1266 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (83, 200, '主动登出', '200', 'system_login_type', 0, 'primary', '', '主动登出', '1', '2021-10-06 00:52:58', '1', '2022-02-16 13:11:49', b'0');
1263 1267 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (85, 202, '强制登出', '202', 'system_login_type', 0, 'danger', '', '强制退出', '1', '2021-10-06 00:53:41', '1', '2022-02-16 13:11:57', b'0');
1264 1268 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (86, 0, '病假', '1', 'bpm_oa_leave_type', 0, 'primary', '', NULL, '1', '2021-09-21 22:35:28', '1', '2022-02-16 10:00:41', b'0');
... ... @@ -1411,7 +1415,7 @@ CREATE TABLE `system_error_code` (
1411 1415 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
1412 1416 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
1413 1417 PRIMARY KEY (`id`) USING BTREE
1414   -) ENGINE = InnoDB AUTO_INCREMENT = 5829 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '错误码表';
  1418 +) ENGINE = InnoDB AUTO_INCREMENT = 5832 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '错误码表';
1415 1419  
1416 1420 -- ----------------------------
1417 1421 -- Records of system_error_code
... ... @@ -1440,7 +1444,7 @@ CREATE TABLE `system_login_log` (
1440 1444 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
1441 1445 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
1442 1446 PRIMARY KEY (`id`) USING BTREE
1443   -) ENGINE = InnoDB AUTO_INCREMENT = 1416 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录';
  1447 +) ENGINE = InnoDB AUTO_INCREMENT = 1489 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录';
1444 1448  
1445 1449 -- ----------------------------
1446 1450 -- Records of system_login_log
... ... @@ -1757,7 +1761,7 @@ CREATE TABLE `system_oauth2_access_token` (
1757 1761 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
1758 1762 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
1759 1763 PRIMARY KEY (`id`) USING BTREE
1760   -) ENGINE = InnoDB AUTO_INCREMENT = 172 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌';
  1764 +) ENGINE = InnoDB AUTO_INCREMENT = 231 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌';
1761 1765  
1762 1766 -- ----------------------------
1763 1767 -- Records of system_oauth2_access_token
... ... @@ -1877,7 +1881,7 @@ CREATE TABLE `system_oauth2_refresh_token` (
1877 1881 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
1878 1882 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
1879 1883 PRIMARY KEY (`id`) USING BTREE
1880   -) ENGINE = InnoDB AUTO_INCREMENT = 106 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '刷新令牌';
  1884 +) ENGINE = InnoDB AUTO_INCREMENT = 165 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '刷新令牌';
1881 1885  
1882 1886 -- ----------------------------
1883 1887 -- Records of system_oauth2_refresh_token
... ... @@ -1917,7 +1921,7 @@ CREATE TABLE `system_operate_log` (
1917 1921 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
1918 1922 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
1919 1923 PRIMARY KEY (`id`) USING BTREE
1920   -) ENGINE = InnoDB AUTO_INCREMENT = 2214 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录';
  1924 +) ENGINE = InnoDB AUTO_INCREMENT = 2432 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录';
1921 1925  
1922 1926 -- ----------------------------
1923 1927 -- Records of system_operate_log
... ... @@ -1983,7 +1987,7 @@ CREATE TABLE `system_role` (
1983 1987 BEGIN;
1984 1988 INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, '超级管理员', 'super_admin', 1, 1, '', 0, 1, '超级管理员', 'admin', '2021-01-05 17:03:48', '', '2022-02-22 05:08:21', b'0', 1);
1985 1989 INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, '普通角色', 'common', 2, 2, '', 0, 1, '普通角色', 'admin', '2021-01-05 17:03:48', '', '2022-02-22 05:08:20', b'0', 1);
1986   -INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (101, '测试账号', 'test', 0, 1, '[]', 0, 2, '132', '', '2021-01-06 13:49:35', '1', '2022-04-01 21:37:13', b'0', 1);
  1990 +INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (101, '测试账号', 'test', 0, 1, '[]', 0, 2, '132', '', '2021-01-06 13:49:35', '1', '2022-05-28 16:11:05', b'0', 1);
1987 1991 INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (109, '租户管理员', 'tenant_admin', 0, 1, '', 0, 1, '系统自动生成', '1', '2022-02-22 00:56:14', '1', '2022-02-22 00:56:14', b'0', 121);
1988 1992 INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (110, '测试角色', 'test', 0, 1, '[]', 0, 2, '嘿嘿', '110', '2022-02-23 00:14:34', '110', '2022-02-23 13:14:58', b'0', 121);
1989 1993 INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (111, '租户管理员', 'tenant_admin', 0, 1, '', 0, 1, '系统自动生成', '1', '2022-03-07 21:37:58', '1', '2022-03-07 21:37:58', b'0', 122);
... ... @@ -2253,7 +2257,7 @@ COMMIT;
2253 2257 DROP TABLE IF EXISTS `system_sms_channel`;
2254 2258 CREATE TABLE `system_sms_channel` (
2255 2259 `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
2256   - `signature` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '短信签名',
  2260 + `signature` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '短信签名',
2257 2261 `code` varchar(63) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '渠道编码',
2258 2262 `status` tinyint NOT NULL COMMENT '开启状态',
2259 2263 `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '备注',
... ... @@ -2300,7 +2304,7 @@ CREATE TABLE `system_sms_code` (
2300 2304 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
2301 2305 PRIMARY KEY (`id`) USING BTREE,
2302 2306 INDEX `idx_mobile`(`mobile` ASC) USING BTREE COMMENT '手机号'
2303   -) ENGINE = InnoDB AUTO_INCREMENT = 468 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '手机验证码';
  2307 +) ENGINE = InnoDB AUTO_INCREMENT = 469 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '手机验证码';
2304 2308  
2305 2309 -- ----------------------------
2306 2310 -- Records of system_sms_code
... ... @@ -2343,7 +2347,7 @@ CREATE TABLE `system_sms_log` (
2343 2347 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
2344 2348 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
2345 2349 PRIMARY KEY (`id`) USING BTREE
2346   -) ENGINE = InnoDB AUTO_INCREMENT = 144 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信日志';
  2350 +) ENGINE = InnoDB AUTO_INCREMENT = 242 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信日志';
2347 2351  
2348 2352 -- ----------------------------
2349 2353 -- Records of system_sms_log
... ... @@ -2413,7 +2417,7 @@ CREATE TABLE `system_social_user` (
2413 2417 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
2414 2418 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
2415 2419 PRIMARY KEY (`id`) USING BTREE
2416   -) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交用户表';
  2420 +) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交用户表';
2417 2421  
2418 2422 -- ----------------------------
2419 2423 -- Records of system_social_user
... ... @@ -2438,7 +2442,7 @@ CREATE TABLE `system_social_user_bind` (
2438 2442 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
2439 2443 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
2440 2444 PRIMARY KEY (`id`) USING BTREE
2441   -) ENGINE = InnoDB AUTO_INCREMENT = 12 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交绑定表';
  2445 +) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交绑定表';
2442 2446  
2443 2447 -- ----------------------------
2444 2448 -- Records of system_social_user_bind
... ... @@ -2545,7 +2549,7 @@ CREATE TABLE `system_user_role` (
2545 2549 `deleted` bit(1) NULL DEFAULT b'0' COMMENT '是否删除',
2546 2550 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
2547 2551 PRIMARY KEY (`id`) USING BTREE
2548   -) ENGINE = InnoDB AUTO_INCREMENT = 20 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户和角色关联表';
  2552 +) ENGINE = InnoDB AUTO_INCREMENT = 21 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户和角色关联表';
2549 2553  
2550 2554 -- ----------------------------
2551 2555 -- Records of system_user_role
... ... @@ -2556,7 +2560,6 @@ INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_t
2556 2560 INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4, 100, 101, '', '2022-01-11 13:19:45', '', '2022-05-12 12:35:13', b'0', 1);
2557 2561 INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, 100, 1, '', '2022-01-11 13:19:45', '', '2022-05-12 12:35:12', b'0', 1);
2558 2562 INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6, 100, 2, '', '2022-01-11 13:19:45', '', '2022-05-12 12:35:11', b'0', 1);
2559   -INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (7, 104, 101, '', '2022-01-11 13:19:45', '', '2022-05-12 12:35:11', b'0', 1);
2560 2563 INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (10, 103, 1, '1', '2022-01-11 13:19:45', '1', '2022-01-11 13:19:45', b'0', 1);
2561 2564 INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (11, 107, 106, '1', '2022-02-20 22:59:33', '1', '2022-02-20 22:59:33', b'0', 118);
2562 2565 INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (12, 108, 107, '1', '2022-02-20 23:00:50', '1', '2022-02-20 23:00:50', b'0', 119);
... ... @@ -2567,6 +2570,7 @@ INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_t
2567 2570 INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (17, 114, 101, '1', '2022-03-19 21:51:13', '1', '2022-03-19 21:51:13', b'0', 1);
2568 2571 INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (18, 1, 2, '1', '2022-05-12 20:39:29', '1', '2022-05-12 20:39:29', b'0', 1);
2569 2572 INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (19, 116, 113, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
  2573 +INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (20, 104, 101, '1', '2022-05-28 15:43:57', '1', '2022-05-28 15:43:57', b'0', 1);
2570 2574 COMMIT;
2571 2575  
2572 2576 -- ----------------------------
... ... @@ -2630,10 +2634,10 @@ CREATE TABLE `system_users` (
2630 2634 -- Records of system_users
2631 2635 -- ----------------------------
2632 2636 BEGIN;
2633   -INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$10$0acJOIk2D25/oC87nyclE..0lzeu9DtQ/n3geP4fkun/zIVRhHJIO', '芋道源码', '管理员', 103, '[1]', 'aoteman@126.com', '15612345678', 1, 'http://test.yudao.iocoder.cn/48934f2f-92d4-4250-b917-d10d2b262c6a', 0, '127.0.0.1', '2022-05-23 20:27:29', 'admin', '2021-01-05 17:03:47', NULL, '2022-05-23 20:27:29', b'0', 1);
  2637 +INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$10$0acJOIk2D25/oC87nyclE..0lzeu9DtQ/n3geP4fkun/zIVRhHJIO', '芋道源码', '管理员', 103, '[1]', 'aoteman@126.com', '15612345678', 1, 'http://test.yudao.iocoder.cn/48934f2f-92d4-4250-b917-d10d2b262c6a', 0, '127.0.0.1', '2022-06-15 08:03:23', 'admin', '2021-01-05 17:03:47', NULL, '2022-06-15 08:03:23', b'0', 1);
2634 2638 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, 'yudao', '$2a$10$11U48RhyJ5pSBYWSn12AD./ld671.ycSzJHbyrtpeoMeYiw31eo8a', '芋道', '不要吓我', 104, '[1]', 'yudao@iocoder.cn', '15601691300', 1, '', 1, '127.0.0.1', '2022-05-22 19:35:33', '', '2021-01-07 09:07:17', NULL, '2022-05-22 19:35:33', b'0', 1);
2635 2639 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (103, 'yuanma', '$2a$10$wWoPT7sqriM2O1YXRL.je.GiL538OR6ZTN8aQZr9JAGdnpCH2tpYe', '源码', NULL, 106, NULL, 'yuanma@iocoder.cn', '15601701300', 0, '', 0, '127.0.0.1', '2022-01-18 00:33:40', '', '2021-01-13 23:50:35', NULL, '2022-01-18 00:33:40', b'0', 1);
2636   -INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, 'test', '$2a$10$e5RpuDCC0GYSt0Hvd2.CjujIXwgGct4SnXi6dVGxdgFsnqgEryk5a', '测试号', NULL, 107, '[1]', '111@qq.com', '15601691200', 1, '', 0, '127.0.0.1', '2022-03-19 21:46:19', '', '2021-01-21 02:13:53', '1', '2022-05-16 19:36:28', b'0', 1);
  2640 +INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, 'test', '$2a$10$GP8zvqHB//TekuzYZSBYAuBQJiNq1.fxQVDYJ.uBCOnWCtDVKE4H6', '测试号', NULL, 107, '[1]', '111@qq.com', '15601691200', 1, '', 0, '127.0.0.1', '2022-05-28 15:43:17', '', '2021-01-21 02:13:53', NULL, '2022-05-28 15:43:17', b'0', 1);
2637 2641 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (107, 'admin107', '$2a$10$dYOOBKMO93v/.ReCqzyFg.o67Tqk.bbc2bhrpyBGkIw9aypCtr2pm', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '', NULL, '1', '2022-02-20 22:59:33', '1', '2022-02-27 08:26:51', b'0', 118);
2638 2642 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (108, 'admin108', '$2a$10$y6mfvKoNYL1GXWak8nYwVOH.kCWqjactkzdoIDgiKl93WN3Ejg.Lu', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '', NULL, '1', '2022-02-20 23:00:50', '1', '2022-02-27 08:26:53', b'0', 119);
2639 2643 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (109, 'admin109', '$2a$10$JAqvH0tEc0I7dfDVBI7zyuB4E3j.uH6daIjV53.vUS6PknFkDJkuK', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '', NULL, '1', '2022-02-20 23:11:50', '1', '2022-02-27 08:26:56', b'0', 120);
... ...
sql/oracle/ruoyi-vue-pro.sql
... ... @@ -11,7 +11,7 @@
11 11 Target Server Version : 110200
12 12 File Encoding : 65001
13 13  
14   - Date: 26/05/2022 00:38:28
  14 + Date: 15/06/2022 08:20:08
15 15 */
16 16  
17 17  
... ... @@ -884,7 +884,8 @@ CREATE TABLE "INFRA_FILE" (
884 884 "CREATE_TIME" DATE NOT NULL,
885 885 "UPDATER" NVARCHAR2(64),
886 886 "UPDATE_TIME" DATE NOT NULL,
887   - "DELETED" NUMBER(1,0) DEFAULT 0
  887 + "DELETED" NUMBER(1,0) DEFAULT 0,
  888 + "NAME" NVARCHAR2(512)
888 889 )
889 890 LOGGING
890 891 NOCOMPRESS
... ... @@ -913,6 +914,7 @@ COMMENT ON COLUMN "INFRA_FILE"."CREATOR" IS '创建者';
913 914 COMMENT ON COLUMN "INFRA_FILE"."CREATE_TIME" IS '创建时间';
914 915 COMMENT ON COLUMN "INFRA_FILE"."UPDATER" IS '更新者';
915 916 COMMENT ON COLUMN "INFRA_FILE"."UPDATE_TIME" IS '更新时间';
  917 +COMMENT ON COLUMN "INFRA_FILE"."NAME" IS '文件名';
916 918 COMMENT ON TABLE "INFRA_FILE" IS '文件表';
917 919  
918 920 -- ----------------------------
... ... @@ -3196,7 +3198,7 @@ COMMENT ON COLUMN "SYSTEM_OAUTH2_CLIENT"."STATUS" IS '状态';
3196 3198 COMMENT ON COLUMN "SYSTEM_OAUTH2_CLIENT"."ACCESS_TOKEN_VALIDITY_SECONDS" IS '访问令牌的有效期';
3197 3199 COMMENT ON COLUMN "SYSTEM_OAUTH2_CLIENT"."REFRESH_TOKEN_VALIDITY_SECONDS" IS '刷新令牌的有效期';
3198 3200 COMMENT ON COLUMN "SYSTEM_OAUTH2_CLIENT"."REDIRECT_URIS" IS '可重定向的 URI 地址';
3199   -COMMENT ON COLUMN "SYSTEM_OAUTH2_CLIENT"."AUTO_APPROVE_SCOPES" IS '是否自动授权';
  3201 +COMMENT ON COLUMN "SYSTEM_OAUTH2_CLIENT"."AUTO_APPROVE_SCOPES" IS '自动通过的授权范围';
3200 3202 COMMENT ON COLUMN "SYSTEM_OAUTH2_CLIENT"."AUTHORIZED_GRANT_TYPES" IS '授权类型';
3201 3203 COMMENT ON COLUMN "SYSTEM_OAUTH2_CLIENT"."SCOPES" IS '授权范围';
3202 3204 COMMENT ON COLUMN "SYSTEM_OAUTH2_CLIENT"."AUTHORITIES" IS '权限';
... ... @@ -3795,7 +3797,7 @@ COMMIT;
3795 3797 DROP TABLE "SYSTEM_SMS_CHANNEL";
3796 3798 CREATE TABLE "SYSTEM_SMS_CHANNEL" (
3797 3799 "ID" NUMBER(20,0) NOT NULL,
3798   - "SIGNATURE" NVARCHAR2(10),
  3800 + "SIGNATURE" NVARCHAR2(12),
3799 3801 "CODE" NVARCHAR2(63),
3800 3802 "STATUS" NUMBER(4,0) NOT NULL,
3801 3803 "REMARK" NVARCHAR2(255),
... ... @@ -5393,10 +5395,8 @@ ALTER TABLE "QRTZ_FIRED_TRIGGERS" ADD CONSTRAINT "SYS_C008671" CHECK ("STATE" IS
5393 5395 -- Indexes structure for table QRTZ_FIRED_TRIGGERS
5394 5396 -- ----------------------------
5395 5397 CREATE INDEX "IDX_QRTZ_FT_INST_JOB_REQ_RCVRY"
5396   - ON "QRTZ_FIRED_TRIGGERS" ("SCHED_NAME" ASC, "INSTANCE_NAME" ASC, "REQUESTS_RECOVERY" ASC) LOCAL
  5398 + ON "QRTZ_FIRED_TRIGGERS" ("SCHED_NAME" ASC, "INSTANCE_NAME" ASC, "REQUESTS_RECOVERY" ASC)
5397 5399 LOGGING
5398   - ONLINE
5399   - NOSORT
5400 5400 VISIBLE
5401 5401 PCTFREE 10
5402 5402 INITRANS 2
... ... @@ -5410,7 +5410,7 @@ STORAGE (
5410 5410 BUFFER_POOL DEFAULT
5411 5411 );
5412 5412 CREATE INDEX "IDX_QRTZ_FT_JG"
5413   - ON "QRTZ_FIRED_TRIGGERS" ("SCHED_NAME" ASC, "JOB_GROUP" ASC) LOCAL
  5413 + ON "QRTZ_FIRED_TRIGGERS" ("SCHED_NAME" ASC, "JOB_GROUP" ASC)
5414 5414 LOGGING
5415 5415 ONLINE
5416 5416 NOSORT
... ... @@ -5427,10 +5427,8 @@ STORAGE (
5427 5427 BUFFER_POOL DEFAULT
5428 5428 );
5429 5429 CREATE INDEX "IDX_QRTZ_FT_J_G"
5430   - ON "QRTZ_FIRED_TRIGGERS" ("SCHED_NAME" ASC, "JOB_NAME" ASC, "JOB_GROUP" ASC) LOCAL
  5430 + ON "QRTZ_FIRED_TRIGGERS" ("SCHED_NAME" ASC, "JOB_NAME" ASC, "JOB_GROUP" ASC)
5431 5431 LOGGING
5432   - ONLINE
5433   - NOSORT
5434 5432 VISIBLE
5435 5433 PCTFREE 10
5436 5434 INITRANS 2
... ... @@ -5446,7 +5444,6 @@ STORAGE (
5446 5444 CREATE INDEX "IDX_QRTZ_FT_TG"
5447 5445 ON "QRTZ_FIRED_TRIGGERS" ("SCHED_NAME" ASC, "TRIGGER_GROUP" ASC) LOCAL
5448 5446 LOGGING
5449   - ONLINE
5450 5447 NOSORT
5451 5448 VISIBLE
5452 5449 PCTFREE 10
... ... @@ -5499,8 +5496,6 @@ STORAGE (
5499 5496 CREATE INDEX "IDX_QRTZ_J_REQ_RECOVERY"
5500 5497 ON "QRTZ_JOB_DETAILS" ("SCHED_NAME" ASC, "REQUESTS_RECOVERY" ASC) LOCAL
5501 5498 LOGGING
5502   - ONLINE
5503   - NOSORT
5504 5499 VISIBLE
5505 5500 PCTFREE 10
5506 5501 INITRANS 2
... ... @@ -5622,8 +5617,10 @@ ALTER TABLE "QRTZ_TRIGGERS" ADD CONSTRAINT "SYS_C008696" CHECK ("START_TIME" IS
5622 5617 -- Indexes structure for table QRTZ_TRIGGERS
5623 5618 -- ----------------------------
5624 5619 CREATE INDEX "IDX_QRTZ_T_C"
5625   - ON "QRTZ_TRIGGERS" ("SCHED_NAME" ASC, "CALENDAR_NAME" ASC)
  5620 + ON "QRTZ_TRIGGERS" ("SCHED_NAME" ASC, "CALENDAR_NAME" ASC) LOCAL
5626 5621 LOGGING
  5622 + ONLINE
  5623 + NOSORT
5627 5624 VISIBLE
5628 5625 PCTFREE 10
5629 5626 INITRANS 2
... ... @@ -5637,10 +5634,8 @@ STORAGE (
5637 5634 BUFFER_POOL DEFAULT
5638 5635 );
5639 5636 CREATE INDEX "IDX_QRTZ_T_J"
5640   - ON "QRTZ_TRIGGERS" ("SCHED_NAME" ASC, "JOB_NAME" ASC, "JOB_GROUP" ASC) LOCAL
  5637 + ON "QRTZ_TRIGGERS" ("SCHED_NAME" ASC, "JOB_NAME" ASC, "JOB_GROUP" ASC)
5641 5638 LOGGING
5642   - ONLINE
5643   - NOSORT
5644 5639 VISIBLE
5645 5640 PCTFREE 10
5646 5641 INITRANS 2
... ... @@ -5654,8 +5649,10 @@ STORAGE (
5654 5649 BUFFER_POOL DEFAULT
5655 5650 );
5656 5651 CREATE INDEX "IDX_QRTZ_T_JG"
5657   - ON "QRTZ_TRIGGERS" ("SCHED_NAME" ASC, "JOB_GROUP" ASC)
  5652 + ON "QRTZ_TRIGGERS" ("SCHED_NAME" ASC, "JOB_GROUP" ASC) LOCAL
5658 5653 LOGGING
  5654 + ONLINE
  5655 + NOSORT
5659 5656 VISIBLE
5660 5657 PCTFREE 10
5661 5658 INITRANS 2
... ... @@ -5669,10 +5666,8 @@ STORAGE (
5669 5666 BUFFER_POOL DEFAULT
5670 5667 );
5671 5668 CREATE INDEX "IDX_QRTZ_T_NEXT_FIRE_TIME"
5672   - ON "QRTZ_TRIGGERS" ("SCHED_NAME" ASC, "NEXT_FIRE_TIME" ASC) LOCAL
  5669 + ON "QRTZ_TRIGGERS" ("SCHED_NAME" ASC, "NEXT_FIRE_TIME" ASC)
5673 5670 LOGGING
5674   - ONLINE
5675   - NOSORT
5676 5671 VISIBLE
5677 5672 PCTFREE 10
5678 5673 INITRANS 2
... ...
sql/postgresql/ruoyi-vue-pro.sql
... ... @@ -12,7 +12,7 @@
12 12 Target Server Version : 140002
13 13 File Encoding : 65001
14 14  
15   - Date: 26/05/2022 00:10:12
  15 + Date: 15/06/2022 08:13:44
16 16 */
17 17  
18 18  
... ... @@ -365,17 +365,6 @@ START 1
365 365 CACHE 1;
366 366  
367 367 -- ----------------------------
368   --- Sequence structure for system_oauth2_approve_seq
369   --- ----------------------------
370   -DROP SEQUENCE IF EXISTS "system_oauth2_approve_seq";
371   -CREATE SEQUENCE "system_oauth2_approve_seq"
372   -INCREMENT 1
373   -MINVALUE 1
374   -MAXVALUE 9223372036854775807
375   -START 1
376   -CACHE 1;
377   -
378   --- ----------------------------
379 368 -- Sequence structure for system_oauth2_client_seq
380 369 -- ----------------------------
381 370 DROP SEQUENCE IF EXISTS "system_oauth2_client_seq";
... ... @@ -387,17 +376,6 @@ START 1
387 376 CACHE 1;
388 377  
389 378 -- ----------------------------
390   --- Sequence structure for system_oauth2_code_seq
391   --- ----------------------------
392   -DROP SEQUENCE IF EXISTS "system_oauth2_code_seq";
393   -CREATE SEQUENCE "system_oauth2_code_seq"
394   -INCREMENT 1
395   -MINVALUE 1
396   -MAXVALUE 9223372036854775807
397   -START 1
398   -CACHE 1;
399   -
400   --- ----------------------------
401 379 -- Sequence structure for system_oauth2_refresh_token_seq
402 380 -- ----------------------------
403 381 DROP SEQUENCE IF EXISTS "system_oauth2_refresh_token_seq";
... ... @@ -1745,7 +1723,8 @@ CREATE TABLE "infra_file" (
1745 1723 "create_time" timestamp(6) NOT NULL,
1746 1724 "updater" varchar(64) COLLATE "pg_catalog"."default",
1747 1725 "update_time" timestamp(6) NOT NULL,
1748   - "deleted" int2 NOT NULL DEFAULT 0
  1726 + "deleted" int2 NOT NULL DEFAULT 0,
  1727 + "name" varchar(255) COLLATE "pg_catalog"."default"
1749 1728 )
1750 1729 ;
1751 1730 COMMENT ON COLUMN "infra_file"."id" IS '文件编号';
... ... @@ -1759,6 +1738,7 @@ COMMENT ON COLUMN "infra_file"."create_time" IS '创建时间';
1759 1738 COMMENT ON COLUMN "infra_file"."updater" IS '更新者';
1760 1739 COMMENT ON COLUMN "infra_file"."update_time" IS '更新时间';
1761 1740 COMMENT ON COLUMN "infra_file"."deleted" IS '是否删除';
  1741 +COMMENT ON COLUMN "infra_file"."name" IS '文件名';
1762 1742 COMMENT ON TABLE "infra_file" IS '文件表';
1763 1743  
1764 1744 -- ----------------------------
... ... @@ -3413,47 +3393,6 @@ BEGIN;
3413 3393 COMMIT;
3414 3394  
3415 3395 -- ----------------------------
3416   --- Table structure for system_oauth2_approve
3417   --- ----------------------------
3418   -DROP TABLE IF EXISTS "system_oauth2_approve";
3419   -CREATE TABLE "system_oauth2_approve" (
3420   - "id" int8 NOT NULL,
3421   - "user_id" int8 NOT NULL,
3422   - "user_type" int2 NOT NULL,
3423   - "client_id" varchar(255) COLLATE "pg_catalog"."default" NOT NULL,
3424   - "scope" varchar(255) COLLATE "pg_catalog"."default" NOT NULL,
3425   - "approved" bool NOT NULL,
3426   - "expires_time" timestamp(6) NOT NULL,
3427   - "creator" varchar(64) COLLATE "pg_catalog"."default",
3428   - "create_time" timestamp(6) NOT NULL,
3429   - "updater" varchar(64) COLLATE "pg_catalog"."default",
3430   - "update_time" timestamp(6) NOT NULL,
3431   - "deleted" int2 NOT NULL DEFAULT 0,
3432   - "tenant_id" int8 NOT NULL
3433   -)
3434   -;
3435   -COMMENT ON COLUMN "system_oauth2_approve"."id" IS '编号';
3436   -COMMENT ON COLUMN "system_oauth2_approve"."user_id" IS '用户编号';
3437   -COMMENT ON COLUMN "system_oauth2_approve"."user_type" IS '用户类型';
3438   -COMMENT ON COLUMN "system_oauth2_approve"."client_id" IS '客户端编号';
3439   -COMMENT ON COLUMN "system_oauth2_approve"."scope" IS '授权范围';
3440   -COMMENT ON COLUMN "system_oauth2_approve"."approved" IS '是否接受';
3441   -COMMENT ON COLUMN "system_oauth2_approve"."expires_time" IS '过期时间';
3442   -COMMENT ON COLUMN "system_oauth2_approve"."creator" IS '创建者';
3443   -COMMENT ON COLUMN "system_oauth2_approve"."create_time" IS '创建时间';
3444   -COMMENT ON COLUMN "system_oauth2_approve"."updater" IS '更新者';
3445   -COMMENT ON COLUMN "system_oauth2_approve"."update_time" IS '更新时间';
3446   -COMMENT ON COLUMN "system_oauth2_approve"."deleted" IS '是否删除';
3447   -COMMENT ON COLUMN "system_oauth2_approve"."tenant_id" IS '租户编号';
3448   -COMMENT ON TABLE "system_oauth2_approve" IS 'OAuth2 批准表';
3449   -
3450   --- ----------------------------
3451   --- Records of system_oauth2_approve
3452   --- ----------------------------
3453   -BEGIN;
3454   -COMMIT;
3455   -
3456   --- ----------------------------
3457 3396 -- Table structure for system_oauth2_client
3458 3397 -- ----------------------------
3459 3398 DROP TABLE IF EXISTS "system_oauth2_client";
... ... @@ -3513,51 +3452,6 @@ INSERT INTO "system_oauth2_client" ("id", "client_id", "secret", "name", "logo",
3513 3452 COMMIT;
3514 3453  
3515 3454 -- ----------------------------
3516   --- Table structure for system_oauth2_code
3517   --- ----------------------------
3518   -DROP TABLE IF EXISTS "system_oauth2_code";
3519   -CREATE TABLE "system_oauth2_code" (
3520   - "id" int8 NOT NULL,
3521   - "user_id" int8 NOT NULL,
3522   - "user_type" int2 NOT NULL,
3523   - "code" varchar(32) COLLATE "pg_catalog"."default" NOT NULL,
3524   - "client_id" varchar(255) COLLATE "pg_catalog"."default" NOT NULL,
3525   - "scopes" varchar(255) COLLATE "pg_catalog"."default",
3526   - "expires_time" timestamp(6) NOT NULL,
3527   - "redirect_uri" varchar(255) COLLATE "pg_catalog"."default",
3528   - "state" varchar(255) COLLATE "pg_catalog"."default",
3529   - "creator" varchar(64) COLLATE "pg_catalog"."default",
3530   - "create_time" timestamp(6) NOT NULL,
3531   - "updater" varchar(64) COLLATE "pg_catalog"."default",
3532   - "update_time" timestamp(6) NOT NULL,
3533   - "deleted" int2 NOT NULL DEFAULT 0,
3534   - "tenant_id" int8 NOT NULL
3535   -)
3536   -;
3537   -COMMENT ON COLUMN "system_oauth2_code"."id" IS '编号';
3538   -COMMENT ON COLUMN "system_oauth2_code"."user_id" IS '用户编号';
3539   -COMMENT ON COLUMN "system_oauth2_code"."user_type" IS '用户类型';
3540   -COMMENT ON COLUMN "system_oauth2_code"."code" IS '授权码';
3541   -COMMENT ON COLUMN "system_oauth2_code"."client_id" IS '客户端编号';
3542   -COMMENT ON COLUMN "system_oauth2_code"."scopes" IS '授权范围';
3543   -COMMENT ON COLUMN "system_oauth2_code"."expires_time" IS '过期时间';
3544   -COMMENT ON COLUMN "system_oauth2_code"."redirect_uri" IS '可重定向的 URI 地址';
3545   -COMMENT ON COLUMN "system_oauth2_code"."state" IS '状态';
3546   -COMMENT ON COLUMN "system_oauth2_code"."creator" IS '创建者';
3547   -COMMENT ON COLUMN "system_oauth2_code"."create_time" IS '创建时间';
3548   -COMMENT ON COLUMN "system_oauth2_code"."updater" IS '更新者';
3549   -COMMENT ON COLUMN "system_oauth2_code"."update_time" IS '更新时间';
3550   -COMMENT ON COLUMN "system_oauth2_code"."deleted" IS '是否删除';
3551   -COMMENT ON COLUMN "system_oauth2_code"."tenant_id" IS '租户编号';
3552   -COMMENT ON TABLE "system_oauth2_code" IS 'OAuth2 授权码表';
3553   -
3554   --- ----------------------------
3555   --- Records of system_oauth2_code
3556   --- ----------------------------
3557   -BEGIN;
3558   -COMMIT;
3559   -
3560   --- ----------------------------
3561 3455 -- Table structure for system_oauth2_refresh_token
3562 3456 -- ----------------------------
3563 3457 DROP TABLE IF EXISTS "system_oauth2_refresh_token";
... ... @@ -4025,7 +3919,7 @@ COMMIT;
4025 3919 DROP TABLE IF EXISTS "system_sms_channel";
4026 3920 CREATE TABLE "system_sms_channel" (
4027 3921 "id" int8 NOT NULL,
4028   - "signature" varchar(10) COLLATE "pg_catalog"."default" NOT NULL,
  3922 + "signature" varchar(12) COLLATE "pg_catalog"."default" NOT NULL,
4029 3923 "code" varchar(63) COLLATE "pg_catalog"."default" NOT NULL,
4030 3924 "status" int2 NOT NULL,
4031 3925 "remark" varchar(255) COLLATE "pg_catalog"."default",
... ... @@ -4729,21 +4623,11 @@ SELECT setval('"system_oauth2_access_token_seq"', 11, true);
4729 4623 -- ----------------------------
4730 4624 -- Alter sequences owned by
4731 4625 -- ----------------------------
4732   -SELECT setval('"system_oauth2_approve_seq"', 4, true);
4733   -
4734   --- ----------------------------
4735   --- Alter sequences owned by
4736   --- ----------------------------
4737 4626 SELECT setval('"system_oauth2_client_seq"', 1, false);
4738 4627  
4739 4628 -- ----------------------------
4740 4629 -- Alter sequences owned by
4741 4630 -- ----------------------------
4742   -SELECT setval('"system_oauth2_code_seq"', 4, true);
4743   -
4744   --- ----------------------------
4745   --- Alter sequences owned by
4746   --- ----------------------------
4747 4631 SELECT setval('"system_oauth2_refresh_token_seq"', 1, true);
4748 4632  
4749 4633 -- ----------------------------
... ... @@ -5169,21 +5053,11 @@ ALTER TABLE "system_notice" ADD CONSTRAINT "system_notice_pkey" PRIMARY KEY ("id
5169 5053 ALTER TABLE "system_oauth2_access_token" ADD CONSTRAINT "system_oauth2_access_token_pkey" PRIMARY KEY ("id");
5170 5054  
5171 5055 -- ----------------------------
5172   --- Primary Key structure for table system_oauth2_approve
5173   --- ----------------------------
5174   -ALTER TABLE "system_oauth2_approve" ADD CONSTRAINT "system_oauth2_approve_pkey" PRIMARY KEY ("id");
5175   -
5176   --- ----------------------------
5177 5056 -- Primary Key structure for table system_oauth2_client
5178 5057 -- ----------------------------
5179 5058 ALTER TABLE "system_oauth2_client" ADD CONSTRAINT "system_oauth2_client_pkey" PRIMARY KEY ("id");
5180 5059  
5181 5060 -- ----------------------------
5182   --- Primary Key structure for table system_oauth2_code
5183   --- ----------------------------
5184   -ALTER TABLE "system_oauth2_code" ADD CONSTRAINT "system_oauth2_code_pkey" PRIMARY KEY ("id");
5185   -
5186   --- ----------------------------
5187 5061 -- Primary Key structure for table system_oauth2_refresh_token
5188 5062 -- ----------------------------
5189 5063 ALTER TABLE "system_oauth2_refresh_token" ADD CONSTRAINT "system_oauth2_refresh_token_pkey" PRIMARY KEY ("id");
... ...
sql/sqlserver/ruoyi-vue-pro.sql
... ... @@ -12,7 +12,7 @@
12 12 Target Server Version : 15004198
13 13 File Encoding : 65001
14 14  
15   - Date: 26/05/2022 01:01:02
  15 + Date: 15/06/2022 08:15:45
16 16 */
17 17  
18 18  
... ... @@ -2640,7 +2640,8 @@ CREATE TABLE [dbo].[infra_file] (
2640 2640 [create_time] datetime2(7) NOT NULL,
2641 2641 [updater] nvarchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
2642 2642 [update_time] datetime2(7) NOT NULL,
2643   - [deleted] bit DEFAULT 0 NOT NULL
  2643 + [deleted] bit DEFAULT 0 NOT NULL,
  2644 + [name] nvarchar(256) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
2644 2645 )
2645 2646 GO
2646 2647  
... ... @@ -2725,6 +2726,13 @@ EXEC sp_addextendedproperty
2725 2726 GO
2726 2727  
2727 2728 EXEC sp_addextendedproperty
  2729 +'MS_Description', N'文件路径',
  2730 +'SCHEMA', N'dbo',
  2731 +'TABLE', N'infra_file',
  2732 +'COLUMN', N'name'
  2733 +GO
  2734 +
  2735 +EXEC sp_addextendedproperty
2728 2736 'MS_Description', N'文件表',
2729 2737 'SCHEMA', N'dbo',
2730 2738 'TABLE', N'infra_file'
... ... @@ -9490,7 +9498,7 @@ GO
9490 9498  
9491 9499 CREATE TABLE [dbo].[system_sms_channel] (
9492 9500 [id] bigint IDENTITY(1,1) NOT NULL,
9493   - [signature] nvarchar(10) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
  9501 + [signature] nvarchar(12) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
9494 9502 [code] nvarchar(63) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
9495 9503 [status] tinyint NOT NULL,
9496 9504 [remark] nvarchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
... ...
yudao-dependencies/pom.xml
... ... @@ -16,31 +16,31 @@
16 16 <properties>
17 17 <revision>1.6.2-snapshot</revision>
18 18 <!-- 统一依赖管理 -->
19   - <spring.boot.version>2.5.12</spring.boot.version>
  19 + <spring.boot.version>2.6.8</spring.boot.version>
20 20 <!-- Web 相关 -->
21   - <knife4j.version>3.0.2</knife4j.version>
22   - <swagger-annotations.version>1.5.22</swagger-annotations.version>
  21 + <knife4j.version>3.0.3</knife4j.version>
  22 + <swagger-annotations.version>1.6.6</swagger-annotations.version>
23 23 <servlet.versoin>2.5</servlet.versoin>
24 24 <!-- DB 相关 -->
25 25 <druid.version>1.2.8</druid.version>
26   - <mybatis-plus.version>3.4.3.4</mybatis-plus.version>
  26 + <mybatis-plus.version>3.5.2</mybatis-plus.version>
27 27 <mybatis-plus-generator.version>3.5.2</mybatis-plus-generator.version>
28 28 <dynamic-datasource.version>3.5.0</dynamic-datasource.version>
29   - <redisson.version>3.17.0</redisson.version>
  29 + <redisson.version>3.17.3</redisson.version>
30 30 <!-- Config 配置中心相关 -->
31 31 <apollo.version>1.9.2</apollo.version>
32 32 <!-- Job 定时任务相关 -->
33 33 <!-- 服务保障相关 -->
34 34 <lock4j.version>2.2.0</lock4j.version>
35   - <resilience4j.version>1.7.0</resilience4j.version>
  35 + <resilience4j.version>1.7.1</resilience4j.version>
36 36 <!-- 监控相关 -->
37 37 <skywalking.version>8.7.0</skywalking.version>
38   - <spring-boot-admin.version>2.6.2</spring-boot-admin.version>
  38 + <spring-boot-admin.version>2.6.7</spring-boot-admin.version>
39 39 <opentracing.version>0.31.0</opentracing.version>
40 40 <!-- Test 测试相关 -->
41 41 <podam.version>7.2.6.RELEASE</podam.version>
42 42 <jedis-mock.version>0.1.16</jedis-mock.version>
43   - <mockito-inline.version>3.9.0</mockito-inline.version>
  43 + <mockito-inline.version>4.0.0</mockito-inline.version>
44 44 <!-- Bpm 工作流相关 -->
45 45 <activiti.version>7.1.0.M6</activiti.version>
46 46 <flowable.version>6.7.0</flowable.version>
... ... @@ -52,6 +52,7 @@
52 52 <easyexcel.verion>2.2.7</easyexcel.verion>
53 53 <velocity.version>2.2</velocity.version>
54 54 <screw.version>1.0.5</screw.version>
  55 + <fastjson.version>2.0.5</fastjson.version>
55 56 <guava.version>30.1.1-jre</guava.version>
56 57 <guice.version>5.1.0</guice.version>
57 58 <transmittable-thread-local.version>2.12.2</transmittable-thread-local.version>
... ... @@ -80,6 +81,11 @@
80 81 <!-- 业务组件 -->
81 82 <dependency>
82 83 <groupId>cn.iocoder.boot</groupId>
  84 + <artifactId>yudao-spring-boot-starter-banner</artifactId>
  85 + <version>${revision}</version>
  86 + </dependency>
  87 + <dependency>
  88 + <groupId>cn.iocoder.boot</groupId>
83 89 <artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
84 90 <version>${revision}</version>
85 91 </dependency>
... ... @@ -118,6 +124,11 @@
118 124 <artifactId>yudao-spring-boot-starter-biz-social</artifactId>
119 125 <version>${revision}</version>
120 126 </dependency>
  127 + <dependency>
  128 + <groupId>cn.iocoder.boot</groupId>
  129 + <artifactId>yudao-spring-boot-starter-biz-error-code</artifactId>
  130 + <version>${revision}</version>
  131 + </dependency>
121 132  
122 133 <!-- Spring 核心 -->
123 134 <dependency>
... ... @@ -476,6 +487,12 @@
476 487 </dependency>
477 488  
478 489 <dependency>
  490 + <groupId>com.alibaba</groupId>
  491 + <artifactId>fastjson</artifactId>
  492 + <version>${fastjson.version}</version>
  493 + </dependency>
  494 +
  495 + <dependency>
479 496 <groupId>cn.smallbun.screw</groupId>
480 497 <artifactId>screw-core</artifactId> <!-- 实现数据库文档 -->
481 498 <version>${screw.version}</version>
... ... @@ -484,6 +501,10 @@
484 501 <groupId>org.freemarker</groupId>
485 502 <artifactId>freemarker</artifactId> <!-- 移除 Freemarker 依赖,采用 Velocity 作为模板引擎 -->
486 503 </exclusion>
  504 + <exclusion>
  505 + <groupId>com.alibaba</groupId>
  506 + <artifactId>fastjson</artifactId> <!-- 最新版screw-core1.0.5依赖fastjson1.2.73存在漏洞,移除。 -->
  507 + </exclusion>
487 508 </exclusions>
488 509 </dependency>
489 510  
... ...
yudao-framework/pom.xml
... ... @@ -11,6 +11,7 @@
11 11 <packaging>pom</packaging>
12 12 <modules>
13 13 <module>yudao-common</module>
  14 + <module>yudao-spring-boot-starter-banner</module>
14 15 <module>yudao-spring-boot-starter-mybatis</module>
15 16 <module>yudao-spring-boot-starter-redis</module>
16 17 <module>yudao-spring-boot-starter-web</module>
... ... @@ -25,17 +26,19 @@
25 26  
26 27 <module>yudao-spring-boot-starter-excel</module>
27 28 <module>yudao-spring-boot-starter-test</module>
28   - <module>yudao-spring-boot-starter-extension</module>
29 29  
30 30 <module>yudao-spring-boot-starter-biz-operatelog</module>
31 31 <module>yudao-spring-boot-starter-biz-dict</module>
32 32 <module>yudao-spring-boot-starter-biz-sms</module>
33   - <module>yudao-spring-boot-starter-activiti</module>
  33 +
34 34 <module>yudao-spring-boot-starter-biz-pay</module>
35 35 <module>yudao-spring-boot-starter-biz-weixin</module>
36 36 <module>yudao-spring-boot-starter-biz-social</module>
37 37 <module>yudao-spring-boot-starter-biz-tenant</module>
38 38 <module>yudao-spring-boot-starter-biz-data-permission</module>
  39 + <module>yudao-spring-boot-starter-biz-error-code</module>
  40 +
  41 + <module>yudao-spring-boot-starter-activiti</module>
39 42 <module>yudao-spring-boot-starter-flowable</module>
40 43 </modules>
41 44  
... ...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/WebFilterOrderEnum.java
... ... @@ -3,7 +3,7 @@ package cn.iocoder.yudao.framework.common.enums;
3 3 /**
4 4 * Web 过滤器顺序的枚举类,保证过滤器按照符合我们的预期
5 5 *
6   - * 考虑到每个 starter 都需要用到该工具类,所以放到 common 模块下的 util 包下
  6 + * 考虑到每个 starter 都需要用到该工具类,所以放到 common 模块下的 enums 包下
7 7 *
8 8 * @author 芋道源码
9 9 */
... ...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/ServerException.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.common.exception;
  2 +
  3 +import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +
  7 +/**
  8 + * 服务器异常 Exception
  9 + */
  10 +@Data
  11 +@EqualsAndHashCode(callSuper = true)
  12 +public final class ServerException extends RuntimeException {
  13 +
  14 + /**
  15 + * 全局错误码
  16 + *
  17 + * @see GlobalErrorCodeConstants
  18 + */
  19 + private Integer code;
  20 + /**
  21 + * 错误提示
  22 + */
  23 + private String message;
  24 +
  25 + /**
  26 + * 空构造方法,避免反序列化问题
  27 + */
  28 + public ServerException() {
  29 + }
  30 +
  31 + public ServerException(ErrorCode errorCode) {
  32 + this.code = errorCode.getCode();
  33 + this.message = errorCode.getMsg();
  34 + }
  35 +
  36 + public ServerException(Integer code, String message) {
  37 + this.code = code;
  38 + this.message = message;
  39 + }
  40 +
  41 + public Integer getCode() {
  42 + return code;
  43 + }
  44 +
  45 + public ServerException setCode(Integer code) {
  46 + this.code = code;
  47 + return this;
  48 + }
  49 +
  50 + @Override
  51 + public String getMessage() {
  52 + return message;
  53 + }
  54 +
  55 + public ServerException setMessage(String message) {
  56 + this.message = message;
  57 + return this;
  58 + }
  59 +
  60 +}
... ...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/enums/GlobalErrorCodeConstants.java
... ... @@ -36,9 +36,15 @@ public interface GlobalErrorCodeConstants {
36 36  
37 37 ErrorCode UNKNOWN = new ErrorCode(999, "未知错误");
38 38  
39   - static boolean isMatch(Integer code) {
  39 + /**
  40 + * 是否为服务端错误,参考 HTTP 5XX 错误码段
  41 + *
  42 + * @param code 错误码
  43 + * @return 是否
  44 + */
  45 + static boolean isServerErrorCode(Integer code) {
40 46 return code != null
41   - && code >= SUCCESS.getCode() && code <= UNKNOWN.getCode();
  47 + && code >= INTERNAL_SERVER_ERROR.getCode() && code <= INTERNAL_SERVER_ERROR.getCode() + 99;
42 48 }
43 49  
44 50 }
... ...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/enums/ServiceErrorCodeRange.java
... ... @@ -29,6 +29,10 @@ package cn.iocoder.yudao.framework.common.exception.enums;
29 29 */
30 30 public class ServiceErrorCodeRange {
31 31  
32   - // 模块 system 错误码区间 [1-000-001-000 ~ 1-000-002-000]
  32 + // 模块 infra 错误码区间 [1-001-000-000 ~ 1-002-000-000)
  33 + // 模块 system 错误码区间 [1-002-000-000 ~ 1-003-000-000)
  34 + // 模块 member 错误码区间 [1-004-000-000 ~ 1-005-000-000)
  35 + // 模块 pay 错误码区间 [1-007-000-000 ~ 1-008-000-000)
  36 + // 模块 bpm 错误码区间 [1-009-000-000 ~ 1-010-000-000)
33 37  
34 38 }
... ...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/CommonResult.java
1 1 package cn.iocoder.yudao.framework.common.pojo;
2 2  
3 3 import cn.iocoder.yudao.framework.common.exception.ErrorCode;
  4 +import cn.iocoder.yudao.framework.common.exception.ServerException;
4 5 import cn.iocoder.yudao.framework.common.exception.ServiceException;
5 6 import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
6 7 import com.fasterxml.jackson.annotation.JsonIgnore;
... ... @@ -91,10 +92,24 @@ public class CommonResult&lt;T&gt; implements Serializable {
91 92 if (isSuccess()) {
92 93 return;
93 94 }
  95 + // 服务端异常
  96 + if (GlobalErrorCodeConstants.isServerErrorCode(code)) {
  97 + throw new ServerException(code, msg);
  98 + }
94 99 // 业务异常
95 100 throw new ServiceException(code, msg);
96 101 }
97 102  
  103 + /**
  104 + * 判断是否有异常。如果有,则抛出 {@link ServiceException} 异常
  105 + * 如果没有,则返回 {@link #data} 数据
  106 + */
  107 + @JsonIgnore // 避免 jackson 序列化
  108 + public T getCheckedData() {
  109 + checkError();
  110 + return data;
  111 + }
  112 +
98 113 public static <T> CommonResult<T> error(ServiceException serviceException) {
99 114 return error(serviceException.getCode(), serviceException.getMessage());
100 115 }
... ...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageParam.java
... ... @@ -23,8 +23,8 @@ public class PageParam implements Serializable {
23 23  
24 24 @ApiModelProperty(value = "每页条数,最大值为 100", required = true, example = "10")
25 25 @NotNull(message = "每页条数不能为空")
26   - @Min(value = 1, message = "页码最小值为 1")
27   - @Max(value = 100, message = "页码最大值为 100")
  26 + @Min(value = 1, message = "每页条数最小值为 1")
  27 + @Max(value = 100, message = "每页条数最大值为 100")
28 28 private Integer pageSize = PAGE_SIZE;
29 29  
30 30 }
... ...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/cache/CacheUtils.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.common.util.cache;
  2 +
  3 +import com.google.common.cache.CacheBuilder;
  4 +import com.google.common.cache.CacheLoader;
  5 +import com.google.common.cache.LoadingCache;
  6 +
  7 +import java.time.Duration;
  8 +import java.util.concurrent.Executors;
  9 +
  10 +/**
  11 + * Cache 工具类
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +public class CacheUtils {
  16 +
  17 + public static <K, V> LoadingCache<K, V> buildAsyncReloadingCache(Duration duration, CacheLoader<K, V> loader) {
  18 + return CacheBuilder.newBuilder()
  19 + // 只阻塞当前数据加载线程,其他线程返回旧值
  20 + .refreshAfterWrite(duration)
  21 + // 通过 asyncReloading 实现全异步加载,包括 refreshAfterWrite 被阻塞的加载线程
  22 + .build(CacheLoader.asyncReloading(loader, Executors.newCachedThreadPool())); // TODO 芋艿:可能要思考下,未来要不要做成可配置
  23 + }
  24 +
  25 +}
... ...
yudao-framework/yudao-spring-boot-starter-banner/pom.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
  3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5 + <parent>
  6 + <artifactId>yudao-framework</artifactId>
  7 + <groupId>cn.iocoder.boot</groupId>
  8 + <version>${revision}</version>
  9 + </parent>
  10 + <modelVersion>4.0.0</modelVersion>
  11 + <artifactId>yudao-spring-boot-starter-banner</artifactId>
  12 + <packaging>jar</packaging>
  13 +
  14 + <name>${project.artifactId}</name>
  15 + <description>Banner 用于在 console 控制台,打印开发文档、接口文档等</description>
  16 + <url>https://github.com/YunaiV/ruoyi-vue-pro</url>
  17 +
  18 + <dependencies>
  19 + <dependency>
  20 + <groupId>cn.iocoder.boot</groupId>
  21 + <artifactId>yudao-common</artifactId>
  22 + </dependency>
  23 +
  24 + <dependency>
  25 + <groupId>org.springframework.boot</groupId>
  26 + <artifactId>spring-boot-starter</artifactId>
  27 + </dependency>
  28 + </dependencies>
  29 +
  30 +</project>
... ...
yudao-framework/yudao-spring-boot-starter-banner/src/main/java/cn/iocoder/yudao/framework/banner/config/YudaoBannerAutoConfiguration.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.banner.config;
  2 +
  3 +import cn.iocoder.yudao.framework.banner.core.BannerApplicationRunner;
  4 +import org.springframework.context.annotation.Bean;
  5 +import org.springframework.context.annotation.Configuration;
  6 +
  7 +/**
  8 + * Banner 的自动配置类
  9 + *
  10 + * @author 芋道源码
  11 + */
  12 +@Configuration
  13 +public class YudaoBannerAutoConfiguration {
  14 +
  15 + @Bean
  16 + public BannerApplicationRunner bannerApplicationRunner() {
  17 + return new BannerApplicationRunner();
  18 + }
  19 +
  20 +}
... ...
yudao-server/src/main/java/cn/iocoder/yudao/server/framework/tip/core/TipApplicationRunner.java renamed to yudao-framework/yudao-spring-boot-starter-banner/src/main/java/cn/iocoder/yudao/framework/banner/core/BannerApplicationRunner.java
1   -package cn.iocoder.yudao.server.framework.tip.core;
  1 +package cn.iocoder.yudao.framework.banner.core;
2 2  
3 3 import cn.hutool.core.thread.ThreadUtil;
4 4 import lombok.extern.slf4j.Slf4j;
5 5 import org.springframework.boot.ApplicationArguments;
6 6 import org.springframework.boot.ApplicationRunner;
7   -import org.springframework.stereotype.Component;
8 7  
9 8 import java.util.concurrent.TimeUnit;
10 9  
11 10 /**
12 11 * 项目启动成功后,提供文档相关的地址
  12 + *
  13 + * @author 芋道源码
13 14 */
14   -@Component
15 15 @Slf4j
16   -public class TipApplicationRunner implements ApplicationRunner {
  16 +public class BannerApplicationRunner implements ApplicationRunner {
17 17  
18 18 @Override
19 19 public void run(ApplicationArguments args) throws Exception {
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/errorcode/package-info.java renamed to yudao-framework/yudao-spring-boot-starter-banner/src/main/java/cn/iocoder/yudao/framework/banner/package-info.java
1 1 /**
2   - * 错误码组件
  2 + * Banner 用于在 console 控制台,打印开发文档、接口文档等
3 3 *
4   - * 将错误码缓存在内存中,同时通过定时器每 n 分钟更新
  4 + * @author 芋道源码
5 5 */
6   -package cn.iocoder.yudao.module.system.framework.errorcode;
  6 +package cn.iocoder.yudao.framework.banner;
... ...
yudao-framework/yudao-spring-boot-starter-banner/src/main/resources/META-INF/spring.factories 0 → 100644
  1 +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  2 + cn.iocoder.yudao.framework.banner.config.YudaoBannerAutoConfiguration
... ...
yudao-server/src/main/resources/banner.txt renamed to yudao-framework/yudao-spring-boot-starter-banner/src/main/resources/banner.txt
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/config/YudaoDataPermissionAutoConfiguration.java
... ... @@ -13,7 +13,7 @@ import org.springframework.context.annotation.Configuration;
13 13 import java.util.List;
14 14  
15 15 /**
16   - * 数据全新啊的自动配置类
  16 + * 数据权限的自动配置类
17 17 *
18 18 * @author 芋道源码
19 19 */
... ...
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptorTest.java
... ... @@ -62,7 +62,7 @@ public class DataPermissionDatabaseInterceptorTest extends BaseMockitoUnitTest {
62 62 // 调用
63 63 interceptor.beforeQuery(null, mappedStatement, null, null, null, boundSql);
64 64 // 断言
65   - pluginUtilsMock.verify(never(), () -> PluginUtils.mpBoundSql(boundSql));
  65 + pluginUtilsMock.verify(() -> PluginUtils.mpBoundSql(boundSql), never());
66 66 }
67 67 }
68 68  
... ...
yudao-framework/yudao-spring-boot-starter-biz-dict/pom.xml
... ... @@ -26,5 +26,18 @@
26 26 <groupId>org.springframework.boot</groupId>
27 27 <artifactId>spring-boot-starter</artifactId>
28 28 </dependency>
  29 +
  30 + <!-- 业务组件 -->
  31 + <dependency>
  32 + <groupId>cn.iocoder.boot</groupId>
  33 + <artifactId>yudao-module-system-api</artifactId> <!-- 需要使用它,进行 Token 的校验 -->
  34 + <version>${revision}</version>
  35 + </dependency>
  36 +
  37 + <!-- 工具类相关 -->
  38 + <dependency>
  39 + <groupId>com.google.guava</groupId>
  40 + <artifactId>guava</artifactId>
  41 + </dependency>
29 42 </dependencies>
30 43 </project>
... ...
yudao-framework/yudao-spring-boot-starter-biz-dict/src/main/java/cn/iocoder/yudao/framework/dict/config/YudaoDictAutoConfiguration.java
1 1 package cn.iocoder.yudao.framework.dict.config;
2 2  
3   -import cn.iocoder.yudao.framework.dict.core.service.DictDataFrameworkService;
4 3 import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
  4 +import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
5 5 import org.springframework.context.annotation.Bean;
6 6 import org.springframework.context.annotation.Configuration;
7 7  
... ... @@ -10,8 +10,8 @@ public class YudaoDictAutoConfiguration {
10 10  
11 11 @Bean
12 12 @SuppressWarnings("InstantiationOfUtilityClass")
13   - public DictFrameworkUtils dictUtils(DictDataFrameworkService service) {
14   - DictFrameworkUtils.init(service);
  13 + public DictFrameworkUtils dictUtils(DictDataApi dictDataApi) {
  14 + DictFrameworkUtils.init(dictDataApi);
15 15 return new DictFrameworkUtils();
16 16 }
17 17  
... ...
yudao-server/src/main/java/cn/iocoder/yudao/server/framework/tip/package-info.java renamed to yudao-framework/yudao-spring-boot-starter-biz-dict/src/main/java/cn/iocoder/yudao/framework/dict/core/package-info.java
1 1 /**
2   - * 目的:项目启动成功后,提供文档相关的地址
  2 + * 占位
3 3 */
4   -package cn.iocoder.yudao.server.framework.tip;
  4 +package cn.iocoder.yudao.framework.dict.core;
... ...
yudao-framework/yudao-spring-boot-starter-biz-dict/src/main/java/cn/iocoder/yudao/framework/dict/core/service/DictDataFrameworkService.java deleted
1   -package cn.iocoder.yudao.framework.dict.core.service;
2   -
3   -import cn.iocoder.yudao.framework.dict.core.dto.DictDataRespDTO;
4   -
5   -import java.util.List;
6   -
7   -public interface DictDataFrameworkService {
8   -
9   - /**
10   - * 获得指定的字典数据,从缓存中
11   - *
12   - * @param type 字典类型
13   - * @param value 字典数据值
14   - * @return 字典数据
15   - */
16   - DictDataRespDTO getDictDataFromCache(String type, String value);
17   -
18   - /**
19   - * 解析获得指定的字典数据,从缓存中
20   - *
21   - * @param type 字典类型
22   - * @param label 字典数据标签
23   - * @return 字典数据
24   - */
25   - DictDataRespDTO parseDictDataFromCache(String type, String label);
26   -
27   - /**
28   - * 获得指定类型的字典数据,从缓存中
29   - *
30   - * @param type 字典类型
31   - * @return 字典数据列表
32   - */
33   - List<DictDataRespDTO> listDictDatasFromCache(String type);
34   -
35   -}
yudao-framework/yudao-spring-boot-starter-biz-dict/src/main/java/cn/iocoder/yudao/framework/dict/core/util/DictFrameworkUtils.java
1 1 package cn.iocoder.yudao.framework.dict.core.util;
2 2  
3   -import cn.iocoder.yudao.framework.dict.core.dto.DictDataRespDTO;
4   -import cn.iocoder.yudao.framework.dict.core.service.DictDataFrameworkService;
  3 +import cn.hutool.core.util.ObjectUtil;
  4 +import cn.iocoder.yudao.framework.common.core.KeyValue;
  5 +import cn.iocoder.yudao.framework.common.util.cache.CacheUtils;
  6 +import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
  7 +import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
  8 +import com.google.common.cache.CacheLoader;
  9 +import com.google.common.cache.LoadingCache;
  10 +import lombok.SneakyThrows;
5 11 import lombok.extern.slf4j.Slf4j;
6 12  
  13 +import java.time.Duration;
  14 +
7 15 /**
8 16 * 字典工具类
  17 + *
  18 + * @author 芋道源码
9 19 */
10 20 @Slf4j
11 21 public class DictFrameworkUtils {
12 22  
13   - private static DictDataFrameworkService service;
  23 + private static DictDataApi dictDataApi;
  24 +
  25 + private static final DictDataRespDTO DICT_DATA_NULL = new DictDataRespDTO();
  26 +
  27 + /**
  28 + * 针对 {@link #getDictDataLabel(String, String)} 的缓存
  29 + */
  30 + private static final LoadingCache<KeyValue<String, String>, DictDataRespDTO> getDictDataCache = CacheUtils.buildAsyncReloadingCache(
  31 + Duration.ofMinutes(1L), // 过期时间 1 分钟
  32 + new CacheLoader<KeyValue<String, String>, DictDataRespDTO>() {
  33 +
  34 + @Override
  35 + public DictDataRespDTO load(KeyValue<String, String> key) {
  36 + return ObjectUtil.defaultIfNull(dictDataApi.getDictData(key.getKey(), key.getValue()), DICT_DATA_NULL);
  37 + }
  38 +
  39 + });
  40 +
  41 + /**
  42 + * 针对 {@link #parseDictDataValue(String, String)} 的缓存
  43 + */
  44 + private static final LoadingCache<KeyValue<String, String>, DictDataRespDTO> parseDictDataCache = CacheUtils.buildAsyncReloadingCache(
  45 + Duration.ofMinutes(1L), // 过期时间 1 分钟
  46 + new CacheLoader<KeyValue<String, String>, DictDataRespDTO>() {
  47 +
  48 + @Override
  49 + public DictDataRespDTO load(KeyValue<String, String> key) {
  50 + return ObjectUtil.defaultIfNull(dictDataApi.parseDictData(key.getKey(), key.getValue()), DICT_DATA_NULL);
  51 + }
  52 +
  53 + });
14 54  
15   - public static void init(DictDataFrameworkService service) {
16   - DictFrameworkUtils.service = service;
  55 + public static void init(DictDataApi dictDataApi) {
  56 + DictFrameworkUtils.dictDataApi = dictDataApi;
17 57 log.info("[init][初始化 DictFrameworkUtils 成功]");
18 58 }
19 59  
20   - public static DictDataRespDTO getDictDataFromCache(String type, String value) {
21   - return service.getDictDataFromCache(type, value);
  60 + @SneakyThrows
  61 + public static String getDictDataLabel(String dictType, String value) {
  62 + return getDictDataCache.get(new KeyValue<>(dictType, value)).getLabel();
22 63 }
23 64  
24   - public static DictDataRespDTO parseDictDataFromCache(String type, String label) {
25   - return service.parseDictDataFromCache(type, label);
  65 + @SneakyThrows
  66 + public static String parseDictDataValue(String dictType, String label) {
  67 + return parseDictDataCache.get(new KeyValue<>(dictType, label)).getValue();
26 68 }
27 69  
28 70 }
... ...
yudao-framework/yudao-spring-boot-starter-extension/pom.xml renamed to yudao-framework/yudao-spring-boot-starter-biz-error-code/pom.xml
... ... @@ -8,18 +8,18 @@
8 8 <version>${revision}</version>
9 9 </parent>
10 10 <modelVersion>4.0.0</modelVersion>
11   -
12   - <artifactId>yudao-spring-boot-starter-extension</artifactId>
  11 + <artifactId>yudao-spring-boot-starter-biz-error-code</artifactId>
13 12 <packaging>jar</packaging>
14 13  
15 14 <name>${project.artifactId}</name>
16   - <description>扩展点组件</description>
  15 + <description>
  16 + 错误码 ErrorCode 的自动配置功能,提供如下功能:
  17 + 1. 远程读取:项目启动时,从 system-server 服务,读取数据库中的 ErrorCode 错误码,实现错误码的提水可配置;
  18 + 2. 自动更新:管理员在管理后台修数据库中的 ErrorCode 错误码时,项目自动从 system-server 服务加载最新的 ErrorCode 错误码;
  19 + 3. 自动写入:项目启动时,将项目本地的错误码写到 system-server 服务中,方便管理员在管理后台编辑;
  20 + </description>
17 21 <url>https://github.com/YunaiV/ruoyi-vue-pro</url>
18 22  
19   - <properties>
20   -
21   - </properties>
22   -
23 23 <dependencies>
24 24 <dependency>
25 25 <groupId>cn.iocoder.boot</groupId>
... ... @@ -28,41 +28,22 @@
28 28  
29 29 <!-- Spring 核心 -->
30 30 <dependency>
31   - <groupId>org.springframework</groupId>
32   - <artifactId>spring-context</artifactId>
33   - <scope>provided</scope>
34   - </dependency>
35   -
36   - <dependency>
37   - <groupId>org.springframework</groupId>
38   - <artifactId>spring-beans</artifactId>
39   - <scope>provided</scope>
40   - </dependency>
41   -
42   - <!-- Spring 核心 -->
43   - <dependency>
44   - <groupId>org.springframework.boot</groupId>
45   - <artifactId>spring-boot-starter-aop</artifactId>
46   - </dependency>
47   -
48   - <!-- 测试包 -->
49   - <dependency>
50 31 <groupId>org.springframework.boot</groupId>
51   - <artifactId>spring-boot-starter-test</artifactId>
52   - <scope>test</scope>
  32 + <artifactId>spring-boot-starter</artifactId>
53 33 </dependency>
54 34  
55   - <!-- 测试包 -->
  35 + <!-- 业务组件 -->
56 36 <dependency>
57   - <groupId>junit</groupId>
58   - <artifactId>junit</artifactId>
59   - <scope>test</scope>
  37 + <groupId>cn.iocoder.boot</groupId>
  38 + <artifactId>yudao-module-system-api</artifactId> <!-- 需要使用它,进行操作日志的记录 -->
  39 + <version>${revision}</version>
60 40 </dependency>
61 41  
62   - <!-- 工具类相关 -->
63 42 <dependency>
64 43 <groupId>jakarta.validation</groupId>
65 44 <artifactId>jakarta.validation-api</artifactId>
  45 + <scope>provided</scope> <!-- 设置为 provided,主要是 ErrorCodeProperties 使用到 -->
66 46 </dependency>
67 47 </dependencies>
68   -</project>
69 48 \ No newline at end of file
  49 +
  50 +</project>
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/errorcode/config/ErrorCodeProperties.java renamed to yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/config/ErrorCodeProperties.java
1   -package cn.iocoder.yudao.module.system.framework.errorcode.config;
  1 +package cn.iocoder.yudao.framework.errorcode.config;
2 2  
3 3 import lombok.Data;
4 4 import org.springframework.boot.context.properties.ConfigurationProperties;
... ... @@ -18,6 +18,10 @@ import java.util.List;
18 18 public class ErrorCodeProperties {
19 19  
20 20 /**
  21 + * 是否开启
  22 + */
  23 + private Boolean enable = true;
  24 + /**
21 25 * 错误码枚举类
22 26 */
23 27 @NotNull(message = "错误码枚举类不能为空")
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/errorcode/config/ErrorCodeConfiguration.java renamed to yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/config/YudaoErrorCodeConfiguration.java
1   -package cn.iocoder.yudao.module.system.framework.errorcode.config;
  1 +package cn.iocoder.yudao.framework.errorcode.config;
2 2  
3   -import cn.iocoder.yudao.module.system.framework.errorcode.core.generator.ErrorCodeAutoGenerator;
4   -import cn.iocoder.yudao.module.system.framework.errorcode.core.loader.ErrorCodeLoader;
5   -import cn.iocoder.yudao.module.system.framework.errorcode.core.service.ErrorCodeFrameworkService;
6   -import cn.iocoder.yudao.module.system.framework.errorcode.core.loader.ErrorCodeLoaderImpl;
7   -import cn.iocoder.yudao.module.system.framework.errorcode.core.generator.ErrorCodeAutoGeneratorImpl;
  3 +import cn.iocoder.yudao.framework.errorcode.core.generator.ErrorCodeAutoGenerator;
  4 +import cn.iocoder.yudao.framework.errorcode.core.generator.ErrorCodeAutoGeneratorImpl;
  5 +import cn.iocoder.yudao.framework.errorcode.core.loader.ErrorCodeLoader;
  6 +import cn.iocoder.yudao.framework.errorcode.core.loader.ErrorCodeLoaderImpl;
  7 +import cn.iocoder.yudao.module.system.api.errorcode.ErrorCodeApi;
8 8 import org.springframework.beans.factory.annotation.Value;
  9 +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
9 10 import org.springframework.boot.context.properties.EnableConfigurationProperties;
10 11 import org.springframework.context.annotation.Bean;
11 12 import org.springframework.context.annotation.Configuration;
12 13 import org.springframework.scheduling.annotation.EnableScheduling;
13 14  
14   -// TODO 芋艿:貌似放的位置有问题
15 15 /**
16 16 * 错误码配置类
  17 + *
  18 + * @author 芋道源码
17 19 */
18 20 @Configuration
  21 +@ConditionalOnProperty(prefix = "yudao.error-code", value = "enable", matchIfMissing = true) // 允许使用 yudao.error-code.enable=false 禁用访问日志
19 22 @EnableConfigurationProperties(ErrorCodeProperties.class)
20 23 @EnableScheduling // 开启调度任务的功能,因为 ErrorCodeRemoteLoader 通过定时刷新错误码
21   -public class ErrorCodeConfiguration {
  24 +public class YudaoErrorCodeConfiguration {
22 25  
23 26 @Bean
24 27 public ErrorCodeAutoGenerator errorCodeAutoGenerator(@Value("${spring.application.name}") String applicationName,
25 28 ErrorCodeProperties errorCodeProperties,
26   - ErrorCodeFrameworkService errorCodeFrameworkService) {
27   - return new ErrorCodeAutoGeneratorImpl(applicationName, errorCodeProperties.getConstantsClassList(),
28   - errorCodeFrameworkService);
  29 + ErrorCodeApi errorCodeApi) {
  30 + return new ErrorCodeAutoGeneratorImpl(applicationName, errorCodeProperties.getConstantsClassList(), errorCodeApi);
29 31 }
30 32  
31 33 @Bean
32 34 public ErrorCodeLoader errorCodeLoader(@Value("${spring.application.name}") String applicationName,
33   - ErrorCodeFrameworkService errorCodeFrameworkService) {
34   - return new ErrorCodeLoaderImpl(applicationName, errorCodeFrameworkService);
  35 + ErrorCodeApi errorCodeApi) {
  36 + return new ErrorCodeLoaderImpl(applicationName, errorCodeApi);
35 37 }
36 38  
37 39 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/errorcode/core/generator/ErrorCodeAutoGenerator.java renamed to yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/core/generator/ErrorCodeAutoGenerator.java
1   -package cn.iocoder.yudao.module.system.framework.errorcode.core.generator;
  1 +package cn.iocoder.yudao.framework.errorcode.core.generator;
2 2  
3 3 /**
4 4 * 错误码的自动生成器
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/errorcode/core/generator/ErrorCodeAutoGeneratorImpl.java renamed to yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/core/generator/ErrorCodeAutoGeneratorImpl.java
1   -package cn.iocoder.yudao.module.system.framework.errorcode.core.generator;
  1 +package cn.iocoder.yudao.framework.errorcode.core.generator;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.exceptions.ExceptionUtil;
5 5 import cn.hutool.core.util.ClassUtil;
6 6 import cn.hutool.core.util.ReflectUtil;
7 7 import cn.iocoder.yudao.framework.common.exception.ErrorCode;
8   -import cn.iocoder.yudao.module.system.framework.errorcode.core.dto.ErrorCodeAutoGenerateReqDTO;
9   -import cn.iocoder.yudao.module.system.framework.errorcode.core.service.ErrorCodeFrameworkService;
  8 +import cn.iocoder.yudao.module.system.api.errorcode.ErrorCodeApi;
  9 +import cn.iocoder.yudao.module.system.api.errorcode.dto.ErrorCodeAutoGenerateReqDTO;
10 10 import lombok.RequiredArgsConstructor;
11 11 import lombok.extern.slf4j.Slf4j;
12 12 import org.springframework.boot.context.event.ApplicationReadyEvent;
... ... @@ -36,9 +36,9 @@ public class ErrorCodeAutoGeneratorImpl implements ErrorCodeAutoGenerator {
36 36 */
37 37 private final List<String> constantsClassList;
38 38 /**
39   - * 错误码 Service
  39 + * 错误码 Api
40 40 */
41   - private final ErrorCodeFrameworkService errorCodeService;
  41 + private final ErrorCodeApi errorCodeApi;
42 42  
43 43 @Override
44 44 @EventListener(ApplicationReadyEvent.class)
... ... @@ -49,7 +49,7 @@ public class ErrorCodeAutoGeneratorImpl implements ErrorCodeAutoGenerator {
49 49 log.info("[execute][解析到错误码数量为 ({}) 个]", autoGenerateDTOs.size());
50 50  
51 51 // 第二步,写入到 system 服务
52   - errorCodeService.autoGenerateErrorCodes(autoGenerateDTOs);
  52 + errorCodeApi.autoGenerateErrorCodes(autoGenerateDTOs);
53 53 log.info("[execute][写入到 system 组件完成]");
54 54 }
55 55  
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/errorcode/core/loader/ErrorCodeLoader.java renamed to yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/core/loader/ErrorCodeLoader.java
1   -package cn.iocoder.yudao.module.system.framework.errorcode.core.loader;
  1 +package cn.iocoder.yudao.framework.errorcode.core.loader;
2 2  
3 3 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
4 4  
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/errorcode/core/loader/ErrorCodeLoaderImpl.java renamed to yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/core/loader/ErrorCodeLoaderImpl.java
1   -package cn.iocoder.yudao.module.system.framework.errorcode.core.loader;
  1 +package cn.iocoder.yudao.framework.errorcode.core.loader;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4   -import cn.iocoder.yudao.module.system.framework.errorcode.core.dto.ErrorCodeRespDTO;
5   -import cn.iocoder.yudao.module.system.framework.errorcode.core.service.ErrorCodeFrameworkService;
6 4 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
  5 +import cn.iocoder.yudao.module.system.api.errorcode.ErrorCodeApi;
  6 +import cn.iocoder.yudao.module.system.api.errorcode.dto.ErrorCodeRespDTO;
7 7 import lombok.RequiredArgsConstructor;
8 8 import lombok.extern.slf4j.Slf4j;
9 9 import org.springframework.boot.context.event.ApplicationReadyEvent;
... ... @@ -34,9 +34,9 @@ public class ErrorCodeLoaderImpl implements ErrorCodeLoader {
34 34 */
35 35 private final String applicationName;
36 36 /**
37   - * 错误码 Service
  37 + * 错误码 Api
38 38 */
39   - private final ErrorCodeFrameworkService errorCodeService;
  39 + private final ErrorCodeApi errorCodeApi;
40 40  
41 41 /**
42 42 * 缓存错误码的最大更新时间,用于后续的增量轮询,判断是否有更新
... ... @@ -55,7 +55,7 @@ public class ErrorCodeLoaderImpl implements ErrorCodeLoader {
55 55  
56 56 private void loadErrorCodes0() {
57 57 // 加载错误码
58   - List<ErrorCodeRespDTO> errorCodeRespDTOs = errorCodeService.getErrorCodeList(applicationName, maxUpdateTime);
  58 + List<ErrorCodeRespDTO> errorCodeRespDTOs = errorCodeApi.getErrorCodeList(applicationName, maxUpdateTime);
59 59 if (CollUtil.isEmpty(errorCodeRespDTOs)) {
60 60 return;
61 61 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/package-info.java 0 → 100644
  1 +/**
  2 + * 错误码 ErrorCode 的自动配置功能,提供如下功能:
  3 + *
  4 + * 1. 远程读取:项目启动时,从 system-service 服务,读取数据库中的 ErrorCode 错误码,实现错误码的提水可配置;
  5 + * 2. 自动更新:管理员在管理后台修数据库中的 ErrorCode 错误码时,项目自动从 system-service 服务加载最新的 ErrorCode 错误码;
  6 + * 3. 自动写入:项目启动时,将项目本地的错误码写到 system-server 服务中,方便管理员在管理后台编辑;
  7 + *
  8 + * @author 芋道源码
  9 + */
  10 +package cn.iocoder.yudao.framework.errorcode;
... ...
yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/resources/META-INF/spring.factories 0 → 100644
  1 +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  2 + cn.iocoder.yudao.framework.errorcode.config.YudaoErrorCodeConfiguration
... ...
yudao-framework/yudao-spring-boot-starter-biz-operatelog/pom.xml
... ... @@ -34,6 +34,13 @@
34 34 <scope>provided</scope>
35 35 </dependency>
36 36  
  37 + <!-- 业务组件 -->
  38 + <dependency>
  39 + <groupId>cn.iocoder.boot</groupId>
  40 + <artifactId>yudao-module-system-api</artifactId> <!-- 需要使用它,进行操作日志的记录 -->
  41 + <version>${revision}</version>
  42 + </dependency>
  43 +
37 44 <!-- 工具类相关 -->
38 45 <dependency>
39 46 <groupId>com.google.guava</groupId>
... ...
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/config/YudaoOperateLogAutoConfiguration.java
1 1 package cn.iocoder.yudao.framework.operatelog.config;
2 2  
3 3 import cn.iocoder.yudao.framework.operatelog.core.aop.OperateLogAspect;
  4 +import cn.iocoder.yudao.framework.operatelog.core.service.OperateLogFrameworkService;
  5 +import cn.iocoder.yudao.framework.operatelog.core.service.OperateLogFrameworkServiceImpl;
  6 +import cn.iocoder.yudao.module.system.api.logger.OperateLogApi;
4 7 import org.springframework.context.annotation.Bean;
5 8 import org.springframework.context.annotation.Configuration;
6 9  
... ... @@ -12,4 +15,9 @@ public class YudaoOperateLogAutoConfiguration {
12 15 return new OperateLogAspect();
13 16 }
14 17  
  18 + @Bean
  19 + public OperateLogFrameworkService operateLogFrameworkService(OperateLogApi operateLogApi) {
  20 + return new OperateLogFrameworkServiceImpl(operateLogApi);
  21 + }
  22 +
15 23 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/aop/OperateLogAspect.java
... ... @@ -9,9 +9,8 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
9 9 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
10 10 import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
11 11 import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
12   -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
13   -import cn.iocoder.yudao.framework.operatelog.core.dto.OperateLogCreateReqDTO;
14 12 import cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum;
  13 +import cn.iocoder.yudao.framework.operatelog.core.service.OperateLog;
15 14 import cn.iocoder.yudao.framework.operatelog.core.service.OperateLogFrameworkService;
16 15 import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
17 16 import com.google.common.collect.Maps;
... ... @@ -45,7 +44,7 @@ import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeC
45 44 * 满足如下任一条件,则会进行记录:
46 45 * 1. 使用 @ApiOperation + 非 @GetMapping
47 46 * 2. 使用 @OperateLog 注解
48   - *
  47 + * <p>
49 48 * 但是,如果声明 @OperateLog 注解时,将 enable 属性设置为 false 时,强制不记录。
50 49 *
51 50 * @author 芋道源码
... ... @@ -57,13 +56,13 @@ public class OperateLogAspect {
57 56 /**
58 57 * 用于记录操作内容的上下文
59 58 *
60   - * @see OperateLogCreateReqDTO#getContent()
  59 + * @see OperateLog#getContent()
61 60 */
62 61 private static final ThreadLocal<String> CONTENT = new ThreadLocal<>();
63 62 /**
64 63 * 用于记录拓展字段的上下文
65 64 *
66   - * @see OperateLogCreateReqDTO#getExts()
  65 + * @see OperateLog#getExts()
67 66 */
68 67 private static final ThreadLocal<Map<String, Object>> EXTS = new ThreadLocal<>();
69 68  
... ... @@ -73,16 +72,21 @@ public class OperateLogAspect {
73 72 @Around("@annotation(apiOperation)")
74 73 public Object around(ProceedingJoinPoint joinPoint, ApiOperation apiOperation) throws Throwable {
75 74 // 可能也添加了 @ApiOperation 注解
76   - OperateLog operateLog = getMethodAnnotation(joinPoint, OperateLog.class);
  75 + cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog operateLog = getMethodAnnotation(joinPoint,
  76 + cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog.class);
77 77 return around0(joinPoint, operateLog, apiOperation);
78 78 }
79 79  
80   - @Around("!@annotation(io.swagger.annotations.ApiOperation) && @annotation(operateLog)") // 兼容处理,只添加 @OperateLog 注解的情况
81   - public Object around(ProceedingJoinPoint joinPoint, OperateLog operateLog) throws Throwable {
  80 + @Around("!@annotation(io.swagger.annotations.ApiOperation) && @annotation(operateLog)")
  81 + // 兼容处理,只添加 @OperateLog 注解的情况
  82 + public Object around(ProceedingJoinPoint joinPoint,
  83 + cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog operateLog) throws Throwable {
82 84 return around0(joinPoint, operateLog, null);
83 85 }
84 86  
85   - private Object around0(ProceedingJoinPoint joinPoint, OperateLog operateLog, ApiOperation apiOperation) throws Throwable {
  87 + private Object around0(ProceedingJoinPoint joinPoint,
  88 + cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog operateLog,
  89 + ApiOperation apiOperation) throws Throwable {
86 90 // 目前,只有管理员,才记录操作日志!所以非管理员,直接调用,不进行记录
87 91 Integer userType = WebFrameworkUtils.getLoginUserType();
88 92 if (!Objects.equals(userType, UserTypeEnum.ADMIN.getValue())) {
... ... @@ -121,7 +125,9 @@ public class OperateLogAspect {
121 125 EXTS.remove();
122 126 }
123 127  
124   - private void log(ProceedingJoinPoint joinPoint, OperateLog operateLog, ApiOperation apiOperation,
  128 + private void log(ProceedingJoinPoint joinPoint,
  129 + cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog operateLog,
  130 + ApiOperation apiOperation,
125 131 Date startTime, Object result, Throwable exception) {
126 132 try {
127 133 // 判断不记录的情况
... ... @@ -136,113 +142,117 @@ public class OperateLogAspect {
136 142 }
137 143 }
138 144  
139   - private void log0(ProceedingJoinPoint joinPoint, OperateLog operateLog, ApiOperation apiOperation,
  145 + private void log0(ProceedingJoinPoint joinPoint,
  146 + cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog operateLog,
  147 + ApiOperation apiOperation,
140 148 Date startTime, Object result, Throwable exception) {
141   - OperateLogCreateReqDTO operateLogDTO = new OperateLogCreateReqDTO();
  149 + OperateLog operateLogObj = new OperateLog();
142 150 // 补全通用字段
143   - operateLogDTO.setTraceId(TracerUtils.getTraceId());
144   - operateLogDTO.setStartTime(startTime);
  151 + operateLogObj.setTraceId(TracerUtils.getTraceId());
  152 + operateLogObj.setStartTime(startTime);
145 153 // 补充用户信息
146   - fillUserFields(operateLogDTO);
  154 + fillUserFields(operateLogObj);
147 155 // 补全模块信息
148   - fillModuleFields(operateLogDTO, joinPoint, operateLog, apiOperation);
  156 + fillModuleFields(operateLogObj, joinPoint, operateLog, apiOperation);
149 157 // 补全请求信息
150   - fillRequestFields(operateLogDTO);
  158 + fillRequestFields(operateLogObj);
151 159 // 补全方法信息
152   - fillMethodFields(operateLogDTO, joinPoint, operateLog, startTime, result, exception);
  160 + fillMethodFields(operateLogObj, joinPoint, operateLog, startTime, result, exception);
153 161  
154 162 // 异步记录日志
155   - operateLogFrameworkService.createOperateLogAsync(operateLogDTO);
  163 + operateLogFrameworkService.createOperateLog(operateLogObj);
156 164 }
157 165  
158   - private static void fillUserFields(OperateLogCreateReqDTO operateLogDTO) {
159   - operateLogDTO.setUserId(WebFrameworkUtils.getLoginUserId());
160   - operateLogDTO.setUserType(WebFrameworkUtils.getLoginUserType());
  166 + private static void fillUserFields(OperateLog operateLogObj) {
  167 + operateLogObj.setUserId(WebFrameworkUtils.getLoginUserId());
  168 + operateLogObj.setUserType(WebFrameworkUtils.getLoginUserType());
161 169 }
162 170  
163   - private static void fillModuleFields(OperateLogCreateReqDTO operateLogDTO,
164   - ProceedingJoinPoint joinPoint, OperateLog operateLog, ApiOperation apiOperation) {
  171 + private static void fillModuleFields(OperateLog operateLogObj,
  172 + ProceedingJoinPoint joinPoint,
  173 + cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog operateLog,
  174 + ApiOperation apiOperation) {
165 175 // module 属性
166 176 if (operateLog != null) {
167   - operateLogDTO.setModule(operateLog.module());
  177 + operateLogObj.setModule(operateLog.module());
168 178 }
169   - if (StrUtil.isEmpty(operateLogDTO.getModule())) {
  179 + if (StrUtil.isEmpty(operateLogObj.getModule())) {
170 180 Api api = getClassAnnotation(joinPoint, Api.class);
171 181 if (api != null) {
172 182 // 优先读取 @API 的 name 属性
173 183 if (StrUtil.isNotEmpty(api.value())) {
174   - operateLogDTO.setModule(api.value());
  184 + operateLogObj.setModule(api.value());
175 185 }
176 186 // 没有的话,读取 @API 的 tags 属性
177   - if (StrUtil.isEmpty(operateLogDTO.getModule()) && ArrayUtil.isNotEmpty(api.tags())) {
178   - operateLogDTO.setModule(api.tags()[0]);
  187 + if (StrUtil.isEmpty(operateLogObj.getModule()) && ArrayUtil.isNotEmpty(api.tags())) {
  188 + operateLogObj.setModule(api.tags()[0]);
179 189 }
180 190 }
181 191 }
182 192 // name 属性
183 193 if (operateLog != null) {
184   - operateLogDTO.setName(operateLog.name());
  194 + operateLogObj.setName(operateLog.name());
185 195 }
186   - if (StrUtil.isEmpty(operateLogDTO.getName()) && apiOperation != null) {
187   - operateLogDTO.setName(apiOperation.value());
  196 + if (StrUtil.isEmpty(operateLogObj.getName()) && apiOperation != null) {
  197 + operateLogObj.setName(apiOperation.value());
188 198 }
189 199 // type 属性
190 200 if (operateLog != null && ArrayUtil.isNotEmpty(operateLog.type())) {
191   - operateLogDTO.setType(operateLog.type()[0].getType());
  201 + operateLogObj.setType(operateLog.type()[0].getType());
192 202 }
193   - if (operateLogDTO.getType() == null) {
  203 + if (operateLogObj.getType() == null) {
194 204 RequestMethod requestMethod = obtainFirstMatchRequestMethod(obtainRequestMethod(joinPoint));
195 205 OperateTypeEnum operateLogType = convertOperateLogType(requestMethod);
196   - operateLogDTO.setType(operateLogType != null ? operateLogType.getType() : null);
  206 + operateLogObj.setType(operateLogType != null ? operateLogType.getType() : null);
197 207 }
198 208 // content 和 exts 属性
199   - operateLogDTO.setContent(CONTENT.get());
200   - operateLogDTO.setExts(EXTS.get());
  209 + operateLogObj.setContent(CONTENT.get());
  210 + operateLogObj.setExts(EXTS.get());
201 211 }
202 212  
203   - private static void fillRequestFields(OperateLogCreateReqDTO operateLogDTO) {
  213 + private static void fillRequestFields(OperateLog operateLogObj) {
204 214 // 获得 Request 对象
205 215 HttpServletRequest request = ServletUtils.getRequest();
206 216 if (request == null) {
207 217 return;
208 218 }
209 219 // 补全请求信息
210   - operateLogDTO.setRequestMethod(request.getMethod());
211   - operateLogDTO.setRequestUrl(request.getRequestURI());
212   - operateLogDTO.setUserIp(ServletUtil.getClientIP(request));
213   - operateLogDTO.setUserAgent(ServletUtils.getUserAgent(request));
  220 + operateLogObj.setRequestMethod(request.getMethod());
  221 + operateLogObj.setRequestUrl(request.getRequestURI());
  222 + operateLogObj.setUserIp(ServletUtil.getClientIP(request));
  223 + operateLogObj.setUserAgent(ServletUtils.getUserAgent(request));
214 224 }
215 225  
216   - private static void fillMethodFields(OperateLogCreateReqDTO operateLogDTO,
217   - ProceedingJoinPoint joinPoint, OperateLog operateLog,
  226 + private static void fillMethodFields(OperateLog operateLogObj,
  227 + ProceedingJoinPoint joinPoint,
  228 + cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog operateLog,
218 229 Date startTime, Object result, Throwable exception) {
219 230 MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
220   - operateLogDTO.setJavaMethod(methodSignature.toString());
  231 + operateLogObj.setJavaMethod(methodSignature.toString());
221 232 if (operateLog == null || operateLog.logArgs()) {
222   - operateLogDTO.setJavaMethodArgs(obtainMethodArgs(joinPoint));
  233 + operateLogObj.setJavaMethodArgs(obtainMethodArgs(joinPoint));
223 234 }
224 235 if (operateLog == null || operateLog.logResultData()) {
225   - operateLogDTO.setResultData(obtainResultData(result));
  236 + operateLogObj.setResultData(obtainResultData(result));
226 237 }
227   - operateLogDTO.setDuration((int) (System.currentTimeMillis() - startTime.getTime()));
  238 + operateLogObj.setDuration((int) (System.currentTimeMillis() - startTime.getTime()));
228 239 // (正常)处理 resultCode 和 resultMsg 字段
229   - if (result != null) {
230   - if (result instanceof CommonResult) {
231   - CommonResult<?> commonResult = (CommonResult<?>) result;
232   - operateLogDTO.setResultCode(commonResult.getCode());
233   - operateLogDTO.setResultMsg(commonResult.getMsg());
234   - } else {
235   - operateLogDTO.setResultCode(SUCCESS.getCode());
236   - }
  240 + if (result instanceof CommonResult) {
  241 + CommonResult<?> commonResult = (CommonResult<?>) result;
  242 + operateLogObj.setResultCode(commonResult.getCode());
  243 + operateLogObj.setResultMsg(commonResult.getMsg());
  244 + } else {
  245 + operateLogObj.setResultCode(SUCCESS.getCode());
237 246 }
238 247 // (异常)处理 resultCode 和 resultMsg 字段
239 248 if (exception != null) {
240   - operateLogDTO.setResultCode(INTERNAL_SERVER_ERROR.getCode());
241   - operateLogDTO.setResultMsg(ExceptionUtil.getRootCauseMessage(exception));
  249 + operateLogObj.setResultCode(INTERNAL_SERVER_ERROR.getCode());
  250 + operateLogObj.setResultMsg(ExceptionUtil.getRootCauseMessage(exception));
242 251 }
243 252 }
244 253  
245   - private static boolean isLogEnable(ProceedingJoinPoint joinPoint, OperateLog operateLog) {
  254 + private static boolean isLogEnable(ProceedingJoinPoint joinPoint,
  255 + cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog operateLog) {
246 256 // 有 @OperateLog 注解的情况下
247 257 if (operateLog != null) {
248 258 return operateLog.enable();
... ... @@ -256,7 +266,7 @@ public class OperateLogAspect {
256 266 return null;
257 267 }
258 268 return Arrays.stream(requestMethods).filter(requestMethod ->
259   - requestMethod == RequestMethod.POST
  269 + requestMethod == RequestMethod.POST
260 270 || requestMethod == RequestMethod.PUT
261 271 || requestMethod == RequestMethod.DELETE)
262 272 .findFirst().orElse(null);
... ...
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/dto/OperateLogCreateReqDTO.java deleted
1   -package cn.iocoder.yudao.framework.operatelog.core.dto;
2   -
3   -import io.swagger.annotations.ApiModelProperty;
4   -import lombok.Data;
5   -
6   -import javax.validation.constraints.NotEmpty;
7   -import javax.validation.constraints.NotNull;
8   -import java.util.Date;
9   -import java.util.Map;
10   -
11   -/**
12   - * 操作日志创建 Request DTO
13   - */
14   -@Data
15   -public class OperateLogCreateReqDTO {
16   -
17   - @ApiModelProperty(value = "链路追踪编号", required = true, example = "89aca178-a370-411c-ae02-3f0d672be4ab")
18   - @NotEmpty(message = "链路追踪编号不能为空")
19   - private String traceId;
20   -
21   - @ApiModelProperty(value = "用户编号", required = true, example = "1024")
22   - @NotNull(message = "用户编号不能为空")
23   - private Long userId;
24   - @ApiModelProperty(value = "用户类型", required = true, example = "1")
25   - @NotNull(message = "用户类型不能为空")
26   - private Integer userType;
27   -
28   - @ApiModelProperty(value = "操作模块", required = true, example = "订单")
29   - @NotEmpty(message = "操作模块不能为空")
30   - private String module;
31   -
32   - @ApiModelProperty(value = "操作名", required = true, example = "创建订单")
33   - @NotEmpty(message = "操作名")
34   - private String name;
35   -
36   - @ApiModelProperty(value = "操作分类", required = true, example = "1", notes = "参见 SysOperateLogTypeEnum 枚举类")
37   - @NotNull(message = "操作分类不能为空")
38   - private Integer type;
39   -
40   - @ApiModelProperty(value = "操作明细", example = "修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。")
41   - private String content;
42   -
43   - @ApiModelProperty(value = "拓展字段", example = "{'orderId': 1}")
44   - private Map<String, Object> exts;
45   -
46   - @ApiModelProperty(value = "请求方法名", required = true, example = "GET")
47   - @NotEmpty(message = "请求方法名不能为空")
48   - private String requestMethod;
49   -
50   - @ApiModelProperty(value = "请求地址", required = true, example = "/xxx/yyy")
51   - @NotEmpty(message = "请求地址不能为空")
52   - private String requestUrl;
53   -
54   - @ApiModelProperty(value = "用户 IP", required = true, example = "127.0.0.1")
55   - @NotEmpty(message = "用户 IP 不能为空")
56   - private String userIp;
57   -
58   - @ApiModelProperty(value = "浏览器 UserAgent", required = true, example = "Mozilla/5.0")
59   - @NotEmpty(message = "浏览器 UserAgent 不能为空")
60   - private String userAgent;
61   -
62   - @ApiModelProperty(value = "Java 方法名", required = true, example = "cn.iocoder.yudao.UserController.save(...)")
63   - @NotEmpty(message = "Java 方法名不能为空")
64   - private String javaMethod;
65   -
66   - @ApiModelProperty(value = "Java 方法的参数")
67   - private String javaMethodArgs;
68   -
69   - @ApiModelProperty(value = "开始时间", required = true)
70   - @NotNull(message = "开始时间不能为空")
71   - private Date startTime;
72   -
73   - @ApiModelProperty(value = "执行时长,单位:毫秒", required = true)
74   - @NotNull(message = "执行时长不能为空")
75   - private Integer duration;
76   -
77   - @ApiModelProperty(value = "结果码", required = true)
78   - @NotNull(message = "结果码不能为空")
79   - private Integer resultCode;
80   -
81   - @ApiModelProperty(value = "结果提示")
82   - private String resultMsg;
83   -
84   - @ApiModelProperty(value = "结果数据")
85   - private String resultData;
86   -
87   -}
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/OperateLog.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.operatelog.core.service;
  2 +
  3 +import lombok.Data;
  4 +
  5 +import java.util.Date;
  6 +import java.util.Map;
  7 +
  8 +/**
  9 + * 操作日志
  10 + *
  11 + * @author 芋道源码
  12 + */
  13 +@Data
  14 +public class OperateLog {
  15 +
  16 + /**
  17 + * 链路追踪编号
  18 + */
  19 + private String traceId;
  20 +
  21 + /**
  22 + * 用户编号
  23 + */
  24 + private Long userId;
  25 + /**
  26 + * 用户类型
  27 + */
  28 + private Integer userType;
  29 +
  30 + /**
  31 + * 操作模块
  32 + */
  33 + private String module;
  34 +
  35 + /**
  36 + * 操作名
  37 + */
  38 + private String name;
  39 +
  40 + /**
  41 + * 操作分类
  42 + */
  43 + private Integer type;
  44 +
  45 + /**
  46 + * 操作明细
  47 + */
  48 + private String content;
  49 +
  50 + /**
  51 + * 拓展字段
  52 + */
  53 + private Map<String, Object> exts;
  54 +
  55 + /**
  56 + * 请求方法名
  57 + */
  58 + private String requestMethod;
  59 +
  60 + /**
  61 + * 请求地址
  62 + */
  63 + private String requestUrl;
  64 +
  65 + /**
  66 + * 用户 IP
  67 + */
  68 + private String userIp;
  69 +
  70 + /**
  71 + * 浏览器 UserAgent
  72 + */
  73 + private String userAgent;
  74 +
  75 + /**
  76 + * Java 方法名
  77 + */
  78 + private String javaMethod;
  79 +
  80 + /**
  81 + * Java 方法的参数
  82 + */
  83 + private String javaMethodArgs;
  84 +
  85 + /**
  86 + * 开始时间
  87 + */
  88 + private Date startTime;
  89 +
  90 + /**
  91 + * 执行时长,单位:毫秒
  92 + */
  93 + private Integer duration;
  94 +
  95 + /**
  96 + * 结果码
  97 + */
  98 + private Integer resultCode;
  99 +
  100 + /**
  101 + * 结果提示
  102 + */
  103 + private String resultMsg;
  104 +
  105 + /**
  106 + * 结果数据
  107 + */
  108 + private String resultData;
  109 +
  110 +}
... ...
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/OperateLogFrameworkService.java
1 1 package cn.iocoder.yudao.framework.operatelog.core.service;
2 2  
3   -import cn.iocoder.yudao.framework.operatelog.core.dto.OperateLogCreateReqDTO;
4   -
5   -import java.util.concurrent.Future;
6   -
  3 +/**
  4 + * 操作日志 Framework Service 接口
  5 + *
  6 + * @author 芋道源码
  7 + */
7 8 public interface OperateLogFrameworkService {
8 9  
9 10 /**
10   - * 异步记录操作日志
  11 + * 记录操作日志
11 12 *
12   - * @param reqVO 操作日志请求
13   - * @return true: 记录成功,false: 记录失败
  13 + * @param operateLog 操作日志请求
14 14 */
15   - Future<Boolean> createOperateLogAsync(OperateLogCreateReqDTO reqVO);
  15 + void createOperateLog(OperateLog operateLog);
16 16  
17 17 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/OperateLogFrameworkServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.operatelog.core.service;
  2 +
  3 +import cn.hutool.core.bean.BeanUtil;
  4 +import cn.iocoder.yudao.module.system.api.logger.OperateLogApi;
  5 +import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO;
  6 +import lombok.RequiredArgsConstructor;
  7 +import org.springframework.scheduling.annotation.Async;
  8 +
  9 +/**
  10 + * 操作日志 Framework Service 实现类
  11 + *
  12 + * 基于 {@link OperateLogApi} 实现,记录操作日志
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +@RequiredArgsConstructor
  17 +public class OperateLogFrameworkServiceImpl implements OperateLogFrameworkService {
  18 +
  19 + private final OperateLogApi operateLogApi;
  20 +
  21 + @Override
  22 + @Async
  23 + public void createOperateLog(OperateLog operateLog) {
  24 + OperateLogCreateReqDTO reqDTO = BeanUtil.copyProperties(operateLog, OperateLogCreateReqDTO.class);
  25 + operateLogApi.createOperateLog(reqDTO);
  26 + }
  27 +
  28 +}
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java
... ... @@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
7 7 import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig;
8 8 import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayQrPayClient;
9 9 import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayWapPayClient;
  10 +import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXLitePayClient;
10 11 import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXNativePayClient;
11 12 import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
12 13 import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPubPayClient;
... ... @@ -62,7 +63,7 @@ public class PayClientFactoryImpl implements PayClientFactory {
62 63 // TODO @芋艿 WX_LITE WX_APP 如果不添加在 项目启动的时候去初始化会报错无法启动。所以我手动加了两个,具体需要你来配
63 64 switch (channelEnum) {
64 65 case WX_PUB: return (AbstractPayClient<Config>) new WXPubPayClient(channelId, (WXPayClientConfig) config);
65   - case WX_LITE: return (AbstractPayClient<Config>) new WXPubPayClient(channelId, (WXPayClientConfig) config);
  66 + case WX_LITE: return (AbstractPayClient<Config>) new WXLitePayClient(channelId, (WXPayClientConfig) config); //微信小程序请求支付
66 67 case WX_APP: return (AbstractPayClient<Config>) new WXPubPayClient(channelId, (WXPayClientConfig) config);
67 68 case WX_NATIVE: return (AbstractPayClient<Config>) new WXNativePayClient(channelId, (WXPayClientConfig) config);
68 69 case ALIPAY_WAP: return (AbstractPayClient<Config>) new AlipayWapPayClient(channelId, (AlipayPayClientConfig) config);
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayClient.java
... ... @@ -2,6 +2,7 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
2 2  
3 3 import cn.hutool.core.bean.BeanUtil;
4 4 import cn.hutool.core.date.DateUtil;
  5 +import cn.hutool.http.HttpUtil;
5 6 import cn.iocoder.yudao.framework.pay.core.client.AbstractPayCodeMapping;
6 7 import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult;
7 8 import cn.iocoder.yudao.framework.pay.core.client.dto.*;
... ... @@ -130,11 +131,20 @@ public abstract class AbstractAlipayClient extends AbstractPayClient&lt;AlipayPayCl
130 131 }
131 132 }
132 133  
  134 +
  135 +
  136 + /**
  137 + * 支付宝统一回调参数 str 转 map
  138 + *
  139 + * @param s 支付宝支付通知回调参数
  140 + * @return map 支付宝集合
  141 + */
133 142 public static Map<String, String> strToMap(String s) {
  143 + // TODO @zxy:这个可以使用 hutool 的 HttpUtil decodeParams 方法么?
134 144 Map<String, String> stringStringMap = new HashMap<>();
135   - //调整时间格式
  145 + // 调整时间格式
136 146 String s3 = s.replaceAll("%3A", ":");
137   - //获取map
  147 + // 获取 map
138 148 String s4 = s3.replace("+", " ");
139 149 String[] split = s4.split("&");
140 150 for (String s1 : split) {
... ... @@ -143,4 +153,5 @@ public abstract class AbstractAlipayClient extends AbstractPayClient&lt;AlipayPayCl
143 153 }
144 154 return stringStringMap;
145 155 }
  156 +
146 157 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXLitePayClient.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.pay.core.client.impl.wx;
  2 +
  3 +import cn.hutool.core.bean.BeanUtil;
  4 +import cn.hutool.core.date.DateUtil;
  5 +import cn.hutool.core.lang.Assert;
  6 +import cn.hutool.core.map.MapUtil;
  7 +import cn.hutool.core.util.StrUtil;
  8 +import cn.iocoder.yudao.framework.common.util.io.FileUtils;
  9 +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
  10 +import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult;
  11 +import cn.iocoder.yudao.framework.pay.core.client.dto.*;
  12 +import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
  13 +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
  14 +import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
  15 +import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
  16 +import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
  17 +import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
  18 +import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
  19 +import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result;
  20 +import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
  21 +import com.github.binarywang.wxpay.config.WxPayConfig;
  22 +import com.github.binarywang.wxpay.constant.WxPayConstants;
  23 +import com.github.binarywang.wxpay.exception.WxPayException;
  24 +import com.github.binarywang.wxpay.service.WxPayService;
  25 +import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
  26 +import lombok.extern.slf4j.Slf4j;
  27 +
  28 +import java.util.Objects;
  29 +
  30 +import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
  31 +import static cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXCodeMapping.CODE_SUCCESS;
  32 +import static cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXCodeMapping.MESSAGE_SUCCESS;
  33 +
  34 +
  35 +/**
  36 + * 微信小程序下支付
  37 + *
  38 + * @author zwy
  39 + */
  40 +@Slf4j
  41 +public class WXLitePayClient extends AbstractPayClient<WXPayClientConfig> {
  42 +
  43 + private WxPayService client;
  44 +
  45 + public WXLitePayClient(Long channelId, WXPayClientConfig config) {
  46 + super(channelId, PayChannelEnum.WX_LITE.getCode(), config, new WXCodeMapping());
  47 + }
  48 +
  49 + @Override
  50 + protected void doInit() {
  51 + WxPayConfig payConfig = new WxPayConfig();
  52 + BeanUtil.copyProperties(config, payConfig, "keyContent");
  53 + payConfig.setTradeType(WxPayConstants.TradeType.JSAPI); // 设置使用 JS API 支付方式
  54 +// if (StrUtil.isNotEmpty(config.getKeyContent())) {
  55 +// payConfig.setKeyContent(config.getKeyContent().getBytes(StandardCharsets.UTF_8));
  56 +// }
  57 + if (StrUtil.isNotEmpty(config.getPrivateKeyContent())) {
  58 + // weixin-pay-java 存在 BUG,无法直接设置内容,所以创建临时文件来解决
  59 + payConfig.setPrivateKeyPath(FileUtils.createTempFile(config.getPrivateKeyContent()).getPath());
  60 + }
  61 + if (StrUtil.isNotEmpty(config.getPrivateCertContent())) {
  62 + // weixin-pay-java 存在 BUG,无法直接设置内容,所以创建临时文件来解决
  63 + payConfig.setPrivateCertPath(FileUtils.createTempFile(config.getPrivateCertContent()).getPath());
  64 + }
  65 + // 真实客户端
  66 + this.client = new WxPayServiceImpl();
  67 + client.setConfig(payConfig);
  68 + }
  69 +
  70 + @Override
  71 + public PayCommonResult<WxPayMpOrderResult> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
  72 + WxPayMpOrderResult response;
  73 + try {
  74 + switch (config.getApiVersion()) {
  75 + case WXPayClientConfig.API_VERSION_V2:
  76 + response = this.unifiedOrderV2(reqDTO);
  77 + break;
  78 + case WXPayClientConfig.API_VERSION_V3:
  79 + WxPayUnifiedOrderV3Result.JsapiResult responseV3 = this.unifiedOrderV3(reqDTO);
  80 + // 将 V3 的结果,统一转换成 V2。返回的字段是一致的
  81 + response = new WxPayMpOrderResult();
  82 + BeanUtil.copyProperties(responseV3, response, true);
  83 + break;
  84 + default:
  85 + throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
  86 + }
  87 + } catch (WxPayException e) {
  88 + log.error("[unifiedOrder][request({}) 发起支付失败,原因({})]", toJsonString(reqDTO), e);
  89 + return PayCommonResult.build(ObjectUtils.defaultIfNull(e.getErrCode(), e.getReturnCode(), "CustomErrorCode"),
  90 + ObjectUtils.defaultIfNull(e.getErrCodeDes(), e.getCustomErrorMsg()), null, codeMapping);
  91 + }
  92 + return PayCommonResult.build(CODE_SUCCESS, MESSAGE_SUCCESS, response, codeMapping);
  93 + }
  94 +
  95 + private WxPayMpOrderResult unifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
  96 + // 构建 WxPayUnifiedOrderRequest 对象
  97 + WxPayUnifiedOrderRequest request = WxPayUnifiedOrderRequest.newBuilder()
  98 + .outTradeNo(reqDTO.getMerchantOrderId())
  99 + .body(reqDTO.getBody())
  100 + .totalFee(reqDTO.getAmount().intValue()) // 单位分
  101 + .timeExpire(DateUtil.format(reqDTO.getExpireTime(), "yyyyMMddHHmmss")) // v2的时间格式
  102 + .spbillCreateIp(reqDTO.getUserIp())
  103 + .openid(getOpenid(reqDTO))
  104 + .notifyUrl(reqDTO.getNotifyUrl())
  105 + .build();
  106 + // 执行请求
  107 + return client.createOrder(request);
  108 + }
  109 +
  110 + private WxPayUnifiedOrderV3Result.JsapiResult unifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
  111 + // 构建 WxPayUnifiedOrderRequest 对象
  112 + WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request();
  113 + request.setOutTradeNo(reqDTO.getMerchantOrderId());
  114 +
  115 + request.setDescription(reqDTO.getBody());
  116 + request.setAmount(new WxPayUnifiedOrderV3Request
  117 + .Amount()
  118 + .setTotal(reqDTO
  119 + .getAmount()
  120 + .intValue())); // 单位分
  121 + request.setTimeExpire(DateUtil.format(reqDTO.getExpireTime(), "yyyy-MM-dd'T'HH:mm:ssXXX")); // v3的时间格式
  122 + request.setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid(getOpenid(reqDTO)));
  123 + request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(reqDTO.getUserIp()));
  124 + request.setNotifyUrl(reqDTO.getNotifyUrl());
  125 + // 执行请求
  126 + return client.createOrderV3(TradeTypeEnum.JSAPI, request);
  127 + }
  128 +
  129 + private static String getOpenid(PayOrderUnifiedReqDTO reqDTO) {
  130 + String openid = MapUtil.getStr(reqDTO.getChannelExtras(), "openid");
  131 + if (StrUtil.isEmpty(openid)) {
  132 + throw new IllegalArgumentException("支付请求的 openid 不能为空!");
  133 + }
  134 + return openid;
  135 + }
  136 +
  137 + /**
  138 + *
  139 + * 微信支付回调 分 v2 和v3 的处理方式
  140 + *
  141 + * @param data 通知结果
  142 + * @return 支付回调对象
  143 + * @throws WxPayException 微信异常类
  144 + */
  145 + @Override
  146 + public PayOrderNotifyRespDTO parseOrderNotify(PayNotifyDataDTO data) throws WxPayException {
  147 + log.info("[parseOrderNotify][微信支付回调data数据:{}]", data.getBody());
  148 + // 微信支付 v2 回调结果处理
  149 + switch (config.getApiVersion()) {
  150 + case WXPayClientConfig.API_VERSION_V2:
  151 + return parseOrderNotifyV2(data);
  152 + case WXPayClientConfig.API_VERSION_V3:
  153 + return parseOrderNotifyV3(data);
  154 + default:
  155 + throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
  156 + }
  157 + }
  158 +
  159 + private PayOrderNotifyRespDTO parseOrderNotifyV3(PayNotifyDataDTO data) throws WxPayException {
  160 + WxPayOrderNotifyV3Result wxPayOrderNotifyV3Result = client.parseOrderNotifyV3Result(data.getBody(), null);
  161 + WxPayOrderNotifyV3Result.DecryptNotifyResult result = wxPayOrderNotifyV3Result.getResult();
  162 + // 转换结果
  163 + Assert.isTrue(Objects.equals(wxPayOrderNotifyV3Result.getResult().getTradeState(), "SUCCESS"),
  164 + "支付结果非 SUCCESS");
  165 +
  166 + return PayOrderNotifyRespDTO
  167 + .builder()
  168 + .orderExtensionNo(result.getOutTradeNo())
  169 + .channelOrderNo(result.getTradeState())
  170 + .successTime(DateUtil.parse(result.getSuccessTime(), "yyyy-MM-dd'T'HH:mm:ssXXX"))
  171 + .data(data.getBody())
  172 + .build();
  173 + }
  174 +
  175 + private PayOrderNotifyRespDTO parseOrderNotifyV2(PayNotifyDataDTO data) throws WxPayException {
  176 + WxPayOrderNotifyResult notifyResult = client.parseOrderNotifyResult(data.getBody());
  177 + Assert.isTrue(Objects.equals(notifyResult.getResultCode(), "SUCCESS"), "支付结果非 SUCCESS");
  178 + // 转换结果
  179 + return PayOrderNotifyRespDTO
  180 + .builder()
  181 + .orderExtensionNo(notifyResult.getOutTradeNo())
  182 + .channelOrderNo(notifyResult.getTransactionId())
  183 + .channelUserId(notifyResult.getOpenid())
  184 + .successTime(DateUtil.parse(notifyResult.getTimeEnd(), "yyyyMMddHHmmss"))
  185 + .data(data.getBody())
  186 + .build();
  187 +
  188 + }
  189 +
  190 + @Override
  191 + public PayRefundNotifyDTO parseRefundNotify(PayNotifyDataDTO notifyData) {
  192 + //TODO 需要实现
  193 + throw new UnsupportedOperationException("需要实现");
  194 + }
  195 +
  196 +
  197 + @Override
  198 + protected PayCommonResult<PayRefundUnifiedRespDTO> doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
  199 + //TODO 需要实现
  200 + throw new UnsupportedOperationException();
  201 + }
  202 +
  203 +}
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXNativePayClient.java
... ... @@ -11,6 +11,7 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.*;
11 11 import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
12 12 import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
13 13 import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
  14 +import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
14 15 import com.github.binarywang.wxpay.bean.order.WxPayNativeOrderResult;
15 16 import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
16 17 import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
... ... @@ -28,9 +29,14 @@ import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString
28 29 import static cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXCodeMapping.CODE_SUCCESS;
29 30 import static cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXCodeMapping.MESSAGE_SUCCESS;
30 31  
31   -
  32 +/**
  33 + * 微信 App 支付
  34 + *
  35 + * @author zwy
  36 + */
32 37 @Slf4j
33 38 public class WXNativePayClient extends AbstractPayClient<WXPayClientConfig> {
  39 +
34 40 private WxPayService client;
35 41  
36 42 public WXNativePayClient(Long channelId, WXPayClientConfig config) {
... ... @@ -61,7 +67,7 @@ public class WXNativePayClient extends AbstractPayClient&lt;WXPayClientConfig&gt; {
61 67 @Override
62 68 public PayCommonResult<String> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
63 69 // 这里原生的返回的是支付的 url 所以直接使用string接收
64   - //"invokeResponse": "weixin://wxpay/bizpayurl?pr=EGYAem7zz"
  70 + // "invokeResponse": "weixin://wxpay/bizpayurl?pr=EGYAem7zz"
65 71 String responseV3;
66 72 try {
67 73 switch (config.getApiVersion()) {
... ... @@ -84,7 +90,7 @@ public class WXNativePayClient extends AbstractPayClient&lt;WXPayClientConfig&gt; {
84 90  
85 91 private WxPayNativeOrderResult unifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
86 92 //前端
87   - String trade_type = reqDTO.getChannelExtras().get("trade_type");
  93 + String tradeType = reqDTO.getChannelExtras().get("trade_type");
88 94 // 构建 WxPayUnifiedOrderRequest 对象
89 95 WxPayUnifiedOrderRequest request = WxPayUnifiedOrderRequest
90 96 .newBuilder()
... ... @@ -94,7 +100,7 @@ public class WXNativePayClient extends AbstractPayClient&lt;WXPayClientConfig&gt; {
94 100 .timeExpire(DateUtil.format(reqDTO.getExpireTime(), "yyyy-MM-dd'T'HH:mm:ssXXX"))
95 101 .spbillCreateIp(reqDTO.getUserIp())
96 102 .notifyUrl(reqDTO.getNotifyUrl())
97   - .productId(trade_type)
  103 + .productId(tradeType)
98 104 .build();
99 105 // 执行请求
100 106 return client.createOrder(request);
... ... @@ -109,33 +115,72 @@ public class WXNativePayClient extends AbstractPayClient&lt;WXPayClientConfig&gt; {
109 115 request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(reqDTO.getUserIp()));
110 116 request.setNotifyUrl(reqDTO.getNotifyUrl());
111 117 // 执行请求
112   -// log.info("支付字段request:{}",request.getTimeExpire());
113   -
114 118 return client.createOrderV3(TradeTypeEnum.NATIVE, request);
115 119 }
116 120  
117   -
  121 + /**
  122 + *
  123 + * 微信支付回调 分v2 和v3 的处理方式
  124 + *
  125 + * @param data 通知结果
  126 + * @return 支付回调对象
  127 + * @throws WxPayException 微信异常类
  128 + */
118 129 @Override
119 130 public PayOrderNotifyRespDTO parseOrderNotify(PayNotifyDataDTO data) throws WxPayException {
  131 + log.info("微信支付回调data数据:{}", data.getBody());
  132 + // 微信支付 v2 回调结果处理
  133 + switch (config.getApiVersion()) {
  134 + case WXPayClientConfig.API_VERSION_V2:
  135 + return parseOrderNotifyV2(data);
  136 + case WXPayClientConfig.API_VERSION_V3:
  137 + return parseOrderNotifyV3(data);
  138 + default:
  139 + throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
  140 + }
  141 + }
  142 +
  143 + private PayOrderNotifyRespDTO parseOrderNotifyV3(PayNotifyDataDTO data) throws WxPayException {
  144 + WxPayOrderNotifyV3Result wxPayOrderNotifyV3Result = client.parseOrderNotifyV3Result(data.getBody(), null);
  145 + WxPayOrderNotifyV3Result.DecryptNotifyResult result = wxPayOrderNotifyV3Result.getResult();
  146 + // 转换结果
  147 + Assert.isTrue(Objects.equals(wxPayOrderNotifyV3Result.getResult().getTradeState(), "SUCCESS"),
  148 + "支付结果非 SUCCESS");
  149 + return PayOrderNotifyRespDTO
  150 + .builder()
  151 + .orderExtensionNo(result.getOutTradeNo())
  152 + .channelOrderNo(result.getTradeState())
  153 + .successTime(DateUtil.parse(result.getSuccessTime(), "yyyy-MM-dd'T'HH:mm:ssXXX"))
  154 + .data(data.getBody())
  155 + .build();
  156 + }
  157 +
  158 + private PayOrderNotifyRespDTO parseOrderNotifyV2(PayNotifyDataDTO data) throws WxPayException {
120 159 WxPayOrderNotifyResult notifyResult = client.parseOrderNotifyResult(data.getBody());
121 160 Assert.isTrue(Objects.equals(notifyResult.getResultCode(), "SUCCESS"), "支付结果非 SUCCESS");
122 161 // 转换结果
123   - return PayOrderNotifyRespDTO.builder().orderExtensionNo(notifyResult.getOutTradeNo())
124   - .channelOrderNo(notifyResult.getTransactionId()).channelUserId(notifyResult.getOpenid())
125   - .successTime(DateUtil.parse(notifyResult.getTimeEnd(), "yyyy-MM-dd'T'HH:mm:ssXXX"))
126   - .data(data.getBody()).build();
  162 + return PayOrderNotifyRespDTO
  163 + .builder()
  164 + .orderExtensionNo(notifyResult.getOutTradeNo())
  165 + .channelOrderNo(notifyResult.getTransactionId())
  166 + .channelUserId(notifyResult.getOpenid())
  167 + .successTime(DateUtil.parse(notifyResult.getTimeEnd(), "yyyyMMddHHmmss"))
  168 + .data(data.getBody())
  169 + .build();
  170 +
127 171 }
128 172  
129 173 @Override
130 174 public PayRefundNotifyDTO parseRefundNotify(PayNotifyDataDTO notifyData) {
131   - //TODO 需要实现
  175 + // TODO 需要实现
132 176 throw new UnsupportedOperationException("需要实现");
133 177 }
134 178  
135 179  
136 180 @Override
137 181 protected PayCommonResult<PayRefundUnifiedRespDTO> doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
138   - //TODO 需要实现
  182 + // TODO 需要实现
139 183 throw new UnsupportedOperationException();
140 184 }
  185 +
141 186 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXPayClientConfig.java
... ... @@ -11,8 +11,6 @@ import java.io.FileInputStream;
11 11 import java.io.FileNotFoundException;
12 12 import java.util.Set;
13 13  
14   -// TODO 芋艿:参数校验
15   -
16 14 /**
17 15 * 微信支付的 PayClientConfig 实现类
18 16 * 属性主要来自 {@link com.github.binarywang.wxpay.config.WxPayConfig} 的必要属性
... ... @@ -22,7 +20,6 @@ import java.util.Set;
22 20 @Data
23 21 public class WXPayClientConfig implements PayClientConfig {
24 22  
25   - // TODO 芋艿:V2 or V3 客户端
26 23 /**
27 24 * API 版本 - V2
28 25 * https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_1
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXPubPayClient.java
... ... @@ -12,6 +12,7 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.*;
12 12 import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
13 13 import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
14 14 import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
  15 +import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
15 16 import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
16 17 import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
17 18 import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
... ... @@ -95,7 +96,6 @@ public class WXPubPayClient extends AbstractPayClient&lt;WXPayClientConfig&gt; {
95 96 // 构建 WxPayUnifiedOrderRequest 对象
96 97 WxPayUnifiedOrderRequest request = WxPayUnifiedOrderRequest.newBuilder()
97 98 .outTradeNo(reqDTO.getMerchantOrderId())
98   - // TODO 芋艿:貌似没 title?
99 99 .body(reqDTO.getBody())
100 100 .totalFee(reqDTO.getAmount().intValue()) // 单位分
101 101 .timeExpire(DateUtil.format(reqDTO.getExpireTime(), "yyyy-MM-dd'T'HH:mm:ssXXX"))
... ... @@ -111,7 +111,6 @@ public class WXPubPayClient extends AbstractPayClient&lt;WXPayClientConfig&gt; {
111 111 // 构建 WxPayUnifiedOrderRequest 对象
112 112 WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request();
113 113 request.setOutTradeNo(reqDTO.getMerchantOrderId());
114   - // TODO 芋艿:貌似没 title?
115 114 request.setDescription(reqDTO.getBody());
116 115 request.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(reqDTO.getAmount().intValue())); // 单位分
117 116 request.setTimeExpire(DateUtil.format(reqDTO.getExpireTime(), "yyyy-MM-dd'T'HH:mm:ssXXX"));
... ... @@ -130,27 +129,67 @@ public class WXPubPayClient extends AbstractPayClient&lt;WXPayClientConfig&gt; {
130 129 return openid;
131 130 }
132 131  
  132 + /**
  133 + *
  134 + * 微信支付回调 分v2 和v3 的处理方式
  135 + *
  136 + * @param data 通知结果
  137 + * @return 支付回调对象
  138 + * @throws WxPayException 微信异常类
  139 + */
133 140 @Override
134 141 public PayOrderNotifyRespDTO parseOrderNotify(PayNotifyDataDTO data) throws WxPayException {
  142 + log.info("[parseOrderNotify][微信支付回调data数据: {}]", data.getBody());
  143 + // 微信支付 v2 回调结果处理
  144 + switch (config.getApiVersion()) {
  145 + case WXPayClientConfig.API_VERSION_V2:
  146 + return parseOrderNotifyV2(data);
  147 + case WXPayClientConfig.API_VERSION_V3:
  148 + return parseOrderNotifyV3(data);
  149 + default:
  150 + throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
  151 + }
  152 + }
  153 +
  154 + private PayOrderNotifyRespDTO parseOrderNotifyV3(PayNotifyDataDTO data) throws WxPayException {
  155 + WxPayOrderNotifyV3Result wxPayOrderNotifyV3Result = client.parseOrderNotifyV3Result(data.getBody(), null);
  156 + WxPayOrderNotifyV3Result.DecryptNotifyResult result = wxPayOrderNotifyV3Result.getResult();
  157 + // 转换结果
  158 + Assert.isTrue(Objects.equals(wxPayOrderNotifyV3Result.getResult().getTradeState(), "SUCCESS"),
  159 + "支付结果非 SUCCESS");
  160 + return PayOrderNotifyRespDTO
  161 + .builder()
  162 + .orderExtensionNo(result.getOutTradeNo())
  163 + .channelOrderNo(result.getTradeState())
  164 + .successTime(DateUtil.parse(result.getSuccessTime(), "yyyy-MM-dd'T'HH:mm:ssXXX"))
  165 + .data(data.getBody())
  166 + .build();
  167 + }
  168 +
  169 + private PayOrderNotifyRespDTO parseOrderNotifyV2(PayNotifyDataDTO data) throws WxPayException {
135 170 WxPayOrderNotifyResult notifyResult = client.parseOrderNotifyResult(data.getBody());
136 171 Assert.isTrue(Objects.equals(notifyResult.getResultCode(), "SUCCESS"), "支付结果非 SUCCESS");
137 172 // 转换结果
138   - return PayOrderNotifyRespDTO.builder().orderExtensionNo(notifyResult.getOutTradeNo())
139   - .channelOrderNo(notifyResult.getTransactionId()).channelUserId(notifyResult.getOpenid())
  173 + return PayOrderNotifyRespDTO
  174 + .builder()
  175 + .orderExtensionNo(notifyResult.getOutTradeNo())
  176 + .channelOrderNo(notifyResult.getTransactionId())
  177 + .channelUserId(notifyResult.getOpenid())
140 178 .successTime(DateUtil.parse(notifyResult.getTimeEnd(), "yyyyMMddHHmmss"))
141   - .data(data.getBody()).build();
  179 + .data(data.getBody())
  180 + .build();
  181 +
142 182 }
143 183  
144 184 @Override
145 185 public PayRefundNotifyDTO parseRefundNotify(PayNotifyDataDTO notifyData) {
146   - //TODO 需要实现
  186 + // TODO 需要实现
147 187 throw new UnsupportedOperationException("需要实现");
148 188 }
149 189  
150   -
151 190 @Override
152 191 protected PayCommonResult<PayRefundUnifiedRespDTO> doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
153   - //TODO 需要实现
  192 + // TODO 需要实现
154 193 throw new UnsupportedOperationException();
155 194 }
156 195  
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/PayChannelEnum.java
... ... @@ -22,7 +22,6 @@ public enum PayChannelEnum {
22 22 WX_APP("wx_app", "微信 App 支付", WXPayClientConfig.class),
23 23 WX_NATIVE("wx_native", "微信 native 支付", WXPayClientConfig.class),
24 24  
25   -
26 25 ALIPAY_PC("alipay_pc", "支付宝 PC 网站支付", AlipayPayClientConfig.class),
27 26 ALIPAY_WAP("alipay_wap", "支付宝 Wap 网站支付", AlipayPayClientConfig.class),
28 27 ALIPAY_APP("alipay_app", "支付宝App 支付", AlipayPayClientConfig.class),
... ...
yudao-framework/yudao-spring-boot-starter-biz-tenant/pom.xml
... ... @@ -56,6 +56,12 @@
56 56 <artifactId>spring-boot-starter-test</artifactId>
57 57 <scope>test</scope>
58 58 </dependency>
  59 +
  60 + <!-- 工具类相关 -->
  61 + <dependency>
  62 + <groupId>com.google.guava</groupId>
  63 + <artifactId>guava</artifactId>
  64 + </dependency>
59 65 </dependencies>
60 66  
61 67 </project>
... ...
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java
... ... @@ -11,9 +11,11 @@ import cn.iocoder.yudao.framework.tenant.core.job.TenantJobHandlerDecorator;
11 11 import cn.iocoder.yudao.framework.tenant.core.mq.TenantRedisMessageInterceptor;
12 12 import cn.iocoder.yudao.framework.tenant.core.security.TenantSecurityWebFilter;
13 13 import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService;
  14 +import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkServiceImpl;
14 15 import cn.iocoder.yudao.framework.tenant.core.web.TenantContextWebFilter;
15 16 import cn.iocoder.yudao.framework.web.config.WebProperties;
16 17 import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler;
  18 +import cn.iocoder.yudao.module.system.api.tenant.TenantApi;
17 19 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
18 20 import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
19 21 import org.springframework.beans.BeansException;
... ... @@ -29,6 +31,11 @@ import org.springframework.context.annotation.Configuration;
29 31 @EnableConfigurationProperties(TenantProperties.class)
30 32 public class YudaoTenantAutoConfiguration {
31 33  
  34 + @Bean
  35 + public TenantFrameworkService tenantFrameworkService(TenantApi tenantApi) {
  36 + return new TenantFrameworkServiceImpl(tenantApi);
  37 + }
  38 +
32 39 // ========== AOP ==========
33 40  
34 41 @Bean
... ...
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/TenantRedisMessageInterceptor.java
... ... @@ -5,6 +5,8 @@ import cn.iocoder.yudao.framework.mq.core.interceptor.RedisMessageInterceptor;
5 5 import cn.iocoder.yudao.framework.mq.core.message.AbstractRedisMessage;
6 6 import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
7 7  
  8 +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID;
  9 +
8 10 /**
9 11 * 多租户 {@link AbstractRedisMessage} 拦截器
10 12 *
... ... @@ -15,8 +17,6 @@ import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
15 17 */
16 18 public class TenantRedisMessageInterceptor implements RedisMessageInterceptor {
17 19  
18   - private static final String HEADER_TENANT_ID = "tenant-id";
19   -
20 20 @Override
21 21 public void sendMessageBefore(AbstractRedisMessage message) {
22 22 Long tenantId = TenantContextHolder.getTenantId();
... ...
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/service/TenantFrameworkServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.tenant.core.service;
  2 +
  3 +import cn.iocoder.yudao.framework.common.exception.ServiceException;
  4 +import cn.iocoder.yudao.framework.common.util.cache.CacheUtils;
  5 +import cn.iocoder.yudao.module.system.api.tenant.TenantApi;
  6 +import com.google.common.cache.CacheLoader;
  7 +import com.google.common.cache.LoadingCache;
  8 +import lombok.RequiredArgsConstructor;
  9 +import lombok.SneakyThrows;
  10 +
  11 +import java.time.Duration;
  12 +import java.util.List;
  13 +
  14 +/**
  15 + * Tenant 框架 Service 实现类
  16 + *
  17 + * @author 芋道源码
  18 + */
  19 +@RequiredArgsConstructor
  20 +public class TenantFrameworkServiceImpl implements TenantFrameworkService {
  21 +
  22 + private static final ServiceException SERVICE_EXCEPTION_NULL = new ServiceException();
  23 +
  24 + private final TenantApi tenantApi;
  25 +
  26 + /**
  27 + * 针对 {@link #getTenantIds()} 的缓存
  28 + */
  29 + private final LoadingCache<Object, List<Long>> getTenantIdsCache = CacheUtils.buildAsyncReloadingCache(
  30 + Duration.ofMinutes(1L), // 过期时间 1 分钟
  31 + new CacheLoader<Object, List<Long>>() {
  32 +
  33 + @Override
  34 + public List<Long> load(Object key) {
  35 + return tenantApi.getTenantIds();
  36 + }
  37 +
  38 + });
  39 +
  40 + /**
  41 + * 针对 {@link #validTenant(Long)} 的缓存
  42 + */
  43 + private final LoadingCache<Long, ServiceException> validTenantCache = CacheUtils.buildAsyncReloadingCache(
  44 + Duration.ofMinutes(1L), // 过期时间 1 分钟
  45 + new CacheLoader<Long, ServiceException>() {
  46 +
  47 + @Override
  48 + public ServiceException load(Long id) {
  49 + try {
  50 + tenantApi.validTenant(id);
  51 + return SERVICE_EXCEPTION_NULL;
  52 + } catch (ServiceException ex) {
  53 + return ex;
  54 + }
  55 + }
  56 +
  57 + });
  58 +
  59 + @Override
  60 + @SneakyThrows
  61 + public List<Long> getTenantIds() {
  62 + return getTenantIdsCache.get(Boolean.TRUE);
  63 + }
  64 +
  65 + @Override
  66 + public void validTenant(Long id) {
  67 + ServiceException serviceException = validTenantCache.getUnchecked(id);
  68 + if (serviceException != SERVICE_EXCEPTION_NULL) {
  69 + throw serviceException;
  70 + }
  71 + }
  72 +
  73 +}
... ...
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/web/TenantContextWebFilter.java
... ... @@ -18,8 +18,6 @@ import java.io.IOException;
18 18 */
19 19 public class TenantContextWebFilter extends OncePerRequestFilter {
20 20  
21   - private static final String HEADER_TENANT_ID = "tenant-id";
22   -
23 21 @Override
24 22 protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
25 23 throws ServletException, IOException {
... ...
yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/convert/DictConvert.java
1 1 package cn.iocoder.yudao.framework.excel.core.convert;
2 2  
3 3 import cn.hutool.core.convert.Convert;
4   -import cn.iocoder.yudao.framework.dict.core.dto.DictDataRespDTO;
5 4 import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
6 5 import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
7 6 import com.alibaba.excel.converters.Converter;
... ... @@ -12,7 +11,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty;
12 11 import lombok.extern.slf4j.Slf4j;
13 12  
14 13 /**
15   - * Excel {@link DictDataRespDTO} 数据字典转换器
  14 + * Excel 数据字典转换器
16 15 *
17 16 * @author 芋道源码
18 17 */
... ... @@ -35,14 +34,14 @@ public class DictConvert implements Converter&lt;Object&gt; {
35 34 // 使用字典解析
36 35 String type = getType(contentProperty);
37 36 String label = cellData.getStringValue();
38   - DictDataRespDTO dictData = DictFrameworkUtils.parseDictDataFromCache(type, label);
39   - if (dictData == null) {
  37 + String value = DictFrameworkUtils.parseDictDataValue(type, label);
  38 + if (value == null) {
40 39 log.error("[convertToJavaData][type({}) 解析不掉 label({})]", type, label);
41 40 return null;
42 41 }
43 42 // 将 String 的 value 转换成对应的属性
44 43 Class<?> fieldClazz = contentProperty.getField().getType();
45   - return Convert.convert(fieldClazz, dictData.getValue());
  44 + return Convert.convert(fieldClazz, value);
46 45 }
47 46  
48 47 @Override
... ... @@ -56,13 +55,13 @@ public class DictConvert implements Converter&lt;Object&gt; {
56 55 // 使用字典格式化
57 56 String type = getType(contentProperty);
58 57 String value = String.valueOf(object);
59   - DictDataRespDTO dictData = DictFrameworkUtils.getDictDataFromCache(type, value);
60   - if (dictData == null) {
  58 + String label = DictFrameworkUtils.getDictDataLabel(type, value);
  59 + if (label == null) {
61 60 log.error("[convertToExcelData][type({}) 转换不了 label({})]", type, value);
62 61 return new CellData<>("");
63 62 }
64 63 // 生成 Excel 小表格
65   - return new CellData<>(dictData.getLabel());
  64 + return new CellData<>(label);
66 65 }
67 66  
68 67 private static String getType(ExcelContentProperty contentProperty) {
... ...
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/config/YudaoExtensionAutoConfiguration.java deleted
1   -package cn.iocoder.yudao.framework.extension.config;
2   -
3   -import cn.iocoder.yudao.framework.extension.core.ExtensionBootstrap;
4   -import cn.iocoder.yudao.framework.extension.core.context.ExtensionContext;
5   -import cn.iocoder.yudao.framework.extension.core.context.ExtensionContextHolder;
6   -import cn.iocoder.yudao.framework.extension.core.context.ExtensionExecutor;
7   -import cn.iocoder.yudao.framework.extension.core.factory.ExtensionFactory;
8   -import cn.iocoder.yudao.framework.extension.core.factory.ExtensionRegisterFactory;
9   -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
10   -import org.springframework.context.annotation.Bean;
11   -import org.springframework.context.annotation.Configuration;
12   -
13   -/**
14   - * @description 扩展点组件自动装配
15   - * @author Qingchen
16   - * @version 1.0.0
17   - * @date 2021-08-28 21:50
18   - * @class cn.iocoder.yudao.framework.extension.config.YudaoExtensionAutoConfiguration.java
19   - */
20   -@Configuration
21   -public class YudaoExtensionAutoConfiguration {
22   -
23   - /**
24   - * 组件初始化
25   - * @return
26   - */
27   - @Bean(initMethod = "init")
28   - @ConditionalOnMissingBean(ExtensionBootstrap.class)
29   - public ExtensionBootstrap bootstrap() {
30   - return new ExtensionBootstrap();
31   - }
32   -
33   - /**
34   - * 扩展点工厂
35   - * @return
36   - */
37   - @Bean
38   - @ConditionalOnMissingBean({ExtensionRegisterFactory.class, ExtensionFactory.class})
39   - public ExtensionRegisterFactory registerFactory() {
40   - return new ExtensionRegisterFactory();
41   - }
42   -
43   - /**
44   - * 扩展组件上下文对象
45   - * @return
46   - */
47   - @Bean
48   - @ConditionalOnMissingBean({ExtensionContextHolder.class, ExtensionContext.class})
49   - public ExtensionContextHolder context() {
50   - return new ExtensionContextHolder();
51   - }
52   -
53   - /**
54   - * 扩展组件执行器
55   - * @return
56   - */
57   - @Bean
58   - @ConditionalOnMissingBean(ExtensionExecutor.class)
59   - public ExtensionExecutor executor() {
60   - return new ExtensionExecutor();
61   - }
62   -}
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/BusinessScenario.java deleted
1   -package cn.iocoder.yudao.framework.extension.core;
2   -
3   -import javax.validation.constraints.NotNull;
4   -import java.io.Serializable;
5   -import java.util.StringJoiner;
6   -
7   -/**
8   - * @description 业务场景 = businessId + useCase + scenario, 用来标识系统中唯一的一个场景<br/>
9   - * @author Qingchen
10   - * @version 1.0.0
11   - * @date 2021-08-28 22:19
12   - * @class cn.iocoder.yudao.framework.extension.core.BusinessScenario.java
13   - */
14   -public class BusinessScenario implements Serializable {
15   -
16   - /**
17   - * 默认业务id
18   - */
19   - public final static String DEFAULT_BUSINESS_ID = "#defaultBusinessId#";
20   -
21   - /**
22   - * 默认用例
23   - */
24   - public final static String DEFAULT_USECASE = "#defaultUseCase#";
25   -
26   - /**
27   - * 默认场景
28   - */
29   - public final static String DEFAULT_SCENARIO = "#defaultScenario#";
30   -
31   - /**
32   - * 分隔符
33   - */
34   - private final static String DOT_SEPARATOR = ".";
35   -
36   - /**
37   - * 业务Id
38   - */
39   - private String businessId;
40   -
41   - /**
42   - * 用例
43   - */
44   - private String useCase;
45   -
46   - /**
47   - * 场景
48   - */
49   - private String scenario;
50   -
51   - public BusinessScenario() {
52   - this.businessId = DEFAULT_BUSINESS_ID;
53   - this.useCase = DEFAULT_USECASE;
54   - this.scenario = DEFAULT_SCENARIO;
55   - }
56   -
57   - public BusinessScenario(@NotNull String businessId, @NotNull String useCase, @NotNull String scenario) {
58   - this.businessId = businessId;
59   - this.useCase = useCase;
60   - this.scenario = scenario;
61   - }
62   -
63   - public BusinessScenario(@NotNull String scenario) {
64   - this();
65   - this.scenario = scenario;
66   - }
67   -
68   - public BusinessScenario(@NotNull String useCase, @NotNull String scenario) {
69   - this(DEFAULT_BUSINESS_ID, useCase, scenario);
70   - }
71   -
72   - public String getBusinessId() {
73   - return businessId;
74   - }
75   -
76   - public void setBusinessId(String businessId) {
77   - this.businessId = businessId;
78   - }
79   -
80   - public String getUseCase() {
81   - return useCase;
82   - }
83   -
84   - public void setUseCase(String useCase) {
85   - this.useCase = useCase;
86   - }
87   -
88   - public String getScenario() {
89   - return scenario;
90   - }
91   -
92   - public void setScenario(String scenario) {
93   - this.scenario = scenario;
94   - }
95   -
96   - /**
97   - * 构建业务场景
98   - * @param businessId
99   - * @param useCase
100   - * @param scenario
101   - * @return
102   - */
103   - public static BusinessScenario valueOf(@NotNull String businessId, @NotNull String useCase, @NotNull String scenario) {
104   - return new BusinessScenario(businessId, useCase, scenario);
105   - }
106   -
107   - /**
108   - * 构建业务场景
109   - * @param useCase
110   - * @param scenario
111   - * @return
112   - */
113   - public static BusinessScenario valueOf(@NotNull String useCase, @NotNull String scenario) {
114   - return new BusinessScenario(useCase, scenario);
115   - }
116   -
117   - /**
118   - * 构建业务场景
119   - * @param scenario
120   - * @return
121   - */
122   - public static BusinessScenario valueOf(@NotNull String scenario) {
123   - return new BusinessScenario(scenario);
124   - }
125   -
126   - /**
127   - * 业务场景唯一标识
128   - * @return
129   - */
130   - public String getUniqueIdentity(){
131   - return new StringJoiner(DOT_SEPARATOR).add(businessId).add(useCase).add(scenario).toString();
132   - }
133   -
134   - @Override
135   - public String toString() {
136   - return "BusinessScenario{" +
137   - "businessId='" + businessId + '\'' +
138   - ", useCase='" + useCase + '\'' +
139   - ", scenario='" + scenario + '\'' +
140   - '}';
141   - }
142   -}
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/ExtensionBootstrap.java deleted
1   -package cn.iocoder.yudao.framework.extension.core;
2   -
3   -import cn.iocoder.yudao.framework.extension.core.factory.ExtensionRegisterFactory;
4   -import org.springframework.beans.BeansException;
5   -import org.springframework.beans.factory.annotation.Autowired;
6   -import org.springframework.context.ApplicationContext;
7   -import org.springframework.context.ApplicationContextAware;
8   -
9   -import javax.annotation.PostConstruct;
10   -
11   -/**
12   - * @description
13   - * @author Qingchen
14   - * @version 1.0.0
15   - * @date 2021-08-29 00:18
16   - * @class cn.iocoder.yudao.framework.extension.core.ExtensionBootstrap.java
17   - */
18   -public class ExtensionBootstrap implements ApplicationContextAware {
19   -
20   - /**
21   - * spring 容器
22   - */
23   - private ApplicationContext applicationContext;
24   -
25   - @Autowired
26   - private ExtensionRegisterFactory registerFactory;
27   -
28   - /**
29   - * 初始化
30   - */
31   - @PostConstruct
32   - public void init() {
33   - registerFactory.setApplicationContext(applicationContext);
34   - registerFactory.register(null);
35   - }
36   -
37   - @Override
38   - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
39   - this.applicationContext = applicationContext;
40   - }
41   -}
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/context/AbstractComponentExecutor.java deleted
1   -package cn.iocoder.yudao.framework.extension.core.context;
2   -
3   -import cn.iocoder.yudao.framework.extension.core.BusinessScenario;
4   -import cn.iocoder.yudao.framework.extension.core.point.ExtensionPoint;
5   -
6   -import java.util.function.Consumer;
7   -import java.util.function.Function;
8   -
9   -/**
10   - * @description 执行器通用方法
11   - * @author Qingchen
12   - * @version 1.0.0
13   - * @date 2021-08-29 00:38
14   - * @class cn.iocoder.yudao.framework.extension.core.context.AbstractComponentExecutor.java
15   - */
16   -public abstract class AbstractComponentExecutor {
17   -
18   - /**
19   - * ("业务" + "用例" + "场景")执行扩展组件,并返回执行结果
20   - * @param targetClazz
21   - * @param businessId
22   - * @param useCase
23   - * @param scenario
24   - * @param function
25   - * @param <R>
26   - * @param <T>
27   - * @return
28   - */
29   - public <R, T extends ExtensionPoint> R execute(Class<T> targetClazz, String businessId, String useCase, String scenario, Function<T, R> function) {
30   - return execute(targetClazz, BusinessScenario.valueOf(businessId, useCase, scenario), function);
31   - }
32   -
33   -
34   - /**
35   - * ("用例" + "场景")执行扩展组件,并返回执行结果
36   - * @param targetClazz
37   - * @param useCase
38   - * @param scenario
39   - * @param function
40   - * @param <R>
41   - * @param <T>
42   - * @return
43   - */
44   - public <R, T extends ExtensionPoint> R execute(Class<T> targetClazz, String useCase, String scenario, Function<T, R> function) {
45   - return execute(targetClazz, BusinessScenario.valueOf(useCase, scenario), function);
46   - }
47   -
48   - /**
49   - * ("场景")执行扩展组件,并返回执行结果
50   - * @param targetClazz
51   - * @param scenario
52   - * @param function
53   - * @param <R>
54   - * @param <T>
55   - * @return
56   - */
57   - public <R, T extends ExtensionPoint> R execute(Class<T> targetClazz, String scenario, Function<T, R> function) {
58   - return execute(targetClazz, BusinessScenario.valueOf(scenario), function);
59   - }
60   -
61   - /**
62   - * 执行扩展组件,并返回执行结果
63   - * @param targetClazz
64   - * @param businessScenario
65   - * @param function
66   - * @param <R> Response Type
67   - * @param <T> Parameter Type
68   - * @return
69   - */
70   - public <R, T extends ExtensionPoint> R execute(Class<T> targetClazz, BusinessScenario businessScenario, Function<T, R> function) {
71   - T component = locateComponent(targetClazz, businessScenario);
72   - return function.apply(component);
73   - }
74   -
75   - /**
76   - * ("业务" + "用例" + "场景")执行扩展组件,适用于无返回值的业务
77   - * @param targetClazz
78   - * @param businessId
79   - * @param useCase
80   - * @param scenario
81   - * @param consumer
82   - * @param <T>
83   - */
84   - public <T extends ExtensionPoint> void accept(Class<T> targetClazz, String businessId, String useCase, String scenario, Consumer<T> consumer) {
85   - accept(targetClazz, BusinessScenario.valueOf(businessId, useCase, scenario), consumer);
86   - }
87   -
88   - /**
89   - * ("场景")执行扩展组件,适用于无返回值的业务
90   - * @param targetClazz
91   - * @param useCase
92   - * @param scenario
93   - * @param consumer
94   - * @param <T>
95   - */
96   - public <T extends ExtensionPoint> void accept(Class<T> targetClazz, String useCase, String scenario, Consumer<T> consumer) {
97   - accept(targetClazz, BusinessScenario.valueOf(useCase, scenario), consumer);
98   - }
99   -
100   - /**
101   - * ("场景")执行扩展组件,适用于无返回值的业务
102   - * @param targetClazz
103   - * @param scenario
104   - * @param consumer
105   - * @param <T>
106   - */
107   - public <T extends ExtensionPoint> void accept(Class<T> targetClazz, String scenario, Consumer<T> consumer) {
108   - accept(targetClazz, BusinessScenario.valueOf(scenario), consumer);
109   - }
110   -
111   - /**
112   - * 执行扩展组件,适用于无返回值的业务
113   - * @param targetClazz
114   - * @param businessScenario
115   - * @param consumer
116   - * @param <T> Parameter Type
117   - */
118   - public <T extends ExtensionPoint> void accept(Class<T> targetClazz, BusinessScenario businessScenario, Consumer<T> consumer) {
119   - T component = locateComponent(targetClazz, businessScenario);
120   - consumer.accept(component);
121   - }
122   -
123   - /**
124   - * 获取/定位扩展点组件
125   - * @param targetClazz
126   - * @param businessScenario
127   - * @param <C>
128   - * @return
129   - */
130   - protected abstract <C extends ExtensionPoint> C locateComponent(Class<C> targetClazz, BusinessScenario businessScenario);
131   -}
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/context/ExtensionContext.java deleted
1   -package cn.iocoder.yudao.framework.extension.core.context;
2   -
3   -import cn.iocoder.yudao.framework.extension.core.BusinessScenario;
4   -import cn.iocoder.yudao.framework.extension.core.point.ExtensionPoint;
5   -
6   -/**
7   - * @description 上下文,包含各个扩展点的相关操作
8   - * @author Qingchen
9   - * @version 1.0.0
10   - * @date 2021-08-28 22:15
11   - * @class cn.iocoder.yudao.framework.extension.core.context.ExtensionContext.java
12   - */
13   -public interface ExtensionContext {
14   -
15   - /**
16   - * 根据业务场景唯一标识获取扩展点组件实现类
17   - * @param businessId
18   - * @param useCase
19   - * @param scenario
20   - * @param clazz
21   - * @param <T>
22   - * @return
23   - */
24   - <T extends ExtensionPoint> T getPoint(String businessId, String useCase, String scenario, Class<T> clazz);
25   -
26   - /**
27   - * 根据("实例" + "场景")获取扩展点组件实现类,其中:业务id(businessId)= {@linkplain cn.iocoder.yudao.framework.extension.core.BusinessScenario.DEFAULT_BUSINESS_ID}
28   - * @param useCase
29   - * @param scenario
30   - * @param clazz
31   - * @param <T>
32   - * @return
33   - */
34   - <T extends ExtensionPoint> T getPoint(String useCase, String scenario, Class<T> clazz);
35   -
36   - /**
37   - * 根据("场景")获取扩展点组件实现类 <br/>
38   - * 其中:
39   - * 业务id(businessId)= {@linkplain cn.iocoder.yudao.framework.extension.core.BusinessScenario.DEFAULT_BUSINESS_ID}
40   - * 实例(useCase)= {@linkplain cn.iocoder.yudao.framework.extension.core.BusinessScenario.DEFAULT_USECASE}
41   - * @param scenario
42   - * @param clazz
43   - * @param <T>
44   - * @return
45   - */
46   - <T extends ExtensionPoint> T getPoint(String scenario, Class<T> clazz);
47   -
48   - /**
49   - * 根据业务场景唯一标识获取扩展点组件实现类
50   - * @param businessScenario
51   - * @param clazz
52   - * @param <T>
53   - * @return
54   - */
55   - <T extends ExtensionPoint> T getPoint(BusinessScenario businessScenario, Class<T> clazz);
56   -}
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/context/ExtensionContextHolder.java deleted
1   -package cn.iocoder.yudao.framework.extension.core.context;
2   -
3   -import cn.iocoder.yudao.framework.extension.core.BusinessScenario;
4   -import cn.iocoder.yudao.framework.extension.core.factory.ExtensionFactory;
5   -import cn.iocoder.yudao.framework.extension.core.point.ExtensionPoint;
6   -import lombok.extern.slf4j.Slf4j;
7   -import org.springframework.beans.factory.annotation.Autowired;
8   -import org.springframework.stereotype.Component;
9   -
10   -import javax.validation.constraints.NotNull;
11   -
12   -/**
13   - * @description 上下文及扩展点组件工厂的持有类
14   - * @author Qingchen
15   - * @version 1.0.0
16   - * @date 2021-08-29 00:29
17   - * @class cn.iocoder.yudao.framework.extension.core.context.ExtensionContextHolder.java
18   - */
19   -@Component
20   -@Slf4j
21   -public class ExtensionContextHolder implements ExtensionContext{
22   -
23   - @Autowired
24   - private ExtensionFactory factory;
25   -
26   - @Override
27   - public <T extends ExtensionPoint> T getPoint(@NotNull String businessId, @NotNull String useCase, @NotNull String scenario, Class<T> clazz) {
28   - return getPoint(BusinessScenario.valueOf(businessId, useCase, scenario), clazz);
29   - }
30   -
31   - @Override
32   - public <T extends ExtensionPoint> T getPoint(@NotNull String useCase, String scenario, Class<T> clazz) {
33   - return getPoint(BusinessScenario.valueOf(useCase, scenario), clazz);
34   - }
35   -
36   - @Override
37   - public <T extends ExtensionPoint> T getPoint(@NotNull String scenario, Class<T> clazz) {
38   - return getPoint(BusinessScenario.valueOf(scenario), clazz);
39   - }
40   -
41   - @Override
42   - public <T extends ExtensionPoint> T getPoint(@NotNull BusinessScenario businessScenario, Class<T> clazz) {
43   - return factory.get(businessScenario, clazz);
44   - }
45   -}
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/context/ExtensionExecutor.java deleted
1   -package cn.iocoder.yudao.framework.extension.core.context;
2   -
3   -import cn.iocoder.yudao.framework.extension.core.BusinessScenario;
4   -import cn.iocoder.yudao.framework.extension.core.point.ExtensionPoint;
5   -import lombok.extern.slf4j.Slf4j;
6   -import org.springframework.beans.factory.annotation.Autowired;
7   -import org.springframework.stereotype.Component;
8   -
9   -/**
10   - * @description 扩展组件执行器
11   - * @author Qingchen
12   - * @version 1.0.0
13   - * @date 2021-08-29 00:32
14   - * @class cn.iocoder.yudao.framework.extension.core.context.ExtensionExecutor.java
15   - */
16   -@Component
17   -@Slf4j
18   -public class ExtensionExecutor extends AbstractComponentExecutor{
19   -
20   - @Autowired
21   - private ExtensionContextHolder contextHolder;
22   -
23   -
24   - @Override
25   - protected <C extends ExtensionPoint> C locateComponent(Class<C> targetClazz, BusinessScenario businessScenario) {
26   - return contextHolder.getPoint(businessScenario, targetClazz);
27   - }
28   -}
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/factory/ExtensionDefinition.java deleted
1   -package cn.iocoder.yudao.framework.extension.core.factory;
2   -
3   -import cn.iocoder.yudao.framework.extension.core.BusinessScenario;
4   -import cn.iocoder.yudao.framework.extension.core.point.ExtensionPoint;
5   -import lombok.Getter;
6   -import lombok.Setter;
7   -
8   -import javax.validation.constraints.NotNull;
9   -import java.io.Serializable;
10   -import java.util.Objects;
11   -
12   -/**
13   - * @description 扩展定义(扩展坐标),标识唯一一个业务场景实现
14   - * @author Qingchen
15   - * @version 1.0.0
16   - * @date 2021-08-28 23:14
17   - * @class cn.iocoder.yudao.framework.extension.core.factory.ExtensionDefinition.java
18   - */
19   -@Setter
20   -@Getter
21   -public class ExtensionDefinition implements Serializable {
22   -
23   - /**
24   - * 业务场景唯一标识(id)
25   - */
26   - private String uniqueIdentify;
27   -
28   - /**
29   - * 扩展点实现类名称
30   - */
31   - private String extensionPointName;
32   -
33   - /**
34   - * 业务场景
35   - */
36   - private BusinessScenario businessScenario;
37   -
38   - /**
39   - * 扩展点实现类
40   - */
41   - private ExtensionPoint extensionPoint;
42   -
43   - /**
44   - * class
45   - */
46   - private Class extensionPointClass;
47   -
48   - public ExtensionDefinition() {
49   - }
50   -
51   - public ExtensionDefinition(@NotNull BusinessScenario businessScenario, @NotNull ExtensionPoint extensionPoint) {
52   - this.businessScenario = businessScenario;
53   - this.extensionPoint = extensionPoint;
54   - this.uniqueIdentify = this.businessScenario.getUniqueIdentity();
55   - this.extensionPointClass = this.extensionPoint.getClass();
56   - }
57   -
58   - /**
59   - * 构建definition
60   - * @param businessScenario
61   - * @param point
62   - * @return
63   - */
64   - public static ExtensionDefinition valueOf(@NotNull BusinessScenario businessScenario, @NotNull ExtensionPoint point) {
65   - return new ExtensionDefinition(businessScenario, point);
66   - }
67   -
68   - @Override
69   - public boolean equals(Object o) {
70   - if (this == o) {
71   - return true;
72   - }
73   - if (o == null || getClass() != o.getClass()) {
74   - return false;
75   - }
76   - ExtensionDefinition that = (ExtensionDefinition) o;
77   - return Objects.equals(uniqueIdentify, that.uniqueIdentify) && Objects.equals(extensionPointName, that.extensionPointName);
78   - }
79   -
80   - @Override
81   - public int hashCode() {
82   - final int prime = 31;
83   - int result = 1;
84   - result = prime * result + ((uniqueIdentify == null) ? 0 : uniqueIdentify.hashCode());
85   - result = prime * result + ((extensionPointName == null) ? 0 : extensionPointName.hashCode());
86   - return result;
87   - }
88   -
89   - @Override
90   - public String toString() {
91   - return "ExtensionDefinition{" +
92   - "uniqueIdentify='" + uniqueIdentify + '\'' +
93   - ", extensionPointName='" + extensionPointName + '\'' +
94   - '}';
95   - }
96   -}
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/factory/ExtensionFactory.java deleted
1   -package cn.iocoder.yudao.framework.extension.core.factory;
2   -
3   -import cn.iocoder.yudao.framework.extension.core.BusinessScenario;
4   -import cn.iocoder.yudao.framework.extension.core.point.ExtensionPoint;
5   -
6   -/**
7   - * @description 扩展点工厂
8   - * @author Qingchen
9   - * @version 1.0.0
10   - * @date 2021-08-28 23:04
11   - * @class cn.iocoder.yudao.framework.extension.core.factory.ExtensionFactory.java
12   - */
13   -public interface ExtensionFactory {
14   -
15   - /**
16   - * 注册所有扩展点实现类
17   - * @param basePackage
18   - */
19   - void register(String basePackage);
20   -
21   - /**
22   - * 根据业务场景获取指定类型的扩展点
23   - * @param businessScenario
24   - * @param clazz
25   - * @param <T>
26   - * @return
27   - */
28   - <T extends ExtensionPoint> T get(BusinessScenario businessScenario, Class<T> clazz);
29   -}
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/factory/ExtensionRegisterFactory.java deleted
1   -package cn.iocoder.yudao.framework.extension.core.factory;
2   -
3   -import cn.iocoder.yudao.framework.extension.core.BusinessScenario;
4   -import cn.iocoder.yudao.framework.extension.core.point.ExtensionPoint;
5   -import cn.iocoder.yudao.framework.extension.core.stereotype.Extension;
6   -import lombok.extern.slf4j.Slf4j;
7   -import org.springframework.aop.support.AopUtils;
8   -import org.springframework.context.ApplicationContext;
9   -import org.springframework.core.annotation.AnnotationUtils;
10   -import org.springframework.stereotype.Component;
11   -import org.springframework.util.ClassUtils;
12   -
13   -import javax.validation.constraints.NotNull;
14   -import java.util.Map;
15   -import java.util.concurrent.ConcurrentHashMap;
16   -
17   -/**
18   - * @description 注册工厂
19   - * @author Qingchen
20   - * @version 1.0.0
21   - * @date 2021-08-28 23:07
22   - * @class cn.iocoder.yudao.framework.extension.core.factory.ExtensionRegisterFactory.java
23   - */
24   -@Component
25   -@Slf4j
26   -public class ExtensionRegisterFactory implements ExtensionFactory {
27   -
28   - /**
29   - * spring ApplicationContext
30   - */
31   - private ApplicationContext applicationContext;
32   -
33   - /**
34   - * 扩展点实现类集合
35   - */
36   - private Map<String, ExtensionDefinition> registerExtensionBeans = new ConcurrentHashMap<>();
37   -
38   - @Override
39   - public void register(String basePackage) {
40   - final Map<String, Object> beans = applicationContext.getBeansWithAnnotation(Extension.class);
41   - if(beans == null || beans.isEmpty()) {
42   - return;
43   - }
44   -
45   - beans.values().forEach(point -> doRegister((ExtensionPoint) point));
46   - log.info("业务场景相关扩展点注册完成,注册数量: {}", registerExtensionBeans.size());
47   - }
48   -
49   - @Override
50   - public <T extends ExtensionPoint> T get(BusinessScenario businessScenario, Class<T> clazz) {
51   -
52   - final ExtensionDefinition definition = registerExtensionBeans.get(businessScenario.getUniqueIdentity());
53   - if(definition == null) {
54   - log.error("获取业务场景扩展点实现失败,失败原因:尚未定义该业务场景相关扩展点。{}", businessScenario);
55   - throw new RuntimeException("尚未定义该业务场景相关扩展点 [" + businessScenario + "]");
56   - }
57   -
58   - return (T) definition.getExtensionPoint();
59   - }
60   -
61   - /**
62   - * 注册扩展点
63   - * @param point
64   - */
65   - private void doRegister(@NotNull ExtensionPoint point) {
66   - Class<?> extensionClazz = point.getClass();
67   -
68   - if (AopUtils.isAopProxy(point)) {
69   - extensionClazz = ClassUtils.getUserClass(point);
70   - }
71   -
72   - Extension extension = AnnotationUtils.findAnnotation(extensionClazz, Extension.class);
73   - final BusinessScenario businessScenario = BusinessScenario.valueOf(extension.businessId(), extension.useCase(), extension.scenario());
74   - final ExtensionDefinition definition = ExtensionDefinition.valueOf(businessScenario, point);
75   - final ExtensionDefinition exist = registerExtensionBeans.get(businessScenario.getUniqueIdentity());
76   - if(exist != null && !exist.equals(definition)) {
77   - throw new RuntimeException("相同的业务场景重复注册了不同类型的扩展点实现 :【" + definition + "】【" + exist + "】");
78   - }
79   -
80   - registerExtensionBeans.put(businessScenario.getUniqueIdentity(), definition);
81   - }
82   -
83   - public void setApplicationContext(ApplicationContext applicationContext) {
84   - this.applicationContext = applicationContext;
85   - }
86   -}
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/package-info.java deleted
1   -/**
2   - * @description core 核心
3   - * @author Qingchen
4   - * @version 1.0.0
5   - * @date 2021-08-28 21:54
6   - * @class cn.iocoder.yudao.framework.extension.core.package-info.java
7   - */
8   -package cn.iocoder.yudao.framework.extension.core;
9 0 \ No newline at end of file
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/point/ExtensionPoint.java deleted
1   -package cn.iocoder.yudao.framework.extension.core.point;
2   -/**
3   - * @description 扩展点 <br/>
4   - * 表示一块逻辑在不同的业务有不同的实现,使用扩展点做接口申明,然后用{@linkplain cn.iocoder.yudao.framework.extension.core.stereotype.Extension}(扩展)去实现扩展点。
5   - * @author Qingchen
6   - * @version 1.0.0
7   - * @date 2021-08-28 22:06
8   - * @class cn.iocoder.yudao.framework.extension.core.point.ExtensionPoint.java
9   - */
10   -public interface ExtensionPoint {
11   -}
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/core/stereotype/Extension.java deleted
1   -package cn.iocoder.yudao.framework.extension.core.stereotype;
2   -
3   -import cn.iocoder.yudao.framework.extension.core.BusinessScenario;
4   -import org.springframework.stereotype.Component;
5   -
6   -import java.lang.annotation.*;
7   -
8   -/**
9   - * @description 表示带注释的类是“扩展组件”
10   - * @author Qingchen
11   - * @version 1.0.0
12   - * @date 2021-08-28 21:59
13   - * @class cn.iocoder.yudao.framework.extension.core.stereotype.Extension.java
14   - */
15   -@Inherited
16   -@Retention(RetentionPolicy.RUNTIME)
17   -@Target({ElementType.TYPE})
18   -@Component
19   -public @interface Extension {
20   -
21   - /**
22   - * 业务 <br/>
23   - * 一个自负盈亏的财务主体,比如tmall、淘宝和零售通就是三个不同的业务
24   - * @return
25   - */
26   - String businessId() default BusinessScenario.DEFAULT_BUSINESS_ID;
27   -
28   - /**
29   - * 用例 <br/>
30   - * 描述了用户和系统之间的互动,每个用例提供了一个或多个场景。比如,支付订单就是一个典型的用例。
31   - * @return
32   - */
33   - String useCase() default BusinessScenario.DEFAULT_USECASE;
34   -
35   - /**
36   - * 场景 <br/>
37   - * 场景也被称为用例的实例(Instance),包括用例所有的可能情况(正常的和异常的)。比如对于"订单支付"这个用例,就有“支付宝支付”、“银行卡支付”、"微信支付"等多个场景
38   - * @return
39   - */
40   - String scenario() default BusinessScenario.DEFAULT_SCENARIO;
41   -}
yudao-framework/yudao-spring-boot-starter-extension/src/main/java/cn/iocoder/yudao/framework/extension/package-info.java deleted
1   -/**
2   - * @description 扩展点组件
3   - * @author Qingchen
4   - * @version 1.0.0
5   - * @date 2021-08-28 14:35
6   - * @class cn.iocoder.yudao.framework.extension.package-info.java
7   - */
8   -package cn.iocoder.yudao.framework.extension;
9 0 \ No newline at end of file
yudao-framework/yudao-spring-boot-starter-extension/src/main/resources/META-INF/spring.factories deleted
1   -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
2   - cn.iocoder.yudao.framework.extension.config.YudaoExtensionAutoConfiguration
yudao-framework/yudao-spring-boot-starter-extension/src/test/java/cn/iocoder/yudao/framework/extension/Application.java deleted
1   -package cn.iocoder.yudao.framework.extension;
2   -
3   -import org.springframework.boot.SpringApplication;
4   -import org.springframework.boot.autoconfigure.SpringBootApplication;
5   -
6   -/**
7   - * @description Application
8   - * @author Qingchen
9   - * @version 1.0.0
10   - * @date 2021-08-30 10:32
11   - * @class cn.iocoder.yudao.framework.extension.Application.java
12   - */
13   -@SpringBootApplication
14   -public class Application {
15   -
16   - public static void main(String[] args) {
17   - SpringApplication.run(Application.class, args);
18   - }
19   -}
yudao-framework/yudao-spring-boot-starter-extension/src/test/java/cn/iocoder/yudao/framework/extension/ExtensionTest.java deleted
1   -package cn.iocoder.yudao.framework.extension;
2   -
3   -import cn.hutool.core.util.IdUtil;
4   -import cn.hutool.json.JSONUtil;
5   -import cn.iocoder.yudao.framework.extension.core.BusinessScenario;
6   -import cn.iocoder.yudao.framework.extension.core.context.ExtensionExecutor;
7   -import cn.iocoder.yudao.framework.extension.pay.PayExtensionPoint;
8   -import cn.iocoder.yudao.framework.extension.pay.command.TransactionsCommand;
9   -import cn.iocoder.yudao.framework.extension.pay.domain.TransactionsResult;
10   -import lombok.extern.slf4j.Slf4j;
11   -import org.junit.Assert;
12   -import org.junit.Test;
13   -import org.junit.runner.RunWith;
14   -import org.springframework.beans.factory.annotation.Autowired;
15   -import org.springframework.boot.test.context.SpringBootTest;
16   -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
17   -
18   -import java.math.BigDecimal;
19   -
20   -/**
21   - * @description
22   - * @author Qingchen
23   - * @version 1.0.0
24   - * @date 2021-08-30 10:30
25   - * @class cn.iocoder.yudao.framework.extension.ExtensionTest.java
26   - */
27   -@RunWith(SpringJUnit4ClassRunner.class)
28   -@SpringBootTest(classes = Application.class)
29   -@Slf4j
30   -public class ExtensionTest {
31   -
32   - @Autowired
33   - private ExtensionExecutor extensionExecutor;
34   -
35   - @Test
36   - public void unifiedOrder() {
37   - final BusinessScenario scenario = BusinessScenario.valueOf("pay", "jsapi", "wechat");
38   - final TransactionsCommand command = new TransactionsCommand(IdUtil.objectId(), new BigDecimal(105), "Image形象店-深圳腾大-QQ公仔", "https://www.weixin.qq.com/wxpay/pay.php");
39   - final TransactionsResult result = extensionExecutor.execute(PayExtensionPoint.class, scenario, extension -> extension.unifiedOrder(command));
40   - log.info("result is: {}", JSONUtil.toJsonStr(result));
41   - Assert.assertSame("wechat", result.getChannel());
42   - }
43   -}
yudao-framework/yudao-spring-boot-starter-extension/src/test/java/cn/iocoder/yudao/framework/extension/package-info.java deleted
1   -/**
2   - * @description
3   - * @author Qingchen
4   - * @version 1.0.0
5   - * @date 2021-08-30 10:25
6   - * @class cn.iocoder.yudao.framework.extension.package-info.java
7   - */
8   -package cn.iocoder.yudao.framework.extension;
9 0 \ No newline at end of file
yudao-framework/yudao-spring-boot-starter-extension/src/test/java/cn/iocoder/yudao/framework/extension/pay/PayExtensionPoint.java deleted
1   -package cn.iocoder.yudao.framework.extension.pay;
2   -
3   -import cn.iocoder.yudao.framework.extension.core.point.ExtensionPoint;
4   -import cn.iocoder.yudao.framework.extension.pay.command.TransactionsCommand;
5   -import cn.iocoder.yudao.framework.extension.pay.domain.TransactionsResult;
6   -
7   -/**
8   - * @description 支付操作接口
9   - * @author Qingchen
10   - * @version 1.0.0
11   - * @date 2021-08-30 10:35
12   - * @class cn.iocoder.yudao.framework.extension.pay.PayExtensionPoint.java
13   - */
14   -public interface PayExtensionPoint extends ExtensionPoint {
15   -
16   - /**
17   - * 统一下单:获取"预支付交易会话标识"
18   - * @param command
19   - * @return
20   - */
21   - TransactionsResult unifiedOrder(TransactionsCommand command);
22   -}
yudao-framework/yudao-spring-boot-starter-extension/src/test/java/cn/iocoder/yudao/framework/extension/pay/command/TransactionsCommand.java deleted
1   -package cn.iocoder.yudao.framework.extension.pay.command;
2   -
3   -import lombok.AllArgsConstructor;
4   -import lombok.Data;
5   -import lombok.NoArgsConstructor;
6   -
7   -import java.io.Serializable;
8   -import java.math.BigDecimal;
9   -
10   -/**
11   - * @description 下单请求
12   - * @author Qingchen
13   - * @version 1.0.0
14   - * @date 2021-08-30 10:48
15   - * @class cn.iocoder.yudao.framework.extension.pay.command.TransactionsCommand.java
16   - */
17   -@Data
18   -@NoArgsConstructor
19   -@AllArgsConstructor
20   -public class TransactionsCommand implements Serializable {
21   - /**
22   - * 订单编号
23   - */
24   - private String orderNo;
25   -
26   - /**
27   - * 支付金额
28   - */
29   - private BigDecimal amount;
30   -
31   - /**
32   - * 商品描述
33   - */
34   - private String productDescription;
35   -
36   - /**
37   - * 通知地址
38   - */
39   - private String notifyUrl;
40   -}
yudao-framework/yudao-spring-boot-starter-extension/src/test/java/cn/iocoder/yudao/framework/extension/pay/domain/TransactionsResult.java deleted
1   -package cn.iocoder.yudao.framework.extension.pay.domain;
2   -
3   -import lombok.*;
4   -
5   -import java.io.Serializable;
6   -
7   -/**
8   - * @description 下单: 预支付交易单返回结果
9   - * @author Qingchen
10   - * @version 1.0.0
11   - * @date 2021-08-30 10:43
12   - * @class cn.iocoder.yudao.framework.extension.pay.domain.TransactionsResult.java
13   - */
14   -@Data
15   -@AllArgsConstructor
16   -public class TransactionsResult implements Serializable {
17   -
18   - /**
19   - * 预支付交易会话标识
20   - */
21   - private String prepayId;
22   -
23   - /**
24   - * 订单编号
25   - */
26   - private String orderNo;
27   -
28   - /**
29   - * 系统内部支付单号
30   - */
31   - private String paymentNo;
32   -
33   - /**
34   - * 支付渠道:微信 or 支付宝
35   - */
36   - private String channel;
37   -
38   -
39   -}
yudao-framework/yudao-spring-boot-starter-extension/src/test/java/cn/iocoder/yudao/framework/extension/pay/impl/AlipayService.java deleted
1   -package cn.iocoder.yudao.framework.extension.pay.impl;
2   -
3   -import cn.hutool.core.util.IdUtil;
4   -import cn.hutool.json.JSONUtil;
5   -import cn.iocoder.yudao.framework.extension.core.stereotype.Extension;
6   -import cn.iocoder.yudao.framework.extension.pay.PayExtensionPoint;
7   -import cn.iocoder.yudao.framework.extension.pay.command.TransactionsCommand;
8   -import cn.iocoder.yudao.framework.extension.pay.domain.TransactionsResult;
9   -import lombok.extern.slf4j.Slf4j;
10   -
11   -/**
12   - * @description 微信 JSAPI 支付
13   - * @author Qingchen
14   - * @version 1.0.0
15   - * @date 2021-08-30 10:38
16   - * @class cn.iocoder.yudao.framework.extension.pay.impl.AlipayService.java
17   - */
18   -@Extension(businessId = "pay", useCase = "jsapi", scenario = "alipay")
19   -@Slf4j
20   -public class AlipayService implements PayExtensionPoint {
21   - @Override
22   - public TransactionsResult unifiedOrder(TransactionsCommand command) {
23   - log.info("微信 JSAPI 支付:{}", JSONUtil.toJsonStr(command));
24   - return new TransactionsResult("alipay26112221580621e9b071c00d9e093b0000", command.getOrderNo(), IdUtil.objectId(), "alipay");
25   - }
26   -}
yudao-framework/yudao-spring-boot-starter-extension/src/test/java/cn/iocoder/yudao/framework/extension/pay/impl/WechatPayService.java deleted
1   -package cn.iocoder.yudao.framework.extension.pay.impl;
2   -
3   -import cn.hutool.core.util.IdUtil;
4   -import cn.hutool.json.JSONUtil;
5   -import cn.iocoder.yudao.framework.extension.core.stereotype.Extension;
6   -import cn.iocoder.yudao.framework.extension.pay.PayExtensionPoint;
7   -import cn.iocoder.yudao.framework.extension.pay.command.TransactionsCommand;
8   -import cn.iocoder.yudao.framework.extension.pay.domain.TransactionsResult;
9   -import lombok.extern.slf4j.Slf4j;
10   -
11   -/**
12   - * @description 微信 JSAPI 支付
13   - * @author Qingchen
14   - * @version 1.0.0
15   - * @date 2021-08-30 10:37
16   - * @class cn.iocoder.yudao.framework.extension.pay.impl.WechatPayService.java
17   - */
18   -@Extension(businessId = "pay", useCase = "jsapi", scenario = "wechat")
19   -@Slf4j
20   -public class WechatPayService implements PayExtensionPoint {
21   - @Override
22   - public TransactionsResult unifiedOrder(TransactionsCommand command) {
23   - log.info("微信 JSAPI 支付:{}", JSONUtil.toJsonStr(command));
24   - return new TransactionsResult("wx26112221580621e9b071c00d9e093b0000", command.getOrderNo(), IdUtil.objectId(), "wechat");
25   - }
26   -}
yudao-framework/yudao-spring-boot-starter-extension/《芋道 Spring Boot 扩展点组件》.md deleted
1   -### 作用
2   -
3   -​ 为了解决同一个流程不同业务有不同处理逻辑而产生,减少代码中 if else 逻辑,降低代码的耦合性,通过统一的扩展形式来支撑业务的变化。
4   -
5   -### 原理
6   -
7   -​ https://blog.csdn.net/significantfrank/article/details/100074716
8   -
9   -
10   -
11   -### 使用介绍
12   -
13   -参考测试代码 `cn.iocoder.yudao.framework.extension.ExtensionTest`
14   -
15   -
16   -
17   -
18   -
19   -
yudao-framework/yudao-spring-boot-starter-monitor/pom.xml
... ... @@ -58,6 +58,12 @@
58 58 <artifactId>apm-toolkit-opentracing</artifactId>
59 59 </dependency>
60 60  
  61 + <!-- Micrometer 对 Prometheus 的支持 -->
  62 + <dependency>
  63 + <groupId>io.micrometer</groupId>
  64 + <artifactId>micrometer-registry-prometheus</artifactId>
  65 + </dependency>
  66 +
61 67 <dependency>
62 68 <groupId>de.codecentric</groupId>
63 69 <artifactId>spring-boot-admin-starter-client</artifactId> <!-- 实现 Spring Boot Admin Server 服务端 -->
... ...
yudao-framework/yudao-spring-boot-starter-monitor/src/main/java/cn/iocoder/yudao/framework/tracer/config/YudaoMetricsAutoConfiguration.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.tracer.config;
  2 +
  3 +import io.micrometer.core.instrument.MeterRegistry;
  4 +import org.springframework.beans.factory.annotation.Value;
  5 +import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
  6 +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
  7 +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  8 +import org.springframework.context.annotation.Bean;
  9 +import org.springframework.context.annotation.Configuration;
  10 +
  11 +/**
  12 + * Metrics 配置类
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +@Configuration
  17 +@ConditionalOnClass({MeterRegistryCustomizer.class})
  18 +@ConditionalOnProperty(prefix = "yudao.metrics", value = "enable", matchIfMissing = true) // 允许使用 yudao.metrics.enable=false 禁用 Metrics
  19 +public class YudaoMetricsAutoConfiguration {
  20 +
  21 + @Bean
  22 + public MeterRegistryCustomizer<MeterRegistry> metricsCommonTags(
  23 + @Value("${spring.application.name}") String applicationName) {
  24 + return registry -> registry.config().commonTags("application", applicationName);
  25 + }
  26 +
  27 +}
... ...
yudao-framework/yudao-spring-boot-starter-monitor/src/main/resources/META-INF/spring.factories
1 1 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
2   - cn.iocoder.yudao.framework.tracer.config.YudaoTracerAutoConfiguration
  2 + cn.iocoder.yudao.framework.tracer.config.YudaoTracerAutoConfiguration,\
  3 + cn.iocoder.yudao.framework.tracer.config.YudaoMetricsAutoConfiguration
... ...
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/SecurityProperties.java
... ... @@ -16,18 +16,18 @@ public class SecurityProperties {
16 16 * HTTP 请求时,访问令牌的请求 Header
17 17 */
18 18 @NotEmpty(message = "Token Header 不能为空")
19   - private String tokenHeader;
  19 + private String tokenHeader = "Authorization";
20 20  
21 21 /**
22 22 * mock 模式的开关
23 23 */
24 24 @NotNull(message = "mock 模式的开关不能为空")
25   - private Boolean mockEnable;
  25 + private Boolean mockEnable = false;
26 26 /**
27 27 * mock 模式的密钥
28 28 * 一定要配置密钥,保证安全性
29 29 */
30 30 @NotEmpty(message = "mock 模式的密钥不能为空") // 这里设置了一个默认值,因为实际上只有 mockEnable 为 true 时才需要配置。
31   - private String mockSecret = "yudaoyuanma";
  31 + private String mockSecret = "test";
32 32  
33 33 }
... ...
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoSecurityAutoConfiguration.java
... ... @@ -8,7 +8,7 @@ import cn.iocoder.yudao.framework.security.core.handler.AuthenticationEntryPoint
8 8 import cn.iocoder.yudao.framework.security.core.service.SecurityFrameworkService;
9 9 import cn.iocoder.yudao.framework.security.core.service.SecurityFrameworkServiceImpl;
10 10 import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler;
11   -import cn.iocoder.yudao.module.system.api.auth.OAuth2TokenApi;
  11 +import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi;
12 12 import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
13 13 import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
14 14 import org.springframework.boot.context.properties.EnableConfigurationProperties;
... ... @@ -81,7 +81,7 @@ public class YudaoSecurityAutoConfiguration {
81 81 return new TokenAuthenticationFilter(securityProperties, globalExceptionHandler, oauth2TokenApi);
82 82 }
83 83  
84   - @Bean("ss") // 使用 Spring Security 的缩写,方便食用
  84 + @Bean("ss") // 使用 Spring Security 的缩写,方便使用
85 85 public SecurityFrameworkService securityFrameworkService(PermissionApi permissionApi) {
86 86 return new SecurityFrameworkServiceImpl(permissionApi);
87 87 }
... ...
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/filter/TokenAuthenticationFilter.java
... ... @@ -10,8 +10,8 @@ import cn.iocoder.yudao.framework.security.core.LoginUser;
10 10 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
11 11 import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler;
12 12 import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
13   -import cn.iocoder.yudao.module.system.api.auth.OAuth2TokenApi;
14   -import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenCheckRespDTO;
  13 +import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi;
  14 +import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenCheckRespDTO;
15 15 import lombok.RequiredArgsConstructor;
16 16 import org.springframework.security.access.AccessDeniedException;
17 17 import org.springframework.web.filter.OncePerRequestFilter;
... ...
yudao-framework/yudao-spring-boot-starter-web/pom.xml
... ... @@ -53,6 +53,13 @@
53 53 <scope>provided</scope> <!-- 设置为 provided,主要是 GlobalExceptionHandler 使用 -->
54 54 </dependency>
55 55  
  56 + <!-- 业务组件 -->
  57 + <dependency>
  58 + <groupId>cn.iocoder.boot</groupId>
  59 + <artifactId>yudao-module-infra-api</artifactId> <!-- 需要使用它,进行操作日志的记录 -->
  60 + <version>${revision}</version>
  61 + </dependency>
  62 +
56 63 <!-- 服务保障相关 -->
57 64 <dependency>
58 65 <groupId>io.github.resilience4j</groupId>
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/config/YudaoApiLogAutoConfiguration.java
... ... @@ -2,11 +2,17 @@ package cn.iocoder.yudao.framework.apilog.config;
2 2  
3 3 import cn.iocoder.yudao.framework.apilog.core.filter.ApiAccessLogFilter;
4 4 import cn.iocoder.yudao.framework.apilog.core.service.ApiAccessLogFrameworkService;
  5 +import cn.iocoder.yudao.framework.apilog.core.service.ApiAccessLogFrameworkServiceImpl;
  6 +import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkService;
  7 +import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkServiceImpl;
  8 +import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
5 9 import cn.iocoder.yudao.framework.web.config.WebProperties;
6 10 import cn.iocoder.yudao.framework.web.config.YudaoWebAutoConfiguration;
7   -import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
  11 +import cn.iocoder.yudao.module.infra.api.logger.ApiAccessLogApi;
  12 +import cn.iocoder.yudao.module.infra.api.logger.ApiErrorLogApi;
8 13 import org.springframework.beans.factory.annotation.Value;
9 14 import org.springframework.boot.autoconfigure.AutoConfigureAfter;
  15 +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
10 16 import org.springframework.boot.web.servlet.FilterRegistrationBean;
11 17 import org.springframework.context.annotation.Bean;
12 18 import org.springframework.context.annotation.Configuration;
... ... @@ -17,10 +23,21 @@ import javax.servlet.Filter;
17 23 @AutoConfigureAfter(YudaoWebAutoConfiguration.class)
18 24 public class YudaoApiLogAutoConfiguration {
19 25  
  26 + @Bean
  27 + public ApiAccessLogFrameworkService apiAccessLogFrameworkService(ApiAccessLogApi apiAccessLogApi) {
  28 + return new ApiAccessLogFrameworkServiceImpl(apiAccessLogApi);
  29 + }
  30 +
  31 + @Bean
  32 + public ApiErrorLogFrameworkService apiErrorLogFrameworkService(ApiErrorLogApi apiErrorLogApi) {
  33 + return new ApiErrorLogFrameworkServiceImpl(apiErrorLogApi);
  34 + }
  35 +
20 36 /**
21 37 * 创建 ApiAccessLogFilter Bean,记录 API 请求日志
22 38 */
23 39 @Bean
  40 + @ConditionalOnProperty(prefix = "yudao.access-log", value = "enable", matchIfMissing = true) // 允许使用 yudao.access-log.enable=false 禁用访问日志
24 41 public FilterRegistrationBean<ApiAccessLogFilter> apiAccessLogFilter(WebProperties webProperties,
25 42 @Value("${spring.application.name}") String applicationName,
26 43 ApiAccessLogFrameworkService apiAccessLogFrameworkService) {
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/core/filter/ApiAccessLogFilter.java
... ... @@ -3,8 +3,8 @@ package cn.iocoder.yudao.framework.apilog.core.filter;
3 3 import cn.hutool.core.exceptions.ExceptionUtil;
4 4 import cn.hutool.core.map.MapUtil;
5 5 import cn.hutool.extra.servlet.ServletUtil;
  6 +import cn.iocoder.yudao.framework.apilog.core.service.ApiAccessLog;
6 7 import cn.iocoder.yudao.framework.apilog.core.service.ApiAccessLogFrameworkService;
7   -import cn.iocoder.yudao.framework.apilog.core.service.dto.ApiAccessLogCreateReqDTO;
8 8 import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
9 9 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
10 10 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
... ... @@ -66,16 +66,16 @@ public class ApiAccessLogFilter extends ApiRequestFilter {
66 66  
67 67 private void createApiAccessLog(HttpServletRequest request, Date beginTime,
68 68 Map<String, String> queryString, String requestBody, Exception ex) {
69   - ApiAccessLogCreateReqDTO accessLog = new ApiAccessLogCreateReqDTO();
  69 + ApiAccessLog accessLog = new ApiAccessLog();
70 70 try {
71 71 this.buildApiAccessLogDTO(accessLog, request, beginTime, queryString, requestBody, ex);
72   - apiAccessLogFrameworkService.createApiAccessLogAsync(accessLog);
  72 + apiAccessLogFrameworkService.createApiAccessLog(accessLog);
73 73 } catch (Throwable th) {
74 74 log.error("[createApiAccessLog][url({}) log({}) 发生异常]", request.getRequestURI(), toJsonString(accessLog), th);
75 75 }
76 76 }
77 77  
78   - private void buildApiAccessLogDTO(ApiAccessLogCreateReqDTO accessLog, HttpServletRequest request, Date beginTime,
  78 + private void buildApiAccessLogDTO(ApiAccessLog accessLog, HttpServletRequest request, Date beginTime,
79 79 Map<String, String> queryString, String requestBody, Exception ex) {
80 80 // 处理用户信息
81 81 accessLog.setUserId(WebFrameworkUtils.getLoginUserId(request));
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/core/service/ApiAccessLog.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.apilog.core.service;
  2 +
  3 +import lombok.Data;
  4 +
  5 +import javax.validation.constraints.NotNull;
  6 +import java.util.Date;
  7 +
  8 +/**
  9 + * API 访问日志
  10 + *
  11 + * @author 芋道源码
  12 + */
  13 +@Data
  14 +public class ApiAccessLog {
  15 +
  16 + /**
  17 + * 链路追踪编号
  18 + */
  19 + private String traceId;
  20 + /**
  21 + * 用户编号
  22 + */
  23 + private Long userId;
  24 + /**
  25 + * 用户类型
  26 + */
  27 + private Integer userType;
  28 + /**
  29 + * 应用名
  30 + */
  31 + @NotNull(message = "应用名不能为空")
  32 + private String applicationName;
  33 +
  34 + /**
  35 + * 请求方法名
  36 + */
  37 + @NotNull(message = "http 请求方法不能为空")
  38 + private String requestMethod;
  39 + /**
  40 + * 访问地址
  41 + */
  42 + @NotNull(message = "访问地址不能为空")
  43 + private String requestUrl;
  44 + /**
  45 + * 请求参数
  46 + */
  47 + @NotNull(message = "请求参数不能为空")
  48 + private String requestParams;
  49 + /**
  50 + * 用户 IP
  51 + */
  52 + @NotNull(message = "ip 不能为空")
  53 + private String userIp;
  54 + /**
  55 + * 浏览器 UA
  56 + */
  57 + @NotNull(message = "User-Agent 不能为空")
  58 + private String userAgent;
  59 +
  60 + /**
  61 + * 开始请求时间
  62 + */
  63 + @NotNull(message = "开始请求时间不能为空")
  64 + private Date beginTime;
  65 + /**
  66 + * 结束请求时间
  67 + */
  68 + @NotNull(message = "结束请求时间不能为空")
  69 + private Date endTime;
  70 + /**
  71 + * 执行时长,单位:毫秒
  72 + */
  73 + @NotNull(message = "执行时长不能为空")
  74 + private Integer duration;
  75 + /**
  76 + * 结果码
  77 + */
  78 + @NotNull(message = "错误码不能为空")
  79 + private Integer resultCode;
  80 + /**
  81 + * 结果提示
  82 + */
  83 + private String resultMsg;
  84 +
  85 +}
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/core/service/ApiAccessLogFrameworkService.java
1 1 package cn.iocoder.yudao.framework.apilog.core.service;
2 2  
3   -import cn.iocoder.yudao.framework.apilog.core.service.dto.ApiAccessLogCreateReqDTO;
4   -
5   -import javax.validation.Valid;
6   -
7 3 /**
8 4 * API 访问日志 Framework Service 接口
9 5 *
... ... @@ -14,8 +10,8 @@ public interface ApiAccessLogFrameworkService {
14 10 /**
15 11 * 创建 API 访问日志
16 12 *
17   - * @param createDTO 创建信息
  13 + * @param apiAccessLog API 访问日志
18 14 */
19   - void createApiAccessLogAsync(@Valid ApiAccessLogCreateReqDTO createDTO);
  15 + void createApiAccessLog(ApiAccessLog apiAccessLog);
20 16  
21 17 }
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/core/service/ApiAccessLogFrameworkServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.apilog.core.service;
  2 +
  3 +import cn.hutool.core.bean.BeanUtil;
  4 +import cn.iocoder.yudao.module.infra.api.logger.ApiAccessLogApi;
  5 +import cn.iocoder.yudao.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO;
  6 +import lombok.RequiredArgsConstructor;
  7 +import org.springframework.scheduling.annotation.Async;
  8 +
  9 +/**
  10 + * API 访问日志 Framework Service 实现类
  11 + *
  12 + * 基于 {@link ApiAccessLogApi} 服务,记录访问日志
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +@RequiredArgsConstructor
  17 +public class ApiAccessLogFrameworkServiceImpl implements ApiAccessLogFrameworkService {
  18 +
  19 + private final ApiAccessLogApi apiAccessLogApi;
  20 +
  21 + @Override
  22 + @Async
  23 + public void createApiAccessLog(ApiAccessLog apiAccessLog) {
  24 + ApiAccessLogCreateReqDTO reqDTO = BeanUtil.copyProperties(apiAccessLog, ApiAccessLogCreateReqDTO.class);
  25 + apiAccessLogApi.createApiAccessLog(reqDTO);
  26 + }
  27 +
  28 +}
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/core/service/ApiErrorLog.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.apilog.core.service;
  2 +
  3 +import lombok.Data;
  4 +
  5 +import javax.validation.constraints.NotNull;
  6 +import java.util.Date;
  7 +
  8 +/**
  9 + * API 错误日志
  10 + *
  11 + * @author 芋道源码
  12 + */
  13 +@Data
  14 +public class ApiErrorLog {
  15 +
  16 + /**
  17 + * 链路编号
  18 + */
  19 + private String traceId;
  20 + /**
  21 + * 账号编号
  22 + */
  23 + private Long userId;
  24 + /**
  25 + * 用户类型
  26 + */
  27 + private Integer userType;
  28 + /**
  29 + * 应用名
  30 + */
  31 + @NotNull(message = "应用名不能为空")
  32 + private String applicationName;
  33 +
  34 + /**
  35 + * 请求方法名
  36 + */
  37 + @NotNull(message = "http 请求方法不能为空")
  38 + private String requestMethod;
  39 + /**
  40 + * 访问地址
  41 + */
  42 + @NotNull(message = "访问地址不能为空")
  43 + private String requestUrl;
  44 + /**
  45 + * 请求参数
  46 + */
  47 + @NotNull(message = "请求参数不能为空")
  48 + private String requestParams;
  49 + /**
  50 + * 用户 IP
  51 + */
  52 + @NotNull(message = "ip 不能为空")
  53 + private String userIp;
  54 + /**
  55 + * 浏览器 UA
  56 + */
  57 + @NotNull(message = "User-Agent 不能为空")
  58 + private String userAgent;
  59 +
  60 + /**
  61 + * 异常时间
  62 + */
  63 + @NotNull(message = "异常时间不能为空")
  64 + private Date exceptionTime;
  65 + /**
  66 + * 异常名
  67 + */
  68 + @NotNull(message = "异常名不能为空")
  69 + private String exceptionName;
  70 + /**
  71 + * 异常发生的类全名
  72 + */
  73 + @NotNull(message = "异常发生的类全名不能为空")
  74 + private String exceptionClassName;
  75 + /**
  76 + * 异常发生的类文件
  77 + */
  78 + @NotNull(message = "异常发生的类文件不能为空")
  79 + private String exceptionFileName;
  80 + /**
  81 + * 异常发生的方法名
  82 + */
  83 + @NotNull(message = "异常发生的方法名不能为空")
  84 + private String exceptionMethodName;
  85 + /**
  86 + * 异常发生的方法所在行
  87 + */
  88 + @NotNull(message = "异常发生的方法所在行不能为空")
  89 + private Integer exceptionLineNumber;
  90 + /**
  91 + * 异常的栈轨迹异常的栈轨迹
  92 + */
  93 + @NotNull(message = "异常的栈轨迹不能为空")
  94 + private String exceptionStackTrace;
  95 + /**
  96 + * 异常导致的根消息
  97 + */
  98 + @NotNull(message = "异常导致的根消息不能为空")
  99 + private String exceptionRootCauseMessage;
  100 + /**
  101 + * 异常导致的消息
  102 + */
  103 + @NotNull(message = "异常导致的消息不能为空")
  104 + private String exceptionMessage;
  105 +
  106 +
  107 +}
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/core/service/ApiErrorLogFrameworkService.java
1 1 package cn.iocoder.yudao.framework.apilog.core.service;
2 2  
3   -import cn.iocoder.yudao.framework.apilog.core.service.dto.ApiErrorLogCreateReqDTO;
4   -
5   -import javax.validation.Valid;
6   -
7 3 /**
8 4 * API 错误日志 Framework Service 接口
9 5 *
... ... @@ -14,8 +10,8 @@ public interface ApiErrorLogFrameworkService {
14 10 /**
15 11 * 创建 API 错误日志
16 12 *
17   - * @param createDTO 创建信息
  13 + * @param apiErrorLog API 错误日志
18 14 */
19   - void createApiErrorLogAsync(@Valid ApiErrorLogCreateReqDTO createDTO);
  15 + void createApiErrorLog(ApiErrorLog apiErrorLog);
20 16  
21 17 }
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/core/service/ApiErrorLogFrameworkServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.apilog.core.service;
  2 +
  3 +import cn.hutool.core.bean.BeanUtil;
  4 +import cn.iocoder.yudao.module.infra.api.logger.ApiErrorLogApi;
  5 +import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO;
  6 +import lombok.RequiredArgsConstructor;
  7 +import org.springframework.scheduling.annotation.Async;
  8 +
  9 +/**
  10 + * API 错误日志 Framework Service 实现类
  11 + *
  12 + * 基于 {@link ApiErrorLogApi} 服务,记录错误日志
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +@RequiredArgsConstructor
  17 +public class ApiErrorLogFrameworkServiceImpl implements ApiErrorLogFrameworkService {
  18 +
  19 + private final ApiErrorLogApi apiErrorLogApi;
  20 +
  21 + @Override
  22 + @Async
  23 + public void createApiErrorLog(ApiErrorLog apiErrorLog) {
  24 + ApiErrorLogCreateReqDTO reqDTO = BeanUtil.copyProperties(apiErrorLog, ApiErrorLogCreateReqDTO.class);
  25 + apiErrorLogApi.createApiErrorLog(reqDTO);
  26 + }
  27 +
  28 +}
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java
1 1 package cn.iocoder.yudao.framework.swagger.config;
2 2  
  3 +import cn.iocoder.yudao.framework.swagger.core.SpringFoxHandlerProviderBeanPostProcessor;
3 4 import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
4 5 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
5   -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
6 6 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
7 7 import org.springframework.boot.context.properties.EnableConfigurationProperties;
8 8 import org.springframework.context.annotation.Bean;
... ... @@ -21,6 +21,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
21 21 import java.util.Collections;
22 22 import java.util.List;
23 23  
  24 +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID;
24 25 import static springfox.documentation.builders.RequestHandlerSelectors.basePackage;
25 26  
26 27 /**
... ... @@ -38,27 +39,27 @@ import static springfox.documentation.builders.RequestHandlerSelectors.basePacka
38 39 public class YudaoSwaggerAutoConfiguration {
39 40  
40 41 @Bean
41   - @ConditionalOnMissingBean
42   - public SwaggerProperties swaggerProperties() {
43   - return new SwaggerProperties();
  42 + public SpringFoxHandlerProviderBeanPostProcessor springFoxHandlerProviderBeanPostProcessor() {
  43 + return new SpringFoxHandlerProviderBeanPostProcessor();
44 44 }
45 45  
46 46 @Bean
47   - public Docket createRestApi() {
48   - SwaggerProperties properties = swaggerProperties();
  47 + public Docket createRestApi(SwaggerProperties properties) {
49 48 // 创建 Docket 对象
50 49 return new Docket(DocumentationType.SWAGGER_2)
51   - // 用来创建该 API 的基本信息,展示在文档的页面中(自定义展示的信息)
  50 + // ① 用来创建该 API 的基本信息,展示在文档的页面中(自定义展示的信息)
52 51 .apiInfo(apiInfo(properties))
53   - // 设置扫描指定 package 包下的
  52 + // ② 设置扫描指定 package 包下的
54 53 .select()
55 54 .apis(basePackage(properties.getBasePackage()))
56   -// .apis(basePackage("cn.iocoder.yudao.module.infra")) // 可用于 swagger 无法展示时使用
  55 +// .apis(basePackage("cn.iocoder.yudao.module.system")) // 可用于 swagger 无法展示时使用
57 56 .paths(PathSelectors.any())
58 57 .build()
  58 + // ③ 安全上下文(认证)
59 59 .securitySchemes(securitySchemes())
60   - .globalRequestParameters(globalRequestParameters())
61   - .securityContexts(securityContexts());
  60 + .securityContexts(securityContexts())
  61 + // ④ 全局参数(多租户 header)
  62 + .globalRequestParameters(globalRequestParameters());
62 63 }
63 64  
64 65 // ========== apiInfo ==========
... ... @@ -93,6 +94,7 @@ public class YudaoSwaggerAutoConfiguration {
93 94 private static List<SecurityContext> securityContexts() {
94 95 return Collections.singletonList(SecurityContext.builder()
95 96 .securityReferences(securityReferences())
  97 + // 通过 PathSelectors.regex("^(?!auth).*$"),排除包含 "auth" 的接口不需要使用securitySchemes
96 98 .forPaths(PathSelectors.regex("^(?!auth).*$"))
97 99 .build());
98 100 }
... ... @@ -108,7 +110,8 @@ public class YudaoSwaggerAutoConfiguration {
108 110 // ========== globalRequestParameters ==========
109 111  
110 112 private static List<RequestParameter> globalRequestParameters() {
111   - RequestParameterBuilder tenantParameter = new RequestParameterBuilder().name("tenant-id").description("租户编号")
  113 + RequestParameterBuilder tenantParameter = new RequestParameterBuilder()
  114 + .name(HEADER_TENANT_ID).description("租户编号")
112 115 .in(ParameterType.HEADER).example(new ExampleBuilder().value(1L).build());
113 116 return Collections.singletonList(tenantParameter.build());
114 117 }
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/core/SpringFoxHandlerProviderBeanPostProcessor.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.swagger.core;
  2 +
  3 +import cn.hutool.core.util.ReflectUtil;
  4 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  5 +import org.springframework.beans.BeansException;
  6 +import org.springframework.beans.factory.config.BeanPostProcessor;
  7 +import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
  8 +import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider;
  9 +import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
  10 +
  11 +import java.util.List;
  12 +
  13 +/**
  14 + * 解决 SpringFox 与 SpringBoot 2.6.x 不兼容的问题
  15 + * 该问题对应的 issue 为 https://github.com/springfox/springfox/issues/3462
  16 + *
  17 + * @author 芋道源码
  18 + */
  19 +public class SpringFoxHandlerProviderBeanPostProcessor implements BeanPostProcessor {
  20 +
  21 + @Override
  22 + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  23 + if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
  24 + customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
  25 + }
  26 + return bean;
  27 + }
  28 +
  29 + private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
  30 + // 移除,只保留 patternParser
  31 + List<T> copy = CollectionUtils.filterList(mappings, mapping -> mapping.getPatternParser() == null);
  32 + // 添加到 mappings 中
  33 + mappings.clear();
  34 + mappings.addAll(copy);
  35 + }
  36 +
  37 + @SuppressWarnings("unchecked")
  38 + private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
  39 + return (List<RequestMappingInfoHandlerMapping>)
  40 + ReflectUtil.getFieldValue(bean, "handlerMappings");
  41 + }
  42 +
  43 +}
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/WebProperties.java
1 1 package cn.iocoder.yudao.framework.web.config;
2 2  
  3 +import lombok.AllArgsConstructor;
3 4 import lombok.Data;
  5 +import lombok.NoArgsConstructor;
4 6 import org.springframework.boot.context.properties.ConfigurationProperties;
5 7 import org.springframework.validation.annotation.Validated;
6 8 import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
... ... @@ -15,14 +17,16 @@ import javax.validation.constraints.NotNull;
15 17 public class WebProperties {
16 18  
17 19 @NotNull(message = "APP API 不能为空")
18   - private Api appApi;
  20 + private Api appApi = new Api("/app-api", "**.controller.app.**");
19 21 @NotNull(message = "Admin API 不能为空")
20   - private Api adminApi;
  22 + private Api adminApi = new Api("/admin-api", "**.controller.admin.**");
21 23  
22 24 @NotNull(message = "Admin UI 不能为空")
23 25 private Ui adminUi;
24 26  
25 27 @Data
  28 + @AllArgsConstructor
  29 + @NoArgsConstructor
26 30 @Valid
27 31 public static class Api {
28 32  
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java
... ... @@ -3,14 +3,14 @@ package cn.iocoder.yudao.framework.web.core.handler;
3 3 import cn.hutool.core.exceptions.ExceptionUtil;
4 4 import cn.hutool.core.map.MapUtil;
5 5 import cn.hutool.extra.servlet.ServletUtil;
  6 +import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLog;
  7 +import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkService;
6 8 import cn.iocoder.yudao.framework.common.exception.ServiceException;
7 9 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
8   -import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkService;
9   -import cn.iocoder.yudao.framework.apilog.core.service.dto.ApiErrorLogCreateReqDTO;
10   -import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
11   -import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
12 10 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  11 +import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
13 12 import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
  13 +import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
14 14 import io.github.resilience4j.ratelimiter.RequestNotPermitted;
15 15 import lombok.AllArgsConstructor;
16 16 import lombok.extern.slf4j.Slf4j;
... ... @@ -229,18 +229,18 @@ public class GlobalExceptionHandler {
229 229  
230 230 private void createExceptionLog(HttpServletRequest req, Throwable e) {
231 231 // 插入错误日志
232   - ApiErrorLogCreateReqDTO errorLog = new ApiErrorLogCreateReqDTO();
  232 + ApiErrorLog errorLog = new ApiErrorLog();
233 233 try {
234 234 // 初始化 errorLog
235 235 initExceptionLog(errorLog, req, e);
236 236 // 执行插入 errorLog
237   - apiErrorLogFrameworkService.createApiErrorLogAsync(errorLog);
  237 + apiErrorLogFrameworkService.createApiErrorLog(errorLog);
238 238 } catch (Throwable th) {
239 239 log.error("[createExceptionLog][url({}) log({}) 发生异常]", req.getRequestURI(), JsonUtils.toJsonString(errorLog), th);
240 240 }
241 241 }
242 242  
243   - private void initExceptionLog(ApiErrorLogCreateReqDTO errorLog, HttpServletRequest request, Throwable e) {
  243 + private void initExceptionLog(ApiErrorLog errorLog, HttpServletRequest request, Throwable e) {
244 244 // 处理用户信息
245 245 errorLog.setUserId(WebFrameworkUtils.getLoginUserId(request));
246 246 errorLog.setUserType(WebFrameworkUtils.getLoginUserType(request));
... ...