lqkj@you07.com 1 рік тому
коміт
7e8bf78515
100 змінених файлів з 14011 додано та 0 видалено
  1. 423 0
      pom.xml
  2. 5 0
      src/main/java/com/lqkj/ApiVersion.java
  3. 46 0
      src/main/java/com/lqkj/LingWeiApplication.java
  4. 228 0
      src/main/java/com/lqkj/business/controller/CameraInfoController.java
  5. 143 0
      src/main/java/com/lqkj/business/controller/CmsCategoryController.java
  6. 168 0
      src/main/java/com/lqkj/business/controller/CmsNewsController.java
  7. 116 0
      src/main/java/com/lqkj/business/controller/DeviceCategoryController.java
  8. 113 0
      src/main/java/com/lqkj/business/entity/CameraInfo.java
  9. 135 0
      src/main/java/com/lqkj/business/entity/CmsCategory.java
  10. 162 0
      src/main/java/com/lqkj/business/entity/CmsNews.java
  11. 198 0
      src/main/java/com/lqkj/business/entity/DeviceCategory.java
  12. 78 0
      src/main/java/com/lqkj/business/mapper/CameraInfoMapper.java
  13. 69 0
      src/main/java/com/lqkj/business/mapper/CmsCategoryMapper.java
  14. 69 0
      src/main/java/com/lqkj/business/mapper/CmsNewsMapper.java
  15. 65 0
      src/main/java/com/lqkj/business/mapper/DeviceCategoryMapper.java
  16. 108 0
      src/main/java/com/lqkj/business/service/CameraInfoService.java
  17. 189 0
      src/main/java/com/lqkj/business/service/CmsCategoryService.java
  18. 107 0
      src/main/java/com/lqkj/business/service/CmsNewsService.java
  19. 99 0
      src/main/java/com/lqkj/business/service/DeviceCategoryService.java
  20. 22 0
      src/main/java/com/lqkj/camera/cache/CameraCacheUtil.java
  21. 85 0
      src/main/java/com/lqkj/camera/config/CameraConfig.java
  22. 71 0
      src/main/java/com/lqkj/camera/model/CameraVo.java
  23. 63 0
      src/main/java/com/lqkj/camera/model/HikDevice.java
  24. 147 0
      src/main/java/com/lqkj/camera/task/CameraOnlineTask.java
  25. 53 0
      src/main/java/com/lqkj/camera/thread/CameraThread.java
  26. 233 0
      src/main/java/com/lqkj/camera/util/CameraPush.java
  27. 155 0
      src/main/java/com/lqkj/camera/util/HIKCameraUtils.java
  28. 72 0
      src/main/java/com/lqkj/camera/util/TimerUtil.java
  29. 127 0
      src/main/java/com/lqkj/camera/util/UniviewCameraUtils.java
  30. 22 0
      src/main/java/com/lqkj/common/annotation/DataScope.java
  31. 178 0
      src/main/java/com/lqkj/common/annotation/Excel.java
  32. 18 0
      src/main/java/com/lqkj/common/annotation/Excels.java
  33. 45 0
      src/main/java/com/lqkj/common/annotation/Log.java
  34. 38 0
      src/main/java/com/lqkj/common/annotation/RateLimiter.java
  35. 26 0
      src/main/java/com/lqkj/common/annotation/RepeatSubmit.java
  36. 123 0
      src/main/java/com/lqkj/common/config/LingWeiConfig.java
  37. 109 0
      src/main/java/com/lqkj/common/constant/Constants.java
  38. 134 0
      src/main/java/com/lqkj/common/constant/GenConstants.java
  39. 27 0
      src/main/java/com/lqkj/common/constant/ScheduleConstants.java
  40. 32 0
      src/main/java/com/lqkj/common/constant/UserConstants.java
  41. 93 0
      src/main/java/com/lqkj/common/core/controller/BaseController.java
  42. 218 0
      src/main/java/com/lqkj/common/core/model/BaseEntity.java
  43. 69 0
      src/main/java/com/lqkj/common/core/model/LoginBody.java
  44. 162 0
      src/main/java/com/lqkj/common/core/model/LoginUser.java
  45. 11 0
      src/main/java/com/lqkj/common/core/model/RegisterBody.java
  46. 97 0
      src/main/java/com/lqkj/common/core/model/ResultUtil.java
  47. 80 0
      src/main/java/com/lqkj/common/core/model/TreeEntity.java
  48. 100 0
      src/main/java/com/lqkj/common/core/model/TreeSelect.java
  49. 79 0
      src/main/java/com/lqkj/common/core/model/TreeStringEntity.java
  50. 244 0
      src/main/java/com/lqkj/common/core/redis/RedisCache.java
  51. 87 0
      src/main/java/com/lqkj/common/core/text/CharsetKit.java
  52. 1006 0
      src/main/java/com/lqkj/common/core/text/Convert.java
  53. 93 0
      src/main/java/com/lqkj/common/core/text/StrFormatter.java
  54. 59 0
      src/main/java/com/lqkj/common/enums/BusinessType.java
  55. 37 0
      src/main/java/com/lqkj/common/enums/HttpMethod.java
  56. 20 0
      src/main/java/com/lqkj/common/enums/LimitType.java
  57. 24 0
      src/main/java/com/lqkj/common/enums/OperatorType.java
  58. 73 0
      src/main/java/com/lqkj/common/exception/ServiceException.java
  59. 26 0
      src/main/java/com/lqkj/common/exception/UtilException.java
  60. 81 0
      src/main/java/com/lqkj/common/exception/base/BaseException.java
  61. 20 0
      src/main/java/com/lqkj/common/exception/file/FileException.java
  62. 16 0
      src/main/java/com/lqkj/common/exception/file/FileNameLengthLimitExceededException.java
  63. 16 0
      src/main/java/com/lqkj/common/exception/file/FileSizeLimitExceededException.java
  64. 82 0
      src/main/java/com/lqkj/common/exception/file/InvalidExtensionException.java
  65. 34 0
      src/main/java/com/lqkj/common/exception/job/TaskException.java
  66. 107 0
      src/main/java/com/lqkj/common/exception/web/GlobalExceptionHandler.java
  67. 48 0
      src/main/java/com/lqkj/common/filter/RepeatableFilter.java
  68. 77 0
      src/main/java/com/lqkj/common/filter/RepeatedlyRequestWrapper.java
  69. 71 0
      src/main/java/com/lqkj/common/filter/XssFilter.java
  70. 112 0
      src/main/java/com/lqkj/common/filter/XssHttpServletRequestWrapper.java
  71. 114 0
      src/main/java/com/lqkj/common/utils/Arith.java
  72. 291 0
      src/main/java/com/lqkj/common/utils/Base64.java
  73. 179 0
      src/main/java/com/lqkj/common/utils/DateUtils.java
  74. 185 0
      src/main/java/com/lqkj/common/utils/DictUtils.java
  75. 42 0
      src/main/java/com/lqkj/common/utils/ExceptionUtil.java
  76. 19 0
      src/main/java/com/lqkj/common/utils/LogUtils.java
  77. 110 0
      src/main/java/com/lqkj/common/utils/OkHttpConfig.java
  78. 122 0
      src/main/java/com/lqkj/common/utils/SecurityUtils.java
  79. 154 0
      src/main/java/com/lqkj/common/utils/ServletUtils.java
  80. 530 0
      src/main/java/com/lqkj/common/utils/StringUtils.java
  81. 96 0
      src/main/java/com/lqkj/common/utils/Threads.java
  82. 44 0
      src/main/java/com/lqkj/common/utils/TimeUtils.java
  83. 108 0
      src/main/java/com/lqkj/common/utils/bean/BeanUtils.java
  84. 40 0
      src/main/java/com/lqkj/common/utils/easyexcel/LocalDateTimeConverter.java
  85. 77 0
      src/main/java/com/lqkj/common/utils/file/FileTypeUtils.java
  86. 236 0
      src/main/java/com/lqkj/common/utils/file/FileUploadUtils.java
  87. 252 0
      src/main/java/com/lqkj/common/utils/file/FileUtils.java
  88. 102 0
      src/main/java/com/lqkj/common/utils/file/ImageUtils.java
  89. 59 0
      src/main/java/com/lqkj/common/utils/file/MimeTypeUtils.java
  90. 137 0
      src/main/java/com/lqkj/common/utils/html/EscapeUtil.java
  91. 566 0
      src/main/java/com/lqkj/common/utils/html/HTMLFilter.java
  92. 56 0
      src/main/java/com/lqkj/common/utils/http/HttpHelper.java
  93. 279 0
      src/main/java/com/lqkj/common/utils/http/HttpUtils.java
  94. 60 0
      src/main/java/com/lqkj/common/utils/ip/AddressUtils.java
  95. 197 0
      src/main/java/com/lqkj/common/utils/ip/IpUtils.java
  96. 17 0
      src/main/java/com/lqkj/common/utils/poi/ExcelHandlerAdapter.java
  97. 1367 0
      src/main/java/com/lqkj/common/utils/poi/ExcelUtil.java
  98. 186 0
      src/main/java/com/lqkj/common/utils/poi/ImageUtil.java
  99. 843 0
      src/main/java/com/lqkj/common/utils/poi/WordUtil.java
  100. 0 0
      src/main/java/com/lqkj/common/utils/poi/model/ImageEntity.java

+ 423 - 0
pom.xml

@@ -0,0 +1,423 @@
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
+    <parent>
7
+        <groupId>org.springframework.boot</groupId>
8
+        <artifactId>spring-boot-starter-parent</artifactId>
9
+        <version>2.6.0</version>
10
+        <relativePath/> <!-- lookup parent from repository -->
11
+    </parent>
12
+    <groupId>com.lqkj</groupId>
13
+    <artifactId>slj-server</artifactId>
14
+    <version>1.0-SNAPSHOT</version>
15
+
16
+
17
+    <properties>
18
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
19
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
20
+        <java.version>1.8</java.version>
21
+        <lingwei.version>1.0.0</lingwei.version>
22
+        <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
23
+        <bitwalker.version>1.21</bitwalker.version>
24
+        <mybatis-spring-boot.version>2.2.0</mybatis-spring-boot.version>
25
+        <pagehelper.boot.version>1.4.1</pagehelper.boot.version>
26
+        <oshi.version>5.8.2</oshi.version>
27
+        <jna.version>5.9.0</jna.version>
28
+        <kaptcha.version>2.3.2</kaptcha.version>
29
+        <swagger.version>3.0.0</swagger.version>
30
+        <commons.io.version>2.11.0</commons.io.version>
31
+        <commons.fileupload.version>1.4</commons.fileupload.version>
32
+        <commons.collections.version>3.2.2</commons.collections.version>
33
+        <poi.version>4.1.2</poi.version>
34
+        <velocity.version>1.7</velocity.version>
35
+        <jwt.version>0.9.1</jwt.version>
36
+        <fastjson.version>1.2.83</fastjson.version>
37
+        <okhttp3.version>4.1.0</okhttp3.version>
38
+        <quartz.version>2.3.2</quartz.version>
39
+        <postgresql.version>42.2.23</postgresql.version>
40
+        <flyway.version>5.2.4</flyway.version>
41
+        <jodconverter.version>4.2.2</jodconverter.version>
42
+    </properties>
43
+    <repositories>
44
+        <repository>
45
+            <id>osgeo</id>
46
+            <name>OSGeo Release Repository</name>
47
+            <url>https://repo.osgeo.org/repository/release/</url>
48
+            <snapshots>
49
+                <enabled>false</enabled>
50
+            </snapshots>
51
+            <releases>
52
+                <enabled>true</enabled>
53
+            </releases>
54
+        </repository>
55
+        <repository>
56
+            <id>aliyun</id>
57
+            <url>https://maven.aliyun.com/repository/public</url>
58
+        </repository>
59
+        <repository>
60
+            <id>ignite-repo</id>
61
+            <url>http://www.gridgainsystems.com/nexus/content/repositories/external/</url>
62
+        </repository>
63
+        <repository>
64
+            <id>spring-milestones</id>
65
+            <name>Spring Milestones</name>
66
+            <url>https://repo.spring.io/milestone</url>
67
+            <snapshots>
68
+                <enabled>false</enabled>
69
+            </snapshots>
70
+        </repository>
71
+    </repositories>
72
+    <dependencies>
73
+        <dependency>
74
+            <groupId>org.springframework.boot</groupId>
75
+            <artifactId>spring-boot-starter</artifactId>
76
+        </dependency>
77
+
78
+        <!-- SpringBoot Web容器 -->
79
+        <dependency>
80
+            <groupId>org.springframework.boot</groupId>
81
+            <artifactId>spring-boot-starter-web</artifactId>
82
+        </dependency>
83
+        <!-- SpringBoot 拦截器 -->
84
+        <dependency>
85
+            <groupId>org.springframework.boot</groupId>
86
+            <artifactId>spring-boot-starter-aop</artifactId>
87
+        </dependency>
88
+        <!-- spring security 安全认证 -->
89
+        <dependency>
90
+            <groupId>org.springframework.boot</groupId>
91
+            <artifactId>spring-boot-starter-security</artifactId>
92
+        </dependency>
93
+        <!-- websocket-->
94
+        <dependency>
95
+            <groupId>org.springframework.boot</groupId>
96
+            <artifactId>spring-boot-starter-websocket</artifactId>
97
+        </dependency>
98
+        <!-- 验证注解 -->
99
+        <dependency>
100
+            <groupId>org.springframework.boot</groupId>
101
+            <artifactId>spring-boot-starter-validation</artifactId>
102
+        </dependency>
103
+        <!-- oauth2认证- -->
104
+        <dependency>
105
+            <groupId>org.springframework.security</groupId>
106
+            <artifactId>spring-security-jwt</artifactId>
107
+            <version>1.0.10.RELEASE</version>
108
+        </dependency>
109
+        <dependency>
110
+            <groupId>org.springframework.security.oauth</groupId>
111
+            <artifactId>spring-security-oauth2</artifactId>
112
+            <version>2.3.6.RELEASE</version>
113
+        </dependency>
114
+
115
+        <!-- log4J -->
116
+        <!--        <dependency>-->
117
+        <!--            <groupId>org.apache.logging.log4j</groupId>-->
118
+        <!--            <artifactId>log4j-api</artifactId>-->
119
+        <!--            <version>${log4j.version}</version>-->
120
+        <!--        </dependency>-->
121
+        <!--        <dependency>-->
122
+        <!--            <groupId>org.apache.logging.log4j</groupId>-->
123
+        <!--            <artifactId>log4j-to-slf4j</artifactId>-->
124
+        <!--            <version>${log4j.version}</version>-->
125
+        <!--        </dependency>-->
126
+        <!-- 视频转码 -->
127
+        <dependency>
128
+            <groupId>org.bytedeco</groupId>
129
+            <artifactId>javacv</artifactId>
130
+            <version>1.5.4</version>
131
+        </dependency>
132
+        <dependency>
133
+            <groupId>org.bytedeco</groupId>
134
+            <artifactId>ffmpeg-platform</artifactId>
135
+            <version>4.3.1-1.5.4</version>
136
+        </dependency>
137
+        <!-- 解析客户端操作系统、浏览器等 -->
138
+        <dependency>
139
+            <groupId>eu.bitwalker</groupId>
140
+            <artifactId>UserAgentUtils</artifactId>
141
+            <version>${bitwalker.version}</version>
142
+        </dependency>
143
+        <!-- 获取系统信息 -->
144
+        <dependency>
145
+            <groupId>com.github.oshi</groupId>
146
+            <artifactId>oshi-core</artifactId>
147
+            <version>${oshi.version}</version>
148
+        </dependency>
149
+        <dependency>
150
+            <groupId>net.java.dev.jna</groupId>
151
+            <artifactId>jna</artifactId>
152
+            <version>${jna.version}</version>
153
+        </dependency>
154
+        <dependency>
155
+            <groupId>net.java.dev.jna</groupId>
156
+            <artifactId>jna-platform</artifactId>
157
+            <version>${jna.version}</version>
158
+        </dependency>
159
+
160
+        <!-- postgresql驱动包 -->
161
+        <dependency>
162
+            <groupId>org.postgresql</groupId>
163
+            <artifactId>postgresql</artifactId>
164
+            <version>${postgresql.version}</version>
165
+        </dependency>
166
+
167
+        <!--数据库迁移-->
168
+        <dependency>
169
+            <groupId>org.flywaydb</groupId>
170
+            <artifactId>flyway-core</artifactId>
171
+            <version>${flyway.version}</version>
172
+        </dependency>
173
+        <!-- SpringBoot集成mybatis框架 -->
174
+        <dependency>
175
+            <groupId>org.mybatis.spring.boot</groupId>
176
+            <artifactId>mybatis-spring-boot-starter</artifactId>
177
+            <version>${mybatis-spring-boot.version}</version>
178
+        </dependency>
179
+        <!-- pagehelper 分页插件 -->
180
+        <dependency>
181
+            <groupId>com.github.pagehelper</groupId>
182
+            <artifactId>pagehelper-spring-boot-starter</artifactId>
183
+            <version>${pagehelper.boot.version}</version>
184
+        </dependency>
185
+        <!-- redis 缓存操作 -->
186
+        <dependency>
187
+            <groupId>org.springframework.boot</groupId>
188
+            <artifactId>spring-boot-starter-data-redis</artifactId>
189
+        </dependency>
190
+        <!-- 验证码 -->
191
+        <dependency>
192
+            <groupId>com.github.penggle</groupId>
193
+            <artifactId>kaptcha</artifactId>
194
+            <version>${kaptcha.version}</version>
195
+        </dependency>
196
+
197
+        <!-- Swagger3依赖 -->
198
+        <dependency>
199
+            <groupId>io.springfox</groupId>
200
+            <artifactId>springfox-boot-starter</artifactId>
201
+            <version>${swagger.version}</version>
202
+            <exclusions>
203
+                <exclusion>
204
+                    <groupId>io.swagger</groupId>
205
+                    <artifactId>swagger-models</artifactId>
206
+                </exclusion>
207
+            </exclusions>
208
+        </dependency>
209
+        <!-- 防止进入swagger页面报类型转换错误,排除3.0.0中的引用,手动增加1.6.2版本 -->
210
+        <dependency>
211
+            <groupId>io.swagger</groupId>
212
+            <artifactId>swagger-models</artifactId>
213
+            <version>1.6.2</version>
214
+        </dependency>
215
+
216
+        <!-- yml工具类 -->
217
+        <dependency>
218
+            <groupId>org.yaml</groupId>
219
+            <artifactId>snakeyaml</artifactId>
220
+        </dependency>
221
+        <dependency>
222
+            <groupId>com.squareup.okhttp3</groupId>
223
+            <artifactId>okhttp</artifactId>
224
+            <version>${okhttp3.version}</version>
225
+        </dependency>
226
+        <!-- 定时任务 -->
227
+        <dependency>
228
+            <groupId>org.quartz-scheduler</groupId>
229
+            <artifactId>quartz</artifactId>
230
+            <version>${quartz.version}</version>
231
+            <exclusions>
232
+                <exclusion>
233
+                    <groupId>com.mchange</groupId>
234
+                    <artifactId>c3p0</artifactId>
235
+                </exclusion>
236
+            </exclusions>
237
+        </dependency>
238
+        <!-- io常用工具类 -->
239
+        <dependency>
240
+            <groupId>commons-io</groupId>
241
+            <artifactId>commons-io</artifactId>
242
+            <version>${commons.io.version}</version>
243
+        </dependency>
244
+        <!--常用工具类 -->
245
+        <dependency>
246
+            <groupId>org.apache.commons</groupId>
247
+            <artifactId>commons-lang3</artifactId>
248
+        </dependency>
249
+        <!-- 文件上传工具类 -->
250
+        <dependency>
251
+            <groupId>commons-fileupload</groupId>
252
+            <artifactId>commons-fileupload</artifactId>
253
+            <version>${commons.fileupload.version}</version>
254
+        </dependency>
255
+
256
+        <!-- velocity代码生成使用模板 -->
257
+        <dependency>
258
+            <groupId>org.apache.velocity</groupId>
259
+            <artifactId>velocity</artifactId>
260
+            <version>${velocity.version}</version>
261
+            <exclusions>
262
+                <exclusion>
263
+                    <groupId>commons-collections</groupId>
264
+                    <artifactId>commons-collections</artifactId>
265
+                </exclusion>
266
+            </exclusions>
267
+        </dependency>
268
+
269
+        <!-- collections工具类 -->
270
+        <dependency>
271
+            <groupId>commons-collections</groupId>
272
+            <artifactId>commons-collections</artifactId>
273
+            <version>${commons.collections.version}</version>
274
+        </dependency>
275
+        <!-- office文档操作工具 -->
276
+        <dependency>
277
+            <groupId>org.apache.poi</groupId>
278
+            <artifactId>poi-ooxml</artifactId>
279
+            <version>${poi.version}</version>
280
+        </dependency>
281
+        <dependency>
282
+            <groupId>org.apache.poi</groupId>
283
+            <artifactId>poi-scratchpad</artifactId>
284
+            <version>${poi.version}</version>
285
+        </dependency>
286
+        <dependency>
287
+            <groupId>org.apache.poi</groupId>
288
+            <artifactId>ooxml-schemas</artifactId>
289
+            <version>1.4</version>
290
+        </dependency>
291
+        <dependency>
292
+            <groupId>com.deepoove</groupId>
293
+            <artifactId>poi-tl</artifactId>
294
+            <version>1.10.2</version>
295
+        </dependency>
296
+
297
+        <dependency>
298
+            <groupId>com.alibaba</groupId>
299
+            <artifactId>easyexcel</artifactId>
300
+            <version>3.0.5</version>
301
+        </dependency>
302
+        <!-- fastjson-->
303
+        <dependency>
304
+            <groupId>com.alibaba</groupId>
305
+            <artifactId>fastjson</artifactId>
306
+            <version>1.2.83</version>
307
+        </dependency>
308
+        <!--html渲染插件-->
309
+        <dependency>
310
+            <groupId>io.github.draco1023</groupId>
311
+            <artifactId>poi-tl-ext</artifactId>
312
+            <version>0.3.11</version>
313
+            <exclusions>
314
+                <exclusion>
315
+                    <groupId>com.deepoove</groupId>
316
+                    <artifactId>poi-tl</artifactId>
317
+                </exclusion>
318
+                <exclusion>
319
+                    <groupId>org.apache.poi</groupId>
320
+                    <artifactId>ooxml-schemas</artifactId>
321
+                </exclusion>
322
+            </exclusions>
323
+        </dependency>
324
+
325
+        <!--海康视频调阅-->
326
+        <dependency>
327
+            <groupId>com.hikvision.ga</groupId>
328
+            <artifactId>artemis-http-client</artifactId>
329
+            <version>1.1.3</version>
330
+        </dependency>
331
+
332
+        <!--字符转义-->
333
+        <dependency>
334
+            <groupId>org.apache.commons</groupId>
335
+            <artifactId>commons-text</artifactId>
336
+            <version>1.9</version>
337
+        </dependency>
338
+        <!-- openOffice 和 jobconverter-->
339
+        <dependency>
340
+            <groupId>org.jodconverter</groupId>
341
+            <artifactId>jodconverter-core</artifactId>
342
+            <version>${jodconverter.version}</version>
343
+        </dependency>
344
+        <dependency>
345
+            <groupId>org.jodconverter</groupId>
346
+            <artifactId>jodconverter-spring-boot-starter</artifactId>
347
+            <version>${jodconverter.version}</version>
348
+        </dependency>
349
+        <dependency>
350
+            <groupId>org.jodconverter</groupId>
351
+            <artifactId>jodconverter-local</artifactId>
352
+            <version>${jodconverter.version}</version>
353
+        </dependency>
354
+        <dependency>
355
+            <groupId>javax.xml.bind</groupId>
356
+            <artifactId>jaxb-api</artifactId>
357
+        </dependency>
358
+    </dependencies>
359
+    <build>
360
+        <plugins>
361
+            <plugin>
362
+                <groupId>org.springframework.boot</groupId>
363
+                <artifactId>spring-boot-maven-plugin</artifactId>
364
+                <configuration>
365
+                    <executable>true</executable>
366
+                </configuration>
367
+            </plugin>
368
+            <plugin>
369
+                <groupId>org.apache.maven.plugins</groupId>
370
+                <artifactId>maven-resources-plugin</artifactId>
371
+                <configuration>
372
+                    <nonFilteredFileExtensions>
373
+                        <nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
374
+                        <nonFilteredFileExtension>xls</nonFilteredFileExtension>
375
+                        <nonFilteredFileExtension>zip</nonFilteredFileExtension>
376
+                        <nonFilteredFileExtension>cer</nonFilteredFileExtension>
377
+                        <nonFilteredFileExtension>pfx</nonFilteredFileExtension>
378
+                        <nonFilteredFileExtension>py</nonFilteredFileExtension>
379
+                        <nonFilteredFileExtension>doc</nonFilteredFileExtension>
380
+                        <nonFilteredFileExtension>docx</nonFilteredFileExtension>
381
+                        <nonFilteredFileExtension>keystore</nonFilteredFileExtension>
382
+                    </nonFilteredFileExtensions>
383
+                </configuration>
384
+            </plugin>
385
+            <plugin>
386
+                <groupId>org.apache.maven.plugins</groupId>
387
+                <artifactId>maven-compiler-plugin</artifactId>
388
+                <configuration>
389
+                    <source>${java.version}</source>
390
+                    <target>${java.version}</target>
391
+                    <encoding>${project.build.sourceEncoding}</encoding>
392
+                </configuration>
393
+
394
+                <executions>
395
+                    <!-- 替换会被 maven 特别处理的 default-compile -->
396
+                    <execution>
397
+                        <id>default-compile</id>
398
+                        <phase>none</phase>
399
+                    </execution>
400
+                    <!-- 替换会被 maven 特别处理的 default-testCompile -->
401
+                    <execution>
402
+                        <id>default-testCompile</id>
403
+                        <phase>none</phase>
404
+                    </execution>
405
+                    <execution>
406
+                        <id>java-compile</id>
407
+                        <phase>compile</phase>
408
+                        <goals>
409
+                            <goal>compile</goal>
410
+                        </goals>
411
+                    </execution>
412
+                    <execution>
413
+                        <id>java-test-compile</id>
414
+                        <phase>test-compile</phase>
415
+                        <goals>
416
+                            <goal>testCompile</goal>
417
+                        </goals>
418
+                    </execution>
419
+                </executions>
420
+            </plugin>
421
+        </plugins>
422
+    </build>
423
+</project>

+ 5 - 0
src/main/java/com/lqkj/ApiVersion.java

@@ -0,0 +1,5 @@
1
+package com.lqkj;
2
+
3
+public class ApiVersion {
4
+    public static final String V1 = "v1";
5
+}

+ 46 - 0
src/main/java/com/lqkj/LingWeiApplication.java

@@ -0,0 +1,46 @@
1
+package com.lqkj;
2
+
3
+import com.lqkj.camera.thread.CameraThread;
4
+import com.lqkj.camera.util.CameraPush;
5
+import com.lqkj.camera.util.TimerUtil;
6
+import com.lqkj.framework.config.PropertyDeploy;
7
+import org.slf4j.Logger;
8
+import org.slf4j.LoggerFactory;
9
+import org.springframework.boot.SpringApplication;
10
+import org.springframework.boot.autoconfigure.SpringBootApplication;
11
+import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
12
+import org.springframework.cache.annotation.EnableCaching;
13
+import org.springframework.context.ApplicationContext;
14
+import org.springframework.scheduling.annotation.EnableScheduling;
15
+import org.springframework.transaction.annotation.EnableTransactionManagement;
16
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
17
+
18
+import javax.annotation.PreDestroy;
19
+
20
+/**
21
+ * 应用启动入口
22
+ * @author lh
23
+ */
24
+@SpringBootApplication(exclude = {FlywayAutoConfiguration.class})
25
+@EnableCaching
26
+@EnableTransactionManagement
27
+@EnableWebMvc
28
+@EnableScheduling
29
+public class LingWeiApplication {
30
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
31
+    public static void main(String[] args) {
32
+        PropertyDeploy deploy = new PropertyDeploy();
33
+        deploy.deploy();
34
+        final ApplicationContext applicationContext = SpringApplication.run(LingWeiApplication.class, args);
35
+        // 将上下文传入CameraPush类中,用于检测tcp连接是否正常
36
+        CameraPush.setApplicationContext(applicationContext);
37
+    }
38
+    @PreDestroy
39
+    public void destory() {
40
+        logger.info("服务结束,开始释放空间...");
41
+        // 关闭线程池
42
+        CameraThread.MyRunnable.es.shutdownNow();
43
+        // 销毁定时器
44
+        TimerUtil.timer.cancel();
45
+    }
46
+}

+ 228 - 0
src/main/java/com/lqkj/business/controller/CameraInfoController.java

@@ -0,0 +1,228 @@
1
+package com.lqkj.business.controller;
2
+
3
+import com.alibaba.fastjson.JSON;
4
+import com.alibaba.fastjson.JSONArray;
5
+import com.alibaba.fastjson.JSONObject;
6
+import com.github.pagehelper.PageInfo;
7
+import com.lqkj.business.entity.CameraInfo;
8
+import com.lqkj.business.service.CameraInfoService;
9
+import com.lqkj.camera.cache.CameraCacheUtil;
10
+import com.lqkj.camera.config.CameraConfig;
11
+import com.lqkj.camera.model.CameraVo;
12
+import com.lqkj.camera.thread.CameraThread;
13
+import com.lqkj.camera.util.HIKCameraUtils;
14
+import com.lqkj.camera.util.UniviewCameraUtils;
15
+import com.lqkj.common.annotation.Log;
16
+import com.lqkj.common.constant.Constants;
17
+import com.lqkj.common.core.controller.BaseController;
18
+import com.lqkj.common.core.model.ResultUtil;
19
+import com.lqkj.common.core.redis.RedisCache;
20
+import com.lqkj.common.core.text.Convert;
21
+import com.lqkj.common.enums.BusinessType;
22
+import com.lqkj.common.utils.StringUtils;
23
+import com.lqkj.common.utils.poi.ExcelUtil;
24
+import com.lqkj.system.service.SysConfigService;
25
+import io.swagger.annotations.Api;
26
+import io.swagger.annotations.ApiOperation;
27
+import org.springframework.beans.factory.annotation.Autowired;
28
+import org.springframework.security.access.prepost.PreAuthorize;
29
+import org.springframework.web.bind.annotation.*;
30
+
31
+import java.util.Date;
32
+import java.util.List;
33
+import java.util.concurrent.TimeUnit;
34
+
35
+/**
36
+ * 监控信息Controller
37
+ *
38
+ * @author lh
39
+ * @date 2022-09-30
40
+ */
41
+@Api(tags = {"监控信息"})
42
+@RestController
43
+@RequestMapping("/business/cameraInfo")
44
+public class CameraInfoController extends BaseController
45
+{
46
+    public static final String univiewAccessTokenKey = "univiewAccessToken";
47
+    @Autowired
48
+    private CameraConfig cameraConfig;
49
+    @Autowired
50
+    private CameraInfoService cameraInfoService;
51
+    @Autowired
52
+    private SysConfigService configService;
53
+    @Autowired
54
+    private RedisCache redisCache;
55
+    /**
56
+     * 获取监控信息详细信息
57
+     */
58
+    @ApiOperation("获取监控流媒体地址")
59
+    @PreAuthorize("@ss.hasPermi('business:cameraInfo:getCameraUrl')")
60
+    @GetMapping(value = "/getCameraUrl/{cameraId}")
61
+    public ResultUtil getCameraUrl(@PathVariable("cameraId") String cameraId)
62
+    {
63
+        String cameraProxyUrl = configService.selectConfigByKey("camera.proxy.url");
64
+        CameraInfo cameraInfo = cameraInfoService.selectCameraInfoByCameraId(cameraId);
65
+        CameraVo cameraVo = new CameraVo();
66
+        switch (cameraInfo.getCameraType()){
67
+            case "0": //自建流媒体
68
+                if (CameraCacheUtil.STREAMMAP.containsKey(cameraId)){
69
+                    cameraVo = CameraCacheUtil.STREAMMAP.get(cameraId);
70
+                    cameraVo.setCount(cameraVo.getCount() + 1);
71
+                    CameraCacheUtil.STREAMMAP.put(cameraId, cameraVo);
72
+                    return ResultUtil.success(cameraVo);
73
+                }else{
74
+                    return ResultUtil.success(openStream(cameraId));
75
+                }
76
+            case "1": //海康平台
77
+                String hikHost = configService.selectConfigByKey("hik.camera.host");
78
+                String appKey = configService.selectConfigByKey("hik.camera.appKey");
79
+                String appSecret = configService.selectConfigByKey("hik.camera.appSecret");
80
+                String httpProtocol = configService.selectConfigByKey("hik.camera.httpProtocol");
81
+                String requestBody = configService.selectConfigByKey("hik.camera.requestBody");
82
+                String cameraViewUrl = HIKCameraUtils.getDefaultInstance(hikHost, appKey,appSecret, httpProtocol)
83
+                        .getCameraPreviewURL(requestBody.replace("#cameraIndexCode", cameraInfo.getCameraIndexCode()));
84
+                if (StringUtils.isNotEmpty(cameraProxyUrl)){
85
+                    cameraVo.setHttpFlv(cameraProxyUrl + "hik/" + cameraViewUrl.substring(cameraViewUrl.indexOf("openUrl")));
86
+                }else{
87
+                    cameraVo.setHttpFlv(cameraViewUrl);
88
+                }
89
+                return ResultUtil.success(cameraVo);
90
+            case "2": //宇视平台
91
+                String univiewHost = configService.selectConfigByKey("uniview.camera.host");
92
+                String univiewUsername = configService.selectConfigByKey("uniview.camera.username");
93
+                String univiewPassword = configService.selectConfigByKey("uniview.camera.password");
94
+                String univiewTSAddress = configService.selectConfigByKey("uniview.camera.TSAddress");
95
+                String univiewTSPort = configService.selectConfigByKey("uniview.camera.TSPort");
96
+                String accessToken = Convert.toStr(redisCache.getCacheObject(univiewAccessTokenKey));
97
+                if (StringUtils.isEmpty(accessToken)){
98
+                    accessToken = UniviewCameraUtils.getDefaultInstance(univiewHost, univiewUsername, univiewPassword)
99
+                            .login();
100
+                    if (StringUtils.isEmpty(accessToken)){
101
+                        return ResultUtil.error("宇视平台登录失败,请检查服务是否可用");
102
+                    }else{
103
+                        redisCache.setCacheObject(univiewAccessTokenKey, accessToken, 1, TimeUnit.DAYS);
104
+                    }
105
+                }
106
+                String result = UniviewCameraUtils.getDefaultInstance(univiewHost, univiewUsername, univiewPassword)
107
+                        .getCameraPreviewUrl(accessToken, univiewTSAddress, univiewTSPort, cameraInfo.getCameraIndexCode());
108
+                if (StringUtils.isEmpty(result)){
109
+                    return ResultUtil.error("获取视频流地址失败");
110
+                }else{
111
+                    JSONObject resultJson = JSONObject.parseObject(result);
112
+                    if (resultJson.getInteger("ErrCode") != 0){
113
+                        redisCache.deleteObject(univiewAccessTokenKey);
114
+                        return ResultUtil.error("获取视频流地址失败");
115
+                    }
116
+                    JSONObject data = resultJson.getJSONArray("Result").getJSONObject(0);
117
+
118
+                    if (StringUtils.isNotEmpty(cameraProxyUrl)){
119
+                        cameraVo.setHttpFlv(cameraProxyUrl + "uniview/" + data.getString("StreamURL").substring(data.getString("StreamURL").indexOf("hls")));
120
+                    }else{
121
+                        cameraVo.setHttpFlv(data.getString("StreamURL"));
122
+                    }
123
+                    return ResultUtil.success(cameraVo);
124
+                }
125
+            case "3": //大华平台
126
+                return ResultUtil.success("暂不支持大华平台");
127
+            case "4": //萤石云平台
128
+                return ResultUtil.success("暂不支持萤石云平台");
129
+            default:
130
+                return ResultUtil.error("获取视频流地址失败");
131
+        }
132
+
133
+    }
134
+
135
+    private CameraVo openStream(String cameraId){
136
+        CameraInfo cameraInfo = cameraInfoService.selectCameraInfoByCameraId(cameraId);
137
+        String rtmp = "rtmp://" + cameraConfig.getPushHost() + ":" + cameraConfig.getPushPort() + "/hls/" + cameraInfo.getCameraId();
138
+        String httpHls = cameraConfig.getHttpFlvHost() + "/hls/" + cameraInfo.getCameraId() + ".m3u8";
139
+        CameraVo cameraVo = new CameraVo();
140
+        cameraVo.setRtsp(cameraInfo.getUrl());
141
+        cameraVo.setToken(cameraInfo.getCameraId());
142
+        cameraVo.setCount(1);
143
+        cameraVo.setOpenTime(new Date());
144
+        cameraVo.setHttpFlv(httpHls);
145
+        cameraVo.setRtmp(rtmp);
146
+        CameraThread.MyRunnable job = new CameraThread.MyRunnable(cameraVo);
147
+        CameraThread.MyRunnable.es.execute(job);
148
+        CameraCacheUtil.STREAMTHREAD.put(cameraInfo.getCameraId(),job);
149
+        return cameraVo;
150
+    }
151
+
152
+
153
+    /**
154
+     * 查询监控信息列表
155
+     */
156
+    @ApiOperation("查询监控信息列表")
157
+    @PreAuthorize("@ss.hasPermi('business:cameraInfo:list')")
158
+    @GetMapping("/list")
159
+    public ResultUtil list(CameraInfo cameraInfo)
160
+    {
161
+        startPage( cameraInfo);
162
+        PageInfo<CameraInfo> pageInfo = new PageInfo<>(cameraInfoService.selectCameraInfoList(cameraInfo));
163
+        return ResultUtil.success(pageInfo);
164
+    }
165
+
166
+    /**
167
+     * 导出监控信息列表
168
+     */
169
+    @ApiOperation("导出监控信息列表")
170
+    @PreAuthorize("@ss.hasPermi('business:cameraInfo:export')")
171
+    @Log(title = "监控信息", businessType = BusinessType.EXPORT)
172
+    @GetMapping("/export")
173
+    public ResultUtil export(CameraInfo cameraInfo)
174
+    {
175
+        List<CameraInfo> list = cameraInfoService.selectCameraInfoList(cameraInfo);
176
+        ExcelUtil<CameraInfo> util = new ExcelUtil<CameraInfo>(CameraInfo.class);
177
+        return util.exportExcel(list, "监控信息数据");
178
+    }
179
+
180
+    /**
181
+     * 获取监控信息详细信息
182
+     */
183
+    @ApiOperation("获取监控信息详细信息")
184
+    @PreAuthorize("@ss.hasPermi('business:cameraInfo:query')")
185
+    @GetMapping(value = "/{cameraId}")
186
+    public ResultUtil getInfo(@PathVariable("cameraId") String cameraId)
187
+    {
188
+        return ResultUtil.success(cameraInfoService.selectCameraInfoByCameraId(cameraId));
189
+    }
190
+
191
+    /**
192
+     * 新增监控信息
193
+     */
194
+    @ApiOperation("新增监控信息")
195
+    @PreAuthorize("@ss.hasPermi('business:cameraInfo:add')")
196
+    @Log(title = "监控信息", businessType = BusinessType.INSERT)
197
+    @PostMapping
198
+    public ResultUtil add(@RequestBody CameraInfo cameraInfo)
199
+    {
200
+        cameraInfo.setCreateBy(getUsername());
201
+        return resultByRows(cameraInfoService.insertCameraInfo(cameraInfo));
202
+    }
203
+
204
+    /**
205
+     * 修改监控信息
206
+     */
207
+    @ApiOperation("修改监控信息")
208
+    @PreAuthorize("@ss.hasPermi('business:cameraInfo:edit')")
209
+    @Log(title = "监控信息", businessType = BusinessType.UPDATE)
210
+    @PutMapping
211
+    public ResultUtil edit(@RequestBody CameraInfo cameraInfo)
212
+    {
213
+        cameraInfo.setUpdateBy(getUsername());
214
+        return resultByRows(cameraInfoService.updateCameraInfo(cameraInfo));
215
+    }
216
+
217
+    /**
218
+     * 删除监控信息
219
+     */
220
+    @ApiOperation("删除监控信息")
221
+    @PreAuthorize("@ss.hasPermi('business:cameraInfo:remove')")
222
+    @Log(title = "监控信息", businessType = BusinessType.DELETE)
223
+    @DeleteMapping("/{cameraIds}")
224
+    public ResultUtil remove(@PathVariable String[] cameraIds)
225
+    {
226
+        return resultByRows(cameraInfoService.deleteCameraInfoByCameraIds(cameraIds));
227
+    }
228
+}

+ 143 - 0
src/main/java/com/lqkj/business/controller/CmsCategoryController.java

@@ -0,0 +1,143 @@
1
+package com.lqkj.business.controller;
2
+
3
+import java.util.List;
4
+
5
+import com.lqkj.system.entity.SysDept;
6
+import org.springframework.security.access.prepost.PreAuthorize;
7
+import org.springframework.beans.factory.annotation.Autowired;
8
+import org.springframework.web.bind.annotation.GetMapping;
9
+import org.springframework.web.bind.annotation.PostMapping;
10
+import org.springframework.web.bind.annotation.PutMapping;
11
+import org.springframework.web.bind.annotation.DeleteMapping;
12
+import org.springframework.web.bind.annotation.PathVariable;
13
+import org.springframework.web.bind.annotation.RequestBody;
14
+import org.springframework.web.bind.annotation.RequestMapping;
15
+import org.springframework.web.bind.annotation.RestController;
16
+import com.lqkj.common.annotation.Log;
17
+import com.lqkj.common.core.controller.BaseController;
18
+import com.lqkj.common.core.model.ResultUtil;
19
+import com.lqkj.common.enums.BusinessType;
20
+import io.swagger.annotations.Api;
21
+import io.swagger.annotations.ApiOperation;
22
+import com.lqkj.business.entity.CmsCategory;
23
+import com.lqkj.business.service.CmsCategoryService;
24
+import com.lqkj.common.utils.poi.ExcelUtil;
25
+
26
+/**
27
+ * 信息分类Controller
28
+ *
29
+ * @author lqkj
30
+ * @date 2023-02-14
31
+ */
32
+@Api(tags = {"信息分类"})
33
+@RestController
34
+@RequestMapping("/business/cmsCategory")
35
+public class CmsCategoryController extends BaseController
36
+{
37
+    @Autowired
38
+    private CmsCategoryService cmsCategoryService;
39
+
40
+    @ApiOperation("查询一级分类列表")
41
+    @GetMapping("/parentList")
42
+    public ResultUtil selectParentList(){
43
+        return ResultUtil.success(cmsCategoryService.selectParentCategoryList());
44
+    }
45
+    /**
46
+     * 查询信息分类列表
47
+     */
48
+    @ApiOperation("查询信息分类列表")
49
+    @PreAuthorize("@ss.hasPermi('business:cmsCategory:list')")
50
+    @GetMapping("/list")
51
+    public ResultUtil list(CmsCategory cmsCategory)
52
+    {
53
+        List<CmsCategory> list = cmsCategoryService.selectCmsCategoryList(cmsCategory);
54
+        return ResultUtil.success(list);
55
+    }
56
+
57
+    /**
58
+     * 导出信息分类列表
59
+     */
60
+    @ApiOperation("导出信息分类列表")
61
+    @PreAuthorize("@ss.hasPermi('business:cmsCategory:export')")
62
+    @Log(title = "信息分类", businessType = BusinessType.EXPORT)
63
+    @GetMapping("/export")
64
+    public ResultUtil export(CmsCategory cmsCategory)
65
+    {
66
+        List<CmsCategory> list = cmsCategoryService.selectCmsCategoryList(cmsCategory);
67
+        ExcelUtil<CmsCategory> util = new ExcelUtil<CmsCategory>(CmsCategory.class);
68
+        return util.exportExcel(list, "信息分类数据");
69
+    }
70
+
71
+    /**
72
+     * 获取信息分类详细信息
73
+     */
74
+    @ApiOperation("获取信息分类详细信息")
75
+    @PreAuthorize("@ss.hasPermi('business:cmsCategory:query')")
76
+    @GetMapping(value = "/{categoryId}")
77
+    public ResultUtil getInfo(@PathVariable("categoryId") Long categoryId)
78
+    {
79
+        return ResultUtil.success(cmsCategoryService.selectCmsCategoryByCategoryId(categoryId));
80
+    }
81
+
82
+
83
+    /**
84
+     * 新增信息分类
85
+     */
86
+    @ApiOperation("新增信息分类")
87
+    @PreAuthorize("@ss.hasPermi('business:cmsCategory:add')")
88
+    @Log(title = "信息分类", businessType = BusinessType.INSERT)
89
+    @PostMapping
90
+    public ResultUtil add(@RequestBody CmsCategory cmsCategory)
91
+    {
92
+        if (cmsCategory.getParentId() == null){
93
+            cmsCategory.setParentId(0l);
94
+        }
95
+        cmsCategory.setCreateBy(getNickName());
96
+        return resultByRows(cmsCategoryService.insertCmsCategory(cmsCategory));
97
+    }
98
+
99
+    /**
100
+     * 修改信息分类
101
+     */
102
+    @ApiOperation("修改信息分类")
103
+    @PreAuthorize("@ss.hasPermi('business:cmsCategory:edit')")
104
+    @Log(title = "信息分类", businessType = BusinessType.UPDATE)
105
+    @PutMapping
106
+    public ResultUtil edit(@RequestBody CmsCategory cmsCategory)
107
+    {
108
+        if(cmsCategory.getCategoryId().equals(cmsCategory.getParentId())){
109
+            return ResultUtil.error("修改分类'" + cmsCategory.getName() + "'失败,父分类不能是自己");
110
+        }
111
+        if (cmsCategory.getParentId() == null){
112
+            cmsCategory.setParentId(0l);
113
+        }
114
+        cmsCategory.setUpdateBy(getNickName());
115
+        return resultByRows(cmsCategoryService.updateCmsCategory(cmsCategory));
116
+    }
117
+
118
+    /**
119
+     * 删除信息分类
120
+     */
121
+    @ApiOperation("删除信息分类")
122
+    @PreAuthorize("@ss.hasPermi('business:cmsCategory:remove')")
123
+    @Log(title = "信息分类", businessType = BusinessType.DELETE)
124
+    @DeleteMapping("/{categoryId}")
125
+    public ResultUtil remove(@PathVariable Long categoryId)
126
+    {
127
+        if (cmsCategoryService.hasChildByCategoryId(categoryId)){
128
+            return ResultUtil.error("存在下级栏目,不允许删除");
129
+        }
130
+        return resultByRows(cmsCategoryService.deleteCmsCategoryByCategoryId(categoryId));
131
+    }
132
+
133
+    /**
134
+     * 获取分类下拉树列表
135
+     */
136
+    @ApiOperation("获取分类下拉树列表")
137
+    @GetMapping("/treeselect")
138
+    public ResultUtil treeselect()
139
+    {
140
+        List<CmsCategory> cmsCategories = cmsCategoryService.selectCmsCategoryList(null);
141
+        return ResultUtil.success(cmsCategoryService.buildCategoryTreeSelect(cmsCategories));
142
+    }
143
+}

+ 168 - 0
src/main/java/com/lqkj/business/controller/CmsNewsController.java

@@ -0,0 +1,168 @@
1
+package com.lqkj.business.controller;
2
+
3
+import java.util.List;
4
+
5
+import com.lqkj.common.utils.StringUtils;
6
+import org.springframework.security.access.prepost.PreAuthorize;
7
+import org.springframework.beans.factory.annotation.Autowired;
8
+import org.springframework.web.bind.annotation.GetMapping;
9
+import org.springframework.web.bind.annotation.PostMapping;
10
+import org.springframework.web.bind.annotation.PutMapping;
11
+import org.springframework.web.bind.annotation.DeleteMapping;
12
+import org.springframework.web.bind.annotation.PathVariable;
13
+import org.springframework.web.bind.annotation.RequestBody;
14
+import org.springframework.web.bind.annotation.RequestMapping;
15
+import org.springframework.web.bind.annotation.RestController;
16
+import com.lqkj.common.annotation.Log;
17
+import com.lqkj.common.core.controller.BaseController;
18
+import com.lqkj.common.core.model.ResultUtil;
19
+import com.lqkj.common.enums.BusinessType;
20
+import io.swagger.annotations.Api;
21
+import io.swagger.annotations.ApiOperation;
22
+import com.lqkj.business.entity.CmsNews;
23
+import com.lqkj.business.service.CmsNewsService;
24
+import com.lqkj.common.utils.poi.ExcelUtil;
25
+import com.github.pagehelper.PageInfo;
26
+import org.springframework.web.util.HtmlUtils;
27
+
28
+/**
29
+ * 信息管理Controller
30
+ *
31
+ * @author lqkj
32
+ * @date 2023-02-16
33
+ */
34
+@Api(tags = {"信息管理"})
35
+@RestController
36
+@RequestMapping("/business/cmsNews")
37
+public class CmsNewsController extends BaseController
38
+{
39
+    @Autowired
40
+    private CmsNewsService cmsNewsService;
41
+
42
+    /**
43
+     * 查询信息管理列表
44
+     */
45
+    @ApiOperation("查询信息列表")
46
+    @PreAuthorize("@ss.hasPermi('business:cmsNews:list')")
47
+    @GetMapping("/list")
48
+    public ResultUtil list(CmsNews cmsNews)
49
+    {
50
+        startPage( cmsNews);
51
+        PageInfo<CmsNews> pageInfo = new PageInfo<>(cmsNewsService.selectCmsNewsList(cmsNews));
52
+        return ResultUtil.success(pageInfo);
53
+    }
54
+
55
+    @ApiOperation("按分类查询列表(前端用)")
56
+    @GetMapping("/front/list")
57
+    public ResultUtil listByCategory(CmsNews cmsNews){
58
+        startPage( cmsNews);
59
+        PageInfo<CmsNews> pageInfo = new PageInfo<>(cmsNewsService.selectCmsNewsList(cmsNews));
60
+        return ResultUtil.success(pageInfo);
61
+    }
62
+
63
+    @ApiOperation("查看详情信息(前端用)")
64
+    @GetMapping(value = "/front/{newsId}")
65
+    public ResultUtil view(@PathVariable("newsId") String newsId)
66
+    {
67
+        cmsNewsService.plusViewCount(newsId);
68
+        return ResultUtil.success(cmsNewsService.selectCmsNewsByNewsId(newsId));
69
+    }
70
+
71
+    @ApiOperation("根据分类ID查看详情信息(前端用)")
72
+    @GetMapping(value = "/front/category/{categoryId}")
73
+    public ResultUtil viewByCategoryId(@PathVariable("categoryId") Long categoryId)
74
+    {
75
+        return ResultUtil.success(cmsNewsService.selectCmsNewsByCategoryId(categoryId));
76
+    }
77
+
78
+
79
+    /**
80
+     * 导出信息列表
81
+     */
82
+    @ApiOperation("导出信息列表")
83
+    @PreAuthorize("@ss.hasPermi('business:cmsNews:export')")
84
+    @Log(title = "信息管理", businessType = BusinessType.EXPORT)
85
+    @GetMapping("/export")
86
+    public ResultUtil export(CmsNews cmsNews)
87
+    {
88
+        List<CmsNews> list = cmsNewsService.selectCmsNewsList(cmsNews);
89
+        ExcelUtil<CmsNews> util = new ExcelUtil<CmsNews>(CmsNews.class);
90
+        return util.exportExcel(list, "信息数据");
91
+    }
92
+
93
+    /**
94
+     * 获取信息详细信息
95
+     */
96
+    @ApiOperation("获取信息详细信息")
97
+    @PreAuthorize("@ss.hasPermi('business:cmsNews:query')")
98
+    @GetMapping(value = "/{newsId}")
99
+    public ResultUtil getInfo(@PathVariable("newsId") String newsId)
100
+    {
101
+        return ResultUtil.success(cmsNewsService.selectCmsNewsByNewsId(newsId));
102
+    }
103
+    /**
104
+     * 获取信息详细信息
105
+     */
106
+    @ApiOperation("根据分类编号获取信息详细信息")
107
+    @PreAuthorize("@ss.hasPermi('business:cmsNews:query')")
108
+    @GetMapping(value = "/getInfoByCategoryId/{categoryId}")
109
+    public ResultUtil getInfoByCategoryId(@PathVariable("categoryId") Long categoryId)
110
+    {
111
+        return ResultUtil.success(cmsNewsService.selectCmsNewsByCategoryId(categoryId));
112
+    }
113
+
114
+
115
+    /**
116
+     * 新增信息
117
+     */
118
+    @ApiOperation("新增信息")
119
+    @PreAuthorize("@ss.hasPermi('business:cmsNews:add')")
120
+    @Log(title = "信息管理", businessType = BusinessType.INSERT)
121
+    @PostMapping
122
+    public ResultUtil add(@RequestBody CmsNews cmsNews)
123
+    {
124
+        if(StringUtils.isNotEmpty(cmsNews.getContent())){
125
+            cmsNews.setContent(HtmlUtils.htmlUnescape(cmsNews.getContent()));
126
+        }
127
+        cmsNews.setCreateBy(getNickName());
128
+        return resultByRows(cmsNewsService.insertCmsNews(cmsNews));
129
+    }
130
+
131
+    /**
132
+     * 修改信息
133
+     */
134
+    @ApiOperation("修改信息")
135
+    @PreAuthorize("@ss.hasPermi('business:cmsNews:edit')")
136
+    @Log(title = "信息管理", businessType = BusinessType.UPDATE)
137
+    @PutMapping
138
+    public ResultUtil edit(@RequestBody CmsNews cmsNews)
139
+    {
140
+        if(StringUtils.isNotEmpty(cmsNews.getContent())){
141
+            cmsNews.setContent(HtmlUtils.htmlUnescape(cmsNews.getContent()));
142
+        }
143
+        cmsNews.setUpdateBy(getNickName());
144
+        return resultByRows(cmsNewsService.updateCmsNews(cmsNews));
145
+    }
146
+
147
+    /**
148
+     * 置顶操作
149
+     */
150
+    @ApiOperation("置顶状态")
151
+    @PreAuthorize("@ss.hasPermi('business:cmsNews:edit')")
152
+    @Log(title = "信息管理", businessType = BusinessType.UPDATE)
153
+    @PutMapping("/updateTopStatus")
154
+    public ResultUtil updateTopStatus(@RequestBody CmsNews cmsNews){
155
+        return resultByRows(cmsNewsService.updateTopStatus(cmsNews));
156
+    }
157
+    /**
158
+     * 删除信息
159
+     */
160
+    @ApiOperation("删除信息")
161
+    @PreAuthorize("@ss.hasPermi('business:cmsNews:remove')")
162
+    @Log(title = "信息管理", businessType = BusinessType.DELETE)
163
+    @DeleteMapping("/{newsIds}")
164
+    public ResultUtil remove(@PathVariable String[] newsIds)
165
+    {
166
+        return resultByRows(cmsNewsService.deleteCmsNewsByNewsIds(newsIds));
167
+    }
168
+}

+ 116 - 0
src/main/java/com/lqkj/business/controller/DeviceCategoryController.java

@@ -0,0 +1,116 @@
1
+package com.lqkj.business.controller;
2
+
3
+import java.util.List;
4
+import org.springframework.security.access.prepost.PreAuthorize;
5
+import org.springframework.beans.factory.annotation.Autowired;
6
+import org.springframework.web.bind.annotation.GetMapping;
7
+import org.springframework.web.bind.annotation.PostMapping;
8
+import org.springframework.web.bind.annotation.PutMapping;
9
+import org.springframework.web.bind.annotation.DeleteMapping;
10
+import org.springframework.web.bind.annotation.PathVariable;
11
+import org.springframework.web.bind.annotation.RequestBody;
12
+import org.springframework.web.bind.annotation.RequestMapping;
13
+import org.springframework.web.bind.annotation.RestController;
14
+import com.lqkj.common.annotation.Log;
15
+import com.lqkj.common.core.controller.BaseController;
16
+import com.lqkj.common.core.model.ResultUtil;
17
+import com.lqkj.common.enums.BusinessType;
18
+import io.swagger.annotations.Api;
19
+import io.swagger.annotations.ApiOperation;
20
+import com.lqkj.business.entity.DeviceCategory;
21
+import com.lqkj.business.service.DeviceCategoryService;
22
+import com.lqkj.common.utils.poi.ExcelUtil;
23
+
24
+/**
25
+ * 设备分类Controller
26
+ *
27
+ * @author lqkj
28
+ * @date 2023-03-14
29
+ */
30
+@Api(tags = {"设备分类"})
31
+@RestController
32
+@RequestMapping("/business/deviceCategory")
33
+public class DeviceCategoryController extends BaseController
34
+{
35
+    @Autowired
36
+    private DeviceCategoryService deviceCategoryService;
37
+    @ApiOperation("查询一级分类列表")
38
+    @GetMapping("/parentList")
39
+    public ResultUtil selectParentList(){
40
+        return ResultUtil.success(deviceCategoryService.selectParentCategoryList());
41
+    }
42
+    /**
43
+     * 查询设备分类列表
44
+     */
45
+    @ApiOperation("查询设备分类列表")
46
+    @PreAuthorize("@ss.hasPermi('business:deviceCategory:list')")
47
+    @GetMapping("/list")
48
+    public ResultUtil list(DeviceCategory deviceCategory)
49
+    {
50
+        List<DeviceCategory> list = deviceCategoryService.selectDeviceCategoryList(deviceCategory);
51
+        return ResultUtil.success(list);
52
+    }
53
+
54
+    /**
55
+     * 导出设备分类列表
56
+     */
57
+    @ApiOperation("导出设备分类列表")
58
+    @PreAuthorize("@ss.hasPermi('business:deviceCategory:export')")
59
+    @Log(title = "设备分类", businessType = BusinessType.EXPORT)
60
+    @GetMapping("/export")
61
+    public ResultUtil export(DeviceCategory deviceCategory)
62
+    {
63
+        List<DeviceCategory> list = deviceCategoryService.selectDeviceCategoryList(deviceCategory);
64
+        ExcelUtil<DeviceCategory> util = new ExcelUtil<DeviceCategory>(DeviceCategory.class);
65
+        return util.exportExcel(list, "设备分类数据");
66
+    }
67
+
68
+    /**
69
+     * 获取设备分类详细信息
70
+     */
71
+    @ApiOperation("获取设备分类详细信息")
72
+    @PreAuthorize("@ss.hasPermi('business:deviceCategory:query')")
73
+    @GetMapping(value = "/{categoryId}")
74
+    public ResultUtil getInfo(@PathVariable("categoryId") Integer categoryId)
75
+    {
76
+        return ResultUtil.success(deviceCategoryService.selectDeviceCategoryByCategoryId(categoryId));
77
+    }
78
+
79
+    /**
80
+     * 新增设备分类
81
+     */
82
+    @ApiOperation("新增设备分类")
83
+    @PreAuthorize("@ss.hasPermi('business:deviceCategory:add')")
84
+    @Log(title = "设备分类", businessType = BusinessType.INSERT)
85
+    @PostMapping
86
+    public ResultUtil add(@RequestBody DeviceCategory deviceCategory)
87
+    {
88
+        deviceCategory.setCreateBy(getNickName());
89
+        return resultByRows(deviceCategoryService.insertDeviceCategory(deviceCategory));
90
+    }
91
+
92
+    /**
93
+     * 修改设备分类
94
+     */
95
+    @ApiOperation("修改设备分类")
96
+    @PreAuthorize("@ss.hasPermi('business:deviceCategory:edit')")
97
+    @Log(title = "设备分类", businessType = BusinessType.UPDATE)
98
+    @PutMapping
99
+    public ResultUtil edit(@RequestBody DeviceCategory deviceCategory)
100
+    {
101
+        deviceCategory.setUpdateBy(getNickName());
102
+        return resultByRows(deviceCategoryService.updateDeviceCategory(deviceCategory));
103
+    }
104
+
105
+    /**
106
+     * 删除设备分类
107
+     */
108
+    @ApiOperation("删除设备分类")
109
+    @PreAuthorize("@ss.hasPermi('business:deviceCategory:remove')")
110
+    @Log(title = "设备分类", businessType = BusinessType.DELETE)
111
+    @DeleteMapping("/{categoryIds}")
112
+    public ResultUtil remove(@PathVariable Integer[] categoryIds)
113
+    {
114
+        return resultByRows(deviceCategoryService.deleteDeviceCategoryByCategoryIds(categoryIds));
115
+    }
116
+}

+ 113 - 0
src/main/java/com/lqkj/business/entity/CameraInfo.java

@@ -0,0 +1,113 @@
1
+package com.lqkj.business.entity;
2
+
3
+import com.lqkj.common.annotation.Excel;
4
+import com.lqkj.common.core.model.BaseEntity;
5
+import org.apache.commons.lang3.builder.ToStringBuilder;
6
+import org.apache.commons.lang3.builder.ToStringStyle;
7
+
8
+/**
9
+ * 监控信息对象 sys_camera_info
10
+ *
11
+ * @author lh
12
+ * @date 2022-09-30
13
+ */
14
+public class CameraInfo extends BaseEntity
15
+{
16
+    private static final long serialVersionUID = 1L;
17
+
18
+    /** 监控编号 */
19
+    private String cameraId;
20
+
21
+    /** 监控名称 */
22
+    @Excel(name = "监控名称")
23
+    private String name;
24
+
25
+    /** 对接类型 */
26
+    @Excel(name = "对接类型",dictType = "camera_interface_type")
27
+    private String cameraType;
28
+
29
+    /** 相机编码 */
30
+    @Excel(name = "相机编码")
31
+    private String cameraIndexCode;
32
+
33
+    /** 监控地址 */
34
+    @Excel(name = "监控地址")
35
+    private String url;
36
+
37
+    /** 在线状态 */
38
+    @Excel(name = "在线状态")
39
+    private Boolean onlineStatus;
40
+
41
+    /** GIS大楼编号 */
42
+    @Excel(name = "在线状态")
43
+    private String gisBuildingCode;
44
+    /** GIS房间编号 */
45
+    @Excel(name = "在线状态")
46
+    private String gisRoomCode;
47
+
48
+
49
+    public void setCameraId(String cameraId)
50
+    {
51
+        this.cameraId = cameraId;
52
+    }
53
+
54
+    public String getCameraId()
55
+    {
56
+        return cameraId;
57
+    }
58
+    public void setName(String name)
59
+    {
60
+        this.name = name;
61
+    }
62
+
63
+    public String getName()
64
+    {
65
+        return name;
66
+    }
67
+    public void setUrl(String url)
68
+    {
69
+        this.url = url;
70
+    }
71
+
72
+    public String getUrl()
73
+    {
74
+        return url;
75
+    }
76
+
77
+    public String getCameraType() {
78
+        return cameraType;
79
+    }
80
+
81
+    public void setCameraType(String cameraType) {
82
+        this.cameraType = cameraType;
83
+    }
84
+
85
+    public String getCameraIndexCode() {
86
+        return cameraIndexCode;
87
+    }
88
+
89
+    public void setCameraIndexCode(String cameraIndexCode) {
90
+        this.cameraIndexCode = cameraIndexCode;
91
+    }
92
+
93
+    public Boolean getOnlineStatus() {
94
+        return onlineStatus;
95
+    }
96
+
97
+    public void setOnlineStatus(Boolean onlineStatus) {
98
+        this.onlineStatus = onlineStatus;
99
+    }
100
+
101
+    @Override
102
+    public String toString() {
103
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
104
+                .append("cameraId", getCameraId())
105
+                .append("name", getName())
106
+                .append("url", getUrl())
107
+                .append("createBy", getCreateBy())
108
+                .append("createTime", getCreateTime())
109
+                .append("updateBy", getUpdateBy())
110
+                .append("updateTime", getUpdateTime())
111
+                .toString();
112
+    }
113
+}

+ 135 - 0
src/main/java/com/lqkj/business/entity/CmsCategory.java

@@ -0,0 +1,135 @@
1
+package com.lqkj.business.entity;
2
+
3
+import com.lqkj.common.core.model.BaseEntity;
4
+import org.apache.commons.lang3.builder.ToStringBuilder;
5
+import org.apache.commons.lang3.builder.ToStringStyle;
6
+import com.lqkj.common.annotation.Excel;
7
+import com.lqkj.common.core.model.TreeEntity;
8
+
9
+import java.util.ArrayList;
10
+import java.util.List;
11
+
12
+/**
13
+ * 信息分类对象 cms_category
14
+ *
15
+ * @author lqkj
16
+ * @date 2023-02-14
17
+ */
18
+public class CmsCategory extends BaseEntity
19
+{
20
+    private static final long serialVersionUID = 1L;
21
+
22
+    /** 编号 */
23
+    private Long categoryId;
24
+
25
+    /** 名称 */
26
+    @Excel(name = "名称")
27
+    private String name;
28
+
29
+    /** 类型 */
30
+    @Excel(name = "类型", dictType = "cms_category_type")
31
+    private Integer categoryType;
32
+
33
+    /** 自定义链接 */
34
+    @Excel(name = "自定义链接")
35
+    private String diyUrl;
36
+
37
+    /** 父菜单ID */
38
+    private Long parentId;
39
+
40
+    /** 显示顺序 */
41
+    private Integer orderNum;
42
+
43
+    /** 祖级列表 */
44
+    private String ancestors;
45
+
46
+    /** 子类别 */
47
+    private List<CmsCategory> children = new ArrayList<>();
48
+
49
+    public void setCategoryId(Long categoryId)
50
+    {
51
+        this.categoryId = categoryId;
52
+    }
53
+
54
+    public Long getCategoryId()
55
+    {
56
+        return categoryId;
57
+    }
58
+    public void setName(String name)
59
+    {
60
+        this.name = name;
61
+    }
62
+
63
+    public String getName()
64
+    {
65
+        return name;
66
+    }
67
+    public void setCategoryType(Integer categoryType)
68
+    {
69
+        this.categoryType = categoryType;
70
+    }
71
+
72
+    public Integer getCategoryType()
73
+    {
74
+        return categoryType;
75
+    }
76
+    public void setDiyUrl(String diyUrl)
77
+    {
78
+        this.diyUrl = diyUrl;
79
+    }
80
+
81
+    public String getDiyUrl()
82
+    {
83
+        return diyUrl;
84
+    }
85
+
86
+    public Long getParentId() {
87
+        return parentId;
88
+    }
89
+
90
+    public void setParentId(Long parentId) {
91
+        this.parentId = parentId;
92
+    }
93
+
94
+    public Integer getOrderNum() {
95
+        return orderNum;
96
+    }
97
+
98
+    public void setOrderNum(Integer orderNum) {
99
+        this.orderNum = orderNum;
100
+    }
101
+
102
+    public String getAncestors() {
103
+        return ancestors;
104
+    }
105
+
106
+    public void setAncestors(String ancestors) {
107
+        this.ancestors = ancestors;
108
+    }
109
+
110
+    public List<CmsCategory> getChildren() {
111
+        return children;
112
+    }
113
+
114
+    public void setChildren(List<CmsCategory> children) {
115
+        this.children = children;
116
+    }
117
+
118
+    @Override
119
+    public String toString() {
120
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
121
+                .append("categoryId", getCategoryId())
122
+                .append("parentId", getParentId())
123
+                .append("ancestors", getAncestors())
124
+                .append("name", getName())
125
+                .append("categoryType", getCategoryType())
126
+                .append("diyUrl", getDiyUrl())
127
+                .append("orderNum", getOrderNum())
128
+                .append("createBy", getCreateBy())
129
+                .append("createTime", getCreateTime())
130
+                .append("updateBy", getUpdateBy())
131
+                .append("updateTime", getUpdateTime())
132
+                .append("remark", getRemark())
133
+                .toString();
134
+    }
135
+}

+ 162 - 0
src/main/java/com/lqkj/business/entity/CmsNews.java

@@ -0,0 +1,162 @@
1
+package com.lqkj.business.entity;
2
+
3
+import com.lqkj.common.annotation.Excels;
4
+import org.apache.commons.lang3.builder.ToStringBuilder;
5
+import org.apache.commons.lang3.builder.ToStringStyle;
6
+import com.lqkj.common.annotation.Excel;
7
+import com.lqkj.common.core.model.BaseEntity;
8
+
9
+/**
10
+ * 信息管理对象 cms_news
11
+ *
12
+ * @author lqkj
13
+ * @date 2023-02-16
14
+ */
15
+public class CmsNews extends BaseEntity
16
+{
17
+    private static final long serialVersionUID = 1L;
18
+
19
+    /** 编号 */
20
+    private String newsId;
21
+
22
+    /** 所属分类 */
23
+    @Excel(name = "所属分类")
24
+    private Integer categoryId;
25
+
26
+    /** 标题 */
27
+    @Excel(name = "标题")
28
+    private String title;
29
+
30
+    /** 内容 */
31
+    private String content;
32
+
33
+    /** 浏览量 */
34
+    @Excel(name = "浏览量")
35
+    private Integer viewCount;
36
+
37
+    /** 是否置顶 */
38
+    @Excel(name = "是否置顶")
39
+    private Boolean isTop;
40
+
41
+    /** 缩略图 */
42
+    @Excel(name = "缩略图")
43
+    private String thumbnail;
44
+
45
+    /** 视频 */
46
+    @Excel(name = "视频")
47
+    private String videoUrl;
48
+
49
+    private Object focusImgs;
50
+
51
+    @Excels({
52
+            @Excel(name = "分类", targetAttr = "name", type = Excel.Type.EXPORT)})
53
+    private CmsCategory cmsCategory;
54
+
55
+    public void setNewsId(String newsId)
56
+    {
57
+        this.newsId = newsId;
58
+    }
59
+
60
+    public String getNewsId()
61
+    {
62
+        return newsId;
63
+    }
64
+    public void setCategoryId(Integer categoryId)
65
+    {
66
+        this.categoryId = categoryId;
67
+    }
68
+
69
+    public Integer getCategoryId()
70
+    {
71
+        return categoryId;
72
+    }
73
+    public void setTitle(String title)
74
+    {
75
+        this.title = title;
76
+    }
77
+
78
+    public String getTitle()
79
+    {
80
+        return title;
81
+    }
82
+    public void setContent(String content)
83
+    {
84
+        this.content = content;
85
+    }
86
+
87
+    public String getContent()
88
+    {
89
+        return content;
90
+    }
91
+    public void setViewCount(Integer viewCount)
92
+    {
93
+        this.viewCount = viewCount;
94
+    }
95
+
96
+    public Integer getViewCount()
97
+    {
98
+        return viewCount;
99
+    }
100
+    public void setIsTop(Boolean isTop)
101
+    {
102
+        this.isTop = isTop;
103
+    }
104
+
105
+    public Boolean getIsTop()
106
+    {
107
+        return isTop;
108
+    }
109
+    public void setThumbnail(String thumbnail)
110
+    {
111
+        this.thumbnail = thumbnail;
112
+    }
113
+
114
+    public String getThumbnail()
115
+    {
116
+        return thumbnail;
117
+    }
118
+    public void setVideoUrl(String videoUrl)
119
+    {
120
+        this.videoUrl = videoUrl;
121
+    }
122
+
123
+    public String getVideoUrl()
124
+    {
125
+        return videoUrl;
126
+    }
127
+
128
+    public CmsCategory getCmsCategory() {
129
+        return cmsCategory;
130
+    }
131
+
132
+    public void setCmsCategory(CmsCategory cmsCategory) {
133
+        this.cmsCategory = cmsCategory;
134
+    }
135
+
136
+    public Object getFocusImgs() {
137
+        return focusImgs;
138
+    }
139
+
140
+    public void setFocusImgs(Object focusImgs) {
141
+        this.focusImgs = focusImgs;
142
+    }
143
+
144
+    @Override
145
+    public String toString() {
146
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
147
+                .append("newsId", getNewsId())
148
+                .append("categoryId", getCategoryId())
149
+                .append("title", getTitle())
150
+                .append("content", getContent())
151
+                .append("viewCount", getViewCount())
152
+                .append("isTop", getIsTop())
153
+                .append("thumbnail", getThumbnail())
154
+                .append("videoUrl", getVideoUrl())
155
+                .append("createBy", getCreateBy())
156
+                .append("createTime", getCreateTime())
157
+                .append("updateBy", getUpdateBy())
158
+                .append("updateTime", getUpdateTime())
159
+                .append("remark", getRemark())
160
+                .toString();
161
+    }
162
+}

+ 198 - 0
src/main/java/com/lqkj/business/entity/DeviceCategory.java

@@ -0,0 +1,198 @@
1
+package com.lqkj.business.entity;
2
+
3
+import org.apache.commons.lang3.builder.ToStringBuilder;
4
+import org.apache.commons.lang3.builder.ToStringStyle;
5
+import com.lqkj.common.annotation.Excel;
6
+import com.lqkj.common.core.model.TreeEntity;
7
+
8
+/**
9
+ * 设备分类对象 device_category
10
+ *
11
+ * @author lqkj
12
+ * @date 2023-03-14
13
+ */
14
+public class DeviceCategory extends TreeEntity
15
+{
16
+    private static final long serialVersionUID = 1L;
17
+
18
+    /** 分类编号 */
19
+    private Integer categoryId;
20
+
21
+    /** 分类名称 */
22
+    @Excel(name = "分类名称")
23
+    private String name;
24
+
25
+    /** 默认图标 */
26
+    @Excel(name = "默认图标")
27
+    private String defaultIcon;
28
+
29
+    /** 异常图标 */
30
+    @Excel(name = "异常图标")
31
+    private String errorIcon;
32
+
33
+    /** 选中图标 */
34
+    @Excel(name = "选中图标")
35
+    private String selectedIcon;
36
+
37
+    /** 最小级数 */
38
+    @Excel(name = "最小级数")
39
+    private Integer minZoom;
40
+
41
+    /** 最大级数 */
42
+    @Excel(name = "最大级数")
43
+    private Integer maxZoom;
44
+
45
+    /** 数据类型 */
46
+    @Excel(name = "数据类型")
47
+    private Integer dataType;
48
+
49
+    /** 填充色 */
50
+    @Excel(name = "填充色")
51
+    private String fillColor;
52
+
53
+    /** 边框色 */
54
+    @Excel(name = "边框色")
55
+    private String borderColor;
56
+
57
+    /** 宽度 */
58
+    @Excel(name = "宽度")
59
+    private Integer width;
60
+
61
+    /** 预设分类 */
62
+    @Excel(name = "预设分类")
63
+    private Boolean preset;
64
+
65
+    public void setCategoryId(Integer categoryId)
66
+    {
67
+        this.categoryId = categoryId;
68
+    }
69
+
70
+    public Integer getCategoryId()
71
+    {
72
+        return categoryId;
73
+    }
74
+    public void setName(String name)
75
+    {
76
+        this.name = name;
77
+    }
78
+
79
+    public String getName()
80
+    {
81
+        return name;
82
+    }
83
+    public void setDefaultIcon(String defaultIcon)
84
+    {
85
+        this.defaultIcon = defaultIcon;
86
+    }
87
+
88
+    public String getDefaultIcon()
89
+    {
90
+        return defaultIcon;
91
+    }
92
+    public void setErrorIcon(String errorIcon)
93
+    {
94
+        this.errorIcon = errorIcon;
95
+    }
96
+
97
+    public String getErrorIcon()
98
+    {
99
+        return errorIcon;
100
+    }
101
+    public void setSelectedIcon(String selectedIcon)
102
+    {
103
+        this.selectedIcon = selectedIcon;
104
+    }
105
+
106
+    public String getSelectedIcon()
107
+    {
108
+        return selectedIcon;
109
+    }
110
+    public void setMinZoom(Integer minZoom)
111
+    {
112
+        this.minZoom = minZoom;
113
+    }
114
+
115
+    public Integer getMinZoom()
116
+    {
117
+        return minZoom;
118
+    }
119
+    public void setMaxZoom(Integer maxZoom)
120
+    {
121
+        this.maxZoom = maxZoom;
122
+    }
123
+
124
+    public Integer getMaxZoom()
125
+    {
126
+        return maxZoom;
127
+    }
128
+    public void setDataType(Integer dataType)
129
+    {
130
+        this.dataType = dataType;
131
+    }
132
+
133
+    public Integer getDataType()
134
+    {
135
+        return dataType;
136
+    }
137
+    public void setFillColor(String fillColor)
138
+    {
139
+        this.fillColor = fillColor;
140
+    }
141
+
142
+    public String getFillColor()
143
+    {
144
+        return fillColor;
145
+    }
146
+    public void setBorderColor(String borderColor)
147
+    {
148
+        this.borderColor = borderColor;
149
+    }
150
+
151
+    public String getBorderColor()
152
+    {
153
+        return borderColor;
154
+    }
155
+    public void setWidth(Integer width)
156
+    {
157
+        this.width = width;
158
+    }
159
+
160
+    public Integer getWidth()
161
+    {
162
+        return width;
163
+    }
164
+    public void setPreset(Boolean preset)
165
+    {
166
+        this.preset = preset;
167
+    }
168
+
169
+    public Boolean getPreset()
170
+    {
171
+        return preset;
172
+    }
173
+
174
+    @Override
175
+    public String toString() {
176
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
177
+                .append("categoryId", getCategoryId())
178
+                .append("parentId", getParentId())
179
+                .append("name", getName())
180
+                .append("defaultIcon", getDefaultIcon())
181
+                .append("errorIcon", getErrorIcon())
182
+                .append("selectedIcon", getSelectedIcon())
183
+                .append("minZoom", getMinZoom())
184
+                .append("maxZoom", getMaxZoom())
185
+                .append("dataType", getDataType())
186
+                .append("fillColor", getFillColor())
187
+                .append("borderColor", getBorderColor())
188
+                .append("width", getWidth())
189
+                .append("orderNum", getOrderNum())
190
+                .append("preset", getPreset())
191
+                .append("createBy", getCreateBy())
192
+                .append("createTime", getCreateTime())
193
+                .append("updateBy", getUpdateBy())
194
+                .append("updateTime", getUpdateTime())
195
+                .append("remark", getRemark())
196
+                .toString();
197
+    }
198
+}

+ 78 - 0
src/main/java/com/lqkj/business/mapper/CameraInfoMapper.java

@@ -0,0 +1,78 @@
1
+package com.lqkj.business.mapper;
2
+
3
+import com.lqkj.business.entity.CameraInfo;
4
+import org.apache.ibatis.annotations.Mapper;
5
+
6
+import java.util.List;
7
+
8
+/**
9
+ * 监控信息Mapper接口
10
+ *
11
+ * @author lh
12
+ * @date 2022-09-30
13
+ */
14
+@Mapper
15
+public interface CameraInfoMapper
16
+{
17
+    /**
18
+     * 查询监控信息
19
+     *
20
+     * @param cameraId 监控信息主键
21
+     * @return 监控信息
22
+     */
23
+    public CameraInfo selectCameraInfoByCameraId(String cameraId);
24
+
25
+    /**
26
+     * 查询监控信息列表
27
+     *
28
+     * @param cameraInfo 监控信息
29
+     * @return 监控信息集合
30
+     */
31
+    public List<CameraInfo> selectCameraInfoList(CameraInfo cameraInfo);
32
+
33
+    /**
34
+     * 新增监控信息
35
+     *
36
+     * @param cameraInfo 监控信息
37
+     * @return 结果
38
+     */
39
+    public int insertCameraInfo(CameraInfo cameraInfo);
40
+
41
+    /**
42
+     * 修改监控信息
43
+     *
44
+     * @param cameraInfo 监控信息
45
+     * @return 结果
46
+     */
47
+    public int updateCameraInfo(CameraInfo cameraInfo);
48
+
49
+    /**
50
+     * 删除监控信息
51
+     *
52
+     * @param cameraId 监控信息主键
53
+     * @return 结果
54
+     */
55
+    public int deleteCameraInfoByCameraId(String cameraId);
56
+
57
+    /**
58
+     * 批量删除监控信息
59
+     *
60
+     * @param cameraIds 需要删除的数据主键集合
61
+     * @return 结果
62
+     */
63
+    public int deleteCameraInfoByCameraIds(String[] cameraIds);
64
+
65
+    /**
66
+     * 更新在线状态(第三方相机编号)
67
+     * @param cameraInfo
68
+     * @return
69
+     */
70
+    public int updateOnlineStatusByIndexCode(CameraInfo cameraInfo);
71
+
72
+    /**
73
+     * 更新在线状态(主键)
74
+     * @param cameraInfo
75
+     * @return
76
+     */
77
+    public int updateOnlineStatusById(CameraInfo cameraInfo);
78
+}

+ 69 - 0
src/main/java/com/lqkj/business/mapper/CmsCategoryMapper.java

@@ -0,0 +1,69 @@
1
+package com.lqkj.business.mapper;
2
+
3
+import java.util.List;
4
+import org.apache.ibatis.annotations.Mapper;
5
+import com.lqkj.business.entity.CmsCategory;
6
+
7
+/**
8
+ * 信息分类Mapper接口
9
+ *
10
+ * @author lqkj
11
+ * @date 2023-02-14
12
+ */
13
+@Mapper
14
+public interface CmsCategoryMapper
15
+{
16
+    /**
17
+     * 查询信息分类
18
+     *
19
+     * @param categoryId 信息分类主键
20
+     * @return 信息分类
21
+     */
22
+    public CmsCategory selectCmsCategoryByCategoryId(Long categoryId);
23
+
24
+    /**
25
+     * 查询信息分类列表
26
+     *
27
+     * @param cmsCategory 信息分类
28
+     * @return 信息分类集合
29
+     */
30
+    public List<CmsCategory> selectCmsCategoryList(CmsCategory cmsCategory);
31
+
32
+    /**
33
+     * 新增信息分类
34
+     *
35
+     * @param cmsCategory 信息分类
36
+     * @return 结果
37
+     */
38
+    public int insertCmsCategory(CmsCategory cmsCategory);
39
+
40
+    /**
41
+     * 修改信息分类
42
+     *
43
+     * @param cmsCategory 信息分类
44
+     * @return 结果
45
+     */
46
+    public int updateCmsCategory(CmsCategory cmsCategory);
47
+
48
+    /**
49
+     * 删除信息分类
50
+     *
51
+     * @param categoryId 信息分类主键
52
+     * @return 结果
53
+     */
54
+    public int deleteCmsCategoryByCategoryId(Long categoryId);
55
+
56
+    /**
57
+     * 批量删除信息分类
58
+     *
59
+     * @param categoryIds 需要删除的数据主键集合
60
+     * @return 结果
61
+     */
62
+    public int deleteCmsCategoryByCategoryIds(Long[] categoryIds);
63
+
64
+    public int hasChildByCategoryId(Long categoryId);
65
+
66
+    public int checkExistCmsNews(Long categoryId);
67
+
68
+    public List<CmsCategory> selectParentCategoryList();
69
+}

+ 69 - 0
src/main/java/com/lqkj/business/mapper/CmsNewsMapper.java

@@ -0,0 +1,69 @@
1
+package com.lqkj.business.mapper;
2
+
3
+import java.util.List;
4
+import org.apache.ibatis.annotations.Mapper;
5
+import com.lqkj.business.entity.CmsNews;
6
+
7
+/**
8
+ * 信息管理Mapper接口
9
+ *
10
+ * @author lqkj
11
+ * @date 2023-02-16
12
+ */
13
+@Mapper
14
+public interface CmsNewsMapper
15
+{
16
+    /**
17
+     * 查询信息管理
18
+     *
19
+     * @param newsId 信息管理主键
20
+     * @return 信息管理
21
+     */
22
+    public CmsNews selectCmsNewsByNewsId(String newsId);
23
+
24
+    /**
25
+     * 查询信息管理列表
26
+     *
27
+     * @param cmsNews 信息管理
28
+     * @return 信息管理集合
29
+     */
30
+    public List<CmsNews> selectCmsNewsList(CmsNews cmsNews);
31
+
32
+    /**
33
+     * 新增信息管理
34
+     *
35
+     * @param cmsNews 信息管理
36
+     * @return 结果
37
+     */
38
+    public int insertCmsNews(CmsNews cmsNews);
39
+
40
+    /**
41
+     * 修改信息管理
42
+     *
43
+     * @param cmsNews 信息管理
44
+     * @return 结果
45
+     */
46
+    public int updateCmsNews(CmsNews cmsNews);
47
+
48
+    /**
49
+     * 删除信息管理
50
+     *
51
+     * @param newsId 信息管理主键
52
+     * @return 结果
53
+     */
54
+    public int deleteCmsNewsByNewsId(String newsId);
55
+
56
+    /**
57
+     * 批量删除信息管理
58
+     *
59
+     * @param newsIds 需要删除的数据主键集合
60
+     * @return 结果
61
+     */
62
+    public int deleteCmsNewsByNewsIds(String[] newsIds);
63
+
64
+    public CmsNews selectCmsNewsByCategoryId(Long categoryId);
65
+
66
+    public int updateTopStatus(CmsNews cmsNews);
67
+
68
+    public int plusViewCount(String newsId);
69
+}

+ 65 - 0
src/main/java/com/lqkj/business/mapper/DeviceCategoryMapper.java

@@ -0,0 +1,65 @@
1
+package com.lqkj.business.mapper;
2
+
3
+import java.util.List;
4
+import org.apache.ibatis.annotations.Mapper;
5
+import com.lqkj.business.entity.DeviceCategory;
6
+
7
+/**
8
+ * 设备分类Mapper接口
9
+ *
10
+ * @author lqkj
11
+ * @date 2023-03-14
12
+ */
13
+@Mapper
14
+public interface DeviceCategoryMapper
15
+{
16
+    /**
17
+     * 查询设备分类
18
+     *
19
+     * @param categoryId 设备分类主键
20
+     * @return 设备分类
21
+     */
22
+    public DeviceCategory selectDeviceCategoryByCategoryId(Integer categoryId);
23
+
24
+    /**
25
+     * 查询设备分类列表
26
+     *
27
+     * @param deviceCategory 设备分类
28
+     * @return 设备分类集合
29
+     */
30
+    public List<DeviceCategory> selectDeviceCategoryList(DeviceCategory deviceCategory);
31
+
32
+    /**
33
+     * 新增设备分类
34
+     *
35
+     * @param deviceCategory 设备分类
36
+     * @return 结果
37
+     */
38
+    public int insertDeviceCategory(DeviceCategory deviceCategory);
39
+
40
+    /**
41
+     * 修改设备分类
42
+     *
43
+     * @param deviceCategory 设备分类
44
+     * @return 结果
45
+     */
46
+    public int updateDeviceCategory(DeviceCategory deviceCategory);
47
+
48
+    /**
49
+     * 删除设备分类
50
+     *
51
+     * @param categoryId 设备分类主键
52
+     * @return 结果
53
+     */
54
+    public int deleteDeviceCategoryByCategoryId(Integer categoryId);
55
+
56
+    /**
57
+     * 批量删除设备分类
58
+     *
59
+     * @param categoryIds 需要删除的数据主键集合
60
+     * @return 结果
61
+     */
62
+    public int deleteDeviceCategoryByCategoryIds(Integer[] categoryIds);
63
+
64
+    public List<DeviceCategory> selectParentCategoryList();
65
+}

+ 108 - 0
src/main/java/com/lqkj/business/service/CameraInfoService.java

@@ -0,0 +1,108 @@
1
+package com.lqkj.business.service;
2
+
3
+import com.lqkj.business.entity.CameraInfo;
4
+import com.lqkj.business.entity.CmsNews;
5
+import com.lqkj.business.mapper.CameraInfoMapper;
6
+import com.lqkj.common.utils.uuid.IdUtils;
7
+import org.springframework.beans.factory.annotation.Autowired;
8
+import org.springframework.stereotype.Service;
9
+
10
+import java.time.LocalDateTime;
11
+import java.util.List;
12
+
13
+/**
14
+ * 监控信息Service业务层处理
15
+ *
16
+ * @author lh
17
+ * @date 2022-09-30
18
+ */
19
+@Service
20
+public class CameraInfoService
21
+{
22
+    @Autowired
23
+    private CameraInfoMapper cameraInfoMapper;
24
+
25
+    /**
26
+     * 查询监控信息
27
+     *
28
+     * @param cameraId 监控信息主键
29
+     * @return 监控信息
30
+     */
31
+
32
+    public CameraInfo selectCameraInfoByCameraId(String cameraId)
33
+    {
34
+        return cameraInfoMapper.selectCameraInfoByCameraId(cameraId);
35
+    }
36
+
37
+    /**
38
+     * 查询监控信息列表
39
+     *
40
+     * @param cameraInfo 监控信息
41
+     * @return 监控信息
42
+     */
43
+    public List<CameraInfo> selectCameraInfoList(CameraInfo cameraInfo)
44
+    {
45
+        return cameraInfoMapper.selectCameraInfoList(cameraInfo);
46
+    }
47
+
48
+    /**
49
+     * 新增监控信息
50
+     *
51
+     * @param cameraInfo 监控信息
52
+     * @return 结果
53
+     */
54
+
55
+    public int insertCameraInfo(CameraInfo cameraInfo)
56
+    {
57
+        cameraInfo.setCreateTime(LocalDateTime.now());
58
+        cameraInfo.setCameraId(IdUtils.simpleUUID());
59
+        return cameraInfoMapper.insertCameraInfo(cameraInfo);
60
+    }
61
+
62
+    /**
63
+     * 修改监控信息
64
+     *
65
+     * @param cameraInfo 监控信息
66
+     * @return 结果
67
+     */
68
+
69
+    public int updateCameraInfo(CameraInfo cameraInfo)
70
+    {
71
+        cameraInfo.setUpdateTime(LocalDateTime.now());
72
+        return cameraInfoMapper.updateCameraInfo(cameraInfo);
73
+    }
74
+
75
+    /**
76
+     * 批量删除监控信息
77
+     *
78
+     * @param cameraIds 需要删除的监控信息主键
79
+     * @return 结果
80
+     */
81
+
82
+    public int deleteCameraInfoByCameraIds(String[] cameraIds)
83
+    {
84
+        return cameraInfoMapper.deleteCameraInfoByCameraIds(cameraIds);
85
+    }
86
+
87
+    /**
88
+     * 删除监控信息信息
89
+     *
90
+     * @param cameraId 监控信息主键
91
+     * @return 结果
92
+     */
93
+
94
+    public int deleteCameraInfoByCameraId(String cameraId)
95
+    {
96
+        return cameraInfoMapper.deleteCameraInfoByCameraId(cameraId);
97
+    }
98
+
99
+    public int updateOnlineStatusByIndexCode(CameraInfo cameraInfo){
100
+        return cameraInfoMapper.updateOnlineStatusByIndexCode(cameraInfo);
101
+    }
102
+
103
+    public int updateOnlineStatusById(CameraInfo cameraInfo){
104
+        return cameraInfoMapper.updateOnlineStatusById(cameraInfo);
105
+    }
106
+
107
+
108
+}

+ 189 - 0
src/main/java/com/lqkj/business/service/CmsCategoryService.java

@@ -0,0 +1,189 @@
1
+package com.lqkj.business.service;
2
+
3
+import java.util.ArrayList;
4
+import java.util.Iterator;
5
+import java.util.List;
6
+import java.time.LocalDateTime;
7
+import java.util.stream.Collectors;
8
+
9
+import com.lqkj.common.core.model.TreeSelect;
10
+import com.lqkj.common.utils.StringUtils;
11
+import com.lqkj.system.entity.SysDept;
12
+import org.springframework.beans.factory.annotation.Autowired;
13
+import org.springframework.stereotype.Service;
14
+import com.lqkj.business.mapper.CmsCategoryMapper;
15
+import com.lqkj.business.entity.CmsCategory;
16
+import com.lqkj.common.utils.uuid.IdUtils;
17
+/**
18
+ * 信息分类Service业务层处理
19
+ *
20
+ * @author lqkj
21
+ * @date 2023-02-14
22
+ */
23
+@Service
24
+public class CmsCategoryService
25
+{
26
+    @Autowired
27
+    private CmsCategoryMapper cmsCategoryMapper;
28
+
29
+    /**
30
+     * 查询信息分类
31
+     *
32
+     * @param categoryId 信息分类主键
33
+     * @return 信息分类
34
+     */
35
+
36
+    public CmsCategory selectCmsCategoryByCategoryId(Long categoryId)
37
+    {
38
+        return cmsCategoryMapper.selectCmsCategoryByCategoryId(categoryId);
39
+    }
40
+
41
+    /**
42
+     * 查询信息分类列表
43
+     *
44
+     * @param cmsCategory 信息分类
45
+     * @return 信息分类
46
+     */
47
+    public List<CmsCategory> selectCmsCategoryList(CmsCategory cmsCategory)
48
+    {
49
+        return cmsCategoryMapper.selectCmsCategoryList(cmsCategory);
50
+    }
51
+
52
+    /**
53
+     * 新增信息分类
54
+     *
55
+     * @param cmsCategory 信息分类
56
+     * @return 结果
57
+     */
58
+
59
+    public int insertCmsCategory(CmsCategory cmsCategory)
60
+    {
61
+        cmsCategory.setCreateTime(LocalDateTime.now());
62
+        return cmsCategoryMapper.insertCmsCategory(cmsCategory);
63
+    }
64
+
65
+    /**
66
+     * 修改信息分类
67
+     *
68
+     * @param cmsCategory 信息分类
69
+     * @return 结果
70
+     */
71
+
72
+    public int updateCmsCategory(CmsCategory cmsCategory)
73
+    {
74
+        cmsCategory.setUpdateTime(LocalDateTime.now());
75
+        return cmsCategoryMapper.updateCmsCategory(cmsCategory);
76
+    }
77
+
78
+    /**
79
+     * 批量删除信息分类
80
+     *
81
+     * @param categoryIds 需要删除的信息分类主键
82
+     * @return 结果
83
+     */
84
+
85
+    public int deleteCmsCategoryByCategoryIds(Long[] categoryIds)
86
+    {
87
+        return cmsCategoryMapper.deleteCmsCategoryByCategoryIds(categoryIds);
88
+    }
89
+
90
+    /**
91
+     * 删除信息分类信息
92
+     *
93
+     * @param categoryId 信息分类主键
94
+     * @return 结果
95
+     */
96
+
97
+    public int deleteCmsCategoryByCategoryId(Long categoryId)
98
+    {
99
+        return cmsCategoryMapper.deleteCmsCategoryByCategoryId(categoryId);
100
+    }
101
+
102
+    public boolean hasChildByCategoryId(Long categoryId) {
103
+        int result = cmsCategoryMapper.hasChildByCategoryId(categoryId);
104
+        return result > 0 ? true : false;
105
+    }
106
+
107
+    public boolean checkExistCmsNews(Long categoryId) {
108
+        int result = cmsCategoryMapper.checkExistCmsNews(categoryId);
109
+        return result > 0 ? true :false;
110
+    }
111
+
112
+    public List<CmsCategory> selectParentCategoryList(){
113
+        return cmsCategoryMapper.selectParentCategoryList();
114
+    }
115
+
116
+
117
+
118
+    public List<TreeSelect> buildCategoryTreeSelect(List<CmsCategory> cmsCategories)
119
+    {
120
+        List<CmsCategory> categoryTrees = buildCategoryTree(cmsCategories);
121
+        return categoryTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
122
+    }
123
+    /**
124
+     * 得到子节点列表
125
+     */
126
+    private List<CmsCategory> getChildList(List<CmsCategory> list, CmsCategory t)
127
+    {
128
+        List<CmsCategory> tlist = new ArrayList<CmsCategory>();
129
+        Iterator<CmsCategory> it = list.iterator();
130
+        while (it.hasNext())
131
+        {
132
+            CmsCategory n = (CmsCategory) it.next();
133
+            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getCategoryId().longValue())
134
+            {
135
+                tlist.add(n);
136
+            }
137
+        }
138
+        return tlist;
139
+    }
140
+
141
+    /**
142
+     * 判断是否有子节点
143
+     */
144
+    private boolean hasChild(List<CmsCategory> list, CmsCategory t)
145
+    {
146
+        return getChildList(list, t).size() > 0 ? true : false;
147
+    }
148
+
149
+    /**
150
+     * 递归列表
151
+     */
152
+    private void recursionFn(List<CmsCategory> list, CmsCategory t)
153
+    {
154
+        // 得到子节点列表
155
+        List<CmsCategory> childList = getChildList(list, t);
156
+        t.setChildren(childList);
157
+        for (CmsCategory tChild : childList)
158
+        {
159
+            if (hasChild(list, tChild))
160
+            {
161
+                recursionFn(list, tChild);
162
+            }
163
+        }
164
+    }
165
+    public List<CmsCategory> buildCategoryTree(List<CmsCategory> cmsCategories)
166
+    {
167
+        List<CmsCategory> returnList = new ArrayList<CmsCategory>();
168
+        List<Long> tempList = new ArrayList<Long>();
169
+        for (CmsCategory cmsCategory : cmsCategories)
170
+        {
171
+            tempList.add(cmsCategory.getCategoryId());
172
+        }
173
+        for (Iterator<CmsCategory> iterator = cmsCategories.iterator(); iterator.hasNext();)
174
+        {
175
+            CmsCategory category = (CmsCategory) iterator.next();
176
+            // 如果是顶级节点, 遍历该父节点的所有子节点
177
+            if (!tempList.contains(category.getParentId()))
178
+            {
179
+                recursionFn(cmsCategories, category);
180
+                returnList.add(category);
181
+            }
182
+        }
183
+        if (returnList.isEmpty())
184
+        {
185
+            returnList = cmsCategories;
186
+        }
187
+        return returnList;
188
+    }
189
+}

+ 107 - 0
src/main/java/com/lqkj/business/service/CmsNewsService.java

@@ -0,0 +1,107 @@
1
+package com.lqkj.business.service;
2
+
3
+import java.util.List;
4
+import java.time.LocalDateTime;
5
+import org.springframework.beans.factory.annotation.Autowired;
6
+import org.springframework.stereotype.Service;
7
+import com.lqkj.business.mapper.CmsNewsMapper;
8
+import com.lqkj.business.entity.CmsNews;
9
+import com.lqkj.common.utils.uuid.IdUtils;
10
+/**
11
+ * 信息管理Service业务层处理
12
+ *
13
+ * @author lqkj
14
+ * @date 2023-02-16
15
+ */
16
+@Service
17
+public class CmsNewsService
18
+{
19
+    @Autowired
20
+    private CmsNewsMapper cmsNewsMapper;
21
+
22
+    /**
23
+     * 查询信息管理
24
+     *
25
+     * @param newsId 信息管理主键
26
+     * @return 信息管理
27
+     */
28
+
29
+    public CmsNews selectCmsNewsByNewsId(String newsId)
30
+    {
31
+        return cmsNewsMapper.selectCmsNewsByNewsId(newsId);
32
+    }
33
+
34
+    /**
35
+     * 查询信息管理列表
36
+     *
37
+     * @param cmsNews 信息管理
38
+     * @return 信息管理
39
+     */
40
+    public List<CmsNews> selectCmsNewsList(CmsNews cmsNews)
41
+    {
42
+        return cmsNewsMapper.selectCmsNewsList(cmsNews);
43
+    }
44
+
45
+    /**
46
+     * 新增信息管理
47
+     *
48
+     * @param cmsNews 信息管理
49
+     * @return 结果
50
+     */
51
+
52
+    public int insertCmsNews(CmsNews cmsNews)
53
+    {
54
+        cmsNews.setCreateTime(LocalDateTime.now());
55
+        cmsNews.setNewsId(IdUtils.simpleUUID());
56
+        return cmsNewsMapper.insertCmsNews(cmsNews);
57
+    }
58
+
59
+    /**
60
+     * 修改信息管理
61
+     *
62
+     * @param cmsNews 信息管理
63
+     * @return 结果
64
+     */
65
+
66
+    public int updateCmsNews(CmsNews cmsNews)
67
+    {
68
+        cmsNews.setUpdateTime(LocalDateTime.now());
69
+        return cmsNewsMapper.updateCmsNews(cmsNews);
70
+    }
71
+
72
+    /**
73
+     * 批量删除信息管理
74
+     *
75
+     * @param newsIds 需要删除的信息管理主键
76
+     * @return 结果
77
+     */
78
+
79
+    public int deleteCmsNewsByNewsIds(String[] newsIds)
80
+    {
81
+        return cmsNewsMapper.deleteCmsNewsByNewsIds(newsIds);
82
+    }
83
+
84
+    /**
85
+     * 删除信息管理信息
86
+     *
87
+     * @param newsId 信息管理主键
88
+     * @return 结果
89
+     */
90
+
91
+    public int deleteCmsNewsByNewsId(String newsId)
92
+    {
93
+        return cmsNewsMapper.deleteCmsNewsByNewsId(newsId);
94
+    }
95
+
96
+    public CmsNews selectCmsNewsByCategoryId(Long categoryId){
97
+        return cmsNewsMapper.selectCmsNewsByCategoryId(categoryId);
98
+    }
99
+
100
+    public int updateTopStatus(CmsNews cmsNews){
101
+        return cmsNewsMapper.updateTopStatus(cmsNews);
102
+    }
103
+
104
+    public int plusViewCount(String newsId){
105
+        return cmsNewsMapper.plusViewCount(newsId);
106
+    }
107
+}

+ 99 - 0
src/main/java/com/lqkj/business/service/DeviceCategoryService.java

@@ -0,0 +1,99 @@
1
+package com.lqkj.business.service;
2
+
3
+import java.util.List;
4
+import java.time.LocalDateTime;
5
+import org.springframework.beans.factory.annotation.Autowired;
6
+import org.springframework.stereotype.Service;
7
+import com.lqkj.business.mapper.DeviceCategoryMapper;
8
+import com.lqkj.business.entity.DeviceCategory;
9
+import com.lqkj.common.utils.uuid.IdUtils;
10
+/**
11
+ * 设备分类Service业务层处理
12
+ *
13
+ * @author lqkj
14
+ * @date 2023-03-14
15
+ */
16
+@Service
17
+public class DeviceCategoryService
18
+{
19
+    @Autowired
20
+    private DeviceCategoryMapper deviceCategoryMapper;
21
+
22
+    /**
23
+     * 查询设备分类
24
+     *
25
+     * @param categoryId 设备分类主键
26
+     * @return 设备分类
27
+     */
28
+
29
+    public DeviceCategory selectDeviceCategoryByCategoryId(Integer categoryId)
30
+    {
31
+        return deviceCategoryMapper.selectDeviceCategoryByCategoryId(categoryId);
32
+    }
33
+
34
+    /**
35
+     * 查询设备分类列表
36
+     *
37
+     * @param deviceCategory 设备分类
38
+     * @return 设备分类
39
+     */
40
+    public List<DeviceCategory> selectDeviceCategoryList(DeviceCategory deviceCategory)
41
+    {
42
+        return deviceCategoryMapper.selectDeviceCategoryList(deviceCategory);
43
+    }
44
+
45
+    /**
46
+     * 新增设备分类
47
+     *
48
+     * @param deviceCategory 设备分类
49
+     * @return 结果
50
+     */
51
+
52
+    public int insertDeviceCategory(DeviceCategory deviceCategory)
53
+    {
54
+        deviceCategory.setCreateTime(LocalDateTime.now());
55
+        return deviceCategoryMapper.insertDeviceCategory(deviceCategory);
56
+    }
57
+
58
+    /**
59
+     * 修改设备分类
60
+     *
61
+     * @param deviceCategory 设备分类
62
+     * @return 结果
63
+     */
64
+
65
+    public int updateDeviceCategory(DeviceCategory deviceCategory)
66
+    {
67
+        deviceCategory.setUpdateTime(LocalDateTime.now());
68
+        return deviceCategoryMapper.updateDeviceCategory(deviceCategory);
69
+    }
70
+
71
+    /**
72
+     * 批量删除设备分类
73
+     *
74
+     * @param categoryIds 需要删除的设备分类主键
75
+     * @return 结果
76
+     */
77
+
78
+    public int deleteDeviceCategoryByCategoryIds(Integer[] categoryIds)
79
+    {
80
+        return deviceCategoryMapper.deleteDeviceCategoryByCategoryIds(categoryIds);
81
+    }
82
+
83
+    /**
84
+     * 删除设备分类信息
85
+     *
86
+     * @param categoryId 设备分类主键
87
+     * @return 结果
88
+     */
89
+
90
+    public int deleteDeviceCategoryByCategoryId(Integer categoryId)
91
+    {
92
+        return deviceCategoryMapper.deleteDeviceCategoryByCategoryId(categoryId);
93
+    }
94
+
95
+    public List<DeviceCategory> selectParentCategoryList()
96
+    {
97
+        return deviceCategoryMapper.selectParentCategoryList();
98
+    }
99
+}

+ 22 - 0
src/main/java/com/lqkj/camera/cache/CameraCacheUtil.java

@@ -0,0 +1,22 @@
1
+package com.lqkj.camera.cache;
2
+
3
+
4
+import com.lqkj.camera.model.CameraVo;
5
+import com.lqkj.camera.thread.CameraThread;
6
+
7
+import java.util.Map;
8
+import java.util.concurrent.ConcurrentHashMap;
9
+
10
+public final class CameraCacheUtil {
11
+    /**
12
+     * 保存已经开始推的流信息
13
+     */
14
+    public static Map<String, CameraVo> STREAMMAP = new ConcurrentHashMap<>();
15
+
16
+    /**
17
+     * 保存已经开始推流线程信息
18
+     */
19
+    public static Map<String, CameraThread.MyRunnable> STREAMTHREAD = new ConcurrentHashMap<>();
20
+
21
+
22
+}

+ 85 - 0
src/main/java/com/lqkj/camera/config/CameraConfig.java

@@ -0,0 +1,85 @@
1
+package com.lqkj.camera.config;
2
+
3
+import org.springframework.boot.context.properties.ConfigurationProperties;
4
+import org.springframework.stereotype.Component;
5
+
6
+/**
7
+ * 流媒体推送服务配置
8
+ */
9
+@Component
10
+@ConfigurationProperties(prefix = "camera-config")
11
+public class CameraConfig {
12
+    private Integer maxOnline = 16; //视频最大并发路数
13
+    private Integer keepalive = Integer.MAX_VALUE;// 保活时长(分钟)默认持续在线
14
+    private String pushHost = "127.0.0.1";// 推送地址
15
+    private String httpFlvHost = "";
16
+    private Integer pushPort = 1935;// 推送端口
17
+    private String mainCode = "1024";// 主码流最大码率
18
+    private Boolean tcpConnectCheck = true; //是否启用tcp连通校验
19
+
20
+    private String videoType = "flv"; //转流类型,flv或hls
21
+
22
+    public String getHttpFlvHost() {
23
+        return httpFlvHost;
24
+    }
25
+
26
+    public void setHttpFlvHost(String httpFlvHost) {
27
+        this.httpFlvHost = httpFlvHost;
28
+    }
29
+
30
+    public Integer getMaxOnline() {
31
+        return maxOnline;
32
+    }
33
+
34
+    public void setMaxOnline(Integer maxOnline) {
35
+        this.maxOnline = maxOnline;
36
+    }
37
+
38
+    public Integer getKeepalive() {
39
+        return keepalive;
40
+    }
41
+
42
+    public void setKeepalive(Integer keepalive) {
43
+        this.keepalive = keepalive;
44
+    }
45
+
46
+    public String getPushHost() {
47
+        return pushHost;
48
+    }
49
+
50
+    public void setPushHost(String pushHost) {
51
+        this.pushHost = pushHost;
52
+    }
53
+
54
+    public Integer getPushPort() {
55
+        return pushPort;
56
+    }
57
+
58
+    public void setPushPort(Integer pushPort) {
59
+        this.pushPort = pushPort;
60
+    }
61
+
62
+    public String getMainCode() {
63
+        return mainCode;
64
+    }
65
+
66
+    public void setMainCode(String mainCode) {
67
+        this.mainCode = mainCode;
68
+    }
69
+
70
+    public String getVideoType() {
71
+        return videoType;
72
+    }
73
+
74
+    public void setVideoType(String videoType) {
75
+        this.videoType = videoType;
76
+    }
77
+
78
+    public Boolean getTcpConnectCheck() {
79
+        return tcpConnectCheck;
80
+    }
81
+
82
+    public void setTcpConnectCheck(Boolean tcpConnectCheck) {
83
+        this.tcpConnectCheck = tcpConnectCheck;
84
+    }
85
+}

+ 71 - 0
src/main/java/com/lqkj/camera/model/CameraVo.java

@@ -0,0 +1,71 @@
1
+package com.lqkj.camera.model;
2
+
3
+
4
+import java.util.Date;
5
+
6
+/**
7
+ * 相机信息
8
+ */
9
+public class CameraVo implements java.io.Serializable{
10
+    private String rtsp; //相机RTSP地址
11
+    private String rtmp; //相机转流RTMP地址
12
+    private String httpFlv; //相机转流http-flv地址
13
+    private Date openTime; //转流开始时间
14
+    private int count = 0; //当前在线人数
15
+    private String token; //token
16
+
17
+    public CameraVo() {
18
+    }
19
+
20
+    public CameraVo(String rtsp) {
21
+        this.rtsp = rtsp;
22
+    }
23
+
24
+    public String getRtsp() {
25
+        return rtsp;
26
+    }
27
+
28
+    public void setRtsp(String rtsp) {
29
+        this.rtsp = rtsp;
30
+    }
31
+
32
+    public String getRtmp() {
33
+        return rtmp;
34
+    }
35
+
36
+    public void setRtmp(String rtmp) {
37
+        this.rtmp = rtmp;
38
+    }
39
+
40
+    public String getHttpFlv() {
41
+        return httpFlv;
42
+    }
43
+
44
+    public void setHttpFlv(String httpFlv) {
45
+        this.httpFlv = httpFlv;
46
+    }
47
+
48
+    public Date getOpenTime() {
49
+        return openTime;
50
+    }
51
+
52
+    public void setOpenTime(Date openTime) {
53
+        this.openTime = openTime;
54
+    }
55
+
56
+    public int getCount() {
57
+        return count;
58
+    }
59
+
60
+    public void setCount(int count) {
61
+        this.count = count;
62
+    }
63
+
64
+    public String getToken() {
65
+        return token;
66
+    }
67
+
68
+    public void setToken(String token) {
69
+        this.token = token;
70
+    }
71
+}

+ 63 - 0
src/main/java/com/lqkj/camera/model/HikDevice.java

@@ -0,0 +1,63 @@
1
+package com.lqkj.camera.model;
2
+
3
+import java.util.Date;
4
+
5
+/**
6
+ * 海康设备
7
+ */
8
+public class HikDevice {
9
+    private String indexCode;
10
+    private Integer online;
11
+    private String manufacturer;
12
+    private String cn;
13
+    private String regionName;
14
+    private Date lastUpdateTime;
15
+
16
+    public String getIndexCode() {
17
+        return indexCode;
18
+    }
19
+
20
+    public void setIndexCode(String indexCode) {
21
+        this.indexCode = indexCode;
22
+    }
23
+
24
+    public Integer getOnline() {
25
+        return online;
26
+    }
27
+
28
+    public void setOnline(Integer online) {
29
+        this.online = online;
30
+    }
31
+
32
+    public String getManufacturer() {
33
+        return manufacturer;
34
+    }
35
+
36
+    public void setManufacturer(String manufacturer) {
37
+        this.manufacturer = manufacturer;
38
+    }
39
+
40
+    public String getCn() {
41
+        return cn;
42
+    }
43
+
44
+    public void setCn(String cn) {
45
+        this.cn = cn;
46
+    }
47
+
48
+    public String getRegionName() {
49
+        return regionName;
50
+    }
51
+
52
+    public void setRegionName(String regionName) {
53
+        this.regionName = regionName;
54
+    }
55
+
56
+    public Date getLastUpdateTime() {
57
+        return lastUpdateTime;
58
+    }
59
+
60
+    public void setLastUpdateTime(Date lastUpdateTime) {
61
+        this.lastUpdateTime = lastUpdateTime;
62
+    }
63
+}

+ 147 - 0
src/main/java/com/lqkj/camera/task/CameraOnlineTask.java

@@ -0,0 +1,147 @@
1
+package com.lqkj.camera.task;
2
+
3
+import com.alibaba.fastjson.JSON;
4
+import com.alibaba.fastjson.JSONObject;
5
+import com.lqkj.business.entity.CameraInfo;
6
+import com.lqkj.business.service.CameraInfoService;
7
+import com.lqkj.camera.model.HikDevice;
8
+import com.lqkj.camera.util.HIKCameraUtils;
9
+import com.lqkj.common.utils.StringUtils;
10
+import com.lqkj.system.service.SysConfigService;
11
+import org.slf4j.Logger;
12
+import org.slf4j.LoggerFactory;
13
+import org.springframework.beans.factory.annotation.Autowired;
14
+import org.springframework.stereotype.Component;
15
+
16
+import java.io.IOException;
17
+import java.net.InetSocketAddress;
18
+import java.net.Socket;
19
+import java.util.ArrayList;
20
+import java.util.List;
21
+import java.util.regex.Matcher;
22
+import java.util.regex.Pattern;
23
+
24
+/**
25
+ * 相机在线状态任务
26
+ */
27
+@Component("cameraOnlineTask")
28
+public class CameraOnlineTask {
29
+    private final static Logger logger = LoggerFactory.getLogger(CameraOnlineTask.class);
30
+    @Autowired
31
+    private CameraInfoService cameraInfoService;
32
+    @Autowired
33
+    private SysConfigService configService;
34
+
35
+    public void handleCameraOnline(){
36
+        updateHikOnline(); //更新海康相机状态
37
+        updateRTSPOnline();
38
+    }
39
+
40
+    /**
41
+     * RTSP/RTMP相机状态更新
42
+     */
43
+    private void updateRTSPOnline(){
44
+        CameraInfo cameraInfo = new CameraInfo();
45
+        cameraInfo.setCameraType("0");
46
+        List<CameraInfo> cameraInfos = cameraInfoService.selectCameraInfoList(cameraInfo);
47
+        if (cameraInfos.size() > 0){
48
+            for (CameraInfo camera : cameraInfos){
49
+                String ip = CameraOnlineTask.getIp(camera.getUrl());
50
+                String port = CameraOnlineTask.getPort(camera.getUrl());
51
+                if (StringUtils.isNotEmpty(ip) && StringUtils.isNotEmpty(port)){
52
+                    Socket rtspSocket = new Socket();
53
+                    try {
54
+                        camera.setOnlineStatus(true);
55
+                        rtspSocket.connect(new InetSocketAddress(ip, Integer.parseInt(port.trim())), 2000);
56
+                    } catch (IOException e) {
57
+                        camera.setOnlineStatus(false);
58
+                        logger.error(camera.getName() + "-" + camera.getUrl() + "-离线");
59
+                    }finally {
60
+                        cameraInfoService.updateOnlineStatusById(camera);
61
+                        try {
62
+                            rtspSocket.close();
63
+                        } catch (IOException e) {
64
+
65
+                        }
66
+                    }
67
+                }
68
+            }
69
+
70
+
71
+        }
72
+
73
+    }
74
+
75
+    /**
76
+     * 海康相机状态更新
77
+     */
78
+    private void updateHikOnline(){
79
+        CameraInfo cameraInfo = new CameraInfo();
80
+        cameraInfo.setCameraType("1");
81
+        List<CameraInfo> cameraInfos = cameraInfoService.selectCameraInfoList(cameraInfo);
82
+        if (cameraInfos.size() > 0){
83
+            List<HikDevice> hikDevices = new ArrayList<>();
84
+            String hikHost = configService.selectConfigByKey("hik.camera.host");
85
+            String appKey = configService.selectConfigByKey("hik.camera.appKey");
86
+            String appSecret = configService.selectConfigByKey("hik.camera.appSecret");
87
+            String httpProtocol = configService.selectConfigByKey("hik.camera.httpProtocol");
88
+            if (StringUtils.isNotEmpty(hikHost)
89
+                && StringUtils.isNotEmpty(appKey)
90
+                && StringUtils.isNotEmpty(appSecret)
91
+                && StringUtils.isNotEmpty(httpProtocol)){
92
+                int page  = 1, pageSize = 1000;
93
+                boolean hasNext = true;
94
+                while (hasNext){
95
+                    String res = null;
96
+                    try {
97
+                        res = HIKCameraUtils.getDefaultInstance(hikHost, appKey, appSecret, httpProtocol)
98
+                                .pageQueryCamerasWithStatus(pageSize, page);
99
+                    } catch (Exception e) {
100
+                        logger.error("海康平台异常");
101
+                    }
102
+                    if (StringUtils.isEmpty(res)){
103
+                        hasNext = false;
104
+                    }else{
105
+                        JSONObject jsonObject = JSON.parseObject(res);
106
+                        JSONObject data = jsonObject.getJSONObject("data");
107
+                        int totalPage = data.getInteger("totalPage");
108
+                        if (page < totalPage){
109
+                            page += 1;
110
+                        }else{
111
+                            hasNext = false;
112
+                        }
113
+                        hikDevices.addAll(JSON.parseArray(data.getString("list"), HikDevice.class));
114
+                    }
115
+                }
116
+            }else{
117
+                logger.warn("海康平台对接参数未配置");
118
+            }
119
+            for (HikDevice hikDevice : hikDevices){
120
+                CameraInfo info = new CameraInfo();
121
+                info.setCameraIndexCode(hikDevice.getIndexCode());
122
+                info.setOnlineStatus(hikDevice.getOnline() == 0 ? false : true);
123
+                cameraInfoService.updateOnlineStatusByIndexCode(info);
124
+            }
125
+        }
126
+    }
127
+
128
+    private static String getIp(String url){
129
+        String ip = "";
130
+        Pattern pattern = Pattern.compile("(\\d+\\.\\d+\\.\\d+\\.\\d+)");
131
+        Matcher matcher = pattern.matcher(url);
132
+        while(matcher.find()) {
133
+            ip = matcher.group(1);
134
+        }
135
+        return ip;
136
+    }
137
+    private static String getPort(String url){
138
+        String port = "";
139
+        Pattern pattern = Pattern.compile("(\\d+\\.\\d+\\.\\d+\\.\\d+)\\:(\\d+)");
140
+        Matcher matcher = pattern.matcher(url);
141
+        while(matcher.find()) {
142
+            port = matcher.group(2);
143
+        }
144
+        return port;
145
+    }
146
+
147
+}

+ 53 - 0
src/main/java/com/lqkj/camera/thread/CameraThread.java

@@ -0,0 +1,53 @@
1
+package com.lqkj.camera.thread;
2
+
3
+import com.lqkj.camera.cache.CameraCacheUtil;
4
+import com.lqkj.camera.model.CameraVo;
5
+import com.lqkj.camera.util.CameraPush;
6
+import org.slf4j.Logger;
7
+import org.slf4j.LoggerFactory;
8
+
9
+import java.util.concurrent.ExecutorService;
10
+import java.util.concurrent.Executors;
11
+
12
+public class CameraThread {
13
+    private final static Logger logger = LoggerFactory.getLogger(CameraThread.class);
14
+    public static class MyRunnable implements Runnable{
15
+        // 创建线程池
16
+        public static ExecutorService es = Executors.newCachedThreadPool();
17
+        private CameraVo cameraVo;
18
+        private Thread nowThread;
19
+
20
+        public MyRunnable(CameraVo cameraVo) {
21
+            this.cameraVo = cameraVo;
22
+        }
23
+
24
+        /**
25
+         * 中断线程停止推流
26
+         */
27
+        public void setInterrupted() {
28
+            nowThread.interrupt();
29
+        }
30
+
31
+        /**
32
+         * 执行线程进行直播推流
33
+         */
34
+        @Override
35
+        public void run() {
36
+            try {
37
+                //获取当前线程存入缓存
38
+                nowThread = Thread.currentThread();
39
+                CameraCacheUtil.STREAMMAP.put(cameraVo.getToken(), cameraVo);
40
+                CameraPush push = new CameraPush(cameraVo).from();
41
+                if (push != null) {
42
+                    push.to().go(nowThread);
43
+                }
44
+                CameraCacheUtil.STREAMMAP.remove(cameraVo.getToken());
45
+                CameraCacheUtil.STREAMTHREAD.remove(cameraVo.getToken());
46
+            }catch (Exception e){
47
+                logger.error("当前任务:" + cameraVo.getRtsp() + "停止...");
48
+                CameraCacheUtil.STREAMMAP.remove(cameraVo.getToken());
49
+                CameraCacheUtil.STREAMTHREAD.remove(cameraVo.getToken());
50
+            }
51
+        }
52
+    }
53
+}

+ 233 - 0
src/main/java/com/lqkj/camera/util/CameraPush.java

@@ -0,0 +1,233 @@
1
+package com.lqkj.camera.util;
2
+
3
+import com.lqkj.camera.config.CameraConfig;
4
+import com.lqkj.camera.model.CameraVo;
5
+import org.bytedeco.ffmpeg.avcodec.AVPacket;
6
+import org.bytedeco.ffmpeg.avformat.AVFormatContext;
7
+import org.bytedeco.javacv.FFmpegFrameGrabber;
8
+import org.bytedeco.javacv.FFmpegFrameRecorder;
9
+import org.slf4j.Logger;
10
+import org.slf4j.LoggerFactory;
11
+import org.springframework.context.ApplicationContext;
12
+
13
+import java.io.IOException;
14
+import java.net.InetSocketAddress;
15
+import java.net.Socket;
16
+import java.util.regex.Matcher;
17
+import java.util.regex.Pattern;
18
+
19
+import static org.bytedeco.ffmpeg.global.avcodec.av_packet_unref;
20
+
21
+public class CameraPush {
22
+    private final static Logger logger = LoggerFactory.getLogger(CameraPush.class);
23
+    private static CameraConfig cameraConfig;
24
+
25
+    // 通过applicationContext上下文获取Config类
26
+    public static void setApplicationContext(ApplicationContext applicationContext) {
27
+        cameraConfig = applicationContext.getBean(CameraConfig.class);
28
+    }
29
+
30
+    protected FFmpegFrameGrabber grabber = null;// 解码器
31
+    protected FFmpegFrameRecorder record = null;// 编码器
32
+    int width;// 视频像素宽
33
+    int height;// 视频像素高
34
+
35
+    // 视频参数
36
+    protected int audiocodecid;
37
+    protected int codecid;
38
+    protected double framerate;// 帧率
39
+    protected int bitrate;// 比特率
40
+
41
+    // 音频参数
42
+    // 想要录制音频,这三个参数必须有:audioChannels > 0 && audioBitrate > 0 && sampleRate > 0
43
+    private int audioChannels;
44
+    private int audioBitrate;
45
+    private int sampleRate;
46
+
47
+    private CameraVo cameraVo;
48
+
49
+    public CameraPush() {
50
+        super();
51
+    }
52
+
53
+    public CameraPush(CameraVo cameraVo) {
54
+        this.cameraVo = cameraVo;
55
+    }
56
+
57
+
58
+    /**
59
+     * 选择视频源
60
+     */
61
+    public CameraPush from() throws Exception {
62
+        // 采集/抓取器
63
+        grabber = FFmpegFrameGrabber.createDefault(cameraVo.getRtsp());
64
+
65
+        //校验相机和rtmp服务器是否能访问
66
+        Socket rtspSocket = new Socket();
67
+        Socket rtmpSocket = new Socket();
68
+        // 建立TCP Scoket连接,超时时间2s,如果成功继续执行,否则return
69
+        logger.debug("******   TCPCheck    BEGIN   ******");
70
+        String cameraIp = "";
71
+        String cameraPort = "";
72
+        if(cameraConfig.getTcpConnectCheck()){
73
+            try {
74
+                Pattern pattern = Pattern.compile("(\\d+\\.\\d+\\.\\d+\\.\\d+)\\:(\\d+)");
75
+                Matcher matcher = pattern.matcher(cameraVo.getRtsp());
76
+                while(matcher.find()) {
77
+                    cameraIp = matcher.group(1);
78
+                    cameraPort = matcher.group(2);
79
+                }
80
+                rtspSocket.connect(new InetSocketAddress(cameraIp, Integer.parseInt(cameraPort.trim())), 2000);
81
+            } catch (IOException e) {
82
+                grabber.stop();
83
+                grabber.close();
84
+                rtspSocket.close();
85
+                logger.error("与拉流IP:   " + cameraIp + "   端口:  " + cameraPort +"    建立TCP连接失败!");
86
+                return null;
87
+            }
88
+        }
89
+        try {
90
+            rtmpSocket.connect(new InetSocketAddress(cameraConfig.getPushHost(),
91
+                    cameraConfig.getPushPort()), 2000);
92
+        } catch (IOException e) {
93
+            grabber.stop();
94
+            grabber.close();
95
+            rtspSocket.close();
96
+            logger.error("与推流IP:   " + cameraConfig.getPushHost() + "   端口:   " +cameraConfig.getPushPort() + " 建立TCP连接失败!");
97
+            return null;
98
+        }
99
+        logger.debug("******   TCPCheck    END     ******");
100
+
101
+        if (cameraVo.getRtsp().indexOf("rtsp") >= 0) {
102
+            grabber.setOption("rtsp_transport", "tcp");// tcp用于解决丢包问题
103
+            grabber.setOption("stimeout", String.valueOf(15 * 1000000));
104
+        }else{
105
+            grabber.setOption("rw_timeout", String.valueOf(15 * 1000000));
106
+        }
107
+        try {
108
+            logger.debug("******   grabber.start()    BEGIN   ******");
109
+            grabber.startUnsafe();
110
+            logger.debug("******   grabber.start()    END     ******");
111
+
112
+            // 开始之后ffmpeg会采集视频信息,之后就可以获取音视频信息
113
+
114
+            width = grabber.getImageWidth();
115
+            height = grabber.getImageHeight();
116
+            // 若视频像素值为0,说明拉流异常,程序结束
117
+            if (width == 0 && height == 0) {
118
+                logger.error(cameraVo.getRtsp() + "  拉流异常!");
119
+                grabber.stop();
120
+                grabber.close();
121
+                return null;
122
+            }
123
+            // 视频参数
124
+            audiocodecid = grabber.getAudioCodec();
125
+            codecid = grabber.getVideoCodec();
126
+            framerate = grabber.getVideoFrameRate();// 帧率
127
+            bitrate = grabber.getVideoBitrate();// 比特率
128
+            // 音频参数
129
+            // 想要录制音频,这三个参数必须有:audioChannels > 0 && audioBitrate > 0 && sampleRate > 0
130
+            audioChannels = grabber.getAudioChannels();
131
+            audioBitrate = grabber.getAudioBitrate();
132
+            if (audioBitrate < 1) {
133
+                audioBitrate = 128 * 1000;// 默认音频比特率
134
+            }
135
+            sampleRate = grabber.getSampleRate();
136
+        } catch (org.bytedeco.javacv.FrameGrabber.Exception e) {
137
+            logger.error("ffmpeg错误信息:", e);
138
+            grabber.stop();
139
+            grabber.close();
140
+            return null;
141
+        }
142
+
143
+        return this;
144
+    }
145
+
146
+    /**
147
+     * 选择输出
148
+     */
149
+    public CameraPush to() throws Exception {
150
+        // 录制/推流器
151
+        record = new FFmpegFrameRecorder(cameraVo.getRtmp(), width, height);
152
+        record.setVideoOption("crf", "28");// 画面质量参数,0~51;18~28是一个合理范围
153
+        record.setGopSize(2);
154
+        record.setFrameRate(framerate);
155
+        record.setVideoBitrate(bitrate);
156
+
157
+        record.setAudioChannels(audioChannels);
158
+        record.setAudioBitrate(audioBitrate);
159
+        record.setSampleRate(sampleRate);
160
+        AVFormatContext fc = null;
161
+        if (cameraVo.getRtmp().indexOf("rtmp") >= 0 || cameraVo.getRtmp().indexOf("flv") > 0) {
162
+            // 封装格式flv
163
+            record.setFormat("flv");
164
+            record.setAudioCodecName("aac");
165
+            record.setVideoCodec(codecid);
166
+            fc = grabber.getFormatContext();
167
+        }
168
+        try {
169
+            record.start(fc);
170
+        } catch (Exception e) {
171
+            logger.error(cameraVo.getRtsp() + "  推流异常!");
172
+            logger.error("ffmpeg错误信息:", e);
173
+            grabber.stop();
174
+            grabber.close();
175
+            record.stop();
176
+            record.close();
177
+            return null;
178
+        }
179
+        return this;
180
+
181
+    }
182
+
183
+    /**
184
+     * 转封装
185
+     */
186
+    public CameraPush go(Thread nowThread)
187
+            throws org.bytedeco.javacv.FrameGrabber.Exception, org.bytedeco.javacv.FrameRecorder.Exception {
188
+        long err_index = 0;// 采集或推流导致的错误次数
189
+        // 连续五次没有采集到帧则认为视频采集结束,程序错误次数超过5次即中断程序
190
+        logger.info(cameraVo.getRtsp() + " 开始推流...");
191
+        // 释放探测时缓存下来的数据帧,避免pts初始值不为0导致画面延时
192
+        grabber.flush();
193
+        for (int no_frame_index = 0; no_frame_index < 5 || err_index < 5; ) {
194
+            try {
195
+                // 用于中断线程时,结束该循环
196
+                nowThread.sleep(1);
197
+                AVPacket pkt = null;
198
+                // 获取没有解码的音视频帧
199
+                pkt = grabber.grabPacket();
200
+                if (pkt == null || pkt.size() <= 0 || pkt.data() == null) {
201
+                    // 空包记录次数跳过
202
+                    no_frame_index++;
203
+                    err_index++;
204
+                    continue;
205
+                }
206
+                // 不需要编码直接把音视频帧推出去
207
+                err_index += (record.recordPacket(pkt) ? 0 : 1);
208
+
209
+                av_packet_unref(pkt);
210
+            } catch (InterruptedException e) {
211
+                e.printStackTrace();
212
+                // 销毁构造器
213
+                grabber.stop();
214
+                grabber.close();
215
+                record.stop();
216
+                record.close();
217
+                logger.info(cameraVo.getRtsp() + " 中断推流成功!");
218
+                break;
219
+            } catch (org.bytedeco.javacv.FrameGrabber.Exception e) {
220
+                err_index++;
221
+            } catch (org.bytedeco.javacv.FrameRecorder.Exception e) {
222
+                err_index++;
223
+            }
224
+        }
225
+        // 程序正常结束销毁构造器
226
+        grabber.stop();
227
+        grabber.close();
228
+        record.stop();
229
+        record.close();
230
+        logger.info(cameraVo.getRtsp() + " 推流结束...");
231
+        return this;
232
+    }
233
+}

+ 155 - 0
src/main/java/com/lqkj/camera/util/HIKCameraUtils.java

@@ -0,0 +1,155 @@
1
+package com.lqkj.camera.util;
2
+
3
+
4
+import com.alibaba.fastjson.JSONObject;
5
+import com.hikvision.artemis.sdk.ArtemisHttpUtil;
6
+import com.hikvision.artemis.sdk.config.ArtemisConfig;
7
+import org.slf4j.Logger;
8
+import org.slf4j.LoggerFactory;
9
+
10
+import java.util.HashMap;
11
+import java.util.Map;
12
+
13
+/**
14
+ * 海康视频调阅工具类
15
+ */
16
+public class HIKCameraUtils {
17
+
18
+    private static Logger logger = LoggerFactory.getLogger("HIK camera api");
19
+
20
+    private static HIKCameraUtils hikCameraUtils;
21
+
22
+    private static String HTTPProtocol = "https";
23
+
24
+    private static String host;
25
+
26
+    private static String appKey;
27
+
28
+    private static String appSecret;
29
+
30
+    private HIKCameraUtils(){}
31
+
32
+    private HIKCameraUtils(String host, String appKey, String appSecret, String httpProtocol){
33
+        this.host = host;
34
+        this.appKey = appKey;
35
+        this.appSecret = appSecret;
36
+        this.HTTPProtocol = httpProtocol;
37
+    }
38
+
39
+    /**
40
+     * 获得一个单一实例
41
+     * @return MD5
42
+     */
43
+    public static synchronized HIKCameraUtils getDefaultInstance(String host,
44
+                                                                 String appKey,
45
+                                                                 String appSecret,
46
+                                                                 String httpProtocol){
47
+        if(hikCameraUtils==null){
48
+            hikCameraUtils = new HIKCameraUtils(host, appKey, appSecret, httpProtocol);
49
+        }
50
+        return hikCameraUtils;
51
+    }
52
+
53
+    /**
54
+     * 获取视频格式预览(实时)流地址
55
+     * @return
56
+     */
57
+    public String getCameraPreviewURL (String body){
58
+
59
+        /**
60
+         * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数.
61
+         */
62
+        ArtemisConfig.host = host; // artemis网关服务器ip端口
63
+        ArtemisConfig.appKey = appKey;  // 秘钥appkey
64
+        ArtemisConfig.appSecret = appSecret;// 秘钥appSecret
65
+
66
+        /**
67
+         * STEP2:设置OpenAPI接口的上下文
68
+         */
69
+        final String ARTEMIS_PATH = "/artemis";
70
+
71
+        /**
72
+         * STEP3:设置接口的URI地址
73
+         */
74
+        final String previewURLsApi = ARTEMIS_PATH + "/api/video/v1/cameras/previewURLs";
75
+        Map<String, String> path = new HashMap<String, String>(2) {
76
+            {
77
+                put(HTTPProtocol + "://", previewURLsApi);//根据现场环境部署确认是http还是https
78
+            }
79
+        };
80
+
81
+        /**
82
+         * STEP4:设置参数提交方式
83
+         */
84
+        String contentType = "application/json";
85
+
86
+        /**
87
+         * STEP:调用接口
88
+         */
89
+        String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType , null);// post请求application/json类型参数
90
+        JSONObject resultJson = JSONObject.parseObject(result);
91
+        try {
92
+            return resultJson.getJSONObject("data").getString("url");
93
+        } catch (Exception e) {
94
+            logger.error(result);
95
+            return null;
96
+        }
97
+    }
98
+
99
+    /**
100
+     * 分页获取监控设备列表
101
+     * @return
102
+     */
103
+    public String pageQueryCamerasWithStatus (Integer pageSize, Integer pageNo){
104
+
105
+        /**
106
+         * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数.
107
+         */
108
+        ArtemisConfig.host = host; // artemis网关服务器ip端口
109
+        ArtemisConfig.appKey = appKey;  // 秘钥appkey
110
+        ArtemisConfig.appSecret = appSecret;// 秘钥appSecret
111
+
112
+        /**
113
+         * STEP2:设置OpenAPI接口的上下文
114
+         */
115
+        final String ARTEMIS_PATH = "/artemis";
116
+
117
+        /**
118
+         * STEP3:设置接口的URI地址
119
+         */
120
+        final String camerasDataApi = ARTEMIS_PATH + "/api/nms/v1/online/camera/get";
121
+        Map<String, String> path = new HashMap<String, String>(2) {
122
+            {
123
+                put(HTTPProtocol + "://", camerasDataApi);//根据现场环境部署确认是http还是https
124
+            }
125
+        };
126
+
127
+        /**
128
+         * STEP4:设置参数提交方式
129
+         */
130
+        String contentType = "application/json";
131
+
132
+        /**
133
+         * STEP5:组装请求参数
134
+         */
135
+        JSONObject jsonBody = new JSONObject();
136
+        jsonBody.put("pageSize", pageSize);
137
+        jsonBody.put("pageNo", pageNo);
138
+        String body = jsonBody.toJSONString();
139
+        /**
140
+         * STEP6:调用接口
141
+         */
142
+        return ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType , null);// post请求application/json类型参数
143
+
144
+    }
145
+
146
+    public static void main(String[] args) {
147
+        String body = "{\"cameraIndexCode\":\"06b9bc8db4764bc984364d5fe555ce5b\",\"streamType\":1,\"protocol\":\"hls\",\"transmode\":1 }";
148
+        String result = getDefaultInstance("10.22.3.60:443",
149
+                "23644070",
150
+                "iTjN7VDYx9eNbPUEPiKw",
151
+                "https").getCameraPreviewURL(body);
152
+        System.out.println("result结果示例: " + result);
153
+    }
154
+
155
+}

+ 72 - 0
src/main/java/com/lqkj/camera/util/TimerUtil.java

@@ -0,0 +1,72 @@
1
+package com.lqkj.camera.util;
2
+
3
+
4
+import com.lqkj.business.entity.CameraInfo;
5
+import com.lqkj.business.service.CameraInfoService;
6
+import com.lqkj.camera.cache.CameraCacheUtil;
7
+import com.lqkj.camera.config.CameraConfig;
8
+import com.lqkj.camera.model.CameraVo;
9
+import com.lqkj.camera.thread.CameraThread;
10
+import org.slf4j.Logger;
11
+import org.slf4j.LoggerFactory;
12
+import org.springframework.beans.factory.annotation.Autowired;
13
+import org.springframework.boot.CommandLineRunner;
14
+import org.springframework.stereotype.Component;
15
+
16
+import java.util.Date;
17
+import java.util.List;
18
+import java.util.Timer;
19
+import java.util.TimerTask;
20
+
21
+/**
22
+ * 定时任务监听相机调用情况
23
+ */
24
+@Component
25
+public class TimerUtil implements CommandLineRunner {
26
+    private final static Logger logger = LoggerFactory.getLogger(TimerUtil.class);
27
+    @Autowired
28
+    private CameraConfig cameraConfig;
29
+    public static Timer timer;
30
+
31
+    static boolean flag = true;
32
+    @Autowired
33
+    private CameraInfoService cameraInfoService;
34
+    @Override
35
+    public void run(String... args) throws Exception {
36
+        timer = new Timer("cameraTimer");
37
+        timer.schedule(new TimerTask() {
38
+            @Override
39
+            public void run() {
40
+
41
+                if (flag){
42
+                    logger.info("******   执行定时任务开始自动推流      BEGIN   ******");
43
+                    flag = false;
44
+                    List<CameraInfo> cameraInfos = cameraInfoService.selectCameraInfoList(null);
45
+                    for (CameraInfo cameraInfo : cameraInfos){
46
+                        CameraVo cameraVo = new CameraVo();
47
+                        cameraVo.setRtsp(cameraInfo.getUrl());
48
+                        if (!CameraCacheUtil.STREAMTHREAD.containsKey(cameraInfo.getCameraId())){
49
+                            String rtmp = "rtmp://" + cameraConfig.getPushHost() + ":" + cameraConfig.getPushPort() + "/hls/" + cameraInfo.getCameraId();
50
+                            String httpHls = cameraConfig.getHttpFlvHost() + "/hls/" + cameraInfo.getCameraId() + ".m3u8";
51
+                            cameraVo.setToken(cameraInfo.getCameraId());
52
+                            cameraVo.setCount(1);
53
+                            cameraVo.setOpenTime(new Date());
54
+                            cameraVo.setHttpFlv(httpHls);
55
+                            cameraVo.setRtmp(rtmp);
56
+                            CameraThread.MyRunnable job = new CameraThread.MyRunnable(cameraVo);
57
+                            CameraThread.MyRunnable.es.execute(job);
58
+                            CameraCacheUtil.STREAMTHREAD.put(cameraInfo.getCameraId(),job);
59
+                            try {
60
+                                Thread.sleep(15000);
61
+                            } catch (InterruptedException e) {
62
+                                e.printStackTrace();
63
+                            }
64
+                        }
65
+                    }
66
+                    flag = true;
67
+                    logger.info("******   执行定时任务开始自动推流      END   ******");
68
+                }
69
+            }
70
+        }, 1, 1000 * 60);
71
+    }
72
+}

+ 127 - 0
src/main/java/com/lqkj/camera/util/UniviewCameraUtils.java

@@ -0,0 +1,127 @@
1
+package com.lqkj.camera.util;
2
+
3
+import com.alibaba.fastjson.JSONObject;
4
+import com.lqkj.common.utils.Base64;
5
+import com.lqkj.common.utils.StringUtils;
6
+import com.lqkj.common.utils.http.HttpUtils;
7
+import okhttp3.*;
8
+import org.apache.commons.codec.digest.DigestUtils;
9
+import org.apache.http.entity.ContentType;
10
+import org.slf4j.Logger;
11
+import org.slf4j.LoggerFactory;
12
+
13
+import java.nio.charset.StandardCharsets;
14
+
15
+/**
16
+ * 宇视相机调用接口
17
+ */
18
+public class UniviewCameraUtils {
19
+    private static Logger logger = LoggerFactory.getLogger("uniview camera api");
20
+    private static String host;
21
+    private static String username;
22
+    private static String password;
23
+    private static UniviewCameraUtils univiewCameraUtils;
24
+    private UniviewCameraUtils(){}
25
+
26
+    private UniviewCameraUtils(String host, String username, String password){
27
+        this.host = host;
28
+        this.username = username;
29
+        this.password = password;
30
+    }
31
+    public static synchronized UniviewCameraUtils getDefaultInstance(String host, String username, String password){
32
+        if (univiewCameraUtils == null){
33
+            univiewCameraUtils = new UniviewCameraUtils(host, username, password);
34
+        }
35
+        return univiewCameraUtils;
36
+    }
37
+    /**
38
+     * 登录
39
+     * @return
40
+     */
41
+    public String login(){
42
+        String accessCode = "";
43
+        String accessToken = "";
44
+        Request request = new Request.Builder()
45
+                .url(host + "login")
46
+                .addHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType())
47
+                .build();
48
+        OkHttpClient okHttpClient = new OkHttpClient();
49
+        try (Response response = okHttpClient.newCall(request).execute()) {
50
+            if (response.code() == 200) {
51
+                String result = response.body().string();
52
+                if (StringUtils.isNotEmpty(result)){
53
+                    JSONObject resultJson = JSONObject.parseObject(result);
54
+                    accessCode = resultJson.getString("AccessCode");
55
+                }
56
+            }
57
+        } catch (Exception e) {
58
+            logger.error(e.getMessage());
59
+        }
60
+        if (StringUtils.isNotEmpty(accessCode)){
61
+            String loginSignature = DigestUtils.md5Hex(Base64.encode(username.getBytes(StandardCharsets.UTF_8)) + accessCode + DigestUtils.md5Hex(password));
62
+            String body = "{\"UserName\":\"" + username +"\", \"AccessCode\":\"" + accessCode +"\", \"LoginSignature\":\"" + loginSignature+ "\"}";
63
+            Request loginRequest = new Request.Builder()
64
+                    .url(host + "login")
65
+                    .post(RequestBody.create(body, MediaType.parse(ContentType.APPLICATION_JSON.getMimeType())))
66
+                    .addHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType())
67
+                    .build();
68
+            OkHttpClient client = new OkHttpClient();
69
+            try (Response response = client.newCall(loginRequest).execute()) {
70
+                if (response.code() == 200) {
71
+                    accessToken = response.header("Authorization");
72
+                }
73
+            } catch (Exception e) {
74
+                logger.error(e.getMessage());
75
+            }
76
+        }
77
+        return accessToken;
78
+    }
79
+
80
+    /**
81
+     * 获取视频流地址
82
+     * @param accessToken
83
+     * @param TSAddress
84
+     * @param TSPort
85
+     * @param CamCode
86
+     * @return
87
+     */
88
+    public String getCameraPreviewUrl(String accessToken,
89
+                                      String TSAddress,
90
+                                      String TSPort,
91
+                                      String CamCode){
92
+        String condition = "{\"ProtocolType\":1,\"TSAddress\":\"" + TSAddress + "\",\"TSPort\":" + TSPort+"," +
93
+                "\"CamCodes\":[\"" + CamCode +"\"],\"StreamType\":0}";
94
+        Request request = new Request.Builder()
95
+                .url(host + "video/live?condition=" + condition)
96
+                .addHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType())
97
+                .addHeader("Authorization", accessToken)
98
+                .get()
99
+                .build();
100
+        OkHttpClient client = new OkHttpClient();
101
+        try (Response response = client.newCall(request).execute()) {
102
+            if (response.code() == 200) {
103
+                return response.body().string();
104
+            }
105
+        } catch (Exception e) {
106
+            logger.error(e.getMessage());
107
+        }
108
+        return null;
109
+    }
110
+
111
+    /**
112
+     * 分页查询相机状态
113
+     * @return
114
+     */
115
+    public String pageQueryCamerasWithStatus(){
116
+//        String condition = "{\"ProtocolType\":1,\"TSAddress\":\"" + TSAddress + "\",\"TSPort\":" + TSPort+"," +
117
+//                "\"CamCodes\":[\"" + CamCode +"\"],\"StreamType\":0}";
118
+//        Request request = new Request.Builder()
119
+//                .url(host + "query?condition=" + condition)
120
+//                .addHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType())
121
+//                .addHeader("Authorization", accessToken)
122
+//                .get()
123
+//                .build();
124
+        return null;
125
+    }
126
+
127
+}

+ 22 - 0
src/main/java/com/lqkj/common/annotation/DataScope.java

@@ -0,0 +1,22 @@
1
+package com.lqkj.common.annotation;
2
+
3
+import java.lang.annotation.*;
4
+
5
+/**
6
+ * 数据权限过滤注解
7
+ * @author  lh
8
+ */
9
+@Target(ElementType.METHOD)
10
+@Retention(RetentionPolicy.RUNTIME)
11
+@Documented
12
+public @interface DataScope {
13
+    /**
14
+     * 部门表的别名
15
+     */
16
+    public String deptAlias() default "";
17
+
18
+    /**
19
+     * 用户表的别名
20
+     */
21
+    public String userAlias() default "";
22
+}

+ 178 - 0
src/main/java/com/lqkj/common/annotation/Excel.java

@@ -0,0 +1,178 @@
1
+package com.lqkj.common.annotation;
2
+
3
+
4
+import com.lqkj.common.utils.poi.ExcelHandlerAdapter;
5
+
6
+import java.lang.annotation.ElementType;
7
+import java.lang.annotation.Retention;
8
+import java.lang.annotation.RetentionPolicy;
9
+import java.lang.annotation.Target;
10
+import java.math.BigDecimal;
11
+
12
+/**
13
+ * 自定义导出Excel数据注解
14
+ * 
15
+ * @author lh
16
+ */
17
+@Retention(RetentionPolicy.RUNTIME)
18
+@Target(ElementType.FIELD)
19
+public @interface Excel
20
+{
21
+    /**
22
+     * 导出时在excel中排序
23
+     */
24
+    public int sort() default Integer.MAX_VALUE;
25
+
26
+    /**
27
+     * 导出到Excel中的名字.
28
+     */
29
+    public String name() default "";
30
+
31
+    /**
32
+     * 日期格式, 如: yyyy-MM-dd
33
+     */
34
+    public String dateFormat() default "";
35
+
36
+    /**
37
+     * 如果是字典类型,请设置字典的type值 (如: sys_user_sex)
38
+     */
39
+    public String dictType() default "";
40
+
41
+    /**
42
+     * 读取内容转表达式 (如: 0=男,1=女,2=未知)
43
+     */
44
+    public String readConverterExp() default "";
45
+
46
+    /**
47
+     * 分隔符,读取字符串组内容
48
+     */
49
+    public String separator() default ",";
50
+
51
+    /**
52
+     * BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化)
53
+     */
54
+    public int scale() default -1;
55
+
56
+    /**
57
+     * BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN
58
+     */
59
+    public int roundingMode() default BigDecimal.ROUND_HALF_EVEN;
60
+
61
+    /**
62
+     * 导出类型(0数字 1字符串)
63
+     */
64
+    public ColumnType cellType() default ColumnType.STRING;
65
+
66
+    /**
67
+     * 导出时在excel中每个列的高度 单位为字符
68
+     */
69
+    public double height() default 14;
70
+
71
+    /**
72
+     * 导出时在excel中每个列的宽 单位为字符
73
+     */
74
+    public double width() default 16;
75
+
76
+    /**
77
+     * 文字后缀,如% 90 变成90%
78
+     */
79
+    public String suffix() default "";
80
+
81
+    /**
82
+     * 当值为空时,字段的默认值
83
+     */
84
+    public String defaultValue() default "";
85
+
86
+    /**
87
+     * 提示信息
88
+     */
89
+    public String prompt() default "";
90
+
91
+    /**
92
+     * 设置只能选择不能输入的列内容.
93
+     */
94
+    public String[] combo() default {};
95
+
96
+    /**
97
+     * 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
98
+     */
99
+    public boolean isExport() default true;
100
+
101
+    /**
102
+     * 另一个类中的属性名称,支持多级获取,以小数点隔开
103
+     */
104
+    public String targetAttr() default "";
105
+
106
+    /**
107
+     * 是否自动统计数据,在最后追加一行统计数据总和
108
+     */
109
+    public boolean isStatistics() default false;
110
+
111
+    /**
112
+     * 导出字段对齐方式(0:默认;1:靠左;2:居中;3:靠右)
113
+     */
114
+    public Align align() default Align.AUTO;
115
+
116
+    /**
117
+     * 自定义数据处理器
118
+     */
119
+    public Class<?> handler() default ExcelHandlerAdapter.class;
120
+
121
+    /**
122
+     * 自定义数据处理器参数
123
+     */
124
+    public String[] args() default {};
125
+
126
+    public enum Align
127
+    {
128
+        AUTO(0), LEFT(1), CENTER(2), RIGHT(3);
129
+        private final int value;
130
+
131
+        Align(int value)
132
+        {
133
+            this.value = value;
134
+        }
135
+
136
+        public int value()
137
+        {
138
+            return this.value;
139
+        }
140
+    }
141
+
142
+    /**
143
+     * 字段类型(0:导出导入;1:仅导出;2:仅导入)
144
+     */
145
+    Type type() default Type.ALL;
146
+
147
+    public enum Type
148
+    {
149
+        ALL(0), EXPORT(1), IMPORT(2);
150
+        private final int value;
151
+
152
+        Type(int value)
153
+        {
154
+            this.value = value;
155
+        }
156
+
157
+        public int value()
158
+        {
159
+            return this.value;
160
+        }
161
+    }
162
+
163
+    public enum ColumnType
164
+    {
165
+        NUMERIC(0), STRING(1), IMAGE(2);
166
+        private final int value;
167
+
168
+        ColumnType(int value)
169
+        {
170
+            this.value = value;
171
+        }
172
+
173
+        public int value()
174
+        {
175
+            return this.value;
176
+        }
177
+    }
178
+}

+ 18 - 0
src/main/java/com/lqkj/common/annotation/Excels.java

@@ -0,0 +1,18 @@
1
+package com.lqkj.common.annotation;
2
+
3
+import java.lang.annotation.ElementType;
4
+import java.lang.annotation.Retention;
5
+import java.lang.annotation.RetentionPolicy;
6
+import java.lang.annotation.Target;
7
+
8
+/**
9
+ * Excel注解集
10
+ * 
11
+ * @author lh
12
+ */
13
+@Target(ElementType.FIELD)
14
+@Retention(RetentionPolicy.RUNTIME)
15
+public @interface Excels
16
+{
17
+    public Excel[] value();
18
+}

+ 45 - 0
src/main/java/com/lqkj/common/annotation/Log.java

@@ -0,0 +1,45 @@
1
+package com.lqkj.common.annotation;
2
+
3
+
4
+
5
+import com.lqkj.common.enums.BusinessType;
6
+import com.lqkj.common.enums.OperatorType;
7
+
8
+import java.lang.annotation.*;
9
+
10
+/**
11
+ * 自定义操作日志记录注解
12
+ * 
13
+ * @author lh
14
+ *
15
+ */
16
+@Target({ ElementType.PARAMETER, ElementType.METHOD })
17
+@Retention(RetentionPolicy.RUNTIME)
18
+@Documented
19
+public @interface Log
20
+{
21
+    /**
22
+     * 模块 
23
+     */
24
+    public String title() default "";
25
+
26
+    /**
27
+     * 功能
28
+     */
29
+    public BusinessType businessType() default BusinessType.OTHER;
30
+
31
+    /**
32
+     * 操作人类别
33
+     */
34
+    public OperatorType operatorType() default OperatorType.MANAGE;
35
+
36
+    /**
37
+     * 是否保存请求的参数
38
+     */
39
+    public boolean isSaveRequestData() default true;
40
+
41
+    /**
42
+     * 是否保存响应的参数
43
+     */
44
+    public boolean isSaveResponseData() default true;
45
+}

+ 38 - 0
src/main/java/com/lqkj/common/annotation/RateLimiter.java

@@ -0,0 +1,38 @@
1
+package com.lqkj.common.annotation;
2
+
3
+
4
+import com.lqkj.common.constant.Constants;
5
+import com.lqkj.common.enums.LimitType;
6
+
7
+import java.lang.annotation.*;
8
+
9
+/**
10
+ * 限流注解
11
+ * 
12
+ * @author lh
13
+ */
14
+@Target(ElementType.METHOD)
15
+@Retention(RetentionPolicy.RUNTIME)
16
+@Documented
17
+public @interface RateLimiter
18
+{
19
+    /**
20
+     * 限流key
21
+     */
22
+    public String key() default Constants.RATE_LIMIT_KEY;
23
+
24
+    /**
25
+     * 限流时间,单位秒
26
+     */
27
+    public int time() default 60;
28
+
29
+    /**
30
+     * 限流次数
31
+     */
32
+    public int count() default 100;
33
+
34
+    /**
35
+     * 限流类型
36
+     */
37
+    public LimitType limitType() default LimitType.DEFAULT;
38
+}

+ 26 - 0
src/main/java/com/lqkj/common/annotation/RepeatSubmit.java

@@ -0,0 +1,26 @@
1
+package com.lqkj.common.annotation;
2
+
3
+import java.lang.annotation.*;
4
+
5
+/**
6
+ * 自定义注解防止表单重复提交
7
+ * 
8
+ * @author lh
9
+ *
10
+ */
11
+@Inherited
12
+@Target(ElementType.METHOD)
13
+@Retention(RetentionPolicy.RUNTIME)
14
+@Documented
15
+public @interface RepeatSubmit
16
+{
17
+    /**
18
+     * 间隔时间(ms),小于此时间视为重复提交
19
+     */
20
+    public int interval() default 5000;
21
+
22
+    /**
23
+     * 提示消息
24
+     */
25
+    public String message() default "不允许重复提交,请稍候再试";
26
+}

+ 123 - 0
src/main/java/com/lqkj/common/config/LingWeiConfig.java

@@ -0,0 +1,123 @@
1
+package com.lqkj.common.config;
2
+
3
+import org.springframework.boot.context.properties.ConfigurationProperties;
4
+import org.springframework.stereotype.Component;
5
+
6
+/**
7
+ * 读取项目相关配置
8
+ *
9
+ * @author lh
10
+ */
11
+@Component
12
+@ConfigurationProperties(prefix = "lingwei")
13
+public class LingWeiConfig {
14
+    /** 项目名称 */
15
+    private String name;
16
+
17
+    /** 版本 */
18
+    private String version;
19
+
20
+    /** 版权年份 */
21
+    private String copyrightYear;
22
+
23
+    /** 实例演示开关 */
24
+    private boolean demoEnabled;
25
+
26
+    /** 上传路径 */
27
+    private static String profile;
28
+
29
+    /** 获取地址开关 */
30
+    private static boolean addressEnabled;
31
+
32
+    public String getName()
33
+    {
34
+        return name;
35
+    }
36
+
37
+    public void setName(String name)
38
+    {
39
+        this.name = name;
40
+    }
41
+
42
+    public String getVersion()
43
+    {
44
+        return version;
45
+    }
46
+
47
+    public void setVersion(String version)
48
+    {
49
+        this.version = version;
50
+    }
51
+
52
+    public String getCopyrightYear()
53
+    {
54
+        return copyrightYear;
55
+    }
56
+
57
+    public void setCopyrightYear(String copyrightYear)
58
+    {
59
+        this.copyrightYear = copyrightYear;
60
+    }
61
+
62
+    public boolean isDemoEnabled()
63
+    {
64
+        return demoEnabled;
65
+    }
66
+
67
+    public void setDemoEnabled(boolean demoEnabled)
68
+    {
69
+        this.demoEnabled = demoEnabled;
70
+    }
71
+
72
+    public static String getProfile()
73
+    {
74
+        return profile;
75
+    }
76
+
77
+    public void setProfile(String profile)
78
+    {
79
+        LingWeiConfig.profile = profile;
80
+    }
81
+
82
+    public static boolean isAddressEnabled()
83
+    {
84
+        return addressEnabled;
85
+    }
86
+
87
+    public void setAddressEnabled(boolean addressEnabled)
88
+    {
89
+        LingWeiConfig.addressEnabled = addressEnabled;
90
+    }
91
+
92
+    /**
93
+     * 获取导入上传路径
94
+     */
95
+    public static String getImportPath()
96
+    {
97
+        return getProfile() + "/import";
98
+    }
99
+
100
+    /**
101
+     * 获取头像上传路径
102
+     */
103
+    public static String getAvatarPath()
104
+    {
105
+        return getProfile() + "/avatar";
106
+    }
107
+
108
+    /**
109
+     * 获取下载路径
110
+     */
111
+    public static String getDownloadPath()
112
+    {
113
+        return getProfile() + "/download/";
114
+    }
115
+
116
+    /**
117
+     * 获取上传路径
118
+     */
119
+    public static String getUploadPath()
120
+    {
121
+        return getProfile() + "/upload";
122
+    }
123
+}

+ 109 - 0
src/main/java/com/lqkj/common/constant/Constants.java

@@ -0,0 +1,109 @@
1
+package com.lqkj.common.constant;
2
+
3
+/**
4
+ * 通用常量信息
5
+ * 
6
+ * @author lh
7
+ */
8
+public class Constants
9
+{
10
+    /**
11
+     * UTF-8 字符集
12
+     */
13
+    public static final String UTF8 = "UTF-8";
14
+
15
+    /**
16
+     * GBK 字符集
17
+     */
18
+    public static final String GBK = "GBK";
19
+
20
+    /**
21
+     * http请求
22
+     */
23
+    public static final String HTTP = "http://";
24
+
25
+    /**
26
+     * https请求
27
+     */
28
+    public static final String HTTPS = "https://";
29
+
30
+    /**
31
+     * 通用成功标识
32
+     */
33
+    public static final String SUCCESS = "0";
34
+
35
+    /**
36
+     * 通用失败标识
37
+     */
38
+    public static final String FAIL = "1";
39
+
40
+    /**
41
+     * 登录成功
42
+     */
43
+    public static final String LOGIN_SUCCESS = "Success";
44
+
45
+    /**
46
+     * 注销
47
+     */
48
+    public static final String LOGOUT = "Logout";
49
+
50
+    /**
51
+     * 注册
52
+     */
53
+    public static final String REGISTER = "Register";
54
+
55
+    /**
56
+     * 登录失败
57
+     */
58
+    public static final String LOGIN_FAIL = "Error";
59
+
60
+    /**
61
+     * 验证码 redis key
62
+     */
63
+    public static final String CAPTCHA_CODE_KEY = "captcha_codes:";
64
+
65
+    /**
66
+     * 登录用户 redis key
67
+     */
68
+    public static final String LOGIN_TOKEN_KEY = "login_tokens:";
69
+
70
+    /**
71
+     * 防重提交 redis key
72
+     */
73
+    public static final String REPEAT_SUBMIT_KEY = "repeat_submit:";
74
+
75
+    /**
76
+     * 限流 redis key
77
+     */
78
+    public static final String RATE_LIMIT_KEY = "rate_limit:";
79
+
80
+    /**
81
+     * 验证码有效期(分钟)
82
+     */
83
+    public static final Integer CAPTCHA_EXPIRATION = 2;
84
+
85
+    /**
86
+     * 参数管理 cache key
87
+     */
88
+    public static final String SYS_CONFIG_KEY = "sys_config:";
89
+
90
+    /**
91
+     * 字典管理 cache key
92
+     */
93
+    public static final String SYS_DICT_KEY = "sys_dict:";
94
+
95
+    /**
96
+     * 资源映射路径 前缀
97
+     */
98
+    public static final String RESOURCE_PREFIX = "/profile";
99
+
100
+    /**
101
+     * RMI 远程方法调用
102
+     */
103
+    public static final String LOOKUP_RMI = "rmi://";
104
+
105
+    /**
106
+     * LDAP 远程方法调用
107
+     */
108
+    public static final String LOOKUP_LDAP = "ldap://";
109
+}

+ 134 - 0
src/main/java/com/lqkj/common/constant/GenConstants.java

@@ -0,0 +1,134 @@
1
+package com.lqkj.common.constant;
2
+
3
+/**
4
+ * 代码生成通用常量
5
+ * 
6
+ * @author lh
7
+ */
8
+public class GenConstants
9
+{
10
+    /** 单表(增删改查) */
11
+    public static final String TPL_CRUD = "crud";
12
+
13
+    /** 树表(增删改查) */
14
+    public static final String TPL_TREE = "tree";
15
+
16
+    /** 主子表(增删改查) */
17
+    public static final String TPL_SUB = "sub";
18
+
19
+    /** 树编码字段 */
20
+    public static final String TREE_CODE = "treeCode";
21
+
22
+    /** 树父编码字段 */
23
+    public static final String TREE_PARENT_CODE = "treeParentCode";
24
+
25
+    /** 树名称字段 */
26
+    public static final String TREE_NAME = "treeName";
27
+
28
+    /** 上级菜单ID字段 */
29
+    public static final String PARENT_MENU_ID = "parentMenuId";
30
+
31
+    /** 上级菜单名称字段 */
32
+    public static final String PARENT_MENU_NAME = "parentMenuName";
33
+
34
+    /** 数据库字符串类型 */
35
+    public static final String[] COLUMNTYPE_STR = { "char", "varchar", "bpchar" };
36
+
37
+    /** 数据库文本类型 */
38
+    public static final String[] COLUMNTYPE_TEXT = { "text" };
39
+
40
+    /** 数据库时间类型 */
41
+    public static final String[] COLUMNTYPE_TIME = { "time", "date", "timestamp" };
42
+
43
+
44
+    /** 数据库数字类型 */
45
+    public static final String[] COLUMNTYPE_NUMBER = {"int2", "int4","int8", "float4", "float8", "numeric",
46
+            "bit",  "decimal" , "money"};
47
+
48
+    public static final String[]  COLUMNTYPE_BOOLEAN = {"bool"};
49
+
50
+    /** 页面不需要编辑字段 */
51
+    public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" };
52
+
53
+    /** 页面不需要显示的列表字段 */
54
+    public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by",
55
+            "update_time" };
56
+
57
+    /** 页面不需要查询字段 */
58
+    public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by",
59
+            "update_time", "remark" };
60
+
61
+    /** Entity基类字段 */
62
+    public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" };
63
+
64
+    /** Tree基类字段 */
65
+    public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors", "children" };
66
+
67
+    /** 文本框 */
68
+    public static final String HTML_INPUT = "input";
69
+
70
+    /** 文本域 */
71
+    public static final String HTML_TEXTAREA = "textarea";
72
+
73
+    /** 下拉框 */
74
+    public static final String HTML_SELECT = "select";
75
+
76
+    /** 单选框 */
77
+    public static final String HTML_RADIO = "radio";
78
+
79
+    /** 复选框 */
80
+    public static final String HTML_CHECKBOX = "checkbox";
81
+
82
+    /** 日期时间控件 */
83
+    public static final String HTML_DATETIME = "datetime";
84
+
85
+    /** 日期控件 */
86
+    public static final String HTML_DATE = "date";
87
+
88
+    /** 时间控件 */
89
+    public static final String HTML_TIME = "time";
90
+
91
+    /** 图片上传控件 */
92
+    public static final String HTML_IMAGE_UPLOAD = "imageUpload";
93
+
94
+    /** 文件上传控件 */
95
+    public static final String HTML_FILE_UPLOAD = "fileUpload";
96
+
97
+    /** 富文本控件 */
98
+    public static final String HTML_EDITOR = "editor";
99
+
100
+    /** switch开关 */
101
+    public static final String HTML_SWITCH = "switch";
102
+
103
+    /** 计数器 */
104
+    public static final String HTML_INPUT_NUMBER = "inputNumber";
105
+
106
+    /** 字符串类型 */
107
+    public static final String TYPE_STRING = "String";
108
+
109
+    /** 整型 */
110
+    public static final String TYPE_INTEGER = "Integer";
111
+
112
+    /** 长整型 */
113
+    public static final String TYPE_LONG = "Long";
114
+
115
+    /** Bool类型*/
116
+    public static final String TYPE_BOOLEAN = "Boolean";
117
+
118
+
119
+    /** 高精度计算类型 */
120
+    public static final String TYPE_BIGDECIMAL = "BigDecimal";
121
+
122
+    /** 时间类型 */
123
+    public static final String TYPE_LOCALTIME = "LocalTime";
124
+
125
+    /** 日期类型 */
126
+    public static final String TYPE_LOCALDATE = "LocalDate";
127
+
128
+    /** 日期时间类型 */
129
+    public static final String TYPE_LOCALDATETIME = "LocalDateTime";
130
+
131
+    /** 模糊查询 */
132
+    public static final String QUERY_LIKE = "LIKE";
133
+
134
+}

+ 27 - 0
src/main/java/com/lqkj/common/constant/ScheduleConstants.java

@@ -0,0 +1,27 @@
1
+package com.lqkj.common.constant;
2
+
3
+/**
4
+ * 任务调度通用常量
5
+ * 
6
+ * @author lh
7
+ */
8
+public class ScheduleConstants
9
+{
10
+    public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME";
11
+
12
+    /** 执行目标key */
13
+    public static final String TASK_PROPERTIES = "TASK_PROPERTIES";
14
+
15
+    /** 默认 */
16
+    public static final String MISFIRE_DEFAULT = "0";
17
+
18
+    /** 立即触发执行 */
19
+    public static final String MISFIRE_IGNORE_MISFIRES = "1";
20
+
21
+    /** 触发一次执行 */
22
+    public static final String MISFIRE_FIRE_AND_PROCEED = "2";
23
+
24
+    /** 不触发立即执行 */
25
+    public static final String MISFIRE_DO_NOTHING = "3";
26
+
27
+}

+ 32 - 0
src/main/java/com/lqkj/common/constant/UserConstants.java

@@ -0,0 +1,32 @@
1
+package com.lqkj.common.constant;
2
+
3
+/**
4
+ * 用户常量信息
5
+ * 
6
+ * @author lh
7
+ */
8
+public class UserConstants
9
+{
10
+    /** 菜单类型(目录) */
11
+    public static final String TYPE_DIR = "M";
12
+
13
+    /** 菜单类型(菜单) */
14
+    public static final String TYPE_MENU = "C";
15
+
16
+    /** 菜单类型(按钮) */
17
+    public static final String TYPE_BUTTON = "F";
18
+
19
+    /** Layout组件标识 */
20
+    public final static String LAYOUT = "Layout";
21
+    
22
+    /** ParentView组件标识 */
23
+    public final static String PARENT_VIEW = "ParentView";
24
+
25
+    /** InnerLink组件标识 */
26
+    public final static String INNER_LINK = "InnerLink";
27
+
28
+    /** 校验返回结果码 */
29
+    public final static String UNIQUE = "0";
30
+    public final static String NOT_UNIQUE = "1";
31
+
32
+}

+ 93 - 0
src/main/java/com/lqkj/common/core/controller/BaseController.java

@@ -0,0 +1,93 @@
1
+package com.lqkj.common.core.controller;
2
+
3
+import com.github.pagehelper.PageHelper;
4
+import com.lqkj.common.core.model.BaseEntity;
5
+import com.lqkj.common.core.model.LoginUser;
6
+import com.lqkj.common.core.model.ResultUtil;
7
+import com.lqkj.common.utils.SecurityUtils;
8
+import com.lqkj.common.utils.StringUtils;
9
+import com.lqkj.common.utils.sql.SqlUtil;
10
+import org.slf4j.Logger;
11
+import org.slf4j.LoggerFactory;
12
+
13
+import java.time.LocalDate;
14
+
15
+/**
16
+ * web层通用Controller
17
+ */
18
+public class BaseController {
19
+    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
20
+
21
+    /**
22
+     * 设置请求分页数据
23
+     */
24
+    protected void startPage(BaseEntity baseEntity){
25
+        if (StringUtils.isNotNull(baseEntity.getPageNum()) && StringUtils.isNotNull(baseEntity.getPageSize())){
26
+            String orderBy = SqlUtil.escapeOrderBySql(baseEntity.convertOrderBy());
27
+            PageHelper.startPage(baseEntity.getPageNum(), baseEntity.getPageSize(), orderBy).setReasonable(baseEntity.getReasonable());
28
+        }
29
+    }
30
+    /**
31
+     * 响应返回结果
32
+     *
33
+     * @param rows 影响行数
34
+     * @return 操作结果
35
+     */
36
+    protected ResultUtil resultByRows(int rows)
37
+    {
38
+        return rows > 0 ? ResultUtil.success() : ResultUtil.error();
39
+    }
40
+    /**
41
+     * 页面跳转
42
+     */
43
+    public String redirect(String url)
44
+    {
45
+        return StringUtils.format("redirect:{}", url);
46
+    }
47
+
48
+    /**
49
+     * 获取用户缓存信息
50
+     */
51
+    public LoginUser getLoginUser()
52
+    {
53
+        return SecurityUtils.getLoginUser();
54
+    }
55
+
56
+    /**
57
+     * 获取登录用户id
58
+     */
59
+    public String getUserId()
60
+    {
61
+        return getLoginUser().getUserId();
62
+    }
63
+
64
+    /**
65
+     * 获取登录部门id
66
+     */
67
+    public Integer getDeptId()
68
+    {
69
+        return getLoginUser().getDeptId();
70
+    }
71
+
72
+    /**
73
+     * 获取登录用户名
74
+     */
75
+    public String getUsername()
76
+    {
77
+        return getLoginUser().getUsername();
78
+    }
79
+
80
+    /**
81
+     * 获取登录用户昵称
82
+     */
83
+    public String getNickName(){
84
+        return getLoginUser().getUser().getNickName();
85
+    }
86
+
87
+    public int getCurrentYear(){
88
+        return LocalDate.now().getYear();
89
+    }
90
+    public int getCurrentMonth(){
91
+        return LocalDate.now().getMonthValue();
92
+    }
93
+}

+ 218 - 0
src/main/java/com/lqkj/common/core/model/BaseEntity.java

@@ -0,0 +1,218 @@
1
+package com.lqkj.common.core.model;
2
+
3
+
4
+import com.alibaba.excel.annotation.ExcelIgnore;
5
+import com.fasterxml.jackson.annotation.JsonFormat;
6
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
7
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
8
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
9
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
10
+import com.lqkj.common.utils.StringUtils;
11
+import io.swagger.annotations.ApiModelProperty;
12
+
13
+import java.io.Serializable;
14
+import java.time.LocalDateTime;
15
+import java.util.HashMap;
16
+import java.util.Map;
17
+
18
+/**
19
+ * Entity基类
20
+ *
21
+ * @author lh
22
+ */
23
+public class BaseEntity implements Serializable {
24
+    private static final long serialVersionUID = 1L;
25
+
26
+    /**
27
+     * 创建者
28
+     */
29
+//    @Excel(name = "创建人", sort = 9999)
30
+    @ApiModelProperty(hidden = true)
31
+    private String createBy;
32
+
33
+    /**
34
+     * 创建时间
35
+     */
36
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
37
+    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
38
+    @JsonSerialize(using = LocalDateTimeSerializer.class)
39
+//    @Excel(name = "创建时间", sort = 10000, width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Excel.Type.EXPORT)
40
+    @ApiModelProperty(hidden = true)
41
+    private LocalDateTime createTime;
42
+
43
+    /**
44
+     * 更新者
45
+     */
46
+    @ExcelIgnore
47
+    @ApiModelProperty(hidden = true)
48
+    private String updateBy;
49
+
50
+    /**
51
+     * 更新时间
52
+     */
53
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
54
+    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
55
+    @JsonSerialize(using = LocalDateTimeSerializer.class)
56
+    @ExcelIgnore
57
+    @ApiModelProperty(hidden = true)
58
+    private LocalDateTime updateTime;
59
+
60
+    /**
61
+     * 备注
62
+     */
63
+    @ExcelIgnore
64
+    @ApiModelProperty(hidden = true)
65
+    private String remark;
66
+
67
+    /**
68
+     * 当前记录起始索引
69
+     */
70
+    @ExcelIgnore
71
+    @ApiModelProperty(value = "分页页码(查询用)", example = "1")
72
+    private Integer pageNum = 1;
73
+
74
+    /**
75
+     * 每页显示记录数
76
+     */
77
+    @ExcelIgnore
78
+    @ApiModelProperty(value = "每页数量(查询用)", example = "10")
79
+    private Integer pageSize = 10;
80
+
81
+    /**
82
+     * 排序列
83
+     */
84
+    @ExcelIgnore
85
+    @ApiModelProperty(hidden = true)
86
+    private String orderByColumn;
87
+
88
+    /**
89
+     * 排序的方向desc或者asc
90
+     */
91
+    @ExcelIgnore
92
+    @ApiModelProperty(hidden = true)
93
+    private String isAsc = "asc";
94
+
95
+    /**
96
+     * 分页参数合理化
97
+     */
98
+    @ExcelIgnore
99
+    @ApiModelProperty(hidden = true)
100
+    private Boolean reasonable = true;
101
+
102
+    /**
103
+     * 请求参数
104
+     */
105
+    @ExcelIgnore
106
+    @ApiModelProperty(hidden = true)
107
+    private Map<String, Object> params;
108
+
109
+    public String getCreateBy() {
110
+        return createBy;
111
+    }
112
+
113
+    public void setCreateBy(String createBy) {
114
+        this.createBy = createBy;
115
+    }
116
+
117
+    public LocalDateTime getCreateTime() {
118
+        return createTime;
119
+    }
120
+
121
+    public void setCreateTime(LocalDateTime createTime) {
122
+        this.createTime = createTime;
123
+    }
124
+
125
+    public String getUpdateBy() {
126
+        return updateBy;
127
+    }
128
+
129
+    public void setUpdateBy(String updateBy) {
130
+        this.updateBy = updateBy;
131
+    }
132
+
133
+    public LocalDateTime getUpdateTime() {
134
+        return updateTime;
135
+    }
136
+
137
+    public void setUpdateTime(LocalDateTime updateTime) {
138
+        this.updateTime = updateTime;
139
+    }
140
+
141
+    public String getRemark() {
142
+        return remark;
143
+    }
144
+
145
+    public void setRemark(String remark) {
146
+        this.remark = remark;
147
+    }
148
+
149
+    public String convertOrderBy() {
150
+        if (StringUtils.isEmpty(orderByColumn)) {
151
+            return "";
152
+        }
153
+        return StringUtils.toUnderScoreCase(orderByColumn) + " " + isAsc;
154
+    }
155
+
156
+    public Integer getPageNum() {
157
+        return pageNum;
158
+    }
159
+
160
+    public void setPageNum(Integer pageNum) {
161
+        this.pageNum = pageNum;
162
+    }
163
+
164
+    public Integer getPageSize() {
165
+        return pageSize;
166
+    }
167
+
168
+    public void setPageSize(Integer pageSize) {
169
+        this.pageSize = pageSize;
170
+    }
171
+
172
+    public String getOrderByColumn() {
173
+        return orderByColumn;
174
+    }
175
+
176
+    public void setOrderByColumn(String orderByColumn) {
177
+        this.orderByColumn = orderByColumn;
178
+    }
179
+
180
+    public String getIsAsc() {
181
+        return isAsc;
182
+    }
183
+
184
+    public void setIsAsc(String isAsc) {
185
+        if (StringUtils.isNotEmpty(isAsc)) {
186
+            // 兼容前端排序类型
187
+            if ("ascending".equals(isAsc)) {
188
+                isAsc = "asc";
189
+            } else if ("descending".equals(isAsc)) {
190
+                isAsc = "desc";
191
+            }
192
+            this.isAsc = isAsc;
193
+        }
194
+    }
195
+
196
+    public Boolean getReasonable() {
197
+        if (StringUtils.isNull(reasonable)) {
198
+            return Boolean.TRUE;
199
+        }
200
+        return reasonable;
201
+    }
202
+
203
+    public void setReasonable(Boolean reasonable) {
204
+        this.reasonable = reasonable;
205
+    }
206
+
207
+    public Map<String, Object> getParams() {
208
+        if (params == null) {
209
+            params = new HashMap<>();
210
+        }
211
+        return params;
212
+    }
213
+
214
+    public void setParams(Map<String, Object> params) {
215
+        this.params = params;
216
+    }
217
+
218
+}

+ 69 - 0
src/main/java/com/lqkj/common/core/model/LoginBody.java

@@ -0,0 +1,69 @@
1
+package com.lqkj.common.core.model;
2
+
3
+/**
4
+ * 用户登录对象
5
+ * 
6
+ * @author lh
7
+ */
8
+public class LoginBody
9
+{
10
+    /**
11
+     * 用户名
12
+     */
13
+    private String username;
14
+
15
+    /**
16
+     * 用户密码
17
+     */
18
+    private String password;
19
+
20
+    /**
21
+     * 验证码
22
+     */
23
+    private String code;
24
+
25
+    /**
26
+     * 唯一标识
27
+     */
28
+    private String uuid = "";
29
+
30
+    public String getUsername()
31
+    {
32
+        return username;
33
+    }
34
+
35
+    public void setUsername(String username)
36
+    {
37
+        this.username = username;
38
+    }
39
+
40
+    public String getPassword()
41
+    {
42
+        return password;
43
+    }
44
+
45
+    public void setPassword(String password)
46
+    {
47
+        this.password = password;
48
+    }
49
+
50
+    public String getCode()
51
+    {
52
+        return code;
53
+    }
54
+
55
+    public void setCode(String code)
56
+    {
57
+        this.code = code;
58
+    }
59
+
60
+    public String getUuid()
61
+    {
62
+        return uuid;
63
+    }
64
+
65
+    public void setUuid(String uuid)
66
+    {
67
+        this.uuid = uuid;
68
+    }
69
+}

+ 162 - 0
src/main/java/com/lqkj/common/core/model/LoginUser.java

@@ -0,0 +1,162 @@
1
+package com.lqkj.common.core.model;
2
+
3
+
4
+import com.fasterxml.jackson.annotation.JsonIgnore;
5
+import com.lqkj.system.entity.SysUser;
6
+import org.springframework.security.core.GrantedAuthority;
7
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
8
+import org.springframework.security.core.userdetails.UserDetails;
9
+
10
+import java.util.ArrayList;
11
+import java.util.Collection;
12
+import java.util.List;
13
+import java.util.Set;
14
+
15
+/**
16
+ * 登录用户身份权限
17
+ * 
18
+ * @author lh
19
+ */
20
+public class LoginUser implements UserDetails
21
+{
22
+    private static final long serialVersionUID = 1L;
23
+
24
+    /**
25
+     * 用户ID
26
+     */
27
+    private String userId;
28
+
29
+    /**
30
+     * 部门ID
31
+     */
32
+    private Integer deptId;
33
+
34
+
35
+    /**
36
+     * 用户信息
37
+     */
38
+    private SysUser user;
39
+    /**
40
+     * 权限列表
41
+     */
42
+    private List<GrantedAuthority> authorities;
43
+
44
+    public String getUserId()
45
+    {
46
+        return userId;
47
+    }
48
+
49
+    public void setUserId(String userId)
50
+    {
51
+        this.userId = userId;
52
+    }
53
+
54
+    public Integer getDeptId()
55
+    {
56
+        return deptId;
57
+    }
58
+
59
+    public void setDeptId(Integer deptId)
60
+    {
61
+        this.deptId = deptId;
62
+    }
63
+
64
+
65
+    public LoginUser()
66
+    {
67
+    }
68
+
69
+    public LoginUser(String userId, Integer deptId, SysUser user)
70
+    {
71
+        this.userId = userId;
72
+        this.deptId = deptId;
73
+        this.user = user;
74
+    }
75
+
76
+    public void setAuthorities(Set<String> perms){
77
+        authorities = new ArrayList<>();
78
+        for (String perm : perms){
79
+            authorities.add(new SimpleGrantedAuthority(perm));
80
+        }
81
+    }
82
+
83
+
84
+    @JsonIgnore
85
+    @Override
86
+    public String getPassword()
87
+    {
88
+        return user.getPassword();
89
+    }
90
+
91
+    @Override
92
+    public String getUsername()
93
+    {
94
+        return user.getUserName();
95
+    }
96
+
97
+    /**
98
+     * 账户是否未过期,过期无法验证
99
+     */
100
+    @JsonIgnore
101
+    @Override
102
+    public boolean isAccountNonExpired()
103
+    {
104
+        return true;
105
+    }
106
+
107
+    /**
108
+     * 指定用户是否解锁,锁定的用户无法进行身份验证
109
+     * 
110
+     * @return
111
+     */
112
+    @JsonIgnore
113
+    @Override
114
+    public boolean isAccountNonLocked()
115
+    {
116
+        return true;
117
+    }
118
+
119
+    /**
120
+     * 指示是否已过期的用户的凭据(密码),过期的凭据防止认证
121
+     * 
122
+     * @return
123
+     */
124
+    @JsonIgnore
125
+    @Override
126
+    public boolean isCredentialsNonExpired()
127
+    {
128
+        return true;
129
+    }
130
+
131
+    /**
132
+     * 是否可用 ,禁用的用户不能身份验证
133
+     * 
134
+     * @return
135
+     */
136
+    @JsonIgnore
137
+    @Override
138
+    public boolean isEnabled()
139
+    {
140
+        return true;
141
+    }
142
+
143
+    public SysUser getUser()
144
+    {
145
+        return user;
146
+    }
147
+
148
+    public void setUser(SysUser user)
149
+    {
150
+        this.user = user;
151
+    }
152
+
153
+    @Override
154
+    public Collection<? extends GrantedAuthority> getAuthorities()
155
+    {
156
+        return this.authorities;
157
+    }
158
+
159
+    public void setAuthorities(List<GrantedAuthority> authorities) {
160
+        this.authorities = authorities;
161
+    }
162
+}

+ 11 - 0
src/main/java/com/lqkj/common/core/model/RegisterBody.java

@@ -0,0 +1,11 @@
1
+package com.lqkj.common.core.model;
2
+
3
+/**
4
+ * 用户注册对象
5
+ * 
6
+ * @author lh
7
+ */
8
+public class RegisterBody extends LoginBody
9
+{
10
+
11
+}

+ 97 - 0
src/main/java/com/lqkj/common/core/model/ResultUtil.java

@@ -0,0 +1,97 @@
1
+package com.lqkj.common.core.model;
2
+
3
+import com.lqkj.common.utils.StringUtils;
4
+import org.springframework.http.HttpStatus;
5
+
6
+import java.util.HashMap;
7
+
8
+/**
9
+ * Ajax操作消息返回对象
10
+ */
11
+public class ResultUtil extends HashMap<String, Object> {
12
+    /**
13
+     * 状态
14
+     */
15
+    public static final String STATUS_TAG = "status";
16
+
17
+    /** 状态码 */
18
+    public static final String CODE_TAG = "code";
19
+
20
+    /** 返回内容 */
21
+    public static final String MSG_TAG = "msg";
22
+
23
+    /** 数据对象 */
24
+    public static final String DATA_TAG = "data";
25
+
26
+    public ResultUtil(){}
27
+
28
+    public ResultUtil(Boolean status, int code, String msg, Object data){
29
+        super.put(STATUS_TAG, status);
30
+        super.put(CODE_TAG, code);
31
+        if (StringUtils.isNotEmpty(msg)){
32
+            super.put(MSG_TAG, msg);
33
+        }
34
+        if (StringUtils.isNotNull(data)){
35
+            super.put(DATA_TAG, data);
36
+        }
37
+    }
38
+    public static ResultUtil success(int code, String msg, Object data){
39
+        return new ResultUtil(true, code, msg, data);
40
+    }
41
+    public static ResultUtil success(){
42
+        return ResultUtil.success("操作成功");
43
+    }
44
+    public static ResultUtil success(Object data){
45
+        return ResultUtil.success("操作成功", data);
46
+    }
47
+    public static ResultUtil success(String msg){
48
+        return ResultUtil.success(msg, null);
49
+    }
50
+    public static ResultUtil success(int code){
51
+        return ResultUtil.success(code, "操作成功");
52
+    }
53
+    public static ResultUtil success(String msg, Object data){
54
+        return ResultUtil.success(HttpStatus.OK.value(), msg, data);
55
+    }
56
+    public static ResultUtil success(int code, String msg){
57
+        return ResultUtil.success(code, msg, null);
58
+    }
59
+    public static ResultUtil success(int code, Object data){
60
+        return ResultUtil.success(code, "操作成功", data);
61
+    }
62
+
63
+    public static ResultUtil error(int code, String msg, Object data){
64
+        return new ResultUtil(false, code, msg, data);
65
+    }
66
+    public static ResultUtil error(int code, String msg){
67
+        return ResultUtil.error( code, msg, null);
68
+    }
69
+    public static ResultUtil error(String msg, Object data){
70
+        return ResultUtil.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), msg, data);
71
+    }
72
+    public static ResultUtil error(String msg){
73
+        return ResultUtil.error(msg, null);
74
+    }
75
+    public static ResultUtil error(int code){
76
+        return ResultUtil.error(code, null);
77
+    }
78
+    public static ResultUtil error(){
79
+        return ResultUtil.error("操作失败");
80
+    }
81
+
82
+
83
+    /**
84
+     * 方便链式调用
85
+     *
86
+     * @param key 键
87
+     * @param value 值
88
+     * @return 数据对象
89
+     */
90
+    @Override
91
+    public ResultUtil put(String key, Object value)
92
+    {
93
+        super.put(key, value);
94
+        return this;
95
+    }
96
+
97
+}

+ 80 - 0
src/main/java/com/lqkj/common/core/model/TreeEntity.java

@@ -0,0 +1,80 @@
1
+package com.lqkj.common.core.model;
2
+
3
+
4
+import java.util.ArrayList;
5
+import java.util.List;
6
+
7
+/**
8
+ * Tree基类
9
+ *
10
+ * @author lh
11
+ */
12
+public class TreeEntity extends BaseEntity
13
+{
14
+    private static final long serialVersionUID = 1L;
15
+
16
+    /** 父菜单名称 */
17
+    private String parentName;
18
+
19
+    /** 父菜单ID */
20
+    private Long parentId;
21
+
22
+    /** 显示顺序 */
23
+    private Integer orderNum;
24
+
25
+    /** 祖级列表 */
26
+    private String ancestors;
27
+
28
+    /** 子部门 */
29
+    private List<?> children = new ArrayList<>();
30
+
31
+    public String getParentName()
32
+    {
33
+        return parentName;
34
+    }
35
+
36
+    public void setParentName(String parentName)
37
+    {
38
+        this.parentName = parentName;
39
+    }
40
+
41
+    public Long getParentId()
42
+    {
43
+        return parentId;
44
+    }
45
+
46
+    public void setParentId(Long parentId)
47
+    {
48
+        this.parentId = parentId;
49
+    }
50
+
51
+    public Integer getOrderNum()
52
+    {
53
+        return orderNum;
54
+    }
55
+
56
+    public void setOrderNum(Integer orderNum)
57
+    {
58
+        this.orderNum = orderNum;
59
+    }
60
+
61
+    public String getAncestors()
62
+    {
63
+        return ancestors;
64
+    }
65
+
66
+    public void setAncestors(String ancestors)
67
+    {
68
+        this.ancestors = ancestors;
69
+    }
70
+
71
+    public List<?> getChildren()
72
+    {
73
+        return children;
74
+    }
75
+
76
+    public void setChildren(List<?> children)
77
+    {
78
+        this.children = children;
79
+    }
80
+}

+ 100 - 0
src/main/java/com/lqkj/common/core/model/TreeSelect.java

@@ -0,0 +1,100 @@
1
+package com.lqkj.common.core.model;
2
+
3
+
4
+import com.fasterxml.jackson.annotation.JsonInclude;
5
+import com.lqkj.business.entity.CmsCategory;
6
+import com.lqkj.system.entity.SysDept;
7
+import com.lqkj.system.entity.SysMenu;
8
+
9
+import java.io.Serializable;
10
+import java.util.List;
11
+import java.util.stream.Collectors;
12
+
13
+/**
14
+ * Treeselect树结构实体类
15
+ *
16
+ * @author lh
17
+ */
18
+public class TreeSelect implements Serializable
19
+{
20
+    private static final long serialVersionUID = 1L;
21
+
22
+    /** 节点ID */
23
+    private Integer id;
24
+
25
+    /** 节点名称 */
26
+    private String label;
27
+
28
+
29
+    private Integer type;
30
+
31
+
32
+    /** 子节点 */
33
+    @JsonInclude(JsonInclude.Include.NON_EMPTY)
34
+    private List<TreeSelect> children;
35
+
36
+    public TreeSelect()
37
+    {
38
+
39
+    }
40
+
41
+    public TreeSelect(SysDept dept)
42
+    {
43
+        this.id = dept.getDeptId();
44
+        this.label = dept.getDeptName();
45
+        this.children = dept.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
46
+    }
47
+
48
+    public TreeSelect(SysMenu menu)
49
+    {
50
+        this.id = menu.getMenuId();
51
+        this.label = menu.getMenuName();
52
+        this.children = menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
53
+    }
54
+
55
+    public TreeSelect(CmsCategory cmsCategory) {
56
+        this.id = cmsCategory.getCategoryId().intValue();
57
+        this.label = cmsCategory.getName();
58
+        this.type = cmsCategory.getCategoryType();
59
+        this.children = cmsCategory.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
60
+
61
+    }
62
+
63
+    public Integer getType() {
64
+        return type;
65
+    }
66
+
67
+    public void setType(Integer type) {
68
+        this.type = type;
69
+    }
70
+
71
+    public Integer getId()
72
+    {
73
+        return id;
74
+    }
75
+
76
+    public void setId(Integer id)
77
+    {
78
+        this.id = id;
79
+    }
80
+
81
+    public String getLabel()
82
+    {
83
+        return label;
84
+    }
85
+
86
+    public void setLabel(String label)
87
+    {
88
+        this.label = label;
89
+    }
90
+
91
+    public List<TreeSelect> getChildren()
92
+    {
93
+        return children;
94
+    }
95
+
96
+    public void setChildren(List<TreeSelect> children)
97
+    {
98
+        this.children = children;
99
+    }
100
+}

+ 79 - 0
src/main/java/com/lqkj/common/core/model/TreeStringEntity.java

@@ -0,0 +1,79 @@
1
+package com.lqkj.common.core.model;
2
+
3
+
4
+import java.util.ArrayList;
5
+import java.util.List;
6
+
7
+/**
8
+ * Tree基类
9
+ *
10
+ * @author lh
11
+ */
12
+public class TreeStringEntity extends BaseEntity {
13
+    private static final long serialVersionUID = 1L;
14
+
15
+    /**
16
+     * 父菜单名称
17
+     */
18
+    private String parentName;
19
+
20
+    /**
21
+     * 父菜单ID
22
+     */
23
+    private String parentId;
24
+
25
+    /**
26
+     * 显示顺序
27
+     */
28
+    private Integer orderNum;
29
+
30
+    /**
31
+     * 祖级列表
32
+     */
33
+    private String ancestors;
34
+
35
+    /**
36
+     * 子部门
37
+     */
38
+    private List<?> children = new ArrayList<>();
39
+
40
+    public String getParentName() {
41
+        return parentName;
42
+    }
43
+
44
+    public void setParentName(String parentName) {
45
+        this.parentName = parentName;
46
+    }
47
+
48
+    public String getParentId() {
49
+        return parentId;
50
+    }
51
+
52
+    public void setParentId(String parentId) {
53
+        this.parentId = parentId;
54
+    }
55
+
56
+    public Integer getOrderNum() {
57
+        return orderNum;
58
+    }
59
+
60
+    public void setOrderNum(Integer orderNum) {
61
+        this.orderNum = orderNum;
62
+    }
63
+
64
+    public String getAncestors() {
65
+        return ancestors;
66
+    }
67
+
68
+    public void setAncestors(String ancestors) {
69
+        this.ancestors = ancestors;
70
+    }
71
+
72
+    public List<?> getChildren() {
73
+        return children;
74
+    }
75
+
76
+    public void setChildren(List<?> children) {
77
+        this.children = children;
78
+    }
79
+}

+ 244 - 0
src/main/java/com/lqkj/common/core/redis/RedisCache.java

@@ -0,0 +1,244 @@
1
+package com.lqkj.common.core.redis;
2
+
3
+
4
+import org.springframework.beans.factory.annotation.Autowired;
5
+import org.springframework.data.redis.core.BoundSetOperations;
6
+import org.springframework.data.redis.core.HashOperations;
7
+import org.springframework.data.redis.core.RedisTemplate;
8
+import org.springframework.data.redis.core.ValueOperations;
9
+import org.springframework.stereotype.Component;
10
+
11
+import java.util.*;
12
+import java.util.concurrent.TimeUnit;
13
+
14
+/**
15
+ * spring redis 工具类
16
+ *
17
+ * @author lh
18
+ **/
19
+@SuppressWarnings(value = { "unchecked", "rawtypes" })
20
+@Component
21
+public class RedisCache
22
+{
23
+    @Autowired
24
+    public RedisTemplate redisTemplate;
25
+
26
+    /**
27
+     * 缓存基本的对象,Integer、String、实体类等
28
+     *
29
+     * @param key 缓存的键值
30
+     * @param value 缓存的值
31
+     */
32
+    public <T> void setCacheObject(final String key, final T value)
33
+    {
34
+        redisTemplate.opsForValue().set(key, value);
35
+    }
36
+
37
+    /**
38
+     * 缓存基本的对象,Integer、String、实体类等
39
+     *
40
+     * @param key 缓存的键值
41
+     * @param value 缓存的值
42
+     * @param timeout 时间
43
+     * @param timeUnit 时间颗粒度
44
+     */
45
+    public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit)
46
+    {
47
+        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
48
+    }
49
+
50
+    /**
51
+     * 设置有效时间
52
+     *
53
+     * @param key Redis键
54
+     * @param timeout 超时时间
55
+     * @return true=设置成功;false=设置失败
56
+     */
57
+    public boolean expire(final String key, final long timeout)
58
+    {
59
+        return expire(key, timeout, TimeUnit.SECONDS);
60
+    }
61
+
62
+    /**
63
+     * 设置有效时间
64
+     *
65
+     * @param key Redis键
66
+     * @param timeout 超时时间
67
+     * @param unit 时间单位
68
+     * @return true=设置成功;false=设置失败
69
+     */
70
+    public boolean expire(final String key, final long timeout, final TimeUnit unit)
71
+    {
72
+        return redisTemplate.expire(key, timeout, unit);
73
+    }
74
+
75
+    /**
76
+     * 获得缓存的基本对象。
77
+     *
78
+     * @param key 缓存键值
79
+     * @return 缓存键值对应的数据
80
+     */
81
+    public <T> T getCacheObject(final String key)
82
+    {
83
+        ValueOperations<String, T> operation = redisTemplate.opsForValue();
84
+        return operation.get(key);
85
+    }
86
+
87
+    /**
88
+     * 删除单个对象
89
+     *
90
+     * @param key
91
+     */
92
+    public boolean deleteObject(final String key)
93
+    {
94
+        return redisTemplate.delete(key);
95
+    }
96
+
97
+    /**
98
+     * 删除集合对象
99
+     *
100
+     * @param collection 多个对象
101
+     * @return
102
+     */
103
+    public long deleteObject(final Collection collection)
104
+    {
105
+        return redisTemplate.delete(collection);
106
+    }
107
+
108
+    /**
109
+     * 缓存List数据
110
+     *
111
+     * @param key 缓存的键值
112
+     * @param dataList 待缓存的List数据
113
+     * @return 缓存的对象
114
+     */
115
+    public <T> long setCacheList(final String key, final List<T> dataList)
116
+    {
117
+        Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
118
+        return count == null ? 0 : count;
119
+    }
120
+
121
+    /**
122
+     * 获得缓存的list对象
123
+     *
124
+     * @param key 缓存的键值
125
+     * @return 缓存键值对应的数据
126
+     */
127
+    public <T> List<T> getCacheList(final String key)
128
+    {
129
+        return redisTemplate.opsForList().range(key, 0, -1);
130
+    }
131
+
132
+    /**
133
+     * 缓存Set
134
+     *
135
+     * @param key 缓存键值
136
+     * @param dataSet 缓存的数据
137
+     * @return 缓存数据的对象
138
+     */
139
+    public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet)
140
+    {
141
+        BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
142
+        Iterator<T> it = dataSet.iterator();
143
+        while (it.hasNext())
144
+        {
145
+            setOperation.add(it.next());
146
+        }
147
+        return setOperation;
148
+    }
149
+
150
+    /**
151
+     * 获得缓存的set
152
+     *
153
+     * @param key
154
+     * @return
155
+     */
156
+    public <T> Set<T> getCacheSet(final String key)
157
+    {
158
+        return redisTemplate.opsForSet().members(key);
159
+    }
160
+
161
+    /**
162
+     * 缓存Map
163
+     *
164
+     * @param key
165
+     * @param dataMap
166
+     */
167
+    public <T> void setCacheMap(final String key, final Map<String, T> dataMap)
168
+    {
169
+        if (dataMap != null) {
170
+            redisTemplate.opsForHash().putAll(key, dataMap);
171
+        }
172
+    }
173
+
174
+    /**
175
+     * 获得缓存的Map
176
+     *
177
+     * @param key
178
+     * @return
179
+     */
180
+    public <T> Map<String, T> getCacheMap(final String key)
181
+    {
182
+        return redisTemplate.opsForHash().entries(key);
183
+    }
184
+
185
+    /**
186
+     * 往Hash中存入数据
187
+     *
188
+     * @param key Redis键
189
+     * @param hKey Hash键
190
+     * @param value 值
191
+     */
192
+    public <T> void setCacheMapValue(final String key, final String hKey, final T value)
193
+    {
194
+        redisTemplate.opsForHash().put(key, hKey, value);
195
+    }
196
+
197
+    /**
198
+     * 获取Hash中的数据
199
+     *
200
+     * @param key Redis键
201
+     * @param hKey Hash键
202
+     * @return Hash中的对象
203
+     */
204
+    public <T> T getCacheMapValue(final String key, final String hKey)
205
+    {
206
+        HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
207
+        return opsForHash.get(key, hKey);
208
+    }
209
+
210
+    /**
211
+     * 删除Hash中的数据
212
+     *
213
+     * @param key
214
+     * @param hkey
215
+     */
216
+    public void delCacheMapValue(final String key, final String hkey)
217
+    {
218
+        HashOperations hashOperations = redisTemplate.opsForHash();
219
+        hashOperations.delete(key, hkey);
220
+    }
221
+
222
+    /**
223
+     * 获取多个Hash中的数据
224
+     *
225
+     * @param key Redis键
226
+     * @param hKeys Hash键集合
227
+     * @return Hash对象集合
228
+     */
229
+    public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys)
230
+    {
231
+        return redisTemplate.opsForHash().multiGet(key, hKeys);
232
+    }
233
+
234
+    /**
235
+     * 获得缓存的基本对象列表
236
+     *
237
+     * @param pattern 字符串前缀
238
+     * @return 对象列表
239
+     */
240
+    public Collection<String> keys(final String pattern)
241
+    {
242
+        return redisTemplate.keys(pattern);
243
+    }
244
+}

+ 87 - 0
src/main/java/com/lqkj/common/core/text/CharsetKit.java

@@ -0,0 +1,87 @@
1
+package com.lqkj.common.core.text;
2
+
3
+import com.lqkj.common.utils.StringUtils;
4
+
5
+import java.nio.charset.Charset;
6
+import java.nio.charset.StandardCharsets;
7
+
8
+/**
9
+ * 字符集工具类
10
+ * 
11
+ * @author lh
12
+ */
13
+public class CharsetKit
14
+{
15
+    /** ISO-8859-1 */
16
+    public static final String ISO_8859_1 = "ISO-8859-1";
17
+    /** UTF-8 */
18
+    public static final String UTF_8 = "UTF-8";
19
+    /** GBK */
20
+    public static final String GBK = "GBK";
21
+
22
+    /** ISO-8859-1 */
23
+    public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1);
24
+    /** UTF-8 */
25
+    public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8);
26
+    /** GBK */
27
+    public static final Charset CHARSET_GBK = Charset.forName(GBK);
28
+
29
+    /**
30
+     * 转换为Charset对象
31
+     * 
32
+     * @param charset 字符集,为空则返回默认字符集
33
+     * @return Charset
34
+     */
35
+    public static Charset charset(String charset)
36
+    {
37
+        return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset);
38
+    }
39
+
40
+    /**
41
+     * 转换字符串的字符集编码
42
+     * 
43
+     * @param source 字符串
44
+     * @param srcCharset 源字符集,默认ISO-8859-1
45
+     * @param destCharset 目标字符集,默认UTF-8
46
+     * @return 转换后的字符集
47
+     */
48
+    public static String convert(String source, String srcCharset, String destCharset)
49
+    {
50
+        return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset));
51
+    }
52
+
53
+    /**
54
+     * 转换字符串的字符集编码
55
+     * 
56
+     * @param source 字符串
57
+     * @param srcCharset 源字符集,默认ISO-8859-1
58
+     * @param destCharset 目标字符集,默认UTF-8
59
+     * @return 转换后的字符集
60
+     */
61
+    public static String convert(String source, Charset srcCharset, Charset destCharset)
62
+    {
63
+        if (null == srcCharset)
64
+        {
65
+            srcCharset = StandardCharsets.ISO_8859_1;
66
+        }
67
+
68
+        if (null == destCharset)
69
+        {
70
+            destCharset = StandardCharsets.UTF_8;
71
+        }
72
+
73
+        if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset))
74
+        {
75
+            return source;
76
+        }
77
+        return new String(source.getBytes(srcCharset), destCharset);
78
+    }
79
+
80
+    /**
81
+     * @return 系统字符集编码
82
+     */
83
+    public static String systemCharset()
84
+    {
85
+        return Charset.defaultCharset().name();
86
+    }
87
+}

Різницю між файлами не показано, бо вона завелика
+ 1006 - 0
src/main/java/com/lqkj/common/core/text/Convert.java


+ 93 - 0
src/main/java/com/lqkj/common/core/text/StrFormatter.java

@@ -0,0 +1,93 @@
1
+package com.lqkj.common.core.text;
2
+
3
+
4
+import com.lqkj.common.utils.StringUtils;
5
+
6
+/**
7
+ * 字符串格式化
8
+ * 
9
+ * @author lh
10
+ */
11
+public class StrFormatter
12
+{
13
+    public static final String EMPTY_JSON = "{}";
14
+    public static final char C_BACKSLASH = '\\';
15
+    public static final char C_DELIM_START = '{';
16
+    public static final char C_DELIM_END = '}';
17
+
18
+    /**
19
+     * 格式化字符串<br>
20
+     * 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
21
+     * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
22
+     * 例:<br>
23
+     * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
24
+     * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
25
+     * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
26
+     * 
27
+     * @param strPattern 字符串模板
28
+     * @param argArray 参数列表
29
+     * @return 结果
30
+     */
31
+    public static String format(final String strPattern, final Object... argArray)
32
+    {
33
+        if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray))
34
+        {
35
+            return strPattern;
36
+        }
37
+        final int strPatternLength = strPattern.length();
38
+
39
+        // 初始化定义好的长度以获得更好的性能
40
+        StringBuilder sbuf = new StringBuilder(strPatternLength + 50);
41
+
42
+        int handledPosition = 0;
43
+        int delimIndex;// 占位符所在位置
44
+        for (int argIndex = 0; argIndex < argArray.length; argIndex++)
45
+        {
46
+            delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition);
47
+            if (delimIndex == -1)
48
+            {
49
+                if (handledPosition == 0)
50
+                {
51
+                    return strPattern;
52
+                }
53
+                else
54
+                { // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果
55
+                    sbuf.append(strPattern, handledPosition, strPatternLength);
56
+                    return sbuf.toString();
57
+                }
58
+            }
59
+            else
60
+            {
61
+                if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH)
62
+                {
63
+                    if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH)
64
+                    {
65
+                        // 转义符之前还有一个转义符,占位符依旧有效
66
+                        sbuf.append(strPattern, handledPosition, delimIndex - 1);
67
+                        sbuf.append(Convert.utf8Str(argArray[argIndex]));
68
+                        handledPosition = delimIndex + 2;
69
+                    }
70
+                    else
71
+                    {
72
+                        // 占位符被转义
73
+                        argIndex--;
74
+                        sbuf.append(strPattern, handledPosition, delimIndex - 1);
75
+                        sbuf.append(C_DELIM_START);
76
+                        handledPosition = delimIndex + 1;
77
+                    }
78
+                }
79
+                else
80
+                {
81
+                    // 正常占位符
82
+                    sbuf.append(strPattern, handledPosition, delimIndex);
83
+                    sbuf.append(Convert.utf8Str(argArray[argIndex]));
84
+                    handledPosition = delimIndex + 2;
85
+                }
86
+            }
87
+        }
88
+        // 加入最后一个占位符后所有的字符
89
+        sbuf.append(strPattern, handledPosition, strPattern.length());
90
+
91
+        return sbuf.toString();
92
+    }
93
+}

+ 59 - 0
src/main/java/com/lqkj/common/enums/BusinessType.java

@@ -0,0 +1,59 @@
1
+package com.lqkj.common.enums;
2
+
3
+/**
4
+ * 业务操作类型
5
+ * 
6
+ * @author lh
7
+ */
8
+public enum BusinessType
9
+{
10
+    /**
11
+     * 其它
12
+     */
13
+    OTHER,
14
+
15
+    /**
16
+     * 新增
17
+     */
18
+    INSERT,
19
+
20
+    /**
21
+     * 修改
22
+     */
23
+    UPDATE,
24
+
25
+    /**
26
+     * 删除
27
+     */
28
+    DELETE,
29
+
30
+    /**
31
+     * 授权
32
+     */
33
+    GRANT,
34
+
35
+    /**
36
+     * 导出
37
+     */
38
+    EXPORT,
39
+
40
+    /**
41
+     * 导入
42
+     */
43
+    IMPORT,
44
+
45
+    /**
46
+     * 强退
47
+     */
48
+    FORCE,
49
+
50
+    /**
51
+     * 生成代码
52
+     */
53
+    GENCODE,
54
+    
55
+    /**
56
+     * 清空数据
57
+     */
58
+    CLEAN,
59
+}

+ 37 - 0
src/main/java/com/lqkj/common/enums/HttpMethod.java

@@ -0,0 +1,37 @@
1
+package com.lqkj.common.enums;
2
+
3
+import org.springframework.lang.Nullable;
4
+
5
+import java.util.HashMap;
6
+import java.util.Map;
7
+
8
+/**
9
+ * 请求方式
10
+ *
11
+ * @author lh
12
+ */
13
+public enum HttpMethod
14
+{
15
+    GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;
16
+
17
+    private static final Map<String, HttpMethod> mappings = new HashMap<>(16);
18
+
19
+    static
20
+    {
21
+        for (HttpMethod httpMethod : values())
22
+        {
23
+            mappings.put(httpMethod.name(), httpMethod);
24
+        }
25
+    }
26
+
27
+    @Nullable
28
+    public static HttpMethod resolve(@Nullable String method)
29
+    {
30
+        return (method != null ? mappings.get(method) : null);
31
+    }
32
+
33
+    public boolean matches(String method)
34
+    {
35
+        return (this == resolve(method));
36
+    }
37
+}

+ 20 - 0
src/main/java/com/lqkj/common/enums/LimitType.java

@@ -0,0 +1,20 @@
1
+package com.lqkj.common.enums;
2
+
3
+/**
4
+ * 限流类型
5
+ *
6
+ * @author lh
7
+ */
8
+
9
+public enum LimitType
10
+{
11
+    /**
12
+     * 默认策略全局限流
13
+     */
14
+    DEFAULT,
15
+
16
+    /**
17
+     * 根据请求者IP进行限流
18
+     */
19
+    IP
20
+}

+ 24 - 0
src/main/java/com/lqkj/common/enums/OperatorType.java

@@ -0,0 +1,24 @@
1
+package com.lqkj.common.enums;
2
+
3
+/**
4
+ * 操作人类别
5
+ * 
6
+ * @author lh
7
+ */
8
+public enum OperatorType
9
+{
10
+    /**
11
+     * 其它
12
+     */
13
+    OTHER,
14
+
15
+    /**
16
+     * 后台用户
17
+     */
18
+    MANAGE,
19
+
20
+    /**
21
+     * 手机端用户
22
+     */
23
+    MOBILE
24
+}

+ 73 - 0
src/main/java/com/lqkj/common/exception/ServiceException.java

@@ -0,0 +1,73 @@
1
+package com.lqkj.common.exception;
2
+
3
+/**
4
+ * 业务异常
5
+ * 
6
+ * @author lh
7
+ */
8
+public final class ServiceException extends RuntimeException
9
+{
10
+    private static final long serialVersionUID = 1L;
11
+
12
+    /**
13
+     * 错误码
14
+     */
15
+    private Integer code;
16
+
17
+    /**
18
+     * 错误提示
19
+     */
20
+    private String message;
21
+
22
+    /**
23
+     * 错误明细,内部调试错误
24
+     *
25
+     *
26
+     */
27
+    private String detailMessage;
28
+
29
+    /**
30
+     * 空构造方法,避免反序列化问题
31
+     */
32
+    public ServiceException()
33
+    {
34
+    }
35
+
36
+    public ServiceException(String message)
37
+    {
38
+        this.message = message;
39
+    }
40
+
41
+    public ServiceException(String message, Integer code)
42
+    {
43
+        this.message = message;
44
+        this.code = code;
45
+    }
46
+
47
+    public String getDetailMessage()
48
+    {
49
+        return detailMessage;
50
+    }
51
+
52
+    public String getMessage()
53
+    {
54
+        return message;
55
+    }
56
+
57
+    public Integer getCode()
58
+    {
59
+        return code;
60
+    }
61
+
62
+    public ServiceException setMessage(String message)
63
+    {
64
+        this.message = message;
65
+        return this;
66
+    }
67
+
68
+    public ServiceException setDetailMessage(String detailMessage)
69
+    {
70
+        this.detailMessage = detailMessage;
71
+        return this;
72
+    }
73
+}

+ 26 - 0
src/main/java/com/lqkj/common/exception/UtilException.java

@@ -0,0 +1,26 @@
1
+package com.lqkj.common.exception;
2
+
3
+/**
4
+ * 工具类异常
5
+ *
6
+ * @author lh
7
+ */
8
+public class UtilException extends RuntimeException
9
+{
10
+    private static final long serialVersionUID = 8247610319171014183L;
11
+
12
+    public UtilException(Throwable e)
13
+    {
14
+        super(e.getMessage(), e);
15
+    }
16
+
17
+    public UtilException(String message)
18
+    {
19
+        super(message);
20
+    }
21
+
22
+    public UtilException(String message, Throwable throwable)
23
+    {
24
+        super(message, throwable);
25
+    }
26
+}

+ 81 - 0
src/main/java/com/lqkj/common/exception/base/BaseException.java

@@ -0,0 +1,81 @@
1
+package com.lqkj.common.exception.base;
2
+
3
+
4
+/**
5
+ * 基础异常
6
+ * 
7
+ * @author lh
8
+ */
9
+public class BaseException extends RuntimeException
10
+{
11
+    private static final long serialVersionUID = 1L;
12
+
13
+    /**
14
+     * 所属模块
15
+     */
16
+    private String module;
17
+
18
+    /**
19
+     * 错误码
20
+     */
21
+    private String code;
22
+
23
+    /**
24
+     * 错误码对应的参数
25
+     */
26
+    private Object[] args;
27
+
28
+    /**
29
+     * 错误消息
30
+     */
31
+    private String defaultMessage;
32
+
33
+    public BaseException(String module, String code, Object[] args, String defaultMessage)
34
+    {
35
+        this.module = module;
36
+        this.code = code;
37
+        this.args = args;
38
+        this.defaultMessage = defaultMessage;
39
+    }
40
+
41
+    public BaseException(String module, String code, Object[] args)
42
+    {
43
+        this(module, code, args, null);
44
+    }
45
+
46
+    public BaseException(String module, String defaultMessage)
47
+    {
48
+        this(module, null, null, defaultMessage);
49
+    }
50
+
51
+    public BaseException(String code, Object[] args)
52
+    {
53
+        this(null, code, args, null);
54
+    }
55
+
56
+    public BaseException(String defaultMessage)
57
+    {
58
+        this(null, null, null, defaultMessage);
59
+    }
60
+
61
+
62
+    public String getModule()
63
+    {
64
+        return module;
65
+    }
66
+
67
+    public String getCode()
68
+    {
69
+        return code;
70
+    }
71
+
72
+    public Object[] getArgs()
73
+    {
74
+        return args;
75
+    }
76
+
77
+    public String getDefaultMessage()
78
+    {
79
+        return defaultMessage;
80
+    }
81
+}

+ 20 - 0
src/main/java/com/lqkj/common/exception/file/FileException.java

@@ -0,0 +1,20 @@
1
+package com.lqkj.common.exception.file;
2
+
3
+
4
+import com.lqkj.common.exception.base.BaseException;
5
+
6
+/**
7
+ * 文件信息异常类
8
+ * 
9
+ * @author lh
10
+ */
11
+public class FileException extends BaseException
12
+{
13
+    private static final long serialVersionUID = 1L;
14
+
15
+    public FileException(String code, Object[] args)
16
+    {
17
+        super("file", code, args, null);
18
+    }
19
+
20
+}

+ 16 - 0
src/main/java/com/lqkj/common/exception/file/FileNameLengthLimitExceededException.java

@@ -0,0 +1,16 @@
1
+package com.lqkj.common.exception.file;
2
+
3
+/**
4
+ * 文件名称超长限制异常类
5
+ * 
6
+ * @author lh
7
+ */
8
+public class FileNameLengthLimitExceededException extends FileException
9
+{
10
+    private static final long serialVersionUID = 1L;
11
+
12
+    public FileNameLengthLimitExceededException(int defaultFileNameLength)
13
+    {
14
+        super("upload.filename.exceed.length", new Object[] { defaultFileNameLength });
15
+    }
16
+}

+ 16 - 0
src/main/java/com/lqkj/common/exception/file/FileSizeLimitExceededException.java

@@ -0,0 +1,16 @@
1
+package com.lqkj.common.exception.file;
2
+
3
+/**
4
+ * 文件名大小限制异常类
5
+ * 
6
+ * @author lh
7
+ */
8
+public class FileSizeLimitExceededException extends FileException
9
+{
10
+    private static final long serialVersionUID = 1L;
11
+
12
+    public FileSizeLimitExceededException(long defaultMaxSize)
13
+    {
14
+        super("upload.exceed.maxSize", new Object[] { defaultMaxSize });
15
+    }
16
+}

+ 82 - 0
src/main/java/com/lqkj/common/exception/file/InvalidExtensionException.java

@@ -0,0 +1,82 @@
1
+package com.lqkj.common.exception.file;
2
+
3
+import org.apache.commons.fileupload.FileUploadException;
4
+
5
+import java.util.Arrays;
6
+
7
+/**
8
+ * 文件上传 误异常类
9
+ * 
10
+ * @author lh
11
+ */
12
+public class InvalidExtensionException extends FileUploadException
13
+{
14
+    private static final long serialVersionUID = 1L;
15
+
16
+    private String[] allowedExtension;
17
+    private String extension;
18
+    private String filename;
19
+
20
+    public InvalidExtensionException(String[] allowedExtension, String extension, String filename)
21
+    {
22
+        super("filename : [" + filename + "], extension : [" + extension + "], allowed extension : [" + Arrays.toString(allowedExtension) + "]");
23
+        this.allowedExtension = allowedExtension;
24
+        this.extension = extension;
25
+        this.filename = filename;
26
+    }
27
+
28
+    public String[] getAllowedExtension()
29
+    {
30
+        return allowedExtension;
31
+    }
32
+
33
+    public String getExtension()
34
+    {
35
+        return extension;
36
+    }
37
+
38
+    public String getFilename()
39
+    {
40
+        return filename;
41
+    }
42
+
43
+    public static class InvalidImageExtensionException extends InvalidExtensionException
44
+    {
45
+        private static final long serialVersionUID = 1L;
46
+
47
+        public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename)
48
+        {
49
+            super(allowedExtension, extension, filename);
50
+        }
51
+    }
52
+
53
+    public static class InvalidFlashExtensionException extends InvalidExtensionException
54
+    {
55
+        private static final long serialVersionUID = 1L;
56
+
57
+        public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename)
58
+        {
59
+            super(allowedExtension, extension, filename);
60
+        }
61
+    }
62
+
63
+    public static class InvalidMediaExtensionException extends InvalidExtensionException
64
+    {
65
+        private static final long serialVersionUID = 1L;
66
+
67
+        public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename)
68
+        {
69
+            super(allowedExtension, extension, filename);
70
+        }
71
+    }
72
+
73
+    public static class InvalidVideoExtensionException extends InvalidExtensionException
74
+    {
75
+        private static final long serialVersionUID = 1L;
76
+
77
+        public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename)
78
+        {
79
+            super(allowedExtension, extension, filename);
80
+        }
81
+    }
82
+}

+ 34 - 0
src/main/java/com/lqkj/common/exception/job/TaskException.java

@@ -0,0 +1,34 @@
1
+package com.lqkj.common.exception.job;
2
+
3
+/**
4
+ * 计划策略异常
5
+ * 
6
+ * @author lh
7
+ */
8
+public class TaskException extends Exception
9
+{
10
+    private static final long serialVersionUID = 1L;
11
+
12
+    private Code code;
13
+
14
+    public TaskException(String msg, Code code)
15
+    {
16
+        this(msg, code, null);
17
+    }
18
+
19
+    public TaskException(String msg, Code code, Exception nestedEx)
20
+    {
21
+        super(msg, nestedEx);
22
+        this.code = code;
23
+    }
24
+
25
+    public Code getCode()
26
+    {
27
+        return code;
28
+    }
29
+
30
+    public enum Code
31
+    {
32
+        TASK_EXISTS, NO_TASK_EXISTS, TASK_ALREADY_STARTED, UNKNOWN, CONFIG_ERROR, TASK_NODE_NOT_AVAILABLE
33
+    }
34
+}

+ 107 - 0
src/main/java/com/lqkj/common/exception/web/GlobalExceptionHandler.java

@@ -0,0 +1,107 @@
1
+package com.lqkj.common.exception.web;
2
+
3
+
4
+import com.lqkj.common.core.model.ResultUtil;
5
+import com.lqkj.common.exception.ServiceException;
6
+import com.lqkj.common.utils.StringUtils;
7
+import org.slf4j.Logger;
8
+import org.slf4j.LoggerFactory;
9
+import org.springframework.http.HttpStatus;
10
+import org.springframework.security.access.AccessDeniedException;
11
+import org.springframework.validation.BindException;
12
+import org.springframework.web.HttpRequestMethodNotSupportedException;
13
+import org.springframework.web.bind.MethodArgumentNotValidException;
14
+import org.springframework.web.bind.annotation.ExceptionHandler;
15
+import org.springframework.web.bind.annotation.RestControllerAdvice;
16
+
17
+import javax.servlet.http.HttpServletRequest;
18
+
19
+/**
20
+ * 全局异常处理器
21
+ *
22
+ * @author lh
23
+ */
24
+@RestControllerAdvice
25
+public class GlobalExceptionHandler
26
+{
27
+    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
28
+
29
+    /**
30
+     * 权限校验异常
31
+     */
32
+    @ExceptionHandler(AccessDeniedException.class)
33
+    public ResultUtil handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request)
34
+    {
35
+        String requestURI = request.getRequestURI();
36
+        log.error("请求地址'{}',权限校验失败'{}'", requestURI, e.getMessage());
37
+        return ResultUtil.error(HttpStatus.FORBIDDEN.value(), "没有权限,请联系管理员授权");
38
+    }
39
+    /**
40
+     * 请求方式不支持
41
+     */
42
+    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
43
+    public ResultUtil handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,
44
+                                                          HttpServletRequest request)
45
+    {
46
+        String requestURI = request.getRequestURI();
47
+        log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
48
+        return ResultUtil.error(e.getMessage());
49
+    }
50
+
51
+    /**
52
+     * 业务异常
53
+     */
54
+    @ExceptionHandler(ServiceException.class)
55
+    public ResultUtil handleServiceException(ServiceException e, HttpServletRequest request)
56
+    {
57
+        log.error(e.getMessage(), e);
58
+        Integer code = e.getCode();
59
+        return StringUtils.isNotNull(code) ? ResultUtil.error(code, e.getMessage()) : ResultUtil.error(e.getMessage());
60
+    }
61
+
62
+
63
+
64
+    /**
65
+     * 拦截未知的运行时异常
66
+     */
67
+    @ExceptionHandler(RuntimeException.class)
68
+    public ResultUtil handleRuntimeException(RuntimeException e, HttpServletRequest request)
69
+    {
70
+        String requestURI = request.getRequestURI();
71
+        log.error("请求地址'{}',发生未知异常.", requestURI, e);
72
+        return ResultUtil.error(e.getMessage());
73
+    }
74
+
75
+    /**
76
+     * 系统异常
77
+     */
78
+    @ExceptionHandler(Exception.class)
79
+    public ResultUtil handleException(Exception e, HttpServletRequest request)
80
+    {
81
+        String requestURI = request.getRequestURI();
82
+        log.error("请求地址'{}',发生系统异常.", requestURI, e);
83
+        return ResultUtil.error(e.getMessage());
84
+    }
85
+
86
+    /**
87
+     * 自定义验证异常
88
+     */
89
+    @ExceptionHandler(BindException.class)
90
+    public ResultUtil handleBindException(BindException e)
91
+    {
92
+        log.error(e.getMessage(), e);
93
+        String message = e.getAllErrors().get(0).getDefaultMessage();
94
+        return ResultUtil.error(message);
95
+    }
96
+
97
+    /**
98
+     * 自定义验证异常
99
+     */
100
+    @ExceptionHandler(MethodArgumentNotValidException.class)
101
+    public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e)
102
+    {
103
+        log.error(e.getMessage(), e);
104
+        String message = e.getBindingResult().getFieldError().getDefaultMessage();
105
+        return ResultUtil.error(message);
106
+    }
107
+}

+ 48 - 0
src/main/java/com/lqkj/common/filter/RepeatableFilter.java

@@ -0,0 +1,48 @@
1
+package com.lqkj.common.filter;
2
+
3
+import com.lqkj.common.utils.StringUtils;
4
+import org.springframework.http.MediaType;
5
+
6
+import javax.servlet.*;
7
+import javax.servlet.http.HttpServletRequest;
8
+import java.io.IOException;
9
+
10
+/**
11
+ * Repeatable 过滤器
12
+ * 
13
+ * @author lh
14
+ */
15
+public class RepeatableFilter implements Filter
16
+{
17
+    @Override
18
+    public void init(FilterConfig filterConfig) throws ServletException
19
+    {
20
+
21
+    }
22
+
23
+    @Override
24
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
25
+            throws IOException, ServletException
26
+    {
27
+        ServletRequest requestWrapper = null;
28
+        if (request instanceof HttpServletRequest
29
+                && StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE))
30
+        {
31
+            requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response);
32
+        }
33
+        if (null == requestWrapper)
34
+        {
35
+            chain.doFilter(request, response);
36
+        }
37
+        else
38
+        {
39
+            chain.doFilter(requestWrapper, response);
40
+        }
41
+    }
42
+
43
+    @Override
44
+    public void destroy()
45
+    {
46
+
47
+    }
48
+}

+ 77 - 0
src/main/java/com/lqkj/common/filter/RepeatedlyRequestWrapper.java

@@ -0,0 +1,77 @@
1
+package com.lqkj.common.filter;
2
+
3
+
4
+import com.lqkj.common.utils.http.HttpHelper;
5
+
6
+import javax.servlet.ReadListener;
7
+import javax.servlet.ServletInputStream;
8
+import javax.servlet.ServletResponse;
9
+import javax.servlet.http.HttpServletRequest;
10
+import javax.servlet.http.HttpServletRequestWrapper;
11
+import java.io.BufferedReader;
12
+import java.io.ByteArrayInputStream;
13
+import java.io.IOException;
14
+import java.io.InputStreamReader;
15
+
16
+/**
17
+ * 构建可重复读取inputStream的request
18
+ * 
19
+ * @author lh
20
+ */
21
+public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper
22
+{
23
+    private final byte[] body;
24
+
25
+    public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException
26
+    {
27
+        super(request);
28
+        request.setCharacterEncoding("UTF-8");
29
+        response.setCharacterEncoding("UTF-8");
30
+
31
+        body = HttpHelper.getBodyString(request).getBytes("UTF-8");
32
+    }
33
+
34
+    @Override
35
+    public BufferedReader getReader() throws IOException
36
+    {
37
+        return new BufferedReader(new InputStreamReader(getInputStream()));
38
+    }
39
+
40
+    @Override
41
+    public ServletInputStream getInputStream() throws IOException
42
+    {
43
+        final ByteArrayInputStream bais = new ByteArrayInputStream(body);
44
+        return new ServletInputStream()
45
+        {
46
+            @Override
47
+            public int read() throws IOException
48
+            {
49
+                return bais.read();
50
+            }
51
+
52
+            @Override
53
+            public int available() throws IOException
54
+            {
55
+                return body.length;
56
+            }
57
+
58
+            @Override
59
+            public boolean isFinished()
60
+            {
61
+                return false;
62
+            }
63
+
64
+            @Override
65
+            public boolean isReady()
66
+            {
67
+                return false;
68
+            }
69
+
70
+            @Override
71
+            public void setReadListener(ReadListener readListener)
72
+            {
73
+
74
+            }
75
+        };
76
+    }
77
+}

+ 71 - 0
src/main/java/com/lqkj/common/filter/XssFilter.java

@@ -0,0 +1,71 @@
1
+package com.lqkj.common.filter;
2
+
3
+
4
+import com.lqkj.common.utils.StringUtils;
5
+
6
+import javax.servlet.*;
7
+import javax.servlet.http.HttpServletRequest;
8
+import javax.servlet.http.HttpServletResponse;
9
+import java.io.IOException;
10
+import java.util.ArrayList;
11
+import java.util.List;
12
+
13
+/**
14
+ * 防止XSS攻击的过滤器
15
+ * 
16
+ * @author lh
17
+ */
18
+public class XssFilter implements Filter
19
+{
20
+    /**
21
+     * 排除链接
22
+     */
23
+    public List<String> excludes = new ArrayList<>();
24
+
25
+    @Override
26
+    public void init(FilterConfig filterConfig) throws ServletException
27
+    {
28
+        String tempExcludes = filterConfig.getInitParameter("excludes");
29
+        if (StringUtils.isNotEmpty(tempExcludes))
30
+        {
31
+            String[] url = tempExcludes.split(",");
32
+            for (int i = 0; url != null && i < url.length; i++)
33
+            {
34
+                excludes.add(url[i]);
35
+            }
36
+        }
37
+    }
38
+
39
+    @Override
40
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
41
+            throws IOException, ServletException
42
+    {
43
+        HttpServletRequest req = (HttpServletRequest) request;
44
+        HttpServletResponse resp = (HttpServletResponse) response;
45
+        if (handleExcludeURL(req, resp))
46
+        {
47
+            chain.doFilter(request, response);
48
+            return;
49
+        }
50
+        XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);
51
+        chain.doFilter(xssRequest, response);
52
+    }
53
+
54
+    private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response)
55
+    {
56
+        String url = request.getServletPath();
57
+        String method = request.getMethod();
58
+        // GET DELETE 不过滤
59
+        if (method == null || method.matches("GET") || method.matches("DELETE"))
60
+        {
61
+            return true;
62
+        }
63
+        return StringUtils.matches(url, excludes);
64
+    }
65
+
66
+    @Override
67
+    public void destroy()
68
+    {
69
+
70
+    }
71
+}

+ 112 - 0
src/main/java/com/lqkj/common/filter/XssHttpServletRequestWrapper.java

@@ -0,0 +1,112 @@
1
+package com.lqkj.common.filter;
2
+
3
+
4
+import com.lqkj.common.utils.StringUtils;
5
+import com.lqkj.common.utils.html.EscapeUtil;
6
+import org.apache.commons.io.IOUtils;
7
+import org.springframework.http.HttpHeaders;
8
+import org.springframework.http.MediaType;
9
+
10
+import javax.servlet.ReadListener;
11
+import javax.servlet.ServletInputStream;
12
+import javax.servlet.http.HttpServletRequest;
13
+import javax.servlet.http.HttpServletRequestWrapper;
14
+import java.io.ByteArrayInputStream;
15
+import java.io.IOException;
16
+
17
+/**
18
+ * XSS过滤处理
19
+ * 
20
+ * @author lh
21
+ */
22
+public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper
23
+{
24
+    /**
25
+     * @param request
26
+     */
27
+    public XssHttpServletRequestWrapper(HttpServletRequest request)
28
+    {
29
+        super(request);
30
+    }
31
+
32
+    @Override
33
+    public String[] getParameterValues(String name)
34
+    {
35
+        String[] values = super.getParameterValues(name);
36
+        if (values != null)
37
+        {
38
+            int length = values.length;
39
+            String[] escapseValues = new String[length];
40
+            for (int i = 0; i < length; i++)
41
+            {
42
+                // 防xss攻击和过滤前后空格
43
+                escapseValues[i] = EscapeUtil.clean(values[i]).trim();
44
+            }
45
+            return escapseValues;
46
+        }
47
+        return super.getParameterValues(name);
48
+    }
49
+
50
+    @Override
51
+    public ServletInputStream getInputStream() throws IOException
52
+    {
53
+        // 非json类型,直接返回
54
+        if (!isJsonRequest())
55
+        {
56
+            return super.getInputStream();
57
+        }
58
+
59
+        // 为空,直接返回
60
+        String json = IOUtils.toString(super.getInputStream(), "utf-8");
61
+        if (StringUtils.isEmpty(json))
62
+        {
63
+            return super.getInputStream();
64
+        }
65
+
66
+        // xss过滤
67
+        json = EscapeUtil.clean(json).trim();
68
+        byte[] jsonBytes = json.getBytes("utf-8");
69
+        final ByteArrayInputStream bis = new ByteArrayInputStream(jsonBytes);
70
+        return new ServletInputStream()
71
+        {
72
+            @Override
73
+            public boolean isFinished()
74
+            {
75
+                return true;
76
+            }
77
+
78
+            @Override
79
+            public boolean isReady()
80
+            {
81
+                return true;
82
+            }
83
+
84
+            @Override
85
+            public int available() throws IOException
86
+            {
87
+                return jsonBytes.length;
88
+            }
89
+
90
+            @Override
91
+            public void setReadListener(ReadListener readListener)
92
+            {
93
+            }
94
+
95
+            @Override
96
+            public int read() throws IOException
97
+            {
98
+                return bis.read();
99
+            }
100
+        };
101
+    }
102
+
103
+    /**
104
+     * 是否是Json请求
105
+     *
106
+     */
107
+    public boolean isJsonRequest()
108
+    {
109
+        String header = super.getHeader(HttpHeaders.CONTENT_TYPE);
110
+        return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE);
111
+    }
112
+}

+ 114 - 0
src/main/java/com/lqkj/common/utils/Arith.java

@@ -0,0 +1,114 @@
1
+package com.lqkj.common.utils;
2
+
3
+import java.math.BigDecimal;
4
+import java.math.RoundingMode;
5
+
6
+/**
7
+ * 精确的浮点数运算
8
+ * 
9
+ * @author lh
10
+ */
11
+public class Arith
12
+{
13
+
14
+    /** 默认除法运算精度 */
15
+    private static final int DEF_DIV_SCALE = 10;
16
+
17
+    /** 这个类不能实例化 */
18
+    private Arith()
19
+    {
20
+    }
21
+
22
+    /**
23
+     * 提供精确的加法运算。
24
+     * @param v1 被加数
25
+     * @param v2 加数
26
+     * @return 两个参数的和
27
+     */
28
+    public static double add(double v1, double v2)
29
+    {
30
+        BigDecimal b1 = new BigDecimal(Double.toString(v1));
31
+        BigDecimal b2 = new BigDecimal(Double.toString(v2));
32
+        return b1.add(b2).doubleValue();
33
+    }
34
+
35
+    /**
36
+     * 提供精确的减法运算。
37
+     * @param v1 被减数
38
+     * @param v2 减数
39
+     * @return 两个参数的差
40
+     */
41
+    public static double sub(double v1, double v2)
42
+    {
43
+        BigDecimal b1 = new BigDecimal(Double.toString(v1));
44
+        BigDecimal b2 = new BigDecimal(Double.toString(v2));
45
+        return b1.subtract(b2).doubleValue();
46
+    }
47
+
48
+    /**
49
+     * 提供精确的乘法运算。
50
+     * @param v1 被乘数
51
+     * @param v2 乘数
52
+     * @return 两个参数的积
53
+     */
54
+    public static double mul(double v1, double v2)
55
+    {
56
+        BigDecimal b1 = new BigDecimal(Double.toString(v1));
57
+        BigDecimal b2 = new BigDecimal(Double.toString(v2));
58
+        return b1.multiply(b2).doubleValue();
59
+    }
60
+
61
+    /**
62
+     * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
63
+     * 小数点以后10位,以后的数字四舍五入。
64
+     * @param v1 被除数
65
+     * @param v2 除数
66
+     * @return 两个参数的商
67
+     */
68
+    public static double div(double v1, double v2)
69
+    {
70
+        return div(v1, v2, DEF_DIV_SCALE);
71
+    }
72
+
73
+    /**
74
+     * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
75
+     * 定精度,以后的数字四舍五入。
76
+     * @param v1 被除数
77
+     * @param v2 除数
78
+     * @param scale 表示表示需要精确到小数点以后几位。
79
+     * @return 两个参数的商
80
+     */
81
+    public static double div(double v1, double v2, int scale)
82
+    {
83
+        if (scale < 0)
84
+        {
85
+            throw new IllegalArgumentException(
86
+                    "The scale must be a positive integer or zero");
87
+        }
88
+        BigDecimal b1 = new BigDecimal(Double.toString(v1));
89
+        BigDecimal b2 = new BigDecimal(Double.toString(v2));
90
+        if (b1.compareTo(BigDecimal.ZERO) == 0)
91
+        {
92
+            return BigDecimal.ZERO.doubleValue();
93
+        }
94
+        return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue();
95
+    }
96
+
97
+    /**
98
+     * 提供精确的小数位四舍五入处理。
99
+     * @param v 需要四舍五入的数字
100
+     * @param scale 小数点后保留几位
101
+     * @return 四舍五入后的结果
102
+     */
103
+    public static double round(double v, int scale)
104
+    {
105
+        if (scale < 0)
106
+        {
107
+            throw new IllegalArgumentException(
108
+                    "The scale must be a positive integer or zero");
109
+        }
110
+        BigDecimal b = new BigDecimal(Double.toString(v));
111
+        BigDecimal one = BigDecimal.ONE;
112
+        return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue();
113
+    }
114
+}

+ 291 - 0
src/main/java/com/lqkj/common/utils/Base64.java

@@ -0,0 +1,291 @@
1
+package com.lqkj.common.utils;
2
+
3
+/**
4
+ * Base64工具类
5
+ * 
6
+ * @author lh
7
+ */
8
+public final class Base64
9
+{
10
+    static private final int     BASELENGTH           = 128;
11
+    static private final int     LOOKUPLENGTH         = 64;
12
+    static private final int     TWENTYFOURBITGROUP   = 24;
13
+    static private final int     EIGHTBIT             = 8;
14
+    static private final int     SIXTEENBIT           = 16;
15
+    static private final int     FOURBYTE             = 4;
16
+    static private final int     SIGN                 = -128;
17
+    static private final char    PAD                  = '=';
18
+    static final private byte[]  base64Alphabet       = new byte[BASELENGTH];
19
+    static final private char[]  lookUpBase64Alphabet = new char[LOOKUPLENGTH];
20
+
21
+    static
22
+    {
23
+        for (int i = 0; i < BASELENGTH; ++i)
24
+        {
25
+            base64Alphabet[i] = -1;
26
+        }
27
+        for (int i = 'Z'; i >= 'A'; i--)
28
+        {
29
+            base64Alphabet[i] = (byte) (i - 'A');
30
+        }
31
+        for (int i = 'z'; i >= 'a'; i--)
32
+        {
33
+            base64Alphabet[i] = (byte) (i - 'a' + 26);
34
+        }
35
+
36
+        for (int i = '9'; i >= '0'; i--)
37
+        {
38
+            base64Alphabet[i] = (byte) (i - '0' + 52);
39
+        }
40
+
41
+        base64Alphabet['+'] = 62;
42
+        base64Alphabet['/'] = 63;
43
+
44
+        for (int i = 0; i <= 25; i++)
45
+        {
46
+            lookUpBase64Alphabet[i] = (char) ('A' + i);
47
+        }
48
+
49
+        for (int i = 26, j = 0; i <= 51; i++, j++)
50
+        {
51
+            lookUpBase64Alphabet[i] = (char) ('a' + j);
52
+        }
53
+
54
+        for (int i = 52, j = 0; i <= 61; i++, j++)
55
+        {
56
+            lookUpBase64Alphabet[i] = (char) ('0' + j);
57
+        }
58
+        lookUpBase64Alphabet[62] = (char) '+';
59
+        lookUpBase64Alphabet[63] = (char) '/';
60
+    }
61
+
62
+    private static boolean isWhiteSpace(char octect)
63
+    {
64
+        return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
65
+    }
66
+
67
+    private static boolean isPad(char octect)
68
+    {
69
+        return (octect == PAD);
70
+    }
71
+
72
+    private static boolean isData(char octect)
73
+    {
74
+        return (octect < BASELENGTH && base64Alphabet[octect] != -1);
75
+    }
76
+
77
+    /**
78
+     * Encodes hex octects into Base64
79
+     *
80
+     * @param binaryData Array containing binaryData
81
+     * @return Encoded Base64 array
82
+     */
83
+    public static String encode(byte[] binaryData)
84
+    {
85
+        if (binaryData == null)
86
+        {
87
+            return null;
88
+        }
89
+
90
+        int lengthDataBits = binaryData.length * EIGHTBIT;
91
+        if (lengthDataBits == 0)
92
+        {
93
+            return "";
94
+        }
95
+
96
+        int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
97
+        int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
98
+        int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets;
99
+        char encodedData[] = null;
100
+
101
+        encodedData = new char[numberQuartet * 4];
102
+
103
+        byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
104
+
105
+        int encodedIndex = 0;
106
+        int dataIndex = 0;
107
+
108
+        for (int i = 0; i < numberTriplets; i++)
109
+        {
110
+            b1 = binaryData[dataIndex++];
111
+            b2 = binaryData[dataIndex++];
112
+            b3 = binaryData[dataIndex++];
113
+
114
+            l = (byte) (b2 & 0x0f);
115
+            k = (byte) (b1 & 0x03);
116
+
117
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
118
+            byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
119
+            byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);
120
+
121
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
122
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
123
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
124
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
125
+        }
126
+
127
+        // form integral number of 6-bit groups
128
+        if (fewerThan24bits == EIGHTBIT)
129
+        {
130
+            b1 = binaryData[dataIndex];
131
+            k = (byte) (b1 & 0x03);
132
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
133
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
134
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
135
+            encodedData[encodedIndex++] = PAD;
136
+            encodedData[encodedIndex++] = PAD;
137
+        }
138
+        else if (fewerThan24bits == SIXTEENBIT)
139
+        {
140
+            b1 = binaryData[dataIndex];
141
+            b2 = binaryData[dataIndex + 1];
142
+            l = (byte) (b2 & 0x0f);
143
+            k = (byte) (b1 & 0x03);
144
+
145
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
146
+            byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
147
+
148
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
149
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
150
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
151
+            encodedData[encodedIndex++] = PAD;
152
+        }
153
+        return new String(encodedData);
154
+    }
155
+
156
+    /**
157
+     * Decodes Base64 data into octects
158
+     *
159
+     * @param encoded string containing Base64 data
160
+     * @return Array containind decoded data.
161
+     */
162
+    public static byte[] decode(String encoded)
163
+    {
164
+        if (encoded == null)
165
+        {
166
+            return null;
167
+        }
168
+
169
+        char[] base64Data = encoded.toCharArray();
170
+        // remove white spaces
171
+        int len = removeWhiteSpace(base64Data);
172
+
173
+        if (len % FOURBYTE != 0)
174
+        {
175
+            return null;// should be divisible by four
176
+        }
177
+
178
+        int numberQuadruple = (len / FOURBYTE);
179
+
180
+        if (numberQuadruple == 0)
181
+        {
182
+            return new byte[0];
183
+        }
184
+
185
+        byte decodedData[] = null;
186
+        byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
187
+        char d1 = 0, d2 = 0, d3 = 0, d4 = 0;
188
+
189
+        int i = 0;
190
+        int encodedIndex = 0;
191
+        int dataIndex = 0;
192
+        decodedData = new byte[(numberQuadruple) * 3];
193
+
194
+        for (; i < numberQuadruple - 1; i++)
195
+        {
196
+
197
+            if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))
198
+                    || !isData((d3 = base64Data[dataIndex++])) || !isData((d4 = base64Data[dataIndex++])))
199
+            {
200
+                return null;
201
+            } // if found "no data" just return null
202
+
203
+            b1 = base64Alphabet[d1];
204
+            b2 = base64Alphabet[d2];
205
+            b3 = base64Alphabet[d3];
206
+            b4 = base64Alphabet[d4];
207
+
208
+            decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
209
+            decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
210
+            decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
211
+        }
212
+
213
+        if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++])))
214
+        {
215
+            return null;// if found "no data" just return null
216
+        }
217
+
218
+        b1 = base64Alphabet[d1];
219
+        b2 = base64Alphabet[d2];
220
+
221
+        d3 = base64Data[dataIndex++];
222
+        d4 = base64Data[dataIndex++];
223
+        if (!isData((d3)) || !isData((d4)))
224
+        {// Check if they are PAD characters
225
+            if (isPad(d3) && isPad(d4))
226
+            {
227
+                if ((b2 & 0xf) != 0)// last 4 bits should be zero
228
+                {
229
+                    return null;
230
+                }
231
+                byte[] tmp = new byte[i * 3 + 1];
232
+                System.arraycopy(decodedData, 0, tmp, 0, i * 3);
233
+                tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
234
+                return tmp;
235
+            }
236
+            else if (!isPad(d3) && isPad(d4))
237
+            {
238
+                b3 = base64Alphabet[d3];
239
+                if ((b3 & 0x3) != 0)// last 2 bits should be zero
240
+                {
241
+                    return null;
242
+                }
243
+                byte[] tmp = new byte[i * 3 + 2];
244
+                System.arraycopy(decodedData, 0, tmp, 0, i * 3);
245
+                tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
246
+                tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
247
+                return tmp;
248
+            }
249
+            else
250
+            {
251
+                return null;
252
+            }
253
+        }
254
+        else
255
+        { // No PAD e.g 3cQl
256
+            b3 = base64Alphabet[d3];
257
+            b4 = base64Alphabet[d4];
258
+            decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
259
+            decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
260
+            decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
261
+
262
+        }
263
+        return decodedData;
264
+    }
265
+
266
+    /**
267
+     * remove WhiteSpace from MIME containing encoded Base64 data.
268
+     *
269
+     * @param data the byte array of base64 data (with WS)
270
+     * @return the new length
271
+     */
272
+    private static int removeWhiteSpace(char[] data)
273
+    {
274
+        if (data == null)
275
+        {
276
+            return 0;
277
+        }
278
+
279
+        // count characters that's not whitespace
280
+        int newSize = 0;
281
+        int len = data.length;
282
+        for (int i = 0; i < len; i++)
283
+        {
284
+            if (!isWhiteSpace(data[i]))
285
+            {
286
+                data[newSize++] = data[i];
287
+            }
288
+        }
289
+        return newSize;
290
+    }
291
+}

+ 179 - 0
src/main/java/com/lqkj/common/utils/DateUtils.java

@@ -0,0 +1,179 @@
1
+package com.lqkj.common.utils;
2
+
3
+
4
+import org.apache.commons.lang3.time.DateFormatUtils;
5
+
6
+import java.lang.management.ManagementFactory;
7
+import java.text.ParseException;
8
+import java.text.SimpleDateFormat;
9
+import java.util.*;
10
+
11
+/**
12
+ * 扩展时间工具类
13
+ *
14
+ * @author lh
15
+ */
16
+public class DateUtils extends org.apache.commons.lang3.time.DateUtils
17
+{
18
+    public static String YYYY = "yyyy";
19
+
20
+    public static String YYYY_MM = "yyyy-MM";
21
+
22
+    public static String YYYY_MM_DD = "yyyy-MM-dd";
23
+
24
+    public static String YYYYMMDD = "yyyy/MM/dd";
25
+
26
+    public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
27
+
28
+    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
29
+
30
+    private static String[] parsePatterns = {
31
+            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
32
+            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
33
+            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
34
+
35
+    /**
36
+     * 获取当前Date型日期
37
+     *
38
+     * @return Date() 当前日期
39
+     */
40
+    public static Date getNowDate()
41
+    {
42
+        return new Date();
43
+    }
44
+
45
+    /**
46
+     * 获取当前日期, 默认格式为yyyy-MM-dd
47
+     *
48
+     * @return String
49
+     */
50
+    public static String getDate()
51
+    {
52
+        return dateTimeNow(YYYY_MM_DD);
53
+    }
54
+
55
+    public static final String getTime()
56
+    {
57
+        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
58
+    }
59
+
60
+    public static final String dateTimeNow()
61
+    {
62
+        return dateTimeNow(YYYYMMDDHHMMSS);
63
+    }
64
+
65
+    public static final String dateTimeNow(final String format)
66
+    {
67
+        return parseDateToStr(format, new Date());
68
+    }
69
+
70
+    public static final String dateTime(final Date date)
71
+    {
72
+        return parseDateToStr(YYYY_MM_DD, date);
73
+    }
74
+
75
+    public static final String parseDateToStr(final String format, final Date date)
76
+    {
77
+        return new SimpleDateFormat(format).format(date);
78
+    }
79
+
80
+    public static final Date dateTime(final String format, final String ts)
81
+    {
82
+        try
83
+        {
84
+            return new SimpleDateFormat(format).parse(ts);
85
+        }
86
+        catch (ParseException e)
87
+        {
88
+            throw new RuntimeException(e);
89
+        }
90
+    }
91
+
92
+    /**
93
+     * 日期路径 即年/月/日 如2018/08/08
94
+     */
95
+    public static final String datePath()
96
+    {
97
+        Date now = new Date();
98
+        return DateFormatUtils.format(now, "yyyy/MM/dd");
99
+    }
100
+
101
+    /**
102
+     * 日期路径 即年/月/日 如20180808
103
+     */
104
+    public static final String dateTime()
105
+    {
106
+        Date now = new Date();
107
+        return DateFormatUtils.format(now, "yyyyMMdd");
108
+    }
109
+
110
+    /**
111
+     * 日期型字符串转化为日期 格式
112
+     */
113
+    public static Date parseDate(Object str)
114
+    {
115
+        if (str == null)
116
+        {
117
+            return null;
118
+        }
119
+        try
120
+        {
121
+            return parseDate(str.toString(), parsePatterns);
122
+        }
123
+        catch (ParseException e)
124
+        {
125
+            return null;
126
+        }
127
+    }
128
+
129
+    /**
130
+     * 获取服务器启动时间
131
+     */
132
+    public static Date getServerStartDate()
133
+    {
134
+        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
135
+        return new Date(time);
136
+    }
137
+
138
+    /**
139
+     * 计算两个时间差
140
+     */
141
+    public static String getDatePoor(Date endDate, Date nowDate)
142
+    {
143
+        long nd = 1000 * 24 * 60 * 60;
144
+        long nh = 1000 * 60 * 60;
145
+        long nm = 1000 * 60;
146
+        // long ns = 1000;
147
+        // 获得两个时间的毫秒时间差异
148
+        long diff = endDate.getTime() - nowDate.getTime();
149
+        // 计算差多少天
150
+        long day = diff / nd;
151
+        // 计算差多少小时
152
+        long hour = diff % nd / nh;
153
+        // 计算差多少分钟
154
+        long min = diff % nd % nh / nm;
155
+        // 计算差多少秒//输出结果
156
+        // long sec = diff % nd % nh % nm / ns;
157
+        return day + "天" + hour + "小时" + min + "分钟";
158
+    }
159
+
160
+
161
+    /**
162
+     * 获取本周开始时间和结束时间
163
+     * @return
164
+     */
165
+    public static Map<String, Object> getWeekStartAndEnd(){
166
+        Map<String, Object> map = new HashMap<>();
167
+        Calendar calendar = Calendar.getInstance(Locale.CHINA);
168
+        calendar.setFirstDayOfWeek(Calendar.MONDAY);
169
+        calendar.setTimeInMillis(System.currentTimeMillis());
170
+        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
171
+        map.put("beginTime",  DateUtils.parseDateToStr(YYYY_MM_DD, calendar.getTime()) + " 00:00:00");
172
+        map.put("beginDate", DateUtils.parseDateToStr(YYYYMMDD, calendar.getTime()));
173
+        calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
174
+        map.put("endTime",  DateUtils.parseDateToStr(YYYY_MM_DD, calendar.getTime()) + " 23:59:59");
175
+        map.put("endDate", DateUtils.parseDateToStr(YYYYMMDD, calendar.getTime()));
176
+        return map;
177
+    }
178
+
179
+}

+ 185 - 0
src/main/java/com/lqkj/common/utils/DictUtils.java

@@ -0,0 +1,185 @@
1
+package com.lqkj.common.utils;
2
+
3
+
4
+import com.lqkj.common.constant.Constants;
5
+import com.lqkj.common.core.redis.RedisCache;
6
+import com.lqkj.common.utils.spring.SpringUtils;
7
+import com.lqkj.system.entity.SysDictData;
8
+
9
+import java.util.Collection;
10
+import java.util.List;
11
+
12
+/**
13
+ * 字典工具类
14
+ * 
15
+ * @author lh
16
+ */
17
+public class DictUtils
18
+{
19
+    /**
20
+     * 分隔符
21
+     */
22
+    public static final String SEPARATOR = ",";
23
+
24
+    /**
25
+     * 设置字典缓存
26
+     * 
27
+     * @param key 参数键
28
+     * @param dictDatas 字典数据列表
29
+     */
30
+    public static void setDictCache(String key, List<SysDictData> dictDatas)
31
+    {
32
+        SpringUtils.getBean(RedisCache.class).setCacheObject(getCacheKey(key), dictDatas);
33
+    }
34
+
35
+    /**
36
+     * 获取字典缓存
37
+     * 
38
+     * @param key 参数键
39
+     * @return dictDatas 字典数据列表
40
+     */
41
+    public static List<SysDictData> getDictCache(String key)
42
+    {
43
+        Object cacheObj = SpringUtils.getBean(RedisCache.class).getCacheObject(getCacheKey(key));
44
+        if (StringUtils.isNotNull(cacheObj))
45
+        {
46
+            List<SysDictData> dictDatas = StringUtils.cast(cacheObj);
47
+            return dictDatas;
48
+        }
49
+        return null;
50
+    }
51
+
52
+    /**
53
+     * 根据字典类型和字典值获取字典标签
54
+     * 
55
+     * @param dictType 字典类型
56
+     * @param dictValue 字典值
57
+     * @return 字典标签
58
+     */
59
+    public static String getDictLabel(String dictType, String dictValue)
60
+    {
61
+        return getDictLabel(dictType, dictValue, SEPARATOR);
62
+    }
63
+
64
+    /**
65
+     * 根据字典类型和字典标签获取字典值
66
+     * 
67
+     * @param dictType 字典类型
68
+     * @param dictLabel 字典标签
69
+     * @return 字典值
70
+     */
71
+    public static String getDictValue(String dictType, String dictLabel)
72
+    {
73
+        return getDictValue(dictType, dictLabel, SEPARATOR);
74
+    }
75
+
76
+    /**
77
+     * 根据字典类型和字典值获取字典标签
78
+     * 
79
+     * @param dictType 字典类型
80
+     * @param dictValue 字典值
81
+     * @param separator 分隔符
82
+     * @return 字典标签
83
+     */
84
+    public static String getDictLabel(String dictType, String dictValue, String separator)
85
+    {
86
+        StringBuilder propertyString = new StringBuilder();
87
+        List<SysDictData> datas = getDictCache(dictType);
88
+
89
+        if (StringUtils.containsAny(separator, dictValue) && StringUtils.isNotEmpty(datas))
90
+        {
91
+            for (SysDictData dict : datas)
92
+            {
93
+                for (String value : dictValue.split(separator))
94
+                {
95
+                    if (value.equals(dict.getDictValue()))
96
+                    {
97
+                        propertyString.append(dict.getDictLabel() + separator);
98
+                        break;
99
+                    }
100
+                }
101
+            }
102
+        }
103
+        else
104
+        {
105
+            for (SysDictData dict : datas)
106
+            {
107
+                if (dictValue.equals(dict.getDictValue()))
108
+                {
109
+                    return dict.getDictLabel();
110
+                }
111
+            }
112
+        }
113
+        return StringUtils.stripEnd(propertyString.toString(), separator);
114
+    }
115
+
116
+    /**
117
+     * 根据字典类型和字典标签获取字典值
118
+     * 
119
+     * @param dictType 字典类型
120
+     * @param dictLabel 字典标签
121
+     * @param separator 分隔符
122
+     * @return 字典值
123
+     */
124
+    public static String getDictValue(String dictType, String dictLabel, String separator)
125
+    {
126
+        StringBuilder propertyString = new StringBuilder();
127
+        List<SysDictData> datas = getDictCache(dictType);
128
+
129
+        if (StringUtils.containsAny(separator, dictLabel) && StringUtils.isNotEmpty(datas))
130
+        {
131
+            for (SysDictData dict : datas)
132
+            {
133
+                for (String label : dictLabel.split(separator))
134
+                {
135
+                    if (label.equals(dict.getDictLabel()))
136
+                    {
137
+                        propertyString.append(dict.getDictValue() + separator);
138
+                        break;
139
+                    }
140
+                }
141
+            }
142
+        }
143
+        else
144
+        {
145
+            for (SysDictData dict : datas)
146
+            {
147
+                if (dictLabel.equals(dict.getDictLabel()))
148
+                {
149
+                    return dict.getDictValue();
150
+                }
151
+            }
152
+        }
153
+        return StringUtils.stripEnd(propertyString.toString(), separator);
154
+    }
155
+
156
+    /**
157
+     * 删除指定字典缓存
158
+     * 
159
+     * @param key 字典键
160
+     */
161
+    public static void removeDictCache(String key)
162
+    {
163
+        SpringUtils.getBean(RedisCache.class).deleteObject(getCacheKey(key));
164
+    }
165
+
166
+    /**
167
+     * 清空字典缓存
168
+     */
169
+    public static void clearDictCache()
170
+    {
171
+        Collection<String> keys = SpringUtils.getBean(RedisCache.class).keys(Constants.SYS_DICT_KEY + "*");
172
+        SpringUtils.getBean(RedisCache.class).deleteObject(keys);
173
+    }
174
+
175
+    /**
176
+     * 设置cache key
177
+     * 
178
+     * @param configKey 参数键
179
+     * @return 缓存键key
180
+     */
181
+    public static String getCacheKey(String configKey)
182
+    {
183
+        return Constants.SYS_DICT_KEY + configKey;
184
+    }
185
+}

+ 42 - 0
src/main/java/com/lqkj/common/utils/ExceptionUtil.java

@@ -0,0 +1,42 @@
1
+package com.lqkj.common.utils;
2
+
3
+
4
+import org.apache.commons.lang3.exception.ExceptionUtils;
5
+
6
+import java.io.PrintWriter;
7
+import java.io.StringWriter;
8
+
9
+/**
10
+ * 错误信息处理类。
11
+ *
12
+ * @author lh
13
+ */
14
+public class ExceptionUtil
15
+{
16
+    /**
17
+     * 获取exception的详细错误信息。
18
+     */
19
+    public static String getExceptionMessage(Throwable e)
20
+    {
21
+        StringWriter sw = new StringWriter();
22
+        e.printStackTrace(new PrintWriter(sw, true));
23
+        String str = sw.toString();
24
+        return str;
25
+    }
26
+
27
+    public static String getRootErrorMessage(Exception e)
28
+    {
29
+        Throwable root = ExceptionUtils.getRootCause(e);
30
+        root = (root == null ? e : root);
31
+        if (root == null)
32
+        {
33
+            return "";
34
+        }
35
+        String msg = root.getMessage();
36
+        if (msg == null)
37
+        {
38
+            return "null";
39
+        }
40
+        return StringUtils.defaultString(msg);
41
+    }
42
+}

+ 19 - 0
src/main/java/com/lqkj/common/utils/LogUtils.java

@@ -0,0 +1,19 @@
1
+package com.lqkj.common.utils;
2
+
3
+
4
+/**
5
+ * 处理并记录日志文件
6
+ *
7
+ * @author lh
8
+ */
9
+public class LogUtils
10
+{
11
+    public static String getBlock(Object msg)
12
+    {
13
+        if (msg == null)
14
+        {
15
+            msg = "";
16
+        }
17
+        return "[" + msg.toString() + "]";
18
+    }
19
+}

+ 110 - 0
src/main/java/com/lqkj/common/utils/OkHttpConfig.java

@@ -0,0 +1,110 @@
1
+package com.lqkj.common.utils;
2
+
3
+
4
+import okhttp3.*;
5
+import org.jetbrains.annotations.NotNull;
6
+import org.springframework.context.annotation.Bean;
7
+import org.springframework.context.annotation.Configuration;
8
+
9
+import javax.net.ssl.SSLContext;
10
+import javax.net.ssl.SSLSocketFactory;
11
+import javax.net.ssl.TrustManager;
12
+import javax.net.ssl.X509TrustManager;
13
+import java.security.KeyManagementException;
14
+import java.security.NoSuchAlgorithmException;
15
+import java.security.SecureRandom;
16
+import java.security.cert.CertificateException;
17
+import java.security.cert.X509Certificate;
18
+import java.util.ArrayList;
19
+import java.util.HashMap;
20
+import java.util.List;
21
+import java.util.Map;
22
+import java.util.concurrent.TimeUnit;
23
+
24
+@Configuration
25
+public class OkHttpConfig {
26
+    @Bean
27
+    public X509TrustManager x509TrustManager() {
28
+        return new X509TrustManager() {
29
+            @Override
30
+            public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
31
+
32
+            }
33
+
34
+            @Override
35
+            public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
36
+
37
+            }
38
+
39
+            @Override
40
+            public X509Certificate[] getAcceptedIssuers() {
41
+                return new X509Certificate[0];
42
+            }
43
+        };
44
+    }
45
+
46
+    @Bean
47
+    public SSLSocketFactory sslSocketFactory() {
48
+        try {
49
+            SSLContext sslContext = SSLContext.getInstance("TLS");
50
+            sslContext.init(null, new TrustManager[]{x509TrustManager()}, new SecureRandom());
51
+            return sslContext.getSocketFactory();
52
+        } catch (NoSuchAlgorithmException e) {
53
+            e.printStackTrace();
54
+        } catch (KeyManagementException e) {
55
+            e.printStackTrace();
56
+        }
57
+        return null;
58
+    }
59
+
60
+    @Bean
61
+    public ConnectionPool pool() {
62
+        return new ConnectionPool(200, 5, TimeUnit.MINUTES);
63
+    }
64
+
65
+    @Bean
66
+    public CookieJar cookieJar() {
67
+        return new CookieJar() {
68
+            private final Map<String, List<Cookie>> cookiesCache = new HashMap<>();
69
+
70
+            @Override
71
+            public void saveFromResponse(@NotNull HttpUrl url, @NotNull List<Cookie> cookies) {
72
+                String host = url.host();
73
+                if (cookiesCache.get(host) != null) {
74
+                    cookiesCache.remove(host);
75
+                }
76
+                cookiesCache.put(host, cookies);
77
+            }
78
+
79
+            @NotNull
80
+            @Override
81
+            public List<Cookie> loadForRequest(@NotNull HttpUrl url) {
82
+                List<Cookie> cookies = cookiesCache.get(url.host());
83
+                if (cookies != null) {
84
+                    List<Cookie> validCookies = new ArrayList<>();
85
+                    for (Cookie cookie : cookies) {
86
+                        if (cookie.matches(url) && cookie.expiresAt() > System.currentTimeMillis()) {
87
+                            validCookies.add(cookie);
88
+                        }
89
+                    }
90
+                    return validCookies;
91
+                } else {
92
+                    return new ArrayList<>();
93
+                }
94
+            }
95
+        };
96
+    }
97
+
98
+    @Bean
99
+    public OkHttpClient okHttpClient() {
100
+        return new OkHttpClient.Builder()
101
+                .cookieJar(cookieJar()) //保持cookie
102
+                .sslSocketFactory(sslSocketFactory(), x509TrustManager())
103
+                .retryOnConnectionFailure(true) //是否开启缓存
104
+                .connectionPool(pool()) //间接池
105
+                .connectTimeout(10L, TimeUnit.SECONDS)
106
+                .readTimeout(10L, TimeUnit.SECONDS)
107
+                .build();
108
+    }
109
+
110
+}

+ 122 - 0
src/main/java/com/lqkj/common/utils/SecurityUtils.java

@@ -0,0 +1,122 @@
1
+package com.lqkj.common.utils;
2
+
3
+
4
+import com.lqkj.common.core.model.LoginUser;
5
+import com.lqkj.common.exception.ServiceException;
6
+import org.springframework.http.HttpStatus;
7
+import org.springframework.security.core.Authentication;
8
+import org.springframework.security.core.context.SecurityContextHolder;
9
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
10
+
11
+/**
12
+ * 安全服务工具类
13
+ * 
14
+ * @author lh
15
+ */
16
+public class SecurityUtils
17
+{
18
+    /**
19
+     * 用户ID
20
+     **/
21
+    public static String getUserId()
22
+    {
23
+        try
24
+        {
25
+            return getLoginUser().getUserId();
26
+        }
27
+        catch (Exception e)
28
+        {
29
+            throw new ServiceException("获取用户ID异常", HttpStatus.UNAUTHORIZED.value());
30
+        }
31
+    }
32
+
33
+    /**
34
+     * 获取部门ID
35
+     **/
36
+    public static Integer getDeptId()
37
+    {
38
+        try
39
+        {
40
+            return getLoginUser().getDeptId();
41
+        }
42
+        catch (Exception e)
43
+        {
44
+            throw new ServiceException("获取部门ID异常", HttpStatus.UNAUTHORIZED.value());
45
+        }
46
+    }
47
+    
48
+    /**
49
+     * 获取用户账户
50
+     **/
51
+    public static String getUsername()
52
+    {
53
+        try
54
+        {
55
+            return getLoginUser().getUsername();
56
+        }
57
+        catch (Exception e)
58
+        {
59
+            throw new ServiceException("获取用户账户异常", HttpStatus.UNAUTHORIZED.value());
60
+        }
61
+    }
62
+
63
+    /**
64
+     * 获取用户
65
+     **/
66
+    public static LoginUser getLoginUser()
67
+    {
68
+        try
69
+        {
70
+            return (LoginUser) getAuthentication().getPrincipal();
71
+        }
72
+        catch (Exception e)
73
+        {
74
+            throw new ServiceException("获取用户信息异常", HttpStatus.UNAUTHORIZED.value());
75
+        }
76
+    }
77
+
78
+    /**
79
+     * 获取Authentication
80
+     */
81
+    public static Authentication getAuthentication()
82
+    {
83
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
84
+        return authentication;
85
+    }
86
+
87
+    /**
88
+     * 生成BCryptPasswordEncoder密码
89
+     *
90
+     * @param password 密码
91
+     * @return 加密字符串
92
+     */
93
+    public static String encryptPassword(String password)
94
+    {
95
+        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
96
+        return passwordEncoder.encode(password);
97
+    }
98
+
99
+    /**
100
+     * 判断密码是否相同
101
+     *
102
+     * @param rawPassword 真实密码
103
+     * @param encodedPassword 加密后字符
104
+     * @return 结果
105
+     */
106
+    public static boolean matchesPassword(String rawPassword, String encodedPassword)
107
+    {
108
+        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
109
+        return passwordEncoder.matches(rawPassword, encodedPassword);
110
+    }
111
+
112
+    /**
113
+     * 是否为管理员
114
+     * 
115
+     * @param userId 用户ID
116
+     * @return 结果
117
+     */
118
+    public static boolean isAdmin(String userId)
119
+    {
120
+        return userId != null && "1".equals(userId) ;
121
+    }
122
+}

+ 154 - 0
src/main/java/com/lqkj/common/utils/ServletUtils.java

@@ -0,0 +1,154 @@
1
+package com.lqkj.common.utils;
2
+
3
+
4
+import com.lqkj.common.core.text.Convert;
5
+import org.springframework.web.context.request.RequestAttributes;
6
+import org.springframework.web.context.request.RequestContextHolder;
7
+import org.springframework.web.context.request.ServletRequestAttributes;
8
+
9
+import javax.servlet.http.HttpServletRequest;
10
+import javax.servlet.http.HttpServletResponse;
11
+import javax.servlet.http.HttpSession;
12
+import java.io.IOException;
13
+
14
+/**
15
+ * 客户端工具类
16
+ * 
17
+ * @author lh
18
+ */
19
+public class ServletUtils
20
+{
21
+    /**
22
+     * 获取String参数
23
+     */
24
+    public static String getParameter(String name)
25
+    {
26
+        return getRequest().getParameter(name);
27
+    }
28
+
29
+    /**
30
+     * 获取String参数
31
+     */
32
+    public static String getParameter(String name, String defaultValue)
33
+    {
34
+        return Convert.toStr(getRequest().getParameter(name), defaultValue);
35
+    }
36
+
37
+    /**
38
+     * 获取Integer参数
39
+     */
40
+    public static Integer getParameterToInt(String name)
41
+    {
42
+        return Convert.toInt(getRequest().getParameter(name));
43
+    }
44
+
45
+    /**
46
+     * 获取Integer参数
47
+     */
48
+    public static Integer getParameterToInt(String name, Integer defaultValue)
49
+    {
50
+        return Convert.toInt(getRequest().getParameter(name), defaultValue);
51
+    }
52
+
53
+    /**
54
+     * 获取Boolean参数
55
+     */
56
+    public static Boolean getParameterToBool(String name)
57
+    {
58
+        return Convert.toBool(getRequest().getParameter(name));
59
+    }
60
+
61
+    /**
62
+     * 获取Boolean参数
63
+     */
64
+    public static Boolean getParameterToBool(String name, Boolean defaultValue)
65
+    {
66
+        return Convert.toBool(getRequest().getParameter(name), defaultValue);
67
+    }
68
+
69
+    /**
70
+     * 获取request
71
+     */
72
+    public static HttpServletRequest getRequest()
73
+    {
74
+        return getRequestAttributes().getRequest();
75
+    }
76
+
77
+    /**
78
+     * 获取response
79
+     */
80
+    public static HttpServletResponse getResponse()
81
+    {
82
+        return getRequestAttributes().getResponse();
83
+    }
84
+
85
+    /**
86
+     * 获取session
87
+     */
88
+    public static HttpSession getSession()
89
+    {
90
+        return getRequest().getSession();
91
+    }
92
+
93
+    public static ServletRequestAttributes getRequestAttributes()
94
+    {
95
+        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
96
+        return (ServletRequestAttributes) attributes;
97
+    }
98
+
99
+    /**
100
+     * 将字符串渲染到客户端
101
+     * 
102
+     * @param response 渲染对象
103
+     * @param string 待渲染的字符串
104
+     * @return null
105
+     */
106
+    public static String renderString(HttpServletResponse response, String string)
107
+    {
108
+        try
109
+        {
110
+            response.setStatus(200);
111
+            response.setContentType("application/json");
112
+            response.setCharacterEncoding("utf-8");
113
+            response.getWriter().print(string);
114
+        }
115
+        catch (IOException e)
116
+        {
117
+            e.printStackTrace();
118
+        }
119
+        return null;
120
+    }
121
+
122
+    /**
123
+     * 是否是Ajax异步请求
124
+     * 
125
+     * @param request
126
+     */
127
+    public static boolean isAjaxRequest(HttpServletRequest request)
128
+    {
129
+        String accept = request.getHeader("accept");
130
+        if (accept != null && accept.indexOf("application/json") != -1)
131
+        {
132
+            return true;
133
+        }
134
+
135
+        String xRequestedWith = request.getHeader("X-Requested-With");
136
+        if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1)
137
+        {
138
+            return true;
139
+        }
140
+
141
+        String uri = request.getRequestURI();
142
+        if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml"))
143
+        {
144
+            return true;
145
+        }
146
+
147
+        String ajax = request.getParameter("__ajax");
148
+        if (StringUtils.inStringIgnoreCase(ajax, "json", "xml"))
149
+        {
150
+            return true;
151
+        }
152
+        return false;
153
+    }
154
+}

+ 530 - 0
src/main/java/com/lqkj/common/utils/StringUtils.java

@@ -0,0 +1,530 @@
1
+package com.lqkj.common.utils;
2
+
3
+
4
+import com.lqkj.common.constant.Constants;
5
+import com.lqkj.common.core.text.StrFormatter;
6
+import org.springframework.util.AntPathMatcher;
7
+
8
+import java.util.*;
9
+
10
+/**
11
+ * 扩展字符串工具类
12
+ *
13
+ * @author lh
14
+ */
15
+public class StringUtils extends org.apache.commons.lang3.StringUtils {
16
+    /** 空字符串 */
17
+    private static final String NULLSTR = "";
18
+
19
+    /** 下划线 */
20
+    private static final char SEPARATOR = '_';
21
+
22
+    /**
23
+     * 获取参数不为空值
24
+     *
25
+     * @param value defaultValue 要判断的value
26
+     * @return value 返回值
27
+     */
28
+    public static <T> T nvl(T value, T defaultValue)
29
+    {
30
+        return value != null ? value : defaultValue;
31
+    }
32
+
33
+    /**
34
+     * * 判断一个Collection是否为空, 包含List,Set,Queue
35
+     *
36
+     * @param coll 要判断的Collection
37
+     * @return true:为空 false:非空
38
+     */
39
+    public static boolean isEmpty(Collection<?> coll)
40
+    {
41
+        return isNull(coll) || coll.isEmpty();
42
+    }
43
+
44
+    /**
45
+     * * 判断一个Collection是否非空,包含List,Set,Queue
46
+     *
47
+     * @param coll 要判断的Collection
48
+     * @return true:非空 false:空
49
+     */
50
+    public static boolean isNotEmpty(Collection<?> coll)
51
+    {
52
+        return !isEmpty(coll);
53
+    }
54
+
55
+    /**
56
+     * * 判断一个对象数组是否为空
57
+     *
58
+     * @param objects 要判断的对象数组
59
+     ** @return true:为空 false:非空
60
+     */
61
+    public static boolean isEmpty(Object[] objects)
62
+    {
63
+        return isNull(objects) || (objects.length == 0);
64
+    }
65
+
66
+    /**
67
+     * * 判断一个对象数组是否非空
68
+     *
69
+     * @param objects 要判断的对象数组
70
+     * @return true:非空 false:空
71
+     */
72
+    public static boolean isNotEmpty(Object[] objects)
73
+    {
74
+        return !isEmpty(objects);
75
+    }
76
+
77
+    /**
78
+     * * 判断一个Map是否为空
79
+     *
80
+     * @param map 要判断的Map
81
+     * @return true:为空 false:非空
82
+     */
83
+    public static boolean isEmpty(Map<?, ?> map)
84
+    {
85
+        return isNull(map) || map.isEmpty();
86
+    }
87
+
88
+    /**
89
+     * * 判断一个Map是否为空
90
+     *
91
+     * @param map 要判断的Map
92
+     * @return true:非空 false:空
93
+     */
94
+    public static boolean isNotEmpty(Map<?, ?> map)
95
+    {
96
+        return !isEmpty(map);
97
+    }
98
+
99
+    /**
100
+     * * 判断一个字符串是否为空串
101
+     *
102
+     * @param str String
103
+     * @return true:为空 false:非空
104
+     */
105
+    public static boolean isEmpty(String str)
106
+    {
107
+        return isNull(str) || NULLSTR.equals(str.trim());
108
+    }
109
+
110
+    /**
111
+     * * 判断一个字符串是否为非空串
112
+     *
113
+     * @param str String
114
+     * @return true:非空串 false:空串
115
+     */
116
+    public static boolean isNotEmpty(String str)
117
+    {
118
+        return !isEmpty(str);
119
+    }
120
+
121
+    /**
122
+     * * 判断一个对象是否为空
123
+     *
124
+     * @param object Object
125
+     * @return true:为空 false:非空
126
+     */
127
+    public static boolean isNull(Object object)
128
+    {
129
+        return object == null;
130
+    }
131
+
132
+    /**
133
+     * * 判断一个对象是否非空
134
+     *
135
+     * @param object Object
136
+     * @return true:非空 false:空
137
+     */
138
+    public static boolean isNotNull(Object object)
139
+    {
140
+        return !isNull(object);
141
+    }
142
+
143
+    /**
144
+     * * 判断一个对象是否是数组类型(Java基本型别的数组)
145
+     *
146
+     * @param object 对象
147
+     * @return true:是数组 false:不是数组
148
+     */
149
+    public static boolean isArray(Object object)
150
+    {
151
+        return isNotNull(object) && object.getClass().isArray();
152
+    }
153
+
154
+    /**
155
+     * 去空格
156
+     */
157
+    public static String trim(String str)
158
+    {
159
+        return (str == null ? "" : str.trim());
160
+    }
161
+
162
+    /**
163
+     * 截取字符串
164
+     *
165
+     * @param str 字符串
166
+     * @param start 开始
167
+     * @return 结果
168
+     */
169
+    public static String substring(final String str, int start)
170
+    {
171
+        if (str == null)
172
+        {
173
+            return NULLSTR;
174
+        }
175
+
176
+        if (start < 0)
177
+        {
178
+            start = str.length() + start;
179
+        }
180
+
181
+        if (start < 0)
182
+        {
183
+            start = 0;
184
+        }
185
+        if (start > str.length())
186
+        {
187
+            return NULLSTR;
188
+        }
189
+
190
+        return str.substring(start);
191
+    }
192
+
193
+    /**
194
+     * 截取字符串
195
+     *
196
+     * @param str 字符串
197
+     * @param start 开始
198
+     * @param end 结束
199
+     * @return 结果
200
+     */
201
+    public static String substring(final String str, int start, int end)
202
+    {
203
+        if (str == null)
204
+        {
205
+            return NULLSTR;
206
+        }
207
+
208
+        if (end < 0)
209
+        {
210
+            end = str.length() + end;
211
+        }
212
+        if (start < 0)
213
+        {
214
+            start = str.length() + start;
215
+        }
216
+
217
+        if (end > str.length())
218
+        {
219
+            end = str.length();
220
+        }
221
+
222
+        if (start > end)
223
+        {
224
+            return NULLSTR;
225
+        }
226
+
227
+        if (start < 0)
228
+        {
229
+            start = 0;
230
+        }
231
+        if (end < 0)
232
+        {
233
+            end = 0;
234
+        }
235
+
236
+        return str.substring(start, end);
237
+    }
238
+
239
+    /**
240
+     * 格式化文本, {} 表示占位符<br>
241
+     * 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
242
+     * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
243
+     * 例:<br>
244
+     * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
245
+     * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
246
+     * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
247
+     *
248
+     * @param template 文本模板,被替换的部分用 {} 表示
249
+     * @param params 参数值
250
+     * @return 格式化后的文本
251
+     */
252
+    public static String format(String template, Object... params)
253
+    {
254
+        if (isEmpty(params) || isEmpty(template))
255
+        {
256
+            return template;
257
+        }
258
+        return StrFormatter.format(template, params);
259
+    }
260
+
261
+    /**
262
+     * 是否为http(s)://开头
263
+     *
264
+     * @param link 链接
265
+     * @return 结果
266
+     */
267
+    public static boolean ishttp(String link)
268
+    {
269
+        return StringUtils.startsWithAny(link, Constants.HTTP, Constants.HTTPS);
270
+    }
271
+
272
+    /**
273
+     * 字符串转set
274
+     *
275
+     * @param str 字符串
276
+     * @param sep 分隔符
277
+     * @return set集合
278
+     */
279
+    public static final Set<String> str2Set(String str, String sep)
280
+    {
281
+        return new HashSet<String>(str2List(str, sep, true, false));
282
+    }
283
+
284
+    /**
285
+     * 字符串转list
286
+     *
287
+     * @param str 字符串
288
+     * @param sep 分隔符
289
+     * @param filterBlank 过滤纯空白
290
+     * @param trim 去掉首尾空白
291
+     * @return list集合
292
+     */
293
+    public static final List<String> str2List(String str, String sep, boolean filterBlank, boolean trim)
294
+    {
295
+        List<String> list = new ArrayList<String>();
296
+        if (StringUtils.isEmpty(str))
297
+        {
298
+            return list;
299
+        }
300
+
301
+        // 过滤空白字符串
302
+        if (filterBlank && StringUtils.isBlank(str))
303
+        {
304
+            return list;
305
+        }
306
+        String[] split = str.split(sep);
307
+        for (String string : split)
308
+        {
309
+            if (filterBlank && StringUtils.isBlank(string))
310
+            {
311
+                continue;
312
+            }
313
+            if (trim)
314
+            {
315
+                string = string.trim();
316
+            }
317
+            list.add(string);
318
+        }
319
+
320
+        return list;
321
+    }
322
+
323
+    /**
324
+     * 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写
325
+     *
326
+     * @param cs 指定字符串
327
+     * @param searchCharSequences 需要检查的字符串数组
328
+     * @return 是否包含任意一个字符串
329
+     */
330
+    public static boolean containsAnyIgnoreCase(CharSequence cs, CharSequence... searchCharSequences)
331
+    {
332
+        if (isEmpty(cs) || isEmpty(searchCharSequences))
333
+        {
334
+            return false;
335
+        }
336
+        for (CharSequence testStr : searchCharSequences)
337
+        {
338
+            if (containsIgnoreCase(cs, testStr))
339
+            {
340
+                return true;
341
+            }
342
+        }
343
+        return false;
344
+    }
345
+
346
+    /**
347
+     * 驼峰转下划线命名
348
+     */
349
+    public static String toUnderScoreCase(String str)
350
+    {
351
+        if (str == null)
352
+        {
353
+            return null;
354
+        }
355
+        StringBuilder sb = new StringBuilder();
356
+        // 前置字符是否大写
357
+        boolean preCharIsUpperCase = true;
358
+        // 当前字符是否大写
359
+        boolean curreCharIsUpperCase = true;
360
+        // 下一字符是否大写
361
+        boolean nexteCharIsUpperCase = true;
362
+        for (int i = 0; i < str.length(); i++)
363
+        {
364
+            char c = str.charAt(i);
365
+            if (i > 0)
366
+            {
367
+                preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
368
+            }
369
+            else
370
+            {
371
+                preCharIsUpperCase = false;
372
+            }
373
+
374
+            curreCharIsUpperCase = Character.isUpperCase(c);
375
+
376
+            if (i < (str.length() - 1))
377
+            {
378
+                nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
379
+            }
380
+
381
+            if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase)
382
+            {
383
+                sb.append(SEPARATOR);
384
+            }
385
+            else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase)
386
+            {
387
+                sb.append(SEPARATOR);
388
+            }
389
+            sb.append(Character.toLowerCase(c));
390
+        }
391
+
392
+        return sb.toString();
393
+    }
394
+
395
+    /**
396
+     * 是否包含字符串
397
+     *
398
+     * @param str 验证字符串
399
+     * @param strs 字符串组
400
+     * @return 包含返回true
401
+     */
402
+    public static boolean inStringIgnoreCase(String str, String... strs)
403
+    {
404
+        if (str != null && strs != null)
405
+        {
406
+            for (String s : strs)
407
+            {
408
+                if (str.equalsIgnoreCase(trim(s)))
409
+                {
410
+                    return true;
411
+                }
412
+            }
413
+        }
414
+        return false;
415
+    }
416
+
417
+    /**
418
+     * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld
419
+     *
420
+     * @param name 转换前的下划线大写方式命名的字符串
421
+     * @return 转换后的驼峰式命名的字符串
422
+     */
423
+    public static String convertToCamelCase(String name)
424
+    {
425
+        StringBuilder result = new StringBuilder();
426
+        // 快速检查
427
+        if (name == null || name.isEmpty())
428
+        {
429
+            // 没必要转换
430
+            return "";
431
+        }
432
+        else if (!name.contains("_"))
433
+        {
434
+            // 不含下划线,仅将首字母大写
435
+            return name.substring(0, 1).toUpperCase() + name.substring(1);
436
+        }
437
+        // 用下划线将原始字符串分割
438
+        String[] camels = name.split("_");
439
+        for (String camel : camels)
440
+        {
441
+            // 跳过原始字符串中开头、结尾的下换线或双重下划线
442
+            if (camel.isEmpty())
443
+            {
444
+                continue;
445
+            }
446
+            // 首字母大写
447
+            result.append(camel.substring(0, 1).toUpperCase());
448
+            result.append(camel.substring(1).toLowerCase());
449
+        }
450
+        return result.toString();
451
+    }
452
+
453
+    /**
454
+     * 驼峰式命名法 例如:user_name->userName
455
+     */
456
+    public static String toCamelCase(String s)
457
+    {
458
+        if (s == null)
459
+        {
460
+            return null;
461
+        }
462
+        s = s.toLowerCase();
463
+        StringBuilder sb = new StringBuilder(s.length());
464
+        boolean upperCase = false;
465
+        for (int i = 0; i < s.length(); i++)
466
+        {
467
+            char c = s.charAt(i);
468
+
469
+            if (c == SEPARATOR)
470
+            {
471
+                upperCase = true;
472
+            }
473
+            else if (upperCase)
474
+            {
475
+                sb.append(Character.toUpperCase(c));
476
+                upperCase = false;
477
+            }
478
+            else
479
+            {
480
+                sb.append(c);
481
+            }
482
+        }
483
+        return sb.toString();
484
+    }
485
+
486
+    /**
487
+     * 查找指定字符串是否匹配指定字符串列表中的任意一个字符串
488
+     *
489
+     * @param str 指定字符串
490
+     * @param strs 需要检查的字符串数组
491
+     * @return 是否匹配
492
+     */
493
+    public static boolean matches(String str, List<String> strs)
494
+    {
495
+        if (isEmpty(str) || isEmpty(strs))
496
+        {
497
+            return false;
498
+        }
499
+        for (String pattern : strs)
500
+        {
501
+            if (isMatch(pattern, str))
502
+            {
503
+                return true;
504
+            }
505
+        }
506
+        return false;
507
+    }
508
+
509
+    /**
510
+     * 判断url是否与规则配置:
511
+     * ? 表示单个字符;
512
+     * * 表示一层路径内的任意字符串,不可跨层级;
513
+     * ** 表示任意层路径;
514
+     *
515
+     * @param pattern 匹配规则
516
+     * @param url 需要匹配的url
517
+     * @return
518
+     */
519
+    public static boolean isMatch(String pattern, String url)
520
+    {
521
+        AntPathMatcher matcher = new AntPathMatcher();
522
+        return matcher.match(pattern, url);
523
+    }
524
+
525
+    @SuppressWarnings("unchecked")
526
+    public static <T> T cast(Object obj)
527
+    {
528
+        return (T) obj;
529
+    }
530
+}

+ 96 - 0
src/main/java/com/lqkj/common/utils/Threads.java

@@ -0,0 +1,96 @@
1
+package com.lqkj.common.utils;
2
+
3
+import org.slf4j.Logger;
4
+import org.slf4j.LoggerFactory;
5
+
6
+import java.util.concurrent.*;
7
+
8
+/**
9
+ * 线程相关工具类.
10
+ * 
11
+ * @author lh
12
+ */
13
+public class Threads
14
+{
15
+    private static final Logger logger = LoggerFactory.getLogger(Threads.class);
16
+
17
+    /**
18
+     * sleep等待,单位为毫秒
19
+     */
20
+    public static void sleep(long milliseconds)
21
+    {
22
+        try
23
+        {
24
+            Thread.sleep(milliseconds);
25
+        }
26
+        catch (InterruptedException e)
27
+        {
28
+            return;
29
+        }
30
+    }
31
+
32
+    /**
33
+     * 停止线程池
34
+     * 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务.
35
+     * 如果超时, 则调用shutdownNow, 取消在workQueue中Pending的任务,并中断所有阻塞函数.
36
+     * 如果仍然超時,則強制退出.
37
+     * 另对在shutdown时线程本身被调用中断做了处理.
38
+     */
39
+    public static void shutdownAndAwaitTermination(ExecutorService pool)
40
+    {
41
+        if (pool != null && !pool.isShutdown())
42
+        {
43
+            pool.shutdown();
44
+            try
45
+            {
46
+                if (!pool.awaitTermination(120, TimeUnit.SECONDS))
47
+                {
48
+                    pool.shutdownNow();
49
+                    if (!pool.awaitTermination(120, TimeUnit.SECONDS))
50
+                    {
51
+                        logger.info("Pool did not terminate");
52
+                    }
53
+                }
54
+            }
55
+            catch (InterruptedException ie)
56
+            {
57
+                pool.shutdownNow();
58
+                Thread.currentThread().interrupt();
59
+            }
60
+        }
61
+    }
62
+
63
+    /**
64
+     * 打印线程异常信息
65
+     */
66
+    public static void printException(Runnable r, Throwable t)
67
+    {
68
+        if (t == null && r instanceof Future<?>)
69
+        {
70
+            try
71
+            {
72
+                Future<?> future = (Future<?>) r;
73
+                if (future.isDone())
74
+                {
75
+                    future.get();
76
+                }
77
+            }
78
+            catch (CancellationException ce)
79
+            {
80
+                t = ce;
81
+            }
82
+            catch (ExecutionException ee)
83
+            {
84
+                t = ee.getCause();
85
+            }
86
+            catch (InterruptedException ie)
87
+            {
88
+                Thread.currentThread().interrupt();
89
+            }
90
+        }
91
+        if (t != null)
92
+        {
93
+            logger.error(t.getMessage(), t);
94
+        }
95
+    }
96
+}

+ 44 - 0
src/main/java/com/lqkj/common/utils/TimeUtils.java

@@ -0,0 +1,44 @@
1
+package com.lqkj.common.utils;
2
+
3
+import java.text.ParseException;
4
+import java.text.SimpleDateFormat;
5
+import java.util.Date;
6
+
7
+public class TimeUtils {
8
+
9
+    /**
10
+     * 时间戳转字符串
11
+     *
12
+     * @param time   时间戳
13
+     * @param format 格式,如"yyyy-MM-dd HH:mm:ss"
14
+     * @return 时间格式字符串
15
+     */
16
+    public static String getTimeString(long time, String format) {
17
+        if (format == null || format.isEmpty())
18
+            format = "yyyy-MM-dd HH:mm:ss";
19
+        SimpleDateFormat sdf = new SimpleDateFormat(format);
20
+        return sdf.format(new Date(time));
21
+    }
22
+
23
+    public static Long getTimestamp(String time) {
24
+        return getTimestamp(time, "yyyy-MM-dd HH:mm:ss");
25
+    }
26
+
27
+    /**
28
+     * 字符串转时间戳
29
+     *
30
+     * @param time 字符串
31
+     * @return 时间戳
32
+     **/
33
+    public static Long getTimestamp(String time, String format) {
34
+        if (format == null || format.isEmpty())
35
+            format = "yyyy-MM-dd HH:mm:ss";
36
+        Long timestamp = null;
37
+        try {
38
+            timestamp = new SimpleDateFormat(format).parse(time).getTime();
39
+        } catch (ParseException e) {
40
+            e.printStackTrace();
41
+        }
42
+        return timestamp;
43
+    }
44
+}

+ 108 - 0
src/main/java/com/lqkj/common/utils/bean/BeanUtils.java

@@ -0,0 +1,108 @@
1
+package com.lqkj.common.utils.bean;
2
+
3
+import java.lang.reflect.Method;
4
+import java.util.ArrayList;
5
+import java.util.List;
6
+import java.util.regex.Matcher;
7
+import java.util.regex.Pattern;
8
+
9
+/**
10
+ * 扩展spirng 工具类
11
+ * @author lh
12
+ */
13
+public class BeanUtils  extends org.springframework.beans.BeanUtils {
14
+    /** Bean方法名中属性名开始的下标 */
15
+    private static final int BEAN_METHOD_PROP_INDEX = 3;
16
+
17
+    /** * 匹配getter方法的正则表达式 */
18
+    private static final Pattern GET_PATTERN = Pattern.compile("get(\\p{javaUpperCase}\\w*)");
19
+
20
+    /** * 匹配setter方法的正则表达式 */
21
+    private static final Pattern SET_PATTERN = Pattern.compile("set(\\p{javaUpperCase}\\w*)");
22
+
23
+    /**
24
+     * Bean属性复制工具方法。
25
+     *
26
+     * @param dest 目标对象
27
+     * @param src 源对象
28
+     */
29
+    public static void copyBeanProp(Object dest, Object src)
30
+    {
31
+        try
32
+        {
33
+            copyProperties(src, dest);
34
+        }
35
+        catch (Exception e)
36
+        {
37
+            e.printStackTrace();
38
+        }
39
+    }
40
+
41
+    /**
42
+     * 获取对象的setter方法。
43
+     *
44
+     * @param obj 对象
45
+     * @return 对象的setter方法列表
46
+     */
47
+    public static List<Method> getSetterMethods(Object obj)
48
+    {
49
+        // setter方法列表
50
+        List<Method> setterMethods = new ArrayList<Method>();
51
+
52
+        // 获取所有方法
53
+        Method[] methods = obj.getClass().getMethods();
54
+
55
+        // 查找setter方法
56
+
57
+        for (Method method : methods)
58
+        {
59
+            Matcher m = SET_PATTERN.matcher(method.getName());
60
+            if (m.matches() && (method.getParameterTypes().length == 1))
61
+            {
62
+                setterMethods.add(method);
63
+            }
64
+        }
65
+        // 返回setter方法列表
66
+        return setterMethods;
67
+    }
68
+
69
+    /**
70
+     * 获取对象的getter方法。
71
+     *
72
+     * @param obj 对象
73
+     * @return 对象的getter方法列表
74
+     */
75
+
76
+    public static List<Method> getGetterMethods(Object obj)
77
+    {
78
+        // getter方法列表
79
+        List<Method> getterMethods = new ArrayList<Method>();
80
+        // 获取所有方法
81
+        Method[] methods = obj.getClass().getMethods();
82
+        // 查找getter方法
83
+        for (Method method : methods)
84
+        {
85
+            Matcher m = GET_PATTERN.matcher(method.getName());
86
+            if (m.matches() && (method.getParameterTypes().length == 0))
87
+            {
88
+                getterMethods.add(method);
89
+            }
90
+        }
91
+        // 返回getter方法列表
92
+        return getterMethods;
93
+    }
94
+
95
+    /**
96
+     * 检查Bean方法名中的属性名是否相等。<br>
97
+     * 如getName()和setName()属性名一样,getName()和setAge()属性名不一样。
98
+     *
99
+     * @param m1 方法名1
100
+     * @param m2 方法名2
101
+     * @return 属性名一样返回true,否则返回false
102
+     */
103
+
104
+    public static boolean isMethodPropEquals(String m1, String m2)
105
+    {
106
+        return m1.substring(BEAN_METHOD_PROP_INDEX).equals(m2.substring(BEAN_METHOD_PROP_INDEX));
107
+    }
108
+}

+ 40 - 0
src/main/java/com/lqkj/common/utils/easyexcel/LocalDateTimeConverter.java

@@ -0,0 +1,40 @@
1
+package com.lqkj.common.utils.easyexcel;
2
+
3
+import com.alibaba.excel.converters.Converter;
4
+import com.alibaba.excel.enums.CellDataTypeEnum;
5
+import com.alibaba.excel.metadata.GlobalConfiguration;
6
+import com.alibaba.excel.metadata.data.ReadCellData;
7
+import com.alibaba.excel.metadata.data.WriteCellData;
8
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
9
+
10
+import java.time.LocalDateTime;
11
+import java.time.format.DateTimeFormatter;
12
+
13
+/**
14
+ * 解决 EasyExcel 日期类型 LocalDateTime 转换的问题
15
+ */
16
+public class LocalDateTimeConverter implements Converter<LocalDateTime> {
17
+
18
+    @Override
19
+    public Class<LocalDateTime> supportJavaTypeKey() {
20
+        return LocalDateTime.class;
21
+    }
22
+
23
+    @Override
24
+    public CellDataTypeEnum supportExcelTypeKey() {
25
+        return CellDataTypeEnum.STRING;
26
+    }
27
+
28
+    @Override
29
+    public LocalDateTime convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty,
30
+                                           GlobalConfiguration globalConfiguration) {
31
+        return LocalDateTime.parse(cellData.getStringValue(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
32
+    }
33
+
34
+    @Override
35
+    public WriteCellData<String> convertToExcelData(LocalDateTime value, ExcelContentProperty contentProperty,
36
+                                                    GlobalConfiguration globalConfiguration) {
37
+        return new WriteCellData(value.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
38
+    }
39
+
40
+}

+ 77 - 0
src/main/java/com/lqkj/common/utils/file/FileTypeUtils.java

@@ -0,0 +1,77 @@
1
+package com.lqkj.common.utils.file;
2
+
3
+import org.apache.commons.lang3.StringUtils;
4
+
5
+import java.io.File;
6
+
7
+/**
8
+ * 文件类型工具类
9
+ *
10
+ * @author lh
11
+ */
12
+public class FileTypeUtils
13
+{
14
+    /**
15
+     * 获取文件类型
16
+     * <p>
17
+     * 例如: lingwei.txt, 返回: txt
18
+     * 
19
+     * @param file 文件名
20
+     * @return 后缀(不含".")
21
+     */
22
+    public static String getFileType(File file)
23
+    {
24
+        if (null == file)
25
+        {
26
+            return StringUtils.EMPTY;
27
+        }
28
+        return getFileType(file.getName());
29
+    }
30
+
31
+    /**
32
+     * 获取文件类型
33
+     * <p>
34
+     * 例如: lingwei.txt, 返回: txt
35
+     *
36
+     * @param fileName 文件名
37
+     * @return 后缀(不含".")
38
+     */
39
+    public static String getFileType(String fileName)
40
+    {
41
+        int separatorIndex = fileName.lastIndexOf(".");
42
+        if (separatorIndex < 0)
43
+        {
44
+            return "";
45
+        }
46
+        return fileName.substring(separatorIndex + 1).toLowerCase();
47
+    }
48
+
49
+    /**
50
+     * 获取文件类型
51
+     * 
52
+     * @param photoByte 文件字节码
53
+     * @return 后缀(不含".")
54
+     */
55
+    public static String getFileExtendName(byte[] photoByte)
56
+    {
57
+        String strFileExtendName = "JPG";
58
+        if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56)
59
+                && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97))
60
+        {
61
+            strFileExtendName = "GIF";
62
+        }
63
+        else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70))
64
+        {
65
+            strFileExtendName = "JPG";
66
+        }
67
+        else if ((photoByte[0] == 66) && (photoByte[1] == 77))
68
+        {
69
+            strFileExtendName = "BMP";
70
+        }
71
+        else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71))
72
+        {
73
+            strFileExtendName = "PNG";
74
+        }
75
+        return strFileExtendName;
76
+    }
77
+}

+ 236 - 0
src/main/java/com/lqkj/common/utils/file/FileUploadUtils.java

@@ -0,0 +1,236 @@
1
+package com.lqkj.common.utils.file;
2
+
3
+import com.lqkj.common.config.LingWeiConfig;
4
+import com.lqkj.common.constant.Constants;
5
+import com.lqkj.common.exception.file.FileNameLengthLimitExceededException;
6
+import com.lqkj.common.exception.file.FileSizeLimitExceededException;
7
+import com.lqkj.common.exception.file.InvalidExtensionException;
8
+import com.lqkj.common.utils.DateUtils;
9
+import com.lqkj.common.utils.StringUtils;
10
+import com.lqkj.common.utils.uuid.IdUtils;
11
+import org.apache.commons.io.FilenameUtils;
12
+import org.springframework.web.multipart.MultipartFile;
13
+
14
+import java.io.File;
15
+import java.io.IOException;
16
+
17
+/**
18
+ * 文件上传工具类
19
+ *
20
+ * @author lh
21
+ */
22
+public class FileUploadUtils
23
+{
24
+    /**
25
+     * 默认大小 2000M
26
+     */
27
+    public static final long DEFAULT_MAX_SIZE = 2000 * 1024 * 1024;
28
+
29
+    /**
30
+     * 默认的文件名最大长度 200
31
+     */
32
+    public static final int DEFAULT_FILE_NAME_LENGTH = 200;
33
+
34
+    /**
35
+     * 默认上传的地址
36
+     */
37
+    private static String defaultBaseDir = LingWeiConfig.getProfile();
38
+
39
+    public static void setDefaultBaseDir(String defaultBaseDir)
40
+    {
41
+        FileUploadUtils.defaultBaseDir = defaultBaseDir;
42
+    }
43
+
44
+    public static String getDefaultBaseDir()
45
+    {
46
+        return defaultBaseDir;
47
+    }
48
+
49
+    /**
50
+     * 以默认配置进行文件上传
51
+     *
52
+     * @param file 上传的文件
53
+     * @return 文件名称
54
+     * @throws Exception
55
+     */
56
+    public static final String upload(MultipartFile file) throws IOException
57
+    {
58
+        try
59
+        {
60
+            return upload(getDefaultBaseDir(), file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
61
+        }
62
+        catch (Exception e)
63
+        {
64
+            throw new IOException(e.getMessage(), e);
65
+        }
66
+    }
67
+
68
+    /**
69
+     * 根据文件路径上传
70
+     *
71
+     * @param baseDir 相对应用的基目录
72
+     * @param file 上传的文件
73
+     * @return 文件名称
74
+     * @throws IOException
75
+     */
76
+    public static final String upload(String baseDir, MultipartFile file) throws IOException
77
+    {
78
+        try
79
+        {
80
+            return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
81
+        }
82
+        catch (Exception e)
83
+        {
84
+            throw new IOException(e.getMessage(), e);
85
+        }
86
+    }
87
+
88
+    /**
89
+     * 文件上传
90
+     *
91
+     * @param baseDir 相对应用的基目录
92
+     * @param file 上传的文件
93
+     * @param allowedExtension 上传文件类型
94
+     * @return 返回上传成功的文件名
95
+     * @throws FileSizeLimitExceededException 如果超出最大大小
96
+     * @throws FileNameLengthLimitExceededException 文件名太长
97
+     * @throws IOException 比如读写文件出错时
98
+     * @throws InvalidExtensionException 文件校验异常
99
+     */
100
+    public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension)
101
+            throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
102
+            InvalidExtensionException
103
+    {
104
+        int fileNamelength = file.getOriginalFilename().length();
105
+        if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
106
+        {
107
+            throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
108
+        }
109
+
110
+        assertAllowed(file, allowedExtension);
111
+
112
+        String fileName = extractFilename(file);
113
+
114
+        File desc = getAbsoluteFile(baseDir, fileName);
115
+        file.transferTo(desc);
116
+        String pathFileName = getPathFileName(baseDir, fileName);
117
+        return pathFileName;
118
+    }
119
+
120
+    /**
121
+     * 编码文件名
122
+     */
123
+    public static final String extractFilename(MultipartFile file)
124
+    {
125
+        String fileName = file.getOriginalFilename();
126
+        String extension = getExtension(file);
127
+        fileName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + extension;
128
+        return fileName;
129
+    }
130
+
131
+    public static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
132
+    {
133
+        File desc = new File(uploadDir + File.separator + fileName);
134
+
135
+        if (!desc.exists())
136
+        {
137
+            if (!desc.getParentFile().exists())
138
+            {
139
+                desc.getParentFile().mkdirs();
140
+            }
141
+        }
142
+        return desc;
143
+    }
144
+
145
+    public static final String getPathFileName(String uploadDir, String fileName) throws IOException
146
+    {
147
+        int dirLastIndex = LingWeiConfig.getProfile().length() + 1;
148
+        String currentDir = StringUtils.substring(uploadDir, dirLastIndex);
149
+        String pathFileName = Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName;
150
+        return pathFileName;
151
+    }
152
+
153
+    /**
154
+     * 文件大小校验
155
+     *
156
+     * @param file 上传的文件
157
+     * @return
158
+     * @throws FileSizeLimitExceededException 如果超出最大大小
159
+     * @throws InvalidExtensionException
160
+     */
161
+    public static final void assertAllowed(MultipartFile file, String[] allowedExtension)
162
+            throws FileSizeLimitExceededException, InvalidExtensionException
163
+    {
164
+        long size = file.getSize();
165
+        if (DEFAULT_MAX_SIZE != -1 && size > DEFAULT_MAX_SIZE)
166
+        {
167
+            throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024);
168
+        }
169
+
170
+        String fileName = file.getOriginalFilename();
171
+        String extension = getExtension(file);
172
+        if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension))
173
+        {
174
+            if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION)
175
+            {
176
+                throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,
177
+                        fileName);
178
+            }
179
+            else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION)
180
+            {
181
+                throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension,
182
+                        fileName);
183
+            }
184
+            else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION)
185
+            {
186
+                throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension,
187
+                        fileName);
188
+            }
189
+            else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION)
190
+            {
191
+                throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension,
192
+                        fileName);
193
+            }
194
+            else
195
+            {
196
+                throw new InvalidExtensionException(allowedExtension, extension, fileName);
197
+            }
198
+        }
199
+
200
+    }
201
+
202
+    /**
203
+     * 判断MIME类型是否是允许的MIME类型
204
+     *
205
+     * @param extension
206
+     * @param allowedExtension
207
+     * @return
208
+     */
209
+    public static final boolean isAllowedExtension(String extension, String[] allowedExtension)
210
+    {
211
+        for (String str : allowedExtension)
212
+        {
213
+            if (str.equalsIgnoreCase(extension))
214
+            {
215
+                return true;
216
+            }
217
+        }
218
+        return false;
219
+    }
220
+
221
+    /**
222
+     * 获取文件名的后缀
223
+     *
224
+     * @param file 表单文件
225
+     * @return 后缀名
226
+     */
227
+    public static final String getExtension(MultipartFile file)
228
+    {
229
+        String extension = FilenameUtils.getExtension(file.getOriginalFilename());
230
+        if (StringUtils.isEmpty(extension))
231
+        {
232
+            extension = MimeTypeUtils.getExtension(file.getContentType());
233
+        }
234
+        return extension;
235
+    }
236
+}

+ 252 - 0
src/main/java/com/lqkj/common/utils/file/FileUtils.java

@@ -0,0 +1,252 @@
1
+package com.lqkj.common.utils.file;
2
+
3
+import com.lqkj.common.config.LingWeiConfig;
4
+import com.lqkj.common.utils.DateUtils;
5
+import com.lqkj.common.utils.StringUtils;
6
+import com.lqkj.common.utils.uuid.IdUtils;
7
+import org.apache.commons.io.IOUtils;
8
+import org.apache.commons.lang3.ArrayUtils;
9
+
10
+import javax.servlet.http.HttpServletRequest;
11
+import javax.servlet.http.HttpServletResponse;
12
+import java.io.*;
13
+import java.net.URLEncoder;
14
+import java.nio.charset.StandardCharsets;
15
+
16
+/**
17
+ * 文件处理工具类
18
+ * 
19
+ * @author lh
20
+ */
21
+public class FileUtils
22
+{
23
+    public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+";
24
+
25
+    /**
26
+     * 输出指定文件的byte数组
27
+     * 
28
+     * @param filePath 文件路径
29
+     * @param os 输出流
30
+     * @return
31
+     */
32
+    public static void writeBytes(String filePath, OutputStream os) throws IOException
33
+    {
34
+        FileInputStream fis = null;
35
+        try
36
+        {
37
+            File file = new File(filePath);
38
+            if (!file.exists())
39
+            {
40
+                throw new FileNotFoundException(filePath);
41
+            }
42
+            fis = new FileInputStream(file);
43
+            byte[] b = new byte[1024];
44
+            int length;
45
+            while ((length = fis.read(b)) > 0)
46
+            {
47
+                os.write(b, 0, length);
48
+            }
49
+        }
50
+        catch (IOException e)
51
+        {
52
+            throw e;
53
+        }
54
+        finally
55
+        {
56
+            IOUtils.close(os);
57
+            IOUtils.close(fis);
58
+        }
59
+    }
60
+
61
+    /**
62
+     * 写数据到文件中
63
+     *
64
+     * @param data 数据
65
+     * @return 目标文件
66
+     * @throws IOException IO异常
67
+     */
68
+    public static String writeImportBytes(byte[] data) throws IOException
69
+    {
70
+        return writeBytes(data, LingWeiConfig.getImportPath());
71
+    }
72
+
73
+    /**
74
+     * 写数据到文件中
75
+     *
76
+     * @param data 数据
77
+     * @param uploadDir 目标文件
78
+     * @return 目标文件
79
+     * @throws IOException IO异常
80
+     */
81
+    public static String writeBytes(byte[] data, String uploadDir) throws IOException
82
+    {
83
+        FileOutputStream fos = null;
84
+        String pathName = "";
85
+        try
86
+        {
87
+            String extension = getFileExtendName(data);
88
+            pathName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + extension;
89
+            File file = FileUploadUtils.getAbsoluteFile(uploadDir, pathName);
90
+            fos = new FileOutputStream(file);
91
+            fos.write(data);
92
+        }
93
+        finally
94
+        {
95
+            IOUtils.close(fos);
96
+        }
97
+        return FileUploadUtils.getPathFileName(uploadDir, pathName);
98
+    }
99
+
100
+    /**
101
+     * 删除文件
102
+     * 
103
+     * @param filePath 文件
104
+     * @return
105
+     */
106
+    public static boolean deleteFile(String filePath)
107
+    {
108
+        boolean flag = false;
109
+        File file = new File(filePath);
110
+        // 路径为文件且不为空则进行删除
111
+        if (file.isFile() && file.exists())
112
+        {
113
+            file.delete();
114
+            flag = true;
115
+        }
116
+        return flag;
117
+    }
118
+
119
+    /**
120
+     * 文件名称验证
121
+     * 
122
+     * @param filename 文件名称
123
+     * @return true 正常 false 非法
124
+     */
125
+    public static boolean isValidFilename(String filename)
126
+    {
127
+        return filename.matches(FILENAME_PATTERN);
128
+    }
129
+
130
+    /**
131
+     * 检查文件是否可下载
132
+     * 
133
+     * @param resource 需要下载的文件
134
+     * @return true 正常 false 非法
135
+     */
136
+    public static boolean checkAllowDownload(String resource)
137
+    {
138
+        // 禁止目录上跳级别
139
+        if (StringUtils.contains(resource, ".."))
140
+        {
141
+            return false;
142
+        }
143
+
144
+        // 检查允许下载的文件规则
145
+        if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource)))
146
+        {
147
+            return true;
148
+        }
149
+
150
+        // 不在允许下载的文件规则
151
+        return false;
152
+    }
153
+
154
+    /**
155
+     * 下载文件名重新编码
156
+     * 
157
+     * @param request 请求对象
158
+     * @param fileName 文件名
159
+     * @return 编码后的文件名
160
+     */
161
+    public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException
162
+    {
163
+        final String agent = request.getHeader("USER-AGENT");
164
+        String filename = fileName;
165
+        if (agent.contains("MSIE"))
166
+        {
167
+            // IE浏览器
168
+            filename = URLEncoder.encode(filename, "utf-8");
169
+            filename = filename.replace("+", " ");
170
+        }
171
+        else if (agent.contains("Firefox"))
172
+        {
173
+            // 火狐浏览器
174
+            filename = new String(fileName.getBytes(), "ISO8859-1");
175
+        }
176
+        else if (agent.contains("Chrome"))
177
+        {
178
+            // google浏览器
179
+            filename = URLEncoder.encode(filename, "utf-8");
180
+        }
181
+        else
182
+        {
183
+            // 其它浏览器
184
+            filename = URLEncoder.encode(filename, "utf-8");
185
+        }
186
+        return filename;
187
+    }
188
+
189
+    /**
190
+     * 下载文件名重新编码
191
+     *
192
+     * @param response 响应对象
193
+     * @param realFileName 真实文件名
194
+     * @return
195
+     */
196
+    public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException
197
+    {
198
+        String percentEncodedFileName = percentEncode(realFileName);
199
+
200
+        StringBuilder contentDispositionValue = new StringBuilder();
201
+        contentDispositionValue.append("attachment; filename=")
202
+                .append(percentEncodedFileName)
203
+                .append(";")
204
+                .append("filename*=")
205
+                .append("utf-8''")
206
+                .append(percentEncodedFileName);
207
+        response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename");
208
+        response.setHeader("Content-disposition", contentDispositionValue.toString());
209
+        response.setHeader("download-filename", percentEncodedFileName);
210
+    }
211
+
212
+    /**
213
+     * 百分号编码工具方法
214
+     *
215
+     * @param s 需要百分号编码的字符串
216
+     * @return 百分号编码后的字符串
217
+     */
218
+    public static String percentEncode(String s) throws UnsupportedEncodingException
219
+    {
220
+        String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
221
+        return encode.replaceAll("\\+", "%20");
222
+    }
223
+
224
+    /**
225
+     * 获取图像后缀
226
+     * 
227
+     * @param photoByte 图像数据
228
+     * @return 后缀名
229
+     */
230
+    public static String getFileExtendName(byte[] photoByte)
231
+    {
232
+        String strFileExtendName = "jpg";
233
+        if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56)
234
+                && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97))
235
+        {
236
+            strFileExtendName = "gif";
237
+        }
238
+        else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70))
239
+        {
240
+            strFileExtendName = "jpg";
241
+        }
242
+        else if ((photoByte[0] == 66) && (photoByte[1] == 77))
243
+        {
244
+            strFileExtendName = "bmp";
245
+        }
246
+        else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71))
247
+        {
248
+            strFileExtendName = "png";
249
+        }
250
+        return strFileExtendName;
251
+    }
252
+}

+ 102 - 0
src/main/java/com/lqkj/common/utils/file/ImageUtils.java

@@ -0,0 +1,102 @@
1
+package com.lqkj.common.utils.file;
2
+
3
+import com.lqkj.common.config.LingWeiConfig;
4
+import com.lqkj.common.constant.Constants;
5
+import com.lqkj.common.utils.StringUtils;
6
+import org.apache.poi.util.IOUtils;
7
+import org.slf4j.Logger;
8
+import org.slf4j.LoggerFactory;
9
+
10
+import java.io.ByteArrayInputStream;
11
+import java.io.ByteArrayOutputStream;
12
+import java.io.FileInputStream;
13
+import java.io.InputStream;
14
+import java.net.URL;
15
+import java.net.URLConnection;
16
+import java.util.Arrays;
17
+
18
+/**
19
+ * 图片处理工具类
20
+ *
21
+ * @author lh
22
+ */
23
+public class ImageUtils
24
+{
25
+    private static final Logger log = LoggerFactory.getLogger(ImageUtils.class);
26
+
27
+    public static byte[] getImage(String imagePath)
28
+    {
29
+        InputStream is = getFile(imagePath);
30
+        try
31
+        {
32
+            return IOUtils.toByteArray(is);
33
+        }
34
+        catch (Exception e)
35
+        {
36
+            log.error("图片加载异常 {}", e);
37
+            return null;
38
+        }
39
+        finally
40
+        {
41
+            IOUtils.closeQuietly(is);
42
+        }
43
+    }
44
+
45
+    public static InputStream getFile(String imagePath)
46
+    {
47
+        try
48
+        {
49
+            byte[] result = readFile(imagePath);
50
+            result = Arrays.copyOf(result, result.length);
51
+            return new ByteArrayInputStream(result);
52
+        }
53
+        catch (Exception e)
54
+        {
55
+            log.error("获取图片异常 {}", e);
56
+        }
57
+        return null;
58
+    }
59
+
60
+    /**
61
+     * 读取文件为字节数据
62
+     * 
63
+     * @param url 地址
64
+     * @return 字节数据
65
+     */
66
+    public static byte[] readFile(String url)
67
+    {
68
+        InputStream in = null;
69
+        ByteArrayOutputStream baos = null;
70
+        try
71
+        {
72
+            if (url.startsWith("http"))
73
+            {
74
+                // 网络地址
75
+                URL urlObj = new URL(url);
76
+                URLConnection urlConnection = urlObj.openConnection();
77
+                urlConnection.setConnectTimeout(30 * 1000);
78
+                urlConnection.setReadTimeout(60 * 1000);
79
+                urlConnection.setDoInput(true);
80
+                in = urlConnection.getInputStream();
81
+            }
82
+            else
83
+            {
84
+                // 本机地址
85
+                String localPath = LingWeiConfig.getProfile();
86
+                String downloadPath = localPath + StringUtils.substringAfter(url, Constants.RESOURCE_PREFIX);
87
+                in = new FileInputStream(downloadPath);
88
+            }
89
+            return IOUtils.toByteArray(in);
90
+        }
91
+        catch (Exception e)
92
+        {
93
+            log.error("获取文件路径异常 {}", e);
94
+            return null;
95
+        }
96
+        finally
97
+        {
98
+            IOUtils.closeQuietly(in);
99
+            IOUtils.closeQuietly(baos);
100
+        }
101
+    }
102
+}

+ 59 - 0
src/main/java/com/lqkj/common/utils/file/MimeTypeUtils.java

@@ -0,0 +1,59 @@
1
+package com.lqkj.common.utils.file;
2
+
3
+/**
4
+ * 媒体类型工具类
5
+ * 
6
+ * @author lh
7
+ */
8
+public class MimeTypeUtils
9
+{
10
+    public static final String IMAGE_PNG = "image/png";
11
+
12
+    public static final String IMAGE_JPG = "image/jpg";
13
+
14
+    public static final String IMAGE_JPEG = "image/jpeg";
15
+
16
+    public static final String IMAGE_BMP = "image/bmp";
17
+
18
+    public static final String IMAGE_GIF = "image/gif";
19
+    
20
+    public static final String[] IMAGE_EXTENSION = { "bmp", "gif", "jpg", "jpeg", "png" };
21
+
22
+    public static final String[] FLASH_EXTENSION = { "swf", "flv" };
23
+
24
+    public static final String[] MEDIA_EXTENSION = { "swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg",
25
+            "asf", "rm", "rmvb" };
26
+
27
+    public static final String[] VIDEO_EXTENSION = { "mp4", "avi", "rmvb" };
28
+
29
+    public static final String[] DEFAULT_ALLOWED_EXTENSION = {
30
+            // 图片
31
+            "bmp", "gif", "jpg", "jpeg", "png",
32
+            // word excel powerpoint
33
+            "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
34
+            // 压缩文件
35
+            "rar", "zip", "gz", "bz2",
36
+            // 视频格式
37
+            "mp4", "avi", "rmvb",
38
+            // pdf
39
+            "pdf" };
40
+
41
+    public static String getExtension(String prefix)
42
+    {
43
+        switch (prefix)
44
+        {
45
+            case IMAGE_PNG:
46
+                return "png";
47
+            case IMAGE_JPG:
48
+                return "jpg";
49
+            case IMAGE_JPEG:
50
+                return "jpeg";
51
+            case IMAGE_BMP:
52
+                return "bmp";
53
+            case IMAGE_GIF:
54
+                return "gif";
55
+            default:
56
+                return "";
57
+        }
58
+    }
59
+}

+ 137 - 0
src/main/java/com/lqkj/common/utils/html/EscapeUtil.java

@@ -0,0 +1,137 @@
1
+package com.lqkj.common.utils.html;
2
+
3
+
4
+import org.apache.commons.lang3.StringUtils;
5
+import org.springframework.web.util.HtmlUtils;
6
+
7
+/**
8
+ * 转义和反转义工具类
9
+ *
10
+ * @author lh
11
+ */
12
+public class EscapeUtil {
13
+    public static final String RE_HTML_MARK = "(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)";
14
+
15
+    private static final char[][] TEXT = new char[64][];
16
+
17
+    static {
18
+        for (int i = 0; i < 64; i++) {
19
+            TEXT[i] = new char[]{(char) i};
20
+        }
21
+
22
+        // special HTML characters
23
+        TEXT['\''] = "&#039;".toCharArray(); // 单引号
24
+        TEXT['"'] = "&#34;".toCharArray(); // 双引号
25
+        TEXT['&'] = "&#38;".toCharArray(); // &符
26
+        TEXT['<'] = "&#60;".toCharArray(); // 小于号
27
+        TEXT['>'] = "&#62;".toCharArray(); // 大于号
28
+    }
29
+
30
+    /**
31
+     * 转义文本中的HTML字符为安全的字符
32
+     *
33
+     * @param text 被转义的文本
34
+     * @return 转义后的文本
35
+     */
36
+    public static String escape(String text) {
37
+        return encode(text);
38
+    }
39
+
40
+    /**
41
+     * 还原被转义的HTML特殊字符
42
+     *
43
+     * @param content 包含转义符的HTML内容
44
+     * @return 转换后的字符串
45
+     */
46
+    public static String unescape(String content) {
47
+        return decode(content);
48
+    }
49
+
50
+    /**
51
+     * 清除所有HTML标签,但是不删除标签内的内容
52
+     *
53
+     * @param content 文本
54
+     * @return 清除标签后的文本
55
+     */
56
+    public static String clean(String content) {
57
+        return new HTMLFilter().filter(content);
58
+    }
59
+
60
+    /**
61
+     * Escape编码
62
+     *
63
+     * @param text 被编码的文本
64
+     * @return 编码后的字符
65
+     */
66
+    private static String encode(String text) {
67
+        int len;
68
+        if ((text == null) || ((len = text.length()) == 0)) {
69
+            return StringUtils.EMPTY;
70
+        }
71
+        StringBuilder buffer = new StringBuilder(len + (len >> 2));
72
+        char c;
73
+        for (int i = 0; i < len; i++) {
74
+            c = text.charAt(i);
75
+            if (c < 64) {
76
+                buffer.append(TEXT[c]);
77
+            } else {
78
+                buffer.append(c);
79
+            }
80
+        }
81
+        return buffer.toString();
82
+    }
83
+
84
+    /**
85
+     * Escape解码
86
+     *
87
+     * @param content 被转义的内容
88
+     * @return 解码后的字符串
89
+     */
90
+    public static String decode(String content) {
91
+        if (StringUtils.isEmpty(content)) {
92
+            return content;
93
+        }
94
+
95
+        StringBuilder tmp = new StringBuilder(content.length());
96
+        int lastPos = 0, pos = 0;
97
+        char ch;
98
+        while (lastPos < content.length()) {
99
+            pos = content.indexOf("%", lastPos);
100
+            if (pos == lastPos) {
101
+                if (content.charAt(pos + 1) == 'u') {
102
+                    ch = (char) Integer.parseInt(content.substring(pos + 2, pos + 6), 16);
103
+                    tmp.append(ch);
104
+                    lastPos = pos + 6;
105
+                } else {
106
+                    ch = (char) Integer.parseInt(content.substring(pos + 1, pos + 3), 16);
107
+                    tmp.append(ch);
108
+                    lastPos = pos + 3;
109
+                }
110
+            } else {
111
+                if (pos == -1) {
112
+                    tmp.append(content.substring(lastPos));
113
+                    lastPos = content.length();
114
+                } else {
115
+                    tmp.append(content.substring(lastPos, pos));
116
+                    lastPos = pos;
117
+                }
118
+            }
119
+        }
120
+        return tmp.toString();
121
+    }
122
+
123
+    public static void main(String[] args) {
124
+        String html = "<script>alert(1);</script>";
125
+        // String html = "<scr<script>ipt>alert(\"XSS\")</scr<script>ipt>";
126
+        // String html = "<123";
127
+        // String html = "123>";
128
+        System.out.println(EscapeUtil.clean(html));
129
+        System.out.println(EscapeUtil.escape(html));
130
+        System.out.println(EscapeUtil.unescape(html));
131
+    }
132
+
133
+    public static String escapeHtml(String s) {
134
+        if (s == null) return null;
135
+        return HtmlUtils.htmlUnescape(s);
136
+    }
137
+}

+ 566 - 0
src/main/java/com/lqkj/common/utils/html/HTMLFilter.java

@@ -0,0 +1,566 @@
1
+package com.lqkj.common.utils.html;
2
+
3
+import java.util.*;
4
+import java.util.concurrent.ConcurrentHashMap;
5
+import java.util.concurrent.ConcurrentMap;
6
+import java.util.regex.Matcher;
7
+import java.util.regex.Pattern;
8
+
9
+/**
10
+ * HTML过滤器,用于去除XSS漏洞隐患。
11
+ *
12
+ * @author lh
13
+ */
14
+public final class HTMLFilter
15
+{
16
+    /**
17
+     * regex flag union representing /si modifiers in php
18
+     **/
19
+    private static final int REGEX_FLAGS_SI = Pattern.CASE_INSENSITIVE | Pattern.DOTALL;
20
+    private static final Pattern P_COMMENTS = Pattern.compile("<!--(.*?)-->", Pattern.DOTALL);
21
+    private static final Pattern P_COMMENT = Pattern.compile("^!--(.*)--$", REGEX_FLAGS_SI);
22
+    private static final Pattern P_TAGS = Pattern.compile("<(.*?)>", Pattern.DOTALL);
23
+    private static final Pattern P_END_TAG = Pattern.compile("^/([a-z0-9]+)", REGEX_FLAGS_SI);
24
+    private static final Pattern P_START_TAG = Pattern.compile("^([a-z0-9]+)(.*?)(/?)$", REGEX_FLAGS_SI);
25
+    private static final Pattern P_QUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)=([\"'])(.*?)\\2", REGEX_FLAGS_SI);
26
+    private static final Pattern P_UNQUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)(=)([^\"\\s']+)", REGEX_FLAGS_SI);
27
+    private static final Pattern P_PROTOCOL = Pattern.compile("^([^:]+):", REGEX_FLAGS_SI);
28
+    private static final Pattern P_ENTITY = Pattern.compile("&#(\\d+);?");
29
+    private static final Pattern P_ENTITY_UNICODE = Pattern.compile("&#x([0-9a-f]+);?");
30
+    private static final Pattern P_ENCODE = Pattern.compile("%([0-9a-f]{2});?");
31
+    private static final Pattern P_VALID_ENTITIES = Pattern.compile("&([^&;]*)(?=(;|&|$))");
32
+    private static final Pattern P_VALID_QUOTES = Pattern.compile("(>|^)([^<]+?)(<|$)", Pattern.DOTALL);
33
+    private static final Pattern P_END_ARROW = Pattern.compile("^>");
34
+    private static final Pattern P_BODY_TO_END = Pattern.compile("<([^>]*?)(?=<|$)");
35
+    private static final Pattern P_XML_CONTENT = Pattern.compile("(^|>)([^<]*?)(?=>)");
36
+    private static final Pattern P_STRAY_LEFT_ARROW = Pattern.compile("<([^>]*?)(?=<|$)");
37
+    private static final Pattern P_STRAY_RIGHT_ARROW = Pattern.compile("(^|>)([^<]*?)(?=>)");
38
+    private static final Pattern P_AMP = Pattern.compile("&");
39
+    private static final Pattern P_QUOTE = Pattern.compile("\"");
40
+    private static final Pattern P_LEFT_ARROW = Pattern.compile("<");
41
+    private static final Pattern P_RIGHT_ARROW = Pattern.compile(">");
42
+    private static final Pattern P_BOTH_ARROWS = Pattern.compile("<>");
43
+
44
+    // @xxx could grow large... maybe use sesat's ReferenceMap
45
+    private static final ConcurrentMap<String, Pattern> P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap<>();
46
+    private static final ConcurrentMap<String, Pattern> P_REMOVE_SELF_BLANKS = new ConcurrentHashMap<>();
47
+
48
+    /**
49
+     * set of allowed html elements, along with allowed attributes for each element
50
+     **/
51
+    private final Map<String, List<String>> vAllowed;
52
+    /**
53
+     * counts of open tags for each (allowable) html element
54
+     **/
55
+    private final Map<String, Integer> vTagCounts = new HashMap<>();
56
+
57
+    /**
58
+     * html elements which must always be self-closing (e.g. "<img />")
59
+     **/
60
+    private final String[] vSelfClosingTags;
61
+    /**
62
+     * html elements which must always have separate opening and closing tags (e.g. "<b></b>")
63
+     **/
64
+    private final String[] vNeedClosingTags;
65
+    /**
66
+     * set of disallowed html elements
67
+     **/
68
+    private final String[] vDisallowed;
69
+    /**
70
+     * attributes which should be checked for valid protocols
71
+     **/
72
+    private final String[] vProtocolAtts;
73
+    /**
74
+     * allowed protocols
75
+     **/
76
+    private final String[] vAllowedProtocols;
77
+    /**
78
+     * tags which should be removed if they contain no content (e.g. "<b></b>" or "<b />")
79
+     **/
80
+    private final String[] vRemoveBlanks;
81
+    /**
82
+     * entities allowed within html markup
83
+     **/
84
+    private final String[] vAllowedEntities;
85
+    /**
86
+     * flag determining whether comments are allowed in input String.
87
+     */
88
+    private final boolean stripComment;
89
+    private final boolean encodeQuotes;
90
+    /**
91
+     * flag determining whether to try to make tags when presented with "unbalanced" angle brackets (e.g. "<b text </b>"
92
+     * becomes "<b> text </b>"). If set to false, unbalanced angle brackets will be html escaped.
93
+     */
94
+    private final boolean alwaysMakeTags;
95
+
96
+    /**
97
+     * Default constructor.
98
+     */
99
+    public HTMLFilter()
100
+    {
101
+        vAllowed = new HashMap<>();
102
+
103
+        final ArrayList<String> a_atts = new ArrayList<>();
104
+        a_atts.add("href");
105
+        a_atts.add("target");
106
+        vAllowed.put("a", a_atts);
107
+
108
+        final ArrayList<String> img_atts = new ArrayList<>();
109
+        img_atts.add("src");
110
+        img_atts.add("width");
111
+        img_atts.add("height");
112
+        img_atts.add("alt");
113
+        vAllowed.put("img", img_atts);
114
+
115
+        final ArrayList<String> no_atts = new ArrayList<>();
116
+        vAllowed.put("b", no_atts);
117
+        vAllowed.put("strong", no_atts);
118
+        vAllowed.put("i", no_atts);
119
+        vAllowed.put("em", no_atts);
120
+
121
+        vSelfClosingTags = new String[] { "img" };
122
+        vNeedClosingTags = new String[] { "a", "b", "strong", "i", "em" };
123
+        vDisallowed = new String[] {};
124
+        vAllowedProtocols = new String[] { "http", "mailto", "https" }; // no ftp.
125
+        vProtocolAtts = new String[] { "src", "href" };
126
+        vRemoveBlanks = new String[] { "a", "b", "strong", "i", "em" };
127
+        vAllowedEntities = new String[] { "amp", "gt", "lt", "quot" };
128
+        stripComment = true;
129
+        encodeQuotes = true;
130
+        alwaysMakeTags = false;
131
+    }
132
+
133
+    /**
134
+     * Map-parameter configurable constructor.
135
+     *
136
+     * @param conf map containing configuration. keys match field names.
137
+     */
138
+    @SuppressWarnings("unchecked")
139
+    public HTMLFilter(final Map<String, Object> conf)
140
+    {
141
+
142
+        assert conf.containsKey("vAllowed") : "configuration requires vAllowed";
143
+        assert conf.containsKey("vSelfClosingTags") : "configuration requires vSelfClosingTags";
144
+        assert conf.containsKey("vNeedClosingTags") : "configuration requires vNeedClosingTags";
145
+        assert conf.containsKey("vDisallowed") : "configuration requires vDisallowed";
146
+        assert conf.containsKey("vAllowedProtocols") : "configuration requires vAllowedProtocols";
147
+        assert conf.containsKey("vProtocolAtts") : "configuration requires vProtocolAtts";
148
+        assert conf.containsKey("vRemoveBlanks") : "configuration requires vRemoveBlanks";
149
+        assert conf.containsKey("vAllowedEntities") : "configuration requires vAllowedEntities";
150
+
151
+        vAllowed = Collections.unmodifiableMap((HashMap<String, List<String>>) conf.get("vAllowed"));
152
+        vSelfClosingTags = (String[]) conf.get("vSelfClosingTags");
153
+        vNeedClosingTags = (String[]) conf.get("vNeedClosingTags");
154
+        vDisallowed = (String[]) conf.get("vDisallowed");
155
+        vAllowedProtocols = (String[]) conf.get("vAllowedProtocols");
156
+        vProtocolAtts = (String[]) conf.get("vProtocolAtts");
157
+        vRemoveBlanks = (String[]) conf.get("vRemoveBlanks");
158
+        vAllowedEntities = (String[]) conf.get("vAllowedEntities");
159
+        stripComment = conf.containsKey("stripComment") ? (Boolean) conf.get("stripComment") : true;
160
+        encodeQuotes = conf.containsKey("encodeQuotes") ? (Boolean) conf.get("encodeQuotes") : true;
161
+        alwaysMakeTags = conf.containsKey("alwaysMakeTags") ? (Boolean) conf.get("alwaysMakeTags") : true;
162
+    }
163
+
164
+    private void reset()
165
+    {
166
+        vTagCounts.clear();
167
+    }
168
+
169
+    // ---------------------------------------------------------------
170
+    // my versions of some PHP library functions
171
+    public static String chr(final int decimal)
172
+    {
173
+        return String.valueOf((char) decimal);
174
+    }
175
+
176
+    public static String htmlSpecialChars(final String s)
177
+    {
178
+        String result = s;
179
+        result = regexReplace(P_AMP, "&amp;", result);
180
+        result = regexReplace(P_QUOTE, "&quot;", result);
181
+        result = regexReplace(P_LEFT_ARROW, "&lt;", result);
182
+        result = regexReplace(P_RIGHT_ARROW, "&gt;", result);
183
+        return result;
184
+    }
185
+
186
+    // ---------------------------------------------------------------
187
+
188
+    /**
189
+     * given a user submitted input String, filter out any invalid or restricted html.
190
+     *
191
+     * @param input text (i.e. submitted by a user) than may contain html
192
+     * @return "clean" version of input, with only valid, whitelisted html elements allowed
193
+     */
194
+    public String filter(final String input)
195
+    {
196
+        reset();
197
+        String s = input;
198
+
199
+        s = escapeComments(s);
200
+
201
+        s = balanceHTML(s);
202
+
203
+        s = checkTags(s);
204
+
205
+        s = processRemoveBlanks(s);
206
+
207
+        // s = validateEntities(s);
208
+
209
+        return s;
210
+    }
211
+
212
+    public boolean isAlwaysMakeTags()
213
+    {
214
+        return alwaysMakeTags;
215
+    }
216
+
217
+    public boolean isStripComments()
218
+    {
219
+        return stripComment;
220
+    }
221
+
222
+    private String escapeComments(final String s)
223
+    {
224
+        final Matcher m = P_COMMENTS.matcher(s);
225
+        final StringBuffer buf = new StringBuffer();
226
+        if (m.find())
227
+        {
228
+            final String match = m.group(1); // (.*?)
229
+            m.appendReplacement(buf, Matcher.quoteReplacement("<!--" + htmlSpecialChars(match) + "-->"));
230
+        }
231
+        m.appendTail(buf);
232
+
233
+        return buf.toString();
234
+    }
235
+
236
+    private String balanceHTML(String s)
237
+    {
238
+        if (alwaysMakeTags)
239
+        {
240
+            //
241
+            // try and form html
242
+            //
243
+            s = regexReplace(P_END_ARROW, "", s);
244
+            // 不追加结束标签
245
+            s = regexReplace(P_BODY_TO_END, "<$1>", s);
246
+            s = regexReplace(P_XML_CONTENT, "$1<$2", s);
247
+
248
+        }
249
+        else
250
+        {
251
+            //
252
+            // escape stray brackets
253
+            //
254
+            s = regexReplace(P_STRAY_LEFT_ARROW, "&lt;$1", s);
255
+            s = regexReplace(P_STRAY_RIGHT_ARROW, "$1$2&gt;<", s);
256
+
257
+            //
258
+            // the last regexp causes '<>' entities to appear
259
+            // (we need to do a lookahead assertion so that the last bracket can
260
+            // be used in the next pass of the regexp)
261
+            //
262
+            s = regexReplace(P_BOTH_ARROWS, "", s);
263
+        }
264
+
265
+        return s;
266
+    }
267
+
268
+    private String checkTags(String s)
269
+    {
270
+        Matcher m = P_TAGS.matcher(s);
271
+
272
+        final StringBuffer buf = new StringBuffer();
273
+        while (m.find())
274
+        {
275
+            String replaceStr = m.group(1);
276
+            replaceStr = processTag(replaceStr);
277
+            m.appendReplacement(buf, Matcher.quoteReplacement(replaceStr));
278
+        }
279
+        m.appendTail(buf);
280
+
281
+        // these get tallied in processTag
282
+        // (remember to reset before subsequent calls to filter method)
283
+        final StringBuilder sBuilder = new StringBuilder(buf.toString());
284
+        for (String key : vTagCounts.keySet())
285
+        {
286
+            for (int ii = 0; ii < vTagCounts.get(key); ii++)
287
+            {
288
+                sBuilder.append("</").append(key).append(">");
289
+            }
290
+        }
291
+        s = sBuilder.toString();
292
+
293
+        return s;
294
+    }
295
+
296
+    private String processRemoveBlanks(final String s)
297
+    {
298
+        String result = s;
299
+        for (String tag : vRemoveBlanks)
300
+        {
301
+            if (!P_REMOVE_PAIR_BLANKS.containsKey(tag))
302
+            {
303
+                P_REMOVE_PAIR_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?></" + tag + ">"));
304
+            }
305
+            result = regexReplace(P_REMOVE_PAIR_BLANKS.get(tag), "", result);
306
+            if (!P_REMOVE_SELF_BLANKS.containsKey(tag))
307
+            {
308
+                P_REMOVE_SELF_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?/>"));
309
+            }
310
+            result = regexReplace(P_REMOVE_SELF_BLANKS.get(tag), "", result);
311
+        }
312
+
313
+        return result;
314
+    }
315
+
316
+    private static String regexReplace(final Pattern regex_pattern, final String replacement, final String s)
317
+    {
318
+        Matcher m = regex_pattern.matcher(s);
319
+        return m.replaceAll(replacement);
320
+    }
321
+
322
+    private String processTag(final String s)
323
+    {
324
+        // ending tags
325
+        Matcher m = P_END_TAG.matcher(s);
326
+        if (m.find())
327
+        {
328
+            final String name = m.group(1).toLowerCase();
329
+            if (allowed(name))
330
+            {
331
+                if (false == inArray(name, vSelfClosingTags))
332
+                {
333
+                    if (vTagCounts.containsKey(name))
334
+                    {
335
+                        vTagCounts.put(name, vTagCounts.get(name) - 1);
336
+                        return "</" + name + ">";
337
+                    }
338
+                }
339
+            }
340
+        }
341
+
342
+        // starting tags
343
+        m = P_START_TAG.matcher(s);
344
+        if (m.find())
345
+        {
346
+            final String name = m.group(1).toLowerCase();
347
+            final String body = m.group(2);
348
+            String ending = m.group(3);
349
+
350
+            // debug( "in a starting tag, name='" + name + "'; body='" + body + "'; ending='" + ending + "'" );
351
+            if (allowed(name))
352
+            {
353
+                final StringBuilder params = new StringBuilder();
354
+
355
+                final Matcher m2 = P_QUOTED_ATTRIBUTES.matcher(body);
356
+                final Matcher m3 = P_UNQUOTED_ATTRIBUTES.matcher(body);
357
+                final List<String> paramNames = new ArrayList<>();
358
+                final List<String> paramValues = new ArrayList<>();
359
+                while (m2.find())
360
+                {
361
+                    paramNames.add(m2.group(1)); // ([a-z0-9]+)
362
+                    paramValues.add(m2.group(3)); // (.*?)
363
+                }
364
+                while (m3.find())
365
+                {
366
+                    paramNames.add(m3.group(1)); // ([a-z0-9]+)
367
+                    paramValues.add(m3.group(3)); // ([^\"\\s']+)
368
+                }
369
+
370
+                String paramName, paramValue;
371
+                for (int ii = 0; ii < paramNames.size(); ii++)
372
+                {
373
+                    paramName = paramNames.get(ii).toLowerCase();
374
+                    paramValue = paramValues.get(ii);
375
+
376
+                    // debug( "paramName='" + paramName + "'" );
377
+                    // debug( "paramValue='" + paramValue + "'" );
378
+                    // debug( "allowed? " + vAllowed.get( name ).contains( paramName ) );
379
+
380
+                    if (allowedAttribute(name, paramName))
381
+                    {
382
+                        if (inArray(paramName, vProtocolAtts))
383
+                        {
384
+                            paramValue = processParamProtocol(paramValue);
385
+                        }
386
+                        params.append(' ').append(paramName).append("=\\\"").append(paramValue).append("\"");
387
+                    }
388
+                }
389
+
390
+                if (inArray(name, vSelfClosingTags))
391
+                {
392
+                    ending = " /";
393
+                }
394
+
395
+                if (inArray(name, vNeedClosingTags))
396
+                {
397
+                    ending = "";
398
+                }
399
+
400
+                if (ending == null || ending.length() < 1)
401
+                {
402
+                    if (vTagCounts.containsKey(name))
403
+                    {
404
+                        vTagCounts.put(name, vTagCounts.get(name) + 1);
405
+                    }
406
+                    else
407
+                    {
408
+                        vTagCounts.put(name, 1);
409
+                    }
410
+                }
411
+                else
412
+                {
413
+                    ending = " /";
414
+                }
415
+                return "<" + name + params + ending + ">";
416
+            }
417
+            else
418
+            {
419
+                return "";
420
+            }
421
+        }
422
+
423
+        // comments
424
+        m = P_COMMENT.matcher(s);
425
+        if (!stripComment && m.find())
426
+        {
427
+            return "<" + m.group() + ">";
428
+        }
429
+
430
+        return "";
431
+    }
432
+
433
+    private String processParamProtocol(String s)
434
+    {
435
+        s = decodeEntities(s);
436
+        final Matcher m = P_PROTOCOL.matcher(s);
437
+        if (m.find())
438
+        {
439
+            final String protocol = m.group(1);
440
+            if (!inArray(protocol, vAllowedProtocols))
441
+            {
442
+                // bad protocol, turn into local anchor link instead
443
+                s = "#" + s.substring(protocol.length() + 1);
444
+                if (s.startsWith("#//"))
445
+                {
446
+                    s = "#" + s.substring(3);
447
+                }
448
+            }
449
+        }
450
+
451
+        return s;
452
+    }
453
+
454
+    private String decodeEntities(String s)
455
+    {
456
+        StringBuffer buf = new StringBuffer();
457
+
458
+        Matcher m = P_ENTITY.matcher(s);
459
+        while (m.find())
460
+        {
461
+            final String match = m.group(1);
462
+            final int decimal = Integer.decode(match).intValue();
463
+            m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));
464
+        }
465
+        m.appendTail(buf);
466
+        s = buf.toString();
467
+
468
+        buf = new StringBuffer();
469
+        m = P_ENTITY_UNICODE.matcher(s);
470
+        while (m.find())
471
+        {
472
+            final String match = m.group(1);
473
+            final int decimal = Integer.valueOf(match, 16).intValue();
474
+            m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));
475
+        }
476
+        m.appendTail(buf);
477
+        s = buf.toString();
478
+
479
+        buf = new StringBuffer();
480
+        m = P_ENCODE.matcher(s);
481
+        while (m.find())
482
+        {
483
+            final String match = m.group(1);
484
+            final int decimal = Integer.valueOf(match, 16).intValue();
485
+            m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));
486
+        }
487
+        m.appendTail(buf);
488
+        s = buf.toString();
489
+
490
+        s = validateEntities(s);
491
+        return s;
492
+    }
493
+
494
+    private String validateEntities(final String s)
495
+    {
496
+        StringBuffer buf = new StringBuffer();
497
+
498
+        // validate entities throughout the string
499
+        Matcher m = P_VALID_ENTITIES.matcher(s);
500
+        while (m.find())
501
+        {
502
+            final String one = m.group(1); // ([^&;]*)
503
+            final String two = m.group(2); // (?=(;|&|$))
504
+            m.appendReplacement(buf, Matcher.quoteReplacement(checkEntity(one, two)));
505
+        }
506
+        m.appendTail(buf);
507
+
508
+        return encodeQuotes(buf.toString());
509
+    }
510
+
511
+    private String encodeQuotes(final String s)
512
+    {
513
+        if (encodeQuotes)
514
+        {
515
+            StringBuffer buf = new StringBuffer();
516
+            Matcher m = P_VALID_QUOTES.matcher(s);
517
+            while (m.find())
518
+            {
519
+                final String one = m.group(1); // (>|^)
520
+                final String two = m.group(2); // ([^<]+?)
521
+                final String three = m.group(3); // (<|$)
522
+                // 不替换双引号为&quot;,防止json格式无效 regexReplace(P_QUOTE, "&quot;", two)
523
+                m.appendReplacement(buf, Matcher.quoteReplacement(one + two + three));
524
+            }
525
+            m.appendTail(buf);
526
+            return buf.toString();
527
+        }
528
+        else
529
+        {
530
+            return s;
531
+        }
532
+    }
533
+
534
+    private String checkEntity(final String preamble, final String term)
535
+    {
536
+
537
+        return ";".equals(term) && isValidEntity(preamble) ? '&' + preamble : "&amp;" + preamble;
538
+    }
539
+
540
+    private boolean isValidEntity(final String entity)
541
+    {
542
+        return inArray(entity, vAllowedEntities);
543
+    }
544
+
545
+    private static boolean inArray(final String s, final String[] array)
546
+    {
547
+        for (String item : array)
548
+        {
549
+            if (item != null && item.equals(s))
550
+            {
551
+                return true;
552
+            }
553
+        }
554
+        return false;
555
+    }
556
+
557
+    private boolean allowed(final String name)
558
+    {
559
+        return (vAllowed.isEmpty() || vAllowed.containsKey(name)) && !inArray(name, vDisallowed);
560
+    }
561
+
562
+    private boolean allowedAttribute(final String name, final String paramName)
563
+    {
564
+        return allowed(name) && (vAllowed.isEmpty() || vAllowed.get(name).contains(paramName));
565
+    }
566
+}

+ 56 - 0
src/main/java/com/lqkj/common/utils/http/HttpHelper.java

@@ -0,0 +1,56 @@
1
+package com.lqkj.common.utils.http;
2
+
3
+import org.apache.commons.lang3.exception.ExceptionUtils;
4
+import org.slf4j.Logger;
5
+import org.slf4j.LoggerFactory;
6
+
7
+import javax.servlet.ServletRequest;
8
+import java.io.BufferedReader;
9
+import java.io.IOException;
10
+import java.io.InputStream;
11
+import java.io.InputStreamReader;
12
+import java.nio.charset.Charset;
13
+
14
+/**
15
+ * 通用http工具封装
16
+ * 
17
+ * @author lh
18
+ */
19
+public class HttpHelper
20
+{
21
+    private static final Logger LOGGER = LoggerFactory.getLogger(HttpHelper.class);
22
+
23
+    public static String getBodyString(ServletRequest request)
24
+    {
25
+        StringBuilder sb = new StringBuilder();
26
+        BufferedReader reader = null;
27
+        try (InputStream inputStream = request.getInputStream())
28
+        {
29
+            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
30
+            String line = "";
31
+            while ((line = reader.readLine()) != null)
32
+            {
33
+                sb.append(line);
34
+            }
35
+        }
36
+        catch (IOException e)
37
+        {
38
+            LOGGER.warn("getBodyString出现问题!");
39
+        }
40
+        finally
41
+        {
42
+            if (reader != null)
43
+            {
44
+                try
45
+                {
46
+                    reader.close();
47
+                }
48
+                catch (IOException e)
49
+                {
50
+                    LOGGER.error(ExceptionUtils.getMessage(e));
51
+                }
52
+            }
53
+        }
54
+        return sb.toString();
55
+    }
56
+}

+ 279 - 0
src/main/java/com/lqkj/common/utils/http/HttpUtils.java

@@ -0,0 +1,279 @@
1
+package com.lqkj.common.utils.http;
2
+
3
+
4
+import com.lqkj.common.constant.Constants;
5
+import com.lqkj.common.utils.StringUtils;
6
+import org.slf4j.Logger;
7
+import org.slf4j.LoggerFactory;
8
+
9
+import javax.net.ssl.*;
10
+import java.io.*;
11
+import java.net.ConnectException;
12
+import java.net.SocketTimeoutException;
13
+import java.net.URL;
14
+import java.net.URLConnection;
15
+import java.security.cert.X509Certificate;
16
+
17
+/**
18
+ * 通用http发送方法
19
+ * 
20
+ * @author lh
21
+ */
22
+public class HttpUtils
23
+{
24
+    private static final Logger log = LoggerFactory.getLogger(HttpUtils.class);
25
+
26
+    /**
27
+     * 向指定 URL 发送GET方法的请求
28
+     *
29
+     * @param url 发送请求的 URL
30
+     * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
31
+     * @return 所代表远程资源的响应结果
32
+     */
33
+    public static String sendGet(String url, String param)
34
+    {
35
+        return sendGet(url, param, Constants.UTF8);
36
+    }
37
+
38
+    public static String sendGetByToken(String url, String param, String token){
39
+        return sendGet(url, param, Constants.UTF8, token);
40
+    }
41
+
42
+    public static String sendGet(String url, String param, String contentType){
43
+        return sendGet(url, param, contentType, null);
44
+    }
45
+    /**
46
+     * 向指定 URL 发送GET方法的请求
47
+     *
48
+     * @param url 发送请求的 URL
49
+     * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
50
+     * @param contentType 编码类型
51
+     * @return 所代表远程资源的响应结果
52
+     */
53
+    public static String sendGet(String url, String param, String contentType, String token)
54
+    {
55
+        StringBuilder result = new StringBuilder();
56
+        BufferedReader in = null;
57
+        try
58
+        {
59
+            String urlNameString = StringUtils.isNotBlank(param) ? url + "?" + param : url;
60
+            log.info("sendGet - {}", urlNameString);
61
+            URL realUrl = new URL(urlNameString);
62
+            URLConnection connection = realUrl.openConnection();
63
+            connection.setRequestProperty("accept", "*/*");
64
+            connection.setRequestProperty("connection", "Keep-Alive");
65
+            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
66
+            if (StringUtils.isNotEmpty(token)){
67
+                connection.setRequestProperty("Authorization", token);
68
+            }
69
+            connection.connect();
70
+            in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType));
71
+            String line;
72
+            while ((line = in.readLine()) != null)
73
+            {
74
+                result.append(line);
75
+            }
76
+            log.info("recv - {}", result);
77
+        }
78
+        catch (ConnectException e)
79
+        {
80
+            log.error("调用HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e);
81
+        }
82
+        catch (SocketTimeoutException e)
83
+        {
84
+            log.error("调用HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e);
85
+        }
86
+        catch (IOException e)
87
+        {
88
+            log.error("调用HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e);
89
+        }
90
+        catch (Exception e)
91
+        {
92
+            log.error("调用HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e);
93
+        }
94
+        finally
95
+        {
96
+            try
97
+            {
98
+                if (in != null)
99
+                {
100
+                    in.close();
101
+                }
102
+            }
103
+            catch (Exception ex)
104
+            {
105
+                log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
106
+            }
107
+        }
108
+        return result.toString();
109
+    }
110
+
111
+
112
+    public static String sendPost(String url, String param){
113
+        return sendPost(url, param, null);
114
+    }
115
+    /**
116
+     * 向指定 URL 发送POST方法的请求
117
+     *
118
+     * @param url 发送请求的 URL
119
+     * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
120
+     * @return 所代表远程资源的响应结果
121
+     */
122
+    public static String sendPost(String url, String param, String token)
123
+    {
124
+        PrintWriter out = null;
125
+        BufferedReader in = null;
126
+        StringBuilder result = new StringBuilder();
127
+        try
128
+        {
129
+            String urlNameString = url;
130
+            log.info("sendPost - {}", urlNameString);
131
+            URL realUrl = new URL(urlNameString);
132
+            URLConnection conn = realUrl.openConnection();
133
+            conn.setRequestProperty("accept", "*/*");
134
+            conn.setRequestProperty("connection", "Keep-Alive");
135
+            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
136
+            conn.setRequestProperty("Accept-Charset", "utf-8");
137
+            conn.setRequestProperty("contentType", "utf-8");
138
+            if (StringUtils.isNotEmpty(token)){
139
+                conn.setRequestProperty("Authorization", token);
140
+            }
141
+            conn.setDoOutput(true);
142
+            conn.setDoInput(true);
143
+            out = new PrintWriter(conn.getOutputStream());
144
+            out.print(param);
145
+            out.flush();
146
+            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
147
+            String line;
148
+            while ((line = in.readLine()) != null)
149
+            {
150
+                result.append(line);
151
+            }
152
+            log.info("recv - {}", result);
153
+        }
154
+        catch (ConnectException e)
155
+        {
156
+            log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e);
157
+        }
158
+        catch (SocketTimeoutException e)
159
+        {
160
+            log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e);
161
+        }
162
+        catch (IOException e)
163
+        {
164
+            log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e);
165
+        }
166
+        catch (Exception e)
167
+        {
168
+            log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e);
169
+        }
170
+        finally
171
+        {
172
+            try
173
+            {
174
+                if (out != null)
175
+                {
176
+                    out.close();
177
+                }
178
+                if (in != null)
179
+                {
180
+                    in.close();
181
+                }
182
+            }
183
+            catch (IOException ex)
184
+            {
185
+                log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
186
+            }
187
+        }
188
+        return result.toString();
189
+    }
190
+    public static String sendSSLPost(String url, String param){
191
+        return sendSSLPost(url, param, null);
192
+    }
193
+    public static String sendSSLPost(String url, String param, String token)
194
+    {
195
+        StringBuilder result = new StringBuilder();
196
+        String urlNameString = url + "?" + param;
197
+        try
198
+        {
199
+            log.info("sendSSLPost - {}", urlNameString);
200
+            SSLContext sc = SSLContext.getInstance("SSL");
201
+            sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom());
202
+            URL console = new URL(urlNameString);
203
+            HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
204
+            conn.setRequestProperty("accept", "*/*");
205
+            if (StringUtils.isNotEmpty(token)){
206
+                conn.setRequestProperty("Authorization", token);
207
+            }
208
+            conn.setRequestProperty("connection", "Keep-Alive");
209
+            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
210
+            conn.setRequestProperty("Accept-Charset", "utf-8");
211
+            conn.setRequestProperty("contentType", "utf-8");
212
+
213
+            conn.setDoOutput(true);
214
+            conn.setDoInput(true);
215
+
216
+            conn.setSSLSocketFactory(sc.getSocketFactory());
217
+            conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
218
+            conn.connect();
219
+            InputStream is = conn.getInputStream();
220
+            BufferedReader br = new BufferedReader(new InputStreamReader(is));
221
+            String ret = "";
222
+            while ((ret = br.readLine()) != null)
223
+            {
224
+                if (ret != null && !"".equals(ret.trim()))
225
+                {
226
+                    result.append(new String(ret.getBytes("ISO-8859-1"), "utf-8"));
227
+                }
228
+            }
229
+            log.info("recv - {}", result);
230
+            conn.disconnect();
231
+            br.close();
232
+        }
233
+        catch (ConnectException e)
234
+        {
235
+            log.error("调用HttpUtils.sendSSLPost ConnectException, url=" + url + ",param=" + param, e);
236
+        }
237
+        catch (SocketTimeoutException e)
238
+        {
239
+            log.error("调用HttpUtils.sendSSLPost SocketTimeoutException, url=" + url + ",param=" + param, e);
240
+        }
241
+        catch (IOException e)
242
+        {
243
+            log.error("调用HttpUtils.sendSSLPost IOException, url=" + url + ",param=" + param, e);
244
+        }
245
+        catch (Exception e)
246
+        {
247
+            log.error("调用HttpsUtil.sendSSLPost Exception, url=" + url + ",param=" + param, e);
248
+        }
249
+        return result.toString();
250
+    }
251
+
252
+    private static class TrustAnyTrustManager implements X509TrustManager
253
+    {
254
+        @Override
255
+        public void checkClientTrusted(X509Certificate[] chain, String authType)
256
+        {
257
+        }
258
+
259
+        @Override
260
+        public void checkServerTrusted(X509Certificate[] chain, String authType)
261
+        {
262
+        }
263
+
264
+        @Override
265
+        public X509Certificate[] getAcceptedIssuers()
266
+        {
267
+            return new X509Certificate[] {};
268
+        }
269
+    }
270
+
271
+    private static class TrustAnyHostnameVerifier implements HostnameVerifier
272
+    {
273
+        @Override
274
+        public boolean verify(String hostname, SSLSession session)
275
+        {
276
+            return true;
277
+        }
278
+    }
279
+}

+ 60 - 0
src/main/java/com/lqkj/common/utils/ip/AddressUtils.java

@@ -0,0 +1,60 @@
1
+package com.lqkj.common.utils.ip;
2
+
3
+
4
+import com.fasterxml.jackson.databind.JsonNode;
5
+import com.fasterxml.jackson.databind.ObjectMapper;
6
+import com.lqkj.common.config.LingWeiConfig;
7
+import com.lqkj.common.constant.Constants;
8
+import com.lqkj.common.utils.StringUtils;
9
+import com.lqkj.common.utils.http.HttpUtils;
10
+import org.slf4j.Logger;
11
+import org.slf4j.LoggerFactory;
12
+
13
+/**
14
+ * 获取地址类
15
+ * 
16
+ * @author lh
17
+ */
18
+public class AddressUtils
19
+{
20
+    private static final Logger log = LoggerFactory.getLogger(AddressUtils.class);
21
+
22
+    // IP地址查询
23
+    public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp";
24
+
25
+    // 未知地址
26
+    public static final String UNKNOWN = "XX XX";
27
+
28
+    public static String getRealAddressByIP(String ip)
29
+    {
30
+        String address = UNKNOWN;
31
+        // 内网不查询
32
+        if (IpUtils.internalIp(ip))
33
+        {
34
+            return "内网IP";
35
+        }
36
+        if (LingWeiConfig.isAddressEnabled())
37
+        {
38
+            try
39
+            {
40
+                String rspStr = HttpUtils.sendGet(IP_URL, "ip=" + ip + "&json=true", Constants.GBK);
41
+                if (StringUtils.isEmpty(rspStr))
42
+                {
43
+                    log.error("获取地理位置异常 {}", ip);
44
+                    return UNKNOWN;
45
+                }
46
+
47
+                ObjectMapper mapper = new ObjectMapper();
48
+                JsonNode obj = mapper.readTree(rspStr);
49
+                String region = obj.get("pro").asText();
50
+                String city = obj.get("city").asText();
51
+                return String.format("%s %s", region, city);
52
+            }
53
+            catch (Exception e)
54
+            {
55
+                log.error("获取地理位置异常 {}", ip);
56
+            }
57
+        }
58
+        return address;
59
+    }
60
+}

+ 197 - 0
src/main/java/com/lqkj/common/utils/ip/IpUtils.java

@@ -0,0 +1,197 @@
1
+package com.lqkj.common.utils.ip;
2
+
3
+
4
+import com.lqkj.common.utils.StringUtils;
5
+import com.lqkj.common.utils.html.EscapeUtil;
6
+
7
+import javax.servlet.http.HttpServletRequest;
8
+import java.net.InetAddress;
9
+import java.net.UnknownHostException;
10
+
11
+/**
12
+ * 获取IP方法
13
+ * 
14
+ * @author lh
15
+ */
16
+public class IpUtils
17
+{
18
+    public static String getIpAddr(HttpServletRequest request)
19
+    {
20
+        if (request == null)
21
+        {
22
+            return "unknown";
23
+        }
24
+        String ip = request.getHeader("x-forwarded-for");
25
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
26
+        {
27
+            ip = request.getHeader("Proxy-Client-IP");
28
+        }
29
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
30
+        {
31
+            ip = request.getHeader("X-Forwarded-For");
32
+        }
33
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
34
+        {
35
+            ip = request.getHeader("WL-Proxy-Client-IP");
36
+        }
37
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
38
+        {
39
+            ip = request.getHeader("X-Real-IP");
40
+        }
41
+
42
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
43
+        {
44
+            ip = request.getRemoteAddr();
45
+        }
46
+        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : EscapeUtil.clean(ip);
47
+    }
48
+
49
+    public static boolean internalIp(String ip)
50
+    {
51
+        byte[] addr = textToNumericFormatV4(ip);
52
+        return internalIp(addr) || "127.0.0.1".equals(ip);
53
+    }
54
+
55
+    private static boolean internalIp(byte[] addr)
56
+    {
57
+        if (StringUtils.isNull(addr) || addr.length < 2)
58
+        {
59
+            return true;
60
+        }
61
+        final byte b0 = addr[0];
62
+        final byte b1 = addr[1];
63
+        // 10.x.x.x/8
64
+        final byte SECTION_1 = 0x0A;
65
+        // 172.16.x.x/12
66
+        final byte SECTION_2 = (byte) 0xAC;
67
+        final byte SECTION_3 = (byte) 0x10;
68
+        final byte SECTION_4 = (byte) 0x1F;
69
+        // 192.168.x.x/16
70
+        final byte SECTION_5 = (byte) 0xC0;
71
+        final byte SECTION_6 = (byte) 0xA8;
72
+        switch (b0)
73
+        {
74
+            case SECTION_1:
75
+                return true;
76
+            case SECTION_2:
77
+                if (b1 >= SECTION_3 && b1 <= SECTION_4)
78
+                {
79
+                    return true;
80
+                }
81
+            case SECTION_5:
82
+                switch (b1)
83
+                {
84
+                    case SECTION_6:
85
+                        return true;
86
+                }
87
+            default:
88
+                return false;
89
+        }
90
+    }
91
+
92
+    /**
93
+     * 将IPv4地址转换成字节
94
+     * 
95
+     * @param text IPv4地址
96
+     * @return byte 字节
97
+     */
98
+    public static byte[] textToNumericFormatV4(String text)
99
+    {
100
+        if (text.length() == 0)
101
+        {
102
+            return null;
103
+        }
104
+
105
+        byte[] bytes = new byte[4];
106
+        String[] elements = text.split("\\.", -1);
107
+        try
108
+        {
109
+            long l;
110
+            int i;
111
+            switch (elements.length)
112
+            {
113
+                case 1:
114
+                    l = Long.parseLong(elements[0]);
115
+                    if ((l < 0L) || (l > 4294967295L)) {
116
+                        return null;
117
+                    }
118
+                    bytes[0] = (byte) (int) (l >> 24 & 0xFF);
119
+                    bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
120
+                    bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
121
+                    bytes[3] = (byte) (int) (l & 0xFF);
122
+                    break;
123
+                case 2:
124
+                    l = Integer.parseInt(elements[0]);
125
+                    if ((l < 0L) || (l > 255L)) {
126
+                        return null;
127
+                    }
128
+                    bytes[0] = (byte) (int) (l & 0xFF);
129
+                    l = Integer.parseInt(elements[1]);
130
+                    if ((l < 0L) || (l > 16777215L)) {
131
+                        return null;
132
+                    }
133
+                    bytes[1] = (byte) (int) (l >> 16 & 0xFF);
134
+                    bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
135
+                    bytes[3] = (byte) (int) (l & 0xFF);
136
+                    break;
137
+                case 3:
138
+                    for (i = 0; i < 2; ++i)
139
+                    {
140
+                        l = Integer.parseInt(elements[i]);
141
+                        if ((l < 0L) || (l > 255L)) {
142
+                            return null;
143
+                        }
144
+                        bytes[i] = (byte) (int) (l & 0xFF);
145
+                    }
146
+                    l = Integer.parseInt(elements[2]);
147
+                    if ((l < 0L) || (l > 65535L)) {
148
+                        return null;
149
+                    }
150
+                    bytes[2] = (byte) (int) (l >> 8 & 0xFF);
151
+                    bytes[3] = (byte) (int) (l & 0xFF);
152
+                    break;
153
+                case 4:
154
+                    for (i = 0; i < 4; ++i)
155
+                    {
156
+                        l = Integer.parseInt(elements[i]);
157
+                        if ((l < 0L) || (l > 255L)) {
158
+                            return null;
159
+                        }
160
+                        bytes[i] = (byte) (int) (l & 0xFF);
161
+                    }
162
+                    break;
163
+                default:
164
+                    return null;
165
+            }
166
+        }
167
+        catch (NumberFormatException e)
168
+        {
169
+            return null;
170
+        }
171
+        return bytes;
172
+    }
173
+
174
+    public static String getHostIp()
175
+    {
176
+        try
177
+        {
178
+            return InetAddress.getLocalHost().getHostAddress();
179
+        }
180
+        catch (UnknownHostException e)
181
+        {
182
+        }
183
+        return "127.0.0.1";
184
+    }
185
+
186
+    public static String getHostName()
187
+    {
188
+        try
189
+        {
190
+            return InetAddress.getLocalHost().getHostName();
191
+        }
192
+        catch (UnknownHostException e)
193
+        {
194
+        }
195
+        return "未知";
196
+    }
197
+}

+ 17 - 0
src/main/java/com/lqkj/common/utils/poi/ExcelHandlerAdapter.java

@@ -0,0 +1,17 @@
1
+package com.lqkj.common.utils.poi;
2
+/**
3
+ * Excel数据格式处理适配器
4
+ *
5
+ * @author lh
6
+ */
7
+public interface ExcelHandlerAdapter {
8
+    /**
9
+     * 格式化
10
+     *
11
+     * @param value 单元格数据值
12
+     * @param args excel注解args参数组
13
+     *
14
+     * @return 处理后的值
15
+     */
16
+    Object format(Object value, String[] args);
17
+}

Різницю між файлами не показано, бо вона завелика
+ 1367 - 0
src/main/java/com/lqkj/common/utils/poi/ExcelUtil.java


+ 186 - 0
src/main/java/com/lqkj/common/utils/poi/ImageUtil.java

@@ -0,0 +1,186 @@
1
+package com.lqkj.common.utils.poi;
2
+
3
+import org.apache.poi.xwpf.usermodel.XWPFDocument;
4
+import org.apache.poi.xwpf.usermodel.XWPFRun;
5
+import org.apache.xmlbeans.XmlException;
6
+import org.apache.xmlbeans.XmlToken;
7
+import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
8
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
9
+import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;
10
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDrawing;
11
+
12
+/**
13
+ * 文档操作图片工具类
14
+ * @author: lh
15
+ */
16
+public class ImageUtil {
17
+    /**
18
+     * 图片类型枚举
19
+     */
20
+    public enum ImageType {
21
+
22
+        /**
23
+         * 支持四种类型 JPG/JPEG, GIT, BMP, PNG
24
+         */
25
+        JPG("JPG", XWPFDocument.PICTURE_TYPE_JPEG),
26
+        JPEG("JPEG", XWPFDocument.PICTURE_TYPE_JPEG),
27
+        GIF("GIF", XWPFDocument.PICTURE_TYPE_GIF),
28
+        BMP("BMP", XWPFDocument.PICTURE_TYPE_GIF),
29
+        PNG("PNG", XWPFDocument.PICTURE_TYPE_PNG)
30
+        ;
31
+        private String name;
32
+        private Integer typeId;
33
+        ImageType(String name, Integer type) {
34
+            this.name = name;
35
+            this.typeId = type;
36
+        }
37
+
38
+        public String getName() {
39
+            return name;
40
+        }
41
+
42
+        public void setName(String name) {
43
+            this.name = name;
44
+        }
45
+
46
+        public Integer getTypeId() {
47
+            return typeId;
48
+        }
49
+
50
+        public void setTypeId(Integer typeId) {
51
+            this.typeId = typeId;
52
+        }
53
+    }
54
+
55
+    /**
56
+     * 插入环绕类型图片
57
+     * @param run
58
+     * @param blipId
59
+     * @param id
60
+     * @param width
61
+     * @param height
62
+
63
+     */
64
+    public static void createAnchorPicture(XWPFRun run, String blipId, int id, int width, int height, boolean behind, String align ) {
65
+        final int EMU = 9525;
66
+        width *= EMU;
67
+        height *= EMU;
68
+        CTDrawing drawing = run.getCTR().addNewDrawing();
69
+        String xml = "<wp:anchor distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\" simplePos=\"0\" relativeHeight=\"0\" behindDoc=\"" + (behind ? 1 : 0) +"\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\" " +
70
+                " xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"" +
71
+                " xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\"" +
72
+                " xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"  >" +
73
+                "<wp:simplePos x=\"0\" y=\"0\"/>" +
74
+                "<wp:positionH relativeFrom=\"column\">" +
75
+                "<wp:align>" + align +"</wp:align>" +
76
+                "</wp:positionH>" +
77
+                "<wp:positionV relativeFrom=\"paragraph\">" +
78
+                "<wp:posOffset>0</wp:posOffset>" +
79
+                "</wp:positionV>" +
80
+                "<wp:extent cx=\"" + width +"\" cy=\"" + height +"\"/>" +
81
+                "<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>" +
82
+                "<wp:wrapNone/>" +
83
+                "<wp:docPr id=\"" + id +"\" name=\"图片 " + id +"\"/>" +
84
+                "<wp:cNvGraphicFramePr>" +
85
+                "<a:graphicFrameLocks xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" noChangeAspect=\"1\"/>" +
86
+                "</wp:cNvGraphicFramePr>" +
87
+                "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">" +
88
+                "<a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +
89
+                "<pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +
90
+                "<pic:nvPicPr>" +
91
+                "<pic:cNvPr id=\"" + id +"\" name=\"Generated\"/>" +
92
+                "<pic:cNvPicPr/>" +
93
+                "</pic:nvPicPr>" +
94
+                "<pic:blipFill>" +
95
+                "<a:blip r:embed=\"" + blipId +"\"/>" +
96
+                "<a:stretch>" +
97
+                "<a:fillRect/>" +
98
+                "</a:stretch>" +
99
+                "</pic:blipFill>" +
100
+                "<pic:spPr>" +
101
+                "<a:xfrm>" +
102
+                "<a:off x=\"0\" y=\"0\"/>" +
103
+                "<a:ext cx=\"" + width +"\" cy=\"" + height +"\"/>" +
104
+                "</a:xfrm>" +
105
+                "<a:prstGeom prst=\"rect\">" +
106
+                "<a:avLst/>" +
107
+                "</a:prstGeom>" +
108
+                "</pic:spPr>" +
109
+                "</pic:pic>" +
110
+                "</a:graphicData>" +
111
+                "</a:graphic>" +
112
+                "</wp:anchor>";
113
+        XmlToken xmlToken = null;
114
+        try {
115
+            xmlToken = XmlToken.Factory.parse(xml);
116
+        } catch(XmlException xe) {
117
+            xe.printStackTrace();
118
+        }
119
+        drawing.set(xmlToken);
120
+//        drawing.removeInline(0);
121
+    }
122
+
123
+    /**
124
+     * 插入嵌入类型图片
125
+     * @param run
126
+     * @param blipId
127
+     * @param id
128
+     * @param width
129
+     * @param height
130
+     */
131
+    public static void createInlinePicture(XWPFRun run, String blipId, int id, int width, int height) {
132
+        final int EMU = 9525;
133
+        width *= EMU;
134
+        height *= EMU;
135
+        CTInline inline = run.getCTR().addNewDrawing().addNewInline();
136
+        XmlToken xmlToken = null;
137
+        try {
138
+            xmlToken = XmlToken.Factory.parse(getPicXml(id, blipId, width, height));
139
+        } catch(XmlException xe) {
140
+            xe.printStackTrace();
141
+        }
142
+        inline.set(xmlToken);
143
+
144
+        inline.setDistT(0);
145
+        inline.setDistB(0);
146
+        inline.setDistL(0);
147
+        inline.setDistR(0);
148
+
149
+        CTPositiveSize2D extent = inline.addNewExtent();
150
+        extent.setCx(width);
151
+        extent.setCy(height);
152
+
153
+        CTNonVisualDrawingProps docPr = inline.addNewDocPr();
154
+        docPr.setId(id);
155
+        docPr.setName("Picture " + id);
156
+        docPr.setDescr("Generated");
157
+    }
158
+    private static String getPicXml(int id, String blipId, int width, int height){
159
+        return
160
+                "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">" +
161
+                "   <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +
162
+                "      <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +
163
+                "         <pic:nvPicPr>" +
164
+                "            <pic:cNvPr id=\"" + id + "\" name=\"Generated\"/>" +
165
+                "            <pic:cNvPicPr/>" +
166
+                "         </pic:nvPicPr>" +
167
+                "         <pic:blipFill>" +
168
+                "            <a:blip r:embed=\"" + blipId + "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>" +
169
+                "            <a:stretch>" +
170
+                "               <a:fillRect/>" +
171
+                "            </a:stretch>" +
172
+                "         </pic:blipFill>" +
173
+                "         <pic:spPr>" +
174
+                "            <a:xfrm>" +
175
+                "               <a:off x=\"0\" y=\"0\"/>" +
176
+                "               <a:ext cx=\"" + width + "\" cy=\"" + height + "\"/>" +
177
+                "            </a:xfrm>" +
178
+                "            <a:prstGeom prst=\"rect\">" +
179
+                "               <a:avLst/>" +
180
+                "            </a:prstGeom>" +
181
+                "         </pic:spPr>" +
182
+                "      </pic:pic>" +
183
+                "   </a:graphicData>" +
184
+                "</a:graphic>";
185
+    }
186
+}

Різницю між файлами не показано, бо вона завелика
+ 843 - 0
src/main/java/com/lqkj/common/utils/poi/WordUtil.java


+ 0 - 0
src/main/java/com/lqkj/common/utils/poi/model/ImageEntity.java


Деякі файли не було показано, через те що забагато файлів було змінено