Commit 5761b10c authored by 赵啸非's avatar 赵啸非

修改设备管理

parent 0f289e4a
......@@ -16,6 +16,7 @@ CREATE TABLE mortals_stp_device(
`deviceFirmname` varchar(20) COMMENT '设备生产厂商名称',
`deviceOnlineStatus` tinyint(2) NOT NULL COMMENT '在线状态 (0.离线,1.在线)',
`status` tinyint(2) NOT NULL COMMENT '启用状态 (0.停止,1.启用)',
`deviceSource` tinyint(2) NOT NULL COMMENT '设备来源,为其它时候上线下线通过查询(0.大厅,1.其它)',
`deviceRemark` varchar(256) COMMENT '备注',
`onlineTime` datetime COMMENT '最近上线时间',
`offlineTime` datetime COMMENT '最近离线时间',
......@@ -25,6 +26,7 @@ CREATE TABLE mortals_stp_device(
`updateTime` datetime COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='设备';
-- ----------------------------
-- 设备生产厂商表
-- ----------------------------
......
......@@ -31,9 +31,7 @@ const router = new Router({
builder('site/list', 'system/site/index'),//站点
...restBuilder('device', 'device'),//
...restBuilder('device/log', 'device/log'),//
...restBuilder('firm', 'firm'),//
//以下为基础路由配置
......
......@@ -3,15 +3,37 @@
<el-dialog :title="title" :visible.sync="open" width="80%" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-row>
<Field :span="20" label="设备名称" prop="deviceName" v-model="form.deviceName" placeholder="请输入设备名称"/>
<Field :span="20" label="设备编码" prop="deviceCode" v-model="form.deviceCode" type="textarea" placeholder="请输入设备编码"/>
<Field :span="20" label="设备类型" prop="deviceType" v-model="form.deviceType" type="select" :enumData="dict.deviceType" placeholder="请选择设备类型"/>
<Field :span="20" label="设备的MAC地址" prop="deviceMac" v-model="form.deviceMac" placeholder="请输入设备的MAC地址"/>
<Field :span="20" label="中心设备编码" v-model="form.centernum" placeholder="请输入中心设备编码"/>
<Field
:span="20"
label="设备名称"
prop="deviceName"
v-model="form.deviceName"
placeholder="请输入设备名称"
/>
<Field
:span="20"
label="设备编码"
prop="deviceCode"
v-model="form.deviceCode"
placeholder="请输入设备编码"
/>
<Field
:span="20"
label="设备的MAC地址"
prop="deviceMac"
v-model="form.deviceMac"
placeholder="请输入设备的MAC地址"
/>
<Field
:span="20"
label="设备类型"
prop="deviceType"
v-model="form.deviceType"
type="select"
:enumData="dict.deviceType"
placeholder="请选择设备类型"
/>
<Field :span="20" disabled label="设备访问ip" v-model="form.ip" />
<Field :span="20" disabled label="端口" v-model="form.port" />
<Field :span="20" disabled label="站点编号" v-model="form.siteNum" />
<Field
:span="20"
label="设备生产商:"
......@@ -21,29 +43,55 @@
type="select"
:enumData="dict.deviceFirmId"
/>
<Field :span="20" label="备注" prop="deviceRemark" v-model="form.deviceRemark" type="textarea" placeholder="请输入备注"/>
<Field :span="20" label="启用状态 " prop="status" v-model="form.status" type="radio" :enumData="dict.status" placeholder="请选择启用状态 "/>
<Field
:span="20"
label="备注"
prop="deviceRemark"
v-model="form.deviceRemark"
type="textarea"
placeholder="请输入备注"
/>
<Field
:span="20"
label="启用状态 "
prop="status"
v-model="form.status"
type="radio"
:enumData="dict.status"
placeholder="请选择启用状态 "
/>
<Field
:span="20"
label="设备来源 "
prop="deviceSource"
v-model="form.deviceSource"
type="radio"
:enumData="dict.deviceSource"
placeholder="请选择设备来源"
/>
</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
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 {
import form from "@/assets/mixins/formdialog";
import dialogShow from "./dialogshow";
export default {
mixins: [form],
components: {
dialogShow ,
dialogShow,
},
data() {
return {
......@@ -53,60 +101,52 @@
title: "设备",
// 是否显示弹出层
open: false,
toString:[
"deviceType",
"deviceOnlineStatus",
"status",
"deviceFirmId"
],
toString: ["deviceType", "deviceOnlineStatus", "status", "deviceFirmId"],
// 表单校验
rules: {
deviceName: [
{required: true,message: "请输入设备名称", trigger: "blur" },
{max: 20,message: "最多只能录入20个字符",trigger: "blur",},
{ required: true, message: "请输入设备名称", trigger: "blur" },
{ max: 20, message: "最多只能录入20个字符", trigger: "blur" },
],
deviceType: [
{required: true,message: "请输入设备类型", trigger: "blur" },
{ required: true, message: "请输入设备类型", trigger: "blur" },
],
deviceOnlineStatus: [
{required: true,message: "请输入在线状态 ", trigger: "blur" },
{ required: true, message: "请输入在线状态 ", trigger: "blur" },
],
status: [
{required: true,message: "请输入启用状态 ", trigger: "blur" },
],
createTime: [
{required: true,message: "请选择创建时间" },
{ required: true, message: "请输入启用状态 ", trigger: "blur" },
],
}
},
};
},
methods: {
/** 编辑 */
edit(row) {
this.reset()
this.reset();
this.query = { id: row.id };
this.urls.currUrl =this.pageInfo.editUrl;;
this.urls.currUrl = this.pageInfo.editUrl;
this.getData();
this.pageInfo.type="edit"
this.pageInfo.type = "edit";
this.title = "修改设备";
},
/** 新增 */
add(row) {
this.reset()
this.reset();
this.query = { id: row.id };
this.urls.currUrl = this.pageInfo.addUrl;
this.getData();
this.pageInfo.type="add"
this.pageInfo.type = "add";
this.title = "新增设备";
},
/** 查看*/
view(row) {
this.reset()
this.reset();
this.query = { id: row.id };
this.urls.currUrl =this.pageInfo.viewUrl;;
this.urls.currUrl = this.pageInfo.viewUrl;
this.getData();
this.pageInfo.type="view"
this.pageInfo.type = "view";
this.title = "设备详细";
},
/**取消按钮 */
......@@ -126,21 +166,21 @@
// 表单重置
reset() {
this.form = {
deviceName : "",
deviceCode : "",
deviceType : 1,
deviceMac : "",
ip : "",
centernum : "",
port : "",
siteNum : "",
deviceFirmId : null,
deviceFirmname : "",
deviceOnlineStatus : 0,
status : 0,
deviceRemark : "",
onlineTime : null,
offlineTime : null,
deviceName: "",
deviceCode: "",
deviceType: 1,
deviceMac: "",
ip: "",
centernum: "",
port: "",
siteNum: "",
deviceFirmId: null,
deviceFirmname: "",
deviceOnlineStatus: 0,
status: 0,
deviceRemark: "",
onlineTime: null,
offlineTime: null,
};
this.resetForm("form");
},
......@@ -150,5 +190,5 @@
}
},
},
};
};
</script>
......@@ -34,12 +34,12 @@ export default {
},
loginFail(error) {
this.$message.error(error.message || '请登录');
this.$router.replace({
path: '/login',
query: {
redirect: this.redirect,
}
});
// this.$router.replace({
// path: '/login',
// query: {
// redirect: this.redirect,
// }
// });
},
getUrlKey (name) {
......
......@@ -10,19 +10,38 @@ import java.io.Serializable;
@Data
public class DeviceReq implements Serializable {
/**
* 行为
*/
private String action;
/**
* 设备编码 唯一
*/
private String devicenum;
/**
* ip地址
*/
private String ip;
/**
* 站点编码
*/
private String sitenum;
/**
* 上传类型
*/
private Integer type;
/**
* 端口
*/
private String port;
/**
* 中心编码
*/
private String centernum;
......
package com.mortals.xhx.busiz.rsp;
import lombok.Data;
import java.io.Serializable;
@Data
public class DeviceResp implements Serializable {
/**
* 在线状态(0在线 1离线)
*/
private String isOnLine;
}
......@@ -9,11 +9,14 @@ import com.mortals.xhx.busiz.req.DeviceReq;
import com.mortals.xhx.busiz.rsp.ApiResp;
import com.mortals.xhx.common.code.ApiRespCodeEnum;
import com.mortals.xhx.common.code.DeviceOnlineStatusEnum;
import com.mortals.xhx.common.utils.SendTaskThreadPool;
import com.mortals.xhx.common.utils.UploadTask;
import com.mortals.xhx.module.device.model.DeviceEntity;
import com.mortals.xhx.module.device.model.DeviceLogEntity;
import com.mortals.xhx.module.device.service.DeviceLogService;
import com.mortals.xhx.module.device.service.DeviceService;
import lombok.extern.apachecommons.CommonsLog;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.PostMapping;
......@@ -29,15 +32,15 @@ import java.util.Date;
* @date: 2021/8/24 20:28
*/
@RestController
@CommonsLog
@Slf4j
@RequestMapping("/api/device")
public class DeviceApiController {
@Autowired
private DeviceLogService deviceLogService;
@Autowired
private DeviceService deviceService;
@Autowired
private SendTaskThreadPool sendTaskThreadPool;
/**
* 设备数据上报
......@@ -47,73 +50,13 @@ public class DeviceApiController {
*/
@PostMapping("upload")
public String upload(DeviceReq req) {
log.info("【设备数据上报】【请求体】--> " + JSONObject.toJSONString(req));
log.debug("【设备数据上报】【请求体】--> " + JSONObject.toJSONString(req));
ApiResp rsp = new ApiResp<>();
rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
try {
//根据设备编码查询设备
DeviceEntity deviceEntity = deviceService.getExtCache(req.getDevicenum());
boolean bool = false;
if (!ObjectUtils.isEmpty(deviceEntity)) {
if (deviceEntity.getDeviceOnlineStatus() == DeviceOnlineStatusEnum.离线.getValue()) {
bool = true;
}
deviceEntity.setOnlineTime(new Date());
deviceEntity.setDeviceOnlineStatus(DeviceOnlineStatusEnum.在线.getValue());
deviceEntity.setIp(req.getIp());
deviceEntity.setPort(req.getPort());
deviceEntity.setSiteNum(req.getSitenum());
deviceEntity.setCenternum(req.getCenternum());
deviceService.update(deviceEntity);
DeviceLogEntity deviceLogEntity = new DeviceLogEntity();
deviceLogEntity.initAttrValue();
deviceLogEntity.setDeviceId(deviceEntity.getId());
deviceLogEntity.setDeviceName(deviceEntity.getDeviceName());
deviceLogEntity.setDeviceNum(deviceEntity.getDeviceCode());
deviceLogEntity.setContent(JSONObject.toJSONString(req));
deviceLogEntity.setCreateTime(new Date());
deviceLogService.save(deviceLogEntity);
if (bool) {
WebSocketUtil.broadcast(SendToAllRequest.TYPE, new SendToAllRequest().setContent(JSON.toJSONString(deviceEntity)));
}
} else {
//新增设备
deviceEntity = new DeviceEntity();
deviceEntity.initAttrValue();
deviceEntity.setDeviceCode(req.getDevicenum());
deviceEntity.setOnlineTime(new Date());
deviceEntity.setDeviceOnlineStatus(DeviceOnlineStatusEnum.在线.getValue());
deviceEntity.setIp(req.getIp());
deviceEntity.setPort(req.getPort());
deviceEntity.setSiteNum(req.getSitenum());
deviceEntity.setCenternum(req.getCenternum());
deviceEntity.setCreateUserId(1L);
deviceEntity.setCreateTime(new Date());
deviceService.save(deviceEntity);
DeviceLogEntity deviceLogEntity = new DeviceLogEntity();
deviceLogEntity.initAttrValue();
deviceLogEntity.setDeviceId(deviceEntity.getId());
deviceLogEntity.setDeviceName(deviceEntity.getDeviceName());
deviceLogEntity.setDeviceNum(deviceEntity.getDeviceCode());
deviceLogEntity.setContent(JSONObject.toJSONString(req));
deviceLogEntity.setCreateTime(new Date());
deviceLogService.save(deviceLogEntity);
WebSocketUtil.broadcast(SendToAllRequest.TYPE, new SendToAllRequest().setContent(JSON.toJSONString(deviceEntity)));
}
} catch (Exception e) {
log.error("接收数据失败", e);
rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
rsp.setMsg(e.getMessage());
return JSON.toJSONString(rsp);
}
log.info("响应【设备数据上报】【响应体】--> " + JSONObject.toJSONString(rsp));
UploadTask uploadTask = new UploadTask(req, deviceLogService, deviceService);
sendTaskThreadPool.execute(uploadTask);
log.debug("响应【设备数据上报】【响应体】--> " + JSONObject.toJSONString(rsp));
return JSON.toJSONString(rsp);
}
......
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 设备来源,为其它时候上线下线通过查询(0.大厅,1.其它)枚举类
*
* @author zxfei
*/
public enum DeviceSourceEnum {
大厅(0, "大厅"),
其它(1, "其它");
private Integer value;
private String desc;
DeviceSourceEnum(Integer value, String desc) {
this.value = value;
this.desc = desc;
}
public Integer getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public static DeviceSourceEnum getByValue(Integer value) {
for (DeviceSourceEnum deviceSourceEnum : DeviceSourceEnum.values()) {
if (deviceSourceEnum.getValue() == value) {
return deviceSourceEnum;
}
}
return null;
}
/**
* 获取Map集合
*
* @param eItem 不包含项
* @return
*/
public static Map<String, String> getEnumMap(Integer... eItem) {
Map<String, String> resultMap = new LinkedHashMap<>();
for (DeviceSourceEnum item : DeviceSourceEnum.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
......@@ -28,4 +28,10 @@ public class ParamKey {
*/
public static String SYS_PARAM_USER_URL = "user_url";
/**
* 设备状态查询url
*/
public static String SYS_PARAM_SEND_QUERY_URL = "send_query_url";
}
package com.mortals.xhx.common.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.mortals.framework.util.HttpUtil;
import com.mortals.xhx.busiz.rsp.ApiResp;
import com.mortals.xhx.busiz.rsp.DeviceResp;
import com.mortals.xhx.common.code.DeviceOnlineStatusEnum;
import com.mortals.xhx.daemon.task.CustomerInfo;
import com.mortals.xhx.module.device.model.DeviceEntity;
import com.mortals.xhx.module.device.service.DeviceService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.mortals.framework.util.HttpUtil.HEADER_CONTENT_TYPE;
/**
* 发送任务
*
* @author: zxfei
* @date: 2022/4/28 10:56
* @description:
**/
@Slf4j
@AllArgsConstructor
public class SendTask implements Runnable {
private String sendUrl;
private Long deviceId;
private String content;
private DeviceService deviceService;
@Override
public void run() {
try {
Map<String, String> headers = new HashMap<>();
DeviceEntity deviceEntity = new DeviceEntity();
deviceEntity.setId(deviceId);
headers.put(HEADER_CONTENT_TYPE, "application/json");
String resp = HttpUtil.doPost(sendUrl, headers, content);
ApiResp<DeviceResp> apiResp = JSON.parseObject(resp, new TypeReference<ApiResp<DeviceResp>>(){});
if (apiResp.getCode() == 0) {
if (apiResp.getData().getIsOnLine() == "0") {
deviceEntity.setDeviceOnlineStatus(DeviceOnlineStatusEnum.在线.getValue());
deviceEntity.setOnlineTime(new Date());
} else if (apiResp.getData().getIsOnLine() == "1") {
deviceEntity.setDeviceOnlineStatus(DeviceOnlineStatusEnum.离线.getValue());
deviceEntity.setOfflineTime(new Date());
} else {
deviceEntity.setDeviceOnlineStatus(DeviceOnlineStatusEnum.在线.getValue());
deviceEntity.setOnlineTime(new Date());
}
deviceService.update(deviceEntity);
}
log.debug("http resp:{}", resp);
} catch (Exception e) {
log.error("发送异常:" + e);
}
}
}
package com.mortals.xhx.common.utils;
import org.springframework.stereotype.Component;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 发送任务线程池
*
* @author: zxfei
* @date: 2022/4/28 10:52
*/
@Component
public class SendTaskThreadPool {
/**
* 线程池
*/
private ThreadPoolExecutor threadPool;
private int poolSize;
private volatile boolean isInit = false;
private Object lock = new Object();
public void init(Integer threadNum) {
if (poolSize < 0) {
throw new IllegalArgumentException();
}
if (poolSize < Runtime.getRuntime().availableProcessors()) {
poolSize = Runtime.getRuntime().availableProcessors() + 1;
}
if (!isInit) {
synchronized (lock) {
if (!isInit) {
threadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(threadNum);
isInit = true;
}
}
}
}
public void execute(Runnable command) {
threadPool.execute(command);
}
public void setPoolSize(int poolSize) {
threadPool.setCorePoolSize(poolSize);
threadPool.setMaximumPoolSize(poolSize);
}
public void incrementPoolSize(int delta) {
setPoolSize(threadPool.getCorePoolSize() + delta);
}
public synchronized void close() {
if (threadPool != null) {
threadPool.shutdown();
threadPool = null;
isInit = false;
}
}
}
package com.mortals.xhx.common.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.mortals.framework.util.HttpUtil;
import com.mortals.xhx.base.framework.ws.message.SendToAllRequest;
import com.mortals.xhx.base.framework.ws.util.WebSocketUtil;
import com.mortals.xhx.busiz.req.DeviceReq;
import com.mortals.xhx.busiz.rsp.ApiResp;
import com.mortals.xhx.busiz.rsp.DeviceResp;
import com.mortals.xhx.common.code.DeviceOnlineStatusEnum;
import com.mortals.xhx.module.device.model.DeviceEntity;
import com.mortals.xhx.module.device.model.DeviceLogEntity;
import com.mortals.xhx.module.device.service.DeviceLogService;
import com.mortals.xhx.module.device.service.DeviceService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import static com.mortals.framework.util.HttpUtil.HEADER_CONTENT_TYPE;
/**
* 上报任务
*
* @author: zxfei
* @date: 2022/4/28 10:56
* @description:
**/
@Slf4j
@AllArgsConstructor
public class UploadTask implements Runnable {
private DeviceReq req;
private DeviceLogService deviceLogService;
private DeviceService deviceService;
@Override
public void run() {
try {
DeviceEntity deviceEntity = deviceService.getExtCache(req.getDevicenum());
boolean bool = false;
if (!ObjectUtils.isEmpty(deviceEntity)) {
if (deviceEntity.getDeviceOnlineStatus() == DeviceOnlineStatusEnum.离线.getValue()) {
bool = true;
}
deviceEntity.setOnlineTime(new Date());
deviceEntity.setDeviceOnlineStatus(DeviceOnlineStatusEnum.在线.getValue());
deviceEntity.setIp(req.getIp());
deviceEntity.setPort(req.getPort());
deviceEntity.setSiteNum(req.getSitenum());
deviceEntity.setCenternum(req.getCenternum());
deviceService.update(deviceEntity);
DeviceLogEntity deviceLogEntity = new DeviceLogEntity();
deviceLogEntity.initAttrValue();
deviceLogEntity.setDeviceId(deviceEntity.getId());
deviceLogEntity.setDeviceName(deviceEntity.getDeviceName());
deviceLogEntity.setDeviceNum(deviceEntity.getDeviceCode());
deviceLogEntity.setContent(JSONObject.toJSONString(req));
deviceLogEntity.setCreateTime(new Date());
deviceLogService.save(deviceLogEntity);
if (bool) {
WebSocketUtil.broadcast(SendToAllRequest.TYPE, new SendToAllRequest().setContent(JSON.toJSONString(deviceEntity)));
}
} else {
//新增设备
deviceEntity = new DeviceEntity();
deviceEntity.initAttrValue();
deviceEntity.setDeviceCode(req.getDevicenum());
deviceEntity.setOnlineTime(new Date());
deviceEntity.setDeviceOnlineStatus(DeviceOnlineStatusEnum.在线.getValue());
deviceEntity.setIp(req.getIp());
deviceEntity.setPort(req.getPort());
deviceEntity.setSiteNum(req.getSitenum());
deviceEntity.setCenternum(req.getCenternum());
deviceEntity.setCreateUserId(1L);
deviceEntity.setCreateTime(new Date());
deviceService.save(deviceEntity);
DeviceLogEntity deviceLogEntity = new DeviceLogEntity();
deviceLogEntity.initAttrValue();
deviceLogEntity.setDeviceId(deviceEntity.getId());
deviceLogEntity.setDeviceName(deviceEntity.getDeviceName());
deviceLogEntity.setDeviceNum(deviceEntity.getDeviceCode());
deviceLogEntity.setContent(JSONObject.toJSONString(req));
deviceLogEntity.setCreateTime(new Date());
deviceLogService.save(deviceLogEntity);
WebSocketUtil.broadcast(SendToAllRequest.TYPE, new SendToAllRequest().setContent(JSON.toJSONString(deviceEntity)));
}
} catch (Exception e) {
log.error("异常:" ,e);
}
}
}
package com.mortals.xhx.daemon.applicationservice;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.mortals.framework.springcloud.service.IApplicationService;
import com.mortals.xhx.common.utils.SendTaskThreadPool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.mortals.framework.springcloud.service.IApplicationService;
/**
* 应用级服务,在应用启动、停止过程中调用
*
* 缺陷:类加载完成后就调用,会由于某些组件还未初始化而导致服务异常,
* 比如Kafka的连接以及订阅初始化比较靠后,在服务启动过程中就调用操作kafka相关API,将导致失败
* 比如开启Socket监听端口,可能端口都接收到连接请求了,但数据库连接还未初始化完成,导致请求处理失败
* 比如定时任务,任务执行时,相关缓存还未初始化,导致处理失败
*
* 应用场景:
* 1、无依赖其它模块或框架的数据初始化等操作
* @author GM
* @date 2020年7月15日
*/
@Component
@Slf4j
public class DemoStartService implements IApplicationService {
private static Log logger = LogFactory.getLog(DemoStartService.class);
@Autowired
private SendTaskThreadPool sendTaskThreadPool;
@Override
public void start() {
logger.info("开始服务..[配置已加载完成,但部分框架还未初始化,比如:Kafka]");
int coreThreadNum = Runtime.getRuntime().availableProcessors();
sendTaskThreadPool.init(coreThreadNum*2);
log.info("开始服务..[配置已加载完成,但部分框架还未初始化,比如:Kafka]");
}
@Override
public void stop() {
logger.info("停止服务..");
log.info("停止服务..");
}
}
package com.mortals.xhx.daemon.task;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.ap.GlobalSysInfo;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.service.ITask;
......@@ -10,7 +11,10 @@ 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.util.WebSocketUtil;
import com.mortals.xhx.common.code.DeviceOnlineStatusEnum;
import com.mortals.xhx.common.code.DeviceSourceEnum;
import com.mortals.xhx.common.key.ParamKey;
import com.mortals.xhx.common.utils.SendTask;
import com.mortals.xhx.common.utils.SendTaskThreadPool;
import com.mortals.xhx.module.device.model.DeviceLogEntity;
import com.mortals.xhx.module.device.model.DeviceLogQuery;
import com.mortals.xhx.module.device.service.DeviceLogService;
......@@ -38,12 +42,15 @@ public class DeviceStatTaskImpl implements ITaskExcuteService {
@Autowired
private DeviceLogService deviceLogService;
@Autowired
private SendTaskThreadPool sendTaskThreadPool;
@Override
public void excuteTask(ITask task) throws AppException {
log.debug("设备状态统计,开始执行");
doDeviceUpOrDown();
doDeviceLogDel();
doDeviceQuery();
log.debug("设备状态统计,结束执行");
}
......@@ -56,6 +63,7 @@ public class DeviceStatTaskImpl implements ITaskExcuteService {
try {
//获取所有设备,针对每个设备查询最近指定秒的日志,如果没有则更新下线
deviceService.getCacheList().stream()
.filter(f -> f.getDeviceSource() == DeviceSourceEnum.大厅.getValue())
.filter(f -> f.getDeviceOnlineStatus() == DeviceOnlineStatusEnum.在线.getValue())
.peek(device -> {
DeviceLogQuery query = new DeviceLogQuery();
......@@ -68,14 +76,14 @@ public class DeviceStatTaskImpl implements ITaskExcuteService {
device.setDeviceOnlineStatus(DeviceOnlineStatusEnum.离线.getValue());
deviceService.update(device);
WebSocketUtil.broadcast(SendToAllRequest.TYPE,new SendToAllRequest().setContent(JSON.toJSONString(device)));
WebSocketUtil.broadcast(SendToAllRequest.TYPE, new SendToAllRequest().setContent(JSON.toJSONString(device)));
}
}).count();
} catch (Exception e) {
log.error("更新设备状态任务异常,结束执行", e);
}
log.info("更新设备状态任务,结束执行");
log.debug("更新设备状态任务,结束执行");
}
......@@ -95,7 +103,29 @@ public class DeviceStatTaskImpl implements ITaskExcuteService {
} catch (Exception e) {
log.error("设备日志删除任务异常,结束执行", e);
}
log.info("设备日志删除任务,结束执行");
log.debug("设备日志删除任务,结束执行");
}
/**
* 定时查询更新其它设备状态
*/
private void doDeviceQuery() {
try {
deviceService.getCacheList().parallelStream()
.filter(f -> f.getDeviceSource() == DeviceSourceEnum.其它.getValue())
.peek(device -> {
String sendUrl = GlobalSysInfo.getParamValue(ParamKey.SYS_PARAM_SEND_QUERY_URL,"http://127.0.0.1:18211/m/test/equipStateQuery");
JSONObject jsonObject = new JSONObject();
jsonObject.put("macAddress",device.getDeviceMac());
SendTask sendTask = new SendTask(sendUrl, device.getId(), jsonObject.toJSONString(), deviceService);
sendTaskThreadPool.execute(sendTask);
}).count();
} catch (Exception e) {
log.error("查询设备状态任务异常,结束执行", e);
}
log.debug("查询设备状态任务,结束执行");
}
......
......@@ -8,11 +8,11 @@ import com.mortals.framework.annotation.Excel;
import com.mortals.framework.model.BaseEntityLong;
import com.mortals.xhx.module.device.model.vo.DeviceVo;
/**
* 设备实体对象
*
* @author zxfei
* @date 2022-03-09
*/
* 设备实体对象
*
* @author zxfei
* @date 2022-05-06
*/
public class DeviceEntity extends DeviceVo {
private static final long serialVersionUID = 1L;
......@@ -67,6 +67,10 @@ public class DeviceEntity extends DeviceVo {
* 启用状态 (0.停止,1.启用)
*/
private Integer status;
/**
* 设备来源,为其它时候上线下线通过查询(0.大厅,1.其它)
*/
private Integer deviceSource;
/**
* 备注
*/
......@@ -251,6 +255,20 @@ public class DeviceEntity extends DeviceVo {
public void setStatus(Integer status){
this.status = status;
}
/**
* 获取 设备来源,为其它时候上线下线通过查询(0.大厅,1.其它)
* @return Integer
*/
public Integer getDeviceSource(){
return deviceSource;
}
/**
* 设置 设备来源,为其它时候上线下线通过查询(0.大厅,1.其它)
* @param deviceSource
*/
public void setDeviceSource(Integer deviceSource){
this.deviceSource = deviceSource;
}
/**
* 获取 备注
* @return String
......@@ -327,6 +345,7 @@ public class DeviceEntity extends DeviceVo {
sb.append(",deviceFirmname:").append(getDeviceFirmname());
sb.append(",deviceOnlineStatus:").append(getDeviceOnlineStatus());
sb.append(",status:").append(getStatus());
sb.append(",deviceSource:").append(getDeviceSource());
sb.append(",deviceRemark:").append(getDeviceRemark());
sb.append(",onlineTime:").append(getOnlineTime());
sb.append(",offlineTime:").append(getOfflineTime());
......@@ -359,6 +378,8 @@ public class DeviceEntity extends DeviceVo {
this.status = 0;
this.deviceSource = 0;
this.deviceRemark = "";
this.onlineTime = null;
......
......@@ -4,11 +4,11 @@ import java.util.Date;
import java.util.List;
import com.mortals.xhx.module.device.model.DeviceEntity;
/**
* 设备查询对象
*
* @author zxfei
* @date 2022-03-09
*/
* 设备查询对象
*
* @author zxfei
* @date 2022-05-06
*/
public class DeviceQuery extends DeviceEntity {
/** 开始 主键ID,主键,自增长 */
private Long idStart;
......@@ -94,6 +94,18 @@ public class DeviceQuery extends DeviceEntity {
/** 启用状态 (0.停止,1.启用)列表 */
private List <Integer> statusList;
/** 开始 设备来源,为其它时候上线下线通过查询(0.大厅,1.其它) */
private Integer deviceSourceStart;
/** 结束 设备来源,为其它时候上线下线通过查询(0.大厅,1.其它) */
private Integer deviceSourceEnd;
/** 增加 设备来源,为其它时候上线下线通过查询(0.大厅,1.其它) */
private Integer deviceSourceIncrement;
/** 设备来源,为其它时候上线下线通过查询(0.大厅,1.其它)列表 */
private List <Integer> deviceSourceList;
/** 备注 */
private List<String> deviceRemarkList;
......@@ -593,6 +605,70 @@ public class DeviceQuery extends DeviceEntity {
this.statusList = statusList;
}
/**
* 获取 开始 设备来源,为其它时候上线下线通过查询(0.大厅,1.其它)
* @return deviceSourceStart
*/
public Integer getDeviceSourceStart(){
return this.deviceSourceStart;
}
/**
* 设置 开始 设备来源,为其它时候上线下线通过查询(0.大厅,1.其它)
* @param deviceSourceStart
*/
public void setDeviceSourceStart(Integer deviceSourceStart){
this.deviceSourceStart = deviceSourceStart;
}
/**
* 获取 结束 设备来源,为其它时候上线下线通过查询(0.大厅,1.其它)
* @return $deviceSourceEnd
*/
public Integer getDeviceSourceEnd(){
return this.deviceSourceEnd;
}
/**
* 设置 结束 设备来源,为其它时候上线下线通过查询(0.大厅,1.其它)
* @param deviceSourceEnd
*/
public void setDeviceSourceEnd(Integer deviceSourceEnd){
this.deviceSourceEnd = deviceSourceEnd;
}
/**
* 获取 增加 设备来源,为其它时候上线下线通过查询(0.大厅,1.其它)
* @return deviceSourceIncrement
*/
public Integer getDeviceSourceIncrement(){
return this.deviceSourceIncrement;
}
/**
* 设置 增加 设备来源,为其它时候上线下线通过查询(0.大厅,1.其它)
* @param deviceSourceIncrement
*/
public void setDeviceSourceIncrement(Integer deviceSourceIncrement){
this.deviceSourceIncrement = deviceSourceIncrement;
}
/**
* 获取 设备来源,为其它时候上线下线通过查询(0.大厅,1.其它)
* @return deviceSourceList
*/
public List<Integer> getDeviceSourceList(){
return this.deviceSourceList;
}
/**
* 设置 设备来源,为其它时候上线下线通过查询(0.大厅,1.其它)
* @param deviceSourceList
*/
public void setDeviceSourceList(List<Integer> deviceSourceList){
this.deviceSourceList = deviceSourceList;
}
/**
* 获取 备注
* @return deviceRemarkList
......@@ -1241,6 +1317,51 @@ public class DeviceQuery extends DeviceEntity {
return this;
}
/**
* 设置 设备来源,为其它时候上线下线通过查询(0.大厅,1.其它)
* @param deviceSource
*/
public DeviceQuery deviceSource(Integer deviceSource){
setDeviceSource(deviceSource);
return this;
}
/**
* 设置 开始 设备来源,为其它时候上线下线通过查询(0.大厅,1.其它)
* @param deviceSourceStart
*/
public DeviceQuery deviceSourceStart(Integer deviceSourceStart){
this.deviceSourceStart = deviceSourceStart;
return this;
}
/**
* 设置 结束 设备来源,为其它时候上线下线通过查询(0.大厅,1.其它)
* @param deviceSourceEnd
*/
public DeviceQuery deviceSourceEnd(Integer deviceSourceEnd){
this.deviceSourceEnd = deviceSourceEnd;
return this;
}
/**
* 设置 增加 设备来源,为其它时候上线下线通过查询(0.大厅,1.其它)
* @param deviceSourceIncrement
*/
public DeviceQuery deviceSourceIncrement(Integer deviceSourceIncrement){
this.deviceSourceIncrement = deviceSourceIncrement;
return this;
}
/**
* 设置 设备来源,为其它时候上线下线通过查询(0.大厅,1.其它)
* @param deviceSourceList
*/
public DeviceQuery deviceSourceList(List<Integer> deviceSourceList){
this.deviceSourceList = deviceSourceList;
return this;
}
/**
* 设置 备注
......
package com.mortals.xhx.module.device.service.impl;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import org.springframework.stereotype.Service;
import com.mortals.framework.service.impl.AbstractCRUDCacheServiceImpl;
import com.mortals.xhx.module.device.dao.DeviceDao;
import com.mortals.xhx.module.device.model.DeviceEntity;
import com.mortals.xhx.module.device.service.DeviceService;
import org.springframework.util.ObjectUtils;
/**
* DeviceService
* 设备 service实现
......@@ -19,4 +23,13 @@ public class DeviceServiceImpl extends AbstractCRUDCacheServiceImpl<DeviceDao, D
protected String getExtKey(DeviceEntity data) {
return data.getDeviceCode();
}
@Override
protected void saveBefore(DeviceEntity entity, Context context) throws AppException {
if(ObjectUtils.isEmpty(entity.getDeviceCode())){
entity.setDeviceCode(entity.getDeviceMac());
}
super.saveBefore(entity, context);
}
}
\ No newline at end of file
......@@ -69,9 +69,8 @@ public class DeviceController extends BaseCRUDJsonMappingController<DeviceServic
this.addDict(model, "deviceOnlineStatus", paramService.getParamBySecondOrganize("Device", "deviceOnlineStatus"));
this.addDict(model, "status", paramService.getParamBySecondOrganize("Device", "status"));
this.addDict(model, "deviceFirmId", firmService.find(new FirmQuery()).stream().collect(Collectors.toMap(x -> x.getId().toString(), y -> y.getFirmName())));
this.addDict(model, "deviceSource", paramService.getParamBySecondOrganize("Device","deviceSource"));
Map<Boolean, Long> collect = this.service.find(new DeviceQuery()).stream().collect(Collectors.partitioningBy(item -> (item.getDeviceOnlineStatus() == DeviceOnlineStatusEnum.在线.getValue()), Collectors.counting()));
model.put("onlineCount", collect.get(true));
model.put("offlineCount", collect.get(false));
super.init(request, response, form, model, context);
......
......@@ -28,7 +28,7 @@ Content-Type: application/json
"status":0,
"deviceRemark":"plxklr",
"onlineTime":"1646755200000",
"offlineTime":"1646755200000",
"offlineTime":"1646755200000"
}
> {%
......@@ -50,4 +50,12 @@ Accept: application/json
###设备上报
POST {{baseUrl}}/api/device/upload
Content-Type: application/json
{
"devicenum":"AB:DD:DF:FD:AD:FA:DA:SS",
"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