Showing
47 changed files
with
4813 additions
and
0 deletions
Too many changes to show.
To preserve performance only 47 of 47+ files are displayed.
.editorconfig
0 → 100644
1 | +# http://editorconfig.org | ||
2 | +root = true | ||
3 | + | ||
4 | +# 空格替代Tab缩进在各种编辑工具下效果一致 | ||
5 | +[*] | ||
6 | +indent_style = space | ||
7 | +indent_size = 4 | ||
8 | +charset = utf-8 | ||
9 | +end_of_line = lf | ||
10 | +trim_trailing_whitespace = true | ||
11 | +insert_final_newline = true | ||
12 | + | ||
13 | +[*.{json,yml,yaml}] | ||
14 | +indent_size = 2 | ||
15 | + | ||
16 | +[*.md] | ||
17 | +insert_final_newline = false | ||
18 | +trim_trailing_whitespace = false |
.gitignore
0 → 100644
1 | +###################################################################### | ||
2 | +# Build Tools | ||
3 | + | ||
4 | +.gradle | ||
5 | +/build/ | ||
6 | +!gradle/wrapper/gradle-wrapper.jar | ||
7 | + | ||
8 | +target/ | ||
9 | +!.mvn/wrapper/maven-wrapper.jar | ||
10 | + | ||
11 | +###################################################################### | ||
12 | +# IDE | ||
13 | + | ||
14 | +### STS ### | ||
15 | +.apt_generated | ||
16 | +.classpath | ||
17 | +.factorypath | ||
18 | +.project | ||
19 | +.settings | ||
20 | +.springBeans | ||
21 | + | ||
22 | +### IntelliJ IDEA ### | ||
23 | +.idea | ||
24 | +*.iws | ||
25 | +*.iml | ||
26 | +*.ipr | ||
27 | + | ||
28 | +### JRebel ### | ||
29 | +rebel.xml | ||
30 | + | ||
31 | +### NetBeans ### | ||
32 | +nbproject/private/ | ||
33 | +build/* | ||
34 | +nbbuild/ | ||
35 | +nbdist/ | ||
36 | +.nb-gradle/ | ||
37 | + | ||
38 | +###################################################################### | ||
39 | +# Others | ||
40 | +*.log | ||
41 | +*.xml.versionsBackup | ||
42 | +*.swp | ||
43 | + | ||
44 | +!*/build/*.java | ||
45 | +!*/build/*.html | ||
46 | +!*/build/*.xml |
.run/ruoyi-monitor-admin.run.xml
0 → 100644
1 | +<component name="ProjectRunConfigurationManager"> | ||
2 | + <configuration default="false" name="ruoyi-monitor-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker"> | ||
3 | + <deployment type="dockerfile"> | ||
4 | + <settings> | ||
5 | + <option name="imageTag" value="ruoyi/ruoyi-monitor-admin:4.8.2" /> | ||
6 | + <option name="buildOnly" value="true" /> | ||
7 | + <option name="sourceFilePath" value="ruoyi-extend/ruoyi-monitor-admin/Dockerfile" /> | ||
8 | + </settings> | ||
9 | + </deployment> | ||
10 | + <method v="2" /> | ||
11 | + </configuration> | ||
12 | +</component> |
.run/ruoyi-server.run.xml
0 → 100644
1 | +<component name="ProjectRunConfigurationManager"> | ||
2 | + <configuration default="false" name="ruoyi-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker"> | ||
3 | + <deployment type="dockerfile"> | ||
4 | + <settings> | ||
5 | + <option name="imageTag" value="ruoyi/ruoyi-server:4.8.2" /> | ||
6 | + <option name="buildOnly" value="true" /> | ||
7 | + <option name="sourceFilePath" value="ruoyi-admin/Dockerfile" /> | ||
8 | + </settings> | ||
9 | + </deployment> | ||
10 | + <method v="2" /> | ||
11 | + </configuration> | ||
12 | +</component> |
.run/ruoyi-xxl-job-admin.run.xml
0 → 100644
1 | +<component name="ProjectRunConfigurationManager"> | ||
2 | + <configuration default="false" name="ruoyi-xxl-job-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker"> | ||
3 | + <deployment type="dockerfile"> | ||
4 | + <settings> | ||
5 | + <option name="imageTag" value="ruoyi/ruoyi-xxl-job-admin:4.8.2" /> | ||
6 | + <option name="buildOnly" value="true" /> | ||
7 | + <option name="sourceFilePath" value="ruoyi-extend/ruoyi-xxl-job-admin/Dockerfile" /> | ||
8 | + </settings> | ||
9 | + </deployment> | ||
10 | + <method v="2" /> | ||
11 | + </configuration> | ||
12 | +</component> |
LICENSE
0 → 100644
1 | +The MIT License (MIT) | ||
2 | + | ||
3 | +Copyright (c) 2019 RuoYi-Vue-Plus | ||
4 | + | ||
5 | +Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
6 | +this software and associated documentation files (the "Software"), to deal in | ||
7 | +the Software without restriction, including without limitation the rights to | ||
8 | +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | ||
9 | +the Software, and to permit persons to whom the Software is furnished to do so, | ||
10 | +subject to the following conditions: | ||
11 | + | ||
12 | +The above copyright notice and this permission notice shall be included in all | ||
13 | +copies or substantial portions of the Software. | ||
14 | + | ||
15 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | ||
17 | +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | ||
18 | +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
19 | +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
20 | +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
README.md
0 → 100644
1 | +接口地址:https://sapi.007vin.com/ | ||
2 | +open_id:489c1079b6ab49d359eced61d7d83804 | ||
3 | +token:8e9b584b2e09db0fb6829fc237f88efd | ||
4 | + | ||
5 | +7874 | ||
6 | +7504 | ||
7 | + | ||
8 | +询价单号: | ||
9 | +XJD20250610004666382 | ||
10 | +定损单号: | ||
11 | +61348110 | ||
12 | +车架号: | ||
13 | +LFV2A1151L6029426 | ||
14 | +车牌号: | ||
15 | +浙F7DV79 | ||
16 | +车型名称: | ||
17 | +2020 一汽大众 宝来 三厢 1.5L 手动档 时尚型(FV7152NAMCG) | ||
18 | + | ||
19 | + | ||
20 | +车型: 大众上汽大众 帕萨特 修改 | ||
21 | +vin码: LSVCF6C44LN0196051 | ||
22 | + | ||
23 | + | ||
24 | +询价单号: | ||
25 | +XJD20250610004667219 | ||
26 | +定损单号: | ||
27 | +61427326 | ||
28 | +车架号: | ||
29 | +LFV2A21K0H4306789 | ||
30 | +车牌号: | ||
31 | +浙FY201E | ||
32 | +车型名称: | ||
33 | +2018 一汽大众 速腾 三厢 1.6L 手自一体 舒适型(FV7166BABBG) | ||
34 | + | ||
35 | + | ||
36 | +询价单号: | ||
37 | +XJD20250609004660147 | ||
38 | +定损单号: | ||
39 | +61398539 | ||
40 | +车架号: | ||
41 | +LSVAF40C7KN112351 | ||
42 | +车牌号: | ||
43 | +皖K537K6 | ||
44 | +车型名称: | ||
45 | +2018 上汽大众 朗逸 三厢 1.5L 手自一体 | ||
46 | + | ||
47 | +询价单号: | ||
48 | +XJD20250604004626210 | ||
49 | +定损单号: | ||
50 | +61321667 | ||
51 | +车架号: | ||
52 | +WBALS2102J0Z29641 | ||
53 | +车牌号: | ||
54 | +苏L8L760 | ||
55 | +车型名称: | ||
56 | +2018 宝马 宝马X5 SUV 2.0T 手自一体 (BMW X5 28i) | ||
57 | + | ||
58 | +大众平均 2.5元 | ||
59 | +宝马平均 10元 | ||
60 | +奥迪平均 3.5元 | ||
61 | + | ||
62 | + | ||
63 | +LFV2A2BS6H4560229 x | ||
64 | +LFV2B2C13M3816698 x | ||
65 | +LSVY460T6S2051608 x | ||
66 | +LFV2A28V7J5392246 x | ||
67 | +LFV2A28V0H5024498 x | ||
68 | +LFV3B2FY1J3513783 x | ||
69 | +LFV3B2FY4P3383572 x | ||
70 | +LFV3A24KXR3152230 | ||
71 | +LBV61AF08NS321734 | ||
72 | +LBV8V3101GMD46730 | ||
73 | +LBVFP3904BSE35458 x | ||
74 | + | ||
75 | + | ||
76 | + | ||
77 | + | ||
78 | +fCVkbmMlPSclPzE3JXo%3D | ||
79 | +fCVkbmMlPSclMzQwJXo%3D | ||
80 | + | ||
81 | + | ||
82 | +LFV2A1151L6029426 | ||
83 | +LFV2A2151G3063539 |
pom.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
4 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
5 | + <modelVersion>4.0.0</modelVersion> | ||
6 | + | ||
7 | + <groupId>com.scm</groupId> | ||
8 | + <artifactId>fp_scm</artifactId> | ||
9 | + <version>4.8.2</version> | ||
10 | + | ||
11 | + <name>fp_scm</name> | ||
12 | + <description>凡配供应链系统</description> | ||
13 | + | ||
14 | + <properties> | ||
15 | + <fp-scm.version>4.8.2</fp-scm.version> | ||
16 | + <spring-boot.version>2.7.18</spring-boot.version> | ||
17 | + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
18 | + <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | ||
19 | + <java.version>1.8</java.version> | ||
20 | + <maven-jar-plugin.version>3.2.2</maven-jar-plugin.version> | ||
21 | + <spring-boot.mybatis>2.2.2</spring-boot.mybatis> | ||
22 | + <springdoc.version>1.6.15</springdoc.version> | ||
23 | + <poi.version>5.2.3</poi.version> | ||
24 | + <easyexcel.version>3.3.2</easyexcel.version> | ||
25 | + <velocity.version>2.3</velocity.version> | ||
26 | + <satoken.version>1.37.0</satoken.version> | ||
27 | + <mybatis-plus.version>3.5.4</mybatis-plus.version> | ||
28 | + <p6spy.version>3.9.1</p6spy.version> | ||
29 | + <hutool.version>5.8.22</hutool.version> | ||
30 | + <okhttp.version>4.10.0</okhttp.version> | ||
31 | + <spring-boot-admin.version>2.7.11</spring-boot-admin.version> | ||
32 | + <redisson.version>3.20.1</redisson.version> | ||
33 | + <lock4j.version>2.2.3</lock4j.version> | ||
34 | + <dynamic-ds.version>4.3.1</dynamic-ds.version> | ||
35 | + <alibaba-ttl.version>2.14.2</alibaba-ttl.version> | ||
36 | + <xxl-job.version>2.4.0</xxl-job.version> | ||
37 | + <lombok.version>1.18.30</lombok.version> | ||
38 | + <bouncycastle.version>1.72</bouncycastle.version> | ||
39 | + <!-- 离线IP地址定位库 --> | ||
40 | + <ip2region.version>2.7.0</ip2region.version> | ||
41 | + | ||
42 | + <!-- OSS 配置 --> | ||
43 | + <aws-java-sdk-s3.version>1.12.540</aws-java-sdk-s3.version> | ||
44 | + <!-- SMS 配置 --> | ||
45 | + <sms4j.version>2.2.0</sms4j.version> | ||
46 | + <sharding-sphere.version>4.0.0</sharding-sphere.version> | ||
47 | + </properties> | ||
48 | + | ||
49 | + <profiles> | ||
50 | + <profile> | ||
51 | + <id>local</id> | ||
52 | + <properties> | ||
53 | + <!-- 环境标识,需要与配置文件的名称相对应 --> | ||
54 | + <profiles.active>local</profiles.active> | ||
55 | + <logging.level>info</logging.level> | ||
56 | + </properties> | ||
57 | + </profile> | ||
58 | + <profile> | ||
59 | + <id>dev</id> | ||
60 | + <properties> | ||
61 | + <!-- 环境标识,需要与配置文件的名称相对应 --> | ||
62 | + <profiles.active>dev</profiles.active> | ||
63 | + <logging.level>info</logging.level> | ||
64 | + </properties> | ||
65 | + <activation> | ||
66 | + <!-- 默认环境 --> | ||
67 | + <activeByDefault>true</activeByDefault> | ||
68 | + </activation> | ||
69 | + </profile> | ||
70 | + <profile> | ||
71 | + <id>prod</id> | ||
72 | + <properties> | ||
73 | + <profiles.active>prod</profiles.active> | ||
74 | + <logging.level>warn</logging.level> | ||
75 | + </properties> | ||
76 | + </profile> | ||
77 | + </profiles> | ||
78 | + | ||
79 | + <!-- 依赖声明 --> | ||
80 | + <dependencyManagement> | ||
81 | + <dependencies> | ||
82 | + | ||
83 | + <!-- SpringBoot的依赖配置--> | ||
84 | + <dependency> | ||
85 | + <groupId>org.springframework.boot</groupId> | ||
86 | + <artifactId>spring-boot-dependencies</artifactId> | ||
87 | + <version>${spring-boot.version}</version> | ||
88 | + <type>pom</type> | ||
89 | + <scope>import</scope> | ||
90 | + </dependency> | ||
91 | + | ||
92 | + <!-- hutool 的依赖配置--> | ||
93 | + <dependency> | ||
94 | + <groupId>cn.hutool</groupId> | ||
95 | + <artifactId>hutool-bom</artifactId> | ||
96 | + <version>${hutool.version}</version> | ||
97 | + <type>pom</type> | ||
98 | + <scope>import</scope> | ||
99 | + </dependency> | ||
100 | + | ||
101 | + <dependency> | ||
102 | + <groupId>org.springdoc</groupId> | ||
103 | + <artifactId>springdoc-openapi-webmvc-core</artifactId> | ||
104 | + <version>${springdoc.version}</version> | ||
105 | + </dependency> | ||
106 | + | ||
107 | + <dependency> | ||
108 | + <groupId>org.springdoc</groupId> | ||
109 | + <artifactId>springdoc-openapi-javadoc</artifactId> | ||
110 | + <version>${springdoc.version}</version> | ||
111 | + </dependency> | ||
112 | + | ||
113 | + <dependency> | ||
114 | + <groupId>org.projectlombok</groupId> | ||
115 | + <artifactId>lombok</artifactId> | ||
116 | + <version>${lombok.version}</version> | ||
117 | + </dependency> | ||
118 | + | ||
119 | + <dependency> | ||
120 | + <groupId>org.apache.poi</groupId> | ||
121 | + <artifactId>poi</artifactId> | ||
122 | + <version>${poi.version}</version> | ||
123 | + </dependency> | ||
124 | + <dependency> | ||
125 | + <groupId>org.apache.poi</groupId> | ||
126 | + <artifactId>poi-ooxml</artifactId> | ||
127 | + <version>${poi.version}</version> | ||
128 | + </dependency> | ||
129 | + <dependency> | ||
130 | + <groupId>com.alibaba</groupId> | ||
131 | + <artifactId>easyexcel</artifactId> | ||
132 | + <version>${easyexcel.version}</version> | ||
133 | + <exclusions> | ||
134 | + <exclusion> | ||
135 | + <groupId>org.apache.poi</groupId> | ||
136 | + <artifactId>poi-ooxml-schemas</artifactId> | ||
137 | + </exclusion> | ||
138 | + </exclusions> | ||
139 | + </dependency> | ||
140 | + | ||
141 | + <!-- velocity代码生成使用模板 --> | ||
142 | + <dependency> | ||
143 | + <groupId>org.apache.velocity</groupId> | ||
144 | + <artifactId>velocity-engine-core</artifactId> | ||
145 | + <version>${velocity.version}</version> | ||
146 | + </dependency> | ||
147 | + | ||
148 | + <!-- Sa-Token 权限认证, 在线文档:http://sa-token.dev33.cn/ --> | ||
149 | + <dependency> | ||
150 | + <groupId>cn.dev33</groupId> | ||
151 | + <artifactId>sa-token-spring-boot-starter</artifactId> | ||
152 | + <version>${satoken.version}</version> | ||
153 | + </dependency> | ||
154 | + <!-- Sa-Token 整合 jwt --> | ||
155 | + <dependency> | ||
156 | + <groupId>cn.dev33</groupId> | ||
157 | + <artifactId>sa-token-jwt</artifactId> | ||
158 | + <version>${satoken.version}</version> | ||
159 | + <exclusions> | ||
160 | + <exclusion> | ||
161 | + <groupId>cn.hutool</groupId> | ||
162 | + <artifactId>hutool-all</artifactId> | ||
163 | + </exclusion> | ||
164 | + </exclusions> | ||
165 | + </dependency> | ||
166 | + | ||
167 | + <!-- dynamic-datasource 多数据源--> | ||
168 | + <dependency> | ||
169 | + <groupId>com.baomidou</groupId> | ||
170 | + <artifactId>dynamic-datasource-spring-boot-starter</artifactId> | ||
171 | + <version>${dynamic-ds.version}</version> | ||
172 | + </dependency> | ||
173 | + | ||
174 | + <dependency> | ||
175 | + <groupId>com.baomidou</groupId> | ||
176 | + <artifactId>mybatis-plus-boot-starter</artifactId> | ||
177 | + <version>${mybatis-plus.version}</version> | ||
178 | + </dependency> | ||
179 | + | ||
180 | + <!-- sql性能分析插件 --> | ||
181 | + <dependency> | ||
182 | + <groupId>p6spy</groupId> | ||
183 | + <artifactId>p6spy</artifactId> | ||
184 | + <version>${p6spy.version}</version> | ||
185 | + </dependency> | ||
186 | + | ||
187 | + <dependency> | ||
188 | + <groupId>com.squareup.okhttp3</groupId> | ||
189 | + <artifactId>okhttp</artifactId> | ||
190 | + <version>${okhttp.version}</version> | ||
191 | + </dependency> | ||
192 | + | ||
193 | + <dependency> | ||
194 | + <groupId>com.amazonaws</groupId> | ||
195 | + <artifactId>aws-java-sdk-s3</artifactId> | ||
196 | + <version>${aws-java-sdk-s3.version}</version> | ||
197 | + </dependency> | ||
198 | + | ||
199 | + <!--短信sms4j--> | ||
200 | + <dependency> | ||
201 | + <groupId>org.dromara.sms4j</groupId> | ||
202 | + <artifactId>sms4j-spring-boot-starter</artifactId> | ||
203 | + <version>${sms4j.version}</version> | ||
204 | + </dependency> | ||
205 | + | ||
206 | + <dependency> | ||
207 | + <groupId>de.codecentric</groupId> | ||
208 | + <artifactId>spring-boot-admin-starter-server</artifactId> | ||
209 | + <version>${spring-boot-admin.version}</version> | ||
210 | + </dependency> | ||
211 | + <dependency> | ||
212 | + <groupId>de.codecentric</groupId> | ||
213 | + <artifactId>spring-boot-admin-starter-client</artifactId> | ||
214 | + <version>${spring-boot-admin.version}</version> | ||
215 | + </dependency> | ||
216 | + | ||
217 | + <!--redisson--> | ||
218 | + <dependency> | ||
219 | + <groupId>org.redisson</groupId> | ||
220 | + <artifactId>redisson-spring-boot-starter</artifactId> | ||
221 | + <version>${redisson.version}</version> | ||
222 | + <exclusions> | ||
223 | + <exclusion> | ||
224 | + <groupId>org.redisson</groupId> | ||
225 | + <artifactId>redisson-spring-data-30</artifactId> | ||
226 | + </exclusion> | ||
227 | + </exclusions> | ||
228 | + </dependency> | ||
229 | + <dependency> | ||
230 | + <groupId>org.redisson</groupId> | ||
231 | + <artifactId>redisson-spring-data-27</artifactId> | ||
232 | + <version>${redisson.version}</version> | ||
233 | + </dependency> | ||
234 | + | ||
235 | + <dependency> | ||
236 | + <groupId>com.baomidou</groupId> | ||
237 | + <artifactId>lock4j-redisson-spring-boot-starter</artifactId> | ||
238 | + <version>${lock4j.version}</version> | ||
239 | + </dependency> | ||
240 | + | ||
241 | + <!-- xxl-job-core --> | ||
242 | + <dependency> | ||
243 | + <groupId>com.xuxueli</groupId> | ||
244 | + <artifactId>xxl-job-core</artifactId> | ||
245 | + <version>${xxl-job.version}</version> | ||
246 | + </dependency> | ||
247 | + | ||
248 | + <dependency> | ||
249 | + <groupId>com.alibaba</groupId> | ||
250 | + <artifactId>transmittable-thread-local</artifactId> | ||
251 | + <version>${alibaba-ttl.version}</version> | ||
252 | + </dependency> | ||
253 | + | ||
254 | + <!-- 离线IP地址定位库 ip2region --> | ||
255 | + <dependency> | ||
256 | + <groupId>org.lionsoul</groupId> | ||
257 | + <artifactId>ip2region</artifactId> | ||
258 | + <version>${ip2region.version}</version> | ||
259 | + </dependency> | ||
260 | + | ||
261 | + <!-- 加密包引入 --> | ||
262 | + <dependency> | ||
263 | + <groupId>org.bouncycastle</groupId> | ||
264 | + <artifactId>bcprov-jdk15to18</artifactId> | ||
265 | + <version>${bouncycastle.version}</version> | ||
266 | + </dependency> | ||
267 | + | ||
268 | + <dependency> | ||
269 | + <groupId>org.apache.shardingsphere</groupId> | ||
270 | + <artifactId>sharding-jdbc-spring-boot-starter</artifactId> | ||
271 | + <version>${sharding-sphere.version}</version> | ||
272 | + </dependency> | ||
273 | + | ||
274 | + <dependency> | ||
275 | + <groupId>org.apache.shardingsphere</groupId> | ||
276 | + <artifactId>shardingsphere-jdbc</artifactId> | ||
277 | + <version>5.5.0</version> | ||
278 | + </dependency> | ||
279 | + | ||
280 | + <!-- 定时任务 --> | ||
281 | + <dependency> | ||
282 | + <groupId>com.scm</groupId> | ||
283 | + <artifactId>scm-job</artifactId> | ||
284 | + <version>${fp-scm.version}</version> | ||
285 | + </dependency> | ||
286 | + | ||
287 | + <!-- 代码生成--> | ||
288 | + <dependency> | ||
289 | + <groupId>com.scm</groupId> | ||
290 | + <artifactId>scm-generator</artifactId> | ||
291 | + <version>${fp-scm.version}</version> | ||
292 | + </dependency> | ||
293 | + | ||
294 | + <!-- 核心模块--> | ||
295 | + <dependency> | ||
296 | + <groupId>com.scm</groupId> | ||
297 | + <artifactId>scm-framework</artifactId> | ||
298 | + <version>${fp-scm.version}</version> | ||
299 | + </dependency> | ||
300 | + | ||
301 | + <!-- 系统模块--> | ||
302 | + <dependency> | ||
303 | + <groupId>com.scm</groupId> | ||
304 | + <artifactId>scm-system</artifactId> | ||
305 | + <version>${fp-scm.version}</version> | ||
306 | + </dependency> | ||
307 | + | ||
308 | + <!-- 通用工具--> | ||
309 | + <dependency> | ||
310 | + <groupId>com.scm</groupId> | ||
311 | + <artifactId>scm-common</artifactId> | ||
312 | + <version>${fp-scm.version}</version> | ||
313 | + </dependency> | ||
314 | + | ||
315 | + <!-- OSS对象存储模块 --> | ||
316 | + <dependency> | ||
317 | + <groupId>com.scm</groupId> | ||
318 | + <artifactId>scm-oss</artifactId> | ||
319 | + <version>${fp-scm.version}</version> | ||
320 | + </dependency> | ||
321 | + | ||
322 | + <!-- SMS短信模块 --> | ||
323 | + <dependency> | ||
324 | + <groupId>com.scm</groupId> | ||
325 | + <artifactId>scm-sms</artifactId> | ||
326 | + <version>${fp-scm.version}</version> | ||
327 | + </dependency> | ||
328 | + </dependencies> | ||
329 | + </dependencyManagement> | ||
330 | + | ||
331 | + <modules> | ||
332 | + <module>scm-admin</module> | ||
333 | + <module>scm-framework</module> | ||
334 | + <module>scm-system</module> | ||
335 | + <module>scm-job</module> | ||
336 | + <module>scm-generator</module> | ||
337 | + <module>scm-common</module> | ||
338 | + <module>scm-extend</module> | ||
339 | + <module>scm-oss</module> | ||
340 | + <module>scm-sms</module> | ||
341 | + </modules> | ||
342 | + <packaging>pom</packaging> | ||
343 | + | ||
344 | + <build> | ||
345 | + <plugins> | ||
346 | + <plugin> | ||
347 | + <groupId>org.apache.maven.plugins</groupId> | ||
348 | + <artifactId>maven-compiler-plugin</artifactId> | ||
349 | + <version>3.9.0</version> | ||
350 | + <configuration> | ||
351 | + <source>${java.version}</source> | ||
352 | + <target>${java.version}</target> | ||
353 | + <encoding>${project.build.sourceEncoding}</encoding> | ||
354 | + <annotationProcessorPaths> | ||
355 | + <path> | ||
356 | + <groupId>com.github.therapi</groupId> | ||
357 | + <artifactId>therapi-runtime-javadoc-scribe</artifactId> | ||
358 | + <version>0.15.0</version> | ||
359 | + </path> | ||
360 | + <path> | ||
361 | + <groupId>org.projectlombok</groupId> | ||
362 | + <artifactId>lombok</artifactId> | ||
363 | + <version>${lombok.version}</version> | ||
364 | + </path> | ||
365 | + <path> | ||
366 | + <groupId>org.springframework.boot</groupId> | ||
367 | + <artifactId>spring-boot-configuration-processor</artifactId> | ||
368 | + <version>${spring-boot.version}</version> | ||
369 | + </path> | ||
370 | + </annotationProcessorPaths> | ||
371 | + </configuration> | ||
372 | + </plugin> | ||
373 | + <!-- 单元测试使用 --> | ||
374 | + <plugin> | ||
375 | + <groupId>org.apache.maven.plugins</groupId> | ||
376 | + <artifactId>maven-surefire-plugin</artifactId> | ||
377 | + <version>2.22.2</version> | ||
378 | + <configuration> | ||
379 | + <argLine>-Dfile.encoding=UTF-8</argLine> | ||
380 | + <!-- 根据打包环境执行对应的@Tag测试方法 --> | ||
381 | + <groups>${profiles.active}</groups> | ||
382 | + <!-- 排除标签 --> | ||
383 | + <excludedGroups>exclude</excludedGroups> | ||
384 | + </configuration> | ||
385 | + </plugin> | ||
386 | + </plugins> | ||
387 | + <resources> | ||
388 | + <resource> | ||
389 | + <directory>src/main/resources</directory> | ||
390 | + <!-- 关闭过滤 --> | ||
391 | + <filtering>false</filtering> | ||
392 | + </resource> | ||
393 | + <resource> | ||
394 | + <directory>src/main/resources</directory> | ||
395 | + <!-- 引入所有 匹配文件进行过滤 --> | ||
396 | + <includes> | ||
397 | + <include>application*</include> | ||
398 | + <include>bootstrap*</include> | ||
399 | + <include>banner*</include> | ||
400 | + </includes> | ||
401 | + <!-- 启用过滤 即该资源中的变量将会被过滤器中的值替换 --> | ||
402 | + <filtering>true</filtering> | ||
403 | + </resource> | ||
404 | + </resources> | ||
405 | + </build> | ||
406 | + | ||
407 | + <repositories> | ||
408 | + <repository> | ||
409 | + <id>public</id> | ||
410 | + <name>huawei nexus</name> | ||
411 | + <url>https://mirrors.huaweicloud.com/repository/maven/</url> | ||
412 | + <releases> | ||
413 | + <enabled>true</enabled> | ||
414 | + </releases> | ||
415 | + </repository> | ||
416 | + </repositories> | ||
417 | + | ||
418 | + <pluginRepositories> | ||
419 | + <pluginRepository> | ||
420 | + <id>public</id> | ||
421 | + <name>huawei nexus</name> | ||
422 | + <url>https://mirrors.huaweicloud.com/repository/maven/</url> | ||
423 | + <releases> | ||
424 | + <enabled>true</enabled> | ||
425 | + </releases> | ||
426 | + <snapshots> | ||
427 | + <enabled>false</enabled> | ||
428 | + </snapshots> | ||
429 | + </pluginRepository> | ||
430 | + </pluginRepositories> | ||
431 | + | ||
432 | +</project> | ||
433 | + | ||
434 | + |
scm-admin/Dockerfile
0 → 100644
1 | +FROM anapsix/alpine-java:8_server-jre_unlimited | ||
2 | + | ||
3 | +MAINTAINER Lion Li | ||
4 | + | ||
5 | +RUN mkdir -p /ruoyi/server/logs \ | ||
6 | + /ruoyi/server/temp \ | ||
7 | + /ruoyi/skywalking/agent | ||
8 | + | ||
9 | +WORKDIR /ruoyi/server | ||
10 | + | ||
11 | +ENV SERVER_PORT=8080 | ||
12 | + | ||
13 | +EXPOSE ${SERVER_PORT} | ||
14 | + | ||
15 | +ADD ./target/ruoyi-admin.jar ./app.jar | ||
16 | + | ||
17 | +ENTRYPOINT ["java", \ | ||
18 | + "-Djava.security.egd=file:/dev/./urandom", \ | ||
19 | + "-Dserver.port=${SERVER_PORT}", \ | ||
20 | + # 应用名称 如果想区分集群节点监控 改成不同的名称即可 | ||
21 | +# "-Dskywalking.agent.service_name=ruoyi-server", \ | ||
22 | +# "-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar", \ | ||
23 | + "-jar", "app.jar"] |
scm-admin/pom.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
4 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
5 | + <parent> | ||
6 | + <artifactId>fp_scm</artifactId> | ||
7 | + <groupId>com.scm</groupId> | ||
8 | + <version>4.8.2</version> | ||
9 | + </parent> | ||
10 | + <modelVersion>4.0.0</modelVersion> | ||
11 | + <packaging>jar</packaging> | ||
12 | + <artifactId>scm-admin</artifactId> | ||
13 | + | ||
14 | + <description> | ||
15 | + web服务入口 | ||
16 | + </description> | ||
17 | + | ||
18 | + <dependencies> | ||
19 | + | ||
20 | + <!-- spring-boot-devtools --> | ||
21 | + <dependency> | ||
22 | + <groupId>org.springframework.boot</groupId> | ||
23 | + <artifactId>spring-boot-devtools</artifactId> | ||
24 | + <optional>true</optional> <!-- 表示依赖不会传递 --> | ||
25 | + </dependency> | ||
26 | + | ||
27 | + <!-- Mysql驱动包 --> | ||
28 | + <dependency> | ||
29 | + <groupId>com.mysql</groupId> | ||
30 | + <artifactId>mysql-connector-j</artifactId> | ||
31 | + </dependency> | ||
32 | + <!-- Oracle --> | ||
33 | + <dependency> | ||
34 | + <groupId>com.oracle.database.jdbc</groupId> | ||
35 | + <artifactId>ojdbc8</artifactId> | ||
36 | + </dependency> | ||
37 | + <!-- PostgreSql --> | ||
38 | + <dependency> | ||
39 | + <groupId>org.postgresql</groupId> | ||
40 | + <artifactId>postgresql</artifactId> | ||
41 | + </dependency> | ||
42 | + <!-- SqlServer --> | ||
43 | + <dependency> | ||
44 | + <groupId>com.microsoft.sqlserver</groupId> | ||
45 | + <artifactId>mssql-jdbc</artifactId> | ||
46 | + </dependency> | ||
47 | + | ||
48 | + <!-- 核心模块--> | ||
49 | + <dependency> | ||
50 | + <groupId>com.scm</groupId> | ||
51 | + <artifactId>scm-framework</artifactId> | ||
52 | + </dependency> | ||
53 | + | ||
54 | + <dependency> | ||
55 | + <groupId>com.scm</groupId> | ||
56 | + <artifactId>scm-system</artifactId> | ||
57 | + </dependency> | ||
58 | + | ||
59 | +<!-- | ||
60 | + <dependency> | ||
61 | + <groupId>com.scm</groupId> | ||
62 | + <artifactId>ruoyi-job</artifactId> | ||
63 | + </dependency> | ||
64 | +--> | ||
65 | + | ||
66 | + <dependency> | ||
67 | + <groupId>com.scm</groupId> | ||
68 | + <artifactId>scm-oss</artifactId> | ||
69 | + </dependency> | ||
70 | + | ||
71 | + <!-- 代码生成--> | ||
72 | + <dependency> | ||
73 | + <groupId>com.scm</groupId> | ||
74 | + <artifactId>scm-generator</artifactId> | ||
75 | + </dependency> | ||
76 | + | ||
77 | + <dependency> | ||
78 | + <groupId>org.springframework.boot</groupId> | ||
79 | + <artifactId>spring-boot-starter-test</artifactId> | ||
80 | + <scope>test</scope> | ||
81 | + </dependency> | ||
82 | + | ||
83 | + <!-- skywalking 整合 logback --> | ||
84 | +<!-- <dependency>--> | ||
85 | +<!-- <groupId>org.apache.skywalking</groupId>--> | ||
86 | +<!-- <artifactId>apm-toolkit-logback-1.x</artifactId>--> | ||
87 | +<!-- <version>${与你的agent探针版本保持一致}</version>--> | ||
88 | +<!-- </dependency>--> | ||
89 | +<!-- <dependency>--> | ||
90 | +<!-- <groupId>org.apache.skywalking</groupId>--> | ||
91 | +<!-- <artifactId>apm-toolkit-trace</artifactId>--> | ||
92 | +<!-- <version>${与你的agent探针版本保持一致}</version>--> | ||
93 | +<!-- </dependency>--> | ||
94 | + | ||
95 | + </dependencies> | ||
96 | + | ||
97 | + <build> | ||
98 | + <finalName>${project.artifactId}</finalName> | ||
99 | + <plugins> | ||
100 | + <plugin> | ||
101 | + <groupId>org.springframework.boot</groupId> | ||
102 | + <artifactId>spring-boot-maven-plugin</artifactId> | ||
103 | + <version>${spring-boot.version}</version> | ||
104 | + <configuration> | ||
105 | + <fork>true</fork> <!-- 如果没有该配置,devtools不会生效 --> | ||
106 | + </configuration> | ||
107 | + <executions> | ||
108 | + <execution> | ||
109 | + <goals> | ||
110 | + <goal>repackage</goal> | ||
111 | + </goals> | ||
112 | + </execution> | ||
113 | + </executions> | ||
114 | + </plugin> | ||
115 | + <plugin> | ||
116 | + <groupId>org.apache.maven.plugins</groupId> | ||
117 | + <artifactId>maven-war-plugin</artifactId> | ||
118 | + <version>3.2.2</version> | ||
119 | + <configuration> | ||
120 | + <failOnMissingWebXml>false</failOnMissingWebXml> | ||
121 | + <warName>${project.artifactId}</warName> | ||
122 | + </configuration> | ||
123 | + </plugin> | ||
124 | + </plugins> | ||
125 | + </build> | ||
126 | + | ||
127 | +</project> |
1 | +package com.ruoyi; | ||
2 | + | ||
3 | +import org.springframework.boot.SpringApplication; | ||
4 | +import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
5 | +import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup; | ||
6 | + | ||
7 | +/** | ||
8 | + * 启动程序 | ||
9 | + * | ||
10 | + * @author ruoyi | ||
11 | + */ | ||
12 | + | ||
13 | +@SpringBootApplication | ||
14 | +public class RuoYiApplication { | ||
15 | + | ||
16 | + public static void main(String[] args) { | ||
17 | + System.setProperty("spring.devtools.restart.enabled", "false"); | ||
18 | + SpringApplication application = new SpringApplication(RuoYiApplication.class); | ||
19 | + application.setApplicationStartup(new BufferingApplicationStartup(2048)); | ||
20 | + application.run(args); | ||
21 | + System.out.println("(♥◠‿◠)ノ゙ RuoYi-Vue-Plus启动成功 ლ(´ڡ`ლ)゙"); | ||
22 | + } | ||
23 | + | ||
24 | +} |
1 | +package com.ruoyi; | ||
2 | + | ||
3 | +import org.springframework.boot.builder.SpringApplicationBuilder; | ||
4 | +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; | ||
5 | + | ||
6 | +/** | ||
7 | + * web容器中进行部署 | ||
8 | + * | ||
9 | + * @author ruoyi | ||
10 | + */ | ||
11 | +public class RuoYiServletInitializer extends SpringBootServletInitializer { | ||
12 | + | ||
13 | + @Override | ||
14 | + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { | ||
15 | + return application.sources(RuoYiApplication.class); | ||
16 | + } | ||
17 | + | ||
18 | +} |
1 | +package com.ruoyi.web.controller.common; | ||
2 | + | ||
3 | +import cn.dev33.satoken.annotation.SaIgnore; | ||
4 | +import cn.hutool.captcha.AbstractCaptcha; | ||
5 | +import cn.hutool.captcha.generator.CodeGenerator; | ||
6 | +import cn.hutool.core.util.IdUtil; | ||
7 | +import cn.hutool.core.util.RandomUtil; | ||
8 | +import com.ruoyi.common.constant.CacheConstants; | ||
9 | +import com.ruoyi.common.constant.Constants; | ||
10 | +import com.ruoyi.common.core.domain.R; | ||
11 | +import com.ruoyi.common.enums.CaptchaType; | ||
12 | +import com.ruoyi.common.utils.StringUtils; | ||
13 | +import com.ruoyi.common.utils.email.MailUtils; | ||
14 | +import com.ruoyi.common.utils.redis.RedisUtils; | ||
15 | +import com.ruoyi.common.utils.reflect.ReflectUtils; | ||
16 | +import com.ruoyi.common.utils.spring.SpringUtils; | ||
17 | +import com.ruoyi.framework.config.properties.CaptchaProperties; | ||
18 | +import com.ruoyi.framework.config.properties.MailProperties; | ||
19 | +import com.ruoyi.system.service.ISysConfigService; | ||
20 | +import lombok.RequiredArgsConstructor; | ||
21 | +import lombok.extern.slf4j.Slf4j; | ||
22 | +import org.dromara.sms4j.api.SmsBlend; | ||
23 | +import org.dromara.sms4j.api.entity.SmsResponse; | ||
24 | +import org.dromara.sms4j.core.factory.SmsFactory; | ||
25 | +import org.dromara.sms4j.provider.enumerate.SupplierType; | ||
26 | +import org.springframework.expression.Expression; | ||
27 | +import org.springframework.expression.ExpressionParser; | ||
28 | +import org.springframework.expression.spel.standard.SpelExpressionParser; | ||
29 | +import org.springframework.validation.annotation.Validated; | ||
30 | +import org.springframework.web.bind.annotation.GetMapping; | ||
31 | +import org.springframework.web.bind.annotation.RestController; | ||
32 | + | ||
33 | +import javax.validation.constraints.NotBlank; | ||
34 | +import java.time.Duration; | ||
35 | +import java.util.HashMap; | ||
36 | +import java.util.LinkedHashMap; | ||
37 | +import java.util.Map; | ||
38 | + | ||
39 | +/** | ||
40 | + * 验证码操作处理 | ||
41 | + * | ||
42 | + * @author Lion Li | ||
43 | + */ | ||
44 | +@SaIgnore | ||
45 | +@Slf4j | ||
46 | +@Validated | ||
47 | +@RequiredArgsConstructor | ||
48 | +@RestController | ||
49 | +public class CaptchaController { | ||
50 | + | ||
51 | + private final CaptchaProperties captchaProperties; | ||
52 | + private final ISysConfigService configService; | ||
53 | + private final MailProperties mailProperties; | ||
54 | + | ||
55 | + /** | ||
56 | + * 短信验证码 | ||
57 | + * | ||
58 | + * @param phonenumber 用户手机号 | ||
59 | + */ | ||
60 | + @GetMapping("/captchaSms") | ||
61 | + public R<Void> smsCaptcha(@NotBlank(message = "{user.phonenumber.not.blank}") String phonenumber) { | ||
62 | + String key = CacheConstants.CAPTCHA_CODE_KEY + phonenumber; | ||
63 | + String code = RandomUtil.randomNumbers(4); | ||
64 | + RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION)); | ||
65 | + // 验证码模板id 自行处理 (查数据库或写死均可) | ||
66 | + String templateId = ""; | ||
67 | + LinkedHashMap<String, String> map = new LinkedHashMap<>(1); | ||
68 | + map.put("code", code); | ||
69 | + SmsBlend smsBlend = SmsFactory.createSmsBlend(SupplierType.ALIBABA); | ||
70 | + SmsResponse smsResponse = smsBlend.sendMessage(phonenumber, templateId, map); | ||
71 | + if (!"OK".equals(smsResponse.getCode())) { | ||
72 | + log.error("验证码短信发送异常 => {}", smsResponse); | ||
73 | + return R.fail(smsResponse.getMessage()); | ||
74 | + } | ||
75 | + return R.ok(); | ||
76 | + } | ||
77 | + | ||
78 | + /** | ||
79 | + * 邮箱验证码 | ||
80 | + * | ||
81 | + * @param email 邮箱 | ||
82 | + */ | ||
83 | + @GetMapping("/captchaEmail") | ||
84 | + public R<Void> emailCode(@NotBlank(message = "{user.email.not.blank}") String email) { | ||
85 | + if (!mailProperties.getEnabled()) { | ||
86 | + return R.fail("当前系统没有开启邮箱功能!"); | ||
87 | + } | ||
88 | + String key = CacheConstants.CAPTCHA_CODE_KEY + email; | ||
89 | + String code = RandomUtil.randomNumbers(4); | ||
90 | + RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION)); | ||
91 | + try { | ||
92 | + MailUtils.sendText(email, "登录验证码", "您本次验证码为:" + code + ",有效性为" + Constants.CAPTCHA_EXPIRATION + "分钟,请尽快填写。"); | ||
93 | + } catch (Exception e) { | ||
94 | + log.error("验证码短信发送异常 => {}", e.getMessage()); | ||
95 | + return R.fail(e.getMessage()); | ||
96 | + } | ||
97 | + return R.ok(); | ||
98 | + } | ||
99 | + | ||
100 | + /** | ||
101 | + * 生成验证码 | ||
102 | + */ | ||
103 | + @GetMapping("/captchaImage") | ||
104 | + public R<Map<String, Object>> getCode() { | ||
105 | + Map<String, Object> ajax = new HashMap<>(); | ||
106 | + boolean captchaEnabled = configService.selectCaptchaEnabled(); | ||
107 | + ajax.put("captchaEnabled", captchaEnabled); | ||
108 | + if (!captchaEnabled) { | ||
109 | + return R.ok(ajax); | ||
110 | + } | ||
111 | + // 保存验证码信息 | ||
112 | + String uuid = IdUtil.simpleUUID(); | ||
113 | + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; | ||
114 | + // 生成验证码 | ||
115 | + CaptchaType captchaType = captchaProperties.getType(); | ||
116 | + boolean isMath = CaptchaType.MATH == captchaType; | ||
117 | + Integer length = isMath ? captchaProperties.getNumberLength() : captchaProperties.getCharLength(); | ||
118 | + CodeGenerator codeGenerator = ReflectUtils.newInstance(captchaType.getClazz(), length); | ||
119 | + AbstractCaptcha captcha = SpringUtils.getBean(captchaProperties.getCategory().getClazz()); | ||
120 | + captcha.setGenerator(codeGenerator); | ||
121 | + captcha.createCode(); | ||
122 | + String code = captcha.getCode(); | ||
123 | + if (isMath) { | ||
124 | + ExpressionParser parser = new SpelExpressionParser(); | ||
125 | + Expression exp = parser.parseExpression(StringUtils.remove(code, "=")); | ||
126 | + code = exp.getValue(String.class); | ||
127 | + } | ||
128 | + RedisUtils.setCacheObject(verifyKey, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION)); | ||
129 | + ajax.put("uuid", uuid); | ||
130 | + ajax.put("img", captcha.getImageBase64()); | ||
131 | + return R.ok(ajax); | ||
132 | + } | ||
133 | + | ||
134 | +} |
1 | +package com.ruoyi.web.controller.monitor; | ||
2 | + | ||
3 | +import cn.dev33.satoken.annotation.SaCheckPermission; | ||
4 | +import cn.hutool.core.collection.CollUtil; | ||
5 | +import com.ruoyi.common.constant.CacheConstants; | ||
6 | +import com.ruoyi.common.constant.CacheNames; | ||
7 | +import com.ruoyi.common.core.domain.R; | ||
8 | +import com.ruoyi.common.utils.JsonUtils; | ||
9 | +import com.ruoyi.common.utils.StringUtils; | ||
10 | +import com.ruoyi.common.utils.redis.CacheUtils; | ||
11 | +import com.ruoyi.common.utils.redis.RedisUtils; | ||
12 | +import com.ruoyi.system.domain.SysCache; | ||
13 | +import lombok.RequiredArgsConstructor; | ||
14 | +import org.redisson.spring.data.connection.RedissonConnectionFactory; | ||
15 | +import org.springframework.data.redis.connection.RedisConnection; | ||
16 | +import org.springframework.web.bind.annotation.*; | ||
17 | + | ||
18 | +import java.util.*; | ||
19 | +import java.util.stream.Collectors; | ||
20 | + | ||
21 | +/** | ||
22 | + * 缓存监控 | ||
23 | + * | ||
24 | + * @author Lion Li | ||
25 | + */ | ||
26 | +@RequiredArgsConstructor | ||
27 | +@RestController | ||
28 | +@RequestMapping("/monitor/cache") | ||
29 | +public class CacheController { | ||
30 | + | ||
31 | + private final RedissonConnectionFactory connectionFactory; | ||
32 | + | ||
33 | + private final static List<SysCache> CACHES = new ArrayList<>(); | ||
34 | + | ||
35 | + static { | ||
36 | + CACHES.add(new SysCache(CacheConstants.ONLINE_TOKEN_KEY, "在线用户")); | ||
37 | + CACHES.add(new SysCache(CacheNames.SYS_CONFIG, "配置信息")); | ||
38 | + CACHES.add(new SysCache(CacheNames.SYS_DICT, "数据字典")); | ||
39 | + CACHES.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码")); | ||
40 | + CACHES.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "防重提交")); | ||
41 | + CACHES.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "限流处理")); | ||
42 | + CACHES.add(new SysCache(CacheNames.SYS_OSS_CONFIG, "OSS配置")); | ||
43 | + CACHES.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "密码错误次数")); | ||
44 | + } | ||
45 | + | ||
46 | + /** | ||
47 | + * 获取缓存监控列表 | ||
48 | + */ | ||
49 | + @SaCheckPermission("monitor:cache:list") | ||
50 | + @GetMapping() | ||
51 | + public R<Map<String, Object>> getInfo() throws Exception { | ||
52 | + RedisConnection connection = connectionFactory.getConnection(); | ||
53 | + Properties info = connection.info(); | ||
54 | + Properties commandStats = connection.info("commandstats"); | ||
55 | + Long dbSize = connection.dbSize(); | ||
56 | + | ||
57 | + Map<String, Object> result = new HashMap<>(3); | ||
58 | + result.put("info", info); | ||
59 | + result.put("dbSize", dbSize); | ||
60 | + | ||
61 | + List<Map<String, String>> pieList = new ArrayList<>(); | ||
62 | + if (commandStats != null) { | ||
63 | + commandStats.stringPropertyNames().forEach(key -> { | ||
64 | + Map<String, String> data = new HashMap<>(2); | ||
65 | + String property = commandStats.getProperty(key); | ||
66 | + data.put("name", StringUtils.removeStart(key, "cmdstat_")); | ||
67 | + data.put("value", StringUtils.substringBetween(property, "calls=", ",usec")); | ||
68 | + pieList.add(data); | ||
69 | + }); | ||
70 | + } | ||
71 | + result.put("commandStats", pieList); | ||
72 | + return R.ok(result); | ||
73 | + } | ||
74 | + | ||
75 | + /** | ||
76 | + * 获取缓存监控缓存名列表 | ||
77 | + */ | ||
78 | + @SaCheckPermission("monitor:cache:list") | ||
79 | + @GetMapping("/getNames") | ||
80 | + public R<List<SysCache>> cache() { | ||
81 | + return R.ok(CACHES); | ||
82 | + } | ||
83 | + | ||
84 | + /** | ||
85 | + * 获取缓存监控Key列表 | ||
86 | + * | ||
87 | + * @param cacheName 缓存名 | ||
88 | + */ | ||
89 | + @SaCheckPermission("monitor:cache:list") | ||
90 | + @GetMapping("/getKeys/{cacheName}") | ||
91 | + public R<Collection<String>> getCacheKeys(@PathVariable String cacheName) { | ||
92 | + Collection<String> cacheKeys = new HashSet<>(0); | ||
93 | + if (isCacheNames(cacheName)) { | ||
94 | + Set<Object> keys = CacheUtils.keys(cacheName); | ||
95 | + if (CollUtil.isNotEmpty(keys)) { | ||
96 | + cacheKeys = keys.stream().map(Object::toString).collect(Collectors.toList()); | ||
97 | + } | ||
98 | + } else { | ||
99 | + cacheKeys = RedisUtils.keys(cacheName + "*"); | ||
100 | + } | ||
101 | + return R.ok(cacheKeys); | ||
102 | + } | ||
103 | + | ||
104 | + /** | ||
105 | + * 获取缓存监控缓存值详情 | ||
106 | + * | ||
107 | + * @param cacheName 缓存名 | ||
108 | + * @param cacheKey 缓存key | ||
109 | + */ | ||
110 | + @SaCheckPermission("monitor:cache:list") | ||
111 | + @GetMapping("/getValue/{cacheName}/{cacheKey}") | ||
112 | + public R<SysCache> getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey) { | ||
113 | + Object cacheValue; | ||
114 | + if (isCacheNames(cacheName)) { | ||
115 | + cacheValue = CacheUtils.get(cacheName, cacheKey); | ||
116 | + } else { | ||
117 | + cacheValue = RedisUtils.getCacheObject(cacheKey); | ||
118 | + } | ||
119 | + SysCache sysCache = new SysCache(cacheName, cacheKey, JsonUtils.toJsonString(cacheValue)); | ||
120 | + return R.ok(sysCache); | ||
121 | + } | ||
122 | + | ||
123 | + /** | ||
124 | + * 清理缓存监控缓存名 | ||
125 | + * | ||
126 | + * @param cacheName 缓存名 | ||
127 | + */ | ||
128 | + @SaCheckPermission("monitor:cache:list") | ||
129 | + @DeleteMapping("/clearCacheName/{cacheName}") | ||
130 | + public R<Void> clearCacheName(@PathVariable String cacheName) { | ||
131 | + if (isCacheNames(cacheName)) { | ||
132 | + CacheUtils.clear(cacheName); | ||
133 | + } else { | ||
134 | + RedisUtils.deleteKeys(cacheName + "*"); | ||
135 | + } | ||
136 | + return R.ok(); | ||
137 | + } | ||
138 | + | ||
139 | + /** | ||
140 | + * 清理缓存监控Key | ||
141 | + * | ||
142 | + * @param cacheKey key名 | ||
143 | + */ | ||
144 | + @SaCheckPermission("monitor:cache:list") | ||
145 | + @DeleteMapping("/clearCacheKey/{cacheName}/{cacheKey}") | ||
146 | + public R<Void> clearCacheKey(@PathVariable String cacheName, @PathVariable String cacheKey) { | ||
147 | + if (isCacheNames(cacheName)) { | ||
148 | + CacheUtils.evict(cacheName, cacheKey); | ||
149 | + } else { | ||
150 | + RedisUtils.deleteObject(cacheKey); | ||
151 | + } | ||
152 | + return R.ok(); | ||
153 | + } | ||
154 | + | ||
155 | + /** | ||
156 | + * 清理全部缓存监控 | ||
157 | + */ | ||
158 | + @SaCheckPermission("monitor:cache:list") | ||
159 | + @DeleteMapping("/clearCacheAll") | ||
160 | + public R<Void> clearCacheAll() { | ||
161 | + RedisUtils.deleteKeys("*"); | ||
162 | + return R.ok(); | ||
163 | + } | ||
164 | + | ||
165 | + private boolean isCacheNames(String cacheName) { | ||
166 | + return !StringUtils.contains(cacheName, ":"); | ||
167 | + } | ||
168 | +} |
1 | +package com.ruoyi.web.controller.monitor; | ||
2 | + | ||
3 | +import cn.dev33.satoken.annotation.SaCheckPermission; | ||
4 | +import com.ruoyi.common.annotation.Log; | ||
5 | +import com.ruoyi.common.constant.CacheConstants; | ||
6 | +import com.ruoyi.common.core.controller.BaseController; | ||
7 | +import com.ruoyi.common.core.domain.PageQuery; | ||
8 | +import com.ruoyi.common.core.domain.R; | ||
9 | +import com.ruoyi.common.core.page.TableDataInfo; | ||
10 | +import com.ruoyi.common.enums.BusinessType; | ||
11 | +import com.ruoyi.common.utils.poi.ExcelUtil; | ||
12 | +import com.ruoyi.common.utils.redis.RedisUtils; | ||
13 | +import com.ruoyi.system.domain.SysLogininfor; | ||
14 | +import com.ruoyi.system.service.ISysLogininforService; | ||
15 | +import lombok.RequiredArgsConstructor; | ||
16 | +import org.springframework.validation.annotation.Validated; | ||
17 | +import org.springframework.web.bind.annotation.*; | ||
18 | + | ||
19 | +import javax.servlet.http.HttpServletResponse; | ||
20 | +import java.util.List; | ||
21 | + | ||
22 | +/** | ||
23 | + * 系统访问记录 | ||
24 | + * | ||
25 | + * @author Lion Li | ||
26 | + */ | ||
27 | +@Validated | ||
28 | +@RequiredArgsConstructor | ||
29 | +@RestController | ||
30 | +@RequestMapping("/monitor/logininfor") | ||
31 | +public class SysLogininforController extends BaseController { | ||
32 | + | ||
33 | + private final ISysLogininforService logininforService; | ||
34 | + | ||
35 | + /** | ||
36 | + * 获取系统访问记录列表 | ||
37 | + */ | ||
38 | + @SaCheckPermission("monitor:logininfor:list") | ||
39 | + @GetMapping("/list") | ||
40 | + public TableDataInfo<SysLogininfor> list(SysLogininfor logininfor, PageQuery pageQuery) { | ||
41 | + return logininforService.selectPageLogininforList(logininfor, pageQuery); | ||
42 | + } | ||
43 | + | ||
44 | + /** | ||
45 | + * 导出系统访问记录列表 | ||
46 | + */ | ||
47 | + @Log(title = "登录日志", businessType = BusinessType.EXPORT) | ||
48 | + @SaCheckPermission("monitor:logininfor:export") | ||
49 | + @PostMapping("/export") | ||
50 | + public void export(SysLogininfor logininfor, HttpServletResponse response) { | ||
51 | + List<SysLogininfor> list = logininforService.selectLogininforList(logininfor); | ||
52 | + ExcelUtil.exportExcel(list, "登录日志", SysLogininfor.class, response); | ||
53 | + } | ||
54 | + | ||
55 | + /** | ||
56 | + * 批量删除登录日志 | ||
57 | + * @param infoIds 日志ids | ||
58 | + */ | ||
59 | + @SaCheckPermission("monitor:logininfor:remove") | ||
60 | + @Log(title = "登录日志", businessType = BusinessType.DELETE) | ||
61 | + @DeleteMapping("/{infoIds}") | ||
62 | + public R<Void> remove(@PathVariable Long[] infoIds) { | ||
63 | + return toAjax(logininforService.deleteLogininforByIds(infoIds)); | ||
64 | + } | ||
65 | + | ||
66 | + /** | ||
67 | + * 清理系统访问记录 | ||
68 | + */ | ||
69 | + @SaCheckPermission("monitor:logininfor:remove") | ||
70 | + @Log(title = "登录日志", businessType = BusinessType.CLEAN) | ||
71 | + @DeleteMapping("/clean") | ||
72 | + public R<Void> clean() { | ||
73 | + logininforService.cleanLogininfor(); | ||
74 | + return R.ok(); | ||
75 | + } | ||
76 | + | ||
77 | + @SaCheckPermission("monitor:logininfor:unlock") | ||
78 | + @Log(title = "账户解锁", businessType = BusinessType.OTHER) | ||
79 | + @GetMapping("/unlock/{userName}") | ||
80 | + public R<Void> unlock(@PathVariable("userName") String userName) { | ||
81 | + String loginName = CacheConstants.PWD_ERR_CNT_KEY + userName; | ||
82 | + if (RedisUtils.hasKey(loginName)) { | ||
83 | + RedisUtils.deleteObject(loginName); | ||
84 | + } | ||
85 | + return R.ok(); | ||
86 | + } | ||
87 | + | ||
88 | +} |
1 | +package com.ruoyi.web.controller.monitor; | ||
2 | + | ||
3 | +import cn.dev33.satoken.annotation.SaCheckPermission; | ||
4 | +import com.ruoyi.common.annotation.Log; | ||
5 | +import com.ruoyi.common.core.controller.BaseController; | ||
6 | +import com.ruoyi.common.core.domain.PageQuery; | ||
7 | +import com.ruoyi.common.core.domain.R; | ||
8 | +import com.ruoyi.common.core.page.TableDataInfo; | ||
9 | +import com.ruoyi.common.enums.BusinessType; | ||
10 | +import com.ruoyi.common.utils.poi.ExcelUtil; | ||
11 | +import com.ruoyi.system.domain.SysOperLog; | ||
12 | +import com.ruoyi.system.service.ISysOperLogService; | ||
13 | +import lombok.RequiredArgsConstructor; | ||
14 | +import org.springframework.validation.annotation.Validated; | ||
15 | +import org.springframework.web.bind.annotation.*; | ||
16 | + | ||
17 | +import javax.servlet.http.HttpServletResponse; | ||
18 | +import java.util.List; | ||
19 | + | ||
20 | +/** | ||
21 | + * 操作日志记录 | ||
22 | + * | ||
23 | + * @author Lion Li | ||
24 | + */ | ||
25 | +@Validated | ||
26 | +@RequiredArgsConstructor | ||
27 | +@RestController | ||
28 | +@RequestMapping("/monitor/operlog") | ||
29 | +public class SysOperlogController extends BaseController { | ||
30 | + | ||
31 | + private final ISysOperLogService operLogService; | ||
32 | + | ||
33 | + /** | ||
34 | + * 获取操作日志记录列表 | ||
35 | + */ | ||
36 | + @SaCheckPermission("monitor:operlog:list") | ||
37 | + @GetMapping("/list") | ||
38 | + public TableDataInfo<SysOperLog> list(SysOperLog operLog, PageQuery pageQuery) { | ||
39 | + return operLogService.selectPageOperLogList(operLog, pageQuery); | ||
40 | + } | ||
41 | + | ||
42 | + /** | ||
43 | + * 导出操作日志记录列表 | ||
44 | + */ | ||
45 | + @Log(title = "操作日志", businessType = BusinessType.EXPORT) | ||
46 | + @SaCheckPermission("monitor:operlog:export") | ||
47 | + @PostMapping("/export") | ||
48 | + public void export(SysOperLog operLog, HttpServletResponse response) { | ||
49 | + List<SysOperLog> list = operLogService.selectOperLogList(operLog); | ||
50 | + ExcelUtil.exportExcel(list, "操作日志", SysOperLog.class, response); | ||
51 | + } | ||
52 | + | ||
53 | + /** | ||
54 | + * 批量删除操作日志记录 | ||
55 | + * @param operIds 日志ids | ||
56 | + */ | ||
57 | + @Log(title = "操作日志", businessType = BusinessType.DELETE) | ||
58 | + @SaCheckPermission("monitor:operlog:remove") | ||
59 | + @DeleteMapping("/{operIds}") | ||
60 | + public R<Void> remove(@PathVariable Long[] operIds) { | ||
61 | + return toAjax(operLogService.deleteOperLogByIds(operIds)); | ||
62 | + } | ||
63 | + | ||
64 | + /** | ||
65 | + * 清理操作日志记录 | ||
66 | + */ | ||
67 | + @Log(title = "操作日志", businessType = BusinessType.CLEAN) | ||
68 | + @SaCheckPermission("monitor:operlog:remove") | ||
69 | + @DeleteMapping("/clean") | ||
70 | + public R<Void> clean() { | ||
71 | + operLogService.cleanOperLog(); | ||
72 | + return R.ok(); | ||
73 | + } | ||
74 | +} |
1 | +package com.ruoyi.web.controller.monitor; | ||
2 | + | ||
3 | +import cn.dev33.satoken.annotation.SaCheckPermission; | ||
4 | +import cn.dev33.satoken.exception.NotLoginException; | ||
5 | +import cn.dev33.satoken.stp.StpUtil; | ||
6 | +import cn.hutool.core.bean.BeanUtil; | ||
7 | +import com.ruoyi.common.annotation.Log; | ||
8 | +import com.ruoyi.common.constant.CacheConstants; | ||
9 | +import com.ruoyi.common.core.controller.BaseController; | ||
10 | +import com.ruoyi.common.core.domain.R; | ||
11 | +import com.ruoyi.common.core.domain.dto.UserOnlineDTO; | ||
12 | +import com.ruoyi.common.core.page.TableDataInfo; | ||
13 | +import com.ruoyi.common.enums.BusinessType; | ||
14 | +import com.ruoyi.common.utils.StreamUtils; | ||
15 | +import com.ruoyi.common.utils.StringUtils; | ||
16 | +import com.ruoyi.common.utils.redis.RedisUtils; | ||
17 | +import com.ruoyi.system.domain.SysUserOnline; | ||
18 | +import lombok.RequiredArgsConstructor; | ||
19 | +import org.springframework.web.bind.annotation.*; | ||
20 | + | ||
21 | +import java.util.ArrayList; | ||
22 | +import java.util.Collections; | ||
23 | +import java.util.List; | ||
24 | + | ||
25 | +/** | ||
26 | + * 在线用户监控 | ||
27 | + * | ||
28 | + * @author Lion Li | ||
29 | + */ | ||
30 | +@RequiredArgsConstructor | ||
31 | +@RestController | ||
32 | +@RequestMapping("/monitor/online") | ||
33 | +public class SysUserOnlineController extends BaseController { | ||
34 | + | ||
35 | + /** | ||
36 | + * 获取在线用户监控列表 | ||
37 | + * | ||
38 | + * @param ipaddr IP地址 | ||
39 | + * @param userName 用户名 | ||
40 | + */ | ||
41 | + @SaCheckPermission("monitor:online:list") | ||
42 | + @GetMapping("/list") | ||
43 | + public TableDataInfo<SysUserOnline> list(String ipaddr, String userName) { | ||
44 | + // 获取所有未过期的 token | ||
45 | + List<String> keys = StpUtil.searchTokenValue("", 0, -1, false); | ||
46 | + List<UserOnlineDTO> userOnlineDTOList = new ArrayList<>(); | ||
47 | + for (String key : keys) { | ||
48 | + String token = StringUtils.substringAfterLast(key, ":"); | ||
49 | + // 如果已经过期则跳过 | ||
50 | + if (StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) < -1) { | ||
51 | + continue; | ||
52 | + } | ||
53 | + userOnlineDTOList.add(RedisUtils.getCacheObject(CacheConstants.ONLINE_TOKEN_KEY + token)); | ||
54 | + } | ||
55 | + if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) { | ||
56 | + userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline -> | ||
57 | + StringUtils.equals(ipaddr, userOnline.getIpaddr()) && | ||
58 | + StringUtils.equals(userName, userOnline.getUserName()) | ||
59 | + ); | ||
60 | + } else if (StringUtils.isNotEmpty(ipaddr)) { | ||
61 | + userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline -> | ||
62 | + StringUtils.equals(ipaddr, userOnline.getIpaddr()) | ||
63 | + ); | ||
64 | + } else if (StringUtils.isNotEmpty(userName)) { | ||
65 | + userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline -> | ||
66 | + StringUtils.equals(userName, userOnline.getUserName()) | ||
67 | + ); | ||
68 | + } | ||
69 | + Collections.reverse(userOnlineDTOList); | ||
70 | + userOnlineDTOList.removeAll(Collections.singleton(null)); | ||
71 | + List<SysUserOnline> userOnlineList = BeanUtil.copyToList(userOnlineDTOList, SysUserOnline.class); | ||
72 | + return TableDataInfo.build(userOnlineList); | ||
73 | + } | ||
74 | + | ||
75 | + /** | ||
76 | + * 强退用户 | ||
77 | + * | ||
78 | + * @param tokenId token值 | ||
79 | + */ | ||
80 | + @SaCheckPermission("monitor:online:forceLogout") | ||
81 | + @Log(title = "在线用户", businessType = BusinessType.FORCE) | ||
82 | + @DeleteMapping("/{tokenId}") | ||
83 | + public R<Void> forceLogout(@PathVariable String tokenId) { | ||
84 | + try { | ||
85 | + StpUtil.kickoutByTokenValue(tokenId); | ||
86 | + } catch (NotLoginException ignored) { | ||
87 | + } | ||
88 | + return R.ok(); | ||
89 | + } | ||
90 | +} |
1 | +package com.ruoyi.web.controller.system; | ||
2 | + | ||
3 | +import cn.dev33.satoken.annotation.SaCheckPermission; | ||
4 | +import com.ruoyi.common.annotation.Log; | ||
5 | +import com.ruoyi.common.constant.UserConstants; | ||
6 | +import com.ruoyi.common.core.controller.BaseController; | ||
7 | +import com.ruoyi.common.core.domain.PageQuery; | ||
8 | +import com.ruoyi.common.core.domain.R; | ||
9 | +import com.ruoyi.common.core.page.TableDataInfo; | ||
10 | +import com.ruoyi.common.enums.BusinessType; | ||
11 | +import com.ruoyi.common.utils.poi.ExcelUtil; | ||
12 | +import com.ruoyi.system.domain.SysConfig; | ||
13 | +import com.ruoyi.system.service.ISysConfigService; | ||
14 | +import lombok.RequiredArgsConstructor; | ||
15 | +import org.springframework.validation.annotation.Validated; | ||
16 | +import org.springframework.web.bind.annotation.*; | ||
17 | + | ||
18 | +import javax.servlet.http.HttpServletResponse; | ||
19 | +import java.util.List; | ||
20 | + | ||
21 | +/** | ||
22 | + * 参数配置 信息操作处理 | ||
23 | + * | ||
24 | + * @author Lion Li | ||
25 | + */ | ||
26 | +@Validated | ||
27 | +@RequiredArgsConstructor | ||
28 | +@RestController | ||
29 | +@RequestMapping("/system/config") | ||
30 | +public class SysConfigController extends BaseController { | ||
31 | + | ||
32 | + private final ISysConfigService configService; | ||
33 | + | ||
34 | + /** | ||
35 | + * 获取参数配置列表 | ||
36 | + */ | ||
37 | + @SaCheckPermission("system:config:list") | ||
38 | + @GetMapping("/list") | ||
39 | + public TableDataInfo<SysConfig> list(SysConfig config, PageQuery pageQuery) { | ||
40 | + return configService.selectPageConfigList(config, pageQuery); | ||
41 | + } | ||
42 | + | ||
43 | + /** | ||
44 | + * 导出参数配置列表 | ||
45 | + */ | ||
46 | + @Log(title = "参数管理", businessType = BusinessType.EXPORT) | ||
47 | + @SaCheckPermission("system:config:export") | ||
48 | + @PostMapping("/export") | ||
49 | + public void export(SysConfig config, HttpServletResponse response) { | ||
50 | + List<SysConfig> list = configService.selectConfigList(config); | ||
51 | + ExcelUtil.exportExcel(list, "参数数据", SysConfig.class, response); | ||
52 | + } | ||
53 | + | ||
54 | + /** | ||
55 | + * 根据参数编号获取详细信息 | ||
56 | + * | ||
57 | + * @param configId 参数ID | ||
58 | + */ | ||
59 | + @SaCheckPermission("system:config:query") | ||
60 | + @GetMapping(value = "/{configId}") | ||
61 | + public R<SysConfig> getInfo(@PathVariable Long configId) { | ||
62 | + return R.ok(configService.selectConfigById(configId)); | ||
63 | + } | ||
64 | + | ||
65 | + /** | ||
66 | + * 根据参数键名查询参数值 | ||
67 | + * | ||
68 | + * @param configKey 参数Key | ||
69 | + */ | ||
70 | + @GetMapping(value = "/configKey/{configKey}") | ||
71 | + public R<Void> getConfigKey(@PathVariable String configKey) { | ||
72 | + return R.ok(configService.selectConfigByKey(configKey)); | ||
73 | + } | ||
74 | + | ||
75 | + /** | ||
76 | + * 新增参数配置 | ||
77 | + */ | ||
78 | + @SaCheckPermission("system:config:add") | ||
79 | + @Log(title = "参数管理", businessType = BusinessType.INSERT) | ||
80 | + @PostMapping | ||
81 | + public R<Void> add(@Validated @RequestBody SysConfig config) { | ||
82 | + if (!configService.checkConfigKeyUnique(config)) { | ||
83 | + return R.fail("新增参数'" + config.getConfigName() + "'失败,参数键名已存在"); | ||
84 | + } | ||
85 | + configService.insertConfig(config); | ||
86 | + return R.ok(); | ||
87 | + } | ||
88 | + | ||
89 | + /** | ||
90 | + * 修改参数配置 | ||
91 | + */ | ||
92 | + @SaCheckPermission("system:config:edit") | ||
93 | + @Log(title = "参数管理", businessType = BusinessType.UPDATE) | ||
94 | + @PutMapping | ||
95 | + public R<Void> edit(@Validated @RequestBody SysConfig config) { | ||
96 | + if (!configService.checkConfigKeyUnique(config)) { | ||
97 | + return R.fail("修改参数'" + config.getConfigName() + "'失败,参数键名已存在"); | ||
98 | + } | ||
99 | + configService.updateConfig(config); | ||
100 | + return R.ok(); | ||
101 | + } | ||
102 | + | ||
103 | + /** | ||
104 | + * 根据参数键名修改参数配置 | ||
105 | + */ | ||
106 | + @SaCheckPermission("system:config:edit") | ||
107 | + @Log(title = "参数管理", businessType = BusinessType.UPDATE) | ||
108 | + @PutMapping("/updateByKey") | ||
109 | + public R<Void> updateByKey(@RequestBody SysConfig config) { | ||
110 | + configService.updateConfig(config); | ||
111 | + return R.ok(); | ||
112 | + } | ||
113 | + | ||
114 | + /** | ||
115 | + * 删除参数配置 | ||
116 | + * | ||
117 | + * @param configIds 参数ID串 | ||
118 | + */ | ||
119 | + @SaCheckPermission("system:config:remove") | ||
120 | + @Log(title = "参数管理", businessType = BusinessType.DELETE) | ||
121 | + @DeleteMapping("/{configIds}") | ||
122 | + public R<Void> remove(@PathVariable Long[] configIds) { | ||
123 | + configService.deleteConfigByIds(configIds); | ||
124 | + return R.ok(); | ||
125 | + } | ||
126 | + | ||
127 | + /** | ||
128 | + * 刷新参数缓存 | ||
129 | + */ | ||
130 | + @SaCheckPermission("system:config:remove") | ||
131 | + @Log(title = "参数管理", businessType = BusinessType.CLEAN) | ||
132 | + @DeleteMapping("/refreshCache") | ||
133 | + public R<Void> refreshCache() { | ||
134 | + configService.resetConfigCache(); | ||
135 | + return R.ok(); | ||
136 | + } | ||
137 | +} |
1 | +package com.ruoyi.web.controller.system; | ||
2 | + | ||
3 | +import cn.dev33.satoken.annotation.SaCheckPermission; | ||
4 | +import cn.hutool.core.convert.Convert; | ||
5 | +import com.ruoyi.common.annotation.Log; | ||
6 | +import com.ruoyi.common.constant.UserConstants; | ||
7 | +import com.ruoyi.common.core.controller.BaseController; | ||
8 | +import com.ruoyi.common.core.domain.R; | ||
9 | +import com.ruoyi.common.core.domain.entity.SysDept; | ||
10 | +import com.ruoyi.common.enums.BusinessType; | ||
11 | +import com.ruoyi.common.utils.StringUtils; | ||
12 | +import com.ruoyi.system.service.ISysDeptService; | ||
13 | +import lombok.RequiredArgsConstructor; | ||
14 | +import org.springframework.validation.annotation.Validated; | ||
15 | +import org.springframework.web.bind.annotation.*; | ||
16 | + | ||
17 | +import java.util.List; | ||
18 | + | ||
19 | +/** | ||
20 | + * 部门信息 | ||
21 | + * | ||
22 | + * @author Lion Li | ||
23 | + */ | ||
24 | +@Validated | ||
25 | +@RequiredArgsConstructor | ||
26 | +@RestController | ||
27 | +@RequestMapping("/system/dept") | ||
28 | +public class SysDeptController extends BaseController { | ||
29 | + | ||
30 | + private final ISysDeptService deptService; | ||
31 | + | ||
32 | + /** | ||
33 | + * 获取部门列表 | ||
34 | + */ | ||
35 | + @SaCheckPermission("system:dept:list") | ||
36 | + @GetMapping("/list") | ||
37 | + public R<List<SysDept>> list(SysDept dept) { | ||
38 | + List<SysDept> depts = deptService.selectDeptList(dept); | ||
39 | + return R.ok(depts); | ||
40 | + } | ||
41 | + | ||
42 | + /** | ||
43 | + * 查询部门列表(排除节点) | ||
44 | + * | ||
45 | + * @param deptId 部门ID | ||
46 | + */ | ||
47 | + @SaCheckPermission("system:dept:list") | ||
48 | + @GetMapping("/list/exclude/{deptId}") | ||
49 | + public R<List<SysDept>> excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) { | ||
50 | + List<SysDept> depts = deptService.selectDeptList(new SysDept()); | ||
51 | + depts.removeIf(d -> d.getDeptId().equals(deptId) | ||
52 | + || StringUtils.splitList(d.getAncestors()).contains(Convert.toStr(deptId))); | ||
53 | + return R.ok(depts); | ||
54 | + } | ||
55 | + | ||
56 | + /** | ||
57 | + * 根据部门编号获取详细信息 | ||
58 | + * | ||
59 | + * @param deptId 部门ID | ||
60 | + */ | ||
61 | + @SaCheckPermission("system:dept:query") | ||
62 | + @GetMapping(value = "/{deptId}") | ||
63 | + public R<SysDept> getInfo(@PathVariable Long deptId) { | ||
64 | + deptService.checkDeptDataScope(deptId); | ||
65 | + return R.ok(deptService.selectDeptById(deptId)); | ||
66 | + } | ||
67 | + | ||
68 | + /** | ||
69 | + * 新增部门 | ||
70 | + */ | ||
71 | + @SaCheckPermission("system:dept:add") | ||
72 | + @Log(title = "部门管理", businessType = BusinessType.INSERT) | ||
73 | + @PostMapping | ||
74 | + public R<Void> add(@Validated @RequestBody SysDept dept) { | ||
75 | + if (!deptService.checkDeptNameUnique(dept)) { | ||
76 | + return R.fail("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在"); | ||
77 | + } | ||
78 | + return toAjax(deptService.insertDept(dept)); | ||
79 | + } | ||
80 | + | ||
81 | + /** | ||
82 | + * 修改部门 | ||
83 | + */ | ||
84 | + @SaCheckPermission("system:dept:edit") | ||
85 | + @Log(title = "部门管理", businessType = BusinessType.UPDATE) | ||
86 | + @PutMapping | ||
87 | + public R<Void> edit(@Validated @RequestBody SysDept dept) { | ||
88 | + Long deptId = dept.getDeptId(); | ||
89 | + deptService.checkDeptDataScope(deptId); | ||
90 | + if (!deptService.checkDeptNameUnique(dept)) { | ||
91 | + return R.fail("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在"); | ||
92 | + } else if (dept.getParentId().equals(deptId)) { | ||
93 | + return R.fail("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己"); | ||
94 | + } else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus())) { | ||
95 | + if (deptService.selectNormalChildrenDeptById(deptId) > 0) { | ||
96 | + return R.fail("该部门包含未停用的子部门!"); | ||
97 | + } else if (deptService.checkDeptExistUser(deptId)) { | ||
98 | + return R.fail("该部门下存在已分配用户,不能禁用!"); | ||
99 | + } | ||
100 | + } | ||
101 | + return toAjax(deptService.updateDept(dept)); | ||
102 | + } | ||
103 | + | ||
104 | + /** | ||
105 | + * 删除部门 | ||
106 | + * | ||
107 | + * @param deptId 部门ID | ||
108 | + */ | ||
109 | + @SaCheckPermission("system:dept:remove") | ||
110 | + @Log(title = "部门管理", businessType = BusinessType.DELETE) | ||
111 | + @DeleteMapping("/{deptId}") | ||
112 | + public R<Void> remove(@PathVariable Long deptId) { | ||
113 | + if (deptService.hasChildByDeptId(deptId)) { | ||
114 | + return R.warn("存在下级部门,不允许删除"); | ||
115 | + } | ||
116 | + if (deptService.checkDeptExistUser(deptId)) { | ||
117 | + return R.warn("部门存在用户,不允许删除"); | ||
118 | + } | ||
119 | + deptService.checkDeptDataScope(deptId); | ||
120 | + return toAjax(deptService.deleteDeptById(deptId)); | ||
121 | + } | ||
122 | +} |
1 | +package com.ruoyi.web.controller.system; | ||
2 | + | ||
3 | +import cn.dev33.satoken.annotation.SaCheckPermission; | ||
4 | +import cn.hutool.core.util.ObjectUtil; | ||
5 | +import com.ruoyi.common.annotation.Log; | ||
6 | +import com.ruoyi.common.core.controller.BaseController; | ||
7 | +import com.ruoyi.common.core.domain.PageQuery; | ||
8 | +import com.ruoyi.common.core.domain.R; | ||
9 | +import com.ruoyi.common.core.domain.entity.SysDictData; | ||
10 | +import com.ruoyi.common.core.page.TableDataInfo; | ||
11 | +import com.ruoyi.common.enums.BusinessType; | ||
12 | +import com.ruoyi.common.utils.poi.ExcelUtil; | ||
13 | +import com.ruoyi.system.service.ISysDictDataService; | ||
14 | +import com.ruoyi.system.service.ISysDictTypeService; | ||
15 | +import lombok.RequiredArgsConstructor; | ||
16 | +import org.springframework.validation.annotation.Validated; | ||
17 | +import org.springframework.web.bind.annotation.*; | ||
18 | + | ||
19 | +import javax.servlet.http.HttpServletResponse; | ||
20 | +import java.util.ArrayList; | ||
21 | +import java.util.List; | ||
22 | + | ||
23 | +/** | ||
24 | + * 数据字典信息 | ||
25 | + * | ||
26 | + * @author Lion Li | ||
27 | + */ | ||
28 | +@Validated | ||
29 | +@RequiredArgsConstructor | ||
30 | +@RestController | ||
31 | +@RequestMapping("/system/dict/data") | ||
32 | +public class SysDictDataController extends BaseController { | ||
33 | + | ||
34 | + private final ISysDictDataService dictDataService; | ||
35 | + private final ISysDictTypeService dictTypeService; | ||
36 | + | ||
37 | + /** | ||
38 | + * 查询字典数据列表 | ||
39 | + */ | ||
40 | + @SaCheckPermission("system:dict:list") | ||
41 | + @GetMapping("/list") | ||
42 | + public TableDataInfo<SysDictData> list(SysDictData dictData, PageQuery pageQuery) { | ||
43 | + return dictDataService.selectPageDictDataList(dictData, pageQuery); | ||
44 | + } | ||
45 | + | ||
46 | + /** | ||
47 | + * 导出字典数据列表 | ||
48 | + */ | ||
49 | + @Log(title = "字典数据", businessType = BusinessType.EXPORT) | ||
50 | + @SaCheckPermission("system:dict:export") | ||
51 | + @PostMapping("/export") | ||
52 | + public void export(SysDictData dictData, HttpServletResponse response) { | ||
53 | + List<SysDictData> list = dictDataService.selectDictDataList(dictData); | ||
54 | + ExcelUtil.exportExcel(list, "字典数据", SysDictData.class, response); | ||
55 | + } | ||
56 | + | ||
57 | + /** | ||
58 | + * 查询字典数据详细 | ||
59 | + * | ||
60 | + * @param dictCode 字典code | ||
61 | + */ | ||
62 | + @SaCheckPermission("system:dict:query") | ||
63 | + @GetMapping(value = "/{dictCode}") | ||
64 | + public R<SysDictData> getInfo(@PathVariable Long dictCode) { | ||
65 | + return R.ok(dictDataService.selectDictDataById(dictCode)); | ||
66 | + } | ||
67 | + | ||
68 | + /** | ||
69 | + * 根据字典类型查询字典数据信息 | ||
70 | + * | ||
71 | + * @param dictType 字典类型 | ||
72 | + */ | ||
73 | + @GetMapping(value = "/type/{dictType}") | ||
74 | + public R<List<SysDictData>> dictType(@PathVariable String dictType) { | ||
75 | + List<SysDictData> data = dictTypeService.selectDictDataByType(dictType); | ||
76 | + if (ObjectUtil.isNull(data)) { | ||
77 | + data = new ArrayList<>(); | ||
78 | + } | ||
79 | + return R.ok(data); | ||
80 | + } | ||
81 | + | ||
82 | + /** | ||
83 | + * 新增字典类型 | ||
84 | + */ | ||
85 | + @SaCheckPermission("system:dict:add") | ||
86 | + @Log(title = "字典数据", businessType = BusinessType.INSERT) | ||
87 | + @PostMapping | ||
88 | + public R<Void> add(@Validated @RequestBody SysDictData dict) { | ||
89 | + dictDataService.insertDictData(dict); | ||
90 | + return R.ok(); | ||
91 | + } | ||
92 | + | ||
93 | + /** | ||
94 | + * 修改保存字典类型 | ||
95 | + */ | ||
96 | + @SaCheckPermission("system:dict:edit") | ||
97 | + @Log(title = "字典数据", businessType = BusinessType.UPDATE) | ||
98 | + @PutMapping | ||
99 | + public R<Void> edit(@Validated @RequestBody SysDictData dict) { | ||
100 | + dictDataService.updateDictData(dict); | ||
101 | + return R.ok(); | ||
102 | + } | ||
103 | + | ||
104 | + /** | ||
105 | + * 删除字典类型 | ||
106 | + * | ||
107 | + * @param dictCodes 字典code串 | ||
108 | + */ | ||
109 | + @SaCheckPermission("system:dict:remove") | ||
110 | + @Log(title = "字典类型", businessType = BusinessType.DELETE) | ||
111 | + @DeleteMapping("/{dictCodes}") | ||
112 | + public R<Void> remove(@PathVariable Long[] dictCodes) { | ||
113 | + dictDataService.deleteDictDataByIds(dictCodes); | ||
114 | + return R.ok(); | ||
115 | + } | ||
116 | +} |
1 | +package com.ruoyi.web.controller.system; | ||
2 | + | ||
3 | +import cn.dev33.satoken.annotation.SaCheckPermission; | ||
4 | +import com.ruoyi.common.annotation.Log; | ||
5 | +import com.ruoyi.common.constant.UserConstants; | ||
6 | +import com.ruoyi.common.core.controller.BaseController; | ||
7 | +import com.ruoyi.common.core.domain.PageQuery; | ||
8 | +import com.ruoyi.common.core.domain.R; | ||
9 | +import com.ruoyi.common.core.domain.entity.SysDictType; | ||
10 | +import com.ruoyi.common.core.page.TableDataInfo; | ||
11 | +import com.ruoyi.common.enums.BusinessType; | ||
12 | +import com.ruoyi.common.utils.poi.ExcelUtil; | ||
13 | +import com.ruoyi.system.service.ISysDictTypeService; | ||
14 | +import lombok.RequiredArgsConstructor; | ||
15 | +import org.springframework.validation.annotation.Validated; | ||
16 | +import org.springframework.web.bind.annotation.*; | ||
17 | + | ||
18 | +import javax.servlet.http.HttpServletResponse; | ||
19 | +import java.util.List; | ||
20 | + | ||
21 | +/** | ||
22 | + * 数据字典信息 | ||
23 | + * | ||
24 | + * @author Lion Li | ||
25 | + */ | ||
26 | +@Validated | ||
27 | +@RequiredArgsConstructor | ||
28 | +@RestController | ||
29 | +@RequestMapping("/system/dict/type") | ||
30 | +public class SysDictTypeController extends BaseController { | ||
31 | + | ||
32 | + private final ISysDictTypeService dictTypeService; | ||
33 | + | ||
34 | + /** | ||
35 | + * 查询字典类型列表 | ||
36 | + */ | ||
37 | + @SaCheckPermission("system:dict:list") | ||
38 | + @GetMapping("/list") | ||
39 | + public TableDataInfo<SysDictType> list(SysDictType dictType, PageQuery pageQuery) { | ||
40 | + return dictTypeService.selectPageDictTypeList(dictType, pageQuery); | ||
41 | + } | ||
42 | + | ||
43 | + /** | ||
44 | + * 导出字典类型列表 | ||
45 | + */ | ||
46 | + @Log(title = "字典类型", businessType = BusinessType.EXPORT) | ||
47 | + @SaCheckPermission("system:dict:export") | ||
48 | + @PostMapping("/export") | ||
49 | + public void export(SysDictType dictType, HttpServletResponse response) { | ||
50 | + List<SysDictType> list = dictTypeService.selectDictTypeList(dictType); | ||
51 | + ExcelUtil.exportExcel(list, "字典类型", SysDictType.class, response); | ||
52 | + } | ||
53 | + | ||
54 | + /** | ||
55 | + * 查询字典类型详细 | ||
56 | + * | ||
57 | + * @param dictId 字典ID | ||
58 | + */ | ||
59 | + @SaCheckPermission("system:dict:query") | ||
60 | + @GetMapping(value = "/{dictId}") | ||
61 | + public R<SysDictType> getInfo(@PathVariable Long dictId) { | ||
62 | + return R.ok(dictTypeService.selectDictTypeById(dictId)); | ||
63 | + } | ||
64 | + | ||
65 | + /** | ||
66 | + * 新增字典类型 | ||
67 | + */ | ||
68 | + @SaCheckPermission("system:dict:add") | ||
69 | + @Log(title = "字典类型", businessType = BusinessType.INSERT) | ||
70 | + @PostMapping | ||
71 | + public R<Void> add(@Validated @RequestBody SysDictType dict) { | ||
72 | + if (!dictTypeService.checkDictTypeUnique(dict)) { | ||
73 | + return R.fail("新增字典'" + dict.getDictName() + "'失败,字典类型已存在"); | ||
74 | + } | ||
75 | + dictTypeService.insertDictType(dict); | ||
76 | + return R.ok(); | ||
77 | + } | ||
78 | + | ||
79 | + /** | ||
80 | + * 修改字典类型 | ||
81 | + */ | ||
82 | + @SaCheckPermission("system:dict:edit") | ||
83 | + @Log(title = "字典类型", businessType = BusinessType.UPDATE) | ||
84 | + @PutMapping | ||
85 | + public R<Void> edit(@Validated @RequestBody SysDictType dict) { | ||
86 | + if (!dictTypeService.checkDictTypeUnique(dict)) { | ||
87 | + return R.fail("修改字典'" + dict.getDictName() + "'失败,字典类型已存在"); | ||
88 | + } | ||
89 | + dictTypeService.updateDictType(dict); | ||
90 | + return R.ok(); | ||
91 | + } | ||
92 | + | ||
93 | + /** | ||
94 | + * 删除字典类型 | ||
95 | + * | ||
96 | + * @param dictIds 字典ID串 | ||
97 | + */ | ||
98 | + @SaCheckPermission("system:dict:remove") | ||
99 | + @Log(title = "字典类型", businessType = BusinessType.DELETE) | ||
100 | + @DeleteMapping("/{dictIds}") | ||
101 | + public R<Void> remove(@PathVariable Long[] dictIds) { | ||
102 | + dictTypeService.deleteDictTypeByIds(dictIds); | ||
103 | + return R.ok(); | ||
104 | + } | ||
105 | + | ||
106 | + /** | ||
107 | + * 刷新字典缓存 | ||
108 | + */ | ||
109 | + @SaCheckPermission("system:dict:remove") | ||
110 | + @Log(title = "字典类型", businessType = BusinessType.CLEAN) | ||
111 | + @DeleteMapping("/refreshCache") | ||
112 | + public R<Void> refreshCache() { | ||
113 | + dictTypeService.resetDictCache(); | ||
114 | + return R.ok(); | ||
115 | + } | ||
116 | + | ||
117 | + /** | ||
118 | + * 获取字典选择框列表 | ||
119 | + */ | ||
120 | + @GetMapping("/optionselect") | ||
121 | + public R<List<SysDictType>> optionselect() { | ||
122 | + List<SysDictType> dictTypes = dictTypeService.selectDictTypeAll(); | ||
123 | + return R.ok(dictTypes); | ||
124 | + } | ||
125 | +} |
1 | +package com.ruoyi.web.controller.system; | ||
2 | + | ||
3 | +import cn.dev33.satoken.annotation.SaIgnore; | ||
4 | +import com.ruoyi.common.config.RuoYiConfig; | ||
5 | +import com.ruoyi.common.utils.StringUtils; | ||
6 | +import lombok.RequiredArgsConstructor; | ||
7 | +import org.springframework.web.bind.annotation.GetMapping; | ||
8 | +import org.springframework.web.bind.annotation.RestController; | ||
9 | + | ||
10 | +/** | ||
11 | + * 首页 | ||
12 | + * | ||
13 | + * @author Lion Li | ||
14 | + */ | ||
15 | +@RequiredArgsConstructor | ||
16 | +@RestController | ||
17 | +public class SysIndexController { | ||
18 | + | ||
19 | + /** | ||
20 | + * 系统基础配置 | ||
21 | + */ | ||
22 | + private final RuoYiConfig ruoyiConfig; | ||
23 | + | ||
24 | + /** | ||
25 | + * 访问首页,提示语 | ||
26 | + */ | ||
27 | + @SaIgnore | ||
28 | + @GetMapping("/") | ||
29 | + public String index() { | ||
30 | + return StringUtils.format("欢迎使用{}后台管理框架,当前版本:v{},请通过前端地址访问。", ruoyiConfig.getName(), ruoyiConfig.getVersion()); | ||
31 | + } | ||
32 | +} |
1 | +package com.ruoyi.web.controller.system; | ||
2 | + | ||
3 | +import cn.dev33.satoken.annotation.SaIgnore; | ||
4 | +import com.ruoyi.common.constant.Constants; | ||
5 | +import com.ruoyi.common.core.domain.R; | ||
6 | +import com.ruoyi.common.core.domain.entity.SysMenu; | ||
7 | +import com.ruoyi.common.core.domain.entity.SysUser; | ||
8 | +import com.ruoyi.common.core.domain.model.EmailLoginBody; | ||
9 | +import com.ruoyi.common.core.domain.model.LoginBody; | ||
10 | +import com.ruoyi.common.core.domain.model.LoginUser; | ||
11 | +import com.ruoyi.common.core.domain.model.SmsLoginBody; | ||
12 | +import com.ruoyi.common.helper.LoginHelper; | ||
13 | +import com.ruoyi.system.domain.vo.RouterVo; | ||
14 | +import com.ruoyi.system.service.ISysMenuService; | ||
15 | +import com.ruoyi.system.service.ISysUserService; | ||
16 | +import com.ruoyi.system.service.SysLoginService; | ||
17 | +import lombok.RequiredArgsConstructor; | ||
18 | +import org.springframework.validation.annotation.Validated; | ||
19 | +import org.springframework.web.bind.annotation.GetMapping; | ||
20 | +import org.springframework.web.bind.annotation.PostMapping; | ||
21 | +import org.springframework.web.bind.annotation.RequestBody; | ||
22 | +import org.springframework.web.bind.annotation.RestController; | ||
23 | + | ||
24 | +import javax.validation.constraints.NotBlank; | ||
25 | +import java.util.HashMap; | ||
26 | +import java.util.List; | ||
27 | +import java.util.Map; | ||
28 | + | ||
29 | +/** | ||
30 | + * 登录验证 | ||
31 | + * | ||
32 | + * @author Lion Li | ||
33 | + */ | ||
34 | +@Validated | ||
35 | +@RequiredArgsConstructor | ||
36 | +@RestController | ||
37 | +public class SysLoginController { | ||
38 | + | ||
39 | + private final SysLoginService loginService; | ||
40 | + private final ISysMenuService menuService; | ||
41 | + private final ISysUserService userService; | ||
42 | + | ||
43 | + /** | ||
44 | + * 登录方法 | ||
45 | + * | ||
46 | + * @param loginBody 登录信息 | ||
47 | + * @return 结果 | ||
48 | + */ | ||
49 | + @SaIgnore | ||
50 | + @PostMapping("/login") | ||
51 | + public R<Map<String, Object>> login(@Validated @RequestBody LoginBody loginBody) { | ||
52 | + Map<String, Object> ajax = new HashMap<>(); | ||
53 | + // 生成令牌 | ||
54 | + String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), | ||
55 | + loginBody.getUuid()); | ||
56 | + ajax.put(Constants.TOKEN, token); | ||
57 | + return R.ok(ajax); | ||
58 | + } | ||
59 | + | ||
60 | + /** | ||
61 | + * 短信登录 | ||
62 | + * | ||
63 | + * @param smsLoginBody 登录信息 | ||
64 | + * @return 结果 | ||
65 | + */ | ||
66 | + @SaIgnore | ||
67 | + @PostMapping("/smsLogin") | ||
68 | + public R<Map<String, Object>> smsLogin(@Validated @RequestBody SmsLoginBody smsLoginBody) { | ||
69 | + Map<String, Object> ajax = new HashMap<>(); | ||
70 | + // 生成令牌 | ||
71 | + String token = loginService.smsLogin(smsLoginBody.getPhonenumber(), smsLoginBody.getSmsCode()); | ||
72 | + ajax.put(Constants.TOKEN, token); | ||
73 | + return R.ok(ajax); | ||
74 | + } | ||
75 | + | ||
76 | + /** | ||
77 | + * 邮件登录 | ||
78 | + * | ||
79 | + * @param body 登录信息 | ||
80 | + * @return 结果 | ||
81 | + */ | ||
82 | + @PostMapping("/emailLogin") | ||
83 | + public R<Map<String, Object>> emailLogin(@Validated @RequestBody EmailLoginBody body) { | ||
84 | + Map<String, Object> ajax = new HashMap<>(); | ||
85 | + // 生成令牌 | ||
86 | + String token = loginService.emailLogin(body.getEmail(), body.getEmailCode()); | ||
87 | + ajax.put(Constants.TOKEN, token); | ||
88 | + return R.ok(ajax); | ||
89 | + } | ||
90 | + | ||
91 | + /** | ||
92 | + * 小程序登录(示例) | ||
93 | + * | ||
94 | + * @param xcxCode 小程序code | ||
95 | + * @return 结果 | ||
96 | + */ | ||
97 | + @SaIgnore | ||
98 | + @PostMapping("/xcxLogin") | ||
99 | + public R<Map<String, Object>> xcxLogin(@NotBlank(message = "{xcx.code.not.blank}") String xcxCode) { | ||
100 | + Map<String, Object> ajax = new HashMap<>(); | ||
101 | + // 生成令牌 | ||
102 | + String token = loginService.xcxLogin(xcxCode); | ||
103 | + ajax.put(Constants.TOKEN, token); | ||
104 | + return R.ok(ajax); | ||
105 | + } | ||
106 | + | ||
107 | + /** | ||
108 | + * 退出登录 | ||
109 | + */ | ||
110 | + @SaIgnore | ||
111 | + @PostMapping("/logout") | ||
112 | + public R<Void> logout() { | ||
113 | + loginService.logout(); | ||
114 | + return R.ok("退出成功"); | ||
115 | + } | ||
116 | + | ||
117 | + /** | ||
118 | + * 获取用户信息 | ||
119 | + * | ||
120 | + * @return 用户信息 | ||
121 | + */ | ||
122 | + @GetMapping("getInfo") | ||
123 | + public R<Map<String, Object>> getInfo() { | ||
124 | + LoginUser loginUser = LoginHelper.getLoginUser(); | ||
125 | + SysUser user = userService.selectUserById(loginUser.getUserId()); | ||
126 | + Map<String, Object> ajax = new HashMap<>(); | ||
127 | + ajax.put("user", user); | ||
128 | + ajax.put("roles", loginUser.getRolePermission()); | ||
129 | + ajax.put("permissions", loginUser.getMenuPermission()); | ||
130 | + return R.ok(ajax); | ||
131 | + } | ||
132 | + | ||
133 | + /** | ||
134 | + * 获取路由信息 | ||
135 | + * | ||
136 | + * @return 路由信息 | ||
137 | + */ | ||
138 | + @GetMapping("getRouters") | ||
139 | + public R<List<RouterVo>> getRouters() { | ||
140 | + Long userId = LoginHelper.getUserId(); | ||
141 | + List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId); | ||
142 | + return R.ok(menuService.buildMenus(menus)); | ||
143 | + } | ||
144 | +} |
1 | +package com.ruoyi.web.controller.system; | ||
2 | + | ||
3 | +import cn.dev33.satoken.annotation.SaCheckPermission; | ||
4 | +import cn.hutool.core.lang.tree.Tree; | ||
5 | +import com.ruoyi.common.annotation.Log; | ||
6 | +import com.ruoyi.common.constant.UserConstants; | ||
7 | +import com.ruoyi.common.core.controller.BaseController; | ||
8 | +import com.ruoyi.common.core.domain.R; | ||
9 | +import com.ruoyi.common.core.domain.entity.SysMenu; | ||
10 | +import com.ruoyi.common.enums.BusinessType; | ||
11 | +import com.ruoyi.common.utils.StringUtils; | ||
12 | +import com.ruoyi.system.service.ISysMenuService; | ||
13 | +import lombok.RequiredArgsConstructor; | ||
14 | +import org.springframework.validation.annotation.Validated; | ||
15 | +import org.springframework.web.bind.annotation.*; | ||
16 | + | ||
17 | +import java.util.HashMap; | ||
18 | +import java.util.List; | ||
19 | +import java.util.Map; | ||
20 | + | ||
21 | +/** | ||
22 | + * 菜单信息 | ||
23 | + * | ||
24 | + * @author Lion Li | ||
25 | + */ | ||
26 | +@Validated | ||
27 | +@RequiredArgsConstructor | ||
28 | +@RestController | ||
29 | +@RequestMapping("/system/menu") | ||
30 | +public class SysMenuController extends BaseController { | ||
31 | + | ||
32 | + private final ISysMenuService menuService; | ||
33 | + | ||
34 | + /** | ||
35 | + * 获取菜单列表 | ||
36 | + */ | ||
37 | + @SaCheckPermission("system:menu:list") | ||
38 | + @GetMapping("/list") | ||
39 | + public R<List<SysMenu>> list(SysMenu menu) { | ||
40 | + List<SysMenu> menus = menuService.selectMenuList(menu, getUserId()); | ||
41 | + return R.ok(menus); | ||
42 | + } | ||
43 | + | ||
44 | + /** | ||
45 | + * 根据菜单编号获取详细信息 | ||
46 | + * | ||
47 | + * @param menuId 菜单ID | ||
48 | + */ | ||
49 | + @SaCheckPermission("system:menu:query") | ||
50 | + @GetMapping(value = "/{menuId}") | ||
51 | + public R<SysMenu> getInfo(@PathVariable Long menuId) { | ||
52 | + return R.ok(menuService.selectMenuById(menuId)); | ||
53 | + } | ||
54 | + | ||
55 | + /** | ||
56 | + * 获取菜单下拉树列表 | ||
57 | + */ | ||
58 | + @GetMapping("/treeselect") | ||
59 | + public R<List<Tree<Long>>> treeselect(SysMenu menu) { | ||
60 | + List<SysMenu> menus = menuService.selectMenuList(menu, getUserId()); | ||
61 | + return R.ok(menuService.buildMenuTreeSelect(menus)); | ||
62 | + } | ||
63 | + | ||
64 | + /** | ||
65 | + * 加载对应角色菜单列表树 | ||
66 | + * | ||
67 | + * @param roleId 角色ID | ||
68 | + */ | ||
69 | + @GetMapping(value = "/roleMenuTreeselect/{roleId}") | ||
70 | + public R<Map<String, Object>> roleMenuTreeselect(@PathVariable("roleId") Long roleId) { | ||
71 | + List<SysMenu> menus = menuService.selectMenuList(getUserId()); | ||
72 | + Map<String, Object> ajax = new HashMap<>(); | ||
73 | + ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId)); | ||
74 | + ajax.put("menus", menuService.buildMenuTreeSelect(menus)); | ||
75 | + return R.ok(ajax); | ||
76 | + } | ||
77 | + | ||
78 | + /** | ||
79 | + * 新增菜单 | ||
80 | + */ | ||
81 | + @SaCheckPermission("system:menu:add") | ||
82 | + @Log(title = "菜单管理", businessType = BusinessType.INSERT) | ||
83 | + @PostMapping | ||
84 | + public R<Void> add(@Validated @RequestBody SysMenu menu) { | ||
85 | + if (!menuService.checkMenuNameUnique(menu)) { | ||
86 | + return R.fail("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); | ||
87 | + } else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) { | ||
88 | + return R.fail("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); | ||
89 | + } | ||
90 | + return toAjax(menuService.insertMenu(menu)); | ||
91 | + } | ||
92 | + | ||
93 | + /** | ||
94 | + * 修改菜单 | ||
95 | + */ | ||
96 | + @SaCheckPermission("system:menu:edit") | ||
97 | + @Log(title = "菜单管理", businessType = BusinessType.UPDATE) | ||
98 | + @PutMapping | ||
99 | + public R<Void> edit(@Validated @RequestBody SysMenu menu) { | ||
100 | + if (!menuService.checkMenuNameUnique(menu)) { | ||
101 | + return R.fail("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); | ||
102 | + } else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) { | ||
103 | + return R.fail("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); | ||
104 | + } else if (menu.getMenuId().equals(menu.getParentId())) { | ||
105 | + return R.fail("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己"); | ||
106 | + } | ||
107 | + return toAjax(menuService.updateMenu(menu)); | ||
108 | + } | ||
109 | + | ||
110 | + /** | ||
111 | + * 删除菜单 | ||
112 | + * | ||
113 | + * @param menuId 菜单ID | ||
114 | + */ | ||
115 | + @SaCheckPermission("system:menu:remove") | ||
116 | + @Log(title = "菜单管理", businessType = BusinessType.DELETE) | ||
117 | + @DeleteMapping("/{menuId}") | ||
118 | + public R<Void> remove(@PathVariable("menuId") Long menuId) { | ||
119 | + if (menuService.hasChildByMenuId(menuId)) { | ||
120 | + return R.warn("存在子菜单,不允许删除"); | ||
121 | + } | ||
122 | + if (menuService.checkMenuExistRole(menuId)) { | ||
123 | + return R.warn("菜单已分配,不允许删除"); | ||
124 | + } | ||
125 | + return toAjax(menuService.deleteMenuById(menuId)); | ||
126 | + } | ||
127 | +} |
1 | +package com.ruoyi.web.controller.system; | ||
2 | + | ||
3 | +import cn.dev33.satoken.annotation.SaCheckPermission; | ||
4 | +import com.ruoyi.common.annotation.Log; | ||
5 | +import com.ruoyi.common.core.controller.BaseController; | ||
6 | +import com.ruoyi.common.core.domain.PageQuery; | ||
7 | +import com.ruoyi.common.core.domain.R; | ||
8 | +import com.ruoyi.common.core.page.TableDataInfo; | ||
9 | +import com.ruoyi.common.enums.BusinessType; | ||
10 | +import com.ruoyi.system.domain.SysNotice; | ||
11 | +import com.ruoyi.system.service.ISysNoticeService; | ||
12 | +import lombok.RequiredArgsConstructor; | ||
13 | +import org.springframework.validation.annotation.Validated; | ||
14 | +import org.springframework.web.bind.annotation.*; | ||
15 | + | ||
16 | +/** | ||
17 | + * 公告 信息操作处理 | ||
18 | + * | ||
19 | + * @author Lion Li | ||
20 | + */ | ||
21 | +@Validated | ||
22 | +@RequiredArgsConstructor | ||
23 | +@RestController | ||
24 | +@RequestMapping("/system/notice") | ||
25 | +public class SysNoticeController extends BaseController { | ||
26 | + | ||
27 | + private final ISysNoticeService noticeService; | ||
28 | + | ||
29 | + /** | ||
30 | + * 获取通知公告列表 | ||
31 | + */ | ||
32 | + @SaCheckPermission("system:notice:list") | ||
33 | + @GetMapping("/list") | ||
34 | + public TableDataInfo<SysNotice> list(SysNotice notice, PageQuery pageQuery) { | ||
35 | + return noticeService.selectPageNoticeList(notice, pageQuery); | ||
36 | + } | ||
37 | + | ||
38 | + /** | ||
39 | + * 根据通知公告编号获取详细信息 | ||
40 | + * | ||
41 | + * @param noticeId 公告ID | ||
42 | + */ | ||
43 | + @SaCheckPermission("system:notice:query") | ||
44 | + @GetMapping(value = "/{noticeId}") | ||
45 | + public R<SysNotice> getInfo(@PathVariable Long noticeId) { | ||
46 | + return R.ok(noticeService.selectNoticeById(noticeId)); | ||
47 | + } | ||
48 | + | ||
49 | + /** | ||
50 | + * 新增通知公告 | ||
51 | + */ | ||
52 | + @SaCheckPermission("system:notice:add") | ||
53 | + @Log(title = "通知公告", businessType = BusinessType.INSERT) | ||
54 | + @PostMapping | ||
55 | + public R<Void> add(@Validated @RequestBody SysNotice notice) { | ||
56 | + return toAjax(noticeService.insertNotice(notice)); | ||
57 | + } | ||
58 | + | ||
59 | + /** | ||
60 | + * 修改通知公告 | ||
61 | + */ | ||
62 | + @SaCheckPermission("system:notice:edit") | ||
63 | + @Log(title = "通知公告", businessType = BusinessType.UPDATE) | ||
64 | + @PutMapping | ||
65 | + public R<Void> edit(@Validated @RequestBody SysNotice notice) { | ||
66 | + return toAjax(noticeService.updateNotice(notice)); | ||
67 | + } | ||
68 | + | ||
69 | + /** | ||
70 | + * 删除通知公告 | ||
71 | + * | ||
72 | + * @param noticeIds 公告ID串 | ||
73 | + */ | ||
74 | + @SaCheckPermission("system:notice:remove") | ||
75 | + @Log(title = "通知公告", businessType = BusinessType.DELETE) | ||
76 | + @DeleteMapping("/{noticeIds}") | ||
77 | + public R<Void> remove(@PathVariable Long[] noticeIds) { | ||
78 | + return toAjax(noticeService.deleteNoticeByIds(noticeIds)); | ||
79 | + } | ||
80 | +} |
1 | +package com.ruoyi.web.controller.system; | ||
2 | + | ||
3 | +import cn.dev33.satoken.annotation.SaCheckPermission; | ||
4 | +import com.ruoyi.common.annotation.Log; | ||
5 | +import com.ruoyi.common.annotation.RepeatSubmit; | ||
6 | +import com.ruoyi.common.core.controller.BaseController; | ||
7 | +import com.ruoyi.common.core.domain.PageQuery; | ||
8 | +import com.ruoyi.common.core.domain.R; | ||
9 | +import com.ruoyi.common.core.page.TableDataInfo; | ||
10 | +import com.ruoyi.common.core.validate.AddGroup; | ||
11 | +import com.ruoyi.common.core.validate.EditGroup; | ||
12 | +import com.ruoyi.common.core.validate.QueryGroup; | ||
13 | +import com.ruoyi.common.enums.BusinessType; | ||
14 | +import com.ruoyi.system.domain.bo.SysOssConfigBo; | ||
15 | +import com.ruoyi.system.domain.vo.SysOssConfigVo; | ||
16 | +import com.ruoyi.system.service.ISysOssConfigService; | ||
17 | +import lombok.RequiredArgsConstructor; | ||
18 | +import org.springframework.validation.annotation.Validated; | ||
19 | +import org.springframework.web.bind.annotation.*; | ||
20 | + | ||
21 | +import javax.validation.constraints.NotEmpty; | ||
22 | +import javax.validation.constraints.NotNull; | ||
23 | +import java.util.Arrays; | ||
24 | + | ||
25 | +/** | ||
26 | + * 对象存储配置 | ||
27 | + * | ||
28 | + * @author Lion Li | ||
29 | + * @author 孤舟烟雨 | ||
30 | + * @date 2021-08-13 | ||
31 | + */ | ||
32 | +@Validated | ||
33 | +@RequiredArgsConstructor | ||
34 | +@RestController | ||
35 | +@RequestMapping("/system/oss/config") | ||
36 | +public class SysOssConfigController extends BaseController { | ||
37 | + | ||
38 | + private final ISysOssConfigService iSysOssConfigService; | ||
39 | + | ||
40 | + /** | ||
41 | + * 查询对象存储配置列表 | ||
42 | + */ | ||
43 | + @SaCheckPermission("system:oss:list") | ||
44 | + @GetMapping("/list") | ||
45 | + public TableDataInfo<SysOssConfigVo> list(@Validated(QueryGroup.class) SysOssConfigBo bo, PageQuery pageQuery) { | ||
46 | + return iSysOssConfigService.queryPageList(bo, pageQuery); | ||
47 | + } | ||
48 | + | ||
49 | + /** | ||
50 | + * 获取对象存储配置详细信息 | ||
51 | + * | ||
52 | + * @param ossConfigId OSS配置ID | ||
53 | + */ | ||
54 | + @SaCheckPermission("system:oss:query") | ||
55 | + @GetMapping("/{ossConfigId}") | ||
56 | + public R<SysOssConfigVo> getInfo(@NotNull(message = "主键不能为空") | ||
57 | + @PathVariable Long ossConfigId) { | ||
58 | + return R.ok(iSysOssConfigService.queryById(ossConfigId)); | ||
59 | + } | ||
60 | + | ||
61 | + /** | ||
62 | + * 新增对象存储配置 | ||
63 | + */ | ||
64 | + @SaCheckPermission("system:oss:add") | ||
65 | + @Log(title = "对象存储配置", businessType = BusinessType.INSERT) | ||
66 | + @RepeatSubmit() | ||
67 | + @PostMapping() | ||
68 | + public R<Void> add(@Validated(AddGroup.class) @RequestBody SysOssConfigBo bo) { | ||
69 | + return toAjax(iSysOssConfigService.insertByBo(bo)); | ||
70 | + } | ||
71 | + | ||
72 | + /** | ||
73 | + * 修改对象存储配置 | ||
74 | + */ | ||
75 | + @SaCheckPermission("system:oss:edit") | ||
76 | + @Log(title = "对象存储配置", businessType = BusinessType.UPDATE) | ||
77 | + @RepeatSubmit() | ||
78 | + @PutMapping() | ||
79 | + public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysOssConfigBo bo) { | ||
80 | + return toAjax(iSysOssConfigService.updateByBo(bo)); | ||
81 | + } | ||
82 | + | ||
83 | + /** | ||
84 | + * 删除对象存储配置 | ||
85 | + * | ||
86 | + * @param ossConfigIds OSS配置ID串 | ||
87 | + */ | ||
88 | + @SaCheckPermission("system:oss:remove") | ||
89 | + @Log(title = "对象存储配置", businessType = BusinessType.DELETE) | ||
90 | + @DeleteMapping("/{ossConfigIds}") | ||
91 | + public R<Void> remove(@NotEmpty(message = "主键不能为空") | ||
92 | + @PathVariable Long[] ossConfigIds) { | ||
93 | + return toAjax(iSysOssConfigService.deleteWithValidByIds(Arrays.asList(ossConfigIds), true)); | ||
94 | + } | ||
95 | + | ||
96 | + /** | ||
97 | + * 状态修改 | ||
98 | + */ | ||
99 | + @SaCheckPermission("system:oss:edit") | ||
100 | + @Log(title = "对象存储状态修改", businessType = BusinessType.UPDATE) | ||
101 | + @PutMapping("/changeStatus") | ||
102 | + public R<Void> changeStatus(@RequestBody SysOssConfigBo bo) { | ||
103 | + return toAjax(iSysOssConfigService.updateOssConfigStatus(bo)); | ||
104 | + } | ||
105 | +} |
1 | +package com.ruoyi.web.controller.system; | ||
2 | + | ||
3 | + | ||
4 | +import cn.dev33.satoken.annotation.SaCheckPermission; | ||
5 | +import cn.hutool.core.util.ObjectUtil; | ||
6 | +import com.ruoyi.common.annotation.Log; | ||
7 | +import com.ruoyi.common.core.controller.BaseController; | ||
8 | +import com.ruoyi.common.core.domain.PageQuery; | ||
9 | +import com.ruoyi.common.core.domain.R; | ||
10 | +import com.ruoyi.common.core.page.TableDataInfo; | ||
11 | +import com.ruoyi.common.core.validate.QueryGroup; | ||
12 | +import com.ruoyi.common.enums.BusinessType; | ||
13 | +import com.ruoyi.system.domain.bo.SysOssBo; | ||
14 | +import com.ruoyi.system.domain.vo.SysOssVo; | ||
15 | +import com.ruoyi.system.service.ISysOssService; | ||
16 | +import lombok.RequiredArgsConstructor; | ||
17 | +import org.springframework.http.MediaType; | ||
18 | +import org.springframework.validation.annotation.Validated; | ||
19 | +import org.springframework.web.bind.annotation.*; | ||
20 | +import org.springframework.web.multipart.MultipartFile; | ||
21 | + | ||
22 | +import javax.servlet.http.HttpServletResponse; | ||
23 | +import javax.validation.constraints.NotEmpty; | ||
24 | +import java.io.IOException; | ||
25 | +import java.util.Arrays; | ||
26 | +import java.util.HashMap; | ||
27 | +import java.util.List; | ||
28 | +import java.util.Map; | ||
29 | + | ||
30 | +/** | ||
31 | + * 文件上传 控制层 | ||
32 | + * | ||
33 | + * @author Lion Li | ||
34 | + */ | ||
35 | +@Validated | ||
36 | +@RequiredArgsConstructor | ||
37 | +@RestController | ||
38 | +@RequestMapping("/system/oss") | ||
39 | +public class SysOssController extends BaseController { | ||
40 | + | ||
41 | + private final ISysOssService iSysOssService; | ||
42 | + | ||
43 | + /** | ||
44 | + * 查询OSS对象存储列表 | ||
45 | + */ | ||
46 | + @SaCheckPermission("system:oss:list") | ||
47 | + @GetMapping("/list") | ||
48 | + public TableDataInfo<SysOssVo> list(@Validated(QueryGroup.class) SysOssBo bo, PageQuery pageQuery) { | ||
49 | + return iSysOssService.queryPageList(bo, pageQuery); | ||
50 | + } | ||
51 | + | ||
52 | + /** | ||
53 | + * 查询OSS对象基于id串 | ||
54 | + * | ||
55 | + * @param ossIds OSS对象ID串 | ||
56 | + */ | ||
57 | + @SaCheckPermission("system:oss:list") | ||
58 | + @GetMapping("/listByIds/{ossIds}") | ||
59 | + public R<List<SysOssVo>> listByIds(@NotEmpty(message = "主键不能为空") | ||
60 | + @PathVariable Long[] ossIds) { | ||
61 | + List<SysOssVo> list = iSysOssService.listByIds(Arrays.asList(ossIds)); | ||
62 | + return R.ok(list); | ||
63 | + } | ||
64 | + | ||
65 | + /** | ||
66 | + * 上传OSS对象存储 | ||
67 | + * | ||
68 | + * @param file 文件 | ||
69 | + */ | ||
70 | + @SaCheckPermission("system:oss:upload") | ||
71 | + @Log(title = "OSS对象存储", businessType = BusinessType.INSERT) | ||
72 | + @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) | ||
73 | + public R<Map<String, String>> upload(@RequestPart("file") MultipartFile file) { | ||
74 | + if (ObjectUtil.isNull(file)) { | ||
75 | + return R.fail("上传文件不能为空"); | ||
76 | + } | ||
77 | + SysOssVo oss = iSysOssService.upload(file); | ||
78 | + Map<String, String> map = new HashMap<>(2); | ||
79 | + map.put("url", oss.getUrl()); | ||
80 | + map.put("fileName", oss.getOriginalName()); | ||
81 | + map.put("ossId", oss.getOssId().toString()); | ||
82 | + return R.ok(map); | ||
83 | + } | ||
84 | + | ||
85 | + /** | ||
86 | + * 下载OSS对象 | ||
87 | + * | ||
88 | + * @param ossId OSS对象ID | ||
89 | + */ | ||
90 | + @SaCheckPermission("system:oss:download") | ||
91 | + @GetMapping("/download/{ossId}") | ||
92 | + public void download(@PathVariable Long ossId, HttpServletResponse response) throws IOException { | ||
93 | + iSysOssService.download(ossId,response); | ||
94 | + } | ||
95 | + | ||
96 | + /** | ||
97 | + * 删除OSS对象存储 | ||
98 | + * | ||
99 | + * @param ossIds OSS对象ID串 | ||
100 | + */ | ||
101 | + @SaCheckPermission("system:oss:remove") | ||
102 | + @Log(title = "OSS对象存储", businessType = BusinessType.DELETE) | ||
103 | + @DeleteMapping("/{ossIds}") | ||
104 | + public R<Void> remove(@NotEmpty(message = "主键不能为空") | ||
105 | + @PathVariable Long[] ossIds) { | ||
106 | + return toAjax(iSysOssService.deleteWithValidByIds(Arrays.asList(ossIds), true)); | ||
107 | + } | ||
108 | + | ||
109 | +} |
1 | +package com.ruoyi.web.controller.system; | ||
2 | + | ||
3 | +import cn.dev33.satoken.annotation.SaCheckPermission; | ||
4 | +import com.ruoyi.common.annotation.Log; | ||
5 | +import com.ruoyi.common.constant.UserConstants; | ||
6 | +import com.ruoyi.common.core.controller.BaseController; | ||
7 | +import com.ruoyi.common.core.domain.PageQuery; | ||
8 | +import com.ruoyi.common.core.domain.R; | ||
9 | +import com.ruoyi.common.core.page.TableDataInfo; | ||
10 | +import com.ruoyi.common.enums.BusinessType; | ||
11 | +import com.ruoyi.common.utils.poi.ExcelUtil; | ||
12 | +import com.ruoyi.system.domain.SysPost; | ||
13 | +import com.ruoyi.system.service.ISysPostService; | ||
14 | +import lombok.RequiredArgsConstructor; | ||
15 | +import org.springframework.validation.annotation.Validated; | ||
16 | +import org.springframework.web.bind.annotation.*; | ||
17 | + | ||
18 | +import javax.servlet.http.HttpServletResponse; | ||
19 | +import java.util.List; | ||
20 | + | ||
21 | +/** | ||
22 | + * 岗位信息操作处理 | ||
23 | + * | ||
24 | + * @author Lion Li | ||
25 | + */ | ||
26 | +@Validated | ||
27 | +@RequiredArgsConstructor | ||
28 | +@RestController | ||
29 | +@RequestMapping("/system/post") | ||
30 | +public class SysPostController extends BaseController { | ||
31 | + | ||
32 | + private final ISysPostService postService; | ||
33 | + | ||
34 | + /** | ||
35 | + * 获取岗位列表 | ||
36 | + */ | ||
37 | + @SaCheckPermission("system:post:list") | ||
38 | + @GetMapping("/list") | ||
39 | + public TableDataInfo<SysPost> list(SysPost post, PageQuery pageQuery) { | ||
40 | + return postService.selectPagePostList(post, pageQuery); | ||
41 | + } | ||
42 | + | ||
43 | + /** | ||
44 | + * 导出岗位列表 | ||
45 | + */ | ||
46 | + @Log(title = "岗位管理", businessType = BusinessType.EXPORT) | ||
47 | + @SaCheckPermission("system:post:export") | ||
48 | + @PostMapping("/export") | ||
49 | + public void export(SysPost post, HttpServletResponse response) { | ||
50 | + List<SysPost> list = postService.selectPostList(post); | ||
51 | + ExcelUtil.exportExcel(list, "岗位数据", SysPost.class, response); | ||
52 | + } | ||
53 | + | ||
54 | + /** | ||
55 | + * 根据岗位编号获取详细信息 | ||
56 | + * | ||
57 | + * @param postId 岗位ID | ||
58 | + */ | ||
59 | + @SaCheckPermission("system:post:query") | ||
60 | + @GetMapping(value = "/{postId}") | ||
61 | + public R<SysPost> getInfo(@PathVariable Long postId) { | ||
62 | + return R.ok(postService.selectPostById(postId)); | ||
63 | + } | ||
64 | + | ||
65 | + /** | ||
66 | + * 新增岗位 | ||
67 | + */ | ||
68 | + @SaCheckPermission("system:post:add") | ||
69 | + @Log(title = "岗位管理", businessType = BusinessType.INSERT) | ||
70 | + @PostMapping | ||
71 | + public R<Void> add(@Validated @RequestBody SysPost post) { | ||
72 | + if (!postService.checkPostNameUnique(post)) { | ||
73 | + return R.fail("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在"); | ||
74 | + } else if (!postService.checkPostCodeUnique(post)) { | ||
75 | + return R.fail("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在"); | ||
76 | + } | ||
77 | + return toAjax(postService.insertPost(post)); | ||
78 | + } | ||
79 | + | ||
80 | + /** | ||
81 | + * 修改岗位 | ||
82 | + */ | ||
83 | + @SaCheckPermission("system:post:edit") | ||
84 | + @Log(title = "岗位管理", businessType = BusinessType.UPDATE) | ||
85 | + @PutMapping | ||
86 | + public R<Void> edit(@Validated @RequestBody SysPost post) { | ||
87 | + if (!postService.checkPostNameUnique(post)) { | ||
88 | + return R.fail("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在"); | ||
89 | + } else if (!postService.checkPostCodeUnique(post)) { | ||
90 | + return R.fail("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在"); | ||
91 | + } else if (UserConstants.POST_DISABLE.equals(post.getStatus()) | ||
92 | + && postService.countUserPostById(post.getPostId()) > 0) { | ||
93 | + return R.fail("该岗位下存在已分配用户,不能禁用!"); | ||
94 | + } | ||
95 | + return toAjax(postService.updatePost(post)); | ||
96 | + } | ||
97 | + | ||
98 | + /** | ||
99 | + * 删除岗位 | ||
100 | + * | ||
101 | + * @param postIds 岗位ID串 | ||
102 | + */ | ||
103 | + @SaCheckPermission("system:post:remove") | ||
104 | + @Log(title = "岗位管理", businessType = BusinessType.DELETE) | ||
105 | + @DeleteMapping("/{postIds}") | ||
106 | + public R<Void> remove(@PathVariable Long[] postIds) { | ||
107 | + return toAjax(postService.deletePostByIds(postIds)); | ||
108 | + } | ||
109 | + | ||
110 | + /** | ||
111 | + * 获取岗位选择框列表 | ||
112 | + */ | ||
113 | + @GetMapping("/optionselect") | ||
114 | + public R<List<SysPost>> optionselect() { | ||
115 | + SysPost post = new SysPost(); | ||
116 | + post.setStatus(UserConstants.POST_NORMAL); | ||
117 | + List<SysPost> posts = postService.selectPostList(post); | ||
118 | + return R.ok(posts); | ||
119 | + } | ||
120 | +} |
1 | +package com.ruoyi.web.controller.system; | ||
2 | + | ||
3 | +import cn.dev33.satoken.secure.BCrypt; | ||
4 | +import cn.hutool.core.io.FileUtil; | ||
5 | +import com.ruoyi.common.annotation.Log; | ||
6 | +import com.ruoyi.common.constant.UserConstants; | ||
7 | +import com.ruoyi.common.core.controller.BaseController; | ||
8 | +import com.ruoyi.common.core.domain.R; | ||
9 | +import com.ruoyi.common.core.domain.entity.SysUser; | ||
10 | +import com.ruoyi.common.enums.BusinessType; | ||
11 | +import com.ruoyi.common.helper.LoginHelper; | ||
12 | +import com.ruoyi.common.utils.StringUtils; | ||
13 | +import com.ruoyi.common.utils.file.MimeTypeUtils; | ||
14 | +import com.ruoyi.system.domain.SysOss; | ||
15 | +import com.ruoyi.system.domain.vo.SysOssVo; | ||
16 | +import com.ruoyi.system.service.ISysOssService; | ||
17 | +import com.ruoyi.system.service.ISysUserService; | ||
18 | +import lombok.RequiredArgsConstructor; | ||
19 | +import org.springframework.http.MediaType; | ||
20 | +import org.springframework.validation.annotation.Validated; | ||
21 | +import org.springframework.web.bind.annotation.*; | ||
22 | +import org.springframework.web.multipart.MultipartFile; | ||
23 | + | ||
24 | +import java.util.Arrays; | ||
25 | +import java.util.HashMap; | ||
26 | +import java.util.Map; | ||
27 | + | ||
28 | +/** | ||
29 | + * 个人信息 业务处理 | ||
30 | + * | ||
31 | + * @author Lion Li | ||
32 | + */ | ||
33 | +@Validated | ||
34 | +@RequiredArgsConstructor | ||
35 | +@RestController | ||
36 | +@RequestMapping("/system/user/profile") | ||
37 | +public class SysProfileController extends BaseController { | ||
38 | + | ||
39 | + private final ISysUserService userService; | ||
40 | + private final ISysOssService iSysOssService; | ||
41 | + | ||
42 | + /** | ||
43 | + * 个人信息 | ||
44 | + */ | ||
45 | + @GetMapping | ||
46 | + public R<Map<String, Object>> profile() { | ||
47 | + SysUser user = userService.selectUserById(getUserId()); | ||
48 | + Map<String, Object> ajax = new HashMap<>(); | ||
49 | + ajax.put("user", user); | ||
50 | + ajax.put("roleGroup", userService.selectUserRoleGroup(user.getUserName())); | ||
51 | + ajax.put("postGroup", userService.selectUserPostGroup(user.getUserName())); | ||
52 | + return R.ok(ajax); | ||
53 | + } | ||
54 | + | ||
55 | + /** | ||
56 | + * 修改用户 | ||
57 | + */ | ||
58 | + @Log(title = "个人信息", businessType = BusinessType.UPDATE) | ||
59 | + @PutMapping | ||
60 | + public R<Void> updateProfile(@RequestBody SysUser user) { | ||
61 | + if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) { | ||
62 | + return R.fail("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); | ||
63 | + } | ||
64 | + if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) { | ||
65 | + return R.fail("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); | ||
66 | + } | ||
67 | + user.setUserId(getUserId()); | ||
68 | + user.setUserName(null); | ||
69 | + user.setPassword(null); | ||
70 | + user.setAvatar(null); | ||
71 | + user.setDeptId(null); | ||
72 | + if (userService.updateUserProfile(user) > 0) { | ||
73 | + return R.ok(); | ||
74 | + } | ||
75 | + return R.fail("修改个人信息异常,请联系管理员"); | ||
76 | + } | ||
77 | + | ||
78 | + /** | ||
79 | + * 重置密码 | ||
80 | + * | ||
81 | + * @param newPassword 新密码 | ||
82 | + * @param oldPassword 旧密码 | ||
83 | + */ | ||
84 | + @Log(title = "个人信息", businessType = BusinessType.UPDATE) | ||
85 | + @PutMapping("/updatePwd") | ||
86 | + public R<Void> updatePwd(String oldPassword, String newPassword) { | ||
87 | + SysUser user = userService.selectUserById(LoginHelper.getUserId()); | ||
88 | + String userName = user.getUserName(); | ||
89 | + String password = user.getPassword(); | ||
90 | + if (!BCrypt.checkpw(oldPassword, password)) { | ||
91 | + return R.fail("修改密码失败,旧密码错误"); | ||
92 | + } | ||
93 | + if (BCrypt.checkpw(newPassword, password)) { | ||
94 | + return R.fail("新密码不能与旧密码相同"); | ||
95 | + } | ||
96 | + | ||
97 | + if (userService.resetUserPwd(userName, BCrypt.hashpw(newPassword)) > 0) { | ||
98 | + return R.ok(); | ||
99 | + } | ||
100 | + return R.fail("修改密码异常,请联系管理员"); | ||
101 | + } | ||
102 | + | ||
103 | + /** | ||
104 | + * 头像上传 | ||
105 | + * | ||
106 | + * @param avatarfile 用户头像 | ||
107 | + */ | ||
108 | + @Log(title = "用户头像", businessType = BusinessType.UPDATE) | ||
109 | + @PostMapping(value = "/avatar", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) | ||
110 | + public R<Map<String, Object>> avatar(@RequestPart("avatarfile") MultipartFile avatarfile) { | ||
111 | + Map<String, Object> ajax = new HashMap<>(); | ||
112 | + if (!avatarfile.isEmpty()) { | ||
113 | + String extension = FileUtil.extName(avatarfile.getOriginalFilename()); | ||
114 | + if (!StringUtils.equalsAnyIgnoreCase(extension, MimeTypeUtils.IMAGE_EXTENSION)) { | ||
115 | + return R.fail("文件格式不正确,请上传" + Arrays.toString(MimeTypeUtils.IMAGE_EXTENSION) + "格式"); | ||
116 | + } | ||
117 | + SysOssVo oss = iSysOssService.upload(avatarfile); | ||
118 | + String avatar = oss.getUrl(); | ||
119 | + if (userService.updateUserAvatar(getUsername(), avatar)) { | ||
120 | + ajax.put("imgUrl", avatar); | ||
121 | + return R.ok(ajax); | ||
122 | + } | ||
123 | + } | ||
124 | + return R.fail("上传图片异常,请联系管理员"); | ||
125 | + } | ||
126 | +} |
1 | +package com.ruoyi.web.controller.system; | ||
2 | + | ||
3 | +import cn.dev33.satoken.annotation.SaIgnore; | ||
4 | +import com.ruoyi.common.core.controller.BaseController; | ||
5 | +import com.ruoyi.common.core.domain.R; | ||
6 | +import com.ruoyi.common.core.domain.model.RegisterBody; | ||
7 | +import com.ruoyi.system.service.ISysConfigService; | ||
8 | +import com.ruoyi.system.service.SysRegisterService; | ||
9 | +import lombok.RequiredArgsConstructor; | ||
10 | +import org.springframework.validation.annotation.Validated; | ||
11 | +import org.springframework.web.bind.annotation.PostMapping; | ||
12 | +import org.springframework.web.bind.annotation.RequestBody; | ||
13 | +import org.springframework.web.bind.annotation.RestController; | ||
14 | + | ||
15 | +/** | ||
16 | + * 注册验证 | ||
17 | + * | ||
18 | + * @author Lion Li | ||
19 | + */ | ||
20 | +@Validated | ||
21 | +@RequiredArgsConstructor | ||
22 | +@RestController | ||
23 | +public class SysRegisterController extends BaseController { | ||
24 | + | ||
25 | + private final SysRegisterService registerService; | ||
26 | + private final ISysConfigService configService; | ||
27 | + | ||
28 | + /** | ||
29 | + * 用户注册 | ||
30 | + */ | ||
31 | + @SaIgnore | ||
32 | + @PostMapping("/register") | ||
33 | + public R<Void> register(@Validated @RequestBody RegisterBody user) { | ||
34 | + if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) { | ||
35 | + return R.fail("当前系统没有开启注册功能!"); | ||
36 | + } | ||
37 | + registerService.register(user); | ||
38 | + return R.ok(); | ||
39 | + } | ||
40 | +} |
1 | +package com.ruoyi.web.controller.system; | ||
2 | + | ||
3 | +import cn.dev33.satoken.annotation.SaCheckPermission; | ||
4 | +import com.ruoyi.common.annotation.Log; | ||
5 | +import com.ruoyi.common.core.controller.BaseController; | ||
6 | +import com.ruoyi.common.core.domain.PageQuery; | ||
7 | +import com.ruoyi.common.core.domain.R; | ||
8 | +import com.ruoyi.common.core.domain.entity.SysDept; | ||
9 | +import com.ruoyi.common.core.domain.entity.SysRole; | ||
10 | +import com.ruoyi.common.core.domain.entity.SysUser; | ||
11 | +import com.ruoyi.common.core.page.TableDataInfo; | ||
12 | +import com.ruoyi.common.enums.BusinessType; | ||
13 | +import com.ruoyi.common.utils.poi.ExcelUtil; | ||
14 | +import com.ruoyi.system.domain.SysUserRole; | ||
15 | +import com.ruoyi.system.service.ISysDeptService; | ||
16 | +import com.ruoyi.system.service.ISysRoleService; | ||
17 | +import com.ruoyi.system.service.ISysUserService; | ||
18 | +import com.ruoyi.system.service.SysPermissionService; | ||
19 | +import lombok.RequiredArgsConstructor; | ||
20 | +import org.springframework.validation.annotation.Validated; | ||
21 | +import org.springframework.web.bind.annotation.*; | ||
22 | + | ||
23 | +import javax.servlet.http.HttpServletResponse; | ||
24 | +import java.util.HashMap; | ||
25 | +import java.util.List; | ||
26 | +import java.util.Map; | ||
27 | + | ||
28 | +/** | ||
29 | + * 角色信息 | ||
30 | + * | ||
31 | + * @author Lion Li | ||
32 | + */ | ||
33 | +@Validated | ||
34 | +@RequiredArgsConstructor | ||
35 | +@RestController | ||
36 | +@RequestMapping("/system/role") | ||
37 | +public class SysRoleController extends BaseController { | ||
38 | + | ||
39 | + private final ISysRoleService roleService; | ||
40 | + private final ISysUserService userService; | ||
41 | + private final ISysDeptService deptService; | ||
42 | + private final SysPermissionService permissionService; | ||
43 | + | ||
44 | + /** | ||
45 | + * 获取角色信息列表 | ||
46 | + */ | ||
47 | + @SaCheckPermission("system:role:list") | ||
48 | + @GetMapping("/list") | ||
49 | + public TableDataInfo<SysRole> list(SysRole role, PageQuery pageQuery) { | ||
50 | + return roleService.selectPageRoleList(role, pageQuery); | ||
51 | + } | ||
52 | + | ||
53 | + /** | ||
54 | + * 导出角色信息列表 | ||
55 | + */ | ||
56 | + @Log(title = "角色管理", businessType = BusinessType.EXPORT) | ||
57 | + @SaCheckPermission("system:role:export") | ||
58 | + @PostMapping("/export") | ||
59 | + public void export(SysRole role, HttpServletResponse response) { | ||
60 | + List<SysRole> list = roleService.selectRoleList(role); | ||
61 | + ExcelUtil.exportExcel(list, "角色数据", SysRole.class, response); | ||
62 | + } | ||
63 | + | ||
64 | + /** | ||
65 | + * 根据角色编号获取详细信息 | ||
66 | + * | ||
67 | + * @param roleId 角色ID | ||
68 | + */ | ||
69 | + @SaCheckPermission("system:role:query") | ||
70 | + @GetMapping(value = "/{roleId}") | ||
71 | + public R<SysRole> getInfo(@PathVariable Long roleId) { | ||
72 | + roleService.checkRoleDataScope(roleId); | ||
73 | + return R.ok(roleService.selectRoleById(roleId)); | ||
74 | + } | ||
75 | + | ||
76 | + /** | ||
77 | + * 新增角色 | ||
78 | + */ | ||
79 | + @SaCheckPermission("system:role:add") | ||
80 | + @Log(title = "角色管理", businessType = BusinessType.INSERT) | ||
81 | + @PostMapping | ||
82 | + public R<Void> add(@Validated @RequestBody SysRole role) { | ||
83 | + roleService.checkRoleAllowed(role); | ||
84 | + if (!roleService.checkRoleNameUnique(role)) { | ||
85 | + return R.fail("新增角色'" + role.getRoleName() + "'失败,角色名称已存在"); | ||
86 | + } else if (!roleService.checkRoleKeyUnique(role)) { | ||
87 | + return R.fail("新增角色'" + role.getRoleName() + "'失败,角色权限已存在"); | ||
88 | + } | ||
89 | + return toAjax(roleService.insertRole(role)); | ||
90 | + | ||
91 | + } | ||
92 | + | ||
93 | + /** | ||
94 | + * 修改保存角色 | ||
95 | + */ | ||
96 | + @SaCheckPermission("system:role:edit") | ||
97 | + @Log(title = "角色管理", businessType = BusinessType.UPDATE) | ||
98 | + @PutMapping | ||
99 | + public R<Void> edit(@Validated @RequestBody SysRole role) { | ||
100 | + roleService.checkRoleAllowed(role); | ||
101 | + roleService.checkRoleDataScope(role.getRoleId()); | ||
102 | + if (!roleService.checkRoleNameUnique(role)) { | ||
103 | + return R.fail("修改角色'" + role.getRoleName() + "'失败,角色名称已存在"); | ||
104 | + } else if (!roleService.checkRoleKeyUnique(role)) { | ||
105 | + return R.fail("修改角色'" + role.getRoleName() + "'失败,角色权限已存在"); | ||
106 | + } | ||
107 | + | ||
108 | + if (roleService.updateRole(role) > 0) { | ||
109 | + roleService.cleanOnlineUserByRole(role.getRoleId()); | ||
110 | + return R.ok(); | ||
111 | + } | ||
112 | + return R.fail("修改角色'" + role.getRoleName() + "'失败,请联系管理员"); | ||
113 | + } | ||
114 | + | ||
115 | + /** | ||
116 | + * 修改保存数据权限 | ||
117 | + */ | ||
118 | + @SaCheckPermission("system:role:edit") | ||
119 | + @Log(title = "角色管理", businessType = BusinessType.UPDATE) | ||
120 | + @PutMapping("/dataScope") | ||
121 | + public R<Void> dataScope(@RequestBody SysRole role) { | ||
122 | + roleService.checkRoleAllowed(role); | ||
123 | + roleService.checkRoleDataScope(role.getRoleId()); | ||
124 | + return toAjax(roleService.authDataScope(role)); | ||
125 | + } | ||
126 | + | ||
127 | + /** | ||
128 | + * 状态修改 | ||
129 | + */ | ||
130 | + @SaCheckPermission("system:role:edit") | ||
131 | + @Log(title = "角色管理", businessType = BusinessType.UPDATE) | ||
132 | + @PutMapping("/changeStatus") | ||
133 | + public R<Void> changeStatus(@RequestBody SysRole role) { | ||
134 | + roleService.checkRoleAllowed(role); | ||
135 | + roleService.checkRoleDataScope(role.getRoleId()); | ||
136 | + return toAjax(roleService.updateRoleStatus(role)); | ||
137 | + } | ||
138 | + | ||
139 | + /** | ||
140 | + * 删除角色 | ||
141 | + * | ||
142 | + * @param roleIds 角色ID串 | ||
143 | + */ | ||
144 | + @SaCheckPermission("system:role:remove") | ||
145 | + @Log(title = "角色管理", businessType = BusinessType.DELETE) | ||
146 | + @DeleteMapping("/{roleIds}") | ||
147 | + public R<Void> remove(@PathVariable Long[] roleIds) { | ||
148 | + return toAjax(roleService.deleteRoleByIds(roleIds)); | ||
149 | + } | ||
150 | + | ||
151 | + /** | ||
152 | + * 获取角色选择框列表 | ||
153 | + */ | ||
154 | + @SaCheckPermission("system:role:query") | ||
155 | + @GetMapping("/optionselect") | ||
156 | + public R<List<SysRole>> optionselect() { | ||
157 | + return R.ok(roleService.selectRoleAll()); | ||
158 | + } | ||
159 | + | ||
160 | + /** | ||
161 | + * 查询已分配用户角色列表 | ||
162 | + */ | ||
163 | + @SaCheckPermission("system:role:list") | ||
164 | + @GetMapping("/authUser/allocatedList") | ||
165 | + public TableDataInfo<SysUser> allocatedList(SysUser user, PageQuery pageQuery) { | ||
166 | + return userService.selectAllocatedList(user, pageQuery); | ||
167 | + } | ||
168 | + | ||
169 | + /** | ||
170 | + * 查询未分配用户角色列表 | ||
171 | + */ | ||
172 | + @SaCheckPermission("system:role:list") | ||
173 | + @GetMapping("/authUser/unallocatedList") | ||
174 | + public TableDataInfo<SysUser> unallocatedList(SysUser user, PageQuery pageQuery) { | ||
175 | + return userService.selectUnallocatedList(user, pageQuery); | ||
176 | + } | ||
177 | + | ||
178 | + /** | ||
179 | + * 取消授权用户 | ||
180 | + */ | ||
181 | + @SaCheckPermission("system:role:edit") | ||
182 | + @Log(title = "角色管理", businessType = BusinessType.GRANT) | ||
183 | + @PutMapping("/authUser/cancel") | ||
184 | + public R<Void> cancelAuthUser(@RequestBody SysUserRole userRole) { | ||
185 | + return toAjax(roleService.deleteAuthUser(userRole)); | ||
186 | + } | ||
187 | + | ||
188 | + /** | ||
189 | + * 批量取消授权用户 | ||
190 | + * | ||
191 | + * @param roleId 角色ID | ||
192 | + * @param userIds 用户ID串 | ||
193 | + */ | ||
194 | + @SaCheckPermission("system:role:edit") | ||
195 | + @Log(title = "角色管理", businessType = BusinessType.GRANT) | ||
196 | + @PutMapping("/authUser/cancelAll") | ||
197 | + public R<Void> cancelAuthUserAll(Long roleId, Long[] userIds) { | ||
198 | + return toAjax(roleService.deleteAuthUsers(roleId, userIds)); | ||
199 | + } | ||
200 | + | ||
201 | + /** | ||
202 | + * 批量选择用户授权 | ||
203 | + * | ||
204 | + * @param roleId 角色ID | ||
205 | + * @param userIds 用户ID串 | ||
206 | + */ | ||
207 | + @SaCheckPermission("system:role:edit") | ||
208 | + @Log(title = "角色管理", businessType = BusinessType.GRANT) | ||
209 | + @PutMapping("/authUser/selectAll") | ||
210 | + public R<Void> selectAuthUserAll(Long roleId, Long[] userIds) { | ||
211 | + roleService.checkRoleDataScope(roleId); | ||
212 | + return toAjax(roleService.insertAuthUsers(roleId, userIds)); | ||
213 | + } | ||
214 | + | ||
215 | + /** | ||
216 | + * 获取对应角色部门树列表 | ||
217 | + * | ||
218 | + * @param roleId 角色ID | ||
219 | + */ | ||
220 | + @SaCheckPermission("system:role:list") | ||
221 | + @GetMapping(value = "/deptTree/{roleId}") | ||
222 | + public R<Map<String, Object>> roleDeptTreeselect(@PathVariable("roleId") Long roleId) { | ||
223 | + Map<String, Object> ajax = new HashMap<>(); | ||
224 | + ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId)); | ||
225 | + ajax.put("depts", deptService.selectDeptTreeList(new SysDept())); | ||
226 | + return R.ok(ajax); | ||
227 | + } | ||
228 | +} |
1 | +package com.ruoyi.web.controller.system; | ||
2 | + | ||
3 | +import cn.dev33.satoken.annotation.SaCheckPermission; | ||
4 | +import cn.dev33.satoken.secure.BCrypt; | ||
5 | +import cn.hutool.core.bean.BeanUtil; | ||
6 | +import cn.hutool.core.lang.tree.Tree; | ||
7 | +import cn.hutool.core.util.ArrayUtil; | ||
8 | +import cn.hutool.core.util.ObjectUtil; | ||
9 | +import com.ruoyi.common.annotation.Log; | ||
10 | +import com.ruoyi.common.constant.UserConstants; | ||
11 | +import com.ruoyi.common.core.controller.BaseController; | ||
12 | +import com.ruoyi.common.core.domain.PageQuery; | ||
13 | +import com.ruoyi.common.core.domain.R; | ||
14 | +import com.ruoyi.common.core.domain.entity.SysDept; | ||
15 | +import com.ruoyi.common.core.domain.entity.SysRole; | ||
16 | +import com.ruoyi.common.core.domain.entity.SysUser; | ||
17 | +import com.ruoyi.common.core.page.TableDataInfo; | ||
18 | +import com.ruoyi.common.enums.BusinessType; | ||
19 | +import com.ruoyi.common.excel.ExcelResult; | ||
20 | +import com.ruoyi.common.helper.LoginHelper; | ||
21 | +import com.ruoyi.common.utils.StreamUtils; | ||
22 | +import com.ruoyi.common.utils.StringUtils; | ||
23 | +import com.ruoyi.common.utils.poi.ExcelUtil; | ||
24 | +import com.ruoyi.system.domain.SysPost; | ||
25 | +import com.ruoyi.system.domain.vo.SysUserExportVo; | ||
26 | +import com.ruoyi.system.domain.vo.SysUserImportVo; | ||
27 | +import com.ruoyi.system.listener.SysUserImportListener; | ||
28 | +import com.ruoyi.system.service.ISysDeptService; | ||
29 | +import com.ruoyi.system.service.ISysPostService; | ||
30 | +import com.ruoyi.system.service.ISysRoleService; | ||
31 | +import com.ruoyi.system.service.ISysUserService; | ||
32 | +import lombok.RequiredArgsConstructor; | ||
33 | +import org.springframework.http.MediaType; | ||
34 | +import org.springframework.validation.annotation.Validated; | ||
35 | +import org.springframework.web.bind.annotation.*; | ||
36 | +import org.springframework.web.multipart.MultipartFile; | ||
37 | + | ||
38 | +import javax.servlet.http.HttpServletResponse; | ||
39 | +import java.util.ArrayList; | ||
40 | +import java.util.HashMap; | ||
41 | +import java.util.List; | ||
42 | +import java.util.Map; | ||
43 | + | ||
44 | +/** | ||
45 | + * 用户信息 | ||
46 | + * | ||
47 | + * @author Lion Li | ||
48 | + */ | ||
49 | +@Validated | ||
50 | +@RequiredArgsConstructor | ||
51 | +@RestController | ||
52 | +@RequestMapping("/system/user") | ||
53 | +public class SysUserController extends BaseController { | ||
54 | + | ||
55 | + private final ISysUserService userService; | ||
56 | + private final ISysRoleService roleService; | ||
57 | + private final ISysPostService postService; | ||
58 | + private final ISysDeptService deptService; | ||
59 | + | ||
60 | + /** | ||
61 | + * 获取用户列表 | ||
62 | + */ | ||
63 | + @SaCheckPermission("system:user:list") | ||
64 | + @GetMapping("/list") | ||
65 | + public TableDataInfo<SysUser> list(SysUser user, PageQuery pageQuery) { | ||
66 | + return userService.selectPageUserList(user, pageQuery); | ||
67 | + } | ||
68 | + | ||
69 | + /** | ||
70 | + * 导出用户列表 | ||
71 | + */ | ||
72 | + @Log(title = "用户管理", businessType = BusinessType.EXPORT) | ||
73 | + @SaCheckPermission("system:user:export") | ||
74 | + @PostMapping("/export") | ||
75 | + public void export(SysUser user, HttpServletResponse response) { | ||
76 | + List<SysUser> list = userService.selectUserList(user); | ||
77 | + List<SysUserExportVo> listVo = BeanUtil.copyToList(list, SysUserExportVo.class); | ||
78 | + for (int i = 0; i < list.size(); i++) { | ||
79 | + SysDept dept = list.get(i).getDept(); | ||
80 | + SysUserExportVo vo = listVo.get(i); | ||
81 | + if (ObjectUtil.isNotEmpty(dept)) { | ||
82 | + vo.setDeptName(dept.getDeptName()); | ||
83 | + vo.setLeader(dept.getLeader()); | ||
84 | + } | ||
85 | + } | ||
86 | + ExcelUtil.exportExcel(listVo, "用户数据", SysUserExportVo.class, response); | ||
87 | + } | ||
88 | + | ||
89 | + /** | ||
90 | + * 导入数据 | ||
91 | + * | ||
92 | + * @param file 导入文件 | ||
93 | + * @param updateSupport 是否更新已存在数据 | ||
94 | + */ | ||
95 | + @Log(title = "用户管理", businessType = BusinessType.IMPORT) | ||
96 | + @SaCheckPermission("system:user:import") | ||
97 | + @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) | ||
98 | + public R<Void> importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception { | ||
99 | + ExcelResult<SysUserImportVo> result = ExcelUtil.importExcel(file.getInputStream(), SysUserImportVo.class, new SysUserImportListener(updateSupport)); | ||
100 | + return R.ok(result.getAnalysis()); | ||
101 | + } | ||
102 | + | ||
103 | + /** | ||
104 | + * 获取导入模板 | ||
105 | + */ | ||
106 | + @PostMapping("/importTemplate") | ||
107 | + public void importTemplate(HttpServletResponse response) { | ||
108 | + ExcelUtil.exportExcel(new ArrayList<>(), "用户数据", SysUserImportVo.class, response); | ||
109 | + } | ||
110 | + | ||
111 | + /** | ||
112 | + * 根据用户编号获取详细信息 | ||
113 | + * | ||
114 | + * @param userId 用户ID | ||
115 | + */ | ||
116 | + @SaCheckPermission("system:user:query") | ||
117 | + @GetMapping(value = {"/", "/{userId}"}) | ||
118 | + public R<Map<String, Object>> getInfo(@PathVariable(value = "userId", required = false) Long userId) { | ||
119 | + userService.checkUserDataScope(userId); | ||
120 | + Map<String, Object> ajax = new HashMap<>(); | ||
121 | + SysRole role = new SysRole(); | ||
122 | + role.setStatus(UserConstants.ROLE_NORMAL); | ||
123 | + SysPost post = new SysPost(); | ||
124 | + post.setStatus(UserConstants.POST_NORMAL); | ||
125 | + List<SysRole> roles = roleService.selectRoleList(role); | ||
126 | + ajax.put("roles", LoginHelper.isAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isAdmin())); | ||
127 | + ajax.put("posts", postService.selectPostList(post)); | ||
128 | + if (ObjectUtil.isNotNull(userId)) { | ||
129 | + SysUser sysUser = userService.selectUserById(userId); | ||
130 | + ajax.put("user", sysUser); | ||
131 | + ajax.put("postIds", postService.selectPostListByUserId(userId)); | ||
132 | + ajax.put("roleIds", StreamUtils.toList(sysUser.getRoles(), SysRole::getRoleId)); | ||
133 | + } | ||
134 | + return R.ok(ajax); | ||
135 | + } | ||
136 | + | ||
137 | + /** | ||
138 | + * 新增用户 | ||
139 | + */ | ||
140 | + @SaCheckPermission("system:user:add") | ||
141 | + @Log(title = "用户管理", businessType = BusinessType.INSERT) | ||
142 | + @PostMapping | ||
143 | + public R<Void> add(@Validated @RequestBody SysUser user) { | ||
144 | + deptService.checkDeptDataScope(user.getDeptId()); | ||
145 | + if (!userService.checkUserNameUnique(user)) { | ||
146 | + return R.fail("新增用户'" + user.getUserName() + "'失败,登录账号已存在"); | ||
147 | + } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) { | ||
148 | + return R.fail("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); | ||
149 | + } else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) { | ||
150 | + return R.fail("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在"); | ||
151 | + } | ||
152 | + user.setPassword(BCrypt.hashpw(user.getPassword())); | ||
153 | + return toAjax(userService.insertUser(user)); | ||
154 | + } | ||
155 | + | ||
156 | + /** | ||
157 | + * 修改用户 | ||
158 | + */ | ||
159 | + @SaCheckPermission("system:user:edit") | ||
160 | + @Log(title = "用户管理", businessType = BusinessType.UPDATE) | ||
161 | + @PutMapping | ||
162 | + public R<Void> edit(@Validated @RequestBody SysUser user) { | ||
163 | + userService.checkUserAllowed(user); | ||
164 | + userService.checkUserDataScope(user.getUserId()); | ||
165 | + deptService.checkDeptDataScope(user.getDeptId()); | ||
166 | + if (!userService.checkUserNameUnique(user)) { | ||
167 | + return R.fail("修改用户'" + user.getUserName() + "'失败,登录账号已存在"); | ||
168 | + } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) { | ||
169 | + return R.fail("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); | ||
170 | + } else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) { | ||
171 | + return R.fail("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); | ||
172 | + } | ||
173 | + return toAjax(userService.updateUser(user)); | ||
174 | + } | ||
175 | + | ||
176 | + /** | ||
177 | + * 删除用户 | ||
178 | + * | ||
179 | + * @param userIds 角色ID串 | ||
180 | + */ | ||
181 | + @SaCheckPermission("system:user:remove") | ||
182 | + @Log(title = "用户管理", businessType = BusinessType.DELETE) | ||
183 | + @DeleteMapping("/{userIds}") | ||
184 | + public R<Void> remove(@PathVariable Long[] userIds) { | ||
185 | + if (ArrayUtil.contains(userIds, getUserId())) { | ||
186 | + return R.fail("当前用户不能删除"); | ||
187 | + } | ||
188 | + return toAjax(userService.deleteUserByIds(userIds)); | ||
189 | + } | ||
190 | + | ||
191 | + /** | ||
192 | + * 重置密码 | ||
193 | + */ | ||
194 | + @SaCheckPermission("system:user:resetPwd") | ||
195 | + @Log(title = "用户管理", businessType = BusinessType.UPDATE) | ||
196 | + @PutMapping("/resetPwd") | ||
197 | + public R<Void> resetPwd(@RequestBody SysUser user) { | ||
198 | + userService.checkUserAllowed(user); | ||
199 | + userService.checkUserDataScope(user.getUserId()); | ||
200 | + user.setPassword(BCrypt.hashpw(user.getPassword())); | ||
201 | + return toAjax(userService.resetPwd(user)); | ||
202 | + } | ||
203 | + | ||
204 | + /** | ||
205 | + * 状态修改 | ||
206 | + */ | ||
207 | + @SaCheckPermission("system:user:edit") | ||
208 | + @Log(title = "用户管理", businessType = BusinessType.UPDATE) | ||
209 | + @PutMapping("/changeStatus") | ||
210 | + public R<Void> changeStatus(@RequestBody SysUser user) { | ||
211 | + userService.checkUserAllowed(user); | ||
212 | + userService.checkUserDataScope(user.getUserId()); | ||
213 | + return toAjax(userService.updateUserStatus(user)); | ||
214 | + } | ||
215 | + | ||
216 | + /** | ||
217 | + * 根据用户编号获取授权角色 | ||
218 | + * | ||
219 | + * @param userId 用户ID | ||
220 | + */ | ||
221 | + @SaCheckPermission("system:user:query") | ||
222 | + @GetMapping("/authRole/{userId}") | ||
223 | + public R<Map<String, Object>> authRole(@PathVariable Long userId) { | ||
224 | + SysUser user = userService.selectUserById(userId); | ||
225 | + List<SysRole> roles = roleService.selectRolesByUserId(userId); | ||
226 | + Map<String, Object> ajax = new HashMap<>(); | ||
227 | + ajax.put("user", user); | ||
228 | + ajax.put("roles", LoginHelper.isAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isAdmin())); | ||
229 | + return R.ok(ajax); | ||
230 | + } | ||
231 | + | ||
232 | + /** | ||
233 | + * 用户授权角色 | ||
234 | + * | ||
235 | + * @param userId 用户Id | ||
236 | + * @param roleIds 角色ID串 | ||
237 | + */ | ||
238 | + @SaCheckPermission("system:user:edit") | ||
239 | + @Log(title = "用户管理", businessType = BusinessType.GRANT) | ||
240 | + @PutMapping("/authRole") | ||
241 | + public R<Void> insertAuthRole(Long userId, Long[] roleIds) { | ||
242 | + userService.checkUserDataScope(userId); | ||
243 | + userService.insertUserAuth(userId, roleIds); | ||
244 | + return R.ok(); | ||
245 | + } | ||
246 | + | ||
247 | + /** | ||
248 | + * 获取部门树列表 | ||
249 | + */ | ||
250 | + @SaCheckPermission("system:user:list") | ||
251 | + @GetMapping("/deptTree") | ||
252 | + public R<List<Tree<Long>>> deptTree(SysDept dept) { | ||
253 | + return R.ok(deptService.selectDeptTreeList(dept)); | ||
254 | + } | ||
255 | + | ||
256 | +} |
1 | +--- # 监控中心配置 | ||
2 | +spring.boot.admin.client: | ||
3 | + # 增加客户端开关 | ||
4 | + enabled: true | ||
5 | + url: http://localhost:9090/admin | ||
6 | + instance: | ||
7 | + service-host-type: IP | ||
8 | + username: ruoyi | ||
9 | + password: 123456 | ||
10 | + | ||
11 | +--- # xxl-job 配置 | ||
12 | +xxl.job: | ||
13 | + # 执行器开关 | ||
14 | + enabled: true | ||
15 | + # 调度中心地址:如调度中心集群部署存在多个地址则用逗号分隔。 | ||
16 | + admin-addresses: http://localhost:9100/xxl-job-admin | ||
17 | + # 执行器通讯TOKEN:非空时启用 | ||
18 | + access-token: xxl-job | ||
19 | + executor: | ||
20 | + # 执行器AppName:执行器心跳注册分组依据;为空则关闭自动注册 | ||
21 | + appname: xxl-job-executor | ||
22 | + # 28080 端口 随着主应用端口飘逸 避免集群冲突 | ||
23 | + port: 2${server.port} | ||
24 | + # 执行器注册:默认IP:PORT | ||
25 | + address: | ||
26 | + # 执行器IP:默认自动获取IP | ||
27 | + ip: | ||
28 | + # 执行器运行日志文件存储磁盘路径 | ||
29 | + logpath: ./logs/xxl-job | ||
30 | + # 执行器日志文件保存天数:大于3生效 | ||
31 | + logretentiondays: 30 | ||
32 | + | ||
33 | +--- # 数据源配置 | ||
34 | +spring: | ||
35 | + datasource: | ||
36 | + type: com.zaxxer.hikari.HikariDataSource | ||
37 | + # 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content | ||
38 | + dynamic: | ||
39 | + # 性能分析插件(有性能损耗 不建议生产环境使用) | ||
40 | + p6spy: true | ||
41 | + # 设置默认的数据源或者数据源组,默认值即为 master | ||
42 | + primary: master | ||
43 | + # 严格模式 匹配不到数据源则报错 | ||
44 | + strict: true | ||
45 | + datasource: | ||
46 | + # 主库数据源 | ||
47 | + master: | ||
48 | + type: ${spring.datasource.type} | ||
49 | + driverClassName: com.mysql.cj.jdbc.Driver | ||
50 | + # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562 | ||
51 | + # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题) | ||
52 | + url: jdbc:mysql://192.168.1.18:3306/ruoyi-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true | ||
53 | + username: root | ||
54 | + password: root | ||
55 | + # 从库数据源 | ||
56 | + slave: | ||
57 | + lazy: true | ||
58 | + type: ${spring.datasource.type} | ||
59 | + driverClassName: com.mysql.cj.jdbc.Driver | ||
60 | + url: jdbc:mysql://192.168.1.18:3306/ruoyi-vue2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true | ||
61 | + username: root | ||
62 | + password: root | ||
63 | + hikari: | ||
64 | + # 最大连接池数量 | ||
65 | + maxPoolSize: 20 | ||
66 | + # 最小空闲线程数量 | ||
67 | + minIdle: 10 | ||
68 | + # 配置获取连接等待超时的时间 | ||
69 | + connectionTimeout: 30000 | ||
70 | + # 校验超时时间 | ||
71 | + validationTimeout: 5000 | ||
72 | + # 空闲连接存活最大时间,默认10分钟 | ||
73 | + idleTimeout: 600000 | ||
74 | + # 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟 | ||
75 | + maxLifetime: 1800000 | ||
76 | + # 多久检查一次连接的活性 | ||
77 | + keepaliveTime: 30000 | ||
78 | + shardingsphere: | ||
79 | + datasource: | ||
80 | + names: ds0,ds1 | ||
81 | + ds0: | ||
82 | + type: com.zaxxer.hikari.HikariDataSource | ||
83 | + driver-class-name: com.mysql.cj.jdbc.Driver | ||
84 | + url: jdbc:mysql://192.168.1.18:3306/ruoyi-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true | ||
85 | + username: root | ||
86 | + password: root | ||
87 | + ds1: | ||
88 | + type: com.zaxxer.hikari.HikariDataSource | ||
89 | + driver-class-name: com.mysql.cj.jdbc.Driver | ||
90 | + url: jdbc:mysql://192.168.1.18:3306/ruoyi-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true | ||
91 | + username: root | ||
92 | + password: root | ||
93 | + rules: # 配置表规则 | ||
94 | + sharding: | ||
95 | + # 表策略配置 | ||
96 | + tables: | ||
97 | + # iot_device_log 是逻辑表 | ||
98 | + iot_device_log: | ||
99 | + actualDataNodes: ds0.iot_device_log_$->{2025}0$->{1..9},ds0.iot_device_log_$->{2025}1$->{0..2} | ||
100 | + tableStrategy: | ||
101 | + # 使用标准分片策略 | ||
102 | + standard: | ||
103 | + # 配置分片字段 | ||
104 | + shardingColumn: create_time | ||
105 | + # 分片算法名称,不支持大写字母和下划线,否则启动就会报错 | ||
106 | + shardingAlgorithmName: time-sharding-algorithm | ||
107 | + # 分片算法配置 | ||
108 | + shardingAlgorithms: | ||
109 | + # 分片算法名称,不支持大写字母和下划线,否则启动就会报错 | ||
110 | + time-sharding-algorithm: | ||
111 | + # 类型:自定义策略 | ||
112 | + type: CLASS_BASED | ||
113 | + props: | ||
114 | + # 分片策略 | ||
115 | + strategy: standard | ||
116 | + # 分片算法类 | ||
117 | + algorithmClassName: com.ruoyi.framework.config.sharding.TimeShardingAlgorithm | ||
118 | + props: | ||
119 | + sql-show: true # 是否打印 ShardingSphere 生成的 SQL | ||
120 | + show-process-log: true # 是否显示处理日志 | ||
121 | + | ||
122 | + | ||
123 | + | ||
124 | +--- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉) | ||
125 | +spring: | ||
126 | + redis: | ||
127 | + # 地址 | ||
128 | + host: 192.168.1.18 | ||
129 | + # 端口,默认为6379 | ||
130 | + port: 6379 | ||
131 | + # 数据库索引 | ||
132 | + database: 0 | ||
133 | + # 密码(如没有密码请注释掉) | ||
134 | + password: zkqk666888 | ||
135 | + # 连接超时时间 | ||
136 | + timeout: 10s | ||
137 | + # 是否开启ssl | ||
138 | + ssl: false | ||
139 | + | ||
140 | +redisson: | ||
141 | + # redis key前缀 | ||
142 | + keyPrefix: | ||
143 | + # 线程池数量 | ||
144 | + threads: 4 | ||
145 | + # Netty线程池数量 | ||
146 | + nettyThreads: 8 | ||
147 | + # 单节点配置 | ||
148 | + singleServerConfig: | ||
149 | + # 客户端名称 | ||
150 | + clientName: ${ruoyi.name} | ||
151 | + # 最小空闲连接数 | ||
152 | + connectionMinimumIdleSize: 8 | ||
153 | + # 连接池大小 | ||
154 | + connectionPoolSize: 32 | ||
155 | + # 连接空闲超时,单位:毫秒 | ||
156 | + idleConnectionTimeout: 10000 | ||
157 | + # 命令等待超时,单位:毫秒 | ||
158 | + timeout: 3000 | ||
159 | + # 发布和订阅连接池大小 | ||
160 | + subscriptionConnectionPoolSize: 50 | ||
161 | + | ||
162 | +--- # mail 邮件发送 | ||
163 | +mail: | ||
164 | + enabled: false | ||
165 | + host: smtp.163.com | ||
166 | + port: 465 | ||
167 | + # 是否需要用户名密码验证 | ||
168 | + auth: true | ||
169 | + # 发送方,遵循RFC-822标准 | ||
170 | + from: xxx@163.com | ||
171 | + # 用户名(注意:如果使用foxmail邮箱,此处user为qq号) | ||
172 | + user: xxx@163.com | ||
173 | + # 密码(注意,某些邮箱需要为SMTP服务单独设置密码,详情查看相关帮助) | ||
174 | + pass: xxxxxxxxxx | ||
175 | + # 使用 STARTTLS安全连接,STARTTLS是对纯文本通信协议的扩展。 | ||
176 | + starttlsEnable: true | ||
177 | + # 使用SSL安全连接 | ||
178 | + sslEnable: true | ||
179 | + # SMTP超时时长,单位毫秒,缺省值不超时 | ||
180 | + timeout: 0 | ||
181 | + # Socket连接超时值,单位毫秒,缺省值不超时 | ||
182 | + connectionTimeout: 0 | ||
183 | + | ||
184 | +--- # sms 短信 支持 阿里云 腾讯云 云片 等等各式各样的短信服务商 | ||
185 | +# https://wind.kim/doc/start 文档地址 各个厂商可同时使用 | ||
186 | +sms: | ||
187 | + # 阿里云 dysmsapi.aliyuncs.com | ||
188 | + alibaba: | ||
189 | + #请求地址 默认为 dysmsapi.aliyuncs.com 如无特殊改变可以不用设置 | ||
190 | + requestUrl: dysmsapi.aliyuncs.com | ||
191 | + #阿里云的accessKey | ||
192 | + accessKeyId: xxxxxxx | ||
193 | + #阿里云的accessKeySecret | ||
194 | + accessKeySecret: xxxxxxx | ||
195 | + #短信签名 | ||
196 | + signature: 测试 | ||
197 | + tencent: | ||
198 | + #请求地址默认为 sms.tencentcloudapi.com 如无特殊改变可不用设置 | ||
199 | + requestUrl: sms.tencentcloudapi.com | ||
200 | + #腾讯云的accessKey | ||
201 | + accessKeyId: xxxxxxx | ||
202 | + #腾讯云的accessKeySecret | ||
203 | + accessKeySecret: xxxxxxx | ||
204 | + #短信签名 | ||
205 | + signature: 测试 | ||
206 | + #短信sdkAppId | ||
207 | + sdkAppId: appid | ||
208 | + #地域信息默认为 ap-guangzhou 如无特殊改变可不用设置 | ||
209 | + territory: ap-guangzhou |
1 | +--- # 临时文件存储位置 避免临时文件被系统清理报错 | ||
2 | +spring.servlet.multipart.location: /ruoyi/server/temp | ||
3 | + | ||
4 | +--- # 监控中心配置 | ||
5 | +spring.boot.admin.client: | ||
6 | + # 增加客户端开关 | ||
7 | + enabled: true | ||
8 | + url: http://localhost:9090/admin | ||
9 | + instance: | ||
10 | + service-host-type: IP | ||
11 | + username: ruoyi | ||
12 | + password: 123456 | ||
13 | + | ||
14 | +--- # xxl-job 配置 | ||
15 | +xxl.job: | ||
16 | + # 执行器开关 | ||
17 | + enabled: true | ||
18 | + # 调度中心地址:如调度中心集群部署存在多个地址则用逗号分隔。 | ||
19 | + admin-addresses: http://localhost:9100/xxl-job-admin | ||
20 | + # 执行器通讯TOKEN:非空时启用 | ||
21 | + access-token: xxl-job | ||
22 | + executor: | ||
23 | + # 执行器AppName:执行器心跳注册分组依据;为空则关闭自动注册 | ||
24 | + appname: xxl-job-executor | ||
25 | + # 28080 端口 随着主应用端口飘逸 避免集群冲突 | ||
26 | + port: 2${server.port} | ||
27 | + # 执行器注册:默认IP:PORT | ||
28 | + address: | ||
29 | + # 执行器IP:默认自动获取IP | ||
30 | + ip: | ||
31 | + # 执行器运行日志文件存储磁盘路径 | ||
32 | + logpath: ./logs/xxl-job | ||
33 | + # 执行器日志文件保存天数:大于3生效 | ||
34 | + logretentiondays: 30 | ||
35 | + | ||
36 | +--- # 数据源配置 | ||
37 | +spring: | ||
38 | + datasource: | ||
39 | + type: com.zaxxer.hikari.HikariDataSource | ||
40 | + # 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content | ||
41 | + dynamic: | ||
42 | + # 性能分析插件(有性能损耗 不建议生产环境使用) | ||
43 | + p6spy: false | ||
44 | + # 设置默认的数据源或者数据源组,默认值即为 master | ||
45 | + primary: master | ||
46 | + # 严格模式 匹配不到数据源则报错 | ||
47 | + strict: true | ||
48 | + datasource: | ||
49 | + # 主库数据源 | ||
50 | + master: | ||
51 | + type: ${spring.datasource.type} | ||
52 | + driverClassName: com.mysql.cj.jdbc.Driver | ||
53 | + # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562 | ||
54 | + # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题) | ||
55 | + url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true | ||
56 | + username: root | ||
57 | + password: root | ||
58 | + # 从库数据源 | ||
59 | + slave: | ||
60 | + lazy: true | ||
61 | + type: ${spring.datasource.type} | ||
62 | + driverClassName: com.mysql.cj.jdbc.Driver | ||
63 | + url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true | ||
64 | + username: | ||
65 | + password: | ||
66 | +# oracle: | ||
67 | +# type: ${spring.datasource.type} | ||
68 | +# driverClassName: oracle.jdbc.OracleDriver | ||
69 | +# url: jdbc:oracle:thin:@//localhost:1521/XE | ||
70 | +# username: ROOT | ||
71 | +# password: root | ||
72 | +# postgres: | ||
73 | +# type: ${spring.datasource.type} | ||
74 | +# driverClassName: org.postgresql.Driver | ||
75 | +# url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true | ||
76 | +# username: root | ||
77 | +# password: root | ||
78 | +# sqlserver: | ||
79 | +# type: ${spring.datasource.type} | ||
80 | +# driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver | ||
81 | +# url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true | ||
82 | +# username: SA | ||
83 | +# password: root | ||
84 | + hikari: | ||
85 | + # 最大连接池数量 | ||
86 | + maxPoolSize: 20 | ||
87 | + # 最小空闲线程数量 | ||
88 | + minIdle: 10 | ||
89 | + # 配置获取连接等待超时的时间 | ||
90 | + connectionTimeout: 30000 | ||
91 | + # 校验超时时间 | ||
92 | + validationTimeout: 5000 | ||
93 | + # 空闲连接存活最大时间,默认10分钟 | ||
94 | + idleTimeout: 600000 | ||
95 | + # 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟 | ||
96 | + maxLifetime: 1800000 | ||
97 | + # 多久检查一次连接的活性 | ||
98 | + keepaliveTime: 30000 | ||
99 | + | ||
100 | +--- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉) | ||
101 | +spring: | ||
102 | + redis: | ||
103 | + # 地址 | ||
104 | + host: localhost | ||
105 | + # 端口,默认为6379 | ||
106 | + port: 6379 | ||
107 | + # 数据库索引 | ||
108 | + database: 0 | ||
109 | + # 密码(如没有密码请注释掉) | ||
110 | + # password: | ||
111 | + # 连接超时时间 | ||
112 | + timeout: 10s | ||
113 | + # 是否开启ssl | ||
114 | + ssl: false | ||
115 | + | ||
116 | +redisson: | ||
117 | + # redis key前缀 | ||
118 | + keyPrefix: | ||
119 | + # 线程池数量 | ||
120 | + threads: 16 | ||
121 | + # Netty线程池数量 | ||
122 | + nettyThreads: 32 | ||
123 | + # 单节点配置 | ||
124 | + singleServerConfig: | ||
125 | + # 客户端名称 | ||
126 | + clientName: ${ruoyi.name} | ||
127 | + # 最小空闲连接数 | ||
128 | + connectionMinimumIdleSize: 32 | ||
129 | + # 连接池大小 | ||
130 | + connectionPoolSize: 64 | ||
131 | + # 连接空闲超时,单位:毫秒 | ||
132 | + idleConnectionTimeout: 10000 | ||
133 | + # 命令等待超时,单位:毫秒 | ||
134 | + timeout: 3000 | ||
135 | + # 发布和订阅连接池大小 | ||
136 | + subscriptionConnectionPoolSize: 50 | ||
137 | + | ||
138 | +--- # mail 邮件发送 | ||
139 | +mail: | ||
140 | + enabled: false | ||
141 | + host: smtp.163.com | ||
142 | + port: 465 | ||
143 | + # 是否需要用户名密码验证 | ||
144 | + auth: true | ||
145 | + # 发送方,遵循RFC-822标准 | ||
146 | + from: xxx@163.com | ||
147 | + # 用户名(注意:如果使用foxmail邮箱,此处user为qq号) | ||
148 | + user: xxx@163.com | ||
149 | + # 密码(注意,某些邮箱需要为SMTP服务单独设置密码,详情查看相关帮助) | ||
150 | + pass: xxxxxxxxxx | ||
151 | + # 使用 STARTTLS安全连接,STARTTLS是对纯文本通信协议的扩展。 | ||
152 | + starttlsEnable: true | ||
153 | + # 使用SSL安全连接 | ||
154 | + sslEnable: true | ||
155 | + # SMTP超时时长,单位毫秒,缺省值不超时 | ||
156 | + timeout: 0 | ||
157 | + # Socket连接超时值,单位毫秒,缺省值不超时 | ||
158 | + connectionTimeout: 0 | ||
159 | + | ||
160 | +--- # sms 短信 支持 阿里云 腾讯云 云片 等等各式各样的短信服务商 | ||
161 | +# https://wind.kim/doc/start 文档地址 各个厂商可同时使用 | ||
162 | +sms: | ||
163 | + # 阿里云 dysmsapi.aliyuncs.com | ||
164 | + alibaba: | ||
165 | + #请求地址 默认为 dysmsapi.aliyuncs.com 如无特殊改变可以不用设置 | ||
166 | + requestUrl: dysmsapi.aliyuncs.com | ||
167 | + #阿里云的accessKey | ||
168 | + accessKeyId: xxxxxxx | ||
169 | + #阿里云的accessKeySecret | ||
170 | + accessKeySecret: xxxxxxx | ||
171 | + #短信签名 | ||
172 | + signature: 测试 | ||
173 | + tencent: | ||
174 | + #请求地址默认为 sms.tencentcloudapi.com 如无特殊改变可不用设置 | ||
175 | + requestUrl: sms.tencentcloudapi.com | ||
176 | + #腾讯云的accessKey | ||
177 | + accessKeyId: xxxxxxx | ||
178 | + #腾讯云的accessKeySecret | ||
179 | + accessKeySecret: xxxxxxx | ||
180 | + #短信签名 | ||
181 | + signature: 测试 | ||
182 | + #短信sdkAppId | ||
183 | + sdkAppId: appid | ||
184 | + #地域信息默认为 ap-guangzhou 如无特殊改变可不用设置 | ||
185 | + territory: ap-guangzhou |
scm-admin/src/main/resources/application.yml
0 → 100644
1 | +# 项目相关配置 | ||
2 | +ruoyi: | ||
3 | + # 名称 | ||
4 | + name: RuoYi-Vue-Plus | ||
5 | + # 版本 | ||
6 | + version: ${ruoyi-vue-plus.version} | ||
7 | + # 版权年份 | ||
8 | + copyrightYear: 2023 | ||
9 | + # 缓存懒加载 | ||
10 | + cacheLazy: false | ||
11 | + | ||
12 | +captcha: | ||
13 | + # 页面 <参数设置> 可开启关闭 验证码校验 | ||
14 | + # 验证码类型 math 数组计算 char 字符验证 | ||
15 | + type: MATH | ||
16 | + # line 线段干扰 circle 圆圈干扰 shear 扭曲干扰 | ||
17 | + category: CIRCLE | ||
18 | + # 数字验证码位数 | ||
19 | + numberLength: 1 | ||
20 | + # 字符验证码长度 | ||
21 | + charLength: 4 | ||
22 | + | ||
23 | +# 开发环境配置 | ||
24 | +server: | ||
25 | + # 服务器的HTTP端口,默认为8080 | ||
26 | + port: 8080 | ||
27 | + servlet: | ||
28 | + # 应用的访问路径 | ||
29 | + context-path: / | ||
30 | + # undertow 配置 | ||
31 | + undertow: | ||
32 | + # HTTP post内容的最大大小。当值为-1时,默认值为大小是无限的 | ||
33 | + max-http-post-size: -1 | ||
34 | + # 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理 | ||
35 | + # 每块buffer的空间大小,越小的空间被利用越充分 | ||
36 | + buffer-size: 512 | ||
37 | + # 是否分配的直接内存 | ||
38 | + direct-buffers: true | ||
39 | + threads: | ||
40 | + # 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程 | ||
41 | + io: 8 | ||
42 | + # 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载 | ||
43 | + worker: 256 | ||
44 | + | ||
45 | +# 日志配置 | ||
46 | +logging: | ||
47 | + level: | ||
48 | + com.ruoyi: @logging.level@ | ||
49 | + org.springframework: warn | ||
50 | + config: classpath:logback-plus.xml | ||
51 | + | ||
52 | +# 用户配置 | ||
53 | +user: | ||
54 | + password: | ||
55 | + # 密码最大错误次数 | ||
56 | + maxRetryCount: 5 | ||
57 | + # 密码锁定时间(默认10分钟) | ||
58 | + lockTime: 10 | ||
59 | + | ||
60 | +# Spring配置 | ||
61 | +spring: | ||
62 | + application: | ||
63 | + name: ${ruoyi.name} | ||
64 | + # 资源信息 | ||
65 | + messages: | ||
66 | + # 国际化资源文件路径 | ||
67 | + basename: i18n/messages | ||
68 | + profiles: | ||
69 | + active: @profiles.active@ | ||
70 | + # 文件上传 | ||
71 | + servlet: | ||
72 | + multipart: | ||
73 | + # 单个文件大小 | ||
74 | + max-file-size: 10MB | ||
75 | + # 设置总上传的文件大小 | ||
76 | + max-request-size: 20MB | ||
77 | + # 服务模块 | ||
78 | + devtools: | ||
79 | + restart: | ||
80 | + # 热部署开关 | ||
81 | + enabled: true | ||
82 | + mvc: | ||
83 | + format: | ||
84 | + date-time: yyyy-MM-dd HH:mm:ss | ||
85 | + jackson: | ||
86 | + # 日期格式化 | ||
87 | + date-format: yyyy-MM-dd HH:mm:ss | ||
88 | + serialization: | ||
89 | + # 格式化输出 | ||
90 | + indent_output: false | ||
91 | + # 忽略无法转换的对象 | ||
92 | + fail_on_empty_beans: false | ||
93 | + deserialization: | ||
94 | + # 允许对象忽略json中不存在的属性 | ||
95 | + fail_on_unknown_properties: false | ||
96 | + | ||
97 | +# Sa-Token配置 | ||
98 | +sa-token: | ||
99 | + # token名称 (同时也是cookie名称) | ||
100 | + token-name: Authorization | ||
101 | + # token有效期 设为一天 (必定过期) 单位: 秒 | ||
102 | + timeout: 86400 | ||
103 | + # 多端不同 token 有效期 可查看 LoginHelper.loginByDevice 方法自定义 | ||
104 | + # token最低活跃时间 (指定时间无操作就过期) 单位: 秒 | ||
105 | + active-timeout: 1800 | ||
106 | + # 允许动态设置 token 有效期 | ||
107 | + dynamic-active-timeout: true | ||
108 | + # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) | ||
109 | + is-concurrent: true | ||
110 | + # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) | ||
111 | + is-share: false | ||
112 | + # 是否尝试从header里读取token | ||
113 | + is-read-header: true | ||
114 | + # 是否尝试从cookie里读取token | ||
115 | + is-read-cookie: false | ||
116 | + # token前缀 | ||
117 | + token-prefix: "Bearer" | ||
118 | + # jwt秘钥 | ||
119 | + jwt-secret-key: abcdefghijklmnopqrstuvwxyz | ||
120 | + | ||
121 | +# security配置 | ||
122 | +security: | ||
123 | + # 排除路径 | ||
124 | + excludes: | ||
125 | + # 静态资源 | ||
126 | + - /*.html | ||
127 | + - /**/*.html | ||
128 | + - /**/*.css | ||
129 | + - /**/*.js | ||
130 | + # 公共路径 | ||
131 | + - /favicon.ico | ||
132 | + - /error | ||
133 | + # swagger 文档配置 | ||
134 | + - /*/api-docs | ||
135 | + - /*/api-docs/** | ||
136 | + # actuator 监控配置 | ||
137 | + - /actuator | ||
138 | + - /actuator/** | ||
139 | + - /test/** | ||
140 | + | ||
141 | +# MyBatisPlus配置 | ||
142 | +# https://baomidou.com/config/ | ||
143 | +mybatis-plus: | ||
144 | + # 不支持多包, 如有需要可在注解配置 或 提升扫包等级 | ||
145 | + # 例如 com.**.**.mapper | ||
146 | + mapperPackage: com.ruoyi.**.mapper | ||
147 | + # 对应的 XML 文件位置 | ||
148 | + mapperLocations: classpath*:mapper/**/*Mapper.xml | ||
149 | + # 实体扫描,多个package用逗号或者分号分隔 | ||
150 | + typeAliasesPackage: com.ruoyi.**.domain | ||
151 | + # 启动时是否检查 MyBatis XML 文件的存在,默认不检查 | ||
152 | + checkConfigLocation: false | ||
153 | + configuration: | ||
154 | + # 自动驼峰命名规则(camel case)映射 | ||
155 | + mapUnderscoreToCamelCase: true | ||
156 | + # MyBatis 自动映射策略 | ||
157 | + # NONE:不启用 PARTIAL:只对非嵌套 resultMap 自动映射 FULL:对所有 resultMap 自动映射 | ||
158 | + autoMappingBehavior: PARTIAL | ||
159 | + # MyBatis 自动映射时未知列或未知属性处理策 | ||
160 | + # NONE:不做处理 WARNING:打印相关警告 FAILING:抛出异常和详细信息 | ||
161 | + autoMappingUnknownColumnBehavior: NONE | ||
162 | + # 更详细的日志输出 会有性能损耗 org.apache.ibatis.logging.stdout.StdOutImpl | ||
163 | + # 关闭日志记录 (可单纯使用 p6spy 分析) org.apache.ibatis.logging.nologging.NoLoggingImpl | ||
164 | + # 默认日志输出 org.apache.ibatis.logging.slf4j.Slf4jImpl | ||
165 | + logImpl: org.apache.ibatis.logging.nologging.NoLoggingImpl | ||
166 | + global-config: | ||
167 | + # 是否打印 Logo banner | ||
168 | + banner: true | ||
169 | + dbConfig: | ||
170 | + # 主键类型 | ||
171 | + # AUTO 自增 NONE 空 INPUT 用户输入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID | ||
172 | + idType: ASSIGN_ID | ||
173 | + # 逻辑已删除值 | ||
174 | + logicDeleteValue: 2 | ||
175 | + # 逻辑未删除值 | ||
176 | + logicNotDeleteValue: 0 | ||
177 | + # 字段验证策略之 insert,在 insert 的时候的字段验证策略 | ||
178 | + # IGNORED 忽略 NOT_NULL 非NULL NOT_EMPTY 非空 DEFAULT 默认 NEVER 不加入 SQL | ||
179 | + insertStrategy: NOT_NULL | ||
180 | + # 字段验证策略之 update,在 update 的时候的字段验证策略 | ||
181 | + updateStrategy: NOT_NULL | ||
182 | + # 字段验证策略之 select,在 select 的时候的字段验证策略既 wrapper 根据内部 entity 生成的 where 条件 | ||
183 | + where-strategy: NOT_NULL | ||
184 | + | ||
185 | +# 数据加密 | ||
186 | +mybatis-encryptor: | ||
187 | + # 是否开启加密 | ||
188 | + enable: false | ||
189 | + # 默认加密算法 | ||
190 | + algorithm: BASE64 | ||
191 | + # 编码方式 BASE64/HEX。默认BASE64 | ||
192 | + encode: BASE64 | ||
193 | + # 安全秘钥 对称算法的秘钥 如:AES,SM4 | ||
194 | + password: | ||
195 | + # 公私钥 非对称算法的公私钥 如:SM2,RSA | ||
196 | + publicKey: | ||
197 | + privateKey: | ||
198 | + | ||
199 | +springdoc: | ||
200 | + api-docs: | ||
201 | + # 是否开启接口文档 | ||
202 | + enabled: true | ||
203 | +# swagger-ui: | ||
204 | +# # 持久化认证数据 | ||
205 | +# persistAuthorization: true | ||
206 | + info: | ||
207 | + # 标题 | ||
208 | + title: '标题:${ruoyi.name}后台管理系统_接口文档' | ||
209 | + # 描述 | ||
210 | + description: '描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...' | ||
211 | + # 版本 | ||
212 | + version: '版本号: ${ruoyi-vue-plus.version}' | ||
213 | + # 作者信息 | ||
214 | + contact: | ||
215 | + name: Lion Li | ||
216 | + email: crazylionli@163.com | ||
217 | + url: https://gitee.com/dromara/RuoYi-Vue-Plus | ||
218 | + components: | ||
219 | + # 鉴权方式配置 | ||
220 | + security-schemes: | ||
221 | + apiKey: | ||
222 | + type: APIKEY | ||
223 | + in: HEADER | ||
224 | + name: ${sa-token.token-name} | ||
225 | + #这里定义了两个分组,可定义多个,也可以不定义 | ||
226 | + group-configs: | ||
227 | + - group: 1.演示模块 | ||
228 | + packages-to-scan: com.ruoyi.demo | ||
229 | + - group: 2.系统模块 | ||
230 | + packages-to-scan: com.ruoyi.web | ||
231 | + - group: 3.代码生成模块 | ||
232 | + packages-to-scan: com.ruoyi.generator | ||
233 | + | ||
234 | +# 防止XSS攻击 | ||
235 | +xss: | ||
236 | + # 过滤开关 | ||
237 | + enabled: true | ||
238 | + # 排除链接(多个用逗号分隔) | ||
239 | + excludes: /system/notice | ||
240 | + # 匹配链接 | ||
241 | + urlPatterns: /system/*,/monitor/*,/tool/* | ||
242 | + | ||
243 | +# 全局线程池相关配置 | ||
244 | +thread-pool: | ||
245 | + # 是否开启线程池 | ||
246 | + enabled: false | ||
247 | + # 队列最大长度 | ||
248 | + queueCapacity: 128 | ||
249 | + # 线程池维护线程所允许的空闲时间 | ||
250 | + keepAliveSeconds: 300 | ||
251 | + | ||
252 | +--- # 分布式锁 lock4j 全局配置 | ||
253 | +lock4j: | ||
254 | + # 获取分布式锁超时时间,默认为 3000 毫秒 | ||
255 | + acquire-timeout: 3000 | ||
256 | + # 分布式锁的超时时间,默认为 30 秒 | ||
257 | + expire: 30000 | ||
258 | + | ||
259 | +--- # Actuator 监控端点的配置项 | ||
260 | +management: | ||
261 | + endpoints: | ||
262 | + web: | ||
263 | + exposure: | ||
264 | + include: '*' | ||
265 | + endpoint: | ||
266 | + health: | ||
267 | + show-details: ALWAYS | ||
268 | + logfile: | ||
269 | + external-file: ./logs/sys-console.log |
scm-admin/src/main/resources/banner.txt
0 → 100644
1 | +Application Version: ${ruoyi-vue-plus.version} | ||
2 | +Spring Boot Version: ${spring-boot.version} | ||
3 | +__________ _____.___.__ ____ ____ __________.__ | ||
4 | +\______ \__ __ ____\__ | |__| \ \ / /_ __ ____ \______ \ | __ __ ______ | ||
5 | + | _/ | \/ _ \/ | | | ______ \ Y / | \_/ __ \ ______ | ___/ | | | \/ ___/ | ||
6 | + | | \ | ( <_> )____ | | /_____/ \ /| | /\ ___/ /_____/ | | | |_| | /\___ \ | ||
7 | + |____|_ /____/ \____// ______|__| \___/ |____/ \___ > |____| |____/____//____ > | ||
8 | + \/ \/ \/ \/ |
1 | +#错误消息 | ||
2 | +not.null=* 必须填写 | ||
3 | +user.jcaptcha.error=验证码错误 | ||
4 | +user.jcaptcha.expire=验证码已失效 | ||
5 | +user.not.exists=对不起, 您的账号:{0} 不存在. | ||
6 | +user.password.not.match=用户不存在/密码错误 | ||
7 | +user.password.retry.limit.count=密码输入错误{0}次 | ||
8 | +user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟 | ||
9 | +user.password.delete=对不起,您的账号:{0} 已被删除 | ||
10 | +user.blocked=对不起,您的账号:{0} 已禁用,请联系管理员 | ||
11 | +role.blocked=角色已封禁,请联系管理员 | ||
12 | +user.logout.success=退出成功 | ||
13 | +length.not.valid=长度必须在{min}到{max}个字符之间 | ||
14 | +user.username.not.blank=用户名不能为空 | ||
15 | +user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头 | ||
16 | +user.username.length.valid=账户长度必须在{min}到{max}个字符之间 | ||
17 | +user.password.not.blank=用户密码不能为空 | ||
18 | +user.password.length.valid=用户密码长度必须在{min}到{max}个字符之间 | ||
19 | +user.password.not.valid=* 5-50个字符 | ||
20 | +user.email.not.valid=邮箱格式错误 | ||
21 | +user.email.not.blank=邮箱不能为空 | ||
22 | +user.phonenumber.not.blank=用户手机号不能为空 | ||
23 | +user.mobile.phone.number.not.valid=手机号格式错误 | ||
24 | +user.login.success=登录成功 | ||
25 | +user.register.success=注册成功 | ||
26 | +user.register.save.error=保存用户 {0} 失败,注册账号已存在 | ||
27 | +user.register.error=注册失败,请联系系统管理人员 | ||
28 | +user.notfound=请重新登录 | ||
29 | +user.forcelogout=管理员强制退出,请重新登录 | ||
30 | +user.unknown.error=未知错误,请重新登录 | ||
31 | +##文件上传消息 | ||
32 | +upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB! | ||
33 | +upload.filename.exceed.length=上传的文件名最长{0}个字符 | ||
34 | +##权限 | ||
35 | +no.permission=您没有数据的权限,请联系管理员添加权限 [{0}] | ||
36 | +no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}] | ||
37 | +no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}] | ||
38 | +no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}] | ||
39 | +no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}] | ||
40 | +no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}] | ||
41 | +repeat.submit.message=不允许重复提交,请稍候再试 | ||
42 | +rate.limiter.message=访问过于频繁,请稍候再试 | ||
43 | +sms.code.not.blank=短信验证码不能为空 | ||
44 | +sms.code.retry.limit.count=短信验证码输入错误{0}次 | ||
45 | +sms.code.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{1}分钟 | ||
46 | +email.code.not.blank=邮箱验证码不能为空 | ||
47 | +email.code.retry.limit.count=邮箱验证码输入错误{0}次 | ||
48 | +email.code.retry.limit.exceed=邮箱验证码输入错误{0}次,帐户锁定{1}分钟 | ||
49 | +xcx.code.not.blank=小程序code不能为空 |
1 | +#错误消息 | ||
2 | +not.null=* Required fill in | ||
3 | +user.jcaptcha.error=Captcha error | ||
4 | +user.jcaptcha.expire=Captcha invalid | ||
5 | +user.not.exists=Sorry, your account: {0} does not exist | ||
6 | +user.password.not.match=User does not exist/Password error | ||
7 | +user.password.retry.limit.count=Password input error {0} times | ||
8 | +user.password.retry.limit.exceed=Password input error {0} times, account locked for {1} minutes | ||
9 | +user.password.delete=Sorry, your account:{0} has been deleted | ||
10 | +user.blocked=Sorry, your account: {0} has been disabled. Please contact the administrator | ||
11 | +role.blocked=Role disabled,please contact administrators | ||
12 | +user.logout.success=Exit successful | ||
13 | +length.not.valid=The length must be between {min} and {max} characters | ||
14 | +user.username.not.blank=Username cannot be blank | ||
15 | +user.username.not.valid=* 2 to 20 chinese characters, letters, numbers or underscores, and must start with a non number | ||
16 | +user.username.length.valid=Account length must be between {min} and {max} characters | ||
17 | +user.password.not.blank=Password cannot be empty | ||
18 | +user.password.length.valid=Password length must be between {min} and {max} characters | ||
19 | +user.password.not.valid=* 5-50 characters | ||
20 | +user.email.not.valid=Mailbox format error | ||
21 | +user.email.not.blank=Mailbox cannot be blank | ||
22 | +user.phonenumber.not.blank=Phone number cannot be blank | ||
23 | +user.mobile.phone.number.not.valid=Phone number format error | ||
24 | +user.login.success=Login successful | ||
25 | +user.register.success=Register successful | ||
26 | +user.register.save.error=Failed to save user {0}, The registered account already exists | ||
27 | +user.register.error=Register failed, please contact system administrator | ||
28 | +user.notfound=Please login again | ||
29 | +user.forcelogout=The administrator is forced to exit,please login again | ||
30 | +user.unknown.error=Unknown error, please login again | ||
31 | +##文件上传消息 | ||
32 | +upload.exceed.maxSize=The uploaded file size exceeds the limit file size!<br/>the maximum allowed file size is:{0}MB! | ||
33 | +upload.filename.exceed.length=The maximum length of uploaded file name is {0} characters | ||
34 | +##权限 | ||
35 | +no.permission=You do not have permission to the data,please contact your administrator to add permissions [{0}] | ||
36 | +no.create.permission=You do not have permission to create data,please contact your administrator to add permissions [{0}] | ||
37 | +no.update.permission=You do not have permission to modify data,please contact your administrator to add permissions [{0}] | ||
38 | +no.delete.permission=You do not have permission to delete data,please contact your administrator to add permissions [{0}] | ||
39 | +no.export.permission=You do not have permission to export data,please contact your administrator to add permissions [{0}] | ||
40 | +no.view.permission=You do not have permission to view data,please contact your administrator to add permissions [{0}] | ||
41 | +repeat.submit.message=Repeat submit is not allowed, please try again later | ||
42 | +rate.limiter.message=Visit too frequently, please try again later | ||
43 | +sms.code.not.blank=Sms code cannot be blank | ||
44 | +sms.code.retry.limit.count=Sms code input error {0} times | ||
45 | +sms.code.retry.limit.exceed=Sms code input error {0} times, account locked for {1} minutes | ||
46 | +email.code.not.blank=Email code cannot be blank | ||
47 | +email.code.retry.limit.count=Email code input error {0} times | ||
48 | +email.code.retry.limit.exceed=Email code input error {0} times, account locked for {1} minutes | ||
49 | +xcx.code.not.blank=Mini program code cannot be blank |
1 | +#错误消息 | ||
2 | +not.null=* 必须填写 | ||
3 | +user.jcaptcha.error=验证码错误 | ||
4 | +user.jcaptcha.expire=验证码已失效 | ||
5 | +user.not.exists=对不起, 您的账号:{0} 不存在. | ||
6 | +user.password.not.match=用户不存在/密码错误 | ||
7 | +user.password.retry.limit.count=密码输入错误{0}次 | ||
8 | +user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟 | ||
9 | +user.password.delete=对不起,您的账号:{0} 已被删除 | ||
10 | +user.blocked=对不起,您的账号:{0} 已禁用,请联系管理员 | ||
11 | +role.blocked=角色已封禁,请联系管理员 | ||
12 | +user.logout.success=退出成功 | ||
13 | +length.not.valid=长度必须在{min}到{max}个字符之间 | ||
14 | +user.username.not.blank=用户名不能为空 | ||
15 | +user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头 | ||
16 | +user.username.length.valid=账户长度必须在{min}到{max}个字符之间 | ||
17 | +user.password.not.blank=用户密码不能为空 | ||
18 | +user.password.length.valid=用户密码长度必须在{min}到{max}个字符之间 | ||
19 | +user.password.not.valid=* 5-50个字符 | ||
20 | +user.email.not.valid=邮箱格式错误 | ||
21 | +user.email.not.blank=邮箱不能为空 | ||
22 | +user.phonenumber.not.blank=用户手机号不能为空 | ||
23 | +user.mobile.phone.number.not.valid=手机号格式错误 | ||
24 | +user.login.success=登录成功 | ||
25 | +user.register.success=注册成功 | ||
26 | +user.register.save.error=保存用户 {0} 失败,注册账号已存在 | ||
27 | +user.register.error=注册失败,请联系系统管理人员 | ||
28 | +user.notfound=请重新登录 | ||
29 | +user.forcelogout=管理员强制退出,请重新登录 | ||
30 | +user.unknown.error=未知错误,请重新登录 | ||
31 | +##文件上传消息 | ||
32 | +upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB! | ||
33 | +upload.filename.exceed.length=上传的文件名最长{0}个字符 | ||
34 | +##权限 | ||
35 | +no.permission=您没有数据的权限,请联系管理员添加权限 [{0}] | ||
36 | +no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}] | ||
37 | +no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}] | ||
38 | +no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}] | ||
39 | +no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}] | ||
40 | +no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}] | ||
41 | +repeat.submit.message=不允许重复提交,请稍候再试 | ||
42 | +rate.limiter.message=访问过于频繁,请稍候再试 | ||
43 | +sms.code.not.blank=短信验证码不能为空 | ||
44 | +sms.code.retry.limit.count=短信验证码输入错误{0}次 | ||
45 | +sms.code.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{1}分钟 | ||
46 | +email.code.not.blank=邮箱验证码不能为空 | ||
47 | +email.code.retry.limit.count=邮箱验证码输入错误{0}次 | ||
48 | +email.code.retry.limit.exceed=邮箱验证码输入错误{0}次,帐户锁定{1}分钟 | ||
49 | +xcx.code.not.blank=小程序code不能为空 |
scm-admin/src/main/resources/ip2region.xdb
0 → 100644
No preview for this file type
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<configuration> | ||
3 | + <property name="log.path" value="./logs"/> | ||
4 | + <property name="console.log.pattern" | ||
5 | + value="%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/> | ||
6 | + <property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"/> | ||
7 | + | ||
8 | + <!-- 控制台输出 --> | ||
9 | + <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> | ||
10 | + <encoder> | ||
11 | + <pattern>${console.log.pattern}</pattern> | ||
12 | + <charset>utf-8</charset> | ||
13 | + </encoder> | ||
14 | + </appender> | ||
15 | + | ||
16 | + <!-- 控制台输出 --> | ||
17 | + <appender name="file_console" class="ch.qos.logback.core.rolling.RollingFileAppender"> | ||
18 | + <file>${log.path}/sys-console.log</file> | ||
19 | + <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> | ||
20 | + <!-- 日志文件名格式 --> | ||
21 | + <fileNamePattern>${log.path}/sys-console.%d{yyyy-MM-dd}.log</fileNamePattern> | ||
22 | + <!-- 日志最大 1天 --> | ||
23 | + <maxHistory>1</maxHistory> | ||
24 | + </rollingPolicy> | ||
25 | + <encoder> | ||
26 | + <pattern>${log.pattern}</pattern> | ||
27 | + <charset>utf-8</charset> | ||
28 | + </encoder> | ||
29 | + <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> | ||
30 | + <!-- 过滤的级别 --> | ||
31 | + <level>INFO</level> | ||
32 | + </filter> | ||
33 | + </appender> | ||
34 | + | ||
35 | + <!-- 系统日志输出 --> | ||
36 | + <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender"> | ||
37 | + <file>${log.path}/sys-info.log</file> | ||
38 | + <!-- 循环政策:基于时间创建日志文件 --> | ||
39 | + <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> | ||
40 | + <!-- 日志文件名格式 --> | ||
41 | + <fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern> | ||
42 | + <!-- 日志最大的历史 60天 --> | ||
43 | + <maxHistory>60</maxHistory> | ||
44 | + </rollingPolicy> | ||
45 | + <encoder> | ||
46 | + <pattern>${log.pattern}</pattern> | ||
47 | + </encoder> | ||
48 | + <filter class="ch.qos.logback.classic.filter.LevelFilter"> | ||
49 | + <!-- 过滤的级别 --> | ||
50 | + <level>INFO</level> | ||
51 | + <!-- 匹配时的操作:接收(记录) --> | ||
52 | + <onMatch>ACCEPT</onMatch> | ||
53 | + <!-- 不匹配时的操作:拒绝(不记录) --> | ||
54 | + <onMismatch>DENY</onMismatch> | ||
55 | + </filter> | ||
56 | + </appender> | ||
57 | + | ||
58 | + <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender"> | ||
59 | + <file>${log.path}/sys-error.log</file> | ||
60 | + <!-- 循环政策:基于时间创建日志文件 --> | ||
61 | + <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> | ||
62 | + <!-- 日志文件名格式 --> | ||
63 | + <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern> | ||
64 | + <!-- 日志最大的历史 60天 --> | ||
65 | + <maxHistory>60</maxHistory> | ||
66 | + </rollingPolicy> | ||
67 | + <encoder> | ||
68 | + <pattern>${log.pattern}</pattern> | ||
69 | + </encoder> | ||
70 | + <filter class="ch.qos.logback.classic.filter.LevelFilter"> | ||
71 | + <!-- 过滤的级别 --> | ||
72 | + <level>ERROR</level> | ||
73 | + <!-- 匹配时的操作:接收(记录) --> | ||
74 | + <onMatch>ACCEPT</onMatch> | ||
75 | + <!-- 不匹配时的操作:拒绝(不记录) --> | ||
76 | + <onMismatch>DENY</onMismatch> | ||
77 | + </filter> | ||
78 | + </appender> | ||
79 | + | ||
80 | + <!-- info异步输出 --> | ||
81 | + <appender name="async_info" class="ch.qos.logback.classic.AsyncAppender"> | ||
82 | + <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 --> | ||
83 | + <discardingThreshold>0</discardingThreshold> | ||
84 | + <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 --> | ||
85 | + <queueSize>512</queueSize> | ||
86 | + <!-- 添加附加的appender,最多只能添加一个 --> | ||
87 | + <appender-ref ref="file_info"/> | ||
88 | + </appender> | ||
89 | + | ||
90 | + <!-- error异步输出 --> | ||
91 | + <appender name="async_error" class="ch.qos.logback.classic.AsyncAppender"> | ||
92 | + <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 --> | ||
93 | + <discardingThreshold>0</discardingThreshold> | ||
94 | + <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 --> | ||
95 | + <queueSize>512</queueSize> | ||
96 | + <!-- 添加附加的appender,最多只能添加一个 --> | ||
97 | + <appender-ref ref="file_error"/> | ||
98 | + </appender> | ||
99 | + | ||
100 | + <!-- 整合 skywalking 控制台输出 tid --> | ||
101 | +<!-- <appender name="console" class="ch.qos.logback.core.ConsoleAppender">--> | ||
102 | +<!-- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">--> | ||
103 | +<!-- <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">--> | ||
104 | +<!-- <pattern>[%tid] ${console.log.pattern}</pattern>--> | ||
105 | +<!-- </layout>--> | ||
106 | +<!-- <charset>utf-8</charset>--> | ||
107 | +<!-- </encoder>--> | ||
108 | +<!-- </appender>--> | ||
109 | + | ||
110 | + <!-- 整合 skywalking 推送采集日志 --> | ||
111 | +<!-- <appender name="sky_log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">--> | ||
112 | +<!-- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">--> | ||
113 | +<!-- <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">--> | ||
114 | +<!-- <pattern>[%tid] ${console.log.pattern}</pattern>--> | ||
115 | +<!-- </layout>--> | ||
116 | +<!-- <charset>utf-8</charset>--> | ||
117 | +<!-- </encoder>--> | ||
118 | +<!-- </appender>--> | ||
119 | + | ||
120 | + <!--系统操作日志--> | ||
121 | + <root level="info"> | ||
122 | + <appender-ref ref="console" /> | ||
123 | + <appender-ref ref="async_info" /> | ||
124 | + <appender-ref ref="async_error" /> | ||
125 | + <appender-ref ref="file_console" /> | ||
126 | +<!-- <appender-ref ref="sky_log"/>--> | ||
127 | + </root> | ||
128 | + | ||
129 | +</configuration> |
scm-admin/src/main/resources/sharding.yml
0 → 100644
1 | +# !!!数据源名称要和动态数据源中配置的名称一致 | ||
2 | +databaseName: master | ||
3 | + | ||
4 | +# 具体参看官网文档说明 | ||
5 | +dataSources: | ||
6 | + coupon_user_db_0: | ||
7 | + dataSourceClassName: com.zaxxer.hikari.HikariDataSource | ||
8 | + driverClassName: com.mysql.jdbc.Driver | ||
9 | + jdbcUrl: jdbc:mysql://192.168.1.18:3306/ruoyi-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true | ||
10 | + username: root | ||
11 | + password: root | ||
12 | + | ||
13 | +rules: | ||
14 | + - !SHARDING | ||
15 | + tables: # 数据分片规则配置 | ||
16 | + coupon_user: # 逻辑表名称 | ||
17 | + actualDataNodes: coupon_user_db_0.coupon_user_$->{0..9} # 由数据源名 + 表名组成(参考 Inline 语法规则) | ||
18 | + databaseStrategy: # 分库策略,缺省表示使用默认分库策略,以下的分片策略只能选其一 | ||
19 | + none: | ||
20 | + tableStrategy: # 分表策略 | ||
21 | + standard: # 用于单分片键的标准分片场景 | ||
22 | + shardingColumn: user_id # 分片列名称 | ||
23 | + shardingAlgorithmName: user_inline | ||
24 | + keyGenerateStrategy: | ||
25 | + column: id | ||
26 | + keyGeneratorName: snowflake | ||
27 | + keyGenerators: | ||
28 | + snowflake: | ||
29 | + type: SNOWFLAKE | ||
30 | + props: | ||
31 | + worker-id: 123 | ||
32 | + # 分片算法配置 | ||
33 | + shardingAlgorithms: | ||
34 | + user_inline: | ||
35 | + type: INLINE | ||
36 | + props: | ||
37 | + algorithm-expression: coupon_user_$->{user_id % 10} | ||
38 | + | ||
39 | +props: | ||
40 | + sql-show: true | ||
41 | + |
scm-admin/src/main/resources/spy.properties
0 → 100644
1 | +# p6spy 性能分析插件配置文件 | ||
2 | +modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory | ||
3 | +# 自定义日志打印 | ||
4 | +logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger | ||
5 | +#日志输出到控制台 | ||
6 | +appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger | ||
7 | +# 使用日志系统记录 sql | ||
8 | +#appender=com.p6spy.engine.spy.appender.Slf4JLogger | ||
9 | +# 设置 p6spy driver 代理 | ||
10 | +#deregisterdrivers=true | ||
11 | +# 取消JDBC URL前缀 | ||
12 | +useprefix=true | ||
13 | +# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset. | ||
14 | +excludecategories=info,debug,result,commit,resultset | ||
15 | +# 日期格式 | ||
16 | +dateformat=yyyy-MM-dd HH:mm:ss | ||
17 | +# SQL语句打印时间格式 | ||
18 | +databaseDialectTimestampFormat=yyyy-MM-dd HH:mm:ss | ||
19 | +# 实际驱动可多个 | ||
20 | +#driverlist=org.h2.Driver | ||
21 | +# 是否开启慢SQL记录 | ||
22 | +outagedetection=true | ||
23 | +# 慢SQL记录标准 2 秒 | ||
24 | +outagedetectioninterval=2 | ||
25 | +# 是否过滤 Log | ||
26 | +filter=true | ||
27 | +# 过滤 Log 时所排除的 sql 关键字,以逗号分隔 | ||
28 | +exclude=SELECT 1 |
1 | +package com.ruoyi.test; | ||
2 | + | ||
3 | +import cn.hutool.core.io.FileUtil; | ||
4 | +import cn.hutool.core.text.UnicodeUtil; | ||
5 | +import cn.hutool.http.HttpUtil; | ||
6 | +import cn.hutool.json.JSONArray; | ||
7 | +import cn.hutool.json.JSONObject; | ||
8 | +import cn.hutool.json.JSONUtil; | ||
9 | +import com.google.gson.Gson; | ||
10 | +import com.google.gson.JsonElement; | ||
11 | +import com.google.gson.JsonParser; | ||
12 | +import com.ruoyi.system.domain.Api; | ||
13 | +import com.ruoyi.system.mapper.ApiMapper; | ||
14 | +import io.micrometer.core.instrument.util.StringEscapeUtils; | ||
15 | +import org.junit.jupiter.api.BeforeAll; | ||
16 | +import org.junit.jupiter.api.BeforeEach; | ||
17 | +import org.junit.jupiter.api.DisplayName; | ||
18 | +import org.junit.jupiter.api.Test; | ||
19 | +import org.springframework.beans.factory.annotation.Autowired; | ||
20 | +import org.springframework.boot.test.context.SpringBootTest; | ||
21 | +import org.springframework.test.context.event.annotation.BeforeTestClass; | ||
22 | + | ||
23 | +import java.io.ByteArrayInputStream; | ||
24 | +import java.util.Date; | ||
25 | +import java.util.HashMap; | ||
26 | +import java.util.Map; | ||
27 | + | ||
28 | +//@SpringBootTest // 此注解只能在 springboot 主包下使用 需包含 main 方法与 yml 配置文件 | ||
29 | +@DisplayName("调用零零汽API") | ||
30 | +public class ApiTest { | ||
31 | + | ||
32 | + private ApiMapper apiMapper; | ||
33 | + | ||
34 | + private static final String BASE_API_URL = "https://sapi.007vin.com"; | ||
35 | + private static final String OPEN_ID = "489c1079b6ab49d359eced61d7d83804"; | ||
36 | + private static final String TOKEN = "8e9b584b2e09db0fb6829fc237f88efd"; | ||
37 | + private static final String VIN = "LFV3B2FY1J3513783"; | ||
38 | + private static final String MCID = "Yjt6cH07Izk7LSshO2Q%3D"; | ||
39 | + | ||
40 | + Map<String, Object> params = new HashMap<>(); | ||
41 | + | ||
42 | + @BeforeEach | ||
43 | + public void setUp() { | ||
44 | + params.put("open_id", OPEN_ID); | ||
45 | + params.put("token", TOKEN); | ||
46 | + params.put("vin", VIN); | ||
47 | + } | ||
48 | + | ||
49 | + /** | ||
50 | + * 基础车型选择 | ||
51 | + */ | ||
52 | + @DisplayName("基础车型选择") | ||
53 | + @Test | ||
54 | + public void chooseMode() { | ||
55 | + params.remove("vin"); | ||
56 | + params.put("brandCode", "vwag"); | ||
57 | + String response = HttpUtil.get(BASE_API_URL + "/api/cars/models", params); | ||
58 | + JSONObject json = JSONUtil.parseObj(response); | ||
59 | + System.out.println(json); | ||
60 | + String targetFilePath = "E:\\data\\基础车型选择.json"; // 定义目标文件路径 | ||
61 | + FileUtil.writeFromStream(new ByteArrayInputStream(json.toString().getBytes()), FileUtil.file(targetFilePath)); | ||
62 | + } | ||
63 | + | ||
64 | + /** | ||
65 | + * 车架号解析全车件车型配置 | ||
66 | + */ | ||
67 | + @DisplayName("车架号解析全车件车型配置") | ||
68 | + @Test | ||
69 | + public void test1000() { | ||
70 | + String response = HttpUtil.get(BASE_API_URL + "/api/cars/vin", params); | ||
71 | + JSONObject json = JSONUtil.parseObj(response); | ||
72 | + System.out.println(json); | ||
73 | + String targetFilePath = "E:\\data\\01车架号解析全车件车型配置.json"; // 定义目标文件路径 | ||
74 | + FileUtil.writeFromStream(new ByteArrayInputStream(json.toString().getBytes()), FileUtil.file(targetFilePath)); | ||
75 | + } | ||
76 | + | ||
77 | + | ||
78 | + /** | ||
79 | + * 全车件主组查询 | ||
80 | + */ | ||
81 | + @DisplayName("全车件主组查询") | ||
82 | + @Test | ||
83 | + public void test1002() { | ||
84 | + params.put("mcid", MCID); | ||
85 | + params.put("brandCode", "vwag"); | ||
86 | + String response = HttpUtil.get(BASE_API_URL + "/api/cars/group", params); | ||
87 | + JSONObject json = JSONUtil.parseObj(response); | ||
88 | + System.out.println(json); | ||
89 | + String targetFilePath = "E:\\data\\02全车件主组查询.json"; // 定义目标文件路径 | ||
90 | + FileUtil.writeFromStream(new ByteArrayInputStream(json.toString().getBytes()), FileUtil.file(targetFilePath)); | ||
91 | + } | ||
92 | + | ||
93 | + /** | ||
94 | + * 全车件分组查询 | ||
95 | + */ | ||
96 | + @DisplayName("全车件分组查询") | ||
97 | + @Test | ||
98 | + public void test1003() { | ||
99 | + params.put("mcid", MCID); | ||
100 | + params.put("brandCode", "vwag"); | ||
101 | + params.put("num", "0"); | ||
102 | + String response = HttpUtil.get(BASE_API_URL + "/api/cars/structure", params); | ||
103 | + JSONObject json = JSONUtil.parseObj(response); | ||
104 | + System.out.println(json); | ||
105 | + String targetFilePath = "E:\\data\\03全车件分组查询.json"; // 定义目标文件路径 | ||
106 | + FileUtil.writeFromStream(new ByteArrayInputStream(json.toString().getBytes()), FileUtil.file(targetFilePath)); | ||
107 | + } | ||
108 | + | ||
109 | + /** | ||
110 | + * 全车件零件列表查询 | ||
111 | + */ | ||
112 | + @DisplayName("全车件零件列表查询") | ||
113 | + @Test | ||
114 | + public void test1005() { | ||
115 | + params.put("mcid", MCID); | ||
116 | + params.put("brandCode", "audi"); | ||
117 | + params.put("num", "6"); | ||
118 | + params.put("mid", "615040"); | ||
119 | + params.put("subgroup", "15"); | ||
120 | + String response = HttpUtil.get(BASE_API_URL + "/api/cars/part", params); | ||
121 | + JSONObject json = JSONUtil.parseObj(response); | ||
122 | + System.out.println(json); | ||
123 | + String targetFilePath = "E:\\data\\04全车件零件列表查询.json"; // 定义目标文件路径 | ||
124 | + FileUtil.writeFromStream(new ByteArrayInputStream(json.toString().getBytes()), FileUtil.file(targetFilePath)); | ||
125 | + } | ||
126 | + | ||
127 | + /** | ||
128 | + * 基础车型选择 | ||
129 | + */ | ||
130 | + @DisplayName("品牌覆盖列表") | ||
131 | + @Test | ||
132 | + public void test0000() { | ||
133 | + String response = HttpUtil.get(BASE_API_URL + "/api/brands", params); | ||
134 | + JSONObject json = JSONUtil.parseObj(response); | ||
135 | + System.out.println(json); | ||
136 | + String targetFilePath = "E:\\data\\品牌覆盖列表.json"; | ||
137 | + FileUtil.writeFromStream(new ByteArrayInputStream(json.toString().getBytes()), FileUtil.file(targetFilePath)); | ||
138 | + } | ||
139 | + | ||
140 | + /** | ||
141 | + * 基础车型选择 | ||
142 | + */ | ||
143 | + @DisplayName("基础车型选择") | ||
144 | + @Test | ||
145 | + public void test5000() { | ||
146 | + params.put("mcid", MCID); | ||
147 | + params.put("brandCode", "audi"); | ||
148 | + params.put("num", "6"); | ||
149 | + params.put("mid", "615040"); | ||
150 | + params.put("subgroup", "15"); | ||
151 | + String response = HttpUtil.get(BASE_API_URL + "/api/cars/part", params); | ||
152 | + JSONObject json = JSONUtil.parseObj(response); | ||
153 | + System.out.println(json); | ||
154 | + String targetFilePath = "E:\\data\\04全车件零件列表查询.json"; // 定义目标文件路径 | ||
155 | + FileUtil.writeFromStream(new ByteArrayInputStream(json.toString().getBytes()), FileUtil.file(targetFilePath)); | ||
156 | + } | ||
157 | +} |
1 | +package com.ruoyi.test; | ||
2 | + | ||
3 | +import org.junit.jupiter.api.Assertions; | ||
4 | +import org.junit.jupiter.api.DisplayName; | ||
5 | +import org.junit.jupiter.api.Test; | ||
6 | + | ||
7 | +/** | ||
8 | + * 断言单元测试案例 | ||
9 | + * | ||
10 | + * @author Lion Li | ||
11 | + */ | ||
12 | +@DisplayName("断言单元测试案例") | ||
13 | +public class AssertUnitTest { | ||
14 | + | ||
15 | + @DisplayName("测试 assertEquals 方法") | ||
16 | + @Test | ||
17 | + public void testAssertEquals() { | ||
18 | + Assertions.assertEquals("666", new String("666")); | ||
19 | + Assertions.assertNotEquals("666", new String("666")); | ||
20 | + } | ||
21 | + | ||
22 | + @DisplayName("测试 assertSame 方法") | ||
23 | + @Test | ||
24 | + public void testAssertSame() { | ||
25 | + Object obj = new Object(); | ||
26 | + Object obj1 = obj; | ||
27 | + Assertions.assertSame(obj, obj1); | ||
28 | + Assertions.assertNotSame(obj, obj1); | ||
29 | + } | ||
30 | + | ||
31 | + @DisplayName("测试 assertTrue 方法") | ||
32 | + @Test | ||
33 | + public void testAssertTrue() { | ||
34 | + Assertions.assertTrue(true); | ||
35 | + Assertions.assertFalse(true); | ||
36 | + } | ||
37 | + | ||
38 | + @DisplayName("测试 assertNull 方法") | ||
39 | + @Test | ||
40 | + public void testAssertNull() { | ||
41 | + Assertions.assertNull(null); | ||
42 | + Assertions.assertNotNull(null); | ||
43 | + } | ||
44 | + | ||
45 | +} |
1 | +package com.ruoyi.test; | ||
2 | + | ||
3 | +import cn.hutool.core.io.FileUtil; | ||
4 | +import cn.hutool.http.HttpUtil; | ||
5 | +import cn.hutool.json.JSONArray; | ||
6 | +import cn.hutool.json.JSONObject; | ||
7 | +import cn.hutool.json.JSONUtil; | ||
8 | +import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||
9 | +import com.ruoyi.system.domain.BrandInfo; | ||
10 | +import com.ruoyi.system.domain.Api; | ||
11 | +import com.ruoyi.system.mapper.ApiMapper; | ||
12 | +import com.ruoyi.system.mapper.BrandInfoMapper; | ||
13 | +import org.junit.jupiter.api.BeforeEach; | ||
14 | +import org.junit.jupiter.api.DisplayName; | ||
15 | +import org.junit.jupiter.api.Test; | ||
16 | +import org.springframework.beans.factory.annotation.Autowired; | ||
17 | +import org.springframework.boot.test.context.SpringBootTest; | ||
18 | + | ||
19 | +import java.io.ByteArrayInputStream; | ||
20 | +import java.util.Date; | ||
21 | +import java.util.HashMap; | ||
22 | +import java.util.Map; | ||
23 | + | ||
24 | +@SpringBootTest // 此注解只能在 springboot 主包下使用 需包含 main 方法与 yml 配置文件 | ||
25 | +@DisplayName("调用零零汽API") | ||
26 | +public class CarDataSpider { | ||
27 | + | ||
28 | + @Autowired | ||
29 | + private ApiMapper apiMapper; | ||
30 | + @Autowired | ||
31 | + private BrandInfoMapper brandInfoMapper; | ||
32 | + | ||
33 | + private static final String BASE_API_URL = "https://sapi.007vin.com"; | ||
34 | + private static final String OPEN_ID = "489c1079b6ab49d359eced61d7d83804"; | ||
35 | + private static final String TOKEN = "8e9b584b2e09db0fb6829fc237f88efd"; | ||
36 | + private static final String VIN = "LBVFP3904BSE35458"; | ||
37 | + private static String name = null; | ||
38 | + private static String modelName = null; | ||
39 | + | ||
40 | + Map<String, Object> params = new HashMap<>(); | ||
41 | + | ||
42 | + @BeforeEach | ||
43 | + public void setUp() { | ||
44 | + params.put("open_id", OPEN_ID); | ||
45 | + params.put("token", TOKEN); | ||
46 | + params.put("vin", VIN); | ||
47 | + } | ||
48 | + | ||
49 | + @DisplayName("获取品牌信息") | ||
50 | + @Test | ||
51 | + public void saveBandInfo() { | ||
52 | + String response = HttpUtil.get(BASE_API_URL + "/api/brands", params); | ||
53 | + System.out.println(response); | ||
54 | + JSONObject json = JSONUtil.parseObj(response); | ||
55 | + String targetFilePath = "E:\\data\\所有品牌信息.json"; // 定义目标文件路径 | ||
56 | + FileUtil.writeFromStream(new ByteArrayInputStream(json.toString().getBytes()), FileUtil.file(targetFilePath)); | ||
57 | + Integer code = json.getInt("code"); | ||
58 | + if (code != 1) { | ||
59 | + System.out.println("获取品牌信息失败"); | ||
60 | + return; | ||
61 | + } | ||
62 | + JSONArray data = json.getJSONArray("data"); | ||
63 | + for (int i = 0; i < data.size(); i++) { | ||
64 | + BrandInfo brandInfo = new BrandInfo(); | ||
65 | + brandInfo.setBrandCode(data.getJSONObject(i).getStr("brandcode")); | ||
66 | + brandInfo.setName(data.getJSONObject(i).getStr("name")); | ||
67 | + brandInfo.setBrandName(data.getJSONObject(i).getStr("brandname")); | ||
68 | + brandInfo.setAcronym(data.getJSONObject(i).getStr("acronym")); | ||
69 | + brandInfo.setAreasId(data.getJSONObject(i).getInt("areas_id")); | ||
70 | + brandInfo.setHasStandardModel(data.getJSONObject(i).getBool("has_standard_model")); | ||
71 | + brandInfo.setMaintenance(data.getJSONObject(i).getInt("maintenance")); | ||
72 | + brandInfo.setIsHot(data.getJSONObject(i).getBool("is_hot")); | ||
73 | + brandInfo.setVin(data.getJSONObject(i).getBool("vin")); | ||
74 | + brandInfo.setVehicleType(data.getJSONObject(i).getInt("vehicle_type")); | ||
75 | + brandInfo.setImg(data.getJSONObject(i).getStr("img")); | ||
76 | + brandInfo.setUri(data.getJSONObject(i).getStr("uri")); | ||
77 | + brandInfo.setAreaName(data.getJSONObject(i).getStr("area_name")); | ||
78 | + System.out.println(brandInfo); | ||
79 | + brandInfoMapper.insert(brandInfo); | ||
80 | + } | ||
81 | + | ||
82 | + } | ||
83 | + | ||
84 | + /** | ||
85 | + * 车架号解析全车件车型配置 | ||
86 | + */ | ||
87 | + @DisplayName("全车型零件查询") | ||
88 | + @Test | ||
89 | + public void test1000() { | ||
90 | + | ||
91 | + Long count = apiMapper.selectCount(Wrappers.lambdaQuery(Api.class).eq(Api::getVin, VIN)); | ||
92 | + if (count > 1) { | ||
93 | + System.out.println("车架号已解析"); | ||
94 | + return; | ||
95 | + } | ||
96 | + | ||
97 | + String response = HttpUtil.get(BASE_API_URL + "/api/cars/vin", params); | ||
98 | +// String decodedResponse = UnicodeUtil.toString(response); | ||
99 | + JSONObject json = JSONUtil.parseObj(response); | ||
100 | + Integer code = json.getInt("code"); | ||
101 | + | ||
102 | + Api api = new Api(); | ||
103 | + api.setUrl("/api/cars/vin"); | ||
104 | + api.setUrlNo("1000"); | ||
105 | + api.setVin(VIN); | ||
106 | + api.setRequest(JSONUtil.toJsonStr(params)); | ||
107 | + api.setResponse(json.toString()); | ||
108 | + api.setCreateTime(new Date()); | ||
109 | + | ||
110 | + if (code != 1) { | ||
111 | + System.out.println("车架号解析失败"); | ||
112 | + System.out.println(response); | ||
113 | + apiMapper.insert(api); | ||
114 | + return; | ||
115 | + } | ||
116 | + JSONObject data = json.getJSONObject("data"); | ||
117 | + String mcid = data.getStr("mcid"); | ||
118 | + String brandCode = data.getStr("brandCode"); | ||
119 | + name = data.getStr("name"); | ||
120 | + modelName = data.getStr("model_name"); | ||
121 | + api.setBrandCode(brandCode); | ||
122 | + api.setName(name); | ||
123 | + api.setModelName(modelName); | ||
124 | + api.setData(data.toString()); | ||
125 | + apiMapper.insert(api); | ||
126 | + getMasterGroup(mcid, brandCode); | ||
127 | + } | ||
128 | + | ||
129 | + /** | ||
130 | + * 获取主组 | ||
131 | + * @param mcid | ||
132 | + */ | ||
133 | + public void getMasterGroup(String mcid, String brandCode) { | ||
134 | + params.put("mcid", mcid); | ||
135 | + params.put("brandCode", brandCode); | ||
136 | + String response = HttpUtil.get(BASE_API_URL + "/api/cars/group", params); | ||
137 | +// String decodedResponse = UnicodeUtil.toString(response); | ||
138 | + JSONObject json = JSONUtil.parseObj(response); | ||
139 | + Integer code = json.getInt("code"); | ||
140 | + | ||
141 | + Api api = new Api(); | ||
142 | + api.setUrl("/api/cars/group"); | ||
143 | + api.setUrlNo("1002"); | ||
144 | + api.setVin(VIN); | ||
145 | + api.setRequest(JSONUtil.toJsonStr(params)); | ||
146 | + api.setResponse(json.toString()); | ||
147 | + api.setCreateTime(new Date()); | ||
148 | + api.setBrandCode(brandCode); | ||
149 | + api.setName(name); | ||
150 | + api.setModelName(modelName); | ||
151 | + | ||
152 | + if (code != 1) { | ||
153 | + System.out.println("查询全车主组失败"); | ||
154 | + System.out.println(response); | ||
155 | + apiMapper.insert(api); | ||
156 | + return; | ||
157 | + } | ||
158 | + | ||
159 | + JSONArray jsonArray = json.getJSONArray("data"); | ||
160 | + api.setNum(jsonArray.size()); | ||
161 | + api.setData(jsonArray.toString()); | ||
162 | + apiMapper.insert(api); | ||
163 | + | ||
164 | + for (int i = 0; i < jsonArray.size(); i++) { | ||
165 | + JSONObject jsonObject = jsonArray.getJSONObject(i); | ||
166 | + String num = jsonObject.getStr("num"); | ||
167 | + params.clear(); | ||
168 | + getChildGroup(mcid, brandCode, num); | ||
169 | + } | ||
170 | + | ||
171 | + } | ||
172 | + | ||
173 | + /** | ||
174 | + * 获取分组 | ||
175 | + * @param num | ||
176 | + */ | ||
177 | + private void getChildGroup(String mcid, String brandCode, String num) { | ||
178 | + | ||
179 | + Map<String, Object> params = new HashMap<>(); | ||
180 | + params.put("open_id", OPEN_ID); | ||
181 | + params.put("token", TOKEN); | ||
182 | + params.put("vin", VIN); | ||
183 | + params.put("mcid", mcid); | ||
184 | + params.put("brandCode", brandCode); | ||
185 | + params.put("num", num); | ||
186 | + | ||
187 | + String response = HttpUtil.get(BASE_API_URL + "/api/cars/structure", params); | ||
188 | +// String decodedResponse = UnicodeUtil.toString(response); | ||
189 | + JSONObject json = JSONUtil.parseObj(response); | ||
190 | + | ||
191 | + Api api = new Api(); | ||
192 | + api.setUrl("/api/cars/structure"); | ||
193 | + api.setUrlNo("1003"); | ||
194 | + api.setVin(VIN); | ||
195 | + api.setRequest(JSONUtil.toJsonStr(params)); | ||
196 | + api.setResponse(json.toString()); | ||
197 | + api.setCreateTime(new Date()); | ||
198 | + api.setBrandCode(brandCode); | ||
199 | + api.setName(name); | ||
200 | + api.setModelName(modelName); | ||
201 | + | ||
202 | + Integer code = json.getInt("code"); | ||
203 | + if (code != 1) { | ||
204 | + System.out.println("查询取分组失败"); | ||
205 | + System.out.println(response); | ||
206 | + apiMapper.insert(api); | ||
207 | + return; | ||
208 | + } | ||
209 | + JSONArray jsonArray = json.getJSONArray("data"); | ||
210 | + | ||
211 | + | ||
212 | + api.setNum(jsonArray.size()); | ||
213 | + api.setData(jsonArray.toString()); | ||
214 | + apiMapper.insert(api); | ||
215 | + | ||
216 | + for (int i = 0; i < jsonArray.size(); i++) { | ||
217 | + JSONObject jsonObject = jsonArray.getJSONObject(i); | ||
218 | + String mid = jsonObject.getStr("mid"); | ||
219 | + String subgroup = jsonObject.getStr("subgroup"); | ||
220 | + | ||
221 | + getLj(mcid, brandCode, num, mid, subgroup); | ||
222 | + } | ||
223 | + } | ||
224 | + | ||
225 | + /** | ||
226 | + * 全车件零件列表查询 | ||
227 | + */ | ||
228 | + private void getLj(String mcid, String brandCode, String num, String mid, String subgroup) { | ||
229 | + | ||
230 | + Map<String, Object> params = new HashMap<>(); | ||
231 | + params.put("open_id", OPEN_ID); | ||
232 | + params.put("token", TOKEN); | ||
233 | + params.put("vin", VIN); | ||
234 | + params.put("mcid", mcid); | ||
235 | + params.put("brandCode", brandCode); | ||
236 | + params.put("num", num); | ||
237 | + params.put("mid", mid); | ||
238 | + params.put("subgroup", subgroup); | ||
239 | + | ||
240 | + String response = HttpUtil.get(BASE_API_URL + "/api/cars/part", params); | ||
241 | +// String decodedResponse = UnicodeUtil.toString(response); | ||
242 | + JSONObject json = JSONUtil.parseObj(response); | ||
243 | + | ||
244 | + Api api = new Api(); | ||
245 | + api.setUrl("/api/cars/part"); | ||
246 | + api.setUrlNo("1005"); | ||
247 | + api.setVin(VIN); | ||
248 | + api.setRequest(JSONUtil.toJsonStr(params)); | ||
249 | + api.setResponse(json.toString()); | ||
250 | + api.setCreateTime(new Date()); | ||
251 | + api.setBrandCode(brandCode); | ||
252 | + api.setName(name); | ||
253 | + api.setModelName(modelName); | ||
254 | + | ||
255 | + Integer code = json.getInt("code"); | ||
256 | + if (code != 1) { | ||
257 | + System.out.println("查询零件列表失败"); | ||
258 | + System.out.println(response); | ||
259 | + apiMapper.insert(api); | ||
260 | + return; | ||
261 | + } | ||
262 | + JSONObject jsonObject = json.getJSONObject("data"); | ||
263 | + | ||
264 | + | ||
265 | + | ||
266 | + api.setData(jsonObject.toString()); | ||
267 | + | ||
268 | + if (jsonObject.containsKey("part_detail")) { | ||
269 | + JSONArray partDetail = jsonObject.getJSONArray("part_detail"); | ||
270 | + api.setNum(partDetail.size()); | ||
271 | + } | ||
272 | + apiMapper.insert(api); | ||
273 | + | ||
274 | + } | ||
275 | +} |
1 | +package com.ruoyi.test; | ||
2 | + | ||
3 | +import com.ruoyi.common.config.RuoYiConfig; | ||
4 | +import org.junit.jupiter.api.*; | ||
5 | +import org.springframework.beans.factory.annotation.Autowired; | ||
6 | +import org.springframework.boot.test.context.SpringBootTest; | ||
7 | + | ||
8 | +import java.util.concurrent.TimeUnit; | ||
9 | + | ||
10 | +/** | ||
11 | + * 单元测试案例 | ||
12 | + * | ||
13 | + * @author Lion Li | ||
14 | + */ | ||
15 | +@SpringBootTest // 此注解只能在 springboot 主包下使用 需包含 main 方法与 yml 配置文件 | ||
16 | +@DisplayName("单元测试案例") | ||
17 | +public class DemoUnitTest { | ||
18 | + | ||
19 | + @Autowired | ||
20 | + private RuoYiConfig ruoYiConfig; | ||
21 | + | ||
22 | + @DisplayName("测试 @SpringBootTest @Test @DisplayName 注解") | ||
23 | + @Test | ||
24 | + public void testTest() { | ||
25 | + System.out.println(ruoYiConfig); | ||
26 | + } | ||
27 | + | ||
28 | + @Disabled | ||
29 | + @DisplayName("测试 @Disabled 注解") | ||
30 | + @Test | ||
31 | + public void testDisabled() { | ||
32 | + System.out.println(ruoYiConfig); | ||
33 | + } | ||
34 | + | ||
35 | + @Timeout(value = 2L, unit = TimeUnit.SECONDS) | ||
36 | + @DisplayName("测试 @Timeout 注解") | ||
37 | + @Test | ||
38 | + public void testTimeout() throws InterruptedException { | ||
39 | + Thread.sleep(3000); | ||
40 | + System.out.println(ruoYiConfig); | ||
41 | + } | ||
42 | + | ||
43 | + | ||
44 | + @DisplayName("测试 @RepeatedTest 注解") | ||
45 | + @RepeatedTest(3) | ||
46 | + public void testRepeatedTest() { | ||
47 | + System.out.println(666); | ||
48 | + } | ||
49 | + | ||
50 | + @BeforeAll | ||
51 | + public static void testBeforeAll() { | ||
52 | + System.out.println("@BeforeAll =================="); | ||
53 | + } | ||
54 | + | ||
55 | + @BeforeEach | ||
56 | + public void testBeforeEach() { | ||
57 | + System.out.println("@BeforeEach =================="); | ||
58 | + } | ||
59 | + | ||
60 | + @AfterEach | ||
61 | + public void testAfterEach() { | ||
62 | + System.out.println("@AfterEach =================="); | ||
63 | + } | ||
64 | + | ||
65 | + @AfterAll | ||
66 | + public static void testAfterAll() { | ||
67 | + System.out.println("@AfterAll =================="); | ||
68 | + } | ||
69 | + | ||
70 | +} |
-
Please register or login to post a comment