diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/GpsEquipmentServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/GpsEquipmentServiceImpl.java index 69ed9ccd..cdafc790 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/GpsEquipmentServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/GpsEquipmentServiceImpl.java @@ -52,9 +52,7 @@ import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.math.RoundingMode; -import java.time.Duration; -import java.time.LocalDate; -import java.time.LocalDateTime; +import java.time.*; import java.util.*; /** @@ -605,6 +603,29 @@ public class GpsEquipmentServiceImpl extends ServiceImpl ONLINE_SESSIONS = new ConcurrentHashMap<>(); @@ -54,34 +73,15 @@ public class RydwWebSocketServer { // 2. 异步获取并推送初始化数据(避免阻塞连接) CompletableFuture.runAsync(() -> { try { + //初始化 + Map map; //连接成功过后 获取当前项目下所有成员最新坐标 Map> params = session.getRequestParameterMap(); List subscriptionIds = params.get("projectId"); - if (subscriptionIds != null && !subscriptionIds.isEmpty()){ - //拿到所有人员 - LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(SubConstructionUser::getProjectId, subscriptionIds.getFirst()); - List list = subConstructionUserService.list(queryWrapper); - //拿到所有人员最新坐标 - if (list != null && !list.isEmpty()){ - LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); - List gpsList = new ArrayList<>(); - for (SubConstructionUser constructionUser : list) { - lqw.clear(); - lqw.eq(GpsEquipmentSon::getUserId, constructionUser.getSysUserId()); - lqw.orderByDesc(GpsEquipmentSon::getCreateTime); - lqw.last("limit 1"); - GpsEquipmentSon one = gpsEquipmentSonService.getOne(lqw); - if (one != null){ - gpsList.add(one); - } - } - if (!gpsList.isEmpty()){ - WebSocketUtils.sendMessage(Long.valueOf(session.getId()), gpsList.toString()); - } - } - } - WebSocketUtils.sendMessage(Long.valueOf(session.getId()), "初始化数据为空"); + String projectId = subscriptionIds.getFirst(); + map = getData(projectId); + + session.getBasicRemote().sendText(JSON.toJSONString(map)); } catch (Exception e) { log.error("会话[{}]初始化数据处理失败", session.getId(), e); } @@ -96,6 +96,22 @@ public class RydwWebSocketServer { log.info("📥 收到会话[{}]消息:{}", session.getId(), message); // 可选:回复客户端(示例) try { + /* 解析消息 暂定json字符串 + { + "type": "1", 1表示心跳包 + "projectId":"", 项目id + "fbdwId":"", 分包单位id + "bzId":"", 班组id + "msg": "" + } + */ + JSONObject jsonObject = JSON.parseObject(message); + if (jsonObject.get("type").equals("1")){ + if (jsonObject.get("projectId") != null){ + Map objectMap = getData(jsonObject.get("projectId").toString()); + session.getBasicRemote().sendText(JSON.toJSONString(objectMap)); + } + } session.getBasicRemote().sendText("服务端已收到消息:" + message); } catch (IOException e) { log.error("📤 回复会话[{}]失败:{}", session.getId(), e.getMessage()); @@ -146,4 +162,167 @@ public class RydwWebSocketServer { public static int getOnlineCount() { return ONLINE_SESSIONS.size(); } + + /** + * 获取数据 用于首次和心跳 + */ + public Map getData(String projectId){ + Map map = new HashMap<>(); + if (projectId != null && !projectId.isEmpty()){ + //拿到项目下所有人员 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SubConstructionUser::getProjectId, projectId); + List list = subConstructionUserService.list(queryWrapper); + //获取此项目打卡范围 + LambdaQueryWrapper busProjectPunchrangeLambdaQueryWrapper = new LambdaQueryWrapper<>(); + busProjectPunchrangeLambdaQueryWrapper.eq(BusProjectPunchrange::getProjectId, projectId); + //打卡范围 + List busProjectPunchranges = busProjectPunchrangeService.list(busProjectPunchrangeLambdaQueryWrapper); + //通过打卡范围构建下方统计数据 + List> allValue = new ArrayList<>(); + for (BusProjectPunchrange busProjectPunchrange : busProjectPunchranges) { + Map map2 = new HashMap<>(); + map2.put("06:00",0); + map2.put("08:00",0); + map2.put("10:00",0); + map2.put("12:00",0); + map2.put("14:00",0); + map2.put("16:00",0); + map2.put("18:00",0); + + Map map1 = new HashMap<>(); + map1.put(busProjectPunchrange.getId()+":"+busProjectPunchrange.getPunchName(),map2); + allValue.add(map1); + } + + int zrys = 0; + int ycry = 0; + int dwcs = 0; + int zgry = 0; + + if (list != null && !list.isEmpty()){ + //初始化 + List gpsList = new ArrayList<>(); + List onlineUserList = ChatServerHandler.getOnlineUserList(); + + + //循环班组人员列表 + for (SubConstructionUser constructionUser : list) { + //从redis拿到缓存最新坐标 + boolean existsObject = RedisUtils.isExistsObject("rydw_userId_:" + constructionUser.getSysUserId()); + if (!existsObject){ + continue; + }else { +// zgry++; + } + GpsEquipmentSon one = RedisUtils.getCacheObject("rydw_userId_:" + constructionUser.getSysUserId()); + + if (one != null){ + //获取人员 + SysUserVo sysUserVo = sysUserService.selectUserById(constructionUser.getSysUserId()); + sysUserVo.setJd(one.getLocLongitude()); + sysUserVo.setWd(one.getLocLatitude()); + sysUserVo.setZhdwsj(one.getCreateTime()); + boolean isFind = false; + //循环打卡范围 判断是否是异常状态 + for (BusProjectPunchrange busProjectPunchrange : busProjectPunchranges) { + //转换范围 + Gson gson = new Gson(); + Type listType = new TypeToken>() {}.getType(); + List coordinates = gson.fromJson(busProjectPunchrange.getPunchRange(), listType); + List matchingRange = JSTUtil.findMatchingRange(one.getLocLatitude().toString(), one.getLocLongitude().toString(), coordinates); + //如果范围外为 空 + if (matchingRange != null && !matchingRange.isEmpty() && !isFind) { + sysUserVo.setQy(busProjectPunchrange.getPunchName()); + isFind = true; + + //判断在线状态 如果在线 范围外 则为异常 目前从聊天服务获取 + if (onlineUserList.contains(constructionUser.getSysUserId().toString())) { + sysUserVo.setZxzt("在线"); + //坐标在范围内在岗 + zgry++; + + String key = busProjectPunchrange.getId() + ":" + busProjectPunchrange.getPunchName(); + //给打卡柱状图赋值 + for (Map mapMap : allValue) { + //这个map为 id+名字 : 时间段 MAP + if (mapMap.containsKey(key)){ + //找到了时间段map + LocalDateTime dateTime = one.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); + // 获取小时数 + int hour = dateTime.getHour(); + // 根据小时数判断所属区间并增加计数 + if (hour >= 6 && hour < 8) { + mapMap.get(mapMap.get(key)).put("06:00", (int)mapMap.get(key).get("06:00") + 1); + } else if (hour >= 8 && hour < 10) { +// map2.put("08:00", ((Integer) map2.get("08:00")) + 1); + mapMap.get(mapMap.get(key)).put("08:00", (int)mapMap.get(key).get("08:00") + 1); + } else if (hour >= 10 && hour < 12) { +// map2.put("10:00", ((Integer) map2.get("10:00")) + 1); + mapMap.get(mapMap.get(key)).put("10:00", (int)mapMap.get(key).get("10:00") + 1); + } else if (hour >= 12 && hour < 14) { +// map2.put("12:00", ((Integer) map2.get("12:00")) + 1); + mapMap.get(mapMap.get(key)).put("12:00", (int)mapMap.get(key).get("12:00") + 1); + } else if (hour >= 14 && hour < 16) { +// map2.put("14:00", ((Integer) map2.get("14:00")) + 1); + mapMap.get(mapMap.get(key)).put("14:00", (int)mapMap.get(key).get("14:00") + 1); + } else if (hour >= 16 && hour < 18) { +// map2.put("16:00", ((Integer) map2.get("16:00")) + 1); + mapMap.get(mapMap.get(key)).put("16:00", (int)mapMap.get(key).get("16:00") + 1); + } else if (hour >= 18 && hour < 20) { +// map2.put("18:00", ((Integer) map2.get("18:00")) + 1); + mapMap.get(mapMap.get(key)).put("18:00", (int)mapMap.get(key).get("18:00") + 1); + } + } + } + } + } + } + //进一步判断状态 + if (sysUserVo.getZxzt() == null || sysUserVo.getZxzt().isEmpty()){ + if (onlineUserList.contains(constructionUser.getSysUserId().toString()) && !isFind){ + sysUserVo.setZxzt("异常"); + }else if (!onlineUserList.contains(constructionUser.getSysUserId().toString())){ + sysUserVo.setZxzt("离线"); + } + } + + //统计异常数 + if (!isFind){ + ycry++; + } + + gpsList.add(sysUserVo); + } +// if (constructionUser.getStatus().equals("0")){ +// zgry++; +// } + } + + //地图实时坐标 + map.put("gpsList", gpsList); + + //在岗人员 + map.put("zgry",zgry); + + //异常人员 + map.put("ycry",ycry); + + //总人员数 +// map.put("zrys",list.size()); + map.put("zrys",zgry + ycry); + //定位次数 + Long cacheObject = RedisUtils.getCacheObject("rydw_"); + if (cacheObject != null){ + dwcs = cacheObject.intValue(); + } + map.put("dwcs",dwcs); + + //柱状图数据 + map.put("zztsj",allValue); + } + } + return map; + } + }