diff --git a/src/main/java/com/zhgd/xmgl/config/SafetyHatWSClient.java b/src/main/java/com/zhgd/xmgl/config/SafetyHatWSClient.java index d7801bcce..469db61cc 100644 --- a/src/main/java/com/zhgd/xmgl/config/SafetyHatWSClient.java +++ b/src/main/java/com/zhgd/xmgl/config/SafetyHatWSClient.java @@ -45,7 +45,7 @@ public class SafetyHatWSClient { } /** - * 插入智能安全帽实时数据和报警数据 + * 更新安全帽在线离线,插入智能安全帽报警数据 * * @param message */ @@ -65,8 +65,8 @@ public class SafetyHatWSClient { this.send("{\"act\":\"ma_get_active_devices\"}"); } } else if (Objects.equals(cmd, "ma_get_active_devices")) { - log.info("SafetyHatWSClient获取实时数据"); - //插入实时数据 + log.info("SafetyHatWSClient更新安全帽在线离线"); + //更新安全帽在线离线 Boolean status = jo.getBoolean("status"); if (status != null && status) { JSONArray jaData = jo.getJSONArray("data"); @@ -77,6 +77,7 @@ public class SafetyHatWSClient { JSONObject joUserInfo = joData.getJSONObject("user_info"); if (joUserInfo != null) { String deviceId = joUserInfo.getString("device_id"); + String userId = joUserInfo.getString("user_id"); devsns.add(deviceId); log.info("SafetyHatWSClient获取实时数据的deviceId:{}", deviceId); SafetyHatDev dev = SpringContextUtils.getBean(SafetyHatDevMapper.class).selectOne(new LambdaQueryWrapper() @@ -96,13 +97,18 @@ public class SafetyHatWSClient { data.setUploadTime(new Date(ctime * 1000L)); data.setProjectSn(dev.getProjectSn()); try { - SpringContextUtils.getBean(ISafetyHatDataService.class).add(data); + //不从这里获取实时坐标,因为从这里获取的轨迹没有经过过滤 + //SpringContextUtils.getBean(ISafetyHatDataService.class).add(data); } catch (Exception e) { e.printStackTrace(); } } - dev.setOnline(1); - SpringContextUtils.getBean(ISafetyHatDataService.class).updateStatus(dev); + //设置在线和外部用户id + if (!Objects.equals(dev.getOnline(), 1) || !Objects.equals(dev.getExtUserId(), userId)) { + dev.setOnline(1); + dev.setExtUserId(userId); + SpringContextUtils.getBean(SafetyHatDevMapper.class).updateById(dev); + } } } } diff --git a/src/main/java/com/zhgd/xmgl/modules/safetyhat/entity/SafetyHatDev.java b/src/main/java/com/zhgd/xmgl/modules/safetyhat/entity/SafetyHatDev.java index b6e7d319e..169cb4db6 100644 --- a/src/main/java/com/zhgd/xmgl/modules/safetyhat/entity/SafetyHatDev.java +++ b/src/main/java/com/zhgd/xmgl/modules/safetyhat/entity/SafetyHatDev.java @@ -1,18 +1,17 @@ package com.zhgd.xmgl.modules.safetyhat.entity; -import java.io.Serializable; -import java.util.Date; - import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; import com.fasterxml.jackson.annotation.JsonFormat; -import org.springframework.format.annotation.DateTimeFormat; -import org.jeecgframework.poi.excel.annotation.Excel; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; /** * @Description: 智能安全帽-设备 @@ -77,6 +76,8 @@ public class SafetyHatDev implements Serializable { private java.util.Date heartbeatTime; @ApiModelProperty(value = "在线状态(0.离线 1.在线)") private java.lang.Integer online; + @ApiModelProperty(value = "安全帽外部user_id") + private java.lang.String extUserId; /** * 人员名称 */ diff --git a/src/main/java/com/zhgd/xmgl/modules/safetyhat/service/impl/SafetyHatDataServiceImpl.java b/src/main/java/com/zhgd/xmgl/modules/safetyhat/service/impl/SafetyHatDataServiceImpl.java index 82359edc7..dd47b876f 100644 --- a/src/main/java/com/zhgd/xmgl/modules/safetyhat/service/impl/SafetyHatDataServiceImpl.java +++ b/src/main/java/com/zhgd/xmgl/modules/safetyhat/service/impl/SafetyHatDataServiceImpl.java @@ -94,10 +94,10 @@ public class SafetyHatDataServiceImpl extends ServiceImpl() - .eq(SafetyHatDev::getDevSn, safetyHatData.getDevSn())); + if (!Objects.equals(dev.getOnline(), 1)) { + dev.setOnline(1); + safetyHatDevMapper.updateById(dev); + } if (Objects.equals(safetyHatData.getLongitude(), 0D) && Objects.equals(safetyHatData.getLatitude(), 0D)) { log.info("设备坐标0,0不插入,devSn:{}", safetyHatData.getDevSn()); return; diff --git a/src/main/java/com/zhgd/xmgl/task/SafetyHatTask.java b/src/main/java/com/zhgd/xmgl/task/SafetyHatTask.java index 9462bc024..031ccc166 100644 --- a/src/main/java/com/zhgd/xmgl/task/SafetyHatTask.java +++ b/src/main/java/com/zhgd/xmgl/task/SafetyHatTask.java @@ -1,14 +1,25 @@ package com.zhgd.xmgl.task; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateUtil; import cn.hutool.core.text.CharSequenceUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpRequest; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.zhgd.xmgl.config.SafetyHatWSClient; import com.zhgd.xmgl.modules.project.entity.Project; import com.zhgd.xmgl.modules.project.service.IProjectService; +import com.zhgd.xmgl.modules.safetyhat.entity.SafetyHatData; +import com.zhgd.xmgl.modules.safetyhat.entity.SafetyHatDev; +import com.zhgd.xmgl.modules.safetyhat.mapper.SafetyHatDataMapper; +import com.zhgd.xmgl.modules.safetyhat.mapper.SafetyHatDevMapper; import com.zhgd.xmgl.util.RundeSafeyHatUtils; import lombok.extern.slf4j.Slf4j; +import net.javacrumbs.shedlock.core.SchedulerLock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.web.bind.annotation.RequestMapping; @@ -19,6 +30,7 @@ import javax.websocket.WebSocketContainer; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; +import java.util.Date; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -32,18 +44,23 @@ public class SafetyHatTask { @Autowired IProjectService projectService; @Autowired + SafetyHatDevMapper safetyHatDevMapper; + @Autowired + SafetyHatDataMapper safetyHatDataMapper; + @Autowired WebSocketContainer webSocketContainer; //@Autowired SafetyHatWSClient safetyHatWSClient; /** - * 获取安全帽最新数据(30秒内的心跳) + * 获取安全帽心跳 */ @Scheduled(cron = "*/20 * * * * ?") - @RequestMapping("getHelmetData") - public void getHelmetData() { + @SchedulerLock(name = "updateHelmetStatus", lockAtMostFor = 1000 * 60 * 2, lockAtLeastFor = 1000 * 10) + @RequestMapping("updateHelmetStatus") + public void updateHelmetStatus() { try { - log.info("定时获取安全帽最新数据(30秒内的心跳)"); + log.info("获取安全帽心跳"); List projectList = projectService.list(Wrappers.lambdaQuery().ne(Project::getHelmetUser, "").ne(Project::getHelmetPassword, "")); if (CollUtil.isNotEmpty(projectList)) { for (Project project : projectList) { @@ -55,7 +72,7 @@ public class SafetyHatTask { log.info("首次连接安全帽:user:{}", project.getHelmetUser()); connect(project); } else { - log.info("发送安全帽获取实时数据,user:{}", project.getHelmetUser()); + log.info("获取安全帽心跳,user:{}", project.getHelmetUser()); client.send("{\"act\":\"ma_get_active_devices\"}"); } } catch (IllegalStateException e) { @@ -74,6 +91,76 @@ public class SafetyHatTask { } } + /** + * 定时2分钟获取安全帽数据 + */ + @Scheduled(cron = "0 */2 * * * ?") + @SchedulerLock(name = "getHelmetData", lockAtMostFor = 1000 * 60 * 2, lockAtLeastFor = 1000 * 10) + @RequestMapping("getHelmetData") + public void getHelmetData() { + log.info("定时2分钟获取安全帽数据任务开始"); + List projectList = projectService.list(Wrappers.lambdaQuery().ne(Project::getHelmetUser, "").ne(Project::getHelmetPassword, "")); + if (CollUtil.isNotEmpty(projectList)) { + for (Project project : projectList) { + List devList = safetyHatDevMapper.selectList(new LambdaQueryWrapper() + .eq(SafetyHatDev::getProjectSn, project.getProjectSn())); + for (SafetyHatDev dev : devList) { + if (StrUtil.isBlank(dev.getExtUserId())) { + log.info("定时2分钟获取安全帽数据任务,安全帽外部user_id没有设置,devSn:{}", dev.getDevSn()); + continue; + } + SafetyHatData lastData = safetyHatDataMapper.selectOne(new LambdaQueryWrapper() + .eq(SafetyHatData::getDevSn, dev.getDevSn()).orderByDesc(SafetyHatData::getUploadTime).last("limit 1")); + String start; + if (lastData != null) { + start = lastData.getUploadTime().getTime() / 1000L + ""; + } else { + start = DateUtil.offsetHour(new Date(), -12).getTime() / 1000L + ""; + } + //轨迹回放 + String url = "https://caps.runde.pro/api/index.php?ctl=location&act=get_user_path_web"; + JSONObject pJo = new JSONObject(); + pJo.put("admin_id", project.getHelmetUser()); + pJo.put("user_id", dev.getExtUserId()); + String end = new Date().getTime() / 1000L + ""; + pJo.put("start", start); + pJo.put("end", end); + String json = pJo.toJSONString(); + log.info("定时2分钟获取安全帽数据任务开始,devSn:{},url:{},json:{}", dev.getDevSn(), url, json); + String rs = HttpRequest.post(url) + .body(json) + .timeout(20000)//超时,毫秒 + .execute().body(); + log.info("定时2分钟获取安全帽数据任务开始rs,devSn:{},rs:{}", dev.getDevSn(), rs); + JSONObject rsJo = JSON.parseObject(rs); + if (rsJo.getBoolean("status")) { + JSONArray dataJa = rsJo.getJSONArray("data"); + if (CollUtil.isEmpty(dataJa)) { + continue; + } + for (int i = 0; i < dataJa.size(); i++) { + JSONObject dataJo = dataJa.getJSONObject(i); + Double xPoint = dataJo.getDouble("x_point"); + Double yPoint = dataJo.getDouble("y_point"); + Long time = dataJo.getLong("time"); + SafetyHatData data = new SafetyHatData(); + data.setWorkerInfoId(dev.getWorkerInfoId()); + data.setDevSn(dev.getDevSn()); + data.setLatitude(xPoint); + data.setLongitude(yPoint); + data.setUploadTime(new Date(time * 1000L)); + data.setProjectSn(dev.getDevSn()); + safetyHatDataMapper.insert(data); + } + } else { + log.error("定时2分钟获取安全帽数据任务失败:devSn:{}", dev.getDevSn()); + } + } + + } + } + } + /** * 测试发生安全帽数据 */