Commit 613eef375805e282ee90b3c25ff0ec977c4deb8d
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 | -| 登录 & 首页 |  |  |  | | |
| 196 | -| 用户 |  |  | - | | |
| 197 | -| 租户 & 套餐 |  |  | - | | |
| 198 | -| 部门 & 岗位 |  |  | - | | |
| 199 | -| 菜单 & 角色 |  |  | - | | |
| 200 | -| 审计日志 |  |  | - | | |
| 201 | -| 短信 |  |  |  | | |
| 202 | -| 字典 |  |  | - | | |
| 203 | -| 错误码 & 通知 |  |  | - | | |
| 195 | +| 登录 & 首页 |  |  |  | | |
| 196 | +| 用户 |  |  | - | | |
| 197 | +| 租户 & 套餐 |  |  | - | | |
| 198 | +| 部门 & 岗位 |  |  | - | | |
| 199 | +| 菜单 & 角色 |  |  | - | | |
| 200 | +| 审计日志 |  |  | - | | |
| 201 | +| 短信 |  |  |  | | |
| 202 | +| 字典 |  |  | - | | |
| 203 | +| 错误码 & 通知 |  |  | - | | |
| 204 | 204 | |
| 205 | 205 | ### 工作流程 |
| 206 | 206 | |
| 207 | 207 | | 模块 | biu | biu | biu | |
| 208 | 208 | |---------|------------------------------------------------------------------------|------------------------------------------------------------------------|------------------------------------------------------------------------| |
| 209 | -| 流程模型 |  |  |  | | |
| 210 | -| 表单 & 分组 |  |  | - | | |
| 211 | -| 我的流程 |  |  |  | | |
| 212 | -| 待办 & 已办 |  |  |  | | |
| 213 | -| OA 请假 |  |  |  | | |
| 214 | - | |
| 215 | -### 支付系统 | |
| 216 | - | |
| 217 | -| 模块 | biu | biu | biu | | |
| 218 | -|---------|------------------------------------------------------------------|------------------------------------------------------------------------|------------------------------------------------------------------------| | |
| 219 | -| 商家 & 应用 |  |  |  | | |
| 220 | -| 支付 & 退款 |  |  | --- | | |
| 209 | +| 流程模型 |  |  |  | | |
| 210 | +| 表单 & 分组 |  |  | - | | |
| 211 | +| 我的流程 |  |  |  | | |
| 212 | +| 待办 & 已办 |  |  |  | | |
| 213 | +| OA 请假 |  |  |  | | |
| 221 | 214 | |
| 222 | 215 | ### 基础设施 |
| 223 | 216 | |
| 224 | 217 | | 模块 | biu | biu | biu | |
| 225 | 218 | |---------------|----------------------------------------------------------------------|--------------------------------------------------------------------|------------------------------------------------------------------| |
| 226 | -| 代码生成 |  |  | - | | |
| 227 | -| 文档 |  |  | - | | |
| 228 | -| 文件 & 配置 |  |  |  | | |
| 229 | -| 定时任务 |  |  | - | | |
| 230 | -| API 日志 |  |  | - | | |
| 231 | -| MySQL & Redis |  |  | - | | |
| 232 | -| 监控平台 |  |  |  | | |
| 219 | +| 代码生成 |  |  | - | | |
| 220 | +| 文档 |  |  | - | | |
| 221 | +| 文件 & 配置 |  |  |  | | |
| 222 | +| 定时任务 |  |  | - | | |
| 223 | +| API 日志 |  |  | - | | |
| 224 | +| MySQL & Redis |  |  | - | | |
| 225 | +| 监控平台 |  |  |  | | |
| 233 | 226 | |
| 227 | +### 支付系统 | |
| 228 | + | |
| 229 | +| 模块 | biu | biu | biu | | |
| 230 | +|---------|------------------------------------------------------------------|------------------------------------------------------------------------|------------------------------------------------------------------------| | |
| 231 | +| 商家 & 应用 |  |  |  | | |
| 232 | +| 支付 & 退款 |  |  | --- | | ... | ... |
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
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<T> 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
yudao-framework/yudao-spring-boot-starter-banner/src/main/resources/META-INF/spring.factories
0 → 100644
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
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
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
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
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
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<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<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<WXPayClientConfig> { |
| 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<WXPayClientConfig> { |
| 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<WXPayClientConfig> { |
| 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<WXPayClientConfig> { |
| 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<WXPayClientConfig> { |
| 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<WXPayClientConfig> { |
| 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<WXPayClientConfig> { |
| 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<Object> { |
| 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<Object> { |
| 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
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
yudao-framework/yudao-spring-boot-starter-extension/src/main/resources/META-INF/spring.factories deleted
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
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)); | ... | ... |