Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
basic-api-boot
概览
概览
详情
活动
周期分析
版本库
存储库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Basic
basic-api-boot
Commits
f360f80d
提交
f360f80d
authored
4月 24, 2022
作者:
方治民
浏览文件
操作
浏览文件
下载
差异文件
合并分支 'merge_dev' 到 'dev_fzm'
Merge dev 查看合并请求 chemical-kesai/kshg-api!15
上级
f490012a
264c18a3
显示空白字符变更
内嵌
并排
正在显示
102 个修改的文件
包含
7770 行增加
和
222 行删除
+7770
-222
README.md
README.md
+1
-0
build.gradle
app-push/build.gradle
+16
-0
PushMessage.java
...src/main/java/com/yiring/app/push/domain/PushMessage.java
+11
-11
PushAppParam.java
...src/main/java/com/yiring/app/push/param/PushAppParam.java
+25
-0
PushRabbitConfig.java
...n/java/com/yiring/app/push/rabbitmq/PushRabbitConfig.java
+36
-13
PushRabbitReceiver.java
...java/com/yiring/app/push/rabbitmq/PushRabbitReceiver.java
+55
-4
PushService.java
...rc/main/java/com/yiring/app/push/service/PushService.java
+7
-0
PushServiceImpl.java
...ava/com/yiring/app/push/service/impl/PushServiceImpl.java
+8
-5
build.gradle
app/build.gradle
+10
-0
Car.java
app/src/main/java/com/yiring/app/domain/car/Car.java
+90
-0
CarRepository.java
...rc/main/java/com/yiring/app/domain/car/CarRepository.java
+32
-0
LocationBeacon.java
...n/java/com/yiring/app/domain/location/LocationBeacon.java
+3
-0
LocationFence.java
...in/java/com/yiring/app/domain/location/LocationFence.java
+3
-0
LocationLog.java
...main/java/com/yiring/app/domain/location/LocationLog.java
+8
-7
LocationTag.java
...main/java/com/yiring/app/domain/location/LocationTag.java
+5
-11
LocationTagRepository.java
...com/yiring/app/domain/location/LocationTagRepository.java
+17
-0
Video.java
app/src/main/java/com/yiring/app/domain/video/Video.java
+18
-12
VideoRepository.java
...ain/java/com/yiring/app/domain/video/VideoRepository.java
+2
-1
LocationTagExportExcel.java
...com/yiring/app/excel/location/LocationTagExportExcel.java
+71
-0
LocationTagImportExcel.java
...com/yiring/app/excel/location/LocationTagImportExcel.java
+39
-0
CarParam.java
app/src/main/java/com/yiring/app/param/car/CarParam.java
+67
-0
CarQueryParam.java
...src/main/java/com/yiring/app/param/car/CarQueryParam.java
+68
-0
DictParam.java
app/src/main/java/com/yiring/app/param/dict/DictParam.java
+43
-0
DictQueryParam.java
...c/main/java/com/yiring/app/param/dict/DictQueryParam.java
+26
-0
DictTypeParam.java
...rc/main/java/com/yiring/app/param/dict/DictTypeParam.java
+33
-0
DictTypeQueryParam.java
...in/java/com/yiring/app/param/dict/DictTypeQueryParam.java
+23
-0
LocationTagAddParam.java
...va/com/yiring/app/param/location/LocationTagAddParam.java
+39
-0
LocationTagDeleteParam.java
...com/yiring/app/param/location/LocationTagDeleteParam.java
+34
-0
LocationTagFindParam.java
...a/com/yiring/app/param/location/LocationTagFindParam.java
+41
-0
LocationTagModifyParam.java
...com/yiring/app/param/location/LocationTagModifyParam.java
+39
-0
ZyLocationTagAddParam.java
...m/yiring/app/param/location/zy/ZyLocationTagAddParam.java
+50
-0
VideoParam.java
app/src/main/java/com/yiring/app/param/video/VideoParam.java
+63
-0
VideoQueryParam.java
...main/java/com/yiring/app/param/video/VideoQueryParam.java
+46
-0
RabbitConfig.java
.../main/java/com/yiring/app/rabbit/config/RabbitConfig.java
+83
-0
ZyConfigProperties.java
...java/com/yiring/app/rabbit/config/ZyConfigProperties.java
+1
-1
ZyRabbitConfig.java
...ain/java/com/yiring/app/rabbit/config/ZyRabbitConfig.java
+7
-28
RabbitReceiver.java
...n/java/com/yiring/app/rabbit/receiver/RabbitReceiver.java
+1
-1
ZyRabbitReceiver.java
...java/com/yiring/app/rabbit/receiver/ZyRabbitReceiver.java
+11
-5
RabbitConfig.java
app/src/main/java/com/yiring/app/rabbitmq/RabbitConfig.java
+0
-13
CarService.java
app/src/main/java/com/yiring/app/service/car/CarService.java
+101
-0
CarServiceImpl.java
.../java/com/yiring/app/service/car/impl/CarServiceImpl.java
+289
-0
DictService.java
...rc/main/java/com/yiring/app/service/dict/DictService.java
+98
-0
DictTypeService.java
...ain/java/com/yiring/app/service/dict/DictTypeService.java
+26
-0
DictServiceImpl.java
...ava/com/yiring/app/service/dict/impl/DictServiceImpl.java
+202
-0
DictTypeServiceImpl.java
...com/yiring/app/service/dict/impl/DictTypeServiceImpl.java
+122
-0
LocationTagService.java
...a/com/yiring/app/service/location/LocationTagService.java
+62
-0
LocationTagServiceImpl.java
...ing/app/service/location/impl/LocationTagServiceImpl.java
+228
-0
VideoService.java
.../main/java/com/yiring/app/service/video/VideoService.java
+66
-0
VideoServiceImpl.java
...a/com/yiring/app/service/video/impl/VideoServiceImpl.java
+164
-0
RabbitmqProperties.java
...rc/main/java/com/yiring/app/stomp/RabbitmqProperties.java
+0
-28
WebSocketStompConfig.java
.../main/java/com/yiring/app/stomp/WebSocketStompConfig.java
+7
-6
CarVo.java
app/src/main/java/com/yiring/app/vo/car/CarVo.java
+96
-0
LocationTagVo.java
...c/main/java/com/yiring/app/vo/location/LocationTagVo.java
+69
-0
VideoVo.java
app/src/main/java/com/yiring/app/vo/video/VideoVo.java
+40
-0
HelloController.java
app/src/main/java/com/yiring/app/web/HelloController.java
+63
-8
LocationTagController.java
...c/main/java/com/yiring/app/web/LocationTagController.java
+74
-0
CarController.java
app/src/main/java/com/yiring/app/web/car/CarController.java
+94
-0
DictController.java
...src/main/java/com/yiring/app/web/dict/DictController.java
+77
-0
DictTypeController.java
...main/java/com/yiring/app/web/dict/DictTypeController.java
+56
-0
VideoController.java
...c/main/java/com/yiring/app/web/video/VideoController.java
+67
-0
application-dev.yml
app/src/main/resources/application-dev.yml
+12
-1
build.gradle
basic-auth/build.gradle
+8
-1
PostRepository.java
...main/java/com/yiring/auth/domain/post/PostRepository.java
+2
-1
User.java
...-auth/src/main/java/com/yiring/auth/domain/user/User.java
+2
-1
PostExcel.java
...h/src/main/java/com/yiring/auth/excel/post/PostExcel.java
+56
-0
PostFindParam.java
...c/main/java/com/yiring/auth/param/post/PostFindParam.java
+37
-0
PostParam.java
...h/src/main/java/com/yiring/auth/param/post/PostParam.java
+39
-0
PostService.java
...c/main/java/com/yiring/auth/service/post/PostService.java
+67
-0
PostServiceImpl.java
...va/com/yiring/auth/service/post/impl/PostServiceImpl.java
+165
-0
ZyUtil.java
basic-auth/src/main/java/com/yiring/auth/util/ZyUtil.java
+171
-0
PostVo.java
basic-auth/src/main/java/com/yiring/auth/vo/post/PostVo.java
+68
-0
PostController.java
...rc/main/java/com/yiring/auth/web/post/PostController.java
+71
-0
build.gradle
basic-common/core/build.gradle
+2
-6
CorsConfig.java
...re/src/main/java/com/yiring/common/config/CorsConfig.java
+30
-0
JacksonConfig.java
...src/main/java/com/yiring/common/config/JacksonConfig.java
+3
-0
JSONArrayConverter.java
...om/yiring/common/config/converter/JSONArrayConverter.java
+0
-28
JSONObjectConverter.java
...m/yiring/common/config/converter/JSONObjectConverter.java
+0
-28
RegEx.java
.../core/src/main/java/com/yiring/common/constant/RegEx.java
+22
-0
RedisCache.java
...rc/main/java/com/yiring/common/core/redis/RedisCache.java
+226
-0
Dict.java
...ommon/core/src/main/java/com/yiring/common/dict/Dict.java
+62
-0
DictRepository.java
.../src/main/java/com/yiring/common/dict/DictRepository.java
+40
-0
DictType.java
...n/core/src/main/java/com/yiring/common/dict/DictType.java
+51
-0
DictTypeRepository.java
.../main/java/com/yiring/common/dict/DictTypeRepository.java
+12
-0
build.gradle
basic-common/redis/build.gradle
+6
-1
CacheKeyGenerator.java
...main/java/com/yiring/common/config/CacheKeyGenerator.java
+40
-0
RedisConfig.java
...s/src/main/java/com/yiring/common/config/RedisConfig.java
+59
-0
Redis.java
...mon/redis/src/main/java/com/yiring/common/core/Redis.java
+9
-0
build.gradle
basic-common/util/build.gradle
+12
-0
Excel.java
...til/src/main/java/com/yiring/common/annotation/Excel.java
+177
-0
Excels.java
...il/src/main/java/com/yiring/common/annotation/Excels.java
+16
-0
RequestAspect.java
...src/main/java/com/yiring/common/aspect/RequestAspect.java
+0
-0
Convert.java
...on/util/src/main/java/com/yiring/common/text/Convert.java
+866
-0
DictUtils.java
.../util/src/main/java/com/yiring/common/util/DictUtils.java
+164
-0
StrUtils.java
...n/util/src/main/java/com/yiring/common/util/StrUtils.java
+424
-0
DateUtils.java
.../src/main/java/com/yiring/common/util/date/DateUtils.java
+166
-0
FileTypeUtils.java
.../main/java/com/yiring/common/util/file/FileTypeUtils.java
+69
-0
ImageUtils.java
...src/main/java/com/yiring/common/util/file/ImageUtils.java
+67
-0
ExcelHandlerAdapter.java
.../java/com/yiring/common/util/poi/ExcelHandlerAdapter.java
+16
-0
ExcelUtils.java
.../src/main/java/com/yiring/common/util/poi/ExcelUtils.java
+1018
-0
ReflectUtils.java
...ain/java/com/yiring/common/util/reflect/ReflectUtils.java
+361
-0
build.gradle
build.gradle
+3
-1
skill.md
doc/skill.md
+18
-0
没有找到文件。
README.md
浏览文件 @
f360f80d
...
...
@@ -18,6 +18,7 @@
<!-- prettier-ignore -->
-
[
开发规范说明
](
./doc/workflow.md
)
-
[
技术栈说明
](
./doc/technique.md
)
-
[
实用技巧
](
./doc/skill.md
)
---
...
...
app-push/build.gradle
浏览文件 @
f360f80d
...
...
@@ -9,8 +9,13 @@ dependencies {
// 本地依赖
implementation
fileTree
(
dir:
project
.
rootDir
.
getPath
()
+
'\\libs'
,
includes:
[
'*jar'
])
// 文档及参数校验
implementation
'org.springframework.boot:spring-boot-starter-validation'
implementation
"io.swagger:swagger-annotations:${swaggerAnnotationsVersion}"
// hutool-core
implementation
"cn.hutool:hutool-core:${hutoolVersion}"
implementation
"cn.hutool:hutool-http:${hutoolVersion}"
// fastjson
implementation
"com.alibaba:fastjson:${fastJsonVersion}"
...
...
@@ -19,4 +24,15 @@ dependencies {
// hibernate-types-55
implementation
"com.vladmihalcea:hibernate-types-55:${hibernateTypesVersion}"
// ======================= 推送相关 =======================
// 个推 SDK(App 推送)
// https://mvnrepository.com/artifact/com.getui.push/restful-sdk
implementation
'com.getui.push:restful-sdk:1.0.0.6'
// 阿里云短信 SDK(SMS 推送)
// https://mvnrepository.com/artifact/com.aliyun/dysmsapi20170525
implementation
'com.aliyun:dysmsapi20170525:2.0.9'
// 邮件 SDK(EMAIL 推送)
implementation
'org.springframework.boot:spring-boot-starter-mail'
// ======================================================
}
app-push/src/main/java/com/yiring/app/push/domain/PushMessage.java
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
push
.
domain
;
import
com.alibaba.fastjson.JSON
;
import
com.vladmihalcea.hibernate.type.json.JsonType
;
import
com.alibaba.fastjson.JSON
Object
;
import
com.vladmihalcea.hibernate.type.json.Json
Binary
Type
;
import
com.yiring.common.domain.BasicEntity
;
import
java.io.Serial
;
import
java.io.Serializable
;
...
...
@@ -34,7 +34,7 @@ import org.hibernate.annotations.TypeDef;
@FieldNameConstants
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
@Entity
@TypeDef
(
name
=
"json
"
,
typeClass
=
Json
Type
.
class
)
@TypeDef
(
name
=
"json
b"
,
typeClass
=
JsonBinary
Type
.
class
)
@Table
(
name
=
"SYS_PUSH_MESSAGE"
,
indexes
=
{
...
...
@@ -73,18 +73,18 @@ public class PushMessage extends BasicEntity implements Serializable {
String
content
;
@Comment
(
"扩展数据"
)
@org
.
hibernate
.
annotations
.
Type
(
type
=
"json"
)
@Column
(
columnDefinition
=
"json"
)
JSON
extra
;
@org
.
hibernate
.
annotations
.
Type
(
type
=
"json
b
"
)
@Column
(
columnDefinition
=
"json
b
"
)
JSON
Object
extra
;
@Comment
(
"消息状态"
)
@Enumerated
(
EnumType
.
STRING
)
Status
status
;
@Comment
(
"推送反馈结果"
)
@org
.
hibernate
.
annotations
.
Type
(
type
=
"json"
)
@Column
(
columnDefinition
=
"json"
)
JSON
result
;
@org
.
hibernate
.
annotations
.
Type
(
type
=
"json
b
"
)
@Column
(
columnDefinition
=
"json
b
"
)
JSON
Object
result
;
@Comment
(
"重试次数"
)
Integer
retryCount
;
...
...
@@ -94,7 +94,7 @@ public class PushMessage extends BasicEntity implements Serializable {
@SuppressWarnings
({
"unused"
})
public
enum
Type
{
W
S
(
"STOMP WebSocket 消息
"
),
W
EBHOOK
(
"webhook
"
),
APP
(
"APP 消息"
),
SMS
(
"短信消息"
),
EMAIL
(
"邮件消息"
),
...
...
@@ -113,7 +113,7 @@ public class PushMessage extends BasicEntity implements Serializable {
}
public
String
queue
()
{
return
String
.
format
(
"push.%s.queue"
,
this
.
name
());
return
String
.
format
(
"push.%s.queue"
,
this
.
name
()
.
toLowerCase
()
);
}
}
...
...
app-push/src/main/java/com/yiring/app/push/param/PushAppParam.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
push
.
param
;
import
io.swagger.annotations.ApiModel
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
/**
* App 推送参数
*
* @author Jim
* @version 0.1
* 2022/4/21 10:27
*/
@ApiModel
(
"A"
)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
PushAppParam
{
String
webhook
;
}
app-push/src/main/java/com/yiring/app/push/rabbitmq/PushRabbitConfig.java
浏览文件 @
f360f80d
...
...
@@ -20,14 +20,37 @@ import org.springframework.context.annotation.Configuration;
@Configuration
public
class
PushRabbitConfig
{
/**
* 消息交换机
*/
public
static
final
String
PUSH_TOPIC_EXCHANGE
=
"push.topic.exchange"
;
/**
* WebHook 推送队列
*/
public
static
final
String
PUSH_WEBHOOK_QUEUE
=
"push.webhook.queue"
;
/**
* App 消息推送队列
*/
public
static
final
String
PUSH_APP_QUEUE
=
"push.app.queue"
;
public
static
final
String
PUSH_WS_QUEUE
=
"push.ws.queue"
;
/**
* 短信推送队列
*/
public
static
final
String
PUSH_SMS_QUEUE
=
"push.sms.queue"
;
public
static
final
String
PUSH_EMAIL_QUEUE
=
"push.email.queue"
;
/**
* 邮箱推送队列
*/
public
static
final
String
PUSH_MAIL_QUEUE
=
"push.mail.queue"
;
/**
* TTS 语音电话队列
*/
public
static
final
String
PUSH_CALL_TTS_QUEUE
=
"push.call.tts.queue"
;
/**
* 语音电话推送队列
*/
public
static
final
String
PUSH_CALL_AUDIO_QUEUE
=
"push.call.audio.queue"
;
/**
* 设备广播推送队列
*/
public
static
final
String
PUSH_DEVICE_TONE_QUEUE
=
"push.device.tone.queue"
;
/**
...
...
@@ -52,16 +75,16 @@ public class PushRabbitConfig {
return
BindingBuilder
.
bind
(
queue
).
to
(
exchange
).
with
(
PUSH_APP_QUEUE
);
}
@Bean
(
PUSH_W
S
_QUEUE
)
public
Queue
pushWeb
Socket
Queue
()
{
@Bean
(
PUSH_W
EBHOOK
_QUEUE
)
public
Queue
pushWeb
Hook
Queue
()
{
Map
<
String
,
Object
>
args
=
new
HashMap
<>(
1
);
args
.
put
(
"x-message-ttl"
,
30
*
1000
);
return
new
Queue
(
PUSH_W
S
_QUEUE
,
true
,
false
,
false
,
args
);
return
new
Queue
(
PUSH_W
EBHOOK
_QUEUE
,
true
,
false
,
false
,
args
);
}
@Bean
Binding
bindingExchangeW
s
(
@Qualifier
(
PUSH_WS
_QUEUE
)
Queue
queue
,
TopicExchange
exchange
)
{
return
BindingBuilder
.
bind
(
queue
).
to
(
exchange
).
with
(
PUSH_W
S
_QUEUE
);
Binding
bindingExchangeW
ebHook
(
@Qualifier
(
PUSH_WEBHOOK
_QUEUE
)
Queue
queue
,
TopicExchange
exchange
)
{
return
BindingBuilder
.
bind
(
queue
).
to
(
exchange
).
with
(
PUSH_W
EBHOOK
_QUEUE
);
}
@Bean
(
PUSH_SMS_QUEUE
)
...
...
@@ -76,16 +99,16 @@ public class PushRabbitConfig {
return
BindingBuilder
.
bind
(
queue
).
to
(
exchange
).
with
(
PUSH_SMS_QUEUE
);
}
@Bean
(
PUSH_
E
MAIL_QUEUE
)
public
Queue
push
Em
ailQueue
()
{
@Bean
(
PUSH_MAIL_QUEUE
)
public
Queue
push
M
ailQueue
()
{
Map
<
String
,
Object
>
args
=
new
HashMap
<>(
1
);
args
.
put
(
"x-message-ttl"
,
60
*
1000
);
return
new
Queue
(
PUSH_
E
MAIL_QUEUE
,
true
,
false
,
false
,
args
);
return
new
Queue
(
PUSH_MAIL_QUEUE
,
true
,
false
,
false
,
args
);
}
@Bean
Binding
bindingExchange
Email
(
@Qualifier
(
PUSH_E
MAIL_QUEUE
)
Queue
queue
,
TopicExchange
exchange
)
{
return
BindingBuilder
.
bind
(
queue
).
to
(
exchange
).
with
(
PUSH_
E
MAIL_QUEUE
);
Binding
bindingExchange
Mail
(
@Qualifier
(
PUSH_
MAIL_QUEUE
)
Queue
queue
,
TopicExchange
exchange
)
{
return
BindingBuilder
.
bind
(
queue
).
to
(
exchange
).
with
(
PUSH_MAIL_QUEUE
);
}
@Bean
(
PUSH_CALL_TTS_QUEUE
)
...
...
app-push/src/main/java/com/yiring/app/push/rabbitmq/PushRabbitReceiver.java
浏览文件 @
f360f80d
...
...
@@ -26,10 +26,61 @@ public class PushRabbitReceiver {
PushMessageRepository
repository
;
@RabbitHandler
@RabbitListener
(
queues
=
PushRabbitConfig
.
PUSH_WS_QUEUE
)
public
void
receiverWebSocketMessage
(
Long
id
)
{
log
.
info
(
"接收到消息: "
+
id
);
@RabbitListener
(
queues
=
PushRabbitConfig
.
PUSH_WEBHOOK_QUEUE
)
public
void
receiverWebHookMessage
(
Long
id
)
{
log
.
info
(
"[WebHook] Message: "
+
id
);
repository
.
findById
(
id
).
ifPresent
(
message
->
log
.
info
(
"{}"
,
message
));
// TODO
// 实现调用 WebHook,基于 WebHook API 发起 HTTPs 请求
}
@RabbitHandler
@RabbitListener
(
queues
=
PushRabbitConfig
.
PUSH_APP_QUEUE
)
public
void
receiverAppMessage
(
Long
id
)
{
log
.
info
(
"[App] Message: "
+
id
);
// TODO
// 实现推送消息到 App,基于个推 API
// https://github.com/GetuiLaboratory/getui-pushapi-java-client-v2
}
@RabbitHandler
@RabbitListener
(
queues
=
PushRabbitConfig
.
PUSH_SMS_QUEUE
)
public
void
receiverSmsMessage
(
Long
id
)
{
log
.
info
(
"[SMS] Message: "
+
id
);
// TODO
// 实现发送短信,基于阿里云短信平台 API
}
@RabbitHandler
@RabbitListener
(
queues
=
PushRabbitConfig
.
PUSH_MAIL_QUEUE
)
public
void
receiverMailMessage
(
Long
id
)
{
log
.
info
(
"[Mail] Message: "
+
id
);
// TODO
// 实现发送邮件,基于邮件配置
}
@RabbitHandler
@RabbitListener
(
queues
=
PushRabbitConfig
.
PUSH_CALL_TTS_QUEUE
)
public
void
receiverTtsMessage
(
Long
id
)
{
log
.
info
(
"[Phone TTS] Message: "
+
id
);
// TODO
// 实现拨打电话播放 TTS 转语音,基于壹润外呼系统 API
}
@RabbitHandler
@RabbitListener
(
queues
=
PushRabbitConfig
.
PUSH_CALL_AUDIO_QUEUE
)
public
void
receiverAudioMessage
(
Long
id
)
{
log
.
info
(
"[Phone Audio] Message: "
+
id
);
// TODO
// 实现拨打电话播放音频文件,基于壹润外呼系统 API
}
@RabbitHandler
@RabbitListener
(
queues
=
PushRabbitConfig
.
PUSH_DEVICE_TONE_QUEUE
)
public
void
receiverToneMessage
(
Long
id
)
{
log
.
info
(
"[Device Tone] Message: "
+
id
);
// TODO
// 实现播放设备铃声,基于音柱广播设备 API
// SDK 暂未拿到,设备未采购,未进行联调
}
}
app-push/src/main/java/com/yiring/app/push/service/PushService.java
浏览文件 @
f360f80d
...
...
@@ -3,6 +3,7 @@ package com.yiring.app.push.service;
import
com.alibaba.fastjson.JSONObject
;
import
com.yiring.app.push.domain.PushMessage
;
import
com.yiring.app.push.param.PushAppParam
;
/**
* 推送服务
...
...
@@ -13,4 +14,10 @@ import com.yiring.app.push.domain.PushMessage;
*/
public
interface
PushService
{
void
push
(
PushMessage
.
Type
type
,
JSONObject
raw
);
/**
* 推送到 App
* @param param 参数
*/
void
app
(
PushAppParam
param
);
}
app-push/src/main/java/com/yiring/app/push/service/impl/PushServiceImpl.java
浏览文件 @
f360f80d
...
...
@@ -4,13 +4,13 @@ package com.yiring.app.push.service.impl;
import
com.alibaba.fastjson.JSONObject
;
import
com.yiring.app.push.domain.PushMessage
;
import
com.yiring.app.push.domain.PushMessageRepository
;
import
com.yiring.app.push.param.PushAppParam
;
import
com.yiring.app.push.rabbitmq.PushRabbitConfig
;
import
com.yiring.app.push.service.PushService
;
import
java.time.LocalDateTime
;
import
javax.annotation.Resource
;
import
javax.transaction.Transactional
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.amqp.
core.Amqp
Template
;
import
org.springframework.amqp.
rabbit.core.Rabbit
Template
;
import
org.springframework.stereotype.Service
;
/**
...
...
@@ -30,15 +30,18 @@ public class PushServiceImpl implements PushService {
PushMessageRepository
repository
;
@Resource
AmqpTemplate
amqp
Template
;
RabbitTemplate
rabbit
Template
;
@Override
public
void
push
(
PushMessage
.
Type
type
,
JSONObject
raw
)
{
PushMessage
message
=
new
PushMessage
();
message
.
setType
(
type
);
message
.
setExtra
(
raw
);
message
.
setCreateTime
(
LocalDateTime
.
now
());
repository
.
saveAndFlush
(
message
);
amqpTemplate
.
convertAndSend
(
PushRabbitConfig
.
PUSH_TOPIC_EXCHANGE
,
type
.
queue
(),
message
.
getId
());
rabbitTemplate
.
convertAndSend
(
PushRabbitConfig
.
PUSH_TOPIC_EXCHANGE
,
type
.
queue
(),
message
.
getId
());
}
@Override
public
void
app
(
PushAppParam
param
)
{}
}
app/build.gradle
浏览文件 @
f360f80d
...
...
@@ -22,9 +22,11 @@ dependencies {
// 本地依赖
implementation
fileTree
(
dir:
project
.
rootDir
.
getPath
()
+
'\\libs'
,
includes:
[
'*jar'
])
// 公共依赖
implementation
project
(
":basic-common:core"
)
implementation
project
(
":basic-common:util"
)
// 服务依赖
implementation
project
(
":app-push"
)
// Optional: Redis
...
...
@@ -49,6 +51,7 @@ dependencies {
// hutool
implementation
"cn.hutool:hutool-core:${hutoolVersion}"
implementation
"cn.hutool:hutool-extra:${hutoolVersion}"
implementation
"cn.hutool:hutool-http:${hutoolVersion}"
// JPA 增加空间字段支持
// https://blog.wuwii.com/jpa-spatial.html
...
...
@@ -59,4 +62,11 @@ dependencies {
// JTS 几何对象操作库
implementation
"org.locationtech.jts:jts-core:${jtsVersion}"
// https://github.com/vladmihalcea/hibernate-types
// hibernate-types-55
implementation
"com.vladmihalcea:hibernate-types-55:${hibernateTypesVersion}"
// myexcel
implementation
"com.github.liaochong:myexcel:${myexcelVersion}"
}
app/src/main/java/com/yiring/app/domain/car/Car.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
domain
.
car
;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
com.yiring.common.annotation.Excel
;
import
java.io.Serializable
;
import
java.time.LocalDateTime
;
import
javax.persistence.*
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
import
lombok.experimental.FieldNameConstants
;
import
org.hibernate.annotations.Comment
;
import
org.hibernate.annotations.GenericGenerator
;
import
org.hibernate.snowflake.SnowflakeId
;
/**
* @author tzl
* 2022/4/11 13:38
*/
@Getter
@Setter
@ToString
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldNameConstants
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
@Entity
@Table
(
name
=
"BS_CAR"
)
@Comment
(
"车辆"
)
public
class
Car
implements
Serializable
{
@Id
@Comment
(
"主键id"
)
@GeneratedValue
(
generator
=
SnowflakeId
.
GENERATOR
)
@GenericGenerator
(
name
=
SnowflakeId
.
GENERATOR
,
strategy
=
SnowflakeId
.
Strategy
.
LONG
)
Long
id
;
@Comment
(
"车牌号"
)
@Excel
(
name
=
"车牌"
,
sort
=
1
)
String
carNum
;
@Comment
(
"车辆类型"
)
@Excel
(
name
=
"车辆类型"
,
sort
=
2
,
dictType
=
"car_type"
)
String
carType
;
@Comment
(
"司机名称"
)
@Excel
(
name
=
"司机"
,
sort
=
3
)
String
driverName
;
@Comment
(
"司机电话"
)
@Excel
(
name
=
"联系电话"
,
sort
=
4
)
String
driverMobile
;
@Comment
(
"标签卡"
)
@Excel
(
name
=
"标签卡"
,
sort
=
9
)
String
labelCard
;
@Comment
(
"标签卡状态"
)
@Excel
(
name
=
"标签卡状态"
,
sort
=
10
,
dictType
=
"car_label_status"
)
String
labelCardStatus
;
@Comment
(
"所属单位id"
)
@Excel
(
name
=
"所属单位"
,
sort
=
5
)
String
orgId
;
@Comment
(
"被访人id"
)
@Excel
(
name
=
"被访人"
,
sort
=
7
)
String
intervieweeId
;
@Comment
(
"来访原因"
)
@Excel
(
name
=
"来访原因"
,
sort
=
6
)
String
reason
;
@Comment
(
"收卡时间"
)
@Excel
(
name
=
"收卡时间"
,
sort
=
11
,
dateFormat
=
"yyyy-MM-dd HH:mm:ss"
)
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
LocalDateTime
cardRecTime
;
@Comment
(
"创建时间"
)
@Excel
(
name
=
"到访时间"
,
sort
=
8
,
dateFormat
=
"yyyy-MM-dd HH:mm:ss"
)
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
LocalDateTime
createTime
;
@Comment
(
"发卡时间"
)
LocalDateTime
cardSendTime
;
@Comment
(
"备用字段"
)
String
reserve4
;
}
app/src/main/java/com/yiring/app/domain/car/CarRepository.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
domain
.
car
;
import
java.io.Serializable
;
import
org.springframework.data.jpa.repository.JpaRepository
;
import
org.springframework.data.jpa.repository.JpaSpecificationExecutor
;
import
org.springframework.stereotype.Repository
;
/**
* @author tzl
* 2022/4/11 13:42
*/
@Repository
public
interface
CarRepository
extends
JpaRepository
<
Car
,
Serializable
>,
JpaSpecificationExecutor
<
Car
>
{
// /**
// * 检查是否存在相同车牌号登记
// *
// * @param param String 车牌号码
// * @return 是否存在
// */
// @Query("SELECT COUNT(c.id) FROM bs_car c where car_num=?1 and label_card_status <>'已收卡'")
// boolean hasCarInfoByCarNum(String param);
//
// /**
// * 检查是否存在相同手机号码登记
// *
// * @param param String 手机号码
// * @return 是否存在
// */
// @Query("SELECT COUNT(c.id) FROM bs_car c where driver_mobile=?1 and label_card_status <>'已收卡'")
// boolean hasCarInfoByMobile(String param);
}
app/src/main/java/com/yiring/app/domain/location/LocationBeacon.java
浏览文件 @
f360f80d
...
...
@@ -14,6 +14,7 @@ import lombok.experimental.FieldNameConstants;
import
org.hibernate.Hibernate
;
import
org.hibernate.annotations.Comment
;
import
org.hibernate.annotations.GenericGenerator
;
import
org.hibernate.annotations.Type
;
import
org.hibernate.snowflake.SnowflakeId
;
import
org.locationtech.jts.geom.Point
;
...
...
@@ -86,6 +87,8 @@ public class LocationBeacon implements Serializable {
Double
distance
;
@Comment
(
"坐标点信息"
)
@Type
(
type
=
"jts_geometry"
)
@Column
(
columnDefinition
=
"point"
)
Point
point
;
@FieldMapping
...
...
app/src/main/java/com/yiring/app/domain/location/LocationFence.java
浏览文件 @
f360f80d
...
...
@@ -13,6 +13,7 @@ import lombok.experimental.FieldDefaults;
import
lombok.experimental.FieldNameConstants
;
import
org.hibernate.annotations.Comment
;
import
org.hibernate.annotations.GenericGenerator
;
import
org.hibernate.annotations.Type
;
import
org.hibernate.snowflake.SnowflakeId
;
import
org.locationtech.jts.geom.Geometry
;
...
...
@@ -71,6 +72,8 @@ public class LocationFence implements Serializable {
String
shapeType
;
@Comment
(
"空间信息"
)
@Type
(
type
=
"jts_geometry"
)
@Column
(
columnDefinition
=
"geometry"
)
Geometry
geometry
;
@Comment
(
"半径,米/单位(圆形围栏)"
)
...
...
app/src/main/java/com/yiring/app/domain/location/LocationLog.java
浏览文件 @
f360f80d
...
...
@@ -2,8 +2,8 @@
package
com
.
yiring
.
app
.
domain
.
location
;
import
com.alibaba.fastjson.JSONObject
;
import
com.vladmihalcea.hibernate.type.json.JsonType
;
import
com.yiring.auth.domain.user.User
;
import
com.yiring.common.config.converter.JSONObjectConverter
;
import
java.io.Serial
;
import
java.io.Serializable
;
import
java.math.BigDecimal
;
...
...
@@ -18,6 +18,8 @@ import lombok.experimental.FieldNameConstants;
import
org.hibernate.Hibernate
;
import
org.hibernate.annotations.Comment
;
import
org.hibernate.annotations.GenericGenerator
;
import
org.hibernate.annotations.Type
;
import
org.hibernate.annotations.TypeDef
;
import
org.hibernate.snowflake.SnowflakeId
;
import
org.locationtech.jts.geom.Point
;
...
...
@@ -39,6 +41,7 @@ import org.locationtech.jts.geom.Point;
@FieldNameConstants
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
@Entity
@TypeDef
(
name
=
"json"
,
typeClass
=
JsonType
.
class
)
@Table
(
name
=
"BS_LOCATION_LOG"
,
indexes
=
{
@Index
(
columnList
=
"time"
),
@Index
(
columnList
=
"silent"
)
})
@Comment
(
"定位数据"
)
public
class
LocationLog
implements
Serializable
{
...
...
@@ -85,7 +88,8 @@ public class LocationLog implements Serializable {
BigDecimal
altitude
;
@Comment
(
"坐标点信息"
)
@Column
(
columnDefinition
=
"POINT"
)
@Type
(
type
=
"jts_geometry"
)
@Column
(
columnDefinition
=
"point"
)
Point
point
;
@Comment
(
"信标集合"
)
...
...
@@ -110,11 +114,8 @@ public class LocationLog implements Serializable {
String
voltUnit
;
@Comment
(
"原始数据"
)
@Convert
(
converter
=
JSONObjectConverter
.
class
)
@Lob
@Basic
(
fetch
=
FetchType
.
LAZY
)
@Column
(
columnDefinition
=
"JSON"
)
@ToString
.
Exclude
@org
.
hibernate
.
annotations
.
Type
(
type
=
"json"
)
@Column
(
columnDefinition
=
"json"
)
JSONObject
raw
;
@Comment
(
"创建时间"
)
...
...
app/src/main/java/com/yiring/app/domain/location/LocationTag.java
浏览文件 @
f360f80d
...
...
@@ -3,6 +3,7 @@ package com.yiring.app.domain.location;
import
com.yiring.auth.domain.user.User
;
import
com.yiring.common.annotation.FieldMapping
;
import
com.yiring.common.domain.BasicEntity
;
import
java.io.Serial
;
import
java.io.Serializable
;
import
java.time.LocalDateTime
;
...
...
@@ -11,10 +12,9 @@ import javax.persistence.*;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
import
lombok.experimental.FieldNameConstants
;
import
lombok.experimental.SuperBuilder
;
import
org.hibernate.Hibernate
;
import
org.hibernate.annotations.Comment
;
import
org.hibernate.annotations.GenericGenerator
;
import
org.hibernate.snowflake.SnowflakeId
;
/**
* 定位标签
...
...
@@ -30,7 +30,7 @@ import org.hibernate.snowflake.SnowflakeId;
@Getter
@Setter
@ToString
@
Builder
@
SuperBuilder
(
toBuilder
=
true
)
@NoArgsConstructor
@AllArgsConstructor
@FieldNameConstants
...
...
@@ -47,17 +47,11 @@ import org.hibernate.snowflake.SnowflakeId;
}
)
@Comment
(
"定位标签"
)
public
class
LocationTag
implements
Serializable
{
public
class
LocationTag
extends
BasicEntity
implements
Serializable
{
@Serial
private
static
final
long
serialVersionUID
=
5419734189897829250L
;
@Comment
(
"主键"
)
@Id
@GeneratedValue
(
generator
=
SnowflakeId
.
GENERATOR
)
@GenericGenerator
(
name
=
SnowflakeId
.
GENERATOR
,
strategy
=
SnowflakeId
.
Strategy
.
LONG
)
Long
id
;
/**
* 数据来源于【真源人员定位系统 - 定位标签】
* 作用: 用于双向联动进行数据同步
...
...
@@ -134,7 +128,7 @@ public class LocationTag implements Serializable {
if
(
this
==
o
)
return
true
;
if
(
o
==
null
||
Hibernate
.
getClass
(
this
)
!=
Hibernate
.
getClass
(
o
))
return
false
;
LocationTag
that
=
(
LocationTag
)
o
;
return
id
!=
null
&&
Objects
.
equals
(
id
,
that
.
id
);
return
getId
()
!=
null
&&
Objects
.
equals
(
getId
(),
that
.
getId
()
);
}
@Override
...
...
app/src/main/java/com/yiring/app/domain/location/LocationTagRepository.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
domain
.
location
;
import
java.io.Serializable
;
import
org.springframework.data.jpa.repository.JpaRepository
;
import
org.springframework.data.jpa.repository.JpaSpecificationExecutor
;
import
org.springframework.stereotype.Repository
;
/**
* 定位标签JPA
* @author LJ-2204
* @date 2022/4/14
*/
@Repository
public
interface
LocationTagRepository
extends
JpaRepository
<
LocationTag
,
Serializable
>,
JpaSpecificationExecutor
<
LocationTag
>
{}
app/src/main/java/com/yiring/app/domain/video/Video.java
浏览文件 @
f360f80d
...
...
@@ -46,27 +46,33 @@ public class Video implements Serializable {
@Comment
(
"坐标点信息"
)
Point
point
;
@Comment
(
"分类"
)
String
type
;
@Comment
(
"标识"
)
String
uuid
;
/**
* rtsp 地址
*/
@Comment
(
"rtsp 媒体地址"
)
String
rtsp
;
@Comment
(
"m3u8 地址"
)
String
m3u8
;
@Comment
(
"备注"
)
String
remark
;
@Comment
(
"创建时间"
)
LocalDateTime
createTime
;
@Comment
(
"状态"
)
String
status
;
@Comment
(
"摄像头名称"
)
String
videoName
;
@Comment
(
"分类"
)
String
type
;
@Comment
(
"rtsp 媒体地址"
)
String
rtsp
;
@Comment
(
"是否在线"
)
Boolean
online
;
@Comment
(
"是否启用"
)
Boolean
enable
;
@Comment
(
"创建时间"
)
LocalDateTime
createTime
;
}
app/src/main/java/com/yiring/app/domain/video/VideoRepository.java
浏览文件 @
f360f80d
...
...
@@ -3,6 +3,7 @@ package com.yiring.app.domain.video;
import
java.io.Serializable
;
import
org.springframework.data.jpa.repository.JpaRepository
;
import
org.springframework.data.jpa.repository.JpaSpecificationExecutor
;
import
org.springframework.stereotype.Repository
;
/**
...
...
@@ -12,4 +13,4 @@ import org.springframework.stereotype.Repository;
*/
@Repository
public
interface
VideoRepository
extends
JpaRepository
<
Video
,
Serializable
>
{}
public
interface
VideoRepository
extends
JpaRepository
<
Video
,
Serializable
>
,
JpaSpecificationExecutor
<
Video
>
{}
app/src/main/java/com/yiring/app/excel/location/LocationTagExportExcel.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
excel
.
location
;
import
com.fasterxml.jackson.databind.annotation.JsonSerialize
;
import
com.fasterxml.jackson.databind.ser.std.ToStringSerializer
;
import
com.github.liaochong.myexcel.core.annotation.ExcelColumn
;
import
com.github.liaochong.myexcel.core.annotation.ExcelModel
;
import
com.yiring.app.domain.location.LocationTag
;
import
java.io.Serializable
;
import
java.time.LocalDateTime
;
import
java.util.List
;
import
java.util.stream.Collectors
;
import
lombok.AccessLevel
;
import
lombok.Builder
;
import
lombok.Data
;
import
lombok.experimental.FieldDefaults
;
/**
* 定位标签导出模型
* @author LJ-2204
* @date 2022/4/14
*/
@ExcelModel
@Data
@Builder
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
LocationTagExportExcel
implements
Serializable
{
private
static
final
long
serialVersionUID
=
-
4549580878785078998L
;
@ExcelColumn
(
title
=
"主键"
)
@JsonSerialize
(
using
=
ToStringSerializer
.
class
)
Long
id
;
@ExcelColumn
(
title
=
"编号"
)
String
code
;
@ExcelColumn
(
title
=
"标签类型"
)
LocationTag
.
Type
type
;
@ExcelColumn
(
title
=
"状态"
)
Boolean
silent
;
@ExcelColumn
(
title
=
"imei"
)
String
imei
;
@ExcelColumn
(
title
=
"电量"
)
Integer
volt
;
@ExcelColumn
(
title
=
"最近更新时间"
)
LocalDateTime
updateTime
;
public
static
List
<
LocationTagExportExcel
>
transforms
(
List
<
LocationTag
>
locationTags
)
{
return
locationTags
.
stream
()
.
map
(
locationTag
->
LocationTagExportExcel
.
builder
()
.
id
(
locationTag
.
getId
())
.
code
(
locationTag
.
getCode
())
.
type
(
locationTag
.
getType
())
.
silent
(
locationTag
.
getSilent
())
.
imei
(
locationTag
.
getImei
())
.
volt
(
locationTag
.
getVolt
())
.
updateTime
(
locationTag
.
getUpdateTime
())
.
build
()
)
.
collect
(
Collectors
.
toList
());
}
}
app/src/main/java/com/yiring/app/excel/location/LocationTagImportExcel.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
excel
.
location
;
import
com.github.liaochong.myexcel.core.annotation.ExcelColumn
;
import
com.yiring.app.domain.location.LocationTag
;
import
java.io.Serializable
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
/**
* @author LJ-2204
* @date 2022/4/14
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
LocationTagImportExcel
implements
Serializable
{
private
static
final
long
serialVersionUID
=
-
8817732062049005201L
;
// 编号
@ExcelColumn
(
index
=
0
)
String
code
;
// 标签型号
@ExcelColumn
(
index
=
1
)
String
type
;
// 设备编码
@ExcelColumn
(
index
=
2
)
String
imei
;
public
LocationTag
transform
()
{
return
LocationTag
.
builder
().
code
(
this
.
code
).
type
(
LocationTag
.
Type
.
valueOf
(
this
.
type
)).
imei
(
this
.
imei
).
build
();
}
}
app/src/main/java/com/yiring/app/param/car/CarParam.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
param
.
car
;
import
com.yiring.common.constant.RegEx
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
javax.validation.constraints.NotEmpty
;
import
javax.validation.constraints.Pattern
;
import
javax.validation.constraints.Size
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
/**
* @author tzl
* 2022/4/11 14:00
*/
@ApiModel
(
"CarParam"
)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
CarParam
{
@ApiModelProperty
(
value
=
"车牌号码"
,
example
=
"湘A99999"
,
required
=
true
)
@NotEmpty
(
message
=
"车牌号码不能为空"
)
@Pattern
(
regexp
=
RegEx
.
CARNUM
,
message
=
"车牌号码格式不正确"
)
String
carNum
;
@ApiModelProperty
(
value
=
"车辆类型"
,
example
=
"1"
)
String
carType
;
@ApiModelProperty
(
value
=
"司机名称"
,
example
=
"张三"
,
required
=
true
)
@NotEmpty
(
message
=
"司机名称不能为空"
)
String
driverName
;
@ApiModelProperty
(
value
=
"司机电话"
,
example
=
"17688888888"
,
required
=
true
)
@NotEmpty
(
message
=
"司机电话不能为空"
)
@Pattern
(
regexp
=
RegEx
.
MOBILE
,
message
=
"手机号码格式不正确"
)
String
driverMobile
;
// @ApiModelProperty(value = "标签卡", example = "DW24515512")
// String labelCard;
//
// @ApiModelProperty(value = "标签卡状态", example = "使用中")
// String labelCardStatus;
@ApiModelProperty
(
value
=
"所属单位id"
,
example
=
"1"
,
required
=
true
)
@NotEmpty
(
message
=
"所属单位id不能为空"
)
String
orgId
;
@ApiModelProperty
(
value
=
"被访人id"
,
example
=
"1"
,
required
=
true
)
@NotEmpty
(
message
=
"被访人id不能为空"
)
String
intervieweeId
;
@ApiModelProperty
(
value
=
"来访原因"
,
example
=
"视察"
,
required
=
true
)
@NotEmpty
(
message
=
"来访原因不能为空"
)
@Size
(
min
=
1
,
max
=
20
,
message
=
"来访原因超出范围"
)
String
reason
;
// @ApiModelProperty(value = "收卡时间", example = "2022-04-11 17:25:33")
// LocalDateTime cardRecTime;
//
// @ApiModelProperty(value = "发卡时间", example = "2022-04-11 17:25:33")
// LocalDateTime cardSendTime;
// @ApiModelProperty(value = "创建时间", example = "")
// LocalDateTime createTime;
}
app/src/main/java/com/yiring/app/param/car/CarQueryParam.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
param
.
car
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
java.time.LocalDateTime
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
/**
* @author tzl
* 2022/4/12 11:11
*/
@ApiModel
(
"CarQueryParam"
)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
CarQueryParam
{
@ApiModelProperty
(
value
=
"每页记录数"
,
example
=
"10"
)
// @DecimalMin(value = "1", message = "分页条数不能小于1")
Integer
pageSize
;
@ApiModelProperty
(
value
=
"页码"
,
example
=
"1"
)
// @DecimalMin(value = "1", message = "页码不能小于1")
Integer
pageNo
;
@ApiModelProperty
(
value
=
"车牌号码"
,
example
=
"湘A12345"
)
String
carNum
;
@ApiModelProperty
(
value
=
"车辆类型"
,
example
=
"轿车"
)
String
carType
;
@ApiModelProperty
(
value
=
"司机名称"
,
example
=
"张三"
)
String
driverName
;
@ApiModelProperty
(
value
=
"司机电话"
,
example
=
"17688888888"
)
String
driverMobile
;
@ApiModelProperty
(
value
=
"标签卡"
,
example
=
"DW24515512"
)
String
labelCard
;
@ApiModelProperty
(
value
=
"标签卡状态"
,
example
=
"2"
)
String
labelCardStatus
;
@ApiModelProperty
(
value
=
"所属单位id"
,
example
=
"1"
)
String
orgId
;
@ApiModelProperty
(
value
=
"被访人id"
,
example
=
"1"
)
String
intervieweeId
;
@ApiModelProperty
(
value
=
"来访原因"
,
example
=
"视察"
)
String
reason
;
@ApiModelProperty
(
value
=
"收卡时间(开始)"
,
example
=
"2022-04-11 17:25:33"
)
LocalDateTime
cardRecTimeStart
;
@ApiModelProperty
(
value
=
"收卡时间(结束)"
,
example
=
"2022-04-11 17:26:33"
)
LocalDateTime
cardRecTimeEnd
;
@ApiModelProperty
(
value
=
"来访时间(开始)"
,
example
=
"2022-04-11 17:25:33"
)
LocalDateTime
createTimeStart
;
@ApiModelProperty
(
value
=
"来访时间(结束)"
,
example
=
"2022-04-11 17:26:33"
)
LocalDateTime
createTimeEnd
;
}
app/src/main/java/com/yiring/app/param/dict/DictParam.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
param
.
dict
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
javax.validation.constraints.NotEmpty
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
/**
* @author tzl
* 2022/4/13 15:51
*/
@ApiModel
(
"DictParam"
)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
DictParam
{
@ApiModelProperty
(
value
=
"排序"
,
example
=
"1"
,
required
=
true
)
Integer
dictSort
;
@ApiModelProperty
(
value
=
"字典标签"
,
example
=
"男"
,
required
=
true
)
@NotEmpty
(
message
=
"字典标签不能为空"
)
String
dictLabel
;
@ApiModelProperty
(
value
=
"字典值"
,
example
=
"1"
,
required
=
true
)
@NotEmpty
(
message
=
"字典值不能为空"
)
String
dictValue
;
@ApiModelProperty
(
value
=
"字典类型"
,
example
=
"user_sex"
,
required
=
true
)
@NotEmpty
(
message
=
"字典类型不能为空"
)
String
dictType
;
@ApiModelProperty
(
value
=
"是否启用"
,
example
=
"1"
,
required
=
true
)
@NotEmpty
(
message
=
"是否启用必填"
)
String
status
;
@ApiModelProperty
(
value
=
"备注"
,
example
=
"性别"
)
String
remark
;
}
app/src/main/java/com/yiring/app/param/dict/DictQueryParam.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
param
.
dict
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
/**
* @author tzl
* 2022/4/13 16:06
*/
@ApiModel
(
"DictQueryParam"
)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
DictQueryParam
{
@ApiModelProperty
(
value
=
"字典标签"
,
example
=
"男"
)
String
dictLabel
;
@ApiModelProperty
(
value
=
"字典类型"
,
example
=
"user_sex"
)
String
dictType
;
}
app/src/main/java/com/yiring/app/param/dict/DictTypeParam.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
param
.
dict
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
javax.validation.constraints.NotEmpty
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
/**
* @author tzl
* 2022/4/13 15:51
*/
@ApiModel
(
"DictParam"
)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
DictTypeParam
{
@ApiModelProperty
(
value
=
"字典名称"
,
example
=
"性别"
,
required
=
true
)
@NotEmpty
(
message
=
"字典名称不能为空"
)
String
dictName
;
@ApiModelProperty
(
value
=
"字典类型"
,
example
=
"user_sex"
,
required
=
true
)
@NotEmpty
(
message
=
"字典类型不能为空"
)
String
dictType
;
@ApiModelProperty
(
value
=
"是否启用"
,
example
=
"1"
,
required
=
true
)
@NotEmpty
(
message
=
"是否启用必填"
)
String
status
;
}
app/src/main/java/com/yiring/app/param/dict/DictTypeQueryParam.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
param
.
dict
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
/**
* @author tzl
* 2022/4/13 16:06
*/
@ApiModel
(
"DictQueryParam"
)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
DictTypeQueryParam
{
@ApiModelProperty
(
value
=
"字典名称"
,
example
=
"性别"
)
String
dictName
;
}
app/src/main/java/com/yiring/app/param/location/LocationTagAddParam.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
param
.
location
;
import
com.yiring.app.domain.location.LocationTag
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
java.io.Serializable
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
/**
* 定位标签新增入参
* @author LJ-2204
* @date 2022/4/14
*/
@ApiModel
(
"LocationTagAddParam"
)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
LocationTagAddParam
implements
Serializable
{
private
static
final
long
serialVersionUID
=
-
2942040230386389302L
;
@ApiModelProperty
(
value
=
"编号"
,
example
=
"BTT88888888"
,
required
=
true
)
String
code
;
@ApiModelProperty
(
value
=
"标签类型"
,
example
=
"蓝牙人员定位卡"
,
required
=
true
)
LocationTag
.
Type
type
;
@ApiModelProperty
(
value
=
"imei 设备编码标识"
,
example
=
"88888888"
)
String
imei
;
public
LocationTag
transform
()
{
return
LocationTag
.
builder
().
code
(
this
.
code
).
type
(
this
.
type
).
imei
(
this
.
imei
).
build
();
}
}
app/src/main/java/com/yiring/app/param/location/LocationTagDeleteParam.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
param
.
location
;
import
com.yiring.auth.domain.user.User
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
java.io.Serializable
;
import
javax.validation.constraints.NotNull
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
/**
* 定位标签销毁入参
* @author LJ-2204
* @date 2022/4/14
*/
@ApiModel
(
"LocationTagDeleteParam"
)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
LocationTagDeleteParam
implements
Serializable
{
private
static
final
long
serialVersionUID
=
2404060244461070885L
;
@ApiModelProperty
(
value
=
"id"
,
example
=
"145235231"
,
required
=
true
)
@NotNull
(
message
=
"id 不能为空"
)
Long
id
;
@ApiModelProperty
(
value
=
"人员"
,
example
=
"1"
)
User
user
;
}
app/src/main/java/com/yiring/app/param/location/LocationTagFindParam.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
param
.
location
;
import
com.yiring.app.domain.location.LocationTag
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
java.io.Serializable
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
/**
* 定位标签分页入参
* @author LJ-2204
* @date 2022/4/14
*/
@ApiModel
(
"LocationTagFindParam"
)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
LocationTagFindParam
implements
Serializable
{
private
static
final
long
serialVersionUID
=
-
5134311481372693111L
;
@ApiModelProperty
(
value
=
"编号"
,
example
=
"BTT88888888"
)
String
code
;
@ApiModelProperty
(
value
=
"标签类型"
,
example
=
"蓝牙人员定位卡"
)
LocationTag
.
Type
type
;
@ApiModelProperty
(
value
=
"状态"
,
example
=
"true"
)
Boolean
silent
;
@ApiModelProperty
(
value
=
"每页记录数"
,
example
=
"10"
)
Integer
pageSize
;
@ApiModelProperty
(
value
=
"页码"
,
example
=
"1"
)
Integer
pageNo
;
}
app/src/main/java/com/yiring/app/param/location/LocationTagModifyParam.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
param
.
location
;
import
com.yiring.app.domain.location.LocationTag
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
java.io.Serializable
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
/**
* 定位标签修改入参
* @author LJ-2204
* @date 2022/4/14
*/
@ApiModel
(
"LocationTagModifyParam"
)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
LocationTagModifyParam
implements
Serializable
{
private
static
final
long
serialVersionUID
=
7711908393372149723L
;
@ApiModelProperty
(
value
=
"编号"
,
example
=
"BTT88888888"
,
required
=
true
)
String
code
;
@ApiModelProperty
(
value
=
"标签类型"
,
example
=
"蓝牙人员定位卡"
,
required
=
true
)
LocationTag
.
Type
type
;
@ApiModelProperty
(
value
=
"imei 设备编码标识"
,
example
=
"88888888"
)
String
imei
;
public
LocationTag
transform
()
{
return
LocationTag
.
builder
().
code
(
this
.
code
).
type
(
this
.
type
).
imei
(
this
.
imei
).
build
();
}
}
app/src/main/java/com/yiring/app/param/location/zy/ZyLocationTagAddParam.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
param
.
location
.
zy
;
import
cn.hutool.core.util.StrUtil
;
import
com.yiring.app.domain.location.LocationTag
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
java.io.Serializable
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
/**
* zy定位标签新增入参
* @author LJ-2204
* @date 2022/4/15
*/
@ApiModel
(
"ZyLocationTagAddParam"
)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
ZyLocationTagAddParam
implements
Serializable
{
private
static
final
long
serialVersionUID
=
-
8828137320896062620L
;
@ApiModelProperty
(
value
=
"工厂"
,
example
=
"100"
)
String
orgId
;
@ApiModelProperty
(
value
=
"标签类型"
,
example
=
"蓝牙人员定位卡"
,
required
=
true
)
LocationTag
.
Type
types
;
@ApiModelProperty
(
value
=
"编号"
,
example
=
"BTT88888888"
,
required
=
true
)
String
tagId
;
@ApiModelProperty
(
value
=
"实体类型"
,
example
=
"car"
,
required
=
true
)
String
entityType
;
public
static
ZyLocationTagAddParam
transform
(
LocationTag
locationTag
)
{
String
entityType
=
StrUtil
.
equals
(
locationTag
.
getType
().
name
(),
"BTT02"
)
?
"car"
:
"staff"
;
return
ZyLocationTagAddParam
.
builder
()
.
orgId
(
"100"
)
.
tagId
(
locationTag
.
getCode
())
.
types
(
locationTag
.
getType
())
.
entityType
(
entityType
)
.
build
();
}
}
app/src/main/java/com/yiring/app/param/video/VideoParam.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
param
.
video
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
java.io.Serializable
;
import
javax.validation.constraints.NotEmpty
;
import
javax.validation.constraints.Size
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
/**
* 监控视频入参类
*
* @author tzl
* 2022/4/8 16:07
*/
@ApiModel
(
"VideoParam"
)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
VideoParam
implements
Serializable
{
@ApiModelProperty
(
value
=
"编号"
,
example
=
"88888888"
,
required
=
true
)
@NotEmpty
(
message
=
"标识不能为空"
)
String
uuid
;
@ApiModelProperty
(
value
=
"m3u8 媒体地址"
,
example
=
""
,
required
=
true
)
@NotEmpty
(
message
=
"m3u8 媒体地址不能为空"
)
String
m3u8
;
@ApiModelProperty
(
value
=
"摄像头名称"
,
example
=
"摄像头1"
,
required
=
true
)
@NotEmpty
(
message
=
"摄像头名称不能为空"
)
String
videoName
;
@ApiModelProperty
(
value
=
"经度"
,
example
=
"1"
,
required
=
true
)
@NotEmpty
(
message
=
"经度"
)
double
lon
;
@ApiModelProperty
(
value
=
"纬度"
,
example
=
"1"
,
required
=
true
)
@NotEmpty
(
message
=
"纬度"
)
double
lat
;
@ApiModelProperty
(
value
=
"备注"
,
example
=
"厂区摄像头"
)
@Size
(
max
=
100
,
message
=
"备注不能超过100字"
)
String
remark
;
// @ApiModelProperty(value = "m3u8 地址", example = "")
// @NotEmpty(message = "m3u8 地址不能为空")
// String m3u8;
// Point point;
// @ApiModelProperty(value = "分类", example = "")
// String type;
// @ApiModelProperty(value = "是否在线", example = "")
// Boolean online;
// @ApiModelProperty(value = "是否启用", example = "")
// Boolean enable;
}
app/src/main/java/com/yiring/app/param/video/VideoQueryParam.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
param
.
video
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
java.io.Serializable
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
/**
* 监控视频入参类
*
* @author tzl
* 2022/4/8 16:07
*/
@ApiModel
(
"VideoQueryParam"
)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
VideoQueryParam
implements
Serializable
{
@ApiModelProperty
(
value
=
"编号"
,
example
=
"88888888"
)
String
uuid
;
@ApiModelProperty
(
value
=
"摄像头名称"
,
example
=
"摄像头1"
)
String
videoName
;
@ApiModelProperty
(
value
=
"状态"
,
example
=
"1"
)
String
status
;
// @ApiModelProperty(value = "m3u8 地址", example = "")
// @NotEmpty(message = "m3u8 地址不能为空")
// String m3u8;
// Point point;
// @ApiModelProperty(value = "分类", example = "")
// String type;
// @ApiModelProperty(value = "是否在线", example = "")
// Boolean online;
// @ApiModelProperty(value = "是否启用", example = "")
// Boolean enable;
}
app/src/main/java/com/yiring/app/rabbit/config/RabbitConfig.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
rabbit
.
config
;
import
javax.annotation.Resource
;
import
org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory
;
import
org.springframework.amqp.rabbit.connection.CachingConnectionFactory
;
import
org.springframework.amqp.rabbit.connection.ConnectionFactory
;
import
org.springframework.amqp.rabbit.core.RabbitTemplate
;
import
org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory
;
import
org.springframework.beans.factory.annotation.Qualifier
;
import
org.springframework.boot.autoconfigure.amqp.RabbitProperties
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Primary
;
/**
* rabbitmq配置
*
* @author ifzm
* 2019/8/21 15:44
*/
@Configuration
public
class
RabbitConfig
{
@Resource
RabbitProperties
rabbitProperties
;
private
static
final
String
CONNECTION_FACTORY_NAME
=
"rabbitConnectionFactory"
;
@Bean
(
CONNECTION_FACTORY_NAME
)
@Primary
public
ConnectionFactory
connectionFactory
()
{
return
RabbitConfig
.
connectionFactory
(
rabbitProperties
.
getHost
(),
rabbitProperties
.
getPort
(),
rabbitProperties
.
getUsername
(),
rabbitProperties
.
getPassword
(),
rabbitProperties
.
getVirtualHost
()
);
}
@Bean
@Primary
public
RabbitListenerContainerFactory
<?>
rabbitListenerContainerFactory
(
@Qualifier
(
CONNECTION_FACTORY_NAME
)
ConnectionFactory
connectionFactory
)
{
SimpleRabbitListenerContainerFactory
factory
=
new
SimpleRabbitListenerContainerFactory
();
factory
.
setConnectionFactory
(
connectionFactory
);
return
factory
;
}
@Bean
@Primary
public
RabbitTemplate
rabbitTemplate
(
@Qualifier
(
CONNECTION_FACTORY_NAME
)
ConnectionFactory
connectionFactory
)
{
return
new
RabbitTemplate
(
connectionFactory
);
}
/**
* 创建连接工厂
*
* @param host 主机
* @param port 端口
* @param username 用户名
* @param password 密码
* @param virtualHost 虚拟主机
* @return 连接工厂
*/
public
static
CachingConnectionFactory
connectionFactory
(
String
host
,
int
port
,
String
username
,
String
password
,
String
virtualHost
)
{
CachingConnectionFactory
connectionFactory
=
new
CachingConnectionFactory
();
connectionFactory
.
setHost
(
host
);
connectionFactory
.
setPort
(
port
);
connectionFactory
.
setUsername
(
username
);
connectionFactory
.
setPassword
(
password
);
connectionFactory
.
setVirtualHost
(
virtualHost
);
return
connectionFactory
;
}
}
app/src/main/java/com/yiring/app/
config/zy
/ZyConfigProperties.java
→
app/src/main/java/com/yiring/app/
rabbit/config
/ZyConfigProperties.java
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
config
.
zy
;
package
com
.
yiring
.
app
.
rabbit
.
config
;
import
javax.annotation.Resource
;
import
lombok.AccessLevel
;
...
...
app/src/main/java/com/yiring/app/
config/zy
/ZyRabbitConfig.java
→
app/src/main/java/com/yiring/app/
rabbit/config
/ZyRabbitConfig.java
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
config
.
zy
;
package
com
.
yiring
.
app
.
rabbit
.
config
;
import
javax.annotation.Resource
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.amqp.core.AcknowledgeMode
;
import
org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory
;
import
org.springframework.amqp.rabbit.connection.CachingConnectionFactory
;
import
org.springframework.amqp.rabbit.connection.ConnectionFactory
;
import
org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory
;
import
org.springframework.beans.factory.annotation.Qualifier
;
import
org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
;
...
...
@@ -43,8 +44,8 @@ public class ZyRabbitConfig {
public
static
final
String
MESSAGE_QUEUES_NAME
=
"tenant_msg_12A14FDC_sc21080400"
;
@Bean
(
CONNECTION_FACTORY_NAME
)
public
C
achingC
onnectionFactory
zyConnectionFactory
()
{
return
connectionFactory
(
public
ConnectionFactory
zyConnectionFactory
()
{
return
RabbitConfig
.
connectionFactory
(
rabbitmq
.
getHost
(),
rabbitmq
.
getPort
(),
rabbitmq
.
getUsername
(),
...
...
@@ -54,9 +55,9 @@ public class ZyRabbitConfig {
}
@Bean
(
LISTENER_FACTORY_NAME
)
public
SimpleRabbitListenerContainerFactory
second
Factory
(
public
RabbitListenerContainerFactory
<?>
rabbitListenerContainer
Factory
(
SimpleRabbitListenerContainerFactoryConfigurer
configurer
,
@Qualifier
(
CONNECTION_FACTORY_NAME
)
C
achingC
onnectionFactory
connectionFactory
@Qualifier
(
CONNECTION_FACTORY_NAME
)
ConnectionFactory
connectionFactory
)
{
// 检查队列名称是否与配置文件一致,避免监听错误
if
(!
MESSAGE_QUEUES_NAME
.
equals
(
rabbitmq
.
getQueueName
()))
{
...
...
@@ -66,31 +67,9 @@ public class ZyRabbitConfig {
}
SimpleRabbitListenerContainerFactory
factory
=
new
SimpleRabbitListenerContainerFactory
();
// 最小消费者数量
factory
.
setConcurrentConsumers
(
1
);
// 最大消费者数量
factory
.
setMaxConcurrentConsumers
(
1
);
// 预读取一条消息
factory
.
setPrefetchCount
(
1
);
// 手动确认消息模式
factory
.
setAcknowledgeMode
(
AcknowledgeMode
.
MANUAL
);
configurer
.
configure
(
factory
,
connectionFactory
);
return
factory
;
}
public
CachingConnectionFactory
connectionFactory
(
String
host
,
int
port
,
String
username
,
String
password
,
String
virtualHost
)
{
CachingConnectionFactory
connectionFactory
=
new
CachingConnectionFactory
();
connectionFactory
.
setHost
(
host
);
connectionFactory
.
setPort
(
port
);
connectionFactory
.
setUsername
(
username
);
connectionFactory
.
setPassword
(
password
);
connectionFactory
.
setVirtualHost
(
virtualHost
);
return
connectionFactory
;
}
}
app/src/main/java/com/yiring/app/rabbit
mq
/RabbitReceiver.java
→
app/src/main/java/com/yiring/app/rabbit
/receiver
/RabbitReceiver.java
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
rabbit
mq
;
package
com
.
yiring
.
app
.
rabbit
.
receiver
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Component
;
...
...
app/src/main/java/com/yiring/app/rabbit
mq/zy/ZyRabbitmq
Receiver.java
→
app/src/main/java/com/yiring/app/rabbit
/receiver/ZyRabbit
Receiver.java
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
rabbit
mq
.
zy
;
package
com
.
yiring
.
app
.
rabbit
.
receiver
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.rabbitmq.client.Channel
;
import
com.yiring.app.config.zy.ZyRabbitConfig
;
import
com.yiring.app.push.domain.PushMessage
;
import
com.yiring.app.push.service.PushService
;
import
com.yiring.app.rabbit.config.ZyRabbitConfig
;
import
java.io.IOException
;
import
javax.annotation.Resource
;
import
lombok.extern.slf4j.Slf4j
;
...
...
@@ -15,6 +14,7 @@ import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import
org.springframework.amqp.rabbit.annotation.RabbitListener
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.messaging.simp.SimpMessagingTemplate
;
import
org.springframework.stereotype.Component
;
import
org.springframework.transaction.annotation.Transactional
;
...
...
@@ -30,7 +30,7 @@ import org.springframework.transaction.annotation.Transactional;
@Component
@Configuration
@ConditionalOnProperty
(
prefix
=
"zy-config.rabbitmq"
,
value
=
"enabled"
,
havingValue
=
"true"
)
public
class
ZyRabbit
mq
Receiver
{
public
class
ZyRabbitReceiver
{
// TODO
// 1. 新增消息订阅定时任务,检查是否正常订阅了真源定位系统的消息
...
...
@@ -40,6 +40,9 @@ public class ZyRabbitmqReceiver {
@Resource
PushService
pushService
;
@Resource
SimpMessagingTemplate
simpMessagingTemplate
;
/**
* 订阅真源定位系统 RabbitMQ 推送过来的消息(主动订阅的一些消息类别)
* 参见: 定位平台接口规范V3.0.1 - 通用版.pdf #6
...
...
@@ -74,6 +77,8 @@ public class ZyRabbitmqReceiver {
case
"deviceStatus"
->
processDeviceStatusMessage
(
data
);
// 按键报警
case
"keyWarning"
->
processKeyWarningMessage
(
data
);
// 围栏报警
case
"enclosure"
->
log
.
warn
(
"Ignore Message Type [enclosure]: {}"
,
info
);
default
->
log
.
warn
(
"Unknown Message Type: {}"
,
info
);
}
}
catch
(
Exception
e
)
{
...
...
@@ -95,9 +100,10 @@ public class ZyRabbitmqReceiver {
// 1. 解析消息内容,进行围栏、出入标识判断等处理,将定位记录录入数据库
// 2. 创建一条需要进行消息推送的记录
// 3. 将记录推送的消息推送模块
// 4. 坚持是否触发围栏告警,记录告警数据,并推送消息
// WebSocket 消息推送
pushService
.
push
(
PushMessage
.
Type
.
WS
,
data
);
simpMessagingTemplate
.
convertAndSend
(
"/topic/position"
,
data
);
}
/**
...
...
app/src/main/java/com/yiring/app/rabbitmq/RabbitConfig.java
deleted
100644 → 0
浏览文件 @
f490012a
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
rabbitmq
;
import
org.springframework.context.annotation.Configuration
;
/**
* rabbitmq配置
*
* @author ifzm
* 2019/8/21 15:44
*/
@Configuration
public
class
RabbitConfig
{}
app/src/main/java/com/yiring/app/service/car/CarService.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
service
.
car
;
import
com.yiring.app.domain.car.Car
;
import
com.yiring.app.param.car.CarParam
;
import
com.yiring.app.param.car.CarQueryParam
;
import
com.yiring.app.vo.car.CarVo
;
import
com.yiring.common.core.Result
;
import
com.yiring.common.param.IdParam
;
import
com.yiring.common.vo.PageVo
;
import
java.util.List
;
import
org.springframework.data.jpa.domain.Specification
;
/**
* @author tzl
* 2022/4/11 13:57
*/
public
interface
CarService
{
/**
* 添加车辆来访信息
*
* @param carParam CarParam
* @return 车辆来访信息id
*/
Result
<
Long
>
saveCarInfo
(
CarParam
carParam
);
/**
* 修改车辆来访信息
*
* @param carParam CarParam
* @return 修改的车辆来访信息id
*/
Result
<
Long
>
updateCarInfo
(
CarParam
carParam
,
IdParam
idParam
);
/**
* 收卡
*
* @param idParam IdParam
* @return 收卡信息id
*/
Result
<
Long
>
cardRec
(
IdParam
idParam
);
/**
* 发卡
*
* @param idParam IdParam
* @return 发卡信息id
*/
Result
<
Long
>
cardSend
(
IdParam
idParam
,
String
labelCard
);
/**
* 删除车辆来访信息
*
* @param idParam IdParam
* @return String
*/
Result
<
String
>
deleteCarInfo
(
IdParam
idParam
);
/**
* 查询车辆来访信息详情
*
* @param idParam IdParam
* @return 车辆来访信息
*/
Result
<
CarVo
>
getCarInfo
(
IdParam
idParam
);
/**
* 查询车辆来访信息(分页)
*
* @param carParam CarParam
* @return 车辆来访信息分页数据
*/
Result
<
PageVo
<
CarVo
>>
pageCarInfo
(
CarQueryParam
carParam
);
/**
* 导出excel
*/
List
<
Car
>
export
(
CarQueryParam
carParam
);
/**
* 检查是否存在相同车牌号登记
*
* @param param String 车牌号码
* @return 是否存在
*/
boolean
hasCarInfoByCarNum
(
String
param
);
/**
* 检查是否存在相同手机号码登记
*
* @param param String 手机号码
* @return 是否存在
*/
boolean
hasCarInfoByMobile
(
String
param
);
/**
* @param carParam CarQueryParam
* @return Specification
*/
Specification
<
Car
>
condition
(
CarQueryParam
carParam
);
}
app/src/main/java/com/yiring/app/service/car/impl/CarServiceImpl.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
service
.
car
.
impl
;
import
cn.hutool.core.util.StrUtil
;
import
com.yiring.app.domain.car.Car
;
import
com.yiring.app.domain.car.CarRepository
;
import
com.yiring.app.param.car.CarParam
;
import
com.yiring.app.param.car.CarQueryParam
;
import
com.yiring.app.service.car.CarService
;
import
com.yiring.app.vo.car.CarVo
;
import
com.yiring.auth.domain.role.Role
;
import
com.yiring.common.core.Result
;
import
com.yiring.common.core.Status
;
import
com.yiring.common.param.IdParam
;
import
com.yiring.common.vo.PageVo
;
import
java.time.LocalDateTime
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Objects
;
import
java.util.Optional
;
import
java.util.stream.Collectors
;
import
javax.annotation.Resource
;
import
javax.persistence.criteria.Predicate
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.data.domain.*
;
import
org.springframework.data.jpa.domain.Specification
;
import
org.springframework.stereotype.Service
;
/**
* @author tzl
* 2022/4/11 13:58
*/
@Service
public
class
CarServiceImpl
implements
CarService
{
@Resource
CarRepository
carRepository
;
@Override
public
Result
<
Long
>
saveCarInfo
(
CarParam
carParam
)
{
// 检查车牌号是否已存在
if
(
hasCarInfoByCarNum
(
carParam
.
getCarNum
()))
{
return
Result
.
no
(
Status
.
BAD_REQUEST
,
"您的车牌号已预约登记"
);
}
// 检查司机手机号码号是否已存在
if
(
hasCarInfoByMobile
(
carParam
.
getDriverMobile
()))
{
return
Result
.
no
(
Status
.
BAD_REQUEST
,
"您的联系方式已预约登记"
);
}
Car
car
=
Car
.
builder
()
.
labelCardStatus
(
"1"
)
.
carNum
(
carParam
.
getCarNum
())
.
carType
(
carParam
.
getCarType
())
.
driverMobile
(
carParam
.
getDriverMobile
())
.
driverName
(
carParam
.
getDriverName
())
.
intervieweeId
(
carParam
.
getIntervieweeId
())
.
orgId
(
carParam
.
getOrgId
())
.
reason
(
carParam
.
getReason
())
.
createTime
(
LocalDateTime
.
now
())
.
build
();
Car
carReuslt
=
carRepository
.
saveAndFlush
(
car
);
return
Result
.
ok
(
carReuslt
.
getId
());
}
@Override
public
Result
<
Long
>
updateCarInfo
(
CarParam
carParam
,
IdParam
idParam
)
{
Optional
<
Car
>
optional
=
carRepository
.
findById
(
idParam
.
getId
());
if
(
optional
.
isEmpty
())
{
return
Result
.
no
(
Status
.
NOT_FOUND
);
}
Car
car
=
optional
.
get
();
//如果标签卡在使用中无法修改
if
(
StrUtil
.
isNotBlank
(
car
.
getLabelCardStatus
())
&&
"2"
.
equals
(
car
.
getLabelCardStatus
()))
{
return
Result
.
no
(
Status
.
BAD_REQUEST
,
"标签卡使用中,信息无法修改"
);
}
if
(!
car
.
getCarNum
().
equals
(
carParam
.
getCarNum
()))
{
// 当修改车牌号时才检查重复
if
(
hasCarInfoByCarNum
(
carParam
.
getCarNum
()))
{
return
Result
.
no
(
Status
.
BAD_REQUEST
,
"您的车牌号已预约登记"
);
}
}
if
(!
car
.
getDriverMobile
().
equals
(
carParam
.
getDriverMobile
()))
{
// 当修改联系方式时才检查重复
if
(
hasCarInfoByMobile
(
carParam
.
getDriverMobile
()))
{
return
Result
.
no
(
Status
.
BAD_REQUEST
,
"您的联系方式已预约登记"
);
}
}
BeanUtils
.
copyProperties
(
carParam
,
car
);
Car
carReuslt
=
carRepository
.
saveAndFlush
(
car
);
return
Result
.
ok
(
carReuslt
.
getId
());
}
@Override
public
Result
<
Long
>
cardRec
(
IdParam
idParam
)
{
Optional
<
Car
>
optional
=
carRepository
.
findById
(
idParam
.
getId
());
if
(
optional
.
isEmpty
())
{
return
Result
.
no
(
Status
.
NOT_FOUND
);
}
Car
car
=
optional
.
get
();
car
.
setLabelCardStatus
(
"3"
);
car
.
setCardRecTime
(
LocalDateTime
.
now
());
Car
carReuslt
=
carRepository
.
saveAndFlush
(
car
);
return
Result
.
ok
(
carReuslt
.
getId
());
}
@Override
public
Result
<
Long
>
cardSend
(
IdParam
idParam
,
String
labelCard
)
{
Optional
<
Car
>
optional
=
carRepository
.
findById
(
idParam
.
getId
());
if
(
optional
.
isEmpty
())
{
return
Result
.
no
(
Status
.
NOT_FOUND
);
}
Car
car
=
optional
.
get
();
car
.
setLabelCardStatus
(
"2"
);
car
.
setCardSendTime
(
LocalDateTime
.
now
());
car
.
setLabelCard
(
labelCard
);
Car
carReuslt
=
carRepository
.
saveAndFlush
(
car
);
return
Result
.
ok
(
carReuslt
.
getId
());
}
@Override
public
Result
<
String
>
deleteCarInfo
(
IdParam
idParam
)
{
Optional
<
Car
>
optional
=
carRepository
.
findById
(
idParam
.
getId
());
if
(
optional
.
isEmpty
())
{
return
Result
.
no
(
Status
.
NOT_FOUND
);
}
//正在使用中的信息无法删除
Car
entity
=
optional
.
get
();
if
(
"2"
.
equals
(
entity
.
getLabelCardStatus
()))
{
return
Result
.
no
(
Status
.
BAD_REQUEST
,
"标签卡使用中,信息无法删除"
);
}
carRepository
.
delete
(
entity
);
return
Result
.
ok
();
}
@Override
public
Result
<
CarVo
>
getCarInfo
(
IdParam
idParam
)
{
Optional
<
Car
>
optional
=
carRepository
.
findById
(
idParam
.
getId
());
if
(
optional
.
isEmpty
())
{
return
Result
.
no
(
Status
.
NOT_FOUND
);
}
Car
entity
=
optional
.
get
();
CarVo
vo
=
new
CarVo
();
BeanUtils
.
copyProperties
(
entity
,
vo
,
Role
.
Fields
.
permissions
);
return
Result
.
ok
(
vo
);
}
@Override
public
Result
<
PageVo
<
CarVo
>>
pageCarInfo
(
CarQueryParam
carParam
)
{
PageVo
<
CarVo
>
resultVo
=
null
;
//排序
Sort
sort
=
Sort
.
by
(
Sort
.
Order
.
desc
(
Car
.
Fields
.
createTime
));
//如果传分页参数则分页,否查全部数据
if
(
Objects
.
nonNull
(
carParam
.
getPageNo
())
&&
Objects
.
nonNull
(
carParam
.
getPageSize
()))
{
//分页
Pageable
pageable
=
PageRequest
.
of
(
carParam
.
getPageNo
()
-
1
,
carParam
.
getPageSize
());
Page
<
Car
>
all
=
carRepository
.
findAll
(
condition
(
carParam
),
pageable
);
List
<
CarVo
>
data
=
all
.
get
()
.
map
(
car
->
{
CarVo
vo
=
new
CarVo
();
BeanUtils
.
copyProperties
(
car
,
vo
);
return
vo
;
})
.
collect
(
Collectors
.
toList
());
resultVo
=
PageVo
.
build
(
data
,
all
.
getTotalElements
());
}
else
{
List
<
Car
>
all
=
carRepository
.
findAll
(
condition
(
carParam
),
sort
);
List
<
CarVo
>
data
=
all
.
stream
()
.
map
(
car
->
{
CarVo
vo
=
new
CarVo
();
BeanUtils
.
copyProperties
(
car
,
vo
);
return
vo
;
})
.
collect
(
Collectors
.
toList
());
resultVo
=
PageVo
.
build
(
data
,
data
.
size
());
}
return
Result
.
ok
(
resultVo
);
}
@Override
public
List
<
Car
>
export
(
CarQueryParam
carParam
)
{
return
carRepository
.
findAll
(
condition
(
carParam
));
}
@Override
public
boolean
hasCarInfoByCarNum
(
String
param
)
{
Car
entity
=
Car
.
builder
().
carNum
(
param
).
labelCardStatus
(
"1"
).
build
();
long
count
=
carRepository
.
count
(
Example
.
of
(
entity
));
entity
=
Car
.
builder
().
carNum
(
param
).
labelCardStatus
(
"2"
).
build
();
long
count1
=
carRepository
.
count
(
Example
.
of
(
entity
));
return
count
+
count1
>
0
;
}
@Override
public
boolean
hasCarInfoByMobile
(
String
param
)
{
Car
entity
=
Car
.
builder
().
driverMobile
(
param
).
labelCardStatus
(
"1"
).
build
();
long
count
=
carRepository
.
count
(
Example
.
of
(
entity
));
entity
=
Car
.
builder
().
driverMobile
(
param
).
labelCardStatus
(
"2"
).
build
();
long
count1
=
carRepository
.
count
(
Example
.
of
(
entity
));
return
count
+
count1
>
0
;
}
@Override
public
Specification
<
Car
>
condition
(
CarQueryParam
carParam
)
{
return
(
root
,
query
,
criteriaBuilder
)
->
{
List
<
Predicate
>
list
=
new
ArrayList
<>();
//查询条件
if
(
StrUtil
.
isNotBlank
(
carParam
.
getCarNum
()))
{
//车牌号码查询
list
.
add
(
criteriaBuilder
.
like
(
root
.
get
(
Car
.
Fields
.
carNum
),
"%"
+
carParam
.
getCarNum
()
+
"%"
));
}
if
(
StrUtil
.
isNotBlank
(
carParam
.
getCarType
()))
{
//车辆类型查询
list
.
add
(
criteriaBuilder
.
like
(
root
.
get
(
"carType"
).
as
(
String
.
class
),
"%"
+
carParam
.
getCarType
()
+
"%"
));
}
if
(
StrUtil
.
isNotBlank
(
carParam
.
getDriverName
()))
{
//司机名称查询
list
.
add
(
criteriaBuilder
.
like
(
root
.
get
(
"driverName"
).
as
(
String
.
class
),
"%"
+
carParam
.
getDriverName
()
+
"%"
)
);
}
if
(
StrUtil
.
isNotBlank
(
carParam
.
getDriverMobile
()))
{
//司机电话号码查询
list
.
add
(
criteriaBuilder
.
like
(
root
.
get
(
"driverMobile"
).
as
(
String
.
class
),
"%"
+
carParam
.
getDriverMobile
()
+
"%"
)
);
}
if
(
StrUtil
.
isNotBlank
(
carParam
.
getOrgId
()))
{
//所属单位查询
list
.
add
(
criteriaBuilder
.
like
(
root
.
get
(
"orgId"
).
as
(
String
.
class
),
"%"
+
carParam
.
getOrgId
()
+
"%"
));
}
if
(
StrUtil
.
isNotBlank
(
carParam
.
getReason
()))
{
//来访原因查询
list
.
add
(
criteriaBuilder
.
like
(
root
.
get
(
"reason"
).
as
(
String
.
class
),
"%"
+
carParam
.
getReason
()
+
"%"
));
}
if
(
Objects
.
nonNull
(
carParam
.
getCreateTimeStart
())
&&
Objects
.
nonNull
(
carParam
.
getCreateTimeEnd
()))
{
//来访时间区间段查询
list
.
add
(
criteriaBuilder
.
between
(
root
.
get
(
Car
.
Fields
.
createTime
),
carParam
.
getCreateTimeStart
(),
carParam
.
getCreateTimeEnd
()
)
);
}
if
(
StrUtil
.
isNotBlank
(
carParam
.
getLabelCard
()))
{
//标签卡号查询
list
.
add
(
criteriaBuilder
.
like
(
root
.
get
(
"labelCard"
).
as
(
String
.
class
),
"%"
+
carParam
.
getLabelCard
()
+
"%"
)
);
}
if
(
StrUtil
.
isNotBlank
(
carParam
.
getLabelCardStatus
()))
{
//标签卡状态查询
list
.
add
(
criteriaBuilder
.
equal
(
root
.
get
(
"labelCardStatus"
).
as
(
String
.
class
),
carParam
.
getLabelCardStatus
())
);
}
if
(
Objects
.
nonNull
(
carParam
.
getCardRecTimeStart
())
&&
Objects
.
nonNull
(
carParam
.
getCardRecTimeEnd
()))
{
//来访时间区间段查询
list
.
add
(
criteriaBuilder
.
between
(
root
.
get
(
Car
.
Fields
.
cardRecTime
),
carParam
.
getCardRecTimeStart
(),
carParam
.
getCardRecTimeEnd
()
)
);
}
Predicate
[]
predicates
=
new
Predicate
[
list
.
size
()];
query
.
where
(
list
.
toArray
(
predicates
));
return
criteriaBuilder
.
and
(
list
.
toArray
(
predicates
));
};
}
}
app/src/main/java/com/yiring/app/service/dict/DictService.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
service
.
dict
;
import
com.yiring.app.param.dict.DictParam
;
import
com.yiring.app.param.dict.DictQueryParam
;
import
com.yiring.common.core.Result
;
import
com.yiring.common.dict.Dict
;
import
com.yiring.common.param.IdParam
;
import
com.yiring.common.param.PageParam
;
import
com.yiring.common.vo.PageVo
;
import
java.util.ArrayList
;
/**
* 字典
*
* @author tzl
* 2022/4/13 15:36
*/
public
interface
DictService
{
/**
* 根据条件分页查询字典数据
*
* @param dictQueryParam DictQueryParam
* @return 字典数据集合信息
*/
Result
<
PageVo
<
Dict
>>
pageDictInfo
(
DictQueryParam
dictQueryParam
,
PageParam
param
);
/**
* 根据字典类型和字典键值查询字典数据信息
*
* @param dictType String
* @param dictValue String
* @return 字典标签
*/
Result
<
String
>
selectDictLabel
(
String
dictType
,
String
dictValue
);
/**
* 从缓存中获取字典
*
* @param dictType 字典类型
* @return 字典数据集合
*/
Result
<
ArrayList
<
Dict
>>
selectDict
(
String
dictType
);
/**
* 根据字典数据ID查询信息
*
* @param id Long
* @return 字典数据
*/
Result
<
Dict
>
getDictInfo
(
Long
id
);
/**
* 删除字典数据信息
*
* @param idParam 主键id
*/
Result
<
String
>
deleteDictById
(
IdParam
idParam
);
/**
* 新增字典数据信息
*
* @param dictParam 字典数据信息入参
* @return 结果
*/
Result
<
String
>
saveDictInfo
(
DictParam
dictParam
);
/**
* 修改字典数据信息
*
* @param idParam 主键id
* @param dictParam 字典数据信息入参
* @return 结果
*/
Result
<
String
>
updateDictInfo
(
DictParam
dictParam
,
IdParam
idParam
);
/**
* 是否已有该字典标签
*
* @param param String
* @return 是否存在
*/
boolean
has
(
String
param
);
/**
* 是否该类型字典已有该字典值
*
* @param dictType String
* @param dictValue String
* @return 是否存在
*/
boolean
hasValue
(
String
dictType
,
String
dictValue
);
/**
* 加载字典缓存
*/
void
loadingDictCache
();
}
app/src/main/java/com/yiring/app/service/dict/DictTypeService.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
service
.
dict
;
/**
* @author tzl
* 2022/4/14 14:10
*/
public
interface
DictTypeService
{
// /**
// * 根据条件分页查询字典类型
// *
// * @param dictTypeQueryParam DictTypeQueryParam
// * @return 字典类型分页信息
// */
// Result<PageVo<DictType>> pageDictTypeInfo(DictTypeQueryParam dictTypeQueryParam, PageParam param);
//
// Result<DictType> getDictTypeInfo(Long id);
//
// Result<String> delecteById(Long id);
//
// Result<String> saveDictTypeInfo(DictTypeParam dictTypeParam);
//
// Result<String> updateDictTypeInfo(DictTypeParam dictTypeParam, IdParam idParam);
//
// boolean has(String param);
}
app/src/main/java/com/yiring/app/service/dict/impl/DictServiceImpl.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
service
.
dict
.
impl
;
import
cn.hutool.core.util.StrUtil
;
import
com.yiring.app.param.dict.DictParam
;
import
com.yiring.app.param.dict.DictQueryParam
;
import
com.yiring.app.service.dict.DictService
;
import
com.yiring.common.core.Result
;
import
com.yiring.common.core.Status
;
import
com.yiring.common.dict.Dict
;
import
com.yiring.common.dict.DictRepository
;
import
com.yiring.common.param.IdParam
;
import
com.yiring.common.param.PageParam
;
import
com.yiring.common.util.DictUtils
;
import
com.yiring.common.vo.PageVo
;
import
java.time.LocalDateTime
;
import
java.util.*
;
import
java.util.stream.Collectors
;
import
javax.annotation.PostConstruct
;
import
javax.annotation.Resource
;
import
javax.persistence.criteria.Predicate
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.data.domain.Example
;
import
org.springframework.data.domain.Page
;
import
org.springframework.data.jpa.domain.Specification
;
import
org.springframework.stereotype.Service
;
/**
* 字典
*
* @author tzl
* 2022/4/13 15:37
*/
@Service
public
class
DictServiceImpl
implements
DictService
{
@Resource
DictRepository
dictRepository
;
/**
* 项目启动时,初始化字典到缓存
*/
@PostConstruct
public
void
init
()
{
loadingDictCache
();
}
/**
* 加载字典缓存数据
*/
@Override
public
void
loadingDictCache
()
{
Dict
dict
=
Dict
.
builder
().
status
(
"1"
).
build
();
Map
<
String
,
List
<
Dict
>>
dictDataMap
=
dictRepository
.
findAll
(
Example
.
of
(
dict
))
.
stream
()
.
collect
(
Collectors
.
groupingBy
(
Dict:
:
getDictType
));
for
(
Map
.
Entry
<
String
,
List
<
Dict
>>
entry
:
dictDataMap
.
entrySet
())
{
DictUtils
.
setDictCache
(
entry
.
getKey
(),
entry
.
getValue
().
stream
().
sorted
(
Comparator
.
comparing
(
Dict:
:
getDictSort
)).
collect
(
Collectors
.
toList
())
);
}
}
@Override
public
Result
<
PageVo
<
Dict
>>
pageDictInfo
(
DictQueryParam
dictQueryParam
,
PageParam
param
)
{
Page
<
Dict
>
all
=
dictRepository
.
findAll
(
condition
(
dictQueryParam
),
PageParam
.
toPageable
(
param
));
List
<
Dict
>
data
=
all
.
get
()
.
map
(
car
->
{
Dict
vo
=
new
Dict
();
BeanUtils
.
copyProperties
(
car
,
vo
);
return
vo
;
})
.
collect
(
Collectors
.
toList
());
PageVo
<
Dict
>
vo
=
PageVo
.
build
(
data
,
all
.
getTotalElements
());
return
Result
.
ok
(
vo
);
}
@Override
public
Result
<
String
>
selectDictLabel
(
String
dictType
,
String
dictValue
)
{
return
Result
.
ok
(
dictRepository
.
findDictLabel
(
dictType
,
dictValue
));
}
@Override
public
Result
<
ArrayList
<
Dict
>>
selectDict
(
String
dictType
)
{
List
<
Dict
>
dictCache1
=
DictUtils
.
getDictCache
(
dictType
);
ArrayList
<
Dict
>
dictCache
=
new
ArrayList
<>();
if
(
dictCache1
!=
null
)
{
dictCache
=
new
ArrayList
<>(
dictCache1
);
}
return
Result
.
ok
(
dictCache
);
}
@Override
public
Result
<
Dict
>
getDictInfo
(
Long
dictCode
)
{
return
Result
.
ok
(
dictRepository
.
getById
(
dictCode
));
}
@Override
public
Result
<
String
>
deleteDictById
(
IdParam
idParam
)
{
Optional
<
Dict
>
optional
=
dictRepository
.
findById
(
idParam
.
getId
());
if
(
optional
.
isEmpty
())
{
return
Result
.
no
(
Status
.
NOT_FOUND
);
}
Dict
entity
=
optional
.
get
();
dictRepository
.
delete
(
entity
);
//刷新缓存
List
<
Dict
>
byDictType
=
dictRepository
.
findByDictType
(
entity
.
getDictType
());
DictUtils
.
setDictCache
(
entity
.
getDictType
(),
byDictType
);
return
Result
.
ok
();
}
@Override
public
Result
<
String
>
saveDictInfo
(
DictParam
dictParam
)
{
if
(
has
(
dictParam
.
getDictLabel
()))
{
return
Result
.
no
(
Status
.
BAD_REQUEST
,
"标签已存在"
);
}
if
(
hasValue
(
dictParam
.
getDictType
(),
dictParam
.
getDictValue
()))
{
return
Result
.
no
(
Status
.
BAD_REQUEST
,
"该类型,字典值已存在"
);
}
Dict
dict
=
new
Dict
();
dict
.
setCreateTime
(
LocalDateTime
.
now
());
BeanUtils
.
copyProperties
(
dictParam
,
dict
);
dictRepository
.
saveAndFlush
(
dict
);
//刷新缓存
List
<
Dict
>
byDictType
=
dictRepository
.
findByDictType
(
dict
.
getDictType
());
DictUtils
.
setDictCache
(
dict
.
getDictType
(),
byDictType
);
return
Result
.
ok
();
}
@Override
public
Result
<
String
>
updateDictInfo
(
DictParam
dictParam
,
IdParam
idParam
)
{
Optional
<
Dict
>
optional
=
dictRepository
.
findById
(
idParam
.
getId
());
if
(
optional
.
isEmpty
())
{
return
Result
.
no
(
Status
.
NOT_FOUND
);
}
Dict
entity
=
optional
.
get
();
if
(!
entity
.
getDictLabel
().
equals
(
dictParam
.
getDictLabel
()))
{
if
(
has
(
dictParam
.
getDictLabel
()))
{
//当修改了字典标签时
return
Result
.
no
(
Status
.
BAD_REQUEST
,
"标签已存在"
);
}
}
if
(
!
entity
.
getDictValue
().
equals
(
dictParam
.
getDictValue
())
||
!
entity
.
getDictType
().
equals
(
dictParam
.
getDictType
())
)
{
//当修改了字典类型或字典值时
if
(
hasValue
(
dictParam
.
getDictType
(),
dictParam
.
getDictValue
()))
{
return
Result
.
no
(
Status
.
BAD_REQUEST
,
"该类型,字典值已存在"
);
}
}
BeanUtils
.
copyProperties
(
dictParam
,
entity
);
Dict
dict
=
dictRepository
.
saveAndFlush
(
entity
);
List
<
Dict
>
byDictType
=
dictRepository
.
findByDictType
(
dict
.
getDictType
());
DictUtils
.
setDictCache
(
dict
.
getDictType
(),
byDictType
);
return
Result
.
ok
();
}
public
Specification
<
Dict
>
condition
(
DictQueryParam
dictQueryParam
)
{
return
(
root
,
query
,
criteriaBuilder
)
->
{
List
<
Predicate
>
list
=
new
ArrayList
<>();
if
(
StrUtil
.
isNotBlank
(
dictQueryParam
.
getDictType
()))
{
list
.
add
(
criteriaBuilder
.
like
(
root
.
get
(
"dictType"
).
as
(
String
.
class
),
"%"
+
dictQueryParam
.
getDictType
()
+
"%"
)
);
}
if
(
StrUtil
.
isNotBlank
(
dictQueryParam
.
getDictLabel
()))
{
list
.
add
(
criteriaBuilder
.
like
(
root
.
get
(
"dictLabel"
).
as
(
String
.
class
),
"%"
+
dictQueryParam
.
getDictLabel
()
+
"%"
)
);
}
Predicate
[]
predicates
=
new
Predicate
[
list
.
size
()];
query
.
where
(
list
.
toArray
(
predicates
));
return
criteriaBuilder
.
and
(
list
.
toArray
(
predicates
));
};
}
@Override
public
boolean
has
(
String
param
)
{
Dict
entity
=
Dict
.
builder
().
dictLabel
(
param
).
build
();
long
count
=
dictRepository
.
count
(
Example
.
of
(
entity
));
return
count
>
0
;
}
@Override
public
boolean
hasValue
(
String
dictType
,
String
dictValue
)
{
Dict
entity
=
Dict
.
builder
().
dictType
(
dictType
).
dictValue
(
dictValue
).
build
();
long
count
=
dictRepository
.
count
(
Example
.
of
(
entity
));
return
count
>
0
;
}
}
app/src/main/java/com/yiring/app/service/dict/impl/DictTypeServiceImpl.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
service
.
dict
.
impl
;
import
com.yiring.app.service.dict.DictTypeService
;
import
java.util.*
;
import
org.springframework.stereotype.Service
;
/**
* 字典类型
*
* @author tzl
* 2022/4/14 14:23
*/
@Service
public
class
DictTypeServiceImpl
implements
DictTypeService
{
//
// @Resource
// DictTypeRepository dictTypeRepository;
//
// @Resource
// DictRepository dictRepository;
//
// @Override
// public Result<PageVo<DictType>> pageDictTypeInfo(DictTypeQueryParam dictTypeQueryParam, PageParam param) {
// Page<DictType> all = dictTypeRepository.findAll(condition(dictTypeQueryParam), PageParam.toPageable(param));
// List<DictType> data = all
// .get()
// .map(car -> {
// DictType vo = new DictType();
// BeanUtils.copyProperties(car, vo);
// return vo;
// })
// .collect(Collectors.toList());
// PageVo<DictType> vo = PageVo.build(data, all.getTotalElements());
// return Result.ok(vo);
// }
//
// @Override
// public Result<DictType> getDictTypeInfo(Long id) {
// return Result.ok(dictTypeRepository.getById(id));
// }
//
// @Override
// public Result<String> delecteById(Long id) {
// Optional<DictType> optional = dictTypeRepository.findById(id);
// if (optional.isEmpty()) {
// return Result.no(Status.NOT_FOUND);
// }
// DictType entity = optional.get();
// List<Dict> byDictType1 = dictRepository.findByDictType(entity.getDictType());
// if (byDictType1.size() > 0) {
// return Result.no(Status.BAD_REQUEST, "该类型下有字典数据,无法删除");
// }
//
// dictTypeRepository.delete(entity);
// //移除该类型缓存
// DictUtils.removeDictCache(entity.getDictType());
// return Result.ok();
// }
//
// @Override
// public Result<String> saveDictTypeInfo(DictTypeParam dictTypeParam) {
// if (has(dictTypeParam.getDictType())) {
// return Result.no(Status.BAD_REQUEST, "字典类型已存在");
// }
// DictType dictType = DictType.builder().createTime(LocalDateTime.now()).build();
// BeanUtils.copyProperties(dictTypeParam, dictType);
// dictTypeRepository.saveAndFlush(dictType);
// //添加空缓存
// DictUtils.setDictCache(dictType.getDictType(), null);
// return Result.ok();
// }
//
// @Override
// public Result<String> updateDictTypeInfo(DictTypeParam dictTypeParam, IdParam idParam) {
// Optional<DictType> optional = dictTypeRepository.findById(idParam.getId());
// if (optional.isEmpty()) {
// return Result.no(Status.NOT_FOUND);
// }
// DictType dictType = optional.get();
// if (!dictType.getDictType().equals(dictTypeParam.getDictType())) {
// //在修改字典类型时
// if (has(dictTypeParam.getDictType())) {
// return Result.no(Status.BAD_REQUEST, "字典类型已存在");
// }
// //将该字典类型下的字典数据一并修改
// dictRepository.updateDictType(dictTypeParam.getDictType(), dictType.getDictType());
// //移除之前的缓存
// DictUtils.removeDictCache(dictType.getDictType());
// }
// BeanUtils.copyProperties(dictTypeParam, dictType);
// dictTypeRepository.saveAndFlush(dictType);
// //查询该字典类型下的字典值数据
// List<Dict> byDictType = dictRepository.findByDictType(dictType.getDictType());
// //添加新缓存
// DictUtils.setDictCache(dictType.getDictType(), byDictType);
// return Result.ok();
// }
//
// @Override
// public boolean has(String param) {
// DictType dictType = DictType.builder().dictType(param).build();
// return dictTypeRepository.count(Example.of(dictType)) > 0;
// }
//
// public Specification<DictType> condition(DictTypeQueryParam dictTypeQueryParam) {
// return (root, query, criteriaBuilder) -> {
// List<Predicate> list = new ArrayList<>();
// if (StrUtils.isNotBlank(dictTypeQueryParam.getDictName())) {
// list.add(
// criteriaBuilder.like(
// root.get("dictType").as(String.class),
// "%" + dictTypeQueryParam.getDictName() + "%"
// )
// );
// }
// Predicate[] predicates = new Predicate[list.size()];
// query.where(list.toArray(predicates));
// return criteriaBuilder.and(list.toArray(predicates));
// };
// }
}
app/src/main/java/com/yiring/app/service/location/LocationTagService.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
service
.
location
;
import
com.yiring.app.param.location.LocationTagAddParam
;
import
com.yiring.app.param.location.LocationTagDeleteParam
;
import
com.yiring.app.param.location.LocationTagFindParam
;
import
com.yiring.app.param.location.LocationTagModifyParam
;
import
com.yiring.app.vo.location.LocationTagVo
;
import
com.yiring.common.core.Result
;
import
com.yiring.common.param.IdParam
;
import
com.yiring.common.vo.PageVo
;
import
javax.servlet.http.HttpServletResponse
;
import
org.springframework.web.multipart.MultipartFile
;
/**
* 定位标签
* @author LJ-2204
* @date 2022/4/14
*/
public
interface
LocationTagService
{
/**
* 新增定位标签
* @param param 入参
* @return Result<String>
*/
Result
<
String
>
addLocationTag
(
LocationTagAddParam
param
);
/**
* 分页查询
* @param param 入参
* @return Result<PageVo<LocationTagVo>>
*/
Result
<
PageVo
<
LocationTagVo
>>
findLocationTagPage
(
LocationTagFindParam
param
);
/**
* 销毁定位标签
* @param param 入参
* @return Result<String>
*/
Result
<
String
>
deleteLocationTag
(
LocationTagDeleteParam
param
);
/**
* 导出定位标签
* @param param 入参
* @param response 响应信息
*/
void
exportLocationTagInfo
(
LocationTagFindParam
param
,
HttpServletResponse
response
);
/**
* 导入定位标签
* @param file 文件
* @return Result<String>
*/
Result
<
String
>
importLocationTagInfo
(
MultipartFile
file
);
/**
* 修改定位标签
* @param param 入参
* @return Result<String>
*/
Result
<
String
>
modifyLocationTag
(
LocationTagModifyParam
param
,
IdParam
idParam
);
}
app/src/main/java/com/yiring/app/service/location/impl/LocationTagServiceImpl.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
service
.
location
.
impl
;
import
cn.hutool.core.collection.ListUtil
;
import
cn.hutool.core.util.ObjectUtil
;
import
cn.hutool.core.util.StrUtil
;
import
com.github.liaochong.myexcel.core.DefaultStreamExcelBuilder
;
import
com.github.liaochong.myexcel.core.SaxExcelReader
;
import
com.yiring.app.domain.location.LocationTag
;
import
com.yiring.app.domain.location.LocationTagRepository
;
import
com.yiring.app.excel.location.LocationTagExportExcel
;
import
com.yiring.app.excel.location.LocationTagImportExcel
;
import
com.yiring.app.param.location.LocationTagAddParam
;
import
com.yiring.app.param.location.LocationTagDeleteParam
;
import
com.yiring.app.param.location.LocationTagFindParam
;
import
com.yiring.app.param.location.LocationTagModifyParam
;
import
com.yiring.app.param.location.zy.ZyLocationTagAddParam
;
import
com.yiring.app.service.location.LocationTagService
;
import
com.yiring.app.vo.location.LocationTagVo
;
import
com.yiring.auth.util.ZyUtil
;
import
com.yiring.common.core.Result
;
import
com.yiring.common.core.Status
;
import
com.yiring.common.param.IdParam
;
import
com.yiring.common.vo.PageVo
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.io.Serializable
;
import
java.net.URLEncoder
;
import
java.nio.charset.StandardCharsets
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Objects
;
import
java.util.Optional
;
import
java.util.concurrent.Executors
;
import
java.util.stream.Collectors
;
import
javax.annotation.Resource
;
import
javax.persistence.criteria.Order
;
import
javax.persistence.criteria.Predicate
;
import
javax.servlet.http.HttpServletResponse
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.poi.ss.usermodel.Workbook
;
import
org.jetbrains.annotations.NotNull
;
import
org.springframework.data.domain.*
;
import
org.springframework.data.jpa.domain.Specification
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.web.multipart.MultipartFile
;
/**
* 定位标签
* @author LJ-2204
* @date 2022/4/14
*/
@Transactional
(
rollbackFor
=
RuntimeException
.
class
)
@Service
@Slf4j
public
class
LocationTagServiceImpl
implements
LocationTagService
{
final
Integer
FACTORY_ID
=
100
;
@Resource
LocationTagRepository
locationTagRepository
;
@Override
public
Result
<
String
>
addLocationTag
(
LocationTagAddParam
param
)
{
if
(
hasLocationTagInfoByCode
(
param
.
getCode
()))
return
Result
.
no
(
Status
.
BAD_REQUEST
,
"编号已存在"
);
LocationTag
locationTag
=
param
.
transform
();
locationTagRepository
.
save
(
locationTag
);
ZyLocationTagAddParam
zyLocationTagAddParam
=
ZyLocationTagAddParam
.
transform
(
locationTag
);
List
<
ZyLocationTagAddParam
>
of
=
ListUtil
.
of
(
zyLocationTagAddParam
);
new
Thread
(()
->
{
Result
<
Serializable
>
result
=
ZyUtil
.
post
(
"/positionApi/api/tag/saveTag"
,
of
,
3000
);
if
(
result
.
getCode
()
!=
200
)
throw
new
RuntimeException
(
result
.
getMessage
());
})
.
start
();
return
Result
.
ok
();
}
@Override
public
Result
<
PageVo
<
LocationTagVo
>>
findLocationTagPage
(
LocationTagFindParam
param
)
{
Specification
<
LocationTag
>
specification
=
getLocationTagPageSpecification
(
param
);
Sort
sort
=
Sort
.
by
(
Sort
.
Order
.
desc
(
LocationTag
.
Fields
.
createTime
));
if
(
Objects
.
nonNull
(
param
.
getPageNo
())
&&
Objects
.
nonNull
(
param
.
getPageSize
()))
{
//分页
Pageable
pageable
=
PageRequest
.
of
(
param
.
getPageNo
()
-
1
,
param
.
getPageSize
());
Page
<
LocationTag
>
locationTags
=
locationTagRepository
.
findAll
(
specification
,
pageable
);
List
<
LocationTagVo
>
locationTagVos
=
LocationTagVo
.
transforms
(
locationTags
.
getContent
());
PageVo
<
LocationTagVo
>
page
=
PageVo
.
build
(
locationTagVos
,
locationTagVos
.
size
());
return
Result
.
ok
(
page
);
}
else
{
List
<
LocationTag
>
locationTags
=
locationTagRepository
.
findAll
(
specification
,
sort
);
List
<
LocationTagVo
>
locationTagVos
=
LocationTagVo
.
transforms
(
locationTags
);
PageVo
<
LocationTagVo
>
page
=
PageVo
.
build
(
locationTagVos
,
locationTagVos
.
size
());
return
Result
.
ok
(
page
);
}
}
@Override
public
Result
<
String
>
deleteLocationTag
(
LocationTagDeleteParam
param
)
{
if
(
ObjectUtil
.
isNotEmpty
(
param
.
getUser
()))
return
Result
.
no
(
Status
.
BAD_REQUEST
,
"请先解绑人员"
);
locationTagRepository
.
deleteById
(
param
.
getId
());
return
Result
.
ok
();
}
@Override
public
void
exportLocationTagInfo
(
LocationTagFindParam
param
,
HttpServletResponse
response
)
{
Specification
<
LocationTag
>
specification
=
getLocationTagPageSpecification
(
param
);
List
<
LocationTag
>
locationTags
=
locationTagRepository
.
findAll
(
specification
);
List
<
LocationTagExportExcel
>
locationTagExportExcels
=
LocationTagExportExcel
.
transforms
(
locationTags
);
try
(
DefaultStreamExcelBuilder
<
LocationTagExportExcel
>
streamExcelBuilder
=
DefaultStreamExcelBuilder
.
of
(
LocationTagExportExcel
.
class
)
.
threadPool
(
Executors
.
newFixedThreadPool
(
2
))
.
rowHeight
(
14
)
.
titleRowHeight
(
14
)
.
style
(
"cell->vertical-align:center;text-align:center"
,
"title->vertical-align:center;text-align:center;font-weight:bold;font-family:等线"
)
.
start
()
)
{
streamExcelBuilder
.
append
(
locationTagExportExcels
);
String
fileName
=
URLEncoder
.
encode
(
"定位标签信息.xlsx"
,
StandardCharsets
.
UTF_8
);
response
.
setContentType
(
"application/octet-stream"
);
response
.
setHeader
(
"Content-Disposition"
,
"attachment;filename="
+
fileName
);
OutputStream
out
=
response
.
getOutputStream
();
Workbook
workbook
=
streamExcelBuilder
.
fixedTitles
().
build
();
workbook
.
write
(
out
);
workbook
.
close
();
out
.
flush
();
out
.
close
();
}
catch
(
Exception
e
)
{
log
.
error
(
e
.
getMessage
(),
e
);
throw
new
RuntimeException
(
"导出岗位信息失败: "
+
e
.
getMessage
());
}
}
@Override
public
Result
<
String
>
importLocationTagInfo
(
MultipartFile
file
)
{
if
(
file
.
isEmpty
())
throw
new
RuntimeException
(
"请选择文件"
);
List
<
LocationTagImportExcel
>
locationTagImportExcels
;
try
(
InputStream
inputStream
=
file
.
getInputStream
())
{
locationTagImportExcels
=
SaxExcelReader
.
of
(
LocationTagImportExcel
.
class
)
.
rowFilter
(
row
->
row
.
getRowNum
()
>
0
)
.
ignoreBlankRow
()
.
read
(
inputStream
);
}
catch
(
IOException
e
)
{
log
.
info
(
e
.
getMessage
());
throw
new
RuntimeException
(
"文件导入异常"
);
}
List
<
LocationTag
>
locationTags
=
locationTagImportExcels
.
stream
()
.
map
(
LocationTagImportExcel:
:
transform
)
.
collect
(
Collectors
.
toList
());
locationTags
.
forEach
(
locationTag
->
{
locationTagRepository
.
findOne
((
root
,
cq
,
cb
)
->
{
List
<
Predicate
>
predicates
=
new
ArrayList
<>();
if
(
StrUtil
.
isNotEmpty
(
locationTag
.
getCode
()))
{
predicates
.
add
(
cb
.
equal
(
root
.
get
(
LocationTag
.
Fields
.
code
),
locationTag
.
getCode
()));
}
return
cq
.
where
(
predicates
.
toArray
(
new
Predicate
[
0
])).
getRestriction
();
})
.
ifPresent
(
temp
->
locationTag
.
setId
(
temp
.
getId
()));
locationTagRepository
.
save
(
locationTag
);
});
return
Result
.
ok
();
}
@Override
public
Result
<
String
>
modifyLocationTag
(
LocationTagModifyParam
param
,
IdParam
idParam
)
{
Optional
<
LocationTag
>
locationTagOptional
=
locationTagRepository
.
findById
(
idParam
.
getId
());
if
(
locationTagOptional
.
isEmpty
())
return
Result
.
no
(
Status
.
BAD_REQUEST
,
"被修改的数据不存在"
);
LocationTag
locationTag
=
locationTagOptional
.
get
();
if
(!
StrUtil
.
equals
(
locationTag
.
getCode
(),
param
.
getCode
()))
{
if
(
hasLocationTagInfoByCode
(
param
.
getCode
()))
return
Result
.
no
(
Status
.
BAD_REQUEST
,
"编号已存在"
);
}
locationTag
=
param
.
transform
();
locationTag
.
setId
(
idParam
.
getId
());
locationTagRepository
.
save
(
locationTag
);
return
Result
.
ok
();
}
private
boolean
hasLocationTagInfoByCode
(
String
code
)
{
LocationTag
locationTag
=
LocationTag
.
builder
().
code
(
code
).
build
();
return
locationTagRepository
.
count
(
Example
.
of
(
locationTag
))
>
0
;
}
@NotNull
private
Specification
<
LocationTag
>
getLocationTagPageSpecification
(
LocationTagFindParam
param
)
{
return
(
root
,
cq
,
cb
)
->
{
List
<
Predicate
>
predicates
=
ListUtil
.
toList
();
if
(
StrUtil
.
isNotEmpty
(
param
.
getCode
()))
{
cb
.
equal
(
root
.
get
(
LocationTag
.
Fields
.
code
),
param
.
getCode
());
}
if
(
ObjectUtil
.
isNotEmpty
(
param
.
getType
()))
{
cb
.
equal
(
root
.
get
(
LocationTag
.
Fields
.
type
),
param
.
getType
());
}
if
(
ObjectUtil
.
isNotEmpty
(
param
.
getSilent
()))
{
cb
.
equal
(
root
.
get
(
LocationTag
.
Fields
.
silent
),
param
.
getSilent
());
}
Order
order
=
cb
.
desc
(
root
.
get
(
LocationTag
.
Fields
.
createTime
));
return
cq
.
orderBy
(
order
).
where
(
predicates
.
toArray
(
new
Predicate
[
0
])).
getRestriction
();
};
}
}
app/src/main/java/com/yiring/app/service/video/VideoService.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
service
.
video
;
import
com.yiring.app.param.video.VideoParam
;
import
com.yiring.app.param.video.VideoQueryParam
;
import
com.yiring.app.vo.video.VideoVo
;
import
com.yiring.common.core.Result
;
import
com.yiring.common.param.IdParam
;
import
com.yiring.common.param.PageParam
;
import
com.yiring.common.vo.PageVo
;
import
java.awt.*
;
import
org.locationtech.jts.geom.Point
;
/**
* @author tzl
* 2022/4/8 15:28
*/
public
interface
VideoService
{
/**
* 监控视频点位添加
*
* @param videoParam VideoParam
* @return Result<String>
* @author tzl
* @date 2022/4/8 16:23
*/
Result
<
String
>
saveVideo
(
VideoParam
videoParam
);
/**
* 删除监控点位信息
* @param idParam 主键id
* @return Result<String>
* @author tzl
* @date 2022/4/15 10:16
*/
Result
<
String
>
deleteVideo
(
IdParam
idParam
);
/**
* 修改监控点位信息
* @param videoParam 修改的参数
* @param idParam 主键id
* @return Result<String>
* @author tzl
* @date 2022/4/15 10:19
*/
Result
<
String
>
updateVideo
(
VideoParam
videoParam
,
IdParam
idParam
);
/**
* 查询监控点坐标
* @param idParam 主键id
* @return Result<Point> 坐标信息
* @author tzl
* @date 2022/4/15 14:15
*/
Result
<
Point
>
selectPoint
(
IdParam
idParam
);
/**
* 分页查询
* @param videoQueryParam 筛选条件
* @param param 分页参数
* @return Result<PageVo<VideoVo>> 分页结果集
* @author tzl
* @date 2022/4/15 14:35
*/
Result
<
PageVo
<
VideoVo
>>
pageVideo
(
VideoQueryParam
videoQueryParam
,
PageParam
param
);
}
app/src/main/java/com/yiring/app/service/video/impl/VideoServiceImpl.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
service
.
video
.
impl
;
import
cn.hutool.core.util.StrUtil
;
import
com.yiring.app.domain.video.Video
;
import
com.yiring.app.domain.video.VideoRepository
;
import
com.yiring.app.param.video.VideoParam
;
import
com.yiring.app.param.video.VideoQueryParam
;
import
com.yiring.app.service.video.VideoService
;
import
com.yiring.app.util.GeoUtils
;
import
com.yiring.app.vo.video.VideoVo
;
import
com.yiring.common.core.Result
;
import
com.yiring.common.core.Status
;
import
com.yiring.common.param.IdParam
;
import
com.yiring.common.param.PageParam
;
import
com.yiring.common.vo.PageVo
;
import
java.time.LocalDateTime
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Optional
;
import
java.util.stream.Collectors
;
import
javax.annotation.Resource
;
import
javax.persistence.criteria.Predicate
;
import
org.locationtech.jts.geom.Point
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.data.domain.Example
;
import
org.springframework.data.domain.Page
;
import
org.springframework.data.jpa.domain.Specification
;
import
org.springframework.stereotype.Service
;
/**
* @author tzl
* 2022/4/8 15:28
*/
@Service
public
class
VideoServiceImpl
implements
VideoService
{
@Resource
VideoRepository
videoRepository
;
@Override
public
Result
<
String
>
saveVideo
(
VideoParam
videoParam
)
{
if
(
has
(
videoParam
.
getUuid
()))
{
return
Result
.
no
(
Status
.
BAD_REQUEST
,
"您输入的编号已存在"
);
}
Video
video
=
Video
.
builder
()
.
createTime
(
LocalDateTime
.
now
())
// .enable(videoParam.getEnable())
// .m3u8(videoParam.getM3u8())
// .point(videoParam.getPoint())
.
m3u8
(
videoParam
.
getM3u8
())
.
point
(
GeoUtils
.
createPoint
(
videoParam
.
getLon
(),
videoParam
.
getLat
()))
// .online(videoParam.getOnline())
// .type(videoParam.getType())
//默认正常
.
videoName
(
videoParam
.
getVideoName
())
.
status
(
"1"
)
.
remark
(
videoParam
.
getRemark
())
.
uuid
(
videoParam
.
getUuid
())
.
build
();
videoRepository
.
saveAndFlush
(
video
);
//还需要同步添加国标28181中对应的摄像头信息
//标识uuid对应流id,m3u8对应拉流地址,如m3u8中有标注 则将类型切换为FFmpeg,摄像头名称videoName对应名称,流名称默认"stream",超时时间默认60
return
Result
.
ok
();
}
@Override
public
Result
<
String
>
deleteVideo
(
IdParam
idParam
)
{
Optional
<
Video
>
optional
=
videoRepository
.
findById
(
idParam
.
getId
());
if
(
optional
.
isEmpty
())
{
return
Result
.
no
(
Status
.
NOT_FOUND
);
}
Video
video
=
optional
.
get
();
videoRepository
.
delete
(
video
);
//还需要同步删除国标28181中对应的摄像头信息
return
Result
.
ok
();
}
@Override
public
Result
<
String
>
updateVideo
(
VideoParam
videoParam
,
IdParam
idParam
)
{
Optional
<
Video
>
optional
=
videoRepository
.
findById
(
idParam
.
getId
());
if
(
optional
.
isEmpty
())
{
return
Result
.
no
(
Status
.
NOT_FOUND
);
}
Video
video
=
optional
.
get
();
if
(!
video
.
getUuid
().
equals
(
videoParam
.
getUuid
()))
{
//当修改编号时
if
(
has
(
videoParam
.
getUuid
()))
{
return
Result
.
no
(
Status
.
BAD_REQUEST
,
"您输入的编号已存在"
);
}
}
BeanUtils
.
copyProperties
(
videoParam
,
video
);
videoRepository
.
saveAndFlush
(
video
);
//还需要同步修改国标28181中对应的摄像头信息
return
Result
.
ok
();
}
@Override
public
Result
<
Point
>
selectPoint
(
IdParam
idParam
)
{
Optional
<
Video
>
optional
=
videoRepository
.
findById
(
idParam
.
getId
());
if
(
optional
.
isEmpty
())
{
return
Result
.
no
(
Status
.
NOT_FOUND
);
}
Video
video
=
optional
.
get
();
return
Result
.
ok
(
video
.
getPoint
());
}
@Override
public
Result
<
PageVo
<
VideoVo
>>
pageVideo
(
VideoQueryParam
videoQueryParam
,
PageParam
param
)
{
Page
<
Video
>
all
=
videoRepository
.
findAll
(
condition
(
videoQueryParam
),
PageParam
.
toPageable
(
param
));
List
<
VideoVo
>
data
=
all
.
get
()
.
map
(
video
->
{
VideoVo
vo
=
new
VideoVo
();
BeanUtils
.
copyProperties
(
video
,
vo
);
return
vo
;
})
.
collect
(
Collectors
.
toList
());
PageVo
<
VideoVo
>
vo
=
PageVo
.
build
(
data
,
all
.
getTotalElements
());
return
Result
.
ok
(
vo
);
}
/**
* 条件查询
* @param videoQueryParam 筛选条件
* @return Specification
*/
public
Specification
<
Video
>
condition
(
VideoQueryParam
videoQueryParam
)
{
return
(
root
,
query
,
criteriaBuilder
)
->
{
List
<
Predicate
>
list
=
new
ArrayList
<>();
if
(
StrUtil
.
isNotBlank
(
videoQueryParam
.
getVideoName
()))
{
list
.
add
(
criteriaBuilder
.
like
(
root
.
get
(
"videoName"
).
as
(
String
.
class
),
"%"
+
videoQueryParam
.
getVideoName
()
+
"%"
)
);
}
if
(
StrUtil
.
isNotBlank
(
videoQueryParam
.
getUuid
()))
{
list
.
add
(
criteriaBuilder
.
like
(
root
.
get
(
"uuid"
).
as
(
String
.
class
),
"%"
+
videoQueryParam
.
getUuid
()
+
"%"
)
);
}
if
(
StrUtil
.
isNotBlank
(
videoQueryParam
.
getStatus
()))
{
list
.
add
(
criteriaBuilder
.
equal
(
root
.
get
(
"uuid"
).
as
(
String
.
class
),
videoQueryParam
.
getStatus
()));
}
Predicate
[]
predicates
=
new
Predicate
[
list
.
size
()];
query
.
where
(
list
.
toArray
(
predicates
));
return
criteriaBuilder
.
and
(
list
.
toArray
(
predicates
));
};
}
boolean
has
(
String
uuid
)
{
Video
video
=
Video
.
builder
().
uuid
(
uuid
).
build
();
return
videoRepository
.
count
(
Example
.
of
(
video
))
>
0
;
}
}
app/src/main/java/com/yiring/app/stomp/RabbitmqProperties.java
deleted
100644 → 0
浏览文件 @
f490012a
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
stomp
;
import
lombok.AccessLevel
;
import
lombok.Data
;
import
lombok.experimental.FieldDefaults
;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
import
org.springframework.stereotype.Component
;
/**
* RabbitmqProperties
*
* @author ifzm
* @version 0.1
* 2019/9/25 21:31
*/
@Data
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
@Component
@ConfigurationProperties
(
prefix
=
"spring.rabbitmq"
)
public
class
RabbitmqProperties
{
int
port
;
String
host
;
String
username
;
String
password
;
}
app/src/main/java/com/yiring/app/stomp/WebSocketStompConfig.java
浏览文件 @
f360f80d
...
...
@@ -5,6 +5,7 @@ import com.yiring.app.constant.RedisKey;
import
com.yiring.common.core.Redis
;
import
javax.annotation.Resource
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.boot.autoconfigure.amqp.RabbitProperties
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.messaging.simp.config.ChannelRegistration
;
import
org.springframework.messaging.simp.config.MessageBrokerRegistry
;
...
...
@@ -32,7 +33,7 @@ public class WebSocketStompConfig implements WebSocketMessageBrokerConfigurer {
Redis
redis
;
@Resource
Rabbit
mqProperties
rabbitmq
Properties
;
Rabbit
Properties
rabbit
Properties
;
@Resource
ClientInboundChannelInterceptor
clientInboundChannelInterceptor
;
...
...
@@ -61,11 +62,11 @@ public class WebSocketStompConfig implements WebSocketMessageBrokerConfigurer {
registry
.
setApplicationDestinationPrefixes
(
"/app"
);
registry
.
enableStompBrokerRelay
(
"/topic"
,
"/queue"
)
.
setRelayHost
(
rabbit
mq
Properties
.
getHost
())
.
setClientLogin
(
rabbit
mq
Properties
.
getUsername
())
.
setClientPasscode
(
rabbit
mq
Properties
.
getPassword
())
.
setSystemLogin
(
rabbit
mq
Properties
.
getUsername
())
.
setSystemPasscode
(
rabbit
mq
Properties
.
getPassword
());
.
setRelayHost
(
rabbitProperties
.
getHost
())
.
setClientLogin
(
rabbitProperties
.
getUsername
())
.
setClientPasscode
(
rabbitProperties
.
getPassword
())
.
setSystemLogin
(
rabbitProperties
.
getUsername
())
.
setSystemPasscode
(
rabbitProperties
.
getPassword
());
log
.
info
(
"Init RabbitMQ STOMP MessageBroker Success."
);
}
...
...
app/src/main/java/com/yiring/app/vo/car/CarVo.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
vo
.
car
;
import
cn.hutool.core.util.StrUtil
;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
com.fasterxml.jackson.databind.annotation.JsonSerialize
;
import
com.fasterxml.jackson.databind.ser.std.ToStringSerializer
;
import
com.yiring.common.util.DictUtils
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
java.io.Serializable
;
import
java.time.LocalDateTime
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
/**
* @author tzl
* 2022/4/11 14:52
*/
@ApiModel
(
"CarVo"
)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
CarVo
implements
Serializable
{
@JsonSerialize
(
using
=
ToStringSerializer
.
class
)
@ApiModelProperty
(
value
=
"主键id"
,
example
=
"1458555485552"
)
Long
id
;
@ApiModelProperty
(
value
=
"车牌号码"
,
example
=
"湘A99999"
)
String
carNum
;
@ApiModelProperty
(
value
=
"车辆类型"
,
example
=
"1"
)
String
carType
;
/**
* 车辆类型翻译
*/
@ApiModelProperty
(
value
=
"车辆类型(字典翻译)"
,
example
=
"货车"
)
String
carTypeName
;
public
String
getCarTypeName
()
{
if
(
StrUtil
.
isNotBlank
(
carType
))
{
return
DictUtils
.
getDictLabel
(
"car_type"
,
carType
);
}
return
null
;
}
@ApiModelProperty
(
value
=
"司机名称"
,
example
=
"张三"
)
String
driverName
;
@ApiModelProperty
(
value
=
"司机电话"
,
example
=
"17688888888"
)
String
driverMobile
;
@ApiModelProperty
(
value
=
"标签卡"
,
example
=
"DT8875666"
)
String
labelCard
;
@ApiModelProperty
(
value
=
"标签卡状态"
,
example
=
"1"
)
String
labelCardStatus
;
/**
* 车辆类型翻译
*/
@ApiModelProperty
(
value
=
"标签卡状态"
,
example
=
"未发卡"
)
String
labelCardStatusName
;
public
String
getLabelCardStatusName
()
{
if
(
StrUtil
.
isNotBlank
(
carType
))
{
return
DictUtils
.
getDictLabel
(
"car_label_status"
,
labelCardStatus
);
}
return
null
;
}
@ApiModelProperty
(
value
=
"单位id"
,
example
=
"湖南壹润科技"
)
String
orgId
;
@ApiModelProperty
(
value
=
"被访人id"
,
example
=
"1"
)
String
intervieweeId
;
@ApiModelProperty
(
value
=
"来访原因"
,
example
=
"装货"
)
String
reason
;
@ApiModelProperty
(
value
=
"收卡时间"
,
example
=
"2022-04-11 17:25:33"
)
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
LocalDateTime
cardRecTime
;
@ApiModelProperty
(
value
=
"创建时间"
,
example
=
"2022-04-11 17:25:33"
)
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
LocalDateTime
createTime
;
@ApiModelProperty
(
value
=
"发卡时间"
,
example
=
"2022-04-11 17:25:33"
)
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
LocalDateTime
cardSendTime
;
}
app/src/main/java/com/yiring/app/vo/location/LocationTagVo.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
vo
.
location
;
import
com.fasterxml.jackson.databind.annotation.JsonSerialize
;
import
com.fasterxml.jackson.databind.ser.std.ToStringSerializer
;
import
com.yiring.app.domain.location.LocationTag
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
java.io.Serializable
;
import
java.time.LocalDateTime
;
import
java.util.List
;
import
java.util.stream.Collectors
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
/**
* 定位标签视图
* @author LJ-2204
* @date 2022/4/14
*/
@ApiModel
(
"LocationTagVo"
)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
LocationTagVo
implements
Serializable
{
private
static
final
long
serialVersionUID
=
-
7884163207638158359L
;
@JsonSerialize
(
using
=
ToStringSerializer
.
class
)
@ApiModelProperty
(
value
=
"主键"
,
example
=
"188354391834"
)
Long
id
;
@ApiModelProperty
(
value
=
"编号"
,
example
=
"BTT88888888"
)
String
code
;
@ApiModelProperty
(
value
=
"标签型号"
,
example
=
"BTT01"
)
LocationTag
.
Type
type
;
@ApiModelProperty
(
value
=
"状态"
,
example
=
"静止"
)
Boolean
silent
;
@ApiModelProperty
(
value
=
"电量"
,
example
=
"1"
)
Integer
volt
;
@ApiModelProperty
(
value
=
"imei 设备编码"
,
example
=
"88888888"
)
String
imei
;
@ApiModelProperty
(
value
=
"最近更新时间"
,
example
=
"2022-01-01 00:00:00"
)
LocalDateTime
updateTime
;
public
static
List
<
LocationTagVo
>
transforms
(
List
<
LocationTag
>
locationTags
)
{
return
locationTags
.
stream
()
.
map
(
locationTag
->
LocationTagVo
.
builder
()
.
id
(
locationTag
.
getId
())
.
code
(
locationTag
.
getCode
())
.
type
(
locationTag
.
getType
())
.
silent
(
locationTag
.
getSilent
())
.
volt
(
locationTag
.
getVolt
())
.
build
()
)
.
collect
(
Collectors
.
toList
());
}
}
app/src/main/java/com/yiring/app/vo/video/VideoVo.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
vo
.
video
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
java.io.Serializable
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
import
org.locationtech.jts.geom.Point
;
/**
* @author tzl
* 2022/4/15 10:48
*/
@ApiModel
(
"VideoVo"
)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
VideoVo
implements
Serializable
{
@ApiModelProperty
(
value
=
"坐标点信息"
,
example
=
""
)
Point
point
;
@ApiModelProperty
(
value
=
"编号"
,
example
=
"88888888"
)
String
uuid
;
@ApiModelProperty
(
value
=
"m3u8地址"
,
example
=
""
)
String
m3u8
;
@ApiModelProperty
(
value
=
"备注"
,
example
=
"摄像头"
)
String
remark
;
@ApiModelProperty
(
value
=
"摄像头名称"
,
example
=
"摄像头1"
)
String
videoName
;
@ApiModelProperty
(
value
=
"状态"
,
example
=
"正常"
)
String
status
;
}
app/src/main/java/com/yiring/app/web/HelloController.java
浏览文件 @
f360f80d
/* (C) 2021 YiRing, Inc. */
package
com
.
yiring
.
app
.
web
;
import
cn.hutool.extra.spring.SpringUtil
;
import
com.alibaba.fastjson.JSONObject
;
import
com.yiring.app.constant.Code
;
import
com.yiring.app.domain.location.LocationTag
;
import
com.yiring.app.exception.CodeException
;
import
com.yiring.app.
push.domain.PushMessage
;
import
com.yiring.a
pp.push.service.PushService
;
import
com.yiring.app.
util.GeoUtils
;
import
com.yiring.a
uth.domain.user.User
;
import
com.yiring.common.core.Result
;
import
com.yiring.common.domain.BasicEntity
;
import
com.yiring.common.param.PageParam
;
import
com.yiring.common.vo.PageVo
;
import
io.swagger.annotations.Api
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
import
javax.annotation.Resource
;
import
javax.persistence.EntityManager
;
import
javax.persistence.criteria.*
;
import
javax.validation.Valid
;
import
lombok.AccessLevel
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.experimental.FieldDefaults
;
import
lombok.extern.slf4j.Slf4j
;
import
org.locationtech.jts.geom.Point
;
import
org.springframework.messaging.simp.SimpMessagingTemplate
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
...
...
@@ -51,10 +61,55 @@ public class HelloController {
return
Result
.
ok
(
vo
);
}
@Resource
SimpMessagingTemplate
simpMessagingTemplate
;
@GetMapping
(
"test"
)
public
Result
<
String
>
test
()
{
PushService
service
=
SpringUtil
.
getBean
(
PushService
.
class
);
service
.
push
(
PushMessage
.
Type
.
WS
,
new
JSONObject
().
fluentPut
(
"msg"
,
"hello"
));
return
Result
.
ok
();
public
Result
<
Point
>
test
()
{
Point
point
=
GeoUtils
.
createPoint
(
112.1
,
23.56
);
simpMessagingTemplate
.
convertAndSend
(
"/topic/position"
,
point
);
return
Result
.
ok
(
point
);
}
@Resource
EntityManager
em
;
@Data
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
static
class
UserVo
{
Long
id
;
String
avatar
;
String
code
;
}
@GetMapping
(
"test2"
)
public
Result
<
ArrayList
<
UserVo
>>
query
()
{
CriteriaBuilder
cb
=
em
.
getCriteriaBuilder
();
CriteriaQuery
<
UserVo
>
cq
=
cb
.
createQuery
(
UserVo
.
class
);
Root
<
User
>
root
=
cq
.
from
(
User
.
class
);
Expression
<
Long
>
id
=
root
.
get
(
BasicEntity
.
Fields
.
id
);
Expression
<
String
>
avatar
=
root
.
get
(
User
.
Fields
.
avatar
);
// 子查询
Subquery
<
String
>
query
=
cq
.
subquery
(
String
.
class
);
Root
<
LocationTag
>
tagRoot
=
query
.
from
(
LocationTag
.
class
);
query
.
select
(
tagRoot
.
get
(
LocationTag
.
Fields
.
code
));
query
.
where
(
cb
.
equal
(
tagRoot
.
get
(
LocationTag
.
Fields
.
user
),
root
));
// 构建查询字段
cq
.
multiselect
(
id
,
avatar
,
query
);
// 查询条件
List
<
Predicate
>
predicates
=
new
ArrayList
<>();
// 可根据入参判断是否需要查询指定字段
predicates
.
add
(
cb
.
isNotNull
(
root
.
get
(
User
.
Fields
.
avatar
)));
predicates
.
add
(
cb
.
equal
(
query
,
"BTT22222222"
));
cq
.
where
(
predicates
.
toArray
(
new
Predicate
[
0
]));
List
<
UserVo
>
users
=
em
.
createQuery
(
cq
).
getResultList
();
return
Result
.
ok
(
new
ArrayList
<>(
users
));
}
}
app/src/main/java/com/yiring/app/web/LocationTagController.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
web
;
import
com.yiring.app.param.location.LocationTagAddParam
;
import
com.yiring.app.param.location.LocationTagDeleteParam
;
import
com.yiring.app.param.location.LocationTagFindParam
;
import
com.yiring.app.param.location.LocationTagModifyParam
;
import
com.yiring.app.service.location.LocationTagService
;
import
com.yiring.app.vo.location.LocationTagVo
;
import
com.yiring.common.core.Result
;
import
com.yiring.common.param.IdParam
;
import
com.yiring.common.vo.PageVo
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
javax.annotation.Resource
;
import
javax.servlet.http.HttpServletResponse
;
import
javax.validation.Valid
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.multipart.MultipartFile
;
/**
* 定位标签
* @author LJ-2204
* @date 2022/4/13
*/
@Slf4j
@Validated
@Api
(
tags
=
"定位标签"
)
@RestController
@RequestMapping
(
"/location/tag/"
)
public
class
LocationTagController
{
@Resource
LocationTagService
locationTagService
;
@ApiOperation
(
"新增定位标签"
)
@PostMapping
(
"addLocationTag"
)
public
Result
<
String
>
addLocationTag
(
@Valid
LocationTagAddParam
param
)
{
return
locationTagService
.
addLocationTag
(
param
);
}
@ApiOperation
(
"分页查询"
)
@GetMapping
(
"findLocationTagPage"
)
public
Result
<
PageVo
<
LocationTagVo
>>
findLocationTagPage
(
@Valid
LocationTagFindParam
param
)
{
return
locationTagService
.
findLocationTagPage
(
param
);
}
@ApiOperation
(
"销毁定位标签"
)
@DeleteMapping
(
"deleteLocationTag"
)
public
Result
<
String
>
deleteLocationTag
(
@Valid
LocationTagDeleteParam
param
)
{
return
locationTagService
.
deleteLocationTag
(
param
);
}
@ApiOperation
(
"导出定位标签"
)
@GetMapping
(
"exportLocationTagInfo"
)
public
void
exportLocationTagInfo
(
@Valid
LocationTagFindParam
param
,
HttpServletResponse
response
)
{
locationTagService
.
exportLocationTagInfo
(
param
,
response
);
}
@ApiOperation
(
"导入定位标签"
)
@PostMapping
(
"importLocationTagInfo"
)
public
Result
<
String
>
importLocationTagInfo
(
@RequestParam
(
"file"
)
MultipartFile
file
)
{
return
locationTagService
.
importLocationTagInfo
(
file
);
}
@ApiOperation
(
"修改定位标签"
)
@PutMapping
(
"modifyLocationTag"
)
public
Result
<
String
>
modifyLocationTag
(
@Valid
LocationTagModifyParam
param
,
IdParam
idParam
)
{
return
locationTagService
.
modifyLocationTag
(
param
,
idParam
);
}
}
app/src/main/java/com/yiring/app/web/car/CarController.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
web
.
car
;
import
com.yiring.app.domain.car.Car
;
import
com.yiring.app.param.car.CarParam
;
import
com.yiring.app.param.car.CarQueryParam
;
import
com.yiring.app.service.car.CarService
;
import
com.yiring.app.vo.car.CarVo
;
import
com.yiring.common.core.Result
;
import
com.yiring.common.param.IdParam
;
import
com.yiring.common.util.poi.ExcelUtils
;
import
com.yiring.common.vo.PageVo
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiImplicitParam
;
import
io.swagger.annotations.ApiOperation
;
import
java.util.List
;
import
javax.annotation.Resource
;
import
javax.servlet.http.HttpServletResponse
;
import
javax.validation.Valid
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.bind.annotation.*
;
/**
* 车辆来访信息控制器
*
* @author tzl
* 2022/4/11 17:02
*/
@Slf4j
@Api
(
tags
=
"Car"
)
@Validated
@RestController
@RequestMapping
(
"/Car/"
)
public
class
CarController
{
@Resource
CarService
carService
;
@ApiOperation
(
value
=
"新增车辆来访信息"
)
@PostMapping
(
"saveCarInfo"
)
public
Result
<
Long
>
saveCarInfo
(
@Valid
CarParam
carParam
)
{
return
carService
.
saveCarInfo
(
carParam
);
}
@ApiOperation
(
value
=
"修改车辆来访信息"
)
@PostMapping
(
"updateCarInfo"
)
public
Result
<
Long
>
updateCarInfo
(
@Valid
CarParam
carParam
,
@Valid
IdParam
idParam
)
{
return
carService
.
updateCarInfo
(
carParam
,
idParam
);
}
@ApiOperation
(
value
=
"收卡"
)
@PostMapping
(
"cardRec"
)
public
Result
<
Long
>
cardRec
(
@Valid
IdParam
idParam
)
{
return
carService
.
cardRec
(
idParam
);
}
@ApiOperation
(
value
=
"发卡"
)
@ApiImplicitParam
(
value
=
"标签卡"
,
example
=
"DW8544568"
,
required
=
true
,
name
=
"labelCard"
)
@PostMapping
(
"cardSend"
)
public
Result
<
Long
>
cardSend
(
@Valid
IdParam
idParam
,
String
labelCard
)
{
return
carService
.
cardSend
(
idParam
,
labelCard
);
}
@ApiOperation
(
value
=
"删除车辆来访信息"
)
@PostMapping
(
"deleteCarInfo"
)
public
Result
<
String
>
deleteCarInfo
(
@Valid
IdParam
idParam
)
{
return
carService
.
deleteCarInfo
(
idParam
);
}
@ApiOperation
(
value
=
"查看车辆来访信息详情"
)
@GetMapping
(
"getCarInfo"
)
public
Result
<
CarVo
>
getCarInfo
(
@Valid
IdParam
idParam
)
{
return
carService
.
getCarInfo
(
idParam
);
}
@ApiOperation
(
value
=
"查看车辆来访信息(分页)"
)
@GetMapping
(
"pageCarInfo"
)
public
Result
<
PageVo
<
CarVo
>>
pageCarInfo
(
@Valid
CarQueryParam
carParam
)
{
return
carService
.
pageCarInfo
(
carParam
);
}
@ApiOperation
(
value
=
"导出车辆来访信息"
)
@PostMapping
(
"exportCarInfo"
)
public
void
exportCarInfo
(
HttpServletResponse
response
,
@Valid
CarQueryParam
carParam
)
{
List
<
Car
>
export
=
carService
.
export
(
carParam
);
ExcelUtils
<
Car
>
util
=
new
ExcelUtils
<>(
Car
.
class
);
// String fileName = URLEncoder.encode("车辆来访信息.xlsx", StandardCharsets.UTF_8);
response
.
setContentType
(
"application/octet-stream"
);
// response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
// response.setCharacterEncoding("utf-8");
util
.
exportExcel
(
response
,
export
,
"车辆来访信息"
);
}
}
app/src/main/java/com/yiring/app/web/dict/DictController.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
web
.
dict
;
import
com.yiring.app.param.dict.DictParam
;
import
com.yiring.app.param.dict.DictQueryParam
;
import
com.yiring.app.service.dict.DictService
;
import
com.yiring.common.core.Result
;
import
com.yiring.common.dict.Dict
;
import
com.yiring.common.param.IdParam
;
import
com.yiring.common.param.PageParam
;
import
com.yiring.common.vo.PageVo
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiImplicitParam
;
import
io.swagger.annotations.ApiOperation
;
import
java.util.ArrayList
;
import
javax.annotation.Resource
;
import
javax.validation.Valid
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
/**
* 字典数据控制器
*
* @author tzl
* 2022/4/13 17:10
*/
@Slf4j
@Validated
@Api
(
tags
=
"Dict"
)
@RestController
@RequestMapping
(
"/Dict/"
)
public
class
DictController
{
@Resource
DictService
dictService
;
@ApiOperation
(
value
=
"新增字典信息"
)
@PostMapping
(
"saveDictInfo"
)
public
Result
<
String
>
saveDictInfo
(
@Valid
DictParam
dictParam
)
{
return
dictService
.
saveDictInfo
(
dictParam
);
}
@ApiOperation
(
value
=
"修改字典信息"
)
@PostMapping
(
"updateDictInfo"
)
public
Result
<
String
>
updateDictInfo
(
@Valid
DictParam
dictParam
,
@Valid
IdParam
idParam
)
{
return
dictService
.
updateDictInfo
(
dictParam
,
idParam
);
}
@ApiOperation
(
value
=
"删除字典信息"
)
@PostMapping
(
"deleteDictById"
)
public
Result
<
String
>
deleteDictById
(
@Valid
IdParam
idParam
)
{
return
dictService
.
deleteDictById
(
idParam
);
}
@ApiOperation
(
value
=
"查看字典信息(分页)"
)
@GetMapping
(
"pageDictInfo"
)
public
Result
<
PageVo
<
Dict
>>
pageDictInfo
(
@Valid
DictQueryParam
queryParam
,
@Valid
PageParam
param
)
{
return
dictService
.
pageDictInfo
(
queryParam
,
param
);
}
@ApiOperation
(
value
=
"查看字典信息详情"
)
@GetMapping
(
"getDictInfo"
)
public
Result
<
Dict
>
getDictInfo
(
@Valid
IdParam
idParam
)
{
return
dictService
.
getDictInfo
(
idParam
.
getId
());
}
@ApiOperation
(
value
=
"根据类型获取字典信息详情"
)
@ApiImplicitParam
(
value
=
"字典类型"
,
example
=
"user_sex"
,
required
=
true
,
name
=
"dictType"
)
@GetMapping
(
"selectDict"
)
public
Result
<
ArrayList
<
Dict
>>
selectDict
(
String
dictType
)
{
return
dictService
.
selectDict
(
dictType
);
}
}
app/src/main/java/com/yiring/app/web/dict/DictTypeController.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
web
.
dict
;
import
io.swagger.annotations.Api
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
/**
* 字典类型控制器
*
* @author tzl
* 2022/4/14 15:14
*/
@Slf4j
@Validated
@Api
(
tags
=
"DictType"
)
@RestController
@RequestMapping
(
"/DictType/"
)
public
class
DictTypeController
{
//
// @Resource
// DictTypeService dictTypeService;
//
// @ApiOperation(value = "新增字典类型信息")
// @PostMapping("saveDictTypeInfo")
// public Result<String> saveDictTypeInfo(@Valid DictTypeParam dictTypeParam) {
// return dictTypeService.saveDictTypeInfo(dictTypeParam);
// }
//
// @ApiOperation(value = "修改字典类型信息")
// @PostMapping("updateDictTypeInfo")
// public Result<String> updateDictTypeInfo(@Valid DictTypeParam dictTypeParam, @Valid IdParam idParam) {
// return dictTypeService.updateDictTypeInfo(dictTypeParam, idParam);
// }
//
// @ApiOperation(value = "删除字典类型信息")
// @PostMapping("delecteById")
// public Result<String> delecteById(@Valid IdParam idParam) {
// return dictTypeService.delecteById(idParam.getId());
// }
//
// @ApiOperation(value = "查看字典类型信息(分页)")
// @GetMapping("pageDictTypeInfo")
// public Result<PageVo<DictType>> pageDictInfo(@Valid DictTypeQueryParam queryParam, @Valid PageParam param) {
// return dictTypeService.pageDictTypeInfo(queryParam, param);
// }
//
// @ApiOperation(value = "查看字典类型信息详情")
// @GetMapping("getDictTypeInfo")
// public Result<DictType> getDictTypeInfo(@Valid IdParam idParam) {
// return dictTypeService.getDictTypeInfo(idParam.getId());
// }
}
app/src/main/java/com/yiring/app/web/video/VideoController.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
web
.
video
;
import
com.yiring.app.param.video.VideoParam
;
import
com.yiring.app.param.video.VideoQueryParam
;
import
com.yiring.app.service.video.VideoService
;
import
com.yiring.app.vo.video.VideoVo
;
import
com.yiring.common.core.Result
;
import
com.yiring.common.param.IdParam
;
import
com.yiring.common.param.PageParam
;
import
com.yiring.common.vo.PageVo
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
javax.annotation.Resource
;
import
javax.validation.Valid
;
import
lombok.extern.slf4j.Slf4j
;
import
org.locationtech.jts.geom.Point
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
/**
* 监控点位控制器
* @author tzl
* 2022/4/8 16:51
*/
@Slf4j
@Validated
@Api
(
tags
=
"Video"
)
@RestController
@RequestMapping
(
"/video/"
)
public
class
VideoController
{
@Resource
VideoService
videoService
;
@ApiOperation
(
value
=
"新增监控点位信息"
)
@PostMapping
(
"saveVideo"
)
public
Result
<
String
>
findLatest
(
@Valid
VideoParam
videoParam
)
{
return
videoService
.
saveVideo
(
videoParam
);
}
@ApiOperation
(
value
=
"删除监控点位信息"
)
@PostMapping
(
"deleteVideo"
)
public
Result
<
String
>
deleteVideo
(
@Valid
IdParam
idParam
)
{
return
videoService
.
deleteVideo
(
idParam
);
}
@ApiOperation
(
value
=
"修改监控点位信息"
)
@PostMapping
(
"updateVideo"
)
public
Result
<
String
>
updateVideo
(
@Valid
VideoParam
videoParam
,
@Valid
IdParam
idParam
)
{
return
videoService
.
updateVideo
(
videoParam
,
idParam
);
}
@ApiOperation
(
value
=
"查看监控点位位置"
)
@PostMapping
(
"selectPoint"
)
public
Result
<
Point
>
selectPoint
(
@Valid
IdParam
idParam
)
{
return
videoService
.
selectPoint
(
idParam
);
}
@ApiOperation
(
value
=
"分页查询监控点位信息"
)
@PostMapping
(
"pageVideo"
)
public
Result
<
PageVo
<
VideoVo
>>
pageVideo
(
@Valid
VideoQueryParam
videoQueryParam
,
@Valid
PageParam
param
)
{
return
videoService
.
pageVideo
(
videoQueryParam
,
param
);
}
}
app/src/main/resources/application-dev.yml
浏览文件 @
f360f80d
...
...
@@ -26,6 +26,17 @@ spring:
username
:
admin
password
:
123456
virtual-host
:
/
# 开启发送端确认
publisher-confirm-type
:
correlated
# 开启接收端确认
publisher-returns
:
true
template
:
# 消息抵达队列,异步回调 confirm
mandatory
:
true
listener
:
simple
:
# 手动确认消息
acknowledge-mode
:
manual
# knife4j
knife4j
:
...
...
@@ -56,7 +67,7 @@ zy-config:
host
:
project.yz-online.com
# RabbitMQ 订阅配置
rabbitmq
:
enabled
:
fals
e
enabled
:
tru
e
host
:
${zy-config.host}
port
:
672
username
:
admin
...
...
basic-auth/build.gradle
浏览文件 @
f360f80d
...
...
@@ -15,9 +15,16 @@ dependencies {
implementation
"cn.dev33:sa-token-spring-boot-starter:${saTokenVersion}"
implementation
"cn.dev33:sa-token-dao-redis-jackson:${saTokenVersion}"
// hutool
-core
// hutool
implementation
"cn.hutool:hutool-core:${hutoolVersion}"
implementation
"cn.hutool:hutool-json:${hutoolVersion}"
implementation
"cn.hutool:hutool-http:${hutoolVersion}"
implementation
"cn.hutool:hutool-extra:${hutoolVersion}"
// fastjson
implementation
"com.alibaba:fastjson:${fastJsonVersion}"
// myexcel
implementation
"com.github.liaochong:myexcel:${myexcelVersion}"
}
basic-auth/src/main/java/com/yiring/auth/domain/post/PostRepository.java
浏览文件 @
f360f80d
...
...
@@ -3,6 +3,7 @@ package com.yiring.auth.domain.post;
import
java.io.Serializable
;
import
org.springframework.data.jpa.repository.JpaRepository
;
import
org.springframework.data.jpa.repository.JpaSpecificationExecutor
;
import
org.springframework.stereotype.Repository
;
/**
...
...
@@ -12,4 +13,4 @@ import org.springframework.stereotype.Repository;
*/
@Repository
public
interface
PostRepository
extends
JpaRepository
<
Post
,
Serializable
>
{}
public
interface
PostRepository
extends
JpaRepository
<
Post
,
Serializable
>
,
JpaSpecificationExecutor
<
Post
>
{}
basic-auth/src/main/java/com/yiring/auth/domain/user/User.java
浏览文件 @
f360f80d
...
...
@@ -16,6 +16,7 @@ import javax.persistence.*;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
import
lombok.experimental.FieldNameConstants
;
import
lombok.experimental.SuperBuilder
;
import
org.hibernate.Hibernate
;
import
org.hibernate.annotations.Comment
;
...
...
@@ -29,7 +30,7 @@ import org.hibernate.annotations.Comment;
@Getter
@Setter
@ToString
@
Builder
@
SuperBuilder
(
toBuilder
=
true
)
@NoArgsConstructor
@AllArgsConstructor
@FieldNameConstants
...
...
basic-auth/src/main/java/com/yiring/auth/excel/post/PostExcel.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
auth
.
excel
.
post
;
import
com.fasterxml.jackson.databind.annotation.JsonSerialize
;
import
com.fasterxml.jackson.databind.ser.std.ToStringSerializer
;
import
com.github.liaochong.myexcel.core.annotation.ExcelColumn
;
import
com.github.liaochong.myexcel.core.annotation.ExcelModel
;
import
com.yiring.auth.domain.post.Post
;
import
java.util.List
;
import
java.util.stream.Collectors
;
import
lombok.AccessLevel
;
import
lombok.Builder
;
import
lombok.Data
;
import
lombok.experimental.FieldDefaults
;
/**
* 职位信息导出模型
* @author LJ-2204
* @date 2022/4/13
*/
@ExcelModel
@Data
@Builder
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
PostExcel
{
@ExcelColumn
(
title
=
"编号"
)
@JsonSerialize
(
using
=
ToStringSerializer
.
class
)
Long
id
;
@ExcelColumn
(
title
=
"职位名称"
)
String
name
;
@ExcelColumn
(
title
=
"职位描述"
)
String
describe
;
@ExcelColumn
(
title
=
"是否启用"
)
@JsonSerialize
(
using
=
ToStringSerializer
.
class
)
Boolean
enable
;
public
static
List
<
PostExcel
>
transforms
(
List
<
Post
>
posts
)
{
return
posts
.
stream
()
.
map
(
post
->
PostExcel
.
builder
()
.
id
(
post
.
getId
())
.
name
(
post
.
getName
())
.
describe
(
post
.
getDescribe
())
.
enable
(
post
.
getEnable
())
.
build
()
)
.
collect
(
Collectors
.
toList
());
}
}
basic-auth/src/main/java/com/yiring/auth/param/post/PostFindParam.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
auth
.
param
.
post
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
java.io.Serializable
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
/**
* 职位分页入参
* @author LJ-2204
* @date 2022/4/13
*/
@ApiModel
(
"PostFindParam"
)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
PostFindParam
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1926710333813935577L
;
@ApiModelProperty
(
value
=
"名称"
,
example
=
"Java"
)
String
name
;
@ApiModelProperty
(
value
=
"是否启用"
,
example
=
"true"
)
Boolean
enable
;
@ApiModelProperty
(
value
=
"每页记录数"
,
example
=
"10"
)
Integer
pageSize
;
@ApiModelProperty
(
value
=
"页码"
,
example
=
"1"
)
Integer
pageNo
;
}
basic-auth/src/main/java/com/yiring/auth/param/post/PostParam.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
auth
.
param
.
post
;
import
com.yiring.auth.domain.post.Post
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
java.io.Serializable
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
/**
* 职位信息入参类
* @author LJ-2204
* @date 2022/4/12
*/
@ApiModel
(
"PostParam"
)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
PostParam
implements
Serializable
{
private
static
final
long
serialVersionUID
=
5247408856592333466L
;
@ApiModelProperty
(
value
=
"名称"
,
example
=
"Java"
,
required
=
true
)
String
name
;
@ApiModelProperty
(
value
=
"描述"
,
example
=
"描述"
,
required
=
true
)
String
describe
;
@ApiModelProperty
(
value
=
"是否启用"
,
example
=
"true"
,
required
=
true
)
Boolean
enable
;
public
Post
transform
()
{
return
Post
.
builder
().
name
(
this
.
name
).
describe
(
this
.
describe
).
enable
(
this
.
enable
).
build
();
}
}
basic-auth/src/main/java/com/yiring/auth/service/post/PostService.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
auth
.
service
.
post
;
import
com.yiring.auth.param.post.PostFindParam
;
import
com.yiring.auth.param.post.PostParam
;
import
com.yiring.auth.vo.post.PostVo
;
import
com.yiring.common.core.Result
;
import
com.yiring.common.param.IdParam
;
import
com.yiring.common.vo.PageVo
;
import
javax.servlet.http.HttpServletResponse
;
/**
* 职位信息
* @author LJ-2204
* @date 2022/4/13
*/
public
interface
PostService
{
/**
* 新增职位信息
* @param postParam 入参
* @return Result<String>
*/
Result
<
String
>
addPost
(
PostParam
postParam
);
/**
* 修改职位信息
* @param postParam 入参
* @param idParam id
* @return Result<String>
*/
Result
<
String
>
modifyPost
(
PostParam
postParam
,
IdParam
idParam
);
/**
* 销毁职位信息
* @param idParam id
* @return Result<String>
*/
Result
<
String
>
deletePost
(
IdParam
idParam
);
/**
* 职位信息分页
* @param param 入参
* @return Result<PageVo<PostVo>>
*/
Result
<
PageVo
<
PostVo
>>
findPostPage
(
PostFindParam
param
);
/**
* 详细信息查询
* @param idParam id
* @return Result<PostVo>
*/
Result
<
PostVo
>
findPostById
(
IdParam
idParam
);
/**
* 根据名称判断是否存在职业信息
* @param name 职业名称
* @return T/F
*/
boolean
hasPostInfo
(
String
name
);
/**
* 导出职位信息
* @param param 入参
* @param response 响应信息
*/
void
exportPostInfo
(
PostFindParam
param
,
HttpServletResponse
response
);
}
basic-auth/src/main/java/com/yiring/auth/service/post/impl/PostServiceImpl.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
auth
.
service
.
post
.
impl
;
import
cn.hutool.core.collection.ListUtil
;
import
cn.hutool.core.util.ObjectUtil
;
import
cn.hutool.core.util.StrUtil
;
import
com.github.liaochong.myexcel.core.DefaultStreamExcelBuilder
;
import
com.yiring.auth.domain.post.Post
;
import
com.yiring.auth.domain.post.PostRepository
;
import
com.yiring.auth.excel.post.PostExcel
;
import
com.yiring.auth.param.post.PostFindParam
;
import
com.yiring.auth.param.post.PostParam
;
import
com.yiring.auth.service.post.PostService
;
import
com.yiring.auth.vo.post.PostVo
;
import
com.yiring.common.core.Result
;
import
com.yiring.common.core.Status
;
import
com.yiring.common.param.IdParam
;
import
com.yiring.common.vo.PageVo
;
import
java.io.OutputStream
;
import
java.net.URLEncoder
;
import
java.nio.charset.StandardCharsets
;
import
java.util.List
;
import
java.util.Optional
;
import
java.util.concurrent.Executors
;
import
javax.annotation.Resource
;
import
javax.persistence.criteria.Predicate
;
import
javax.servlet.http.HttpServletResponse
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.poi.ss.usermodel.Workbook
;
import
org.springframework.data.domain.Example
;
import
org.springframework.data.domain.Page
;
import
org.springframework.data.domain.PageRequest
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.data.jpa.domain.Specification
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
/**
* 职位信息
* @author LJ-2204
* @date 2022/4/13
*/
@Transactional
(
rollbackFor
=
RuntimeException
.
class
)
@Service
@Slf4j
public
class
PostServiceImpl
implements
PostService
{
@Resource
PostRepository
postRepository
;
@Override
public
Result
<
String
>
addPost
(
PostParam
postParam
)
{
if
(
hasPostInfo
(
postParam
.
getName
()))
return
Result
.
no
(
Status
.
BAD_REQUEST
,
"职位已存在"
);
Post
post
=
postParam
.
transform
();
postRepository
.
save
(
post
);
return
Result
.
ok
();
}
@Override
public
Result
<
String
>
modifyPost
(
PostParam
postParam
,
IdParam
idParam
)
{
Optional
<
Post
>
postOptional
=
postRepository
.
findById
(
idParam
.
getId
());
if
(
postOptional
.
isEmpty
())
return
Result
.
no
(
Status
.
BAD_REQUEST
,
"被修改的数据不存在"
);
Post
post
=
postOptional
.
get
();
if
(!
StrUtil
.
equals
(
post
.
getName
(),
postParam
.
getName
()))
{
if
(
hasPostInfo
(
postParam
.
getName
()))
return
Result
.
no
(
Status
.
BAD_REQUEST
,
"职位已存在"
);
}
post
=
postParam
.
transform
();
post
.
setId
(
idParam
.
getId
());
postRepository
.
save
(
post
);
return
Result
.
ok
();
}
@Override
public
Result
<
String
>
deletePost
(
IdParam
idParam
)
{
Post
post
=
Post
.
builder
().
id
(
idParam
.
getId
()).
build
();
postRepository
.
delete
(
post
);
return
Result
.
ok
();
}
@Override
public
Result
<
PageVo
<
PostVo
>>
findPostPage
(
PostFindParam
param
)
{
Specification
<
Post
>
specification
=
getPostPageSpecification
(
param
);
if
(
ObjectUtil
.
isEmpty
(
param
.
getPageSize
())
&&
ObjectUtil
.
isEmpty
(
param
.
getPageNo
()))
{
//分页
Pageable
pageable
=
PageRequest
.
of
(
param
.
getPageNo
()
-
1
,
param
.
getPageSize
());
Page
<
Post
>
page
=
postRepository
.
findAll
(
specification
,
pageable
);
List
<
PostVo
>
postVos
=
PostVo
.
transforms
(
page
.
getContent
());
PageVo
<
PostVo
>
pageVo
=
PageVo
.
build
(
postVos
,
postVos
.
size
());
return
Result
.
ok
(
pageVo
);
}
else
{
List
<
Post
>
posts
=
postRepository
.
findAll
(
specification
);
List
<
PostVo
>
postVos
=
PostVo
.
transforms
(
posts
);
PageVo
<
PostVo
>
pageVo
=
PageVo
.
build
(
postVos
,
postVos
.
size
());
return
Result
.
ok
(
pageVo
);
}
}
@Override
public
Result
<
PostVo
>
findPostById
(
IdParam
idParam
)
{
Post
post
=
postRepository
.
getById
(
idParam
.
getId
());
PostVo
postVo
=
PostVo
.
transform
(
post
);
return
Result
.
ok
(
postVo
);
}
@Override
public
boolean
hasPostInfo
(
String
name
)
{
Post
post
=
Post
.
builder
().
name
(
name
).
build
();
return
postRepository
.
count
(
Example
.
of
(
post
))
>
0
;
}
@Override
public
void
exportPostInfo
(
PostFindParam
param
,
HttpServletResponse
response
)
{
Specification
<
Post
>
specification
=
getPostPageSpecification
(
param
);
List
<
Post
>
postList
=
postRepository
.
findAll
(
specification
);
List
<
PostExcel
>
postExcels
=
PostExcel
.
transforms
(
postList
);
try
(
DefaultStreamExcelBuilder
<
PostExcel
>
streamExcelBuilder
=
DefaultStreamExcelBuilder
.
of
(
PostExcel
.
class
)
.
threadPool
(
Executors
.
newFixedThreadPool
(
2
))
.
rowHeight
(
14
)
.
titleRowHeight
(
14
)
.
style
(
"cell->vertical-align:center;text-align:center"
,
"title->vertical-align:center;text-align:center;font-weight:bold;font-family:等线"
)
.
start
()
)
{
streamExcelBuilder
.
append
(
postExcels
);
String
fileName
=
URLEncoder
.
encode
(
"职位信息.xlsx"
,
StandardCharsets
.
UTF_8
);
response
.
setContentType
(
"application/octet-stream"
);
response
.
setHeader
(
"Content-Disposition"
,
"attachment;filename="
+
fileName
);
OutputStream
out
=
response
.
getOutputStream
();
Workbook
workbook
=
streamExcelBuilder
.
fixedTitles
().
build
();
workbook
.
write
(
out
);
workbook
.
close
();
out
.
flush
();
out
.
close
();
}
catch
(
Exception
e
)
{
log
.
error
(
e
.
getMessage
(),
e
);
throw
new
RuntimeException
(
"导出岗位信息失败: "
+
e
.
getMessage
());
}
}
private
Specification
<
Post
>
getPostPageSpecification
(
PostFindParam
param
)
{
return
(
root
,
cq
,
cb
)
->
{
List
<
Predicate
>
predicates
=
ListUtil
.
toList
();
if
(
StrUtil
.
isNotEmpty
(
param
.
getName
()))
{
predicates
.
add
(
cb
.
equal
(
root
.
get
(
Post
.
Fields
.
name
),
param
.
getName
()));
}
if
(
ObjectUtil
.
isNotEmpty
(
param
.
getEnable
()))
{
predicates
.
add
(
cb
.
equal
(
root
.
get
(
Post
.
Fields
.
enable
),
param
.
getEnable
()));
}
return
cq
.
where
(
predicates
.
toArray
(
new
Predicate
[
0
])).
getRestriction
();
};
}
}
basic-auth/src/main/java/com/yiring/auth/util/ZyUtil.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
auth
.
util
;
import
cn.hutool.core.convert.Convert
;
import
cn.hutool.core.map.MapUtil
;
import
cn.hutool.core.util.ObjectUtil
;
import
cn.hutool.extra.spring.SpringUtil
;
import
cn.hutool.http.Header
;
import
cn.hutool.http.HttpRequest
;
import
cn.hutool.http.HttpUtil
;
import
cn.hutool.json.JSONUtil
;
import
com.alibaba.fastjson.JSON
;
import
com.yiring.common.core.Result
;
import
java.io.Serializable
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.concurrent.TimeUnit
;
import
lombok.experimental.UtilityClass
;
import
org.springframework.data.redis.core.RedisTemplate
;
/**
* 真源授权工具
* @author LJ-2204
* @date 2022/4/15
*/
@UtilityClass
public
class
ZyUtil
{
RedisTemplate
<
String
,
Object
>
redisTemplate
;
static
{
redisTemplate
=
SpringUtil
.
getBean
(
"redisTemplate"
);
}
public
final
String
CLIENT_ID
=
"sc21080400"
;
public
final
String
CLIENT_SECRET
=
"12A14FDC"
;
public
final
String
GRANT_TYPE
=
"client_credentials"
;
public
final
String
KEY
=
"zy_token"
;
public
final
String
TOKEN_TYPE
=
"bearer "
;
public
final
String
URL_PREFIX
=
"http://project.yz-online.com:789"
;
/**
* 获取token
* @return token
*/
public
static
String
login
()
{
Object
obj
=
redisTemplate
.
opsForValue
().
get
(
KEY
);
if
(
ObjectUtil
.
isNotEmpty
(
obj
))
{
return
String
.
valueOf
(
obj
);
}
Map
<
String
,
Object
>
map
=
MapUtil
.
createMap
(
HashMap
.
class
);
map
.
put
(
"client_id"
,
CLIENT_ID
);
map
.
put
(
"client_secret"
,
CLIENT_SECRET
);
map
.
put
(
"grant_type"
,
GRANT_TYPE
);
String
json
=
HttpUtil
.
get
(
"http://project.yz-online.com:789/positionApi/oauth/token"
,
map
);
Map
result
=
JSON
.
parseObject
(
json
,
Map
.
class
);
String
access_token
=
result
.
get
(
"access_token"
).
toString
();
redisTemplate
.
opsForValue
().
set
(
KEY
,
access_token
,
1200
,
TimeUnit
.
SECONDS
);
return
access_token
;
}
/**
* 判断token是否有效
* @return T/F
*/
public
static
boolean
getToken
()
{
return
ObjectUtil
.
isNotEmpty
(
redisTemplate
.
opsForValue
().
get
(
KEY
));
}
/**
* get请求
* @param urlString 路径
* @param obj 参数
* @param timeout 请求时长
* @return json
*/
public
static
Result
get
(
String
urlString
,
Object
obj
,
int
timeout
)
{
String
json
=
JSONUtil
.
toJsonStr
(
obj
);
String
token
=
login
();
String
body
=
HttpRequest
.
get
(
URL_PREFIX
+
urlString
)
.
header
(
Header
.
AUTHORIZATION
,
TOKEN_TYPE
+
token
)
.
header
(
Header
.
CONTENT_TYPE
,
"application/json"
)
.
body
(
json
)
.
timeout
(
timeout
)
.
execute
()
.
body
();
return
getResult
(
body
);
}
/**
* post请求
* @param urlString 路径
* @param obj 参数
* @param timeout 请求时长
* @return json
*/
public
static
Result
<
Serializable
>
post
(
String
urlString
,
Object
obj
,
int
timeout
)
{
String
json
=
JSONUtil
.
toJsonStr
(
obj
);
String
token
=
login
();
String
body
=
HttpRequest
.
post
(
URL_PREFIX
+
urlString
)
.
header
(
Header
.
AUTHORIZATION
,
TOKEN_TYPE
+
token
)
.
header
(
Header
.
CONTENT_TYPE
,
"application/json"
)
.
body
(
json
)
.
timeout
(
timeout
)
.
execute
()
.
body
();
return
getResult
(
body
);
}
/**
* put请求
* @param urlString 路径
* @param obj 参数
* @param timeout 请求时长
* @return json
*/
public
static
Result
<
Serializable
>
put
(
String
urlString
,
Object
obj
,
int
timeout
)
{
String
json
=
JSONUtil
.
toJsonStr
(
obj
);
String
token
=
login
();
String
body
=
HttpRequest
.
put
(
URL_PREFIX
+
urlString
)
.
header
(
Header
.
AUTHORIZATION
,
TOKEN_TYPE
+
token
)
.
header
(
Header
.
CONTENT_TYPE
,
"application/json"
)
.
body
(
json
)
.
timeout
(
timeout
)
.
execute
()
.
body
();
return
getResult
(
body
);
}
/**
* delete请求
* @param urlString 路径
* @param obj 参数
* @param timeout 请求时长
* @return json
*/
public
static
Result
<
Serializable
>
delete
(
String
urlString
,
Object
obj
,
int
timeout
)
{
String
json
=
JSONUtil
.
toJsonStr
(
obj
);
String
token
=
login
();
String
body
=
HttpRequest
.
delete
(
URL_PREFIX
+
urlString
)
.
header
(
Header
.
AUTHORIZATION
,
TOKEN_TYPE
+
token
)
.
header
(
Header
.
CONTENT_TYPE
,
"application/json"
)
.
body
(
json
)
.
timeout
(
timeout
)
.
execute
()
.
body
();
return
getResult
(
body
);
}
/**
* 返回类型转换
* @param body json
* @return Result
*/
private
static
Result
<
Serializable
>
getResult
(
String
body
)
{
Map
map
=
JSONUtil
.
toBean
(
body
,
Map
.
class
);
Integer
code
=
Convert
.
toInt
(
map
.
get
(
"code"
));
String
msg
=
Convert
.
toStr
(
map
.
get
(
"msg"
));
return
Result
.
builder
().
code
(
code
).
message
(
msg
).
build
();
}
}
basic-auth/src/main/java/com/yiring/auth/vo/post/PostVo.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
auth
.
vo
.
post
;
import
com.fasterxml.jackson.databind.annotation.JsonSerialize
;
import
com.fasterxml.jackson.databind.ser.std.ToStringSerializer
;
import
com.yiring.auth.domain.post.Post
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
java.io.Serializable
;
import
java.util.List
;
import
java.util.stream.Collectors
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
/**
* 职位信息视图
* @author LJ-2204
* @date 2022/4/13
*/
@ApiModel
(
"PostVo"
)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
PostVo
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1011259844584399825L
;
@JsonSerialize
(
using
=
ToStringSerializer
.
class
)
@ApiModelProperty
(
value
=
"主键"
,
example
=
"1"
)
Long
id
;
@ApiModelProperty
(
value
=
"名称"
,
example
=
"Java"
)
String
name
;
@ApiModelProperty
(
value
=
"描述"
,
example
=
"描述"
)
String
describe
;
@ApiModelProperty
(
value
=
"是否启用"
,
example
=
"true"
)
Boolean
enable
;
public
static
PostVo
transform
(
Post
post
)
{
return
PostVo
.
builder
()
.
id
(
post
.
getId
())
.
name
(
post
.
getName
())
.
describe
(
post
.
getDescribe
())
.
enable
(
post
.
getEnable
())
.
build
();
}
public
static
List
<
PostVo
>
transforms
(
List
<
Post
>
posts
)
{
return
posts
.
stream
()
.
map
(
post
->
PostVo
.
builder
()
.
id
(
post
.
getId
())
.
name
(
post
.
getName
())
.
describe
(
post
.
getDescribe
())
.
enable
(
post
.
getEnable
())
.
build
()
)
.
collect
(
Collectors
.
toList
());
}
}
basic-auth/src/main/java/com/yiring/auth/web/post/PostController.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
auth
.
web
.
post
;
import
com.yiring.auth.param.post.PostFindParam
;
import
com.yiring.auth.param.post.PostParam
;
import
com.yiring.auth.service.post.PostService
;
import
com.yiring.auth.vo.post.PostVo
;
import
com.yiring.common.core.Result
;
import
com.yiring.common.param.IdParam
;
import
com.yiring.common.vo.PageVo
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
javax.annotation.Resource
;
import
javax.servlet.http.HttpServletResponse
;
import
javax.validation.Valid
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.bind.annotation.*
;
/**
* 职位信息控制器
* @author LJ-2204
* @date 2022/4/12
*/
@Slf4j
@Validated
@Api
(
tags
=
"职位信息"
)
@RestController
@RequestMapping
(
"/post/"
)
public
class
PostController
{
@Resource
PostService
postService
;
@ApiOperation
(
value
=
"新增职位"
)
@PostMapping
(
"addPost"
)
public
Result
<
String
>
addPost
(
@Valid
PostParam
postParam
)
{
return
postService
.
addPost
(
postParam
);
}
@ApiOperation
(
value
=
"修改职位"
)
@PutMapping
(
"modifyPost"
)
public
Result
<
String
>
modifyPost
(
@Valid
PostParam
postParam
,
@Valid
IdParam
idParam
)
{
return
postService
.
modifyPost
(
postParam
,
idParam
);
}
@ApiOperation
(
value
=
"销毁职位"
)
@DeleteMapping
(
"deletePost"
)
public
Result
<
String
>
deletePost
(
@Valid
IdParam
idParam
)
{
return
postService
.
deletePost
(
idParam
);
}
@ApiOperation
(
value
=
"分页查询"
)
@GetMapping
(
"findPostPage"
)
public
Result
<
PageVo
<
PostVo
>>
findPostPage
(
@Valid
PostFindParam
param
)
{
return
postService
.
findPostPage
(
param
);
}
@ApiOperation
(
value
=
"详细信息查询"
)
@GetMapping
(
"findPostById"
)
public
Result
<
PostVo
>
findPostById
(
@Valid
IdParam
idParam
)
{
return
postService
.
findPostById
(
idParam
);
}
@ApiOperation
(
value
=
"导出职位信息"
)
@GetMapping
(
"exportPostInfo"
)
public
void
exportPostInfo
(
@Valid
PostFindParam
param
,
HttpServletResponse
response
)
{
postService
.
exportPostInfo
(
param
,
response
);
}
}
basic-common/core/build.gradle
浏览文件 @
f360f80d
dependencies
{
implementation
project
(
":basic-common:util"
)
implementation
'org.springframework.boot:spring-boot-starter-aop'
implementation
'org.springframework.boot:spring-boot-starter-web'
implementation
'org.springframework.boot:spring-boot-starter-validation'
...
...
@@ -12,11 +10,9 @@ dependencies {
// swagger annotations
implementation
"io.swagger:swagger-annotations:${swaggerAnnotationsVersion}"
// hutool-extra
implementation
"cn.hutool:hutool-extra:${hutoolVersion}"
implementation
"cn.dev33:sa-token-dao-redis-jackson:${saTokenVersion}"
// fastjson
implementation
"com.alibaba:fastjson:${fastJsonVersion}"
implementation
fileTree
(
dir:
project
.
rootDir
.
getPath
()
+
'\\libs'
,
includes:
[
'*jar'
])
// JTS 几何对象操作库
implementation
"org.locationtech.jts:jts-core:${jtsVersion}"
...
...
basic-common/core/src/main/java/com/yiring/common/config/CorsConfig.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
config
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.web.cors.CorsConfiguration
;
import
org.springframework.web.cors.UrlBasedCorsConfigurationSource
;
import
org.springframework.web.filter.CorsFilter
;
/**
* 跨域设置
* @author tzl
* 2022/4/18 10:29
*/
@Configuration
public
class
CorsConfig
{
@Bean
public
CorsFilter
corsFilter
()
{
final
UrlBasedCorsConfigurationSource
urlBasedCorsConfigurationSource
=
new
UrlBasedCorsConfigurationSource
();
final
CorsConfiguration
corsConfiguration
=
new
CorsConfiguration
();
// corsConfiguration.setAllowCredentials(true);
corsConfiguration
.
addAllowedOrigin
(
"*"
);
corsConfiguration
.
addAllowedHeader
(
"*"
);
corsConfiguration
.
addAllowedMethod
(
"*"
);
urlBasedCorsConfigurationSource
.
registerCorsConfiguration
(
"/**"
,
corsConfiguration
);
return
new
CorsFilter
(
urlBasedCorsConfigurationSource
);
}
}
basic-common/core/src/main/java/com/yiring/common/config/JacksonConfig.java
浏览文件 @
f360f80d
...
...
@@ -8,6 +8,8 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import
javax.annotation.Resource
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.core.Ordered
;
import
org.springframework.core.annotation.Order
;
/**
* Jackson Config
...
...
@@ -17,6 +19,7 @@ import org.springframework.context.annotation.Configuration;
* 2022/4/17 16:54
*/
@Order
(
Ordered
.
HIGHEST_PRECEDENCE
)
@Configuration
public
class
JacksonConfig
{
...
...
basic-common/core/src/main/java/com/yiring/common/config/converter/JSONArrayConverter.java
deleted
100644 → 0
浏览文件 @
f490012a
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
config
.
converter
;
import
com.alibaba.fastjson.JSONArray
;
import
javax.persistence.AttributeConverter
;
import
javax.persistence.Converter
;
/**
* JSONArray JPA 类型转换
*
* @author Jim
* @version 0.1
* 2022/4/7 18:03
*/
@Converter
public
class
JSONArrayConverter
implements
AttributeConverter
<
JSONArray
,
String
>
{
@Override
public
String
convertToDatabaseColumn
(
JSONArray
json
)
{
return
json
.
toJSONString
();
}
@Override
public
JSONArray
convertToEntityAttribute
(
String
s
)
{
return
JSONArray
.
parseArray
(
s
);
}
}
basic-common/core/src/main/java/com/yiring/common/config/converter/JSONObjectConverter.java
deleted
100644 → 0
浏览文件 @
f490012a
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
config
.
converter
;
import
com.alibaba.fastjson.JSONObject
;
import
javax.persistence.AttributeConverter
;
import
javax.persistence.Converter
;
/**
* JSONObject JPA 类型转换
*
* @author Jim
* @version 0.1
* 2022/4/7 18:03
*/
@Converter
public
class
JSONObjectConverter
implements
AttributeConverter
<
JSONObject
,
String
>
{
@Override
public
String
convertToDatabaseColumn
(
JSONObject
json
)
{
return
json
.
toJSONString
();
}
@Override
public
JSONObject
convertToEntityAttribute
(
String
s
)
{
return
JSONObject
.
parseObject
(
s
);
}
}
basic-common/core/src/main/java/com/yiring/common/constant/RegEx.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
constant
;
/**
* 常用相关验证正则表达式
* @author tzl
* 2022/4/12 12:00
*/
public
class
RegEx
{
//车牌号码验证
public
static
final
String
CARNUM
=
"([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼]"
+
"{1}(([A-HJ-Z]{1}[A-HJ-NP-Z0-9]{5})|([A-HJ-Z]{1}(([DF]{1}[A-HJ-NP-Z0-9]{1}[0-9]{4})|([0-9]{5}[DF]"
+
"{1})))|([A-HJ-Z]{1}[A-D0-9]{1}[0-9]{3}警)))|([0-9]{6}使)|((([沪粤川云桂鄂陕蒙藏黑辽渝]{1}A)|鲁B|闽D|蒙E|蒙H)[0-9]{4}领)"
+
"|(WJ[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼·•]{1}[0-9]{4}[TDSHBXJ0-9]{1})"
+
"|([VKHBSLJNGCE]{1}[A-DJ-PR-TVY]{1}[0-9]{5})"
;
//手机号码验证
public
static
final
String
MOBILE
=
"^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(16[5,6])|(17[0-8])|(18[0-9])|(19[1、5、8、9]))\\d{8}$"
;
}
basic-common/core/src/main/java/com/yiring/common/core/redis/RedisCache.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
core
.
redis
;
import
java.util.Collection
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.concurrent.TimeUnit
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.redis.core.BoundSetOperations
;
import
org.springframework.data.redis.core.HashOperations
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.data.redis.core.ValueOperations
;
import
org.springframework.stereotype.Component
;
/**
* redis缓存 工具类
*
* @author tzl
* 2022/4/13 15:36
*/
@Component
public
class
RedisCache
{
@Autowired
public
RedisTemplate
redisTemplate
;
/**
* 缓存基本的对象,Integer、String、实体类等
*
* @param key 缓存的键值
* @param value 缓存的值
*/
public
<
T
>
void
setCacheObject
(
final
String
key
,
final
T
value
)
{
redisTemplate
.
opsForValue
().
set
(
key
,
value
);
}
/**
* 缓存基本的对象,Integer、String、实体类等
*
* @param key 缓存的键值
* @param value 缓存的值
* @param timeout 时间
* @param timeUnit 时间颗粒度
*/
public
<
T
>
void
setCacheObject
(
final
String
key
,
final
T
value
,
final
Integer
timeout
,
final
TimeUnit
timeUnit
)
{
redisTemplate
.
opsForValue
().
set
(
key
,
value
,
timeout
,
timeUnit
);
}
/**
* 设置有效时间
*
* @param key Redis键
* @param timeout 超时时间
* @return true=设置成功;false=设置失败
*/
public
boolean
expire
(
final
String
key
,
final
long
timeout
)
{
return
expire
(
key
,
timeout
,
TimeUnit
.
SECONDS
);
}
/**
* 设置有效时间
*
* @param key Redis键
* @param timeout 超时时间
* @param unit 时间单位
* @return true=设置成功;false=设置失败
*/
public
boolean
expire
(
final
String
key
,
final
long
timeout
,
final
TimeUnit
unit
)
{
return
Boolean
.
TRUE
.
equals
(
redisTemplate
.
expire
(
key
,
timeout
,
unit
));
}
/**
* 获得缓存的基本对象。
*
* @param key 缓存键值
* @return 缓存键值对应的数据
*/
public
<
T
>
T
getCacheObject
(
final
String
key
)
{
ValueOperations
<
String
,
T
>
operation
=
redisTemplate
.
opsForValue
();
return
operation
.
get
(
key
);
}
/**
* 删除单个对象
*
* @param key
*/
public
boolean
deleteObject
(
final
String
key
)
{
return
Boolean
.
TRUE
.
equals
(
redisTemplate
.
delete
(
key
));
}
/**
* 删除集合对象
*
* @param collection 多个对象
* @return
*/
public
long
deleteObject
(
final
Collection
collection
)
{
return
redisTemplate
.
delete
(
collection
);
}
/**
* 缓存List数据
*
* @param key 缓存的键值
* @param dataList 待缓存的List数据
* @return 缓存的对象
*/
public
<
T
>
long
setCacheList
(
final
String
key
,
final
List
<
T
>
dataList
)
{
Long
count
=
redisTemplate
.
opsForList
().
rightPushAll
(
key
,
dataList
);
return
count
==
null
?
0
:
count
;
}
/**
* 获得缓存的list对象
*
* @param key 缓存的键值
* @return 缓存键值对应的数据
*/
public
<
T
>
List
<
T
>
getCacheList
(
final
String
key
)
{
return
redisTemplate
.
opsForList
().
range
(
key
,
0
,
-
1
);
}
/**
* 缓存Set
*
* @param key 缓存键值
* @param dataSet 缓存的数据
* @return 缓存数据的对象
*/
public
<
T
>
BoundSetOperations
<
String
,
T
>
setCacheSet
(
final
String
key
,
final
Set
<
T
>
dataSet
)
{
BoundSetOperations
<
String
,
T
>
setOperation
=
redisTemplate
.
boundSetOps
(
key
);
for
(
T
t
:
dataSet
)
{
setOperation
.
add
(
t
);
}
return
setOperation
;
}
/**
* 获得缓存的set
*
* @param key String
* @return
*/
public
<
T
>
Set
<
T
>
getCacheSet
(
final
String
key
)
{
return
redisTemplate
.
opsForSet
().
members
(
key
);
}
/**
* 缓存Map
*
* @param key
* @param dataMap
*/
public
<
T
>
void
setCacheMap
(
final
String
key
,
final
Map
<
String
,
T
>
dataMap
)
{
if
(
dataMap
!=
null
)
{
redisTemplate
.
opsForHash
().
putAll
(
key
,
dataMap
);
}
}
/**
* 获得缓存的Map
*
* @param key
* @return
*/
public
<
T
>
Map
<
String
,
T
>
getCacheMap
(
final
String
key
)
{
return
redisTemplate
.
opsForHash
().
entries
(
key
);
}
/**
* 往Hash中存入数据
*
* @param key Redis键
* @param hKey Hash键
* @param value 值
*/
public
<
T
>
void
setCacheMapValue
(
final
String
key
,
final
String
hKey
,
final
T
value
)
{
redisTemplate
.
opsForHash
().
put
(
key
,
hKey
,
value
);
}
/**
* 获取Hash中的数据
*
* @param key Redis键
* @param hKey Hash键
* @return Hash中的对象
*/
public
<
T
>
T
getCacheMapValue
(
final
String
key
,
final
String
hKey
)
{
HashOperations
<
String
,
String
,
T
>
opsForHash
=
redisTemplate
.
opsForHash
();
return
opsForHash
.
get
(
key
,
hKey
);
}
/**
* 删除Hash中的数据
*
* @param key
* @param hKey
*/
public
void
delCacheMapValue
(
final
String
key
,
final
String
hKey
)
{
HashOperations
hashOperations
=
redisTemplate
.
opsForHash
();
hashOperations
.
delete
(
key
,
hKey
);
}
/**
* 获取多个Hash中的数据
*
* @param key Redis键
* @param hKeys Hash键集合
* @return Hash对象集合
*/
public
<
T
>
List
<
T
>
getMultiCacheMapValue
(
final
String
key
,
final
Collection
<
Object
>
hKeys
)
{
return
redisTemplate
.
opsForHash
().
multiGet
(
key
,
hKeys
);
}
/**
* 获得缓存的基本对象列表
*
* @param pattern 字符串前缀
* @return 对象列表
*/
public
Collection
<
String
>
keys
(
final
String
pattern
)
{
return
redisTemplate
.
keys
(
pattern
);
}
}
basic-common/core/src/main/java/com/yiring/common/dict/Dict.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
dict
;
import
java.io.Serializable
;
import
java.time.LocalDateTime
;
import
javax.persistence.Entity
;
import
javax.persistence.GeneratedValue
;
import
javax.persistence.Id
;
import
javax.persistence.Table
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
import
lombok.experimental.FieldNameConstants
;
import
org.hibernate.annotations.Comment
;
import
org.hibernate.annotations.GenericGenerator
;
import
org.hibernate.snowflake.SnowflakeId
;
/**
* 字典表
*
* @author tzl
* 2022/4/13 15:36
*/
@Getter
@Setter
@ToString
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldNameConstants
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
@Entity
@Table
(
name
=
"SYS_DICT"
)
@Comment
(
"字典"
)
public
class
Dict
implements
Serializable
{
@Id
@Comment
(
"主键id"
)
@GeneratedValue
(
generator
=
SnowflakeId
.
GENERATOR
)
@GenericGenerator
(
name
=
SnowflakeId
.
GENERATOR
,
strategy
=
SnowflakeId
.
Strategy
.
LONG
)
Long
id
;
@Comment
(
"字典排序"
)
Integer
dictSort
;
@Comment
(
"字典标签"
)
String
dictLabel
;
@Comment
(
"字典键值"
)
String
dictValue
;
@Comment
(
"字典类型"
)
String
dictType
;
@Comment
(
"状态(0正常 1停用)"
)
String
status
;
@Comment
(
"备注"
)
String
remark
;
@Comment
(
"创建时间"
)
LocalDateTime
createTime
;
}
basic-common/core/src/main/java/com/yiring/common/dict/DictRepository.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
dict
;
import
java.io.Serializable
;
import
java.util.List
;
import
org.springframework.data.jpa.repository.JpaRepository
;
import
org.springframework.data.jpa.repository.JpaSpecificationExecutor
;
import
org.springframework.data.jpa.repository.Modifying
;
import
org.springframework.data.jpa.repository.Query
;
import
org.springframework.transaction.annotation.Transactional
;
/**
* @author tzl
* 2022/4/13 15:32
*/
public
interface
DictRepository
extends
JpaRepository
<
Dict
,
Serializable
>,
JpaSpecificationExecutor
<
Dict
>
{
/**
* 根据字典类型和字典键值查询字典数据信息
*
* @param dictType String
* @param dictValue String
* @return 字典标签
*/
@Query
(
"select dictLabel from Dict where dictType = ?1 and dictValue = ?2"
)
String
findDictLabel
(
String
dictType
,
String
dictValue
);
/**
* 根据字典类型查询所有启用的字典数据
*
* @param dictType 字典类型
* @return 字典数据集合
*/
@Query
(
"select d from Dict d where d.dictType = ?1"
)
List
<
Dict
>
findByDictType
(
String
dictType
);
@Modifying
@Transactional
@Query
(
"update Dict set dictType=?1 where dictType=?2"
)
boolean
updateDictType
(
String
param
,
String
dictType
);
}
basic-common/core/src/main/java/com/yiring/common/dict/DictType.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
dict
;
import
java.io.Serializable
;
import
java.time.LocalDateTime
;
import
javax.persistence.Entity
;
import
javax.persistence.GeneratedValue
;
import
javax.persistence.Id
;
import
javax.persistence.Table
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
import
lombok.experimental.FieldNameConstants
;
import
org.hibernate.annotations.Comment
;
import
org.hibernate.annotations.GenericGenerator
;
import
org.hibernate.snowflake.SnowflakeId
;
/**
* @author tzl
* 2022/4/14 14:07
*/
@Getter
@Setter
@ToString
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldNameConstants
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
@Entity
@Table
(
name
=
"SYS_DICT_TYPE"
)
@Comment
(
"字典类型"
)
public
class
DictType
implements
Serializable
{
@Id
@Comment
(
"主键id"
)
@GeneratedValue
(
generator
=
SnowflakeId
.
GENERATOR
)
@GenericGenerator
(
name
=
SnowflakeId
.
GENERATOR
,
strategy
=
SnowflakeId
.
Strategy
.
LONG
)
Long
id
;
@Comment
(
"字典名称"
)
String
dictName
;
@Comment
(
"字典类型"
)
String
dictType
;
@Comment
(
"状态(0正常 1停用)"
)
String
status
;
@Comment
(
"创建时间"
)
LocalDateTime
createTime
;
}
basic-common/core/src/main/java/com/yiring/common/dict/DictTypeRepository.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
dict
;
import
java.io.Serializable
;
import
org.springframework.data.jpa.repository.JpaRepository
;
import
org.springframework.data.jpa.repository.JpaSpecificationExecutor
;
/**
* @author tzl
* 2022/4/13 15:32
*/
public
interface
DictTypeRepository
extends
JpaRepository
<
DictType
,
Serializable
>,
JpaSpecificationExecutor
<
DictType
>
{}
basic-common/redis/build.gradle
浏览文件 @
f360f80d
dependencies
{
implementation
'org.springframework.boot:spring-boot-starter-data-redis'
// jackson-databind ( io.spring.dependency-management )
implementation
"com.fasterxml.jackson.core:jackson-databind"
// hutool-crypto
implementation
"cn.hutool:hutool-crypto:${hutoolVersion}"
}
basic-common/redis/src/main/java/com/yiring/common/config/CacheKeyGenerator.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
config
;
import
cn.hutool.crypto.digest.DigestUtil
;
import
java.lang.reflect.Method
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Objects
;
import
lombok.NonNull
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.cache.interceptor.KeyGenerator
;
import
org.springframework.stereotype.Component
;
/**
* Cache KeyGenerator
*
* @author Jim
* @version 0.1
* 2022/4/19 15:36
*/
@Slf4j
@Component
public
class
CacheKeyGenerator
implements
KeyGenerator
{
@Override
@NonNull
public
Object
generate
(
Object
target
,
Method
method
,
Object
...
params
)
{
int
len
=
params
.
length
;
Map
<
String
,
Object
>
map
=
new
HashMap
<>(
2
+
len
);
map
.
put
(
"target"
,
target
.
getClass
().
toGenericString
());
map
.
put
(
"method"
,
method
.
getName
());
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
map
.
put
(
"params-"
+
i
,
Objects
.
toString
(
params
[
i
]));
}
return
DigestUtil
.
sha256
(
map
.
toString
());
}
}
basic-common/redis/src/main/java/com/yiring/common/config/RedisConfig.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
config
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
java.time.Duration
;
import
javax.annotation.Resource
;
import
org.springframework.cache.annotation.EnableCaching
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.data.redis.cache.RedisCacheConfiguration
;
import
org.springframework.data.redis.cache.RedisCacheManager
;
import
org.springframework.data.redis.connection.RedisConnectionFactory
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer
;
import
org.springframework.data.redis.serializer.RedisSerializationContext
;
import
org.springframework.data.redis.serializer.StringRedisSerializer
;
/**
* Redis Config
*
* @author Jim
* @version 0.1
* 2022/4/19 15:27
*/
@EnableCaching
@Configuration
public
class
RedisConfig
{
@Resource
ObjectMapper
objectMapper
;
@Bean
public
RedisTemplate
<
String
,
Object
>
redisTemplate
(
RedisConnectionFactory
factory
)
{
RedisTemplate
<
String
,
Object
>
redisTemplate
=
new
RedisTemplate
<>();
StringRedisSerializer
stringRedisSerializer
=
new
StringRedisSerializer
();
redisTemplate
.
setKeySerializer
(
stringRedisSerializer
);
redisTemplate
.
setHashKeySerializer
(
stringRedisSerializer
);
redisTemplate
.
setDefaultSerializer
(
new
GenericJackson2JsonRedisSerializer
(
objectMapper
));
redisTemplate
.
setEnableTransactionSupport
(
false
);
redisTemplate
.
setConnectionFactory
(
factory
);
redisTemplate
.
afterPropertiesSet
();
return
redisTemplate
;
}
@Bean
public
RedisCacheManager
cacheManager
(
RedisConnectionFactory
connectionFactory
)
{
RedisCacheConfiguration
config
=
RedisCacheConfiguration
.
defaultCacheConfig
()
.
entryTtl
(
Duration
.
ofMinutes
(
5
))
.
serializeKeysWith
(
RedisSerializationContext
.
SerializationPair
.
fromSerializer
(
new
StringRedisSerializer
()))
.
serializeValuesWith
(
RedisSerializationContext
.
SerializationPair
.
fromSerializer
(
new
GenericJackson2JsonRedisSerializer
())
)
.
disableCachingNullValues
();
return
RedisCacheManager
.
builder
(
connectionFactory
).
cacheDefaults
(
config
).
transactionAware
().
build
();
}
}
basic-common/redis/src/main/java/com/yiring/common/core/Redis.java
浏览文件 @
f360f80d
...
...
@@ -441,6 +441,15 @@ public final class Redis {
}
/**
* 获取所有 key
* @param pattern 查询规则
* @return 所有匹配的 Key 集合
*/
public
Set
<
String
>
keys
(
String
pattern
)
{
return
redisTemplate
.
keys
(
pattern
);
}
/**
* 返回最新的redis状态信息
*
* @return 信息
...
...
basic-common/util/build.gradle
浏览文件 @
f360f80d
dependencies
{
implementation
project
(
":basic-common:core"
)
implementation
project
(
":basic-common:redis"
)
implementation
'org.springframework.boot:spring-boot-starter-web'
implementation
'org.springframework.boot:spring-boot-starter-aop'
// hutool-extra
implementation
"cn.hutool:hutool-extra:${hutoolVersion}"
// fastjson
implementation
"com.alibaba:fastjson:${fastJsonVersion}"
implementation
group:
'org.apache.poi'
,
name:
'poi'
,
version:
'5.2.2'
implementation
group:
'org.apache.poi'
,
name:
'poi-ooxml'
,
version:
'5.2.2'
implementation
group:
'org.apache.commons'
,
name:
'commons-lang3'
,
version:
'3.12.0'
}
basic-common/util/src/main/java/com/yiring/common/annotation/Excel.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
annotation
;
import
com.yiring.common.util.poi.ExcelHandlerAdapter
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
import
java.math.BigDecimal
;
/**
* 自定义导出Excel数据注解
*
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
(
ElementType
.
FIELD
)
public
@interface
Excel
{
/**
* 导出时在excel中排序
*/
int
sort
()
default
Integer
.
MAX_VALUE
;
/**
* 导出到Excel中的名字.
*/
String
name
()
default
""
;
/**
* 日期格式, 如: yyyy-MM-dd
*/
String
dateFormat
()
default
""
;
/**
* 如果是字典类型,请设置字典的type值 (如: user_sex)
*/
String
dictType
()
default
""
;
/**
* 读取内容转表达式 (如: 0=男,1=女,2=未知)
*/
String
readConverterExp
()
default
""
;
/**
* 分隔符,读取字符串组内容
*/
String
separator
()
default
","
;
/**
* BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化)
*/
int
scale
()
default
-
1
;
/**
* BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN
*/
int
roundingMode
()
default
BigDecimal
.
ROUND_HALF_EVEN
;
/**
* 导出类型(0数字 1字符串)
*/
ColumnType
cellType
()
default
ColumnType
.
STRING
;
/**
* 导出时在excel中每个列的高度 单位为字符
*/
double
height
()
default
14
;
/**
* 导出时在excel中每个列的宽 单位为字符
*/
double
width
()
default
16
;
/**
* 文字后缀,如% 90 变成90%
*/
String
suffix
()
default
""
;
/**
* 当值为空时,字段的默认值
*/
String
defaultValue
()
default
""
;
/**
* 提示信息
*/
String
prompt
()
default
""
;
/**
* 设置只能选择不能输入的列内容.
*/
String
[]
combo
()
default
{};
/**
* 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
*/
boolean
isExport
()
default
true
;
/**
* 另一个类中的属性名称,支持多级获取,以小数点隔开
*/
String
targetAttr
()
default
""
;
/**
* 是否自动统计数据,在最后追加一行统计数据总和
*/
boolean
isStatistics
()
default
false
;
/**
* 导出字段对齐方式(0:默认;1:靠左;2:居中;3:靠右)
*/
Align
align
()
default
Align
.
AUTO
;
/**
* 自定义数据处理器
*/
Class
<?>
handler
()
default
ExcelHandlerAdapter
.
class
;
/**
* 自定义数据处理器参数
*/
String
[]
args
()
default
{};
enum
Align
{
AUTO
(
0
),
LEFT
(
1
),
CENTER
(
2
),
RIGHT
(
3
);
private
final
int
value
;
Align
(
int
value
)
{
this
.
value
=
value
;
}
public
int
value
()
{
return
this
.
value
;
}
}
/**
* 字段类型(0:导出导入;1:仅导出;2:仅导入)
*/
Type
type
()
default
Type
.
ALL
;
enum
Type
{
ALL
(
0
),
EXPORT
(
1
),
IMPORT
(
2
);
private
final
int
value
;
Type
(
int
value
)
{
this
.
value
=
value
;
}
int
value
()
{
return
this
.
value
;
}
}
enum
ColumnType
{
NUMERIC
(
0
),
STRING
(
1
),
IMAGE
(
2
);
private
final
int
value
;
ColumnType
(
int
value
)
{
this
.
value
=
value
;
}
int
value
()
{
return
this
.
value
;
}
}
}
basic-common/util/src/main/java/com/yiring/common/annotation/Excels.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
annotation
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* Excel注解集
*/
@Target
(
ElementType
.
FIELD
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
Excels
{
Excel
[]
value
();
}
basic-common/
core
/src/main/java/com/yiring/common/aspect/RequestAspect.java
→
basic-common/
util
/src/main/java/com/yiring/common/aspect/RequestAspect.java
浏览文件 @
f360f80d
File moved
basic-common/util/src/main/java/com/yiring/common/text/Convert.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
text
;
import
com.yiring.common.util.StrUtils
;
import
java.math.BigDecimal
;
import
java.math.BigInteger
;
import
java.nio.ByteBuffer
;
import
java.nio.charset.Charset
;
import
java.text.NumberFormat
;
import
java.util.Set
;
/**
* 类型转换器
*/
public
class
Convert
{
/**
* 转换为字符串<br>
* 如果给定的值为null,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public
static
String
toStr
(
Object
value
,
String
defaultValue
)
{
if
(
null
==
value
)
{
return
defaultValue
;
}
if
(
value
instanceof
String
)
{
return
(
String
)
value
;
}
return
value
.
toString
();
}
/**
* 转换为字符串<br>
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public
static
String
toStr
(
Object
value
)
{
return
toStr
(
value
,
null
);
}
/**
* 转换为字符<br>
* 如果给定的值为null,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public
static
Character
toChar
(
Object
value
,
Character
defaultValue
)
{
if
(
null
==
value
)
{
return
defaultValue
;
}
if
(
value
instanceof
Character
)
{
return
(
Character
)
value
;
}
final
String
valueStr
=
toStr
(
value
,
null
);
return
StrUtils
.
isEmpty
(
valueStr
)
?
defaultValue
:
valueStr
.
charAt
(
0
);
}
/**
* 转换为字符<br>
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public
static
Character
toChar
(
Object
value
)
{
return
toChar
(
value
,
null
);
}
/**
* 转换为byte<br>
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public
static
Byte
toByte
(
Object
value
,
Byte
defaultValue
)
{
if
(
value
==
null
)
{
return
defaultValue
;
}
if
(
value
instanceof
Byte
)
{
return
(
Byte
)
value
;
}
if
(
value
instanceof
Number
)
{
return
((
Number
)
value
).
byteValue
();
}
final
String
valueStr
=
toStr
(
value
,
null
);
if
(
StrUtils
.
isEmpty
(
valueStr
))
{
return
defaultValue
;
}
try
{
return
Byte
.
parseByte
(
valueStr
);
}
catch
(
Exception
e
)
{
return
defaultValue
;
}
}
/**
* 转换为byte<br>
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public
static
Byte
toByte
(
Object
value
)
{
return
toByte
(
value
,
null
);
}
/**
* 转换为Short<br>
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public
static
Short
toShort
(
Object
value
,
Short
defaultValue
)
{
if
(
value
==
null
)
{
return
defaultValue
;
}
if
(
value
instanceof
Short
)
{
return
(
Short
)
value
;
}
if
(
value
instanceof
Number
)
{
return
((
Number
)
value
).
shortValue
();
}
final
String
valueStr
=
toStr
(
value
,
null
);
if
(
StrUtils
.
isEmpty
(
valueStr
))
{
return
defaultValue
;
}
try
{
return
Short
.
parseShort
(
valueStr
.
trim
());
}
catch
(
Exception
e
)
{
return
defaultValue
;
}
}
/**
* 转换为Short<br>
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public
static
Short
toShort
(
Object
value
)
{
return
toShort
(
value
,
null
);
}
/**
* 转换为Number<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public
static
Number
toNumber
(
Object
value
,
Number
defaultValue
)
{
if
(
value
==
null
)
{
return
defaultValue
;
}
if
(
value
instanceof
Number
)
{
return
(
Number
)
value
;
}
final
String
valueStr
=
toStr
(
value
,
null
);
if
(
StrUtils
.
isEmpty
(
valueStr
))
{
return
defaultValue
;
}
try
{
return
NumberFormat
.
getInstance
().
parse
(
valueStr
);
}
catch
(
Exception
e
)
{
return
defaultValue
;
}
}
/**
* 转换为Number<br>
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public
static
Number
toNumber
(
Object
value
)
{
return
toNumber
(
value
,
null
);
}
/**
* 转换为int<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public
static
Integer
toInt
(
Object
value
,
Integer
defaultValue
)
{
if
(
value
==
null
)
{
return
defaultValue
;
}
if
(
value
instanceof
Integer
)
{
return
(
Integer
)
value
;
}
if
(
value
instanceof
Number
)
{
return
((
Number
)
value
).
intValue
();
}
final
String
valueStr
=
toStr
(
value
,
null
);
if
(
StrUtils
.
isEmpty
(
valueStr
))
{
return
defaultValue
;
}
try
{
return
Integer
.
parseInt
(
valueStr
.
trim
());
}
catch
(
Exception
e
)
{
return
defaultValue
;
}
}
/**
* 转换为int<br>
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public
static
Integer
toInt
(
Object
value
)
{
return
toInt
(
value
,
null
);
}
/**
* 转换为Integer数组<br>
*
* @param str 被转换的值
* @return 结果
*/
public
static
Integer
[]
toIntArray
(
String
str
)
{
return
toIntArray
(
","
,
str
);
}
/**
* 转换为Long数组<br>
*
* @param str 被转换的值
* @return 结果
*/
public
static
Long
[]
toLongArray
(
String
str
)
{
return
toLongArray
(
","
,
str
);
}
/**
* 转换为Integer数组<br>
*
* @param split 分隔符
* @param split 被转换的值
* @return 结果
*/
public
static
Integer
[]
toIntArray
(
String
split
,
String
str
)
{
if
(
StrUtils
.
isEmpty
(
str
))
{
return
new
Integer
[]
{};
}
String
[]
arr
=
str
.
split
(
split
);
final
Integer
[]
ints
=
new
Integer
[
arr
.
length
];
for
(
int
i
=
0
;
i
<
arr
.
length
;
i
++)
{
final
Integer
v
=
toInt
(
arr
[
i
],
0
);
ints
[
i
]
=
v
;
}
return
ints
;
}
/**
* 转换为Long数组<br>
*
* @param split 分隔符
* @param str 被转换的值
* @return 结果
*/
public
static
Long
[]
toLongArray
(
String
split
,
String
str
)
{
if
(
StrUtils
.
isEmpty
(
str
))
{
return
new
Long
[]
{};
}
String
[]
arr
=
str
.
split
(
split
);
final
Long
[]
longs
=
new
Long
[
arr
.
length
];
for
(
int
i
=
0
;
i
<
arr
.
length
;
i
++)
{
final
Long
v
=
toLong
(
arr
[
i
],
null
);
longs
[
i
]
=
v
;
}
return
longs
;
}
/**
* 转换为String数组<br>
*
* @param str 被转换的值
* @return 结果
*/
public
static
String
[]
toStrArray
(
String
str
)
{
return
toStrArray
(
","
,
str
);
}
/**
* 转换为String数组<br>
*
* @param split 分隔符
* @param split 被转换的值
* @return 结果
*/
public
static
String
[]
toStrArray
(
String
split
,
String
str
)
{
return
str
.
split
(
split
);
}
/**
* 转换为long<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public
static
Long
toLong
(
Object
value
,
Long
defaultValue
)
{
if
(
value
==
null
)
{
return
defaultValue
;
}
if
(
value
instanceof
Long
)
{
return
(
Long
)
value
;
}
if
(
value
instanceof
Number
)
{
return
((
Number
)
value
).
longValue
();
}
final
String
valueStr
=
toStr
(
value
,
null
);
if
(
StrUtils
.
isEmpty
(
valueStr
))
{
return
defaultValue
;
}
try
{
// 支持科学计数法
return
new
BigDecimal
(
valueStr
.
trim
()).
longValue
();
}
catch
(
Exception
e
)
{
return
defaultValue
;
}
}
/**
* 转换为long<br>
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public
static
Long
toLong
(
Object
value
)
{
return
toLong
(
value
,
null
);
}
/**
* 转换为double<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public
static
Double
toDouble
(
Object
value
,
Double
defaultValue
)
{
if
(
value
==
null
)
{
return
defaultValue
;
}
if
(
value
instanceof
Double
)
{
return
(
Double
)
value
;
}
if
(
value
instanceof
Number
)
{
return
((
Number
)
value
).
doubleValue
();
}
final
String
valueStr
=
toStr
(
value
,
null
);
if
(
StrUtils
.
isEmpty
(
valueStr
))
{
return
defaultValue
;
}
try
{
// 支持科学计数法
return
new
BigDecimal
(
valueStr
.
trim
()).
doubleValue
();
}
catch
(
Exception
e
)
{
return
defaultValue
;
}
}
/**
* 转换为double<br>
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public
static
Double
toDouble
(
Object
value
)
{
return
toDouble
(
value
,
null
);
}
/**
* 转换为Float<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public
static
Float
toFloat
(
Object
value
,
Float
defaultValue
)
{
if
(
value
==
null
)
{
return
defaultValue
;
}
if
(
value
instanceof
Float
)
{
return
(
Float
)
value
;
}
if
(
value
instanceof
Number
)
{
return
((
Number
)
value
).
floatValue
();
}
final
String
valueStr
=
toStr
(
value
,
null
);
if
(
StrUtils
.
isEmpty
(
valueStr
))
{
return
defaultValue
;
}
try
{
return
Float
.
parseFloat
(
valueStr
.
trim
());
}
catch
(
Exception
e
)
{
return
defaultValue
;
}
}
/**
* 转换为Float<br>
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public
static
Float
toFloat
(
Object
value
)
{
return
toFloat
(
value
,
null
);
}
/**
* 转换为boolean<br>
* String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public
static
Boolean
toBool
(
Object
value
,
Boolean
defaultValue
)
{
if
(
value
==
null
)
{
return
defaultValue
;
}
if
(
value
instanceof
Boolean
)
{
return
(
Boolean
)
value
;
}
String
valueStr
=
toStr
(
value
,
null
);
if
(
StrUtils
.
isEmpty
(
valueStr
))
{
return
defaultValue
;
}
valueStr
=
valueStr
.
trim
().
toLowerCase
();
switch
(
valueStr
)
{
case
"true"
:
return
true
;
case
"false"
:
return
false
;
case
"yes"
:
return
true
;
case
"ok"
:
return
true
;
case
"no"
:
return
false
;
case
"1"
:
return
true
;
case
"0"
:
return
false
;
default
:
return
defaultValue
;
}
}
/**
* 转换为boolean<br>
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public
static
Boolean
toBool
(
Object
value
)
{
return
toBool
(
value
,
null
);
}
/**
* 转换为Enum对象<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
*
* @param clazz Enum的Class
* @param value 值
* @param defaultValue 默认值
* @return Enum
*/
public
static
<
E
extends
Enum
<
E
>>
E
toEnum
(
Class
<
E
>
clazz
,
Object
value
,
E
defaultValue
)
{
if
(
value
==
null
)
{
return
defaultValue
;
}
if
(
clazz
.
isAssignableFrom
(
value
.
getClass
()))
{
@SuppressWarnings
(
"unchecked"
)
E
myE
=
(
E
)
value
;
return
myE
;
}
final
String
valueStr
=
toStr
(
value
,
null
);
if
(
StrUtils
.
isEmpty
(
valueStr
))
{
return
defaultValue
;
}
try
{
return
Enum
.
valueOf
(
clazz
,
valueStr
);
}
catch
(
Exception
e
)
{
return
defaultValue
;
}
}
/**
* 转换为Enum对象<br>
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
*
* @param clazz Enum的Class
* @param value 值
* @return Enum
*/
public
static
<
E
extends
Enum
<
E
>>
E
toEnum
(
Class
<
E
>
clazz
,
Object
value
)
{
return
toEnum
(
clazz
,
value
,
null
);
}
/**
* 转换为BigInteger<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public
static
BigInteger
toBigInteger
(
Object
value
,
BigInteger
defaultValue
)
{
if
(
value
==
null
)
{
return
defaultValue
;
}
if
(
value
instanceof
BigInteger
)
{
return
(
BigInteger
)
value
;
}
if
(
value
instanceof
Long
)
{
return
BigInteger
.
valueOf
((
Long
)
value
);
}
final
String
valueStr
=
toStr
(
value
,
null
);
if
(
StrUtils
.
isEmpty
(
valueStr
))
{
return
defaultValue
;
}
try
{
return
new
BigInteger
(
valueStr
);
}
catch
(
Exception
e
)
{
return
defaultValue
;
}
}
/**
* 转换为BigInteger<br>
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public
static
BigInteger
toBigInteger
(
Object
value
)
{
return
toBigInteger
(
value
,
null
);
}
/**
* 转换为BigDecimal<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public
static
BigDecimal
toBigDecimal
(
Object
value
,
BigDecimal
defaultValue
)
{
if
(
value
==
null
)
{
return
defaultValue
;
}
if
(
value
instanceof
BigDecimal
)
{
return
(
BigDecimal
)
value
;
}
if
(
value
instanceof
Long
)
{
return
new
BigDecimal
((
Long
)
value
);
}
if
(
value
instanceof
Double
)
{
return
new
BigDecimal
((
Double
)
value
);
}
if
(
value
instanceof
Integer
)
{
return
new
BigDecimal
((
Integer
)
value
);
}
final
String
valueStr
=
toStr
(
value
,
null
);
if
(
StrUtils
.
isEmpty
(
valueStr
))
{
return
defaultValue
;
}
try
{
return
new
BigDecimal
(
valueStr
);
}
catch
(
Exception
e
)
{
return
defaultValue
;
}
}
/**
* 转换为BigDecimal<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public
static
BigDecimal
toBigDecimal
(
Object
value
)
{
return
toBigDecimal
(
value
,
null
);
}
// /**
// * 将对象转为字符串<br>
// * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
// *
// * @param obj 对象
// * @return 字符串
// */
// public static String utf8Str(Object obj)
// {
// return str(obj, CharsetKit.CHARSET_UTF_8);
// }
/**
* 将对象转为字符串<br>
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
*
* @param obj 对象
* @param charsetName 字符集
* @return 字符串
*/
public
static
String
str
(
Object
obj
,
String
charsetName
)
{
return
str
(
obj
,
Charset
.
forName
(
charsetName
));
}
/**
* 将对象转为字符串<br>
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
*
* @param obj 对象
* @param charset 字符集
* @return 字符串
*/
public
static
String
str
(
Object
obj
,
Charset
charset
)
{
if
(
null
==
obj
)
{
return
null
;
}
if
(
obj
instanceof
String
)
{
return
(
String
)
obj
;
}
else
if
(
obj
instanceof
byte
[]
||
obj
instanceof
Byte
[])
{
if
(
obj
instanceof
byte
[])
{
return
str
((
byte
[])
obj
,
charset
);
}
else
{
Byte
[]
bytes
=
(
Byte
[])
obj
;
int
length
=
bytes
.
length
;
byte
[]
dest
=
new
byte
[
length
];
for
(
int
i
=
0
;
i
<
length
;
i
++)
{
dest
[
i
]
=
bytes
[
i
];
}
return
str
(
dest
,
charset
);
}
}
else
if
(
obj
instanceof
ByteBuffer
)
{
return
str
((
ByteBuffer
)
obj
,
charset
);
}
return
obj
.
toString
();
}
/**
* 将byte数组转为字符串
*
* @param bytes byte数组
* @param charset 字符集
* @return 字符串
*/
public
static
String
str
(
byte
[]
bytes
,
String
charset
)
{
return
str
(
bytes
,
StrUtils
.
isEmpty
(
charset
)
?
Charset
.
defaultCharset
()
:
Charset
.
forName
(
charset
));
}
/**
* 解码字节码
*
* @param data 字符串
* @param charset 字符集,如果此字段为空,则解码的结果取决于平台
* @return 解码后的字符串
*/
public
static
String
str
(
byte
[]
data
,
Charset
charset
)
{
if
(
data
==
null
)
{
return
null
;
}
if
(
null
==
charset
)
{
return
new
String
(
data
);
}
return
new
String
(
data
,
charset
);
}
/**
* 将编码的byteBuffer数据转换为字符串
*
* @param data 数据
* @param charset 字符集,如果为空使用当前系统字符集
* @return 字符串
*/
public
static
String
str
(
ByteBuffer
data
,
String
charset
)
{
if
(
data
==
null
)
{
return
null
;
}
return
str
(
data
,
Charset
.
forName
(
charset
));
}
/**
* 将编码的byteBuffer数据转换为字符串
*
* @param data 数据
* @param charset 字符集,如果为空使用当前系统字符集
* @return 字符串
*/
public
static
String
str
(
ByteBuffer
data
,
Charset
charset
)
{
if
(
null
==
charset
)
{
charset
=
Charset
.
defaultCharset
();
}
return
charset
.
decode
(
data
).
toString
();
}
// ----------------------------------------------------------------------- 全角半角转换
/**
* 半角转全角
*
* @param input String.
* @return 全角字符串.
*/
public
static
String
toSBC
(
String
input
)
{
return
toSBC
(
input
,
null
);
}
/**
* 半角转全角
*
* @param input String
* @param notConvertSet 不替换的字符集合
* @return 全角字符串.
*/
public
static
String
toSBC
(
String
input
,
Set
<
Character
>
notConvertSet
)
{
char
c
[]
=
input
.
toCharArray
();
for
(
int
i
=
0
;
i
<
c
.
length
;
i
++)
{
if
(
null
!=
notConvertSet
&&
notConvertSet
.
contains
(
c
[
i
]))
{
// 跳过不替换的字符
continue
;
}
if
(
c
[
i
]
==
' '
)
{
c
[
i
]
=
'\u3000'
;
}
else
if
(
c
[
i
]
<
'\
177
'
)
{
c
[
i
]
=
(
char
)
(
c
[
i
]
+
65248
);
}
}
return
new
String
(
c
);
}
/**
* 全角转半角
*
* @param input String.
* @return 半角字符串
*/
public
static
String
toDBC
(
String
input
)
{
return
toDBC
(
input
,
null
);
}
/**
* 替换全角为半角
*
* @param text 文本
* @param notConvertSet 不替换的字符集合
* @return 替换后的字符
*/
public
static
String
toDBC
(
String
text
,
Set
<
Character
>
notConvertSet
)
{
char
c
[]
=
text
.
toCharArray
();
for
(
int
i
=
0
;
i
<
c
.
length
;
i
++)
{
if
(
null
!=
notConvertSet
&&
notConvertSet
.
contains
(
c
[
i
]))
{
// 跳过不替换的字符
continue
;
}
if
(
c
[
i
]
==
'\u3000'
)
{
c
[
i
]
=
' '
;
}
else
if
(
c
[
i
]
>
'\
uFF00
'
&&
c
[
i
]
<
'\
uFF5F
'
)
{
c
[
i
]
=
(
char
)
(
c
[
i
]
-
65248
);
}
}
String
returnString
=
new
String
(
c
);
return
returnString
;
}
/**
* 数字金额大写转换 先写个完整的然后将如零拾替换成零
*
* @param n 数字
* @return 中文大写数字
*/
public
static
String
digitUppercase
(
double
n
)
{
String
[]
fraction
=
{
"角"
,
"分"
};
String
[]
digit
=
{
"零"
,
"壹"
,
"贰"
,
"叁"
,
"肆"
,
"伍"
,
"陆"
,
"柒"
,
"捌"
,
"玖"
};
String
[][]
unit
=
{
{
"元"
,
"万"
,
"亿"
},
{
""
,
"拾"
,
"佰"
,
"仟"
}
};
String
head
=
n
<
0
?
"负"
:
""
;
n
=
Math
.
abs
(
n
);
String
s
=
""
;
for
(
int
i
=
0
;
i
<
fraction
.
length
;
i
++)
{
s
+=
(
digit
[(
int
)
(
Math
.
floor
(
n
*
10
*
Math
.
pow
(
10
,
i
))
%
10
)]
+
fraction
[
i
]).
replaceAll
(
"(零.)+"
,
""
);
}
if
(
s
.
length
()
<
1
)
{
s
=
"整"
;
}
int
integerPart
=
(
int
)
Math
.
floor
(
n
);
for
(
int
i
=
0
;
i
<
unit
[
0
].
length
&&
integerPart
>
0
;
i
++)
{
String
p
=
""
;
for
(
int
j
=
0
;
j
<
unit
[
1
].
length
&&
n
>
0
;
j
++)
{
p
=
digit
[
integerPart
%
10
]
+
unit
[
1
][
j
]
+
p
;
integerPart
=
integerPart
/
10
;
}
s
=
p
.
replaceAll
(
"(零.)*零$"
,
""
).
replaceAll
(
"^$"
,
"零"
)
+
unit
[
0
][
i
]
+
s
;
}
return
(
head
+
s
.
replaceAll
(
"(零.)*零元"
,
"元"
)
.
replaceFirst
(
"(零.)+"
,
""
)
.
replaceAll
(
"(零.)+"
,
"零"
)
.
replaceAll
(
"^整$"
,
"零元整"
)
);
}
}
basic-common/util/src/main/java/com/yiring/common/util/DictUtils.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
util
;
import
cn.hutool.extra.spring.SpringUtil
;
import
com.yiring.common.core.Redis
;
import
com.yiring.common.dict.Dict
;
import
java.util.Collection
;
import
java.util.List
;
/**
* 字典工具类
*
* @author tzl
*/
public
class
DictUtils
{
/**
* 分隔符
*/
public
static
final
String
SEPARATOR
=
","
;
/**
* 设置字典缓存
*
* @param key 参数键
* @param dictDatas 字典数据列表
*/
public
static
void
setDictCache
(
String
key
,
List
<
Dict
>
dictDatas
)
{
SpringUtil
.
getBean
(
Redis
.
class
).
set
(
getCacheKey
(
key
),
dictDatas
);
}
/**
* 获取字典缓存
*
* @param key 参数键
* @return dictDatas 字典数据列表
*/
public
static
List
<
Dict
>
getDictCache
(
String
key
)
{
Object
cacheObj
=
SpringUtil
.
getBean
(
Redis
.
class
).
get
(
getCacheKey
(
key
));
if
(
StrUtils
.
isNotNull
(
cacheObj
))
{
return
StrUtils
.
cast
(
cacheObj
);
}
return
null
;
}
/**
* 根据字典类型和字典值获取字典标签
*
* @param dictType 字典类型
* @param dictValue 字典值
* @return 字典标签
*/
public
static
String
getDictLabel
(
String
dictType
,
String
dictValue
)
{
return
getDictLabel
(
dictType
,
dictValue
,
SEPARATOR
);
}
/**
* 根据字典类型和字典标签获取字典值
*
* @param dictType 字典类型
* @param dictLabel 字典标签
* @return 字典值
*/
public
static
String
getDictValue
(
String
dictType
,
String
dictLabel
)
{
return
getDictValue
(
dictType
,
dictLabel
,
SEPARATOR
);
}
/**
* 根据字典类型和字典值获取字典标签
*
* @param dictType 字典类型
* @param dictValue 字典值
* @param separator 分隔符
* @return 字典标签
*/
public
static
String
getDictLabel
(
String
dictType
,
String
dictValue
,
String
separator
)
{
StringBuilder
propertyString
=
new
StringBuilder
();
List
<
Dict
>
datas
=
getDictCache
(
dictType
);
if
(
StrUtils
.
containsAny
(
separator
,
dictValue
)
&&
StrUtils
.
isNotEmpty
(
datas
))
{
if
(
datas
!=
null
)
{
for
(
Dict
dict
:
datas
)
{
for
(
String
value
:
dictValue
.
split
(
separator
))
{
if
(
value
.
equals
(
dict
.
getDictValue
()))
{
propertyString
.
append
(
dict
.
getDictLabel
()).
append
(
separator
);
break
;
}
}
}
}
}
else
{
if
(
datas
!=
null
)
{
for
(
Dict
dict
:
datas
)
{
if
(
dictValue
.
equals
(
dict
.
getDictValue
()))
{
return
dict
.
getDictLabel
();
}
}
}
}
return
StrUtils
.
stripEnd
(
propertyString
.
toString
(),
separator
);
}
/**
* 根据字典类型和字典标签获取字典值
*
* @param dictType 字典类型
* @param dictLabel 字典标签
* @param separator 分隔符
* @return 字典值
*/
public
static
String
getDictValue
(
String
dictType
,
String
dictLabel
,
String
separator
)
{
StringBuilder
propertyString
=
new
StringBuilder
();
List
<
Dict
>
datas
=
getDictCache
(
dictType
);
if
(
StrUtils
.
containsAny
(
separator
,
dictLabel
)
&&
StrUtils
.
isNotEmpty
(
datas
))
{
if
(
datas
!=
null
)
{
for
(
Dict
dict
:
datas
)
{
for
(
String
label
:
dictLabel
.
split
(
separator
))
{
if
(
label
.
equals
(
dict
.
getDictLabel
()))
{
propertyString
.
append
(
dict
.
getDictValue
()).
append
(
separator
);
break
;
}
}
}
}
}
else
{
if
(
datas
!=
null
)
{
for
(
Dict
dict
:
datas
)
{
if
(
dictLabel
.
equals
(
dict
.
getDictLabel
()))
{
return
dict
.
getDictValue
();
}
}
}
}
return
StrUtils
.
stripEnd
(
propertyString
.
toString
(),
separator
);
}
/**
* 删除指定字典缓存
*
* @param key 字典键
*/
public
static
void
removeDictCache
(
String
key
)
{
SpringUtil
.
getBean
(
Redis
.
class
).
del
(
getCacheKey
(
key
));
}
/**
* 清空字典缓存
*/
public
static
void
clearDictCache
()
{
Collection
<
String
>
keys
=
SpringUtil
.
getBean
(
Redis
.
class
).
keys
(
"sys_dict:*"
);
SpringUtil
.
getBean
(
Redis
.
class
).
del
(
keys
.
toArray
(
new
String
[
0
]));
}
/**
* 设置cache key
*
* @param configKey 参数键
* @return 缓存键key
*/
public
static
String
getCacheKey
(
String
configKey
)
{
return
"sys_dict:"
+
configKey
;
}
}
basic-common/util/src/main/java/com/yiring/common/util/StrUtils.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
util
;
import
java.util.Collection
;
import
java.util.List
;
import
java.util.Map
;
import
org.springframework.util.AntPathMatcher
;
/**
* 字符串工具类
*/
public
class
StrUtils
extends
org
.
apache
.
commons
.
lang3
.
StringUtils
{
/**
* 空字符串
*/
private
static
final
String
NULLSTR
=
""
;
/**
* 下划线
*/
private
static
final
char
SEPARATOR
=
'_'
;
/**
* 获取参数不为空值
*
* @param value defaultValue 要判断的value
* @return value 返回值
*/
public
static
<
T
>
T
nvl
(
T
value
,
T
defaultValue
)
{
return
value
!=
null
?
value
:
defaultValue
;
}
/**
* * 判断一个Collection是否为空, 包含List,Set,Queue
*
* @param coll 要判断的Collection
* @return true:为空 false:非空
*/
public
static
boolean
isEmpty
(
Collection
<?>
coll
)
{
return
isNull
(
coll
)
||
coll
.
isEmpty
();
}
/**
* * 判断一个Collection是否非空,包含List,Set,Queue
*
* @param coll 要判断的Collection
* @return true:非空 false:空
*/
public
static
boolean
isNotEmpty
(
Collection
<?>
coll
)
{
return
!
isEmpty
(
coll
);
}
/**
* * 判断一个对象数组是否为空
*
* @param objects 要判断的对象数组
* * @return true:为空 false:非空
*/
public
static
boolean
isEmpty
(
Object
[]
objects
)
{
return
isNull
(
objects
)
||
(
objects
.
length
==
0
);
}
/**
* * 判断一个对象数组是否非空
*
* @param objects 要判断的对象数组
* @return true:非空 false:空
*/
public
static
boolean
isNotEmpty
(
Object
[]
objects
)
{
return
!
isEmpty
(
objects
);
}
/**
* * 判断一个Map是否为空
*
* @param map 要判断的Map
* @return true:为空 false:非空
*/
public
static
boolean
isEmpty
(
Map
<?,
?>
map
)
{
return
isNull
(
map
)
||
map
.
isEmpty
();
}
/**
* * 判断一个Map是否为空
*
* @param map 要判断的Map
* @return true:非空 false:空
*/
public
static
boolean
isNotEmpty
(
Map
<?,
?>
map
)
{
return
!
isEmpty
(
map
);
}
/**
* * 判断一个字符串是否为空串
*
* @param str String
* @return true:为空 false:非空
*/
public
static
boolean
isEmpty
(
String
str
)
{
return
isNull
(
str
)
||
NULLSTR
.
equals
(
str
.
trim
());
}
/**
* * 判断一个字符串是否为非空串
*
* @param str String
* @return true:非空串 false:空串
*/
public
static
boolean
isNotEmpty
(
String
str
)
{
return
!
isEmpty
(
str
);
}
/**
* * 判断一个对象是否为空
*
* @param object Object
* @return true:为空 false:非空
*/
public
static
boolean
isNull
(
Object
object
)
{
return
object
==
null
;
}
/**
* * 判断一个对象是否非空
*
* @param object Object
* @return true:非空 false:空
*/
public
static
boolean
isNotNull
(
Object
object
)
{
return
!
isNull
(
object
);
}
/**
* * 判断一个对象是否是数组类型(Java基本型别的数组)
*
* @param object 对象
* @return true:是数组 false:不是数组
*/
public
static
boolean
isArray
(
Object
object
)
{
return
isNotNull
(
object
)
&&
object
.
getClass
().
isArray
();
}
/**
* 去空格
*/
public
static
String
trim
(
String
str
)
{
return
(
str
==
null
?
""
:
str
.
trim
());
}
/**
* 截取字符串
*
* @param str 字符串
* @param start 开始
* @return 结果
*/
public
static
String
substring
(
final
String
str
,
int
start
)
{
if
(
str
==
null
)
{
return
NULLSTR
;
}
if
(
start
<
0
)
{
start
=
str
.
length
()
+
start
;
}
if
(
start
<
0
)
{
start
=
0
;
}
if
(
start
>
str
.
length
())
{
return
NULLSTR
;
}
return
str
.
substring
(
start
);
}
/**
* 截取字符串
*
* @param str 字符串
* @param start 开始
* @param end 结束
* @return 结果
*/
public
static
String
substring
(
final
String
str
,
int
start
,
int
end
)
{
if
(
str
==
null
)
{
return
NULLSTR
;
}
if
(
end
<
0
)
{
end
=
str
.
length
()
+
end
;
}
if
(
start
<
0
)
{
start
=
str
.
length
()
+
start
;
}
if
(
end
>
str
.
length
())
{
end
=
str
.
length
();
}
if
(
start
>
end
)
{
return
NULLSTR
;
}
if
(
start
<
0
)
{
start
=
0
;
}
if
(
end
<
0
)
{
end
=
0
;
}
return
str
.
substring
(
start
,
end
);
}
/**
* 判断是否为空,并且不是空白字符
*
* @param str 要判断的value
* @return 结果
*/
public
static
boolean
hasText
(
String
str
)
{
return
(
str
!=
null
&&
!
str
.
isEmpty
()
&&
containsText
(
str
));
}
private
static
boolean
containsText
(
CharSequence
str
)
{
int
strLen
=
str
.
length
();
for
(
int
i
=
0
;
i
<
strLen
;
i
++)
{
if
(!
Character
.
isWhitespace
(
str
.
charAt
(
i
)))
{
return
true
;
}
}
return
false
;
}
/**
* 驼峰转下划线命名
*/
public
static
String
toUnderScoreCase
(
String
str
)
{
if
(
str
==
null
)
{
return
null
;
}
StringBuilder
sb
=
new
StringBuilder
();
// 前置字符是否大写
boolean
preCharIsUpperCase
=
true
;
// 当前字符是否大写
boolean
curreCharIsUpperCase
=
true
;
// 下一字符是否大写
boolean
nexteCharIsUpperCase
=
true
;
for
(
int
i
=
0
;
i
<
str
.
length
();
i
++)
{
char
c
=
str
.
charAt
(
i
);
if
(
i
>
0
)
{
preCharIsUpperCase
=
Character
.
isUpperCase
(
str
.
charAt
(
i
-
1
));
}
else
{
preCharIsUpperCase
=
false
;
}
curreCharIsUpperCase
=
Character
.
isUpperCase
(
c
);
if
(
i
<
(
str
.
length
()
-
1
))
{
nexteCharIsUpperCase
=
Character
.
isUpperCase
(
str
.
charAt
(
i
+
1
));
}
if
(
preCharIsUpperCase
&&
curreCharIsUpperCase
&&
!
nexteCharIsUpperCase
)
{
sb
.
append
(
SEPARATOR
);
}
else
if
((
i
!=
0
&&
!
preCharIsUpperCase
)
&&
curreCharIsUpperCase
)
{
sb
.
append
(
SEPARATOR
);
}
sb
.
append
(
Character
.
toLowerCase
(
c
));
}
return
sb
.
toString
();
}
/**
* 是否包含字符串
*
* @param str 验证字符串
* @param strs 字符串组
* @return 包含返回true
*/
public
static
boolean
inStringIgnoreCase
(
String
str
,
String
...
strs
)
{
if
(
str
!=
null
&&
strs
!=
null
)
{
for
(
String
s
:
strs
)
{
if
(
str
.
equalsIgnoreCase
(
trim
(
s
)))
{
return
true
;
}
}
}
return
false
;
}
/**
* 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld
*
* @param name 转换前的下划线大写方式命名的字符串
* @return 转换后的驼峰式命名的字符串
*/
public
static
String
convertToCamelCase
(
String
name
)
{
StringBuilder
result
=
new
StringBuilder
();
// 快速检查
if
(
name
==
null
||
name
.
isEmpty
())
{
// 没必要转换
return
""
;
}
else
if
(!
name
.
contains
(
"_"
))
{
// 不含下划线,仅将首字母大写
return
name
.
substring
(
0
,
1
).
toUpperCase
()
+
name
.
substring
(
1
);
}
// 用下划线将原始字符串分割
String
[]
camels
=
name
.
split
(
"_"
);
for
(
String
camel
:
camels
)
{
// 跳过原始字符串中开头、结尾的下换线或双重下划线
if
(
camel
.
isEmpty
())
{
continue
;
}
// 首字母大写
result
.
append
(
camel
.
substring
(
0
,
1
).
toUpperCase
());
result
.
append
(
camel
.
substring
(
1
).
toLowerCase
());
}
return
result
.
toString
();
}
/**
* 驼峰式命名法 例如:user_name->userName
*/
public
static
String
toCamelCase
(
String
s
)
{
if
(
s
==
null
)
{
return
null
;
}
s
=
s
.
toLowerCase
();
StringBuilder
sb
=
new
StringBuilder
(
s
.
length
());
boolean
upperCase
=
false
;
for
(
int
i
=
0
;
i
<
s
.
length
();
i
++)
{
char
c
=
s
.
charAt
(
i
);
if
(
c
==
SEPARATOR
)
{
upperCase
=
true
;
}
else
if
(
upperCase
)
{
sb
.
append
(
Character
.
toUpperCase
(
c
));
upperCase
=
false
;
}
else
{
sb
.
append
(
c
);
}
}
return
sb
.
toString
();
}
/**
* 查找指定字符串是否匹配指定字符串列表中的任意一个字符串
*
* @param str 指定字符串
* @param strs 需要检查的字符串数组
* @return 是否匹配
*/
public
static
boolean
matches
(
String
str
,
List
<
String
>
strs
)
{
if
(
isEmpty
(
str
)
||
isEmpty
(
strs
))
{
return
false
;
}
for
(
String
pattern
:
strs
)
{
if
(
isMatch
(
pattern
,
str
))
{
return
true
;
}
}
return
false
;
}
/**
* 判断url是否与规则配置:
* ? 表示单个字符;
* * 表示一层路径内的任意字符串,不可跨层级;
* ** 表示任意层路径;
*
* @param pattern 匹配规则
* @param url 需要匹配的url
* @return
*/
public
static
boolean
isMatch
(
String
pattern
,
String
url
)
{
AntPathMatcher
matcher
=
new
AntPathMatcher
();
return
matcher
.
match
(
pattern
,
url
);
}
@SuppressWarnings
(
"unchecked"
)
public
static
<
T
>
T
cast
(
Object
obj
)
{
return
(
T
)
obj
;
}
/**
* 数字左边补齐0,使之达到指定长度。注意,如果数字转换为字符串后,长度大于size,则只保留 最后size个字符。
*
* @param num 数字对象
* @param size 字符串指定长度
* @return 返回数字的字符串格式,该字符串为指定长度。
*/
public
static
final
String
padl
(
final
Number
num
,
final
int
size
)
{
return
padl
(
num
.
toString
(),
size
,
'0'
);
}
/**
* 字符串左补齐。如果原始字符串s长度大于size,则只保留最后size个字符。
*
* @param s 原始字符串
* @param size 字符串指定长度
* @param c 用于补齐的字符
* @return 返回指定长度的字符串,由原字符串左补齐或截取得到。
*/
public
static
final
String
padl
(
final
String
s
,
final
int
size
,
final
char
c
)
{
final
StringBuilder
sb
=
new
StringBuilder
(
size
);
if
(
s
!=
null
)
{
final
int
len
=
s
.
length
();
if
(
s
.
length
()
<=
size
)
{
for
(
int
i
=
size
-
len
;
i
>
0
;
i
--)
{
sb
.
append
(
c
);
}
sb
.
append
(
s
);
}
else
{
return
s
.
substring
(
len
-
size
,
len
);
}
}
else
{
for
(
int
i
=
size
;
i
>
0
;
i
--)
{
sb
.
append
(
c
);
}
}
return
sb
.
toString
();
}
}
basic-common/util/src/main/java/com/yiring/common/util/date/DateUtils.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
util
.
date
;
import
java.lang.management.ManagementFactory
;
import
java.text.ParseException
;
import
java.text.SimpleDateFormat
;
import
java.time.LocalDate
;
import
java.time.LocalDateTime
;
import
java.time.LocalTime
;
import
java.time.ZoneId
;
import
java.time.ZonedDateTime
;
import
java.util.Date
;
import
org.apache.commons.lang3.time.DateFormatUtils
;
/**
* 时间工具类
*/
public
class
DateUtils
extends
org
.
apache
.
commons
.
lang3
.
time
.
DateUtils
{
public
static
String
YYYY
=
"yyyy"
;
public
static
String
YYYY_MM
=
"yyyy-MM"
;
public
static
String
YYYY_MM_DD
=
"yyyy-MM-dd"
;
public
static
String
YYYYMMDDHHMMSS
=
"yyyyMMddHHmmss"
;
public
static
String
YYYY_MM_DD_HH_MM_SS
=
"yyyy-MM-dd HH:mm:ss"
;
private
static
final
String
[]
parsePatterns
=
{
"yyyy-MM-dd"
,
"yyyy-MM-dd HH:mm:ss"
,
"yyyy-MM-dd HH:mm"
,
"yyyy-MM"
,
"yyyy/MM/dd"
,
"yyyy/MM/dd HH:mm:ss"
,
"yyyy/MM/dd HH:mm"
,
"yyyy/MM"
,
"yyyy.MM.dd"
,
"yyyy.MM.dd HH:mm:ss"
,
"yyyy.MM.dd HH:mm"
,
"yyyy.MM"
,
};
/**
* 获取当前Date型日期
*
* @return Date() 当前日期
*/
public
static
Date
getNowDate
()
{
return
new
Date
();
}
/**
* 获取当前日期, 默认格式为yyyy-MM-dd
*
* @return String
*/
public
static
String
getDate
()
{
return
dateTimeNow
(
YYYY_MM_DD
);
}
public
static
String
getTime
()
{
return
dateTimeNow
(
YYYY_MM_DD_HH_MM_SS
);
}
public
static
String
dateTimeNow
()
{
return
dateTimeNow
(
YYYYMMDDHHMMSS
);
}
public
static
String
dateTimeNow
(
final
String
format
)
{
return
parseDateToStr
(
format
,
new
Date
());
}
public
static
String
dateTime
(
final
Date
date
)
{
return
parseDateToStr
(
YYYY_MM_DD
,
date
);
}
public
static
String
parseDateToStr
(
final
String
format
,
final
Date
date
)
{
return
new
SimpleDateFormat
(
format
).
format
(
date
);
}
public
static
Date
dateTime
(
final
String
format
,
final
String
ts
)
{
try
{
return
new
SimpleDateFormat
(
format
).
parse
(
ts
);
}
catch
(
ParseException
e
)
{
throw
new
RuntimeException
(
e
);
}
}
/**
* 日期路径 即年/月/日 如2018/08/08
*/
public
static
String
datePath
()
{
Date
now
=
new
Date
();
return
DateFormatUtils
.
format
(
now
,
"yyyy/MM/dd"
);
}
/**
* 日期路径 即年/月/日 如20180808
*/
public
static
String
dateTime
()
{
Date
now
=
new
Date
();
return
DateFormatUtils
.
format
(
now
,
"yyyyMMdd"
);
}
/**
* 日期型字符串转化为日期 格式
*/
public
static
Date
parseDate
(
Object
str
)
{
if
(
str
==
null
)
{
return
null
;
}
try
{
return
parseDate
(
str
.
toString
(),
parsePatterns
);
}
catch
(
ParseException
e
)
{
return
null
;
}
}
/**
* 获取服务器启动时间
*/
public
static
Date
getServerStartDate
()
{
long
time
=
ManagementFactory
.
getRuntimeMXBean
().
getStartTime
();
return
new
Date
(
time
);
}
/**
* 计算两个时间差
*/
public
static
String
getDatePoor
(
Date
endDate
,
Date
nowDate
)
{
long
nd
=
1000
*
24
*
60
*
60
;
long
nh
=
1000
*
60
*
60
;
long
nm
=
1000
*
60
;
// long ns = 1000;
// 获得两个时间的毫秒时间差异
long
diff
=
endDate
.
getTime
()
-
nowDate
.
getTime
();
// 计算差多少天
long
day
=
diff
/
nd
;
// 计算差多少小时
long
hour
=
diff
%
nd
/
nh
;
// 计算差多少分钟
long
min
=
diff
%
nd
%
nh
/
nm
;
// 计算差多少秒//输出结果
// long sec = diff % nd % nh % nm / ns;
return
day
+
"天"
+
hour
+
"小时"
+
min
+
"分钟"
;
}
/**
* 增加 LocalDateTime ==> Date
*/
public
static
Date
toDate
(
LocalDateTime
temporalAccessor
)
{
ZonedDateTime
zdt
=
temporalAccessor
.
atZone
(
ZoneId
.
systemDefault
());
return
Date
.
from
(
zdt
.
toInstant
());
}
/**
* 增加 LocalDate ==> Date
*/
public
static
Date
toDate
(
LocalDate
temporalAccessor
)
{
LocalDateTime
localDateTime
=
LocalDateTime
.
of
(
temporalAccessor
,
LocalTime
.
of
(
0
,
0
,
0
));
ZonedDateTime
zdt
=
localDateTime
.
atZone
(
ZoneId
.
systemDefault
());
return
Date
.
from
(
zdt
.
toInstant
());
}
}
basic-common/util/src/main/java/com/yiring/common/util/file/FileTypeUtils.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
util
.
file
;
import
java.io.File
;
import
org.apache.commons.lang3.StringUtils
;
/**
* 文件类型工具类
*/
public
class
FileTypeUtils
{
/**
* 获取文件类型
* <p>
* 例如: ruoyi.txt, 返回: txt
*
* @param file 文件名
* @return 后缀(不含".")
*/
public
static
String
getFileType
(
File
file
)
{
if
(
null
==
file
)
{
return
StringUtils
.
EMPTY
;
}
return
getFileType
(
file
.
getName
());
}
/**
* 获取文件类型
* <p>
* 例如: ruoyi.txt, 返回: txt
*
* @param fileName 文件名
* @return 后缀(不含".")
*/
public
static
String
getFileType
(
String
fileName
)
{
int
separatorIndex
=
fileName
.
lastIndexOf
(
"."
);
if
(
separatorIndex
<
0
)
{
return
""
;
}
return
fileName
.
substring
(
separatorIndex
+
1
).
toLowerCase
();
}
/**
* 获取文件类型
*
* @param photoByte 文件字节码
* @return 后缀(不含".")
*/
public
static
String
getFileExtendName
(
byte
[]
photoByte
)
{
String
strFileExtendName
=
"JPG"
;
if
(
(
photoByte
[
0
]
==
71
)
&&
(
photoByte
[
1
]
==
73
)
&&
(
photoByte
[
2
]
==
70
)
&&
(
photoByte
[
3
]
==
56
)
&&
((
photoByte
[
4
]
==
55
)
||
(
photoByte
[
4
]
==
57
))
&&
(
photoByte
[
5
]
==
97
)
)
{
strFileExtendName
=
"GIF"
;
}
else
if
((
photoByte
[
6
]
==
74
)
&&
(
photoByte
[
7
]
==
70
)
&&
(
photoByte
[
8
]
==
73
)
&&
(
photoByte
[
9
]
==
70
))
{
strFileExtendName
=
"JPG"
;
}
else
if
((
photoByte
[
0
]
==
66
)
&&
(
photoByte
[
1
]
==
77
))
{
strFileExtendName
=
"BMP"
;
}
else
if
((
photoByte
[
1
]
==
80
)
&&
(
photoByte
[
2
]
==
78
)
&&
(
photoByte
[
3
]
==
71
))
{
strFileExtendName
=
"PNG"
;
}
return
strFileExtendName
;
}
}
basic-common/util/src/main/java/com/yiring/common/util/file/ImageUtils.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
util
.
file
;
import
java.io.ByteArrayInputStream
;
import
java.io.InputStream
;
import
java.net.URL
;
import
java.net.URLConnection
;
import
java.util.Arrays
;
import
org.apache.poi.util.IOUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
/**
* 图片处理工具类
*/
public
class
ImageUtils
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
ImageUtils
.
class
);
public
static
byte
[]
getImage
(
String
imagePath
)
{
InputStream
is
=
getFile
(
imagePath
);
try
{
return
IOUtils
.
toByteArray
(
is
);
}
catch
(
Exception
e
)
{
log
.
error
(
"图片加载异常 {}"
,
e
);
return
null
;
}
finally
{
IOUtils
.
closeQuietly
(
is
);
}
}
public
static
InputStream
getFile
(
String
imagePath
)
{
try
{
byte
[]
result
=
readFile
(
imagePath
);
result
=
Arrays
.
copyOf
(
result
,
result
.
length
);
return
new
ByteArrayInputStream
(
result
);
}
catch
(
Exception
e
)
{
log
.
error
(
"获取图片异常 {}"
,
e
);
}
return
null
;
}
/**
* 读取文件为字节数据
*
* @param url 地址
* @return 字节数据
*/
public
static
byte
[]
readFile
(
String
url
)
{
InputStream
in
=
null
;
try
{
// 网络地址
URL
urlObj
=
new
URL
(
url
);
URLConnection
urlConnection
=
urlObj
.
openConnection
();
urlConnection
.
setConnectTimeout
(
30
*
1000
);
urlConnection
.
setReadTimeout
(
60
*
1000
);
urlConnection
.
setDoInput
(
true
);
in
=
urlConnection
.
getInputStream
();
return
IOUtils
.
toByteArray
(
in
);
}
catch
(
Exception
e
)
{
log
.
error
(
"访问文件异常 {}"
,
e
);
return
null
;
}
finally
{
IOUtils
.
closeQuietly
(
in
);
}
}
}
basic-common/util/src/main/java/com/yiring/common/util/poi/ExcelHandlerAdapter.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
util
.
poi
;
/**
* Excel数据格式处理适配器
*/
public
interface
ExcelHandlerAdapter
{
/**
* 格式化
*
* @param value 单元格数据值
* @param args excel注解args参数组
* @return 处理后的值
*/
Object
format
(
Object
value
,
String
[]
args
);
}
basic-common/util/src/main/java/com/yiring/common/util/poi/ExcelUtils.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
util
.
poi
;
import
com.yiring.common.annotation.Excel
;
import
com.yiring.common.annotation.Excel.ColumnType
;
import
com.yiring.common.annotation.Excel.Type
;
import
com.yiring.common.annotation.Excels
;
import
com.yiring.common.text.Convert
;
import
com.yiring.common.util.DictUtils
;
import
com.yiring.common.util.StrUtils
;
import
com.yiring.common.util.date.DateUtils
;
import
com.yiring.common.util.file.FileTypeUtils
;
import
com.yiring.common.util.file.ImageUtils
;
import
com.yiring.common.util.reflect.ReflectUtils
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
import
java.math.BigDecimal
;
import
java.text.DecimalFormat
;
import
java.time.LocalDate
;
import
java.time.LocalDateTime
;
import
java.util.*
;
import
java.util.stream.Collectors
;
import
javax.servlet.http.HttpServletResponse
;
import
org.apache.commons.lang3.RegExUtils
;
import
org.apache.poi.ss.usermodel.*
;
import
org.apache.poi.ss.util.CellRangeAddress
;
import
org.apache.poi.ss.util.CellRangeAddressList
;
import
org.apache.poi.util.IOUtils
;
import
org.apache.poi.xssf.streaming.SXSSFWorkbook
;
import
org.apache.poi.xssf.usermodel.XSSFClientAnchor
;
import
org.apache.poi.xssf.usermodel.XSSFDataValidation
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
/**
* Excel相关处理
*
* @author ruoyi
*/
public
class
ExcelUtils
<
T
>
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
ExcelUtils
.
class
);
public
static
final
String
FORMULA_REGEX_STR
=
"=|-|\\+|@"
;
public
static
final
String
[]
FORMULA_STR
=
{
"="
,
"-"
,
"+"
,
"@"
};
/**
* Excel sheet最大行数,默认65536
*/
public
static
final
int
sheetSize
=
65536
;
/**
* 工作表名称
*/
private
String
sheetName
;
/**
* 导出类型(EXPORT:导出数据;IMPORT:导入模板)
*/
private
Type
type
;
/**
* 工作薄对象
*/
private
Workbook
wb
;
/**
* 工作表对象
*/
private
Sheet
sheet
;
/**
* 样式列表
*/
private
Map
<
String
,
CellStyle
>
styles
;
/**
* 导入导出数据列表
*/
private
List
<
T
>
list
;
/**
* 注解列表
*/
private
List
<
Object
[]>
fields
;
/**
* 当前行号
*/
private
int
rownum
;
/**
* 标题
*/
private
String
title
;
/**
* 最大高度
*/
private
short
maxHeight
;
/**
* 统计列表
*/
private
Map
<
Integer
,
Double
>
statistics
=
new
HashMap
<
Integer
,
Double
>();
/**
* 数字格式
*/
private
static
final
DecimalFormat
DOUBLE_FORMAT
=
new
DecimalFormat
(
"######0.00"
);
/**
* 实体对象
*/
public
Class
<
T
>
clazz
;
public
ExcelUtils
(
Class
<
T
>
clazz
)
{
this
.
clazz
=
clazz
;
}
public
void
init
(
List
<
T
>
list
,
String
sheetName
,
String
title
,
Type
type
)
{
if
(
list
==
null
)
{
list
=
new
ArrayList
<
T
>();
}
this
.
list
=
list
;
this
.
sheetName
=
sheetName
;
this
.
type
=
type
;
this
.
title
=
title
;
createExcelField
();
createWorkbook
();
createTitle
();
}
/**
* 创建excel第一行标题
*/
public
void
createTitle
()
{
if
(
StrUtils
.
isNotEmpty
(
title
))
{
Row
titleRow
=
sheet
.
createRow
(
rownum
==
0
?
rownum
++
:
0
);
titleRow
.
setHeightInPoints
(
30
);
Cell
titleCell
=
titleRow
.
createCell
(
0
);
titleCell
.
setCellStyle
(
styles
.
get
(
"title"
));
titleCell
.
setCellValue
(
title
);
sheet
.
addMergedRegion
(
new
CellRangeAddress
(
titleRow
.
getRowNum
(),
titleRow
.
getRowNum
(),
titleRow
.
getRowNum
(),
this
.
fields
.
size
()
-
1
)
);
}
}
/**
* 对excel表单默认第一个索引名转换成list
*
* @param is 输入流
* @return 转换后集合
*/
public
List
<
T
>
importExcel
(
InputStream
is
)
throws
Exception
{
return
importExcel
(
is
,
0
);
}
/**
* 对excel表单默认第一个索引名转换成list
*
* @param is 输入流
* @param titleNum 标题占用行数
* @return 转换后集合
*/
public
List
<
T
>
importExcel
(
InputStream
is
,
int
titleNum
)
throws
Exception
{
return
importExcel
(
StrUtils
.
EMPTY
,
is
,
titleNum
);
}
/**
* 对excel表单指定表格索引名转换成list
*
* @param sheetName 表格索引名
* @param titleNum 标题占用第几行数
* @param is 输入流
* @return 转换后集合
*/
public
List
<
T
>
importExcel
(
String
sheetName
,
InputStream
is
,
int
titleNum
)
throws
Exception
{
this
.
type
=
Type
.
IMPORT
;
this
.
wb
=
WorkbookFactory
.
create
(
is
);
List
<
T
>
list
=
new
ArrayList
<
T
>();
// 如果指定sheet名,则取指定sheet中的内容 否则默认指向第1个sheet
Sheet
sheet
=
StrUtils
.
isNotEmpty
(
sheetName
)
?
wb
.
getSheet
(
sheetName
)
:
wb
.
getSheetAt
(
0
);
if
(
sheet
==
null
)
{
throw
new
IOException
(
"文件sheet不存在"
);
}
// 获取最后一个非空行的行下标,比如总行数为n,则返回的为n-1
int
rows
=
sheet
.
getLastRowNum
();
if
(
rows
>
0
)
{
// 定义一个map用于存放excel列的序号和field.
Map
<
String
,
Integer
>
cellMap
=
new
HashMap
<
String
,
Integer
>();
// 获取表头
Row
heard
=
sheet
.
getRow
(
titleNum
);
for
(
int
i
=
0
;
i
<
heard
.
getPhysicalNumberOfCells
();
i
++)
{
Cell
cell
=
heard
.
getCell
(
i
);
if
(
StrUtils
.
isNotNull
(
cell
))
{
String
value
=
this
.
getCellValue
(
heard
,
i
).
toString
();
cellMap
.
put
(
value
,
i
);
}
else
{
cellMap
.
put
(
null
,
i
);
}
}
// 有数据时才处理 得到类的所有field.
List
<
Object
[]>
fields
=
this
.
getFields
();
Map
<
Integer
,
Object
[]>
fieldsMap
=
new
HashMap
<
Integer
,
Object
[]>();
for
(
Object
[]
objects
:
fields
)
{
Excel
attr
=
(
Excel
)
objects
[
1
];
Integer
column
=
cellMap
.
get
(
attr
.
name
());
if
(
column
!=
null
)
{
fieldsMap
.
put
(
column
,
objects
);
}
}
for
(
int
i
=
titleNum
+
1
;
i
<=
rows
;
i
++)
{
// 从第2行开始取数据,默认第一行是表头.
Row
row
=
sheet
.
getRow
(
i
);
// 判断当前行是否是空行
if
(
isRowEmpty
(
row
))
{
continue
;
}
T
entity
=
null
;
for
(
Map
.
Entry
<
Integer
,
Object
[]>
entry
:
fieldsMap
.
entrySet
())
{
Object
val
=
this
.
getCellValue
(
row
,
entry
.
getKey
());
// 如果不存在实例则新建.
entity
=
(
entity
==
null
?
clazz
.
newInstance
()
:
entity
);
// 从map中得到对应列的field.
Field
field
=
(
Field
)
entry
.
getValue
()[
0
];
Excel
attr
=
(
Excel
)
entry
.
getValue
()[
1
];
// 取得类型,并根据对象类型设置值.
Class
<?>
fieldType
=
field
.
getType
();
if
(
String
.
class
==
fieldType
)
{
String
s
=
Convert
.
toStr
(
val
);
if
(
StrUtils
.
endsWith
(
s
,
".0"
))
{
val
=
StrUtils
.
substringBefore
(
s
,
".0"
);
}
else
{
String
dateFormat
=
field
.
getAnnotation
(
Excel
.
class
).
dateFormat
();
if
(
StrUtils
.
isNotEmpty
(
dateFormat
))
{
val
=
parseDateToStr
(
dateFormat
,
val
);
}
else
{
val
=
Convert
.
toStr
(
val
);
}
}
}
else
if
(
(
Integer
.
TYPE
==
fieldType
||
Integer
.
class
==
fieldType
)
&&
StrUtils
.
isNumeric
(
Convert
.
toStr
(
val
))
)
{
val
=
Convert
.
toInt
(
val
);
}
else
if
(
(
Long
.
TYPE
==
fieldType
||
Long
.
class
==
fieldType
)
&&
StrUtils
.
isNumeric
(
Convert
.
toStr
(
val
))
)
{
val
=
Convert
.
toLong
(
val
);
}
else
if
(
Double
.
TYPE
==
fieldType
||
Double
.
class
==
fieldType
)
{
val
=
Convert
.
toDouble
(
val
);
}
else
if
(
Float
.
TYPE
==
fieldType
||
Float
.
class
==
fieldType
)
{
val
=
Convert
.
toFloat
(
val
);
}
else
if
(
BigDecimal
.
class
==
fieldType
)
{
val
=
Convert
.
toBigDecimal
(
val
);
}
else
if
(
Date
.
class
==
fieldType
)
{
if
(
val
instanceof
String
)
{
val
=
DateUtils
.
parseDate
(
val
);
}
else
if
(
val
instanceof
Double
)
{
val
=
DateUtil
.
getJavaDate
((
Double
)
val
);
}
}
else
if
(
Boolean
.
TYPE
==
fieldType
||
Boolean
.
class
==
fieldType
)
{
val
=
Convert
.
toBool
(
val
,
false
);
}
if
(
StrUtils
.
isNotNull
(
fieldType
))
{
String
propertyName
=
field
.
getName
();
if
(
StrUtils
.
isNotEmpty
(
attr
.
targetAttr
()))
{
propertyName
=
field
.
getName
()
+
"."
+
attr
.
targetAttr
();
}
else
if
(
StrUtils
.
isNotEmpty
(
attr
.
readConverterExp
()))
{
val
=
reverseByExp
(
Convert
.
toStr
(
val
),
attr
.
readConverterExp
(),
attr
.
separator
());
}
else
if
(!
attr
.
handler
().
equals
(
ExcelHandlerAdapter
.
class
))
{
val
=
dataFormatHandlerAdapter
(
val
,
attr
);
}
ReflectUtils
.
invokeSetter
(
entity
,
propertyName
,
val
);
}
}
list
.
add
(
entity
);
}
}
return
list
;
}
/**
* 对list数据源将其里面的数据导入到excel表单
*
* @param response 返回数据
* @param list 导出数据集合
* @param sheetName 工作表的名称
* @return 结果
* @throws IOException
*/
public
void
exportExcel
(
HttpServletResponse
response
,
List
<
T
>
list
,
String
sheetName
)
{
exportExcel
(
response
,
list
,
sheetName
,
StrUtils
.
EMPTY
);
}
/**
* 对list数据源将其里面的数据导入到excel表单
*
* @param response 返回数据
* @param list 导出数据集合
* @param sheetName 工作表的名称
* @param title 标题
* @return 结果
* @throws IOException
*/
public
void
exportExcel
(
HttpServletResponse
response
,
List
<
T
>
list
,
String
sheetName
,
String
title
)
{
// response.setContentType("application/octet-stream");
// response.setCharacterEncoding("utf-8");
this
.
init
(
list
,
sheetName
,
title
,
Type
.
EXPORT
);
exportExcel
(
response
);
}
/**
* 对list数据源将其里面的数据导入到excel表单
*
* @param sheetName 工作表的名称
* @return 结果
*/
/**
* 对list数据源将其里面的数据导入到excel表单
*
* @param sheetName 工作表的名称
* @return 结果
*/
public
void
importTemplateExcel
(
HttpServletResponse
response
,
String
sheetName
)
{
importTemplateExcel
(
response
,
sheetName
,
StrUtils
.
EMPTY
);
}
/**
* 对list数据源将其里面的数据导入到excel表单
*
* @param sheetName 工作表的名称
* @param title 标题
* @return 结果
*/
public
void
importTemplateExcel
(
HttpServletResponse
response
,
String
sheetName
,
String
title
)
{
response
.
setContentType
(
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
);
response
.
setCharacterEncoding
(
"utf-8"
);
this
.
init
(
null
,
sheetName
,
title
,
Type
.
IMPORT
);
exportExcel
(
response
);
}
/**
* 对list数据源将其里面的数据导入到excel表单
*
* @return 结果
*/
public
void
exportExcel
(
HttpServletResponse
response
)
{
try
{
writeSheet
();
wb
.
write
(
response
.
getOutputStream
());
// FileOutputStream fos = new FileOutputStream("D:/a.xls");
// wb.write(fos);
// fos.close();
}
catch
(
Exception
e
)
{
log
.
error
(
"导出Excel异常{}"
,
e
.
getMessage
());
}
finally
{
IOUtils
.
closeQuietly
(
wb
);
}
}
/**
* 创建写入数据到Sheet
*/
public
void
writeSheet
()
{
// 取出一共有多少个sheet.
int
sheetNo
=
Math
.
max
(
1
,
(
int
)
Math
.
ceil
(
list
.
size
()
*
1.0
/
sheetSize
));
for
(
int
index
=
0
;
index
<
sheetNo
;
index
++)
{
createSheet
(
sheetNo
,
index
);
// 产生一行
Row
row
=
sheet
.
createRow
(
rownum
);
int
column
=
0
;
// 写入各个字段的列头名称
for
(
Object
[]
os
:
fields
)
{
Excel
excel
=
(
Excel
)
os
[
1
];
this
.
createCell
(
excel
,
row
,
column
++);
}
if
(
Type
.
EXPORT
.
equals
(
type
))
{
fillExcelData
(
index
,
row
);
addStatisticsRow
();
}
}
}
/**
* 填充excel数据
*
* @param index 序号
* @param row 单元格行
*/
public
void
fillExcelData
(
int
index
,
Row
row
)
{
int
startNo
=
index
*
sheetSize
;
int
endNo
=
Math
.
min
(
startNo
+
sheetSize
,
list
.
size
());
for
(
int
i
=
startNo
;
i
<
endNo
;
i
++)
{
row
=
sheet
.
createRow
(
i
+
1
+
rownum
-
startNo
);
// 得到导出对象.
T
vo
=
(
T
)
list
.
get
(
i
);
int
column
=
0
;
for
(
Object
[]
os
:
fields
)
{
Field
field
=
(
Field
)
os
[
0
];
Excel
excel
=
(
Excel
)
os
[
1
];
this
.
addCell
(
excel
,
row
,
vo
,
field
,
column
++);
}
}
}
/**
* 创建表格样式
*
* @param wb 工作薄对象
* @return 样式列表
*/
private
Map
<
String
,
CellStyle
>
createStyles
(
Workbook
wb
)
{
// 写入各条记录,每条记录对应excel表中的一行
Map
<
String
,
CellStyle
>
styles
=
new
HashMap
<
String
,
CellStyle
>();
CellStyle
style
=
wb
.
createCellStyle
();
style
.
setAlignment
(
HorizontalAlignment
.
CENTER
);
style
.
setVerticalAlignment
(
VerticalAlignment
.
CENTER
);
Font
titleFont
=
wb
.
createFont
();
titleFont
.
setFontName
(
"Arial"
);
titleFont
.
setFontHeightInPoints
((
short
)
16
);
titleFont
.
setBold
(
true
);
style
.
setFont
(
titleFont
);
styles
.
put
(
"title"
,
style
);
style
=
wb
.
createCellStyle
();
style
.
setAlignment
(
HorizontalAlignment
.
CENTER
);
style
.
setVerticalAlignment
(
VerticalAlignment
.
CENTER
);
style
.
setBorderRight
(
BorderStyle
.
THIN
);
style
.
setRightBorderColor
(
IndexedColors
.
GREY_50_PERCENT
.
getIndex
());
style
.
setBorderLeft
(
BorderStyle
.
THIN
);
style
.
setLeftBorderColor
(
IndexedColors
.
GREY_50_PERCENT
.
getIndex
());
style
.
setBorderTop
(
BorderStyle
.
THIN
);
style
.
setTopBorderColor
(
IndexedColors
.
GREY_50_PERCENT
.
getIndex
());
style
.
setBorderBottom
(
BorderStyle
.
THIN
);
style
.
setBottomBorderColor
(
IndexedColors
.
GREY_50_PERCENT
.
getIndex
());
Font
dataFont
=
wb
.
createFont
();
dataFont
.
setFontName
(
"Arial"
);
dataFont
.
setFontHeightInPoints
((
short
)
10
);
style
.
setFont
(
dataFont
);
styles
.
put
(
"data"
,
style
);
style
=
wb
.
createCellStyle
();
style
.
cloneStyleFrom
(
styles
.
get
(
"data"
));
style
.
setAlignment
(
HorizontalAlignment
.
CENTER
);
style
.
setVerticalAlignment
(
VerticalAlignment
.
CENTER
);
style
.
setFillForegroundColor
(
IndexedColors
.
GREY_50_PERCENT
.
getIndex
());
style
.
setFillPattern
(
FillPatternType
.
SOLID_FOREGROUND
);
Font
headerFont
=
wb
.
createFont
();
headerFont
.
setFontName
(
"Arial"
);
headerFont
.
setFontHeightInPoints
((
short
)
10
);
headerFont
.
setBold
(
true
);
headerFont
.
setColor
(
IndexedColors
.
WHITE
.
getIndex
());
style
.
setFont
(
headerFont
);
styles
.
put
(
"header"
,
style
);
style
=
wb
.
createCellStyle
();
style
.
setAlignment
(
HorizontalAlignment
.
CENTER
);
style
.
setVerticalAlignment
(
VerticalAlignment
.
CENTER
);
Font
totalFont
=
wb
.
createFont
();
totalFont
.
setFontName
(
"Arial"
);
totalFont
.
setFontHeightInPoints
((
short
)
10
);
style
.
setFont
(
totalFont
);
styles
.
put
(
"total"
,
style
);
style
=
wb
.
createCellStyle
();
style
.
cloneStyleFrom
(
styles
.
get
(
"data"
));
style
.
setAlignment
(
HorizontalAlignment
.
LEFT
);
styles
.
put
(
"data1"
,
style
);
style
=
wb
.
createCellStyle
();
style
.
cloneStyleFrom
(
styles
.
get
(
"data"
));
style
.
setAlignment
(
HorizontalAlignment
.
CENTER
);
styles
.
put
(
"data2"
,
style
);
style
=
wb
.
createCellStyle
();
style
.
cloneStyleFrom
(
styles
.
get
(
"data"
));
style
.
setAlignment
(
HorizontalAlignment
.
RIGHT
);
styles
.
put
(
"data3"
,
style
);
return
styles
;
}
/**
* 创建单元格
*/
public
Cell
createCell
(
Excel
attr
,
Row
row
,
int
column
)
{
// 创建列
Cell
cell
=
row
.
createCell
(
column
);
// 写入列信息
cell
.
setCellValue
(
attr
.
name
());
setDataValidation
(
attr
,
row
,
column
);
cell
.
setCellStyle
(
styles
.
get
(
"header"
));
return
cell
;
}
/**
* 设置单元格信息
*
* @param value 单元格值
* @param attr 注解相关
* @param cell 单元格信息
*/
public
void
setCellVo
(
Object
value
,
Excel
attr
,
Cell
cell
)
{
if
(
ColumnType
.
STRING
==
attr
.
cellType
())
{
String
cellValue
=
Convert
.
toStr
(
value
);
// 对于任何以表达式触发字符 =-+@开头的单元格,直接使用tab字符作为前缀,防止CSV注入。
if
(
StrUtils
.
startsWithAny
(
cellValue
,
FORMULA_STR
))
{
cellValue
=
RegExUtils
.
replaceFirst
(
cellValue
,
FORMULA_REGEX_STR
,
"\t$0"
);
}
cell
.
setCellValue
(
StrUtils
.
isNull
(
cellValue
)
?
attr
.
defaultValue
()
:
cellValue
+
attr
.
suffix
());
}
else
if
(
ColumnType
.
NUMERIC
==
attr
.
cellType
())
{
if
(
StrUtils
.
isNotNull
(
value
))
{
cell
.
setCellValue
(
StrUtils
.
contains
(
Convert
.
toStr
(
value
),
"."
)
?
Convert
.
toDouble
(
value
)
:
Convert
.
toInt
(
value
)
);
}
}
else
if
(
ColumnType
.
IMAGE
==
attr
.
cellType
())
{
ClientAnchor
anchor
=
new
XSSFClientAnchor
(
0
,
0
,
0
,
0
,
(
short
)
cell
.
getColumnIndex
(),
cell
.
getRow
().
getRowNum
(),
(
short
)
(
cell
.
getColumnIndex
()
+
1
),
cell
.
getRow
().
getRowNum
()
+
1
);
String
imagePath
=
Convert
.
toStr
(
value
);
if
(
StrUtils
.
isNotEmpty
(
imagePath
))
{
byte
[]
data
=
ImageUtils
.
getImage
(
imagePath
);
getDrawingPatriarch
(
cell
.
getSheet
())
.
createPicture
(
anchor
,
cell
.
getSheet
().
getWorkbook
().
addPicture
(
data
,
getImageType
(
data
)));
}
}
}
/**
* 获取画布
*/
public
static
Drawing
<?>
getDrawingPatriarch
(
Sheet
sheet
)
{
if
(
sheet
.
getDrawingPatriarch
()
==
null
)
{
sheet
.
createDrawingPatriarch
();
}
return
sheet
.
getDrawingPatriarch
();
}
/**
* 获取图片类型,设置图片插入类型
*/
public
int
getImageType
(
byte
[]
value
)
{
String
type
=
FileTypeUtils
.
getFileExtendName
(
value
);
if
(
"JPG"
.
equalsIgnoreCase
(
type
))
{
return
Workbook
.
PICTURE_TYPE_JPEG
;
}
else
if
(
"PNG"
.
equalsIgnoreCase
(
type
))
{
return
Workbook
.
PICTURE_TYPE_PNG
;
}
return
Workbook
.
PICTURE_TYPE_JPEG
;
}
/**
* 创建表格样式
*/
public
void
setDataValidation
(
Excel
attr
,
Row
row
,
int
column
)
{
if
(
attr
.
name
().
indexOf
(
"注:"
)
>=
0
)
{
sheet
.
setColumnWidth
(
column
,
6000
);
}
else
{
// 设置列宽
sheet
.
setColumnWidth
(
column
,
(
int
)
((
attr
.
width
()
+
0.72
)
*
256
));
}
if
(
StrUtils
.
isNotEmpty
(
attr
.
prompt
())
||
attr
.
combo
().
length
>
0
)
{
// 提示信息或只能选择不能输入的列内容.
setPromptOrValidation
(
sheet
,
attr
.
combo
(),
attr
.
prompt
(),
1
,
100
,
column
,
column
);
}
}
/**
* 添加单元格
*/
public
Cell
addCell
(
Excel
attr
,
Row
row
,
T
vo
,
Field
field
,
int
column
)
{
Cell
cell
=
null
;
try
{
// 设置行高
row
.
setHeight
(
maxHeight
);
// 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列.
if
(
attr
.
isExport
())
{
// 创建cell
cell
=
row
.
createCell
(
column
);
int
align
=
attr
.
align
().
value
();
cell
.
setCellStyle
(
styles
.
get
(
"data"
+
(
align
>=
1
&&
align
<=
3
?
align
:
""
)));
// 用于读取对象中的属性
Object
value
=
getTargetValue
(
vo
,
field
,
attr
);
String
dateFormat
=
attr
.
dateFormat
();
String
readConverterExp
=
attr
.
readConverterExp
();
String
separator
=
attr
.
separator
();
String
dictType
=
attr
.
dictType
();
if
(
StrUtils
.
isNotEmpty
(
dateFormat
)
&&
StrUtils
.
isNotNull
(
value
))
{
cell
.
setCellValue
(
parseDateToStr
(
dateFormat
,
value
));
}
else
if
(
StrUtils
.
isNotEmpty
(
readConverterExp
)
&&
StrUtils
.
isNotNull
(
value
))
{
cell
.
setCellValue
(
convertByExp
(
Convert
.
toStr
(
value
),
readConverterExp
,
separator
));
}
else
if
(
StrUtils
.
isNotEmpty
(
dictType
)
&&
StrUtils
.
isNotNull
(
value
))
{
cell
.
setCellValue
(
convertDictByExp
(
Convert
.
toStr
(
value
),
dictType
,
separator
));
}
else
if
(
value
instanceof
BigDecimal
&&
-
1
!=
attr
.
scale
())
{
cell
.
setCellValue
((((
BigDecimal
)
value
).
setScale
(
attr
.
scale
(),
attr
.
roundingMode
())).
toString
());
}
else
if
(!
attr
.
handler
().
equals
(
ExcelHandlerAdapter
.
class
))
{
cell
.
setCellValue
(
dataFormatHandlerAdapter
(
value
,
attr
));
}
else
{
// 设置列类型
setCellVo
(
value
,
attr
,
cell
);
}
addStatisticsData
(
column
,
Convert
.
toStr
(
value
),
attr
);
}
}
catch
(
Exception
e
)
{
log
.
error
(
"导出Excel失败{}"
,
e
);
}
return
cell
;
}
/**
* 设置 POI XSSFSheet 单元格提示或选择框
*
* @param sheet 表单
* @param textlist 下拉框显示的内容
* @param promptContent 提示内容
* @param firstRow 开始行
* @param endRow 结束行
* @param firstCol 开始列
* @param endCol 结束列
*/
public
void
setPromptOrValidation
(
Sheet
sheet
,
String
[]
textlist
,
String
promptContent
,
int
firstRow
,
int
endRow
,
int
firstCol
,
int
endCol
)
{
DataValidationHelper
helper
=
sheet
.
getDataValidationHelper
();
DataValidationConstraint
constraint
=
textlist
.
length
>
0
?
helper
.
createExplicitListConstraint
(
textlist
)
:
helper
.
createCustomConstraint
(
"DD1"
);
CellRangeAddressList
regions
=
new
CellRangeAddressList
(
firstRow
,
endRow
,
firstCol
,
endCol
);
DataValidation
dataValidation
=
helper
.
createValidation
(
constraint
,
regions
);
if
(
StrUtils
.
isNotEmpty
(
promptContent
))
{
// 如果设置了提示信息则鼠标放上去提示
dataValidation
.
createPromptBox
(
""
,
promptContent
);
dataValidation
.
setShowPromptBox
(
true
);
}
// 处理Excel兼容性问题
if
(
dataValidation
instanceof
XSSFDataValidation
)
{
dataValidation
.
setSuppressDropDownArrow
(
true
);
dataValidation
.
setShowErrorBox
(
true
);
}
else
{
dataValidation
.
setSuppressDropDownArrow
(
false
);
}
sheet
.
addValidationData
(
dataValidation
);
}
/**
* 解析导出值 0=男,1=女,2=未知
*
* @param propertyValue 参数值
* @param converterExp 翻译注解
* @param separator 分隔符
* @return 解析后值
*/
public
static
String
convertByExp
(
String
propertyValue
,
String
converterExp
,
String
separator
)
{
StringBuilder
propertyString
=
new
StringBuilder
();
String
[]
convertSource
=
converterExp
.
split
(
","
);
for
(
String
item
:
convertSource
)
{
String
[]
itemArray
=
item
.
split
(
"="
);
if
(
StrUtils
.
containsAny
(
separator
,
propertyValue
))
{
for
(
String
value
:
propertyValue
.
split
(
separator
))
{
if
(
itemArray
[
0
].
equals
(
value
))
{
propertyString
.
append
(
itemArray
[
1
]
+
separator
);
break
;
}
}
}
else
{
if
(
itemArray
[
0
].
equals
(
propertyValue
))
{
return
itemArray
[
1
];
}
}
}
return
StrUtils
.
stripEnd
(
propertyString
.
toString
(),
separator
);
}
/**
* 反向解析值 男=0,女=1,未知=2
*
* @param propertyValue 参数值
* @param converterExp 翻译注解
* @param separator 分隔符
* @return 解析后值
*/
public
static
String
reverseByExp
(
String
propertyValue
,
String
converterExp
,
String
separator
)
{
StringBuilder
propertyString
=
new
StringBuilder
();
String
[]
convertSource
=
converterExp
.
split
(
","
);
for
(
String
item
:
convertSource
)
{
String
[]
itemArray
=
item
.
split
(
"="
);
if
(
StrUtils
.
containsAny
(
separator
,
propertyValue
))
{
for
(
String
value
:
propertyValue
.
split
(
separator
))
{
if
(
itemArray
[
1
].
equals
(
value
))
{
propertyString
.
append
(
itemArray
[
0
]
+
separator
);
break
;
}
}
}
else
{
if
(
itemArray
[
1
].
equals
(
propertyValue
))
{
return
itemArray
[
0
];
}
}
}
return
StrUtils
.
stripEnd
(
propertyString
.
toString
(),
separator
);
}
/**
* 解析字典值
*
* @param dictValue 字典值
* @param dictType 字典类型
* @param separator 分隔符
* @return 字典标签
*/
public
static
String
convertDictByExp
(
String
dictValue
,
String
dictType
,
String
separator
)
{
return
DictUtils
.
getDictLabel
(
dictType
,
dictValue
,
separator
);
}
/**
* 反向解析值字典值
*
* @param dictLabel 字典标签
* @param dictType 字典类型
* @param separator 分隔符
* @return 字典值
*/
public
static
String
reverseDictByExp
(
String
dictLabel
,
String
dictType
,
String
separator
)
{
return
DictUtils
.
getDictValue
(
dictType
,
dictLabel
,
separator
);
}
/**
* 数据处理器
*
* @param value 数据值
* @param excel 数据注解
* @return
*/
public
String
dataFormatHandlerAdapter
(
Object
value
,
Excel
excel
)
{
try
{
Object
instance
=
excel
.
handler
().
newInstance
();
Method
formatMethod
=
excel
.
handler
().
getMethod
(
"format"
,
new
Class
[]
{
Object
.
class
,
String
[].
class
});
value
=
formatMethod
.
invoke
(
instance
,
value
,
excel
.
args
());
}
catch
(
Exception
e
)
{
log
.
error
(
"不能格式化数据 "
+
excel
.
handler
(),
e
.
getMessage
());
}
return
Convert
.
toStr
(
value
);
}
/**
* 合计统计信息
*/
private
void
addStatisticsData
(
Integer
index
,
String
text
,
Excel
entity
)
{
if
(
entity
!=
null
&&
entity
.
isStatistics
())
{
Double
temp
=
0
D
;
if
(!
statistics
.
containsKey
(
index
))
{
statistics
.
put
(
index
,
temp
);
}
try
{
temp
=
Double
.
valueOf
(
text
);
}
catch
(
NumberFormatException
e
)
{}
statistics
.
put
(
index
,
statistics
.
get
(
index
)
+
temp
);
}
}
/**
* 创建统计行
*/
public
void
addStatisticsRow
()
{
if
(
statistics
.
size
()
>
0
)
{
Row
row
=
sheet
.
createRow
(
sheet
.
getLastRowNum
()
+
1
);
Set
<
Integer
>
keys
=
statistics
.
keySet
();
Cell
cell
=
row
.
createCell
(
0
);
cell
.
setCellStyle
(
styles
.
get
(
"total"
));
cell
.
setCellValue
(
"合计"
);
for
(
Integer
key
:
keys
)
{
cell
=
row
.
createCell
(
key
);
cell
.
setCellStyle
(
styles
.
get
(
"total"
));
cell
.
setCellValue
(
DOUBLE_FORMAT
.
format
(
statistics
.
get
(
key
)));
}
statistics
.
clear
();
}
}
/**
* 获取bean中的属性值
*
* @param vo 实体对象
* @param field 字段
* @param excel 注解
* @return 最终的属性值
* @throws Exception
*/
private
Object
getTargetValue
(
T
vo
,
Field
field
,
Excel
excel
)
throws
Exception
{
Object
o
=
field
.
get
(
vo
);
if
(
StrUtils
.
isNotEmpty
(
excel
.
targetAttr
()))
{
String
target
=
excel
.
targetAttr
();
if
(
target
.
contains
(
"."
))
{
String
[]
targets
=
target
.
split
(
"[.]"
);
for
(
String
name
:
targets
)
{
o
=
getValue
(
o
,
name
);
}
}
else
{
o
=
getValue
(
o
,
target
);
}
}
return
o
;
}
/**
* 以类的属性的get方法方法形式获取值
*
* @param o
* @param name
* @return value
* @throws Exception
*/
private
Object
getValue
(
Object
o
,
String
name
)
throws
Exception
{
if
(
StrUtils
.
isNotNull
(
o
)
&&
StrUtils
.
isNotEmpty
(
name
))
{
Class
<?>
clazz
=
o
.
getClass
();
Field
field
=
clazz
.
getDeclaredField
(
name
);
field
.
setAccessible
(
true
);
o
=
field
.
get
(
o
);
}
return
o
;
}
/**
* 得到所有定义字段
*/
private
void
createExcelField
()
{
this
.
fields
=
getFields
();
this
.
fields
=
this
.
fields
.
stream
()
.
sorted
(
Comparator
.
comparing
(
objects
->
((
Excel
)
objects
[
1
]).
sort
()))
.
collect
(
Collectors
.
toList
());
this
.
maxHeight
=
getRowHeight
();
}
/**
* 获取字段注解信息
*/
public
List
<
Object
[]>
getFields
()
{
List
<
Object
[]>
fields
=
new
ArrayList
<
Object
[]>();
List
<
Field
>
tempFields
=
new
ArrayList
<>();
tempFields
.
addAll
(
Arrays
.
asList
(
clazz
.
getSuperclass
().
getDeclaredFields
()));
tempFields
.
addAll
(
Arrays
.
asList
(
clazz
.
getDeclaredFields
()));
for
(
Field
field
:
tempFields
)
{
// 单注解
if
(
field
.
isAnnotationPresent
(
Excel
.
class
))
{
Excel
attr
=
field
.
getAnnotation
(
Excel
.
class
);
if
(
attr
!=
null
&&
(
attr
.
type
()
==
Type
.
ALL
||
attr
.
type
()
==
type
))
{
field
.
setAccessible
(
true
);
fields
.
add
(
new
Object
[]
{
field
,
attr
});
}
}
// 多注解
if
(
field
.
isAnnotationPresent
(
Excels
.
class
))
{
Excels
attrs
=
field
.
getAnnotation
(
Excels
.
class
);
Excel
[]
excels
=
attrs
.
value
();
for
(
Excel
attr
:
excels
)
{
if
(
attr
!=
null
&&
(
attr
.
type
()
==
Type
.
ALL
||
attr
.
type
()
==
type
))
{
field
.
setAccessible
(
true
);
fields
.
add
(
new
Object
[]
{
field
,
attr
});
}
}
}
}
return
fields
;
}
/**
* 根据注解获取最大行高
*/
public
short
getRowHeight
()
{
double
maxHeight
=
0
;
for
(
Object
[]
os
:
this
.
fields
)
{
Excel
excel
=
(
Excel
)
os
[
1
];
maxHeight
=
Math
.
max
(
maxHeight
,
excel
.
height
());
}
return
(
short
)
(
maxHeight
*
20
);
}
/**
* 创建一个工作簿
*/
public
void
createWorkbook
()
{
this
.
wb
=
new
SXSSFWorkbook
(
500
);
this
.
sheet
=
wb
.
createSheet
();
wb
.
setSheetName
(
0
,
sheetName
);
this
.
styles
=
createStyles
(
wb
);
}
/**
* 创建工作表
*
* @param sheetNo sheet数量
* @param index 序号
*/
public
void
createSheet
(
int
sheetNo
,
int
index
)
{
// 设置工作表的名称.
if
(
sheetNo
>
1
&&
index
>
0
)
{
this
.
sheet
=
wb
.
createSheet
();
this
.
createTitle
();
wb
.
setSheetName
(
index
,
sheetName
+
index
);
}
}
/**
* 获取单元格值
*
* @param row 获取的行
* @param column 获取单元格列号
* @return 单元格值
*/
public
Object
getCellValue
(
Row
row
,
int
column
)
{
if
(
row
==
null
)
{
return
row
;
}
Object
val
=
""
;
try
{
Cell
cell
=
row
.
getCell
(
column
);
if
(
StrUtils
.
isNotNull
(
cell
))
{
if
(
cell
.
getCellType
()
==
CellType
.
NUMERIC
||
cell
.
getCellType
()
==
CellType
.
FORMULA
)
{
val
=
cell
.
getNumericCellValue
();
if
(
DateUtil
.
isCellDateFormatted
(
cell
))
{
val
=
DateUtil
.
getJavaDate
((
Double
)
val
);
// POI Excel 日期格式转换
}
else
{
if
((
Double
)
val
%
1
!=
0
)
{
val
=
new
BigDecimal
(
val
.
toString
());
}
else
{
val
=
new
DecimalFormat
(
"0"
).
format
(
val
);
}
}
}
else
if
(
cell
.
getCellType
()
==
CellType
.
STRING
)
{
val
=
cell
.
getStringCellValue
();
}
else
if
(
cell
.
getCellType
()
==
CellType
.
BOOLEAN
)
{
val
=
cell
.
getBooleanCellValue
();
}
else
if
(
cell
.
getCellType
()
==
CellType
.
ERROR
)
{
val
=
cell
.
getErrorCellValue
();
}
}
}
catch
(
Exception
e
)
{
return
val
;
}
return
val
;
}
/**
* 判断是否是空行
*
* @param row 判断的行
* @return
*/
private
boolean
isRowEmpty
(
Row
row
)
{
if
(
row
==
null
)
{
return
true
;
}
for
(
int
i
=
row
.
getFirstCellNum
();
i
<
row
.
getLastCellNum
();
i
++)
{
Cell
cell
=
row
.
getCell
(
i
);
if
(
cell
!=
null
&&
cell
.
getCellType
()
!=
CellType
.
BLANK
)
{
return
false
;
}
}
return
true
;
}
/**
* 格式化不同类型的日期对象
*
* @param dateFormat 日期格式
* @param val 被格式化的日期对象
* @return 格式化后的日期字符
*/
public
String
parseDateToStr
(
String
dateFormat
,
Object
val
)
{
if
(
val
==
null
)
{
return
""
;
}
String
str
;
if
(
val
instanceof
Date
)
{
str
=
DateUtils
.
parseDateToStr
(
dateFormat
,
(
Date
)
val
);
}
else
if
(
val
instanceof
LocalDateTime
)
{
str
=
DateUtils
.
parseDateToStr
(
dateFormat
,
DateUtils
.
toDate
((
LocalDateTime
)
val
));
}
else
if
(
val
instanceof
LocalDate
)
{
str
=
DateUtils
.
parseDateToStr
(
dateFormat
,
DateUtils
.
toDate
((
LocalDate
)
val
));
}
else
{
str
=
val
.
toString
();
}
return
str
;
}
}
basic-common/util/src/main/java/com/yiring/common/util/reflect/ReflectUtils.java
0 → 100644
浏览文件 @
f360f80d
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
util
.
reflect
;
import
com.yiring.common.text.Convert
;
import
com.yiring.common.util.date.DateUtils
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Modifier
;
import
java.lang.reflect.ParameterizedType
;
import
java.lang.reflect.Type
;
import
java.util.Date
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.Validate
;
import
org.apache.poi.ss.usermodel.DateUtil
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
/**
* 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数.
*/
@SuppressWarnings
(
"rawtypes"
)
public
class
ReflectUtils
{
private
static
final
String
SETTER_PREFIX
=
"set"
;
private
static
final
String
GETTER_PREFIX
=
"get"
;
private
static
final
String
CGLIB_CLASS_SEPARATOR
=
"$$"
;
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
ReflectUtils
.
class
);
/**
* 调用Getter方法.
* 支持多级,如:对象名.对象名.方法
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
E
>
E
invokeGetter
(
Object
obj
,
String
propertyName
)
{
Object
object
=
obj
;
for
(
String
name
:
StringUtils
.
split
(
propertyName
,
"."
))
{
String
getterMethodName
=
GETTER_PREFIX
+
StringUtils
.
capitalize
(
name
);
object
=
invokeMethod
(
object
,
getterMethodName
,
new
Class
[]
{},
new
Object
[]
{});
}
return
(
E
)
object
;
}
/**
* 调用Setter方法, 仅匹配方法名。
* 支持多级,如:对象名.对象名.方法
*/
public
static
<
E
>
void
invokeSetter
(
Object
obj
,
String
propertyName
,
E
value
)
{
Object
object
=
obj
;
String
[]
names
=
StringUtils
.
split
(
propertyName
,
"."
);
for
(
int
i
=
0
;
i
<
names
.
length
;
i
++)
{
if
(
i
<
names
.
length
-
1
)
{
String
getterMethodName
=
GETTER_PREFIX
+
StringUtils
.
capitalize
(
names
[
i
]);
object
=
invokeMethod
(
object
,
getterMethodName
,
new
Class
[]
{},
new
Object
[]
{});
}
else
{
String
setterMethodName
=
SETTER_PREFIX
+
StringUtils
.
capitalize
(
names
[
i
]);
invokeMethodByName
(
object
,
setterMethodName
,
new
Object
[]
{
value
});
}
}
}
/**
* 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数.
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
E
>
E
getFieldValue
(
final
Object
obj
,
final
String
fieldName
)
{
Field
field
=
getAccessibleField
(
obj
,
fieldName
);
if
(
field
==
null
)
{
logger
.
debug
(
"在 ["
+
obj
.
getClass
()
+
"] 中,没有找到 ["
+
fieldName
+
"] 字段 "
);
return
null
;
}
E
result
=
null
;
try
{
result
=
(
E
)
field
.
get
(
obj
);
}
catch
(
IllegalAccessException
e
)
{
logger
.
error
(
"不可能抛出的异常{}"
,
e
.
getMessage
());
}
return
result
;
}
/**
* 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.
*/
public
static
<
E
>
void
setFieldValue
(
final
Object
obj
,
final
String
fieldName
,
final
E
value
)
{
Field
field
=
getAccessibleField
(
obj
,
fieldName
);
if
(
field
==
null
)
{
// throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 ");
logger
.
debug
(
"在 ["
+
obj
.
getClass
()
+
"] 中,没有找到 ["
+
fieldName
+
"] 字段 "
);
return
;
}
try
{
field
.
set
(
obj
,
value
);
}
catch
(
IllegalAccessException
e
)
{
logger
.
error
(
"不可能抛出的异常: {}"
,
e
.
getMessage
());
}
}
/**
* 直接调用对象方法, 无视private/protected修饰符.
* 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用.
* 同时匹配方法名+参数类型,
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
E
>
E
invokeMethod
(
final
Object
obj
,
final
String
methodName
,
final
Class
<?>[]
parameterTypes
,
final
Object
[]
args
)
{
if
(
obj
==
null
||
methodName
==
null
)
{
return
null
;
}
Method
method
=
getAccessibleMethod
(
obj
,
methodName
,
parameterTypes
);
if
(
method
==
null
)
{
logger
.
debug
(
"在 ["
+
obj
.
getClass
()
+
"] 中,没有找到 ["
+
methodName
+
"] 方法 "
);
return
null
;
}
try
{
return
(
E
)
method
.
invoke
(
obj
,
args
);
}
catch
(
Exception
e
)
{
String
msg
=
"method: "
+
method
+
", obj: "
+
obj
+
", args: "
+
args
+
""
;
throw
convertReflectionExceptionToUnchecked
(
msg
,
e
);
}
}
/**
* 直接调用对象方法, 无视private/protected修饰符,
* 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用.
* 只匹配函数名,如果有多个同名函数调用第一个。
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
E
>
E
invokeMethodByName
(
final
Object
obj
,
final
String
methodName
,
final
Object
[]
args
)
{
Method
method
=
getAccessibleMethodByName
(
obj
,
methodName
,
args
.
length
);
if
(
method
==
null
)
{
// 如果为空不报错,直接返回空。
logger
.
debug
(
"在 ["
+
obj
.
getClass
()
+
"] 中,没有找到 ["
+
methodName
+
"] 方法 "
);
return
null
;
}
try
{
// 类型转换(将参数数据类型转换为目标方法参数类型)
Class
<?>[]
cs
=
method
.
getParameterTypes
();
for
(
int
i
=
0
;
i
<
cs
.
length
;
i
++)
{
if
(
args
[
i
]
!=
null
&&
!
args
[
i
].
getClass
().
equals
(
cs
[
i
]))
{
if
(
cs
[
i
]
==
String
.
class
)
{
args
[
i
]
=
Convert
.
toStr
(
args
[
i
]);
if
(
StringUtils
.
endsWith
((
String
)
args
[
i
],
".0"
))
{
args
[
i
]
=
StringUtils
.
substringBefore
((
String
)
args
[
i
],
".0"
);
}
}
else
if
(
cs
[
i
]
==
Integer
.
class
)
{
args
[
i
]
=
Convert
.
toInt
(
args
[
i
]);
}
else
if
(
cs
[
i
]
==
Long
.
class
)
{
args
[
i
]
=
Convert
.
toLong
(
args
[
i
]);
}
else
if
(
cs
[
i
]
==
Double
.
class
)
{
args
[
i
]
=
Convert
.
toDouble
(
args
[
i
]);
}
else
if
(
cs
[
i
]
==
Float
.
class
)
{
args
[
i
]
=
Convert
.
toFloat
(
args
[
i
]);
}
else
if
(
cs
[
i
]
==
Date
.
class
)
{
if
(
args
[
i
]
instanceof
String
)
{
args
[
i
]
=
DateUtils
.
parseDate
(
args
[
i
]);
}
else
{
args
[
i
]
=
DateUtil
.
getJavaDate
((
Double
)
args
[
i
]);
}
}
else
if
(
cs
[
i
]
==
boolean
.
class
||
cs
[
i
]
==
Boolean
.
class
)
{
args
[
i
]
=
Convert
.
toBool
(
args
[
i
]);
}
}
}
return
(
E
)
method
.
invoke
(
obj
,
args
);
}
catch
(
Exception
e
)
{
String
msg
=
"method: "
+
method
+
", obj: "
+
obj
+
", args: "
+
args
+
""
;
throw
convertReflectionExceptionToUnchecked
(
msg
,
e
);
}
}
/**
* 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问.
* 如向上转型到Object仍无法找到, 返回null.
*/
public
static
Field
getAccessibleField
(
final
Object
obj
,
final
String
fieldName
)
{
// 为空不报错。直接返回 null
if
(
obj
==
null
)
{
return
null
;
}
Validate
.
notBlank
(
fieldName
,
"fieldName can't be blank"
);
for
(
Class
<?>
superClass
=
obj
.
getClass
();
superClass
!=
Object
.
class
;
superClass
=
superClass
.
getSuperclass
()
)
{
try
{
Field
field
=
superClass
.
getDeclaredField
(
fieldName
);
makeAccessible
(
field
);
return
field
;
}
catch
(
NoSuchFieldException
e
)
{
continue
;
}
}
return
null
;
}
/**
* 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
* 如向上转型到Object仍无法找到, 返回null.
* 匹配函数名+参数类型。
* 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
*/
public
static
Method
getAccessibleMethod
(
final
Object
obj
,
final
String
methodName
,
final
Class
<?>...
parameterTypes
)
{
// 为空不报错。直接返回 null
if
(
obj
==
null
)
{
return
null
;
}
Validate
.
notBlank
(
methodName
,
"methodName can't be blank"
);
for
(
Class
<?>
searchType
=
obj
.
getClass
();
searchType
!=
Object
.
class
;
searchType
=
searchType
.
getSuperclass
()
)
{
try
{
Method
method
=
searchType
.
getDeclaredMethod
(
methodName
,
parameterTypes
);
makeAccessible
(
method
);
return
method
;
}
catch
(
NoSuchMethodException
e
)
{
continue
;
}
}
return
null
;
}
/**
* 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
* 如向上转型到Object仍无法找到, 返回null.
* 只匹配函数名。
* 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
*/
public
static
Method
getAccessibleMethodByName
(
final
Object
obj
,
final
String
methodName
,
int
argsNum
)
{
// 为空不报错。直接返回 null
if
(
obj
==
null
)
{
return
null
;
}
Validate
.
notBlank
(
methodName
,
"methodName can't be blank"
);
for
(
Class
<?>
searchType
=
obj
.
getClass
();
searchType
!=
Object
.
class
;
searchType
=
searchType
.
getSuperclass
()
)
{
Method
[]
methods
=
searchType
.
getDeclaredMethods
();
for
(
Method
method
:
methods
)
{
if
(
method
.
getName
().
equals
(
methodName
)
&&
method
.
getParameterTypes
().
length
==
argsNum
)
{
makeAccessible
(
method
);
return
method
;
}
}
}
return
null
;
}
/**
* 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
*/
public
static
void
makeAccessible
(
Method
method
)
{
if
(
(
!
Modifier
.
isPublic
(
method
.
getModifiers
())
||
!
Modifier
.
isPublic
(
method
.
getDeclaringClass
().
getModifiers
())
)
&&
!
method
.
isAccessible
()
)
{
method
.
setAccessible
(
true
);
}
}
/**
* 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
*/
public
static
void
makeAccessible
(
Field
field
)
{
if
(
(
!
Modifier
.
isPublic
(
field
.
getModifiers
())
||
!
Modifier
.
isPublic
(
field
.
getDeclaringClass
().
getModifiers
())
||
Modifier
.
isFinal
(
field
.
getModifiers
())
)
&&
!
field
.
isAccessible
()
)
{
field
.
setAccessible
(
true
);
}
}
/**
* 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处
* 如无法找到, 返回Object.class.
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
T
>
Class
<
T
>
getClassGenricType
(
final
Class
clazz
)
{
return
getClassGenricType
(
clazz
,
0
);
}
/**
* 通过反射, 获得Class定义中声明的父类的泛型参数的类型.
* 如无法找到, 返回Object.class.
*/
public
static
Class
getClassGenricType
(
final
Class
clazz
,
final
int
index
)
{
Type
genType
=
clazz
.
getGenericSuperclass
();
if
(!(
genType
instanceof
ParameterizedType
))
{
logger
.
debug
(
clazz
.
getSimpleName
()
+
"'s superclass not ParameterizedType"
);
return
Object
.
class
;
}
Type
[]
params
=
((
ParameterizedType
)
genType
).
getActualTypeArguments
();
if
(
index
>=
params
.
length
||
index
<
0
)
{
logger
.
debug
(
"Index: "
+
index
+
", Size of "
+
clazz
.
getSimpleName
()
+
"'s Parameterized Type: "
+
params
.
length
);
return
Object
.
class
;
}
if
(!(
params
[
index
]
instanceof
Class
))
{
logger
.
debug
(
clazz
.
getSimpleName
()
+
" not set the actual class on superclass generic parameter"
);
return
Object
.
class
;
}
return
(
Class
)
params
[
index
];
}
public
static
Class
<?>
getUserClass
(
Object
instance
)
{
if
(
instance
==
null
)
{
throw
new
RuntimeException
(
"Instance must not be null"
);
}
Class
clazz
=
instance
.
getClass
();
if
(
clazz
!=
null
&&
clazz
.
getName
().
contains
(
CGLIB_CLASS_SEPARATOR
))
{
Class
<?>
superClass
=
clazz
.
getSuperclass
();
if
(
superClass
!=
null
&&
!
Object
.
class
.
equals
(
superClass
))
{
return
superClass
;
}
}
return
clazz
;
}
/**
* 将反射时的checked exception转换为unchecked exception.
*/
public
static
RuntimeException
convertReflectionExceptionToUnchecked
(
String
msg
,
Exception
e
)
{
if
(
e
instanceof
IllegalAccessException
||
e
instanceof
IllegalArgumentException
||
e
instanceof
NoSuchMethodException
)
{
return
new
IllegalArgumentException
(
msg
,
e
);
}
else
if
(
e
instanceof
InvocationTargetException
)
{
return
new
RuntimeException
(
msg
,
((
InvocationTargetException
)
e
).
getTargetException
());
}
return
new
RuntimeException
(
msg
,
e
);
}
}
build.gradle
浏览文件 @
f360f80d
...
...
@@ -10,7 +10,7 @@ buildscript {
// https://mvnrepository.com/artifact/cn.dev33/sa-token-spring-boot-starter
saTokenVersion
=
'1.29.1.trial'
// https://mvnrepository.com/artifact/cn.hutool/hutool-all
hutoolVersion
=
'5.
7.22
'
hutoolVersion
=
'5.
8.0.M3
'
// https://mvnrepository.com/artifact/com.alibaba/fastjson
fastJsonVersion
=
'1.2.80'
// https://mvnrepository.com/artifact/com.xuxueli/xxl-job-core
...
...
@@ -27,6 +27,8 @@ buildscript {
jtsVersion
=
'1.18.2'
// https://mvnrepository.com/artifact/com.vladmihalcea/hibernate-types-55
hibernateTypesVersion
=
'2.16.1'
// https://mvnrepository.com/artifact/com.github.liaochong/myexcel
myexcelVersion
=
'4.1.1'
}
}
...
...
doc/skill.md
0 → 100644
浏览文件 @
f360f80d
## 实用技巧
> Swagger 文档进行文件下载
```
diff
# 将下载接口上的 @ApiOperation 注解中的 produces 属性值改为 application/octet-stream
- @ApiOperation(value = "文件下载")
+ @ApiOperation(value = "文件下载", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
```
> Redis 使用
```
diff
+ @Resource
+ Redis redis;
+ Object value = redis.get(key);
```
> Excel 导入/导出,使用 [MyExcel](https://github.com/liaochong/myexcel) 工具库
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论