Compare commits
261 Commits
OLD
...
406f20f7cb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
406f20f7cb | ||
|
|
fb130a65f3 | ||
|
|
8847f3edef | ||
|
|
18bb9f9c95 | ||
|
|
979f2aa5f0 | ||
|
|
189930f0ab | ||
|
|
3c78e2bb53 | ||
|
|
63dc394c54 | ||
|
|
f24137eb8f | ||
|
|
504fc94b8c | ||
|
|
6ef6a344c6 | ||
|
|
5e3e0890f3 | ||
|
|
b7a7fca5f3 | ||
|
|
6adfe238be | ||
|
|
c1eac2a224 | ||
|
|
c5b01251d8 | ||
|
|
d40232d335 | ||
|
|
f37ea57bce | ||
|
|
b366869a00 | ||
|
|
a8e2887bbf | ||
|
|
92b772373b | ||
|
|
8f433a2594 | ||
|
|
e0db7a251c | ||
|
|
84bb7410cf | ||
|
|
2d75478bb7 | ||
|
|
5e47425ab5 | ||
|
|
a4d6306259 | ||
|
|
852eb05cbf | ||
|
|
90f98d66cc | ||
|
|
bf6e0dd952 | ||
|
|
04da9f9c02 | ||
|
|
b4525cd1a6 | ||
|
|
b51f113053 | ||
|
|
685cc3d92c | ||
|
|
e512fc29e0 | ||
|
|
5d19f5589a | ||
|
|
d6be017f37 | ||
|
|
db5bda1bba | ||
|
|
c9929c84d2 | ||
|
|
f91ecee6cc | ||
|
|
142c24ca90 | ||
|
|
a59dd25156 | ||
|
|
d23500d656 | ||
|
|
fe8d987527 | ||
|
|
a3ec97fec1 | ||
|
|
ea37855991 | ||
|
|
c54a0db6ab | ||
|
|
f0633dfcea | ||
|
|
ccfdd18516 | ||
|
|
f4ce15986c | ||
|
|
46da855dd4 | ||
|
|
b06d2503a4 | ||
|
|
b2c882f70f | ||
|
|
c8899a20a4 | ||
|
|
59e5777e28 | ||
|
|
c724387a16 | ||
|
|
ced025e292 | ||
|
|
37e264491f | ||
|
|
d379f79869 | ||
|
|
be4adbe00b | ||
| 33fc749363 | |||
|
|
eb5978eb9d | ||
|
|
db7dbcc97e | ||
|
|
cba659010a | ||
| 0a8c05e1df | |||
|
|
7a961d63a6 | ||
|
|
16779413a6 | ||
|
|
c0c2e492b8 | ||
|
|
023d35fecd | ||
| 895ae7383a | |||
|
|
0d12345ed4 | ||
| e6c1041202 | |||
| d7b36d9f59 | |||
| fb81670776 | |||
| f22189bc00 | |||
|
|
74d030a97e | ||
|
|
609bef8a87 | ||
| 0fa91a472d | |||
|
|
bdd3f251a2 | ||
| 4a0b1499c7 | |||
| 74064a4dc4 | |||
| 4c4f1acf32 | |||
|
|
92246a6767 | ||
|
|
6419f88c63 | ||
|
|
eee546fcc4 | ||
| 714b759050 | |||
|
|
2d3024b3e7 | ||
|
|
8b79ae515d | ||
|
|
8ccfe35b49 | ||
|
|
b12f104161 | ||
|
|
a9bb36dacc | ||
| 8a73e9bec4 | |||
| 0002cf457d | |||
| 01748fe738 | |||
| bf2956c51c | |||
| 1e9baade51 | |||
| 0babec14cf | |||
| 4806918ef9 | |||
| 0c87b1d63e | |||
| cbaa3e7c42 | |||
| 30f8584d33 | |||
|
|
29e43f6e36 | ||
|
|
985b82c604 | ||
|
|
54cc4c4ba5 | ||
|
|
302e085a18 | ||
|
|
ff174056a0 | ||
|
|
c2a9f58926 | ||
| c80d8909dd | |||
| e04a663fdb | |||
| b92f6a6f53 | |||
| 99e64a9295 | |||
| c13efa788c | |||
| ea916df3ce | |||
| 3b7501458a | |||
| f301ea5840 | |||
| 084dad491e | |||
|
|
0bb060b273 | ||
|
|
4e9ab30d68 | ||
|
|
454bdd44bc | ||
|
|
2fa20aaaf3 | ||
|
|
d017e2bb64 | ||
|
|
e2f398b794 | ||
|
|
664d845ea4 | ||
|
|
5b3809abd9 | ||
|
|
9fbc14c171 | ||
|
|
bc1b97f720 | ||
|
|
f5c6125d74 | ||
|
|
4ed71fdf5d | ||
|
|
ab3bcda857 | ||
|
|
68575d141c | ||
|
|
dd535bfa50 | ||
|
|
47394d92ae | ||
|
|
2644ed4368 | ||
|
|
c09c7e4ca8 | ||
|
|
ce83324c44 | ||
|
|
9ad9895510 | ||
|
|
f489ef45fd | ||
|
|
f1b3ca650d | ||
|
|
42bf932d86 | ||
|
|
1ccbfa2881 | ||
|
|
6e4155a146 | ||
|
|
0bc4148a34 | ||
|
|
6a4245f541 | ||
|
|
660dfa6a1e | ||
|
|
62f81adc74 | ||
|
|
21ed5ef781 | ||
|
|
073cda31e8 | ||
|
|
a845cf66ce | ||
|
|
d2eb733ab3 | ||
|
|
f09c1fa47f | ||
|
|
4716b3c977 | ||
|
|
aa2de6a6f2 | ||
|
|
e9df8f01a1 | ||
|
|
9793f97613 | ||
|
|
ea6117cf4e | ||
|
|
a8afdce2fa | ||
|
|
7b78527e6d | ||
|
|
5a20edaff8 | ||
|
|
c054f3e3e8 | ||
|
|
1ba6a55e93 | ||
|
|
72cde4c5cf | ||
|
|
050905fbc0 | ||
|
|
135a135d0f | ||
|
|
0c4f58fd23 | ||
|
|
a6344a2662 | ||
|
|
9527c95734 | ||
|
|
fcf41c68da | ||
|
|
c7436ec289 | ||
|
|
90f80a7d27 | ||
|
|
4aeafb8ab1 | ||
|
|
d8093fffe9 | ||
|
|
33ce250371 | ||
|
|
88841b7ed0 | ||
|
|
1a93fe4d95 | ||
|
|
251db3a146 | ||
|
|
18cba6b975 | ||
|
|
a6792705ba | ||
|
|
02fb771994 | ||
|
|
6ebea15fb3 | ||
|
|
76f1ddc9fe | ||
|
|
198b0856af | ||
|
|
0ab467dc6c | ||
|
|
b920a748ed | ||
|
|
4e0c6b80b7 | ||
|
|
16a06edb89 | ||
|
|
53e63c8b8e | ||
|
|
00f65d91ab | ||
|
|
f3aaa771f6 | ||
|
|
5f31b9c27e | ||
|
|
01afc4505f | ||
|
|
b340bff225 | ||
|
|
74c71156f0 | ||
|
|
90c231221f | ||
|
|
58b0d14340 | ||
|
|
d72be1a446 | ||
|
|
157afb3673 | ||
|
|
0ae219e942 | ||
|
|
377afbb8fc | ||
|
|
64e2fc9912 | ||
|
|
3e25d18463 | ||
|
|
37e052ef62 | ||
|
|
aa0e1f91c5 | ||
|
|
242f536986 | ||
|
|
df7f6950d1 | ||
|
|
3f384fbe79 | ||
|
|
7c9b86a304 | ||
|
|
917050e543 | ||
|
|
6f96216248 | ||
|
|
fcb88e5a94 | ||
|
|
37f2b63038 | ||
|
|
b59ed7d7d6 | ||
|
|
3a9fbb563e | ||
|
|
ec8dda127a | ||
|
|
59f6693005 | ||
|
|
7a570300b5 | ||
|
|
4174c15934 | ||
|
|
891f908522 | ||
|
|
d52a5bcbe5 | ||
|
|
7da7481887 | ||
|
|
71c9a7589d | ||
|
|
3b091cbd4a | ||
|
|
df4996096c | ||
|
|
f148232f0a | ||
|
|
2318ce903d | ||
|
|
83df81583c | ||
|
|
aa3b050b3f | ||
|
|
4605289348 | ||
|
|
fc0a41a4e6 | ||
|
|
1382d2a32d | ||
|
|
97fc6d0367 | ||
|
|
52890e6e6e | ||
|
|
259e948325 | ||
|
|
9859bb1360 | ||
|
|
f03f441cb4 | ||
|
|
92782b9407 | ||
|
|
0573b66ddc | ||
|
|
fb40f307b9 | ||
|
|
2e435497b9 | ||
|
|
32e95e858e | ||
|
|
92b698a313 | ||
|
|
bcc9d7c757 | ||
|
|
8d214bc4d1 | ||
|
|
7bb6d625e4 | ||
|
|
2401ec2c62 | ||
|
|
7fdd8ef871 | ||
|
|
4f7ada223a | ||
|
|
88e22c270d | ||
|
|
19f4eb29bb | ||
|
|
37e297626b | ||
|
|
0b0edfa7a5 | ||
|
|
c56dd18064 | ||
|
|
d6bb477219 | ||
|
|
aea62eb6e2 | ||
|
|
76d5cccf95 | ||
|
|
d27352ecbc | ||
|
|
c46dbc512b | ||
|
|
aeb3576be6 | ||
|
|
afddd03fda | ||
|
|
a37997583a | ||
|
|
8976a867e3 | ||
|
|
fdef3ed7ad |
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,36 +0,0 @@
|
||||
---
|
||||
name: Bug 报告
|
||||
about: 创建BUG报告以改进项目
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**BUG描述**
|
||||
关于BUG清晰简洁的描述。
|
||||
|
||||
**复现步骤**
|
||||
详细的复现步骤。
|
||||
|
||||
|
||||
**正确的行为**
|
||||
你认为这个修复这个BUG后,正确的行为应该是什么。
|
||||
|
||||
|
||||
**详细截图**
|
||||
如果可以的话,请添加截图以帮助调查BUG.
|
||||
|
||||
**桌面端:**
|
||||
- 操作系统: [例如. iOS]
|
||||
- 浏览器及版本 [例如. chrome 11]
|
||||
- 项目版本 [例如. 1.6.0]
|
||||
|
||||
**手机端:**
|
||||
- 设备: [例如. iPhone6]
|
||||
- 操作系统: [例如. iOS8.1]
|
||||
- 浏览器及版本 [例如.safari 8]
|
||||
- 项目版本 [例如. 1.6.0]
|
||||
|
||||
**Additional context**
|
||||
任何其他你认为有助于排查错误的信息,或者你的猜测。
|
||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,20 +0,0 @@
|
||||
---
|
||||
name: 功能建议
|
||||
about: 关于该项目的建议
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**您的功能请求是否与问题相关? 请描述。**
|
||||
清楚简明地描述问题所在。
|
||||
|
||||
**描述您想要的解决方案**
|
||||
对您所设想的问题的清晰简洁的描述。
|
||||
|
||||
**描述您考虑过的替代方案**
|
||||
对您考虑过的任何替代解决方案或功能的清晰简洁的描述。
|
||||
|
||||
**附加上下文**
|
||||
在此处添加有关功能请求的任何其他上下文或屏幕截图。
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -45,6 +45,6 @@ nbdist/
|
||||
!*/build/*.java
|
||||
!*/build/*.html
|
||||
!*/build/*.xml
|
||||
/agileboot-admin/src/main/resources/application-dev.yml
|
||||
/agileboot-infrastructure/src/main/resources/application-prod.yml
|
||||
/agileboot-infrastructure/src/main/resources/logback-prod.xml
|
||||
|
||||
/agileboot-admin/src/main/resources/application-prod.yml
|
||||
|
||||
|
||||
8
Dockerfile
Normal file
8
Dockerfile
Normal file
@@ -0,0 +1,8 @@
|
||||
FROM amazoncorretto:17
|
||||
ADD agileboot-admin/target/agileboot-admin-1.0.0.jar /agileboot-admin.jar
|
||||
|
||||
EXPOSE 18080
|
||||
#ENV CONTEXT_PATH /
|
||||
# ENV NACOS_ENABLED true
|
||||
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
|
||||
ENTRYPOINT ["java", "-jar", "/agileboot-admin.jar"]
|
||||
21
LICENSE
21
LICENSE
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 valarchie
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
60
README.md
60
README.md
@@ -15,8 +15,7 @@
|
||||
|
||||
<img alt="logo" height="200" src="https://oscimg.oschina.net/oscnet/up-eda2a402cc061f1f5f40d9ac4c084f4c98c.png">
|
||||
</p>
|
||||
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">AgileBoot v1.8.0</h1>
|
||||
|
||||
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">AgileBoot v2.0.0 </h1>
|
||||
<h4 align="center">基于SpringBoot+Vue3前后端分离的Java快速开发脚手架</h4>
|
||||
<p align="center">
|
||||
</p>
|
||||
@@ -27,7 +26,8 @@ AgileBoot是一套开源的全栈精简快速开发平台,毫无保留给个
|
||||
适合个人开发者的小型项目或者公司内部项目使用。也可作为供初学者学习使用的案例。
|
||||
|
||||
|
||||
* 前端采用Vue3、Element Plus。对应前端仓库 [AgileBoot-Front-End](https://github.com/valarchie/AgileBoot-Front-End) ,保持同步更新。
|
||||
* 前端是基于优秀的开源项目[Pure-Admin](https://github.com/pure-admin/vue-pure-admin)开发而成。在此感谢Pure-Admin作者。
|
||||
* 前端采用Vue3、Element Plus、TypeScript、Pinia。对应前端仓库 [AgileBoot-Front-End](https://github.com/valarchie/AgileBoot-Front-End) ,保持同步更新。
|
||||
* 后端采用Spring Boot、Spring Security & Jwt、Redis & MySql、Mybatis Plus、Hutool工具包。
|
||||
* 权限认证使用Jwt,支持多终端认证系统。
|
||||
* 支持注解式主从数据库切换,注解式请求限流,注解式重复请求拦截。
|
||||
@@ -35,6 +35,9 @@ AgileBoot是一套开源的全栈精简快速开发平台,毫无保留给个
|
||||
* 支持加载动态权限菜单,实时权限控制。
|
||||
* ***有大量的单元测试,集成测试覆盖确保业务逻辑正确***。
|
||||
|
||||
***V1.0.0版本使用JS开发,V2.0.0版本使用TS开发***。
|
||||
***V1.0.0地址:[后端(AgileBoot-Back-End-Basic)](https://github.com/valarchie/AgileBoot-Back-End-Basic) - [前端(AgileBoot-Front-End-Basic)](https://github.com/valarchie/AgileBoot-Front-End-Basic)***
|
||||
|
||||
> 有任何问题或者建议,可以在 _Issues_ 中提给作者。
|
||||
>
|
||||
> 您的Issue比Star更重要
|
||||
@@ -148,9 +151,9 @@ git clone https://github.com/valarchie/AgileBoot-Front-End
|
||||
#### 后端启动
|
||||
```
|
||||
1. 生成所需的数据库表
|
||||
找到后端项目根目录下的sql目录中的agileboot_xxxxx.sql脚本文件。 导入到你新建的数据库中。
|
||||
找到后端项目根目录下的sql目录中的agileboot_xxxxx.sql脚本文件(取最新的sql文件)。 导入到你新建的数据库中。
|
||||
|
||||
2. 在infrastructure模块底下,找到resource目录下的application-dev.yml文件
|
||||
2. 在admin模块底下,找到resource目录下的application-dev.yml文件
|
||||
配置数据库以及Redis的 地址、端口、账号密码
|
||||
|
||||
3. 在根目录执行mvn install
|
||||
@@ -168,10 +171,12 @@ git clone https://github.com/valarchie/AgileBoot-Front-End
|
||||
```
|
||||
|
||||
#### 前端启动
|
||||
```
|
||||
1. npm install
|
||||
详细步骤请查看对应前端部分
|
||||
|
||||
2. npm run dev
|
||||
```
|
||||
1. pnpm install
|
||||
|
||||
2. pnpm run dev
|
||||
|
||||
3. 当出现以下字样时即为启动成功
|
||||
|
||||
@@ -202,6 +207,8 @@ agileboot.embedded.redis: false
|
||||
agileboot.embedded.mysql: true
|
||||
agileboot.embedded.redis: true
|
||||
|
||||
请注意:高版本的MacOS系统,无法启动内置的Redis
|
||||
|
||||
|
||||
3. 找到agileboot-admin模块中的AgileBootAdminApplication启动类,直接启动即可
|
||||
```
|
||||
@@ -230,8 +237,6 @@ agileboot.embedded.redis: true
|
||||
| | 连接池监视 | 监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈 |
|
||||
|
||||
|
||||
目前版本是V1.8.0,将在2.0版本后陆续新增新功能。
|
||||
|
||||
## 🐯 工程结构 🐯
|
||||
|
||||
```
|
||||
@@ -242,25 +247,20 @@ agileboot
|
||||
│
|
||||
├── agileboot-common -- 精简基础工具模块
|
||||
│
|
||||
├── agileboot-infrastructure -- 基础设施模块(主要是配置和集成)
|
||||
├── agileboot-infrastructure -- 基础设施模块(主要是配置和集成,不包含业务逻辑)
|
||||
│
|
||||
├── agileboot-domain -- 业务模块
|
||||
├ ├── user -- 用户模块(举例)
|
||||
├ ├── command -- 命令参数接收模型(命令)
|
||||
├ ├── dto -- 返回数据类
|
||||
├ ├── db -- DB操作类
|
||||
├ ├── entity -- 实体类
|
||||
├ ├── service -- DB Service
|
||||
├ ├── mapper -- DB Dao
|
||||
├ ├── model -- 领域模型类
|
||||
├ ├── query -- 查询参数模型(查询)
|
||||
│ ├────── UserApplicationService -- 应用服务(事务层,操作领域模型类完成业务逻辑)
|
||||
│
|
||||
├── agileboot-integration-test -- 集成测试模块
|
||||
│
|
||||
├── agileboot-orm -- 数据映射模块(仅包含数据相关逻辑)
|
||||
├ ├── entiy -- 实体类
|
||||
├ ├── enums -- 数据相关枚举
|
||||
├ ├── mapper -- DAO
|
||||
├ ├── query -- 封装查询对象
|
||||
├ ├── result -- 封装多表查询对象
|
||||
└── └── service -- 服务层
|
||||
|
||||
```
|
||||
|
||||
### 代码流转
|
||||
@@ -284,11 +284,16 @@ agileboot
|
||||
│ ├── member -- 会员模块
|
||||
│
|
||||
├── agileboot-domain --
|
||||
├ ├── member -- 会员模块
|
||||
│
|
||||
├── agileboot-orm --
|
||||
│ ├── member -- 会员模块
|
||||
│
|
||||
├ ├── member -- 会员模块(举例)
|
||||
├ ├── command -- 命令参数接收模型(命令)
|
||||
├ ├── dto -- 返回数据类
|
||||
├ ├── db -- DB操作类
|
||||
├ ├── entity -- 实体类
|
||||
├ ├── service -- DB Service
|
||||
├ ├── mapper -- DB Dao
|
||||
├ ├── model -- 领域模型类
|
||||
├ ├── query -- 查询参数模型(查询)
|
||||
│ ├────── MemberApplicationService -- 应用服务(事务层,操作领域模型类完成业务逻辑)
|
||||
└─
|
||||
```
|
||||
|
||||
@@ -313,11 +318,12 @@ agileboot
|
||||
- 请导入统一的代码格式化模板(Google): Settings > Editor > Code Style > Java > 设置按钮 > import schema > 选择项目根目录下的GoogleStyle.xml文件
|
||||
- 如需要生成新的表,请使用CodeGenerator类进行生成。
|
||||
- 填入数据库地址,账号密码,库名。然后填入所需的表名执行代码即可。(大概看一下代码就知道怎么填啦)
|
||||
- 生成的类在orm模块下的target/classes目录下
|
||||
- 生成的类在infrastructure模块下的target/classes目录下
|
||||
- 不同的数据库keywordsHandler方法请填入对应不同数据库handler。(搜索keywordsHandler关键字)
|
||||
- 项目基础环境搭建,请参考docker目录下的指南搭建。保姆级启动说明:
|
||||
- [AgileBoot - 手把手一步一步带你Run起全栈项目(SpringBoot+Vue3)](https://juejin.cn/post/7153812187834744845)
|
||||
- 注意:管理后台的后端启动类是AgileBoot**Admin**Application
|
||||
- Swagger的API地址为 http://localhost:8080/v3/api-docs
|
||||
|
||||
## 🎬 AgileBoot全栈交流群 🎬
|
||||
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.agileboot.admin;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
/**
|
||||
* 启动程序
|
||||
* 定制banner.txt的网站
|
||||
* http://patorjk.com/software/taag
|
||||
* http://www.network-science.de/ascii/
|
||||
* http://www.degraeve.com/img2txt.php
|
||||
* http://life.chacuo.net/convertfont2char
|
||||
* @author valarchie
|
||||
*/
|
||||
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
|
||||
@ComponentScan(basePackages = "com.agileboot.*")
|
||||
public class AgileBootAdminApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AgileBootAdminApplication.class, args);
|
||||
String successMsg = " ____ _ _ __ _ _ \n"
|
||||
+ " / ___| | |_ __ _ _ __ | |_ _ _ _ __ ___ _ _ ___ ___ ___ ___ ___ / _| _ _ | || |\n"
|
||||
+ " \\___ \\ | __|/ _` || '__|| __| | | | || '_ \\ / __|| | | | / __|/ __|/ _ \\/ __|/ __|| |_ | | | || || |\n"
|
||||
+ " ___) || |_| (_| || | | |_ | |_| || |_) | \\__ \\| |_| || (__| (__| __/\\__ \\\\__ \\| _|| |_| || ||_|\n"
|
||||
+ " |____/ \\__|\\__,_||_| \\__| \\__,_|| .__/ |___/ \\__,_| \\___|\\___|\\___||___/|___/|_| \\__,_||_|(_)\n"
|
||||
+ " |_| ";
|
||||
|
||||
System.out.println(successMsg);
|
||||
}
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
package com.agileboot.admin.controller.common;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.file.FileNameUtil;
|
||||
import com.agileboot.common.constant.Constants.UploadSubDir;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode;
|
||||
import com.agileboot.common.exception.error.ErrorCode.Business;
|
||||
import com.agileboot.common.utils.ServletHolderUtil;
|
||||
import com.agileboot.common.utils.file.FileUploadUtils;
|
||||
import com.agileboot.common.utils.jackson.JacksonUtil;
|
||||
import com.agileboot.domain.common.dto.UploadDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 通用请求处理
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Tag(name = "上传API", description = "上传相关接口")
|
||||
@RestController
|
||||
@RequestMapping("/file")
|
||||
@Slf4j
|
||||
public class FileController {
|
||||
|
||||
|
||||
/**
|
||||
* 通用下载请求
|
||||
* download接口 其实不是很有必要
|
||||
* @param fileName 文件名称
|
||||
*/
|
||||
@Operation(summary = "下载文件")
|
||||
@GetMapping("/download")
|
||||
public ResponseEntity<byte[]> fileDownload(String fileName, HttpServletResponse response) {
|
||||
try {
|
||||
if (!FileUploadUtils.isAllowDownload(fileName)) {
|
||||
// 返回类型是ResponseEntity 不能捕获异常, 需要手动将错误填到 ResponseEntity
|
||||
ResponseDTO<Object> fail = ResponseDTO.fail(
|
||||
new ApiException(Business.FILE_NOT_ALLOWED_TO_DOWNLOAD, fileName));
|
||||
return new ResponseEntity<>(JacksonUtil.to(fail).getBytes(), null, HttpStatus.OK);
|
||||
}
|
||||
|
||||
String filePath = FileUploadUtils.getFileAbsolutePath(UploadSubDir.DOWNLOAD_PATH, fileName);
|
||||
|
||||
HttpHeaders downloadHeader = FileUploadUtils.getDownloadHeader(fileName);
|
||||
|
||||
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||
return new ResponseEntity<>(FileUtil.readBytes(filePath), downloadHeader, HttpStatus.OK);
|
||||
} catch (Exception e) {
|
||||
log.error("下载文件失败", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用上传请求(单个)
|
||||
*/
|
||||
@Operation(summary = "单个上传文件")
|
||||
@PostMapping("/upload")
|
||||
public ResponseDTO<UploadDTO> uploadFile(MultipartFile file) {
|
||||
if (file == null) {
|
||||
throw new ApiException(ErrorCode.Business.UPLOAD_FILE_IS_EMPTY);
|
||||
}
|
||||
|
||||
// 上传并返回新文件名称
|
||||
String fileName = FileUploadUtils.upload(UploadSubDir.UPLOAD_PATH, file);
|
||||
|
||||
String url = ServletHolderUtil.getContextUrl() + fileName;
|
||||
|
||||
UploadDTO uploadDTO = UploadDTO.builder()
|
||||
// 全路径
|
||||
.url(url)
|
||||
// 相对路径
|
||||
.fileName(fileName)
|
||||
// 新生成的文件名
|
||||
.newFileName(FileNameUtil.getName(fileName))
|
||||
// 原始的文件名
|
||||
.originalFilename(file.getOriginalFilename()).build();
|
||||
|
||||
return ResponseDTO.ok(uploadDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用上传请求(多个)
|
||||
*/
|
||||
@Operation(summary = "多个上传文件")
|
||||
@PostMapping("/uploads")
|
||||
public ResponseDTO<List<UploadDTO>> uploadFiles(List<MultipartFile> files) {
|
||||
if (CollUtil.isEmpty(files)) {
|
||||
throw new ApiException(ErrorCode.Business.UPLOAD_FILE_IS_EMPTY);
|
||||
}
|
||||
|
||||
List<UploadDTO> uploads = new ArrayList<>();
|
||||
|
||||
for (MultipartFile file : files) {
|
||||
if (file != null) {
|
||||
// 上传并返回新文件名称
|
||||
String fileName = FileUploadUtils.upload(UploadSubDir.UPLOAD_PATH, file);
|
||||
String url = ServletHolderUtil.getContextUrl() + fileName;
|
||||
UploadDTO uploadDTO = UploadDTO.builder()
|
||||
.url(url)
|
||||
.fileName(fileName)
|
||||
.newFileName(FileNameUtil.getName(fileName))
|
||||
.originalFilename(file.getOriginalFilename()).build();
|
||||
|
||||
uploads.add(uploadDTO);
|
||||
|
||||
}
|
||||
}
|
||||
return ResponseDTO.ok(uploads);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
package com.agileboot.admin.controller.common;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.agileboot.common.config.AgileBootConfig;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.exception.error.ErrorCode.Business;
|
||||
import com.agileboot.domain.common.cache.CacheCenter;
|
||||
import com.agileboot.domain.common.dto.UserPermissionDTO;
|
||||
import com.agileboot.domain.system.menu.MenuApplicationService;
|
||||
import com.agileboot.domain.system.menu.dto.RouterDTO;
|
||||
import com.agileboot.domain.system.user.command.AddUserCommand;
|
||||
import com.agileboot.domain.system.user.dto.UserDTO;
|
||||
import com.agileboot.infrastructure.annotations.RateLimit;
|
||||
import com.agileboot.infrastructure.annotations.RateLimit.CacheType;
|
||||
import com.agileboot.infrastructure.annotations.RateLimit.LimitType;
|
||||
import com.agileboot.infrastructure.cache.map.MapCache;
|
||||
import com.agileboot.infrastructure.security.AuthenticationUtils;
|
||||
import com.agileboot.infrastructure.web.domain.login.CaptchaDTO;
|
||||
import com.agileboot.infrastructure.web.domain.login.LoginDTO;
|
||||
import com.agileboot.infrastructure.web.domain.login.LoginUser;
|
||||
import com.agileboot.infrastructure.web.domain.login.TokenDTO;
|
||||
import com.agileboot.infrastructure.web.domain.ratelimit.RateLimitKey;
|
||||
import com.agileboot.infrastructure.web.service.LoginService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.List;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 首页
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Tag(name = "登录API", description = "登录相关接口")
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
public class LoginController {
|
||||
|
||||
@NonNull
|
||||
private LoginService loginService;
|
||||
|
||||
@NonNull
|
||||
private MenuApplicationService menuApplicationService;
|
||||
|
||||
@NonNull
|
||||
private AgileBootConfig agileBootConfig;
|
||||
|
||||
/**
|
||||
* 访问首页,提示语
|
||||
*/
|
||||
@Operation(summary = "首页")
|
||||
@GetMapping("/")
|
||||
@RateLimit(key = RateLimitKey.TEST_KEY, time = 10, maxCount = 5, cacheType = CacheType.Map,
|
||||
limitType = LimitType.GLOBAL)
|
||||
public String index() {
|
||||
return StrUtil.format("欢迎使用{}后台管理框架,当前版本:v{},请通过前端地址访问。",
|
||||
agileBootConfig.getName(), agileBootConfig.getVersion());
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成验证码
|
||||
*/
|
||||
@Operation(summary = "验证码")
|
||||
@RateLimit(key = RateLimitKey.LOGIN_CAPTCHA_KEY, time = 10, maxCount = 10, cacheType = CacheType.REDIS,
|
||||
limitType = LimitType.IP)
|
||||
@GetMapping("/captchaImage")
|
||||
public ResponseDTO<CaptchaDTO> getCaptchaImg() {
|
||||
CaptchaDTO captchaImg = loginService.generateCaptchaImg();
|
||||
return ResponseDTO.ok(captchaImg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录方法
|
||||
*
|
||||
* @param loginDTO 登录信息
|
||||
* @return 结果
|
||||
*/
|
||||
@Operation(summary = "登录")
|
||||
@PostMapping("/login")
|
||||
public ResponseDTO<TokenDTO> login(@RequestBody LoginDTO loginDTO) {
|
||||
// 生成令牌
|
||||
String token = loginService.login(loginDTO);
|
||||
|
||||
return ResponseDTO.ok(new TokenDTO(token));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
*
|
||||
* @return 用户信息
|
||||
*/
|
||||
@Operation(summary = "获取当前登录用户信息")
|
||||
@GetMapping("/getLoginUserInfo")
|
||||
public ResponseDTO<UserPermissionDTO> getLoginUserInfo() {
|
||||
LoginUser loginUser = AuthenticationUtils.getLoginUser();
|
||||
|
||||
UserPermissionDTO permissionDTO = new UserPermissionDTO();
|
||||
|
||||
permissionDTO.setUser(new UserDTO(CacheCenter.userCache.getObjectById(loginUser.getUserId())));
|
||||
permissionDTO.setRoleKey(loginUser.getRoleInfo().getRoleKey());
|
||||
permissionDTO.setPermissions(loginUser.getRoleInfo().getMenuPermissions());
|
||||
permissionDTO.setDictTypes(MapCache.dictionaryCache());
|
||||
|
||||
return ResponseDTO.ok(permissionDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取路由信息
|
||||
*
|
||||
* @return 路由信息
|
||||
*/
|
||||
@Operation(summary = "获取用户对应的菜单路由", description = "用于动态生成路由")
|
||||
@GetMapping("/getRouters")
|
||||
public ResponseDTO<List<RouterDTO>> getRouters() {
|
||||
LoginUser loginUser = AuthenticationUtils.getLoginUser();
|
||||
List<RouterDTO> routerTree = menuApplicationService.getRouterTree(loginUser);
|
||||
return ResponseDTO.ok(routerTree);
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "注册接口", description = "暂未实现")
|
||||
@PostMapping("/register")
|
||||
public ResponseDTO<Void> register(@RequestBody AddUserCommand command) {
|
||||
return ResponseDTO.fail(Business.UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
package com.agileboot.admin.controller.monitor;
|
||||
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.core.page.PageDTO;
|
||||
import com.agileboot.domain.common.cache.CacheCenter;
|
||||
import com.agileboot.domain.system.monitor.MonitorApplicationService;
|
||||
import com.agileboot.domain.system.monitor.dto.OnlineUserInfo;
|
||||
import com.agileboot.domain.system.monitor.dto.RedisCacheInfoDTO;
|
||||
import com.agileboot.domain.system.monitor.dto.ServerInfo;
|
||||
import com.agileboot.infrastructure.annotations.AccessLog;
|
||||
import com.agileboot.orm.common.enums.BusinessTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.List;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 缓存监控
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Tag(name = "监控API", description = "监控相关信息")
|
||||
@RestController
|
||||
@RequestMapping("/monitor")
|
||||
@RequiredArgsConstructor
|
||||
public class MonitorController extends BaseController {
|
||||
|
||||
@NonNull
|
||||
private MonitorApplicationService monitorApplicationService;
|
||||
|
||||
@Operation(summary = "Redis信息")
|
||||
@PreAuthorize("@permission.has('monitor:cache:list')")
|
||||
@GetMapping("/cacheInfo")
|
||||
public ResponseDTO<RedisCacheInfoDTO> getRedisCacheInfo() {
|
||||
RedisCacheInfoDTO redisCacheInfo = monitorApplicationService.getRedisCacheInfo();
|
||||
return ResponseDTO.ok(redisCacheInfo);
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "服务器信息")
|
||||
@PreAuthorize("@permission.has('monitor:server:list')")
|
||||
@GetMapping("/serverInfo")
|
||||
public ResponseDTO<ServerInfo> getServerInfo() {
|
||||
ServerInfo serverInfo = monitorApplicationService.getServerInfo();
|
||||
return ResponseDTO.ok(serverInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取在线用户列表
|
||||
* @param ipaddr
|
||||
* @param userName
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "在线用户列表")
|
||||
@PreAuthorize("@permission.has('monitor:online:list')")
|
||||
@GetMapping("/onlineUser/list")
|
||||
public ResponseDTO<PageDTO<OnlineUserInfo>> list(String ipaddr, String userName) {
|
||||
List<OnlineUserInfo> onlineUserList = monitorApplicationService.getOnlineUserList(userName, ipaddr);
|
||||
return ResponseDTO.ok(new PageDTO<>(onlineUserList));
|
||||
}
|
||||
|
||||
/**
|
||||
* 强退用户
|
||||
*/
|
||||
@Operation(summary = "强退用户")
|
||||
@PreAuthorize("@permission.has('monitor:online:forceLogout')")
|
||||
@AccessLog(title = "在线用户", businessType = BusinessTypeEnum.FORCE_LOGOUT)
|
||||
@DeleteMapping("/onlineUser/{tokenId}")
|
||||
public ResponseDTO<Void> forceLogout(@PathVariable String tokenId) {
|
||||
CacheCenter.loginUserCache.delete(tokenId);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
package com.agileboot.admin.controller.system;
|
||||
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.core.page.PageDTO;
|
||||
import com.agileboot.domain.common.cache.CacheCenter;
|
||||
import com.agileboot.domain.system.config.ConfigApplicationService;
|
||||
import com.agileboot.domain.system.config.command.ConfigUpdateCommand;
|
||||
import com.agileboot.domain.system.config.dto.ConfigDTO;
|
||||
import com.agileboot.domain.system.config.query.ConfigQuery;
|
||||
import com.agileboot.infrastructure.annotations.AccessLog;
|
||||
import com.agileboot.infrastructure.cache.map.MapCache;
|
||||
import com.agileboot.orm.common.enums.BusinessTypeEnum;
|
||||
import com.agileboot.orm.common.result.DictionaryData;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.List;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Positive;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 参数配置 信息操作处理
|
||||
* @author valarchie
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/system/config")
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@Tag(name = "配置API", description = "配置相关的增删查改")
|
||||
public class SysConfigController extends BaseController {
|
||||
|
||||
@NonNull
|
||||
private ConfigApplicationService configApplicationService;
|
||||
|
||||
/**
|
||||
* 获取参数配置列表
|
||||
*/
|
||||
@Operation(summary = "参数列表", description = "分页获取配置参数列表")
|
||||
@PreAuthorize("@permission.has('system:config:list')")
|
||||
@GetMapping("/list")
|
||||
public ResponseDTO<PageDTO<ConfigDTO>> list(ConfigQuery query) {
|
||||
PageDTO<ConfigDTO> page = configApplicationService.getConfigList(query);
|
||||
return ResponseDTO.ok(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型查询字典数据信息
|
||||
* 换成用Enum
|
||||
*/
|
||||
@GetMapping(value = "/dict/{dictType}")
|
||||
@Operation(summary = "字典数据", description = "获取字典列表")
|
||||
@Parameter(name = "dictType", description = "字典对应类别")
|
||||
public ResponseDTO<List<DictionaryData>> dictType(@PathVariable String dictType) {
|
||||
List<DictionaryData> dictionaryData = MapCache.dictionaryCache().get(dictType);
|
||||
return ResponseDTO.ok(dictionaryData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据参数编号获取详细信息
|
||||
*/
|
||||
@PreAuthorize("@permission.has('system:config:query')")
|
||||
@GetMapping(value = "/{configId}")
|
||||
@Operation(summary = "配置信息", description = "配置的详细信息")
|
||||
public ResponseDTO<ConfigDTO> getInfo(@NotNull @Positive @PathVariable Long configId) {
|
||||
ConfigDTO config = configApplicationService.getConfigInfo(configId);
|
||||
return ResponseDTO.ok(config);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修改参数配置
|
||||
*/
|
||||
@PreAuthorize("@permission.has('system:config:edit')")
|
||||
@AccessLog(title = "参数管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@Operation(summary = "配置修改", description = "配置修改")
|
||||
@PutMapping
|
||||
public ResponseDTO<Void> edit(@RequestBody ConfigUpdateCommand config) {
|
||||
configApplicationService.updateConfig(config);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新参数缓存
|
||||
*/
|
||||
@Operation(summary = "刷新配置缓存")
|
||||
@PreAuthorize("@permission.has('system:config:remove')")
|
||||
@AccessLog(title = "参数管理", businessType = BusinessTypeEnum.CLEAN)
|
||||
@DeleteMapping("/refreshCache")
|
||||
public ResponseDTO<Void> refreshCache() {
|
||||
CacheCenter.configCache.invalidateAll();
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
package com.agileboot.admin.controller.system;
|
||||
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.domain.system.dept.DeptApplicationService;
|
||||
import com.agileboot.domain.system.dept.command.AddDeptCommand;
|
||||
import com.agileboot.domain.system.dept.command.UpdateDeptCommand;
|
||||
import com.agileboot.domain.system.dept.dto.DeptDTO;
|
||||
import com.agileboot.domain.system.dept.query.DeptQuery;
|
||||
import com.agileboot.infrastructure.annotations.AccessLog;
|
||||
import com.agileboot.orm.common.enums.BusinessTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.List;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 部门信息
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/system/dept")
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@Tag(name = "部门API", description = "部门相关的增删查改")
|
||||
public class SysDeptController extends BaseController {
|
||||
|
||||
@NonNull
|
||||
private DeptApplicationService deptApplicationService;
|
||||
|
||||
/**
|
||||
* 获取部门列表
|
||||
*/
|
||||
@Operation(summary = "部门列表")
|
||||
@PreAuthorize("@permission.has('system:dept:list')")
|
||||
@GetMapping("/list")
|
||||
public ResponseDTO<List<DeptDTO>> list(DeptQuery query) {
|
||||
List<DeptDTO> deptList = deptApplicationService.getDeptList(query);
|
||||
return ResponseDTO.ok(deptList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据部门编号获取详细信息
|
||||
*/
|
||||
@Operation(summary = "部门详情")
|
||||
@PreAuthorize("@permission.has('system:dept:query')")
|
||||
@GetMapping(value = "/{deptId}")
|
||||
public ResponseDTO<DeptDTO> getInfo(@PathVariable Long deptId) {
|
||||
DeptDTO dept = deptApplicationService.getDeptInfo(deptId);
|
||||
return ResponseDTO.ok(dept);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取部门下拉树列表
|
||||
*/
|
||||
@Operation(summary = "获取部门树级结构")
|
||||
@GetMapping("/dropdownList")
|
||||
public ResponseDTO<List<Tree<Long>>> dropdownList() {
|
||||
List<Tree<Long>> deptTree = deptApplicationService.getDeptTree();
|
||||
return ResponseDTO.ok(deptTree);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增部门
|
||||
*/
|
||||
@Operation(summary = "新增部门")
|
||||
@PreAuthorize("@permission.has('system:dept:add')")
|
||||
@AccessLog(title = "部门管理", businessType = BusinessTypeEnum.ADD)
|
||||
@PostMapping
|
||||
public ResponseDTO<Void> add(@RequestBody AddDeptCommand addCommand) {
|
||||
deptApplicationService.addDept(addCommand);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改部门
|
||||
*/
|
||||
@Operation(summary = "修改部门")
|
||||
@PreAuthorize("@permission.has('system:dept:edit') AND @dataScope.checkDeptId(#updateCommand.deptId)")
|
||||
@AccessLog(title = "部门管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@PutMapping
|
||||
public ResponseDTO<Void> edit(@RequestBody UpdateDeptCommand updateCommand) {
|
||||
deptApplicationService.updateDept(updateCommand);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除部门
|
||||
*/
|
||||
@Operation(summary = "删除部门")
|
||||
@PreAuthorize("@permission.has('system:dept:remove') AND @dataScope.checkDeptId(#deptId)")
|
||||
@AccessLog(title = "部门管理", businessType = BusinessTypeEnum.DELETE)
|
||||
@DeleteMapping("/{deptId}")
|
||||
public ResponseDTO<Void> remove(@PathVariable @NotNull Long deptId) {
|
||||
deptApplicationService.removeDept(deptId);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
package com.agileboot.admin.controller.system;
|
||||
|
||||
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.core.page.PageDTO;
|
||||
import com.agileboot.common.exception.error.ErrorCode;
|
||||
import com.agileboot.common.utils.poi.CustomExcelUtil;
|
||||
import com.agileboot.domain.common.command.BulkOperationCommand;
|
||||
import com.agileboot.domain.system.logininfo.LoginInfoApplicationService;
|
||||
import com.agileboot.domain.system.logininfo.dto.LoginInfoDTO;
|
||||
import com.agileboot.domain.system.logininfo.query.LoginInfoQuery;
|
||||
import com.agileboot.infrastructure.annotations.AccessLog;
|
||||
import com.agileboot.orm.common.enums.BusinessTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 系统访问记录
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Tag(name = "登录日志API", description = "登录日志相关API")
|
||||
@RestController
|
||||
@RequestMapping("/loginInfo")
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
public class SysLoginInfoController extends BaseController {
|
||||
|
||||
@NonNull
|
||||
private LoginInfoApplicationService loginInfoApplicationService;
|
||||
|
||||
@Operation(summary = "日志列表")
|
||||
@PreAuthorize("@permission.has('monitor:logininfor:list')")
|
||||
@GetMapping("/list")
|
||||
public ResponseDTO<PageDTO<LoginInfoDTO>> list(LoginInfoQuery query) {
|
||||
PageDTO<LoginInfoDTO> pageDTO = loginInfoApplicationService.getLoginInfoList(query);
|
||||
return ResponseDTO.ok(pageDTO);
|
||||
}
|
||||
|
||||
@Operation(summary = "日志列表导出", description = "将登录日志导出到excel")
|
||||
@AccessLog(title = "登录日志", businessType = BusinessTypeEnum.EXPORT)
|
||||
@PreAuthorize("@permission.has('monitor:logininfor:export')")
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, LoginInfoQuery query) {
|
||||
PageDTO<LoginInfoDTO> pageDTO = loginInfoApplicationService.getLoginInfoList(query);
|
||||
CustomExcelUtil.writeToResponse(pageDTO.getRows(), LoginInfoDTO.class, response);
|
||||
}
|
||||
|
||||
@Operation(summary = "删除登录日志")
|
||||
@PreAuthorize("@permission.has('monitor:logininfor:remove')")
|
||||
@AccessLog(title = "登录日志", businessType = BusinessTypeEnum.DELETE)
|
||||
@DeleteMapping("/{infoIds}")
|
||||
public ResponseDTO<Void> remove(@PathVariable @NotNull @NotEmpty List<Long> infoIds) {
|
||||
loginInfoApplicationService.deleteLoginInfo(new BulkOperationCommand<>(infoIds));
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
@Operation(summary = "清空登录日志", description = "暂时不支持")
|
||||
@PreAuthorize("@permission.has('monitor:logininfor:remove')")
|
||||
@AccessLog(title = "登录日志", businessType = BusinessTypeEnum.CLEAN)
|
||||
@DeleteMapping("/clean")
|
||||
public ResponseDTO<Void> clean() {
|
||||
return ResponseDTO.fail(ErrorCode.Business.UNSUPPORTED_OPERATION);
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
package com.agileboot.admin.controller.system;
|
||||
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.domain.system.menu.MenuApplicationService;
|
||||
import com.agileboot.domain.system.menu.command.AddMenuCommand;
|
||||
import com.agileboot.domain.system.menu.command.UpdateMenuCommand;
|
||||
import com.agileboot.domain.system.menu.dto.MenuDTO;
|
||||
import com.agileboot.domain.system.menu.query.MenuQuery;
|
||||
import com.agileboot.infrastructure.annotations.AccessLog;
|
||||
import com.agileboot.infrastructure.security.AuthenticationUtils;
|
||||
import com.agileboot.infrastructure.web.domain.login.LoginUser;
|
||||
import com.agileboot.orm.common.enums.BusinessTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.List;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.PositiveOrZero;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 菜单信息
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Tag(name = "菜单API", description = "菜单相关的增删查改")
|
||||
@RestController
|
||||
@RequestMapping("/system/menu")
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
public class SysMenuController extends BaseController {
|
||||
|
||||
@NonNull
|
||||
MenuApplicationService menuApplicationService;
|
||||
|
||||
/**
|
||||
* 获取菜单列表
|
||||
*/
|
||||
@Operation(summary = "菜单列表")
|
||||
@PreAuthorize("@permission.has('system:menu:list')")
|
||||
@GetMapping("/list")
|
||||
public ResponseDTO<List<MenuDTO>> list(MenuQuery query) {
|
||||
List<MenuDTO> menuList = menuApplicationService.getMenuList(query);
|
||||
return ResponseDTO.ok(menuList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据菜单编号获取详细信息
|
||||
*/
|
||||
@Operation(summary = "菜单详情")
|
||||
@PreAuthorize("@permission.has('system:menu:query')")
|
||||
@GetMapping(value = "/{menuId}")
|
||||
public ResponseDTO<MenuDTO> getInfo(@PathVariable @NotNull @PositiveOrZero Long menuId) {
|
||||
MenuDTO menu = menuApplicationService.getMenuInfo(menuId);
|
||||
return ResponseDTO.ok(menu);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取菜单下拉树列表
|
||||
*/
|
||||
@Operation(summary = "菜单列表(树级)", description = "菜单树级下拉框")
|
||||
@GetMapping("/dropdownList")
|
||||
public ResponseDTO<List<Tree<Long>>> dropdownList() {
|
||||
LoginUser loginUser = AuthenticationUtils.getLoginUser();
|
||||
List<Tree<Long>> dropdownList = menuApplicationService.getDropdownList(loginUser);
|
||||
return ResponseDTO.ok(dropdownList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增菜单
|
||||
*/
|
||||
@Operation(summary = "添加菜单")
|
||||
@PreAuthorize("@permission.has('system:menu:add')")
|
||||
@AccessLog(title = "菜单管理", businessType = BusinessTypeEnum.ADD)
|
||||
@PostMapping
|
||||
public ResponseDTO<Void> add(@RequestBody AddMenuCommand addCommand) {
|
||||
menuApplicationService.addMenu(addCommand);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改菜单
|
||||
*/
|
||||
@Operation(summary = "编辑菜单")
|
||||
@PreAuthorize("@permission.has('system:menu:edit')")
|
||||
@AccessLog(title = "菜单管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@PutMapping
|
||||
public ResponseDTO<Void> edit(@RequestBody UpdateMenuCommand updateCommand) {
|
||||
menuApplicationService.updateMenu(updateCommand);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除菜单
|
||||
*/
|
||||
@Operation(summary = "删除菜单")
|
||||
@PreAuthorize("@permission.has('system:menu:remove')")
|
||||
@AccessLog(title = "菜单管理", businessType = BusinessTypeEnum.DELETE)
|
||||
@DeleteMapping("/{menuId}")
|
||||
public ResponseDTO<Void> remove(@PathVariable("menuId") Long menuId) {
|
||||
menuApplicationService.remove(menuId);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
package com.agileboot.admin.controller.system;
|
||||
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.core.page.PageDTO;
|
||||
import com.agileboot.domain.common.command.BulkOperationCommand;
|
||||
import com.agileboot.domain.system.notice.NoticeApplicationService;
|
||||
import com.agileboot.domain.system.notice.command.NoticeAddCommand;
|
||||
import com.agileboot.domain.system.notice.command.NoticeUpdateCommand;
|
||||
import com.agileboot.domain.system.notice.dto.NoticeDTO;
|
||||
import com.agileboot.domain.system.notice.query.NoticeQuery;
|
||||
import com.agileboot.infrastructure.annotations.AccessLog;
|
||||
import com.agileboot.infrastructure.annotations.Unrepeatable;
|
||||
import com.agileboot.orm.common.enums.BusinessTypeEnum;
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.List;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Positive;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 公告 信息操作处理
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Tag(name = "公告API", description = "公告相关的增删查改")
|
||||
@RestController
|
||||
@RequestMapping("/system/notice")
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
public class SysNoticeController extends BaseController {
|
||||
|
||||
@NonNull
|
||||
private NoticeApplicationService noticeApplicationService;
|
||||
|
||||
/**
|
||||
* 获取通知公告列表
|
||||
*/
|
||||
@Operation(summary = "公告列表")
|
||||
@PreAuthorize("@permission.has('system:notice:list')")
|
||||
@GetMapping("/list")
|
||||
public ResponseDTO<PageDTO<NoticeDTO>> list(NoticeQuery query) {
|
||||
PageDTO<NoticeDTO> pageDTO = noticeApplicationService.getNoticeList(query);
|
||||
return ResponseDTO.ok(pageDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取通知公告列表
|
||||
* 从从库获取数据 例子 仅供参考
|
||||
*/
|
||||
@Operation(summary = "公告列表(从数据库从库获取)", description = "演示主从库的例子")
|
||||
@DS("slave")
|
||||
@PreAuthorize("@permission.has('system:notice:list')")
|
||||
@GetMapping("/listFromSlave")
|
||||
public ResponseDTO<PageDTO<NoticeDTO>> listFromSlave(NoticeQuery query) {
|
||||
PageDTO<NoticeDTO> pageDTO = noticeApplicationService.getNoticeList(query);
|
||||
return ResponseDTO.ok(pageDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据通知公告编号获取详细信息
|
||||
*/
|
||||
@Operation(summary = "公告详情")
|
||||
@PreAuthorize("@permission.has('system:notice:query')")
|
||||
@GetMapping(value = "/{noticeId}")
|
||||
public ResponseDTO<NoticeDTO> getInfo(@PathVariable @NotNull @Positive Long noticeId) {
|
||||
return ResponseDTO.ok(noticeApplicationService.getNoticeInfo(noticeId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增通知公告
|
||||
*/
|
||||
@Operation(summary = "添加公告")
|
||||
@Unrepeatable(interval = 60)
|
||||
@PreAuthorize("@permission.has('system:notice:add')")
|
||||
@AccessLog(title = "通知公告", businessType = BusinessTypeEnum.ADD)
|
||||
@PostMapping
|
||||
public ResponseDTO<Void> add(@RequestBody NoticeAddCommand addCommand) {
|
||||
noticeApplicationService.addNotice(addCommand);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改通知公告
|
||||
*/
|
||||
@Operation(summary = "修改公告")
|
||||
@PreAuthorize("@permission.has('system:notice:edit')")
|
||||
@AccessLog(title = "通知公告", businessType = BusinessTypeEnum.MODIFY)
|
||||
@PutMapping
|
||||
public ResponseDTO<Void> edit(@RequestBody NoticeUpdateCommand updateCommand) {
|
||||
noticeApplicationService.updateNotice(updateCommand);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除通知公告
|
||||
*/
|
||||
@Operation(summary = "删除公告")
|
||||
@PreAuthorize("@permission.has('system:notice:remove')")
|
||||
@AccessLog(title = "通知公告", businessType = BusinessTypeEnum.DELETE)
|
||||
@DeleteMapping("/{noticeIds}")
|
||||
public ResponseDTO<Void> remove(@PathVariable List<Integer> noticeIds) {
|
||||
noticeApplicationService.deleteNotice(new BulkOperationCommand<>(noticeIds));
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
package com.agileboot.admin.controller.system;
|
||||
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.core.page.PageDTO;
|
||||
import com.agileboot.common.exception.error.ErrorCode;
|
||||
import com.agileboot.common.utils.poi.CustomExcelUtil;
|
||||
import com.agileboot.domain.common.command.BulkOperationCommand;
|
||||
import com.agileboot.domain.system.operationlog.OperationLogApplicationService;
|
||||
import com.agileboot.domain.system.operationlog.dto.OperationLogDTO;
|
||||
import com.agileboot.domain.system.operationlog.query.OperationLogQuery;
|
||||
import com.agileboot.infrastructure.annotations.AccessLog;
|
||||
import com.agileboot.orm.common.enums.BusinessTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 操作日志记录
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Tag(name = "操作日志API", description = "操作日志相关接口")
|
||||
@RestController
|
||||
@RequestMapping("/operationLog")
|
||||
@RequiredArgsConstructor
|
||||
public class SysOperationLogController extends BaseController {
|
||||
|
||||
@NonNull
|
||||
private OperationLogApplicationService operationLogApplicationService;
|
||||
|
||||
@Operation(summary = "操作日志列表")
|
||||
@PreAuthorize("@permission.has('monitor:operlog:list')")
|
||||
@GetMapping("/list")
|
||||
public ResponseDTO<PageDTO<OperationLogDTO>> list(OperationLogQuery query) {
|
||||
PageDTO<OperationLogDTO> pageDTO = operationLogApplicationService.getOperationLogList(query);
|
||||
return ResponseDTO.ok(pageDTO);
|
||||
}
|
||||
|
||||
@Operation(summary = "操作日志导出")
|
||||
@AccessLog(title = "操作日志", businessType = BusinessTypeEnum.EXPORT)
|
||||
@PreAuthorize("@permission.has('monitor:operlog:export')")
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, OperationLogQuery query) {
|
||||
PageDTO<OperationLogDTO> pageDTO = operationLogApplicationService.getOperationLogList(query);
|
||||
CustomExcelUtil.writeToResponse(pageDTO.getRows(), OperationLogDTO.class, response);
|
||||
}
|
||||
|
||||
@Operation(summary = "删除操作日志")
|
||||
@AccessLog(title = "操作日志", businessType = BusinessTypeEnum.DELETE)
|
||||
@PreAuthorize("@permission.has('monitor:operlog:remove')")
|
||||
@DeleteMapping("/{operationIds}")
|
||||
public ResponseDTO<Void> remove(@PathVariable List<Long> operationIds) {
|
||||
operationLogApplicationService.deleteOperationLog(new BulkOperationCommand<>(operationIds));
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
@Operation(summary = "清空操作日志", description = "暂未支持")
|
||||
@AccessLog(title = "操作日志", businessType = BusinessTypeEnum.CLEAN)
|
||||
@PreAuthorize("@permission.has('monitor:operlog:remove')")
|
||||
@DeleteMapping("/clean")
|
||||
public ResponseDTO<Void> clean() {
|
||||
return ResponseDTO.fail(ErrorCode.Business.UNSUPPORTED_OPERATION);
|
||||
}
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
package com.agileboot.admin.controller.system;
|
||||
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.core.page.PageDTO;
|
||||
import com.agileboot.common.utils.poi.CustomExcelUtil;
|
||||
import com.agileboot.domain.common.command.BulkOperationCommand;
|
||||
import com.agileboot.domain.system.post.PostApplicationService;
|
||||
import com.agileboot.domain.system.post.command.AddPostCommand;
|
||||
import com.agileboot.domain.system.post.command.UpdatePostCommand;
|
||||
import com.agileboot.domain.system.post.dto.PostDTO;
|
||||
import com.agileboot.domain.system.post.query.PostQuery;
|
||||
import com.agileboot.infrastructure.annotations.AccessLog;
|
||||
import com.agileboot.orm.common.enums.BusinessTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 岗位信息操作处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Tag(name = "职位API", description = "职位相关的增删查改")
|
||||
@RestController
|
||||
@RequestMapping("/system/post")
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
public class SysPostController extends BaseController {
|
||||
|
||||
@NonNull
|
||||
private PostApplicationService postApplicationService;
|
||||
|
||||
/**
|
||||
* 获取岗位列表
|
||||
*/
|
||||
@Operation(summary = "职位列表")
|
||||
@PreAuthorize("@permission.has('system:post:list')")
|
||||
@GetMapping("/list")
|
||||
public ResponseDTO<PageDTO<PostDTO>> list(PostQuery query) {
|
||||
PageDTO<PostDTO> pageDTO = postApplicationService.getPostList(query);
|
||||
return ResponseDTO.ok(pageDTO);
|
||||
}
|
||||
|
||||
@Operation(summary = "职位列表导出")
|
||||
@AccessLog(title = "岗位管理", businessType = BusinessTypeEnum.EXPORT)
|
||||
@PreAuthorize("@permission.has('system:post:export')")
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, PostQuery query) {
|
||||
PageDTO<PostDTO> pageDTO = postApplicationService.getPostList(query);
|
||||
CustomExcelUtil.writeToResponse(pageDTO.getRows(), PostDTO.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据岗位编号获取详细信息
|
||||
*/
|
||||
@Operation(summary = "职位详情")
|
||||
@PreAuthorize("@permission.has('system:post:query')")
|
||||
@GetMapping(value = "/{postId}")
|
||||
public ResponseDTO<PostDTO> getInfo(@PathVariable Long postId) {
|
||||
PostDTO post = postApplicationService.getPostInfo(postId);
|
||||
return ResponseDTO.ok(post);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增岗位
|
||||
*/
|
||||
@Operation(summary = "添加职位")
|
||||
@PreAuthorize("@permission.has('system:post:add')")
|
||||
@AccessLog(title = "岗位管理", businessType = BusinessTypeEnum.ADD)
|
||||
@PostMapping
|
||||
public ResponseDTO<Void> add(@RequestBody AddPostCommand addCommand) {
|
||||
postApplicationService.addPost(addCommand);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改岗位
|
||||
*/
|
||||
@Operation(summary = "修改职位")
|
||||
@PreAuthorize("@permission.has('system:post:edit')")
|
||||
@AccessLog(title = "岗位管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@PutMapping
|
||||
public ResponseDTO<Void> edit(@RequestBody UpdatePostCommand updateCommand) {
|
||||
postApplicationService.updatePost(updateCommand);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除岗位
|
||||
*/
|
||||
@Operation(summary = "删除职位")
|
||||
@PreAuthorize("@permission.has('system:post:remove')")
|
||||
@AccessLog(title = "岗位管理", businessType = BusinessTypeEnum.DELETE)
|
||||
@DeleteMapping("/{postIds}")
|
||||
public ResponseDTO<Void> remove(@PathVariable List<Long> postIds) {
|
||||
postApplicationService.deletePost(new BulkOperationCommand<>(postIds));
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
package com.agileboot.admin.controller.system;
|
||||
|
||||
import com.agileboot.common.constant.Constants.UploadSubDir;
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode;
|
||||
import com.agileboot.common.utils.file.FileUploadUtils;
|
||||
import com.agileboot.domain.common.dto.UploadFileDTO;
|
||||
import com.agileboot.domain.system.user.UserApplicationService;
|
||||
import com.agileboot.domain.system.user.command.UpdateProfileCommand;
|
||||
import com.agileboot.domain.system.user.command.UpdateUserAvatarCommand;
|
||||
import com.agileboot.domain.system.user.command.UpdateUserPasswordCommand;
|
||||
import com.agileboot.domain.system.user.dto.UserProfileDTO;
|
||||
import com.agileboot.infrastructure.annotations.AccessLog;
|
||||
import com.agileboot.infrastructure.security.AuthenticationUtils;
|
||||
import com.agileboot.infrastructure.web.domain.login.LoginUser;
|
||||
import com.agileboot.orm.common.enums.BusinessTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 个人信息 业务处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Tag(name = "个人信息API", description = "个人信息相关接口")
|
||||
@RestController
|
||||
@RequestMapping("/system/user/profile")
|
||||
@RequiredArgsConstructor
|
||||
public class SysProfileController extends BaseController {
|
||||
|
||||
@NonNull
|
||||
private UserApplicationService userApplicationService;
|
||||
|
||||
/**
|
||||
* 个人信息
|
||||
*/
|
||||
@Operation(summary = "获取个人信息")
|
||||
@GetMapping
|
||||
public ResponseDTO<UserProfileDTO> profile() {
|
||||
LoginUser user = AuthenticationUtils.getLoginUser();
|
||||
UserProfileDTO userProfile = userApplicationService.getUserProfile(user.getUserId());
|
||||
return ResponseDTO.ok(userProfile);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户
|
||||
*/
|
||||
@Operation(summary = "修改个人信息")
|
||||
@AccessLog(title = "个人信息", businessType = BusinessTypeEnum.MODIFY)
|
||||
@PutMapping
|
||||
public ResponseDTO<Void> updateProfile(@RequestBody UpdateProfileCommand command) {
|
||||
LoginUser loginUser = AuthenticationUtils.getLoginUser();
|
||||
command.setUserId(loginUser.getUserId());
|
||||
userApplicationService.updateUserProfile(command);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置密码
|
||||
*/
|
||||
@Operation(summary = "重置个人密码")
|
||||
@AccessLog(title = "个人信息", businessType = BusinessTypeEnum.MODIFY)
|
||||
@PutMapping("/password")
|
||||
public ResponseDTO<Void> updatePassword(@RequestBody UpdateUserPasswordCommand command) {
|
||||
LoginUser loginUser = AuthenticationUtils.getLoginUser();
|
||||
command.setUserId(loginUser.getUserId());
|
||||
userApplicationService.updatePasswordBySelf(loginUser, command);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 头像上传
|
||||
*/
|
||||
@Operation(summary = "修改个人头像")
|
||||
@AccessLog(title = "用户头像", businessType = BusinessTypeEnum.MODIFY)
|
||||
@PostMapping("/avatar")
|
||||
public ResponseDTO<UploadFileDTO> avatar(@RequestParam("avatarfile") MultipartFile file) {
|
||||
if (file.isEmpty()) {
|
||||
throw new ApiException(ErrorCode.Business.USER_UPLOAD_FILE_FAILED);
|
||||
}
|
||||
LoginUser loginUser = AuthenticationUtils.getLoginUser();
|
||||
String avatarUrl = FileUploadUtils.upload(UploadSubDir.AVATAR_PATH, file);
|
||||
|
||||
userApplicationService.updateUserAvatar(new UpdateUserAvatarCommand(loginUser.getUserId(), avatarUrl));
|
||||
return ResponseDTO.ok(new UploadFileDTO(avatarUrl));
|
||||
}
|
||||
}
|
||||
@@ -1,199 +0,0 @@
|
||||
package com.agileboot.admin.controller.system;
|
||||
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.core.page.PageDTO;
|
||||
import com.agileboot.common.utils.poi.CustomExcelUtil;
|
||||
import com.agileboot.domain.system.role.RoleApplicationService;
|
||||
import com.agileboot.domain.system.role.command.AddRoleCommand;
|
||||
import com.agileboot.domain.system.role.command.UpdateDataScopeCommand;
|
||||
import com.agileboot.domain.system.role.command.UpdateRoleCommand;
|
||||
import com.agileboot.domain.system.role.command.UpdateStatusCommand;
|
||||
import com.agileboot.domain.system.role.dto.RoleDTO;
|
||||
import com.agileboot.domain.system.role.query.AllocatedRoleQuery;
|
||||
import com.agileboot.domain.system.role.query.RoleQuery;
|
||||
import com.agileboot.domain.system.role.query.UnallocatedRoleQuery;
|
||||
import com.agileboot.domain.system.user.dto.UserDTO;
|
||||
import com.agileboot.infrastructure.annotations.AccessLog;
|
||||
import com.agileboot.orm.common.enums.BusinessTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 角色信息
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Tag(name = "角色API", description = "角色相关的增删查改")
|
||||
@RestController
|
||||
@RequestMapping("/system/role")
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
public class SysRoleController extends BaseController {
|
||||
|
||||
@NonNull
|
||||
private RoleApplicationService roleApplicationService;
|
||||
|
||||
@Operation(summary = "角色列表")
|
||||
@PreAuthorize("@permission.has('system:role:list')")
|
||||
@GetMapping("/list")
|
||||
public ResponseDTO<PageDTO<RoleDTO>> list(RoleQuery query) {
|
||||
PageDTO<RoleDTO> pageDTO = roleApplicationService.getRoleList(query);
|
||||
return ResponseDTO.ok(pageDTO);
|
||||
}
|
||||
|
||||
@Operation(summary = "角色列表导出")
|
||||
@AccessLog(title = "角色管理", businessType = BusinessTypeEnum.EXPORT)
|
||||
@PreAuthorize("@permission.has('system:role:export')")
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, RoleQuery query) {
|
||||
PageDTO<RoleDTO> pageDTO = roleApplicationService.getRoleList(query);
|
||||
CustomExcelUtil.writeToResponse(pageDTO.getRows(), RoleDTO.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据角色编号获取详细信息
|
||||
*/
|
||||
@Operation(summary = "角色详情")
|
||||
@PreAuthorize("@permission.has('system:role:query')")
|
||||
@GetMapping(value = "/{roleId}")
|
||||
public ResponseDTO<RoleDTO> getInfo(@PathVariable @NotNull Long roleId) {
|
||||
RoleDTO roleInfo = roleApplicationService.getRoleInfo(roleId);
|
||||
return ResponseDTO.ok(roleInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增角色
|
||||
*/
|
||||
@Operation(summary = "添加角色")
|
||||
@PreAuthorize("@permission.has('system:role:add')")
|
||||
@AccessLog(title = "角色管理", businessType = BusinessTypeEnum.ADD)
|
||||
@PostMapping
|
||||
public ResponseDTO<Void> add(@RequestBody AddRoleCommand addCommand) {
|
||||
roleApplicationService.addRole(addCommand);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除角色
|
||||
*/
|
||||
@Operation(summary = "删除角色")
|
||||
@PreAuthorize("@permission.has('system:role:remove')")
|
||||
@AccessLog(title = "角色管理", businessType = BusinessTypeEnum.ADD)
|
||||
@DeleteMapping(value = "/{roleId}")
|
||||
public ResponseDTO<Void> remove(@PathVariable("roleId") List<Long> roleIds) {
|
||||
roleApplicationService.deleteRoleByBulk(roleIds);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改保存角色
|
||||
*/
|
||||
@Operation(summary = "修改角色")
|
||||
@PreAuthorize("@permission.has('system:role:edit')")
|
||||
@AccessLog(title = "角色管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@PutMapping
|
||||
public ResponseDTO<Void> edit(@Validated @RequestBody UpdateRoleCommand updateCommand) {
|
||||
roleApplicationService.updateRole(updateCommand);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改保存数据权限
|
||||
*/
|
||||
@Operation(summary = "修改角色数据权限")
|
||||
@PreAuthorize("@permission.has('system:role:edit')")
|
||||
@AccessLog(title = "角色管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@PutMapping("/{roleId}/dataScope")
|
||||
public ResponseDTO<Void> dataScope(@PathVariable("roleId") Long roleId,
|
||||
@RequestBody UpdateDataScopeCommand command) {
|
||||
command.setRoleId(roleId);
|
||||
|
||||
roleApplicationService.updateDataScope(command);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 角色状态修改
|
||||
*/
|
||||
@Operation(summary = "修改角色状态")
|
||||
@PreAuthorize("@permission.has('system:role:edit')")
|
||||
@AccessLog(title = "角色管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@PutMapping("/{roleId}/status")
|
||||
public ResponseDTO<Void> changeStatus(@PathVariable("roleId") Long roleId,
|
||||
@RequestBody UpdateStatusCommand command) {
|
||||
command.setRoleId(roleId);
|
||||
|
||||
roleApplicationService.updateStatus(command);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询已分配用户角色列表
|
||||
*/
|
||||
@Operation(summary = "已关联该角色的用户列表")
|
||||
@PreAuthorize("@permission.has('system:role:list')")
|
||||
@GetMapping("/{roleId}/allocated/list")
|
||||
public ResponseDTO<PageDTO<UserDTO>> allocatedUserList(@PathVariable("roleId") Long roleId,
|
||||
AllocatedRoleQuery query) {
|
||||
query.setRoleId(roleId);
|
||||
PageDTO<UserDTO> page = roleApplicationService.getAllocatedUserList(query);
|
||||
return ResponseDTO.ok(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询未分配用户角色列表
|
||||
*/
|
||||
@Operation(summary = "未关联该角色的用户列表")
|
||||
@PreAuthorize("@permission.has('system:role:list')")
|
||||
@GetMapping("/{roleId}/unallocated/list")
|
||||
public ResponseDTO<PageDTO<UserDTO>> unallocatedUserList(@PathVariable("roleId") Long roleId,
|
||||
UnallocatedRoleQuery query) {
|
||||
query.setRoleId(roleId);
|
||||
PageDTO<UserDTO> page = roleApplicationService.getUnallocatedUserList(query);
|
||||
return ResponseDTO.ok(page);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 批量取消授权用户
|
||||
*/
|
||||
@Operation(summary = "批量解除角色和用户的关联")
|
||||
@PreAuthorize("@permission.has('system:role:edit')")
|
||||
@AccessLog(title = "角色管理", businessType = BusinessTypeEnum.GRANT)
|
||||
@DeleteMapping("/users/{userIds}/grant/bulk")
|
||||
public ResponseDTO<Void> deleteRoleOfUserByBulk(@PathVariable("userIds") List<Long> userIds) {
|
||||
roleApplicationService.deleteRoleOfUserByBulk(userIds);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量选择用户授权
|
||||
*/
|
||||
@Operation(summary = "批量添加用户和角色关联")
|
||||
@PreAuthorize("@permission.has('system:role:edit')")
|
||||
@AccessLog(title = "角色管理", businessType = BusinessTypeEnum.GRANT)
|
||||
@PostMapping("/{roleId}/users/{userIds}/grant/bulk")
|
||||
public ResponseDTO<Void> addRoleForUserByBulk(@PathVariable("roleId") Long roleId,
|
||||
@PathVariable("userIds") List<Long> userIds) {
|
||||
roleApplicationService.addRoleOfUserByBulk(roleId, userIds);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,172 +0,0 @@
|
||||
package com.agileboot.admin.controller.system;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.core.page.PageDTO;
|
||||
import com.agileboot.common.utils.poi.CustomExcelUtil;
|
||||
import com.agileboot.domain.common.command.BulkOperationCommand;
|
||||
import com.agileboot.domain.system.user.UserApplicationService;
|
||||
import com.agileboot.domain.system.user.command.AddUserCommand;
|
||||
import com.agileboot.domain.system.user.command.ChangeStatusCommand;
|
||||
import com.agileboot.domain.system.user.command.ResetPasswordCommand;
|
||||
import com.agileboot.domain.system.user.command.UpdateUserCommand;
|
||||
import com.agileboot.domain.system.user.dto.UserDTO;
|
||||
import com.agileboot.domain.system.user.dto.UserDetailDTO;
|
||||
import com.agileboot.domain.system.user.query.SearchUserQuery;
|
||||
import com.agileboot.infrastructure.annotations.AccessLog;
|
||||
import com.agileboot.infrastructure.security.AuthenticationUtils;
|
||||
import com.agileboot.infrastructure.web.domain.login.LoginUser;
|
||||
import com.agileboot.orm.common.enums.BusinessTypeEnum;
|
||||
import com.agileboot.orm.system.result.SearchUserDO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Tag(name = "用户API", description = "用户相关的增删查改")
|
||||
@RestController
|
||||
@RequestMapping("/system/user")
|
||||
@RequiredArgsConstructor
|
||||
public class SysUserController extends BaseController {
|
||||
|
||||
@NonNull
|
||||
private UserApplicationService userApplicationService;
|
||||
|
||||
/**
|
||||
* 获取用户列表
|
||||
*/
|
||||
@Operation(summary = "用户列表")
|
||||
@PreAuthorize("@permission.has('system:user:list') AND @dataScope.checkDeptId(#query.deptId)")
|
||||
@GetMapping("/list")
|
||||
public ResponseDTO<PageDTO<UserDTO>> list(SearchUserQuery<SearchUserDO> query) {
|
||||
PageDTO<UserDTO> page = userApplicationService.getUserList(query);
|
||||
return ResponseDTO.ok(page);
|
||||
}
|
||||
|
||||
@Operation(summary = "用户列表导出")
|
||||
@AccessLog(title = "用户管理", businessType = BusinessTypeEnum.EXPORT)
|
||||
@PreAuthorize("@permission.has('system:user:export')")
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, SearchUserQuery<SearchUserDO> query) {
|
||||
PageDTO<UserDTO> userList = userApplicationService.getUserList(query);
|
||||
CustomExcelUtil.writeToResponse(userList.getRows(), UserDTO.class, response);
|
||||
}
|
||||
|
||||
@Operation(summary = "用户列表导入")
|
||||
@AccessLog(title = "用户管理", businessType = BusinessTypeEnum.IMPORT)
|
||||
@PreAuthorize("@permission.has('system:user:import')")
|
||||
@PostMapping("/importData")
|
||||
public ResponseDTO<Void> importData(MultipartFile file) {
|
||||
List<AddUserCommand> commands = CustomExcelUtil.readFromRequest(AddUserCommand.class, file);
|
||||
|
||||
for (AddUserCommand command : commands) {
|
||||
userApplicationService.addUser(command);
|
||||
}
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载批量导入模板
|
||||
*/
|
||||
@Operation(summary = "用户导入excel下载")
|
||||
@PostMapping("/downloadTemplate")
|
||||
public void downloadTemplate(HttpServletResponse response) {
|
||||
CustomExcelUtil.writeToResponse(ListUtil.toList(new AddUserCommand()), AddUserCommand.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户编号获取详细信息
|
||||
*/
|
||||
@Operation(summary = "用户详情")
|
||||
@PreAuthorize("@permission.has('system:user:query')")
|
||||
@GetMapping(value = {"/", "/{userId}"})
|
||||
public ResponseDTO<UserDetailDTO> getUserDetailInfo(@PathVariable(value = "userId", required = false) Long userId) {
|
||||
UserDetailDTO userDetailInfo = userApplicationService.getUserDetailInfo(userId);
|
||||
return ResponseDTO.ok(userDetailInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增用户
|
||||
*/
|
||||
@Operation(summary = "新增用户")
|
||||
@PreAuthorize("@permission.has('system:user:add') AND @dataScope.checkDeptId(#command.deptId)")
|
||||
@AccessLog(title = "用户管理", businessType = BusinessTypeEnum.ADD)
|
||||
@PostMapping
|
||||
public ResponseDTO<Void> add(@Validated @RequestBody AddUserCommand command) {
|
||||
userApplicationService.addUser(command);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户
|
||||
*/
|
||||
@Operation(summary = "修改用户")
|
||||
@PreAuthorize("@permission.has('system:user:edit') AND @dataScope.checkUserId(#command.userId)")
|
||||
@AccessLog(title = "用户管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@PutMapping
|
||||
public ResponseDTO<Void> edit(@Validated @RequestBody UpdateUserCommand command) {
|
||||
userApplicationService.updateUser(command);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户
|
||||
*/
|
||||
@Operation(summary = "删除用户")
|
||||
@PreAuthorize("@permission.has('system:user:remove') AND @dataScope.checkUserIds(#userIds)")
|
||||
@AccessLog(title = "用户管理", businessType = BusinessTypeEnum.DELETE)
|
||||
@DeleteMapping("/{userIds}")
|
||||
public ResponseDTO<Void> remove(@PathVariable List<Long> userIds) {
|
||||
BulkOperationCommand<Long> bulkDeleteCommand = new BulkOperationCommand<>(userIds);
|
||||
LoginUser loginUser = AuthenticationUtils.getLoginUser();
|
||||
userApplicationService.deleteUsers(loginUser, bulkDeleteCommand);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置密码
|
||||
*/
|
||||
@Operation(summary = "重置用户密码")
|
||||
@PreAuthorize("@permission.has('system:user:resetPwd') AND @dataScope.checkUserId(#userId)")
|
||||
@AccessLog(title = "用户管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@PutMapping("/{userId}/password/reset")
|
||||
public ResponseDTO<Void> resetPassword(@PathVariable Long userId, @RequestBody ResetPasswordCommand command) {
|
||||
command.setUserId(userId);
|
||||
userApplicationService.resetUserPassword(command);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 状态修改
|
||||
*/
|
||||
@Operation(summary = "修改用户状态")
|
||||
@PreAuthorize("@permission.has('system:user:edit') AND @dataScope.checkUserId(#command.userId)")
|
||||
@AccessLog(title = "用户管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@PutMapping("/{userId}/status")
|
||||
public ResponseDTO<Void> changeStatus(@PathVariable Long userId, @RequestBody ChangeStatusCommand command) {
|
||||
command.setUserId(userId);
|
||||
userApplicationService.changeUserStatus(command);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package com.agileboot.admin.controller.tool;
|
||||
|
||||
import cn.hutool.core.net.URLEncodeUtil;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import com.agileboot.common.config.AgileBootConfig;
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.io.IOException;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* swagger 接口
|
||||
* TODO Swagger这边权限拦截并没有生效,需要改进
|
||||
* PreAuthorize注解加在transfer接口上 获取不到登录用户 iframe请求header中没有token
|
||||
* @author valarchie
|
||||
*/
|
||||
@Tag(name = "文档API", description = "角色相关接口")
|
||||
@RestController
|
||||
public class SwaggerController extends BaseController {
|
||||
|
||||
/**
|
||||
* TODO 这个接口没有触发, 后续看如何改进, 应该把权限拦截放在下面的接口
|
||||
*/
|
||||
@Operation(summary = "文档首页")
|
||||
@PreAuthorize("@permission.has('tool:swagger:view')")
|
||||
@GetMapping("/tool/swagger")
|
||||
public String index() {
|
||||
return redirect("/doc.html");
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问首页,提示语
|
||||
*/
|
||||
@Operation(summary = "文档接口数据")
|
||||
@GetMapping("/v3/api-docs/{url}")
|
||||
public void transfer(HttpServletResponse response, @PathVariable String url) throws IOException {
|
||||
response.sendRedirect(AgileBootConfig.getApiDocsPathPrefix() + "/v3/api-docs/" + URLEncodeUtil.encode(url,
|
||||
CharsetUtil.CHARSET_UTF_8));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
# 开发环境配置
|
||||
server:
|
||||
# 服务器的HTTP端口,默认为8080
|
||||
port: 8080
|
||||
servlet:
|
||||
# 应用的访问路径
|
||||
context-path: /
|
||||
tomcat:
|
||||
# tomcat的URI编码
|
||||
uri-encoding: UTF-8
|
||||
# 连接数满后的排队数,默认为100
|
||||
accept-count: 1000
|
||||
threads:
|
||||
# tomcat最大线程数,默认为200
|
||||
max: 800
|
||||
# Tomcat启动初始化的线程数,默认值10
|
||||
min-spare: 100
|
||||
|
||||
|
||||
# Spring配置 如果需要无Mysql 无Redis直接启动的话 dev改为test
|
||||
# 生产环境把dev改为prod
|
||||
spring:
|
||||
profiles:
|
||||
active: basic,dev
|
||||
|
||||
# 如果需要无Mysql 无Redis直接启动的话 可以将这两个参数置为true, 并且spring.profile.active: dev换成test
|
||||
# redis的端口可能会被占用,如果被占用请自己修改一下端口号
|
||||
agileboot:
|
||||
embedded:
|
||||
mysql: false
|
||||
redis: false
|
||||
|
||||
|
||||
|
||||
springdoc:
|
||||
api-docs:
|
||||
enabled: true
|
||||
groups:
|
||||
enabled: true
|
||||
group-configs:
|
||||
- group: '公共管理API'
|
||||
packages-to-scan: com.agileboot.admin.controller.common
|
||||
- group: '监控管理API'
|
||||
packages-to-scan: com.agileboot.admin.controller.monitor
|
||||
- group: '系统管理API'
|
||||
packages-to-scan: com.agileboot.admin.controller.system
|
||||
- group: '工具管理API'
|
||||
packages-to-scan: com.agileboot.admin.controller.tool
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
package com.agileboot.admin.config;
|
||||
|
||||
|
||||
import com.agileboot.admin.AgileBootAdminApplication;
|
||||
import com.agileboot.common.config.AgileBootConfig;
|
||||
import com.agileboot.common.constant.Constants.UploadSubDir;
|
||||
import java.io.File;
|
||||
import javax.annotation.Resource;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@SpringBootTest(classes = AgileBootAdminApplication.class)
|
||||
@RunWith(SpringRunner.class)
|
||||
public class AgileBootConfigTest {
|
||||
|
||||
@Resource
|
||||
private AgileBootConfig config;
|
||||
|
||||
@Test
|
||||
public void testConfig() {
|
||||
String fileBaseDir = "D:\\agileboot\\profile";
|
||||
|
||||
Assertions.assertEquals("AgileBoot", config.getName());
|
||||
Assertions.assertEquals("1.0.0", config.getVersion());
|
||||
Assertions.assertEquals("2022", config.getCopyrightYear());
|
||||
Assertions.assertTrue(config.isDemoEnabled());
|
||||
Assertions.assertEquals(fileBaseDir, AgileBootConfig.getFileBaseDir());
|
||||
Assertions.assertFalse(AgileBootConfig.isAddressEnabled());
|
||||
Assertions.assertEquals("math", AgileBootConfig.getCaptchaType());
|
||||
Assertions.assertEquals("math", AgileBootConfig.getCaptchaType());
|
||||
Assertions.assertEquals(fileBaseDir + "\\import",
|
||||
AgileBootConfig.getFileBaseDir() + File.separator + UploadSubDir.IMPORT_PATH);
|
||||
Assertions.assertEquals(fileBaseDir + "\\avatar",
|
||||
AgileBootConfig.getFileBaseDir() + File.separator + UploadSubDir.AVATAR_PATH);
|
||||
Assertions.assertEquals(fileBaseDir + "\\download",
|
||||
AgileBootConfig.getFileBaseDir() + File.separator + UploadSubDir.DOWNLOAD_PATH);
|
||||
Assertions.assertEquals(fileBaseDir + "\\upload",
|
||||
AgileBootConfig.getFileBaseDir() + File.separator + UploadSubDir.UPLOAD_PATH);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.agileboot.api;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
/**
|
||||
* 启动程序
|
||||
* 定制banner.txt的网站
|
||||
* http://patorjk.com/software/taag
|
||||
* http://www.network-science.de/ascii/
|
||||
* http://www.degraeve.com/img2txt.php
|
||||
* http://life.chacuo.net/convertfont2char
|
||||
* @author valarchie
|
||||
*/
|
||||
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
|
||||
@ComponentScan(basePackages = "com.agileboot.*")
|
||||
public class AgileBooApiApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AgileBooApiApplication.class, args);
|
||||
String successMsg = " ____ _ _ __ _ _ \n"
|
||||
+ " / ___| | |_ __ _ _ __ | |_ _ _ _ __ ___ _ _ ___ ___ ___ ___ ___ / _| _ _ | || |\n"
|
||||
+ " \\___ \\ | __|/ _` || '__|| __| | | | || '_ \\ / __|| | | | / __|/ __|/ _ \\/ __|/ __|| |_ | | | || || |\n"
|
||||
+ " ___) || |_| (_| || | | |_ | |_| || |_) | \\__ \\| |_| || (__| (__| __/\\__ \\\\__ \\| _|| |_| || ||_|\n"
|
||||
+ " |____/ \\__|\\__,_||_| \\__| \\__,_|| .__/ |___/ \\__,_| \\___|\\___|\\___||___/|___/|_| \\__,_||_|(_)\n"
|
||||
+ " |_| ";
|
||||
|
||||
System.out.println(successMsg);
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package com.agileboot.api.controller;
|
||||
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 调度日志操作处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/order")
|
||||
public class OrderController extends BaseController {
|
||||
|
||||
/**
|
||||
* 访问首页,提示语
|
||||
*/
|
||||
@RequestMapping("/")
|
||||
public String index() {
|
||||
return "暂无订单";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
# 开发环境配置
|
||||
server:
|
||||
# 服务器的HTTP端口,默认为8080
|
||||
port: 8090
|
||||
servlet:
|
||||
# 应用的访问路径
|
||||
context-path: /
|
||||
tomcat:
|
||||
# tomcat的URI编码
|
||||
uri-encoding: UTF-8
|
||||
# 连接数满后的排队数,默认为100
|
||||
accept-count: 1000
|
||||
threads:
|
||||
# tomcat最大线程数,默认为200
|
||||
max: 800
|
||||
# Tomcat启动初始化的线程数,默认值10
|
||||
min-spare: 100
|
||||
|
||||
|
||||
# Spring配置
|
||||
spring:
|
||||
profiles:
|
||||
active: basic,dev
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,10 +5,23 @@
|
||||
<parent>
|
||||
<artifactId>agileboot</artifactId>
|
||||
<groupId>com.agileboot</groupId>
|
||||
<version>${revision}</version>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<modules>
|
||||
<module>wol-common-box</module>
|
||||
<module>wol-common-core</module>
|
||||
<module>wol-common-doc</module>
|
||||
<module>wol-common-web</module>
|
||||
<module>wol-common-mybatis</module>
|
||||
<module>wol-common-redis</module>
|
||||
<module>wol-common-json</module>
|
||||
<module>wol-common-satoken</module>
|
||||
<module>wol-common-nacos</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<artifactId>agileboot-common</artifactId>
|
||||
|
||||
<description>
|
||||
@@ -17,176 +30,78 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- Spring框架基本的核心工具 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringWeb模块 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- spring security 安全认证 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 自定义验证注解 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--常用工具类 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- JSON工具类 -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- io常用工具类 -->
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.springframework.boot</groupId>-->
|
||||
<!-- <artifactId>spring-boot-starter-security</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<!-- 文件上传工具类 -->
|
||||
<dependency>
|
||||
<groupId>commons-fileupload</groupId>
|
||||
<artifactId>commons-fileupload</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- excel工具 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>commons-fileupload</groupId>-->
|
||||
<!-- <artifactId>commons-fileupload</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<!-- yml解析器 -->
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.yaml</groupId>-->
|
||||
<!-- <artifactId>snakeyaml</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<!-- Token生成与解析-->
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt</artifactId>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>io.jsonwebtoken</groupId>-->
|
||||
<!-- <artifactId>jjwt</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<!-- Jaxb -->
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>javax.xml.bind</groupId>-->
|
||||
<!-- <artifactId>jaxb-api</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<!-- redis 缓存操作 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- pool 对象池 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.springframework.boot</groupId>-->
|
||||
<!-- <artifactId>spring-boot-starter-data-redis</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<!-- 解析客户端操作系统、浏览器等 -->
|
||||
<dependency>
|
||||
<groupId>eu.bitwalker</groupId>
|
||||
<artifactId>UserAgentUtils</artifactId>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>eu.bitwalker</groupId>-->
|
||||
<!-- <artifactId>UserAgentUtils</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<!-- servlet包 -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>it.ozimov</groupId>-->
|
||||
<!-- <artifactId>embedded-redis</artifactId>-->
|
||||
<!-- <!– 不排除掉slf4j的话 会冲突–>-->
|
||||
<!-- <exclusions>-->
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>org.slf4j</groupId>-->
|
||||
<!-- <artifactId>slf4j-simple</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
<!-- <!– 排除掉guava依赖,以本项目的guava依赖为准 –>-->
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>com.google.guava</groupId>-->
|
||||
<!-- <artifactId>guava</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
<!-- </exclusions>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
<artifactId>jackson-module-parameter-names</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jdk8</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.lionsoul</groupId>
|
||||
<artifactId>ip2region</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>it.ozimov</groupId>
|
||||
<artifactId>embedded-redis</artifactId>
|
||||
<!-- 不排除掉slf4j的话 会冲突-->
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
</exclusion>
|
||||
<!-- 排除掉guava依赖,以本项目的guava依赖为准 -->
|
||||
<exclusion>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- 多数据源 -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.baomidou</groupId>-->
|
||||
<!-- <artifactId>dynamic-datasource-spring-boot-starter</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<!-- swagger注解 -->
|
||||
<dependency>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-annotations</artifactId>
|
||||
</dependency>
|
||||
<!--ENC加密-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.github.ulisesbocchio</groupId>-->
|
||||
<!-- <artifactId>jasypt-spring-boot-starter</artifactId>-->
|
||||
<!-- <version>2.1.1</version>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
package com.agileboot.common.constant;
|
||||
|
||||
|
||||
/**
|
||||
* 通用常量信息
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
public class Constants {
|
||||
private Constants() {
|
||||
}
|
||||
|
||||
public static final int KB = 1024;
|
||||
|
||||
public static final int MB = KB * 1024;
|
||||
|
||||
public static final int GB = MB * 1024;
|
||||
|
||||
/**
|
||||
* http请求
|
||||
*/
|
||||
public static final String HTTP = "http://";
|
||||
|
||||
/**
|
||||
* https请求
|
||||
*/
|
||||
public static final String HTTPS = "https://";
|
||||
|
||||
|
||||
public static class Token {
|
||||
|
||||
private Token() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 令牌前缀
|
||||
*/
|
||||
public static final String TOKEN_PREFIX = "Bearer ";
|
||||
|
||||
/**
|
||||
* 令牌前缀
|
||||
*/
|
||||
public static final String LOGIN_USER_KEY = "login_user_key";
|
||||
|
||||
}
|
||||
|
||||
public static class Captcha {
|
||||
|
||||
private Captcha() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 令牌
|
||||
*/
|
||||
public static final String MATH_TYPE = "math";
|
||||
|
||||
/**
|
||||
* 令牌前缀
|
||||
*/
|
||||
public static final String CHAR_TYPE = "char";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 资源映射路径 前缀
|
||||
*/
|
||||
public static final String RESOURCE_PREFIX = "profile";
|
||||
|
||||
public static class UploadSubDir {
|
||||
|
||||
private UploadSubDir() {
|
||||
}
|
||||
|
||||
public static final String IMPORT_PATH = "import";
|
||||
|
||||
public static final String AVATAR_PATH = "avatar";
|
||||
|
||||
public static final String DOWNLOAD_PATH = "download";
|
||||
|
||||
public static final String UPLOAD_PATH = "upload";
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package com.agileboot.common.core.base;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import java.util.Date;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* Entity基类
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class BaseEntity<T extends Model<?>> extends Model<T> {
|
||||
|
||||
@ApiModelProperty("创建者ID")
|
||||
@TableField(value = "creator_id", fill = FieldFill.INSERT)
|
||||
private Long creatorId;
|
||||
|
||||
@ApiModelProperty("创建时间")
|
||||
@TableField(value = "create_time", fill = FieldFill.INSERT)
|
||||
private Date createTime;
|
||||
|
||||
@ApiModelProperty("更新者ID")
|
||||
@TableField(value = "updater_id", fill = FieldFill.UPDATE, updateStrategy = FieldStrategy.NOT_NULL)
|
||||
private Long updaterId;
|
||||
|
||||
@ApiModelProperty("更新时间")
|
||||
@TableField(value = "update_time", fill = FieldFill.UPDATE)
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* deleted字段请在数据库中 设置为tinyInt 并且非null 默认值为0
|
||||
*/
|
||||
@ApiModelProperty("删除标志(0代表存在 1代表删除)")
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
private Boolean deleted;
|
||||
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package com.agileboot.common.core.dto;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode;
|
||||
import com.agileboot.common.exception.error.ErrorCodeInterface;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 响应信息主体
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class ResponseDTO<T> {
|
||||
|
||||
private Integer code;
|
||||
|
||||
private String msg;
|
||||
|
||||
private T data;
|
||||
|
||||
public static <T> ResponseDTO<T> ok() {
|
||||
return build(null, ErrorCode.SUCCESS);
|
||||
}
|
||||
|
||||
public static <T> ResponseDTO<T> ok(T data) {
|
||||
return build(data, ErrorCode.SUCCESS);
|
||||
}
|
||||
|
||||
public static <T> ResponseDTO<T> fail() {
|
||||
return build(null, ErrorCode.FAIL);
|
||||
}
|
||||
|
||||
public static <T> ResponseDTO<T> fail(T data) {
|
||||
return build(data, ErrorCode.FAIL);
|
||||
}
|
||||
|
||||
public static <T> ResponseDTO<T> fail(ErrorCodeInterface code) {
|
||||
return build(null, code);
|
||||
}
|
||||
|
||||
public static <T> ResponseDTO<T> fail(ErrorCodeInterface code, Object... args) {
|
||||
return build(null, code, args);
|
||||
}
|
||||
|
||||
public static <T> ResponseDTO<T> fail(ApiException exception) {
|
||||
return build(exception.getErrorCode().code(), exception.getMessage());
|
||||
}
|
||||
|
||||
public static <T> ResponseDTO<T> build(T data, ErrorCodeInterface code, Object... args) {
|
||||
return new ResponseDTO<>(code.code(), StrUtil.format(code.message(), args), data);
|
||||
}
|
||||
|
||||
public static <T> ResponseDTO<T> build(Integer code, String msg) {
|
||||
return new ResponseDTO<>(code, msg, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
package com.agileboot.common.core.page;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 分页模型类
|
||||
* @author valarchie
|
||||
*/
|
||||
@Data
|
||||
public class PageDTO<T> {
|
||||
/**
|
||||
* 总记录数
|
||||
*/
|
||||
private Long total;
|
||||
|
||||
/**
|
||||
* 列表数据
|
||||
*/
|
||||
private List<T> rows;
|
||||
|
||||
public PageDTO(List<T> list) {
|
||||
this.rows = list;
|
||||
this.total = (long) list.size();
|
||||
}
|
||||
|
||||
public PageDTO(Page<T> page) {
|
||||
this.rows = page.getRecords();
|
||||
this.total = page.getTotal();
|
||||
}
|
||||
|
||||
public PageDTO(List<T> list, Long count) {
|
||||
this.rows = list;
|
||||
this.total = count;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package com.agileboot.common.exception;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.agileboot.common.exception.error.ErrorCodeInterface;
|
||||
import com.agileboot.common.utils.i18n.MessageUtils;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 统一异常类
|
||||
* @author valarchie
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Slf4j
|
||||
@Data
|
||||
public class ApiException extends RuntimeException{
|
||||
|
||||
protected ErrorCodeInterface errorCode;
|
||||
|
||||
protected String message;
|
||||
|
||||
protected Object[] args;
|
||||
|
||||
protected String formattedMessage;
|
||||
protected String i18nFormattedMessage;
|
||||
|
||||
public ApiException(Throwable e, ErrorCodeInterface errorCode, Object... args) {
|
||||
super(e);
|
||||
fillErrorCode(errorCode, args);
|
||||
}
|
||||
|
||||
public ApiException(ErrorCodeInterface errorCode, Object... args) {
|
||||
fillErrorCode(errorCode, args);
|
||||
}
|
||||
|
||||
public ApiException(ErrorCodeInterface errorCode) {
|
||||
fillErrorCode(errorCode);
|
||||
}
|
||||
|
||||
private void fillErrorCode(ErrorCodeInterface errorCode, Object... args) {
|
||||
this.errorCode = errorCode;
|
||||
this.message = errorCode.message();
|
||||
this.args = args;
|
||||
|
||||
this.formattedMessage = StrUtil.format(this.message, args);
|
||||
|
||||
try {
|
||||
this.i18nFormattedMessage = MessageUtils.message(errorCode.i18nKey(), args);
|
||||
} catch (Exception e) {
|
||||
log.error("could not found i18nMessage entry for key: " + errorCode.i18nKey());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return i18nFormattedMessage != null ? i18nFormattedMessage : formattedMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocalizedMessage() {
|
||||
return i18nFormattedMessage;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,328 +0,0 @@
|
||||
package com.agileboot.common.exception.error;
|
||||
|
||||
/**
|
||||
* 错误码集合
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
public enum ErrorCode implements ErrorCodeInterface {
|
||||
|
||||
/**
|
||||
* 错误码集合
|
||||
* 1~9999 为保留错误码 或者 常用错误码
|
||||
* 10000~19999 为内部错误码
|
||||
* 20000~29999 客户端错误码 (客户端异常调用之类的错误)
|
||||
* 30000~39999 为第三方错误码 (代码正常,但是第三方异常)
|
||||
* 40000~49999 为业务逻辑 错误码 (无异常,代码正常流转,并返回提示给用户)
|
||||
* 由于系统内的错误码都是独一无二的,所以错误码应该放在common包集中管理
|
||||
*/
|
||||
// -------------- 普通错误码 及保留错误码 ---------------
|
||||
SUCCESS(0, "操作成功"),
|
||||
FAIL(9999, "操作失败"),
|
||||
|
||||
UNKNOWN_ERROR(99999, "未知错误");
|
||||
|
||||
private final int code;
|
||||
private final String msg;
|
||||
|
||||
ErrorCode(int code, String msg) {
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int code() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String message() {
|
||||
return this.msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* 40000~49999 为业务逻辑 错误码 (无代码异常,代码正常流转,并返回提示给用户)
|
||||
*/
|
||||
public enum Business implements ErrorCodeInterface {
|
||||
|
||||
// ----------------------------- Common --------------------------------------
|
||||
|
||||
OBJECT_NOT_FOUND(Module.COMMON, 1, "找不到ID为 {} 的 {}"),
|
||||
|
||||
UNSUPPORTED_OPERATION(Module.COMMON, 2, "不支持的操作"),
|
||||
|
||||
BULK_DELETE_IDS_IS_INVALID(Module.COMMON, 3, "批量参数ID列表为空"),
|
||||
|
||||
FILE_NOT_ALLOWED_TO_DOWNLOAD(Module.COMMON, 3, "文件名称({})非法,不允许下载"),
|
||||
|
||||
// ----------------------------- Permission -----------------------------------
|
||||
|
||||
FORBIDDEN_TO_MODIFY_ADMIN(Module.PERMISSION, 1, "不允许修改管理员的信息"),
|
||||
|
||||
NO_PERMISSION_TO_OPERATE(Module.PERMISSION, 2, "没有权限进行此操作,请联系管理员"),
|
||||
|
||||
// ----------------------------- Login -----------------------------------------
|
||||
|
||||
LOGIN_WRONG_USER_PASSWORD(Module.LOGIN, 1, "用户密码错误,请重输"),
|
||||
|
||||
LOGIN_ERROR(Module.LOGIN, 2, "登录失败:{}"),
|
||||
|
||||
LOGIN_CAPTCHA_CODE_WRONG(Module.LOGIN, 3, "验证码错误"),
|
||||
|
||||
LOGIN_CAPTCHA_CODE_EXPIRE(Module.LOGIN, 4, "验证码过期"),
|
||||
|
||||
LOGIN_CAPTCHA_CODE_NULL(Module.LOGIN, 5, "验证码为空"),
|
||||
|
||||
// ----------------------------- Upload -----------------------------------------
|
||||
|
||||
UPLOAD_FILE_TYPE_NOT_ALLOWED(Module.UPLOAD, 1, "不允许上传的文件类型,仅允许:{}"),
|
||||
|
||||
UPLOAD_FILE_NAME_EXCEED_MAX_LENGTH(Module.UPLOAD, 2, "文件名长度超过:{} "),
|
||||
|
||||
UPLOAD_FILE_SIZE_EXCEED_MAX_SIZE(Module.UPLOAD, 3, "文件名大小超过:{} MB"),
|
||||
|
||||
UPLOAD_IMPORT_EXCEL_FAILED(Module.UPLOAD, 4, "导入excel失败:{}"),
|
||||
|
||||
UPLOAD_FILE_IS_EMPTY(Module.UPLOAD, 5, "上传文件为空"),
|
||||
|
||||
UPLOAD_FILE_FAILED(Module.UPLOAD, 6, "上传文件失败:{}"),
|
||||
|
||||
// ----------------------------- Config -----------------------------------------
|
||||
|
||||
CONFIG_VALUE_IS_NOT_ALLOW_TO_EMPTY(Module.CONFIG, 1, "参数键值不允许为空"),
|
||||
|
||||
CONFIG_VALUE_IS_NOT_IN_OPTIONS(Module.CONFIG, 2, "参数键值不存在列表中"),
|
||||
|
||||
// ------------------------------- Post --------------------------------------------
|
||||
|
||||
POST_NAME_IS_NOT_UNIQUE(Module.POST, 1, "岗位名称:{}, 已存在"),
|
||||
|
||||
POST_CODE_IS_NOT_UNIQUE(Module.POST, 2, "岗位编号:{}, 已存在"),
|
||||
|
||||
POST_ALREADY_ASSIGNED_TO_USER_CAN_NOT_BE_DELETED(Module.POST, 3, "职位已分配给用户,请先取消分配再删除"),
|
||||
|
||||
// ------------------------------- Dept ---------------------------------------------
|
||||
|
||||
DEPT_NAME_IS_NOT_UNIQUE(Module.DEPT, 1, "部门名称:{}, 已存在"),
|
||||
|
||||
DEPT_PARENT_ID_IS_NOT_ALLOWED_SELF(Module.DEPT, 2, "父级部门不能选择自己"),
|
||||
|
||||
DEPT_STATUS_ID_IS_NOT_ALLOWED_CHANGE(Module.DEPT, 3, "子部门还有正在启用的部门,暂时不能停用该部门"),
|
||||
|
||||
DEPT_EXIST_CHILD_DEPT_NOT_ALLOW_DELETE(Module.DEPT, 4, "该部门存在下级部门不允许删除"),
|
||||
|
||||
DEPT_EXIST_LINK_USER_NOT_ALLOW_DELETE(Module.DEPT, 5, "该部门存在关联的用户不允许删除"),
|
||||
|
||||
DEPT_PARENT_DEPT_NO_EXIST_OR_DISABLED(Module.DEPT, 6, "该父级部门不存在或已停用"),
|
||||
|
||||
// ------------------------------- Menu -------------------------------------------------
|
||||
|
||||
MENU_NAME_IS_NOT_UNIQUE(Module.MENU, 1, "新增菜单:{} 失败,菜单名称已存在"),
|
||||
|
||||
MENU_EXTERNAL_LINK_MUST_BE_HTTP(Module.MENU, 2, "菜单外链必须以 http(s)://开头"),
|
||||
|
||||
MENU_PARENT_ID_NOT_ALLOW_SELF(Module.MENU, 3, "父级菜单不能选择自身"),
|
||||
|
||||
MENU_EXIST_CHILD_MENU_NOT_ALLOW_DELETE(Module.MENU, 4, "存在子菜单不允许删除"),
|
||||
|
||||
MENU_ALREADY_ASSIGN_TO_ROLE_NOT_ALLOW_DELETE(Module.MENU, 5, "菜单已分配给角色,不允许"),
|
||||
|
||||
// -------------------------------- Role -------------------------------------------------
|
||||
|
||||
ROLE_NAME_IS_NOT_UNIQUE(Module.ROLE, 1, "角色名称:{}, 已存在"),
|
||||
|
||||
ROLE_KEY_IS_NOT_UNIQUE(Module.ROLE, 2, "角色标识:{}, 已存在"),
|
||||
|
||||
ROLE_DATA_SCOPE_DUPLICATED_DEPT(Module.ROLE, 3, "重复的部门id"),
|
||||
|
||||
ROLE_ALREADY_ASSIGN_TO_USER(Module.ROLE, 4, "角色已分配给用户,请先取消分配,再删除角色"),
|
||||
|
||||
ROLE_IS_NOT_AVAILABLE(Module.ROLE, 5, "角色:{} 已禁用,无法分配给用户"),
|
||||
|
||||
// ---------------------------------- User -----------------------------------------------
|
||||
|
||||
USER_NON_EXIST(Module.USER, 1, "登录用户:{} 不存在"),
|
||||
|
||||
USER_IS_DISABLE(Module.USER, 2, "对不起, 您的账号:{} 已停用"),
|
||||
|
||||
USER_CACHE_IS_EXPIRE(Module.USER, 3, "用户缓存信息已经过期"),
|
||||
|
||||
USER_FAIL_TO_GET_USER_ID(Module.USER, 3, "获取用户ID失败"),
|
||||
|
||||
USER_FAIL_TO_GET_DEPT_ID(Module.USER, 4, "获取用户部门ID失败"),
|
||||
|
||||
USER_FAIL_TO_GET_ACCOUNT(Module.USER, 5, "获取用户账户失败"),
|
||||
|
||||
USER_FAIL_TO_GET_USER_INFO(Module.USER, 6, "获取用户信息失败"),
|
||||
|
||||
USER_IMPORT_DATA_IS_NULL(Module.USER, 7, "导入的用户为空"),
|
||||
|
||||
USER_PHONE_NUMBER_IS_NOT_UNIQUE(Module.USER, 8, "该电话号码已被其他用户占用"),
|
||||
|
||||
USER_EMAIL_IS_NOT_UNIQUE(Module.USER, 9, "该邮件地址已被其他用户占用"),
|
||||
|
||||
USER_PASSWORD_IS_NOT_CORRECT(Module.USER, 10, "用户密码错误"),
|
||||
|
||||
USER_NEW_PASSWORD_IS_THE_SAME_AS_OLD(Module.USER, 11, "用户新密码与旧密码相同"),
|
||||
|
||||
USER_UPLOAD_FILE_FAILED(Module.USER, 12, "用户上传文件失败"),
|
||||
|
||||
USER_NAME_IS_NOT_UNIQUE(Module.USER, 13, "用户名已被其他用户占用"),
|
||||
|
||||
USER_CURRENT_USER_CAN_NOT_BE_DELETE(Module.USER, 14, "当前用户不允许被删除"),
|
||||
|
||||
USER_ADMIN_CAN_NOT_BE_MODIFY(Module.USER, 15, "管理员不允许做任何修改"),
|
||||
|
||||
;
|
||||
|
||||
|
||||
private final int code;
|
||||
private final String msg;
|
||||
|
||||
private static final int BASE_CODE = 40000;
|
||||
|
||||
Business(Module module, int code, String msg) {
|
||||
this.code = BASE_CODE + module.code() + code;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int code() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String message() {
|
||||
return this.msg;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 30000~39999是外部错误码 比如调用支付失败
|
||||
*/
|
||||
public enum External implements ErrorCodeInterface {
|
||||
|
||||
/**
|
||||
* 支付宝调用失败
|
||||
*/
|
||||
FAIL_TO_PAY_ON_ALIPAY(Module.COMMON, 1, "支付宝调用失败");
|
||||
|
||||
|
||||
private final int code;
|
||||
private final String msg;
|
||||
|
||||
private static final int BASE_CODE = 30000;
|
||||
|
||||
External(Module module, int code, String msg) {
|
||||
this.code = BASE_CODE + module.code() + code;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int code() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String message() {
|
||||
return this.msg;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 20000~29999是客户端错误码
|
||||
*/
|
||||
public enum Client implements ErrorCodeInterface {
|
||||
|
||||
/**
|
||||
* 客户端错误码
|
||||
*/
|
||||
COMMON_FORBIDDEN_TO_CALL(Module.COMMON, 1, "禁止调用"),
|
||||
|
||||
COMMON_REQUEST_TOO_OFTEN(Module.COMMON, 2, "调用太过频繁"),
|
||||
|
||||
COMMON_REQUEST_PARAMETERS_INVALID(Module.COMMON, 3, "请求参数异常,{}"),
|
||||
|
||||
COMMON_REQUEST_METHOD_INVALID(Module.COMMON, 4, "请求方式: {} 不支持"),
|
||||
|
||||
COMMON_REQUEST_RESUBMIT(Module.COMMON, 5, "请求重复提交"),
|
||||
|
||||
COMMON_NO_AUTHORIZATION(Module.PERMISSION, 1, "请求接口:{} 失败,用户未授权"),
|
||||
|
||||
;
|
||||
|
||||
private final int code;
|
||||
private final String msg;
|
||||
|
||||
private static final int BASE_CODE = 20000;
|
||||
|
||||
Client(Module module, int code, String msg) {
|
||||
this.code = BASE_CODE + module.code() + code;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int code() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String message() {
|
||||
return this.msg;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 10000~19999是内部错误码 例如 框架有问题之类的
|
||||
*/
|
||||
public enum Internal implements ErrorCodeInterface {
|
||||
/**
|
||||
* 内部错误码
|
||||
*/
|
||||
INVALID_PARAMETER(Module.COMMON, 1, "参数异常:{}"),
|
||||
|
||||
UNKNOWN_ERROR(Module.COMMON, 2, "未知异常, 请查看系统日志"),
|
||||
|
||||
GET_ENUM_FAILED(Module.COMMON, 3, "获取枚举类型失败, 枚举类: {}"),
|
||||
|
||||
GET_CACHE_FAILED(Module.COMMON, 4, "获取缓存失败"),
|
||||
|
||||
INTERNAL_ERROR(Module.COMMON, 5, "系统内部错误:{}"),
|
||||
|
||||
LOGIN_CAPTCHA_GENERATE_FAIL(Module.LOGIN, 1, "验证码生成失败"),
|
||||
|
||||
INVALID_TOKEN(Module.PERMISSION, 1, "token异常"),
|
||||
|
||||
DB_INTERNAL_ERROR(Module.DB, 1, "数据库异常: {}"),
|
||||
|
||||
;
|
||||
|
||||
private final int code;
|
||||
private final String msg;
|
||||
|
||||
private static final int BASE_CODE = 10000;
|
||||
|
||||
Internal(Module module, int code, String msg) {
|
||||
this.code = BASE_CODE + module.code() + code;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int code() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String message() {
|
||||
return this.msg;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
package com.agileboot.common.exception.error;
|
||||
|
||||
/**
|
||||
* 系统内的模块
|
||||
* @author valarchie
|
||||
*/
|
||||
public enum Module {
|
||||
|
||||
/**
|
||||
* 普通模块
|
||||
*/
|
||||
COMMON(0),
|
||||
|
||||
/**
|
||||
* 权限模块
|
||||
*/
|
||||
PERMISSION(1),
|
||||
|
||||
/**
|
||||
* 登录模块
|
||||
*/
|
||||
LOGIN(2),
|
||||
|
||||
/**
|
||||
* 数据库模块
|
||||
*/
|
||||
DB(3),
|
||||
|
||||
/**
|
||||
* 上传
|
||||
*/
|
||||
UPLOAD(4),
|
||||
|
||||
/**
|
||||
* 用户
|
||||
*/
|
||||
USER(5),
|
||||
|
||||
/**
|
||||
* 配置
|
||||
*/
|
||||
CONFIG(6),
|
||||
|
||||
/**
|
||||
* 职位
|
||||
*/
|
||||
POST(7),
|
||||
|
||||
/**
|
||||
* 部门
|
||||
*/
|
||||
DEPT(8),
|
||||
|
||||
/**
|
||||
* 菜单
|
||||
*/
|
||||
MENU(9),
|
||||
|
||||
/**
|
||||
* 角色
|
||||
*/
|
||||
ROLE(10),
|
||||
|
||||
;
|
||||
|
||||
|
||||
private final int code;
|
||||
|
||||
Module(int code) { this.code = code * 100; }
|
||||
|
||||
public int code() {return code; }
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package com.agileboot.common.core.exception;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ApiExceptionTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void testVarargsWithArrayArgs() {
|
||||
String errorMsg = "these parameters are null: %s, %s, %s.";
|
||||
Object[] array = new Object[] { "param1" , "param2" , "param3"};
|
||||
|
||||
String formatWithArray = String.format(errorMsg, array);
|
||||
String formatWithVarargs = String.format(errorMsg, "param1", "param2", "param3");
|
||||
|
||||
Assert.assertEquals(formatWithVarargs, formatWithArray);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVarargsWithNullArgs() {
|
||||
String errorMsg = "these parameters are null: %s, %s, %s.";
|
||||
|
||||
String format = String.format(errorMsg, "param1", null, null);
|
||||
|
||||
Assert.assertEquals("these parameters are null: param1, null, null.", format);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package com.agileboot.common.exception.error;
|
||||
|
||||
import com.agileboot.common.exception.error.ErrorCode.Client;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class ErrorCodeInterfaceTest {
|
||||
|
||||
@Test
|
||||
void testI18nKey() {
|
||||
String i18nKey = Client.COMMON_FORBIDDEN_TO_CALL.i18nKey();
|
||||
Assertions.assertEquals("20001_COMMON_FORBIDDEN_TO_CALL", i18nKey);
|
||||
}
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
package com.agileboot.common.utils.file;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.agileboot.common.config.AgileBootConfig;
|
||||
import com.agileboot.common.constant.Constants.UploadSubDir;
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode.Business;
|
||||
import com.agileboot.common.exception.error.ErrorCode.Internal;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
class FileUploadUtilsTest {
|
||||
|
||||
@Test
|
||||
void testIsAllowedExtension() {
|
||||
String[] imageTypes = new String[]{"img", "gif"};
|
||||
|
||||
boolean isAllow = FileUploadUtils.isExtensionAllowed("img", imageTypes);
|
||||
boolean isNotAllow = FileUploadUtils.isExtensionAllowed("png", imageTypes);
|
||||
|
||||
Assertions.assertTrue(isAllow);
|
||||
Assertions.assertFalse(isNotAllow);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsAllowedExtensionWhenNull() {
|
||||
String[] imageTypes = null;
|
||||
|
||||
boolean isAllow = FileUploadUtils.isExtensionAllowed("img", imageTypes);
|
||||
|
||||
Assertions.assertTrue(isAllow);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetRelativeFileUrl() {
|
||||
String relativeFilePath = FileUploadUtils.getRelativeFileUrl(UploadSubDir.UPLOAD_PATH, "test.jpg");
|
||||
|
||||
Assertions.assertEquals("/profile/upload/test.jpg", relativeFilePath);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSaveFileToLocal() {
|
||||
MultipartFile fileMock = Mockito.mock(MultipartFile.class);
|
||||
|
||||
ApiException exceptionWithNullSubDir = Assertions.assertThrows(ApiException.class,
|
||||
() -> FileUploadUtils.saveFileToLocal(fileMock, "", ""));
|
||||
ApiException exceptionWitEmptyFileName = Assertions.assertThrows(ApiException.class,
|
||||
() -> FileUploadUtils.saveFileToLocal(fileMock, "", ""));
|
||||
|
||||
Assertions.assertEquals(Internal.INVALID_PARAMETER, exceptionWithNullSubDir.getErrorCode());
|
||||
Assertions.assertEquals(Internal.INVALID_PARAMETER, exceptionWitEmptyFileName.getErrorCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsAllowedUploadWhenFileNameTooLong() {
|
||||
MultipartFile fileMock = Mockito.mock(MultipartFile.class);
|
||||
String longFileName = "this is a very very long sentence, this is a very very long sentence, "
|
||||
+ "this is a very very long sentence, this is a very very long sentence, ";
|
||||
|
||||
Mockito.when(fileMock.getOriginalFilename()).thenReturn(longFileName);
|
||||
|
||||
ApiException exception = Assertions.assertThrows(ApiException.class,
|
||||
() -> FileUploadUtils.isAllowedUpload(fileMock, null));
|
||||
Assertions.assertEquals(Business.UPLOAD_FILE_NAME_EXCEED_MAX_LENGTH, exception.getErrorCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsAllowedUploadWhenFileTooBig() {
|
||||
MultipartFile fileMock = Mockito.mock(MultipartFile.class);
|
||||
Mockito.when(fileMock.getOriginalFilename()).thenReturn("test.jpg");
|
||||
Mockito.when(fileMock.getSize()).thenReturn(FileUploadUtils.MAX_FILE_SIZE + 1);
|
||||
|
||||
ApiException exception = Assertions.assertThrows(ApiException.class,
|
||||
() -> FileUploadUtils.isAllowedUpload(fileMock, null));
|
||||
Assertions.assertEquals(Business.UPLOAD_FILE_SIZE_EXCEED_MAX_SIZE, exception.getErrorCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testisAllowDownload() {
|
||||
Assertions.assertFalse(FileUploadUtils.isAllowDownload("../test.jpg"));
|
||||
Assertions.assertFalse(FileUploadUtils.isAllowDownload("../test.exe"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetFileExtension() {
|
||||
MultipartFile fileMock = Mockito.mock(MultipartFile.class);
|
||||
Mockito.when(fileMock.getOriginalFilename()).thenReturn("test.jpg");
|
||||
|
||||
String fileExtension = FileUploadUtils.getFileExtension(fileMock);
|
||||
|
||||
Assertions.assertEquals("jpg", fileExtension);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenerateFilename() {
|
||||
String fileName = "test.jpg";
|
||||
MultipartFile fileMock = Mockito.mock(MultipartFile.class);
|
||||
Mockito.when(fileMock.getOriginalFilename()).thenReturn(fileName);
|
||||
|
||||
String randomFileName = FileUploadUtils.generateFilename(fileMock);
|
||||
|
||||
String[] nameParts = randomFileName.split("_");
|
||||
Assertions.assertEquals("test", nameParts[1]);
|
||||
Assertions.assertTrue(StrUtil.endWith(nameParts[2], ".jpg"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void getFileAbsolutePath() {
|
||||
AgileBootConfig agileBootConfig = new AgileBootConfig();
|
||||
agileBootConfig.setFileBaseDir("D:\\agileboot");
|
||||
|
||||
String fileAbsolutePath = FileUploadUtils.getFileAbsolutePath(UploadSubDir.AVATAR_PATH, "test.jpg");
|
||||
|
||||
Assertions.assertEquals("D:\\agileboot\\profile\\avatar\\test.jpg", fileAbsolutePath);
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package com.agileboot.common.utils.ip;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class IpRegionUtilTest {
|
||||
|
||||
@Test
|
||||
void testGetIpRegion() {
|
||||
IpRegion ipRegion = IpRegionUtil.getIpRegion("110.81.189.80");
|
||||
|
||||
Assertions.assertEquals("中国", ipRegion.getCountry());
|
||||
Assertions.assertEquals("福建省", ipRegion.getProvince());
|
||||
Assertions.assertEquals("泉州市", ipRegion.getCity());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetIpRegionWhenLocalHost() {
|
||||
IpRegion ipRegion = IpRegionUtil.getIpRegion("127.0.0.1");
|
||||
Assertions.assertEquals("内网IP", ipRegion.briefLocation());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetIpRegionWithIpv6() {
|
||||
IpRegion ipRegion = IpRegionUtil.getIpRegion("2001:0DB8:0000:0023:0008:0800:200C:417A");
|
||||
|
||||
Assertions.assertNotNull(ipRegion);
|
||||
Assertions.assertNull(ipRegion.getCountry());
|
||||
Assertions.assertEquals("未知 未知", ipRegion.briefLocation());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetIpRegionWithEmpty() {
|
||||
IpRegion ipRegion = IpRegionUtil.getIpRegion("");
|
||||
|
||||
Assertions.assertNotNull(ipRegion);
|
||||
Assertions.assertNull(ipRegion.getCountry());
|
||||
Assertions.assertEquals("未知 未知", ipRegion.briefLocation());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetIpRegionWithNull() {
|
||||
IpRegion ipRegion = IpRegionUtil.getIpRegion(null);
|
||||
|
||||
Assertions.assertNotNull(ipRegion);
|
||||
Assertions.assertNull(ipRegion.getCountry());
|
||||
Assertions.assertEquals("未知 未知", ipRegion.briefLocation());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetIpRegionWithWrongIpString() {
|
||||
IpRegion ipRegion = IpRegionUtil.getIpRegion("xsdfwefsfsd");
|
||||
|
||||
Assertions.assertNotNull(ipRegion);
|
||||
Assertions.assertNull(ipRegion.getCountry());
|
||||
Assertions.assertEquals("未知 未知", ipRegion.briefLocation());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getBriefLocationByIp() {
|
||||
String briefLocationByIp = IpRegionUtil.getBriefLocationByIp("110.81.189.80");
|
||||
|
||||
Assertions.assertEquals("福建省 泉州市", briefLocationByIp);
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package com.agileboot.common.utils.ip;
|
||||
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class IpUtilTest {
|
||||
|
||||
@Test
|
||||
void isInnerIp() {
|
||||
boolean innerIp1 = IpUtil.isLocalHost("127.0.0.1");
|
||||
boolean innerIp2 = IpUtil.isLocalHost("0:0:0:0:0:0:0:1");
|
||||
boolean innerIp3 = IpUtil.isLocalHost("localhost");
|
||||
boolean innerIp4 = IpUtil.isLocalHost("192.168.1.1");
|
||||
boolean innerIp5 = IpUtil.isLocalHost("10.32.1.1");
|
||||
boolean innerIp6 = IpUtil.isLocalHost("172.16.1.1");
|
||||
boolean notInnerIP = IpUtil.isLocalHost("110.81.189.80");
|
||||
|
||||
Assertions.assertTrue(innerIp1);
|
||||
Assertions.assertTrue(innerIp2);
|
||||
Assertions.assertTrue(innerIp3);
|
||||
Assertions.assertTrue(innerIp4);
|
||||
Assertions.assertTrue(innerIp5);
|
||||
Assertions.assertTrue(innerIp6);
|
||||
Assertions.assertFalse(notInnerIP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLocalHost() {
|
||||
boolean localHost1 = IpUtil.isLocalHost("127.0.0.1");
|
||||
boolean localHost2 = IpUtil.isLocalHost("0:0:0:0:0:0:0:1");
|
||||
boolean localHost4 = IpUtil.isLocalHost("localhost");
|
||||
boolean notLocalHost = IpUtil.isLocalHost("110.81.189.80");
|
||||
|
||||
Assertions.assertTrue(localHost1);
|
||||
Assertions.assertTrue(localHost2);
|
||||
Assertions.assertTrue(localHost4);
|
||||
Assertions.assertFalse(notLocalHost);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
package com.agileboot.common.utils.ip;
|
||||
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class OfflineIpRegionUtilTest {
|
||||
|
||||
@Test
|
||||
void testGetIpRegionWhenIpv4() {
|
||||
IpRegion ipRegion = OfflineIpRegionUtil.getIpRegion("110.81.189.80");
|
||||
|
||||
Assertions.assertEquals("中国", ipRegion.getCountry());
|
||||
Assertions.assertEquals("福建省", ipRegion.getProvince());
|
||||
Assertions.assertEquals("泉州市", ipRegion.getCity());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetIpRegionWithIpv6() {
|
||||
IpRegion region = Assertions.assertDoesNotThrow(() ->
|
||||
OfflineIpRegionUtil.getIpRegion("2001:0DB8:0000:0023:0008:0800:200C:417A")
|
||||
);
|
||||
|
||||
Assertions.assertNull(region);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetIpRegionWithEmpty() {
|
||||
IpRegion region = Assertions.assertDoesNotThrow(() ->
|
||||
OfflineIpRegionUtil.getIpRegion("")
|
||||
);
|
||||
|
||||
Assertions.assertNull(region);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetIpRegionWithNull() {
|
||||
IpRegion region = Assertions.assertDoesNotThrow(() ->
|
||||
OfflineIpRegionUtil.getIpRegion(null)
|
||||
);
|
||||
|
||||
Assertions.assertNull(region);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetIpRegionWithWrongIpString() {
|
||||
IpRegion region = Assertions.assertDoesNotThrow(() ->
|
||||
OfflineIpRegionUtil.getIpRegion("asfdsfdsff")
|
||||
);
|
||||
Assertions.assertNull(region);
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
package com.agileboot.common.utils.ip;
|
||||
|
||||
import com.agileboot.common.config.AgileBootConfig;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class OnlineIpRegionUtilTest {
|
||||
|
||||
@BeforeEach
|
||||
public void enableOnlineAddressQuery() {
|
||||
AgileBootConfig agileBootConfig = new AgileBootConfig();
|
||||
agileBootConfig.setAddressEnabled(true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void getIpRegionWithIpv6() {
|
||||
IpRegion region = Assertions.assertDoesNotThrow(() ->
|
||||
OnlineIpRegionUtil.getIpRegion("ABCD:EF01:2345:6789:ABCD:EF01:2345:6789")
|
||||
);
|
||||
Assertions.assertNull(region);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getIpRegionWithIpv4() {
|
||||
IpRegion ipRegion = OnlineIpRegionUtil.getIpRegion("120.42.247.130");
|
||||
|
||||
Assertions.assertEquals("福建省", ipRegion.getProvince());
|
||||
Assertions.assertEquals("泉州市", ipRegion.getCity());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getIpRegionWithEmpty() {
|
||||
IpRegion region = Assertions.assertDoesNotThrow(() ->
|
||||
OnlineIpRegionUtil.getIpRegion("")
|
||||
);
|
||||
|
||||
Assertions.assertNull(region);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void getIpRegionWithNull() {
|
||||
IpRegion region = Assertions.assertDoesNotThrow(() ->
|
||||
OnlineIpRegionUtil.getIpRegion(null)
|
||||
);
|
||||
|
||||
Assertions.assertNull(region);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getIpRegionWithWrongIpString() {
|
||||
IpRegion region = Assertions.assertDoesNotThrow(() ->
|
||||
OnlineIpRegionUtil.getIpRegion("seffsdfsdf")
|
||||
);
|
||||
|
||||
Assertions.assertNull(region);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
package com.agileboot.common.utils.jackson;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author duanxinyuan 2019/1/21 18:17
|
||||
*/
|
||||
public class JacksonUtilTest {
|
||||
|
||||
@Test
|
||||
public void testObjectToJson() {
|
||||
Person person = Person.newPerson();
|
||||
|
||||
String jacksonStr = JacksonUtil.to(person);
|
||||
Assert.assertEquals(DateUtil.formatDateTime(person.getDate()), JacksonUtil.getAsString(jacksonStr, "date"));
|
||||
Assert.assertEquals(DateUtil.formatLocalDateTime(person.getLocalDateTime()),
|
||||
JacksonUtil.getAsString(jacksonStr, "localDateTime"));
|
||||
Assert.assertEquals(person.getName(), JacksonUtil.getAsString(jacksonStr, "name"));
|
||||
Assert.assertEquals(person.getAge(), JacksonUtil.getAsInt(jacksonStr, "age"));
|
||||
Assert.assertEquals(person.isMan(), JacksonUtil.getAsBoolean(jacksonStr, "man"));
|
||||
Assert.assertEquals(person.getMoney(), JacksonUtil.getAsBigDecimal(jacksonStr, "money"));
|
||||
Assert.assertEquals(person.getTrait(), JacksonUtil.getAsList(jacksonStr, "trait", String.class));
|
||||
|
||||
Assert.assertNotNull(JacksonUtil.getAsString(jacksonStr, "name"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试兼容情况
|
||||
*/
|
||||
@Test
|
||||
public void testAllPrimitiveTypeToJson() {
|
||||
String json = "{\n"
|
||||
+ "\"code\": \"200\",\n"
|
||||
+ "\"id\": \"2001215464647687987\",\n"
|
||||
+ "\"message\": \"success\",\n"
|
||||
+ "\"amount\": \"1.12345\",\n"
|
||||
+ "\"amount1\": \"0.12345\",\n"
|
||||
+ "\"isSuccess\": \"true\",\n"
|
||||
+ "\"isSuccess1\": \"1\",\n"
|
||||
+ "\"key\": \"8209167202090377654857374178856064487200234961995543450245362822537162918731039965956758726661669012305745755921310000297396309887550627402157318910581311\"\n"
|
||||
+ "}";
|
||||
Assert.assertEquals(200, JacksonUtil.getAsInt(json, "code"));
|
||||
Assert.assertEquals(2001215464647687987L,JacksonUtil.getAsLong(json, "id"));
|
||||
Assert.assertEquals("success", JacksonUtil.getAsString(json, "message"));
|
||||
Assert.assertEquals(new BigDecimal("1.12345"), JacksonUtil.getAsBigDecimal(json, "amount"));
|
||||
Assert.assertEquals(new BigDecimal("0.12345"), JacksonUtil.getAsBigDecimal(json, "amount1"));
|
||||
Assert.assertEquals(1.12345d, JacksonUtil.getAsDouble(json, "amount"), 0.00001);
|
||||
Assert.assertEquals(0.12345d, JacksonUtil.getAsDouble(json, "amount1"), 0.00001);
|
||||
Assert.assertTrue(JacksonUtil.getAsBoolean(json, "isSuccess"));
|
||||
Assert.assertTrue(JacksonUtil.getAsBoolean(json, "isSuccess1"));
|
||||
Assert.assertEquals(new BigInteger(
|
||||
"8209167202090377654857374178856064487200234961995543450245362822537162918731039965956758726661669012305745755921310000297396309887550627402157318910581311"),
|
||||
JacksonUtil.getAsBigInteger(json, "key"));
|
||||
Assert.assertEquals("1", JacksonUtil.getAsString(json, "isSuccess1"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package com.agileboot.common.utils.jackson;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author duanxinyuan
|
||||
* 2018/6/29 14:17
|
||||
*/
|
||||
@Data
|
||||
public class Person {
|
||||
public String name;
|
||||
public Date date;
|
||||
public LocalDateTime localDateTime;
|
||||
public int age;
|
||||
public BigDecimal money;
|
||||
public boolean man;
|
||||
public ArrayList<String> trait;
|
||||
public HashMap<String, String> cards;
|
||||
|
||||
public static Person newPerson() {
|
||||
Person person = new Person();
|
||||
person.name = "张三";
|
||||
person.date = new Date();
|
||||
person.localDateTime = LocalDateTime.now();
|
||||
person.age = 100;
|
||||
person.money = BigDecimal.valueOf(500.21);
|
||||
person.man = true;
|
||||
person.trait = new ArrayList<>();
|
||||
person.trait.add("淡然");
|
||||
person.trait.add("温和");
|
||||
person.cards = new HashMap<>();
|
||||
person.cards.put("身份证", "4a6d456as");
|
||||
person.cards.put("建行卡", "649874545");
|
||||
return person;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package com.agileboot.common.utils.poi;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.http.HtmlUtil;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class CustomExcelUtilTest {
|
||||
|
||||
@Test
|
||||
void testImportAndExport() {
|
||||
PostDTO post1 = new PostDTO(1L, "admin1", "管理员1", "1", "无备注", "1", "正常");
|
||||
PostDTO post2 = new PostDTO(2L, "admin2", "管理员2<script>alert(1)</script>", "2", "无备注", "1", "正常");
|
||||
|
||||
List<PostDTO> postDTOList = new ArrayList<>();
|
||||
postDTOList.add(post1);
|
||||
postDTOList.add(post2);
|
||||
|
||||
File file = FileUtil.createTempFile();
|
||||
|
||||
CustomExcelUtil.writeToOutputStream(postDTOList, PostDTO.class, FileUtil.getOutputStream(file));
|
||||
|
||||
List<PostDTO> postListFromExcel = CustomExcelUtil.readFromInputStream(PostDTO.class, FileUtil.getInputStream(file));
|
||||
|
||||
PostDTO post1fromExcel = postListFromExcel.get(0);
|
||||
PostDTO post2fromExcel = postListFromExcel.get(1);
|
||||
|
||||
Assertions.assertEquals(post1.getPostId(), post1fromExcel.getPostId());
|
||||
Assertions.assertEquals(post1.getPostCode(), post1fromExcel.getPostCode());
|
||||
Assertions.assertEquals(post2.getPostId(), post2fromExcel.getPostId());
|
||||
Assertions.assertEquals(post2.getPostCode(), post2fromExcel.getPostCode());
|
||||
// 检查脚本注入的字符串是否被去除
|
||||
Assertions.assertNotEquals(post2.getPostName(), post2fromExcel.getPostName());
|
||||
Assertions.assertEquals(HtmlUtil.cleanHtmlTag(post2.getPostName()), post2fromExcel.getPostName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package com.agileboot.common.utils.poi;
|
||||
|
||||
import com.agileboot.common.annotation.ExcelColumn;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
@EqualsAndHashCode
|
||||
public class PostDTO {
|
||||
|
||||
@ExcelColumn(name = "岗位ID")
|
||||
private Long postId;
|
||||
|
||||
|
||||
@ExcelColumn(name = "岗位编码")
|
||||
private String postCode;
|
||||
|
||||
@ExcelColumn(name = "岗位名称")
|
||||
private String postName;
|
||||
|
||||
|
||||
@ExcelColumn(name = "岗位排序")
|
||||
private String postSort;
|
||||
|
||||
@ExcelColumn(name = "备注")
|
||||
private String remark;
|
||||
|
||||
private String status;
|
||||
|
||||
@ExcelColumn(name = "状态")
|
||||
private String statusStr;
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package com.agileboot.common.utils.time;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class DatePickUtilTest {
|
||||
|
||||
@Test
|
||||
void testGetBeginOfTheDay() {
|
||||
Date beginOfTheDay = DatePickUtil.getBeginOfTheDay(new Date());
|
||||
|
||||
Calendar instance = Calendar.getInstance();
|
||||
instance.setTime(beginOfTheDay);
|
||||
|
||||
Assertions.assertEquals(0, instance.get(Calendar.HOUR));
|
||||
Assertions.assertEquals(0, instance.get(Calendar.MINUTE));
|
||||
Assertions.assertEquals(0, instance.get(Calendar.SECOND));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetBeginOfTheDayWhenNull() {
|
||||
Assertions.assertDoesNotThrow(() -> DatePickUtil.getBeginOfTheDay(null)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetEndOfTheDay() {
|
||||
Date endOfTheDay = DatePickUtil.getEndOfTheDay(new Date());
|
||||
|
||||
Calendar instance = Calendar.getInstance();
|
||||
instance.setTime(endOfTheDay);
|
||||
|
||||
Assertions.assertEquals(23, instance.get(Calendar.HOUR_OF_DAY));
|
||||
Assertions.assertEquals(59, instance.get(Calendar.MINUTE));
|
||||
Assertions.assertEquals(59, instance.get(Calendar.SECOND));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetEndOfTheDayWhenNull() {
|
||||
Assertions.assertDoesNotThrow(() -> DatePickUtil.getEndOfTheDay(null)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
64
agileboot-common/wol-common-box/pom.xml
Normal file
64
agileboot-common/wol-common-box/pom.xml
Normal file
@@ -0,0 +1,64 @@
|
||||
<?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>
|
||||
|
||||
<groupId>com.agileboot</groupId>
|
||||
<artifactId>wol-common-box</artifactId>
|
||||
<version>${revision}</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<properties>
|
||||
<revision>1.0.0</revision>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
<!-- 核心模块 -->
|
||||
<dependency>
|
||||
<groupId>com.agileboot</groupId>
|
||||
<artifactId>wol-common-core</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.agileboot</groupId>
|
||||
<artifactId>wol-common-doc</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.agileboot</groupId>
|
||||
<artifactId>wol-common-mybatis</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.agileboot</groupId>
|
||||
<artifactId>wol-common-redis</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.agileboot</groupId>
|
||||
<artifactId>wol-common-web</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.agileboot</groupId>
|
||||
<artifactId>wol-common-json</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.agileboot</groupId>
|
||||
<artifactId>wol-common-satoken</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.agileboot</groupId>
|
||||
<artifactId>wol-common-nacos</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
||||
106
agileboot-common/wol-common-core/pom.xml
Normal file
106
agileboot-common/wol-common-core/pom.xml
Normal file
@@ -0,0 +1,106 @@
|
||||
<?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>com.agileboot</groupId>
|
||||
<artifactId>agileboot-common</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>wol-common-core</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<!-- Spring框架基本的核心工具 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
</dependency>
|
||||
<!-- servlet包 -->
|
||||
<dependency>
|
||||
<groupId>jakarta.servlet</groupId>
|
||||
<artifactId>jakarta.servlet-api</artifactId>
|
||||
</dependency>
|
||||
<!-- SpringWeb模块 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
</dependency>
|
||||
<!-- pool 对象池 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency>
|
||||
<!-- 自定义验证注解 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.lionsoul</groupId>
|
||||
<artifactId>ip2region</artifactId>
|
||||
</dependency>
|
||||
<!-- excel工具 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
</dependency>
|
||||
<!-- io常用工具类 -->
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
<!--常用工具类 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
<artifactId>jackson-module-parameter-names</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jdk8</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fastjson2</groupId>
|
||||
<artifactId>fastjson2</artifactId>
|
||||
</dependency>
|
||||
<!--ENC加密-->
|
||||
<dependency>
|
||||
<groupId>com.github.ulisesbocchio</groupId>
|
||||
<artifactId>jasypt-spring-boot-starter</artifactId>
|
||||
<version>2.1.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- swagger注解 -->
|
||||
<dependency>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-annotations</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.annotation;
|
||||
package com.agileboot.common.core.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.annotation;
|
||||
package com.agileboot.common.core.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.agileboot.common.config;
|
||||
package com.agileboot.common.core.config;
|
||||
|
||||
import com.agileboot.common.constant.Constants;
|
||||
import com.agileboot.common.core.constant.Constants;
|
||||
import java.io.File;
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
@@ -8,7 +8,7 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 读取项目相关配置
|
||||
*
|
||||
* TODO 移走 不合适放在这里common包底下
|
||||
* @author valarchie
|
||||
*/
|
||||
@Component
|
||||
@@ -56,7 +56,7 @@ public class AgileBootConfig {
|
||||
*/
|
||||
private static String rsaPrivateKey;
|
||||
|
||||
private static String apiDocsPathPrefix;
|
||||
private static String apiPrefix;
|
||||
|
||||
public static String getFileBaseDir() {
|
||||
return fileBaseDir;
|
||||
@@ -66,12 +66,12 @@ public class AgileBootConfig {
|
||||
AgileBootConfig.fileBaseDir = fileBaseDir + File.separator + Constants.RESOURCE_PREFIX;
|
||||
}
|
||||
|
||||
public static String getApiDocsPathPrefix() {
|
||||
return apiDocsPathPrefix;
|
||||
public static String getApiPrefix() {
|
||||
return apiPrefix;
|
||||
}
|
||||
|
||||
public void setApiDocsPathPrefix(String apiDocsPathPrefix) {
|
||||
AgileBootConfig.apiDocsPathPrefix = apiDocsPathPrefix;
|
||||
public void setApiPrefix(String apiDocsPathPrefix) {
|
||||
AgileBootConfig.apiPrefix = apiDocsPathPrefix;
|
||||
}
|
||||
|
||||
public static boolean isAddressEnabled() {
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.agileboot.common.core.constant;
|
||||
|
||||
/**
|
||||
* 通用常量信息
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface Constants {
|
||||
|
||||
int KB = 1024;
|
||||
int MB = KB * 1024;
|
||||
int GB = MB * 1024;
|
||||
|
||||
/**
|
||||
* 资源映射路径 前缀
|
||||
*/
|
||||
String RESOURCE_PREFIX = "profile";
|
||||
|
||||
/**
|
||||
* UTF-8 字符集
|
||||
*/
|
||||
String UTF8 = "UTF-8";
|
||||
|
||||
/**
|
||||
* GBK 字符集
|
||||
*/
|
||||
String GBK = "GBK";
|
||||
|
||||
/**
|
||||
* www主域
|
||||
*/
|
||||
String WWW = "www.";
|
||||
|
||||
/**
|
||||
* http请求
|
||||
*/
|
||||
String HTTP = "http://";
|
||||
|
||||
/**
|
||||
* https请求
|
||||
*/
|
||||
String HTTPS = "https://";
|
||||
|
||||
/**
|
||||
* 通用成功标识
|
||||
*/
|
||||
String SUCCESS = "0";
|
||||
String NORMAL = "0"; // 正常状态
|
||||
|
||||
/**
|
||||
* 通用失败标识
|
||||
*/
|
||||
String FAIL = "1";
|
||||
String DISABLE = "1"; // 异常/停用状态
|
||||
|
||||
/**
|
||||
* 登录成功
|
||||
*/
|
||||
String LOGIN_SUCCESS = "Success";
|
||||
|
||||
/**
|
||||
* 注销
|
||||
*/
|
||||
String LOGOUT = "Logout";
|
||||
|
||||
/**
|
||||
* 注册
|
||||
*/
|
||||
String REGISTER = "Register";
|
||||
|
||||
/**
|
||||
* 登录失败
|
||||
*/
|
||||
String LOGIN_FAIL = "Error";
|
||||
|
||||
/**
|
||||
* 验证码有效期(分钟)
|
||||
*/
|
||||
Integer CAPTCHA_EXPIRATION = 2;
|
||||
|
||||
/**
|
||||
* 顶级部门id
|
||||
*/
|
||||
Long TOP_PARENT_ID = 0L;
|
||||
/**
|
||||
* 超级管理员ID
|
||||
*/
|
||||
Long SUPER_ADMIN_ID = 1L;
|
||||
/**
|
||||
* 超级管理员角色 roleKey
|
||||
*/
|
||||
String SUPER_ADMIN_ROLE_KEY = "superadmin";
|
||||
|
||||
/**
|
||||
* 租户管理员角色 roleKey
|
||||
*/
|
||||
String TENANT_ADMIN_ROLE_KEY = "admin";
|
||||
|
||||
/**
|
||||
* 租户管理员角色名称
|
||||
*/
|
||||
String TENANT_ADMIN_ROLE_NAME = "管理员";
|
||||
|
||||
/**
|
||||
* 默认租户ID
|
||||
*/
|
||||
String DEFAULT_TENANT_ID = "000000";
|
||||
|
||||
interface Cache {
|
||||
/**
|
||||
* 全局 redis key (业务无关的key)
|
||||
*/
|
||||
String GLOBAL_REDIS_KEY = "global:";
|
||||
|
||||
/**
|
||||
* 登录账户密码错误次数 redis key
|
||||
*/
|
||||
String PWD_ERR_CNT_KEY = "pwd_err_cnt:";
|
||||
/**
|
||||
* 验证码 redis key
|
||||
*/
|
||||
String CAPTCHA_CODE_KEY = GLOBAL_REDIS_KEY + "captcha_codes:";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.agileboot.common.core.constant;
|
||||
|
||||
/**
|
||||
* 返回状态码
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface HttpStatus {
|
||||
/**
|
||||
* 操作成功
|
||||
*/
|
||||
int SUCCESS = 200;
|
||||
|
||||
/**
|
||||
* 对象创建成功
|
||||
*/
|
||||
int CREATED = 201;
|
||||
|
||||
/**
|
||||
* 请求已经被接受
|
||||
*/
|
||||
int ACCEPTED = 202;
|
||||
|
||||
/**
|
||||
* 操作已经执行成功,但是没有返回数据
|
||||
*/
|
||||
int NO_CONTENT = 204;
|
||||
|
||||
/**
|
||||
* 资源已被移除
|
||||
*/
|
||||
int MOVED_PERM = 301;
|
||||
|
||||
/**
|
||||
* 重定向
|
||||
*/
|
||||
int SEE_OTHER = 303;
|
||||
|
||||
/**
|
||||
* 资源没有被修改
|
||||
*/
|
||||
int NOT_MODIFIED = 304;
|
||||
|
||||
/**
|
||||
* 参数列表错误(缺少,格式不匹配)
|
||||
*/
|
||||
int BAD_REQUEST = 400;
|
||||
|
||||
/**
|
||||
* 未授权
|
||||
*/
|
||||
int UNAUTHORIZED = 401;
|
||||
|
||||
/**
|
||||
* 访问受限,授权过期
|
||||
*/
|
||||
int FORBIDDEN = 403;
|
||||
|
||||
/**
|
||||
* 资源,服务未找到
|
||||
*/
|
||||
int NOT_FOUND = 404;
|
||||
|
||||
/**
|
||||
* 不允许的http方法
|
||||
*/
|
||||
int BAD_METHOD = 405;
|
||||
|
||||
/**
|
||||
* 资源冲突,或者资源被锁
|
||||
*/
|
||||
int CONFLICT = 409;
|
||||
|
||||
/**
|
||||
* 不支持的数据,媒体类型
|
||||
*/
|
||||
int UNSUPPORTED_TYPE = 415;
|
||||
|
||||
/**
|
||||
* 系统内部错误
|
||||
*/
|
||||
int ERROR = 500;
|
||||
|
||||
/**
|
||||
* 接口未实现
|
||||
*/
|
||||
int NOT_IMPLEMENTED = 501;
|
||||
|
||||
/**
|
||||
* 系统警告消息
|
||||
*/
|
||||
int WARN = 601;
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package com.agileboot.common.core.core;
|
||||
|
||||
import com.agileboot.common.core.constant.HttpStatus;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 响应信息主体
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class R<T> implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 成功
|
||||
*/
|
||||
public static final int SUCCESS = 200;
|
||||
|
||||
/**
|
||||
* 失败
|
||||
*/
|
||||
public static final int FAIL = 500;
|
||||
|
||||
/**
|
||||
* 消息状态码
|
||||
*/
|
||||
private int code;
|
||||
|
||||
/**
|
||||
* 消息内容
|
||||
*/
|
||||
private String msg;
|
||||
|
||||
/**
|
||||
* 数据对象
|
||||
*/
|
||||
private T data;
|
||||
|
||||
public static <T> R<T> ok() {
|
||||
return restResult(null, SUCCESS, "操作成功");
|
||||
}
|
||||
|
||||
public static <T> R<T> ok(T data) {
|
||||
return restResult(data, SUCCESS, "操作成功");
|
||||
}
|
||||
|
||||
public static <T> R<T> ok(String msg) {
|
||||
return restResult(null, SUCCESS, msg);
|
||||
}
|
||||
|
||||
public static <T> R<T> ok(String msg, T data) {
|
||||
return restResult(data, SUCCESS, msg);
|
||||
}
|
||||
|
||||
public static <T> R<T> fail() {
|
||||
return restResult(null, FAIL, "操作失败");
|
||||
}
|
||||
|
||||
public static <T> R<T> fail(String msg) {
|
||||
return restResult(null, FAIL, msg);
|
||||
}
|
||||
|
||||
public static <T> R<T> fail(T data) {
|
||||
return restResult(data, FAIL, "操作失败");
|
||||
}
|
||||
|
||||
public static <T> R<T> fail(String msg, T data) {
|
||||
return restResult(data, FAIL, msg);
|
||||
}
|
||||
|
||||
public static <T> R<T> fail(int code, String msg) {
|
||||
return restResult(null, code, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回警告消息
|
||||
*
|
||||
* @param msg 返回内容
|
||||
* @return 警告消息
|
||||
*/
|
||||
public static <T> R<T> warn(String msg) {
|
||||
return restResult(null, HttpStatus.WARN, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回警告消息
|
||||
*
|
||||
* @param msg 返回内容
|
||||
* @param data 数据对象
|
||||
* @return 警告消息
|
||||
*/
|
||||
public static <T> R<T> warn(String msg, T data) {
|
||||
return restResult(data, HttpStatus.WARN, msg);
|
||||
}
|
||||
|
||||
private static <T> R<T> restResult(T data, int code, String msg) {
|
||||
R<T> r = new R<>();
|
||||
r.setCode(code);
|
||||
r.setData(data);
|
||||
r.setMsg(msg);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static <T> Boolean isError(R<T> ret) {
|
||||
return !isSuccess(ret);
|
||||
}
|
||||
|
||||
public static <T> Boolean isSuccess(R<T> ret) {
|
||||
return R.SUCCESS == ret.getCode();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.core.base;
|
||||
package com.agileboot.common.core.core.base;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.orm.common.interfaces;
|
||||
package com.agileboot.common.core.enums;
|
||||
|
||||
/**
|
||||
* @author valarchie
|
||||
@@ -18,7 +18,7 @@ public interface BasicEnum<T>{
|
||||
* 获取枚举的描述
|
||||
* @return 描述
|
||||
*/
|
||||
String description();
|
||||
String getDesc();
|
||||
|
||||
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
package com.agileboot.orm.common.util;
|
||||
package com.agileboot.common.core.enums;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode;
|
||||
import com.agileboot.orm.common.interfaces.BasicEnum;
|
||||
import com.agileboot.common.core.exception.ApiException;
|
||||
import com.agileboot.common.core.exception.error.ErrorCode;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -55,7 +54,7 @@ public class BasicEnumUtil {
|
||||
public static <E extends Enum<E>> String getDescriptionByValue(Class<E> enumClass, Object value) {
|
||||
E basicEnum = fromValueSafely(enumClass, value);
|
||||
if (basicEnum != null) {
|
||||
return ((BasicEnum<?>) basicEnum).description();
|
||||
return ((BasicEnum<?>) basicEnum).getDesc();
|
||||
}
|
||||
return UNKNOWN;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.orm.common.interfaces;
|
||||
package com.agileboot.common.core.enums;
|
||||
|
||||
/**
|
||||
* 字典类型 接口
|
||||
@@ -10,6 +10,6 @@ public interface DictionaryEnum<T> extends BasicEnum<T> {
|
||||
* 获取css标签
|
||||
* @return css标签
|
||||
*/
|
||||
String cssTag();
|
||||
String getCssTag();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.agileboot.common.core.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 登录类型
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum LoginType {
|
||||
|
||||
/**
|
||||
* 密码登录
|
||||
*/
|
||||
PASSWORD("user.password.retry.limit.exceed", "user.password.retry.limit.count"),
|
||||
|
||||
/**
|
||||
* 短信登录
|
||||
*/
|
||||
SMS("sms.code.retry.limit.exceed", "sms.code.retry.limit.count"),
|
||||
|
||||
/**
|
||||
* 邮箱登录
|
||||
*/
|
||||
EMAIL("email.code.retry.limit.exceed", "email.code.retry.limit.count"),
|
||||
|
||||
/**
|
||||
* 小程序登录
|
||||
*/
|
||||
XCX("", "");
|
||||
|
||||
/**
|
||||
* 登录重试超出限制提示
|
||||
*/
|
||||
final String retryLimitExceed;
|
||||
|
||||
/**
|
||||
* 登录重试限制计数提示
|
||||
*/
|
||||
final String retryLimitCount;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.agileboot.common.core.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* 用户类型
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum UserType {
|
||||
|
||||
/**
|
||||
* 后台系统用户
|
||||
*/
|
||||
SYS_USER("sys_user"),
|
||||
|
||||
/**
|
||||
* 移动客户端用户
|
||||
*/
|
||||
APP_USER("app_user");
|
||||
|
||||
/**
|
||||
* 用户类型标识(用于 token、权限识别等)
|
||||
*/
|
||||
private final String userType;
|
||||
|
||||
public static UserType getUserType(String str) {
|
||||
for (UserType value : values()) {
|
||||
if (StringUtils.contains(str, value.getUserType())) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("'UserType' not found By " + str);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.core.enums.dictionary.Dictionary;
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 对应sys_operation_log的business_type
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
@Dictionary(name = "sysOperationLog.businessType")
|
||||
public enum BusinessTypeEnum implements DictionaryEnum<Integer> {
|
||||
|
||||
/**
|
||||
* 操作类型
|
||||
*/
|
||||
OTHER(0, "其他操作", CssTag.INFO),
|
||||
ADD(1, "添加", CssTag.PRIMARY),
|
||||
MODIFY(2, "修改", CssTag.PRIMARY),
|
||||
DELETE(3, "删除", CssTag.DANGER),
|
||||
GRANT(4, "授权", CssTag.PRIMARY),
|
||||
EXPORT(5, "导出", CssTag.WARNING),
|
||||
IMPORT(6, "导入", CssTag.WARNING),
|
||||
FORCE_LOGOUT(7, "强退", CssTag.DANGER),
|
||||
CLEAN(8, "清空", CssTag.DANGER),
|
||||
;
|
||||
|
||||
private final Integer value;
|
||||
private final String desc;
|
||||
private final String cssTag;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import com.agileboot.common.core.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.core.enums.dictionary.Dictionary;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 对应sys_user的sex字段
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
@Dictionary(name = "sysUser.sex")
|
||||
public enum GenderEnum implements DictionaryEnum<Integer> {
|
||||
|
||||
/**
|
||||
* 用户性别
|
||||
*/
|
||||
MALE(1, "男", CssTag.PRIMARY),
|
||||
FEMALE(2, "女", CssTag.PRIMARY),
|
||||
UNKNOWN(0, "未知", CssTag.PRIMARY);
|
||||
|
||||
private final Integer value;
|
||||
private final String desc;
|
||||
private final String cssTag;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import com.agileboot.common.core.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.core.enums.dictionary.Dictionary;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 用户状态
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
// TODO 表记得改成LoginLog
|
||||
@Dictionary(name = "sysLoginLog.status")
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum LoginStatusEnum implements DictionaryEnum<Integer> {
|
||||
/**
|
||||
* status of user
|
||||
*/
|
||||
LOGIN_SUCCESS(1, "登录成功", CssTag.SUCCESS),
|
||||
LOGOUT(2, "退出成功", CssTag.INFO),
|
||||
REGISTER(3, "注册", CssTag.PRIMARY),
|
||||
LOGIN_FAIL(0, "登录失败", CssTag.DANGER);
|
||||
|
||||
private final Integer value;
|
||||
private final String desc;
|
||||
private final String cssTag;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.BasicEnum;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author valarchie
|
||||
*/
|
||||
@Deprecated
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum MenuComponentEnum implements BasicEnum<Integer> {
|
||||
|
||||
/**
|
||||
* 菜单组件类型
|
||||
*/
|
||||
LAYOUT(1, "Layout"),
|
||||
PARENT_VIEW(2, "ParentView"),
|
||||
INNER_LINK(3, "InnerLink");
|
||||
|
||||
private final Integer value;
|
||||
private final String desc;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.BasicEnum;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author valarchie
|
||||
* 对应 sys_menu表的menu_type字段
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum MenuTypeEnum implements BasicEnum<Integer> {
|
||||
|
||||
/**
|
||||
* 菜单类型
|
||||
*/
|
||||
MENU(1, "页面"),
|
||||
CATALOG(2, "目录"),
|
||||
IFRAME(3, "内嵌Iframe"),
|
||||
OUTSIDE_LINK_REDIRECT(4, "外链跳转");
|
||||
|
||||
private final Integer value;
|
||||
private final String desc;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import com.agileboot.common.core.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.core.enums.dictionary.Dictionary;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 对应sys_notice的 status字段
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Dictionary(name = "sysNotice.status")
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum NoticeStatusEnum implements DictionaryEnum<Integer> {
|
||||
|
||||
/**
|
||||
* 通知状态
|
||||
*/
|
||||
OPEN(1, "正常", CssTag.PRIMARY),
|
||||
CLOSE(0, "关闭", CssTag.DANGER);
|
||||
|
||||
private final Integer value;
|
||||
private final String desc;
|
||||
private final String cssTag;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import com.agileboot.common.core.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.core.enums.dictionary.Dictionary;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 对应sys_notice的 notice_type字段
|
||||
* 名称一般由对应的表名.字段构成
|
||||
* 全局的话使用common作为表名
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Dictionary(name = "sysNotice.noticeType")
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum NoticeTypeEnum implements DictionaryEnum<Integer> {
|
||||
|
||||
/**
|
||||
* 通知类型
|
||||
*/
|
||||
NOTIFICATION(1, "通知", CssTag.WARNING),
|
||||
ANNOUNCEMENT(2, "公告", CssTag.SUCCESS);
|
||||
|
||||
private final Integer value;
|
||||
private final String desc;
|
||||
private final String cssTag;
|
||||
|
||||
public static Integer getDescByValue(Integer value) {
|
||||
for (NoticeTypeEnum item : values()) {
|
||||
if (item.value.equals(value)) {
|
||||
return item.value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import com.agileboot.common.core.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.core.enums.dictionary.Dictionary;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 对应sys_operation_log的status字段
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Dictionary(name = "sysOperationLog.status")
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum OperationStatusEnum implements DictionaryEnum<Integer> {
|
||||
|
||||
/**
|
||||
* 操作状态
|
||||
*/
|
||||
SUCCESS(1, "成功", CssTag.PRIMARY),
|
||||
FAIL(0, "失败", CssTag.DANGER);
|
||||
|
||||
private final Integer value;
|
||||
private final String desc;
|
||||
private final String cssTag;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.BasicEnum;
|
||||
import com.agileboot.common.core.enums.dictionary.Dictionary;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 操作者类型
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
@Dictionary(name = "sysOperationLog.operatorType")
|
||||
public enum OperatorTypeEnum implements BasicEnum<Integer> {
|
||||
|
||||
/**
|
||||
* 菜单类型
|
||||
*/
|
||||
OTHER(1, "其他"),
|
||||
WEB(2, "Web用户"),
|
||||
MOBILE(3, "手机端用户");
|
||||
|
||||
private final Integer value;
|
||||
private final String desc;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.BasicEnum;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* Http Method
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum RequestMethodEnum implements BasicEnum<Integer> {
|
||||
|
||||
/**
|
||||
* 菜单类型
|
||||
*/
|
||||
GET(1, "GET"),
|
||||
POST(2, "POST"),
|
||||
PUT(3, "PUT"),
|
||||
DELETE(4, "DELETE"),
|
||||
UNKNOWN(-1, "UNKNOWN");
|
||||
|
||||
private final Integer value;
|
||||
private final String desc;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import com.agileboot.common.core.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.core.enums.dictionary.Dictionary;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 除非表有特殊指明的话,一般用这个枚举代表 status字段
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Dictionary(name = "common.status")
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum StatusEnum implements DictionaryEnum<Integer> {
|
||||
/**
|
||||
* 开关状态
|
||||
*/
|
||||
ENABLE(1, "正常", CssTag.PRIMARY),
|
||||
DISABLE(0, "停用", CssTag.DANGER);
|
||||
|
||||
private final Integer value;
|
||||
private final String desc;
|
||||
private final String cssTag;
|
||||
|
||||
public static Integer getDescByValue(Integer value) {
|
||||
for (StatusEnum item : StatusEnum.values()) {
|
||||
if (item.value.equals(value)) {
|
||||
return item.value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import com.agileboot.common.core.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.core.enums.dictionary.Dictionary;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 对应sys_user的status字段
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
@Dictionary(name = "sysUser.status")
|
||||
public enum UserStatusEnum implements DictionaryEnum<Integer> {
|
||||
|
||||
/**
|
||||
* 用户账户状态
|
||||
*/
|
||||
NORMAL(1, "正常", CssTag.PRIMARY),
|
||||
DISABLED(2, "禁用", CssTag.DANGER),
|
||||
FROZEN(3, "冻结", CssTag.WARNING);
|
||||
|
||||
private final Integer value;
|
||||
private final String desc;
|
||||
private final String cssTag;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import com.agileboot.common.core.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.core.enums.dictionary.Dictionary;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 对应sys_menu表的is_visible字段
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Deprecated
|
||||
@Dictionary(name = "sysMenu.isVisible")
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum VisibleStatusEnum implements DictionaryEnum<Integer> {
|
||||
|
||||
/**
|
||||
* 显示与否
|
||||
*/
|
||||
SHOW(1, "显示", CssTag.PRIMARY),
|
||||
HIDE(0, "隐藏", CssTag.DANGER);
|
||||
|
||||
private final Integer value;
|
||||
private final String desc;
|
||||
private final String cssTag;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import com.agileboot.common.core.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.core.enums.dictionary.Dictionary;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 系统内代表是与否的枚举
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Dictionary(name = "common.yesOrNo")
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum YesOrNoEnum implements DictionaryEnum<Integer> {
|
||||
/**
|
||||
* 是与否
|
||||
*/
|
||||
YES(1, "是", CssTag.PRIMARY),
|
||||
NO(0, "否", CssTag.DANGER);
|
||||
|
||||
private final Integer value;
|
||||
private final String desc;
|
||||
private final String cssTag;
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.orm.common;
|
||||
package com.agileboot.common.core.enums.dictionary;
|
||||
|
||||
/**
|
||||
* Css 样式
|
||||
@@ -6,8 +6,7 @@ package com.agileboot.orm.common;
|
||||
*/
|
||||
public class CssTag {
|
||||
|
||||
public static final String NONE = "";
|
||||
public static final String PRIMARY = "primary";
|
||||
public static final String PRIMARY = "";
|
||||
public static final String DANGER = "danger";
|
||||
public static final String WARNING = "warning";
|
||||
public static final String SUCCESS = "success";
|
||||
@@ -1,12 +1,10 @@
|
||||
package com.agileboot.infrastructure.cache.map;
|
||||
package com.agileboot.common.core.enums.dictionary;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import com.agileboot.orm.common.annotations.Dictionary;
|
||||
import com.agileboot.orm.common.enums.*;
|
||||
import com.agileboot.orm.common.interfaces.DictionaryEnum;
|
||||
import com.agileboot.orm.common.result.DictionaryData;
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import com.agileboot.common.core.enums.common.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -19,11 +17,11 @@ import java.util.stream.Collectors;
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
public class MapCache {
|
||||
public class DictCache {
|
||||
|
||||
private static final Map<String, List<DictionaryData>> DICTIONARY_CACHE = MapUtil.newHashMap(128);
|
||||
|
||||
private MapCache() {
|
||||
private DictCache() {
|
||||
}
|
||||
|
||||
static {
|
||||
@@ -31,7 +29,7 @@ public class MapCache {
|
||||
}
|
||||
|
||||
private static void initDictionaryCache() {
|
||||
|
||||
// TODO 这个可以做成自动扫描
|
||||
loadInCache(BusinessTypeEnum.values());
|
||||
loadInCache(YesOrNoEnum.values());
|
||||
loadInCache(StatusEnum.values());
|
||||
@@ -41,7 +39,7 @@ public class MapCache {
|
||||
loadInCache(OperationStatusEnum.values());
|
||||
loadInCache(LoginStatusEnum.values());
|
||||
loadInCache(VisibleStatusEnum.values());
|
||||
|
||||
loadInCache(UserStatusEnum.values());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.orm.common.annotations;
|
||||
package com.agileboot.common.core.enums.dictionary;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.agileboot.orm.common.result;
|
||||
package com.agileboot.common.core.enums.dictionary;
|
||||
|
||||
import com.agileboot.orm.common.interfaces.DictionaryEnum;
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
@@ -17,9 +17,9 @@ public class DictionaryData {
|
||||
@SuppressWarnings("rawtypes")
|
||||
public DictionaryData(DictionaryEnum enumType) {
|
||||
if (enumType != null) {
|
||||
this.label = enumType.description();
|
||||
this.label = enumType.getDesc();
|
||||
this.value = (Integer) enumType.getValue();
|
||||
this.cssTag = enumType.cssTag();
|
||||
this.cssTag = enumType.getCssTag();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.agileboot.common.core.exception;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.agileboot.common.core.exception.error.ErrorCodeInterface;
|
||||
import com.agileboot.common.core.utils.i18n.MessageUtils;
|
||||
import java.util.HashMap;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 统一异常类
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Slf4j
|
||||
@Data
|
||||
public class ApiException extends RuntimeException {
|
||||
|
||||
protected ErrorCodeInterface errorCode;
|
||||
|
||||
protected String message;
|
||||
|
||||
protected String i18nMessage;
|
||||
|
||||
/**
|
||||
* 如果有一些特殊的数据 可以放在这个payload里面
|
||||
* 有时候错误的返回信息太少 不便前端处理的话 可以放在这个payload字段当中
|
||||
* 比如你做了一个大批量操作,操作ID为1~10的实体, 其中1~5成功 6~10失败
|
||||
* 你可以将这些相关信息放在这个payload中
|
||||
*/
|
||||
protected HashMap<String, Object> payload;
|
||||
|
||||
public ApiException(ErrorCodeInterface errorCode) {
|
||||
fillErrorCode(errorCode);
|
||||
}
|
||||
|
||||
public ApiException(ErrorCodeInterface errorCode, Object... args) {
|
||||
fillErrorCode(errorCode, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注意 如果是try catch的情况下捕获异常 并转为ApiException的话 一定要填入Throwable e
|
||||
* @param e 捕获到的原始异常
|
||||
* @param errorCode 错误码
|
||||
* @param args 错误详细信息参数
|
||||
*/
|
||||
public ApiException(Throwable e, ErrorCodeInterface errorCode, Object... args) {
|
||||
super(e);
|
||||
fillErrorCode(errorCode, args);
|
||||
}
|
||||
|
||||
private void fillErrorCode(ErrorCodeInterface errorCode, Object... args) {
|
||||
this.errorCode = errorCode;
|
||||
this.message = StrUtil.format(errorCode.message(), args);
|
||||
|
||||
try {
|
||||
this.i18nMessage = MessageUtils.message(errorCode.i18nKey(), args);
|
||||
} catch (Exception e) {
|
||||
log.error("could not found i18nMessage entry for key: " + errorCode.i18nKey());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return i18nMessage != null ? i18nMessage : message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocalizedMessage() {
|
||||
return i18nMessage != null ? i18nMessage : message;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.agileboot.common.core.exception;
|
||||
|
||||
import cn.hutool.core.text.StrFormatter;
|
||||
import com.agileboot.common.core.exception.error.ErrorCodeInterface;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* @Author cuiJiaWang
|
||||
* @Create 2025-08-12 16:32
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class BizException extends RuntimeException {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 错误码
|
||||
*/
|
||||
private Integer code;
|
||||
|
||||
/**
|
||||
* 错误提示
|
||||
*/
|
||||
private String message;
|
||||
|
||||
public BizException(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public BizException(ErrorCodeInterface errorCode) {
|
||||
this.code = errorCode.code();
|
||||
this.message = errorCode.message();
|
||||
}
|
||||
|
||||
public BizException(String message, Integer code) {
|
||||
this.message = message;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public BizException(String message, Object... args) {
|
||||
this.message = StrFormatter.format(message, args);
|
||||
}
|
||||
|
||||
public BizException(ErrorCodeInterface errorCode, Object... args) {
|
||||
this.message = StrFormatter.format(errorCode.message(), args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.agileboot.common.core.exception;
|
||||
|
||||
import cn.hutool.core.text.StrFormatter;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 业务异常(支持占位符 {} )
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public final class ServiceException extends RuntimeException {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 错误码
|
||||
*/
|
||||
private Integer code;
|
||||
|
||||
/**
|
||||
* 错误提示
|
||||
*/
|
||||
private String message;
|
||||
|
||||
/**
|
||||
* 错误明细,内部调试错误
|
||||
*/
|
||||
private String detailMessage;
|
||||
|
||||
public ServiceException(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public ServiceException(String message, Integer code) {
|
||||
this.message = message;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public ServiceException(String message, Object... args) {
|
||||
this.message = StrFormatter.format(message, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,410 @@
|
||||
package com.agileboot.common.core.exception.error;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* 错误码集合
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
public enum ErrorCode implements ErrorCodeInterface {
|
||||
|
||||
/**
|
||||
* 错误码集合
|
||||
* ******以下是旧的设计****
|
||||
* 1~9999 为保留错误码 或者 常用错误码
|
||||
* 10000~19999 为内部错误码
|
||||
* 20000~29999 客户端错误码 (客户端异常调用之类的错误)
|
||||
* 30000~39999 为第三方错误码 (代码正常,但是第三方异常)
|
||||
* 40000~49999 为业务逻辑 错误码 (无异常,代码正常流转,并返回提示给用户)
|
||||
* 由于系统内的错误码都是独一无二的,所以错误码应该放在common包集中管理
|
||||
* ---------------------------
|
||||
* 旧的设计的缺陷,比如内部错误码其实并不会很多 但是占用了1~9999的序列,其实是不必要的。
|
||||
* 而且错误码不一定位数一定要相同。比如腾讯的微信接口错误码的位数就并不相同。按照常理错误码的数量大小应该是:
|
||||
* 内部错误码< 客户端错误码< 第三方错误码< 业务错误码
|
||||
* 所以我们应该尽可能的把错误码的数量留给业务错误码
|
||||
* ---------------------------
|
||||
* *******新的设计**********
|
||||
* 1~99 为内部错误码(框架本身的错误)
|
||||
* 100~999 客户端错误码 (客户端异常调用之类的错误)
|
||||
* 1000~9999为第三方错误码 (代码正常,但是第三方异常)
|
||||
* 10000~99999 为业务逻辑 错误码 (无异常,代码正常流转,并返回提示给用户)
|
||||
* 由于系统内的错误码都是独一无二的,所以错误码应该放在common包集中管理
|
||||
* ---------------------------
|
||||
* 总体设计就是值越小 错误严重性越高
|
||||
* 目前10000~19999是初始系统内嵌功能使用的错误码,后续开发者可以直接使用20000以上的错误码作为业务错误码
|
||||
*/
|
||||
|
||||
SUCCESS(0, "操作成功", "SUCCESS"),
|
||||
FAILED(99999, "操作失败", "FAILED");
|
||||
|
||||
private final int code;
|
||||
private final String msg;
|
||||
private final String i18nKey;
|
||||
|
||||
ErrorCode(int code, String msg, String i18nKey) {
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
this.i18nKey = i18nKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int code() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String message() {
|
||||
return this.msg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String i18nKey() {
|
||||
return this.i18nKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* 10000~99999 为业务逻辑 错误码 (无代码异常,代码正常流转,并返回提示给用户)
|
||||
* 1XX01 XX是代表模块的意思 比如10101 01是Permission模块
|
||||
* 错误码的命名最好以模块为开头 比如 NOT_ALLOWED_TO_OPERATE前面加上PERMISSION = PERMISSION_NOT_ALLOWED_TO_OPERATE
|
||||
*/
|
||||
public enum Business implements ErrorCodeInterface {
|
||||
|
||||
// ----------------------------- COMMON --------------------------------------
|
||||
|
||||
COMMON_OBJECT_NOT_FOUND(10001, "找不到ID为 {} 的 {}", "Business.OBJECT_NOT_FOUND"),
|
||||
|
||||
COMMON_UNSUPPORTED_OPERATION(10002, "不支持的操作", "Business.UNSUPPORTED_OPERATION"),
|
||||
|
||||
COMMON_BULK_DELETE_IDS_IS_INVALID(10003, "批量参数ID列表为空", "Business.BULK_DELETE_IDS_IS_INVALID"),
|
||||
|
||||
COMMON_FILE_NOT_ALLOWED_TO_DOWNLOAD(10004, "文件名称({})非法,不允许下载", "Business.FILE_NOT_ALLOWED_TO_DOWNLOAD"),
|
||||
|
||||
// ----------------------------- PERMISSION -----------------------------------
|
||||
|
||||
PERMISSION_FORBIDDEN_TO_MODIFY_ADMIN(10101, "不允许修改管理员的信息", "Business.FORBIDDEN_TO_MODIFY_ADMIN"),
|
||||
|
||||
PERMISSION_NOT_ALLOWED_TO_OPERATE(10202, "没有权限进行此操作,请联系管理员", "Business.NO_PERMISSION_TO_OPERATE"),
|
||||
|
||||
// ----------------------------- LOGIN -----------------------------------------
|
||||
|
||||
LOGIN_WRONG_USER_PASSWORD(10201, "用户密码错误,请重输", "Business.LOGIN_WRONG_USER_PASSWORD"),
|
||||
|
||||
LOGIN_ERROR(10202, "登录失败:{}", "Business.LOGIN_ERROR"),
|
||||
|
||||
LOGIN_CAPTCHA_CODE_WRONG(10203, "验证码错误", "Business.LOGIN_CAPTCHA_CODE_WRONG"),
|
||||
|
||||
LOGIN_CAPTCHA_CODE_EXPIRE(10204, "验证码过期", "Business.LOGIN_CAPTCHA_CODE_EXPIRE"),
|
||||
|
||||
LOGIN_CAPTCHA_CODE_NULL(10205, "验证码为空", "Business.LOGIN_CAPTCHA_CODE_NULL"),
|
||||
|
||||
// ----------------------------- UPLOAD -----------------------------------------
|
||||
|
||||
UPLOAD_FILE_TYPE_NOT_ALLOWED(10401, "不允许上传的文件类型,仅允许:{}", "Business.UPLOAD_FILE_TYPE_NOT_ALLOWED"),
|
||||
|
||||
UPLOAD_FILE_NAME_EXCEED_MAX_LENGTH(10402, "文件名长度超过:{} ", "Business.UPLOAD_FILE_NAME_EXCEED_MAX_LENGTH"),
|
||||
|
||||
UPLOAD_FILE_SIZE_EXCEED_MAX_SIZE(10403, "文件名大小超过:{} MB", "Business.UPLOAD_FILE_SIZE_EXCEED_MAX_SIZE"),
|
||||
|
||||
UPLOAD_IMPORT_EXCEL_FAILED(10404, "导入excel失败:{}", "Business.UPLOAD_IMPORT_EXCEL_FAILED"),
|
||||
|
||||
UPLOAD_FILE_IS_EMPTY(10405, "上传文件为空", "Business.UPLOAD_FILE_IS_EMPTY"),
|
||||
|
||||
UPLOAD_FILE_FAILED(10406, "上传文件失败:{}", "Business.UPLOAD_FILE_FAILED"),
|
||||
|
||||
// ----------------------------- CONFIG -----------------------------------------
|
||||
|
||||
CONFIG_VALUE_IS_NOT_ALLOW_TO_EMPTY(10601, "参数键值不允许为空", "Business.CONFIG_VALUE_IS_NOT_ALLOW_TO_EMPTY"),
|
||||
|
||||
CONFIG_VALUE_IS_NOT_IN_OPTIONS(10602, "参数键值不存在列表中", "Business.CONFIG_VALUE_IS_NOT_IN_OPTIONS"),
|
||||
|
||||
// ------------------------------- POST --------------------------------------------
|
||||
|
||||
POST_NAME_IS_NOT_UNIQUE(10701, "岗位名称:{}, 已存在", "Business.POST_NAME_IS_NOT_UNIQUE"),
|
||||
|
||||
POST_CODE_IS_NOT_UNIQUE(10702, "岗位编号:{}, 已存在", "Business.POST_CODE_IS_NOT_UNIQUE"),
|
||||
|
||||
POST_ALREADY_ASSIGNED_TO_USER_CAN_NOT_BE_DELETED(10703, "职位已分配给用户,请先取消分配再删除", "Business.POST_ALREADY_ASSIGNED_TO_USER_CAN_NOT_BE_DELETED"),
|
||||
|
||||
// ------------------------------- DEPT ---------------------------------------------
|
||||
|
||||
DEPT_NAME_IS_NOT_UNIQUE(10801, "部门名称:{}, 已存在", "Business.DEPT_NAME_IS_NOT_UNIQUE"),
|
||||
|
||||
DEPT_PARENT_ID_IS_NOT_ALLOWED_SELF(10802, "父级部门不能选择自己", "Business.DEPT_PARENT_ID_IS_NOT_ALLOWED_SELF"),
|
||||
|
||||
DEPT_STATUS_ID_IS_NOT_ALLOWED_CHANGE(10803, "子部门还有正在启用的部门,暂时不能停用该部门", "Business.DEPT_STATUS_ID_IS_NOT_ALLOWED_CHANGE"),
|
||||
|
||||
DEPT_EXIST_CHILD_DEPT_NOT_ALLOW_DELETE(10804, "该部门存在下级部门不允许删除", "Business.DEPT_EXIST_CHILD_DEPT_NOT_ALLOW_DELETE"),
|
||||
|
||||
DEPT_EXIST_LINK_USER_NOT_ALLOW_DELETE(10805, "该部门存在关联的用户不允许删除", "Business.DEPT_EXIST_LINK_USER_NOT_ALLOW_DELETE"),
|
||||
|
||||
DEPT_PARENT_DEPT_NO_EXIST_OR_DISABLED(10806, "该父级部门不存在或已停用", "Business.DEPT_PARENT_DEPT_NO_EXIST_OR_DISABLED"),
|
||||
|
||||
// ------------------------------- MENU -------------------------------------------------
|
||||
|
||||
MENU_NAME_IS_NOT_UNIQUE(10901, "新增菜单:{} 失败,菜单名称已存在", "Business.MENU_NAME_IS_NOT_UNIQUE"),
|
||||
|
||||
MENU_EXTERNAL_LINK_MUST_BE_HTTP(10902, "菜单外链必须以 http(s)://开头", "Business.MENU_EXTERNAL_LINK_MUST_BE_HTTP"),
|
||||
|
||||
MENU_PARENT_ID_NOT_ALLOW_SELF(10903, "父级菜单不能选择自身", "Business.MENU_PARENT_ID_NOT_ALLOW_SELF"),
|
||||
|
||||
MENU_EXIST_CHILD_MENU_NOT_ALLOW_DELETE(10904, "存在子菜单不允许删除", "Business.MENU_EXIST_CHILD_MENU_NOT_ALLOW_DELETE"),
|
||||
|
||||
MENU_ALREADY_ASSIGN_TO_ROLE_NOT_ALLOW_DELETE(10905, "菜单已分配给角色,不允许", "Business.MENU_ALREADY_ASSIGN_TO_ROLE_NOT_ALLOW_DELETE"),
|
||||
|
||||
MENU_NOT_ALLOWED_TO_CREATE_BUTTON_ON_IFRAME_OR_OUT_LINK(10906, "不允许在Iframe和外链跳转类型下创建按钮", "Business.MENU_ONLY_ALLOWED_TO_CREATE_BUTTON_ON_PAGE"),
|
||||
|
||||
MENU_ONLY_ALLOWED_TO_CREATE_SUB_MENU_IN_CATALOG(10907, "只允许在目录类型底下创建子菜单", "Business.MENU_ONLY_ALLOWED_TO_CREATE_SUB_MENU_IN_CATALOG"),
|
||||
|
||||
MENU_CAN_NOT_CHANGE_MENU_TYPE(10908, "不允许更改菜单的类型", "Business.MENU_CAN_NOT_CHANGE_MENU_TYPE"),
|
||||
|
||||
// -------------------------------- ROLE -------------------------------------------------
|
||||
|
||||
ROLE_NAME_IS_NOT_UNIQUE(11001, "角色名称:{}, 已存在", "Business.ROLE_NAME_IS_NOT_UNIQUE"),
|
||||
|
||||
ROLE_KEY_IS_NOT_UNIQUE(11002, "角色标识:{}, 已存在", "Business.ROLE_KEY_IS_NOT_UNIQUE"),
|
||||
|
||||
ROLE_DATA_SCOPE_DUPLICATED_DEPT(11003, "重复的部门id", "Business.ROLE_DATA_SCOPE_DUPLICATED_DEPT"),
|
||||
|
||||
ROLE_ALREADY_ASSIGN_TO_USER(11004, "角色:{} 已分配给用户,请先取消分配,再删除角色", "Business.ROLE_ALREADY_ASSIGN_TO_USER"),
|
||||
|
||||
ROLE_IS_NOT_AVAILABLE(11005, "角色:{} 已禁用,无法分配给用户", "Business.ROLE_IS_NOT_AVAILABLE"),
|
||||
|
||||
// ---------------------------------- USER -----------------------------------------------
|
||||
|
||||
USER_NON_EXIST(10501, "登录用户:{} 不存在", "Business.USER_NON_EXIST"),
|
||||
|
||||
USER_IS_DISABLE(10502, "对不起, 您的账号:{} 已停用", "Business.USER_IS_DISABLE"),
|
||||
|
||||
USER_CACHE_IS_EXPIRE(11003, "用户缓存信息已经过期", "Business.USER_CACHE_IS_EXPIRE"),
|
||||
|
||||
USER_FAIL_TO_GET_USER_ID(11004, "获取用户ID失败", "Business.USER_FAIL_TO_GET_USER_ID"),
|
||||
|
||||
USER_FAIL_TO_GET_DEPT_ID(10504, "获取用户部门ID失败", "Business.USER_FAIL_TO_GET_DEPT_ID"),
|
||||
|
||||
USER_FAIL_TO_GET_ACCOUNT(10505, "获取用户账户失败", "Business.USER_FAIL_TO_GET_ACCOUNT"),
|
||||
|
||||
USER_FAIL_TO_GET_USER_INFO(10506, "获取用户信息失败", "Business.USER_FAIL_TO_GET_USER_INFO"),
|
||||
|
||||
USER_IMPORT_DATA_IS_NULL(10507, "导入的用户为空", "Business.USER_IMPORT_DATA_IS_NULL"),
|
||||
|
||||
USER_PHONE_NUMBER_IS_NOT_UNIQUE(10508, "该电话号码已被其他用户占用", "Business.USER_PHONE_NUMBER_IS_NOT_UNIQUE"),
|
||||
|
||||
USER_EMAIL_IS_NOT_UNIQUE(10509, "该邮件地址已被其他用户占用", "Business.USER_EMAIL_IS_NOT_UNIQUE"),
|
||||
|
||||
USER_PASSWORD_IS_NOT_CORRECT(10510, "用户密码错误", "Business.USER_PASSWORD_IS_NOT_CORRECT"),
|
||||
|
||||
USER_NEW_PASSWORD_IS_THE_SAME_AS_OLD(10511, "用户新密码与旧密码相同", "Business.USER_NEW_PASSWORD_IS_THE_SAME_AS_OLD"),
|
||||
|
||||
USER_UPLOAD_FILE_FAILED(10512, "用户上传文件失败", "Business.USER_UPLOAD_FILE_FAILED"),
|
||||
|
||||
USER_NAME_IS_NOT_UNIQUE(10513, "用户名已被其他用户占用", "Business.USER_NAME_IS_NOT_UNIQUE"),
|
||||
|
||||
USER_CURRENT_USER_CAN_NOT_BE_DELETE(10514, "当前用户不允许被删除", "Business.USER_CURRENT_USER_CAN_NOT_BE_DELETE"),
|
||||
|
||||
USER_ADMIN_CAN_NOT_BE_MODIFY(10515, "管理员不允许做任何修改", "Business.USER_ADMIN_CAN_NOT_BE_MODIFY"),
|
||||
|
||||
;
|
||||
|
||||
|
||||
private final int code;
|
||||
private final String msg;
|
||||
|
||||
private final String i18nKey;
|
||||
|
||||
Business(int code, String msg, String i18nKey) {
|
||||
Assert.isTrue(code > 10000 && code < 99999,
|
||||
"错误码code值定义失败,Business错误码code值范围在10000~99099之间,请查看ErrorCode.Business类,当前错误码码为" + name());
|
||||
|
||||
String errorTypeName = this.getClass().getSimpleName();
|
||||
Assert.isTrue(i18nKey != null && i18nKey.startsWith(errorTypeName),
|
||||
String.format("错误码i18nKey值定义失败,%s错误码i18nKey值必须以%s开头,当前错误码为%s", errorTypeName, errorTypeName, name()));
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
this.i18nKey = i18nKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int code() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String message() {
|
||||
return this.msg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String i18nKey() {
|
||||
return i18nKey;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 1000~9999是外部错误码 比如调用支付失败
|
||||
*/
|
||||
public enum External implements ErrorCodeInterface {
|
||||
|
||||
/**
|
||||
* 支付宝调用失败
|
||||
*/
|
||||
FAIL_TO_PAY_ON_ALIPAY(1001, "支付宝调用失败", "External.FAIL_TO_PAY_ON_ALIPAY");
|
||||
|
||||
|
||||
private final int code;
|
||||
private final String msg;
|
||||
|
||||
private final String i18nKey;
|
||||
|
||||
External(int code, String msg, String i18nKey) {
|
||||
Assert.isTrue(code > 1000 && code < 9999,
|
||||
"错误码code值定义失败,External错误码code值范围在1000~9999之间,请查看ErrorCode.External类,当前错误码码为" + name());
|
||||
|
||||
String errorTypeName = this.getClass().getSimpleName();
|
||||
Assert.isTrue(i18nKey != null && i18nKey.startsWith(errorTypeName),
|
||||
String.format("错误码i18nKey值定义失败,%s错误码i18nKey值必须以%s开头,当前错误码为%s", errorTypeName, errorTypeName, name()));
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
this.i18nKey = i18nKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int code() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String message() {
|
||||
return this.msg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String i18nKey() {
|
||||
return this.i18nKey;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 100~999是客户端错误码
|
||||
* 客户端如 Web+小程序+手机端 调用出错
|
||||
* 可能由于参数问题或者授权问题或者调用过去频繁
|
||||
*/
|
||||
public enum Client implements ErrorCodeInterface {
|
||||
|
||||
COMMON_FORBIDDEN_TO_CALL(101, "禁止调用", "Client.COMMON_FORBIDDEN_TO_CALL"),
|
||||
|
||||
COMMON_REQUEST_TOO_OFTEN(102, "调用太过频繁", "Client.COMMON_REQUEST_TOO_OFTEN"),
|
||||
|
||||
COMMON_REQUEST_PARAMETERS_INVALID(103, "请求参数异常,{}", "Client.COMMON_REQUEST_PARAMETERS_INVALID"),
|
||||
|
||||
COMMON_REQUEST_METHOD_INVALID(104, "请求方式: {} 不支持", "Client.COMMON_REQUEST_METHOD_INVALID"),
|
||||
|
||||
COMMON_REQUEST_RESUBMIT(105, "请求重复提交", "Client.COMMON_REQUEST_RESUBMIT"),
|
||||
|
||||
COMMON_NO_AUTHORIZATION(106, "请求接口:{} 失败,用户未授权", "Client.COMMON_NO_AUTHORIZATION"),
|
||||
|
||||
INVALID_TOKEN(107, "token异常", "Client.INVALID_TOKEN"),
|
||||
|
||||
TOKEN_PROCESS_FAILED(108, "token处理失败:{}", "Client.TOKEN_PROCESS_FAILED"),
|
||||
|
||||
;
|
||||
|
||||
private final int code;
|
||||
private final String msg;
|
||||
private final String i18nKey;
|
||||
|
||||
Client(int code, String msg, String i18nKey) {
|
||||
Assert.isTrue(code > 100 && code < 999,
|
||||
"错误码code值定义失败,Client错误码code值范围在100~999之间,请查看ErrorCode.Client类,当前错误码码为" + name());
|
||||
|
||||
String errorTypeName = this.getClass().getSimpleName();
|
||||
Assert.isTrue(i18nKey != null && i18nKey.startsWith(errorTypeName),
|
||||
String.format("错误码i18nKey值定义失败,%s错误码i18nKey值必须以%s开头,当前错误码为%s", errorTypeName, errorTypeName, name()));
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
this.i18nKey = i18nKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int code() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String message() {
|
||||
return this.msg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String i18nKey() {
|
||||
return this.i18nKey;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 0~99是内部错误码 例如 框架内部问题之类的
|
||||
*/
|
||||
public enum Internal implements ErrorCodeInterface {
|
||||
/**
|
||||
* 内部错误码
|
||||
*/
|
||||
INVALID_PARAMETER(1, "参数异常:{}", "Internal.INVALID_PARAMETER"),
|
||||
|
||||
/**
|
||||
* 该错误主要用于返回 未知的异常(大部分是RuntimeException) 程序未能捕获 未能预料的错误
|
||||
*/
|
||||
INTERNAL_ERROR(2, "系统内部错误:{}", "Internal.INTERNAL_ERROR"),
|
||||
|
||||
GET_ENUM_FAILED(3, "获取枚举类型失败, 枚举类:{}", "Internal.GET_ENUM_FAILED"),
|
||||
|
||||
GET_CACHE_FAILED(4, "获取缓存失败:{}", "Internal.GET_CACHE_FAILED"),
|
||||
|
||||
DB_INTERNAL_ERROR(5, "数据库异常", "Internal.DB_INTERNAL_ERROR"),
|
||||
|
||||
LOGIN_CAPTCHA_GENERATE_FAIL(7, "验证码生成失败", "Internal.LOGIN_CAPTCHA_GENERATE_FAIL"),
|
||||
|
||||
EXCEL_PROCESS_ERROR(8, "excel处理失败:{}", "Internal.EXCEL_PROCESS_ERROR"),
|
||||
|
||||
;
|
||||
|
||||
private final int code;
|
||||
private final String msg;
|
||||
|
||||
private final String i18nKey;
|
||||
|
||||
Internal(int code, String msg, String i18nKey) {
|
||||
Assert.isTrue(code < 100,
|
||||
"错误码code值定义失败,Internal错误码code值范围在100~999之间,请查看ErrorCode.Internal类,当前错误码码为" + name());
|
||||
|
||||
String errorTypeName = this.getClass().getSimpleName();
|
||||
Assert.isTrue(i18nKey != null && i18nKey.startsWith(errorTypeName),
|
||||
String.format("错误码i18nKey值定义失败,%s错误码i18nKey值必须以%s开头,当前错误码为%s", errorTypeName, errorTypeName, name()));
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
this.i18nKey = i18nKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int code() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String message() {
|
||||
return this.msg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String i18nKey() {
|
||||
return this.i18nKey;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,16 +1,10 @@
|
||||
package com.agileboot.common.exception.error;
|
||||
package com.agileboot.common.core.exception.error;
|
||||
|
||||
/**
|
||||
* @author valarchie
|
||||
*/
|
||||
public interface ErrorCodeInterface {
|
||||
|
||||
/**
|
||||
* 返回错误码名称
|
||||
* @return 枚举名称
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* 返回错误码
|
||||
* @return 错误码
|
||||
@@ -27,8 +21,6 @@ public interface ErrorCodeInterface {
|
||||
* i18n资源文件的key, 详见messages.properties文件
|
||||
* @return key
|
||||
*/
|
||||
default String i18nKey() {
|
||||
return code() + "_" + name();
|
||||
}
|
||||
String i18nKey();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.agileboot.common.core.factory;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
|
||||
import org.springframework.core.env.PropertiesPropertySource;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.io.support.DefaultPropertySourceFactory;
|
||||
import org.springframework.core.io.support.EncodedResource;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* yml 配置源工厂
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public class YmlPropertySourceFactory extends DefaultPropertySourceFactory {
|
||||
|
||||
@Override
|
||||
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
|
||||
String sourceName = resource.getResource().getFilename();
|
||||
if (StringUtils.isNotBlank(sourceName) && StringUtils.endsWithAny(sourceName, ".yml", ".yaml")) {
|
||||
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
|
||||
factory.setResources(resource.getResource());
|
||||
factory.afterPropertiesSet();
|
||||
return new PropertiesPropertySource(sourceName, factory.getObject());
|
||||
}
|
||||
return super.createPropertySource(name, resource);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
package com.agileboot.common.utils;
|
||||
package com.agileboot.common.core.utils;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
@@ -14,6 +15,7 @@ import java.io.IOException;
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Slf4j
|
||||
public class ServletHolderUtil {
|
||||
|
||||
private ServletHolderUtil() {
|
||||
@@ -52,7 +54,7 @@ public class ServletHolderUtil {
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.getWriter().print(string);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
log.error("返回response失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,5 +73,24 @@ public class ServletHolderUtil {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取客户端IP地址(兼容代理头)
|
||||
*/
|
||||
public static String getClientIp() {
|
||||
HttpServletRequest request = getRequest();
|
||||
String xForwardedFor = request.getHeader("X-Forwarded-For");
|
||||
if (StrUtil.isNotEmpty(xForwardedFor)) {
|
||||
// 可能存在多个IP,取第一个
|
||||
int commaIndex = xForwardedFor.indexOf(',');
|
||||
return commaIndex > 0 ? xForwardedFor.substring(0, commaIndex).trim() : xForwardedFor.trim();
|
||||
}
|
||||
String realIp = request.getHeader("X-Real-IP");
|
||||
if (StrUtil.isNotEmpty(realIp)) {
|
||||
return realIp.trim();
|
||||
}
|
||||
return request.getRemoteAddr();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.agileboot.common.core.utils;
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import jakarta.validation.ConstraintViolation;
|
||||
import jakarta.validation.ConstraintViolationException;
|
||||
import jakarta.validation.Validator;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Validator 校验框架工具
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class ValidatorUtils {
|
||||
|
||||
private static final Validator VALID = SpringUtil.getBean(Validator.class);
|
||||
|
||||
/**
|
||||
* 对给定对象进行参数校验,并根据指定的校验组进行校验
|
||||
*
|
||||
* @param object 要进行校验的对象
|
||||
* @param groups 校验组
|
||||
* @throws ConstraintViolationException 如果校验不通过,则抛出参数校验异常
|
||||
*/
|
||||
public static <T> void validate(T object, Class<?>... groups) {
|
||||
Set<ConstraintViolation<T>> validate = VALID.validate(object, groups);
|
||||
if (!validate.isEmpty()) {
|
||||
throw new ConstraintViolationException("参数校验异常", validate);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.utils.file;
|
||||
package com.agileboot.common.core.utils.file;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
@@ -7,12 +7,12 @@ import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import com.agileboot.common.config.AgileBootConfig;
|
||||
import com.agileboot.common.constant.Constants;
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode;
|
||||
import com.agileboot.common.exception.error.ErrorCode.Business;
|
||||
import com.agileboot.common.exception.error.ErrorCode.Internal;
|
||||
import com.agileboot.common.core.config.AgileBootConfig;
|
||||
import com.agileboot.common.core.constant.Constants;
|
||||
import com.agileboot.common.core.exception.ApiException;
|
||||
import com.agileboot.common.core.exception.error.ErrorCode;
|
||||
import com.agileboot.common.core.exception.error.ErrorCode.Business;
|
||||
import com.agileboot.common.core.exception.error.ErrorCode.Internal;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.util.MimeType;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.utils.i18n;
|
||||
package com.agileboot.common.core.utils.i18n;
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import org.springframework.context.MessageSource;
|
||||
@@ -7,7 +7,7 @@ import org.springframework.context.i18n.LocaleContextHolder;
|
||||
/**
|
||||
* 获取i18n资源文件
|
||||
*
|
||||
* @author ruoyi
|
||||
* @author valarchie
|
||||
*/
|
||||
public class MessageUtils {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.utils.ip;
|
||||
package com.agileboot.common.core.utils.ip;
|
||||
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.utils.ip;
|
||||
package com.agileboot.common.core.utils.ip;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
package com.agileboot.common.utils.ip;
|
||||
package com.agileboot.common.core.utils.ip;
|
||||
|
||||
import cn.hutool.core.lang.Validator;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.regex.Pattern;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* ip校验器
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Slf4j
|
||||
public class IpUtil {
|
||||
|
||||
public static final String INNER_IP_REGEX = "^(127\\.0\\.0\\.\\d{1,3})|(localhost)|(10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})|(172\\.((1[6-9])|(2\\d)|(3[01]))\\.\\d{1,3}\\.\\d{1,3})|(192\\.168\\.\\d{1,3}\\.\\d{1,3})$";
|
||||
@@ -30,6 +32,7 @@ public class IpUtil {
|
||||
byte[] ip = ad.getAddress();
|
||||
ia = InetAddress.getByAddress(ip);
|
||||
} catch (UnknownHostException e) {
|
||||
log.error("解析Ip失败", e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (ia == null) {
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.utils.ip;
|
||||
package com.agileboot.common.core.utils.ip;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -55,7 +55,7 @@ public class OfflineIpRegionUtil {
|
||||
return new IpRegion(split[0], split[1], split[2], split[3], split[4]);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.error("获取IP地理位置失败", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.agileboot.common.utils.ip;
|
||||
package com.agileboot.common.core.utils.ip;
|
||||
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.agileboot.common.config.AgileBootConfig;
|
||||
import com.agileboot.common.utils.jackson.JacksonUtil;
|
||||
import com.agileboot.common.core.config.AgileBootConfig;
|
||||
import com.agileboot.common.core.utils.jackson.JacksonUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.utils.jackson;
|
||||
package com.agileboot.common.core.utils.jackson;
|
||||
|
||||
/**
|
||||
* @author valarchie
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.utils.jackson;
|
||||
package com.agileboot.common.core.utils.jackson;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
@@ -35,6 +35,7 @@ import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -81,6 +82,10 @@ public class JacksonUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private JacksonUtil() {
|
||||
throw new IllegalStateException("Utility class JacksonUtil can not be instantiated");
|
||||
}
|
||||
|
||||
public static ObjectMapper initMapper() {
|
||||
JsonMapper.Builder builder = JsonMapper.builder()
|
||||
.enable(JSON_READ_FEATURES_ENABLED.toArray(new JsonReadFeature[0]));
|
||||
@@ -266,7 +271,7 @@ public class JacksonUtil {
|
||||
*/
|
||||
public static <V> List<V> fromList(String json, Class<V> type) {
|
||||
if (StringUtils.isEmpty(json)) {
|
||||
return null;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
try {
|
||||
CollectionType collectionType = mapper.getTypeFactory().constructCollectionType(ArrayList.class, type);
|
||||
@@ -281,7 +286,7 @@ public class JacksonUtil {
|
||||
*/
|
||||
public static Map<String, Object> fromMap(String json) {
|
||||
if (StringUtils.isEmpty(json)) {
|
||||
return null;
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
try {
|
||||
MapType mapType = mapper.getTypeFactory().constructMapType(HashMap.class, String.class, Object.class);
|
||||
@@ -497,12 +502,12 @@ public class JacksonUtil {
|
||||
*/
|
||||
public static byte[] getAsBytes(String json, String key) {
|
||||
if (StringUtils.isEmpty(json)) {
|
||||
return null;
|
||||
return new byte[0];
|
||||
}
|
||||
try {
|
||||
JsonNode jsonNode = getAsJsonObject(json, key);
|
||||
if (null == jsonNode) {
|
||||
return null;
|
||||
return new byte[0];
|
||||
}
|
||||
return jsonNode.isBinary() ? jsonNode.binaryValue() : getAsString(jsonNode).getBytes();
|
||||
} catch (Exception e) {
|
||||
@@ -540,12 +545,12 @@ public class JacksonUtil {
|
||||
*/
|
||||
public static <V> List<V> getAsList(String json, String key, Class<V> type) {
|
||||
if (StringUtils.isEmpty(json)) {
|
||||
return null;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
try {
|
||||
JsonNode jsonNode = getAsJsonObject(json, key);
|
||||
if (null == jsonNode) {
|
||||
return null;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
CollectionType collectionType = mapper.getTypeFactory().constructCollectionType(ArrayList.class, type);
|
||||
return from(getAsString(jsonNode), collectionType);
|
||||
@@ -1,15 +1,16 @@
|
||||
package com.agileboot.common.utils.poi;
|
||||
package com.agileboot.common.core.utils.poi;
|
||||
|
||||
import cn.hutool.poi.excel.ExcelReader;
|
||||
import cn.hutool.poi.excel.ExcelUtil;
|
||||
import cn.hutool.poi.excel.ExcelWriter;
|
||||
import com.agileboot.common.annotation.ExcelColumn;
|
||||
import com.agileboot.common.annotation.ExcelSheet;
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode.Internal;
|
||||
import com.agileboot.common.core.annotation.ExcelColumn;
|
||||
import com.agileboot.common.core.annotation.ExcelSheet;
|
||||
import com.agileboot.common.core.exception.ApiException;
|
||||
import com.agileboot.common.core.exception.error.ErrorCode.Internal;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
@@ -21,6 +22,7 @@ import java.util.List;
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Slf4j
|
||||
public class CustomExcelUtil {
|
||||
|
||||
private CustomExcelUtil() {
|
||||
@@ -30,8 +32,7 @@ public class CustomExcelUtil {
|
||||
try {
|
||||
writeToOutputStream(list, clazz, response.getOutputStream());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new ApiException(Internal.UNKNOWN_ERROR);
|
||||
throw new ApiException(e, Internal.EXCEL_PROCESS_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,15 +40,15 @@ public class CustomExcelUtil {
|
||||
try {
|
||||
return readFromInputStream(clazz, file.getInputStream());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new ApiException(Internal.UNKNOWN_ERROR);
|
||||
// 注意如果是捕获到的错误 一定要放进ApiException当中
|
||||
throw new ApiException(e, Internal.EXCEL_PROCESS_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> void writeToOutputStream(List<T> list, Class<T> clazz, OutputStream outputStream) {
|
||||
|
||||
// 通过工具类创建writer
|
||||
ExcelWriter writer = ExcelUtil.getWriter();
|
||||
ExcelWriter writer = ExcelUtil.getWriter(true);
|
||||
|
||||
ExcelSheet sheetAnno = clazz.getAnnotation(ExcelSheet.class);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.utils.poi;
|
||||
package com.agileboot.common.core.utils.poi;
|
||||
|
||||
import cn.hutool.http.HtmlUtil;
|
||||
import cn.hutool.poi.excel.cell.CellEditor;
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.agileboot.common.core.utils.sql;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* sql操作工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class SqlUtil {
|
||||
|
||||
/**
|
||||
* 定义常用的 sql关键字
|
||||
*/
|
||||
public static String SQL_REGEX = "\u000B|and |extractvalue|updatexml|sleep|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |union |like |+|/*|user()";
|
||||
|
||||
/**
|
||||
* 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序)
|
||||
*/
|
||||
public static final String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+";
|
||||
|
||||
/**
|
||||
* 检查字符,防止注入绕过
|
||||
*/
|
||||
public static String escapeOrderBySql(String value) {
|
||||
if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) {
|
||||
throw new IllegalArgumentException("参数不符合规范,不能进行查询");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证 order by 语法是否符合规范
|
||||
*/
|
||||
public static boolean isValidOrderBySql(String value) {
|
||||
return value.matches(SQL_PATTERN);
|
||||
}
|
||||
|
||||
/**
|
||||
* SQL关键字检查
|
||||
*/
|
||||
public static void filterKeyword(String value) {
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
return;
|
||||
}
|
||||
String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");
|
||||
for (String sqlKeyword : sqlKeywords) {
|
||||
if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1) {
|
||||
throw new IllegalArgumentException("参数存在SQL注入风险");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
package com.agileboot.common.utils.time;
|
||||
package com.agileboot.common.core.utils.time;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Date;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* @author valarchie
|
||||
@@ -15,11 +14,10 @@ public class DatePickUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全地获取日期的一天开始时间, date为null 则返回null
|
||||
* DateUtil.beginOfDay(date) 如果传null 会NPE
|
||||
* 安全地获取日期的一天开始时间, date为null 则返回null DateUtil.beginOfDay(date) 如果传null 会NPE
|
||||
*
|
||||
* @param date
|
||||
* @return
|
||||
* @param date 当前日期
|
||||
* @return 日期的一天开始时间
|
||||
*/
|
||||
public static Date getBeginOfTheDay(Date date) {
|
||||
if (date == null) {
|
||||
@@ -37,7 +35,7 @@ public class DatePickUtil {
|
||||
* 安全地获取日期的一天结束时间, date为null 则返回null。 避免NPE
|
||||
* DateUtil.endOfDay(date) 如果传null 会NPE
|
||||
* @param date 23:59:59
|
||||
* @return
|
||||
* @return 日期的一天结束时间
|
||||
*/
|
||||
public static Date getEndOfTheDay(Date date) {
|
||||
if (date == null) {
|
||||
21
agileboot-common/wol-common-core/src/main/resources/base.yml
Normal file
21
agileboot-common/wol-common-core/src/main/resources/base.yml
Normal file
@@ -0,0 +1,21 @@
|
||||
wol:
|
||||
mysql:
|
||||
maser:
|
||||
url: ${MYSQL_URL:121.41.64.98:3306}
|
||||
username: ${MYSQL_USERNAME:agileboot}
|
||||
password: ${MYSQL_PASSWORD:123456}
|
||||
redis:
|
||||
database: ${REDIS_DATABASE:3}
|
||||
host: ${REDIS_HOST:121.41.64.98}
|
||||
port: ${REDIS_PORT:6379}
|
||||
password: ${REDIS_PASSWORD:'Wyy123123'}
|
||||
nacos:
|
||||
server:
|
||||
addr: ${NACOS_ADDR:192.168.110.27:8848}
|
||||
username: ${NACOS_USERNAME:nacos}
|
||||
password: ${NACOS_PASSWORD:nacos}
|
||||
namespace: ${NACOS_NAMESPACE:public}
|
||||
group: ${NACOS_GROUP:DEFAULT_GROUP}
|
||||
jasypt:
|
||||
encryptor:
|
||||
password: ${JASYPT_ENCRYPTOR_PASSWORD:}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user