Commit 84e5b6db authored by 赵啸非's avatar 赵啸非

添加设备告警

parent ad4aa300
...@@ -127,3 +127,25 @@ INSERT INTO `mortals_xhx_param` VALUES (null, '设备来源,为其它时候上 ...@@ -127,3 +127,25 @@ INSERT INTO `mortals_xhx_param` VALUES (null, '设备来源,为其它时候上
INSERT INTO `mortals_xhx_param` VALUES (null, '设备类型', 'Device', 'deviceType', '13', '无感一码通', 1, 4, 0, 'deviceType', NULL, NULL, NULL); INSERT INTO `mortals_xhx_param` VALUES (null, '设备类型', 'Device', 'deviceType', '13', '无感一码通', 1, 4, 0, 'deviceType', NULL, NULL, NULL);
-- ----------------------------
-- 设备告警日志表
-- ----------------------------
DROP TABLE IF EXISTS `mortals_xhx_device_alarm`;
CREATE TABLE mortals_xhx_device_alarm(
`id` bigint(20) AUTO_INCREMENT COMMENT '主键ID,主键,自增长',
`deviceId` bigint(20) NOT NULL COMMENT '告警设备Id',
`deviceCode` varchar(64) NOT NULL COMMENT '告警设备编码',
`alarmType` tinyint(2) NOT NULL COMMENT '告警类型,(0.离线)',
`alarmLevel` tinyint(2) NOT NULL COMMENT '告警级别(0.危险,1.次要,2.一般)',
`alarmContent` varchar(512) NOT NULL COMMENT '告警详细内容',
`alarmTime` datetime NOT NULL COMMENT '告警时间',
`createTime` datetime NOT NULL COMMENT '创建时间',
`updateUserId` bigint(20) COMMENT '更新用户',
`updateTime` datetime COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='设备告警日志';
...@@ -31,6 +31,7 @@ const router = new Router({ ...@@ -31,6 +31,7 @@ const router = new Router({
builder('site/list', 'system/site/index'),//站点 builder('site/list', 'system/site/index'),//站点
...restBuilder('device', 'device'),// ...restBuilder('device', 'device'),//
...restBuilder('device/alarm', 'device/alarm'),//
...restBuilder('device/log', 'device/log'),// ...restBuilder('device/log', 'device/log'),//
...restBuilder('firm', 'firm'),// ...restBuilder('firm', 'firm'),//
......
<template>
<!-- 弹出框表单 -->
<el-dialog :title="title" :visible.sync="open" width="90%" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-row>
<Field label="告警设备Id" prop="deviceId" v-model="form.deviceId" placeholder="请输入告警设备Id"/>
<Field label="告警设备编码" prop="deviceCode" v-model="form.deviceCode" placeholder="请输入告警设备编码"/>
<Field label="告警类型," prop="alarmType" v-model="form.alarmType" type="select" :enumData="dict.alarmType" placeholder="请选择告警类型,"/>
<Field label="告警级别" prop="alarmLevel" v-model="form.alarmLevel" type="select" :enumData="dict.alarmLevel" placeholder="请选择告警级别"/>
<Field label="告警详细内容" prop="alarmContent" v-model="form.alarmContent" type="textarea" placeholder="请输入告警详细内容"/>
<Field label="告警时间" prop="alarmTime" v-model="form.alarmTime" type="date" />
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" v-if="pageInfo.type !== 'view'" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
</template>
<script>
import form from "@/assets/mixins/formdialog";
import dialogShow from "./dialogshow";
export default {
mixins: [form],
components: {
dialogShow ,
},
data() {
return {
// 遮罩层
loading: true,
// 弹出层标题
title: "设备告警日志",
// 是否显示弹出层
open: false,
toString:[
"alarmType",
"alarmLevel",
],
// 表单校验
rules: {
deviceCode: [
{required: true,message: "请输入告警设备编码", trigger: "blur" },
{max: 64,message: "最多只能录入64个字符",trigger: "blur",},
],
alarmType: [
{required: true,message: "请输入告警类型,", trigger: "blur" },
],
alarmLevel: [
{required: true,message: "请输入告警级别", trigger: "blur" },
],
alarmContent: [
{required: true,message: "请输入告警详细内容", trigger: "blur" },
{max: 512,message: "最多只能录入512个字符",trigger: "blur",},
],
alarmTime: [
{required: true,message: "请选择告警时间" },
],
createTime: [
{required: true,message: "请选择创建时间" },
],
}
};
},
methods: {
/** 编辑 */
edit(row) {
this.reset()
this.query = { id: row.id };
this.urls.currUrl ="device/alarm/edit";
this.getData();
this.pageInfo.type="edit"
this.title = "修改设备告警日志";
},
/** 新增 */
add(row) {
this.reset()
this.urls.currUrl = "device/alarm/add";
this.getData();
this.pageInfo.type="add"
this.title = "新增设备告警日志";
},
/** 查看*/
view(row) {
this.reset()
this.query = { id: row.id };
this.urls.currUrl ="device/alarm/view";
this.getData();
this.pageInfo.type="view"
this.title = "设备告警日志详细";
},
/**取消按钮 */
cancel() {
this.open = false;
},
/**获取数据后弹框 */
afterRender(data) {
this.open = true;
},
afterSubmit(data) {
this.open = false;
this.$emit("ok");
},
// 表单重置
reset() {
this.form = {
deviceId : null,
deviceCode : "",
alarmType : null,
alarmLevel : null,
alarmContent : "",
alarmTime : null,
};
this.resetForm("form");
},
resetForm(refName) {
if (this.$refs[refName]) {
this.$refs[refName].resetFields();
}
},
},
};
</script>
<template>
<div class="page">
<LayoutTable :data="tableData" :config="tableConfig"> </LayoutTable>
<dialog-show ref="dialogform" @ok="getData" />
</div>
</template>
<script>
/** 表单弹出框模式需引入 */
import dialogShow from "./dialogshow";
import table from "@/assets/mixins/table";
export default {
name: "DeviceAlarmList",
components: {
dialogShow,
},
mixins: [table],
created() {},
methods: {
/** 重写新增方法 */
toAdd(row) {
this.$refs.dialogform.add(row);
},
/** 重写编辑方法 */
toEdit(row) {
this.$refs.dialogform.edit(row);
},
/** 重写查看方法 */
toView(row) {
this.$refs.dialogform.view(row);
},
},
data() {
return {
config: {
search: [],
columns: [
{ type: "selection", width: 60 },
{ type: "index", label: "序号", width: 50 },
{ label: "站点名称", prop: "siteName" },
{ label: "站点编码", prop: "siteNum" },
{ label: "设备编码", prop: "deviceCode" },
{ label: "设备类型", prop: "deviceType" },
{ label: "告警类型", prop: "alarmType", },
{ label: "告警级别", prop: "alarmLevel", },
{ label: "告警详细内容", prop: "alarmContent" },
{
label: "告警时间",
prop: "alarmTime",
formatter: this.formatterDate,
},
],
},
};
},
};
</script>
\ No newline at end of file
<template>
<layout-view>
<el-descriptions :title="title" :column="column" :size="size" :colon="false" border>
<template slot="title">
<i class="el-icon-tickets"></i>
基本详细信息
</template>
<template slot="extra">
<el-button type="primary" @click="$router.go(-1)" size="small">返回</el-button>
</template>
<el-descriptions-item label="告警设备Id" label-class-name="labelClass" content-class-name="contentClass">
{{form.deviceId}}
</el-descriptions-item>
<el-descriptions-item label="告警设备编码" label-class-name="labelClass" content-class-name="contentClass">
{{form.deviceCode}}
</el-descriptions-item>
<el-descriptions-item label="告警类型," label-class-name="labelClass" content-class-name="contentClass">
{{ util_formatters("alarmType", form.alarmType) }}
</el-descriptions-item>
<el-descriptions-item label="告警级别" label-class-name="labelClass" content-class-name="contentClass">
{{ util_formatters("alarmLevel", form.alarmLevel) }}
</el-descriptions-item>
<el-descriptions-item label="告警详细内容" label-class-name="labelClass" content-class-name="contentClass">
{{form.alarmContent}}
</el-descriptions-item>
<el-descriptions-item label="告警时间" label-class-name="labelClass" content-class-name="contentClass">
{{ util_formatterDate(form.alarmTime)}}
</el-descriptions-item>
</el-descriptions>
</layout-view>
</template>
<script>
import view from "@/assets/mixins/view";
export default {
mixins: [view],
components: {
},
methods: {
},
data() {
return {
size:"small",
column:2,
toString:[
"alarmType",
"alarmLevel",
],
toArrays: [
],
toDate: [
]
}
}
}
</script>
<style lang="less">
.labelClass{
width: 200px;
}
.el-descriptions__body{
margin-left: 5px;
margin-right: 5px;
color: #606266;
background-color: #FFF;
}
.contentClass{
width: 600px;
}
</style>
\ No newline at end of file
<template> <template>
<div class="page"> <div class="page">
<LayoutTable :data="tableData" :config="tableConfig"> <LayoutTable :data="tableData" :config="tableConfig">
<el-tag slot="table-body-head" style="margin:5px" type="success">当前在线设备:{{tableData.onlineCount}}</el-tag> <el-tag slot="table-body-head" style="margin: 5px" type="success"
>当前在线设备:{{ tableData.onlineCount }}</el-tag
>
<el-tag slot="table-body-head" style="margin:5px" type="danger">当前离线设备:{{tableData.offlineCount}}</el-tag> <el-tag slot="table-body-head" style="margin: 5px" type="danger"
>当前离线设备:{{ tableData.offlineCount }}</el-tag
>
</LayoutTable> </LayoutTable>
<dialog-show ref="dialogform" @ok="getData" /> <dialog-show ref="dialogform" @ok="getData" />
...@@ -31,10 +33,18 @@ export default { ...@@ -31,10 +33,18 @@ export default {
let msg = ""; let msg = "";
let content = JSON.parse(obj.body.content); let content = JSON.parse(obj.body.content);
if (content.deviceOnlineStatus == 1) { if (content.deviceOnlineStatus == 1) {
console.log(_this.tableData.dict) console.log(_this.tableData.dict);
msg = _this.tableData.dict.deviceType[content.deviceType]+ "设备:" + content.deviceCode + " 上线!"; msg =
_this.tableData.dict.deviceType[content.deviceType] +
"设备:" +
content.deviceCode +
" 上线!";
} else { } else {
msg = _this.tableData.dict.deviceType[content.deviceType]+"设备:" + content.deviceCode + " 离线!"; msg =
_this.tableData.dict.deviceType[content.deviceType] +
"设备:" +
content.deviceCode +
" 离线!";
} }
_this.$notify({ _this.$notify({
...@@ -52,7 +62,7 @@ export default { ...@@ -52,7 +62,7 @@ export default {
this.getsocketData = getsocketData; this.getsocketData = getsocketData;
// 注册监听事件 // 注册监听事件
window.addEventListener("onmessageWS", getsocketData,false); window.addEventListener("onmessageWS", getsocketData, false);
}, },
methods: { methods: {
/** 重写新增方法 */ /** 重写新增方法 */
...@@ -65,7 +75,39 @@ export default { ...@@ -65,7 +75,39 @@ export default {
}, },
/** 重写查看方法 */ /** 重写查看方法 */
toView(row) { toView(row) {
this.$refs.dialogform.view(row); this.$refs.dialogform.view(row);
},
rebootDevice(row) {
this.$post("/device/execmd", {
id: row.id,
type: 1,
})
.then((res) => {
if (res.code == 1) {
this.$message.success("重启设备命令下发成功!");
//this.getData();
}
})
.catch((error) => {
this.$message.error(error.message);
});
},
closeDevice(row) {
this.$post("/device/execmd", {
id: row.id,
type: 2,
})
.then((res) => {
if (res.code == 1) {
this.$message.success("关闭设备命令下发成功!");
//this.getData();
}
})
.catch((error) => {
this.$message.error(error.message);
});
}, },
}, },
data() { data() {
...@@ -73,42 +115,41 @@ export default { ...@@ -73,42 +115,41 @@ export default {
config: { config: {
getsocketData: null, getsocketData: null,
search: [ search: [
{ {
name: 'deviceCode', name: "deviceCode",
type: 'text', type: "text",
label: '设备编码', label: "设备编码",
fuzzy:true fuzzy: true,
}, },
{ {
name: 'siteName', name: "siteName",
type: 'text', type: "text",
label: '站点名称', label: "站点名称",
fuzzy:true fuzzy: true,
}, },
{ {
name: 'deviceType', name: "deviceType",
type: 'select', type: "select",
label: '设备类型', label: "设备类型",
}, },
{ {
name: 'deviceOnlineStatus', name: "deviceOnlineStatus",
type: 'select', type: "select",
label: '在线状态', label: "在线状态",
}, },
], ],
columns: [ columns: [
{ type: "selection", width: 60 }, { type: "selection", width: 60 },
// { label: "设备名称", prop: "deviceName" }, // { label: "设备名称", prop: "deviceName" },
{ label: "所属站点", prop: "siteName" }, { label: "所属站点", prop: "siteName" },
{ label: "设备编码", prop: "deviceCode" }, { label: "设备编码", prop: "deviceCode" },
{ label: "设备类型", prop: "deviceType", formatter: this.formatter }, { label: "设备类型", prop: "deviceType", formatter: this.formatter },
{ {
label: "在线状态 ", label: "在线状态 ",
prop: "deviceOnlineStatus", prop: "deviceOnlineStatus",
...@@ -122,16 +163,50 @@ export default { ...@@ -122,16 +163,50 @@ export default {
}, },
{ {
label: "操作", label: "操作",
width: 240, width: 280,
formatter: (row) => { formatter: (row) => {
return ( return (
<table-buttons <div>
noAdd <table-buttons
row={row} noAdd
onEdit={this.toEdit} row={row}
onView={this.toView} onEdit={this.toEdit}
onDel={this.toDel} onView={this.toView}
/> onDel={this.toDel}
/>
{row.deviceType === 15 ? (
<el-button
size="mini"
type="text"
icon="el-icon-refresh-right"
onClick={() => {
this.rebootDevice(row);
}}
>
重启
</el-button>
) : (
""
)}
<span> </span>
{row.deviceType === 15 ? (
<el-button
size="mini"
type="text"
icon="el-icon-switch-button"
onClick={() => {
this.closeDevice(row);
}}
>
关机
</el-button>
) : (
""
)}
<span> </span>
</div>
); );
}, },
}, },
......
...@@ -12,6 +12,10 @@ public class DeviceResp implements Serializable { ...@@ -12,6 +12,10 @@ public class DeviceResp implements Serializable {
* 在线状态(0在线 1离线) * 在线状态(0在线 1离线)
*/ */
private String isOnLine; private String isOnLine;
/**
* 0.正常,1.重启,2.关机
*/
private Integer type;
} }
...@@ -3,10 +3,12 @@ package com.mortals.xhx.busiz.web; ...@@ -3,10 +3,12 @@ package com.mortals.xhx.busiz.web;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.exception.AppException; import com.mortals.framework.exception.AppException;
import com.mortals.framework.service.ICacheService;
import com.mortals.xhx.base.framework.ws.message.SendToAllRequest; import com.mortals.xhx.base.framework.ws.message.SendToAllRequest;
import com.mortals.xhx.base.framework.ws.util.WebSocketUtil; import com.mortals.xhx.base.framework.ws.util.WebSocketUtil;
import com.mortals.xhx.busiz.req.DeviceReq; import com.mortals.xhx.busiz.req.DeviceReq;
import com.mortals.xhx.busiz.rsp.ApiResp; import com.mortals.xhx.busiz.rsp.ApiResp;
import com.mortals.xhx.busiz.rsp.DeviceResp;
import com.mortals.xhx.common.code.ApiRespCodeEnum; import com.mortals.xhx.common.code.ApiRespCodeEnum;
import com.mortals.xhx.common.code.DeviceOnlineStatusEnum; import com.mortals.xhx.common.code.DeviceOnlineStatusEnum;
import com.mortals.xhx.common.utils.SendTaskThreadPool; import com.mortals.xhx.common.utils.SendTaskThreadPool;
...@@ -25,6 +27,8 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -25,6 +27,8 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.Date; import java.util.Date;
import static com.mortals.xhx.common.key.RedisKey.KEY_DEVICE_TYPE_CACHE;
/** /**
* 设备 * 设备
* *
...@@ -41,6 +45,8 @@ public class DeviceApiController { ...@@ -41,6 +45,8 @@ public class DeviceApiController {
private DeviceService deviceService; private DeviceService deviceService;
@Autowired @Autowired
private SendTaskThreadPool sendTaskThreadPool; private SendTaskThreadPool sendTaskThreadPool;
@Autowired
private ICacheService cacheService;
/** /**
* 设备数据上报 * 设备数据上报
...@@ -51,13 +57,23 @@ public class DeviceApiController { ...@@ -51,13 +57,23 @@ public class DeviceApiController {
@PostMapping("upload") @PostMapping("upload")
public String upload(DeviceReq req) { public String upload(DeviceReq req) {
log.debug("【设备数据上报】【请求体】--> " + JSONObject.toJSONString(req)); log.debug("【设备数据上报】【请求体】--> " + JSONObject.toJSONString(req));
ApiResp rsp = new ApiResp<>(); ApiResp<DeviceResp> rsp = new ApiResp<>();
rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel()); rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue()); rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
UploadTask uploadTask = new UploadTask(req, deviceLogService, deviceService); UploadTask uploadTask = new UploadTask(req, deviceLogService, deviceService);
if(!ObjectUtils.isEmpty(sendTaskThreadPool)){ if (!ObjectUtils.isEmpty(sendTaskThreadPool)) {
sendTaskThreadPool.execute(uploadTask); sendTaskThreadPool.execute(uploadTask);
} }
//判断当前设备是否设置了标志类型,如果设置了 则访问
Integer type = cacheService.get(KEY_DEVICE_TYPE_CACHE + req.getDevicenum(), Integer.class);
if (!ObjectUtils.isEmpty(type)) {
DeviceResp deviceResp = new DeviceResp();
deviceResp.setType(type);
rsp.setData(deviceResp);
}
cacheService.del(KEY_DEVICE_TYPE_CACHE + req.getDevicenum());
//if(!ObjectUtils.isEmpty(type))
log.debug("响应【设备数据上报】【响应体】--> " + JSONObject.toJSONString(rsp)); log.debug("响应【设备数据上报】【响应体】--> " + JSONObject.toJSONString(rsp));
return JSON.toJSONString(rsp); return JSON.toJSONString(rsp);
} }
......
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 告警级别(0.危险,1.次要,2.一般)枚举类
*
* @author zxfei
*/
public enum AlarmLevelEnum {
危险(0, "危险"),
次要(1, "次要"),
一般(2, "一般");
private Integer value;
private String desc;
AlarmLevelEnum(Integer value, String desc) {
this.value = value;
this.desc = desc;
}
public Integer getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public static AlarmLevelEnum getByValue(Integer value) {
for (AlarmLevelEnum alarmLevelEnum : AlarmLevelEnum.values()) {
if (alarmLevelEnum.getValue() == value) {
return alarmLevelEnum;
}
}
return null;
}
/**
* 获取Map集合
*
* @param eItem 不包含项
* @return
*/
public static Map<String, String> getEnumMap(Integer... eItem) {
Map<String, String> resultMap = new LinkedHashMap<>();
for (AlarmLevelEnum item : AlarmLevelEnum.values()) {
try {
boolean hasE = false;
for (Integer e : eItem) {
if (item.getValue() == e) {
hasE = true;
break;
}
}
if (!hasE) {
resultMap.put(item.getValue() + "", item.getDesc());
}
} catch (Exception ex) {
}
}
return resultMap;
}
}
\ No newline at end of file
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 告警类型,(0.离线)枚举类
*
* @author zxfei
*/
public enum AlarmTypeEnum {
离线(0, "离线");
private Integer value;
private String desc;
AlarmTypeEnum(Integer value, String desc) {
this.value = value;
this.desc = desc;
}
public Integer getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public static AlarmTypeEnum getByValue(Integer value) {
for (AlarmTypeEnum alarmTypeEnum : AlarmTypeEnum.values()) {
if (alarmTypeEnum.getValue() == value) {
return alarmTypeEnum;
}
}
return null;
}
/**
* 获取Map集合
*
* @param eItem 不包含项
* @return
*/
public static Map<String, String> getEnumMap(Integer... eItem) {
Map<String, String> resultMap = new LinkedHashMap<>();
for (AlarmTypeEnum item : AlarmTypeEnum.values()) {
try {
boolean hasE = false;
for (Integer e : eItem) {
if (item.getValue() == e) {
hasE = true;
break;
}
}
if (!hasE) {
resultMap.put(item.getValue() + "", item.getDesc());
}
} catch (Exception ex) {
}
}
return resultMap;
}
}
\ No newline at end of file
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
public enum DeviceActionEnum {
正常(0, "正常"),
重启(1, "重启"),
关机(2, "关机");
private Integer value;
private String desc;
DeviceActionEnum(Integer value, String desc) {
this.value = value;
this.desc = desc;
}
public Integer getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public static DeviceActionEnum getByValue(Integer value) {
for (DeviceActionEnum alarmLevelEnum : DeviceActionEnum.values()) {
if (alarmLevelEnum.getValue() == value) {
return alarmLevelEnum;
}
}
return null;
}
/**
* 获取Map集合
*
* @param eItem 不包含项
* @return
*/
public static Map<String, String> getEnumMap(Integer... eItem) {
Map<String, String> resultMap = new LinkedHashMap<>();
for (DeviceActionEnum item : DeviceActionEnum.values()) {
try {
boolean hasE = false;
for (Integer e : eItem) {
if (item.getValue() == e) {
hasE = true;
break;
}
}
if (!hasE) {
resultMap.put(item.getValue() + "", item.getDesc());
}
} catch (Exception ex) {
}
}
return resultMap;
}
}
\ No newline at end of file
...@@ -20,7 +20,12 @@ public enum DeviceTypeEnum { ...@@ -20,7 +20,12 @@ public enum DeviceTypeEnum {
信息发布(9, "信息发布"), 信息发布(9, "信息发布"),
导视机(10, "导视机"), 导视机(10, "导视机"),
开标室设备(11, "开标室设备"), 开标室设备(11, "开标室设备"),
背靠背(12, "背靠背"); 背靠背(12, "背靠背"),
无感一码通(13, "无感一码通"),
桌面式自助终端(14, "桌面式自助终端"),
可视化触控大屏(15, "可视化触控大屏"),
人脸识别考勤机(16, "人脸识别考勤机"),
;
private Integer value; private Integer value;
private String desc; private String desc;
......
...@@ -10,4 +10,7 @@ public class RedisKey { ...@@ -10,4 +10,7 @@ public class RedisKey {
*/ */
public static final String KEY_MENU_CACHE = "iot:base:MenuCacheKey:"; public static final String KEY_MENU_CACHE = "iot:base:MenuCacheKey:";
public static final String KEY_DEVICE_TYPE_CACHE = "device:TypeCacheKey:";
} }
...@@ -10,14 +10,18 @@ import com.mortals.framework.util.DateUtils; ...@@ -10,14 +10,18 @@ import com.mortals.framework.util.DateUtils;
import com.mortals.xhx.base.framework.ws.message.SendToAllRequest; import com.mortals.xhx.base.framework.ws.message.SendToAllRequest;
import com.mortals.xhx.base.framework.ws.message.UserJoinNoticeRequest; import com.mortals.xhx.base.framework.ws.message.UserJoinNoticeRequest;
import com.mortals.xhx.base.framework.ws.util.WebSocketUtil; import com.mortals.xhx.base.framework.ws.util.WebSocketUtil;
import com.mortals.xhx.common.code.AlarmLevelEnum;
import com.mortals.xhx.common.code.AlarmTypeEnum;
import com.mortals.xhx.common.code.DeviceOnlineStatusEnum; import com.mortals.xhx.common.code.DeviceOnlineStatusEnum;
import com.mortals.xhx.common.code.DeviceSourceEnum; import com.mortals.xhx.common.code.DeviceSourceEnum;
import com.mortals.xhx.common.key.ParamKey; import com.mortals.xhx.common.key.ParamKey;
import com.mortals.xhx.common.utils.SendTask; import com.mortals.xhx.common.utils.SendTask;
import com.mortals.xhx.common.utils.SendTaskThreadPool; import com.mortals.xhx.common.utils.SendTaskThreadPool;
import com.mortals.xhx.module.device.model.DeviceAlarmEntity;
import com.mortals.xhx.module.device.model.DeviceEntity; import com.mortals.xhx.module.device.model.DeviceEntity;
import com.mortals.xhx.module.device.model.DeviceLogEntity; import com.mortals.xhx.module.device.model.DeviceLogEntity;
import com.mortals.xhx.module.device.model.DeviceLogQuery; import com.mortals.xhx.module.device.model.DeviceLogQuery;
import com.mortals.xhx.module.device.service.DeviceAlarmService;
import com.mortals.xhx.module.device.service.DeviceLogService; import com.mortals.xhx.module.device.service.DeviceLogService;
import com.mortals.xhx.module.device.service.DeviceService; import com.mortals.xhx.module.device.service.DeviceService;
import lombok.extern.apachecommons.CommonsLog; import lombok.extern.apachecommons.CommonsLog;
...@@ -46,6 +50,9 @@ public class DeviceStatTaskImpl implements ITaskExcuteService { ...@@ -46,6 +50,9 @@ public class DeviceStatTaskImpl implements ITaskExcuteService {
@Autowired @Autowired
private SendTaskThreadPool sendTaskThreadPool; private SendTaskThreadPool sendTaskThreadPool;
@Autowired
private DeviceAlarmService deviceAlarmService;
@Override @Override
public void excuteTask(ITask task) throws AppException { public void excuteTask(ITask task) throws AppException {
...@@ -76,14 +83,27 @@ public class DeviceStatTaskImpl implements ITaskExcuteService { ...@@ -76,14 +83,27 @@ public class DeviceStatTaskImpl implements ITaskExcuteService {
//更新设备下线 //更新设备下线
device.setOfflineTime(new Date()); device.setOfflineTime(new Date());
device.setDeviceOnlineStatus(DeviceOnlineStatusEnum.离线.getValue()); device.setDeviceOnlineStatus(DeviceOnlineStatusEnum.离线.getValue());
// deviceService.update(device);
WebSocketUtil.broadcast(SendToAllRequest.TYPE, new SendToAllRequest().setContent(JSON.toJSONString(device)));
return device; return device;
} }
return null; return null;
}).filter(f->f!=null).collect(Collectors.toList()); }).filter(f->f!=null).collect(Collectors.toList());
deviceService.update(collect,null); deviceService.update(collect,null);
List<DeviceAlarmEntity> alarmEntityList = collect.stream().map(device -> {
//新增告警信息
DeviceAlarmEntity deviceAlarmEntity = new DeviceAlarmEntity();
deviceAlarmEntity.initAttrValue();
deviceAlarmEntity.setDeviceId(device.getId());
deviceAlarmEntity.setDeviceCode(device.getDeviceCode());
deviceAlarmEntity.setAlarmType(AlarmTypeEnum.离线.getValue());
deviceAlarmEntity.setAlarmLevel(AlarmLevelEnum.一般.getValue());
deviceAlarmEntity.setAlarmTime(new Date());
deviceAlarmEntity.setAlarmContent("当前设备已离线,请注意!");
deviceAlarmEntity.setCreateTime(new Date());
deviceAlarmEntity.setCreateUserId(1L);
return deviceAlarmEntity;
}).collect(Collectors.toList());
deviceAlarmService.save(alarmEntityList);
} catch (Exception e) { } catch (Exception e) {
log.error("更新设备状态任务异常,结束执行", e); log.error("更新设备状态任务异常,结束执行", e);
} }
......
package com.mortals.xhx.module.device.dao;
import com.mortals.framework.dao.ICRUDDao;
import com.mortals.xhx.module.device.model.DeviceAlarmEntity;
import java.util.List;
/**
* 设备告警日志Dao
* 设备告警日志 DAO接口
*
* @author zxfei
* @date 2022-08-04
*/
public interface DeviceAlarmDao extends ICRUDDao<DeviceAlarmEntity,Long>{
}
package com.mortals.xhx.module.device.dao.ibatis;
import org.springframework.stereotype.Repository;
import com.mortals.xhx.module.device.dao.DeviceAlarmDao;
import com.mortals.xhx.module.device.model.DeviceAlarmEntity;
import java.util.Date;
import com.mortals.framework.dao.ibatis.BaseCRUDDaoMybatis;
import java.util.List;
/**
* 设备告警日志DaoImpl DAO接口
*
* @author zxfei
* @date 2022-08-04
*/
@Repository("deviceAlarmDao")
public class DeviceAlarmDaoImpl extends BaseCRUDDaoMybatis<DeviceAlarmEntity,Long> implements DeviceAlarmDao {
}
package com.mortals.xhx.module.device.model;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.mortals.framework.annotation.Excel;
import com.mortals.framework.model.BaseEntityLong;
import com.mortals.xhx.module.device.model.vo.DeviceAlarmVo;
/**
* 设备告警日志实体对象
*
* @author zxfei
* @date 2022-08-04
*/
public class DeviceAlarmEntity extends DeviceAlarmVo {
private static final long serialVersionUID = 1L;
/**
* 告警设备Id
*/
private Long deviceId;
/**
* 告警设备编码
*/
private String deviceCode;
/**
* 告警类型,(0.离线)
*/
private Integer alarmType;
/**
* 告警级别(0.危险,1.次要,2.一般)
*/
private Integer alarmLevel;
/**
* 告警详细内容
*/
private String alarmContent;
/**
* 告警时间
*/
@Excel(name = "告警时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date alarmTime;
public DeviceAlarmEntity(){}
/**
* 获取 告警设备Id
* @return Long
*/
public Long getDeviceId(){
return deviceId;
}
/**
* 设置 告警设备Id
* @param deviceId
*/
public void setDeviceId(Long deviceId){
this.deviceId = deviceId;
}
/**
* 获取 告警设备编码
* @return String
*/
public String getDeviceCode(){
return deviceCode;
}
/**
* 设置 告警设备编码
* @param deviceCode
*/
public void setDeviceCode(String deviceCode){
this.deviceCode = deviceCode;
}
/**
* 获取 告警类型,(0.离线)
* @return Integer
*/
public Integer getAlarmType(){
return alarmType;
}
/**
* 设置 告警类型,(0.离线)
* @param alarmType
*/
public void setAlarmType(Integer alarmType){
this.alarmType = alarmType;
}
/**
* 获取 告警级别(0.危险,1.次要,2.一般)
* @return Integer
*/
public Integer getAlarmLevel(){
return alarmLevel;
}
/**
* 设置 告警级别(0.危险,1.次要,2.一般)
* @param alarmLevel
*/
public void setAlarmLevel(Integer alarmLevel){
this.alarmLevel = alarmLevel;
}
/**
* 获取 告警详细内容
* @return String
*/
public String getAlarmContent(){
return alarmContent;
}
/**
* 设置 告警详细内容
* @param alarmContent
*/
public void setAlarmContent(String alarmContent){
this.alarmContent = alarmContent;
}
/**
* 获取 告警时间
* @return Date
*/
public Date getAlarmTime(){
return alarmTime;
}
/**
* 设置 告警时间
* @param alarmTime
*/
public void setAlarmTime(Date alarmTime){
this.alarmTime = alarmTime;
}
@Override
public int hashCode() {
return this.getId().hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (obj instanceof DeviceAlarmEntity) {
DeviceAlarmEntity tmp = (DeviceAlarmEntity) obj;
if (this.getId() == tmp.getId()) {
return true;
}
}
return false;
}
public String toString(){
StringBuilder sb = new StringBuilder("");
sb.append(",deviceId:").append(getDeviceId());
sb.append(",deviceCode:").append(getDeviceCode());
sb.append(",alarmType:").append(getAlarmType());
sb.append(",alarmLevel:").append(getAlarmLevel());
sb.append(",alarmContent:").append(getAlarmContent());
sb.append(",alarmTime:").append(getAlarmTime());
return sb.toString();
}
public void initAttrValue(){
this.deviceId = null;
this.deviceCode = "";
this.alarmType = null;
this.alarmLevel = null;
this.alarmContent = "";
this.alarmTime = null;
}
}
\ No newline at end of file
package com.mortals.xhx.module.device.model.vo;
import com.mortals.framework.model.BaseEntityLong;
import com.mortals.xhx.module.device.model.DeviceAlarmEntity;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* 设备告警日志视图对象
*
* @author zxfei
* @date 2022-08-04
*/
@Data
public class DeviceAlarmVo extends BaseEntityLong {
/**
* 站点编号
*/
private String siteNum;
/**
* 站点名称
*/
private String siteName;
private String deviceCode;
private String deviceType;
}
\ No newline at end of file
...@@ -14,4 +14,5 @@ import java.util.List; ...@@ -14,4 +14,5 @@ import java.util.List;
@Data @Data
public class DeviceVo extends BaseEntityLong { public class DeviceVo extends BaseEntityLong {
} }
\ No newline at end of file
package com.mortals.xhx.module.device.service;
import com.mortals.framework.service.ICRUDService;
import com.mortals.xhx.module.device.model.DeviceAlarmEntity;
/**
* DeviceAlarmService
*
* 设备告警日志 service接口
*
* @author zxfei
* @date 2022-08-04
*/
public interface DeviceAlarmService extends ICRUDService<DeviceAlarmEntity,Long>{
}
\ No newline at end of file
package com.mortals.xhx.module.device.service; package com.mortals.xhx.module.device.service;
import com.mortals.framework.model.Context;
import com.mortals.framework.service.ICRUDCacheService; import com.mortals.framework.service.ICRUDCacheService;
import com.mortals.xhx.module.device.model.DeviceEntity; import com.mortals.xhx.module.device.model.DeviceEntity;
/** /**
* DeviceService * DeviceService
* *
...@@ -11,4 +13,7 @@ import com.mortals.xhx.module.device.model.DeviceEntity; ...@@ -11,4 +13,7 @@ import com.mortals.xhx.module.device.model.DeviceEntity;
*/ */
public interface DeviceService extends ICRUDCacheService<DeviceEntity,Long>{ public interface DeviceService extends ICRUDCacheService<DeviceEntity,Long>{
void action(Long id, Integer type, Context context);
} }
\ No newline at end of file
package com.mortals.xhx.module.device.service.impl;
import com.mortals.framework.model.PageInfo;
import com.mortals.xhx.common.code.DeviceTypeEnum;
import com.mortals.xhx.module.device.model.DeviceEntity;
import com.mortals.xhx.module.device.service.DeviceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.xhx.module.device.dao.DeviceAlarmDao;
import com.mortals.xhx.module.device.model.DeviceAlarmEntity;
import com.mortals.xhx.module.device.service.DeviceAlarmService;
import java.util.List;
/**
* DeviceAlarmService
* 设备告警日志 service实现
*
* @author zxfei
* @date 2022-08-04
*/
@Service("deviceAlarmService")
public class DeviceAlarmServiceImpl extends AbstractCRUDServiceImpl<DeviceAlarmDao, DeviceAlarmEntity, Long> implements DeviceAlarmService {
@Autowired
private DeviceService deviceService;
@Override
protected void findAfter(DeviceAlarmEntity params, PageInfo pageInfo, Context context, List<DeviceAlarmEntity> list) throws AppException {
list.forEach(item -> {
DeviceEntity deviceEntity = deviceService.get(item.getDeviceId());
item.setSiteName(deviceEntity.getSiteName());
item.setSiteNum(deviceEntity.getSiteNum());
item.setDeviceType(DeviceTypeEnum.getByValue(deviceEntity.getDeviceType()).getDesc());
});
super.findAfter(params, pageInfo, context, list);
}
}
\ No newline at end of file
package com.mortals.xhx.module.device.service.impl; package com.mortals.xhx.module.device.service.impl;
import com.mortals.framework.exception.AppException; import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context; import com.mortals.framework.model.Context;
import com.mortals.framework.service.ICacheService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.mortals.framework.service.impl.AbstractCRUDCacheServiceImpl; import com.mortals.framework.service.impl.AbstractCRUDCacheServiceImpl;
import com.mortals.xhx.module.device.dao.DeviceDao; import com.mortals.xhx.module.device.dao.DeviceDao;
...@@ -8,16 +11,20 @@ import com.mortals.xhx.module.device.model.DeviceEntity; ...@@ -8,16 +11,20 @@ import com.mortals.xhx.module.device.model.DeviceEntity;
import com.mortals.xhx.module.device.service.DeviceService; import com.mortals.xhx.module.device.service.DeviceService;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import static com.mortals.xhx.common.key.RedisKey.KEY_DEVICE_TYPE_CACHE;
/** /**
* DeviceService * DeviceService
* 设备 service实现 * 设备 service实现
* *
* @author zxfei * @author zxfei
* @date 2022-03-09 * @date 2022-03-09
*/ */
@Service("deviceService") @Service("deviceService")
public class DeviceServiceImpl extends AbstractCRUDCacheServiceImpl<DeviceDao, DeviceEntity, Long> implements DeviceService { public class DeviceServiceImpl extends AbstractCRUDCacheServiceImpl<DeviceDao, DeviceEntity, Long> implements DeviceService {
@Autowired
private ICacheService cacheService;
@Override @Override
protected String getExtKey(DeviceEntity data) { protected String getExtKey(DeviceEntity data) {
...@@ -27,9 +34,17 @@ public class DeviceServiceImpl extends AbstractCRUDCacheServiceImpl<DeviceDao, D ...@@ -27,9 +34,17 @@ public class DeviceServiceImpl extends AbstractCRUDCacheServiceImpl<DeviceDao, D
@Override @Override
protected void saveBefore(DeviceEntity entity, Context context) throws AppException { protected void saveBefore(DeviceEntity entity, Context context) throws AppException {
if(ObjectUtils.isEmpty(entity.getDeviceCode())){ if (ObjectUtils.isEmpty(entity.getDeviceCode())) {
entity.setDeviceCode(entity.getDeviceMac()); entity.setDeviceCode(entity.getDeviceMac());
} }
super.saveBefore(entity, context); super.saveBefore(entity, context);
} }
@Override
public void action(Long id, Integer type, Context context) {
DeviceEntity deviceEntity = this.get(id, context);
if (!ObjectUtils.isEmpty(deviceEntity)) {
cacheService.set(KEY_DEVICE_TYPE_CACHE + deviceEntity.getDeviceCode(), type);
}
}
} }
\ No newline at end of file
package com.mortals.xhx.module.device.web;
import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.xhx.base.system.param.service.ParamService;
import com.mortals.xhx.common.code.AlarmLevelEnum;
import com.mortals.xhx.common.code.AlarmTypeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import com.mortals.framework.model.Context;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.xhx.module.device.model.DeviceAlarmEntity;
import com.mortals.xhx.module.device.service.DeviceAlarmService;
import org.apache.commons.lang3.ArrayUtils;
import com.mortals.framework.util.StringUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.alibaba.fastjson.JSONObject;
import java.util.Arrays;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import static com.mortals.framework.ap.SysConstains.*;
/**
*
* 设备告警日志
*
* @author zxfei
* @date 2022-08-04
*/
@RestController
@RequestMapping("device/alarm")
public class DeviceAlarmController extends BaseCRUDJsonBodyMappingController<DeviceAlarmService,DeviceAlarmEntity,Long> {
@Autowired
private ParamService paramService;
public DeviceAlarmController(){
super.setModuleDesc( "设备告警日志");
}
@Override
protected void init(Map<String, Object> model, Context context) {
this.addDict(model, "alarmType", AlarmTypeEnum.getEnumMap());
this.addDict(model, "alarmLevel", AlarmLevelEnum.getEnumMap());
super.init(model, context);
}
}
\ No newline at end of file
package com.mortals.xhx.module.device.web; package com.mortals.xhx.module.device.web;
import com.mortals.framework.annotation.UnAuth; import com.mortals.framework.annotation.UnAuth;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException; import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.OrderCol; import com.mortals.framework.model.OrderCol;
import com.mortals.framework.model.Result; import com.mortals.framework.model.Result;
import com.mortals.framework.web.BaseCRUDJsonBodyMappingController; import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.xhx.base.system.param.service.ParamService; import com.mortals.xhx.base.system.param.service.ParamService;
import com.mortals.xhx.common.code.DeviceActionEnum;
import com.mortals.xhx.common.code.DeviceOnlineStatusEnum; import com.mortals.xhx.common.code.DeviceOnlineStatusEnum;
import com.mortals.xhx.common.code.DeviceTypeEnum; import com.mortals.xhx.common.code.DeviceTypeEnum;
import com.mortals.xhx.module.firm.model.FirmQuery; import com.mortals.xhx.module.firm.model.FirmQuery;
...@@ -77,6 +79,27 @@ public class DeviceController extends BaseCRUDJsonMappingController<DeviceServic ...@@ -77,6 +79,27 @@ public class DeviceController extends BaseCRUDJsonMappingController<DeviceServic
return ret.toJSONString(); return ret.toJSONString();
} }
/**
* 设备执行功能
*/
@PostMapping(value = "execmd")
public Rest<Void> deviceExecCmd(@RequestParam(value = "id") Long id,
@RequestParam(value = "type") Integer type) {
String busiDesc = this.getModuleDesc() + "设备执行"+ DeviceActionEnum.getByValue(type).getDesc();
Rest<Void> rest = Rest.ok(busiDesc + " 【成功】");
try {
this.service.action(id,type,getContext());
recordSysLog(request, busiDesc + " 【成功】");
} catch (Exception e) {
log.error("设备执行命令异常", e);
rest = Rest.fail(super.convertException(e));
}
return rest;
}
@Override @Override
protected void doListBefore(HttpServletRequest request, HttpServletResponse response, DeviceForm form, Map<String, Object> model, Context context) throws AppException { protected void doListBefore(HttpServletRequest request, HttpServletResponse response, DeviceForm form, Map<String, Object> model, Context context) throws AppException {
form.getQuery().setOrderColList(new ArrayList<OrderCol>() { form.getQuery().setOrderColList(new ArrayList<OrderCol>() {
......
...@@ -16,6 +16,30 @@ Content-Type: application/json ...@@ -16,6 +16,30 @@ Content-Type: application/json
} }
###设备更新与保存
POST {{baseUrl}}/device/save
Content-Type: application/json
{
"id":60,
"deviceCode":"ksdmo7",
"deviceType":1,
"deviceMac":"a3ku15",
"ip":"5ffz2e",
"centernum":"pcou8p",
"port":"0ujj4h",
"siteNum":"8aw47p",
"deviceFirmId":922,
"deviceFirmname":"cwzu1n",
"deviceOnlineStatus":0,
"status":0,
"deviceRemark":"plxklr",
"onlineTime":"1646755200000",
"offlineTime":"1646755200000"
}
###设备更新与保存 ###设备更新与保存
POST {{baseUrl}}/device/save POST {{baseUrl}}/device/save
Content-Type: application/json Content-Type: application/json
...@@ -62,7 +86,7 @@ POST {{baseUrl}}/api/device/upload ...@@ -62,7 +86,7 @@ POST {{baseUrl}}/api/device/upload
Content-Type: application/json Content-Type: application/json
{ {
"devicenum":"AB:DD:DF:FD:AD:FA:DA:SS", "devicenum":"94-DE-80-D5-3D-63",
"action":"upload" "action":"upload"
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment