Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
basic-api-boot
概览
概览
详情
活动
周期分析
版本库
存储库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Basic
basic-api-boot
Commits
77515b59
提交
77515b59
authored
4月 19, 2022
作者:
方治民
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'dev_tzl' of
https://gitlab.yiring.com/chemical-kesai/kshg-api
into merge_dev
Conflicts: app/build.gradle
上级
f490012a
c7db2617
显示空白字符变更
内嵌
并排
正在显示
49 个修改的文件
包含
5852 行增加
和
18 行删除
+5852
-18
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
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
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
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
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
+290
-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
+201
-0
DictTypeServiceImpl.java
...com/yiring/app/service/dict/impl/DictTypeServiceImpl.java
+122
-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
CarVo.java
app/src/main/java/com/yiring/app/vo/car/CarVo.java
+96
-0
VideoVo.java
app/src/main/java/com/yiring/app/vo/video/VideoVo.java
+40
-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
build.gradle
basic-common/core/build.gradle
+3
-5
CorsConfig.java
...re/src/main/java/com/yiring/common/config/CorsConfig.java
+30
-0
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/util/build.gradle
+6
-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
SpringUtil.java
...c/main/java/com/yiring/common/util/spring/SpringUtil.java
+44
-0
build.gradle
build.gradle
+3
-0
没有找到文件。
app/src/main/java/com/yiring/app/domain/car/Car.java
0 → 100644
浏览文件 @
77515b59
/* (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.annotaions.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
浏览文件 @
77515b59
/* (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/video/Video.java
浏览文件 @
77515b59
...
...
@@ -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
浏览文件 @
77515b59
...
...
@@ -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/param/car/CarParam.java
0 → 100644
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (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/video/VideoParam.java
0 → 100644
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (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/service/car/CarService.java
0 → 100644
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
service
.
car
.
impl
;
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.util.StrUtils
;
import
com.yiring.common.util.date.DateUtils
;
import
com.yiring.common.vo.PageVo
;
import
java.time.LocalDateTime
;
import
java.util.*
;
import
java.util.stream.Collectors
;
import
javax.annotation.Resource
;
import
javax.persistence.criteria.Predicate
;
import
org.apache.commons.lang3.StringUtils
;
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
(
StringUtils
.
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
(
StrUtils
.
isNotBlank
(
carParam
.
getCarNum
()))
{
//车牌号码查询
list
.
add
(
criteriaBuilder
.
like
(
root
.
get
(
"carNum"
).
as
(
String
.
class
),
"%"
+
carParam
.
getCarNum
()
+
"%"
));
}
if
(
StrUtils
.
isNotBlank
(
carParam
.
getCarType
()))
{
//车辆类型查询
list
.
add
(
criteriaBuilder
.
like
(
root
.
get
(
"carType"
).
as
(
String
.
class
),
"%"
+
carParam
.
getCarType
()
+
"%"
));
}
if
(
StrUtils
.
isNotBlank
(
carParam
.
getDriverName
()))
{
//司机名称查询
list
.
add
(
criteriaBuilder
.
like
(
root
.
get
(
"driverName"
).
as
(
String
.
class
),
"%"
+
carParam
.
getDriverName
()
+
"%"
)
);
}
if
(
StrUtils
.
isNotBlank
(
carParam
.
getDriverMobile
()))
{
//司机电话号码查询
list
.
add
(
criteriaBuilder
.
like
(
root
.
get
(
"driverMobile"
).
as
(
String
.
class
),
"%"
+
carParam
.
getDriverMobile
()
+
"%"
)
);
}
if
(
StrUtils
.
isNotBlank
(
carParam
.
getOrgId
()))
{
//所属单位查询
list
.
add
(
criteriaBuilder
.
like
(
root
.
get
(
"orgId"
).
as
(
String
.
class
),
"%"
+
carParam
.
getOrgId
()
+
"%"
));
}
if
(
StrUtils
.
isNotBlank
(
carParam
.
getReason
()))
{
//来访原因查询
list
.
add
(
criteriaBuilder
.
like
(
root
.
get
(
"reason"
).
as
(
String
.
class
),
"%"
+
carParam
.
getReason
()
+
"%"
));
}
if
(
StrUtils
.
isNotNull
(
carParam
.
getCreateTimeStart
())
&&
StrUtils
.
isNotNull
(
carParam
.
getCreateTimeEnd
()))
{
//来访时间区间段查询
list
.
add
(
criteriaBuilder
.
between
(
root
.
get
(
"createTime"
).
as
(
Date
.
class
),
DateUtils
.
toDate
(
carParam
.
getCreateTimeStart
()),
DateUtils
.
toDate
(
carParam
.
getCreateTimeEnd
())
)
);
}
if
(
StrUtils
.
isNotBlank
(
carParam
.
getLabelCard
()))
{
//标签卡号查询
list
.
add
(
criteriaBuilder
.
like
(
root
.
get
(
"labelCard"
).
as
(
String
.
class
),
"%"
+
carParam
.
getLabelCard
()
+
"%"
)
);
}
if
(
StrUtils
.
isNotBlank
(
carParam
.
getLabelCardStatus
()))
{
//标签卡状态查询
list
.
add
(
criteriaBuilder
.
equal
(
root
.
get
(
"labelCardStatus"
).
as
(
String
.
class
),
carParam
.
getLabelCardStatus
())
);
}
if
(
StrUtils
.
isNotNull
(
carParam
.
getCardRecTimeStart
())
&&
StrUtils
.
isNotNull
(
carParam
.
getCardRecTimeEnd
())
)
{
//来访时间区间段查询
list
.
add
(
criteriaBuilder
.
between
(
root
.
get
(
"cardRecTime"
).
as
(
Date
.
class
),
DateUtils
.
toDate
(
carParam
.
getCardRecTimeStart
()),
DateUtils
.
toDate
(
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
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
service
.
dict
.
impl
;
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.util.StrUtils
;
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
(
StrUtils
.
isNotBlank
(
dictQueryParam
.
getDictType
()))
{
list
.
add
(
criteriaBuilder
.
like
(
root
.
get
(
"dictType"
).
as
(
String
.
class
),
"%"
+
dictQueryParam
.
getDictType
()
+
"%"
)
);
}
if
(
StrUtils
.
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
浏览文件 @
77515b59
/* (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/video/VideoService.java
0 → 100644
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
service
.
video
.
impl
;
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.util.StrUtils
;
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
(
StrUtils
.
isNotBlank
(
videoQueryParam
.
getVideoName
()))
{
list
.
add
(
criteriaBuilder
.
like
(
root
.
get
(
"videoName"
).
as
(
String
.
class
),
"%"
+
videoQueryParam
.
getVideoName
()
+
"%"
)
);
}
if
(
StrUtils
.
isNotBlank
(
videoQueryParam
.
getUuid
()))
{
list
.
add
(
criteriaBuilder
.
like
(
root
.
get
(
"uuid"
).
as
(
String
.
class
),
"%"
+
videoQueryParam
.
getUuid
()
+
"%"
)
);
}
if
(
StrUtils
.
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/vo/car/CarVo.java
0 → 100644
浏览文件 @
77515b59
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
app
.
vo
.
car
;
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
;
import
org.apache.commons.lang3.StringUtils
;
/**
* @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
(
StringUtils
.
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
(
StringUtils
.
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/video/VideoVo.java
0 → 100644
浏览文件 @
77515b59
/* (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/car/CarController.java
0 → 100644
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (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
);
}
}
basic-common/core/build.gradle
浏览文件 @
77515b59
dependencies
{
implementation
project
(
":basic-common:util"
)
//
implementation project(":basic-common:util")
implementation
'org.springframework.boot:spring-boot-starter-aop'
implementation
'org.springframework.boot:spring-boot-starter-web'
...
...
@@ -12,11 +12,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
浏览文件 @
77515b59
/* (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/constant/RegEx.java
0 → 100644
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (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.annotaions.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
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (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.annotaions.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
浏览文件 @
77515b59
/* (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/util/build.gradle
浏览文件 @
77515b59
dependencies
{
implementation
project
(
":basic-common:core"
)
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}"
}
basic-common/util/src/main/java/com/yiring/common/annotation/Excel.java
0 → 100644
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
File moved
basic-common/util/src/main/java/com/yiring/common/text/Convert.java
0 → 100644
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
util
;
import
com.yiring.common.core.redis.RedisCache
;
import
com.yiring.common.dict.Dict
;
import
com.yiring.common.util.spring.SpringUtil
;
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
(
RedisCache
.
class
).
setCacheObject
(
getCacheKey
(
key
),
dictDatas
);
}
/**
* 获取字典缓存
*
* @param key 参数键
* @return dictDatas 字典数据列表
*/
public
static
List
<
Dict
>
getDictCache
(
String
key
)
{
Object
cacheObj
=
SpringUtil
.
getBean
(
RedisCache
.
class
).
getCacheObject
(
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
(
RedisCache
.
class
).
deleteObject
(
getCacheKey
(
key
));
}
/**
* 清空字典缓存
*/
public
static
void
clearDictCache
()
{
Collection
<
String
>
keys
=
SpringUtil
.
getBean
(
RedisCache
.
class
).
keys
(
"sys_dict:*"
);
SpringUtil
.
getBean
(
RedisCache
.
class
).
deleteObject
(
keys
);
}
/**
* 设置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
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (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
浏览文件 @
77515b59
/* (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
);
}
}
basic-common/util/src/main/java/com/yiring/common/util/spring/SpringUtil.java
0 → 100644
浏览文件 @
77515b59
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
util
.
spring
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.factory.config.BeanFactoryPostProcessor
;
import
org.springframework.beans.factory.config.ConfigurableListableBeanFactory
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.ApplicationContextAware
;
import
org.springframework.stereotype.Component
;
/**
* spring工具类 方便在非spring管理环境中获取bean
*
* @author ruoyi
*/
@Component
public
final
class
SpringUtil
implements
BeanFactoryPostProcessor
,
ApplicationContextAware
{
/** Spring应用上下文环境 */
private
static
ConfigurableListableBeanFactory
beanFactory
;
private
static
ApplicationContext
applicationContext
;
@Override
public
void
postProcessBeanFactory
(
ConfigurableListableBeanFactory
beanFactory
)
throws
BeansException
{
SpringUtil
.
beanFactory
=
beanFactory
;
}
@Override
public
void
setApplicationContext
(
ApplicationContext
applicationContext
)
throws
BeansException
{
SpringUtil
.
applicationContext
=
applicationContext
;
}
/**
* 获取类型为requiredType的对象
*
* @param clz Class
* @return T
*
*/
public
static
<
T
>
T
getBean
(
Class
<
T
>
clz
)
throws
BeansException
{
return
(
T
)
beanFactory
.
getBean
(
clz
);
}
}
build.gradle
浏览文件 @
77515b59
...
...
@@ -73,6 +73,9 @@ subprojects {
compileOnly
'org.projectlombok:lombok'
annotationProcessor
'org.projectlombok:lombok'
annotationProcessor
'org.springframework.boot:spring-boot-configuration-processor'
implementation
group:
'org.apache.poi'
,
name:
'poi'
,
version:
'5.0.0'
implementation
group:
'org.apache.poi'
,
name:
'poi-ooxml'
,
version:
'5.0.0'
implementation
group:
'org.apache.commons'
,
name:
'commons-lang3'
,
version:
'3.12.0'
}
[
compileJava
,
compileTestJava
,
javadoc
]*.
options
*.
encoding
=
'UTF-8'
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论