Compare commits

...

35 Commits

Author SHA1 Message Date
8d00ae32ce release: v2.1.0 2024-06-05 19:47:59 +08:00
5cd6af8e7b chore: 优化部分代码 2024-06-05 19:45:09 +08:00
cc079e8bf4 feat(messaging/websocket): 新增消息模块 - WebSocket 2024-06-04 22:43:27 +08:00
3d2a4271d5 feat(extension/crud): BaseService 新增查询字典列表方法 2024-06-01 22:15:03 +08:00
124c7ffe11 refactor(extension/crud): 优化项目结构 2024-06-01 21:18:53 +08:00
7feda79359 refactor: 调整邮件服务配置 2024-05-31 22:52:50 +08:00
ee30e861ff refactor: 调整邮件服务配置 2024-05-31 00:22:01 +08:00
hellokaton
774db91d19 feat(extension/crud-mf): 支持Mybatis Flex 2024-05-24 01:53:54 +00:00
KAI
c562e47f4a feat(messaging/mail): 新增动态邮箱配置 2024-05-24 01:31:28 +00:00
9e78305e27 release: v2.0.2 2024-05-20 23:21:07 +08:00
joshua
3e60197a31 fix: 修复封装分页 dataList 索引计算错误 2024-05-20 23:13:02 +08:00
881fd37dd6 fix: 移除部分错误依赖声明 2024-05-20 23:12:46 +08:00
9bee01baa3 chore: 优化部分代码 2024-05-20 22:57:13 +08:00
1faa46e125 feat(file/excel): 新增 Easy Excel List 集合转换器 2024-05-20 22:56:23 +08:00
Yoofff
62121b78ec fix(captcha): 修复行为验证码接口请求次数限制 2024-05-20 20:53:38 +08:00
e3de3b6721 release: v2.0.1 2024-05-13 22:51:54 +08:00
5b76534df7 feat(extension/crud): 新增多种实体 Base 模型降低 BaseService 耦合 2024-05-13 22:30:40 +08:00
57eef274a3 refactor(web): 优化部分方法使用 2024-05-13 22:07:18 +08:00
f138e5cd45 fix(extension/crud): 修复查询树列表方法中的错误判断 2024-05-13 22:06:57 +08:00
ca6c7098b1 feat(core): 新增字符串工具类 2024-05-13 21:58:13 +08:00
596605b27b feat(cache/redisson): RedisUtils 新增递增、递减方法 2024-05-13 21:57:42 +08:00
b5dd5c7f18 chore: 升级依赖
SaToken 1.37.0 => 1.38.0
Redisson 3.28.0 => 3.30.0
Crane4j 2.7.0 => 2.8.0
AWS S3 1.12.702 => 1.12.720
IP2Region 3.1.10 => 3.1.11
2024-05-13 21:56:14 +08:00
macroju
cde9b01fc1 chore: 升级依赖修复安全漏洞 (#2) 2024-05-06 20:31:19 +08:00
c5e2516acd release: v2.0.0 2024-04-17 22:38:15 +08:00
2d71eca075 chore: 升级依赖
1.Spring Boot 3.1.9 => 3.1.10
2.Redisson 3.27.2 => 3.28.0(修复Failed to submit a listener notification task. Event loop shut down?)
3.CosId 2.6.6 => 2.6.8
4.SMS4J 3.1.1 => 3.2.1
5.Easy Excel 3.3.3 => 3.3.4
6.AWS S3 1.12.675 => 1.12.702
7.Crane4j 2.6.1 => 2.7.0(多对多装配处理器增强)
8.TLog 1.5.1 => 1.5.2
9.Hutool 5.8.26 => 5.8.27
10.IP2Region 3.1.9 => 3.1.10
2024-04-17 21:49:47 +08:00
fe310bcb87 style(extension/crud): 优化部分注释 2024-04-17 21:18:51 +08:00
8695cf9e09 chore: 部分代码格式优化 2024-04-16 22:44:33 +08:00
b0e567d749 chore: 移除 Qodana 扫描 2024-04-16 22:40:32 +08:00
f757438d1b refactor(web/xss): 优化 XSS 过滤部分代码 2024-04-16 22:39:34 +08:00
jasmine
c4051a6465 refactor: 应用关闭,关闭自定义线程池ScheduledExecutorService
* 程序结束,关闭ScheduledExecutorService 线程池。
2024-04-15 03:34:56 +00:00
dbb7a6319e chore: top.charles7c.continew => top.continew 2024-04-09 22:33:19 +08:00
whhya
2573fb04f0 feat(web/xss): XSS 增加过滤模式字段,提供清空、转义 2 种方式,默认使用清空模式
* update:完善XssProperties.mode属性为枚举类型
* feat(web/xss): xss增加过滤模式(mode)字段,提供清空(clean)/转义(escape)2种方式,默认使用clean模式
2024-04-09 02:15:31 +00:00
8c91d4a26c refactor(web): 优化 XSS 过滤部分代码 2024-03-30 21:42:51 +08:00
whhya
2656da450c feat(web): 新增 XSS 过滤器 2024-03-30 12:59:01 +00:00
2ff05c82ee chore: 更新版本号为 2.0.0-SNAPSHOT 2024-03-24 10:18:27 +08:00
265 changed files with 5205 additions and 784 deletions

View File

@@ -8,23 +8,6 @@ on:
workflow_dispatch:
jobs:
# Qodana 扫描
qodana-scan:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
checks: write
steps:
- name: Checkout
uses: actions/checkout@master
with:
ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit
fetch-depth: 0 # a full history is required for pull request analysis
- name: Scan
uses: JetBrains/qodana-action@v2023.3
env:
QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
# Sonar 扫描
sonar-scan:
runs-on: ubuntu-latest

View File

@@ -1,3 +1,82 @@
## [v2.1.0](https://github.com/Charles7c/continew-starter/compare/v2.0.2...v2.1.0) (2024-06-05)
### ✨ 新特性
- 【messaging/mail】新增动态邮箱配置 ([Gitee#19](https://gitee.com/continew/continew-starter/pulls/19)) ([ee30e86](https://github.com/Charles7c/continew-starter/commit/ee30e861ff536ee3ed6f14ff5ded5af7a513941d)) ([7feda79](https://github.com/Charles7c/continew-starter/commit/7feda79359ea40331eee1e3d4d5fd12000f027c5))
- 【data/mybatis-flex】新增 continew-starter-data-mybatis-flex 数据访问模块Mybatis Flex 自动配置) ([Gitee#18](https://gitee.com/continew/continew-starter/pulls/18)) ([124c7ff](https://github.com/Charles7c/continew-starter/commit/124c7ffe11a0e6563d9b513036c53ff66edbb9b3))
- 【extension/crud】新增查询字典列表方法 ([3d2a427](https://github.com/Charles7c/continew-starter/commit/3d2a4271d5eed676f16f4728b461dc3b298a65a9))
- 【messaging/websocket】新增 continew-starter-messaging-websocket 消息模块 ([cc079e8](https://github.com/Charles7c/continew-starter/commit/cc079e8bf422825bf9a96ddbd4329fc77d3cbf2c))
## [v2.0.2](https://github.com/Charles7c/continew-starter/compare/v2.0.1...v2.0.2) (2024-05-20)
### ✨ 新特性
- 【file/excel】新增 Easy Excel List 集合转换器 ([1faa46e](https://github.com/Charles7c/continew-starter/commit/1faa46e12505c025e5ca6f1a45158324ac210799))
### 🐛 问题修复
- 【captcha/behavior】修复行为验证码接口请求次数限制 ([Gitee#17](https://gitee.com/continew/continew-starter/pulls/17))
- 【extension/crud】修复封装分页 dataList 索引计算错误 ([3e60197](https://github.com/Charles7c/continew-starter/commit/3e60197a31f140c863868440944df0427a9cf8e8))
- 移除部分错误依赖声明 ([881fd37](https://github.com/Charles7c/continew-starter/commit/881fd37dd61836daf3343d9053e9a7c81b005923))
## [v2.0.1](https://github.com/Charles7c/continew-starter/compare/v2.0.0...v2.0.1) (2024-05-13)
### ✨ 新特性
- 【cache/redisson】RedisUtils 新增递增、递减方法 ([596605b](https://github.com/Charles7c/continew-starter/commit/596605b27b046fa0488b113b1c3d87c60277e4ec))
- 【core】新增字符串工具类 ([ca6c709](https://github.com/Charles7c/continew-starter/commit/ca6c7098b124c3121fe626811ea61d53c80a9a4e))
- 【extension/crud】新增多种实体 Base 模型降低 BaseService 耦合 ([5b76534](https://github.com/Charles7c/continew-starter/commit/5b76534df7a54aa6d696515cfbf8059fcdc4a067))
### 🐛 问题修复
- 【extension/crud】修复查询树列表方法中的错误判断 ([f138e5c](https://github.com/Charles7c/continew-starter/commit/f138e5cd4526d8be0fe5e7ae54833b4541748346))
### 💎 功能优化
- 【web】优化部分方法使用 ([57eef27](https://github.com/Charles7c/continew-starter/commit/57eef274a3e34e8bb4de6073452080b2bbdbee53))
### 📦 依赖升级
- 【dependencies】Spring Boot 3.1.10 => 3.1.11 ([GitHub#2](https://github.com/Charles7c/continew-starter/pull/2))
- 【dependencies】SaToken 1.37.0 => 1.38.0 ([b5dd5c7](https://github.com/Charles7c/continew-starter/commit/b5dd5c7f18603b5bd5a509c04ef410c1d64bc2e9))
- 【dependencies】Redisson 3.28.0 => 3.30.0 ([b5dd5c7](https://github.com/Charles7c/continew-starter/commit/b5dd5c7f18603b5bd5a509c04ef410c1d64bc2e9))
- 【dependencies】Crane4j 2.7.0 => 2.8.0 ([b5dd5c7](https://github.com/Charles7c/continew-starter/commit/b5dd5c7f18603b5bd5a509c04ef410c1d64bc2e9))
- 【dependencies】AWS S3 1.12.702 => 1.12.720 ([b5dd5c7](https://github.com/Charles7c/continew-starter/commit/b5dd5c7f18603b5bd5a509c04ef410c1d64bc2e9))
- 【dependencies】IP2Region 3.1.10 => 3.1.11 ([b5dd5c7](https://github.com/Charles7c/continew-starter/commit/b5dd5c7f18603b5bd5a509c04ef410c1d64bc2e9))
## [v2.0.0](https://github.com/Charles7c/continew-starter/compare/v1.5.1...v2.0.0) (2024-04-17)
### ✨ 新特性
- 【web】新增 XSS 过滤器 ([2656da4](https://github.com/Charles7c/continew-starter/commit/2656da450c866681c270c30131c028847e1e21d4)) ([2573fb0](https://github.com/Charles7c/continew-starter/commit/2573fb04f0698db3ab662a0e7bf762c04300468b)) ([Gitee PR#13](https://gitee.com/continew/continew-starter/pulls/13))
### 🐛 问题修复
- 【cache/redisson】修复Failed to submit a listener notification task. Event loop shut down? 问题 ([2d71eca](https://github.com/Charles7c/continew-starter/commit/2d71eca07505f143c82cca8d24bc6f54105d0bbb))
### 💎 功能优化
- 【core】应用关闭支持优雅关闭自定义线程池 ScheduledExecutorService ([c4051a6](https://github.com/Charles7c/continew-starter/commit/c4051a6465e0d70d119ec27c6ae4eb4d1893339a))
- 【extension/crud】优化部分注释 ([fe310bc](https://github.com/Charles7c/continew-starter/commit/fe310bcb879d3f20eb8ead4b39436ec96b99e7f6))
- 移除 Qodana 扫描License 已过期 ([b0e567d](https://github.com/Charles7c/continew-starter/commit/b0e567d749b988e3f45772742a273a422a661edb))
### 📦 依赖升级
- 【dependencies】Spring Boot 3.1.9 => 3.1.10 ([2d71eca](https://github.com/Charles7c/continew-starter/commit/2d71eca07505f143c82cca8d24bc6f54105d0bbb))
- 【dependencies】Redisson 3.27.2 => 3.28.0 ([2d71eca](https://github.com/Charles7c/continew-starter/commit/2d71eca07505f143c82cca8d24bc6f54105d0bbb))
- 【dependencies】CosId 2.6.6 => 2.6.8 ([2d71eca](https://github.com/Charles7c/continew-starter/commit/2d71eca07505f143c82cca8d24bc6f54105d0bbb))
- 【dependencies】SMS4J 3.1.1 => 3.2.1 ([2d71eca](https://github.com/Charles7c/continew-starter/commit/2d71eca07505f143c82cca8d24bc6f54105d0bbb))
- 【dependencies】Easy Excel 3.3.3 => 3.3.4 ([2d71eca](https://github.com/Charles7c/continew-starter/commit/2d71eca07505f143c82cca8d24bc6f54105d0bbb))
- 【dependencies】AWS S3 1.12.675 => 1.12.702 ([2d71eca](https://github.com/Charles7c/continew-starter/commit/2d71eca07505f143c82cca8d24bc6f54105d0bbb))
- 【dependencies】Crane4j 2.6.1 => 2.7.0 ([2d71eca](https://github.com/Charles7c/continew-starter/commit/2d71eca07505f143c82cca8d24bc6f54105d0bbb))
- 【dependencies】TLog 1.5.1 => 1.5.2 ([2d71eca](https://github.com/Charles7c/continew-starter/commit/2d71eca07505f143c82cca8d24bc6f54105d0bbb))
- 【dependencies】Hutool 5.8.26 => 5.8.27 ([2d71eca](https://github.com/Charles7c/continew-starter/commit/2d71eca07505f143c82cca8d24bc6f54105d0bbb))
- 【dependencies】IP2Region 3.1.9 => 3.1.10 ([2d71eca](https://github.com/Charles7c/continew-starter/commit/2d71eca07505f143c82cca8d24bc6f54105d0bbb))
### 💥 破坏性变更
- groupId 及基础包名调整更短的包名聚合品牌形象。top.charles7c.continew => top.continew ([dbb7a63](https://github.com/Charles7c/continew-starter/commit/dbb7a6319e9440e7a05f2eb4aab3b445f43197f7))
## [v1.5.1](https://github.com/Charles7c/continew-starter/compare/v1.5.0...v1.5.1) (2024-03-23)
### ✨ 新特性

View File

@@ -4,10 +4,10 @@
<img src="https://img.shields.io/badge/License-LGPL--3.0-blue.svg" alt="License" />
</a>
<a href="https://central.sonatype.com/search?q=continew-starter" target="_blank">
<img src="https://img.shields.io/maven-central/v/top.charles7c.continew/continew-starter.svg?label=Maven%20Central&logo=sonatype&logoColor=FFF" alt="Release" />
<img src="https://img.shields.io/maven-central/v/top.continew/continew-starter.svg?label=Maven%20Central&logo=sonatype&logoColor=FFF" alt="Release" />
</a>
<a href="https://github.com/Charles7c/continew-starter" target="_blank">
<img src="https://img.shields.io/badge/RELEASE-v1.5.1-%23ff3f59.svg" alt="Release" />
<img src="https://img.shields.io/badge/RELEASE-v2.1.0-%23ff3f59.svg" alt="Release" />
</a>
<a href="https://app.codacy.com/gh/Charles7c/continew-starter/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade" target="_blank">
<img src="https://app.codacy.com/project/badge/Grade/90ed633957a9410aa8745f0654827c01" alt="Codacy Badge" />
@@ -16,7 +16,7 @@
<img src="https://sonarcloud.io/api/project_badges/measure?project=Charles7c_continew-starter&metric=alert_status" alt="Sonar Status" />
</a>
<a href="https://spring.io/projects/spring-boot" target="_blank">
<img src="https://img.shields.io/badge/Spring Boot-3.1.8-%236CB52D.svg?logo=Spring-Boot" alt="Spring Boot" />
<img src="https://img.shields.io/badge/Spring Boot-3.1.11-%236CB52D.svg?logo=Spring-Boot" alt="Spring Boot" />
</a>
<a href="https://github.com/Charles7c/continew-starter" target="_blank">
<img src="https://img.shields.io/badge/Open JDK-17-%236CB52D.svg?logo=OpenJDK&logoColor=FFF" alt="Open JDK" />
@@ -76,7 +76,7 @@ ContiNew Starter 就是将脚手架项目中的通用基础配置进行了封装
```xml
<parent>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter</artifactId>
<version>{latest-version}</version>
</parent>
@@ -96,7 +96,7 @@ ContiNew Starter 就是将脚手架项目中的通用基础配置进行了封装
<dependencies>
<!-- ContiNew Starter Dependencies -->
<dependency>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter-dependencies</artifactId>
<version>{latest-version}</version>
<type>pom</type>
@@ -112,7 +112,7 @@ ContiNew Starter 就是将脚手架项目中的通用基础配置进行了封装
<dependencies>
<!-- Web 模块 -->
<dependency>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter-web</artifactId>
</dependency>
</dependencies>
@@ -137,38 +137,13 @@ continew-starter.web:
exposed-headers: '*'
```
<details>
<summary>抢先体验快照SNAPSHOT版本💡</summary>
> **注意:** 快照版本目前处于开发测试阶段,其中很多特性或改动尚不稳定,可能会因为修复或优化而频繁调整。因此,仅可用于体验,切勿用于生产环境!
1.在项目 pom.xml 中配置 SNAPSHOT快照仓库地址如果你已配有其他仓库地址追加下方快照仓库地址即可
```xml
<repositories>
<repository>
<id>sonatype-nexus-snapshots</id>
<name>Sonatype Nexus Snapshots</name>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
<snapshots>
<updatePolicy>always</updatePolicy>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
```
2.将 ContiNew Starter 版本改为对应快照版本例如1.3.0-SNAPSHOT
</details>
## 模块结构
### 核心模块
| 模块名称 | 模块说明 | 依赖版本 |
| --------------------- | ------------------------------------ | ------------------------------------------------------------ |
| continew-starter-core | 核心模块:包含线程池、项目等自动配置 | <a href="https://spring.io/projects/spring-boot" target="_blank">Spring Boot</a>3.1.8<br /><a href="https://www.hutool.cn/" target="_blank">Hutool</a>5.8.25<br />mica-ip2region3.1.7 |
| 模块名称 | 模块说明 | 依赖版本 |
| --------------------- | ------------------------------------ |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| continew-starter-core | 核心模块:包含线程池、项目等自动配置 | <a href="https://spring.io/projects/spring-boot" target="_blank">Spring Boot</a>3.1.11<br /><a href="https://www.hutool.cn/" target="_blank">Hutool</a>5.8.25<br />mica-ip2region3.1.7 |
### JSON模块
@@ -189,7 +164,6 @@ continew-starter.web:
| continew-starter-security-password | 密码编码器 | |
| continew-starter-security-mask | JSON 脱敏 | |
| continew-starter-security-crypto | 数据库字段加/解密 | |
| continew-starter-security-all | | |
### Web模块
@@ -212,9 +186,9 @@ continew-starter.web:
### 文件处理模块
| 模块名称 | 模块说明 | 依赖版本 |
| --------------------------- | -------------- | ------------------------------------------------------------ |
| continew-starter-file-excel | Excel 相关配置 | <a href="https://easyexcel.opensource.alibaba.com/" target="_blank">Easy Excel</a>3.3.3 |
| 模块名称 | 模块说明 | 依赖版本 |
| --------------------------- | -------------- |------------------------------------------------------------------------------------------|
| continew-starter-file-excel | Excel 相关配置 | <a href="https://easyexcel.opensource.alibaba.com/" target="_blank">Easy Excel</a>3.3.4 |
### 验证码模块
@@ -225,32 +199,33 @@ continew-starter.web:
### 缓存模块
| 模块名称 | 模块说明 | 依赖版本 |
| ---------------------------------- | --------------------- | ------------------------------------------------------------ |
| continew-starter-cache-redisson | Redisson 自动配置 | <a href="https://github.com/redisson/redisson/wiki/Redisson%E9%A1%B9%E7%9B%AE%E4%BB%8B%E7%BB%8D" target="_blank">Redisson</a>3.26.0 |
| continew-starter-cache-springcache | Spring Cache 自动配置 | |
| continew-starter-cache-jetcache | JetCache 自动配置 | |
| 模块名称 | 模块说明 | 依赖版本 |
| ---------------------------------- | --------------------- |--------------------------------------------------------------------------------------------------------------------------------------|
| continew-starter-cache-redisson | Redisson 自动配置 | <a href="https://github.com/redisson/redisson/wiki/Redisson%E9%A1%B9%E7%9B%AE%E4%BB%8B%E7%BB%8D" target="_blank">Redisson</a>3.30.0 |
| continew-starter-cache-springcache | Spring Cache 自动配置 | |
| continew-starter-cache-jetcache | JetCache 自动配置 | |
### 数据访问模块
| 模块名称 | 模块说明 | 依赖版本 |
| ---------------------------------- | --------------------- | ------------------------------------------------------------ |
| continew-starter-data-core | 数据访问核心模块 | |
| 模块名称 | 模块说明 | 依赖版本 |
|------------------------------------|-------------------| ----------------------------------------------------------- |
| continew-starter-data-core | 数据访问核心模块 | |
| continew-starter-data-mybatis-plus | MyBatis Plus 自动配置 | <a href="https://baomidou.com/" target="_blank">MyBatis Plus</a>3.5.5<br /><a href="https://www.kancloud.cn/tracy5546/dynamic-datasource/2264611" target="_blank">dynamic-datasource-spring-boot-starter</a>4.3.0<br /><a href="https://github.com/p6spy/p6spy" target="_blank">P6Spy</a>3.9.1 |
| continew-starter-data-mybatis-flex | MyBatis Flex 自动配置 | |
### 认证模块
| 模块名称 | 模块说明 | 依赖版本 |
| ------------------------------ | ----------------- | ------------------------------------------------------------ |
| continew-starter-auth-satoken | SaToken 自动配置 | <a href="https://sa-token.dev33.cn/" target="_blank">Sa-Token</a>1.37.0 |
| continew-starter-auth-justauth | JustAuth 自动配置 | <a href="https://justauth.cn/" target="_blank">Just Auth</a>1.16.6 |
| 模块名称 | 模块说明 | 依赖版本 |
| ------------------------------ | ----------------- |--------------------------------------------------------------------------|
| continew-starter-auth-satoken | SaToken 自动配置 | <a href="https://sa-token.dev33.cn/" target="_blank">Sa-Token</a>1.38.0 |
| continew-starter-auth-justauth | JustAuth 自动配置 | <a href="https://justauth.cn/" target="_blank">Just Auth</a>1.16.6 |
### 消息模块
| 模块名称 | 模块说明 | 依赖版本 |
| ------------------------------- | -------- | ------------------------------------------------------------ |
| continew-starter-messaging-mail | 邮件 | Jakarta Mail1.1.0 |
| continew-starter-messaging-sms | 短信 | <a href="https://sms4j.com/" target="_blank">SMS4J</a>3.1.1 |
| 模块名称 | 模块说明 | 依赖版本 |
|--------------------------------------|-----------| ------------------------------------------------------------ |
| continew-starter-messaging-mail | 邮件 | Jakarta Mail1.1.0 |
| continew-starter-messaging-websocket | WebSocket | |
### 扩展模块

View File

@@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter</artifactId>
<version>${revision}</version>
</parent>
@@ -21,7 +21,7 @@
<!-- 核心模块 -->
<dependency>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter-core</artifactId>
</dependency>
</dependencies>

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.apidoc.autoconfigure;
package top.continew.starter.apidoc.autoconfigure;
import cn.hutool.core.map.MapUtil;
import io.swagger.v3.oas.models.Components;
@@ -38,9 +38,9 @@ import org.springframework.http.CacheControl;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import top.charles7c.continew.starter.core.autoconfigure.project.ProjectProperties;
import top.charles7c.continew.starter.core.constant.PropertiesConstants;
import top.charles7c.continew.starter.core.util.GeneralPropertySourceFactory;
import top.continew.starter.core.autoconfigure.project.ProjectProperties;
import top.continew.starter.core.constant.PropertiesConstants;
import top.continew.starter.core.util.GeneralPropertySourceFactory;
import java.util.List;
import java.util.Map;
@@ -54,7 +54,7 @@ import java.util.concurrent.TimeUnit;
*/
@EnableWebMvc
@AutoConfiguration
@ConditionalOnProperty(prefix = PropertiesConstants.SPRINGDOC_SWAGGER_UI, name = PropertiesConstants.ENABLED, havingValue = "true")
@ConditionalOnProperty(prefix = PropertiesConstants.SPRINGDOC_SWAGGER_UI, name = PropertiesConstants.ENABLED, matchIfMissing = true)
@EnableConfigurationProperties(SpringDocExtensionProperties.class)
@PropertySource(value = "classpath:default-api-doc.yml", factory = GeneralPropertySourceFactory.class)
public class SpringDocAutoConfiguration implements WebMvcConfigurer {

View File

@@ -14,12 +14,12 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.apidoc.autoconfigure;
package top.continew.starter.apidoc.autoconfigure;
import io.swagger.v3.oas.models.Components;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import top.charles7c.continew.starter.core.constant.PropertiesConstants;
import top.continew.starter.core.constant.PropertiesConstants;
/**
* API 文档扩展配置属性

View File

@@ -1 +1 @@
top.charles7c.continew.starter.apidoc.autoconfigure.SpringDocAutoConfiguration
top.continew.starter.apidoc.autoconfigure.SpringDocAutoConfiguration

View File

@@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter-auth</artifactId>
<version>${revision}</version>
</parent>
@@ -26,7 +26,7 @@
<!-- 缓存模块 - Redisson -->
<dependency>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter-cache-redisson</artifactId>
<optional>true</optional>
</dependency>

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.auth.justauth.autoconfigure;
package top.continew.starter.auth.justauth.autoconfigure;
import jakarta.annotation.PostConstruct;
import me.zhyd.oauth.cache.AuthStateCache;
@@ -25,8 +25,8 @@ import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import top.charles7c.continew.starter.auth.justauth.core.JustAuthStateCacheRedisImpl;
import top.charles7c.continew.starter.core.constant.PropertiesConstants;
import top.continew.starter.auth.justauth.core.JustAuthStateCacheRedisImpl;
import top.continew.starter.core.constant.PropertiesConstants;
/**
* JustAuth 自动配置
@@ -35,7 +35,7 @@ import top.charles7c.continew.starter.core.constant.PropertiesConstants;
* @since 1.0.0
*/
@AutoConfiguration(before = com.xkcoding.justauth.autoconfigure.JustAuthAutoConfiguration.class)
@ConditionalOnProperty(prefix = "justauth", name = PropertiesConstants.ENABLED, havingValue = "true", matchIfMissing = true)
@ConditionalOnProperty(prefix = "justauth", name = PropertiesConstants.ENABLED, matchIfMissing = true)
public class JustAuthAutoConfiguration {
private static final Logger log = LoggerFactory.getLogger(JustAuthAutoConfiguration.class);

View File

@@ -14,10 +14,10 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.auth.justauth.core;
package top.continew.starter.auth.justauth.core;
import me.zhyd.oauth.cache.AuthStateCache;
import top.charles7c.continew.starter.cache.redisson.util.RedisUtils;
import top.continew.starter.cache.redisson.util.RedisUtils;
import java.time.Duration;
@@ -74,6 +74,6 @@ public class JustAuthStateCacheRedisImpl implements AuthStateCache {
*/
@Override
public boolean containsKey(String key) {
return RedisUtils.hasKey(RedisUtils.formatKey(KEY_PREFIX, key));
return RedisUtils.exists(RedisUtils.formatKey(KEY_PREFIX, key));
}
}

View File

@@ -1,2 +1,2 @@
top.charles7c.continew.starter.auth.justauth.autoconfigure.JustAuthAutoConfiguration
top.continew.starter.auth.justauth.autoconfigure.JustAuthAutoConfiguration
com.xkcoding.justauth.autoconfigure.JustAuthAutoConfiguration

View File

@@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter-auth</artifactId>
<version>${revision}</version>
</parent>
@@ -27,14 +27,14 @@
<!-- 缓存模块 - Redisson -->
<dependency>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter-cache-redisson</artifactId>
<optional>true</optional>
</dependency>
<!-- Web 模块 -->
<dependency>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter-web</artifactId>
</dependency>
</dependencies>

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.auth.satoken.autoconfigure;
package top.continew.starter.auth.satoken.autoconfigure;
import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.jwt.StpLogicJwtForSimple;
@@ -32,10 +32,10 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.*;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import top.charles7c.continew.starter.auth.satoken.autoconfigure.dao.SaTokenDaoConfiguration;
import top.charles7c.continew.starter.core.constant.PropertiesConstants;
import top.charles7c.continew.starter.core.constant.StringConstants;
import top.charles7c.continew.starter.core.util.GeneralPropertySourceFactory;
import top.continew.starter.auth.satoken.autoconfigure.dao.SaTokenDaoConfiguration;
import top.continew.starter.core.constant.PropertiesConstants;
import top.continew.starter.core.constant.StringConstants;
import top.continew.starter.core.util.GeneralPropertySourceFactory;
/**
* Sa-Token 自动配置
@@ -44,7 +44,7 @@ import top.charles7c.continew.starter.core.util.GeneralPropertySourceFactory;
* @since 1.0.0
*/
@AutoConfiguration
@ComponentScan("top.charles7c.continew.starter.auth.satoken.exception")
@ComponentScan("top.continew.starter.auth.satoken.exception")
@EnableConfigurationProperties(SaTokenExtensionProperties.class)
@ConditionalOnProperty(prefix = "sa-token.extension", name = PropertiesConstants.ENABLED, havingValue = "true")
@PropertySource(value = "classpath:default-auth-satoken.yml", factory = GeneralPropertySourceFactory.class)

View File

@@ -14,11 +14,11 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.auth.satoken.autoconfigure;
package top.continew.starter.auth.satoken.autoconfigure;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import top.charles7c.continew.starter.auth.satoken.autoconfigure.dao.SaTokenDaoProperties;
import top.continew.starter.auth.satoken.autoconfigure.dao.SaTokenDaoProperties;
/**
* SaToken 扩展配置属性

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.auth.satoken.autoconfigure;
package top.continew.starter.auth.satoken.autoconfigure;
/**
* SaToken 安全配置属性

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.auth.satoken.autoconfigure.dao;
package top.continew.starter.auth.satoken.autoconfigure.dao;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.dao.SaTokenDaoDefaultImpl;
@@ -28,7 +28,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.core.ResolvableType;
import top.charles7c.continew.starter.cache.redisson.autoconfigure.RedissonAutoConfiguration;
import top.continew.starter.cache.redisson.autoconfigure.RedissonAutoConfiguration;
/**
* SaToken 持久层配置

View File

@@ -14,9 +14,9 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.auth.satoken.autoconfigure.dao;
package top.continew.starter.auth.satoken.autoconfigure.dao;
import top.charles7c.continew.starter.auth.satoken.enums.SaTokenDaoType;
import top.continew.starter.auth.satoken.enums.SaTokenDaoType;
/**
* SaToken 持久层配置属性

View File

@@ -14,11 +14,11 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.auth.satoken.autoconfigure.dao;
package top.continew.starter.auth.satoken.autoconfigure.dao;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.util.SaFoxUtil;
import top.charles7c.continew.starter.cache.redisson.util.RedisUtils;
import top.continew.starter.cache.redisson.util.RedisUtils;
import java.time.Duration;
import java.util.ArrayList;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.auth.satoken.enums;
package top.continew.starter.auth.satoken.enums;
/**
* SaToken 持久层类型枚举

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.auth.satoken.exception;
package top.continew.starter.auth.satoken.exception;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
@@ -25,7 +25,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import top.charles7c.continew.starter.web.model.R;
import top.continew.starter.web.model.R;
/**
* 全局 SaToken 异常处理器

View File

@@ -1 +1 @@
top.charles7c.continew.starter.auth.satoken.autoconfigure.SaTokenAutoConfiguration
top.continew.starter.auth.satoken.autoconfigure.SaTokenAutoConfiguration

View File

@@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter</artifactId>
<version>${revision}</version>
</parent>
@@ -21,7 +21,7 @@
<dependencies>
<!-- 核心模块 -->
<dependency>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter-core</artifactId>
</dependency>
</dependencies>

View File

@@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter-cache</artifactId>
<version>${revision}</version>
</parent>
@@ -38,7 +38,7 @@
<!-- 缓存模块 - Redisson -->
<dependency>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter-cache-redisson</artifactId>
</dependency>
</dependencies>

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.cache.jetcache.autoconfigure;
package top.continew.starter.cache.jetcache.autoconfigure;
import jakarta.annotation.PostConstruct;
import org.slf4j.Logger;
@@ -22,7 +22,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import top.charles7c.continew.starter.core.util.GeneralPropertySourceFactory;
import top.continew.starter.core.util.GeneralPropertySourceFactory;
/**
* JetCache 自动配置

View File

@@ -1 +1 @@
top.charles7c.continew.starter.cache.jetcache.autoconfigure.JetCacheAutoConfiguration
top.continew.starter.cache.jetcache.autoconfigure.JetCacheAutoConfiguration

View File

@@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter-cache</artifactId>
<version>${revision}</version>
</parent>

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.cache.redisson.autoconfigure;
package top.continew.starter.cache.redisson.autoconfigure;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
@@ -33,8 +33,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import top.charles7c.continew.starter.core.constant.PropertiesConstants;
import top.charles7c.continew.starter.core.constant.StringConstants;
import top.continew.starter.core.constant.PropertiesConstants;
import top.continew.starter.core.constant.StringConstants;
import java.util.List;
@@ -46,7 +46,7 @@ import java.util.List;
* @since 1.0.0
*/
@AutoConfiguration
@ConditionalOnProperty(prefix = "spring.data.redisson", name = PropertiesConstants.ENABLED, havingValue = "true")
@ConditionalOnProperty(prefix = "spring.data.redisson", name = PropertiesConstants.ENABLED, matchIfMissing = true)
@EnableConfigurationProperties(RedissonProperties.class)
public class RedissonAutoConfiguration {

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.cache.redisson.autoconfigure;
package top.continew.starter.cache.redisson.autoconfigure;
import org.redisson.config.ClusterServersConfig;
import org.redisson.config.SentinelServersConfig;
@@ -34,7 +34,7 @@ public class RedissonProperties {
/**
* 是否启用 Redisson
*/
private boolean enabled = false;
private boolean enabled = true;
/**
* Redis 模式

View File

@@ -14,15 +14,14 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.cache.redisson.util;
package top.continew.starter.cache.redisson.util;
import cn.hutool.extra.spring.SpringUtil;
import org.redisson.api.*;
import top.charles7c.continew.starter.core.constant.StringConstants;
import top.continew.starter.core.constant.StringConstants;
import java.time.Duration;
import java.util.Collection;
import java.util.stream.Stream;
/**
* Redis 工具类
@@ -92,6 +91,28 @@ public class RedisUtils {
CLIENT.getKeys().deleteByPattern(pattern);
}
/**
* 递增 1
*
* @param key
* @return 当前值
* @since 2.0.1
*/
public static long incr(String key) {
return CLIENT.getAtomicLong(key).incrementAndGet();
}
/**
* 递减 1
*
* @param key
* @return 当前值
* @since 2.0.1
*/
public static long decr(String key) {
return CLIENT.getAtomicLong(key).decrementAndGet();
}
/**
* 设置缓存过期时间
*
@@ -130,9 +151,8 @@ public class RedisUtils {
* @param key
* @return true存在false不存在
*/
public static boolean hasKey(String key) {
RKeys keys = CLIENT.getKeys();
return keys.countExists(key) > 0;
public static boolean exists(String key) {
return CLIENT.getKeys().countExists(key) > 0;
}
/**
@@ -142,8 +162,7 @@ public class RedisUtils {
* @return 缓存列表
*/
public static Collection<String> keys(String pattern) {
Stream<String> stream = CLIENT.getKeys().getKeysStreamByPattern(pattern);
return stream.toList();
return CLIENT.getKeys().getKeysStreamByPattern(pattern).toList();
}
/**

View File

@@ -1 +1 @@
top.charles7c.continew.starter.cache.redisson.autoconfigure.RedissonAutoConfiguration
top.continew.starter.cache.redisson.autoconfigure.RedissonAutoConfiguration

View File

@@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter-cache</artifactId>
<version>${revision}</version>
</parent>
@@ -15,7 +15,7 @@
<dependencies>
<!-- 缓存模块 - Redisson -->
<dependency>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter-cache-redisson</artifactId>
</dependency>

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.cache.springcache.autoconfigure;
package top.continew.starter.cache.springcache.autoconfigure;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.CharSequenceUtil;
@@ -35,7 +35,7 @@ import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import top.charles7c.continew.starter.core.util.GeneralPropertySourceFactory;
import top.continew.starter.core.util.GeneralPropertySourceFactory;
import java.util.Map;

View File

@@ -1 +1 @@
top.charles7c.continew.starter.cache.springcache.autoconfigure.SpringCacheAutoConfiguration
top.continew.starter.cache.springcache.autoconfigure.SpringCacheAutoConfiguration

View File

@@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter</artifactId>
<version>${revision}</version>
</parent>
@@ -22,7 +22,7 @@
<dependencies>
<!-- 核心模块 -->
<dependency>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter-core</artifactId>
</dependency>
</dependencies>

View File

@@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter-captcha</artifactId>
<version>${revision}</version>
</parent>
@@ -21,7 +21,7 @@
<!-- 缓存模块 - Redisson -->
<dependency>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter-cache-redisson</artifactId>
</dependency>
</dependencies>

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.captcha.behavior.autoconfigure;
package top.continew.starter.captcha.behavior.autoconfigure;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.FileUtil;
@@ -31,13 +31,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import top.charles7c.continew.starter.captcha.behavior.autoconfigure.cache.BehaviorCaptchaCacheConfiguration;
import top.charles7c.continew.starter.core.constant.PropertiesConstants;
import top.continew.starter.core.constant.PropertiesConstants;
import java.util.HashMap;
import java.util.Map;
@@ -61,18 +59,11 @@ public class BehaviorCaptchaAutoConfiguration {
this.properties = properties;
}
/**
* 自定义缓存实现配置
*/
@Configuration
@Import({BehaviorCaptchaCacheConfiguration.Default.class, BehaviorCaptchaCacheConfiguration.Redis.class,
BehaviorCaptchaCacheConfiguration.Custom.class})
protected static class BehaviorCaptchaCacheAutoConfiguration {}
/**
* 行为验证码服务接口
*/
@Bean
@DependsOn("captchaCacheService")
@ConditionalOnMissingBean
public CaptchaService captchaService() {
Properties config = new Properties();

View File

@@ -14,12 +14,13 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.captcha.behavior.autoconfigure;
package top.continew.starter.captcha.behavior.autoconfigure;
import cn.hutool.core.convert.Convert;
import com.anji.captcha.model.common.CaptchaTypeEnum;
import org.springframework.boot.context.properties.ConfigurationProperties;
import top.charles7c.continew.starter.captcha.behavior.enums.StorageType;
import top.charles7c.continew.starter.core.constant.PropertiesConstants;
import top.continew.starter.captcha.behavior.enums.StorageType;
import top.continew.starter.core.constant.PropertiesConstants;
import java.awt.*;
@@ -75,37 +76,37 @@ public class BehaviorCaptchaProperties {
/**
* 历史数据清除开关0关闭1开启
*/
private Integer historyDataClearEnable = 0;
private String historyDataClearEnable = "0";
/**
* 一分钟内接口请求次数限制开关0关闭1开启
*/
private Integer reqFrequencyLimitEnable = 0;
private String reqFrequencyLimitEnable = "0";
/**
* 一分钟内验证码最多失败次数限制默认5次
*/
private int reqGetLockLimit = 5;
private String reqGetLockLimit = "5";
/**
* 一分钟内验证码最多失败次数限制达标后锁定时间默认300秒
*/
private int reqGetLockSeconds = 300;
private String reqGetLockSeconds = "300";
/**
* 获取验证码接口一分钟内请求次数限制默认100次
*/
private int reqGetMinuteLimit = 100;
private String reqGetMinuteLimit = "100";
/**
* 校验检验码接口一分内请求次数限制默认100次
*/
private int reqCheckMinuteLimit = 100;
private String reqCheckMinuteLimit = "100";
/**
* 二次校验检验码接口一分钟内请求次数限制默认100次
*/
private int reqVerifyMinuteLimit = 100;
private String reqVerifyMinuteLimit = "100";
/**
* local缓存的阈值默认1000个
@@ -135,12 +136,12 @@ public class BehaviorCaptchaProperties {
/**
* 点选字体样式默认BOLD
*/
private int fontStyle = Font.BOLD;
private String fontStyle = Convert.toStr(Font.BOLD);
/**
* 点选字体大小默认25
*/
private int fontSize = 25;
private String fontSize = "25";
public boolean isEnabled() {
return enabled;
@@ -206,59 +207,59 @@ public class BehaviorCaptchaProperties {
this.fontType = fontType;
}
public Integer getHistoryDataClearEnable() {
public String getHistoryDataClearEnable() {
return historyDataClearEnable;
}
public void setHistoryDataClearEnable(Integer historyDataClearEnable) {
public void setHistoryDataClearEnable(String historyDataClearEnable) {
this.historyDataClearEnable = historyDataClearEnable;
}
public Integer getReqFrequencyLimitEnable() {
public String getReqFrequencyLimitEnable() {
return reqFrequencyLimitEnable;
}
public void setReqFrequencyLimitEnable(Integer reqFrequencyLimitEnable) {
public void setReqFrequencyLimitEnable(String reqFrequencyLimitEnable) {
this.reqFrequencyLimitEnable = reqFrequencyLimitEnable;
}
public int getReqGetLockLimit() {
public String getReqGetLockLimit() {
return reqGetLockLimit;
}
public void setReqGetLockLimit(int reqGetLockLimit) {
public void setReqGetLockLimit(String reqGetLockLimit) {
this.reqGetLockLimit = reqGetLockLimit;
}
public int getReqGetLockSeconds() {
public String getReqGetLockSeconds() {
return reqGetLockSeconds;
}
public void setReqGetLockSeconds(int reqGetLockSeconds) {
public void setReqGetLockSeconds(String reqGetLockSeconds) {
this.reqGetLockSeconds = reqGetLockSeconds;
}
public int getReqGetMinuteLimit() {
public String getReqGetMinuteLimit() {
return reqGetMinuteLimit;
}
public void setReqGetMinuteLimit(int reqGetMinuteLimit) {
public void setReqGetMinuteLimit(String reqGetMinuteLimit) {
this.reqGetMinuteLimit = reqGetMinuteLimit;
}
public int getReqCheckMinuteLimit() {
public String getReqCheckMinuteLimit() {
return reqCheckMinuteLimit;
}
public void setReqCheckMinuteLimit(int reqCheckMinuteLimit) {
public void setReqCheckMinuteLimit(String reqCheckMinuteLimit) {
this.reqCheckMinuteLimit = reqCheckMinuteLimit;
}
public int getReqVerifyMinuteLimit() {
public String getReqVerifyMinuteLimit() {
return reqVerifyMinuteLimit;
}
public void setReqVerifyMinuteLimit(int reqVerifyMinuteLimit) {
public void setReqVerifyMinuteLimit(String reqVerifyMinuteLimit) {
this.reqVerifyMinuteLimit = reqVerifyMinuteLimit;
}
@@ -302,19 +303,19 @@ public class BehaviorCaptchaProperties {
this.interferenceOptions = interferenceOptions;
}
public int getFontStyle() {
public String getFontStyle() {
return fontStyle;
}
public void setFontStyle(int fontStyle) {
public void setFontStyle(String fontStyle) {
this.fontStyle = fontStyle;
}
public int getFontSize() {
public String getFontSize() {
return fontSize;
}
public void setFontSize(int fontSize) {
public void setFontSize(String fontSize) {
this.fontSize = fontSize;
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.captcha.behavior.autoconfigure.cache;
package top.continew.starter.captcha.behavior.autoconfigure.cache;
import cn.hutool.extra.spring.SpringUtil;
import com.anji.captcha.service.CaptchaCacheService;
@@ -25,40 +25,46 @@ import org.redisson.client.RedisClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.core.ResolvableType;
import top.charles7c.continew.starter.cache.redisson.autoconfigure.RedissonAutoConfiguration;
import top.charles7c.continew.starter.captcha.behavior.enums.StorageType;
import top.charles7c.continew.starter.core.constant.PropertiesConstants;
import top.continew.starter.cache.redisson.autoconfigure.RedissonAutoConfiguration;
import top.continew.starter.captcha.behavior.enums.StorageType;
import top.continew.starter.core.constant.PropertiesConstants;
/**
* 行为验证码缓存配置
* 行为验证码缓存自动配置
*
* @author Bull-BCLS
* @author Charles7c
* @since 1.1.0
*/
public class BehaviorCaptchaCacheConfiguration {
@AutoConfiguration
public class BehaviorCaptchaCacheAutoConfiguration {
private static final Logger log = LoggerFactory.getLogger(BehaviorCaptchaCacheConfiguration.class);
private static final Logger log = LoggerFactory.getLogger(BehaviorCaptchaCacheAutoConfiguration.class);
private BehaviorCaptchaCacheConfiguration() {
private BehaviorCaptchaCacheAutoConfiguration() {
}
/**
* 自定义缓存实现-默认内存
*/
@AutoConfiguration
@ConditionalOnMissingBean(CaptchaCacheService.class)
@ConditionalOnProperty(name = PropertiesConstants.CAPTCHA_BEHAVIOR + ".cache-type", havingValue = "default", matchIfMissing = true)
public static class Default {
@Bean
public CaptchaCacheService captchaCacheService() {
return new CaptchaCacheServiceMemImpl();
}
@PostConstruct
public void postConstruct() {
CaptchaServiceFactory.cacheService.put(StorageType.DEFAULT.name()
.toLowerCase(), new CaptchaCacheServiceMemImpl());
CaptchaServiceFactory.cacheService.put(StorageType.DEFAULT.name().toLowerCase(), captchaCacheService());
log.debug("[ContiNew Starter] - Auto Configuration 'Captcha-Behavior-Cache-Default' completed initialization.");
}
}
@@ -66,15 +72,19 @@ public class BehaviorCaptchaCacheConfiguration {
/**
* 自定义缓存实现-Redis
*/
@ConditionalOnMissingBean(CaptchaCacheService.class)
@AutoConfiguration(before = RedissonAutoConfiguration.class)
@ConditionalOnClass(RedisClient.class)
@AutoConfigureBefore(RedissonAutoConfiguration.class)
@ConditionalOnMissingBean(CaptchaCacheService.class)
@ConditionalOnProperty(name = PropertiesConstants.CAPTCHA_BEHAVIOR + ".cache-type", havingValue = "redis")
public static class Redis {
@Bean
public CaptchaCacheService captchaCacheService() {
return new BehaviorCaptchaCacheServiceImpl();
}
@PostConstruct
public void postConstruct() {
CaptchaServiceFactory.cacheService.put(StorageType.REDIS.name()
.toLowerCase(), new BehaviorCaptchaCacheServiceImpl());
CaptchaServiceFactory.cacheService.put(StorageType.REDIS.name().toLowerCase(), captchaCacheService());
log.debug("[ContiNew Starter] - Auto Configuration 'Captcha-Behavior-Cache-Redis' completed initialization.");
}
}
@@ -82,6 +92,7 @@ public class BehaviorCaptchaCacheConfiguration {
/**
* 自定义缓存实现
*/
@AutoConfiguration
@ConditionalOnProperty(name = PropertiesConstants.CAPTCHA_BEHAVIOR + ".cache-type", havingValue = "custom")
public static class Custom {
@Bean

View File

@@ -14,11 +14,13 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.captcha.behavior.autoconfigure.cache;
package top.continew.starter.captcha.behavior.autoconfigure.cache;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NumberUtil;
import com.anji.captcha.service.CaptchaCacheService;
import top.charles7c.continew.starter.cache.redisson.util.RedisUtils;
import top.charles7c.continew.starter.captcha.behavior.enums.StorageType;
import top.continew.starter.cache.redisson.util.RedisUtils;
import top.continew.starter.captcha.behavior.enums.StorageType;
import java.time.Duration;
@@ -31,12 +33,16 @@ import java.time.Duration;
public class BehaviorCaptchaCacheServiceImpl implements CaptchaCacheService {
@Override
public void set(String key, String value, long expiresInSeconds) {
RedisUtils.set(key, value, Duration.ofSeconds(expiresInSeconds));
if (NumberUtil.isNumber(value)) {
RedisUtils.set(key, Convert.toInt(value), Duration.ofSeconds(expiresInSeconds));
} else {
RedisUtils.set(key, value, Duration.ofSeconds(expiresInSeconds));
}
}
@Override
public boolean exists(String key) {
return RedisUtils.hasKey(key);
return RedisUtils.exists(key);
}
@Override
@@ -46,11 +52,16 @@ public class BehaviorCaptchaCacheServiceImpl implements CaptchaCacheService {
@Override
public String get(String key) {
return RedisUtils.get(key);
return Convert.toStr(RedisUtils.get(key));
}
@Override
public String type() {
return StorageType.REDIS.name().toLowerCase();
}
@Override
public Long increment(String key, long val) {
return RedisUtils.incr(key);
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.captcha.behavior.enums;
package top.continew.starter.captcha.behavior.enums;
/**
* 缓存类型枚举

View File

@@ -1 +1,2 @@
top.charles7c.continew.starter.captcha.behavior.autoconfigure.BehaviorCaptchaAutoConfiguration
top.continew.starter.captcha.behavior.autoconfigure.BehaviorCaptchaAutoConfiguration
top.continew.starter.captcha.behavior.autoconfigure.cache.BehaviorCaptchaCacheAutoConfiguration

View File

@@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter-captcha</artifactId>
<version>${revision}</version>
</parent>

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.captcha.graphic.autoconfigure;
package top.continew.starter.captcha.graphic.autoconfigure;
import jakarta.annotation.PostConstruct;
import org.slf4j.Logger;
@@ -24,8 +24,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import top.charles7c.continew.starter.captcha.graphic.core.GraphicCaptchaService;
import top.charles7c.continew.starter.core.constant.PropertiesConstants;
import top.continew.starter.captcha.graphic.core.GraphicCaptchaService;
import top.continew.starter.core.constant.PropertiesConstants;
/**
* 图形验证码自动配置
@@ -35,7 +35,7 @@ import top.charles7c.continew.starter.core.constant.PropertiesConstants;
*/
@AutoConfiguration
@EnableConfigurationProperties(GraphicCaptchaProperties.class)
@ConditionalOnProperty(prefix = PropertiesConstants.CAPTCHA_GRAPHIC, name = PropertiesConstants.ENABLED, havingValue = "true", matchIfMissing = true)
@ConditionalOnProperty(prefix = PropertiesConstants.CAPTCHA_GRAPHIC, name = PropertiesConstants.ENABLED, matchIfMissing = true)
public class GraphicCaptchaAutoConfiguration {
private static final Logger log = LoggerFactory.getLogger(GraphicCaptchaAutoConfiguration.class);

View File

@@ -14,11 +14,11 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.captcha.graphic.autoconfigure;
package top.continew.starter.captcha.graphic.autoconfigure;
import org.springframework.boot.context.properties.ConfigurationProperties;
import top.charles7c.continew.starter.captcha.graphic.enums.GraphicCaptchaType;
import top.charles7c.continew.starter.core.constant.PropertiesConstants;
import top.continew.starter.captcha.graphic.enums.GraphicCaptchaType;
import top.continew.starter.core.constant.PropertiesConstants;
/**
* 图形验证码配置属性

View File

@@ -14,12 +14,12 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.captcha.graphic.core;
package top.continew.starter.captcha.graphic.core;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.wf.captcha.base.Captcha;
import top.charles7c.continew.starter.captcha.graphic.autoconfigure.GraphicCaptchaProperties;
import top.continew.starter.captcha.graphic.autoconfigure.GraphicCaptchaProperties;
import java.awt.*;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.captcha.graphic.enums;
package top.continew.starter.captcha.graphic.enums;
import com.wf.captcha.*;
import com.wf.captcha.base.Captcha;

View File

@@ -1 +1 @@
top.charles7c.continew.starter.captcha.graphic.autoconfigure.GraphicCaptchaAutoConfiguration
top.continew.starter.captcha.graphic.autoconfigure.GraphicCaptchaAutoConfiguration

View File

@@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter</artifactId>
<version>${revision}</version>
</parent>
@@ -21,7 +21,7 @@
<dependencies>
<!-- 核心模块 -->
<dependency>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter-core</artifactId>
</dependency>
</dependencies>

View File

@@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter</artifactId>
<version>${revision}</version>
</parent>

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.core.autoconfigure.project;
package top.continew.starter.core.autoconfigure.project;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.core.autoconfigure.project;
package top.continew.starter.core.autoconfigure.project;
import org.springframework.boot.context.properties.ConfigurationProperties;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.core.autoconfigure.threadpool;
package top.continew.starter.core.autoconfigure.threadpool;
import cn.hutool.core.util.ArrayUtil;
import org.slf4j.Logger;
@@ -25,8 +25,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import top.charles7c.continew.starter.core.constant.PropertiesConstants;
import top.charles7c.continew.starter.core.exception.BaseException;
import top.continew.starter.core.constant.PropertiesConstants;
import top.continew.starter.core.exception.BaseException;
import java.util.Arrays;
import java.util.concurrent.Executor;

View File

@@ -14,12 +14,13 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.core.autoconfigure.threadpool;
package top.continew.starter.core.autoconfigure.threadpool;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ObjectUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -27,12 +28,16 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import top.charles7c.continew.starter.core.constant.PropertiesConstants;
import top.charles7c.continew.starter.core.util.ExceptionUtils;
import top.continew.starter.core.constant.PropertiesConstants;
import top.continew.starter.core.util.ExceptionUtils;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.RunnableFuture;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 线程池自动配置
@@ -69,6 +74,10 @@ public class ThreadPoolAutoConfiguration {
executor.setKeepAliveSeconds(properties.getKeepAliveSeconds());
// 配置当池内线程数已达到上限的时候该如何处理新任务不在新线程中执行任务而是由调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 关闭线程池是否等待任务完成
executor.setWaitForTasksToCompleteOnShutdown(properties.isWaitForTasksToCompleteOnShutdown());
// 执行器在关闭时阻塞的最长毫秒数以等待剩余任务完成执行
executor.setAwaitTerminationMillis(properties.getAwaitTerminationMillis());
log.debug("[ContiNew Starter] - Auto Configuration 'ThreadPoolTaskExecutor' completed initialization.");
return executor;
}
@@ -88,7 +97,62 @@ public class ThreadPoolAutoConfiguration {
ExceptionUtils.printException(runnable, throwable);
}
};
// 应用关闭时关闭线程池
SpringApplication.getShutdownHandlers().add(() -> shutdown(executor, properties));
log.debug("[ContiNew Starter] - Auto Configuration 'ScheduledExecutorService' completed initialization.");
return executor;
}
/**
* 根据相应的配置设置关闭 ExecutorService
*
* @see org.springframework.scheduling.concurrent.ExecutorConfigurationSupport#shutdown()
*/
public void shutdown(ExecutorService executor, ThreadPoolProperties properties) {
log.debug("[ContiNew Starter] - Shutting down ScheduledExecutorService start.");
if (executor != null) {
if (properties.isWaitForTasksToCompleteOnShutdown()) {
executor.shutdown();
} else {
for (Runnable remainingTask : executor.shutdownNow()) {
cancelRemainingTask(remainingTask);
}
}
awaitTerminationIfNecessary(executor, properties);
log.debug("[ContiNew Starter] - Shutting down ScheduledExecutorService complete.");
}
}
/**
* Cancel the given remaining task which never commenced execution,
* as returned from {@link ExecutorService#shutdownNow()}.
*
* @param task the task to cancel (typically a {@link RunnableFuture})
* @see RunnableFuture#cancel(boolean)
*/
protected void cancelRemainingTask(Runnable task) {
if (task instanceof Future<?> future) {
future.cancel(true);
}
}
/**
* Wait for the executor to terminate, according to the value of the properties
*/
private void awaitTerminationIfNecessary(ExecutorService executor, ThreadPoolProperties properties) {
if (properties.getAwaitTerminationMillis() > 0) {
try {
if (!executor.awaitTermination(properties.getAwaitTerminationMillis(), TimeUnit.MILLISECONDS)) {
if (log.isWarnEnabled()) {
log.warn("[ContiNew Starter] - Timed out while waiting for executor 'ScheduledExecutorService' to terminate.");
}
}
} catch (InterruptedException ex) {
if (log.isWarnEnabled()) {
log.warn("[ContiNew Starter] - Interrupted while waiting for executor 'ScheduledExecutorService' to terminate");
}
Thread.currentThread().interrupt();
}
}
}
}

View File

@@ -14,10 +14,10 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.core.autoconfigure.threadpool;
package top.continew.starter.core.autoconfigure.threadpool;
import org.springframework.boot.context.properties.ConfigurationProperties;
import top.charles7c.continew.starter.core.constant.PropertiesConstants;
import top.continew.starter.core.constant.PropertiesConstants;
/**
* 线程池配置属性
@@ -54,6 +54,16 @@ public class ThreadPoolProperties {
*/
private int keepAliveSeconds = 300;
/**
* 关闭线程池是否等待任务完成
*/
private boolean waitForTasksToCompleteOnShutdown = false;
/**
* 执行器在关闭时阻塞的最长毫秒数以等待剩余任务完成执行
*/
private long awaitTerminationMillis = 0;
public boolean isEnabled() {
return enabled;
}
@@ -93,4 +103,20 @@ public class ThreadPoolProperties {
public void setKeepAliveSeconds(int keepAliveSeconds) {
this.keepAliveSeconds = keepAliveSeconds;
}
public boolean isWaitForTasksToCompleteOnShutdown() {
return waitForTasksToCompleteOnShutdown;
}
public void setWaitForTasksToCompleteOnShutdown(boolean waitForTasksToCompleteOnShutdown) {
this.waitForTasksToCompleteOnShutdown = waitForTasksToCompleteOnShutdown;
}
public long getAwaitTerminationMillis() {
return awaitTerminationMillis;
}
public void setAwaitTerminationMillis(long awaitTerminationMillis) {
this.awaitTerminationMillis = awaitTerminationMillis;
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.core.constant;
package top.continew.starter.core.constant;
/**
* 配置属性相关常量
@@ -37,7 +37,7 @@ public class PropertiesConstants {
/**
* 线程池配置
*/
public static final String THREAD_POOL = CONTINEW_STARTER + ".thread-pool";
public static final String THREAD_POOL = CONTINEW_STARTER + StringConstants.DOT + "thread-pool";
/**
* Spring Doc 配置
@@ -47,7 +47,7 @@ public class PropertiesConstants {
/**
* Spring Doc Swagger UI 配置
*/
public static final String SPRINGDOC_SWAGGER_UI = SPRINGDOC + ".swagger-ui";
public static final String SPRINGDOC_SWAGGER_UI = SPRINGDOC + StringConstants.DOT + "swagger-ui";
/**
* 安全配置
@@ -67,47 +67,62 @@ public class PropertiesConstants {
/**
* Web 配置
*/
public static final String WEB = CONTINEW_STARTER + ".web";
public static final String WEB = CONTINEW_STARTER + StringConstants.DOT + "web";
/**
* 跨域配置
*/
public static final String CORS = WEB + ".cors";
public static final String CORS = WEB + StringConstants.DOT + "cors";
/**
* 链路配置
*/
public static final String TRACE = WEB + ".trace";
public static final String TRACE = WEB + StringConstants.DOT + "trace";
/**
* XSS 配置
*/
public static final String XSS = WEB + StringConstants.DOT + "xss";
/**
* 日志配置
*/
public static final String LOG = CONTINEW_STARTER + ".log";
public static final String LOG = CONTINEW_STARTER + StringConstants.DOT + "log";
/**
* 存储配置
*/
public static final String STORAGE = CONTINEW_STARTER + ".storage";
public static final String STORAGE = CONTINEW_STARTER + StringConstants.DOT + "storage";
/**
* 本地存储配置
*/
public static final String STORAGE_LOCAL = STORAGE + ".local";
public static final String STORAGE_LOCAL = STORAGE + StringConstants.DOT + "local";
/**
* 验证码配置
*/
public static final String CAPTCHA = CONTINEW_STARTER + ".captcha";
public static final String CAPTCHA = CONTINEW_STARTER + StringConstants.DOT + "captcha";
/**
* 图形验证码配置
*/
public static final String CAPTCHA_GRAPHIC = CAPTCHA + ".graphic";
public static final String CAPTCHA_GRAPHIC = CAPTCHA + StringConstants.DOT + "graphic";
/**
* 行为验证码配置
*/
public static final String CAPTCHA_BEHAVIOR = CAPTCHA + ".behavior";
public static final String CAPTCHA_BEHAVIOR = CAPTCHA + StringConstants.DOT + "behavior";
/**
* 消息配置
*/
public static final String MESSAGING = CONTINEW_STARTER + StringConstants.DOT + "messaging";
/**
* WebSocket 配置
*/
public static final String MESSAGING_WEBSOCKET = MESSAGING + StringConstants.DOT + "websocket";
private PropertiesConstants() {
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.core.constant;
package top.continew.starter.core.constant;
import cn.hutool.core.text.CharPool;
import cn.hutool.core.text.StrPool;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.core.exception;
package top.continew.starter.core.exception;
import java.io.Serial;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.core.exception;
package top.continew.starter.core.exception;
import java.io.Serial;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.core.exception;
package top.continew.starter.core.exception;
import java.io.Serial;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.core.util;
package top.continew.starter.core.util;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.TypeUtil;

View File

@@ -14,11 +14,11 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.core.util;
package top.continew.starter.core.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import top.charles7c.continew.starter.core.constant.StringConstants;
import top.continew.starter.core.constant.StringConstants;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.core.util;
package top.continew.starter.core.util;
import cn.hutool.core.text.CharSequenceUtil;
import org.springframework.boot.env.YamlPropertySourceLoader;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.core.util;
package top.continew.starter.core.util;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.net.NetUtil;
@@ -23,7 +23,7 @@ import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.http.HtmlUtil;
import net.dreamlu.mica.ip2region.core.Ip2regionSearcher;
import net.dreamlu.mica.ip2region.core.IpInfo;
import top.charles7c.continew.starter.core.constant.StringConstants;
import top.continew.starter.core.constant.StringConstants;
import java.util.Set;

View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.core.util;
import java.util.Map;
import java.util.Properties;
/**
* Map 工具类
*
* @author Charles7c
* @since 2.1.0
*/
public class MapUtils {
private MapUtils() {
}
/**
* 转换为 Properties 对象
*
* @param source 数据源
* @return Properties 对象
*/
public static Properties toProperties(Map<String, String> source) {
Properties properties = new Properties();
properties.putAll(source);
return properties;
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.core.util;
package top.continew.starter.core.util;
import cn.hutool.core.util.ReflectUtil;

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.core.util;
import cn.hutool.core.text.CharSequenceUtil;
import java.util.function.Function;
/**
* 字符串工具类
*
* @author Charles7c
* @since 2.0.1
*/
public class StrUtils {
private StrUtils() {
}
/**
* 如果字符串是{@code null}或者&quot;&quot;或者空白,则返回指定默认字符串,否则针对字符串处理后返回
*
* @param str 要转换的字符串
* @param defaultValue 默认值
* @param mapper 针对字符串的转换方法
* @return 转换后的字符串或指定的默认字符串
* @since 2.0.1
*/
public static <T> T blankToDefault(CharSequence str, T defaultValue, Function<String, T> mapper) {
return CharSequenceUtil.isBlank(str) ? defaultValue : mapper.apply(str.toString());
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.core.util;
package top.continew.starter.core.util;
import cn.hutool.extra.template.Template;
import cn.hutool.extra.template.TemplateConfig;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.core.util;
package top.continew.starter.core.util;
import cn.hutool.http.HttpUtil;

View File

@@ -14,11 +14,11 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.core.util.validate;
package top.continew.starter.core.util.validate;
import cn.hutool.core.text.CharSequenceUtil;
import top.charles7c.continew.starter.core.constant.StringConstants;
import top.charles7c.continew.starter.core.exception.BusinessException;
import top.continew.starter.core.constant.StringConstants;
import top.continew.starter.core.exception.BusinessException;
import java.util.function.BooleanSupplier;

View File

@@ -14,10 +14,10 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.core.util.validate;
package top.continew.starter.core.util.validate;
import cn.hutool.core.text.CharSequenceUtil;
import top.charles7c.continew.starter.core.exception.BadRequestException;
import top.continew.starter.core.exception.BadRequestException;
import java.util.function.BooleanSupplier;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.core.util.validate;
package top.continew.starter.core.util.validate;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;

View File

@@ -1,3 +1,3 @@
top.charles7c.continew.starter.core.autoconfigure.project.ProjectAutoConfiguration
top.charles7c.continew.starter.core.autoconfigure.threadpool.ThreadPoolAutoConfiguration
top.charles7c.continew.starter.core.autoconfigure.threadpool.AsyncAutoConfiguration
top.continew.starter.core.autoconfigure.project.ProjectAutoConfiguration
top.continew.starter.core.autoconfigure.threadpool.ThreadPoolAutoConfiguration
top.continew.starter.core.autoconfigure.threadpool.AsyncAutoConfiguration

View File

@@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter-data</artifactId>
<version>${revision}</version>
</parent>

View File

@@ -14,9 +14,9 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.data.core.annotation;
package top.continew.starter.data.core.annotation;
import top.charles7c.continew.starter.data.core.enums.QueryType;
import top.continew.starter.data.core.enums.QueryType;
import java.lang.annotation.*;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.data.core.annotation;
package top.continew.starter.data.core.annotation;
import java.lang.annotation.*;

View File

@@ -14,9 +14,9 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.data.core.enums;
package top.continew.starter.data.core.enums;
import top.charles7c.continew.starter.data.core.function.ISqlFunction;
import top.continew.starter.data.core.function.ISqlFunction;
import java.io.Serializable;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.data.core.enums;
package top.continew.starter.data.core.enums;
/**
* 查询类型枚举

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.data.core.function;
package top.continew.starter.data.core.function;
import java.io.Serializable;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.data.core.util;
package top.continew.starter.data.core.util;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
@@ -22,8 +22,8 @@ import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.db.meta.Column;
import cn.hutool.db.meta.MetaUtil;
import top.charles7c.continew.starter.core.exception.BusinessException;
import top.charles7c.continew.starter.data.core.enums.DatabaseType;
import top.continew.starter.core.exception.BusinessException;
import top.continew.starter.data.core.enums.DatabaseType;
import javax.sql.DataSource;
import java.sql.Connection;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.data.core.util;
package top.continew.starter.data.core.util;
import java.io.Serial;
import java.io.Serializable;

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.continew</groupId>
<artifactId>continew-starter-data</artifactId>
<version>${revision}</version>
</parent>
<artifactId>continew-starter-data-mybatis-flex</artifactId>
<description>ContiNew Starter 数据访问模块 - MyBatis Flex</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- MyBatis PlusMyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,简化开发、提高效率) -->
<dependency>
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-spring-boot3-starter</artifactId>
</dependency>
<dependency>
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-processor</artifactId>
<scope>provided</scope>
</dependency>
<!-- 数据访问模块 - 核心模块 -->
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-data-core</artifactId>
</dependency>
<!-- CosId通用、灵活、高性能的分布式 ID 生成器) -->
<dependency>
<groupId>me.ahoo.cosid</groupId>
<artifactId>cosid-spring-boot-starter</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.data.mybatis.flex.autoconfigure;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import top.continew.starter.core.constant.PropertiesConstants;
import java.lang.annotation.*;
/**
* 是否启用数据权限注解
*
* @author hellokaton
* @since 2.0.2
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Documented
@ConditionalOnProperty(prefix = "mybatis-flex.extension.data-permission", name = PropertiesConstants.ENABLED, havingValue = "true")
public @interface ConditionalOnEnabledDataPermission {
}

View File

@@ -0,0 +1,162 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.data.mybatis.flex.autoconfigure;
import com.mybatisflex.core.dialect.DbType;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* MyBatis Plus 扩展配置属性
*
* @author Charles7c
* @since 1.0.0
*/
@ConfigurationProperties(prefix = "mybatis-flex.extension")
public class MyBatisFlexExtensionProperties {
/**
* 是否启用扩展
*/
private boolean enabled = false;
/**
* Mapper 接口扫描包配置时必须使用mapper-package 键名)
* <p>
* e.g. com.example.**.mapper
* </p>
*/
private String mapperPackage;
/**
* 数据权限插件配置
*/
private DataPermissionProperties dataPermission;
/**
* 分页插件配置
*/
private PaginationProperties pagination;
/**
* 数据权限插件配置属性
*/
public static class DataPermissionProperties {
/**
* 是否启用数据权限插件
*/
private boolean enabled = false;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
/**
* 分页插件配置属性
*/
public static class PaginationProperties {
/**
* 是否启用分页插件
*/
private boolean enabled = true;
/**
* 数据库类型
*/
private DbType dbType;
/**
* 是否溢出处理
*/
private boolean overflow = false;
/**
* 单页分页条数限制(默认:-1 表示无限制)
*/
private Long maxLimit = -1L;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public DbType getDbType() {
return dbType;
}
public void setDbType(DbType dbType) {
this.dbType = dbType;
}
public boolean isOverflow() {
return overflow;
}
public void setOverflow(boolean overflow) {
this.overflow = overflow;
}
public Long getMaxLimit() {
return maxLimit;
}
public void setMaxLimit(Long maxLimit) {
this.maxLimit = maxLimit;
}
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getMapperPackage() {
return mapperPackage;
}
public void setMapperPackage(String mapperPackage) {
this.mapperPackage = mapperPackage;
}
public DataPermissionProperties getDataPermission() {
return dataPermission;
}
public void setDataPermission(DataPermissionProperties dataPermission) {
this.dataPermission = dataPermission;
}
public PaginationProperties getPagination() {
return pagination;
}
public void setPagination(PaginationProperties pagination) {
this.pagination = pagination;
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.data.mybatis.flex.autoconfigure;
import com.mybatisflex.core.dialect.DbType;
import com.mybatisflex.core.dialect.DialectFactory;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import top.continew.starter.core.constant.PropertiesConstants;
import top.continew.starter.core.util.GeneralPropertySourceFactory;
import top.continew.starter.data.mybatis.flex.datapermission.DataPermissionDialect;
import top.continew.starter.data.mybatis.flex.datapermission.DataPermissionFilter;
/**
* MyBatis Flex 自动配置
*
* @author hellokaton
* @since 2.0.2
*/
@AutoConfiguration
@MapperScan("${mybatis-flex.extension.mapper-package}")
@EnableTransactionManagement(proxyTargetClass = true)
@EnableConfigurationProperties(MyBatisFlexExtensionProperties.class)
@ConditionalOnProperty(prefix = "mybatis-flex.extension", name = PropertiesConstants.ENABLED, havingValue = "true")
@PropertySource(value = "classpath:default-data-mybatis-flex.yml", factory = GeneralPropertySourceFactory.class)
public class MybatisFlexAutoConfiguration {
private static final Logger log = LoggerFactory.getLogger(MybatisFlexAutoConfiguration.class);
@Resource
private DataPermissionFilter dataPermissionFilter;
@PostConstruct
public void postConstruct() {
log.debug("[ContiNew Starter] - Auto Configuration 'MyBatis Flex' completed initialization.");
DialectFactory.registerDialect(DbType.MYSQL, new DataPermissionDialect(dataPermissionFilter));
}
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.data.mybatis.flex.base;
import cn.hutool.core.util.ClassUtil;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.Db;
import java.util.Collection;
/**
* Mapper 基类
*
* @param <T> 实体类
* @author hellokaton
* @since 1.0.0
*/
public interface BaseMapper<T> extends com.mybatisflex.core.BaseMapper<T> {
/**
* 批量更新记录
*
* @param entityList 实体列表
* @return 是否成功
*/
default boolean updateBatchById(Collection<T> entityList) {
return Db.updateEntitiesBatch(entityList) > 0;
}
/**
* 链式查询
*
* @return QueryWrapper 的包装类
*/
default QueryWrapper query() {
return QueryWrapper.create();
}
/**
* 链式查询
*
* @return QueryWrapper 的包装类
*/
default QueryWrapper query(T entity) {
return QueryWrapper.create(entity);
}
/**
* 获取实体类 Class 对象
*
* @return 实体类 Class 对象
*/
default Class<T> currentEntityClass() {
return (Class<T>)ClassUtil.getTypeArgument(this.getClass(), 0);
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.data.mybatis.flex.base;
import java.io.Serializable;
/**
* 枚举接口
*
* @param <T> value 类型
* @author hellokaton
* @since 1.0.0
*/
public interface IBaseEnum<T extends Serializable> {
/**
* 枚举描述
*
* @return 枚举描述
*/
String getDescription();
/**
* 枚举数据库存储值
*/
T getValue();
/**
* 颜色
*
* @return 颜色
*/
default String getColor() {
return null;
}
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.data.mybatis.flex.datapermission;
import org.springframework.core.annotation.AliasFor;
import java.lang.annotation.*;
/**
* 数据权限注解
*
* @author hellokaton
* @since 2.0.2
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataPermission {
/**
* Alias for the {@link #tableAlias()} attribute.
*/
@AliasFor("tableAlias")
String value() default "";
/**
* 表别名
*/
@AliasFor("value")
String tableAlias() default "";
/**
* ID
*/
String id() default "id";
/**
* 部门 ID
*/
String deptId() default "dept_id";
/**
* 用户 ID
*/
String userId() default "create_user";
/**
* 角色 ID角色和部门关联表
*/
String roleId() default "role_id";
/**
* 部门表别名
*/
String deptTableAlias() default "sys_dept";
/**
* 角色和部门关联表别名
*/
String roleDeptTableAlias() default "sys_role_dept";
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.data.mybatis.flex.datapermission;
import org.aspectj.lang.annotation.*;
@Aspect
public class DataPermissionAspect {
// ThreadLocal用于存储注解信息
private static final ThreadLocal<DataPermission> THREAD_LOCAL = new ThreadLocal<>();
@Pointcut("@annotation(dataPermission)")
public void dataPermissionPointcut(DataPermission dataPermission) {
}
@Before("dataPermissionPointcut(dataPermission)")
public void beforeMethod(DataPermission dataPermission) {
THREAD_LOCAL.set(dataPermission);
}
@AfterThrowing(pointcut = "dataPermissionPointcut(dataPermission)")
public void afterThrowingMethod(DataPermission dataPermission) {
THREAD_LOCAL.remove();
}
@After("dataPermissionPointcut(dataPermission)")
public void afterMethod(DataPermission dataPermission) {
THREAD_LOCAL.remove();
}
public static DataPermission currentDataPermission() {
return THREAD_LOCAL.get();
}
}

View File

@@ -0,0 +1,107 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.data.mybatis.flex.datapermission;
import java.util.Set;
/**
* 当前用户信息
*
* @author hellokaton
* @since 2.0.2
*/
public class DataPermissionCurrentUser {
/**
* 用户 ID
*/
private String userId;
/**
* 角色列表
*/
private Set<CurrentUserRole> roles;
/**
* 部门 ID
*/
private String deptId;
/**
* 当前用户角色信息
*/
public static class CurrentUserRole {
/**
* 角色 ID
*/
private String roleId;
/**
* 数据权限
*/
private DataScope dataScope;
public CurrentUserRole() {
}
public CurrentUserRole(String roleId, DataScope dataScope) {
this.roleId = roleId;
this.dataScope = dataScope;
}
public String getRoleId() {
return roleId;
}
public void setRoleId(String roleId) {
this.roleId = roleId;
}
public DataScope getDataScope() {
return dataScope;
}
public void setDataScope(DataScope dataScope) {
this.dataScope = dataScope;
}
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public Set<CurrentUserRole> getRoles() {
return roles;
}
public void setRoles(Set<CurrentUserRole> roles) {
this.roles = roles;
}
public String getDeptId() {
return deptId;
}
public void setDeptId(String deptId) {
this.deptId = deptId;
}
}

View File

@@ -0,0 +1,161 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.data.mybatis.flex.datapermission;
import cn.hutool.core.util.StrUtil;
import com.mybatisflex.core.dialect.impl.CommonsDialectImpl;
import com.mybatisflex.core.query.QueryWrapper;
import java.util.Set;
/**
* 数据权限处理器实现类
*
* @author <a href="https://mybatis-flex.com/zh/core/data-permission.html">数据权限</a>
* @author hellokaton
* @since 2.0.2
*/
public class DataPermissionDialect extends CommonsDialectImpl {
private final DataPermissionFilter dataPermissionFilter;
public DataPermissionDialect(DataPermissionFilter dataPermissionFilter) {
this.dataPermissionFilter = dataPermissionFilter;
}
@Override
public String forSelectByQuery(QueryWrapper queryWrapper) {
if (!dataPermissionFilter.isFilter()) {
return super.buildSelectSql(queryWrapper);
}
DataPermission dataPermission = DataPermissionAspect.currentDataPermission();
if (null == dataPermission) {
return super.buildSelectSql(queryWrapper);
}
DataPermissionCurrentUser currentUser = dataPermissionFilter.getCurrentUser();
Set<DataPermissionCurrentUser.CurrentUserRole> roles = currentUser.getRoles();
for (DataPermissionCurrentUser.CurrentUserRole role : roles) {
DataScope dataScope = role.getDataScope();
if (DataScope.ALL.equals(dataScope)) {
return super.buildSelectSql(queryWrapper);
}
switch (dataScope) {
case DEPT_AND_CHILD -> this.buildDeptAndChildExpression(dataPermission, currentUser, queryWrapper);
case DEPT -> this.buildDeptExpression(dataPermission, currentUser, queryWrapper);
case SELF -> this.buildSelfExpression(dataPermission, currentUser, queryWrapper);
case CUSTOM -> this.buildCustomExpression(dataPermission, role, queryWrapper);
default -> throw new IllegalArgumentException("暂不支持 [%s] 数据权限".formatted(dataScope));
}
}
return super.buildSelectSql(queryWrapper);
}
/**
* 构建自定义数据权限表达式
*
* <p>
* 处理完后的 SQL 示例:<br /> select t1.* from table as t1 where t1.dept_id in (select dept_id from sys_role_dept
* where role_id = xxx);
* </p>
*
* @param dataPermission 数据权限
* @param role 当前用户角色
* @param queryWrapper 查询条件
* @return 处理完后的表达式
*/
private void buildCustomExpression(DataPermission dataPermission,
DataPermissionCurrentUser.CurrentUserRole role,
QueryWrapper queryWrapper) {
QueryWrapper subQueryWrapper = QueryWrapper.create();
subQueryWrapper.select(dataPermission.deptId()).from(dataPermission.roleDeptTableAlias());
subQueryWrapper.eq(dataPermission.roleId(), role.getRoleId());
queryWrapper.in(buildColumn(dataPermission.tableAlias(), dataPermission.deptId()), subQueryWrapper);
}
/**
* 构建仅本人数据权限表达式
*
* <p>
* 处理完后的 SQL 示例:<br /> select t1.* from table as t1 where t1.create_user = xxx;
* </p>
*
* @param dataPermission 数据权限
* @param currentUser 当前用户
* @param queryWrapper 处理前的表达式
*/
private void buildSelfExpression(DataPermission dataPermission,
DataPermissionCurrentUser currentUser,
QueryWrapper queryWrapper) {
queryWrapper.eq(buildColumn(dataPermission.tableAlias(), dataPermission.userId()), currentUser.getUserId());
}
/**
* 构建本部门数据权限表达式
*
* <p>
* 处理完后的 SQL 示例:<br /> select t1.* from table as t1 where t1.dept_id = xxx;
* </p>
*
* @param dataPermission 数据权限
* @param currentUser 当前用户
* @param queryWrapper 查询条件
*/
private void buildDeptExpression(DataPermission dataPermission,
DataPermissionCurrentUser currentUser,
QueryWrapper queryWrapper) {
queryWrapper.eq(buildColumn(dataPermission.tableAlias(), dataPermission.deptId()), currentUser.getDeptId());
}
/**
* 构建本部门及以下数据权限表达式
*
* <p>
* 处理完后的 SQL 示例:<br /> select t1.* from table as t1 where t1.dept_id in (select id from sys_dept where id =
* xxx or find_in_set(xxx, ancestors));
* </p>
*
* @param dataPermission 数据权限
* @param currentUser 当前用户
* @param queryWrapper 查询条件
*/
private void buildDeptAndChildExpression(DataPermission dataPermission,
DataPermissionCurrentUser currentUser,
QueryWrapper queryWrapper) {
QueryWrapper subQueryWrapper = QueryWrapper.create();
subQueryWrapper.select(dataPermission.id()).from(dataPermission.deptTableAlias());
subQueryWrapper.and(qw -> {
qw.eq(dataPermission.id(), currentUser.getDeptId())
.or("find_in_set(" + currentUser.getDeptId() + ",ancestors)");
});
queryWrapper.in(buildColumn(dataPermission.tableAlias(), dataPermission.deptId()), subQueryWrapper);
}
/**
* 构建 Column
*
* @param tableAlias 表别名
* @param columnName 字段名称
* @return 带表别名字段
*/
private String buildColumn(String tableAlias, String columnName) {
if (StrUtil.isNotEmpty(tableAlias)) {
return "%s.%s".formatted(tableAlias, columnName);
}
return columnName;
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.data.mybatis.flex.datapermission;
/**
* 数据权限过滤器接口
*
* @author hellokaton
* @since 2.0.2
*/
public interface DataPermissionFilter {
/**
* 是否过滤
*
* @return true过滤false不过滤
*/
boolean isFilter();
/**
* 获取当前用户信息
*
* @return 当前用户信息
*/
DataPermissionCurrentUser getCurrentUser();
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.data.mybatis.flex.datapermission;
/**
* 数据权限枚举
*
* @author hellokaton
* @since 2.0.2
*/
public enum DataScope {
/**
* 全部数据权限
*/
ALL,
/**
* 本部门及以下数据权限
*/
DEPT_AND_CHILD,
/**
* 本部门数据权限
*/
DEPT,
/**
* 仅本人数据权限
*/
SELF,
/**
* 自定义数据权限
*/
CUSTOM,
}

View File

@@ -0,0 +1,193 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.data.mybatis.flex.query;
import com.mybatisflex.core.query.QueryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.text.CharSequenceUtil;
import top.continew.starter.core.exception.BadRequestException;
import top.continew.starter.core.util.ReflectUtils;
import top.continew.starter.core.util.validate.ValidationUtils;
import top.continew.starter.data.core.annotation.Query;
import top.continew.starter.data.core.annotation.QueryIgnore;
import top.continew.starter.data.core.enums.QueryType;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
/**
* QueryWrapper 助手
*
* @author hellokaton
* @author Jasmine
* @since 1.0.0
*/
public class QueryWrapperHelper {
private static final Logger log = LoggerFactory.getLogger(QueryWrapperHelper.class);
private QueryWrapperHelper() {
}
/**
* 构建 QueryWrapper
*
* @param query 查询条件
* @param <Q> 查询条件数据类型
* @param <R> 查询数据类型
* @return QueryWrapper
*/
public static <Q, R> QueryWrapper build(Q query) {
QueryWrapper queryWrapper = QueryWrapper.create();
// 没有查询条件,直接返回
if (null == query) {
return queryWrapper;
}
// 获取查询条件中所有的字段
List<Field> fieldList = ReflectUtils.getNonStaticFields(query.getClass());
return build(query, fieldList, queryWrapper);
}
/**
* 构建 QueryWrapper
*
* @param query 查询条件
* @param fields 查询条件字段列表
* @param queryWrapper QueryWrapper
* @param <Q> 查询条件数据类型
* @return QueryWrapper
*/
public static <Q> QueryWrapper build(Q query, List<Field> fields, QueryWrapper queryWrapper) {
// 没有查询条件,直接返回
if (null == query) {
return queryWrapper;
}
// 解析并拼接查询条件
for (Field field : fields) {
List<Consumer<QueryWrapper>> consumers = buildWrapperConsumer(query, field);
if (CollUtil.isNotEmpty(consumers)) {
consumers.forEach(queryWrapper::and);
}
}
return queryWrapper;
}
/**
* 构建 QueryWrapper Consumer
*
* @param query 查询条件
* @param field 查询条件字段
* @param <Q> 查询条件数据类型
* @param <R> 查询数据类型
* @return QueryWrapper Consumer
*/
private static <Q, R> List<Consumer<QueryWrapper>> buildWrapperConsumer(Q query, Field field) {
boolean accessible = field.canAccess(query);
try {
field.setAccessible(true);
// 如果字段值为空,直接返回
Object fieldValue = field.get(query);
if (ObjectUtil.isEmpty(fieldValue)) {
return Collections.emptyList();
}
// 设置了 @QueryIgnore 注解,直接忽略
QueryIgnore queryIgnoreAnnotation = field.getAnnotation(QueryIgnore.class);
if (null != queryIgnoreAnnotation && queryIgnoreAnnotation.value()) {
return Collections.emptyList();
}
// 建议:数据库表列建议采用下划线连接法命名,程序变量建议采用驼峰法命名
String fieldName = field.getName();
// 没有 @Query 注解,默认等值查询
Query queryAnnotation = field.getAnnotation(Query.class);
if (null == queryAnnotation) {
return Collections.singletonList(q -> q.eq(CharSequenceUtil.toUnderlineCase(fieldName), fieldValue));
}
// 解析单列查询
QueryType queryType = queryAnnotation.type();
String[] columns = queryAnnotation.columns();
final int columnLength = ArrayUtil.length(columns);
List<Consumer<QueryWrapper>> consumers = new ArrayList<>(columnLength);
if (columnLength <= 1) {
String columnName = columnLength == 1 ? columns[0] : CharSequenceUtil.toUnderlineCase(fieldName);
parse(queryType, columnName, fieldValue, consumers);
return consumers;
}
// 解析多列查询
for (String column : columns) {
parse(queryType, column, fieldValue, consumers);
}
return consumers;
} catch (BadRequestException e) {
throw e;
} catch (Exception e) {
log.error("Build query wrapper occurred an error: {}. Query: {}, Field: {}.", e
.getMessage(), query, field, e);
} finally {
field.setAccessible(accessible);
}
return Collections.emptyList();
}
/**
* 解析查询条件
*
* @param queryType 查询类型
* @param columnName 列名
* @param fieldValue 字段值
* @param <R> 查询数据类型
*/
private static <R> void parse(QueryType queryType,
String columnName,
Object fieldValue,
List<Consumer<QueryWrapper>> consumers) {
switch (queryType) {
case EQ -> consumers.add(q -> q.eq(columnName, fieldValue));
case NE -> consumers.add(q -> q.ne(columnName, fieldValue));
case GT -> consumers.add(q -> q.gt(columnName, fieldValue));
case GE -> consumers.add(q -> q.ge(columnName, fieldValue));
case LT -> consumers.add(q -> q.lt(columnName, fieldValue));
case LE -> consumers.add(q -> q.le(columnName, fieldValue));
case BETWEEN -> {
List<Object> between = new ArrayList<>((List<Object>)fieldValue);
ValidationUtils.throwIf(between.size() != 2, "[{}] 必须是一个范围", columnName);
consumers.add(q -> q.between(columnName, between.get(0), between.get(1)));
}
case LIKE -> consumers.add(q -> q.like(columnName, fieldValue));
case LIKE_LEFT -> consumers.add(q -> q.likeLeft(columnName, fieldValue));
case LIKE_RIGHT -> consumers.add(q -> q.likeRight(columnName, fieldValue));
case IN -> {
ValidationUtils.throwIfEmpty(fieldValue, "[{}] 不能为空", columnName);
consumers.add(q -> q.in(columnName, (Collection<Object>)fieldValue));
}
case NOT_IN -> {
ValidationUtils.throwIfEmpty(fieldValue, "[{}] 不能为空", columnName);
consumers.add(q -> q.notIn(columnName, (Collection<Object>)fieldValue));
}
case IS_NULL -> consumers.add(q -> q.isNull(columnName));
case IS_NOT_NULL -> consumers.add(q -> q.isNotNull(columnName));
default -> throw new IllegalArgumentException("暂不支持 [%s] 查询类型".formatted(queryType));
}
}
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.data.mybatis.flex.service;
/**
* 通用业务接口
*
* @param <T> 实体类型
* @author hellokaton
* @since 1.2.0
*/
public interface IService<T> extends com.mybatisflex.core.service.IService<T> {
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.data.mybatis.flex.service.impl;
import top.continew.starter.core.util.ClassUtils;
import top.continew.starter.data.mybatis.flex.base.BaseMapper;
import top.continew.starter.data.mybatis.flex.service.IService;
/**
* 通用业务实现类
*
* @param <M> Mapper 接口
* @param <T> 实体类型
* @author hellokaton
* @since 1.5.0
*/
public class ServiceImpl<M extends BaseMapper<T>, T> extends com.mybatisflex.spring.service.impl.ServiceImpl<M, T> implements IService<T> {
protected final Class<?>[] typeArguments = ClassUtils.getTypeArguments(this.getClass());
protected final Class<T> entityClass = currentModelClass();
protected Class<T> currentModelClass() {
return (Class<T>)this.typeArguments[1];
}
}

View File

@@ -0,0 +1 @@
top.continew.starter.data.mybatis.flex.autoconfigure.MybatisFlexAutoConfiguration

View File

@@ -0,0 +1,22 @@
--- ### MyBatis Flex 配置https://mybatis-flex.com/zh/base/configuration.html
mybatis-flex:
# 启动时是否检查 MyBatis XML 文件的存在默认false 不检查)
check-config-location: true
## MyBatis 原生支持配置
configuration:
# 是否开启自动驼峰命名规则camel case映射即从经典数据库列名 A_COLUMN下划线命名到经典 Java 属性名 aColumn驼峰命名的类似映射
# 此属性在 MyBatis 中原默认值为 false在 MyBatis-Plus 中,此属性也将用于生成最终的 SQL 的 select body如果您的数据库命名符合规则无需使用 @TableField 注解指定数据库字段名
map-underscore-to-camel-case: true
# MyBatis 自动映射时未知列或未知属性处理策略,通过该配置可指定 MyBatis 在自动映射过程中遇到未知列或者未知属性时如何处理
# NONE不做任何处理 (默认值)WARNING以日志的形式打印相关警告信息FAILING当作映射失败处理并抛出异常和详细信息
auto-mapping-unknown-column-behavior: NONE
# 日志配置
# 默认org.apache.ibatis.logging.slf4j.Slf4jImpl
# 更详细会有性能损耗org.apache.ibatis.logging.stdout.StdOutImpl
# 关闭(可单纯使用 p6spy 分析org.apache.ibatis.logging.nologging.NoLoggingImpl
log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
global-config:
key-config:
key-type: generator
# flexId 主键生成器 com.mybatisflex.core.keygen.impl.FlexIDKeyGenerator
value: flexId

View File

@@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter-data</artifactId>
<version>${revision}</version>
</parent>
@@ -33,7 +33,7 @@
<!-- 数据访问模块 - 核心模块 -->
<dependency>
<groupId>top.charles7c.continew</groupId>
<groupId>top.continew</groupId>
<artifactId>continew-starter-data-core</artifactId>
</dependency>

View File

@@ -14,10 +14,10 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.data.mybatis.plus.autoconfigure;
package top.continew.starter.data.mybatis.plus.autoconfigure;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import top.charles7c.continew.starter.core.constant.PropertiesConstants;
import top.continew.starter.core.constant.PropertiesConstants;
import java.lang.annotation.*;

View File

@@ -14,12 +14,12 @@
* limitations under the License.
*/
package top.charles7c.continew.starter.data.mybatis.plus.autoconfigure;
package top.continew.starter.data.mybatis.plus.autoconfigure;
import com.baomidou.mybatisplus.annotation.DbType;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import top.charles7c.continew.starter.data.mybatis.plus.autoconfigure.idgenerator.MyBatisPlusIdGeneratorProperties;
import top.continew.starter.data.mybatis.plus.autoconfigure.idgenerator.MyBatisPlusIdGeneratorProperties;
/**
* MyBatis Plus 扩展配置属性

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