From 684209aa36b80f739a435b7ad550b5aa07815e48 Mon Sep 17 00:00:00 2001 From: dfdg <2710245601@qq.com> Date: Sun, 12 Oct 2025 18:18:30 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=89=E5=85=A8=E5=B8=BD=E5=92=8C=E5=A4=A7?= =?UTF-8?q?=E5=B1=8F=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application.yml | 1 + .../dromara/bigscreen/config/RedisConfig.java | 10 +- .../ProjectBigScreenController.java | 8 + .../domain/dto/TanchuangInfoReq.java | 15 ++ .../listener/RedisMessageListener.java | 12 +- .../manager/RedisSubscribeManager.java | 192 ++++++++++++++++ .../service/ProjectBigScreenService.java | 6 + .../impl/ProjectBigScreenServiceImpl.java | 73 +++--- .../gps/controller/DeviceController.java | 166 ++++++++++++++ .../dromara/gps/controller/HatController.java | 94 ++++++++ .../gps/controller/LocationController.java | 152 +++++++++++++ .../dromara/gps/domain/AnqmManmachine.java | 35 +++ .../java/org/dromara/gps/domain/Device.java | 101 ++++++++ .../java/org/dromara/gps/domain/Location.java | 126 ++++++++++ .../gps/domain/bo/AnqmManmachineBo.java | 34 +++ .../org/dromara/gps/domain/bo/DeviceBo.java | 101 ++++++++ .../org/dromara/gps/domain/bo/LocationBo.java | 138 +++++++++++ .../gps/domain/vo/AnqmManmachineVo.java | 40 ++++ .../org/dromara/gps/domain/vo/DeviceVo.java | 116 ++++++++++ .../org/dromara/gps/domain/vo/LocationVo.java | 154 +++++++++++++ .../gps/mapper/AnqmManmachineMapper.java | 17 ++ .../org/dromara/gps/mapper/DeviceMapper.java | 15 ++ .../dromara/gps/mapper/LocationMapper.java | 31 +++ .../gps/service/IAnqmManmachineService.java | 71 ++++++ .../dromara/gps/service/IDeviceService.java | 79 +++++++ .../dromara/gps/service/ILocationService.java | 72 ++++++ .../impl/AnqmManmachineServiceImpl.java | 134 +++++++++++ .../gps/service/impl/DeviceServiceImpl.java | 215 ++++++++++++++++++ .../gps/service/impl/LocationServiceImpl.java | 155 +++++++++++++ .../java/org/dromara/gps/utils/AuthUtil.java | 79 +++++++ .../java/org/dromara/gps/utils/JsonUtil.java | 7 + .../project/service/IBusProjectService.java | 2 + .../service/impl/BusProjectServiceImpl.java | 20 ++ .../resources/mapper/gps/DeviceMapper.xml | 7 + .../resources/mapper/gps/LocationMapper.xml | 7 + 35 files changed, 2449 insertions(+), 36 deletions(-) create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/domain/dto/TanchuangInfoReq.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/manager/RedisSubscribeManager.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/controller/DeviceController.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/controller/HatController.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/controller/LocationController.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/AnqmManmachine.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/Device.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/Location.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/bo/AnqmManmachineBo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/bo/DeviceBo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/bo/LocationBo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/vo/AnqmManmachineVo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/vo/DeviceVo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/vo/LocationVo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/mapper/AnqmManmachineMapper.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/mapper/DeviceMapper.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/mapper/LocationMapper.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/IAnqmManmachineService.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/IDeviceService.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/ILocationService.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/AnqmManmachineServiceImpl.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/DeviceServiceImpl.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/LocationServiceImpl.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/utils/AuthUtil.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/utils/JsonUtil.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/gps/DeviceMapper.xml create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/gps/LocationMapper.xml diff --git a/xinnengyuan/ruoyi-admin/src/main/resources/application.yml b/xinnengyuan/ruoyi-admin/src/main/resources/application.yml index b2536c86..2879f78d 100644 --- a/xinnengyuan/ruoyi-admin/src/main/resources/application.yml +++ b/xinnengyuan/ruoyi-admin/src/main/resources/application.yml @@ -129,6 +129,7 @@ security: - /resource/oss/upload # todo 仅测试 - /facility/matrix/** + - /hat/device/data # 多租户配置 tenant: diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/config/RedisConfig.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/config/RedisConfig.java index a6a7dd71..28274800 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/config/RedisConfig.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/config/RedisConfig.java @@ -30,11 +30,11 @@ public class RedisConfig { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); - List wrjKeys = droProjectDroneService.getTopicsByKeyPrefix(); - for (String key : wrjKeys) { - // 订阅 wrj:8UUXN4P00A06NK 频道 - container.addMessageListener(listenerAdapter, new PatternTopic("wrj:"+key)); - } +// List wrjKeys = droProjectDroneService.getTopicsByKeyPrefix(); +// for (String key : wrjKeys) { +// // 订阅 wrj:8UUXN4P00A06NK 频道 +// container.addMessageListener(listenerAdapter, new PatternTopic("wrj:osd4"+key)); +// } return container; } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/controller/ProjectBigScreenController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/controller/ProjectBigScreenController.java index d107ea42..6bf1773d 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/controller/ProjectBigScreenController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/controller/ProjectBigScreenController.java @@ -410,4 +410,12 @@ public class ProjectBigScreenController extends BaseController { } + /** + * 更新无人机缓存 + */ + @GetMapping("/setWrjHc") + public void setWrjHc(){ + projectBigScreenService.setWrjHc(); + } + } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/domain/dto/TanchuangInfoReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/domain/dto/TanchuangInfoReq.java new file mode 100644 index 00000000..c9603eae --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/domain/dto/TanchuangInfoReq.java @@ -0,0 +1,15 @@ +package org.dromara.bigscreen.domain.dto; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class TanchuangInfoReq implements Serializable { + + private Long id; + + private String sn; + + private Integer type; +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/listener/RedisMessageListener.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/listener/RedisMessageListener.java index 665cb9bf..8a14764a 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/listener/RedisMessageListener.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/listener/RedisMessageListener.java @@ -46,9 +46,19 @@ public class RedisMessageListener implements MessageListener { // 处理消息 // System.out.println("返回:"+stringRedisTemplate.getStringSerializer().deserialize(message.getBody())); String gateway = JSONUtil.parseObj(stringRedisTemplate.getStringSerializer().deserialize(message.getBody())).getStr("gateway"); + String key = ""; + if (JSONUtil.parseObj(stringRedisTemplate.getStringSerializer().deserialize(message.getBody())).getJSONObject("data").get("job_number") != null) { + key = "wrj:osd1:"+gateway; + }else if (JSONUtil.parseObj(stringRedisTemplate.getStringSerializer().deserialize(message.getBody())).getJSONObject("data").get("wireless_link") != null) { + key = "wrj:osd2:"+gateway; + }else if (JSONUtil.parseObj(stringRedisTemplate.getStringSerializer().deserialize(message.getBody())).getJSONObject("data").get("network_state") != null) { + key = "wrj:osd3:"+gateway; + }else{ + key = "wrj:osd4:"+gateway; + } stringRedisTemplate .opsForValue() - .set("wrj:"+gateway + .set(key , Objects.requireNonNull(stringRedisTemplate.getStringSerializer().deserialize(message.getBody()))); DroProjectDrone droProjectDrone = droProjectDroneService.getBaseMapper().selectOne(new LambdaQueryWrapper().eq(DroProjectDrone::getDroneSn, gateway)); String pushContent = buildPushMessage(gateway,stringRedisTemplate.getStringSerializer().deserialize(message.getBody()),droProjectDrone.getProjectId()); diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/manager/RedisSubscribeManager.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/manager/RedisSubscribeManager.java new file mode 100644 index 00000000..62bafbd4 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/manager/RedisSubscribeManager.java @@ -0,0 +1,192 @@ +package org.dromara.bigscreen.manager; + +import jakarta.annotation.PostConstruct; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.redis.utils.RedisUtils; +import org.dromara.drone.service.IDroProjectDroneService; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.redis.listener.PatternTopic; +import org.springframework.data.redis.listener.RedisMessageListenerContainer; +import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +/** + * Redis 订阅管理器(定时任务动态更新订阅关系) + */ +@Component +@Slf4j +public class RedisSubscribeManager { + + // 1. 注入 Redis 核心组件 + @Resource + private RedisMessageListenerContainer redisMessageListenerContainer; + @Resource + private MessageListenerAdapter redisMessageListenerAdapter; + + // 2. 注入业务 Service(延迟加载,避免循环依赖) + @Resource + @Lazy + private IDroProjectDroneService droProjectDroneService; + + // 3. 维护已订阅的主题关系:key=完整主题(如wrj:8UUXN4P00A06NK),value=对应的PatternTopic + private final Map subscribedTopics = new ConcurrentHashMap<>(); + + + /** + * 项目启动后立即执行一次订阅(避免等待定时任务首次执行) + */ + @PostConstruct + public void initSubscribe() { + log.info("项目启动,初始化Redis订阅..."); + // 步骤1:从数据库获取最新的主题列表(原逻辑:getTopicsByKeyPrefix) + List latestKeys = droProjectDroneService.getTopicsByKeyPrefix(); + if (latestKeys == null || latestKeys.isEmpty()) { + log.warn("未获取到任何主题,将取消所有现有订阅"); + cancelAllSubscribes(); + return; + } + + // 步骤2:构建最新的完整主题(格式:wrj:key) + Set latestFullTopics = new HashSet<>(); + for (String key : latestKeys) { + latestFullTopics.add("wrj:osd1:" + key); + latestFullTopics.add("wrj:osd2:" + key); + latestFullTopics.add("wrj:osd3:" + key); + latestFullTopics.add("wrj:osd4:" + key); + } + + + // 步骤3:对比现有订阅,删除过期主题 + cancelExpiredSubscribes(latestFullTopics); + + // 步骤4:对比现有订阅,新增未订阅的主题 + addNewSubscribes(latestFullTopics); + } + + /** + * 4. 定时任务:定期更新订阅(每5分钟执行一次,可调整cron表达式) + * cron格式:秒 分 时 日 月 周 年(示例:0 0/5 * * * ? 表示每5分钟) + */ + @Scheduled(cron = "0 0/5 * * * ?") + public void dynamicUpdateSubscribe() { + try { + Object object = RedisUtils.getCacheObject("xmjdap:ws"); + log.info("开始执行Redis订阅更新定时任务..."); + if (object == null) { + return; + } + long oldTime = Long.parseLong(String.valueOf(object)); + long now = System.currentTimeMillis(); + if (now-oldTime > 300000) { + RedisUtils.deleteObject("xmjdap:ws"); + cancelAllSubscribes(); + return; + } + // 步骤1:从数据库获取最新的主题列表(原逻辑:getTopicsByKeyPrefix) + List latestKeys = droProjectDroneService.getTopicsByKeyPrefix(); + if (latestKeys == null || latestKeys.isEmpty()) { + log.warn("定时任务未获取到任何主题,将取消所有现有订阅"); + cancelAllSubscribes(); + return; + } + + // 步骤2:构建最新的完整主题(格式:wrj:key) + Set latestFullTopics = new HashSet<>(); + for (String key : latestKeys) { + latestFullTopics.add("wrj:osd1:" + key); + latestFullTopics.add("wrj:osd2:" + key); + latestFullTopics.add("wrj:osd3:" + key); + latestFullTopics.add("wrj:osd4:" + key); + } + + // 步骤3:对比现有订阅,删除过期主题 + cancelExpiredSubscribes(latestFullTopics); + + // 步骤4:对比现有订阅,新增未订阅的主题 + addNewSubscribes(latestFullTopics); + + log.info("Redis订阅更新完成,当前已订阅主题数:{}", subscribedTopics.size()); + } catch (Exception e) { + log.error("Redis订阅更新定时任务执行失败", e); + // 异常时不修改现有订阅,避免误删 + } + } + + /** + * 取消过期的订阅(现有订阅不在最新列表中的主题) + */ + private void cancelExpiredSubscribes(Set latestFullTopics) { + // 遍历现有订阅,找出需要删除的主题 + Set expiredTopics = subscribedTopics.keySet().stream() + .filter(topic -> !latestFullTopics.contains(topic)) + .collect(Collectors.toSet()); + + if (expiredTopics.isEmpty()) { + log.info("无过期订阅主题,无需删除"); + return; + } + + // 取消每个过期主题的订阅 + for (String expiredTopic : expiredTopics) { + PatternTopic topic = subscribedTopics.get(expiredTopic); + if (topic != null) { + // 从容器中移除监听器(取消订阅) + redisMessageListenerContainer.removeMessageListener(redisMessageListenerAdapter, topic); + subscribedTopics.remove(expiredTopic); + log.info("已取消过期订阅:{}", expiredTopic); + } + } + } + + /** + * 新增未订阅的主题(最新列表中有但现有订阅没有的主题) + */ + private void addNewSubscribes(Set latestFullTopics) { + // 遍历最新主题,找出需要新增的主题 + Set newTopics = latestFullTopics.stream() + .filter(topic -> !subscribedTopics.containsKey(topic)) + .collect(Collectors.toSet()); + + if (newTopics.isEmpty()) { + log.info("无新增订阅主题,无需添加"); + return; + } + + // 为每个新主题添加订阅 + for (String newTopic : newTopics) { + PatternTopic topic = new PatternTopic(newTopic); + // 向容器中添加监听器(新增订阅) + redisMessageListenerContainer.addMessageListener(redisMessageListenerAdapter, topic); + subscribedTopics.put(newTopic, topic); + log.info("已新增订阅:{}", newTopic); + } + } + + /** + * 取消所有现有订阅(兜底方法) + */ + public void cancelAllSubscribes() { + if (subscribedTopics.isEmpty()) { + return; + } + // 遍历所有已订阅主题,取消订阅 + for (Map.Entry entry : subscribedTopics.entrySet()) { + redisMessageListenerContainer.removeMessageListener(redisMessageListenerAdapter, entry.getValue()); + log.info("已取消订阅:{}", entry.getKey()); + } + subscribedTopics.clear(); + } + + + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/service/ProjectBigScreenService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/service/ProjectBigScreenService.java index 0c5e64b3..90e12df8 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/service/ProjectBigScreenService.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/service/ProjectBigScreenService.java @@ -78,4 +78,10 @@ public interface ProjectBigScreenService { void setList(GpsEquipmentBo bo); List> getClientList(Long projectId); + + /** + * 更新无人机缓存 + */ + void setWrjHc(); + } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/service/impl/ProjectBigScreenServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/service/impl/ProjectBigScreenServiceImpl.java index 4a0ef7a9..c5cc9381 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/service/impl/ProjectBigScreenServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/service/impl/ProjectBigScreenServiceImpl.java @@ -484,23 +484,39 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { Map sbMap = new HashMap<>(); Map wrjMap = new HashMap<>(); Map sxtMap = new HashMap<>(); - Map wrjMap1 = new HashMap<>(); - Map sxtMap1 = new HashMap<>(); List> gpsChildrenMap = new ArrayList<>(); List> sbChildrenMap = new ArrayList<>(); List> appChildrenMap = new ArrayList<>(); List> anqmChildrenMap = new ArrayList<>(); List> wrjChildrenMap = new ArrayList<>(); - List> wrjChildrenMap1 = new ArrayList<>(); List> sxtChildrenMap = new ArrayList<>(); - List> sxtChildrenMap1 = new ArrayList<>(); + + Map sxt = new HashMap<>(); + sxt.put("id", 4545555); + sxt.put("label", ""); + sxt.put("name", "摄像头"); + sxt.put("type", "shexiangtou"); + sxt.put("lat", 23.81524718); + sxt.put("lng", 107.13038137); + sxt.put("alt", 0); + sxtChildrenMap.add(sxt); + Map anqm = new HashMap<>(); + anqm.put("id", 45454455154L); + anqm.put("label", ""); + anqm.put("name", "安全帽"); + anqm.put("type", "positioningDevice"); + anqm.put("lat", 23.81488041); + anqm.put("lng", 107.12917371); + anqm.put("alt", 0); + + anqmChildrenMap.add(anqm); if (voList != null && !voList.isEmpty()) { for (GpsEquipmentSonVo item : voList) { Map gps = new HashMap<>(); gps.put("id", item.getClientId()); gps.put("label", item.getClientId()); gps.put("name", item.getDeviceName()); - gps.put("type", "positioningDevice"); + gps.put("type", "gps"); gps.put("lat", item.getLocLatitude()); gps.put("lng", item.getLocLongitude()); gps.put("alt", item.getLocAltitude()); @@ -513,30 +529,30 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { app.put("id", item.getClientId()); app.put("label", item.getClientId()); app.put("name", item.getDeviceName()); - app.put("type", "positioningDevice"); + app.put("type", "app"); app.put("lat", item.getLocLatitude()); app.put("lng", item.getLocLongitude()); app.put("alt", item.getLocAltitude()); appChildrenMap.add(app); } } - if (othYs7DeviceList != null && !othYs7DeviceList.isEmpty()) { - for (OthYs7Device item : othYs7DeviceList) { - Map sxt = new HashMap<>(); - sxt.put("id", item.getDeviceSerial()); - sxt.put("label", item.getDeviceSerial()); - sxt.put("name", item.getDeviceName()); - sxt.put("type", "shexiangtou"); - sxt.put("lat", item.getLatitude()); - sxt.put("lng", item.getLongitude()); - sxt.put("alt", item.getAltitude()); - sxt.put("detail", item.getDetail()); - sxtChildrenMap1.add(sxt); - } - } +// if (othYs7DeviceList != null && !othYs7DeviceList.isEmpty()) { +// for (OthYs7Device item : othYs7DeviceList) { +// Map sxt = new HashMap<>(); +// sxt.put("id", item.getDeviceSerial()); +// sxt.put("label", item.getDeviceSerial()); +// sxt.put("name", item.getDeviceName()); +// sxt.put("type", "shexiangtou"); +// sxt.put("lat", item.getLatitude()); +// sxt.put("lng", item.getLongitude()); +// sxt.put("alt", item.getAltitude()); +// sxt.put("detail", item.getDetail()); +// sxtChildrenMap.add(sxt); +// } +// } if (wrjKeys != null && !wrjKeys.isEmpty()) { for (String key : wrjKeys) { - Object object = stringRedisTemplate.opsForValue().get("wrj:" + key); + Object object = stringRedisTemplate.opsForValue().get("wrj:osd4:" + key); if (object != null) { JSONObject object1 = JSONUtil.parseObj(object); Map wrj = new HashMap<>(); @@ -546,15 +562,13 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { wrj.put("type", "wurenji"); wrj.put("lat", object1.getJSONObject("data").get("latitude")); wrj.put("lng", object1.getJSONObject("data").get("longitude")); - wrjChildrenMap1.add(wrj); + wrjChildrenMap.add(wrj); } } } gpsChildrenMap.add(sbMap); gpsChildrenMap.add(appMap); gpsChildrenMap.add(anqmMap); - sxtChildrenMap.add(sxtMap1); - wrjChildrenMap.add(wrjMap1); gpsMap.put("id", 1); gpsMap.put("label", "人员定位"); @@ -571,15 +585,9 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { sxtMap.put("id", 2); sxtMap.put("label", "摄像头"); sxtMap.put("children", sxtChildrenMap); - sxtMap1.put("id", 7); - sxtMap1.put("label", "摄像头"); - sxtMap1.put("children", sxtChildrenMap1); wrjMap.put("id", 3); wrjMap.put("label", "无人机"); wrjMap.put("children", wrjChildrenMap); - wrjMap1.put("id", 8); - wrjMap1.put("label", "无人机"); - wrjMap1.put("children", wrjChildrenMap1); maps.add(gpsMap); @@ -587,4 +595,9 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { maps.add(sxtMap); return maps; } + + @Override + public void setWrjHc() { + RedisUtils.setCacheObject("xmjdap:ws",System.currentTimeMillis() ); + } } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/controller/DeviceController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/controller/DeviceController.java new file mode 100644 index 00000000..34e8d925 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/controller/DeviceController.java @@ -0,0 +1,166 @@ +package org.dromara.gps.controller; + +import java.util.List; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.contractor.domain.SubConstructionUser; +import org.dromara.contractor.domain.dto.constructionuser.SubConstructionUserQueryReq; +import org.dromara.contractor.service.ISubConstructionUserService; +import org.dromara.gps.domain.bo.GpsEquipmentBo; +import org.dromara.gps.domain.vo.ConstructionUser; +import org.dromara.gps.domain.vo.GpsProjectVo; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.web.core.BaseController; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.excel.utils.ExcelUtil; +import org.dromara.gps.domain.vo.DeviceVo; +import org.dromara.gps.domain.bo.DeviceBo; +import org.dromara.gps.service.IDeviceService; +import org.dromara.common.mybatis.core.page.TableDataInfo; + +/** + * 安全帽设备 + * + * @author Lion Li + * @date 2025-10-11 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/gps/device") +public class DeviceController extends BaseController { + + private final IDeviceService deviceService; + + private final ISubConstructionUserService constructionUserService; + + /** + * 查询安全帽设备列表 + */ + @SaCheckPermission("gps:device:list") + @GetMapping("/list") + public TableDataInfo list(DeviceBo bo, PageQuery pageQuery) { + return deviceService.queryPageList(bo, pageQuery); + } + + /** + * 导出安全帽设备列表 + */ + @SaCheckPermission("gps:device:export") + @Log(title = "安全帽设备", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(DeviceBo bo, HttpServletResponse response) { + List list = deviceService.queryList(bo); + ExcelUtil.exportExcel(list, "安全帽设备", DeviceVo.class, response); + } + + /** + * 获取安全帽设备详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("gps:device:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(deviceService.queryById(id)); + } + + /** + * 新增安全帽设备 + */ + @SaCheckPermission("gps:device:add") + @Log(title = "安全帽设备", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody DeviceBo bo) { + return toAjax(deviceService.insertByBo(bo)); + } + + /** + * 修改安全帽设备 + */ + @SaCheckPermission("gps:device:edit") + @Log(title = "安全帽设备", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody DeviceBo bo) { + return toAjax(deviceService.updateByBo(bo)); + } + + /** + * 删除安全帽设备 + * + * @param ids 主键串 + */ + @SaCheckPermission("gps:device:remove") + @Log(title = "安全帽设备", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(deviceService.deleteWithValidByIds(List.of(ids), true)); + } + + + /** + * 项目列表 + */ + @SaCheckPermission("gps:device:getProjectList") + @GetMapping("/getProjectList") + public R> getProjectList() { + return R.ok(deviceService.getProjectList()); + } + + /** + * 查询施工人员列表 + */ + @SaCheckPermission("gps:device:userList") + @GetMapping("/userList") + public R> list(SubConstructionUserQueryReq req) { + List list = constructionUserService.list(Wrappers.lambdaQuery() + .eq(SubConstructionUser::getProjectId, req.getProjectId()) + ); + return R.ok(BeanUtil.copyToList(list,ConstructionUser.class )); + } + + /** + * GPS人机关联绑定 + */ + @SaCheckPermission("gps:device:bindManmachine") + @Log(title = "GPS设备详细", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PostMapping("/bindManmachine") + public R bindManmachine(@RequestBody DeviceBo bo) { + if (bo.getDevNum() == null) { + throw new ServiceException("设备id不能为空!!!"); + } + return toAjax(deviceService.bindManmachine(bo)); + } + + /** + * GPS人机关联解绑 + */ + @SaCheckPermission("gps:device:unbindManmachine") + @Log(title = "GPS设备详细", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PostMapping("/unbindManmachine") + public R unbindManmachine(@RequestBody DeviceBo bo) { + if (bo.getDevNum() == null) { + throw new ServiceException("设备id不能为空!!!"); + } + return toAjax(deviceService.unbindManmachine(bo)); + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/controller/HatController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/controller/HatController.java new file mode 100644 index 00000000..e8ce0067 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/controller/HatController.java @@ -0,0 +1,94 @@ +package org.dromara.gps.controller; + +import com.fasterxml.jackson.core.JsonProcessingException; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.HashMap; +import java.util.Map; + + +import static org.dromara.gps.utils.AuthUtil.*; +import static org.dromara.gps.utils.JsonUtil.*; + +@Tag(name = "安全帽管理") +@RestController +@RequestMapping("/hat") +public class HatController { + @Operation(summary = "服务下发定位(把线上接口给服务商)") + @PostMapping(value = "/device/data") + public ResponseEntity data(@RequestBody String body, @RequestHeader("timestamp") String timestamp, @RequestHeader("signature") String signature) { + // 验证签名的有效性 + if (!verifySignature(body + timestamp, signature, SECRET)) { + return ResponseEntity.badRequest().body("验证签名失败"); + } + System.out.println("接收到三方服务发送的数据:" + body); + return ResponseEntity.ok().build(); + } + + @Operation(summary = "刷新设备定位") + @PostMapping("/refresh") + public String refresh(@RequestParam @Parameter(description = "设备号") String data) throws NoSuchAlgorithmException, IOException { + long timestamp = System.currentTimeMillis() / 1000; + // 准备生成签名的参数 + Map params = new HashMap<>(); + params.put("appid", APPID); + params.put("data", data); + params.put("secret", SECRET); + params.put("timestamp", String.valueOf(timestamp)); + // 生成签名 + String sign = generateSignature(params); + // 构造请求体 + Map payload = new HashMap<>(); + payload.put("appid", APPID); + payload.put("data", data); + payload.put("secret", SECRET); + payload.put("timestamp", timestamp); + payload.put("sign", sign); + // 使用Jackson转换为JSON + String jsonPayload; + try { + jsonPayload = objectMapper.writeValueAsString(payload); + } catch (JsonProcessingException e) { + throw new RuntimeException("JSON序列化失败", e); + } + // 发送POST请求 + URL url = new URL("https://www.loctp.com/api/crm/v1/refresh/location"); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Content-Type", "application/json"); + connection.setDoOutput(true); + + try (OutputStream os = connection.getOutputStream()) { + byte[] input = jsonPayload.getBytes(StandardCharsets.UTF_8); + os.write(input, 0, input.length); + } + // 读取响应内容 + try (BufferedReader br = new BufferedReader( + new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) { + StringBuilder response = new StringBuilder(); + String responseLine; + while ((responseLine = br.readLine()) != null) { + response.append(responseLine.trim()); + } + return response.toString(); + } finally { + connection.disconnect(); + } + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/controller/LocationController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/controller/LocationController.java new file mode 100644 index 00000000..ef4866a7 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/controller/LocationController.java @@ -0,0 +1,152 @@ +package org.dromara.gps.controller; + +import java.util.List; +import java.util.Map; + +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.gps.domain.bo.GpsEquipmentSonBo; +import org.dromara.gps.domain.vo.GpsEquipmentSonVo; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.web.core.BaseController; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.excel.utils.ExcelUtil; +import org.dromara.gps.domain.vo.LocationVo; +import org.dromara.gps.domain.bo.LocationBo; +import org.dromara.gps.service.ILocationService; +import org.dromara.common.mybatis.core.page.TableDataInfo; + +/** + * 安全帽经纬度数据 + * + * @author Lion Li + * @date 2025-10-11 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/gps/location") +public class LocationController extends BaseController { + + private final ILocationService locationService; + + /** + * 查询安全帽经纬度数据列表 + */ + @SaCheckPermission("gps:location:list") + @GetMapping("/list") + public TableDataInfo list(LocationBo bo, PageQuery pageQuery) { + return locationService.queryPageList(bo, pageQuery); + } + + /** + * 导出安全帽经纬度数据列表 + */ + @SaCheckPermission("gps:location:export") + @Log(title = "安全帽经纬度数据", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(LocationBo bo, HttpServletResponse response) { + List list = locationService.queryList(bo); + ExcelUtil.exportExcel(list, "安全帽经纬度数据", LocationVo.class, response); + } + + /** + * 获取安全帽经纬度数据详细信息 + * + * @param devNum 主键 + */ + @SaCheckPermission("gps:location:query") + @GetMapping("/{devNum}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable String devNum) { + return R.ok(locationService.queryById(devNum)); + } + + /** + * 新增安全帽经纬度数据 + */ + @SaCheckPermission("gps:location:add") + @Log(title = "安全帽经纬度数据", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody LocationBo bo) { + return toAjax(locationService.insertByBo(bo)); + } + + /** + * 修改安全帽经纬度数据 + */ + @SaCheckPermission("gps:location:edit") + @Log(title = "安全帽经纬度数据", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody LocationBo bo) { + return toAjax(locationService.updateByBo(bo)); + } + + /** + * 删除安全帽经纬度数据 + * + * @param devNums 主键串 + */ + @SaCheckPermission("gps:location:remove") + @Log(title = "安全帽经纬度数据", businessType = BusinessType.DELETE) + @DeleteMapping("/{devNums}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable String[] devNums) { + return toAjax(locationService.deleteWithValidByIds(List.of(devNums), true)); + } + + /** + * 查询GPS设备定位信息列表 + */ + @SaCheckPermission("gps:equipmentSon:getList") + @GetMapping("/getList") + public R> getList(LocationBo bo) { + return R.ok(locationService.queryList(bo)); + } + + /** + * 查询GPS设备定位信息列表(大屏获取人员最后一次位置) + */ +// @SaCheckPermission("gps:equipmentSon:getList") + @GetMapping("/largerScreen/getList") + public R> getLargerScreenList(LocationBo bo) { + return R.ok(locationService.getLargerScreenList(bo)); + } + + + /** + * 查询GPS设备定位信息列表 + */ +// @SaCheckPermission("gps:equipmentSon:appGetList") +// @GetMapping("/app/getList") +// public R> getAppList(GpsEquipmentSonBo bo) { +// if (bo.getUserId() == null) { +// throw new ServiceException("用户id不能为空!!!"); +// } +// if (bo.getProjectId() == null) { +// throw new ServiceException("项目id不能为空!!!"); +// } +// if (bo.getStartTime() == null ) { +// throw new ServiceException("开始时间不能为空!!!"); +// } +// if (bo.getEndTime() == null) { +// throw new ServiceException("结束时间不能为空!!!"); +// } +// if (bo.getStartTime().isAfter(bo.getEndTime())) { +// throw new ServiceException("结束时间不能在开始时间之前!!!"); +// } +// return R.ok(locationService.getAppList(bo)); +// } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/AnqmManmachine.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/AnqmManmachine.java new file mode 100644 index 00000000..f7b7add1 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/AnqmManmachine.java @@ -0,0 +1,35 @@ +package org.dromara.gps.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * GPS人机关联对象 gps_manmachine + * + * @author Lion Li + * @date 2025-08-28 + */ +@Data +@TableName("anqm_manmachine") +public class AnqmManmachine implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * + */ + @TableId(value = "client_id") + private String clientId; + + /** + * + */ + private Long userId; + + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/Device.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/Device.java new file mode 100644 index 00000000..87a6dd15 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/Device.java @@ -0,0 +1,101 @@ +package org.dromara.gps.domain; + +import org.dromara.common.mybatis.core.domain.BaseEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; + +/** + * 安全帽设备对象 device + * + * @author Lion Li + * @date 2025-10-11 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("device") +public class Device extends BaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId(value = "id") + private Long id; + + /** + * 项目id + */ + private Long projectId; + /** + * 设备编号 + */ + private String devNum; + + /** + * 用户id + */ + private Long userId; + + /** + * 设备名称 + */ + private String devName; + + /** + * 状态 + */ + private Long status; + + + /** + * 设备采集温度 + */ + private Long temperature; + + /** + * 设备采集湿度 + */ + private Long humidity; + + /** + * 姿势 1正常 -1脱帽 -2倒地 + */ + private Long posture; + + /** + * 电池温度 + */ + private Long batteryTemp; + + /** + * 定位方 + */ + private String fixedBy; + + /** + * 电量 + */ + private Long batteryLevel; + + /** + * 是否处于低电量,1代表低电量,0则不是低电量 + */ + private Long isLowBattery; + + /** + * 电池开机时间 + */ + private String batteryOn; + + /** + * 电池关机时间 + */ + private String batteryOff; + + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/Location.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/Location.java new file mode 100644 index 00000000..5ac034f3 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/Location.java @@ -0,0 +1,126 @@ +package org.dromara.gps.domain; + +import org.dromara.common.mybatis.core.domain.BaseEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; + +/** + * 安全帽经纬度数据对象 location + * + * @author Lion Li + * @date 2025-10-11 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("location") +public class Location extends BaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId(value = "id") + private Long id; + + /** + * 项目id + */ + private Long projectId; + + /** + * 设备编号 + */ + private String devNum; + + /** + * 用户id + */ + private Long userId; + + /** + * 时间 + */ + private String time; + + /** + * 告警信息 + */ + private Long alarm; + + /** + * 状态 + */ + private Long status; + + /** + * 纬度 + */ + private Long latitude; + + /** + * 经度 + */ + private Long longitude; + + /** + * 海拔 + */ + private Long elevation; + + /** + * 速度 + */ + private Long speed; + + /** + * 方向 + */ + private Long direction; + + /** + * 里程数 + */ + private Long mileage; + + /** + * ACC开关 + */ + private Long accEnable; + + /** + * 定位开关 + */ + private Long locateEnable; + + /** + * 纬度类型(0:北纬,1:南纬) + */ + private Long latitudeType; + + /** + * 经度类型(0:东经,1:西经) + */ + private Long longitudeType; + + /** + * 超速报警 + */ + private Long speedingWarn; + + /** + * 电压告警 + */ + private Long powerVoltageWarn; + + /** + * 电源掉电 + */ + private Long powerFailure; + + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/bo/AnqmManmachineBo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/bo/AnqmManmachineBo.java new file mode 100644 index 00000000..7b7d31f0 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/bo/AnqmManmachineBo.java @@ -0,0 +1,34 @@ +package org.dromara.gps.domain.bo; + +import io.github.linpeilie.annotations.AutoMapper; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.gps.domain.AnqmManmachine; + +/** + * GPS人机关联业务对象 gps_manmachine + * + * @author Lion Li + * @date 2025-08-28 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = AnqmManmachine.class, reverseConvertGenerate = false) +public class AnqmManmachineBo extends BaseEntity { + + /** + * + */ + @NotBlank(message = "不能为空", groups = { EditGroup.class }) + private String clientId; + + /** + * + */ + private Long userId; + + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/bo/DeviceBo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/bo/DeviceBo.java new file mode 100644 index 00000000..651d62f0 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/bo/DeviceBo.java @@ -0,0 +1,101 @@ +package org.dromara.gps.domain.bo; + +import org.dromara.gps.domain.Device; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; + +/** + * 安全帽设备业务对象 device + * + * @author Lion Li + * @date 2025-10-11 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = Device.class, reverseConvertGenerate = false) +public class DeviceBo extends BaseEntity { + + /** + * id + */ + @NotNull(message = "id不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 设备编号 + */ + @NotBlank(message = "设备编号不能为空", groups = { AddGroup.class, EditGroup.class }) + private String devNum; + + /** + * 用户id + */ + private Long userId; + + /** + * 设备名称 + */ + private String devName; + + /** + * 状态 + */ + private Long status; + + /** + * 项目id + */ + private Long projectId; + + /** + * 设备采集温度 + */ + private Long temperature; + + /** + * 设备采集湿度 + */ + private Long humidity; + + /** + * 姿势 1正常 -1脱帽 -2倒地 + */ + private Long posture; + + /** + * 电池温度 + */ + private Long batteryTemp; + + /** + * 定位方 + */ + private String fixedBy; + + /** + * 电量 + */ + private Long batteryLevel; + + /** + * 是否处于低电量,1代表低电量,0则不是低电量 + */ + private Long isLowBattery; + + /** + * 电池开机时间 + */ + private String batteryOn; + + /** + * 电池关机时间 + */ + private String batteryOff; + + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/bo/LocationBo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/bo/LocationBo.java new file mode 100644 index 00000000..25b082bc --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/bo/LocationBo.java @@ -0,0 +1,138 @@ +package org.dromara.gps.domain.bo; + +import com.baomidou.mybatisplus.annotation.TableId; +import org.dromara.gps.domain.Location; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; + +import java.time.LocalDateTime; + +/** + * 安全帽经纬度数据业务对象 location + * + * @author Lion Li + * @date 2025-10-11 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = Location.class, reverseConvertGenerate = false) +public class LocationBo extends BaseEntity { + + + /** + * id + */ + private Long id; + + /** + * 项目id + */ + private Long projectId; + /** + * 设备编号 + */ + @NotBlank(message = "设备编号不能为空", groups = { EditGroup.class }) + private String devNum; + + /** + * 用户id + */ + private Long userId; + + /** + * 时间 + */ + @NotBlank(message = "时间不能为空", groups = { EditGroup.class }) + private String time; + + /** + * 告警信息 + */ + private Long alarm; + + /** + * 状态 + */ + private Long status; + + /** + * 纬度 + */ + private Long latitude; + + /** + * 经度 + */ + private Long longitude; + + /** + * 海拔 + */ + private Long elevation; + + /** + * 速度 + */ + private Long speed; + + /** + * 方向 + */ + private Long direction; + + /** + * 里程数 + */ + private Long mileage; + + /** + * ACC开关 + */ + private Long accEnable; + + /** + * 定位开关 + */ + private Long locateEnable; + + /** + * 纬度类型(0:北纬,1:南纬) + */ + private Long latitudeType; + + /** + * 经度类型(0:东经,1:西经) + */ + private Long longitudeType; + + /** + * 超速报警 + */ + private Long speedingWarn; + + /** + * 电压告警 + */ + private Long powerVoltageWarn; + + /** + * 电源掉电 + */ + private Long powerFailure; + + + /** + * 开始时间 + */ + private LocalDateTime startTime; + /** + * 结束时间 + */ + private LocalDateTime endTime; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/vo/AnqmManmachineVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/vo/AnqmManmachineVo.java new file mode 100644 index 00000000..3c18e6ed --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/vo/AnqmManmachineVo.java @@ -0,0 +1,40 @@ +package org.dromara.gps.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import org.dromara.gps.domain.AnqmManmachine; + +import java.io.Serial; +import java.io.Serializable; + + +/** + * GPS人机关联视图对象 gps_manmachine + * + * @author Lion Li + * @date 2025-08-28 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = AnqmManmachine.class) +public class AnqmManmachineVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * + */ + @ExcelProperty(value = "") + private String clientId; + + /** + * + */ + @ExcelProperty(value = "") + private Long userId; + + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/vo/DeviceVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/vo/DeviceVo.java new file mode 100644 index 00000000..3881ee62 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/vo/DeviceVo.java @@ -0,0 +1,116 @@ +package org.dromara.gps.domain.vo; + +import org.dromara.gps.domain.Device; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + + +/** + * 安全帽设备视图对象 device + * + * @author Lion Li + * @date 2025-10-11 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = Device.class) +public class DeviceVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * id + */ + @ExcelProperty(value = "id") + private Long id; + + /** + * 设备编号 + */ + @ExcelProperty(value = "设备编号") + private String devNum; + + /** + * 设备名称 + */ + @ExcelProperty(value = "设备名称") + private String devName; + + /** + * 状态 + */ + @ExcelProperty(value = "状态") + private Long status; + + /** + * 项目id + */ + @ExcelProperty(value = "项目id") + private Long projectId; + + /** + * 设备采集温度 + */ + @ExcelProperty(value = "设备采集温度") + private Long temperature; + + /** + * 设备采集湿度 + */ + @ExcelProperty(value = "设备采集湿度") + private Long humidity; + + /** + * 姿势 1正常 -1脱帽 -2倒地 + */ + @ExcelProperty(value = "姿势 1正常 -1脱帽 -2倒地") + private Long posture; + + /** + * 电池温度 + */ + @ExcelProperty(value = "电池温度") + private Long batteryTemp; + + /** + * 定位方 + */ + @ExcelProperty(value = "定位方") + private String fixedBy; + + /** + * 电量 + */ + @ExcelProperty(value = "电量") + private Long batteryLevel; + + /** + * 是否处于低电量,1代表低电量,0则不是低电量 + */ + @ExcelProperty(value = "是否处于低电量,1代表低电量,0则不是低电量") + private Long isLowBattery; + + /** + * 电池开机时间 + */ + @ExcelProperty(value = "电池开机时间") + private String batteryOn; + + /** + * 电池关机时间 + */ + @ExcelProperty(value = "电池关机时间") + private String batteryOff; + + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/vo/LocationVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/vo/LocationVo.java new file mode 100644 index 00000000..6eb3ea99 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/vo/LocationVo.java @@ -0,0 +1,154 @@ +package org.dromara.gps.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableId; +import org.dromara.gps.domain.Location; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + + +/** + * 安全帽经纬度数据视图对象 location + * + * @author Lion Li + * @date 2025-10-11 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = Location.class) +public class LocationVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + + /** + * id + */ + private Long id; + + /** + * 项目id + */ + private Long projectId; + + /** + * 设备编号 + */ + @ExcelProperty(value = "设备编号") + private String devNum; + + /** + * 用户id + */ + private Long userId; + + + private String userName; + + /** + * 时间 + */ + @ExcelProperty(value = "时间") + private String time; + + /** + * 告警信息 + */ + @ExcelProperty(value = "告警信息") + private Long alarm; + + /** + * 状态 + */ + @ExcelProperty(value = "状态") + private Long status; + + /** + * 纬度 + */ + @ExcelProperty(value = "纬度") + private Long latitude; + + /** + * 经度 + */ + @ExcelProperty(value = "经度") + private Long longitude; + + /** + * 海拔 + */ + @ExcelProperty(value = "海拔") + private Long elevation; + + /** + * 速度 + */ + @ExcelProperty(value = "速度") + private Long speed; + + /** + * 方向 + */ + @ExcelProperty(value = "方向") + private Long direction; + + /** + * 里程数 + */ + @ExcelProperty(value = "里程数") + private Long mileage; + + /** + * ACC开关 + */ + @ExcelProperty(value = "ACC开关") + private Long accEnable; + + /** + * 定位开关 + */ + @ExcelProperty(value = "定位开关") + private Long locateEnable; + + /** + * 纬度类型(0:北纬,1:南纬) + */ + @ExcelProperty(value = "纬度类型(0:北纬,1:南纬)") + private Long latitudeType; + + /** + * 经度类型(0:东经,1:西经) + */ + @ExcelProperty(value = "经度类型(0:东经,1:西经)") + private Long longitudeType; + + /** + * 超速报警 + */ + @ExcelProperty(value = "超速报警") + private Long speedingWarn; + + /** + * 电压告警 + */ + @ExcelProperty(value = "电压告警") + private Long powerVoltageWarn; + + /** + * 电源掉电 + */ + @ExcelProperty(value = "电源掉电") + private Long powerFailure; + + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/mapper/AnqmManmachineMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/mapper/AnqmManmachineMapper.java new file mode 100644 index 00000000..01b012b4 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/mapper/AnqmManmachineMapper.java @@ -0,0 +1,17 @@ +package org.dromara.gps.mapper; + +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; +import org.dromara.gps.domain.AnqmManmachine; +import org.dromara.gps.domain.GpsManmachine; +import org.dromara.gps.domain.vo.AnqmManmachineVo; +import org.dromara.gps.domain.vo.GpsManmachineVo; + +/** + * GPS人机关联Mapper接口 + * + * @author Lion Li + * @date 2025-08-28 + */ +public interface AnqmManmachineMapper extends BaseMapperPlus { + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/mapper/DeviceMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/mapper/DeviceMapper.java new file mode 100644 index 00000000..4d5ea284 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/mapper/DeviceMapper.java @@ -0,0 +1,15 @@ +package org.dromara.gps.mapper; + +import org.dromara.gps.domain.Device; +import org.dromara.gps.domain.vo.DeviceVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 安全帽设备Mapper接口 + * + * @author Lion Li + * @date 2025-10-11 + */ +public interface DeviceMapper extends BaseMapperPlus { + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/mapper/LocationMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/mapper/LocationMapper.java new file mode 100644 index 00000000..07286d78 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/mapper/LocationMapper.java @@ -0,0 +1,31 @@ +package org.dromara.gps.mapper; + +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.dromara.gps.domain.Location; +import org.dromara.gps.domain.vo.LocationVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +import java.util.List; + +/** + * 安全帽经纬度数据Mapper接口 + * + * @author Lion Li + * @date 2025-10-11 + */ +public interface LocationMapper extends BaseMapperPlus { + + @Select(" WITH ges AS (" + + " SELECT user_id,latitude,longitude,create_time,id , " + + "ROW_NUMBER() OVER(" + + "PARTITION BY user_id " + + "ORDER BY create_time DESC, id DESC) AS rn " + + "FROM location WHERE project_id = #{projectId})" + + "SELECT user_id AS userId," + + "latitude AS latitude, " + + "longitude AS longitude " + + "FROM ges " + + "WHERE rn=1;") + List selectVoFristList(@Param("projectId") Long projectId); +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/IAnqmManmachineService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/IAnqmManmachineService.java new file mode 100644 index 00000000..2c80b8bf --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/IAnqmManmachineService.java @@ -0,0 +1,71 @@ +package org.dromara.gps.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.gps.domain.AnqmManmachine; +import org.dromara.gps.domain.GpsManmachine; +import org.dromara.gps.domain.bo.AnqmManmachineBo; +import org.dromara.gps.domain.vo.AnqmManmachineVo; + +import java.util.Collection; +import java.util.List; + +/** + * GPS人机关联Service接口 + * + * @author Lion Li + * @date 2025-08-28 + */ +public interface IAnqmManmachineService extends IService{ + + /** + * 查询GPS人机关联 + * + * @param clientId 主键 + * @return GPS人机关联 + */ + AnqmManmachineVo queryById(String clientId); + + /** + * 分页查询GPS人机关联列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return GPS人机关联分页列表 + */ + TableDataInfo queryPageList(AnqmManmachineBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的GPS人机关联列表 + * + * @param bo 查询条件 + * @return GPS人机关联列表 + */ + List queryList(AnqmManmachineBo bo); + + /** + * 新增GPS人机关联 + * + * @param bo GPS人机关联 + * @return 是否新增成功 + */ + Boolean insertByBo(AnqmManmachineBo bo); + + /** + * 修改GPS人机关联 + * + * @param bo GPS人机关联 + * @return 是否修改成功 + */ + Boolean updateByBo(AnqmManmachineBo bo); + + /** + * 校验并批量删除GPS人机关联信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/IDeviceService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/IDeviceService.java new file mode 100644 index 00000000..d985df31 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/IDeviceService.java @@ -0,0 +1,79 @@ +package org.dromara.gps.service; + +import org.dromara.gps.domain.bo.GpsEquipmentBo; +import org.dromara.gps.domain.vo.DeviceVo; +import org.dromara.gps.domain.bo.DeviceBo; +import org.dromara.gps.domain.Device; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.dromara.gps.domain.vo.GpsProjectVo; + +import java.util.Collection; +import java.util.List; + +/** + * 安全帽设备Service接口 + * + * @author Lion Li + * @date 2025-10-11 + */ +public interface IDeviceService extends IService{ + + /** + * 查询安全帽设备 + * + * @param id 主键 + * @return 安全帽设备 + */ + DeviceVo queryById(Long id); + + /** + * 分页查询安全帽设备列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 安全帽设备分页列表 + */ + TableDataInfo queryPageList(DeviceBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的安全帽设备列表 + * + * @param bo 查询条件 + * @return 安全帽设备列表 + */ + List queryList(DeviceBo bo); + + /** + * 新增安全帽设备 + * + * @param bo 安全帽设备 + * @return 是否新增成功 + */ + Boolean insertByBo(DeviceBo bo); + + /** + * 修改安全帽设备 + * + * @param bo 安全帽设备 + * @return 是否修改成功 + */ + Boolean updateByBo(DeviceBo bo); + + /** + * 校验并批量删除安全帽设备信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + List getProjectList(); + + Boolean bindManmachine(DeviceBo bo); + + Boolean unbindManmachine(DeviceBo bo); +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/ILocationService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/ILocationService.java new file mode 100644 index 00000000..80e794c6 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/ILocationService.java @@ -0,0 +1,72 @@ +package org.dromara.gps.service; + +import org.dromara.gps.domain.vo.LocationVo; +import org.dromara.gps.domain.bo.LocationBo; +import org.dromara.gps.domain.Location; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; + +import com.baomidou.mybatisplus.extension.service.IService; +import java.util.Collection; +import java.util.List; + +/** + * 安全帽经纬度数据Service接口 + * + * @author Lion Li + * @date 2025-10-11 + */ +public interface ILocationService extends IService{ + + /** + * 查询安全帽经纬度数据 + * + * @param devNum 主键 + * @return 安全帽经纬度数据 + */ + LocationVo queryById(String devNum); + + /** + * 分页查询安全帽经纬度数据列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 安全帽经纬度数据分页列表 + */ + TableDataInfo queryPageList(LocationBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的安全帽经纬度数据列表 + * + * @param bo 查询条件 + * @return 安全帽经纬度数据列表 + */ + List queryList(LocationBo bo); + + /** + * 新增安全帽经纬度数据 + * + * @param bo 安全帽经纬度数据 + * @return 是否新增成功 + */ + Boolean insertByBo(LocationBo bo); + + /** + * 修改安全帽经纬度数据 + * + * @param bo 安全帽经纬度数据 + * @return 是否修改成功 + */ + Boolean updateByBo(LocationBo bo); + + /** + * 校验并批量删除安全帽经纬度数据信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + List getLargerScreenList(LocationBo bo); +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/AnqmManmachineServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/AnqmManmachineServiceImpl.java new file mode 100644 index 00000000..b9472e5b --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/AnqmManmachineServiceImpl.java @@ -0,0 +1,134 @@ +package org.dromara.gps.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.RequiredArgsConstructor; +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.gps.domain.AnqmManmachine; +import org.dromara.gps.domain.AnqmManmachine; +import org.dromara.gps.domain.bo.AnqmManmachineBo; +import org.dromara.gps.domain.vo.AnqmManmachineVo; +import org.dromara.gps.domain.vo.AnqmManmachineVo; +import org.dromara.gps.mapper.AnqmManmachineMapper; +import org.dromara.gps.mapper.AnqmManmachineMapper; +import org.dromara.gps.service.IAnqmManmachineService; +import org.dromara.gps.service.IAnqmManmachineService; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * GPS人机关联Service业务层处理 + * + * @author Lion Li + * @date 2025-08-28 + */ +@RequiredArgsConstructor +@Service +public class AnqmManmachineServiceImpl extends ServiceImpl implements IAnqmManmachineService { + + private final AnqmManmachineMapper baseMapper; + + /** + * 查询GPS人机关联 + * + * @param clientId 主键 + * @return GPS人机关联 + */ + @Override + public AnqmManmachineVo queryById(String clientId){ + return baseMapper.selectVoById(clientId); + } + + /** + * 分页查询GPS人机关联列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return GPS人机关联分页列表 + */ + @Override + public TableDataInfo queryPageList(AnqmManmachineBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的GPS人机关联列表 + * + * @param bo 查询条件 + * @return GPS人机关联列表 + */ + @Override + public List queryList(AnqmManmachineBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(AnqmManmachineBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.orderByDesc(AnqmManmachine::getClientId); + lqw.eq(bo.getUserId() != null, AnqmManmachine::getUserId, bo.getUserId()); + return lqw; + } + + /** + * 新增GPS人机关联 + * + * @param bo GPS人机关联 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(AnqmManmachineBo bo) { + AnqmManmachine add = MapstructUtils.convert(bo, AnqmManmachine.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setClientId(add.getClientId()); + } + return flag; + } + + /** + * 修改GPS人机关联 + * + * @param bo GPS人机关联 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(AnqmManmachineBo bo) { + AnqmManmachine update = MapstructUtils.convert(bo, AnqmManmachine.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(AnqmManmachine entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除GPS人机关联信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/DeviceServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/DeviceServiceImpl.java new file mode 100644 index 00000000..8ceb62eb --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/DeviceServiceImpl.java @@ -0,0 +1,215 @@ +package org.dromara.gps.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import org.dromara.gps.domain.AnqmManmachine; +import org.dromara.gps.domain.GpsEquipment; +import org.dromara.gps.domain.GpsManmachine; +import org.dromara.gps.domain.vo.GpsProjectVo; +import org.dromara.gps.mapper.AnqmManmachineMapper; +import org.dromara.project.domain.vo.project.BusProjectVo; +import org.dromara.project.service.IBusProjectService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.dromara.gps.domain.bo.DeviceBo; +import org.dromara.gps.domain.vo.DeviceVo; +import org.dromara.gps.domain.Device; +import org.dromara.gps.mapper.DeviceMapper; +import org.dromara.gps.service.IDeviceService; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 安全帽设备Service业务层处理 + * + * @author Lion Li + * @date 2025-10-11 + */ +@RequiredArgsConstructor +@Service +public class DeviceServiceImpl extends ServiceImpl implements IDeviceService { + + private final DeviceMapper baseMapper; + + @Autowired + private IBusProjectService projectService; + + @Autowired + private AnqmManmachineMapper anqmManmachineMapper; + + /** + * 查询安全帽设备 + * + * @param id 主键 + * @return 安全帽设备 + */ + @Override + public DeviceVo queryById(Long id){ + return baseMapper.selectVoById(id); + } + + /** + * 分页查询安全帽设备列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 安全帽设备分页列表 + */ + @Override + public TableDataInfo queryPageList(DeviceBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的安全帽设备列表 + * + * @param bo 查询条件 + * @return 安全帽设备列表 + */ + @Override + public List queryList(DeviceBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(DeviceBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.orderByDesc(Device::getId); + lqw.eq(StringUtils.isNotBlank(bo.getDevNum()), Device::getDevNum, bo.getDevNum()); + lqw.like(StringUtils.isNotBlank(bo.getDevName()), Device::getDevName, bo.getDevName()); + lqw.eq(bo.getStatus() != null, Device::getStatus, bo.getStatus()); + lqw.eq(bo.getProjectId() != null, Device::getProjectId, bo.getProjectId()); + lqw.eq(bo.getTemperature() != null, Device::getTemperature, bo.getTemperature()); + lqw.eq(bo.getHumidity() != null, Device::getHumidity, bo.getHumidity()); + lqw.eq(bo.getPosture() != null, Device::getPosture, bo.getPosture()); + lqw.eq(bo.getBatteryTemp() != null, Device::getBatteryTemp, bo.getBatteryTemp()); + lqw.eq(StringUtils.isNotBlank(bo.getFixedBy()), Device::getFixedBy, bo.getFixedBy()); + lqw.eq(bo.getBatteryLevel() != null, Device::getBatteryLevel, bo.getBatteryLevel()); + lqw.eq(bo.getIsLowBattery() != null, Device::getIsLowBattery, bo.getIsLowBattery()); + lqw.eq(StringUtils.isNotBlank(bo.getBatteryOn()), Device::getBatteryOn, bo.getBatteryOn()); + lqw.eq(StringUtils.isNotBlank(bo.getBatteryOff()), Device::getBatteryOff, bo.getBatteryOff()); + return lqw; + } + + /** + * 新增安全帽设备 + * + * @param bo 安全帽设备 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(DeviceBo bo) { + Device add = MapstructUtils.convert(bo, Device.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改安全帽设备 + * + * @param bo 安全帽设备 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(DeviceBo bo) { + Device update = MapstructUtils.convert(bo, Device.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(Device entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除安全帽设备信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } + + @Override + public List getProjectList() { + List projectVos = projectService.selectProjectVoList(); + if (projectVos == null || projectVos.isEmpty()) { + return null; + } + List list = new ArrayList<>(); + projectVos.forEach(item -> { + GpsProjectVo vo = new GpsProjectVo(); + vo.setProjectId(item.getId()); + vo.setProjectName(item.getProjectName()); + list.add(vo); + }); + return list; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean bindManmachine(DeviceBo bo) { + if (bo.getProjectId() == null) { + throw new ServiceException("请选择绑定项目"); + } + if (bo.getUserId() == null) { + throw new ServiceException("请选择绑定用户"); + } + List gpsManmachines = anqmManmachineMapper.selectList(Wrappers.lambdaQuery() + .eq(AnqmManmachine::getUserId, bo.getUserId())); + if(CollectionUtil.isNotEmpty(gpsManmachines)){ + throw new ServiceException("选中用户已绑定设备"); + } + baseMapper.update(new LambdaUpdateWrapper() + .set(Device::getUserId,bo.getUserId()) + .set(Device::getProjectId,bo.getProjectId()) + .eq(Device::getId,bo.getId())); + //只能绑定一个设备 + + AnqmManmachine gpsManmachine = new AnqmManmachine(); + gpsManmachine.setClientId(bo.getDevNum()); + gpsManmachine.setUserId(bo.getUserId()); + return anqmManmachineMapper.insert(gpsManmachine) > 0; + } + + @Override + public Boolean unbindManmachine(DeviceBo bo) { + baseMapper.update(new LambdaUpdateWrapper() + .set(Device::getUserId,null) + .eq(Device::getId,bo.getId())); + AnqmManmachine gpsManmachine = new AnqmManmachine(); + gpsManmachine.setClientId(bo.getDevNum()); + return anqmManmachineMapper.delete(new LambdaQueryWrapper() + .eq(AnqmManmachine::getClientId, gpsManmachine.getClientId()))> 0; + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/LocationServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/LocationServiceImpl.java new file mode 100644 index 00000000..03ef1184 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/LocationServiceImpl.java @@ -0,0 +1,155 @@ +package org.dromara.gps.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.dromara.common.core.utils.MapstructUtils; + +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import org.dromara.gps.domain.GpsEquipmentSon; +import org.dromara.gps.domain.vo.GpsEquipmentSonVo; +import org.dromara.system.domain.vo.SysUserVo; +import org.dromara.system.service.ISysUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.dromara.gps.domain.bo.LocationBo; +import org.dromara.gps.domain.vo.LocationVo; +import org.dromara.gps.domain.Location; +import org.dromara.gps.mapper.LocationMapper; +import org.dromara.gps.service.ILocationService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 安全帽经纬度数据Service业务层处理 + * + * @author Lion Li + * @date 2025-10-11 + */ +@RequiredArgsConstructor +@Service +public class LocationServiceImpl extends ServiceImpl implements ILocationService { + + private final LocationMapper baseMapper; + + @Autowired + private ISysUserService sysUserService; + + /** + * 查询安全帽经纬度数据 + * + * @param devNum 主键 + * @return 安全帽经纬度数据 + */ + @Override + public LocationVo queryById(String devNum){ + return baseMapper.selectVoById(devNum); + } + + /** + * 分页查询安全帽经纬度数据列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 安全帽经纬度数据分页列表 + */ + @Override + public TableDataInfo queryPageList(LocationBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的安全帽经纬度数据列表 + * + * @param bo 查询条件 + * @return 安全帽经纬度数据列表 + */ + @Override + public List queryList(LocationBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(LocationBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.orderByDesc(Location::getDevNum); + lqw.orderByDesc(Location::getTime); + lqw.eq(bo.getProjectId() != null, Location::getProjectId, bo.getProjectId()); + lqw.eq(bo.getUserId() != null, Location::getUserId, bo.getUserId()); + lqw.eq(StringUtils.isNotBlank(bo.getDevNum()), Location::getDevNum, bo.getDevNum()); + return lqw; + } + + /** + * 新增安全帽经纬度数据 + * + * @param bo 安全帽经纬度数据 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(LocationBo bo) { + Location add = MapstructUtils.convert(bo, Location.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setDevNum(add.getDevNum()); + } + return flag; + } + + /** + * 修改安全帽经纬度数据 + * + * @param bo 安全帽经纬度数据 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(LocationBo bo) { + Location update = MapstructUtils.convert(bo, Location.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(Location entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除安全帽经纬度数据信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } + + @Override + public List getLargerScreenList(LocationBo bo) { + List gpsEquipmentSonVoList = baseMapper.selectVoFristList(bo.getProjectId()); + for (LocationVo vo : gpsEquipmentSonVoList) { + SysUserVo sysUserVo = sysUserService.selectUserById(vo.getUserId()); + if (sysUserVo != null) { + vo.setUserName(sysUserVo.getNickName()); + } + } + return gpsEquipmentSonVoList; + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/utils/AuthUtil.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/utils/AuthUtil.java new file mode 100644 index 00000000..0421d5b3 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/utils/AuthUtil.java @@ -0,0 +1,79 @@ +package org.dromara.gps.utils; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +public class AuthUtil { + // 定义签名的 APPID 和密钥常量 + public static final String SECRET = "5366474e589c4dcfadeef223a466ca0b"; + public static final String APPID = "0c9ab925c6684ab4a33350e15ee35062"; + + public static String generateSignature(Map params) throws NoSuchAlgorithmException { + // 获取所有键并按ASCII排序 + List keys = new ArrayList<>(params.keySet()); + Collections.sort(keys); + + // 按排序后的键拼接值 + StringBuilder signStrBuilder = new StringBuilder(); + for (int i = 0; i < keys.size(); i++) { + if (i > 0) { + signStrBuilder.append("&"); + } + signStrBuilder.append(params.get(keys.get(i))); + } + String signStr = signStrBuilder.toString(); + + // 转换为小写后进行MD5加密 + signStr = signStr.toLowerCase(); + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] hashInBytes = md.digest(signStr.getBytes(StandardCharsets.UTF_8)); + + // 转换为十六进制字符串 + StringBuilder sb = new StringBuilder(); + for (byte b : hashInBytes) { + sb.append(String.format("%02x", b)); + } + return sb.toString(); + } + + /** + * 验证请求的签名 + */ + public static boolean verifySignature(String message, String messageSignature, String secret) { + try { + // 初始化HMAC-SHA1 + Mac mac = Mac.getInstance("HmacSHA1"); + SecretKeySpec secretKeySpec = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA1"); + mac.init(secretKeySpec); + // 计算消息的摘要 + byte[] expectedMac = mac.doFinal(message.getBytes(StandardCharsets.UTF_8)); + // 将签名从十六进制字符串解码 + byte[] signatureBytes = hexStringToByteArray(messageSignature); + // 比较计算得到的摘要和传入的签名 + return MessageDigest.isEqual(expectedMac, signatureBytes); + } catch (NoSuchAlgorithmException | InvalidKeyException e) { + return false; + } + } + + /** + * 将十六进制字符串转换为字节数组 + */ + private static byte[] hexStringToByteArray(String s) { + int len = s.length(); + byte[] data = new byte[len / 2]; + for (int i = 0; i < len; i += 2) { + data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + + Character.digit(s.charAt(i + 1), 16)); + } + return data; + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/utils/JsonUtil.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/utils/JsonUtil.java new file mode 100644 index 00000000..d52db035 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/utils/JsonUtil.java @@ -0,0 +1,7 @@ +package org.dromara.gps.utils; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JsonUtil { + public static ObjectMapper objectMapper = new ObjectMapper(); +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/IBusProjectService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/IBusProjectService.java index 33ac015e..9a34b7bd 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/IBusProjectService.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/IBusProjectService.java @@ -3,6 +3,7 @@ package org.dromara.project.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; +import org.dromara.bigscreen.domain.dto.TanchuangInfoReq; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.manager.weathermanager.vo.WeatherVo; @@ -237,4 +238,5 @@ public interface IBusProjectService extends IService { */ Map> getProjectCapacity(); + Map> getInfoData(TanchuangInfoReq req); } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusProjectServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusProjectServiceImpl.java index 81b961a5..6d91bd29 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusProjectServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusProjectServiceImpl.java @@ -14,6 +14,7 @@ import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; +import org.dromara.bigscreen.domain.dto.TanchuangInfoReq; import org.dromara.common.core.constant.CacheNames; import org.dromara.common.core.constant.HttpStatus; import org.dromara.common.core.constant.SystemConstants; @@ -1177,6 +1178,25 @@ public class BusProjectServiceImpl extends ServiceImpl> getInfoData(TanchuangInfoReq req) { + switch (req.getType()) { + case 1: + break; + case 2: + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + break; + } + return Map.of(); + } + /** * 构造分项工程树 */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/gps/DeviceMapper.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/gps/DeviceMapper.xml new file mode 100644 index 00000000..c93acf9f --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/gps/DeviceMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/gps/LocationMapper.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/gps/LocationMapper.xml new file mode 100644 index 00000000..a3e63ef9 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/gps/LocationMapper.xml @@ -0,0 +1,7 @@ + + + + +