Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
YeeAmosFireAutoSysRoot
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
station
YeeAmosFireAutoSysRoot
Commits
6f5819ae
Commit
6f5819ae
authored
Nov 05, 2021
by
suhuiguang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1.修改消息
parent
f2771e3f
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
255 additions
and
229 deletions
+255
-229
ExecutionTypeEnum.java
.../com/yeejoin/amos/fas/common/enums/ExecutionTypeEnum.java
+1
-1
BaseController.java
.../yeejoin/amos/fas/business/controller/BaseController.java
+1
-1
PlanDetailMapper.java
...eejoin/amos/fas/business/dao/mapper/PlanDetailMapper.java
+4
-0
ContingencyPlanServiceImpl.java
...fas/business/service/impl/ContingencyPlanServiceImpl.java
+78
-68
HandlerMqttMessageImpl.java
...mos/fas/business/service/impl/HandlerMqttMessageImpl.java
+125
-108
IContingencyPlanService.java
...s/fas/business/service/intfc/IContingencyPlanService.java
+24
-10
ContingencyPlanParamVo.java
.../yeejoin/amos/fas/business/vo/ContingencyPlanParamVo.java
+8
-40
ApplicationRunnerImpl.java
...va/com/yeejoin/amos/fas/config/ApplicationRunnerImpl.java
+1
-1
PlanDetailMapper.xml
...ysStart/src/main/resources/db/mapper/PlanDetailMapper.xml
+13
-0
No files found.
YeeAmosFireAutoSysCommon/src/main/java/com/yeejoin/amos/fas/common/enums/ExecutionTypeEnum.java
View file @
6f5819ae
...
...
@@ -5,7 +5,7 @@ package com.yeejoin.amos.fas.common.enums;
*/
public
enum
ExecutionTypeEnum
{
PLANCHECK
(
"预案验证"
,
0
),
PLANCHECK
(
"预案验证"
,
0
),
FIREMANAGEMENT
(
"火灾处置"
,
1
);
/**
* 名称,描述
...
...
YeeAmosFireAutoSysService/src/main/java/com/yeejoin/amos/fas/business/controller/BaseController.java
View file @
6f5819ae
...
...
@@ -66,7 +66,7 @@ public class BaseController {
protected
static
final
int
DEFAULT_PAGE_SIZE
=
10
;
@Autowired
private
RedisTemplate
<
String
,
String
>
redisTemplate
;
private
RedisTemplate
<
String
,
String
>
redisTemplate
;
protected
String
getToken
()
{
...
...
YeeAmosFireAutoSysService/src/main/java/com/yeejoin/amos/fas/business/dao/mapper/PlanDetailMapper.java
View file @
6f5819ae
...
...
@@ -45,4 +45,8 @@ public interface PlanDetailMapper {
List
<
PlanDetailVo
>
filterList
(
@Param
(
"planName"
)
String
planName
,
@Param
(
"classifyId"
)
List
<
Long
>
classifyId
,
@Param
(
"planRange"
)
List
<
String
>
planRange
,
@Param
(
"editOrgName"
)
String
editOrgName
,
@Param
(
"implementationTimeLeft"
)
Date
implementationTimeLeft
,
@Param
(
"implementationTimeRight"
)
Date
implementationTimeRight
,
@Param
(
"start"
)
int
start
,
@Param
(
"size"
)
int
size
);
List
<
String
>
getRuleIdByEquipment
(
@Param
(
"id"
)
Long
id
);
PlanDetailVo
getPlanDetailByEquipmentId
(
@Param
(
"fire_equipment_id"
)
Long
fireEquipmentId
);
}
YeeAmosFireAutoSysService/src/main/java/com/yeejoin/amos/fas/business/service/impl/ContingencyPlanServiceImpl.java
View file @
6f5819ae
package
com
.
yeejoin
.
amos
.
fas
.
business
.
service
.
impl
;
import
com.alibaba.fastjson.JSON
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
com.yeejoin.amos.component.rule.config.ClazzUtils
;
import
com.yeejoin.amos.fas.business.action.CustomerAction
;
...
...
@@ -26,6 +27,7 @@ import org.springframework.beans.BeanUtils;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Qualifier
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.typroject.tyboot.component.emq.EmqKeeper
;
...
...
@@ -44,18 +46,12 @@ import java.util.*;
public
class
ContingencyPlanServiceImpl
implements
IContingencyPlanService
{
private
final
Logger
logger
=
LogManager
.
getLogger
(
ContingencyPlanServiceImpl
.
class
);
@Autowired
private
IEquipmentService
equipmentService
;
@Autowired
private
IRiskSourceService
riskSourceService
;
@Autowired
private
IPlanOperationRecordDao
planOperationRecordDao
;
@Autowired
private
IEquipmentFireEquipmentDao
equipmentFireEquipmentDao
;
@Qualifier
(
"iEquipmentDao"
)
@Autowired
private
IEquipmentDao
equipmentDao
;
@Autowired
private
EquipmentSpecificMapper
equipmentSpecificMapper
;
@Autowired
...
...
@@ -67,8 +63,6 @@ public class ContingencyPlanServiceImpl implements IContingencyPlanService {
private
CustomerAction
customerAction
;
@Value
(
"${now.gateway.address}"
)
private
String
gateWayAddress
;
// @Value("${number.plan.projectName}")
// private String projectName;
private
final
PlanOperationRecordMapper
planOperationRecordMapper
;
private
final
IPlanDetailDao
planDetailDao
;
private
final
IPlanDocDao
planDocDao
;
...
...
@@ -84,6 +78,11 @@ public class ContingencyPlanServiceImpl implements IContingencyPlanService {
@Autowired
IContingencyInstance
iContingencyInstance
;
@Autowired
private
RedisTemplate
<
String
,
String
>
redisTemplate
;
@Autowired
public
ContingencyPlanServiceImpl
(
IPlanDetailDao
planDetailDao
,
IPlanDocDao
planDocDao
,
IPlanEquipmentDao
planEquipmentDao
,
IPlanRuleDao
planRuleDao
,
IPlanClassifyTreeDao
classifyTreeDao
,
PlanDetailMapper
planDetailMapper
,
PlanEquipmentMapper
planEquipmentMapper
,
PlanRuleMapper
planRuleMapper
,
PlanDocMapper
planDocMapper
,
...
...
@@ -119,69 +118,77 @@ public class ContingencyPlanServiceImpl implements IContingencyPlanService {
Optional
<
PlanDetail
>
PlanDetailOp
=
planDetailDao
.
findById
(
Long
.
valueOf
(
vo
.
getPlanId
()));
List
<
PlanEquipment
>
equipmentList
=
planEquipmentDao
.
findByPlanId
(
PlanDetailOp
.
get
().
getId
());
//预案启动
if
(
PlanDetailOp
.
get
()
!=
null
)
{
//获取规则名称
List
<
PlanRule
>
planRuleList
=
planRuleDao
.
getPlanDocsByPlanId
(
Long
.
valueOf
(
vo
.
getPlanId
()));
if
(
planRuleList
.
size
()
==
0
)
{
result
.
setMessage
(
ReserveEnum
.
NOPLAN
.
getText
());
return
result
;
}
//电力设备
Equipment
equipment
=
equipmentService
.
queryOne
(
equipmentList
.
get
(
0
).
getFireEquipmentId
());
if
(
equipment
==
null
)
{
result
.
setMessage
(
ReserveEnum
.
NOEQUIP
.
getText
());
//获取规则名称
List
<
PlanRule
>
planRuleList
=
planRuleDao
.
getPlanDocsByPlanId
(
Long
.
valueOf
(
vo
.
getPlanId
()));
if
(
planRuleList
.
size
()
==
0
)
{
result
.
setMessage
(
ReserveEnum
.
NOPLAN
.
getText
());
return
result
;
}
//电力设备
Equipment
equipment
=
equipmentService
.
queryOne
(
equipmentList
.
get
(
0
).
getFireEquipmentId
());
if
(
equipment
==
null
)
{
result
.
setMessage
(
ReserveEnum
.
NOEQUIP
.
getText
());
return
result
;
}
equipment
.
setReservePlan
(
"换流站消防专项预案"
+
"/"
+
planRuleList
.
get
(
0
).
getRuleId
());
//电力设备绑定装备
EquipmentSpecificForRiskVo
equipmentSpecific
;
if
(
vo
.
getFireEquipmentId
()
!=
null
){
equipmentSpecific
=
equipmentSpecificMapper
.
getOneById
(
vo
.
getFireEquipmentId
());
//不会为null 在告警处理时已经判断过
if
(
equipmentSpecific
==
null
)
{
result
.
setMessage
(
"该预案保护的电力设备尚未绑定配套的火灾报警设备"
);
return
result
;
}
equipment
.
setReservePlan
(
"换流站消防专项预案"
+
"/"
+
planRuleList
.
get
(
0
).
getRuleId
());
//电力设备绑定装备
}
else
{
List
<
EquipmentFireEquipment
>
equipmentFireEquipmentList
=
equipmentFireEquipmentDao
.
findAllByEquipmentId
(
equipmentList
.
get
(
0
).
getFireEquipmentId
());
if
(
equipmentFireEquipmentList
.
size
()
==
0
)
{
result
.
setMessage
(
"该预案保护的电力设备尚未绑定配套的火灾报警设备"
);
return
result
;
}
//查询设备
EquipmentSpecificForRiskVo
equipmentSpecific
=
equipmentSpecificMapper
.
getOneById
(
equipmentFireEquipmentList
.
get
(
0
).
getFireEquipmentId
());
equipmentSpecific
=
equipmentSpecificMapper
.
getOneById
(
equipmentFireEquipmentList
.
get
(
0
).
getFireEquipmentId
());
if
(
equipmentSpecific
==
null
)
{
result
.
setMessage
(
"该预案保护的电力设备尚未绑定配套的火灾报警设备"
);
return
result
;
}
}
//插入运行记录表
PlanOperationRecord
planOperationRecord
=
new
PlanOperationRecord
();
planOperationRecord
.
setStatus
(
PlanRecordStatusEnum
.
OPERATION
.
getCode
());
planOperationRecord
.
setPlanId
(
PlanDetailOp
.
get
().
getId
());
planOperationRecord
.
setIsDelete
(
false
);
planOperationRecord
.
setStartTime
(
new
Date
());
planOperationRecord
.
setPlanPattern
(
vo
.
getStatus
());
planOperationRecord
.
setStartUserId
(
vo
.
getUserId
());
planOperationRecord
.
setStartUserName
(
vo
.
getUserName
());
planOperationRecord
.
setEquipmentCode
(
equipmentSpecific
.
getCode
());
planOperationRecord
.
setEquipmentName
(
equipmentSpecific
.
getName
());
planOperationRecord
.
setEquipmentId
(
equipmentSpecific
.
getId
());
planOperationRecord
.
setFireEquipmentId
(
equipment
.
getId
());
if
(
ContingencyPlanStatusEnum
.
SIMULATION_START
.
getCode
().
equals
(
vo
.
getStatus
()))
{
planOperationRecord
.
setExecutionType
(
ExecutionTypeEnum
.
PLANCHECK
.
getCode
());
}
else
{
planOperationRecord
.
setExecutionType
(
ExecutionTypeEnum
.
FIREMANAGEMENT
.
getCode
());
}
PlanOperationRecord
operationRecord
=
planOperationRecordDao
.
save
(
planOperationRecord
);
//预案启动
AlarmParam
deviceData
=
new
AlarmParam
();
deviceData
.
setMonitor
(
equipment
!=
null
?
equipment
.
getName
()
:
""
);
deviceData
.
setId
(
String
.
valueOf
(
equipmentSpecific
.
getId
()));
deviceData
.
setCode
(
equipmentSpecific
.
getCode
());
String
batchNo
=
equipmentHandlerService
.
executeDynamicPlan
(
deviceData
,
equipment
,
equipmentSpecific
,
toke
,
operationRecord
.
getId
());
//更新模型状态
PlanDetail
planDetail
=
PlanDetailOp
.
get
();
planDetail
.
setStatus
(
vo
.
getStatus
());
planDetailDao
.
save
(
planDetail
);
//更新预案执行记录表的批次号
operationRecord
.
setBatchNo
(
batchNo
);
planOperationRecordDao
.
save
(
operationRecord
);
result
.
setMessage
(
ReserveEnum
.
RUN
.
getText
());
result
.
setBatchNo
(
batchNo
);
//插入运行记录表
PlanOperationRecord
planOperationRecord
=
new
PlanOperationRecord
();
planOperationRecord
.
setStatus
(
PlanRecordStatusEnum
.
OPERATION
.
getCode
());
planOperationRecord
.
setPlanId
(
PlanDetailOp
.
get
().
getId
());
planOperationRecord
.
setIsDelete
(
false
);
planOperationRecord
.
setStartTime
(
new
Date
());
planOperationRecord
.
setPlanPattern
(
vo
.
getStatus
());
planOperationRecord
.
setStartUserId
(
vo
.
getUserId
());
planOperationRecord
.
setStartUserName
(
vo
.
getUserName
());
planOperationRecord
.
setEquipmentCode
(
equipmentSpecific
.
getCode
());
planOperationRecord
.
setEquipmentName
(
equipmentSpecific
.
getName
());
planOperationRecord
.
setEquipmentId
(
equipmentSpecific
.
getId
());
planOperationRecord
.
setFireEquipmentId
(
equipment
.
getId
());
if
(
ContingencyPlanStatusEnum
.
SIMULATION_START
.
getCode
().
equals
(
vo
.
getStatus
()))
{
planOperationRecord
.
setExecutionType
(
ExecutionTypeEnum
.
PLANCHECK
.
getCode
());
}
else
{
planOperationRecord
.
setExecutionType
(
ExecutionTypeEnum
.
FIREMANAGEMENT
.
getCode
());
}
PlanOperationRecord
operationRecord
=
planOperationRecordDao
.
save
(
planOperationRecord
);
//预案启动
AlarmParam
deviceData
=
new
AlarmParam
();
deviceData
.
setMonitor
(
equipment
.
getName
());
deviceData
.
setId
(
String
.
valueOf
(
equipmentSpecific
.
getId
()));
deviceData
.
setCode
(
equipmentSpecific
.
getCode
());
String
batchNo
=
equipmentHandlerService
.
executeDynamicPlan
(
deviceData
,
equipment
,
equipmentSpecific
,
toke
,
operationRecord
.
getId
());
//更新模型状态
PlanDetail
planDetail
=
PlanDetailOp
.
get
();
planDetail
.
setStatus
(
vo
.
getStatus
());
planDetailDao
.
save
(
planDetail
);
//更新预案执行记录表的批次号
operationRecord
.
setBatchNo
(
batchNo
);
planOperationRecordDao
.
save
(
operationRecord
);
result
.
setMessage
(
ReserveEnum
.
RUN
.
getText
());
result
.
setBatchNo
(
batchNo
);
}
return
result
;
}
...
...
@@ -644,21 +651,23 @@ public class ContingencyPlanServiceImpl implements IContingencyPlanService {
}
catch
(
MqttException
e
)
{
logger
.
fatal
(
"订阅规则删除同步消息失败,资源删除或取消无法同步"
,
e
);
}
/*try {
emqKeeper.getMqttClient().subscribe(DELETE_SYNC_PLAN_EQUIP, (s, mqttMessage) -> {
byte[] payload = mqttMessage.getPayload();
try {
List<Long> ids = (List<Long>) ClazzUtils.deserializableObject(payload);
if (!ValidationUtil.isEmpty(ids)) {
planEquipmentMapper.logicDeleteByEquipIdList(ids);
try
{
emqKeeper
.
getMqttClient
().
subscribe
(
VIEW_3D_OPEN_STATUS
,
(
s
,
mqttMessage
)
->
{
Map
msg
=
JSON
.
parseObject
(
mqttMessage
.
toString
());
if
(
msg
.
containsKey
(
"status"
)
&&
msg
.
containsKey
(
"seq"
)){
String
seq
=
msg
.
get
(
"seq"
).
toString
();
String
status
=
msg
.
get
(
"status"
).
toString
();
String
key
=
KEY_VIEW_3D_PAGE
+
seq
;
if
(
"offLine"
.
equals
(
status
)){
redisTemplate
.
delete
(
key
);
}
else
{
redisTemplate
.
opsForValue
().
set
(
key
,
status
);
}
} catch (Exception e) {
logger.error("预案保护对象删除同步出错", e);
}
});
}
catch
(
MqttException
e
)
{
logger.fatal("订阅
保护对象
删除同步消息失败,资源删除或取消无法同步", e);
}
*/
logger
.
fatal
(
"订阅
规则
删除同步消息失败,资源删除或取消无法同步"
,
e
);
}
}
}
\ No newline at end of file
YeeAmosFireAutoSysService/src/main/java/com/yeejoin/amos/fas/business/service/impl/HandlerMqttMessageImpl.java
View file @
6f5819ae
...
...
@@ -12,19 +12,15 @@ import com.yeejoin.amos.fas.business.bo.SafetyExecuteBo;
import
com.yeejoin.amos.fas.business.dao.mapper.*
;
import
com.yeejoin.amos.fas.business.dao.repository.IContingencyOriginalDataDao
;
import
com.yeejoin.amos.fas.business.dao.repository.IEvaluationModelDao
;
import
com.yeejoin.amos.fas.business.dao.repository.IPlanOperationRecordDao
;
import
com.yeejoin.amos.fas.business.dao.repository.IPreplanPictureDao
;
import
com.yeejoin.amos.fas.business.feign.RemoteSecurityService
;
import
com.yeejoin.amos.fas.business.param.AlarmParam
;
import
com.yeejoin.amos.fas.business.service.intfc.I
DataRefresh
Service
;
import
com.yeejoin.amos.fas.business.service.intfc.I
ContingencyPlan
Service
;
import
com.yeejoin.amos.fas.business.service.intfc.IEquipmentHandlerService
;
import
com.yeejoin.amos.fas.business.service.intfc.IView3dService
;
import
com.yeejoin.amos.fas.business.util.JexlUtil
;
import
com.yeejoin.amos.fas.business.util.RpnUtils
;
import
com.yeejoin.amos.fas.business.vo.EquipmentSpecificForRiskVo
;
import
com.yeejoin.amos.fas.business.vo.EquipmentSpecificIndexVo
;
import
com.yeejoin.amos.fas.business.vo.Toke
;
import
com.yeejoin.amos.fas.business.vo.TopicEntityVo
;
import
com.yeejoin.amos.fas.business.vo.*
;
import
com.yeejoin.amos.fas.client.invoke.RsDataQueue
;
import
com.yeejoin.amos.fas.common.enums.EquipmentRiskTypeEnum
;
import
com.yeejoin.amos.fas.core.util.StringUtil
;
...
...
@@ -35,6 +31,7 @@ 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.context.annotation.Lazy
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.scheduling.annotation.Async
;
import
org.springframework.stereotype.Service
;
...
...
@@ -98,9 +95,6 @@ public class HandlerMqttMessageImpl implements IEquipmentHandlerService {
IContingencyOriginalDataDao
iContingencyOriginalDataDao
;
@Autowired
private
IDataRefreshService
iDataRefreshService
;
@Autowired
private
IView3dService
view3dService
;
@Autowired
...
...
@@ -118,18 +112,25 @@ public class HandlerMqttMessageImpl implements IEquipmentHandlerService {
@Autowired
private
FmeaMapper
fmeaMapper
;
@Value
(
"${station.name}"
)
private
String
stationName
;
@Value
(
"${spring.application.name}"
)
private
String
serviceName
;
@Autowired
private
IPlanOperationRecordDao
planOperationRecordDao
;
@Value
(
"${autoSys.alarm.nameKeys}"
)
private
String
nameKeys
;
@Value
(
"${security.loginId}"
)
private
String
loginId
;
@Autowired
PlanDetailMapper
planDetailMapper
;
@Lazy
@Autowired
IContingencyPlanService
iContingencyPlanService
;
@Override
public
void
handlerMqttMessage
(
String
topic
,
String
data
)
{
...
...
@@ -140,16 +141,12 @@ public class HandlerMqttMessageImpl implements IEquipmentHandlerService {
EquipmentSpecificIndexVo
equipmentSpecificIndex
=
JSONObject
.
parseObject
(
topicEntity
.
getMessage
(),
EquipmentSpecificIndexVo
.
class
);
long
eqSpecId
=
equipmentSpecificIndex
.
getEquipmentSpecificId
();
String
nameKey
=
equipmentSpecificIndex
.
getNameKey
();
// if(topicEntity.getSimulationDate().equals("false") && !indexStateIsChange(equipmentSpecificIndex)){
// log.info("指标值没有发生变化: " + equipmentSpecificIndex.getIotCode()+"-"+equipmentSpecificIndex.getNameKey()+":"+equipmentSpecificIndex.getValue());
// return;
// }
EquipmentSpecificForRiskVo
equipmentSpecific
=
equipmentSpecificMapper
.
getOneById
(
eqSpecId
);
// 三维屏指标状态推送
String
specificIndexType
=
equipmentSpecificIndex
.
getType
();
String
typeCode
=
equipmentSpecificIndex
.
getTypeCode
();
if
(
nameKey
!=
null
&&
nameKeys
.
contains
(
nameKey
))
{
if
(
nameKey
!=
null
&&
nameKeys
.
contains
(
nameKey
))
{
if
(
equipmentSpecific
!=
null
)
{
equipmentSpecificIndex
.
setId
(
equipmentSpecific
.
getId
());
equipmentSpecificIndex
.
setName
(
equipmentSpecific
.
getName
());
...
...
@@ -159,7 +156,7 @@ public class HandlerMqttMessageImpl implements IEquipmentHandlerService {
String
title
=
String
.
format
(
"/%s/%s"
,
serviceName
,
"data/refresh/indexStatus"
);
webMqttComponent
.
publish
(
title
,
JSON
.
toJSONString
(
equipmentSpecificIndex
));
}
Equipment
equipment
=
topicEntity
.
getEquipment
()
==
null
?
impAndFireEquipMapper
.
queryImpEqumtByFireEquipmt
(
eqSpecId
):
topicEntity
.
getEquipment
();
Equipment
equipment
=
topicEntity
.
getEquipment
()
==
null
?
impAndFireEquipMapper
.
queryImpEqumtByFireEquipmt
(
eqSpecId
)
:
topicEntity
.
getEquipment
();
Toke
toke
=
remoteSecurityService
.
getServerToken
();
AlarmParam
deviceData
=
new
AlarmParam
();
log
.
info
(
"========equipmentSpecific==========: "
+
JSON
.
toJSONString
(
equipmentSpecific
));
...
...
@@ -173,20 +170,19 @@ public class HandlerMqttMessageImpl implements IEquipmentHandlerService {
* 推送告警数据
* 影响区域:消防安全=>火灾告警
*/
String
title
=
String
.
format
(
"/%s/%s/%s/%s"
,
serviceName
,
stationName
,
"data/refresh"
,
"fireSafety"
);
String
title
=
String
.
format
(
"/%s/%s/%s/%s"
,
serviceName
,
stationName
,
"data/refresh"
,
"fireSafety"
);
List
<
SafetyExecuteBo
>
dataList
=
view3dService
.
getSafetyExecuteListTop5
(
"fire"
,
equipmentSpecific
.
getOrgCode
());
Map
<
String
,
Object
>
result
=
new
HashMap
<>();
result
.
put
(
"type"
,
"fire"
);
Map
<
String
,
Object
>
result
=
new
HashMap
<>();
result
.
put
(
"type"
,
"fire"
);
result
.
put
(
"dataList"
,
dataList
);
webMqttComponent
.
publish
(
title
,
JSON
.
toJSONString
(
result
));
// 报警触发调用规则服务
if
(
EquipmentRiskTypeEnum
.
HZGJ
.
getCode
().
equals
(
specificIndexType
)&&!
ObjectUtils
.
isEmpty
(
equipment
)
&&
!
ObjectUtils
.
isEmpty
(
equipment
.
getReservePlan
()))
{
executeDynamicPlan
(
deviceData
,
equipment
,
equipmentSpecific
,
toke
,
null
);
if
(
EquipmentRiskTypeEnum
.
HZGJ
.
getCode
().
equals
(
specificIndexType
)
&&
!
ObjectUtils
.
isEmpty
(
equipment
))
{
this
.
startPlan
(
equipment
,
toke
,
eqSpecId
);
}
}
else
if
(
EquipmentRiskTypeEnum
.
GZ
.
getCode
().
equals
(
typeCode
))
{
// 设备故障处理逻辑
log
.
info
(
"(故障)Message typeCode is: "
+
typeCode
);
log
.
info
(
"(故障)Message typeCode is: "
+
typeCode
);
final
String
stateTrue
=
"true"
;
final
String
stateFalse
=
"false"
;
String
state
=
equipmentSpecificIndex
.
getValue
();
...
...
@@ -198,11 +194,11 @@ public class HandlerMqttMessageImpl implements IEquipmentHandlerService {
notifyAlarm
(
equipmentSpecificIndex
,
0
);
}
long
equipId
=
0
;
if
(
StringUtil
.
isNotEmpty
(
equipment
))
{
if
(
StringUtil
.
isNotEmpty
(
equipment
))
{
equipId
=
equipment
.
getId
();
// 是否关联风险点
List
<
FmeaEquipmentPoint
>
list
=
fmeaEquipmentPointMapper
.
listFmeaByEquipIndexIdAndEquipId
(
equipmentSpecificIndex
.
getId
(),
equipId
);
if
(
list
.
size
()
>
0
)
{
if
(
list
.
size
()
>
0
)
{
// 关联风险点进行rpn,rpni值的修改
list
.
forEach
(
fmeaEqPoint
->
{
long
fmeaId
=
fmeaEqPoint
.
getFmeaId
();
...
...
@@ -222,27 +218,50 @@ public class HandlerMqttMessageImpl implements IEquipmentHandlerService {
// 监测数据逻辑
log
.
info
(
"(监测)Message type is: "
+
specificIndexType
);
Map
<
String
,
Object
>
content
=
new
HashMap
<>();
String
location
=
equipmentSpecific
.
getLocation
()
+
" "
+
equipmentSpecific
.
getDescription
();
String
location
=
equipmentSpecific
.
getLocation
()
+
" "
+
equipmentSpecific
.
getDescription
();
content
.
put
(
"id"
,
equipmentSpecific
.
getId
());
content
.
put
(
"label"
,
equipmentSpecific
.
getName
()
+
" "
+
equipmentSpecificIndex
.
getEquipmentIndexName
()
+
(
ObjectUtils
.
isEmpty
(
location
)?(
"【"
+
location
+
"】"
):
""
));
content
.
put
(
"label"
,
equipmentSpecific
.
getName
()
+
" "
+
equipmentSpecificIndex
.
getEquipmentIndexName
()
+
(
ObjectUtils
.
isEmpty
(
location
)
?
(
"【"
+
location
+
"】"
)
:
""
));
content
.
put
(
"code"
,
equipmentSpecific
.
getCode
());
content
.
put
(
"changeDate"
,
new
Date
());
content
.
put
(
"orgCode"
,
equipmentSpecific
.
getOrgCode
());
content
.
put
(
"indexKey"
,
equipmentSpecificIndex
.
getNameKey
());
content
.
put
(
"status"
,
equipmentSpecificIndex
.
getValue
());
String
title
=
String
.
format
(
"/%s/%s/%s"
,
serviceName
,
stationName
,
"data/refresh/monitorData"
);
String
title
=
String
.
format
(
"/%s/%s/%s"
,
serviceName
,
stationName
,
"data/refresh/monitorData"
);
webMqttComponent
.
publish
(
title
,
JSON
.
toJSONString
(
view3dService
.
getEquipStatusList
(
equipmentSpecific
.
getOrgCode
())));
}
}
private
boolean
indexStateIsChange
(
EquipmentSpecificIndexVo
equipmentSpecificIndex
){
if
(
ObjectUtils
.
isEmpty
(
equipmentSpecificIndex
.
getValue
())){
private
void
startPlan
(
Equipment
equipment
,
Toke
toke
,
long
fireEquipmentId
)
{
PlanDetailVo
planDetailVo
=
planDetailMapper
.
getPlanDetailByEquipmentId
(
equipment
.
getId
());
//3d页面打开且存在预案,套用之前数字源码启动逻辑 进行预案的启动
boolean
isOnLine
=
this
.
getOpen3dUser
();
if
(
planDetailVo
!=
null
&&
isOnLine
)
{
ContingencyPlanParamVo
vo
=
new
ContingencyPlanParamVo
();
vo
.
setUserId
(
loginId
);
//TODO 待优化为调用平台进行查询
vo
.
setUserName
(
"系统用户"
);
vo
.
setFireEquipmentId
(
fireEquipmentId
);
try
{
iContingencyPlanService
.
planStart
(
vo
,
toke
);
}
catch
(
Exception
e
)
{
log
.
error
(
"启动预案失败"
,
e
);
}
}
}
private
boolean
getOpen3dUser
()
{
Set
keys
=
redisTemplate
.
keys
(
IContingencyPlanService
.
KEY_VIEW_3D_PAGE
);
return
!
CollectionUtils
.
isEmpty
(
keys
);
}
private
boolean
indexStateIsChange
(
EquipmentSpecificIndexVo
equipmentSpecificIndex
)
{
if
(
ObjectUtils
.
isEmpty
(
equipmentSpecificIndex
.
getValue
()))
{
return
false
;
}
String
key
=
equipmentSpecificIndex
.
getIotCode
()
+
"-"
+
equipmentSpecificIndex
.
getNameKey
();
if
(
redisTemplate
.
hasKey
(
key
))
{
String
key
=
equipmentSpecificIndex
.
getIotCode
()
+
"-"
+
equipmentSpecificIndex
.
getNameKey
();
if
(
redisTemplate
.
hasKey
(
key
))
{
EquipmentSpecificIndexVo
equipmentSpecificIndexVo
=
JSON
.
parseObject
(
redisTemplate
.
opsForValue
().
get
(
key
).
toString
(),
EquipmentSpecificIndexVo
.
class
);
if
(
equipmentSpecificIndex
.
getValue
().
equals
(
equipmentSpecificIndexVo
.
getValue
()))
{
if
(
equipmentSpecificIndex
.
getValue
().
equals
(
equipmentSpecificIndexVo
.
getValue
()))
{
return
false
;
}
}
...
...
@@ -252,7 +271,7 @@ public class HandlerMqttMessageImpl implements IEquipmentHandlerService {
/**
* <pre>
* @Description: rpn,rpni值修改
* @Description: rpn,
rpni值修改
* </pre>
*
* @MethodName:
...
...
@@ -262,34 +281,33 @@ public class HandlerMqttMessageImpl implements IEquipmentHandlerService {
* @Author keyong
* @Date 2020/11/16 18:26
*/
public
void
updateFmeaRpn
(
long
fmeaId
)
{
Fmea
fmea
=
fmeaMapper
.
getById
(
fmeaId
);
BigDecimal
oidValue
=
new
BigDecimal
(
fmea
.
getOidValue
());
BigDecimal
sidValue
=
new
BigDecimal
(
fmea
.
getSidValue
());
BigDecimal
didValue
=
new
BigDecimal
(
fmea
.
getDidValue
());
// 计算rpni
BigDecimal
rpni
=
oidValue
.
multiply
(
sidValue
).
multiply
(
didValue
).
setScale
(
2
,
BigDecimal
.
ROUND_HALF_UP
);
BigDecimal
rpn
;
if
(
fmea
.
getNewEvaluationOid
()
==
null
)
{
EvaluationModel
evaluationModel
=
this
.
getEvaluationModel
(
fmeaId
);
if
(
evaluationModel
!=
null
)
{
// 已经绑定点位或者巡检点项且匹配到风险模型,则更新为计算后的结果
BigDecimal
newOidValue
=
new
BigDecimal
(
evaluationModel
.
getCoefficient
());
rpn
=
newOidValue
.
multiply
(
sidValue
).
multiply
(
didValue
).
setScale
(
2
,
BigDecimal
.
ROUND_HALF_UP
);
fmea
.
setNewEvaluationOid
(
evaluationModel
.
getId
());
}
else
{
// 未绑定点位或者巡检点项或者匹配不到风险模型,则更新为rpn与rpni一致
fmea
.
setNewEvaluationOid
(
fmea
.
getEvaluationOid
());
rpn
=
rpni
;
}
}
else
{
BigDecimal
newOidValue
=
new
BigDecimal
(
fmea
.
getNewOidValue
());
rpn
=
newOidValue
.
multiply
(
sidValue
).
multiply
(
didValue
).
setScale
(
2
,
BigDecimal
.
ROUND_HALF_UP
);
}
fmea
.
setRpni
(
rpni
);
fmea
.
setRpn
(
rpn
);
// 更新fmea
fmeaMapper
.
updateRpn
(
fmea
);
}
public
void
updateFmeaRpn
(
long
fmeaId
)
{
Fmea
fmea
=
fmeaMapper
.
getById
(
fmeaId
);
BigDecimal
oidValue
=
new
BigDecimal
(
fmea
.
getOidValue
());
BigDecimal
sidValue
=
new
BigDecimal
(
fmea
.
getSidValue
());
BigDecimal
didValue
=
new
BigDecimal
(
fmea
.
getDidValue
());
// 计算rpni
BigDecimal
rpni
=
oidValue
.
multiply
(
sidValue
).
multiply
(
didValue
).
setScale
(
2
,
BigDecimal
.
ROUND_HALF_UP
);
BigDecimal
rpn
;
if
(
fmea
.
getNewEvaluationOid
()
==
null
)
{
EvaluationModel
evaluationModel
=
this
.
getEvaluationModel
(
fmeaId
);
if
(
evaluationModel
!=
null
)
{
// 已经绑定点位或者巡检点项且匹配到风险模型,则更新为计算后的结果
BigDecimal
newOidValue
=
new
BigDecimal
(
evaluationModel
.
getCoefficient
());
rpn
=
newOidValue
.
multiply
(
sidValue
).
multiply
(
didValue
).
setScale
(
2
,
BigDecimal
.
ROUND_HALF_UP
);
fmea
.
setNewEvaluationOid
(
evaluationModel
.
getId
());
}
else
{
// 未绑定点位或者巡检点项或者匹配不到风险模型,则更新为rpn与rpni一致
fmea
.
setNewEvaluationOid
(
fmea
.
getEvaluationOid
());
rpn
=
rpni
;
}
}
else
{
BigDecimal
newOidValue
=
new
BigDecimal
(
fmea
.
getNewOidValue
());
rpn
=
newOidValue
.
multiply
(
sidValue
).
multiply
(
didValue
).
setScale
(
2
,
BigDecimal
.
ROUND_HALF_UP
);
}
fmea
.
setRpni
(
rpni
);
fmea
.
setRpn
(
rpn
);
// 更新fmea
fmeaMapper
.
updateRpn
(
fmea
);
}
@Override
...
...
@@ -297,11 +315,11 @@ public class HandlerMqttMessageImpl implements IEquipmentHandlerService {
// 若登录系统则订阅装备数据
webMqttSubscribe
.
adapter
.
removeTopic
(
defaultTopic
);
String
topic
=
String
.
format
(
"%s.%s%s"
,
serverName
,
"equipment"
,
"/#"
);
String
[]
strs
=
webMqttSubscribe
.
adapter
.
getTopic
();
String
[]
strs
=
webMqttSubscribe
.
adapter
.
getTopic
();
List
<
String
>
list
=
Stream
.
of
(
strs
).
collect
(
Collectors
.
toList
());
if
(
list
.
size
()
>
0
)
{
if
(
list
.
size
()
>
0
)
{
list
.
forEach
(
x
->
{
if
(!(
x
.
equals
(
topic
)))
{
if
(!(
x
.
equals
(
topic
)))
{
webMqttSubscribe
.
adapter
.
addTopic
(
topic
);
}
});
...
...
@@ -312,34 +330,34 @@ public class HandlerMqttMessageImpl implements IEquipmentHandlerService {
}
/**
* <pre>
* @Description: 设备消息规则推送
* </pre>
*
* @MethodName:
* @Param: [deviceData, toke]
* @Return: void
* @Throws
* @Author keyong
* @Date 2020/11/16 18:26
*/
* <pre>
* @Description: 设备消息规则推送
* </pre>
*
* @MethodName:
* @Param: [deviceData, toke]
* @Return: void
* @Throws
* @Author keyong
* @Date 2020/11/16 18:26
*/
@Async
void
fireEquipRuleMessagePush
(
AlarmParam
deviceData
,
Toke
toke
)
{
RiskSourceServiceImpl
.
ruleMsgSend
(
deviceData
,
toke
,
log
,
ruleTrigger
);
}
/**
* <pre>
* @Description: 故障通知
* </pre>
*
* @MethodName:
* @Param: [fireEquipmentPoint, param]
* @Return: void
* @Throws
* @Author keyong
* @Date 2020/11/16 15:25
*/
* <pre>
* @Description: 故障通知
* </pre>
*
* @MethodName:
* @Param: [fireEquipmentPoint, param]
* @Return: void
* @Throws
* @Author keyong
* @Date 2020/11/16 15:25
*/
private
void
notifyAlarm
(
EquipmentSpecificIndexVo
equipmentSpecificIndex
,
int
state
)
{
List
<
FmeaEquipmentPoint
>
fmeaEquipmentPoints
=
fmeaEquipmentPointMapper
.
listByEquipmentPointId
(
equipmentSpecificIndex
.
getEquipmentIndexId
());
Set
<
Long
>
fmeaIds
=
Sets
.
newHashSet
();
...
...
@@ -380,33 +398,32 @@ public class HandlerMqttMessageImpl implements IEquipmentHandlerService {
}
/**
* <pre>
* @Description: 火警执行动态预案
* </pre>
*
* @MethodName:
* @Param:
* @Return: null
* @Throws
* @Author keyong
* @Date 2020/11/11 20:46
*/
* <pre>
* @Description: 火警执行动态预案
* </pre>
*
* @MethodName:
* @Param:
* @Return: null
* @Throws
* @Author keyong
* @Date 2020/11/11 20:46
*/
// @Async
@Override
public
String
executeDynamicPlan
(
AlarmParam
deviceData
,
Equipment
equipment
,
EquipmentSpecificForRiskVo
equipmentSpecific
,
Toke
toke
,
Long
recordId
)
{
public
String
executeDynamicPlan
(
AlarmParam
deviceData
,
Equipment
equipment
,
EquipmentSpecificForRiskVo
equipmentSpecific
,
Toke
toke
,
Long
recordId
)
{
String
batchNo
=
UUID
.
randomUUID
().
toString
();
RequestContext
.
setToken
(
toke
.
getToke
());
RequestContext
.
setProduct
(
toke
.
getProduct
());
try
{
alarmContingency
(
batchNo
,
equipmentSpecific
,
equipment
,
recordId
);
alarmContingency
(
batchNo
,
equipmentSpecific
,
equipment
,
recordId
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
batchNo
;
return
batchNo
;
}
public
void
alarmContingency
(
String
batchNo
,
EquipmentSpecificForRiskVo
equipmentSpecific
,
Equipment
equipment
,
Long
recordId
)
throws
Exception
{
// Object oldContingencyRo = redisTemplate.opsForValue().get("contingencyRo");
public
void
alarmContingency
(
String
batchNo
,
EquipmentSpecificForRiskVo
equipmentSpecific
,
Equipment
equipment
,
Long
recordId
)
throws
Exception
{
ContingencyRo
contingencyRo
=
new
ContingencyRo
();
contingencyRo
.
setBatchNo
(
batchNo
);
contingencyRo
.
setEquipmentId
(
String
.
valueOf
(
equipment
.
getId
()));
...
...
@@ -422,7 +439,7 @@ public class HandlerMqttMessageImpl implements IEquipmentHandlerService {
contingencyRo
.
setEquipmentOrgCode
(
equipment
.
getOrgCode
());
//查询重点设备关联视频点位
Map
<
String
,
Object
>
cameraInfo
=
impAndFireEquipMapper
.
queryCamera
(
String
.
valueOf
(
equipment
.
getId
()));
Map
<
String
,
Object
>
cameraInfo
=
impAndFireEquipMapper
.
queryCamera
(
String
.
valueOf
(
equipment
.
getId
()));
if
(
cameraInfo
!=
null
&&
!
cameraInfo
.
isEmpty
())
{
contingencyRo
.
setCameraCodes
(
String
.
valueOf
(
cameraInfo
.
get
(
"codes"
)));
contingencyRo
.
setCameraIds
(
String
.
valueOf
(
cameraInfo
.
get
(
"ids"
)));
...
...
@@ -468,9 +485,9 @@ public class HandlerMqttMessageImpl implements IEquipmentHandlerService {
}
contingencyRo
.
setTelemetryMap
(
telemetryMap
);
log
.
info
(
"开始调用规则 参数 contingencyRo{},reservePlan{},equipmentNames"
+
contingencyRo
.
toString
()+
","
+
equipment
.
getReservePlan
()+
","
+
ArrayUtils
.
toArray
(
equipment
.
getName
()));
log
.
info
(
"开始调用规则 参数 contingencyRo{},reservePlan{},equipmentNames"
+
contingencyRo
.
toString
()
+
","
+
equipment
.
getReservePlan
()
+
","
+
ArrayUtils
.
toArray
(
equipment
.
getName
()));
Object
result
=
ruleTrigger
.
publish
(
contingencyRo
,
equipment
.
getReservePlan
(),
ArrayUtils
.
toArray
(
equipment
.
getName
()));
log
.
info
(
"规则调用返回=="
,
result
);
log
.
info
(
"规则调用返回=="
,
result
);
ContingencyOriginalData
contingencyOriginalData
=
new
ContingencyOriginalData
();
BeanUtils
.
copyProperties
(
contingencyRo
,
contingencyOriginalData
);
...
...
YeeAmosFireAutoSysService/src/main/java/com/yeejoin/amos/fas/business/service/intfc/IContingencyPlanService.java
View file @
6f5819ae
...
...
@@ -23,14 +23,19 @@ public interface IContingencyPlanService {
String
DELETE_SYNC_PLAN_DOC
=
"DELETE_SYNC_PLAN_DOC"
;
String
DELETE_SYNC_PLAN_RULE
=
"urule/package/remove"
;
String
DELETE_SYNC_PLAN_EQUIP
=
"DELETE_SYNC_PLAN_EQUIP"
;
String
VIEW_3D_OPEN_STATUS
=
"/view/3d/page"
;
/**
* 3d用戶在线redis key前缀
*/
String
KEY_VIEW_3D_PAGE
=
"KEY_VIEW_3D_PAGE_"
;
ContingencyPlanResponseVo
planStart
(
ContingencyPlanParamVo
vo
,
Toke
toke
)
throws
Exception
;
ContingencyPlanResponseVo
planStart
(
ContingencyPlanParamVo
vo
,
Toke
toke
)
throws
Exception
;
ContingencyPlanParamVo
equipmentScene
(
Long
equipmentId
,
String
riskType
);
ContingencyPlanParamVo
equipmentScene
(
Long
equipmentId
,
String
riskType
);
/**
* 创建
*
* @param planDetail
* @return
*/
...
...
@@ -39,6 +44,7 @@ public interface IContingencyPlanService {
/**
* 编辑
*
* @param planDetail
* @return
*/
...
...
@@ -47,6 +53,7 @@ public interface IContingencyPlanService {
/**
* 单个详情
*
* @param id
* @return
*/
...
...
@@ -54,6 +61,7 @@ public interface IContingencyPlanService {
/**
* 启用
*
* @param idList
* @return
*/
...
...
@@ -61,6 +69,7 @@ public interface IContingencyPlanService {
/**
* 停用
*
* @param idList
* @return
*/
...
...
@@ -68,6 +77,7 @@ public interface IContingencyPlanService {
/**
* 删除
*
* @param idList
* @return
*/
...
...
@@ -76,12 +86,13 @@ public interface IContingencyPlanService {
/**
* 分页查询
* @param page 分页
* @param planName 预案名称
* @param classifyId 预案类型
* @param planRange 适用范围
* @param editOrgName 编写部门
* @param implementationTimeLeft 实施时间左界限
*
* @param page 分页
* @param planName 预案名称
* @param classifyId 预案类型
* @param planRange 适用范围
* @param editOrgName 编写部门
* @param implementationTimeLeft 实施时间左界限
* @param implementationTimeRight 实施时间右界限
* @return Page
*/
...
...
@@ -89,18 +100,21 @@ public interface IContingencyPlanService {
/**
* 查询预案使用的文档ID
*
* @return
*/
Map
<
Long
,
Long
>
getPlanUsedDocs
();
/**
* 查询预案使用的规则ID
*
* @return
*/
Map
<
String
,
Long
>
getPlanUsedRules
();
/**
* 查询预案使用的装备ID
*
* @return
*/
Map
<
Long
,
Long
>
getPlanUsedEquipments
();
...
...
@@ -112,7 +126,7 @@ public interface IContingencyPlanService {
Map
<
String
,
Object
>
firstGetRecord
(
String
batchNo
);
List
<
HashMap
<
String
,
Object
>>
getRecordList
(
String
batchNo
);
List
<
HashMap
<
String
,
Object
>>
getRecordList
(
String
batchNo
);
Page
recordListByPage
(
Page
page
,
Long
planId
,
String
planName
,
List
<
Long
>
classifyId
,
Date
startTimeLeft
,
Date
startTimeRight
,
Integer
executionType
,
Integer
planPattern
);
...
...
YeeAmosFireAutoSysService/src/main/java/com/yeejoin/amos/fas/business/vo/ContingencyPlanParamVo.java
View file @
6f5819ae
package
com
.
yeejoin
.
amos
.
fas
.
business
.
vo
;
//请求参数
import
lombok.Data
;
/**
* @author DELL
*/
@Data
public
class
ContingencyPlanParamVo
{
public
Long
fireEquipmentId
;
public
String
planId
;
public
Integer
status
;
...
...
@@ -11,44 +18,5 @@ public class ContingencyPlanParamVo {
public
String
riskType
;
public
String
userName
;
public
String
userId
;
public
String
getPlanId
()
{
return
planId
;
}
public
void
setPlanId
(
String
planId
)
{
this
.
planId
=
planId
;
}
public
Integer
getStatus
()
{
return
status
;
}
public
void
setStatus
(
Integer
status
)
{
this
.
status
=
status
;
}
public
String
getRiskType
()
{
return
riskType
;
}
public
void
setRiskType
(
String
riskType
)
{
this
.
riskType
=
riskType
;
}
public
String
getUserName
()
{
return
userName
;
}
public
void
setUserName
(
String
userName
)
{
this
.
userName
=
userName
;
}
public
String
getUserId
()
{
return
userId
;
}
public
void
setUserId
(
String
userId
)
{
this
.
userId
=
userId
;
}
}
YeeAmosFireAutoSysService/src/main/java/com/yeejoin/amos/fas/config/ApplicationRunnerImpl.java
View file @
6f5819ae
...
...
@@ -24,7 +24,7 @@ public class ApplicationRunnerImpl implements ApplicationRunner {
private
IContingencyPlanService
contingencyPlanService
;
@Override
public
void
run
(
ApplicationArguments
args
)
throws
Exception
{
public
void
run
(
ApplicationArguments
args
)
{
equipmentHandlerService
.
subscribeTopic
();
contingencyPlanService
.
subscribeTopic
();
}
...
...
YeeAmosFireAutoSysStart/src/main/resources/db/mapper/PlanDetailMapper.xml
View file @
6f5819ae
...
...
@@ -121,4 +121,16 @@
AND equip.is_delete != 1
AND rule.is_delete !=1
</select>
<select
id=
"getPlanDetailByEquipmentId"
resultType=
"com.yeejoin.amos.fas.business.vo.PlanDetailVo"
>
select
d.id,
d.status
from
c_plan_detail d,
c_plan_equipment e
where e.plan_id = d.id
and e.fire_equipment_id=#{fireEquipmentId}
and d.is_delete = false
limit 1
</select>
</mapper>
\ No newline at end of file
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