Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
聂康
ivccs
Commits
07602a7b
Commit
07602a7b
authored
Apr 18, 2023
by
kang.nie@inzymeits.com
Browse files
提交代码
parent
e0c7be76
Changes
479
Show whitespace changes
Inline
Side-by-side
ivccs-vmm-backservice/src/main/java/com/ssi/service/impl/VmsHangerStatusInfoServiceImpl.java
0 → 100644
View file @
07602a7b
package
com.ssi.service.impl
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.ssi.constant.enums.VmsTosOrderStatusEnum
;
import
com.ssi.entity.VmsHangerStatusInfo
;
import
com.ssi.mapper.VmsHangerStatusInfoMapper
;
import
com.ssi.model.RedisDataModel
;
import
com.ssi.response.SSIResponse
;
import
com.ssi.service.VmsHangerStatusInfoService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Service
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
java.util.Map
;
/**
* 吊具状态服务实现类
*/
@Service
(
"vmsHangerStatusInfoService"
)
public
class
VmsHangerStatusInfoServiceImpl
extends
ServiceImpl
<
VmsHangerStatusInfoMapper
,
VmsHangerStatusInfo
>
implements
VmsHangerStatusInfoService
{
@Autowired
private
RedisDataModel
redisDataModel
;
@Value
(
"${order.latestOrderKeyPrefix:harbor:command:status}"
)
private
String
latestOrderKeyPrefix
;
@Value
(
"${harbor.vehicle.confirm_status_prefix}"
)
private
String
harborVehicleConfirmStatusPrefix
;
@Value
(
"${harbor.crane.realTimeInfoKeyPrefix}"
)
private
String
craneRealTimeInfoKeyPrefix
;
@Override
public
IPage
<
VmsHangerStatusInfo
>
queryPage
(
int
current
,
int
size
,
VmsHangerStatusInfo
vmsHangerStatusInfo
)
{
IPage
<
VmsHangerStatusInfo
>
page
=
new
Page
<>(
current
,
size
);
QueryWrapper
<
VmsHangerStatusInfo
>
wrapper
=
new
QueryWrapper
<>();
return
this
.
page
(
page
,
wrapper
);
}
/**
* 查询车辆装卸箱时吊具状态信息
*/
@Override
public
SSIResponse
getHangerStatusByVin
(
String
vin
)
{
String
orderKey
=
String
.
format
(
"%s:%s"
,
latestOrderKeyPrefix
,
vin
);
Map
<
String
,
Object
>
map
=
redisDataModel
.
getJson2Map
(
orderKey
);
if
(
map
!=
null
){
int
status
=
(
int
)
map
.
get
(
"status"
);
if
(
VmsTosOrderStatusEnum
.
isLoadUnloadStatus
(
status
)){
String
portCode
=
(
String
)
map
.
get
(
"portCode"
);
if
(
portCode
==
null
){
return
SSIResponse
.
no
(
"未查询到吊具状态信息"
);
}
Map
<
String
,
Object
>
hangerStatusMap
=
redisDataModel
.
getJson2Map
(
String
.
format
(
"%s:%s"
,
craneRealTimeInfoKeyPrefix
,
portCode
));
hangerStatusMap
.
put
(
"orderStatus"
,
status
);
String
confirmStatusKey
=
String
.
format
(
"%s:%s"
,
harborVehicleConfirmStatusPrefix
,
vin
);
Map
<
String
,
Object
>
confirmStatusMap
=
redisDataModel
.
getJson2Map
(
confirmStatusKey
);
hangerStatusMap
.
putAll
(
confirmStatusMap
);
return
SSIResponse
.
ok
(
hangerStatusMap
);
}
else
{
return
SSIResponse
.
no
(
"等待车辆停稳锁死"
);
}
}
return
SSIResponse
.
no
(
"未查询到车辆任务"
);
}
}
ivccs-vmm-backservice/src/main/java/com/ssi/service/impl/VmsIndividuationConfigServiceImpl.java
0 → 100644
View file @
07602a7b
package
com.ssi.service.impl
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.ssi.entity.VmsIndividuationConfig
;
import
com.ssi.entity.VmsTerminalVersion
;
import
com.ssi.response.SSIPage
;
import
com.ssi.service.VmsIndividuationConfigService
;
import
com.ssi.mapper.VmsIndividuationConfigMapper
;
import
com.ssi.utils.QueryUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.stereotype.Service
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Map
;
/**
*
*/
@Service
public
class
VmsIndividuationConfigServiceImpl
extends
ServiceImpl
<
VmsIndividuationConfigMapper
,
VmsIndividuationConfig
>
implements
VmsIndividuationConfigService
{
@Override
public
SSIPage
queryPage
(
VmsIndividuationConfig
params
)
{
IPage
<
VmsIndividuationConfig
>
page
=
this
.
page
(
new
Page
<>(
params
.
getPageIndex
(),
params
.
getPageSize
()),
new
LambdaQueryWrapper
<
VmsIndividuationConfig
>()
.
like
(
StringUtils
.
isNotBlank
(
params
.
getConfigKey
()),
VmsIndividuationConfig:
:
getConfigKey
,
params
.
getConfigKey
())
.
eq
(
VmsIndividuationConfig:
:
getStatus
,
1
)
.
orderByDesc
(
VmsIndividuationConfig:
:
getCreateTime
)
);
return
new
SSIPage
(
page
);
}
@Override
public
List
<
VmsIndividuationConfig
>
listByParent
(
String
name
)
{
return
this
.
baseMapper
.
listByParent
(
name
);
}
}
ivccs-vmm-backservice/src/main/java/com/ssi/service/impl/VmsKpiAnalysisServiceImpl.java
0 → 100644
View file @
07602a7b
package
com.ssi.service.impl
;
import
cn.afterturn.easypoi.excel.ExcelExportUtil
;
import
com.alibaba.fastjson.JSONObject
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.ssi.entity.VmsKpiAnalysis
;
import
com.ssi.entity.VmsVehicle
;
import
com.ssi.entity.vo.KpiCostTimeVo
;
import
com.ssi.mapper.VmsKpiAnalysisMapper
;
import
com.ssi.response.SSIResponse
;
import
com.ssi.service.VmsKpiAnalysisService
;
import
com.ssi.service.VmsVehicleService
;
import
com.ssi.utils.DateUtils
;
import
com.ssi.utils.PoiUtils
;
import
io.swagger.models.auth.In
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.apache.commons.lang.StringUtils
;
import
org.apache.poi.ss.usermodel.Sheet
;
import
org.apache.poi.ss.usermodel.Workbook
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
javax.servlet.http.HttpServletResponse
;
import
java.math.BigDecimal
;
import
java.math.RoundingMode
;
import
java.text.DecimalFormat
;
import
java.time.LocalDate
;
import
java.time.LocalDateTime
;
import
java.time.LocalTime
;
import
java.time.ZoneOffset
;
import
java.time.format.DateTimeFormatter
;
import
java.time.temporal.ChronoUnit
;
import
java.util.*
;
import
java.util.function.Function
;
import
java.util.stream.Collectors
;
/**
* @author Admin
* @description 针对表【vms_kpi_analysis】的数据库操作Service实现
* @createDate 2023-02-28 14:17:30
*/
@Slf4j
@Service
public
class
VmsKpiAnalysisServiceImpl
extends
ServiceImpl
<
VmsKpiAnalysisMapper
,
VmsKpiAnalysis
>
implements
VmsKpiAnalysisService
{
@Autowired
private
VmsVehicleService
vmsVehicleService
;
@Override
public
List
<
JSONObject
>
staticsWorkTime
(
KpiCostTimeVo
kpiCostTimeVo
)
{
return
this
.
baseMapper
.
staticsWorkTime
(
kpiCostTimeVo
);
}
@Override
public
List
<
JSONObject
>
taskAnalysis
(
KpiCostTimeVo
kpiCostTimeVo
)
{
kpiCostTimeVo
.
setVehicleTaskLabels
(
Arrays
.
asList
(
TaskType
.
LOAD_TASK
.
code
,
TaskType
.
UNLOAD_TASK
.
code
));
List
<
VmsKpiAnalysis
>
vmsKpiAnalyses
=
this
.
baseMapper
.
taskAnalysis
(
kpiCostTimeVo
);
if
(
CollectionUtils
.
isEmpty
(
vmsKpiAnalyses
)){
return
Collections
.
emptyList
();
}
// List<VmsKpiAnalysis> mergedList = componentWholeOrder(vmsKpiAnalyses);
//计算统计数据
return
kaiCalculate
(
vmsKpiAnalyses
);
}
@Override
public
VmsKpiAnalysis
staticsSpeciParam
(
KpiCostTimeVo
qryKpi
)
{
return
this
.
baseMapper
.
staticsSpeciParam
(
qryKpi
);
}
@Override
public
JSONObject
taskIndexAnalysis
(
KpiCostTimeVo
qryKpi
)
{
qryKpi
.
setVehicleTaskLabels
(
Arrays
.
asList
(
TaskType
.
LOAD_TASK
.
code
,
TaskType
.
UNLOAD_TASK
.
code
,
TaskType
.
COMPETE_TASK
.
code
));
List
<
VmsKpiAnalysis
>
vmsKpiAnalyses
=
this
.
baseMapper
.
taskAnalysis
(
qryKpi
);
JSONObject
result
=
new
JSONObject
();
if
(
CollectionUtils
.
isEmpty
(
vmsKpiAnalyses
)){
return
result
;
}
List
<
VmsKpiAnalysis
>
mergedList
=
componentWholeOrder
(
vmsKpiAnalyses
);
result
.
put
(
"totalTask"
,
mergedList
.
size
());
Map
<
Integer
,
List
<
VmsKpiAnalysis
>>
lableCollect
=
mergedList
.
stream
().
collect
(
Collectors
.
groupingBy
(
VmsKpiAnalysis:
:
getVehicleTaskLabel
,
Collectors
.
toList
()));
result
.
put
(
"loadTask"
,
CollectionUtils
.
isNotEmpty
(
lableCollect
.
get
(
TaskType
.
LOAD_TASK
.
code
))?
lableCollect
.
get
(
TaskType
.
LOAD_TASK
.
code
).
size
():
0
);
result
.
put
(
"loadNum"
,
CollectionUtils
.
isNotEmpty
(
lableCollect
.
get
(
TaskType
.
LOAD_TASK
.
code
))?
lableCollect
.
get
(
TaskType
.
LOAD_TASK
.
code
).
size
():
0
);
result
.
put
(
"loadStandNum"
,
CollectionUtils
.
isNotEmpty
(
lableCollect
.
get
(
TaskType
.
LOAD_TASK
.
code
))?
lableCollect
.
get
(
TaskType
.
LOAD_TASK
.
code
).
stream
().
mapToDouble
(
VmsKpiAnalysis:
:
getStandardBoxNum
).
sum
():
0
);
result
.
put
(
"loadAvaTime"
,
CollectionUtils
.
isNotEmpty
(
lableCollect
.
get
(
TaskType
.
LOAD_TASK
.
code
))?
new
BigDecimal
(
lableCollect
.
get
(
TaskType
.
LOAD_TASK
.
code
).
stream
().
mapToDouble
(
VmsKpiAnalysis:
:
getWorkTime
).
sum
()/
lableCollect
.
get
(
TaskType
.
LOAD_TASK
.
code
).
size
()).
setScale
(
2
,
RoundingMode
.
HALF_UP
):
0
);
result
.
put
(
"unloadTask"
,
CollectionUtils
.
isNotEmpty
(
lableCollect
.
get
(
TaskType
.
UNLOAD_TASK
.
code
))?
lableCollect
.
get
(
TaskType
.
UNLOAD_TASK
.
code
).
size
():
0
);
result
.
put
(
"unloadNum"
,
CollectionUtils
.
isNotEmpty
(
lableCollect
.
get
(
TaskType
.
UNLOAD_TASK
.
code
))?
lableCollect
.
get
(
TaskType
.
UNLOAD_TASK
.
code
).
size
():
0
);
result
.
put
(
"unloadStandNum"
,
CollectionUtils
.
isNotEmpty
(
lableCollect
.
get
(
TaskType
.
UNLOAD_TASK
.
code
))?
lableCollect
.
get
(
TaskType
.
UNLOAD_TASK
.
code
).
stream
().
mapToDouble
(
VmsKpiAnalysis:
:
getStandardBoxNum
).
sum
():
0
);
result
.
put
(
"unloadAvaTime"
,
CollectionUtils
.
isNotEmpty
(
lableCollect
.
get
(
TaskType
.
UNLOAD_TASK
.
code
))?
new
BigDecimal
(
lableCollect
.
get
(
TaskType
.
UNLOAD_TASK
.
code
).
stream
().
mapToDouble
(
VmsKpiAnalysis:
:
getWorkTime
).
sum
()/
lableCollect
.
get
(
TaskType
.
UNLOAD_TASK
.
code
).
size
()).
setScale
(
2
,
RoundingMode
.
HALF_UP
):
0
);
result
.
put
(
"competeTask"
,
CollectionUtils
.
isNotEmpty
(
lableCollect
.
get
(
TaskType
.
COMPETE_TASK
.
code
))?
lableCollect
.
get
(
TaskType
.
COMPETE_TASK
.
code
).
size
():
0
);
result
.
put
(
"competeNum"
,
CollectionUtils
.
isNotEmpty
(
lableCollect
.
get
(
TaskType
.
COMPETE_TASK
.
code
))?
lableCollect
.
get
(
TaskType
.
COMPETE_TASK
.
code
).
size
():
0
);
result
.
put
(
"competeStandNum"
,
CollectionUtils
.
isNotEmpty
(
lableCollect
.
get
(
TaskType
.
COMPETE_TASK
.
code
))?
lableCollect
.
get
(
TaskType
.
COMPETE_TASK
.
code
).
stream
().
mapToDouble
(
VmsKpiAnalysis:
:
getStandardBoxNum
).
sum
():
0
);
result
.
put
(
"competeAvaTime"
,
CollectionUtils
.
isNotEmpty
(
lableCollect
.
get
(
TaskType
.
COMPETE_TASK
.
code
))?
new
BigDecimal
(
lableCollect
.
get
(
TaskType
.
COMPETE_TASK
.
code
).
stream
().
mapToDouble
(
VmsKpiAnalysis:
:
getWorkTime
).
sum
()/
lableCollect
.
get
(
TaskType
.
COMPETE_TASK
.
code
).
size
()).
setScale
(
2
,
RoundingMode
.
HALF_UP
):
0
);
return
result
;
}
@Override
public
SSIResponse
getTaskTrend
(
Integer
timeType
,
Integer
groupType
)
{
assert
timeType
!=
null
:
"时间不能为空"
;
assert
groupType
!=
null
:
"分组类型不能为空"
;
int
deltDate
=
timeType
==
2
?
7
:
timeType
==
3
?
30
:
1
;
LocalDateTime
startTime
=
LocalDateTime
.
of
(
LocalDateTime
.
now
().
minus
(
deltDate
,
ChronoUnit
.
DAYS
).
toLocalDate
(),
LocalTime
.
MIN
);
LocalDateTime
endTime
=
LocalDateTime
.
of
(
LocalDateTime
.
now
().
minus
(
1
,
ChronoUnit
.
DAYS
).
toLocalDate
(),
LocalTime
.
MAX
);
List
<
VmsKpiAnalysis
>
taskTrends
=
this
.
baseMapper
.
getTaskTrend
(
startTime
.
toInstant
(
ZoneOffset
.
of
(
"+8"
)).
toEpochMilli
(),
endTime
.
toInstant
(
ZoneOffset
.
of
(
"+8"
)).
toEpochMilli
());
List
<
VmsKpiAnalysis
>
vmsKpiAnalyses
=
componentWholeOrder
(
taskTrends
);
//分组
Map
<
String
,
List
<
VmsKpiAnalysis
>>
groupMap
=
vmsKpiAnalyses
.
stream
().
collect
(
Collectors
.
groupingBy
(
vmsKpiAnalysis
->
{
if
(
groupType
==
1
)
{
String
portCode
=
vmsKpiAnalysis
.
getPortCode
();
return
StringUtils
.
isNotBlank
(
portCode
)?
portCode:
"other"
;
}
else
if
(
groupType
==
2
)
{
String
voyageNo
=
vmsKpiAnalysis
.
getVoyageNo
();
return
StringUtils
.
isNotBlank
(
voyageNo
)?
voyageNo:
"other"
;
}
else
if
(
groupType
==
3
)
{
Long
collectTime
=
vmsKpiAnalysis
.
getCollectTime
();
Date
date
=
new
Date
(
collectTime
);
if
(
timeType
==
1
)
{
return
DateUtils
.
format
(
date
,
"HH"
);
}
return
DateUtils
.
format
(
date
,
DateUtils
.
DATE_PATTERN
);
}
VmsVehicle
one
=
vmsVehicleService
.
lambdaQuery
().
eq
(
VmsVehicle:
:
getVin
,
vmsKpiAnalysis
.
getVin
()).
one
();
return
Objects
.
isNull
(
one
)?
vmsKpiAnalysis
.
getVin
():
one
.
getVehicleNum
();
},
Collectors
.
toList
()));
List
<
JSONObject
>
jsonObjects
=
calTaskTrend
(
groupMap
);
if
(
groupType
==
3
){
//时间填充坐标轴
fillTimeLine
(
startTime
,
endTime
,
jsonObjects
);
}
jsonObjects
.
sort
(
Comparator
.
comparing
(
a
->
a
.
getString
(
"xAis"
)));
return
SSIResponse
.
ok
(
jsonObjects
);
}
@Override
public
void
exportExcel
(
KpiCostTimeVo
kpiCostTimeVo
,
HttpServletResponse
response
)
{
List
<
VmsKpiAnalysis
>
vmsKpiAnalyses
=
this
.
baseMapper
.
taskAnalysis
(
kpiCostTimeVo
);
String
fileName
=
"KPI数据详情"
+
DateUtils
.
format
(
new
Date
(),
2
)
+
".xls"
;
PoiUtils
.
exportExcel
(
vmsKpiAnalyses
,
null
,
"orderList"
,
VmsKpiAnalysis
.
class
,
fileName
,
true
,
response
);
}
@Override
public
List
<
String
>
getVoyageNo
()
{
return
this
.
baseMapper
.
getVoyageNo
();
}
private
void
fillTimeLine
(
LocalDateTime
startTime
,
LocalDateTime
endTime
,
List
<
JSONObject
>
jsonObjects
)
{
String
formatter
=
"yyyy-MM-dd"
;
if
(
startTime
.
toLocalDate
().
compareTo
(
endTime
.
toLocalDate
())==
0
){
formatter
=
"HH"
;
}
do
{
String
format
=
startTime
.
format
(
DateTimeFormatter
.
ofPattern
(
formatter
));
Boolean
xAis
=
jsonObjects
.
stream
().
filter
(
jsonObject
->
jsonObject
.
getString
(
"xAis"
).
equalsIgnoreCase
(
format
)).
findAny
().
isPresent
();
log
.
info
(
"~~{} 存在吗 {}"
,
format
,
xAis
);
if
(!
xAis
){
JSONObject
tmpObj
=
new
JSONObject
();
tmpObj
.
put
(
"xAis"
,
format
);
tmpObj
.
put
(
"loadNum"
,
0
);
tmpObj
.
put
(
"unloadNum"
,
0
);
tmpObj
.
put
(
"competeNum"
,
0
);
tmpObj
.
put
(
"loadAvaTime"
,
0
);
tmpObj
.
put
(
"unloadAvaTime"
,
0
);
tmpObj
.
put
(
"competeAvaTime"
,
0
);
jsonObjects
.
add
(
tmpObj
);
}
if
(
startTime
.
toLocalDate
().
compareTo
(
endTime
.
toLocalDate
())==
0
){
startTime
=
startTime
.
plusHours
(
1
l
);
}
else
{
startTime
=
startTime
.
plusDays
(
1
l
);
}
}
while
(
startTime
.
compareTo
(
endTime
)<
0
);
}
private
List
<
JSONObject
>
calTaskTrend
(
Map
<
String
,
List
<
VmsKpiAnalysis
>>
groupMap
)
{
List
<
JSONObject
>
jsonObjects
=
new
ArrayList
<>();
for
(
Map
.
Entry
<
String
,
List
<
VmsKpiAnalysis
>>
entry:
groupMap
.
entrySet
()){
JSONObject
jsonObject
=
new
JSONObject
();
jsonObject
.
put
(
"xAis"
,
entry
.
getKey
());
List
<
VmsKpiAnalysis
>
mergedList
=
entry
.
getValue
();
Map
<
Integer
,
List
<
VmsKpiAnalysis
>>
lableCollect
=
mergedList
.
stream
().
collect
(
Collectors
.
groupingBy
(
VmsKpiAnalysis:
:
getVehicleTaskLabel
,
Collectors
.
toList
()));
jsonObject
.
put
(
"loadNum"
,
CollectionUtils
.
isNotEmpty
(
lableCollect
.
get
(
TaskType
.
LOAD_TASK
.
code
))?
lableCollect
.
get
(
TaskType
.
LOAD_TASK
.
code
).
size
():
0
);
jsonObject
.
put
(
"unloadNum"
,
CollectionUtils
.
isNotEmpty
(
lableCollect
.
get
(
TaskType
.
UNLOAD_TASK
.
code
))?
lableCollect
.
get
(
TaskType
.
UNLOAD_TASK
.
code
).
size
():
0
);
jsonObject
.
put
(
"competeNum"
,
CollectionUtils
.
isNotEmpty
(
lableCollect
.
get
(
TaskType
.
COMPETE_TASK
.
code
))?
lableCollect
.
get
(
TaskType
.
COMPETE_TASK
.
code
).
size
():
0
);
jsonObject
.
put
(
"loadAvaTime"
,
CollectionUtils
.
isNotEmpty
(
lableCollect
.
get
(
TaskType
.
LOAD_TASK
.
code
))?
new
BigDecimal
(
lableCollect
.
get
(
TaskType
.
LOAD_TASK
.
code
).
stream
().
mapToDouble
(
VmsKpiAnalysis:
:
getWorkTime
).
sum
()/
lableCollect
.
get
(
TaskType
.
LOAD_TASK
.
code
).
size
()).
setScale
(
2
,
RoundingMode
.
HALF_UP
):
0
);
jsonObject
.
put
(
"unloadAvaTime"
,
CollectionUtils
.
isNotEmpty
(
lableCollect
.
get
(
TaskType
.
UNLOAD_TASK
.
code
))?
new
BigDecimal
(
lableCollect
.
get
(
TaskType
.
UNLOAD_TASK
.
code
).
stream
().
mapToDouble
(
VmsKpiAnalysis:
:
getWorkTime
).
sum
()/
lableCollect
.
get
(
TaskType
.
UNLOAD_TASK
.
code
).
size
()).
setScale
(
2
,
RoundingMode
.
HALF_UP
):
0
);
jsonObject
.
put
(
"competeAvaTime"
,
CollectionUtils
.
isNotEmpty
(
lableCollect
.
get
(
TaskType
.
COMPETE_TASK
.
code
))?
new
BigDecimal
(
lableCollect
.
get
(
TaskType
.
COMPETE_TASK
.
code
).
stream
().
mapToDouble
(
VmsKpiAnalysis:
:
getWorkTime
).
sum
()/
lableCollect
.
get
(
TaskType
.
COMPETE_TASK
.
code
).
size
()).
setScale
(
2
,
RoundingMode
.
HALF_UP
):
0
);
jsonObject
.
put
(
"loadStandNum"
,
CollectionUtils
.
isNotEmpty
(
lableCollect
.
get
(
TaskType
.
LOAD_TASK
.
code
))?
lableCollect
.
get
(
TaskType
.
LOAD_TASK
.
code
).
stream
().
filter
(
e
->
Objects
.
nonNull
(
e
.
getStandardBoxNum
())).
mapToDouble
(
VmsKpiAnalysis:
:
getStandardBoxNum
).
sum
():
0
);
jsonObject
.
put
(
"unloadStandNum"
,
CollectionUtils
.
isNotEmpty
(
lableCollect
.
get
(
TaskType
.
UNLOAD_TASK
.
code
))?
lableCollect
.
get
(
TaskType
.
UNLOAD_TASK
.
code
).
stream
().
filter
(
e
->
Objects
.
nonNull
(
e
.
getStandardBoxNum
())).
mapToDouble
(
VmsKpiAnalysis:
:
getStandardBoxNum
).
sum
():
0
);
jsonObject
.
put
(
"competeStandNum"
,
CollectionUtils
.
isNotEmpty
(
lableCollect
.
get
(
TaskType
.
COMPETE_TASK
.
code
))?
lableCollect
.
get
(
TaskType
.
COMPETE_TASK
.
code
).
stream
().
filter
(
e
->
Objects
.
nonNull
(
e
.
getStandardBoxNum
())).
mapToDouble
(
VmsKpiAnalysis:
:
getStandardBoxNum
).
sum
():
0
);
jsonObjects
.
add
(
jsonObject
);
}
return
jsonObjects
;
}
private
List
<
JSONObject
>
kaiCalculate
(
List
<
VmsKpiAnalysis
>
mergedList
)
{
List
<
JSONObject
>
resultList
=
new
ArrayList
<>();
if
(
CollectionUtils
.
isEmpty
(
mergedList
)){
return
resultList
;
}
Map
<
String
,
List
<
VmsKpiAnalysis
>>
vinListMap
=
mergedList
.
stream
().
collect
(
Collectors
.
groupingBy
(
VmsKpiAnalysis:
:
getVin
,
Collectors
.
toList
()));
for
(
Map
.
Entry
<
String
,
List
<
VmsKpiAnalysis
>>
entry
:
vinListMap
.
entrySet
()){
//平均收箱里程, 平均送箱里程, 单圈里程 重载率(%)空载率(%)
List
<
VmsKpiAnalysis
>
tmpList
=
entry
.
getValue
();
double
receiveMile
=
tmpList
.
stream
().
filter
(
vmsKpiAnalysis
->
vmsKpiAnalysis
.
getTaskType
()
==
TaskType
.
LOAD_TASK
.
code
).
mapToDouble
(
VmsKpiAnalysis:
:
getMileage
).
sum
();
double
senMile
=
tmpList
.
stream
().
filter
(
vmsKpiAnalysis
->
vmsKpiAnalysis
.
getTaskType
()
==
TaskType
.
UNLOAD_TASK
.
code
).
mapToDouble
(
VmsKpiAnalysis:
:
getMileage
).
sum
();
double
receiveTime
=
tmpList
.
stream
().
filter
(
vmsKpiAnalysis
->
vmsKpiAnalysis
.
getTaskType
()
==
TaskType
.
LOAD_TASK
.
code
).
mapToDouble
(
VmsKpiAnalysis:
:
getWorkTime
).
sum
();
double
senTime
=
tmpList
.
stream
().
filter
(
vmsKpiAnalysis
->
vmsKpiAnalysis
.
getTaskType
()
==
TaskType
.
UNLOAD_TASK
.
code
).
mapToDouble
(
VmsKpiAnalysis:
:
getWorkTime
).
sum
();
double
total
=
receiveMile
+
senMile
;
JSONObject
jsonObject
=
new
JSONObject
();
VmsVehicle
one
=
vmsVehicleService
.
lambdaQuery
().
eq
(
VmsVehicle:
:
getVin
,
entry
.
getKey
()).
one
();
jsonObject
.
put
(
"vin"
,
Objects
.
nonNull
(
one
)?
one
.
getVehicleNum
():
entry
.
getKey
());
jsonObject
.
put
(
"avgReciveMile"
,
new
BigDecimal
(
receiveMile
/
tmpList
.
size
()).
setScale
(
2
,
RoundingMode
.
HALF_UP
));
jsonObject
.
put
(
"avgSendMile"
,
new
BigDecimal
(
senMile
/
tmpList
.
size
()).
setScale
(
2
,
RoundingMode
.
HALF_UP
));
jsonObject
.
put
(
"singleMile"
,
new
BigDecimal
(
total
/
tmpList
.
size
()).
setScale
(
2
,
RoundingMode
.
HALF_UP
));
jsonObject
.
put
(
"loadRatio"
,
new
BigDecimal
(
receiveTime
/(
receiveTime
+
senTime
)).
setScale
(
2
,
RoundingMode
.
HALF_UP
));
jsonObject
.
put
(
"unloadRatio"
,
new
BigDecimal
(
senTime
/(
receiveTime
+
senTime
)).
setScale
(
2
,
RoundingMode
.
HALF_UP
));
resultList
.
add
(
jsonObject
);
}
return
resultList
;
}
/**
*
* @param vmsKpiAnalyses 未组装任务列表
* @return 组装好的任务列表
*/
private
List
<
VmsKpiAnalysis
>
componentWholeOrder
(
List
<
VmsKpiAnalysis
>
vmsKpiAnalyses
)
{
List
<
VmsKpiAnalysis
>
mergedList
=
new
ArrayList
<>();
Map
<
String
,
VmsKpiAnalysis
>
tmpMap
=
new
HashMap
<>();
for
(
VmsKpiAnalysis
vmsKpiAnalysis:
vmsKpiAnalyses
)
{
VmsKpiAnalysis
oldKpi
=
tmpMap
.
get
(
vmsKpiAnalysis
.
getVin
());
if
(
Objects
.
isNull
(
oldKpi
)){
tmpMap
.
put
(
vmsKpiAnalysis
.
getVin
(),
vmsKpiAnalysis
);
continue
;
}
//任务合并逻辑
int
mergeFlag
=
mergeTaskInfo
(
mergedList
,
oldKpi
,
vmsKpiAnalysis
);
if
(
mergeFlag
==
0
){
tmpMap
.
remove
(
vmsKpiAnalysis
.
getVin
());
}
//处理任务异常逻辑
if
(
mergeFlag
==
1
){
tmpMap
.
put
(
vmsKpiAnalysis
.
getVin
(),
vmsKpiAnalysis
);
}
}
//处理剩余数据
tmpMap
.
forEach
((
k
,
v
)->{
if
((
v
.
getVehicleTaskLabel
()==
TaskType
.
LOAD_TASK
.
code
&&
v
.
getPortType
()==
1
)
||(
v
.
getVehicleTaskLabel
()==
TaskType
.
UNLOAD_TASK
.
code
&&
v
.
getPortType
()==
2
)
||(
v
.
getVehicleTaskLabel
()==
TaskType
.
COMPETE_TASK
.
code
&&
v
.
getPortType
()==
2
)
){
mergedList
.
add
(
v
);
}
});
return
mergedList
;
}
/**
*
* @param mergedList
* @param oldKpi
* @param vmsKpiAnalysis
* @return 0: 完成任务链,List新增任务,移除tmpMap; 1: 任务变更,List新增任务,覆盖旧任务;2:任务周期中,无需操作
*/
private
int
mergeTaskInfo
(
List
<
VmsKpiAnalysis
>
mergedList
,
VmsKpiAnalysis
oldKpi
,
VmsKpiAnalysis
vmsKpiAnalysis
)
{
//非当前任务||旧任务为结束任务
if
(
oldKpi
.
getVehicleTaskLabel
()!=
vmsKpiAnalysis
.
getVehicleTaskLabel
()
||(
oldKpi
.
getVehicleTaskLabel
()==
TaskType
.
LOAD_TASK
.
code
&&
oldKpi
.
getPortType
()==
1
)
||(
oldKpi
.
getVehicleTaskLabel
()==
TaskType
.
UNLOAD_TASK
.
code
&&
oldKpi
.
getPortType
()==
2
)
||(
oldKpi
.
getVehicleTaskLabel
()==
TaskType
.
COMPETE_TASK
.
code
&&
oldKpi
.
getPortType
()==
2
)
){
mergedList
.
add
(
oldKpi
);
return
1
;
}
//当前任务||新任务为起始任务, 多个起始任务统计为一个任务,
oldKpi
.
setMileage
(
oldKpi
.
getMileage
()+
vmsKpiAnalysis
.
getMileage
());
oldKpi
.
setEnergyConsumption
(
oldKpi
.
getEnergyConsumption
()+
vmsKpiAnalysis
.
getEnergyConsumption
());
oldKpi
.
setWorkTime
(
oldKpi
.
getWorkTime
()+
vmsKpiAnalysis
.
getWorkTime
());
oldKpi
.
setVehicleTaskLabel
(
vmsKpiAnalysis
.
getVehicleTaskLabel
());
oldKpi
.
setPortType
(
vmsKpiAnalysis
.
getPortType
());
if
(
StringUtils
.
isNotBlank
(
vmsKpiAnalysis
.
getPortCode
())&&
vmsKpiAnalysis
.
getPortType
()==
1
)
oldKpi
.
setPortCode
(
vmsKpiAnalysis
.
getPortCode
());
if
(
StringUtils
.
isNotBlank
(
vmsKpiAnalysis
.
getVoyageNo
()))
oldKpi
.
setVoyageNo
(
vmsKpiAnalysis
.
getVoyageNo
());
//相同任务类型, 判断是否为完整任务链
if
((
oldKpi
.
getVehicleTaskLabel
()==
TaskType
.
LOAD_TASK
.
code
&&
vmsKpiAnalysis
.
getPortType
()==
1
)
||(
oldKpi
.
getVehicleTaskLabel
()==
TaskType
.
UNLOAD_TASK
.
code
&&
vmsKpiAnalysis
.
getPortType
()==
2
)
||(
oldKpi
.
getVehicleTaskLabel
()==
TaskType
.
COMPETE_TASK
.
code
&&
vmsKpiAnalysis
.
getPortType
()==
2
)
){
mergedList
.
add
(
oldKpi
);
return
0
;
}
else
{
return
2
;
}
}
enum
TaskType
{
LOAD_TASK
(
1
),
UNLOAD_TASK
(
2
),
COMPETE_TASK
(
3
);
private
Integer
code
;
TaskType
(
Integer
code
)
{
this
.
code
=
code
;
}
public
Integer
getCode
()
{
return
code
;
}
}
}
ivccs-vmm-backservice/src/main/java/com/ssi/service/impl/VmsOrdersVehicleAlterServiceImpl.java
0 → 100644
View file @
07602a7b
package
com.ssi.service.impl
;
import
com.alibaba.fastjson.JSON
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.ssi.entity.VmsTosOrders
;
import
com.ssi.model.RedisDataModel
;
import
com.ssi.response.SSIResponse
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Service
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.ssi.mapper.VmsOrdersVehicleAlterMapper
;
import
com.ssi.entity.VmsOrdersVehicleAlter
;
import
com.ssi.service.VmsOrdersVehicleAlterService
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
@Service
(
"ordersVehicleAlterService"
)
public
class
VmsOrdersVehicleAlterServiceImpl
extends
ServiceImpl
<
VmsOrdersVehicleAlterMapper
,
VmsOrdersVehicleAlter
>
implements
VmsOrdersVehicleAlterService
{
@Autowired
private
RedisDataModel
redisDataModel
;
@Value
(
"${order.latestOrderKeyPrefix:harbor:command:status}"
)
private
String
latestOrderKeyPrefix
;
/**
* 确认任务车辆
*/
@Override
public
SSIResponse
changeOrdersVehicle
(
String
taskNo
,
String
vin
)
{
int
count
=
this
.
count
(
new
LambdaQueryWrapper
<
VmsOrdersVehicleAlter
>().
eq
(
VmsOrdersVehicleAlter:
:
getTaskNo
,
taskNo
));
if
(
count
>
0
){
return
SSIResponse
.
no
(
"该任务已确认,请勿重复确认"
);
}
//获取任务原vin
String
originalVin
=
null
;
Set
<
String
>
keys
=
redisDataModel
.
keys
(
latestOrderKeyPrefix
+
"*"
);
List
<
String
>
list
=
redisDataModel
.
mget
(
keys
.
toArray
(
new
String
[
keys
.
size
()]));
if
(
CollectionUtils
.
isNotEmpty
(
keys
))
{
if
(
CollectionUtils
.
isNotEmpty
(
list
))
{
List
<
VmsTosOrders
>
res
=
list
.
stream
().
map
(
s
->
JSON
.
parseObject
(
s
,
VmsTosOrders
.
class
)).
collect
(
Collectors
.
toList
());
for
(
VmsTosOrders
vmsTosOrders
:
res
){
if
(
vmsTosOrders
.
getTaskNo
().
equals
(
taskNo
)){
originalVin
=
vmsTosOrders
.
getVin
();
}
}
}
}
VmsOrdersVehicleAlter
vmsOrdersVehicleAlter
=
new
VmsOrdersVehicleAlter
();
vmsOrdersVehicleAlter
.
setTaskNo
(
taskNo
);
vmsOrdersVehicleAlter
.
setVin
(
vin
);
vmsOrdersVehicleAlter
.
setOriginalVin
(
originalVin
);
this
.
save
(
vmsOrdersVehicleAlter
);
return
SSIResponse
.
ok
();
}
}
ivccs-vmm-backservice/src/main/java/com/ssi/service/impl/VmsPositionInfoServiceImpl.java
0 → 100644
View file @
07602a7b
package
com.ssi.service.impl
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.ssi.entity.VmsPositionInfo
;
import
com.ssi.service.VmsPositionInfoService
;
import
com.ssi.mapper.VmsPositionInfoMapper
;
import
org.springframework.stereotype.Service
;
/**
*
*/
@Service
public
class
VmsPositionInfoServiceImpl
extends
ServiceImpl
<
VmsPositionInfoMapper
,
VmsPositionInfo
>
implements
VmsPositionInfoService
{
}
ivccs-vmm-backservice/src/main/java/com/ssi/service/impl/VmsRoadDeviceServiceImpl.java
0 → 100644
View file @
07602a7b
package
com.ssi.service.impl
;
import
com.alibaba.fastjson.JSONObject
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.google.common.collect.Lists
;
import
com.ssi.constant.URL
;
import
com.ssi.entity.vo.VmsRoadDeviceVo
;
import
com.ssi.mapper.VmsRoadDeviceMapper
;
import
com.ssi.model.RedisDataModel
;
import
com.ssi.response.SSIPage
;
import
com.ssi.utils.RestTemplateUtil
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Service
;
import
java.util.Arrays
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.stream.Collectors
;
import
java.util.stream.Stream
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.ssi.utils.QueryUtils
;
import
com.ssi.entity.VmsRoadDevice
;
import
com.ssi.service.VmsRoadDeviceService
;
/**
* 路侧设备服务实现类
*/
@Service
(
"roadDeviceService"
)
public
class
VmsRoadDeviceServiceImpl
extends
ServiceImpl
<
VmsRoadDeviceMapper
,
VmsRoadDevice
>
implements
VmsRoadDeviceService
{
@Autowired
private
RedisDataModel
redisDataModel
;
@Value
(
"${road-device.video-platform-url}"
)
private
String
videoPlatformUrl
;
@Value
(
"${road-device.need-get-video}"
)
private
boolean
needGetVideo
;
@Value
(
"${harbor.v2x.rsm}"
)
private
String
rsmPrefix
;
@Value
(
"${BridgeCrane-url}"
)
private
String
bcUrl
;
// 桥吊 url
/**
* 路侧设备分页数据
* @param params
* @return
*/
@Override
public
SSIPage
queryPage
(
Map
<
String
,
Object
>
params
)
{
String
deviceNum
=
(
String
)
params
.
get
(
"deviceNum"
);
String
deviceType
=
(
String
)
params
.
get
(
"deviceType"
);
Integer
onlineStatus
=
(
Integer
)
params
.
get
(
"onlineStatus"
);
Integer
workStatus
=
(
Integer
)
params
.
get
(
"workStatus"
);
IPage
<
VmsRoadDevice
>
page
=
this
.
page
(
new
QueryUtils
<
VmsRoadDevice
>().
getPage
(
params
),
new
LambdaQueryWrapper
<
VmsRoadDevice
>().
like
(
StringUtils
.
isNotBlank
(
deviceNum
),
VmsRoadDevice:
:
getDeviceNum
,
deviceNum
)
.
eq
(
StringUtils
.
isNotBlank
(
deviceType
),
VmsRoadDevice:
:
getDeviceType
,
deviceType
)
.
eq
(
onlineStatus
!=
null
,
VmsRoadDevice:
:
getOnlineStatus
,
onlineStatus
)
.
eq
(
workStatus
!=
null
,
VmsRoadDevice:
:
getWorkStatus
,
workStatus
)
);
if
(
needGetVideo
){
page
.
getRecords
().
parallelStream
().
forEach
(
vmsRoadDevice
->
{
getVideoPlayUrl
(
vmsRoadDevice
);
});
}
page
.
getRecords
().
parallelStream
().
forEach
(
vmsRoadDevice
->
{
if
(
StringUtils
.
startsWith
(
vmsRoadDevice
.
getType
(),
"C"
)){
Map
m
=
getBridgeCrane
(
StringUtils
.
substring
(
vmsRoadDevice
.
getType
(),
1
,
4
));
vmsRoadDevice
.
setLat
(
Double
.
valueOf
(
m
.
get
(
"latitude"
)+
""
));
vmsRoadDevice
.
setLon
(
Double
.
valueOf
(
m
.
get
(
"longitude"
)+
""
));
}
});
return
new
SSIPage
(
page
);
}
private
Map
getBridgeCrane
(
String
number
){
JSONObject
jsonObject
=
new
JSONObject
();
jsonObject
.
put
(
"craneNum"
,
number
);
jsonObject
.
put
(
"laneNum"
,
4
);
jsonObject
.
put
(
"containerSize"
,
1
);
jsonObject
.
put
(
"containerPosition"
,
2
);
String
result
=
""
;
try
{
result
=
RestTemplateUtil
.
post
(
bcUrl
,
jsonObject
.
toString
(),
null
);
}
catch
(
Exception
e
)
{
result
=
null
;
}
if
(
result
!=
null
){
Map
m
=
JSONObject
.
parseObject
(
result
,
Map
.
class
);
return
m
;
}
return
new
HashMap
<>();
}
private
void
getVideoPlayUrl
(
VmsRoadDevice
vmsRoadDevice
)
{
vmsRoadDevice
.
setVideoOnline
(
false
);
List
<
String
>
playVideoAddressList
=
Lists
.
newArrayList
();
try
{
String
videoAddress
=
vmsRoadDevice
.
getVideoAddress
();
if
(
StringUtils
.
isNotBlank
(
videoAddress
)){
List
<
String
>
videoAddressList
=
Arrays
.
asList
(
videoAddress
.
split
(
","
));
videoAddressList
.
stream
().
forEach
(
curAddr
->
{
String
playVideoAddress
=
getPlayVideoAddress
(
curAddr
);
if
(
StringUtils
.
isNotBlank
(
playVideoAddress
)){
playVideoAddressList
.
add
(
playVideoAddress
);
}
});
}
if
(!
playVideoAddressList
.
isEmpty
()){
vmsRoadDevice
.
setVideoOnline
(
true
);
vmsRoadDevice
.
setPlayVideoAddress
(
playVideoAddressList
);
}
}
catch
(
Exception
e
)
{
log
.
error
(
"路测设备请求视频地址接口失败:vmsRoadDevice:"
+
JSONObject
.
toJSONString
(
vmsRoadDevice
));
}
}
private
String
getPlayVideoAddress
(
String
videoAddress
)
{
boolean
rtspAddr
=
videoAddress
.
startsWith
(
"rtsp:"
);
if
(
rtspAddr
){
String
checkResult
=
RestTemplateUtil
.
get
(
String
.
format
(
"%s/%s%s"
,
videoPlatformUrl
,
URL
.
ROAD_DEVICE_CHECKONLINE
,
videoAddress
),
null
);
JSONObject
checkResultJson
=
JSONObject
.
parseObject
(
checkResult
);
if
(
0
==
checkResultJson
.
getInteger
(
"code"
)){
Boolean
online
=
checkResultJson
.
getJSONObject
(
"data"
).
getBoolean
(
"online"
);
if
(
online
){
String
urlResult
=
RestTemplateUtil
.
get
(
String
.
format
(
"%s/%s%s"
,
videoPlatformUrl
,
URL
.
ROAD_DEVICE_RTSPSTART
,
videoAddress
),
null
);
JSONObject
urlResultJson
=
JSONObject
.
parseObject
(
urlResult
);
if
(
0
==
urlResultJson
.
getInteger
(
"code"
)
||
201
==
urlResultJson
.
getInteger
(
"code"
)){
return
urlResultJson
.
getJSONObject
(
"data"
).
toJSONString
();
}
}
}
}
boolean
rtmpAddr
=
videoAddress
.
startsWith
(
"rtmp:"
);
if
(
rtmpAddr
){
String
checkResult
=
RestTemplateUtil
.
get
(
String
.
format
(
"%s/%s%s"
,
videoPlatformUrl
,
URL
.
RTMP_CHECKONLINE
,
videoAddress
),
null
);
JSONObject
checkResultJson
=
JSONObject
.
parseObject
(
checkResult
);
if
(
0
==
checkResultJson
.
getInteger
(
"code"
)){
Boolean
online
=
checkResultJson
.
getJSONObject
(
"data"
).
getBoolean
(
"online"
);
if
(
online
){
String
urlResult
=
RestTemplateUtil
.
get
(
String
.
format
(
"%s/%s%s"
,
videoPlatformUrl
,
URL
.
RTMP_PLAY
,
videoAddress
),
null
);
JSONObject
urlResultJson
=
JSONObject
.
parseObject
(
urlResult
);
if
(
0
==
urlResultJson
.
getInteger
(
"code"
)
||
201
==
urlResultJson
.
getInteger
(
"code"
)){
return
urlResultJson
.
getJSONObject
(
"data"
).
toJSONString
();
}
}
}
}
return
null
;
}
/**
* 获取视频播放地址
* @return
*/
@Override
public
List
<
VmsRoadDeviceVo
>
videoPlayUrlList
(){
List
<
VmsRoadDevice
>
list
=
this
.
list
();
List
<
VmsRoadDeviceVo
>
collect
=
list
.
stream
().
flatMap
(
vmsRoadDevice
->
{
getVideoPlayUrl
(
vmsRoadDevice
);
List
<
String
>
playVideoAddress
=
vmsRoadDevice
.
getPlayVideoAddress
();
if
(
playVideoAddress
!=
null
){
return
playVideoAddress
.
stream
().
map
(
url
->
{
VmsRoadDeviceVo
vmsRoadDeviceVo
=
new
VmsRoadDeviceVo
();
vmsRoadDeviceVo
.
setDeviceName
(
vmsRoadDevice
.
getDeviceName
());
vmsRoadDeviceVo
.
setUrl
(
url
);
return
vmsRoadDeviceVo
;
});
}
return
Stream
.
empty
();
}).
collect
(
Collectors
.
toList
());
return
collect
;
}
/**
* 路测安全消息信息
*/
@Override
public
Map
getRsmInfo
(
Long
id
)
{
Map
<
String
,
Object
>
map
=
redisDataModel
.
getJson2Map
(
rsmPrefix
+
":"
+
id
);
return
map
;
}
}
ivccs-vmm-backservice/src/main/java/com/ssi/service/impl/VmsShipsDrawingServiceImpl.java
0 → 100644
View file @
07602a7b
package
com.ssi.service.impl
;
import
com.alibaba.fastjson.JSONObject
;
import
com.baomidou.dynamic.datasource.annotation.DS
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.ssi.entity.*
;
import
com.ssi.entity.vo.CargoShipConfigDto
;
import
com.ssi.mapper.VmsShipsDrawingMapper
;
import
com.ssi.response.SSIPage
;
import
com.ssi.response.SSIResponse
;
import
com.ssi.service.CargoShipConfigInfoService
;
import
com.ssi.service.VmsShipsDrawingService
;
import
com.ssi.utils.AuthorizationUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
java.util.*
;
import
java.util.stream.Collectors
;
/**
* 船模图
*/
@Service
(
"shipsDrawingService"
)
@DS
(
"oracle"
)
public
class
VmsShipsDrawingServiceImpl
extends
ServiceImpl
<
VmsShipsDrawingMapper
,
VmsShipsDrawing
>
implements
VmsShipsDrawingService
{
@Autowired
private
CargoShipConfigInfoService
cargoShipConfigInfoService
;
@Override
public
VmsShipsDrawing
getVmsShipsDrawing
(
Map
<
String
,
Object
>
params
)
{
//参数解析
String
shipCod
=
String
.
valueOf
(
params
.
get
(
"shipCod"
));
String
voyageNo
=
String
.
valueOf
(
params
.
get
(
"voyageNo"
));
String
workStatus
=
String
.
valueOf
(
params
.
get
(
"workStatus"
));
String
[]
bayNo
=
parseBayId
(
String
.
valueOf
(
params
.
get
(
"bayNo"
)));
Map
<
String
,
VmsShipNcl
>
shipBayNcl
=
new
HashMap
<>(
0
);
if
(
"1"
.
equals
(
workStatus
)){
shipBayNcl
=
getShipBayNcl
(
voyageNo
,
bayNo
[
0
]);
if
(!
bayNo
[
0
].
equals
(
bayNo
[
1
])){
shipBayNcl
.
putAll
(
getShipBayNcl
(
voyageNo
,
bayNo
[
1
]));
}
}
VmsShipsDrawing
shipDraw
=
new
VmsShipsDrawing
();
searchShipUDrawByBayNo
(
shipDraw
,
shipCod
,
bayNo
,
shipBayNcl
);
searchShipDDrawByBayNo
(
shipDraw
,
shipCod
,
bayNo
,
shipBayNcl
);
return
shipDraw
;
}
private
Map
<
String
,
VmsShipNcl
>
getShipBayNcl
(
String
voyageNo
,
String
shortBayNo
){
//贝位处于工作状态
List
<
VmsShipNcl
>
vmsShipNcls
=
this
.
baseMapper
.
queryShipNclByShortBayNo
(
voyageNo
,
shortBayNo
);
Map
<
String
,
VmsShipNcl
>
bayNclMap
;
if
(
vmsShipNcls
!=
null
){
int
size
=
vmsShipNcls
.
size
();
bayNclMap
=
new
HashMap
<>(
size
);
VmsShipNcl
vmsShipNcl
;
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
vmsShipNcl
=
vmsShipNcls
.
get
(
i
);
//强制上船状态解析
if
(
vmsShipNcl
.
getAllowFlag
()
!=
null
){
if
(
"Y"
.
equalsIgnoreCase
(
vmsShipNcl
.
getAllowFlag
())){
//强制上船
vmsShipNcl
.
setCommStatus
(
"7"
);
}
else
if
(
"N"
.
equalsIgnoreCase
(
vmsShipNcl
.
getAllowFlag
())){
//禁止上船
vmsShipNcl
.
setCommStatus
(
"8"
);
}
}
bayNclMap
.
put
(
vmsShipNcl
.
getBayNo
(),
vmsShipNcl
);
}
}
else
{
bayNclMap
=
new
HashMap
<>(
0
);
}
return
bayNclMap
;
}
public
void
searchShipUDrawByBayNo
(
VmsShipsDrawing
shipDraw
,
String
shipCod
,
String
[]
bayNo
,
Map
<
String
,
VmsShipNcl
>
shipBayNcl
){
List
<
VmsShipsDrawing
>
layNoU
=
this
.
baseMapper
.
queryShipDrawBylayNo
(
shipCod
,
"U"
,
bayNo
[
0
]);
if
(
layNoU
==
null
){
return
;}
shipDraw
.
setU
(
layNoU
);
List
<
String
>
layNolist
=
new
ArrayList
<>();
int
maxRow
=
0
;
for
(
VmsShipsDrawing
layNo
:
layNoU
)
{
// 添加列编号
layNolist
.
add
(
layNo
.
getLayNo
());
List
<
VmsShipsDrawing
>
rowNoList
=
this
.
baseMapper
.
queryShipDrawByRowNo
(
shipCod
,
"U"
,
bayNo
[
0
],
layNo
.
getLayNo
());
if
(
rowNoList
==
null
){
continue
;
}
int
size
=
rowNoList
.
size
();
if
(
size
>
maxRow
){
maxRow
=
size
;
}
layNo
.
setU
(
rowNoList
);
// 根据船号 U舱体,贝号,层号 获取 箱体的信息
for
(
VmsShipsDrawing
row
:
rowNoList
)
{
VmsShipNcl
vmsShipNcl
=
shipBayNcl
.
get
(
String
.
format
(
"%s%s%s"
,
bayNo
[
0
],
row
.
getRowNo
(),
layNo
.
getLayNo
()));
if
(
vmsShipNcl
==
null
){
vmsShipNcl
=
shipBayNcl
.
get
(
String
.
format
(
"%s%s%s"
,
bayNo
[
1
],
row
.
getRowNo
(),
layNo
.
getLayNo
()));
}
if
(
vmsShipNcl
!=
null
){
List
<
VmsShipNcl
>
tempnclList1
=
row
.
getShipNcl
();
if
(
tempnclList1
==
null
){
tempnclList1
=
new
ArrayList
<>();
row
.
setShipNcl
(
tempnclList1
);
}
tempnclList1
.
add
(
vmsShipNcl
);
row
.
setWorkStatus
(
1
);
}
}
}
shipDraw
.
setUlayNoList
(
layNolist
);
shipDraw
.
setUmaxRow
(
maxRow
);
}
public
void
searchShipDDrawByBayNo
(
VmsShipsDrawing
shipDraw
,
String
shipCod
,
String
[]
bayNo
,
Map
<
String
,
VmsShipNcl
>
shipBayNcl
){
List
<
VmsShipsDrawing
>
layNoD
=
this
.
baseMapper
.
queryShipDrawBylayNo
(
shipCod
,
"D"
,
bayNo
[
0
]);
if
(
layNoD
==
null
){
return
;}
shipDraw
.
setD
(
layNoD
);
List
<
String
>
layNolist
=
new
ArrayList
<>();
int
maxRow
=
0
;
for
(
VmsShipsDrawing
layNo
:
layNoD
)
{
// 添加列编号
layNolist
.
add
(
layNo
.
getLayNo
());
List
<
VmsShipsDrawing
>
rowNoList
=
this
.
baseMapper
.
queryShipDrawByRowNo
(
shipCod
,
"D"
,
bayNo
[
0
],
layNo
.
getLayNo
());
if
(
rowNoList
==
null
){
continue
;
}
int
size
=
rowNoList
.
size
();
if
(
size
>
maxRow
){
maxRow
=
size
;
}
layNo
.
setD
(
rowNoList
);
// 根据船号 U舱体,贝号,层号 获取 箱体的信息
for
(
VmsShipsDrawing
row
:
rowNoList
)
{
VmsShipNcl
vmsShipNcl
=
shipBayNcl
.
get
(
String
.
format
(
"%s%s%s"
,
bayNo
[
0
],
row
.
getRowNo
(),
layNo
.
getLayNo
()));
if
(
vmsShipNcl
==
null
){
vmsShipNcl
=
shipBayNcl
.
get
(
String
.
format
(
"%s%s%s"
,
bayNo
[
1
],
row
.
getRowNo
(),
layNo
.
getLayNo
()));
}
if
(
vmsShipNcl
!=
null
){
List
<
VmsShipNcl
>
tempnclList1
=
row
.
getShipNcl
();
if
(
tempnclList1
==
null
){
tempnclList1
=
new
ArrayList
<>();
row
.
setShipNcl
(
tempnclList1
);
}
tempnclList1
.
add
(
vmsShipNcl
);
row
.
setWorkStatus
(
1
);
}
}
}
shipDraw
.
setDlayNoList
(
layNolist
);
shipDraw
.
setDmaxRow
(
maxRow
);
}
public
VmsShipsDrawing
test
(
String
shipCod
,
String
bayNo
,
String
voyageNo
)
{
VmsShipsDrawing
shipDraw
=
new
VmsShipsDrawing
();
List
<
VmsShipsDrawing
>
shipMaplist
=
this
.
baseMapper
.
findShipMap
(
shipCod
,
bayNo
);
// 根据船号和贝号 获取所有的箱体信息
List
<
VmsShipNcl
>
shipNclList
=
this
.
baseMapper
.
findShipNcl
(
voyageNo
,
bayNo
);
// 根据船号和贝号 获取所有的箱体信息
List
<
VmsShipsDrawing
>
layNoU
=
new
ArrayList
();
List
<
VmsShipsDrawing
>
layNoD
=
new
ArrayList
();
VmsShipsDrawing
layNo
;
VmsShipsDrawing
rowNo
;
Map
<
String
,
VmsShipsDrawing
>
keyMap
=
new
HashMap
<
String
,
VmsShipsDrawing
>();
for
(
VmsShipsDrawing
smp:
shipMaplist
)
{
if
(
smp
.
getDeckId
().
equals
(
"D"
))
{
rowNo
=
new
VmsShipsDrawing
();
rowNo
.
setBayNo
(
smp
.
getBayNo
());
rowNo
.
setLayNo
(
smp
.
getLayNo
());
rowNo
.
setRowNo
(
smp
.
getRowNo
());
// rowNo.setShipsmp(shipsmp);
String
tempBayNo
=
bayNo
+
smp
.
getLayNo
()+
smp
.
getRowNo
();
// String temp=bayNo+ncl.getLayNo()+
List
<
VmsShipNcl
>
teml
=
new
ArrayList
<
VmsShipNcl
>();
for
(
VmsShipNcl
ncl:
shipNclList
)
{
if
(
tempBayNo
.
equals
(
ncl
.
getBayNo
()))
{
teml
.
add
(
ncl
);
rowNo
.
setShipNcl
(
teml
);
}
}
if
(!
keyMap
.
containsKey
(
smp
.
getLayNo
()))
{
layNo
=
new
VmsShipsDrawing
();
List
<
VmsShipsDrawing
>
childrenList
=
new
ArrayList
<
VmsShipsDrawing
>();
layNo
.
setLayNo
(
smp
.
getLayNo
());
layNo
.
setD
(
childrenList
);
keyMap
.
put
(
smp
.
getLayNo
(),
layNo
);
// if() {
//
// }
}
keyMap
.
get
(
smp
.
getLayNo
()).
getD
().
add
(
rowNo
);
// layNoU.add(sd);
// shipDraw.setBayNo(bayNo);
}
}
// VmsShipsDrawing tt= (VmsShipsDrawing) keyMap.values();
List
<
VmsShipsDrawing
>
cc
=
new
ArrayList
<
VmsShipsDrawing
>();
for
(
VmsShipsDrawing
tt
:
keyMap
.
values
())
{
cc
.
add
(
tt
);
}
shipDraw
.
setD
(
cc
);
// shipDraw.setD(keyMap.values());
return
shipDraw
;
}
@Override
public
SSIPage
getVmsShipsDrawingBayNo
(
Map
<
String
,
Object
>
params
)
{
// TODO Auto-generated method stub
Integer
pageSize
=
params
.
get
(
"pageSize"
)
==
null
?
10
:
(
Integer
)
params
.
get
(
"pageSize"
);
Integer
pageIndex
=
params
.
get
(
"pageIndex"
)
==
null
?
1
:
(
Integer
)
params
.
get
(
"pageIndex"
);
params
.
put
(
"shipCod"
,
(
String
)
params
.
get
(
"shipCod"
));
params
.
put
(
"bayNo"
,
(
String
)
params
.
get
(
"bayNo"
));
IPage
<
VmsShipsDrawing
>
page
=
new
Page
<>(
pageIndex
,
pageSize
);
page
=
this
.
baseMapper
.
queryShipDrawByCode
(
page
,
params
);
List
<
VmsShipsDrawing
>
records
=
page
.
getRecords
();
if
(
records
!=
null
&&
!
records
.
isEmpty
()){
//获取需作业的贝位列表, 将偶数贝 减一 调整为 奇数贝
Map
<
String
,
String
>
workBayIdMap
=
getWorkBayIdMap
(
String
.
valueOf
(
params
.
get
(
"voyageNo"
)));
//更新船图贝位状态信息
records
.
forEach
(
record
->{
String
bayNo
=
workBayIdMap
.
get
(
record
.
getBayNo
());
if
(
bayNo
!=
null
){
record
.
setWorkStatus
(
1
);
record
.
setBayNo
(
bayNo
);
}
else
{
record
.
setWorkStatus
(
0
);
}
});
}
return
new
SSIPage
(
page
);
}
private
Map
<
String
,
String
>
getWorkBayIdMap
(
String
voyageNo
){
List
<
String
>
workBays
=
this
.
baseMapper
.
queryShipWorkBay
(
voyageNo
);
Map
<
String
,
String
>
workBayIdMap
=
new
HashMap
<>();
String
bayId
;
//获取需作业的贝位列表, 将偶数贝 减一 调整为 奇数贝
for
(
String
workBay
:
workBays
)
{
try
{
int
bayNum
=
Integer
.
parseInt
(
workBay
);
if
(
bayNum
%
2
==
0
){
//偶数贝,大箱,
bayNum
=
bayNum
-
1
;
bayId
=
String
.
format
(
"%03d"
,
bayNum
);
workBayIdMap
.
put
(
bayId
,
String
.
format
(
"%s:%s"
,
bayId
,
workBay
));
}
else
if
(!
workBayIdMap
.
containsKey
(
workBay
)){
//避免顺序问题,导致奇数贝覆盖了偶数贝信息
workBayIdMap
.
put
(
workBay
,
workBay
);
}
}
catch
(
NumberFormatException
e
)
{
log
.
error
(
String
.
format
(
"贝位编号转整数失败:%s"
,
workBay
),
e
);
}
}
return
workBayIdMap
;
}
private
String
[]
parseBayId
(
String
bayIdStr
){
String
[]
bayId
=
new
String
[
2
];
if
(
StringUtils
.
isNotBlank
(
bayIdStr
)){
String
[]
bayIds
=
bayIdStr
.
split
(
":"
);
if
(
bayIds
.
length
>
1
){
bayId
=
bayIds
;
}
else
{
bayId
[
0
]
=
bayIds
[
0
];
bayId
[
1
]
=
bayIds
[
0
];
}
}
return
bayId
;
}
@Override
public
List
<
VmsCable
>
getCableList
()
{
// TODO Auto-generated method stub
List
<
VmsCable
>
cablist
=
this
.
baseMapper
.
cableList
();
// 根据船号和贝号 获取所有的箱体信息
return
cablist
;
}
@Override
public
List
<
VmsShipInfo
>
getShipInfoCoor
()
{
// TODO Auto-generated method stub
List
<
VmsShipInfo
>
cablist
=
this
.
baseMapper
.
queryshipInfoCoor
();
// 根据船号和贝号 获取所有的箱体信息
List
<
CargoShipConfigDto
>
cargoShipConfigDtos
=
cargoShipConfigInfoService
.
queryOnWorkingList
();
List
<
String
>
defaultConfigs
=
cargoShipConfigDtos
.
stream
().
map
(
CargoShipConfigDto:
:
getName
).
collect
(
Collectors
.
toList
());
cablist
.
parallelStream
().
forEach
(
shipInfoCoor
->
{
shipInfoCoor
.
setHasConfig
(
0
);
if
(
defaultConfigs
.
contains
(
shipInfoCoor
.
getShipNam
())){
shipInfoCoor
.
setHasConfig
(
1
);
}
});
return
cablist
;
}
@Override
public
SSIPage
queryPage
(
Map
<
String
,
Object
>
params
)
{
Integer
pageSize
=
params
.
get
(
"pageSize"
)
==
null
?
10
:
(
Integer
)
params
.
get
(
"pageSize"
);
Integer
pageIndex
=
params
.
get
(
"pageIndex"
)
==
null
?
1
:
(
Integer
)
params
.
get
(
"pageIndex"
);
params
.
put
(
"voyageNo"
,
(
String
)
params
.
get
(
"voyageNo"
));
params
.
put
(
"shipCod"
,
(
String
)
params
.
get
(
"shipCod"
));
IPage
<
VmsShipInfo
>
page
=
new
Page
<>(
pageIndex
,
pageSize
);
page
=
this
.
getBaseMapper
().
queryshipInfoList
(
page
,
params
);
return
new
SSIPage
(
page
);
}
@Override
public
SSIResponse
<?>
saveShipTx
(
DcvAllowGoShipLaneTxVo
vo
)
{
// TODO Auto-generated method stub
List
<
DcvAllowGoShipLaneTx
>
tempList
=
vo
.
getShipList
();
JSONObject
curUser
=
AuthorizationUtils
.
getCurUser
();
// Integer userId = (Integer) curUser.get("userId");
String
username
=
""
;
if
(
null
!=
curUser
)
{
username
=
(
String
)
curUser
.
get
(
"username"
);
}
List
<
String
>
t
=
new
ArrayList
<
String
>();
for
(
DcvAllowGoShipLaneTx
temp
:
tempList
)
{
temp
.
setRecUser
(
username
);
temp
.
getCntr
();
t
.
add
(
temp
.
getCntr
());
VmsShipNcl
tempncl
=
this
.
getBaseMapper
().
queryShipNclByCntr
(
temp
.
getCntr
());
temp
.
setBayNo
(
tempncl
.
getBayNo
());
}
// List<VmsShipNcl> tempNcl= this.getBaseMapper().queryShipNclByCntr(t);
// tempList=new ArrayList<DcvAllowGoShipLaneTx>();
// for(VmsShipNcl c : tempNcl ) {
// DcvAllowGoShipLaneTx tx=new DcvAllowGoShipLaneTx();
// tx.setAllowFlag(list.get(0).getAllowFlag());
// tx.setRecUser(username);
// tx.setCntr(c.getCntr());
// tx.setBayNo(c.getBayNo());
// tempList.add(tx);
// }
int
result
=
0
;
if
(
Objects
.
nonNull
(
vo
.
getDeleteItem
())&&
1
==
vo
.
getDeleteItem
()){
//删除对应船贝位设置
this
.
baseMapper
.
deleteBatch
(
tempList
);
}
else
{
result
=
this
.
getBaseMapper
().
saveBatch
(
tempList
);
}
// int result=this.getBaseMapper().updateShipTx(list);
// if(result!=1) {
// result=this.getBaseMapper().saveShipTx(list);
// }
return
SSIResponse
.
ok
(
result
);
}
@Override
public
Map
getPileInfo
(
String
portCode
)
{
// TODO Auto-generated method stub
Map
map
=
this
.
baseMapper
.
getPileInfo
(
portCode
);
return
map
;
}
@Override
public
String
getShipWorkingBay
(
String
voyageNo
,
String
portCode
)
{
// TODO Auto-generated method stub
String
bayNo
=
this
.
baseMapper
.
getShipWorkingBay
(
voyageNo
,
portCode
);
return
bayNo
;
}
}
ivccs-vmm-backservice/src/main/java/com/ssi/service/impl/VmsTerminalServiceImpl.java
0 → 100644
View file @
07602a7b
package
com.ssi.service.impl
;
import
com.alibaba.fastjson.JSONArray
;
import
com.alibaba.fastjson.JSONObject
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Maps
;
import
com.ssi.constant.VehicleConstant
;
import
com.ssi.entity.VmsVehicle
;
import
com.ssi.entity.dto.VmsVehicleDto
;
import
com.ssi.entity.vo.VideoMonitorParams
;
import
com.ssi.mapper.VmsTerminalMapper
;
import
com.ssi.mapper.VmsVehicleMapper
;
import
com.ssi.mqtt.MQTTPublishClient
;
import
com.ssi.response.AccessResponse
;
import
com.ssi.response.SSIPage
;
import
com.ssi.response.SSIResponse
;
import
org.apache.commons.lang3.StringUtils
;
import
org.eclipse.paho.client.mqttv3.MqttMessage
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Service
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.ssi.utils.QueryUtils
;
import
com.ssi.entity.VmsTerminal
;
import
com.ssi.service.VmsTerminalService
;
import
org.springframework.web.client.RestTemplate
;
/**
* 终端服务实现类
*/
@Service
(
"terminalService"
)
public
class
VmsTerminalServiceImpl
extends
ServiceImpl
<
VmsTerminalMapper
,
VmsTerminal
>
implements
VmsTerminalService
{
@Value
(
"${command-url}"
)
private
String
commandUrl
;
@Value
(
"${mqtt.address}"
)
private
String
mqttAddress
;
@Value
(
"${mqtt.serverId}"
)
private
String
mqttServerId
;
@Value
(
"${mqtt.name}"
)
private
String
mqttName
;
@Value
(
"${mqtt.password}"
)
private
String
mqttPassword
;
@Value
(
"${mqtt.url}"
)
private
String
mqttUrl
;
@Value
(
"${mqtt.CAPath}"
)
private
String
mqttCAPath
;
@Autowired
private
RestTemplate
restTemplate
;
@Autowired
private
VmsVehicleMapper
vmsVehicleMapper
;
/**
* 终端分页数据
* @param params
* @return
*/
@Override
public
SSIPage
queryPage
(
Map
<
String
,
Object
>
params
)
{
String
terminalNum
=
(
String
)
params
.
get
(
"terminalNum"
);
IPage
<
VmsTerminal
>
page
=
this
.
page
(
new
QueryUtils
<
VmsTerminal
>().
getPage
(
params
),
new
LambdaQueryWrapper
<
VmsTerminal
>().
like
(
StringUtils
.
isNotBlank
(
terminalNum
),
VmsTerminal:
:
getTerminalNum
,
terminalNum
)
.
orderByDesc
(
VmsTerminal:
:
getCreateTime
)
);
return
new
SSIPage
(
page
);
}
@Override
public
SSIResponse
saveTerminal
(
VmsTerminal
vmsTerminal
)
{
Map
<
String
,
Object
>
repeatMap
=
checkRepeat
(
vmsTerminal
);
if
((
Boolean
)
repeatMap
.
get
(
"repeat"
))
{
return
SSIResponse
.
no
((
String
)
repeatMap
.
get
(
"repeatInfo"
));
}
this
.
saveOrUpdate
(
vmsTerminal
);
return
SSIResponse
.
ok
();
}
private
Map
<
String
,
Object
>
checkRepeat
(
VmsTerminal
vmsTerminal
)
{
Map
<
String
,
Object
>
repeatMap
=
Maps
.
newHashMap
();
repeatMap
.
put
(
"repeat"
,
true
);
List
<
VmsTerminal
>
list
=
this
.
list
();
Map
<
String
,
VmsTerminal
>
simMap
=
Maps
.
newHashMap
();
Map
<
String
,
VmsTerminal
>
tNumMap
=
Maps
.
newHashMap
();
Map
<
String
,
VmsTerminal
>
tTypeMap
=
Maps
.
newHashMap
();
Map
<
String
,
VmsTerminal
>
iccidMap
=
Maps
.
newHashMap
();
list
.
parallelStream
().
forEach
(
vmsTerminal1
->
{
simMap
.
put
(
vmsTerminal1
.
getSim
(),
vmsTerminal1
);
tNumMap
.
put
(
vmsTerminal1
.
getTerminalNum
(),
vmsTerminal1
);
tTypeMap
.
put
(
vmsTerminal1
.
getTerminalType
(),
vmsTerminal1
);
iccidMap
.
put
(
vmsTerminal1
.
getIccid
(),
vmsTerminal1
);
});
VmsTerminal
repeatSim
=
simMap
.
get
(
vmsTerminal
.
getSim
());
VmsTerminal
repeatTnum
=
tNumMap
.
get
(
vmsTerminal
.
getTerminalNum
());
VmsTerminal
repeatTtype
=
tTypeMap
.
get
(
vmsTerminal
.
getTerminalType
());
VmsTerminal
repeatIccid
=
iccidMap
.
get
(
vmsTerminal
.
getIccid
());
if
(
repeatSim
!=
null
)
{
if
(
vmsTerminal
.
getId
()
==
null
||
(
vmsTerminal
.
getId
()
!=
null
&&
vmsTerminal
.
getId
()
!=
repeatSim
.
getId
()))
{
repeatMap
.
put
(
"repeatInfo"
,
"sim卡号不能重复"
);
return
repeatMap
;
}
}
if
(
repeatTnum
!=
null
)
{
if
(
vmsTerminal
.
getId
()
==
null
||
(
vmsTerminal
.
getId
()
!=
null
&&
vmsTerminal
.
getId
()
!=
repeatTnum
.
getId
()))
{
repeatMap
.
put
(
"repeatInfo"
,
"终端编号不能重复"
);
return
repeatMap
;
}
}
if
(
repeatTtype
!=
null
)
{
if
(
vmsTerminal
.
getId
()
==
null
||
(
vmsTerminal
.
getId
()
!=
null
&&
vmsTerminal
.
getId
()
!=
repeatTtype
.
getId
()))
{
repeatMap
.
put
(
"repeatInfo"
,
"终端型号不能重复"
);
return
repeatMap
;
}
}
if
(
repeatIccid
!=
null
)
{
if
(
vmsTerminal
.
getId
()
==
null
||
(
vmsTerminal
.
getId
()
!=
null
&&
vmsTerminal
.
getId
()
!=
repeatIccid
.
getId
()))
{
repeatMap
.
put
(
"repeatInfo"
,
"iccid不能重复"
);
return
repeatMap
;
}
}
repeatMap
.
put
(
"repeat"
,
false
);
return
repeatMap
;
}
@Override
public
SSIResponse
videoMonitor
(
String
vin
)
{
VmsVehicleDto
vehicle
=
vmsVehicleMapper
.
queryVehicleByVin
(
vin
);
if
(
vehicle
==
null
){
return
SSIResponse
.
no
(
"车辆不存在"
);
}
//发起mqtt请求,请求后视摄像头
MQTTPublishClient
mqttClientSend
=
new
MQTTPublishClient
(
mqttAddress
,
mqttServerId
,
mqttCAPath
,
mqttName
,
mqttPassword
,
mqttUrl
);
mqttClientSend
.
mqttRequest
(
vehicle
,
VehicleConstant
.
START_PUSHER
);
String
videoTerminalNum
=
vehicle
.
getVideoTerminalNum
();
VmsTerminal
vmsTerminal
=
this
.
lambdaQuery
().
eq
(
VmsTerminal:
:
getTerminalNum
,
videoTerminalNum
).
one
();
if
(
vmsTerminal
!=
null
){
List
<
Object
>
result
=
Lists
.
newArrayList
();
String
sim
=
vmsTerminal
.
getSim
();
VideoMonitorParams
.
VideoMonitorParamsBuilder
builder
=
VideoMonitorParams
.
builder
().
sim
(
sim
).
dataType
(
1
).
controlType
(
0
).
hdType
(
0
);
for
(
int
i
=
0
;
i
<
3
;
i
++)
{
VideoMonitorParams
params
=
builder
.
channel
(
i
+
1
).
build
();
AccessResponse
accessResponse
=
restTemplate
.
postForObject
(
commandUrl
+
"/media/9101"
,
params
,
AccessResponse
.
class
);
if
(
accessResponse
.
isSuccess
()){
Map
data
=
(
Map
)
accessResponse
.
getData
();
data
.
put
(
"channel"
,
i
+
1
);
result
.
add
(
data
);
}
else
{
Map
data
=
new
HashMap
();
data
.
put
(
"result"
,
0
);
result
.
add
(
data
);
}
}
return
SSIResponse
.
ok
(
result
);
}
else
{
return
SSIResponse
.
no
(
"车辆视频卡终端不在线"
);
}
}
}
ivccs-vmm-backservice/src/main/java/com/ssi/service/impl/VmsTerminalVersionServiceImpl.java
0 → 100644
View file @
07602a7b
package
com.ssi.service.impl
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.ssi.mapper.VmsTerminalVersionMapper
;
import
com.ssi.response.SSIPage
;
import
com.ssi.utils.QueryUtils
;
import
org.springframework.stereotype.Service
;
import
java.util.Date
;
import
java.util.Map
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.ssi.entity.VmsTerminalVersion
;
import
com.ssi.service.VmsTerminalVersionService
;
/**
* 终端版本服务实现类
*/
@Service
(
"terminalVersionService"
)
public
class
VmsTerminalVersionServiceImpl
extends
ServiceImpl
<
VmsTerminalVersionMapper
,
VmsTerminalVersion
>
implements
VmsTerminalVersionService
{
@Override
public
SSIPage
queryPage
(
Map
<
String
,
Object
>
params
)
{
Integer
publishStatus
=
(
Integer
)
params
.
get
(
"publishStatus"
);
IPage
<
VmsTerminalVersion
>
page
=
this
.
page
(
new
QueryUtils
<
VmsTerminalVersion
>().
getPage
(
params
),
new
LambdaQueryWrapper
<
VmsTerminalVersion
>()
.
lt
(
publishStatus
!=
null
&&
publishStatus
==
0
,
VmsTerminalVersion:
:
getPublishTime
,
new
Date
())
.
ge
(
publishStatus
!=
null
&&
publishStatus
==
1
,
VmsTerminalVersion:
:
getPublishTime
,
new
Date
())
.
orderByDesc
(
VmsTerminalVersion:
:
getPublishTime
)
);
return
new
SSIPage
(
page
);
}
}
ivccs-vmm-backservice/src/main/java/com/ssi/service/impl/VmsTosOrderDailyKpiServiceImpl.java
0 → 100644
View file @
07602a7b
package
com.ssi.service.impl
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.ssi.entity.VmsTosOrders
;
import
com.ssi.entity.VmsVehicle
;
import
com.ssi.entity.VmsTosOrderDailyKpi
;
import
com.ssi.entity.vo.VehicleKpiVo
;
import
com.ssi.mapper.VmsTosOrderDailyKpiMapper
;
import
com.ssi.service.VmsTosOrderDailyKpiService
;
import
com.ssi.service.VmsTosOrdersService
;
import
com.ssi.service.VmsVehicleService
;
import
com.ssi.utils.DateUtils
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.data.redis.core.StringRedisTemplate
;
import
org.springframework.stereotype.Service
;
import
java.time.Instant
;
import
java.time.LocalDateTime
;
import
java.time.ZoneId
;
import
java.util.*
;
import
java.util.stream.Collectors
;
/**
* @description:
* @author: dt
* @create: 2022-10-28 16:58
*/
@Service
public
class
VmsTosOrderDailyKpiServiceImpl
extends
ServiceImpl
<
VmsTosOrderDailyKpiMapper
,
VmsTosOrderDailyKpi
>
implements
VmsTosOrderDailyKpiService
{
private
final
Logger
log
=
LoggerFactory
.
getLogger
(
VmsTosOrderDailyKpiServiceImpl
.
class
);
private
VmsTosOrdersService
vmsTosOrdersService
;
private
VmsVehicleService
vmsVehicleService
;
private
StringRedisTemplate
redisTemplate
;
/**
* redis key
*/
@Value
(
"${harbor.order.dailyKpi:harbor:order:dailyKpi}"
)
private
String
redisDailyKpiKey
;
public
VmsTosOrderDailyKpiServiceImpl
(
VmsTosOrdersService
vmsTosOrdersService
,
VmsVehicleService
vmsVehicleService
,
StringRedisTemplate
redisTemplate
)
{
this
.
vmsTosOrdersService
=
vmsTosOrdersService
;
this
.
vmsVehicleService
=
vmsVehicleService
;
this
.
redisTemplate
=
redisTemplate
;
}
/**
* 预处理任务
* @param vins
* @return
*/
@Override
public
Boolean
analysisTosOrderDailyKpi
(
String
vins
)
{
LambdaQueryWrapper
<
VmsVehicle
>
vmsVehicleLambdaQueryWrapper
=
new
LambdaQueryWrapper
<>();
if
(
StringUtils
.
isNotEmpty
(
vins
))
{
vmsVehicleLambdaQueryWrapper
.
in
(
VmsVehicle:
:
getVin
,
vins
.
split
(
","
));
}
List
<
VmsVehicle
>
vehicles
=
vmsVehicleService
.
list
(
vmsVehicleLambdaQueryWrapper
.
eq
(
VmsVehicle:
:
getStatus
,
0
));
if
(
CollectionUtils
.
isEmpty
(
vehicles
))
{
log
.
info
(
"预处理每日 KPI 任务,查询的车辆信息为空..."
);
return
false
;
}
LocalDateTime
now
=
LocalDateTime
.
now
();
vehicles
.
parallelStream
().
forEach
(
vehicle
->
{
String
updateTime
=
redisTemplate
.<
String
,
String
>
boundHashOps
(
redisDailyKpiKey
).
get
(
vehicle
.
getVin
());
log
.
info
(
"------ 开始处理 vin = "
+
vehicle
.
getVin
()+
", updateTime = "
+
updateTime
+
", 时间 = "
+
LocalDateTime
.
now
().
toString
()
+
" ------"
);
LambdaQueryWrapper
<
VmsTosOrders
>
vmsTosOrdersLambdaQueryWrapper
=
new
LambdaQueryWrapper
<
VmsTosOrders
>()
.
eq
(
VmsTosOrders:
:
getVin
,
vehicle
.
getVin
());
if
(
StringUtils
.
isNotEmpty
(
updateTime
))
{
vmsTosOrdersLambdaQueryWrapper
.
ge
(
StringUtils
.
isNotEmpty
(
updateTime
),
VmsTosOrders:
:
getUpdateTime
,
LocalDateTime
.
ofInstant
(
Instant
.
ofEpochMilli
(
Long
.
parseLong
(
updateTime
)),
ZoneId
.
systemDefault
()))
.
lt
(
StringUtils
.
isNotEmpty
(
updateTime
),
VmsTosOrders:
:
getUpdateTime
,
now
);
}
List
<
VmsTosOrders
>
vmsTosOrders
=
vmsTosOrdersService
.
list
(
vmsTosOrdersLambdaQueryWrapper
.
in
(
VmsTosOrders:
:
getVehicleTaskLabel
,
1
,
2
,
3
)
.
in
(
VmsTosOrders:
:
getTaskLocationType
,
1
,
5
));
if
(
CollectionUtils
.
isNotEmpty
(
vmsTosOrders
))
{
Map
<
String
,
List
<
VmsTosOrders
>>
vmsTosOrderMap
=
vmsTosOrders
.
stream
().
filter
(
vmsTosOrder
->
Objects
.
nonNull
(
vmsTosOrder
.
getStartTime
()))
.
collect
(
Collectors
.
groupingBy
(
vmsTosOrder
->
getDateHourKey
(
vmsTosOrder
)));
vmsTosOrderMap
.
forEach
((
k
,
v
)
->
{
VmsTosOrderDailyKpi
vmsTosOrderDailyKpi
=
getVmsTosOrderDailyKpi
(
k
,
v
,
vehicle
);
saveOrUpdateVmsTosOrderDailyKpi
(
vmsTosOrderDailyKpi
);
});
}
else
{
log
.
info
(
"vin = "
+
vehicle
.
getVin
()+
", updateTime = "
+
updateTime
+
", 未查询到相关指令数据!"
);
}
redisTemplate
.
boundHashOps
(
redisDailyKpiKey
).
put
(
vehicle
.
getVin
(),
String
.
valueOf
(
now
.
atZone
(
ZoneId
.
systemDefault
()).
toInstant
().
toEpochMilli
()));
log
.
info
(
"------ 结束处理 vin = "
+
vehicle
.
getVin
()
+
", 时间 = "
+
LocalDateTime
.
now
().
toString
()
+
" ------"
);
});
return
true
;
}
/**
* 得到分组的 key
* @param vmsTosOrders
* @return
*/
private
String
getDateHourKey
(
VmsTosOrders
vmsTosOrders
)
{
return
DateUtils
.
format
(
vmsTosOrders
.
getStartTime
(),
"yyyy-MM-dd HH"
);
}
/**
* 生成任务分析的结果类
* @param vmsTosOrders
* @return
*/
private
VmsTosOrderDailyKpi
getVmsTosOrderDailyKpi
(
String
key
,
List
<
VmsTosOrders
>
vmsTosOrders
,
VmsVehicle
vehicle
)
{
VmsTosOrderDailyKpi
vmsTosOrderDailyKpi
=
new
VmsTosOrderDailyKpi
();
vmsTosOrderDailyKpi
.
setVin
(
vehicle
.
getVin
());
vmsTosOrderDailyKpi
.
setVehicleNum
(
vehicle
.
getVehicleNum
());
String
[]
dates
=
key
.
split
(
" "
);
vmsTosOrderDailyKpi
.
setAnalysisDate
(
dates
[
0
]);
vmsTosOrderDailyKpi
.
setAnalysisHour
(
Integer
.
parseInt
(
dates
[
1
]));
getContainers
(
vmsTosOrders
,
vmsTosOrderDailyKpi
);
getFinishedOrderNum
(
vmsTosOrders
,
vmsTosOrderDailyKpi
);
getOrderNum
(
vmsTosOrders
,
vmsTosOrderDailyKpi
);
return
vmsTosOrderDailyKpi
;
}
/**
* 填充 containerNum 和 containerIds
* @param vmsTosOrders
* @return
*/
private
void
getContainers
(
List
<
VmsTosOrders
>
vmsTosOrders
,
VmsTosOrderDailyKpi
vmsTosOrderDailyKpi
)
{
Set
<
String
>
containerIds
=
vmsTosOrders
.
stream
().
filter
(
vmsTosOrder
->
(
Objects
.
equals
(
1
,
vmsTosOrder
.
getTaskLocationType
())
&&
Objects
.
equals
(
2
,
vmsTosOrder
.
getVehicleTaskLabel
()))
||
(
Objects
.
equals
(
5
,
vmsTosOrder
.
getTaskLocationType
())
&&
Objects
.
equals
(
1
,
vmsTosOrder
.
getVehicleTaskLabel
()))).
map
(
VmsTosOrders:
:
getContainerId
)
.
filter
(
StringUtils:
:
isNotEmpty
).
collect
(
Collectors
.
toSet
());
vmsTosOrderDailyKpi
.
setContainerIds
(
String
.
join
(
","
,
containerIds
));
}
/**
* 填充结束任务
* @param vmsTosOrders
* @param vmsTosOrderDailyKpi
*/
private
void
getFinishedOrderNum
(
List
<
VmsTosOrders
>
vmsTosOrders
,
VmsTosOrderDailyKpi
vmsTosOrderDailyKpi
)
{
String
finishOrderIds
=
vmsTosOrders
.
stream
().
filter
(
vmsTosOrder
->
Objects
.
equals
(
37
,
vmsTosOrder
.
getStatus
()))
.
map
(
vmsTosOrder
->
String
.
valueOf
(
vmsTosOrder
.
getId
())).
collect
(
Collectors
.
joining
(
","
));
vmsTosOrderDailyKpi
.
setFinishedOrderIds
(
finishOrderIds
);
}
/**
* 填充任务数量
* @param vmsTosOrders
* @param vmsTosOrderDailyKpi
*/
private
void
getOrderNum
(
List
<
VmsTosOrders
>
vmsTosOrders
,
VmsTosOrderDailyKpi
vmsTosOrderDailyKpi
)
{
String
orderIds
=
vmsTosOrders
.
stream
().
map
(
vmsTosOrder
->
String
.
valueOf
(
vmsTosOrder
.
getId
()))
.
collect
(
Collectors
.
joining
(
","
));
vmsTosOrderDailyKpi
.
setOrderIds
(
orderIds
);
}
/**
* 保存或更新
* @param vmsTosOrderDailyKpi
* @return
*/
private
Boolean
saveOrUpdateVmsTosOrderDailyKpi
(
VmsTosOrderDailyKpi
vmsTosOrderDailyKpi
)
{
VmsTosOrderDailyKpi
orderDailyKpi
=
this
.
getOne
(
new
LambdaQueryWrapper
<
VmsTosOrderDailyKpi
>()
.
eq
(
VmsTosOrderDailyKpi:
:
getAnalysisDate
,
vmsTosOrderDailyKpi
.
getAnalysisDate
())
.
eq
(
VmsTosOrderDailyKpi:
:
getVin
,
vmsTosOrderDailyKpi
.
getVin
())
.
eq
(
VmsTosOrderDailyKpi:
:
getAnalysisHour
,
vmsTosOrderDailyKpi
.
getAnalysisHour
()));
if
(
Objects
.
nonNull
(
orderDailyKpi
))
{
String
containerIds
=
Arrays
.
stream
((
orderDailyKpi
.
getContainerIds
()
+
","
+
vmsTosOrderDailyKpi
.
getContainerIds
()).
split
(
","
)).
distinct
().
filter
(
StringUtils:
:
isNotEmpty
).
collect
(
Collectors
.
joining
(
","
));
vmsTosOrderDailyKpi
.
setContainerIds
(
containerIds
);
String
finishedOrderIds
=
Arrays
.
stream
((
orderDailyKpi
.
getFinishedOrderIds
()
+
","
+
vmsTosOrderDailyKpi
.
getFinishedOrderIds
()).
split
(
","
)).
distinct
().
filter
(
StringUtils:
:
isNotEmpty
).
collect
(
Collectors
.
joining
(
","
));
vmsTosOrderDailyKpi
.
setFinishedOrderIds
(
finishedOrderIds
);
String
orderIds
=
Arrays
.
stream
((
orderDailyKpi
.
getOrderIds
()
+
","
+
vmsTosOrderDailyKpi
.
getOrderIds
()).
split
(
","
)).
distinct
().
filter
(
StringUtils:
:
isNotEmpty
).
collect
(
Collectors
.
joining
(
","
));
vmsTosOrderDailyKpi
.
setOrderIds
(
orderIds
);
return
this
.
update
(
vmsTosOrderDailyKpi
,
new
LambdaUpdateWrapper
<
VmsTosOrderDailyKpi
>()
.
eq
(
VmsTosOrderDailyKpi:
:
getAnalysisDate
,
vmsTosOrderDailyKpi
.
getAnalysisDate
())
.
eq
(
VmsTosOrderDailyKpi:
:
getVin
,
vmsTosOrderDailyKpi
.
getVin
())
.
eq
(
VmsTosOrderDailyKpi:
:
getAnalysisHour
,
vmsTosOrderDailyKpi
.
getAnalysisHour
()));
}
else
{
return
this
.
save
(
vmsTosOrderDailyKpi
);
}
}
/**
* 查询分析好的 order kpi 任务
* @param day
* @param vehicleNum
* @return
*/
@Override
public
List
<
Map
<
String
,
String
>>
getOrderDailyKpi
(
String
day
,
String
vehicleNum
)
{
List
<
VmsVehicle
>
vehicles
=
vmsVehicleService
.
list
(
new
LambdaQueryWrapper
<
VmsVehicle
>()
.
eq
(
VmsVehicle:
:
getStatus
,
0
)
.
like
(
StringUtils
.
isNotBlank
(
vehicleNum
),
VmsVehicle:
:
getVehicleNum
,
vehicleNum
)
.
orderByAsc
(
VmsVehicle:
:
getVehicleNum
));
if
(
CollectionUtils
.
isNotEmpty
(
vehicles
))
{
String
[]
vins
=
vehicles
.
stream
().
map
(
VmsVehicle:
:
getVin
).
toArray
(
String
[]::
new
);
List
<
VmsTosOrderDailyKpi
>
orderDailyKpis
=
this
.
list
(
new
LambdaQueryWrapper
<
VmsTosOrderDailyKpi
>()
.
eq
(
VmsTosOrderDailyKpi:
:
getAnalysisDate
,
day
)
.
in
(
VmsTosOrderDailyKpi:
:
getVin
,
vins
));
Map
<
String
,
List
<
VmsTosOrderDailyKpi
>>
orderDailyKpiMap
=
orderDailyKpis
.
stream
().
collect
(
Collectors
.
groupingBy
(
VmsTosOrderDailyKpi:
:
getVin
));
List
<
Map
<
String
,
String
>>
resultList
=
vehicles
.
stream
().
map
(
vmsVehicle
->
{
try
{
VehicleKpiVo
vehicleKpiVo
=
new
VehicleKpiVo
(
vmsVehicle
.
getVin
(),
vmsVehicle
.
getVehicleNum
());
vehicleKpiVo
.
setDate
(
day
);
List
<
VmsTosOrderDailyKpi
>
vmsTosOrderDailyKpis
=
orderDailyKpiMap
.
get
(
vmsVehicle
.
getVin
());
vehicleKpiVo
.
fillDataForOrderDailyKpi
(
vmsTosOrderDailyKpis
);
Map
<
String
,
String
>
map
=
vehicleKpiVo
.
toMap
();
if
(
CollectionUtils
.
isNotEmpty
(
vmsTosOrderDailyKpis
))
{
int
containerNum
=
vmsTosOrderDailyKpis
.
stream
().
map
(
VmsTosOrderDailyKpi:
:
getContainerIds
).
filter
(
StringUtils:
:
isNotEmpty
)
.
flatMap
(
containerIds
->
Arrays
.
stream
(
containerIds
.
split
(
","
)))
.
collect
(
Collectors
.
toSet
()).
size
();
map
.
put
(
"containerNum"
,
String
.
valueOf
(
containerNum
));
}
else
{
map
.
put
(
"containerNum"
,
"0"
);
}
return
map
;
}
catch
(
Exception
e
)
{
log
.
error
(
"获取daily kpi异常"
,
e
);
}
return
null
;
}).
filter
(
Objects:
:
nonNull
).
collect
(
Collectors
.
toList
());
return
resultList
;
}
return
null
;
}
}
ivccs-vmm-backservice/src/main/java/com/ssi/service/impl/VmsTosOrdersAnalysisServiceImpl.java
0 → 100644
View file @
07602a7b
package
com.ssi.service.impl
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.ssi.entity.VmsTosOrdersAnalysis
;
import
com.ssi.entity.VmsVehicle
;
import
com.ssi.entity.vo.TaskAnalysisVo
;
import
com.ssi.mapper.VmsTosOrdersAnalysisMapper
;
import
com.ssi.mapper.VmsTosOrdersMapper
;
import
com.ssi.mapper.VmsVehicleMapper
;
import
com.ssi.service.VmsTosOrdersAnalysisService
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.time.LocalDate
;
import
java.time.LocalDateTime
;
import
java.time.LocalTime
;
import
java.time.ZoneOffset
;
import
java.util.List
;
/**
* 任务分析实现类
*/
@Service
(
"vmsTosOrdersAnalysisService"
)
public
class
VmsTosOrdersAnalysisServiceImpl
extends
ServiceImpl
<
VmsTosOrdersAnalysisMapper
,
VmsTosOrdersAnalysis
>
implements
VmsTosOrdersAnalysisService
{
@Autowired
private
VmsTosOrdersMapper
vmsTosOrdersMapper
;
@Autowired
private
VmsVehicleMapper
vmsVehicleMapper
;
@Override
public
IPage
<
VmsTosOrdersAnalysis
>
queryPage
(
int
current
,
int
size
,
VmsTosOrdersAnalysis
vmsTosOrdersAnalysis
)
{
IPage
<
VmsTosOrdersAnalysis
>
page
=
new
Page
<>(
current
,
size
);
QueryWrapper
<
VmsTosOrdersAnalysis
>
wrapper
=
new
QueryWrapper
<>();
return
this
.
page
(
page
,
wrapper
);
}
/**
* 根据时间段执行任务分析
* @param startTime
* @param endTime
*/
@Override
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
void
runTosAnalysisTask
(
LocalDateTime
startTime
,
LocalDateTime
endTime
)
{
Long
startTimeStamp
=
startTime
.
toInstant
(
ZoneOffset
.
of
(
"+8"
)).
toEpochMilli
();
List
<
TaskAnalysisVo
>
taskNumTimeByDay
=
vmsTosOrdersMapper
.
getTaskNumTimeByDay
(
startTime
,
endTime
,
startTimeStamp
);
LocalDate
startDate
=
startTime
.
toLocalDate
();
LocalDate
endDate
=
endTime
.
toLocalDate
();
List
<
VmsVehicle
>
vehicleList
=
vmsVehicleMapper
.
selectList
(
new
LambdaQueryWrapper
<
VmsVehicle
>()
.
eq
(
VmsVehicle:
:
getStatus
,
0
));
for
(
LocalDate
ld
=
startDate
;
ld
.
compareTo
(
endDate
)
<=
0
;
ld
=
ld
.
plusDays
(
1
))
{
LocalDate
ld1
=
ld
;
lambdaUpdate
().
set
(
VmsTosOrdersAnalysis:
:
getDeleted
,
1
)
.
eq
(
VmsTosOrdersAnalysis:
:
getAnalysisDate
,
ld1
)
.
update
();
for
(
int
i
=
0
;
i
<
vehicleList
.
size
();
i
++)
{
VmsVehicle
v
=
vehicleList
.
get
(
i
);
String
vin
=
v
.
getVin
();
boolean
present
=
taskNumTimeByDay
.
stream
().
anyMatch
(
vo
->
vo
.
getVin
().
equals
(
vin
)
&&
ld1
.
isEqual
(
vo
.
getDate
()));
if
(!
present
)
{
VmsTosOrdersAnalysis
analysis
=
new
VmsTosOrdersAnalysis
();
analysis
.
setAnalysisDate
(
ld
);
analysis
.
setVin
(
vin
);
getBaseMapper
().
insert
(
analysis
);
}
}
}
if
(
CollectionUtils
.
isNotEmpty
(
taskNumTimeByDay
))
{
taskNumTimeByDay
.
forEach
(
this
::
accept
);
}
}
/**
* 重新计算任务数据
*/
@Override
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
void
reAnalysis
(
LocalDate
date
)
{
LocalDateTime
startTime
=
LocalDateTime
.
of
(
date
,
LocalTime
.
MIN
);
Long
startTimeStamp
=
startTime
.
toInstant
(
ZoneOffset
.
of
(
"+8"
)).
toEpochMilli
();
LocalDateTime
endTime
=
LocalDateTime
.
of
(
date
,
LocalTime
.
MAX
);
List
<
TaskAnalysisVo
>
taskNumTimeByDay
=
vmsTosOrdersMapper
.
getTaskNumTimeByDay
(
startTime
,
endTime
,
startTimeStamp
);
if
(
CollectionUtils
.
isNotEmpty
(
taskNumTimeByDay
))
{
//原始数据未删除的情况下,可以进行重新分析
lambdaUpdate
().
set
(
VmsTosOrdersAnalysis:
:
getDeleted
,
1
)
.
eq
(
VmsTosOrdersAnalysis:
:
getAnalysisDate
,
date
)
.
update
();
List
<
VmsVehicle
>
vehicleList
=
vmsVehicleMapper
.
selectList
(
new
LambdaQueryWrapper
<
VmsVehicle
>()
.
eq
(
VmsVehicle:
:
getStatus
,
0
));
for
(
int
i
=
0
;
i
<
vehicleList
.
size
();
i
++)
{
String
vin
=
vehicleList
.
get
(
i
).
getVin
();
boolean
present
=
taskNumTimeByDay
.
stream
().
anyMatch
(
vo
->
vo
.
getVin
().
equals
(
vin
));
if
(!
present
)
{
VmsTosOrdersAnalysis
analysis
=
new
VmsTosOrdersAnalysis
();
analysis
.
setAnalysisDate
(
date
);
analysis
.
setVin
(
vin
);
getBaseMapper
().
insert
(
analysis
);
}
}
taskNumTimeByDay
.
forEach
(
this
::
accept
);
}
}
private
void
accept
(
TaskAnalysisVo
dayHourTrend
)
{
VmsTosOrdersAnalysis
analysis
=
new
VmsTosOrdersAnalysis
();
analysis
.
setAnalysisDate
(
dayHourTrend
.
getDate
());
analysis
.
setVin
(
dayHourTrend
.
getVin
());
analysis
.
setLoadContainerNum
(
dayHourTrend
.
getLoadContainerNum
());
analysis
.
setLoadContainerTime
(
dayHourTrend
.
getLoadContainerTime
());
analysis
.
setUnloadContainerNum
(
dayHourTrend
.
getUnloadContainerNum
());
analysis
.
setUnloadContainerTime
(
dayHourTrend
.
getUnloadContainerTime
());
analysis
.
setHandleContainerNum
(
dayHourTrend
.
getHandleContainerNum
());
analysis
.
setHandleContainerTime
(
dayHourTrend
.
getHandleContainerTime
());
getBaseMapper
().
insert
(
analysis
);
}
}
ivccs-vmm-backservice/src/main/java/com/ssi/service/impl/VmsTosOrdersOeeServiceImpl.java
0 → 100644
View file @
07602a7b
package
com.ssi.service.impl
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.ssi.constant.enums.VmsTosOrderStatusEnum
;
import
com.ssi.entity.VmsTosOrders
;
import
com.ssi.entity.VmsTosOrdersOee
;
import
com.ssi.entity.VmsVehicle
;
import
com.ssi.entity.vo.TaskKPIVo
;
import
com.ssi.entity.vo.TaskStatusHistory
;
import
com.ssi.entity.vo.VmsTosOrdersKPIVo
;
import
com.ssi.mapper.VmsTosOrdersOeeMapper
;
import
com.ssi.mapper.VmsVehicleMapper
;
import
com.ssi.model.VehicleElasticSearchModel
;
import
com.ssi.service.VmsTosOrdersOeeService
;
import
com.ssi.service.VmsTosOrdersService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.beanutils.BeanUtils
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
java.time.*
;
import
java.time.temporal.ChronoUnit
;
import
java.util.Date
;
import
java.util.List
;
/**
* OEE分析任务实现类
*/
@Service
(
"vmsTosOrdersOeeService"
)
@Slf4j
public
class
VmsTosOrdersOeeServiceImpl
extends
ServiceImpl
<
VmsTosOrdersOeeMapper
,
VmsTosOrdersOee
>
implements
VmsTosOrdersOeeService
{
@Autowired
private
VmsTosOrdersService
vmsTosOrdersService
;
@Autowired
private
VehicleElasticSearchModel
vehicleElasticSearchModel
;
@Autowired
private
VmsVehicleMapper
vmsVehicleMapper
;
/**
* 根据时间段执行OEE分析
* @param startTime
* @param endTime
*/
@Override
public
void
runTosOeeTask
(
LocalDateTime
startTime
,
LocalDateTime
endTime
)
{
List
<
VmsTosOrders
>
list
=
vmsTosOrdersService
.
lambdaQuery
()
.
eq
(
VmsTosOrders:
:
getDeleted
,
0
)
.
in
(
VmsTosOrders:
:
getStatus
,
VmsTosOrderStatusEnum
.
FINISH_CONFIRM
.
getCode
(),
VmsTosOrderStatusEnum
.
ARRIVED_DESTINATION
.
getCode
(),
VmsTosOrderStatusEnum
.
VEHICLE_LOCKUP
.
getCode
(),
VmsTosOrderStatusEnum
.
FINISH_CRANE_CONFIRM
.
getCode
(),
VmsTosOrderStatusEnum
.
FINISH_DRIVER_CONFIRM
.
getCode
())
.
in
(
VmsTosOrders:
:
getVehicleTaskLabel
,
1
,
2
,
3
)
.
ge
(
VmsTosOrders:
:
getCollectTime
,
Date
.
from
(
startTime
.
atZone
(
ZoneId
.
systemDefault
()).
toInstant
()).
getTime
())
.
lt
(
VmsTosOrders:
:
getCollectTime
,
Date
.
from
(
endTime
.
atZone
(
ZoneId
.
systemDefault
()).
toInstant
()).
getTime
())
.
list
();
if
(
CollectionUtils
.
isNotEmpty
(
list
))
{
list
.
stream
().
forEach
(
vmsTosOrders
->
{
try
{
String
taskNo
=
vmsTosOrders
.
getTaskNo
();
Integer
count
=
this
.
lambdaQuery
()
.
eq
(
VmsTosOrdersOee:
:
getTaskNo
,
taskNo
)
.
eq
(
VmsTosOrdersOee:
:
getDeleted
,
0
)
.
ge
(
VmsTosOrdersOee:
:
getCollectTime
,
Date
.
from
(
startTime
.
atZone
(
ZoneId
.
systemDefault
()).
toInstant
()).
getTime
())
.
lt
(
VmsTosOrdersOee:
:
getCollectTime
,
Date
.
from
(
endTime
.
atZone
(
ZoneId
.
systemDefault
()).
toInstant
()).
getTime
())
.
count
();
if
(
count
==
0
)
{
VmsTosOrdersOee
vmsTosOrdersOee
=
new
VmsTosOrdersOee
();
vmsTosOrders
.
setId
(
null
);
BeanUtils
.
copyProperties
(
vmsTosOrdersOee
,
vmsTosOrders
);
String
vin
=
vmsTosOrders
.
getVin
();
VmsVehicle
vmsVehicle
=
vmsVehicleMapper
.
selectOne
(
new
LambdaQueryWrapper
<
VmsVehicle
>().
eq
(
VmsVehicle:
:
getVin
,
vin
));
vmsTosOrdersOee
.
setVehicleNum
(
vmsVehicle
.
getVehicleNum
());
int
year
=
startTime
.
getYear
();
List
<
TaskStatusHistory
>
taskStatusHistoryList
=
vehicleElasticSearchModel
.
searchTaskHistory
(
taskNo
,
String
.
valueOf
(
year
));
Long
collectTime
=
vmsTosOrders
.
getCollectTime
();
Long
lastCollectTime
=
collectTime
;
for
(
int
j
=
0
;
j
<
taskStatusHistoryList
.
size
();
j
++)
{
Integer
status
=
taskStatusHistoryList
.
get
(
j
).
getStatus
();
Long
currentCollectTime
=
taskStatusHistoryList
.
get
(
j
).
getCollectTime
();
if
(
VmsTosOrderStatusEnum
.
OBU_RECEIVED
.
getCode
()
==
status
)
{
//车辆接受 43;
//指令等待时间 = 车辆接收时间 - collect_time
vmsTosOrdersOee
.
setInstructionWaitingTime
(
calTime
(
lastCollectTime
,
currentCollectTime
));
lastCollectTime
=
currentCollectTime
;
}
if
(
VmsTosOrderStatusEnum
.
START_TASK
.
getCode
()
==
status
)
{
//车辆开始行驶 65;
//作业准备时间 = 任务开始(开始行驶)-车辆接受
vmsTosOrdersOee
.
setHomeworkPreparationTime
(
calTime
(
lastCollectTime
,
currentCollectTime
));
lastCollectTime
=
currentCollectTime
;
}
if
(
VmsTosOrderStatusEnum
.
ARRIVED_DESTINATION
.
getCode
()
==
status
)
{
//到达目的地 3;
//移动到取箱点时间 = 到达目的地或者车辆停稳锁死-任务开始或车辆接受时间(任务开始时间为空)
vmsTosOrdersOee
.
setMoveTheBoxTime
(
calTime
(
lastCollectTime
,
currentCollectTime
));
lastCollectTime
=
currentCollectTime
;
}
if
(
VmsTosOrderStatusEnum
.
VEHICLE_LOCKUP
.
getCode
()
==
status
)
{
//车辆停稳锁死 49;
if
(
vmsTosOrdersOee
.
getMoveTheBoxTime
()
==
null
)
{
vmsTosOrdersOee
.
setMoveTheBoxTime
(
calTime
(
lastCollectTime
,
currentCollectTime
));
}
lastCollectTime
=
currentCollectTime
;
}
if
(
VmsTosOrderStatusEnum
.
FINISH_CONFIRM
.
getCode
()
==
status
)
{
//三重确认完成 37;
//取箱点等待时间 = 三重确认完成-到达目的地或者车辆停稳锁死
vmsTosOrdersOee
.
setPickingTime
(
calTime
(
lastCollectTime
,
currentCollectTime
));
}
}
this
.
save
(
vmsTosOrdersOee
);
}
}
catch
(
Exception
e
)
{
log
.
error
(
"runTosOeeTask出错,vmsTosOrders.TaskNo:"
+
vmsTosOrders
.
getTaskNo
(),
e
);
}
});
}
}
/**
* 任务KPI-效率OEE分析
*/
@Override
public
List
taskOee
(
VmsTosOrdersKPIVo
vmsTosOrders
)
{
if
(
vmsTosOrders
.
getStartTime
()
==
null
&&
vmsTosOrders
.
getEndTime
()
==
null
)
{
LocalDateTime
startTime
=
LocalDateTime
.
of
(
LocalDateTime
.
now
().
minus
(
3
,
ChronoUnit
.
DAYS
).
toLocalDate
(),
LocalTime
.
MIN
);
LocalDateTime
endTime
=
LocalDateTime
.
of
(
LocalDateTime
.
now
().
minus
(
1
,
ChronoUnit
.
DAYS
).
toLocalDate
(),
LocalTime
.
MAX
);
vmsTosOrders
.
setStartTime
(
startTime
.
atZone
(
ZoneId
.
systemDefault
()).
toInstant
().
toEpochMilli
());
vmsTosOrders
.
setEndTime
(
endTime
.
atZone
(
ZoneId
.
systemDefault
()).
toInstant
().
toEpochMilli
());
}
List
<
TaskKPIVo
>
taskKPIVos
=
this
.
getBaseMapper
().
taskOee
(
vmsTosOrders
);
return
taskKPIVos
;
}
private
long
calTime
(
Long
startDate
,
Long
endDate
)
{
if
(
startDate
==
null
||
endDate
==
null
)
{
return
0
;
}
long
diff
=
endDate
-
startDate
;
return
diff
>
0
?
diff
:
0
;
}
}
ivccs-vmm-backservice/src/main/java/com/ssi/service/impl/VmsTosOrdersServiceImpl.java
0 → 100644
View file @
07602a7b
package
com.ssi.service.impl
;
import
cn.afterturn.easypoi.excel.ExcelExportUtil
;
import
cn.afterturn.easypoi.excel.entity.ExportParams
;
import
cn.afterturn.easypoi.excel.export.ExcelBatchExportService
;
import
cn.afterturn.easypoi.handler.impl.ExcelDataHandlerDefaultImpl
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.alicp.jetcache.anno.CacheRefresh
;
import
com.alicp.jetcache.anno.Cached
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Maps
;
import
com.google.gson.Gson
;
import
com.google.gson.GsonBuilder
;
import
com.ssi.constant.VehicleConstant
;
import
com.ssi.constant.enums.VmsTosOrderStatusEnum
;
import
com.ssi.entity.*
;
import
com.ssi.entity.dto.VehicleTerminalData
;
import
com.ssi.entity.dto.VmsTosOrdersDto
;
import
com.ssi.entity.dto.kpi.VehicleDateStageDto
;
import
com.ssi.entity.dto.kpi.VmsTosOrdersKpiDto
;
import
com.ssi.entity.vo.*
;
import
com.ssi.mapper.*
;
import
com.ssi.model.RedisDataModel
;
import
com.ssi.model.VehicleElasticSearchModel
;
import
com.ssi.response.AccessResponse
;
import
com.ssi.response.SSIPage
;
import
com.ssi.response.SSIResponse
;
import
com.ssi.service.VmsCranePadBindService
;
import
com.ssi.service.VehicleTroubleService
;
import
com.ssi.service.VmsVehicleService
;
import
com.ssi.utils.*
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.apache.commons.collections.map.HashedMap
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.poi.ss.usermodel.Workbook
;
import
org.elasticsearch.action.search.*
;
import
org.elasticsearch.client.RequestOptions
;
import
org.elasticsearch.client.RestHighLevelClient
;
import
org.elasticsearch.common.unit.TimeValue
;
import
org.elasticsearch.index.query.BoolQueryBuilder
;
import
org.elasticsearch.index.query.MatchQueryBuilder
;
import
org.elasticsearch.index.query.QueryBuilders
;
import
org.elasticsearch.index.query.RangeQueryBuilder
;
import
org.elasticsearch.search.Scroll
;
import
org.elasticsearch.search.SearchHit
;
import
org.elasticsearch.search.builder.SearchSourceBuilder
;
import
org.elasticsearch.search.sort.FieldSortBuilder
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Service
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.ssi.service.VmsTosOrdersService
;
import
org.springframework.web.client.RestTemplate
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
import
java.math.BigDecimal
;
import
java.time.LocalDateTime
;
import
java.math.RoundingMode
;
import
java.text.SimpleDateFormat
;
import
java.time.ZoneId
;
import
java.time.format.DateTimeFormatter
;
import
java.time.temporal.ChronoUnit
;
import
java.util.*
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
java.util.function.Function
;
import
java.util.stream.Collectors
;
/**
* 任务服务实现类
*/
@Service
(
"vmsTosOrdersService"
)
public
class
VmsTosOrdersServiceImpl
extends
ServiceImpl
<
VmsTosOrdersMapper
,
VmsTosOrders
>
implements
VmsTosOrdersService
{
private
static
Logger
log
=
LoggerFactory
.
getLogger
(
VmsTosOrdersServiceImpl
.
class
);
@Autowired
VmsTaskJourneyInfoMapper
taskJourneyInfoMapper
;
@Autowired
private
VehicleTroubleService
vehicleTroubleService
;
@Autowired
private
RestHighLevelClient
restHighLevelClient
;
@Autowired
private
VmsCranePadBindService
vmsCranePadBindService
;
@Autowired
private
VmsVehicleService
vmsVehicleService
;
@Autowired
private
RedisDataModel
redisDataModel
;
@Autowired
private
VehicleTroubleHistoryMapper
vehicleTroubleHistoryMapper
;
@Autowired
private
VehicleElasticSearchModel
vehicleElasticSearchModel
;
@Autowired
private
VehicleDataUtil
vehicleDataUtil
;
@Autowired
private
VmsTosOrdersAnalysisMapper
vmsTosOrdersAnalysisMapper
;
@Autowired
private
VmsTosOrdersMapper
vmsTosOrdersMapper
;
@Autowired
private
RestTemplate
restTemplate
;
@Autowired
private
VehicleRemoteInstructionMapper
vehicleRemoteInstructionMapper
;
@Value
(
"${analysis.vehicle-data.es-index-name}"
)
private
String
esVehicleDataIndexName
;
@Value
(
"${analysis.vehicle-data.index-rule:year}"
)
private
String
indexRule
;
@Value
(
"${order.latestOrderKeyPrefix:harbor:command:status}"
)
private
String
latestOrderKeyPrefix
;
@Value
(
"${vehicle.cache.key:ivccs:vms:vehicle:cache}"
)
private
String
vehicleCacheKey
;
@Value
(
"${command-url}"
)
private
String
commandUrl
;
private
ThreadLocal
<
VehicleDateStageDto
>
threadStage
=
new
ThreadLocal
<
VehicleDateStageDto
>();
@Override
public
Map
<
String
,
VmsTosOrders
>
getAllVehicleLatestWork
()
{
Map
<
String
,
VmsTosOrders
>
resultMap
=
Maps
.
newHashMap
();
List
<
VmsTosOrders
>
list
=
this
.
list
();
list
.
parallelStream
().
forEach
(
vmsTosOrders
->
{
VmsTosOrders
tempOrders
=
resultMap
.
get
(
vmsTosOrders
.
getVin
());
if
(
tempOrders
==
null
||
tempOrders
.
getReceiveTime
().
getTime
()
<
vmsTosOrders
.
getReceiveTime
().
getTime
())
{
resultMap
.
put
(
vmsTosOrders
.
getVin
(),
vmsTosOrders
);
}
});
return
resultMap
;
}
/**
* 获取车辆当前任务
* @param vin 车辆vin
*/
@Override
public
Map
<
String
,
Object
>
getOrdersByVin
(
String
vin
)
{
Map
<
String
,
Object
>
resultMap
=
Maps
.
newHashMap
();
Map
<
String
,
Object
>
json2Map
=
redisDataModel
.
getJson2Map
(
String
.
format
(
"%s:%s"
,
latestOrderKeyPrefix
,
vin
));
JSONObject
jsonObject
=
JSONObject
.
parseObject
(
JSONObject
.
toJSONString
(
json2Map
));
VmsTosOrders
vmsTosOrders
=
JSONObject
.
toJavaObject
(
jsonObject
,
VmsTosOrders
.
class
);
if
(
vmsTosOrders
!=
null
)
{
resultMap
.
put
(
"vmsTosOrders"
,
vmsTosOrders
);
resultMap
.
put
(
"workStatus"
,
!
VehicleUtil
.
isTaskOver
(
vmsTosOrders
.
getStatus
())
?
0
:
1
);
// resultMap.put("taskAssociation", vmsTosOrders.getTaskAssociation());
resultMap
.
put
(
"taskType"
,
vmsTosOrders
.
getTaskType
());
if
(!
VehicleUtil
.
isTaskOver
(
vmsTosOrders
.
getStatus
()))
{
if
(!(
vmsTosOrders
.
getStartTime
()
==
null
))
{
resultMap
.
put
(
"workTime"
,
System
.
currentTimeMillis
()
-
vmsTosOrders
.
getStartTime
().
getTime
());
}
}
}
else
{
resultMap
.
put
(
"workStatus"
,
1
);
}
return
resultMap
;
}
/**
* 车辆行程查询
* @param vin 车辆vin
* @param startTime 查询起始时间
* @param stopTime 查询截止时间
* @param faultGrade 故障等级
*/
@Override
public
SSIResponse
getVehicleTrip
(
String
vin
,
Long
startTime
,
Long
stopTime
,
String
faultGrade
)
{
Date
startDate
=
startTime
==
null
?
null
:
new
Date
(
startTime
);
Date
stopDate
=
stopTime
==
null
?
null
:
new
Date
(
stopTime
);
List
<
VmsTosOrders
>
list
=
baseMapper
.
getVehicleTrip
(
vin
,
startDate
,
stopDate
);
Map
<
String
,
Object
>
params
=
new
HashMap
<>();
params
.
put
(
"startTime"
,
startDate
);
params
.
put
(
"stopTime"
,
stopDate
);
params
.
put
(
"faultGrade"
,
faultGrade
);
List
<
String
>
vins
=
new
ArrayList
<>();
vins
.
add
(
vin
);
params
.
put
(
"vins"
,
vins
);
List
<
VmsVehicleAlertHistoryVo
>
vehicleAlertHistoryList
=
vehicleTroubleHistoryMapper
.
getAlertHistoryList
(
params
);
//异常过滤任务
List
<
VmsTosOrders
>
resultList
=
filterOrders
(
list
,
faultGrade
,
vehicleAlertHistoryList
);
//查询里程能耗信息
resultList
.
parallelStream
().
forEach
(
vmsTosOrders
->
{
VmsTaskJourneyInfo
vmsTaskJourneyInfo
=
taskJourneyInfoMapper
.
selectOne
(
new
LambdaQueryWrapper
<
VmsTaskJourneyInfo
>()
.
eq
(
VmsTaskJourneyInfo:
:
getTaskId
,
vmsTosOrders
.
getTaskNo
()));
changeUnit
(
vmsTaskJourneyInfo
);
//计算百公里能耗
calcHundredEnergy
(
vmsTaskJourneyInfo
);
vmsTosOrders
.
setVmsTaskJourneyInfo
(
vmsTaskJourneyInfo
);
});
return
SSIResponse
.
ok
(
resultList
);
}
private
void
changeUnit
(
VmsTaskJourneyInfo
vmsTaskJourneyInfo
)
{
if
(
vmsTaskJourneyInfo
==
null
)
{
return
;
}
//mile单位已经是千米了,不用再除以1000
/*if(vmsTaskJourneyInfo.getMile() != null){
vmsTaskJourneyInfo.setMile(vmsTaskJourneyInfo.getMile().divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP));
}*/
if
(
vmsTaskJourneyInfo
.
getTimeConsuming
()
!=
null
)
{
BigDecimal
timeSeconds
=
new
BigDecimal
(
vmsTaskJourneyInfo
.
getTimeConsuming
()).
divide
(
new
BigDecimal
(
1000
),
0
,
BigDecimal
.
ROUND_CEILING
);
vmsTaskJourneyInfo
.
setTime
(
formatTime
(
timeSeconds
));
}
}
private
List
<
VmsTosOrders
>
filterOrders
(
List
<
VmsTosOrders
>
list
,
String
faultGrade
,
List
<
VmsVehicleAlertHistoryVo
>
alertList
)
{
//时长一分钟以内的任务过滤掉
list
=
list
.
stream
().
filter
(
vmsTosOrders
->
{
Date
startTime
=
vmsTosOrders
.
getStartTime
();
Date
endTime
=
vmsTosOrders
.
getEndTime
();
if
(
startTime
!=
null
&&
endTime
!=
null
)
{
return
vmsTosOrders
.
getEndTime
().
getTime
()
-
vmsTosOrders
.
getStartTime
().
getTime
()
>
60000
;
}
return
true
;
}).
collect
(
Collectors
.
toList
());
if
(
StringUtils
.
isBlank
(
faultGrade
))
{
return
list
;
}
else
{
if
(
alertList
==
null
||
alertList
.
isEmpty
())
{
return
new
ArrayList
<
VmsTosOrders
>();
}
}
List
<
VmsTosOrders
>
resultList
=
Lists
.
newArrayList
();
list
.
stream
().
forEach
(
vmsTosOrders
->
{
if
(
vmsTosOrders
.
getStartTime
()
==
null
||
vmsTosOrders
.
getEndTime
()
==
null
)
{
return
;
}
if
(
vmsTosOrders
.
getStartTime
().
getTime
()
>
alertList
.
get
(
0
).
getAlarmTime
().
getTime
())
{
//任务结束时间大于最大异常开始时间
}
else
if
(
vmsTosOrders
.
getEndTime
().
getTime
()
<
alertList
.
get
(
alertList
.
size
()
-
1
).
getAlarmTime
().
getTime
())
{
//任务结束时间小于最小异常开始时间
}
else
{
resultList
.
add
(
vmsTosOrders
);
}
});
return
resultList
;
}
/**
* 根据时间查询车辆能耗里程
*/
@Override
public
SSIResponse
getMileTimeByTime
(
String
vin
,
Long
startTime
,
Long
stopTime
)
{
VmsTaskJourneyInfo
vmsTaskJourneyInfo
=
execAnalysisForVmsTosOrders
(
vin
,
startTime
,
stopTime
);
return
SSIResponse
.
ok
(
vmsTaskJourneyInfo
);
}
private
VmsTaskJourneyInfo
execAnalysisForVmsTosOrders
(
String
vin
,
Long
startTime
,
Long
stopTime
)
{
VmsTaskJourneyInfo
vmsTaskJourneyInfo
=
new
VmsTaskJourneyInfo
();
try
{
vmsTaskJourneyInfo
.
setMileVal
(
0
D
);
vmsTaskJourneyInfo
.
setEnergyConsumingVal
(
0
D
);
vmsTaskJourneyInfo
.
setTimeConsuming
(
0L
);
calc
(
vmsTaskJourneyInfo
,
vin
,
startTime
,
stopTime
);
//单位转换
changeUnit
(
vmsTaskJourneyInfo
);
vmsTaskJourneyInfo
.
setMile
(
new
BigDecimal
(
vmsTaskJourneyInfo
.
getMileVal
()).
setScale
(
2
,
BigDecimal
.
ROUND_UP
));
vmsTaskJourneyInfo
.
setEnergyConsuming
(
new
BigDecimal
(
vmsTaskJourneyInfo
.
getEnergyConsumingVal
()).
setScale
(
2
,
BigDecimal
.
ROUND_HALF_UP
));
calcHundredEnergy
(
vmsTaskJourneyInfo
);
}
catch
(
Exception
e
)
{
log
.
error
(
"Fail to analysis vmstoorders."
,
e
);
}
return
vmsTaskJourneyInfo
;
}
private
void
calc
(
VmsTaskJourneyInfo
vmsTaskJourneyInfo
,
String
vin
,
Long
startTime
,
Long
stopTime
)
throws
IOException
{
Gson
gson
=
new
GsonBuilder
().
create
();
int
size
=
10000
;
final
Scroll
scroll
=
new
Scroll
(
TimeValue
.
timeValueMinutes
(
10L
));
SearchResponse
response
=
getSearchResponse
(
vin
,
startTime
,
stopTime
,
size
,
scroll
);
String
scrollId
=
response
.
getScrollId
();
SearchHit
[]
searchHits
=
response
.
getHits
().
getHits
();
VehicleTerminalData
lastVehicleTerminalData
=
null
;
while
(
searchHits
!=
null
&&
searchHits
.
length
>
0
)
{
for
(
SearchHit
hit
:
searchHits
)
{
VehicleTerminalData
currentVehicleTerminalData
=
null
;
String
sourceAsString
=
hit
.
getSourceAsString
();
if
(
sourceAsString
!=
null
)
{
currentVehicleTerminalData
=
parseVehicleTerminalDate
(
gson
,
sourceAsString
);
}
if
(
lastVehicleTerminalData
!=
null
&&
currentVehicleTerminalData
!=
null
)
{
long
time
=
currentVehicleTerminalData
.
getCollectTime
()
-
lastVehicleTerminalData
.
getCollectTime
();
if
(
time
<=
60000
)
{
calcMile
(
vmsTaskJourneyInfo
,
lastVehicleTerminalData
,
currentVehicleTerminalData
);
caclTime
(
vmsTaskJourneyInfo
,
lastVehicleTerminalData
,
currentVehicleTerminalData
);
calcEnergy
(
vmsTaskJourneyInfo
,
lastVehicleTerminalData
,
currentVehicleTerminalData
);
}
}
lastVehicleTerminalData
=
currentVehicleTerminalData
;
}
/* Next batch data. */
if
(
searchHits
.
length
==
size
)
{
response
=
getNextScrollResponse
(
scrollId
,
scroll
);
searchHits
=
response
.
getHits
().
getHits
();
}
else
{
break
;
}
}
clearScroll
(
scrollId
);
}
private
void
calcHundredEnergy
(
VmsTaskJourneyInfo
vmsTaskJourneyInfo
)
{
if
(
vmsTaskJourneyInfo
!=
null
&&
vmsTaskJourneyInfo
.
getEnergyConsuming
()
!=
null
&&
vmsTaskJourneyInfo
.
getMile
()
!=
null
&&
vmsTaskJourneyInfo
.
getMile
().
doubleValue
()
>
0
)
{
vmsTaskJourneyInfo
.
setHundredEnergyConsuming
(
vmsTaskJourneyInfo
.
getEnergyConsuming
()
.
divide
(
vmsTaskJourneyInfo
.
getMile
(),
2
,
RoundingMode
.
HALF_UP
).
multiply
(
new
BigDecimal
(
100
)));
}
}
private
void
calcMile
(
VmsTaskJourneyInfo
vmsTaskJourneyInfo
,
VehicleTerminalData
lastVehicleTerminalData
,
VehicleTerminalData
currentVehicleTerminalData
)
{
// Double dist = GpsUtil.getDistance(lastVehicleTerminalData.getLatitude(),
// lastVehicleTerminalData.getLongitude(), currentVehicleTerminalData.getLatitude(),
// currentVehicleTerminalData.getLongitude());
// if (dist > 0 && dist < 1 && currentVehicleTerminalData.getSpeed().compareTo(BigDecimal.ZERO)!=0) {
// vmsTaskJourneyInfo.setMileVal(vmsTaskJourneyInfo.getMileVal() + dist);
// }
if
(
lastVehicleTerminalData
.
getSpeed
().
doubleValue
()
>=
0.0
&&
currentVehicleTerminalData
.
getSpeed
().
doubleValue
()
>=
0.0
)
{
double
curSpeed
=
currentVehicleTerminalData
.
getSpeed
().
doubleValue
();
double
lastSpeed
=
lastVehicleTerminalData
.
getSpeed
().
doubleValue
();
double
avgSpeed
=
(
lastSpeed
+
curSpeed
)
/
2
;
long
time
=
currentVehicleTerminalData
.
getCollectTime
()
-
lastVehicleTerminalData
.
getCollectTime
();
double
mile
=
avgSpeed
/
60
/
60
*
(
time
/
1000
);
vmsTaskJourneyInfo
.
setMileVal
(
vmsTaskJourneyInfo
.
getMileVal
()
+
mile
);
}
}
private
void
caclTime
(
VmsTaskJourneyInfo
vmsTaskJourneyInfo
,
VehicleTerminalData
lastVehicleTerminalData
,
VehicleTerminalData
currentVehicleTerminalData
)
{
long
time
=
currentVehicleTerminalData
.
getCollectTime
()
-
lastVehicleTerminalData
.
getCollectTime
();
vmsTaskJourneyInfo
.
setTimeConsuming
(
vmsTaskJourneyInfo
.
getTimeConsuming
()
+
time
);
}
private
void
calcEnergy
(
VmsTaskJourneyInfo
vmsTaskJourneyInfo
,
VehicleTerminalData
lastVehicleTerminalData
,
VehicleTerminalData
currentVehicleTerminalData
)
{
double
energyConsuming
=
calcEnergy
(
lastVehicleTerminalData
,
currentVehicleTerminalData
);
vmsTaskJourneyInfo
.
setEnergyConsumingVal
(
energyConsuming
+
vmsTaskJourneyInfo
.
getEnergyConsumingVal
());
}
public
static
double
calcEnergy
(
VehicleTerminalData
lastVehicleTerminalData
,
VehicleTerminalData
currentVehicleTerminalData
)
{
double
totalElectricity
=
lastVehicleTerminalData
.
getTotalElectricity
();
double
totalVoltage
=
lastVehicleTerminalData
.
getTotalVoltage
();
if
(
totalElectricity
==
-
1
||
totalVoltage
==
-
1
)
{
return
0
;
}
return
Math
.
abs
((
totalElectricity
*
totalVoltage
)
/
1000
*
(
Double
.
parseDouble
(
String
.
valueOf
(
currentVehicleTerminalData
.
getCollectTime
()
-
lastVehicleTerminalData
.
getCollectTime
()))
/
(
1000
*
60
*
60
)));
}
private
VehicleTerminalData
parseVehicleTerminalDate
(
Gson
gson
,
String
jsonStr
)
{
try
{
return
gson
.
fromJson
(
jsonStr
,
VehicleTerminalData
.
class
);
}
catch
(
Throwable
t
)
{
log
.
error
(
"[Analysis Executor]Fail to convert VehicleTerminalDate vmstoorders.\n"
+
jsonStr
,
t
);
}
return
null
;
}
private
SearchResponse
getSearchResponse
(
String
vin
,
Long
startTime
,
Long
stopTime
,
int
size
,
Scroll
scroll
)
throws
IOException
{
BoolQueryBuilder
boolBuilder
=
QueryBuilders
.
boolQuery
();
SearchSourceBuilder
sourceBuilder
=
new
SearchSourceBuilder
();
sourceBuilder
.
size
(
size
);
MatchQueryBuilder
matchQueryBuilder
=
QueryBuilders
.
matchQuery
(
"vin"
,
vin
);
RangeQueryBuilder
rangeQueryBuilder
=
QueryBuilders
.
rangeQuery
(
"collectTime"
);
rangeQueryBuilder
.
gte
(
startTime
);
rangeQueryBuilder
.
lte
(
stopTime
);
boolBuilder
.
must
(
rangeQueryBuilder
);
boolBuilder
.
must
(
matchQueryBuilder
);
FieldSortBuilder
fieldSortBuilder
=
new
FieldSortBuilder
(
"collectTime"
);
sourceBuilder
.
query
(
boolBuilder
);
sourceBuilder
.
sort
(
fieldSortBuilder
);
sourceBuilder
.
timeout
(
new
TimeValue
(
600
,
TimeUnit
.
SECONDS
));
String
[]
indexs
=
ElasticSearchUtil
.
getIndexs
(
startTime
,
stopTime
,
esVehicleDataIndexName
,
1
,
true
,
indexRule
);
SearchRequest
searchRequest
=
new
SearchRequest
(
indexs
);
searchRequest
.
scroll
(
scroll
);
searchRequest
.
source
(
sourceBuilder
);
return
restHighLevelClient
.
search
(
searchRequest
,
RequestOptions
.
DEFAULT
);
}
private
SearchResponse
getNextScrollResponse
(
String
scrollId
,
Scroll
scroll
)
throws
IOException
{
SearchScrollRequest
scrollRequest
=
new
SearchScrollRequest
(
scrollId
);
scrollRequest
.
scroll
(
scroll
);
return
restHighLevelClient
.
scroll
(
scrollRequest
,
RequestOptions
.
DEFAULT
);
}
private
void
clearScroll
(
String
scrollId
)
throws
IOException
{
ClearScrollRequest
clearScrollRequest
=
new
ClearScrollRequest
();
clearScrollRequest
.
addScrollId
(
scrollId
);
restHighLevelClient
.
clearScroll
(
clearScrollRequest
,
RequestOptions
.
DEFAULT
);
}
@Override
public
SSIPage
queryPage
(
VmsTosOrdersVo
ordersVo
)
{
String
vehicleNum
=
ordersVo
.
getVehicleNum
();
if
(
StringUtils
.
isNotBlank
(
vehicleNum
))
{
VmsVehicle
vehicle
=
vmsVehicleService
.
lambdaQuery
().
eq
(
VmsVehicle:
:
getVehicleNum
,
vehicleNum
).
one
();
if
(
vehicle
==
null
)
{
return
new
SSIPage
(
new
Page
<>());
}
String
vin
=
vehicle
.
getVin
();
ordersVo
.
setVin
(
vin
);
}
IPage
<
VmsTosOrders
>
iPage
=
new
Page
<
VmsTosOrders
>(
ordersVo
.
getPageIndex
(),
ordersVo
.
getPageSize
());
IPage
<
VmsTosOrders
>
page
=
baseMapper
.
pageQuery
(
iPage
,
ordersVo
);
List
<
VmsTosOrders
>
records
=
page
.
getRecords
();
if
(
CollectionUtils
.
isEmpty
(
records
))
{
return
new
SSIPage
(
page
);
}
records
.
forEach
(
vmsTosOrders
->
{
try
{
vmsTosOrders
.
setStartTimeStamp
(
vmsTosOrders
.
getStartTime
().
getTime
()/
1000
);
String
costTime
=
getCostTime
(
vmsTosOrders
);
vmsTosOrders
.
setCostTime
(
costTime
);
Map
<
String
,
Object
>
map
=
redisDataModel
.
hgetJson2Map
(
vehicleCacheKey
,
vmsTosOrders
.
getVin
());
vmsTosOrders
.
setVehicleNum
((
String
)
map
.
get
(
"vehicleNum"
));
String
description
=
vehicleDataUtil
.
generateTaskLocationDescription
(
vmsTosOrders
.
getTaskLocationType
(),
vmsTosOrders
.
getVehicleLocation
());
vmsTosOrders
.
setLocationDescription
(
description
);
//添加lockLabel
Map
<
String
,
Object
>
orderMap
=
redisDataModel
.
getJson2Map
(
String
.
format
(
"%s:%s"
,
latestOrderKeyPrefix
,
vmsTosOrders
.
getVin
()));
vmsTosOrders
.
setLockLabel
(
Objects
.
isNull
(
orderMap
.
get
(
"lockLabel"
))?
null
:(
Integer
)
orderMap
.
get
(
"lockLabel"
));
}
catch
(
Exception
e
)
{
log
.
error
(
"获取时间、车辆编号、地点描述异常:"
,
e
);
}
});
return
new
SSIPage
(
page
);
}
/**
* 搬运集装箱的列表
*/
@Override
public
SSIPage
queryPageByAllStatus
(
VmsTosOrdersVo
ordersVo
)
{
//查询车辆任务数据
List
<
VmsTosOrdersDto
>
ordersDtosList
=
vmsTosOrdersMapper
.
queryPageByAllStatus
(
ordersVo
);
IPage
<
VmsTosOrdersKpiDto
>
vmsPage
=
new
Page
<>(
ordersVo
.
getPageIndex
(),
ordersVo
.
getPageSize
());
if
(
CollectionUtils
.
isEmpty
(
ordersDtosList
))
{
return
new
SSIPage
(
vmsPage
);
}
//查询任务的所有状态信息
List
<
String
>
taskNoList
=
ordersDtosList
.
stream
().
map
(
vmsTosOrders
->
vmsTosOrders
.
getTaskNo
()).
collect
(
Collectors
.
toList
());
String
year
=
DateUtils
.
format
(
ordersVo
.
getQueryStartTime
(),
"yyyy"
);
Map
<
String
,
List
<
TaskStatusHistory
>>
statusMap
=
vehicleElasticSearchModel
.
searchTaskHistory
(
taskNoList
,
year
);
//封装大任务方法
List
<
VmsTosOrdersKpiDto
>
kpiOrderList
=
getVmsTosOrdersKpiDtos
(
ordersDtosList
,
statusMap
);
//将队列逆序
Collections
.
reverse
(
kpiOrderList
);
vmsPage
.
setRecords
(
kpiOrderList
);
// threadStage.remove();
return
new
SSIPage
(
vmsPage
);
}
/**
* 任务封装逻辑
* @param ordersDtosList
* @param statusMap
* @return
*/
public
List
<
VmsTosOrdersKpiDto
>
getVmsTosOrdersKpiDtos
(
List
<
VmsTosOrdersDto
>
ordersDtosList
,
Map
<
String
,
List
<
TaskStatusHistory
>>
statusMap
)
{
/**
* 封装KPI数据
*/
List
<
VmsTosOrdersKpiDto
>
kpiOrderList
=
new
ArrayList
<>();
//结果集
VmsTosOrdersKpiDto
kpiParentDto
=
new
VmsTosOrdersKpiDto
();
//大任务信息
kpiParentDto
.
setCollectTime
(
ordersDtosList
.
get
(
0
).
getCollectTime
());
List
<
VmsTosOrdersDto
>
orderList
=
new
ArrayList
<>();
//大任务下子任务集合
List
<
VehicleDateStageDto
>
dateList
=
new
ArrayList
<>();
//大任务下步骤时间
VehicleDateStageDto
dateStageDto
=
null
;
int
startPortType
=
0
;
int
lastPortType
=
0
;
//记录前一条记录的portType
int
lastVehicleTaskLabel
=
0
;
//记录前一条记录的任务标签 装船or卸船
int
appControl
=
0
;
for
(
int
i
=
0
;
i
<
ordersDtosList
.
size
();
i
++){
VmsTosOrdersDto
vmsTosOrdersDto
=
ordersDtosList
.
get
(
i
);
//装船任务,任务从堆场作业开始;卸船任务,任务从桥吊开始;搬移任务,从第一个PortCode开始
if
(
vmsTosOrdersDto
.
getVehicleTaskLabel
()
==
1
){
//装船
startPortType
=
2
;
//起点为场吊
}
else
if
(
vmsTosOrdersDto
.
getVehicleTaskLabel
()
==
2
){
//卸船
startPortType
=
1
;
//起点轮胎吊
}
//APP控制
if
(
vmsTosOrdersDto
.
getAppControl
()==
1
){
appControl
=
1
;
}
//封装当前任务的状态链
List
<
TaskStatusHistory
>
list
=
statusMap
.
get
(
vmsTosOrdersDto
.
getTaskNo
());
if
(
CollectionUtils
.
isEmpty
(
list
))
{
continue
;
}
//转换状态链,并判断是否有车辆启动状态, 这个方法的代码似乎有些问题
TaskStatusHistory
startTask
=
this
.
transferTaskStatus
(
list
);
vmsTosOrdersDto
.
setStatusHistoryList
(
list
);
//封装当前子任务的描述、耗时
long
endTime
=
list
.
get
(
list
.
size
()-
1
).
getCollectTime
();
//最后状态的时间
vmsTosOrdersDto
.
setCostTime
(
getCostTime
(
vmsTosOrdersDto
.
getCollectTime
(),
endTime
));
//最后状态时间-任务指令时间
String
description
=
vehicleDataUtil
.
generateTaskLocationDescription
(
vmsTosOrdersDto
.
getTaskLocationType
(),
vmsTosOrdersDto
.
getVehicleLocation
());
vmsTosOrdersDto
.
setLocationDescription
(
description
);
//大任务处理 非第一次进入, 结束上一个大任务,并开始新的大任务,根据任务的起点portType和任务类型标签VehicleTaskLabel来判断
/** 例如
* portType VehicleTaskLabel
* 1 2 |
* 1 2 | 大任务一
* 2 2 |————————
* 1 2 |
* 1 2 |大任务二
* 2 2 |——————
* 1 2 |
* 1 2 |大任务三
* 1 2 |
* 2 2 |______
*/
if
((
vmsTosOrdersDto
.
getPortType
()
==
startPortType
&&
lastPortType
!=
vmsTosOrdersDto
.
getPortType
()
&&
lastPortType
!=
0
)
||
(
lastVehicleTaskLabel
!=
vmsTosOrdersDto
.
getVehicleTaskLabel
()
&&
lastVehicleTaskLabel
!=
0
)){
//保存上一个大任务
kpiParentDto
.
setCostTime
(
getCostTime
(
kpiParentDto
.
getCollectTime
(),
kpiParentDto
.
getEndTime
()));
dateList
.
add
(
dateStageDto
);
kpiParentDto
.
setStatusDateList
(
dateList
);
kpiParentDto
.
setVmsOrderList
(
orderList
);
kpiOrderList
.
add
(
kpiParentDto
);
//新建一个大任务
kpiParentDto
=
new
VmsTosOrdersKpiDto
();
//新建任务列表
orderList
=
new
ArrayList
<>();
//新建时间列表
dateList
=
new
ArrayList
<>();
//大任务开始时间
kpiParentDto
.
setCollectTime
(
vmsTosOrdersDto
.
getCollectTime
());
kpiParentDto
.
setTaskNo
(
vmsTosOrdersDto
.
getTaskNo
());
kpiParentDto
.
setContainerId
(
vmsTosOrdersDto
.
getContainerId
());
kpiParentDto
.
setContainerSize
(
vmsTosOrdersDto
.
getContainerSize
());
kpiParentDto
.
setContainerWeight
(
vmsTosOrdersDto
.
getContainerWeight
());
kpiParentDto
.
setVehicleNum
(
vmsTosOrdersDto
.
getVehicleNum
());
kpiParentDto
.
setVehicleTaskLabel
(
vmsTosOrdersDto
.
getVehicleTaskLabel
());
kpiParentDto
.
setTaskSource
(
vmsTosOrdersDto
.
getTaskSource
());
kpiParentDto
.
setAppControl
(
appControl
);
}
//新建一个子任务时间对象,并赋值子任务开始时间
if
(
vmsTosOrdersDto
.
getPortType
()
!=
lastPortType
){
if
(
dateStageDto
!=
null
&&
vmsTosOrdersDto
.
getPortType
()
!=
startPortType
){
dateList
.
add
(
dateStageDto
);
}
dateStageDto
=
new
VehicleDateStageDto
();
dateStageDto
.
setReceiveTosDate
(
vmsTosOrdersDto
.
getCollectTime
());
}
//赋值子任务车辆启动时间
if
(
startTask
!=
null
){
dateStageDto
.
setVehicleStartDate
(
startTask
.
getCollectTime
());
}
//赋值子任务结束时间
if
((
i
<
ordersDtosList
.
size
()
-
1
&&
ordersDtosList
.
get
(
i
+
1
).
getPortType
()
!=
vmsTosOrdersDto
.
getPortType
()
&&
vmsTosOrdersDto
.
getEndTime
()
!=
null
)
||
i
==
ordersDtosList
.
size
()
-
1
){
dateStageDto
.
setFinishDate
(
vmsTosOrdersDto
.
getEndTime
()
!=
null
?
vmsTosOrdersDto
.
getEndTime
().
getTime
():
null
);
}
//设置大任务信息(存在第二段任务,将第一段任务覆盖)
if
(
vmsTosOrdersDto
.
getPortType
()
!=
startPortType
){
kpiParentDto
.
setContainerId
(
vmsTosOrdersDto
.
getContainerId
());
kpiParentDto
.
setContainerSize
(
vmsTosOrdersDto
.
getContainerSize
());
kpiParentDto
.
setContainerWeight
(
vmsTosOrdersDto
.
getContainerWeight
());
kpiParentDto
.
setVehicleNum
(
vmsTosOrdersDto
.
getVehicleNum
());
kpiParentDto
.
setVehicleTaskLabel
(
vmsTosOrdersDto
.
getVehicleTaskLabel
());
kpiParentDto
.
setAppControl
(
appControl
);
}
else
{
kpiParentDto
.
setTaskNo
(
vmsTosOrdersDto
.
getTaskNo
());
kpiParentDto
.
setTaskSource
(
vmsTosOrdersDto
.
getTaskSource
());
}
kpiParentDto
.
setEndTime
(
endTime
);
orderList
.
add
(
vmsTosOrdersDto
);
lastPortType
=
vmsTosOrdersDto
.
getPortType
();
lastVehicleTaskLabel
=
vmsTosOrdersDto
.
getVehicleTaskLabel
();
}
kpiParentDto
.
setCostTime
(
"0"
);
//保存最后一个大任务
if
(
Objects
.
nonNull
(
kpiParentDto
.
getCollectTime
())&&
Objects
.
nonNull
(
kpiParentDto
.
getEndTime
())){
kpiParentDto
.
setCostTime
(
getCostTime
(
kpiParentDto
.
getCollectTime
(),
kpiParentDto
.
getEndTime
()));
}
if
(
Objects
.
nonNull
(
dateStageDto
)){
dateList
.
add
(
dateStageDto
);
}
kpiParentDto
.
setStatusDateList
(
dateList
);
kpiParentDto
.
setVmsOrderList
(
orderList
);
kpiOrderList
.
add
(
kpiParentDto
);
return
kpiOrderList
;
}
//根据状态模板转化
private
TaskStatusHistory
transferTaskStatus
(
List
<
TaskStatusHistory
>
list
)
{
int
transferNum
=
0
;
TaskStatusHistory
startTask
=
null
;
for
(
Integer
status
:
VehicleConstant
.
statusTemp
){
TaskStatusHistory
historyStatus
=
null
;
if
(
transferNum
<
list
.
size
()){
historyStatus
=
list
.
get
(
transferNum
);
if
(
historyStatus
.
getStatus
()
==
VehicleConstant
.
START_TASK
){
startTask
=
historyStatus
;
}
if
(
historyStatus
.
getStatus
()
==
VehicleConstant
.
TASK_FAIL
&&
transferNum
<
list
.
size
()-
1
){
list
.
remove
(
0
);
}
//任务终止、取消成功状态,直接返回
if
(
historyStatus
.
getStatus
()
==
VehicleConstant
.
TASK_FAIL
||
historyStatus
.
getStatus
()
==
VehicleConstant
.
TASK_CANCEL_SUCCESS
||
historyStatus
.
getStatus
()
==
VehicleConstant
.
FORCE_CANCEL_SUCCESS
){
break
;
}
//状态不存在于模板中,跳过该状态
if
(!
VehicleConstant
.
statusTemp
.
contains
(
historyStatus
.
getStatus
())){
transferNum
++;
if
(
transferNum
>=
list
.
size
()){
continue
;
}
historyStatus
=
list
.
get
(
transferNum
);
//???跳过当前状态,进入下一状态
}
//当前状态与模板一致
if
(
historyStatus
.
getStatus
()
==
status
){
transferNum
++;
continue
;
}
}
//构建缺失的状态数据
TaskStatusHistory
transferStatus
=
new
TaskStatusHistory
();
VmsTosOrderStatusEnum
anEnum
=
VmsTosOrderStatusEnum
.
find
(
status
);
//获取当前状态的状态描述
if
(
anEnum
!=
null
)
{
transferStatus
.
setStatusDescription
(
anEnum
.
getDescription
());
}
transferStatus
.
setStatus
(
status
);
if
(
transferNum
-
1
>=
0
){
historyStatus
=
list
.
get
(
transferNum
-
1
);
}
transferStatus
.
setVehicleNum
(
historyStatus
.
getVehicleNum
());
transferStatus
.
setCollectTime
(
historyStatus
.
getCollectTime
());
transferStatus
.
setSn
(
historyStatus
.
getSn
());
transferStatus
.
setVin
(
historyStatus
.
getVin
());
transferStatus
.
setExisted
(
false
);
list
.
add
(
transferNum
,
transferStatus
);
transferNum
++;
}
return
startTask
;
}
@Override
public
void
export
(
VmsTosOrdersVo
vmsTosOrdersVo
,
HttpServletResponse
response
)
{
int
exportType
=
vmsTosOrdersVo
.
getExportType
();
List
<
VmsTosOrders
>
list
;
ExcelDataHandlerDefaultImpl
<
Object
>
excelDataHandler
=
new
ExcelDataHandlerDefaultImpl
<
Object
>()
{
@Override
public
String
[]
getNeedHandlerFields
()
{
return
new
String
[]{
"作业时间"
,
"指令来源"
,
"APP介入"
};
}
@Override
public
Object
exportHandler
(
Object
obj
,
String
name
,
Object
value
)
{
if
(
"作业时间"
.
equals
(
name
))
{
VmsTosOrders
order
=
(
VmsTosOrders
)
obj
;
return
getCostTime
(
order
);
}
if
(
"指令来源"
.
equals
(
name
)){
if
(
1
==
(
Integer
)
value
){
return
"TOS下发"
;}
else
if
(
2
==
(
Integer
)
value
){
return
"手动下发"
;}
else
if
(
3
==
(
Integer
)
value
){
return
"VMS下发"
;}
}
if
(
"APP介入"
.
equals
(
name
)){
return
1
==
(
Integer
)
value
?
"是"
:
"否"
;
}
return
super
.
exportHandler
(
obj
,
name
,
value
);
}
};
if
(
vmsTosOrdersVo
.
getStartTime
()
==
null
){
Calendar
calendar
=
Calendar
.
getInstance
();
calendar
.
add
(
Calendar
.
MONTH
,-
3
);
vmsTosOrdersVo
.
setStartTime
(
calendar
.
getTime
());
}
if
(
exportType
==
0
)
{
SSIPage
ssiPage
=
queryPage
(
vmsTosOrdersVo
);
list
=
(
List
<
VmsTosOrders
>)
ssiPage
.
getList
();
PoiUtils
.
exportExcel
(
excelDataHandler
,
list
,
"任务清单"
,
"ChargeOrder"
,
VmsTosOrders
.
class
,
"任务清单"
+
".xls"
,
true
,
response
);
}
else
{
vmsTosOrdersVo
.
setPageIndex
(
1
);
vmsTosOrdersVo
.
setPageSize
(
1000000
);
SSIPage
ssiPage
=
queryPage
(
vmsTosOrdersVo
);
list
=
(
List
<
VmsTosOrders
>)
ssiPage
.
getList
();
PoiUtils
.
exportExcel
(
excelDataHandler
,
list
,
"任务清单"
,
"ChargeOrder"
,
VmsTosOrders
.
class
,
"任务清单"
+
".xls"
,
true
,
response
);
// ExcelBatchExportService batchExportService = new ExcelBatchExportService();
// ExportParams exportParams = new ExportParams("任务清单", "任务清单");
// exportParams.setDataHandler(excelDataHandler);
// exportParams.setMaxNum(1000000);
// batchExportService.init(exportParams, VmsTosOrdersVo.class);
// this.getBaseMapper().getListAsStream(vmsTosOrdersVo, resultContext -> {
// VmsTosOrders orders = resultContext.getResultObject();
// batchExportService.appendData(Arrays.asList(orders));
// });
// Workbook workbook = batchExportService.closeExportBigExcel();
// PoiUtils.downLoadExcel("任务清单.xlsx", response, workbook);
}
}
private
String
formatTime
(
BigDecimal
seconds
)
{
int
sec
=
seconds
.
intValue
();
if
(
sec
<
0
)
{
return
"0秒"
;
}
StringBuilder
sb
=
new
StringBuilder
();
if
(
sec
<
60
)
{
sb
.
append
(
seconds
+
"秒"
);
}
else
if
(
sec
>=
60
&&
sec
<
3600
)
{
int
m
=
sec
/
60
;
int
s
=
sec
%
60
;
sb
.
append
(
m
+
"分"
);
if
(
s
>
0
)
{
sb
.
append
(
s
+
"秒"
);
}
}
else
{
int
h
=
sec
/
3600
;
int
m
=
(
sec
%
3600
)
/
60
;
int
s
=
(
sec
%
3600
)
%
60
;
sb
.
append
(
h
+
"小时"
);
if
(
m
>
0
)
{
sb
.
append
(
m
+
"分"
);
}
if
(
s
>
0
)
{
sb
.
append
(
s
+
"秒"
);
}
}
return
sb
.
toString
();
}
/**
* 根据异常报警查询行程
*/
@Override
public
SSIResponse
getTripByAlert
(
String
vin
,
String
alertId
)
{
VmsVehicleAlertHistory
alertHistory
=
vehicleTroubleService
.
getById
(
alertId
);
if
(
alertHistory
==
null
)
{
return
SSIResponse
.
ok
();
}
List
<
VmsTosOrders
>
list
=
this
.
list
(
new
LambdaQueryWrapper
<
VmsTosOrders
>()
.
eq
(
StringUtils
.
isNotBlank
(
vin
),
VmsTosOrders:
:
getVin
,
vin
)
.
le
(
alertHistory
.
getAlarmTime
()
!=
null
,
VmsTosOrders:
:
getStartTime
,
alertHistory
.
getAlarmTime
())
.
ge
(
alertHistory
.
getAlarmTime
()
!=
null
,
VmsTosOrders:
:
getEndTime
,
alertHistory
.
getAlarmTime
())
.
orderByDesc
(
VmsTosOrders:
:
getStartTime
));
if
(
list
!=
null
&&
!
list
.
isEmpty
())
{
return
SSIResponse
.
ok
(
list
.
get
(
0
));
}
return
SSIResponse
.
ok
();
}
/**
* 获得各业务箱数
*/
@Override
@Cached
(
name
=
"vmsTosOrdersServiceImpl:queryContainerNumOneDay"
,
expire
=
60
,
timeUnit
=
TimeUnit
.
SECONDS
)
@CacheRefresh
(
refresh
=
30
,
stopRefreshAfterLastAccess
=
1440
,
timeUnit
=
TimeUnit
.
SECONDS
)
public
SSIResponse
queryContainerNumOneDay
(
LocalDateTime
startTime
,
LocalDateTime
endTime
)
{
List
<
TaskAnalysisVo
>
list
=
this
.
getBaseMapper
().
queryContainerNumByDay
(
startTime
,
endTime
);
if
(
CollectionUtils
.
isEmpty
(
list
))
{
TaskAnalysisVo
vo
=
new
TaskAnalysisVo
();
vo
.
setDate
(
startTime
.
toLocalDate
());
vo
.
setHandleContainerNum
(
0
);
vo
.
setLoadContainerNum
(
0
);
vo
.
setUnloadContainerNum
(
0
);
return
SSIResponse
.
ok
(
vo
);
}
return
SSIResponse
.
ok
(
list
.
get
(
0
));
}
@Override
@Cached
(
name
=
"vmsTosOrdersServiceImpl:queryContainerNum"
,
expire
=
60
,
timeUnit
=
TimeUnit
.
SECONDS
)
@CacheRefresh
(
refresh
=
30
,
stopRefreshAfterLastAccess
=
1440
,
timeUnit
=
TimeUnit
.
SECONDS
)
public
SSIResponse
queryContainerNum
()
{
TaskAnalysisVo
vo
=
this
.
getBaseMapper
().
queryContainerNum
(
null
,
null
,
null
);
return
SSIResponse
.
ok
(
vo
);
}
/**
* 获得最近n天各业务箱数
*/
@Override
@Cached
(
name
=
"vmsTosOrdersServiceImpl:queryContainerNumByDay"
,
expire
=
60
,
timeUnit
=
TimeUnit
.
SECONDS
)
@CacheRefresh
(
refresh
=
30
,
stopRefreshAfterLastAccess
=
1440
,
timeUnit
=
TimeUnit
.
SECONDS
)
public
SSIResponse
queryContainerNumByDay
(
LocalDateTime
startTime
,
LocalDateTime
endTime
)
throws
Exception
{
if
(
startTime
.
isAfter
(
endTime
))
{
return
SSIResponse
.
no
(
"查询起始时间需在结束时间之前"
);
}
List
<
TaskAnalysisVo
>
list
=
vmsTosOrdersAnalysisMapper
.
getTaskTrendByDay
(
startTime
,
endTime
);
List
<
DayHourTrend
>
resList
=
TaskAnalysisVo
.
fillBlankDay
(
list
,
TaskAnalysisVo
.
class
,
startTime
,
endTime
);
return
SSIResponse
.
ok
(
resList
);
}
/**
* 获得各业务运输效率
*/
@Override
@Cached
(
name
=
"vmsTosOrdersServiceImpl:queryContainerAvgTimeOneDay"
,
expire
=
60
,
timeUnit
=
TimeUnit
.
SECONDS
)
@CacheRefresh
(
refresh
=
30
,
stopRefreshAfterLastAccess
=
1440
,
timeUnit
=
TimeUnit
.
SECONDS
)
public
SSIResponse
queryContainerAvgTimeOneDay
(
LocalDateTime
startTime
,
LocalDateTime
endTime
)
{
List
<
TaskAnalysisVo
>
list
=
this
.
getBaseMapper
().
queryContainerAvgTimeByDay
(
startTime
,
endTime
);
if
(
CollectionUtils
.
isEmpty
(
list
))
{
TaskAnalysisVo
vo
=
new
TaskAnalysisVo
();
vo
.
setDate
(
startTime
.
toLocalDate
());
vo
.
setHandleContainerAvgTime
(
0
d
);
vo
.
setLoadContainerAvgTime
(
0
d
);
vo
.
setUnloadContainerAvgTime
(
0
d
);
return
SSIResponse
.
ok
(
vo
);
}
return
SSIResponse
.
ok
(
list
.
get
(
0
));
}
@Override
@Cached
(
name
=
"vmsTosOrdersServiceImpl:queryContainerAvgTime"
,
expire
=
60
,
timeUnit
=
TimeUnit
.
SECONDS
)
@CacheRefresh
(
refresh
=
30
,
stopRefreshAfterLastAccess
=
1440
,
timeUnit
=
TimeUnit
.
SECONDS
)
public
SSIResponse
queryContainerAvgTime
()
{
TaskAnalysisVo
vo
=
this
.
getBaseMapper
().
queryContainerAvgTime
(
null
,
null
,
null
);
return
SSIResponse
.
ok
(
vo
);
}
@Override
public
SSIResponse
getNumByVin
(
String
vin
)
{
Map
<
String
,
Integer
>
resultMap
=
new
HashMap
<>();
AtomicInteger
loadingGoodsNum
=
new
AtomicInteger
(
0
);
AtomicInteger
unloadingGoodsNum
=
new
AtomicInteger
(
0
);
AtomicInteger
arrangeGoodsNum
=
new
AtomicInteger
(
0
);
List
<
VmsTosOrders
>
list
=
this
.
list
(
new
LambdaQueryWrapper
<
VmsTosOrders
>().
eq
(
VmsTosOrders:
:
getVin
,
vin
));
list
.
parallelStream
().
forEach
(
vmsTosOrders
->
{
if
(
vmsTosOrders
.
getTaskType
()
!=
null
&&
vmsTosOrders
.
getVehicleTaskLabel
()
!=
null
)
{
Integer
containerNum
=
vmsTosOrders
.
getContainerNum
()
!=
null
?
vmsTosOrders
.
getContainerNum
()
:
0
;
Integer
vehicleTaskLabel
=
vmsTosOrders
.
getVehicleTaskLabel
();
Integer
taskType
=
vmsTosOrders
.
getTaskType
();
if
(
vehicleTaskLabel
==
2
&&
taskType
==
1
)
{
unloadingGoodsNum
.
getAndAdd
(
containerNum
);
}
else
if
(
vehicleTaskLabel
==
1
&&
taskType
==
2
)
{
loadingGoodsNum
.
getAndAdd
(
containerNum
);
}
else
if
(
vehicleTaskLabel
==
3
&&
taskType
==
1
)
{
arrangeGoodsNum
.
getAndAdd
(
containerNum
);
}
}
});
resultMap
.
put
(
"loadingGoodsNum"
,
loadingGoodsNum
.
intValue
());
resultMap
.
put
(
"unloadingGoodsNum"
,
unloadingGoodsNum
.
intValue
());
resultMap
.
put
(
"arrangeGoodsNum"
,
arrangeGoodsNum
.
intValue
());
return
SSIResponse
.
ok
(
resultMap
);
}
/**
* 获取当前pad对应桥吊可选车辆
*/
@Override
public
SSIResponse
getVehicleByPadMac
(
String
padMac
,
String
taskNo
)
{
// List<VehicleOrderVo> list = baseMapper.getVehicleByPadMac(padMac);
// VehicleOrderVo cur = null;
// for (int i = 0; i < list.size(); i++) {
// if (taskNo.equals(list.get(i).getTaskNo())) {
// cur = list.get(i);
// list.remove(i);
// }
// }
// list.add(0, cur);
// return SSIResponse.ok(list);
List
<
VmsVehicle
>
normalVehicle
=
vmsVehicleService
.
getNormalVehicle
();
Map
<
String
,
VmsVehicle
>
vinMap
=
normalVehicle
.
stream
().
collect
(
Collectors
.
toMap
(
VmsVehicle:
:
getVin
,
Function
.
identity
()));
List
<
VmsCranePadBind
>
padBindList
=
vmsCranePadBindService
.
list
(
new
LambdaQueryWrapper
<
VmsCranePadBind
>().
eq
(
VmsCranePadBind:
:
getPadMac
,
padMac
));
String
craneNo
=
padBindList
.
get
(
0
).
getCraneNo
();
//判断港机类型
Integer
taskLocationType
=
padBindList
.
get
(
0
).
getCraneType
()
==
1
?
5
:
1
;
//获取当前所有任务
Set
<
String
>
keys
=
redisDataModel
.
keys
(
latestOrderKeyPrefix
+
"*"
);
List
<
String
>
orderList
=
redisDataModel
.
mget
(
keys
.
toArray
(
new
String
[
keys
.
size
()]));
List
<
VehicleOrderVo
>
vehicleOrderVos
=
Lists
.
newArrayList
();
if
(
CollectionUtils
.
isNotEmpty
(
keys
))
{
if
(
CollectionUtils
.
isNotEmpty
(
orderList
))
{
List
<
VmsTosOrders
>
res
=
orderList
.
stream
().
map
(
s
->
JSON
.
parseObject
(
s
,
VmsTosOrders
.
class
))
.
filter
(
vmsTosOrders
->
{
if
(
craneNo
.
equals
(
vmsTosOrders
.
getPortCode
())
&&
!
VehicleUtil
.
isTaskOver
(
vmsTosOrders
.
getStatus
())
&&
vmsTosOrders
.
getTaskLocationType
()
==
taskLocationType
)
{
return
true
;
}
return
false
;
}).
collect
(
Collectors
.
toList
());
if
(!
res
.
isEmpty
())
{
res
=
res
.
stream
().
sorted
(
Comparator
.
comparing
(
VmsTosOrders:
:
getCollectTime
)).
collect
(
Collectors
.
toList
());
res
.
stream
().
forEach
(
vmsTosOrders
->
{
VmsVehicle
vmsVehicle
=
vinMap
.
get
(
vmsTosOrders
.
getVin
());
if
(
vmsVehicle
==
null
)
{
return
;
}
VehicleOrderVo
vehicleOrderVo
=
new
VehicleOrderVo
();
BeanUtils
.
copyProperties
(
vmsVehicle
,
vehicleOrderVo
);
vehicleOrderVo
.
setStartTime
(
vmsTosOrders
.
getStartTime
());
vehicleOrderVo
.
setTaskNo
(
vmsTosOrders
.
getTaskNo
());
vehicleOrderVos
.
add
(
vehicleOrderVo
);
});
VehicleOrderVo
cur
=
null
;
for
(
int
i
=
0
;
i
<
vehicleOrderVos
.
size
();
i
++)
{
if
(
taskNo
.
equals
(
vehicleOrderVos
.
get
(
i
).
getTaskNo
()))
{
cur
=
vehicleOrderVos
.
get
(
i
);
vehicleOrderVos
.
remove
(
i
);
}
}
if
(
cur
!=
null
)
{
vehicleOrderVos
.
add
(
0
,
cur
);
}
}
}
}
return
SSIResponse
.
ok
(
vehicleOrderVos
);
}
/**
* 查询任务状态历史
*/
@Override
public
SSIResponse
getTaskHistory
(
String
taskNo
)
{
List
<
VmsTosOrders
>
orders
=
this
.
lambdaQuery
().
eq
(
VmsTosOrders:
:
getTaskNo
,
taskNo
)
// .eq(VmsTosOrders::getDeleted, 0)
.
list
();
if
(
CollectionUtils
.
isEmpty
(
orders
))
{
return
SSIResponse
.
no
(
"任务不存在"
);
}
Date
collectTime
=
new
Date
(
orders
.
get
(
0
).
getCollectTime
());
String
year
=
DateUtils
.
format
(
collectTime
,
"yyyy"
);
List
<
TaskStatusHistory
>
list
=
vehicleElasticSearchModel
.
searchTaskHistory
(
taskNo
,
year
);
if
(
CollectionUtils
.
isNotEmpty
(
list
))
{
list
.
forEach
(
taskStatusHistory
->
{
Map
<
String
,
Object
>
map
=
redisDataModel
.
hgetJson2Map
(
vehicleCacheKey
,
taskStatusHistory
.
getVin
());
String
num
=
(
String
)
map
.
get
(
"vehicleNum"
);
taskStatusHistory
.
setVehicleNum
(
num
);
});
}
return
SSIResponse
.
ok
(
list
);
}
/**
* 进行中的任务列表
*/
@Override
public
SSIPage
listInProcess
(
VmsTosOrdersVo
vmsTosOrdersVo
)
{
if
(
vmsTosOrdersVo
==
null
)
{
vmsTosOrdersVo
=
new
VmsTosOrdersVo
();
}
String
vehicleNum
=
vmsTosOrdersVo
.
getVehicleNum
();
if
(
StringUtils
.
isNotBlank
(
vehicleNum
))
{
VmsVehicle
vehicle
=
vmsVehicleService
.
lambdaQuery
().
eq
(
VmsVehicle:
:
getVehicleNum
,
vehicleNum
).
one
();
if
(
vehicle
==
null
)
{
return
new
SSIPage
(
new
Page
<>());
}
vmsTosOrdersVo
.
setVin
(
vehicle
.
getVin
());
}
LocalDateTime
dateTime
=
LocalDateTime
.
now
().
minus
(
24
,
ChronoUnit
.
HOURS
);
Date
startTime
=
Date
.
from
(
dateTime
.
atZone
(
ZoneId
.
systemDefault
()).
toInstant
());
IPage
<
VmsTosOrders
>
page
=
this
.
lambdaQuery
()
.
eq
(
vmsTosOrdersVo
.
getTaskType
()
!=
null
,
VmsTosOrders:
:
getTaskType
,
vmsTosOrdersVo
.
getTaskType
())
.
eq
(
vmsTosOrdersVo
.
getStatus
()
!=
null
,
VmsTosOrders:
:
getStatus
,
vmsTosOrdersVo
.
getStatus
())
.
eq
(
VmsTosOrders:
:
getDeleted
,
0
)
.
like
(
StringUtils
.
isNotBlank
(
vmsTosOrdersVo
.
getTaskNo
()),
VmsTosOrders:
:
getTaskNo
,
vmsTosOrdersVo
.
getTaskNo
())
.
like
(
StringUtils
.
isNotBlank
(
vmsTosOrdersVo
.
getVin
()),
VmsTosOrders:
:
getVin
,
vmsTosOrdersVo
.
getVin
())
.
ge
(
VmsTosOrders:
:
getCollectTime
,
startTime
)
.
notIn
(
VmsTosOrders:
:
getStatus
,
35
,
36
,
37
)
.
orderByDesc
(
VmsTosOrders:
:
getCollectTime
)
.
page
(
new
Page
<>(
vmsTosOrdersVo
.
getPageIndex
(),
vmsTosOrdersVo
.
getPageSize
()));
List
<
VmsTosOrders
>
records
=
page
.
getRecords
();
if
(
CollectionUtils
.
isNotEmpty
(
records
))
{
records
.
forEach
(
vmsTosOrders
->
{
try
{
String
costTime
=
getCostTime
(
vmsTosOrders
);
vmsTosOrders
.
setCostTime
(
costTime
);
Map
<
String
,
Object
>
map
=
redisDataModel
.
hgetJson2Map
(
vehicleCacheKey
,
vmsTosOrders
.
getVin
());
String
num
=
(
String
)
map
.
get
(
"vehicleNum"
);
vmsTosOrders
.
setVehicleNum
(
num
);
}
catch
(
Exception
e
)
{
log
.
error
(
"获取时间、车辆编号异常:"
,
e
);
}
});
}
return
new
SSIPage
(
page
);
}
private
String
getCostTime
(
long
startTime
,
long
endTime
)
{
Date
startDate
=
new
Date
(
startTime
);
Date
endDate
=
new
Date
(
endTime
);
return
getCostTime
(
startDate
,
endDate
);
}
private
String
getCostTime
(
VmsTosOrders
vmsTosOrders
)
{
Date
startTime
=
new
Date
(
vmsTosOrders
.
getCollectTime
());
Date
endTime
=
vmsTosOrders
.
getEndTime
();
if
(
endTime
==
null
)
{
endTime
=
vmsTosOrders
.
getUpdateTime
();
}
if
(
startTime
==
null
)
{
return
""
;
}
long
diff
=
0
;
if
(
endTime
!=
null
)
{
diff
=
endTime
.
getTime
()
-
startTime
.
getTime
();
}
BigDecimal
timeSeconds
=
new
BigDecimal
(
diff
).
divide
(
new
BigDecimal
(
1000
),
0
,
BigDecimal
.
ROUND_HALF_UP
);
vmsTosOrders
.
setCostTimeSeconds
(
timeSeconds
.
intValue
());
return
formatTime
(
timeSeconds
);
}
private
String
getCostTime
(
Date
startTime
,
Date
endTime
)
{
if
(
startTime
==
null
)
{
return
""
;
}
long
diff
=
0
;
if
(
endTime
!=
null
)
{
diff
=
endTime
.
getTime
()
-
startTime
.
getTime
();
}
BigDecimal
timeSeconds
=
new
BigDecimal
(
diff
).
divide
(
new
BigDecimal
(
1000
),
0
,
BigDecimal
.
ROUND_HALF_UP
);
String
time
=
formatTime
(
timeSeconds
);
return
time
;
}
/**
* 实时任务列表
*/
@Override
public
SSIPage
realTimeTasks
(
VmsTosOrdersVo
vmsTosOrdersVo
)
{
Page
<
VmsVehicle
>
page
=
vmsVehicleService
.
page
(
new
Page
<>(
vmsTosOrdersVo
.
getPageIndex
(),
vmsTosOrdersVo
.
getPageSize
()),
new
LambdaQueryWrapper
<
VmsVehicle
>().
eq
(
VmsVehicle:
:
getStatus
,
0
));
List
<
VmsVehicle
>
vehicles
=
page
.
getRecords
();
if
(
CollectionUtils
.
isNotEmpty
(
vehicles
))
{
List
<
Map
<
String
,
Object
>>
list
=
vehicles
.
stream
().
map
(
vmsVehicle
->
{
Map
<
String
,
Object
>
map
=
redisDataModel
.
getJson2Map
(
String
.
format
(
"%s:%s"
,
latestOrderKeyPrefix
,
vmsVehicle
.
getVin
()));
if
(
map
!=
null
)
{
String
description
=
vehicleDataUtil
.
generateTaskLocationDescription
(
map
);
map
.
put
(
"locationDescription"
,
description
);
Date
collectTime
=
null
;
if
(
map
.
get
(
"collectTime"
)
!=
null
)
{
collectTime
=
new
Date
((
long
)
map
.
get
(
"collectTime"
));
}
Date
endTime
=
null
;
if
(
map
.
get
(
"endTime"
)
!=
null
)
{
endTime
=
new
Date
((
long
)
map
.
get
(
"endTime"
));
}
map
.
put
(
"costTime"
,
getCostTime
(
collectTime
,
endTime
));
map
.
put
(
"vehicleNum"
,
vmsVehicle
.
getVehicleNum
());
VmsVehicleRemoteInstruction
queryEntity
=
new
VmsVehicleRemoteInstruction
();
queryEntity
.
setInstructionType
(
"APP"
);
queryEntity
.
setResult
((
byte
)
1
);
queryEntity
.
setTaskId
(
map
.
get
(
"taskNo"
)+
","
+
map
.
get
(
"taskNoMapping"
));
Integer
count
=
vehicleRemoteInstructionMapper
.
selectCount
(
new
QueryWrapper
<>(
queryEntity
));
map
.
put
(
"appControl"
,
0
);
if
(
count
>
0
){
map
.
put
(
"appControl"
,
1
);
}
if
(
Objects
.
isNull
(
map
.
get
(
"taskSource"
))){
map
.
put
(
"taskSource"
,
1
);
}
}
else
{
map
=
new
HashMap
<>();
map
.
put
(
"vehicleNum"
,
vmsVehicle
.
getVehicleNum
());
map
.
put
(
"collectTime"
,
0L
);
}
return
map
;
}).
sorted
((
o1
,
o2
)
->
(
long
)
o1
.
get
(
"collectTime"
)
>
(
long
)
o2
.
get
(
"collectTime"
)
?
-
1
:
1
)
.
collect
(
Collectors
.
toList
());
return
new
SSIPage
(
list
,
(
int
)
page
.
getTotal
(),
(
int
)
page
.
getSize
(),
(
int
)
page
.
getCurrent
());
}
return
new
SSIPage
(
null
,
(
int
)
page
.
getTotal
(),
(
int
)
page
.
getSize
(),
(
int
)
page
.
getCurrent
());
}
/**
* 获取某一天的任务KPI
*/
@Override
public
List
getDailyKpi
(
LocalDateTime
startTime
,
LocalDateTime
endTime
,
String
vehicleNum
)
{
List
<
VmsVehicle
>
vehicles
=
vmsVehicleService
.
list
(
new
LambdaQueryWrapper
<
VmsVehicle
>()
.
eq
(
VmsVehicle:
:
getStatus
,
0
)
.
like
(
StringUtils
.
isNotBlank
(
vehicleNum
),
VmsVehicle:
:
getVehicleNum
,
vehicleNum
)
.
orderByAsc
(
VmsVehicle:
:
getVehicleNum
));
List
<
VehicleKpiVo
.
HourKpi
>
list
=
getBaseMapper
().
getDailyKpi
(
startTime
,
endTime
);
List
<
Map
<
String
,
Object
>>
containerList
=
getBaseMapper
().
getContainNum
(
startTime
,
endTime
);
Map
<
String
,
String
>
containerMap
=
new
HashedMap
();
for
(
Map
<
String
,
Object
>
map
:
containerList
)
{
containerMap
.
put
(
String
.
valueOf
(
map
.
get
(
"vin"
)),
String
.
valueOf
(
map
.
get
(
"count"
)));
}
if
(
CollectionUtils
.
isNotEmpty
(
vehicles
))
{
List
<
Map
>
resList
=
vehicles
.
stream
().
map
(
vmsVehicle
->
{
try
{
String
vNum
=
vmsVehicle
.
getVehicleNum
();
String
vin
=
vmsVehicle
.
getVin
();
VehicleKpiVo
vehicleKpiVo
=
new
VehicleKpiVo
(
vin
,
vNum
);
vehicleKpiVo
.
setDate
(
startTime
.
format
(
DateTimeFormatter
.
ofPattern
(
"yyyy-MM-dd"
)));
vehicleKpiVo
.
fillData
(
list
);
Map
<
String
,
String
>
map
=
vehicleKpiVo
.
toMap
();
map
.
put
(
"containerNum"
,
containerMap
.
get
(
vin
)
!=
null
?
containerMap
.
get
(
vin
)
:
"0"
);
return
map
;
}
catch
(
Exception
e
)
{
log
.
error
(
"获取daily kpi异常"
,
e
);
}
return
null
;
}).
filter
(
map
->
map
!=
null
).
collect
(
Collectors
.
toList
());
return
resList
;
}
return
null
;
}
@Override
public
List
taskKPI
(
VmsTosOrdersKPIVo
vmsTosOrders
)
throws
Exception
{
//任务KPI-效率OEE分析
SimpleDateFormat
format
=
new
SimpleDateFormat
(
"yyyy-MM-dd HH:mm:ss"
);
List
<
TaskKPIVo
>
resLists
=
new
ArrayList
<>();
if
(
vmsTosOrders
.
getStartTime
()
==
null
||
vmsTosOrders
.
getEndTime
()
==
null
)
{
Calendar
calendar
=
Calendar
.
getInstance
();
calendar
.
set
(
calendar
.
get
(
Calendar
.
YEAR
),
calendar
.
get
(
Calendar
.
MONTH
),
calendar
.
get
(
Calendar
.
DAY_OF_MONTH
)
-
1
,
23
,
59
,
59
);
//昨天的时间
long
nowStartTime
=
calendar
.
getTime
().
getTime
();
//毫秒级时间戳
calendar
.
set
(
calendar
.
get
(
Calendar
.
YEAR
),
calendar
.
get
(
Calendar
.
MONTH
),
calendar
.
get
(
Calendar
.
DAY_OF_MONTH
)
-
3
,
00
,
00
,
00
);
//三天前的时间
long
nowEndTime
=
calendar
.
getTime
().
getTime
();
//毫秒级时间戳
resLists
=
vmsTosOrdersMapper
.
taskKPI
(
vmsTosOrders
,
String
.
valueOf
(
nowStartTime
),
String
.
valueOf
(
nowEndTime
));
//查询 任务KPI-效率OEE分析
}
else
{
resLists
=
vmsTosOrdersMapper
.
taskKPI
(
vmsTosOrders
,
null
,
null
);
//查询 任务KPI-效率OEE分析
}
List
<
TaskKPIVo
>
rest
=
new
ArrayList
<>();
for
(
int
i
=
0
;
i
<
resLists
.
size
();
i
++)
{
TaskKPIVo
taskKPIVo
=
new
TaskKPIVo
();
taskKPIVo
.
setVin
(
resLists
.
get
(
i
).
getVin
());
//VIN
taskKPIVo
.
setVehicleNum
(
resLists
.
get
(
i
).
getVehicleNum
());
//车辆编号
taskKPIVo
.
setTaskNo
(
resLists
.
get
(
i
).
getTaskNo
());
//任务编号
Date
collectTimeYear
=
format
.
parse
(
resLists
.
get
(
i
).
getInstructionWaitingTime
());
String
year
=
DateUtils
.
format
(
collectTimeYear
,
"yyyy"
);
List
<
TaskStatusHistory
>
list
=
vehicleElasticSearchModel
.
searchTaskHistory
(
resLists
.
get
(
i
).
getTaskNo
(),
year
);
Date
collectTime
=
format
.
parse
(
resLists
.
get
(
i
).
getInstructionWaitingTime
());
Long
vehicleReceivingTime
=
null
;
//车辆接收时间
Long
taskBegins
=
null
;
//任务开始
Long
destination
=
null
;
//到达目的地
Long
vehicleStoppingLocking
=
null
;
//车辆停稳锁死
Long
threeConfirmedCompletion
=
null
;
//三重确认完成
for
(
int
j
=
0
;
j
<
list
.
size
();
j
++)
{
if
(
list
.
get
(
j
).
getStatus
()
==
43
)
{
//车辆接受 43;
vehicleReceivingTime
=
list
.
get
(
j
).
getCollectTime
();
}
if
(
list
.
get
(
j
).
getStatus
()
==
15
)
{
//任务开始 15;
taskBegins
=
list
.
get
(
j
).
getCollectTime
();
}
if
(
list
.
get
(
j
).
getStatus
()
==
3
)
{
//到达目的地 3;
destination
=
list
.
get
(
j
).
getCollectTime
();
}
if
(
list
.
get
(
j
).
getStatus
()
==
49
)
{
//车辆停稳锁死 49;
vehicleStoppingLocking
=
list
.
get
(
j
).
getCollectTime
();
}
if
(
list
.
get
(
j
).
getStatus
()
==
37
)
{
//三重确认完成 37;
threeConfirmedCompletion
=
list
.
get
(
j
).
getCollectTime
();
}
}
//指令等待时间 = 车辆接收时间 - collect_time
if
(
vehicleReceivingTime
==
null
)
{
taskKPIVo
.
setInstructionWaitingTime
(
"0"
);
}
else
{
long
diff1
=
vehicleReceivingTime
-
collectTime
.
getTime
();
String
instruc
=
String
.
valueOf
(
diff1
/
(
60
*
1000
)
%
60
);
taskKPIVo
.
setInstructionWaitingTime
(
isNumeric
(
instruc
)
?
instruc
:
"0"
);
}
//作业准备时间 = 任务开始-车辆接受
if
(
vehicleReceivingTime
==
null
||
taskBegins
==
null
)
{
taskKPIVo
.
setHomeworkPreparationTime
(
"0"
);
}
else
{
long
diff2
=
taskBegins
-
vehicleReceivingTime
;
String
homework
=
String
.
valueOf
(
diff2
/
(
60
*
1000
)
%
60
);
taskKPIVo
.
setHomeworkPreparationTime
(
isNumeric
(
homework
)
?
homework
:
"0"
);
}
//移动到去箱点时间 = 到达目的地或者车辆停稳锁死-任务开始
if
(
taskBegins
==
null
)
{
taskKPIVo
.
setMoveTheBoxTime
(
"0"
);
}
else
{
if
(
vehicleStoppingLocking
!=
null
)
{
//车辆停稳锁死
long
diff3
=
vehicleStoppingLocking
-
taskBegins
;
String
moveThe
=
String
.
valueOf
(
diff3
/
(
60
*
1000
)
%
60
);
taskKPIVo
.
setMoveTheBoxTime
(
isNumeric
(
moveThe
)
?
moveThe
:
"0"
);
}
else
if
(
destination
!=
null
)
{
//到达目的地
long
diff3
=
destination
-
taskBegins
;
String
moveThe
=
String
.
valueOf
(
diff3
/
(
60
*
1000
)
%
60
);
taskKPIVo
.
setMoveTheBoxTime
(
isNumeric
(
moveThe
)
?
moveThe
:
"0"
);
}
else
{
// long diff3 = taskBegins.getTime();
// String moveThe = String.valueOf(diff3 / (60 * 1000) % 60);
// taskKPIVo.setMoveTheBoxTime(isNumeric(moveThe)? moveThe : "0");
taskKPIVo
.
setMoveTheBoxTime
(
"0"
);
}
}
//取箱点等待时间 = 三重确认完成-到达目的地或者车辆停稳锁死
if
(
threeConfirmedCompletion
==
null
)
{
taskKPIVo
.
setPickingTime
(
"0"
);
}
else
{
if
(
vehicleStoppingLocking
!=
null
)
{
//车辆停稳锁死
long
diff4
=
threeConfirmedCompletion
-
vehicleStoppingLocking
;
String
pickingTime
=
String
.
valueOf
(
diff4
/
(
60
*
1000
)
%
60
);
taskKPIVo
.
setPickingTime
(
isNumeric
(
pickingTime
)
?
pickingTime
:
"0"
);
}
else
if
(
destination
!=
null
)
{
//到达目的地
long
diff4
=
threeConfirmedCompletion
-
destination
;
String
pickingTime
=
String
.
valueOf
(
diff4
/
(
60
*
1000
)
%
60
);
taskKPIVo
.
setPickingTime
(
isNumeric
(
pickingTime
)
?
pickingTime
:
"0"
);
}
else
{
// long diff4 = threeConfirmedCompletion.getTime();
// String pickingTime = String.valueOf(diff4 / (60 * 1000) % 60);
// taskKPIVo.setPickingTime(isNumeric(pickingTime)? pickingTime : "0");
taskKPIVo
.
setPickingTime
(
"0"
);
}
}
taskKPIVo
.
setBoxQuantity
(
resLists
.
get
(
i
).
getBoxQuantity
());
rest
.
add
(
taskKPIVo
);
}
return
rest
;
}
/**
* 判断是否为数字,包含负数情况
*
* @param str
* @return
*/
private
boolean
isNumeric
(
String
str
)
{
Boolean
flag
=
false
;
String
tmp
;
if
(
StringUtils
.
isNotBlank
(
str
))
{
if
(
str
.
startsWith
(
"-"
))
{
tmp
=
str
.
substring
(
1
);
flag
=
false
;
return
flag
;
}
else
{
tmp
=
str
;
}
flag
=
tmp
.
matches
(
"^[0.0-9.0]+$"
);
}
return
flag
;
}
/**
* 车管平台强制取消
*/
@Override
public
SSIResponse
forceCancel
(
String
taskNo
)
{
log
.
info
(
"强制取消任务,任务编号:{}"
,
taskNo
);
VmsTosOrders
order
=
lambdaQuery
().
eq
(
VmsTosOrders:
:
getTaskNo
,
taskNo
).
one
();
if
(
order
==
null
)
{
return
SSIResponse
.
no
(
"任务不存在"
);
}
String
vin
=
order
.
getVin
();
String
url
=
commandUrl
+
"/command/force/cancel"
;
HashMap
<
String
,
Object
>
param
=
new
HashMap
<>();
param
.
put
(
"vin"
,
vin
);
param
.
put
(
"taskNo"
,
taskNo
);
param
.
put
(
"taskOperation"
,
2
);
AccessResponse
accessResponse
=
restTemplate
.
postForObject
(
url
,
param
,
AccessResponse
.
class
);
log
.
info
(
"强制取消任务,任务编号:"
+
taskNo
+
",返回结果:"
+
JSON
.
toJSONString
(
accessResponse
));
if
(
accessResponse
.
isSuccess
())
{
Map
data
=
(
Map
)
accessResponse
.
getData
();
Integer
res
=
(
Integer
)
data
.
get
(
"result"
);
if
(
res
==
1
)
{
return
SSIResponse
.
ok
(
"取消成功"
);
}
else
if
(
res
==
2
)
{
return
SSIResponse
.
no
(
"取消失败"
);
}
}
else
{
String
msg
=
accessResponse
.
getStatus
().
getDetails
();
return
SSIResponse
.
no
(
msg
);
}
return
SSIResponse
.
no
(
"取消成功"
);
}
}
ivccs-vmm-backservice/src/main/java/com/ssi/service/impl/VmsTosOriginalOrdersServiceImpl.java
0 → 100644
View file @
07602a7b
package
com.ssi.service.impl
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.ssi.entity.VmsTosOrders
;
import
com.ssi.entity.VmsTosOriginalOrders
;
import
com.ssi.entity.VmsVehicle
;
import
com.ssi.entity.vo.VmsTosOrdersVo
;
import
com.ssi.model.RedisDataModel
;
import
com.ssi.response.SSIPage
;
import
com.ssi.service.VmsTosOriginalOrdersService
;
import
com.ssi.mapper.VmsTosOriginalOrdersMapper
;
import
com.ssi.service.VmsVehicleService
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Service
;
import
java.math.BigDecimal
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Objects
;
import
java.util.stream.Collectors
;
/**
*
*/
@Service
public
class
VmsTosOriginalOrdersServiceImpl
extends
ServiceImpl
<
VmsTosOriginalOrdersMapper
,
VmsTosOriginalOrders
>
implements
VmsTosOriginalOrdersService
{
@Autowired
private
VmsVehicleService
vmsVehicleService
;
@Autowired
private
RedisDataModel
redisDataModel
;
@Value
(
"${order.latestOrderKeyPrefix:harbor:command:status}"
)
private
String
latestOrderKeyPrefix
;
@Value
(
"${vehicle.cache.key:ivccs:vms:vehicle:cache}"
)
private
String
vehicleCacheKey
;
@Override
public
SSIPage
queryPageByCondition
(
VmsTosOrdersVo
ordersVo
)
{
List
<
VmsVehicle
>
vehicles
=
vmsVehicleService
.
list
();
Map
<
String
,
String
>
vin2Num
=
vehicles
.
stream
().
collect
(
Collectors
.
toMap
(
VmsVehicle:
:
getVin
,
VmsVehicle:
:
getVehicleNum
));
String
vehicleNum
=
ordersVo
.
getVehicleNum
();
if
(
StringUtils
.
isNotBlank
(
vehicleNum
))
{
Map
.
Entry
<
String
,
String
>
currentEntry
=
vin2Num
.
entrySet
().
stream
().
filter
(
e
->
e
.
getValue
().
equalsIgnoreCase
(
"vehicleNum"
)).
findAny
().
orElse
(
null
);
if
(
currentEntry
==
null
)
{
return
new
SSIPage
(
new
Page
<>());
}
String
vin
=
currentEntry
.
getKey
();
ordersVo
.
setVin
(
vin
);
}
IPage
<
VmsTosOriginalOrders
>
iPage
=
new
Page
<>(
ordersVo
.
getPageIndex
(),
ordersVo
.
getPageSize
());
IPage
<
VmsTosOriginalOrders
>
page
=
baseMapper
.
pageQuery
(
iPage
,
ordersVo
);
List
<
VmsTosOriginalOrders
>
records
=
page
.
getRecords
();
if
(
CollectionUtils
.
isEmpty
(
records
))
{
return
new
SSIPage
(
page
);
}
records
.
forEach
(
vmsTosOrders
->
{
try
{
vmsTosOrders
.
setStartTimeStamp
(
vmsTosOrders
.
getStartTime
().
getTime
()/
1000
);
String
costTime
=
getCostTime
(
vmsTosOrders
);
vmsTosOrders
.
setCostTime
(
costTime
);
vmsTosOrders
.
setVehicleNum
(
vin2Num
.
get
(
vmsTosOrders
.
getVin
()));
//添加lockLabel
Map
<
String
,
Object
>
orderMap
=
redisDataModel
.
getJson2Map
(
String
.
format
(
"%s:%s"
,
latestOrderKeyPrefix
,
vmsTosOrders
.
getVin
()));
vmsTosOrders
.
setLockLabel
(
Objects
.
isNull
(
orderMap
.
get
(
"lockLabel"
))?
null
:(
Integer
)
orderMap
.
get
(
"lockLabel"
));
}
catch
(
Exception
e
)
{
log
.
error
(
"获取时间、车辆编号、地点描述异常:"
,
e
);
}
});
return
new
SSIPage
(
page
);
}
private
String
getCostTime
(
VmsTosOriginalOrders
vmsTosOrders
)
{
Date
startTime
=
new
Date
(
vmsTosOrders
.
getCollectTime
());
Date
endTime
=
vmsTosOrders
.
getEndTime
();
if
(
endTime
==
null
)
{
endTime
=
vmsTosOrders
.
getUpdateTime
();
}
if
(
startTime
==
null
)
{
return
""
;
}
long
diff
=
0
;
if
(
endTime
!=
null
)
{
diff
=
endTime
.
getTime
()
-
startTime
.
getTime
();
}
BigDecimal
timeSeconds
=
new
BigDecimal
(
diff
).
divide
(
new
BigDecimal
(
1000
),
0
,
BigDecimal
.
ROUND_HALF_UP
);
vmsTosOrders
.
setCostTimeSeconds
(
timeSeconds
.
intValue
());
return
formatTime
(
timeSeconds
);
}
private
String
formatTime
(
BigDecimal
seconds
)
{
int
sec
=
seconds
.
intValue
();
if
(
sec
<
0
)
{
return
"0秒"
;
}
StringBuilder
sb
=
new
StringBuilder
();
if
(
sec
<
60
)
{
sb
.
append
(
seconds
+
"秒"
);
}
else
if
(
sec
>=
60
&&
sec
<
3600
)
{
int
m
=
sec
/
60
;
int
s
=
sec
%
60
;
sb
.
append
(
m
+
"分"
);
if
(
s
>
0
)
{
sb
.
append
(
s
+
"秒"
);
}
}
else
{
int
h
=
sec
/
3600
;
int
m
=
(
sec
%
3600
)
/
60
;
int
s
=
(
sec
%
3600
)
%
60
;
sb
.
append
(
h
+
"小时"
);
if
(
m
>
0
)
{
sb
.
append
(
m
+
"分"
);
}
if
(
s
>
0
)
{
sb
.
append
(
s
+
"秒"
);
}
}
return
sb
.
toString
();
}
}
ivccs-vmm-backservice/src/main/java/com/ssi/service/impl/VmsTrafficLightInfoServiceImpl.java
0 → 100644
View file @
07602a7b
package
com.ssi.service.impl
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.ssi.constant.URL
;
import
com.ssi.constant.enums.TrafficLightEnum
;
import
com.ssi.entity.VmsTrafficLightInfo
;
import
com.ssi.mapper.VmsTrafficLightInfoMapper
;
import
com.ssi.model.RedisDataModel
;
import
com.ssi.response.SSIPage
;
import
com.ssi.service.VmsTrafficLightInfoService
;
import
com.ssi.utils.RestTemplateUtil
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.apache.commons.collections.MapUtils
;
import
org.apache.commons.lang.StringUtils
;
import
org.apache.http.util.Asserts
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Service
;
import
java.util.*
;
import
java.util.concurrent.locks.ReentrantLock
;
/**
*
*/
@Service
@Slf4j
public
class
VmsTrafficLightInfoServiceImpl
extends
ServiceImpl
<
VmsTrafficLightInfoMapper
,
VmsTrafficLightInfo
>
implements
VmsTrafficLightInfoService
{
@Autowired
private
RedisDataModel
redisDataModel
;
private
ReentrantLock
lock
=
new
ReentrantLock
();
@Value
(
"${map-edit-url}"
)
private
String
mapEditUrl
;
@Override
public
SSIPage
queryPage
(
VmsTrafficLightInfo
req
)
{
IPage
<
VmsTrafficLightInfo
>
page
=
new
Page
(
req
.
getPageIndex
(),
req
.
getPageSize
());
IPage
<
VmsTrafficLightInfo
>
quryResult
=
this
.
baseMapper
.
selectPage
(
page
,
new
QueryWrapper
<
VmsTrafficLightInfo
>()
.
eq
(
Objects
.
nonNull
(
req
.
getStatus
()),
"status"
,
req
.
getStatus
())
.
eq
(
StringUtils
.
isNotBlank
(
req
.
getCrossId
()),
"cross_id"
,
req
.
getCrossId
()));
//查询接入接口
List
<
VmsTrafficLightInfo
>
records
=
quryResult
.
getRecords
();
for
(
VmsTrafficLightInfo
info:
records
)
{
/* Map<String, Object> map = redisDataModel.hgetJson2Map("ivccs:vms:traffic:light", info.getCrossId());
if(MapUtils.isEmpty(map)){
continue;
}
List<JSONObject> lists = (List<JSONObject>)map.get("list");*/
List
<
JSONObject
>
lists
=
new
ArrayList
<>();
fillLights
(
"北向"
,
lists
);
fillLights
(
"南向"
,
lists
);
fillLights
(
"东向"
,
lists
);
fillLights
(
"西向"
,
lists
);
info
.
setLights
(
lists
);
}
return
new
SSIPage
(
quryResult
);
}
private
void
fillLights
(
String
faceDirect
,
List
<
JSONObject
>
lists
)
{
JSONObject
jsonObject
=
new
JSONObject
();
List
<
TrafficLightEnum
>
enums
=
TrafficLightEnum
.
getEnumsByPhaseNoFlagName
(
faceDirect
);
jsonObject
.
put
(
"direction"
,
faceDirect
);
for
(
int
i
=
0
;
i
<
enums
.
size
();
i
++)
{
jsonObject
.
put
(
enums
.
get
(
i
).
getDirectName
(),
enums
.
get
(
i
).
getPhaseNo
());
}
lists
.
add
(
jsonObject
);
}
@Override
public
String
manual
(
VmsTrafficLightInfo
req
)
{
if
(!
lock
.
tryLock
()){
return
"操作频繁,请稍后"
;
}
try
{
Asserts
.
notNull
(
req
.
getCrossId
(),
"CrossId"
);
String
lamps
=
req
.
getLampNos
();
lamps
=
getLamps
(
req
,
lamps
);
VmsTrafficLightInfo
one
=
this
.
lambdaQuery
().
eq
(
VmsTrafficLightInfo:
:
getCrossId
,
req
.
getCrossId
()).
eq
(
VmsTrafficLightInfo:
:
getIsLock
,
1
).
one
();
if
(
Objects
.
nonNull
(
one
))
{
//解锁操作
boolean
b
=
sendRequest
(
req
.
getCrossId
(),
0
,
null
);
if
(!
b
)
{
return
"解锁失败"
;
}
try
{
Thread
.
sleep
(
3000
);
//
}
catch
(
Exception
e
)
{
log
.
error
(
"解锁等待出现异常:"
,
e
);
}
}
//人工控制
boolean
b
=
sendRequest
(
req
.
getCrossId
(),
1
,
lamps
);
if
(!
b
)
{
return
"控制失败"
;
}
Map
<
String
,
List
>
saveObj
=
new
HashMap
<>();
saveObj
.
put
(
"list"
,
StringUtils
.
isNotBlank
(
lamps
)?
Arrays
.
asList
(
lamps
.
split
(
","
)):
Collections
.
EMPTY_LIST
);
redisDataModel
.
hset
(
"ivccs:vms:traffic:light"
,
req
.
getCrossId
(),
JSON
.
toJSONString
(
saveObj
));
//锁 定
VmsTrafficLightInfo
updateEntity
=
new
VmsTrafficLightInfo
();
updateEntity
.
setCrossId
(
req
.
getCrossId
());
updateEntity
.
setIsLock
((
byte
)
1
);
this
.
saveOrUpdate
(
updateEntity
);
return
null
;
}
catch
(
Exception
e
){
return
"控制失败"
;
}
finally
{
lock
.
unlock
();
}
}
private
String
getLamps
(
VmsTrafficLightInfo
req
,
final
String
lamps
)
{
String
newLamps
=
lamps
;
Map
<
String
,
Object
>
map
=
redisDataModel
.
hgetJson2Map
(
"ivccs:vms:traffic:light"
,
req
.
getCrossId
());
if
(!
MapUtils
.
isEmpty
(
map
)&&
CollectionUtils
.
isNotEmpty
((
List
<
String
>)
map
.
get
(
"list"
))){
List
<
String
>
olamps
=
(
List
<
String
>)
map
.
get
(
"list"
);
if
(
req
.
getFlag
()==
2
){
olamps
.
add
(
req
.
getLampNos
());
}
else
{
olamps
.
removeIf
(
e
->
e
.
equalsIgnoreCase
(
lamps
));
}
newLamps
=
StringUtils
.
join
(
olamps
,
","
)
;
}
else
if
(
req
.
getFlag
()==
0
){
newLamps
=
""
;
}
return
newLamps
;
}
private
boolean
sendRequest
(
String
crossId
,
Integer
enable
,
String
objData
){
JSONObject
object
=
new
JSONObject
();
object
.
put
(
"controlType"
,
4
);
object
.
put
(
"custom"
,
1
);
object
.
put
(
"planId"
,
1
);
object
.
put
(
"delay"
,
0
);
object
.
put
(
"sys"
,
"UICP"
);
object
.
put
(
"crossId"
,
crossId
);
object
.
put
(
"enable"
,
enable
);
object
.
put
(
"objData"
,
objData
);
log
.
info
(
String
.
format
(
"控制交通灯保存请求发送:----%s"
,
object
.
toJSONString
()));
String
result
=
RestTemplateUtil
.
post
(
String
.
format
(
"%s%s"
,
"http://10.11.10.32:8090/"
,
URL
.
TRAFFIC_LIGHT
),
object
.
toJSONString
()
,
null
);
log
.
info
(
String
.
format
(
"控制交通灯保存请求结果:----%s"
,
result
));
JSONObject
qryResult
=
JSON
.
parseObject
(
result
);
if
(
qryResult
.
getString
(
"code"
).
equalsIgnoreCase
(
"1"
)){
return
false
;
}
return
true
;
}
}
ivccs-vmm-backservice/src/main/java/com/ssi/service/impl/VmsVehicleAlertProcessServiceImpl.java
0 → 100644
View file @
07602a7b
package
com.ssi.service.impl
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.ssi.entity.VmsVehicleAlertProcess
;
import
com.ssi.service.VmsVehicleAlertProcessService
;
import
com.ssi.mapper.VmsVehicleAlertProcessMapper
;
import
org.springframework.stereotype.Service
;
/**
*
*/
@Service
public
class
VmsVehicleAlertProcessServiceImpl
extends
ServiceImpl
<
VmsVehicleAlertProcessMapper
,
VmsVehicleAlertProcess
>
implements
VmsVehicleAlertProcessService
{
}
ivccs-vmm-backservice/src/main/java/com/ssi/service/impl/VmsVehicleFreeTimeServiceImpl.java
0 → 100644
View file @
07602a7b
package
com.ssi.service.impl
;
import
com.alibaba.fastjson.JSON
;
import
com.ssi.entity.VmsVehicleFreeTime
;
import
com.ssi.entity.dto.VmsVehicleFreeTimeDto
;
import
com.ssi.entity.dto.VmsVehicleVinFreeTimeDto
;
import
com.ssi.service.VmsVehicleFreeTimeService
;
import
com.ssi.utils.DateUtils
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.math.NumberUtils
;
import
org.elasticsearch.action.search.ClearScrollRequest
;
import
org.elasticsearch.action.search.SearchRequest
;
import
org.elasticsearch.action.search.SearchResponse
;
import
org.elasticsearch.action.search.SearchScrollRequest
;
import
org.elasticsearch.client.RequestOptions
;
import
org.elasticsearch.client.RestHighLevelClient
;
import
org.elasticsearch.client.indices.GetIndexRequest
;
import
org.elasticsearch.client.indices.GetIndexResponse
;
import
org.elasticsearch.common.unit.TimeValue
;
import
org.elasticsearch.index.query.BoolQueryBuilder
;
import
org.elasticsearch.index.query.MatchQueryBuilder
;
import
org.elasticsearch.index.query.QueryBuilders
;
import
org.elasticsearch.index.query.RangeQueryBuilder
;
import
org.elasticsearch.search.Scroll
;
import
org.elasticsearch.search.SearchHit
;
import
org.elasticsearch.search.builder.SearchSourceBuilder
;
import
org.elasticsearch.search.sort.FieldSortBuilder
;
import
org.elasticsearch.search.sort.SortOrder
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Service
;
import
reactor.util.function.Tuple2
;
import
java.io.IOException
;
import
java.util.*
;
import
java.util.concurrent.TimeUnit
;
/**
* @description: 车辆空闲时间 service
* @author: dt
* @create: 2022-11-09 18:28
*/
@Service
@Slf4j
public
class
VmsVehicleFreeTimeServiceImpl
implements
VmsVehicleFreeTimeService
{
/**
* es 每个批次查询的条数
*/
public
static
final
int
SEARCH_SIZE
=
10000
;
/**
* es 游标生效时间
*/
public
final
Scroll
scroll
=
new
Scroll
(
TimeValue
.
timeValueMinutes
(
10L
));
/**
* es 索引名
*/
@Value
(
"${vehicle-trip.es-index-name:vms_vehicle_trip}"
)
private
String
tripIndexName
;
/**
* es
*/
private
RestHighLevelClient
restHighLevelClient
;
public
VmsVehicleFreeTimeServiceImpl
(
RestHighLevelClient
restHighLevelClient
)
{
this
.
restHighLevelClient
=
restHighLevelClient
;
}
/**
* 查询车辆空闲时间
* @param vmsVehicleVinFreeTimeDto
* @return
*/
@Override
public
VmsVehicleVinFreeTimeDto
getVehicleFreeTime
(
VmsVehicleVinFreeTimeDto
vmsVehicleVinFreeTimeDto
)
{
if
(
CollectionUtils
.
isEmpty
(
vmsVehicleVinFreeTimeDto
.
getVmsVehicleFreeTimeDtos
()))
{
return
null
;
}
try
{
SearchResponse
response
=
this
.
getSearchResponse
(
vmsVehicleVinFreeTimeDto
,
SEARCH_SIZE
,
scroll
,
SortOrder
.
ASC
);
String
scrollId
=
response
.
getScrollId
();
SearchHit
[]
searchHits
=
response
.
getHits
().
getHits
();
while
(
searchHits
!=
null
&&
searchHits
.
length
>
0
)
{
for
(
SearchHit
hit
:
searchHits
)
{
String
sourceAsString
=
hit
.
getSourceAsString
();
if
(
StringUtils
.
isNotEmpty
(
sourceAsString
))
{
VmsVehicleFreeTime
vmsVehicleFreeTime
=
JSON
.
parseObject
(
sourceAsString
,
VmsVehicleFreeTime
.
class
);
vmsVehicleVinFreeTimeDto
.
getVmsVehicleFreeTimeDtos
().
forEach
(
vmsVehicleFreeTimeDto
->
{
calcFreeTime
(
vmsVehicleFreeTime
,
vmsVehicleFreeTimeDto
);
});
}
}
if
(
searchHits
.
length
==
SEARCH_SIZE
)
{
response
=
this
.
getNextScrollResponse
(
scrollId
,
scroll
);
searchHits
=
response
.
getHits
().
getHits
();
}
else
{
break
;
}
}
}
catch
(
Exception
e
)
{
log
.
error
(
"查询统计车辆空闲时间出错"
,
e
);
}
return
vmsVehicleVinFreeTimeDto
;
}
/**
* 计算空闲时间
* @param vmsVehicleFreeTime
* @param vmsVehicleFreeTimeDto
*/
public
void
calcFreeTime
(
VmsVehicleFreeTime
vmsVehicleFreeTime
,
VmsVehicleFreeTimeDto
vmsVehicleFreeTimeDto
)
{
Long
startTime
=
0L
;
Long
endTime
=
0L
;
// 时间不在该范围内
if
(
vmsVehicleFreeTime
.
getStartTime
()
>
vmsVehicleFreeTimeDto
.
getEndTime
()
||
vmsVehicleFreeTime
.
getEndTime
()
<
vmsVehicleFreeTimeDto
.
getStartTime
())
{
return
;
}
// 确定开始时间
if
(
vmsVehicleFreeTime
.
getStartTime
()
<
vmsVehicleFreeTimeDto
.
getStartTime
())
{
startTime
=
vmsVehicleFreeTimeDto
.
getStartTime
();
}
if
(
vmsVehicleFreeTime
.
getStartTime
()
>
vmsVehicleFreeTimeDto
.
getStartTime
())
{
startTime
=
vmsVehicleFreeTime
.
getStartTime
();
}
// 确定结束时间
if
(
vmsVehicleFreeTime
.
getEndTime
()
<
vmsVehicleFreeTimeDto
.
getEndTime
())
{
endTime
=
vmsVehicleFreeTime
.
getEndTime
();
}
if
(
vmsVehicleFreeTime
.
getEndTime
()
>
vmsVehicleFreeTimeDto
.
getEndTime
())
{
endTime
=
vmsVehicleFreeTimeDto
.
getEndTime
();
}
// 计算空闲时间
vmsVehicleFreeTimeDto
.
setFreeTime
(
Objects
.
nonNull
(
vmsVehicleFreeTimeDto
.
getFreeTime
())
?
vmsVehicleFreeTimeDto
.
getFreeTime
()
+
(
endTime
-
startTime
)
:
(
endTime
-
startTime
));
}
/**
*
* @param vmsVehicleVinFreeTimeDto
* @param size
* @param scroll
* @param sortOrder
* @return
* @throws IOException
*/
public
SearchResponse
getSearchResponse
(
VmsVehicleVinFreeTimeDto
vmsVehicleVinFreeTimeDto
,
int
size
,
Scroll
scroll
,
SortOrder
sortOrder
)
throws
IOException
{
MatchQueryBuilder
matchQueryBuilder
=
QueryBuilders
.
matchQuery
(
"vin"
,
vmsVehicleVinFreeTimeDto
.
getVin
());
BoolQueryBuilder
boolBuilder
=
QueryBuilders
.
boolQuery
();
boolBuilder
.
must
(
matchQueryBuilder
);
vmsVehicleVinFreeTimeDto
.
getVmsVehicleFreeTimeDtos
().
forEach
(
vmsVehicleFreeTimeDto
->
{
RangeQueryBuilder
rangeQueryBuilder
=
QueryBuilders
.
rangeQuery
(
"startTime"
);
rangeQueryBuilder
.
gte
(
vmsVehicleFreeTimeDto
.
getStartTime
());
rangeQueryBuilder
.
lte
(
vmsVehicleFreeTimeDto
.
getEndTime
());
boolBuilder
.
should
(
rangeQueryBuilder
);
});
log
.
info
(
"查询 es 条件:\n"
+
boolBuilder
.
toString
());
FieldSortBuilder
fieldSortBuilder
=
new
FieldSortBuilder
(
"startTime"
).
order
(
sortOrder
);
SearchSourceBuilder
sourceBuilder
=
new
SearchSourceBuilder
();
sourceBuilder
.
size
(
size
);
sourceBuilder
.
query
(
boolBuilder
);
sourceBuilder
.
sort
(
fieldSortBuilder
);
sourceBuilder
.
timeout
(
new
TimeValue
(
600
,
TimeUnit
.
SECONDS
));
Map
<
String
,
Long
>
timeMap
=
getMinStartTimeAndMaxEndTime
(
vmsVehicleVinFreeTimeDto
);
String
[]
indexNames
=
getAllIndexNamesByYear
(
timeMap
.
get
(
"startTime"
),
timeMap
.
get
(
"endTime"
));
log
.
info
(
"查询的索引: "
+
Arrays
.
toString
(
indexNames
));
SearchRequest
searchRequest
=
new
SearchRequest
(
indexNames
,
sourceBuilder
);
searchRequest
.
scroll
(
scroll
);
return
restHighLevelClient
.
search
(
searchRequest
,
RequestOptions
.
DEFAULT
);
}
/**
* 判断获取时间最大值和最小值
* @param vmsVehicleVinFreeTimeDto
* @return
*/
private
Map
<
String
,
Long
>
getMinStartTimeAndMaxEndTime
(
VmsVehicleVinFreeTimeDto
vmsVehicleVinFreeTimeDto
)
{
Map
<
String
,
Long
>
map
=
new
HashMap
<
String
,
Long
>(
2
);
vmsVehicleVinFreeTimeDto
.
getVmsVehicleFreeTimeDtos
().
forEach
(
vmsVehicleFreeTimeDto
->
{
Long
startTime
=
map
.
getOrDefault
(
"startTime"
,
0L
);
Long
endTime
=
map
.
getOrDefault
(
"endTime"
,
0L
);
if
(
startTime
>
vmsVehicleFreeTimeDto
.
getStartTime
())
{
map
.
put
(
"startTime"
,
vmsVehicleFreeTimeDto
.
getStartTime
());
}
if
(
endTime
<
vmsVehicleFreeTimeDto
.
getEndTime
())
{
map
.
put
(
"endTime"
,
vmsVehicleFreeTimeDto
.
getStartTime
());
}
});
return
map
;
}
/**
* 得到下一个游标的数据
* @param scrollId
* @param scroll
* @return
* @throws IOException
*/
public
SearchResponse
getNextScrollResponse
(
String
scrollId
,
Scroll
scroll
)
throws
IOException
{
SearchScrollRequest
scrollRequest
=
new
SearchScrollRequest
(
scrollId
);
scrollRequest
.
scroll
(
scroll
);
return
restHighLevelClient
.
scroll
(
scrollRequest
,
RequestOptions
.
DEFAULT
);
}
/**
* 清楚游标
* @param scrollId
* @throws IOException
*/
public
void
clearScroll
(
String
scrollId
)
throws
IOException
{
ClearScrollRequest
clearScrollRequest
=
new
ClearScrollRequest
();
clearScrollRequest
.
addScrollId
(
scrollId
);
restHighLevelClient
.
clearScroll
(
clearScrollRequest
,
RequestOptions
.
DEFAULT
);
}
/**
* type: 0:year,1:yearmonth
*
* @param startTime
* @param endTime
* @return
* @throws IOException
*/
private
String
[]
getAllIndexNamesByYear
(
long
startTime
,
long
endTime
)
throws
IOException
{
GetIndexRequest
request
=
new
GetIndexRequest
(
tripIndexName
+
"*"
);
request
.
humanReadable
(
true
);
GetIndexResponse
response
=
restHighLevelClient
.
indices
().
get
(
request
,
RequestOptions
.
DEFAULT
);
String
[]
indices
=
response
.
getIndices
();
int
startYear
=
Integer
.
parseInt
(
DateUtils
.
getYear
(
startTime
));
int
endYear
=
Integer
.
parseInt
(
DateUtils
.
getYear
(
endTime
));
List
<
String
>
result
=
new
ArrayList
<>();
for
(
String
indexName
:
indices
)
{
String
suffix
=
StringUtils
.
substringAfter
(
indexName
,
tripIndexName
+
"_"
);
if
(
NumberUtils
.
isDigits
(
suffix
))
{
int
suffixYearMonth
=
Integer
.
parseInt
(
suffix
);
if
(
suffixYearMonth
>=
startYear
&&
suffixYearMonth
<=
endYear
)
{
result
.
add
(
indexName
);
}
}
}
return
result
.
toArray
(
new
String
[
0
]);
}
}
ivccs-vmm-backservice/src/main/java/com/ssi/service/impl/VmsVehicleServiceImpl.java
0 → 100644
View file @
07602a7b
package
com.ssi.service.impl
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.alicp.jetcache.anno.CacheRefresh
;
import
com.alicp.jetcache.anno.Cached
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.fasterxml.jackson.databind.DeserializationFeature
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.SerializationFeature
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Maps
;
import
com.ssi.constant.VehicleConstant
;
import
com.ssi.entity.VmsAlertThreshold
;
import
com.ssi.entity.VmsAlertThresholdNew
;
import
com.ssi.entity.VmsTosOrders
;
import
com.ssi.entity.VmsVehicle
;
import
com.ssi.entity.vo.*
;
import
com.ssi.mapper.VmsVehicleMapper
;
import
com.ssi.model.RedisDataModel
;
import
com.ssi.model.TelecontrolModel
;
import
com.ssi.model.VehicleElasticSearchModel
;
import
com.ssi.model.VehicleLatestDataModel
;
import
com.ssi.response.SSIPage
;
import
com.ssi.response.SSIResponse
;
import
com.ssi.service.VmsAlertThresholdNewService
;
import
com.ssi.service.VmsAlertThresholdService
;
import
com.ssi.service.VmsTosOrdersService
;
import
com.ssi.service.VmsVehicleService
;
import
com.ssi.utils.*
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Service
;
import
javax.tools.Tool
;
import
java.io.IOException
;
import
java.math.BigDecimal
;
import
java.text.DecimalFormat
;
import
java.util.*
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.atomic.AtomicInteger
;
/**
* 车辆服务实现类
*/
@Service
(
"vehicleService"
)
@Slf4j
public
class
VmsVehicleServiceImpl
extends
ServiceImpl
<
VmsVehicleMapper
,
VmsVehicle
>
implements
VmsVehicleService
{
@Value
(
"${ivccs.vehicle.latestData.redis.prefix:ivccs:vms:vehicle:latest}"
)
private
String
latestRedisKeyPrefix
;
@Value
(
"${vehicle.status.redis.keyPrefixOn}"
)
private
String
statusRedisKeyPrefix
;
@Value
(
"${vehicle.list.redis.keyPrefix:harbor:vehicle:list}"
)
private
String
vehicleListKeyPrefix
;
@Value
(
"${vehicle.latestData.redis.postfix:harbor_D00A}"
)
private
String
realPostfix
;
@Value
(
"${order.latestOrderKeyPrefix:harbor:command:status}"
)
private
String
latestOrderKeyPrefix
;
@Value
(
"${harbor.remote.emergencyParking}"
)
private
String
emergencyParkingKeyPrefix
;
@Value
(
"${harbor.vehicle.confirm_status_prefix}"
)
private
String
harborVehicleConfirmStatusPrefix
;
@Value
(
"${harbor.vehicle.onstatusKey:harbor:vehicle:onstatus}"
)
private
String
onstatusKey
;
@Autowired
private
RedisDataModel
redisDataModel
;
@Autowired
private
VmsTosOrdersService
vmsTosOrdersService
;
@Autowired
private
VmsAlertThresholdService
vmsAlertThresholdService
;
@Autowired
private
VmsAlertThresholdNewService
vmsAlertThresholdNewService
;
@Autowired
private
VehicleLatestDataModel
vehicleLatestDataModel
;
@Autowired
private
VehicleDataUtil
vehicleDataUtil
;
@Autowired
private
TelecontrolModel
telecontrolModel
;
@Autowired
private
VehicleElasticSearchModel
vehicleElasticSearchModel
;
private
final
String
CACHE_NAME
=
"vehicle:vehicleInfo"
;
@Override
public
SSIPage
queryPage
(
Map
<
String
,
Object
>
params
)
{
String
vehicleNum
=
(
String
)
params
.
get
(
"vehicleNum"
);
Integer
vehicleStatus
=
(
Integer
)
params
.
get
(
"vehicleStatus"
);
Integer
vehicleType
=
(
Integer
)
params
.
get
(
"vehicleType"
);
IPage
<
VmsVehicle
>
page
=
this
.
page
(
new
QueryUtils
<
VmsVehicle
>().
getPage
(
params
),
new
LambdaQueryWrapper
<
VmsVehicle
>()
.
like
(
StringUtils
.
isNotBlank
(
vehicleNum
),
VmsVehicle:
:
getVehicleNum
,
vehicleNum
)
.
eq
(
vehicleStatus
!=
null
,
VmsVehicle:
:
getStatus
,
vehicleStatus
)
.
eq
(
vehicleType
!=
null
,
VmsVehicle:
:
getVehicleType
,
vehicleType
)
.
orderByAsc
(
VmsVehicle:
:
getVehicleNum
));
List
<
VmsVehicle
>
records
=
page
.
getRecords
();
List
<
VehicleOrderVo
>
vehicleOrderVos
=
new
ArrayList
<>();
if
(
CollectionUtils
.
isNotEmpty
(
records
)){
records
.
stream
().
forEach
(
vehicle
->{
VehicleOrderVo
vehicleOrderVo
=
new
VehicleOrderVo
();
BeanUtils
.
copyProperties
(
vehicle
,
vehicleOrderVo
);
Map
<
String
,
Object
>
map
=
handleVehicleData
(
vehicle
.
getVin
());
vehicleOrderVo
.
setSoc
(
Objects
.
isNull
(
map
.
get
(
"soc"
))?
Integer
.
valueOf
(-
1
):(
Integer
)
map
.
get
(
"soc"
));
vehicleOrderVo
.
setOnlineStatus
((
Integer
)
map
.
get
(
"state"
));
vehicleOrderVos
.
add
(
vehicleOrderVo
);
});
}
return
new
SSIPage
(
vehicleOrderVos
,(
int
)
page
.
getTotal
(),(
int
)
page
.
getSize
(),(
int
)
page
.
getCurrent
());
}
@Override
public
List
<
VmsVehicle
>
getNormalVehicle
()
{
// 先从缓存中取
String
vehicleString
=
redisDataModel
.
get
(
String
.
format
(
"%s"
,
vehicleListKeyPrefix
));
if
(
StringUtils
.
isNotBlank
(
vehicleString
))
{
return
this
.
toListOfObject
(
vehicleString
,
VmsVehicle
.
class
);
}
LambdaQueryWrapper
<
VmsVehicle
>
wrapper
=
new
LambdaQueryWrapper
<
VmsVehicle
>().
eq
(
VmsVehicle:
:
getStatus
,
0
)
.
in
(
VmsVehicle:
:
getVehicleType
,
1
,
2
);
List
<
VmsVehicle
>
vehicleList
=
this
.
list
(
wrapper
);
if
(
CollectionUtils
.
isNotEmpty
(
vehicleList
))
{
redisDataModel
.
set
(
String
.
format
(
"%s"
,
vehicleListKeyPrefix
),
JSON
.
toJSONString
(
vehicleList
),
(
long
)
VehicleConstant
.
DEFAULT_EXPIRATION_TIME
);
}
return
vehicleList
;
}
public
static
<
T
>
List
<
T
>
toListOfObject
(
String
json
,
Class
<
T
>
clazz
)
{
ObjectMapper
om
=
new
ObjectMapper
();
// 反序列化时,忽略Javabean中不存在的属性,而不是抛出异常
om
.
configure
(
DeserializationFeature
.
FAIL_ON_UNKNOWN_PROPERTIES
,
false
);
// 忽略入参没有任何属性导致的序列化报错
om
.
configure
(
SerializationFeature
.
FAIL_ON_EMPTY_BEANS
,
false
);
try
{
Class
<
T
[]>
arrayClass
=
(
Class
<
T
[]>)
Class
.
forName
(
"[L"
+
clazz
.
getName
()
+
";"
);
return
Lists
.
newArrayList
(
om
.
readValue
(
json
,
arrayClass
));
}
catch
(
IOException
|
ClassNotFoundException
e
)
{
log
.
error
(
"json={}, clazz={}"
,
json
,
clazz
,
e
);
}
return
null
;
}
@Override
public
List
<
VmsVehicle
>
getNormalVehicleByVehicleNum
(
String
vehicleNum
,
Integer
vehicleType
)
{
LambdaQueryWrapper
<
VmsVehicle
>
wrapper
=
new
LambdaQueryWrapper
<
VmsVehicle
>().
eq
(
VmsVehicle:
:
getStatus
,
0
)
.
in
(
VmsVehicle:
:
getVehicleType
,
1
,
2
);
if
(
StringUtils
.
isNotBlank
(
vehicleNum
))
{
wrapper
.
like
(
VmsVehicle:
:
getVehicleNum
,
vehicleNum
);
}
List
<
VmsVehicle
>
vehicleList
=
this
.
list
(
wrapper
);
return
vehicleList
;
}
@Cached
(
name
=
CACHE_NAME
,
expire
=
120
,
timeUnit
=
TimeUnit
.
MINUTES
)
@CacheRefresh
(
refresh
=
1
,
stopRefreshAfterLastAccess
=
1440
,
timeUnit
=
TimeUnit
.
MINUTES
)
@Override
public
List
<
VmsVehicle
>
listAndCache
()
{
return
this
.
list
(
new
LambdaQueryWrapper
<
VmsVehicle
>().
eq
(
VmsVehicle:
:
getStatus
,
0
));
}
/**
* 车辆监控列表接口
*/
@Override
public
SSIResponse
listForMonitor
(
List
<
VmsVehicle
>
vehicleList
)
{
VmsAlertThreshold
info
=
new
VmsAlertThreshold
();
info
.
setParamKey
(
"wait_overtime_energy_key"
);
VmsAlertThreshold
current
=
vmsAlertThresholdService
.
getOne
(
new
LambdaQueryWrapper
<>(
info
));
// VehicleVo vehicleVo = new VehicleVo();
List
<
VehicleVo
.
vehicleTemp
>
vehicleTempList
=
Lists
.
newArrayList
();
vehicleList
.
stream
().
forEach
(
vehicle
->
{
Map
<
String
,
Object
>
realMap
=
handleVehicleData
(
vehicle
,
current
);
VehicleVo
.
vehicleTemp
vehicleTemp
=
vehicleDataUtil
.
toVehicleTemp
(
realMap
);
vehicleTempList
.
add
(
vehicleTemp
);
});
Collections
.
sort
(
vehicleTempList
,
new
Comparator
<
VehicleVo
.
vehicleTemp
>()
{
@Override
public
int
compare
(
VehicleVo
.
vehicleTemp
x
,
VehicleVo
.
vehicleTemp
y
)
{
if
(
x
.
getOnlineStatus
()
<
y
.
getOnlineStatus
())
{
return
1
;
}
else
if
(
x
.
getOnlineStatus
()
==
y
.
getOnlineStatus
())
{
if
(
x
.
getWorkStatus
()
<
y
.
getWorkStatus
())
{
return
1
;
}
else
if
(
x
.
getWorkStatus
()
==
y
.
getWorkStatus
())
{
return
x
.
getVehicleNum
().
compareTo
(
y
.
getVehicleNum
());
}
else
{
return
-
1
;
}
}
else
{
return
-
1
;
}
}
});
// vehicleVo.setVehicleList(vehicleTempList);
return
SSIResponse
.
ok
(
vehicleTempList
);
}
@Override
public
SSIResponse
vehicleStatusForMonitor
(
List
<
VmsVehicle
>
vehicleList
)
{
VehicleStatusVo
vehicleStatusVo
=
vehicleStatusDist
(
vehicleList
);
return
SSIResponse
.
ok
(
vehicleStatusVo
);
}
@Override
public
VehicleStatusVo
vehicleStatusDist
(
List
<
VmsVehicle
>
vehicleList
)
{
VehicleStatusVo
vehicleStatusVo
=
new
VehicleStatusVo
();
AtomicInteger
parkNum
=
new
AtomicInteger
(
0
);
AtomicInteger
loadingGoodsNum
=
new
AtomicInteger
(
0
);
AtomicInteger
unloadingGoodsNum
=
new
AtomicInteger
(
0
);
AtomicInteger
arrangeGoodsNum
=
new
AtomicInteger
(
0
);
AtomicInteger
chargeNum
=
new
AtomicInteger
(
0
);
AtomicInteger
temporaryParkNum
=
new
AtomicInteger
(
0
);
AtomicInteger
offlineNum
=
new
AtomicInteger
(
0
);
vehicleList
.
parallelStream
().
forEach
(
vehicle
->
{
Map
<
String
,
Object
>
realMap
=
redisDataModel
.
getJson2Map
(
String
.
format
(
"%s:%s-%s"
,
latestRedisKeyPrefix
,
vehicle
.
getVin
(),
realPostfix
));
// 不在线
if
(
realMap
==
null
)
{
offlineNum
.
incrementAndGet
();
return
;
}
//String onlineStatus = redisDataModel.get(String.format("%s:%s", statusRedisKeyPrefix, vehicle.getVin()));
//离线状态
String
onlineStatus
=
redisDataModel
.
get
(
String
.
format
(
"%s:%s"
,
onstatusKey
,
vehicle
.
getVin
()));
if
(
onlineStatus
==
null
&&
StringUtils
.
isBlank
(
onlineStatus
)||
!
onlineStatus
.
equals
(
"1"
))
{
realMap
.
put
(
"state"
,
0
);
offlineNum
.
incrementAndGet
();
return
;
}
else
{
realMap
.
put
(
"state"
,
Integer
.
parseInt
(
onlineStatus
));
}
// int online = vehicleDataUtil.checkOnline(realMap.get("state") == null ? 0 : (Integer) realMap.get("state"),
// (Long) realMap.get("collectTime"));
// if (online == 0) {
// offlineNum.incrementAndGet();
// return;
// }
// 在线
VmsTosOrders
vmsTosOrders
=
getLatestOrderByVin
(
vehicle
.
getVin
());
if
(
vmsTosOrders
!=
null
&&
!
VehicleUtil
.
isTaskOver
(
vmsTosOrders
.
getStatus
()))
{
if
(
vmsTosOrders
.
getVehicleTaskLabel
()
==
null
)
{
log
.
error
(
String
.
format
(
"车辆:%s:%s最新任务 车辆任务标签 为null, 任务信息如下:\n %s"
,
vehicle
.
getVehicleNum
(),
vehicle
.
getVin
(),
vmsTosOrders
));
return
;
}
switch
(
vmsTosOrders
.
getVehicleTaskLabel
())
{
case
1
:
loadingGoodsNum
.
incrementAndGet
();
break
;
case
2
:
unloadingGoodsNum
.
incrementAndGet
();
break
;
case
3
:
arrangeGoodsNum
.
incrementAndGet
();
break
;
case
4
:
parkNum
.
incrementAndGet
();
break
;
case
5
:
chargeNum
.
incrementAndGet
();
break
;
case
6
:
temporaryParkNum
.
incrementAndGet
();
break
;
}
}
else
{
parkNum
.
incrementAndGet
();
}
});
vehicleStatusVo
.
setVehicleNum
(
vehicleList
.
size
());
vehicleStatusVo
.
setLoadingGoodsNum
(
loadingGoodsNum
.
get
());
vehicleStatusVo
.
setUnloadingGoodsNum
(
unloadingGoodsNum
.
get
());
vehicleStatusVo
.
setArrangeGoodsNum
(
arrangeGoodsNum
.
get
());
vehicleStatusVo
.
setOfflineNum
(
offlineNum
.
get
());
vehicleStatusVo
.
setParkNum
(
parkNum
.
get
());
vehicleStatusVo
.
setChargeNum
(
chargeNum
.
get
());
vehicleStatusVo
.
setTemporaryParkNum
(
temporaryParkNum
.
get
());
vehicleStatusVo
.
setOtherOrdersNum
(
vehicleStatusVo
.
getOfflineNum
()
+
vehicleStatusVo
.
getParkNum
()
+
vehicleStatusVo
.
getChargeNum
()
+
vehicleStatusVo
.
getTemporaryParkNum
());
DecimalFormat
df
=
new
DecimalFormat
(
"######0.00"
);
vehicleStatusVo
.
setLoadingGoodsPer
(
df
.
format
(
vehicleStatusVo
.
getLoadingGoodsNum
()
*
1.0
/
vehicleStatusVo
.
getVehicleNum
()
*
100
)
+
"%"
);
vehicleStatusVo
.
setUnloadingGoodsPer
(
df
.
format
(
vehicleStatusVo
.
getUnloadingGoodsNum
()
*
1.0
/
vehicleStatusVo
.
getVehicleNum
()
*
100
)
+
"%"
);
vehicleStatusVo
.
setArrangeGoodsPer
(
df
.
format
(
vehicleStatusVo
.
getArrangeGoodsNum
()
*
1.0
/
vehicleStatusVo
.
getVehicleNum
()
*
100
)
+
"%"
);
vehicleStatusVo
.
setOfflinePer
(
df
.
format
(
vehicleStatusVo
.
getOfflineNum
()
*
1.0
/
vehicleStatusVo
.
getVehicleNum
()
*
100
)
+
"%"
);
vehicleStatusVo
.
setParkPer
(
df
.
format
(
vehicleStatusVo
.
getParkNum
()
*
1.0
/
vehicleStatusVo
.
getVehicleNum
()
*
100
)
+
"%"
);
vehicleStatusVo
.
setChargePer
(
df
.
format
(
vehicleStatusVo
.
getChargeNum
()
*
1.0
/
vehicleStatusVo
.
getVehicleNum
()
*
100
)
+
"%"
);
vehicleStatusVo
.
setTemporaryParkPer
(
df
.
format
(
vehicleStatusVo
.
getTemporaryParkNum
()
*
1.0
/
vehicleStatusVo
.
getVehicleNum
()
*
100
)
+
"%"
);
vehicleStatusVo
.
setOtherOrdersPer
(
df
.
format
(
vehicleStatusVo
.
getOtherOrdersNum
()
*
1.0
/
vehicleStatusVo
.
getVehicleNum
()
*
100
)
+
"%"
);
return
vehicleStatusVo
;
}
@Override
public
SSIResponse
saveVehicle
(
VmsVehicle
vehicle
)
{
Map
<
String
,
Object
>
repeatMap
=
checkRepeat
(
vehicle
);
if
((
Boolean
)
repeatMap
.
get
(
"repeat"
))
{
return
SSIResponse
.
no
((
String
)
repeatMap
.
get
(
"repeatInfo"
));
}
this
.
saveOrUpdate
(
vehicle
);
return
SSIResponse
.
ok
();
}
private
Map
<
String
,
Object
>
checkRepeat
(
VmsVehicle
vehicle
)
{
Map
<
String
,
Object
>
repeatMap
=
Maps
.
newHashMap
();
repeatMap
.
put
(
"repeat"
,
true
);
List
<
VmsVehicle
>
list
=
new
ArrayList
<
VmsVehicle
>();
if
(
null
!=
vehicle
.
getId
())
{
LambdaQueryWrapper
<
VmsVehicle
>
wrapper
=
new
LambdaQueryWrapper
<
VmsVehicle
>().
ne
(
VmsVehicle:
:
getId
,
vehicle
.
getId
());
list
=
this
.
list
(
wrapper
);
}
else
{
list
=
this
.
list
();
}
Map
<
String
,
VmsVehicle
>
vNumMap
=
Maps
.
newHashMap
();
Map
<
String
,
VmsVehicle
>
vTnumMap
=
Maps
.
newHashMap
();
Map
<
String
,
VmsVehicle
>
chassisMap
=
Maps
.
newHashMap
();
Map
<
String
,
VmsVehicle
>
platNumMap
=
Maps
.
newHashMap
();
Map
<
String
,
VmsVehicle
>
vinMap
=
Maps
.
newHashMap
();
list
.
parallelStream
().
forEach
(
vehicle1
->
{
vNumMap
.
put
(
vehicle1
.
getVehicleNum
(),
vehicle1
);
vTnumMap
.
put
(
vehicle1
.
getTerminalNum
(),
vehicle1
);
chassisMap
.
put
(
vehicle1
.
getChassisNum
(),
vehicle1
);
platNumMap
.
put
(
vehicle1
.
getPlateNo
(),
vehicle1
);
vinMap
.
put
(
vehicle1
.
getVin
(),
vehicle1
);
});
VmsVehicle
repeatVnum
=
vNumMap
.
get
(
vehicle
.
getVehicleNum
());
VmsVehicle
repeatVtnum
=
vTnumMap
.
get
(
vehicle
.
getTerminalNum
());
VmsVehicle
repeatChassis
=
chassisMap
.
get
(
vehicle
.
getChassisNum
());
VmsVehicle
repeatPlatNum
=
platNumMap
.
get
(
vehicle
.
getPlateNo
());
VmsVehicle
repeatVinNum
=
platNumMap
.
get
(
vehicle
.
getVin
());
if
(
repeatVnum
!=
null
)
{
if
(
vehicle
.
getVehicleNum
()
==
null
||
(
vehicle
.
getVehicleNum
()
!=
null
&&
vehicle
.
getVehicleNum
()
!=
repeatVnum
.
getVehicleNum
()))
{
repeatMap
.
put
(
"repeatInfo"
,
"车辆编号不能重复"
);
return
repeatMap
;
}
}
if
(
repeatVtnum
!=
null
)
{
if
(
vehicle
.
getTerminalNum
()
==
null
||
(
vehicle
.
getTerminalNum
()
!=
null
&&
vehicle
.
getTerminalNum
()
!=
repeatVtnum
.
getTerminalNum
()))
{
repeatMap
.
put
(
"repeatInfo"
,
"一个终端只能绑定一个车辆"
);
return
repeatMap
;
}
}
if
(
repeatChassis
!=
null
)
{
if
(
vehicle
.
getChassisNum
()
==
null
||
(
vehicle
.
getChassisNum
()
!=
null
&&
vehicle
.
getChassisNum
()
!=
repeatChassis
.
getChassisNum
()))
{
repeatMap
.
put
(
"repeatInfo"
,
"底盘号不能重复"
);
return
repeatMap
;
}
}
if
(
repeatPlatNum
!=
null
)
{
if
(
vehicle
.
getPlateNo
()
==
null
||
(
vehicle
.
getPlateNo
()
!=
null
&&
vehicle
.
getPlateNo
()
!=
repeatPlatNum
.
getPlateNo
()))
{
repeatMap
.
put
(
"repeatInfo"
,
"车牌号不能重复"
);
return
repeatMap
;
}
}
if
(
repeatVinNum
!=
null
)
{
if
(
vehicle
.
getVin
()
==
null
||
(
vehicle
.
getVin
()
!=
null
&&
vehicle
.
getVin
()
!=
repeatVinNum
.
getVin
()))
{
repeatMap
.
put
(
"repeatInfo"
,
"VIN不能重复"
);
return
repeatMap
;
}
}
repeatMap
.
put
(
"repeat"
,
false
);
return
repeatMap
;
}
private
Map
<
String
,
Object
>
handleVehicleData
(
String
vin
){
if
(
StringUtils
.
isBlank
(
vin
)){
return
Collections
.
emptyMap
();
}
Map
<
String
,
Object
>
realMap
=
redisDataModel
.
getJson2Map
(
String
.
format
(
"%s:%s-%s"
,
latestRedisKeyPrefix
,
vin
,
realPostfix
));
if
(
realMap
==
null
)
{
realMap
=
vehicleElasticSearchModel
.
searchLatestVehicleData
(
vin
);
}
if
(
realMap
==
null
)
{
realMap
=
Maps
.
newHashMap
();
}
String
onlineStatus
=
redisDataModel
.
get
(
String
.
format
(
"%s:%s"
,
"harbor:vehicle:online"
,
vin
));
if
(
onlineStatus
==
null
&&
StringUtils
.
isBlank
(
onlineStatus
)
||
!
onlineStatus
.
equals
(
"1"
))
{
realMap
.
put
(
"state"
,
0
);
}
else
{
realMap
.
put
(
"state"
,
Integer
.
parseInt
(
onlineStatus
));
}
return
realMap
;
}
private
Map
<
String
,
Object
>
handleVehicleData
(
VmsVehicle
vehicle
,
VmsAlertThreshold
current
)
{
Map
<
String
,
Object
>
realMap
=
redisDataModel
.
getJson2Map
(
String
.
format
(
"%s:%s-%s"
,
latestRedisKeyPrefix
,
vehicle
.
getVin
(),
realPostfix
));
if
(
realMap
==
null
)
{
realMap
=
vehicleElasticSearchModel
.
searchLatestVehicleData
(
vehicle
.
getVin
());
}
if
(
realMap
==
null
)
{
realMap
=
Maps
.
newHashMap
();
}
VmsTosOrdersVo
latestOrders
=
getLatestOrderByVin
(
vehicle
.
getVin
());
realMap
.
put
(
"vehicleNum"
,
vehicle
.
getVehicleNum
());
realMap
.
put
(
"vehicleType"
,
vehicle
.
getVehicleType
());
realMap
.
put
(
"vin"
,
vehicle
.
getVin
());
// 查询在线状态
//String onlineStatus = redisDataModel.get(String.format("%s:%s", statusRedisKeyPrefix, vehicle.getVin()));
String
onlineStatus
=
redisDataModel
.
get
(
String
.
format
(
"%s:%s"
,
"harbor:vehicle:onstatus"
,
vehicle
.
getVin
()));
if
(
onlineStatus
==
null
&&
StringUtils
.
isBlank
(
onlineStatus
)
||
!
onlineStatus
.
equals
(
"1"
))
{
realMap
.
put
(
"state"
,
0
);
}
else
{
realMap
.
put
(
"state"
,
Integer
.
parseInt
(
onlineStatus
));
}
if
(
latestOrders
==
null
||
latestOrders
.
getStatus
()
==
35
||
latestOrders
.
getStatus
()
==
36
||
latestOrders
.
getStatus
()
==
37
||
latestOrders
.
getStatus
()
==
41
)
{
realMap
.
put
(
"workStatus"
,
0
);
}
else
{
realMap
.
put
(
"orderData"
,
latestOrders
);
realMap
.
put
(
"workStatus"
,
1
);
// 是否超时
if
(
latestOrders
.
getStartTime
()
==
null
)
{
realMap
.
put
(
"waitOvertimeStatus"
,
0
);
}
else
{
Long
startTime
=
latestOrders
.
getStartTime
().
getTime
();
long
time
;
time
=
startTime
+
Integer
.
parseInt
(
current
.
getParamValue
())
*
60
*
1000
;
if
(
time
<
System
.
currentTimeMillis
())
{
realMap
.
put
(
"waitOvertimeStatus"
,
1
);
}
else
{
realMap
.
put
(
"waitOvertimeStatus"
,
0
);
}
}
}
VmsAlertThreshold
info
=
new
VmsAlertThreshold
();
info
.
setParamKey
(
"low_energy_key"
);
VmsAlertThreshold
vmsAlertThreshold
=
vmsAlertThresholdService
.
getOne
(
new
LambdaQueryWrapper
<>(
info
));
realMap
.
put
(
"lowEnergy"
,
Integer
.
parseInt
(
vmsAlertThreshold
.
getParamValue
()));
// 添加紧急停车状态
Map
<
String
,
Object
>
emergencyStatusMap
=
redisDataModel
.
getJson2Map
(
String
.
format
(
"%s:%s"
,
emergencyParkingKeyPrefix
,
vehicle
.
getVin
()));
if
(
emergencyStatusMap
!=
null
)
{
Object
emergencyStatus
=
emergencyStatusMap
.
get
(
"emergencyStatus"
);
realMap
.
put
(
"emergencyType"
,
emergencyStatus
);
}
else
{
realMap
.
put
(
"emergencyType"
,
2
);
}
// 三重确认状态添加
Map
<
String
,
Object
>
threeConfirmStatus
=
redisDataModel
.
getJson2Map
(
String
.
format
(
"%s:%s"
,
harborVehicleConfirmStatusPrefix
,
vehicle
.
getVin
()));
realMap
.
put
(
"threeConfirmStatus"
,
threeConfirmStatus
);
return
realMap
;
}
private
VmsTosOrdersVo
getLatestOrderByVin
(
String
vin
)
{
// List<VmsTosOrders> list = vmsTosOrdersService.list(new LambdaQueryWrapper<VmsTosOrders>()
// .eq(VmsTosOrders::getVin, vin)
// .orderByDesc(VmsTosOrders::getReceiveTime));
// VmsTosOrders latestOrders = list == null || list.isEmpty() ? null:list.get(0);
// return latestOrders;
Map
<
String
,
Object
>
json2Map
=
redisDataModel
.
getJson2Map
(
String
.
format
(
"%s:%s"
,
latestOrderKeyPrefix
,
vin
));
JSONObject
jsonObject
=
JSONObject
.
parseObject
(
JSONObject
.
toJSONString
(
json2Map
));
VmsTosOrdersVo
vmsTosOrders
=
JSONObject
.
toJavaObject
(
jsonObject
,
VmsTosOrdersVo
.
class
);
return
vmsTosOrders
;
}
/**
* 运力分析
*/
@Override
public
SSIResponse
transportCapacity
()
{
List
<
VmsVehicle
>
vehicleList
=
this
.
getNormalVehicle
();
VmsAlertThreshold
current
=
vmsAlertThresholdService
.
getOne
(
new
LambdaQueryWrapper
<>());
Double
socSum
=
0.0
;
Integer
vehicleSum
=
0
;
TransportCapacityAnalysisVo
capacityAnalysisVo
=
new
TransportCapacityAnalysisVo
();
for
(
VmsVehicle
vehicle
:
vehicleList
)
{
Map
<
String
,
Object
>
realMap
=
handleVehicleData
(
vehicle
,
current
);
int
online
=
vehicleDataUtil
.
checkOnline
(
realMap
.
get
(
"state"
)
==
null
?
0
:
(
Integer
)
realMap
.
get
(
"state"
),
(
Long
)
realMap
.
get
(
"collectTime"
));
if
(
online
==
1
)
{
vehicleSum
++;
Integer
workStatus
=
(
Integer
)
realMap
.
get
(
"workStatus"
);
Integer
faultStatus
=
realMap
.
get
(
"equipStatus"
)
==
null
?
1
:
(
Integer
)
realMap
.
get
(
"equipStatus"
)
==
1
?
1
:
0
;
Integer
chargingStatus
=
(
Integer
)
realMap
.
get
(
"chargingStatus"
);
chargingStatus
=
chargingStatus
==
null
?
0
:
chargingStatus
;
Integer
soc
=
(
Integer
)
realMap
.
get
(
"soc"
);
if
(
soc
==
null
)
{
soc
=
0
;
}
// 车辆任务超时也算入运力里
Object
waitOvertimeStatus
=
realMap
.
get
(
"waitOvertimeStatus"
);
if
(
waitOvertimeStatus
==
null
)
{
waitOvertimeStatus
=
0
;
}
// chargingStatus 3:未充电,4:充电完成
// if ((workStatus != 1 || (int)waitOvertimeStatus == 1) && faultStatus != 1 && (chargingStatus == 3 || chargingStatus == 4)) {
capacityAnalysisVo
.
rangeMatch
(
soc
);
socSum
=
socSum
+
soc
;
// }
}
}
Double
transportCapacity
=
vehicleSum
!=
0
?
socSum
/
vehicleSum
:
0
;
BigDecimal
bg
=
new
BigDecimal
(
transportCapacity
).
setScale
(
1
,
BigDecimal
.
ROUND_HALF_UP
);
capacityAnalysisVo
.
setTransportCapacity
(
bg
);
return
SSIResponse
.
ok
(
capacityAnalysisVo
);
}
/**
* 获取当前定位周边车辆
*/
@Override
public
List
<
VehicleControlStatusVo
>
getVehicleByLocation
(
String
location
,
final
Integer
distance
)
{
log
.
info
(
String
.
format
(
"%s:%s,%s:%s"
,
"根据经纬度获取车辆接口调用:经纬度"
,
location
,
"遥控距离"
,
distance
));
List
<
VehicleControlStatusVo
>
resultList
=
Lists
.
newArrayList
();
String
[]
split
=
location
.
split
(
","
);
double
[]
curLoc
=
new
double
[]
{
Double
.
parseDouble
(
split
[
0
]),
Double
.
parseDouble
(
split
[
1
])
};
List
<
VmsVehicle
>
list
=
this
.
list
(
new
LambdaQueryWrapper
<
VmsVehicle
>().
orderByAsc
(
VmsVehicle:
:
getVehicleNum
));
list
.
stream
().
forEach
(
vehicle
->
{
Map
<
String
,
Object
>
realMap
=
redisDataModel
.
getJson2Map
(
String
.
format
(
"%s:%s-%s"
,
latestRedisKeyPrefix
,
vehicle
.
getVin
(),
realPostfix
));
// 查询在线状态
if
(
realMap
!=
null
&&
!
realMap
.
isEmpty
()
&&
realMap
.
get
(
"longitude"
)
!=
null
&&
realMap
.
get
(
"latitude"
)
!=
null
)
{
String
onlineStatus
=
redisDataModel
.
get
(
String
.
format
(
"%s:%s"
,
statusRedisKeyPrefix
,
vehicle
.
getVin
()));
if
(
StringUtils
.
isBlank
(
onlineStatus
))
{
realMap
.
put
(
"state"
,
0
);
}
else
{
realMap
.
put
(
"state"
,
Integer
.
parseInt
(
onlineStatus
));
}
int
online
=
vehicleDataUtil
.
checkOnline
(
realMap
.
get
(
"state"
)
==
null
?
0
:
(
Integer
)
realMap
.
get
(
"state"
),
(
Long
)
realMap
.
get
(
"collectTime"
));
if
(
online
==
1
)
{
Double
longitude
=
ConfigUtils
.
getAsDoubleWithDefault
(
realMap
,
"longitude"
,
0.0
);
Double
latitude
=
ConfigUtils
.
getAsDoubleWithDefault
(
realMap
,
"latitude"
,
0.0
);
double
vehicleDistance
=
GpsUtil
.
getDistance
(
curLoc
[
0
],
curLoc
[
1
],
latitude
,
longitude
);
if
(
vehicleDistance
*
1000
<
distance
)
{
// 接管状态
Map
controlStatus
=
telecontrolModel
.
getControlStatus
(
vehicle
.
getVin
());
VehicleControlStatusVo
vehicleControlStatusVo
=
new
VehicleControlStatusVo
();
BeanUtils
.
copyProperties
(
vehicle
,
vehicleControlStatusVo
);
if
(
controlStatus
!=
null
)
{
vehicleControlStatusVo
.
setAppControl
((
Integer
)
controlStatus
.
get
(
"appControl"
));
vehicleControlStatusVo
.
setAppActive
((
Integer
)
controlStatus
.
get
(
"appActive"
));
vehicleControlStatusVo
.
setAppMac
((
String
)
controlStatus
.
get
(
"appMac"
));
}
// 紧停状态
Map
emergencyStatusMap
=
telecontrolModel
.
getEmergencyStatus
(
vehicle
.
getVin
());
Integer
emergencyStatus
=
2
;
if
(
emergencyStatusMap
!=
null
)
{
emergencyStatus
=
(
Integer
)
emergencyStatusMap
.
get
(
"emergencyStatus"
);
}
vehicleControlStatusVo
.
setEmergencyStatus
(
emergencyStatus
);
// 切换自动驾驶状态
Map
autoPilotMap
=
telecontrolModel
.
getAutoPilotStatus
(
vehicle
.
getVin
());
Integer
autoPilotStatus
=
4
;
if
(
autoPilotMap
!=
null
)
{
autoPilotStatus
=
(
Integer
)
autoPilotMap
.
get
(
"autopilot"
);
}
vehicleControlStatusVo
.
setAutopilot
(
autoPilotStatus
);
int
soc
=
ConfigUtils
.
getAsIntegerWithDefault
(
realMap
,
"soc"
,
0
);
vehicleControlStatusVo
.
setSoc
(
soc
);
resultList
.
add
(
vehicleControlStatusVo
);
}
}
}
});
return
resultList
;
}
@Override
public
Map
getVmsCranePosMapInfo
(
String
name
)
{
Map
map
=
this
.
baseMapper
.
getVmsCranePosMapInfo
(
name
);
return
map
;
}
@Override
public
List
<
Map
>
getVmsVehicle
()
{
// TODO Auto-generated method stub
List
<
Map
>
result
=
this
.
baseMapper
.
getVmsVehicle
();
return
result
;
}
}
ivccs-vmm-backservice/src/main/java/com/ssi/service/impl/WebSocketDataBackServiceImpl.java
0 → 100644
View file @
07602a7b
package
com.ssi.service.impl
;
import
com.google.common.collect.Maps
;
import
com.google.common.collect.Sets
;
import
com.ssi.model.RedisConfigModel
;
import
com.ssi.service.WebSocketDataBackService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.elasticsearch.client.transport.TransportClient
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Service
;
import
java.util.Arrays
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.concurrent.ExecutorService
;
/**
* Description:
*
* @author LiXiaoCong
* @version 2019/10/16 17:51
*/
@Service
@Slf4j
public
class
WebSocketDataBackServiceImpl
implements
WebSocketDataBackService
{
private
static
final
Object
LOCK
=
new
Object
();
@Value
(
"${meilan.history.esIndex:vms_history_data}"
)
private
String
indexBase
;
@Value
(
"${meilan.history.config.group:playBack}"
)
private
String
redisConfigGroup
;
@Value
(
"${meilan.history.playBack.normal:false}"
)
private
boolean
playBackNormal
;
@Value
(
"${meilan.history.playBack.delay:1000}"
)
private
long
delay
;
@Value
(
"${meilan.history.playBack.open.randomDelay:true}"
)
private
boolean
randomDelay
;
@Value
(
"${meilan.history.playBack.open.randomDelayScale:0.05}"
)
private
double
randomDelayScale
;
@Value
(
"${meilan.history.playBack.open.randomDelayScenesId:6,8,9}"
)
private
String
randomDelayScenesId
;
@Value
(
"${LinuxFile.playBackFolder}"
)
private
String
playBackFolder
;
@Autowired
private
RedisConfigModel
redisConfigModel
;
@Autowired
protected
TransportClient
transportClient
;
@Autowired
private
ExecutorService
executorService
;
private
Map
<
String
,
WebSocketDataEsBackor
>
backorMap
=
Maps
.
newConcurrentMap
();
@Override
public
int
playBack
(
String
sessionId
,
String
backorId
,
String
scenesId
,
Set
<
String
>
vins
,
Long
startTime
,
Long
stopTime
)
{
synchronized
(
LOCK
)
{
int
status
;
if
(!
backorMap
.
containsKey
(
backorId
))
{
if
(!
backorId
.
contains
(
"v2x"
))
{
WebSocketDataEsBackor
webSocketDataEsBackor
=
initPlayBackor
(
backorId
,
scenesId
,
vins
,
sessionId
);
webSocketDataEsBackor
.
setRandomDelay
(
randomDelay
);
webSocketDataEsBackor
.
setRandomDelayScale
(
randomDelayScale
);
webSocketDataEsBackor
.
setRandomDelayScenesId
(
randomDelayScenesId
);
backorMap
.
put
(
backorId
,
webSocketDataEsBackor
);
final
BackCondition
backConditionBean
=
getBackCondition
(
scenesId
,
startTime
,
stopTime
);
if
(
backConditionBean
!=
null
)
{
log
.
info
(
String
.
format
(
"启动回放任务: (%s, %s, %s)"
,
sessionId
,
backorId
,
vins
));
executorService
.
execute
(()
->
{
webSocketDataEsBackor
.
playBack
(
backConditionBean
.
startTime
,
backConditionBean
.
stopTime
,
backConditionBean
.
delay
,
playBackNormal
);
});
status
=
0
;
}
else
{
status
=
1
;
backorMap
.
remove
(
backorId
);
log
.
warn
(
String
.
format
(
"无回放数据时间段: (%s, %s, %s)"
,
sessionId
,
backorId
,
vins
));
}
}
else
{
WebSocketDataFileBackor
webSocketDataFileBackor
=
initPlayFileBackor
(
backorId
,
scenesId
,
vins
,
sessionId
);
webSocketDataFileBackor
.
setRandomDelay
(
randomDelay
);
webSocketDataFileBackor
.
setRandomDelayScale
(
randomDelayScale
);
webSocketDataFileBackor
.
setRandomDelayScenesId
(
randomDelayScenesId
);
backorMap
.
put
(
backorId
,
webSocketDataFileBackor
);
final
BackCondition
backConditionBean
=
getBackCondition
(
scenesId
,
startTime
,
stopTime
);
webSocketDataFileBackor
.
setPath
(
backConditionBean
.
getPath
());
if
(
StringUtils
.
isNotBlank
(
backConditionBean
.
getVins
())){
vins
.
addAll
(
Arrays
.
asList
(
backConditionBean
.
getVins
().
split
(
","
)));
}
if
(
backConditionBean
!=
null
)
{
log
.
info
(
String
.
format
(
"启动回放任务: (%s, %s, %s)"
,
sessionId
,
backorId
,
vins
));
executorService
.
execute
(()
->
{
webSocketDataFileBackor
.
playBack
(
backConditionBean
.
startTime
,
backConditionBean
.
stopTime
,
backConditionBean
.
delay
,
playBackNormal
);
});
status
=
0
;
}
else
{
status
=
1
;
backorMap
.
remove
(
backorId
);
log
.
warn
(
String
.
format
(
"无回放数据时间段: (%s, %s, %s)"
,
sessionId
,
backorId
,
vins
));
}
}
}
else
{
status
=
2
;
log
.
info
(
String
.
format
(
"已存在回放任务: (%s, %s, %s),无需重复启动。"
,
sessionId
,
backorId
,
vins
));
backorMap
.
get
(
backorId
).
sessions
.
add
(
sessionId
);
}
return
status
;
}
}
@Override
public
void
close
(
String
sessionId
,
String
backorId
)
{
synchronized
(
LOCK
)
{
WebSocketDataEsBackor
webSocketDataEsBackor
=
backorMap
.
get
(
backorId
);
if
(
webSocketDataEsBackor
!=
null
)
{
if
(
sessionId
.
equals
(
webSocketDataEsBackor
.
mainSession
))
{
webSocketDataEsBackor
.
shutDown
();
backorMap
.
remove
(
backorId
);
}
else
{
webSocketDataEsBackor
.
sessions
.
remove
(
sessionId
);
}
}
}
}
private
BackCondition
getBackCondition
(
String
scenesId
,
Long
startTime
,
Long
stopTime
){
BackCondition
backCondition
=
getRedisBackCondition
(
scenesId
);
if
(
backCondition
==
null
&&
startTime
!=
null
&&
stopTime
!=
null
)
{
backCondition
=
new
BackCondition
(
scenesId
,
startTime
,
stopTime
,
this
.
delay
);
}
return
backCondition
;
}
private
WebSocketDataEsBackor
initPlayBackor
(
String
backorId
,
String
scenesId
,
Set
<
String
>
vins
,
String
sessionId
)
{
Set
<
String
>
sessions
=
Sets
.
newConcurrentHashSet
();
sessions
.
add
(
sessionId
);
return
new
WebSocketDataEsBackor
(
backorId
,
scenesId
,
this
,
vins
,
sessionId
,
sessions
,
transportClient
,
indexBase
,
playBackFolder
);
}
private
WebSocketDataFileBackor
initPlayFileBackor
(
String
backorId
,
String
scenesId
,
Set
<
String
>
vins
,
String
sessionId
)
{
Set
<
String
>
sessions
=
Sets
.
newConcurrentHashSet
();
sessions
.
add
(
sessionId
);
return
new
WebSocketDataFileBackor
(
backorId
,
scenesId
,
this
,
vins
,
sessionId
,
sessions
);
}
private
BackCondition
getRedisBackCondition
(
String
scenesId
){
BackCondition
backCondition
=
null
;
String
config
=
redisConfigModel
.
getConfig
(
redisConfigGroup
,
scenesId
);
if
(
config
!=
null
){
String
[]
backConditions
=
config
.
split
(
"#"
);
int
length
=
backConditions
.
length
;
if
(
length
==
2
||
length
==
3
||
length
==
5
){
try
{
long
startTime
=
Long
.
parseLong
(
backConditions
[
0
]);
long
stopTime
=
Long
.
parseLong
(
backConditions
[
1
]);
Long
delay
=
this
.
delay
;
if
(
length
==
3
){
delay
=
Long
.
parseLong
(
backConditions
[
2
]);
}
backCondition
=
new
BackCondition
(
scenesId
,
startTime
,
stopTime
,
delay
);
if
(
length
==
5
){
backCondition
.
setPath
(
backConditions
[
3
]);
backCondition
.
setVins
(
backConditions
[
4
]);
}
log
.
info
(
String
.
format
(
"redis配置中场景%s的回放时间配置:%s"
,
scenesId
,
backCondition
));
}
catch
(
NumberFormatException
e
)
{
log
.
error
(
String
.
format
(
"回放条件解析失败:%s"
,
config
));
}
}
else
{
log
.
error
(
String
.
format
(
"redis配置中场景%s的回放时间配置错误:%s"
,
scenesId
,
config
));
}
}
else
{
log
.
warn
(
String
.
format
(
"redis配置中无此场景id的回放时间配置:%s"
,
scenesId
));
}
return
backCondition
;
}
private
class
BackCondition
{
private
String
scenesId
;
private
long
startTime
;
private
long
stopTime
;
private
long
delay
;
private
String
path
;
private
String
vins
;
public
BackCondition
(
String
scenesId
,
long
startTime
,
long
stopTime
,
long
delay
){
this
.
scenesId
=
scenesId
;
this
.
startTime
=
startTime
;
this
.
stopTime
=
stopTime
;
this
.
delay
=
delay
;
}
@Override
public
String
toString
()
{
return
String
.
format
(
"(%s, %s, %s, %s)"
,
scenesId
,
startTime
,
stopTime
,
delay
);
}
public
String
getScenesId
()
{
return
scenesId
;
}
public
void
setScenesId
(
String
scenesId
)
{
this
.
scenesId
=
scenesId
;
}
public
long
getStartTime
()
{
return
startTime
;
}
public
void
setStartTime
(
long
startTime
)
{
this
.
startTime
=
startTime
;
}
public
long
getStopTime
()
{
return
stopTime
;
}
public
void
setStopTime
(
long
stopTime
)
{
this
.
stopTime
=
stopTime
;
}
public
long
getDelay
()
{
return
delay
;
}
public
void
setDelay
(
long
delay
)
{
this
.
delay
=
delay
;
}
public
String
getPath
()
{
return
path
;
}
public
void
setPath
(
String
path
)
{
this
.
path
=
path
;
}
public
String
getVins
()
{
return
vins
;
}
public
void
setVins
(
String
vins
)
{
this
.
vins
=
vins
;
}
}
}
ivccs-vmm-backservice/src/main/java/com/ssi/service/impl/WebSocketDataEsBackor.java
0 → 100644
View file @
07602a7b
package
com.ssi.service.impl
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.TypeReference
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Maps
;
import
com.google.common.collect.Sets
;
import
com.ssi.utils.ElasticSearchUtil
;
import
com.ssi.websocket.WebBackSocketService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest
;
import
org.elasticsearch.action.search.SearchRequestBuilder
;
import
org.elasticsearch.action.search.SearchResponse
;
import
org.elasticsearch.client.transport.TransportClient
;
import
org.elasticsearch.common.unit.TimeValue
;
import
org.elasticsearch.index.query.BoolQueryBuilder
;
import
org.elasticsearch.index.query.QueryBuilders
;
import
org.elasticsearch.index.query.RangeQueryBuilder
;
import
org.elasticsearch.search.SearchHit
;
import
org.elasticsearch.search.SearchHits
;
import
org.elasticsearch.search.sort.SortOrder
;
import
org.joda.time.DateTime
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileOutputStream
;
import
java.util.*
;
import
java.util.concurrent.CountDownLatch
;
import
java.util.concurrent.atomic.AtomicBoolean
;
import
java.util.stream.Collectors
;
/**
* Description:
* 用于读取kafka数据回放
* @author LiXiaoCong
* @version 2019/10/12 12:47
*/
@Slf4j
public
class
WebSocketDataEsBackor
{
Set
<
String
>
sessions
;
String
mainSession
;
private
String
backorId
;
private
String
scenesId
;
private
WebSocketDataBackServiceImpl
webSocketDataBackService
;
private
Set
<
String
>
vins
;
private
TransportClient
transportClient
;
private
String
indexBase
;
private
Map
<
String
,
Map
<
String
,
Object
>>
latestMap
;
private
Map
<
String
,
String
>
latestJson
;
private
AtomicBoolean
closed
=
new
AtomicBoolean
(
false
);
private
boolean
randomDelay
;
private
double
randomDelayScale
;
private
String
randomDelayScenesId
;
private
String
playBackFolder
;
public
WebSocketDataEsBackor
(
String
backorId
,
String
scenesId
,
WebSocketDataBackServiceImpl
webSocketDataBackService
,
Set
<
String
>
vins
,
String
mainSession
,
Set
<
String
>
sessions
,
TransportClient
transportClient
,
String
indexBase
,
String
playBackFolder
){
this
.
backorId
=
backorId
;
this
.
scenesId
=
scenesId
;
this
.
webSocketDataBackService
=
webSocketDataBackService
;
this
.
vins
=
vins
;
this
.
mainSession
=
mainSession
;
this
.
sessions
=
sessions
;
this
.
transportClient
=
transportClient
;
this
.
indexBase
=
indexBase
;
this
.
latestMap
=
new
HashMap
<>();
this
.
latestJson
=
new
HashMap
<>();
this
.
playBackFolder
=
playBackFolder
;
}
public
WebSocketDataEsBackor
()
{
}
public
void
playBack
(
Long
startTime
,
Long
stopTime
,
long
delay
,
boolean
normal
){
try
{
//初始化结果容器
Map
<
String
,
List
<
Map
<
String
,
Object
>>>
records
=
Maps
.
newHashMap
();
for
(
String
vin
:
vins
){
records
.
put
(
vin
,
Lists
.
newLinkedList
());
}
Map
<
String
,
List
<
Map
<
String
,
Object
>>>
res
=
getRecordsFromFile
(
startTime
,
stopTime
);
if
(
res
==
null
){
getRecords
(
startTime
,
stopTime
,
records
);
if
(!
records
.
isEmpty
()){
//这个地方把数据保存到文件
String
filePath
=
playBackFolder
+
"/"
+
startTime
+
"-"
+
stopTime
+
".json"
;
JSON
.
writeJSONString
(
new
FileOutputStream
(
filePath
),
records
);
}
}
else
{
records
=
res
;
}
Iterator
<
Map
.
Entry
<
String
,
List
<
Map
<
String
,
Object
>>>>
iterator
=
records
.
entrySet
().
iterator
();
while
(
iterator
.
hasNext
()){
if
(
iterator
.
next
().
getValue
().
size
()
==
0
){
iterator
.
remove
();
}
}
if
(!
records
.
isEmpty
())
{
if
(
normal
)
{
playBackByNormal
(
records
,
delay
);
}
/*else if(randomDelay && randomDelayScenesId != null){
playBackInThread(records, delay);
}*/
else
{
playBack
(
records
,
delay
);
}
}
else
{
log
.
warn
(
String
.
format
(
"车辆%s的数据查询成功,时间段:[%s, %s], 无数据, 无需回放。"
,
vins
,
startTime
,
stopTime
));
}
}
catch
(
Exception
e
)
{
log
.
warn
(
String
.
format
(
"车辆%s的数据回放失败,时间段:[%s, %s]。"
,
vins
,
startTime
,
stopTime
),
e
);
shutDown
();
WebBackSocketService
.
messageBroadcast
(
backorId
,
Sets
.
newHashSet
(
this
.
sessions
),
Lists
.
newArrayList
(),
true
);
}
}
Map
<
String
,
List
<
Map
<
String
,
Object
>>>
getRecordsFromFile
(
Long
startTime
,
Long
stopTime
)
throws
Exception
{
String
filePath
=
playBackFolder
+
"/"
+
startTime
+
"-"
+
stopTime
+
".json"
;
boolean
exists
=
new
File
(
filePath
).
exists
();
if
(!
exists
){
return
null
;
}
Map
<
String
,
List
<
Map
<
String
,
Object
>>>
records
=
JSON
.
parseObject
(
new
FileInputStream
(
filePath
),
Map
.
class
);
return
records
;
}
private
void
playBack
(
Map
<
String
,
List
<
Map
<
String
,
Object
>>>
data
,
long
delay
){
log
.
info
(
String
.
format
(
"开始回放车辆%s的数据."
,
vins
));
String
recordJson
;
long
sleepTime
;
Map
<
String
,
Object
>
map
;
//获取最多数据集合个数
Set
<
Map
.
Entry
<
String
,
List
<
Map
<
String
,
Object
>>>>
entries
=
data
.
entrySet
();
Map
<
String
,
Integer
>
sizeMap
=
Maps
.
newHashMap
();
Integer
max
=
entries
.
stream
().
map
(
entry
->{
int
size
=
entry
.
getValue
().
size
();
sizeMap
.
put
(
entry
.
getKey
(),
size
);
return
size
;
}).
max
(
Integer:
:
compareTo
).
get
();
Integer
vinSize
;
for
(
int
i
=
0
;
i
<
max
;
i
++)
{
long
t
=
System
.
currentTimeMillis
();
log
.
info
(
String
.
format
(
"开始%s的第%s次推送数据:%s"
,
backorId
,
i
+
1
,
t
));
List
<
String
>
recordList
=
Lists
.
newArrayList
();
for
(
Map
.
Entry
<
String
,
List
<
Map
<
String
,
Object
>>>
entry
:
entries
){
vinSize
=
sizeMap
.
get
(
entry
.
getKey
());
vinSize
=
(
i
>=
vinSize
)
?
(
vinSize
-
1
)
:
i
;
map
=
entry
.
getValue
().
get
(
vinSize
);
if
(!
closed
.
get
())
{
int
i1
=
checkRandomDelay
(
map
);
recordJson
=
JSON
.
toJSONString
(
map
);
this
.
latestJson
.
put
(
entry
.
getKey
(),
recordJson
);
recordList
.
add
(
recordJson
);
}
else
{
return
;
}
}
WebBackSocketService
.
messageBroadcast
(
backorId
,
Sets
.
newHashSet
(
sessions
),
recordList
);
//计算休眠时间
sleepTime
=
delay
-
(
System
.
currentTimeMillis
()
-
t
);
sleep
(
sleepTime
>
0
?
sleepTime
:
1000L
);
}
pushLast
();
log
.
info
(
String
.
format
(
"回放车辆数据完成:%s, 回放数据记录情况:%s。"
,
vins
,
sizeMap
));
}
/**
* 仅适合车辆少的情况, 用于测试
* @param data
* @param delay
*/
private
void
playBackInThread
(
Map
<
String
,
List
<
Map
<
String
,
Object
>>>
data
,
long
delay
){
log
.
info
(
String
.
format
(
"开始使用多线程回放车辆%s的数据."
,
vins
));
CountDownLatch
countDownLatch
=
new
CountDownLatch
(
data
.
size
());
data
.
forEach
((
vin
,
records
)
->{
new
Thread
(()
->
{
try
{
String
recordJson
;
long
sleepTime
;
long
t
=
System
.
currentTimeMillis
();
log
.
info
(
String
.
format
(
"开始%s的车辆%s推送数据: %s"
,
backorId
,
vin
,
t
));
for
(
Map
<
String
,
Object
>
map
:
records
){
if
(!
closed
.
get
())
{
int
i1
=
checkRandomDelay
(
map
);
recordJson
=
JSON
.
toJSONString
(
map
);
this
.
latestJson
.
put
(
vin
,
recordJson
);
WebBackSocketService
.
messageBroadcast
(
backorId
,
Sets
.
newHashSet
(
sessions
),
recordJson
);
if
(
i1
>
100
){
sleep
(
i1
);
}
}
else
{
return
;
}
//计算休眠时间
sleepTime
=
delay
-
(
System
.
currentTimeMillis
()
-
t
);
sleep
(
sleepTime
>
0
?
sleepTime
:
1000L
);
}
}
finally
{
countDownLatch
.
countDown
();
}
}).
start
();
});
try
{
countDownLatch
.
await
();
}
catch
(
InterruptedException
e
)
{
}
pushLast
();
List
<
String
>
collect
=
data
.
entrySet
()
.
stream
()
.
map
(
entry
->
String
.
format
(
"%s:%s"
,
entry
.
getKey
(),
entry
.
getValue
().
size
()))
.
collect
(
Collectors
.
toList
());
log
.
info
(
String
.
format
(
"回放车辆数据完成:%s, 回放数据记录情况:%s。"
,
vins
,
collect
));
}
private
int
checkRandomDelay
(
Map
<
String
,
Object
>
map
){
int
delay
=
0
;
if
(
randomDelay
&&
randomDelayScenesId
.
equals
(
scenesId
)){
double
random
=
Math
.
random
();
if
(
random
<
randomDelayScale
){
map
.
put
(
"netError"
,
true
);
delay
=
(
int
)
(
random
*
100000
);
log
.
warn
(
String
.
format
(
"触发随机延迟:%s, 延迟时长:%s。"
,
map
,
delay
));
}
}
return
delay
;
}
private
void
playBackByNormal
(
Map
<
String
,
List
<
Map
<
String
,
Object
>>>
data
,
long
delay
){
log
.
info
(
String
.
format
(
"开始使用队列回放车辆%s的数据."
,
vins
));
String
json
;
long
sleepTime
;
LinkedList
<
Map
<
String
,
Object
>>
res
;
Map
<
String
,
Object
>
map
;
boolean
empty
;
Iterator
<
Map
.
Entry
<
String
,
List
<
Map
<
String
,
Object
>>>>
iterator
;
Map
.
Entry
<
String
,
List
<
Map
<
String
,
Object
>>>
entry
;
int
i
=
0
;
while
(!
data
.
isEmpty
()){
long
t
=
System
.
currentTimeMillis
();
log
.
info
(
String
.
format
(
"开始%s的第%s次推送数据:%s"
,
backorId
,
i
++,
t
));
iterator
=
data
.
entrySet
().
iterator
();
while
(
iterator
.
hasNext
()){
entry
=
iterator
.
next
();
res
=
(
LinkedList
<
Map
<
String
,
Object
>>)
entry
.
getValue
();
map
=
res
.
poll
();
empty
=
res
.
isEmpty
();
if
(
map
!=
null
){
if
(!
closed
.
get
())
{
checkRandomDelay
(
map
);
json
=
JSON
.
toJSONString
(
map
);
if
(
empty
){
json
=
String
.
format
(
"#%s"
,
json
);
}
WebBackSocketService
.
messageBroadcast
(
backorId
,
Sets
.
newHashSet
(
sessions
),
json
);
}
else
{
return
;
}
}
if
(
empty
){
log
.
info
(
String
.
format
(
"车辆%s的数据回放完成。"
,
entry
.
getKey
()));
this
.
latestJson
.
put
(
entry
.
getKey
(),
null
);
iterator
.
remove
();
}
}
//计算休眠时间
sleepTime
=
delay
-
(
System
.
currentTimeMillis
()
-
t
);
sleep
(
sleepTime
>
0
?
sleepTime
:
1000L
);
}
pushLast
();
log
.
info
(
String
.
format
(
"回放车辆数据完成:%s。"
,
vins
));
}
void
getRecords
(
Long
startTime
,
Long
stopTime
,
Map
<
String
,
List
<
Map
<
String
,
Object
>>>
resultContain
){
SearchRequestBuilder
searchRequestBuilder
=
getSearchRequestBuilder
(
startTime
,
stopTime
);
if
(
searchRequestBuilder
==
null
){
resultContain
.
clear
();
return
;
}
log
.
info
(
String
.
format
(
"开始查询车辆%s的数据, 查询索引为:%s."
,
vins
,
Arrays
.
asList
(
searchRequestBuilder
.
request
().
indices
())));
searchRequestBuilder
.
setFetchSource
(
new
String
[]{
"timestamp"
,
"value"
},
null
);
BoolQueryBuilder
queryBuilder
=
QueryBuilders
.
boolQuery
();
queryBuilder
.
must
(
QueryBuilders
.
termQuery
(
"key"
,
"all"
));
RangeQueryBuilder
rangeQueryBuilder
=
ElasticSearchUtil
.
createRangeQueryBuilder
(
"timestamp"
,
startTime
,
stopTime
);
queryBuilder
.
must
(
rangeQueryBuilder
);
SearchResponse
searchResponse
=
searchRequestBuilder
.
setQuery
(
queryBuilder
)
.
setScroll
(
TimeValue
.
timeValueMinutes
(
5
))
.
addSort
(
"timestamp"
,
SortOrder
.
ASC
)
.
setSize
(
1000
)
.
get
();
SearchHits
hits
=
searchResponse
.
getHits
();
SearchHit
[]
hitsHits
=
hits
.
getHits
();
Object
line
;
Map
<
String
,
Object
>
record
;
Map
<
String
,
Object
>
sourceAsMap
;
while
(
hitsHits
.
length
>
0
)
{
for
(
int
i
=
0
;
i
<
hitsHits
.
length
;
i
++)
{
sourceAsMap
=
hitsHits
[
i
].
getSourceAsMap
();
line
=
sourceAsMap
.
get
(
"value"
);
if
(
line
!=
null
){
record
=
jsonToMap
(
line
.
toString
());
if
(
record
!=
null
){
checkAndPushResultContain
(
record
,
sourceAsMap
.
get
(
"timestamp"
),
resultContain
);
}
}
}
searchResponse
=
transportClient
.
prepareSearchScroll
(
searchResponse
.
getScrollId
())
.
setScroll
(
TimeValue
.
timeValueMinutes
(
5
)).
get
();
hitsHits
=
searchResponse
.
getHits
().
getHits
();
}
List
<
String
>
collect
=
resultContain
.
entrySet
()
.
stream
()
.
map
(
entry
->
String
.
format
(
"%s:%s"
,
entry
.
getKey
(),
entry
.
getValue
().
size
()))
.
collect
(
Collectors
.
toList
());
log
.
info
(
String
.
format
(
"车辆%s的数据查询成功,时间段:[%s, %s], 数据量:%s"
,
vins
,
startTime
,
stopTime
,
collect
));
}
private
void
checkAndPushResultContain
(
Map
<
String
,
Object
>
record
,
Object
time
,
Map
<
String
,
List
<
Map
<
String
,
Object
>>>
resultContains
){
resultContains
.
forEach
((
vin
,
resultContain
)
->{
Object
map
=
record
.
get
(
vin
);
if
(
map
!=
null
&&
isValid
(
vin
,
map
)){
Map
<
String
,
Object
>
res
=
(
Map
<
String
,
Object
>)
map
;
res
.
put
(
"timestamp"
,
time
);
resultContain
.
add
(
res
);
}
});
}
private
SearchRequestBuilder
getSearchRequestBuilder
(
Long
startTime
,
Long
stopTime
)
{
SearchRequestBuilder
searchRequestBuilder
;
if
(
stopTime
>=
1570982400000L
)
{
String
startDay
=
new
DateTime
(
startTime
).
toString
(
"yyyyMMdd"
);
String
stopDay
=
new
DateTime
(
stopTime
).
toString
(
"yyyyMMdd"
);
boolean
exists
=
transportClient
.
admin
().
indices
()
.
exists
(
new
IndicesExistsRequest
()
.
indices
(
new
String
[]{
String
.
format
(
"%s_%s"
,
indexBase
,
startDay
),
String
.
format
(
"%s_%s"
,
indexBase
,
stopDay
)}))
.
actionGet
()
.
isExists
();
if
(!
exists
){
return
null
;
}
if
(
startDay
.
equals
(
stopDay
)){
searchRequestBuilder
=
transportClient
.
prepareSearch
(
String
.
format
(
"%s_%s"
,
indexBase
,
startDay
));
}
else
{
searchRequestBuilder
=
transportClient
.
prepareSearch
(
String
.
format
(
"%s_%s"
,
indexBase
,
startDay
),
String
.
format
(
"%s_%s"
,
indexBase
,
stopDay
));
}
}
else
{
searchRequestBuilder
=
transportClient
.
prepareSearch
(
String
.
format
(
"%s_exception_2019"
,
indexBase
));
}
return
searchRequestBuilder
;
}
private
Map
<
String
,
Object
>
jsonToMap
(
String
json
){
Map
<
String
,
Object
>
map
=
null
;
try
{
map
=
JSON
.
parseObject
(
json
,
new
TypeReference
<
Map
<
String
,
Object
>>()
{
});
}
catch
(
Exception
e
)
{
log
.
error
(
String
.
format
(
"json数据转换Map失败:%s"
,
json
),
e
);
}
return
map
;
}
public
void
shutDown
()
{
this
.
closed
.
set
(
true
);
}
private
boolean
isValid
(
String
vin
,
Object
record
){
boolean
valid
;
try
{
Map
<
String
,
Object
>
map
=
(
Map
<
String
,
Object
>)
record
;
valid
=
(
"在线"
.
equals
(
map
.
get
(
"clientStatus"
)));
if
(
valid
){
Map
<
String
,
Object
>
preMap
=
this
.
latestMap
.
get
(
vin
);
if
(
preMap
!=
null
){
String
prelocation
=
String
.
format
(
"%s,%s"
,
preMap
.
get
(
"latitude"
),
preMap
.
get
(
"longitude"
));
String
location
=
String
.
format
(
"%s,%s"
,
map
.
get
(
"latitude"
),
map
.
get
(
"longitude"
));
double
speed
=
Double
.
parseDouble
(
map
.
getOrDefault
(
"speed"
,
"0"
).
toString
());
valid
=
!(
prelocation
.
equals
(
location
)
&&
speed
!=
0
);
}
if
(
valid
)
{
this
.
latestMap
.
put
(
vin
,
map
);
}
}
}
catch
(
Exception
e
)
{
log
.
error
(
"数据检查异常。"
,
e
);
valid
=
false
;
}
return
valid
;
}
private
void
sleep
(
long
time
){
try
{
Thread
.
sleep
(
time
);
}
catch
(
InterruptedException
e
)
{
}
}
private
void
pushLast
(){
this
.
latestJson
.
forEach
((
key
,
json
)
->{
if
(!
closed
.
get
())
{
HashSet
<
String
>
sessions
=
Sets
.
newHashSet
(
this
.
sessions
);
WebBackSocketService
.
messageBroadcast
(
backorId
,
sessions
,
json
,
true
);
log
.
info
(
String
.
format
(
"推送%s的车辆%s的最后一条数据。"
,
sessions
,
key
));
}
else
{
return
;
}
});
shutDown
();
}
public
void
setRandomDelay
(
boolean
randomDelay
)
{
this
.
randomDelay
=
randomDelay
;
}
public
void
setRandomDelayScale
(
double
randomDelayScale
)
{
this
.
randomDelayScale
=
randomDelayScale
;
}
public
void
setRandomDelayScenesId
(
String
randomDelayScenesId
)
{
this
.
randomDelayScenesId
=
randomDelayScenesId
;
}
}
Prev
1
…
14
15
16
17
18
19
20
21
22
…
24
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment