From 024a6bb9525cdc8b533ede23edc792e6205f6a12 Mon Sep 17 00:00:00 2001 From: wangwei_123 <1255324804@qq.com> Date: Fri, 17 Oct 2025 17:16:22 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=8B=E6=8C=81=E8=A1=A8=E5=A4=A7=E5=B1=8F?= =?UTF-8?q?=E5=B1=95=E7=A4=BA=EF=BC=8C=E5=9B=B4=E6=A0=8F=E6=8A=A5=E8=AD=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/mqtt/config/TdengineBatchConfig.java | 42 ++++++++-- .../mqtt/processor/DeviceMessageProcessor.java | 68 +++++++++++++--- .../hand/controller/admin/AlarmRuleController.java | 1 + .../controller/admin/HandDetectorController.java | 6 ++ .../iocoder/yudao/module/hand/dal/AlarmRuleDO.java | 2 +- .../yudao/module/hand/dal/FenceAlarmDO.java | 5 -- .../iocoder/yudao/module/hand/dal/HandAlarmDO.java | 10 +++ .../yudao/module/hand/dal/HandDetectorDO.java | 5 ++ .../yudao/module/hand/enums/EnableStatus.java | 2 +- .../iocoder/yudao/module/hand/enums/FenceType.java | 4 +- .../yudao/module/hand/mapper/AlarmRuleMapper.java | 2 +- .../yudao/module/hand/mapper/AlarmTypeMapper.java | 2 +- .../yudao/module/hand/mapper/GasTypeMapper.java | 2 +- .../yudao/module/hand/mapper/TdengineMapper.java | 4 +- .../module/hand/service/HandDetectorService.java | 2 + .../hand/service/impl/HandAlarmServiceImpl.java | 2 + .../hand/service/impl/HandDetectorServiceImpl.java | 10 +++ .../yudao/module/hand/util/GeofenceUtils.java | 92 +++++++++++++++++----- .../yudao/module/hand/vo/AlarmRuleSaveReqVO.java | 4 +- .../yudao/module/hand/vo/AlarmTypeSaveReqVO.java | 6 +- .../yudao/module/hand/vo/FenceAlarmPageReqVO.java | 3 + .../yudao/module/hand/vo/FenceAlarmRespVO.java | 6 ++ .../yudao/module/hand/vo/FenceAlarmSaveReqVO.java | 18 ++++- .../yudao/module/hand/vo/FencePageReqVO.java | 1 + .../yudao/module/hand/vo/HandAlarmPageReqVO.java | 7 ++ .../yudao/module/hand/vo/HandAlarmRespVO.java | 8 ++ .../yudao/module/hand/vo/HandAlarmSaveReqVO.java | 20 ++++- .../iocoder/yudao/module/hand/vo/HandDataVo.java | 5 +- .../module/hand/vo/HandDetectorPageReqVO.java | 11 +++ .../yudao/module/hand/vo/HandDetectorRespVO.java | 10 +++ .../module/hand/vo/HandDetectorSaveReqVO.java | 9 +++ .../yudao/module/hand/vo/HandTdenginePageVO.java | 2 + .../yudao/module/hand/vo/TdengineDataVo.java | 1 + .../main/resources/mapper/HandDetectorMapper.xml | 3 +- .../src/main/resources/mapper/TdengineMapper.xml | 14 +++- cc-admin-master/yudao-server/pom.xml | 2 +- .../yudao/server/YudaoServerApplication.java | 12 ++- .../src/main/resources/application-dev.yaml | 24 +++++- .../src/main/resources/application-local.yaml | 8 +- .../src/main/resources/application-prod.yaml | 39 ++++----- .../src/main/resources/application.yaml | 2 +- 41 files changed, 381 insertions(+), 95 deletions(-) diff --git a/cc-admin-master/yudao-module-hand-mqtt/src/main/java/cn/iocoder/yudao/module/mqtt/config/TdengineBatchConfig.java b/cc-admin-master/yudao-module-hand-mqtt/src/main/java/cn/iocoder/yudao/module/mqtt/config/TdengineBatchConfig.java index 530021a..cb6460d 100644 --- a/cc-admin-master/yudao-module-hand-mqtt/src/main/java/cn/iocoder/yudao/module/mqtt/config/TdengineBatchConfig.java +++ b/cc-admin-master/yudao-module-hand-mqtt/src/main/java/cn/iocoder/yudao/module/mqtt/config/TdengineBatchConfig.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; @Slf4j @@ -16,13 +17,14 @@ public class TdengineBatchConfig { // --- 这些参数可以在构造时传入,使其更灵活 --- private final int queueCapacity; private final int batchSize; - private final long fixedRateMs; private final long offerTimeoutMs; private final String processorName; // 用于日志,区分不同的处理器实例 private final BlockingQueue dataQueue; private final Consumer> batchAction; // 【核心】用于处理一个批次的具体业务逻辑 + private final AtomicBoolean shuttingDown = new AtomicBoolean(false); + /** * 构造函数 * @param processorName 处理器名称,用于日志区分 @@ -37,7 +39,6 @@ public class TdengineBatchConfig { this.batchAction = batchAction; this.queueCapacity = queueCapacity; this.batchSize = batchSize; - this.fixedRateMs = fixedRateMs; this.offerTimeoutMs = 100L; this.dataQueue = new LinkedBlockingQueue<>(this.queueCapacity); } @@ -46,6 +47,11 @@ public class TdengineBatchConfig { if (data == null) { return; } + // 如果正在关闭,则不再接受新数据 + if (shuttingDown.get()) { + log.warn("[{}] 正在关闭,已拒绝添加新数据。", this.processorName); + return; + } try { if (!dataQueue.offer(data, offerTimeoutMs, TimeUnit.MILLISECONDS)) { log.warn("[{}] 缓冲区已满且在 {} 毫秒内无法添加,数据可能被丢弃!当前队列大小: {}", @@ -80,10 +86,34 @@ public class TdengineBatchConfig { @PreDestroy public void onShutdown() { log.info("[{}] 应用即将关闭,开始执行最后的缓冲区数据刷新...", this.processorName); - while (!dataQueue.isEmpty()) { - log.debug("[{}] 停机处理中,剩余 {} 条数据待处理...", this.processorName, dataQueue.size()); - flush(); + // 1. 设置关闭标志,阻止新数据进入 + shuttingDown.set(true); + + // 2. 将队列中剩余的所有数据一次性取出到一个临时列表 + List remainingData = new ArrayList<>(); + dataQueue.drainTo(remainingData); + + if (remainingData.isEmpty()) { + log.info("[{}] 缓冲区为空,无需处理。", this.processorName); + return; } - log.debug("[{}] 缓冲区数据已全部处理完毕。", this.processorName); + log.info("[{}] 停机处理中,剩余 {} 条数据待处理...", this.processorName, remainingData.size()); + + // 3. 对取出的数据进行分批处理 + for (int i = 0; i < remainingData.size(); i += batchSize) { + // 计算当前批次的结束索引 + int end = Math.min(i + batchSize, remainingData.size()); + // 获取子列表作为当前批次 + List batch = remainingData.subList(i, end); + + try { + log.debug("[{}] 正在处理最后批次的数据,数量: {}", this.processorName, batch.size()); + this.batchAction.accept(batch); + } catch (Exception e) { + log.error("[{}] 关闭过程中批量处理数据时发生严重错误!数据量: {}", this.processorName, batch.size(), e); + } + } + + log.info("[{}] 缓冲区数据已全部处理完毕。", this.processorName); } } \ No newline at end of file diff --git a/cc-admin-master/yudao-module-hand-mqtt/src/main/java/cn/iocoder/yudao/module/mqtt/processor/DeviceMessageProcessor.java b/cc-admin-master/yudao-module-hand-mqtt/src/main/java/cn/iocoder/yudao/module/mqtt/processor/DeviceMessageProcessor.java index 9be89a0..60bcb35 100644 --- a/cc-admin-master/yudao-module-hand-mqtt/src/main/java/cn/iocoder/yudao/module/mqtt/processor/DeviceMessageProcessor.java +++ b/cc-admin-master/yudao-module-hand-mqtt/src/main/java/cn/iocoder/yudao/module/mqtt/processor/DeviceMessageProcessor.java @@ -162,19 +162,27 @@ public class DeviceMessageProcessor { // 场景一:从“正常”变为“告警” -> 创建新告警 if (shouldBeInAlarm && !isCurrentlyInAlarm) { HandAlarmSaveReqVO alarm = new HandAlarmSaveReqVO(); + alarm.setId(null); + alarm.setDetectorId(handVo.getId()); + alarm.setSn(handVo.getSn()); alarm.setAlarmType(AlarmType.BATTERY.getType()); alarm.setTAlarmStart(LocalDateTime.now()); alarm.setVAlarmFirst(handVo.getFirstValue()); alarm.setPicX(handVo.getLatitude()); alarm.setPicY(handVo.getLongitude()); + alarm.setCreator("admin"); + alarm.setCreateTime(LocalDateTime.now()); handAlarmService.createHandAlarm(alarm); // 场景二:从“告警”变为“正常” -> 结束告警 } else if (!shouldBeInAlarm && isCurrentlyInAlarm) { - HandAlarmSaveReqVO alarm = new HandAlarmSaveReqVO(); + HandAlarmDO alarm = new HandAlarmDO(); + alarm.setId(handVo.getBatteryStatusAlarmId()); alarm.setTAlarmEnd(LocalDateTime.now()); + alarm.setUpdater("admin"); + alarm.setUpdateTime(LocalDateTime.now()); // alarm.setId(handVo.getBatteryStatusAlarmId()); // 别忘了传递告警ID - handAlarmService.updateHandAlarm(alarm); + handAlarmService.updateById(alarm); } // 如果状态未变(持续告警或持续正常),不执行任何数据库操作。 // 根据当前是否应该告警来设置最终的正确状态。 @@ -182,6 +190,7 @@ public class DeviceMessageProcessor { handVo.setBatteryStatus(EnableStatus.ENABLED.value()); } else { handVo.setBatteryStatus(EnableStatus.DISABLED.value()); + handVo.setBatteryStatusAlarmId(null); } } @@ -202,9 +211,11 @@ public class DeviceMessageProcessor { HandAlarmDO alarm = new HandAlarmDO(); alarm.setTAlarmEnd(vo.getTAlarmEnd()); alarm.setId(vo.getAlarmId()); + alarm.setVAlarmFirst(vo.getFirstValue()); alarm.setVAlarmMaximum(vo.getMaxValue()); alarm.setAlarmLevel(vo.getMaxAlarmLevel()); alarm.setTenantId(vo.getTenantId()); + alarm.setStatus(EnableStatus.HANDLE.value()); int count = handAlarmService.updateById(alarm); if (count > 0) { log.info("报警事件(ID: {})已结束,成功更新数据库。", alarm.getId()); @@ -222,17 +233,33 @@ public class DeviceMessageProcessor { } else { if (vo.getAlarmId() == null) { HandAlarmSaveReqVO alarmDO = BeanUtils.toBean(vo, HandAlarmSaveReqVO.class); - + alarmDO.setId(null); + alarmDO.setDetectorId(vo.getId()); + alarmDO.setSn(vo.getSn()); + alarmDO.setVAlarmFirst(vo.getFirstValue()); + alarmDO.setGasType(vo.getGasChemical()); + alarmDO.setPicX(vo.getLatitude()); + alarmDO.setPicY(vo.getLongitude()); + alarmDO.setAlarmType(AlarmType.GAS.getType()); + alarmDO.setCreator("admin"); + alarmDO.setCreateTime(LocalDateTime.now()); Long count = handAlarmService.createHandAlarm(alarmDO); + if (count > 0) { vo.setAlarmId(count); log.info("新报警事件已创建,数据库ID: {},并已回写至Redis。", count); } } else { + if (vo.getValue() <= vo.getMaxValue()) { + return; + } // -- 更新 -- HandAlarmDO alarmToUpdate = new HandAlarmDO(); alarmToUpdate.setId(vo.getAlarmId()); alarmToUpdate.setVAlarmMaximum(vo.getMaxValue()); + alarmToUpdate.setUpdater("admin"); + alarmToUpdate.setUpdateTime(LocalDateTime.now()); + alarmToUpdate.setTenantId(vo.getTenantId()); handAlarmService.updateById(alarmToUpdate); } } @@ -300,25 +327,29 @@ public class DeviceMessageProcessor { // --- 场景:当前处于违规状态 --- // 计算当前的违规距离 double currentDistance = GeofenceUtils.fenceDistance(handVo, fenceType, fenceList); + String formattedDistance = String.format("%.2f", currentDistance); + double roundedDistance = Double.parseDouble(formattedDistance); if (!hasOngoingAlarm) { // 1. 【触发新报警】: 之前不报警,现在开始违规 log.warn("触发 [{}] 类型围栏报警! sn: {}", fenceType, handVo.getSn()); - + //log.warn("当前位置距离【{}】类型围栏违规距离为:{}米。", fenceType, currentDistance); FenceAlarmSaveReqVO newAlarm = new FenceAlarmSaveReqVO(); newAlarm.setDetectorId(handVo.getId()); + newAlarm.setSn(handVo.getSn()); /* newAlarm.setFenceId(fenceDO.getId());*/ newAlarm.setType(fenceType.getType()); newAlarm.setTAlarmStart(LocalDateTime.now()); // 记录报警开始时间 newAlarm.setPicX(handVo.getLongitude()); newAlarm.setPicY(handVo.getLatitude()); newAlarm.setTenantId(handVo.getTenantId()); - // 初始化距离 - newAlarm.setDistance(currentDistance); - newAlarm.setMaxDistance(currentDistance); - handVo.setDistance(currentDistance); - handVo.setMaxDistance(currentDistance); + newAlarm.setDistance(roundedDistance); + newAlarm.setMaxDistance(roundedDistance); + newAlarm.setCreator("admin"); + newAlarm.setCreateTime(LocalDateTime.now()); + handVo.setDistance(roundedDistance); + handVo.setMaxDistance(roundedDistance); // 保存新报警,并获取返回的ID,用于更新 handVo 的状态 Long fenceAlarm = fenceAlarmService.createFenceAlarm(newAlarm); @@ -338,10 +369,10 @@ public class DeviceMessageProcessor { return; } - existingAlarm.setDistance(currentDistance); - if (existingAlarm.getMaxDistance() == null || currentDistance > existingAlarm.getMaxDistance()) { - existingAlarm.setMaxDistance(currentDistance); - handVo.setMaxDistance(currentDistance); + existingAlarm.setDistance(roundedDistance); + if (existingAlarm.getMaxDistance() == null || roundedDistance > existingAlarm.getMaxDistance()) { + existingAlarm.setMaxDistance(roundedDistance); + handVo.setMaxDistance(roundedDistance); } fenceAlarmService.update(existingAlarm); } @@ -356,6 +387,7 @@ public class DeviceMessageProcessor { FenceAlarmDO fenceAlarmDO = new FenceAlarmDO(); fenceAlarmDO.setId(handVo.getFenceAlarmId()); fenceAlarmDO.setTAlarmEnd(LocalDateTime.now()); + fenceAlarmDO.setStatus(EnableStatus.HANDLE.value()); fenceAlarmService.update(fenceAlarmDO); // *** 关键:重置内存/缓存中的 handVo 状态 *** @@ -375,6 +407,12 @@ public class DeviceMessageProcessor { Long gasTypeId = handVo.getGasTypeId(); List gasAlarmRuleList = ruleMap.get(gasTypeId); + // 2. 如果获取结果为 null,再尝试将其作为 String key 获取一次 + // 这是为了兼容从 Redis 缓存中反序列化回来的 Map 的情况 + if (gasAlarmRuleList == null) { + gasAlarmRuleList = ruleMap.get(gasTypeId.toString()); + } + if (gasAlarmRuleList == null || gasAlarmRuleList.isEmpty()) { log.error("无报警规则:detector={} gas type={} value={}", handVo.getSn(), handVo.getGasChemical(), gasValue); @@ -475,6 +513,10 @@ public class DeviceMessageProcessor { // 将字符串按逗号分割成数组 String[] split = numbersString.split(","); + if (split.length != 3) { + log.error("数据格式错误:{}", payload); + return detector; + } Map wgs84ToGcj02 = CoordinateTransferUtils.wgs84ToGcj02(Double.parseDouble(split[0]), Double.parseDouble(split[1])); Double lon = wgs84ToGcj02.get("lon"); diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/controller/admin/AlarmRuleController.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/controller/admin/AlarmRuleController.java index 3689c9c..d9abb9e 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/controller/admin/AlarmRuleController.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/controller/admin/AlarmRuleController.java @@ -88,6 +88,7 @@ public class AlarmRuleController { @PreAuthorize("@ss.hasPermission('gas:alarm-rule:query')") public CommonResult> getAlarmRulePage(@Valid AlarmRulePageReqVO pageReqVO) { PageResult pageResult = alarmRuleService.getAlarmRulePage(pageReqVO); + return success(BeanUtils.toBean(pageResult, AlarmRuleRespVO.class)); } diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/controller/admin/HandDetectorController.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/controller/admin/HandDetectorController.java index 219efd6..e535cbb 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/controller/admin/HandDetectorController.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/controller/admin/HandDetectorController.java @@ -122,4 +122,10 @@ public class HandDetectorController { Map handData = handDetectorService.getHandData(tenantDeviceHashKey); return CommonResult.success(handData); } + @GetMapping("/getMonitor") + @Operation(summary = "综合监控数据展示") + public CommonResult> getMonitor(){ + Map monitor = handDetectorService.getMonitor(); + return CommonResult.success(monitor); + } } \ No newline at end of file diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/dal/AlarmRuleDO.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/dal/AlarmRuleDO.java index 9ba2b74..b2abae9 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/dal/AlarmRuleDO.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/dal/AlarmRuleDO.java @@ -75,5 +75,5 @@ public class AlarmRuleDO extends BaseDO { /** * 租户id */ - private Integer tenantId; + private Long tenantId; } \ No newline at end of file diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/dal/FenceAlarmDO.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/dal/FenceAlarmDO.java index 1bcdf54..d198ec3 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/dal/FenceAlarmDO.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/dal/FenceAlarmDO.java @@ -35,11 +35,6 @@ public class FenceAlarmDO extends BaseDO { */ private Long detectorId; - - /** - * 手持表ID - */ - private String name; /** * 手持表SN */ diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/dal/HandAlarmDO.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/dal/HandAlarmDO.java index 573f644..1eb8b6b 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/dal/HandAlarmDO.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/dal/HandAlarmDO.java @@ -32,6 +32,16 @@ public class HandAlarmDO extends BaseDO { private Long id; /** + * 探头ID + */ + + private Long detectorId; + + /** + * 探头sn + */ + private String sn; + /** * 名称 */ private String name; diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/dal/HandDetectorDO.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/dal/HandDetectorDO.java index eb96129..d212468 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/dal/HandDetectorDO.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/dal/HandDetectorDO.java @@ -38,6 +38,11 @@ public class HandDetectorDO extends BaseDO { * 围栏id */ private String fenceIds; + + /** + * 围栏类型 + */ + private Integer fenceType; /** * 气体类型ID */ diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/enums/EnableStatus.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/enums/EnableStatus.java index 8d54076..9b808ed 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/enums/EnableStatus.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/enums/EnableStatus.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.hand.enums; public enum EnableStatus { - DISABLED(0), ENABLED(1),REPAIR(2); + DISABLED(0), ENABLED(1),HANDLE(2); private Integer value; EnableStatus(Integer val) { diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/enums/FenceType.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/enums/FenceType.java index 232c9a0..dfd249d 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/enums/FenceType.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/enums/FenceType.java @@ -24,7 +24,7 @@ public enum FenceType { return valveType; } } - throw new IllegalArgumentException("未知的阀门类型: " + type); + throw new IllegalArgumentException("未知的围栏类型: " + type); } // 通过 int 值获取名称 @@ -40,7 +40,7 @@ public enum FenceType { return valveType; } } - throw new IllegalArgumentException("未知的阀门名称: " + name); + throw new IllegalArgumentException("未知的围栏名称: " + name); } // 通过名称获取 int 值 diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/mapper/AlarmRuleMapper.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/mapper/AlarmRuleMapper.java index 484b425..a8ccf2d 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/mapper/AlarmRuleMapper.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/mapper/AlarmRuleMapper.java @@ -31,7 +31,7 @@ public interface AlarmRuleMapper extends BaseMapperX { .eqIfPresent(AlarmRuleDO::getSortOrder, reqVO.getSortOrder()) .eqIfPresent(AlarmRuleDO::getRemark, reqVO.getRemark()) .betweenIfPresent(AlarmRuleDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(AlarmRuleDO::getId)); + .orderByDesc(AlarmRuleDO::getSortOrder)); } } \ No newline at end of file diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/mapper/AlarmTypeMapper.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/mapper/AlarmTypeMapper.java index 2617dda..0439db9 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/mapper/AlarmTypeMapper.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/mapper/AlarmTypeMapper.java @@ -26,7 +26,7 @@ public interface AlarmTypeMapper extends BaseMapperX { .eqIfPresent(AlarmTypeDO::getSortOrder, reqVO.getSortOrder()) .eqIfPresent(AlarmTypeDO::getRemark, reqVO.getRemark()) .betweenIfPresent(AlarmTypeDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(AlarmTypeDO::getId)); + .orderByDesc(AlarmTypeDO::getSortOrder)); } } \ No newline at end of file diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/mapper/GasTypeMapper.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/mapper/GasTypeMapper.java index c7dbe6a..bed0fb3 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/mapper/GasTypeMapper.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/mapper/GasTypeMapper.java @@ -25,7 +25,7 @@ public interface GasTypeMapper extends BaseMapperX { .eqIfPresent(GasTypeDO::getSortOrder, reqVO.getSortOrder()) .eqIfPresent(GasTypeDO::getRemark, reqVO.getRemark()) .betweenIfPresent(GasTypeDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(GasTypeDO::getId)); + .orderByDesc(GasTypeDO::getSortOrder)); } } \ No newline at end of file diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/mapper/TdengineMapper.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/mapper/TdengineMapper.java index 440f5dd..52654e9 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/mapper/TdengineMapper.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/mapper/TdengineMapper.java @@ -24,7 +24,7 @@ public interface TdengineMapper { void saveDataLogBatch(@Param("sn")String sn,@Param("tenantId")Long tenantId, @Param("dataVoList")List dataVoList); - IPage selectPage(IPage page,@Param("vo") HandTdenginePageVO pageReqVO); + IPage selectPage(IPage page,@Param("vo") HandTdenginePageVO vo); - IPage selectOriginalPage(IPage page,@Param("vo") HandTdenginePageVO pageReqVO); + IPage selectOriginalPage(IPage page,@Param("vo") HandTdenginePageVO vo); } diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/service/HandDetectorService.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/service/HandDetectorService.java index 0dfbab3..1b2bd4a 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/service/HandDetectorService.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/service/HandDetectorService.java @@ -69,4 +69,6 @@ public interface HandDetectorService { void updateRedisData(Long tenantId, String topic, HandDataVo handVo); + Map getMonitor(); + } \ No newline at end of file diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/service/impl/HandAlarmServiceImpl.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/service/impl/HandAlarmServiceImpl.java index f99359d..3f62ac8 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/service/impl/HandAlarmServiceImpl.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/service/impl/HandAlarmServiceImpl.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.hand.service.impl; +import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; import cn.iocoder.yudao.module.hand.dal.HandAlarmDO; import cn.iocoder.yudao.module.hand.mapper.HandAlarmMapper; import cn.iocoder.yudao.module.hand.service.HandAlarmService; @@ -84,6 +85,7 @@ public class HandAlarmServiceImpl implements HandAlarmService { @Override @Transactional(rollbackFor = Exception.class) + @TenantIgnore public int updateById(HandAlarmDO alarm) { return handAlarmMapper.updateById(alarm); } diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/service/impl/HandDetectorServiceImpl.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/service/impl/HandDetectorServiceImpl.java index 0208acd..85c89e1 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/service/impl/HandDetectorServiceImpl.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/service/impl/HandDetectorServiceImpl.java @@ -51,6 +51,7 @@ public class HandDetectorServiceImpl implements HandDetectorService { @Resource private HandDetectorMapper handDetectorMapper; + @Resource private SqlSessionFactory sqlSessionFactory; @Resource @@ -248,4 +249,13 @@ public class HandDetectorServiceImpl implements HandDetectorService { } + @Override + public Map getMonitor() { + Long count = handDetectorMapper.selectCount(); + HashMap objectObjectHashMap = new HashMap<>(); + objectObjectHashMap.put("deviceCount", count); + + return objectObjectHashMap; + } + } \ No newline at end of file diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/util/GeofenceUtils.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/util/GeofenceUtils.java index 6c9bf71..1ac5a5f 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/util/GeofenceUtils.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/util/GeofenceUtils.java @@ -36,6 +36,9 @@ import java.util.List; public final class GeofenceUtils { private static final double METERS_PER_DEGREE_LATITUDE = 111132.954; + + private static final double EARTH_RADIUS_METERS = 6371000; // 地球平均半径(米) + private static final Gson GSON_INSTANCE = new Gson(); // 私有构造函数,防止实例化工具类 private GeofenceUtils() { @@ -48,7 +51,7 @@ public final class GeofenceUtils { * @param fenceRangeJson 符合`double[][][]`格式的JSON字符串 * @return Geofence对象列表,如果解析失败或无有效多边形则返回空列表 */ - public static List parseFences(String fenceRangeJson) { +/* public static List parseFences(String fenceRangeJson) { if (fenceRangeJson == null || fenceRangeJson.trim().isEmpty()) { return Collections.emptyList(); } @@ -73,9 +76,44 @@ public final class GeofenceUtils { log.error("解析围栏JSON失败{} ", e.getMessage()); return Collections.emptyList(); } - } + }*/ + + public static List parseFences(String fenceRangeJson) { + if (fenceRangeJson == null || fenceRangeJson.trim().isEmpty()) { + return Collections.emptyList(); + } + try { + // --- 主要改动点 1: 将期望的类型从 double[][][] 改为 double[][] --- + double[][] coordinates = GSON_INSTANCE.fromJson(fenceRangeJson, double[][].class); + + if (coordinates == null) { + return Collections.emptyList(); + } + // --- 主要改动点 2: 移除了最外层的 for 循环 --- + // 因为现在我们直接处理一个多边形的坐标,而不是一个多边形列表。 + List polygon = new ArrayList<>(); + for (double[] coordinate : coordinates) { + // 确保坐标点是有效的(包含经度和纬度) + if (coordinate != null && coordinate.length >= 2) { + polygon.add(new FencePointVo(coordinate[0], coordinate[1])); + } + } + // 确保多边形有效才创建Geofence对象 + if (polygon.size() >= 3) { + List geofences = new ArrayList<>(); + geofences.add(new Geofence(polygon)); + return geofences; // 返回包含一个围栏的列表 + } else { + return Collections.emptyList(); // 点数量不足以构成多边形 + } + + } catch (JsonSyntaxException e) { + log.error("解析围栏JSON失败{} ", e.getMessage()); + return Collections.emptyList(); + } + } /** * 检查点是否在任何一个电子围栏内部(高性能版)。 * @@ -108,35 +146,32 @@ public final class GeofenceUtils { * @param geofences Geofence对象列表 * @return 点到所有围栏边界的最短距离(米) */ + /** + * 计算点到一组围栏边界的最短距离(高精度版,使用 Haversine 公式)。 + * + * @param x 点的经度 + * @param y 点的纬度 + * @param geofences Geofence对象列表 + * @return 点到所有围栏边界顶点的最短距离(米) + */ public static double calculateDistanceToFences(double x, double y, List geofences) { if (geofences == null || geofences.isEmpty()) { return Double.POSITIVE_INFINITY; } - // 预先计算一次转换因子 - double metersPerDegreeLongitude = METERS_PER_DEGREE_LATITUDE * Math.cos(Math.toRadians(y)); - double minDistance = Double.MAX_VALUE; // 优化:先检查是否在内部,如果在则直接返回0 if (isInsideAnyFence(x, y, geofences)) { return 0.0; } - for (Geofence fence : geofences) { - // *** 核心优化:剪枝 (Pruning) *** - // 计算点到该围栏包围盒的距离。 - double distToBox = pointToBoundingBoxDistanceInMeters(x, y, fence, metersPerDegreeLongitude); - // 如果点到包围盒的距离已经比当前找到的最小距离还要大, - // 那么这个围栏内的任何一条边都不可能提供更短的距离,直接跳过。 - if (distToBox >= minDistance) { - continue; - } + double minDistance = Double.MAX_VALUE; - // 通过剪枝测试后,再对这个围栏的每条边进行精确计算 + for (Geofence fence : geofences) { + // 遍历围栏的每一个顶点 List polygon = fence.getVertices(); - for (int i = 0, j = polygon.size() - 1; i < polygon.size(); j = i++) { - FencePointVo p1 = polygon.get(i); - FencePointVo p2 = polygon.get(j); - double distance = pointToLineSegmentDistanceInMeters(x, y, p1, p2, metersPerDegreeLongitude); + for (FencePointVo vertex : polygon) { + // 使用 Haversine 公式计算点到每个顶点的距离 + double distance = haversineDistance(x, y, vertex.getX(), vertex.getY()); minDistance = Math.min(minDistance, distance); } } @@ -261,6 +296,25 @@ public final class GeofenceUtils { return minDistance; } + + /** + * 使用 Haversine 公式计算两个经纬度点之间的距离。 + * @param lon1 第一个点的经度 + * @param lat1 第一个点的纬度 + * @param lon2 第二个点的经度 + * @param lat2 第二个点的纬度 + * @return 两点之间的距离(米) + */ + public static double haversineDistance(double lon1, double lat1, double lon2, double lat2) { + double latDistance = Math.toRadians(lat2 - lat1); + double lonDistance = Math.toRadians(lon2 - lon1); + double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2) + + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) + * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2); + double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + return EARTH_RADIUS_METERS * c; + } + /** * 计算违规距离。 * diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/AlarmRuleSaveReqVO.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/AlarmRuleSaveReqVO.java index 7e0e8dd..15a8887 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/AlarmRuleSaveReqVO.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/AlarmRuleSaveReqVO.java @@ -12,8 +12,9 @@ public class AlarmRuleSaveReqVO { @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "4303") private Long id; + @Schema(description = "气体类型ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2833") - @NotEmpty(message = "气体类型ID不能为空") + @NotNull(message = "气体类型ID不能为空") private Long gasTypeId; @Schema(description = "警报类型ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "12917") @@ -43,7 +44,6 @@ public class AlarmRuleSaveReqVO { private Integer direction; @Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED) - @NotNull(message = "排序不能为空") private Integer sortOrder; @Schema(description = "备注", example = "你说的对") diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/AlarmTypeSaveReqVO.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/AlarmTypeSaveReqVO.java index 80eb99e..c9964ea 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/AlarmTypeSaveReqVO.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/AlarmTypeSaveReqVO.java @@ -7,7 +7,7 @@ import jakarta.validation.constraints.*; @Schema(description = "管理后台 - GAS警报类型新增/修改 Request VO") @Data -public class AlarmTypeSaveReqVO { +public class AlarmTypeSaveReqVO { @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "18440") private Long id; @@ -27,6 +27,10 @@ public class AlarmTypeSaveReqVO { @NotNull(message = "警报方式/级别(0:正常状态;1:一级警报;2:二级警报;3:弹窗警报)不能为空") private Integer level; + @Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED) + private Integer sortOrder; + + @Schema(description = "备注", example = "随便") private String remark; diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/FenceAlarmPageReqVO.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/FenceAlarmPageReqVO.java index 1066289..e6fb21e 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/FenceAlarmPageReqVO.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/FenceAlarmPageReqVO.java @@ -17,6 +17,9 @@ public class FenceAlarmPageReqVO extends PageParam { @Schema(description = "探头ID", example = "32133") private Long detectorId; + @Schema(description = "手持表SN", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456") + private String sn; + @Schema(description = "围栏id", example = "31072") private Long fenceId; diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/FenceAlarmRespVO.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/FenceAlarmRespVO.java index 23567af..a044cc7 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/FenceAlarmRespVO.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/FenceAlarmRespVO.java @@ -16,6 +16,12 @@ public class FenceAlarmRespVO { @ExcelProperty("主键ID") private Long id; + /** + * 手持表SN + */ + @Schema(description = "手持表SN", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456") + private String sn; + @Schema(description = "探头ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "32133") @ExcelProperty("探头ID") private Long detectorId; diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/FenceAlarmSaveReqVO.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/FenceAlarmSaveReqVO.java index bf89d27..68c6a5a 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/FenceAlarmSaveReqVO.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/FenceAlarmSaveReqVO.java @@ -17,12 +17,14 @@ public class FenceAlarmSaveReqVO { @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "12756") private Long id; + @Schema(description = "手持表SN", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456") + private String sn; + @Schema(description = "探头ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "32133") - @NotEmpty(message = "探头ID不能为空") + @NotNull(message = "探头ID不能为空") private Long detectorId; @Schema(description = "围栏id", requiredMode = Schema.RequiredMode.REQUIRED, example = "31072") - @NotEmpty(message = "围栏id不能为空") private String fenceId; @Schema(description = "报警类型", example = "2") @@ -32,7 +34,6 @@ public class FenceAlarmSaveReqVO { private Double picX; @Schema(description = "在区域图X坐标值", requiredMode = Schema.RequiredMode.REQUIRED) - @NotNull(message = "在区域图X坐标值不能为空") private Double picY; @Schema(description = "超出围栏米数") @@ -51,9 +52,18 @@ public class FenceAlarmSaveReqVO { private Integer status; @Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "随便") - @NotEmpty(message = "备注不能为空") private String remark; @Schema(description = "租户id") private Long tenantId; + + + /** + * 创建者 + */ + private String creator; + /** + * 创建时间 + */ + private LocalDateTime createTime; } \ No newline at end of file diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/FencePageReqVO.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/FencePageReqVO.java index c4bdf01..ce5bcb3 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/FencePageReqVO.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/FencePageReqVO.java @@ -14,6 +14,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class FencePageReqVO extends PageParam { + @Schema(description = "围栏名称", example = "王五") private String name; diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandAlarmPageReqVO.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandAlarmPageReqVO.java index 2059334..7565c95 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandAlarmPageReqVO.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandAlarmPageReqVO.java @@ -14,6 +14,13 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class HandAlarmPageReqVO extends PageParam { + + @Schema(description = "探头ID", example = "1") + private Long detectorId; + + @Schema(description = "探头sn", example = "1") + private String sn; + @Schema(description = "持有人姓名", example = "赵六") private String name; diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandAlarmRespVO.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandAlarmRespVO.java index 1bb056f..c41511f 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandAlarmRespVO.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandAlarmRespVO.java @@ -12,6 +12,14 @@ import com.alibaba.excel.annotation.*; @ExcelIgnoreUnannotated public class HandAlarmRespVO { + + + @Schema(description = "探头ID", example = "1") + private Long detectorId; + + @Schema(description = "探头sn", example = "1") + private String sn; + @Schema(description = "持有人姓名", example = "赵六") private String name; diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandAlarmSaveReqVO.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandAlarmSaveReqVO.java index db6c7d7..d5c0ba6 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandAlarmSaveReqVO.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandAlarmSaveReqVO.java @@ -17,6 +17,15 @@ public class HandAlarmSaveReqVO { @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "17955") private Long id; + + + @Schema(description = "探头ID", example = "1") + private Long detectorId; + + @Schema(description = "探头sn", example = "1") + private String sn; + + @Schema(description = "持有人姓名", example = "赵六") private String name; @@ -43,7 +52,6 @@ public class HandAlarmSaveReqVO { private Double picX; @Schema(description = "在区域图X坐标值", requiredMode = Schema.RequiredMode.REQUIRED) - @NotNull(message = "在区域图X坐标值不能为空") private Double picY; @Schema(description = "首报值") @@ -59,7 +67,6 @@ public class HandAlarmSaveReqVO { private LocalDateTime tAlarmEnd; @Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "随便") - @NotEmpty(message = "备注不能为空") private String remark; @@ -67,4 +74,13 @@ public class HandAlarmSaveReqVO { * 租户id */ private Integer tenantId; + + /** + * 创建者 + */ + private String creator; + /** + * 创建时间 + */ + private LocalDateTime createTime; } \ No newline at end of file diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandDataVo.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandDataVo.java index 95b3bea..99892fd 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandDataVo.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandDataVo.java @@ -45,6 +45,9 @@ public class HandDataVo { @Schema(description = "气体类型ID") private Long gasTypeId; + @Schema(description = "单位") + private String unit; + @Schema(description = "气体化学式") private String gasChemical; @@ -79,7 +82,7 @@ public class HandDataVo { @Schema(description = "电池报警状态(0:正常;1:报警)") private Integer batteryStatus; - private Integer batteryStatusAlarmId; + private Long batteryStatusAlarmId; @Schema(description = "电子围栏报警状态(0:正常;1:报警)") private Integer fenceStatus; diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandDetectorPageReqVO.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandDetectorPageReqVO.java index da34f08..98107e2 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandDetectorPageReqVO.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandDetectorPageReqVO.java @@ -5,6 +5,8 @@ import lombok.*; import io.swagger.v3.oas.annotations.media.Schema; import cn.iocoder.yudao.framework.common.pojo.PageParam; import org.springframework.format.annotation.DateTimeFormat; + +import java.math.BigDecimal; import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; @@ -22,6 +24,10 @@ public class HandDetectorPageReqVO extends PageParam { @Schema(description = "围栏id", example = "15853") private Long fenceId; + + @Schema(description = "围栏类型", example = "1") + private Integer fenceType; + @Schema(description = "气体类型ID", example = "31358") private Long gasTypeId; @@ -48,6 +54,11 @@ public class HandDetectorPageReqVO extends PageParam { @Schema(description = "启用状态(0:备用;1:启用)", example = "1") private Integer enableStatus; + /** + * 低于多少电量报警 + */ + @Schema(description = "低于多少电量报警", example = "1") + private BigDecimal batteryAlarmValue; @Schema(description = "在区域图X坐标值") private Double picX; diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandDetectorRespVO.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandDetectorRespVO.java index 92e6d63..8bbfd00 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandDetectorRespVO.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandDetectorRespVO.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.hand.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; +import java.math.BigDecimal; import java.time.LocalDateTime; import com.alibaba.excel.annotation.*; @@ -27,6 +28,9 @@ public class HandDetectorRespVO { @ExcelProperty("围栏id") private Long fenceId; + @Schema(description = "围栏类型", example = "1") + private Integer fenceType; + @Schema(description = "气体类型ID", example = "31358") @ExcelProperty("气体类型ID") private Long gasTypeId; @@ -59,6 +63,12 @@ public class HandDetectorRespVO { @ExcelProperty("生产厂家") private String manufacturer; + /** + * 低于多少电量报警 + */ + @Schema(description = "低于多少电量报警", example = "1") + private BigDecimal batteryAlarmValue; + @Schema(description = "启用状态(0:备用;1:启用)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @ExcelProperty("启用状态(0:备用;1:启用)") private Integer enableStatus; diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandDetectorSaveReqVO.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandDetectorSaveReqVO.java index 49e159e..a4ff591 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandDetectorSaveReqVO.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandDetectorSaveReqVO.java @@ -4,6 +4,8 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import jakarta.validation.constraints.*; +import java.math.BigDecimal; + @Schema(description = "管理后台 - GAS手持探测器新增/修改 Request VO") @Data public class HandDetectorSaveReqVO { @@ -20,6 +22,9 @@ public class HandDetectorSaveReqVO { @Schema(description = "围栏id", example = "15853") private Long fenceId; + @Schema(description = "围栏类型", example = "1") + private Integer fenceType; + @Schema(description = "气体类型ID", example = "31358") private Long gasTypeId; @@ -45,6 +50,10 @@ public class HandDetectorSaveReqVO { @Schema(description = "启用状态(0:备用;1:启用)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private Integer enableStatus; + + @Schema(description = "低于多少电量报警", example = "1") + private BigDecimal batteryAlarmValue; + @Schema(description = "在区域图X坐标值") private Double picX; diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandTdenginePageVO.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandTdenginePageVO.java index 45986c8..3f3aed6 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandTdenginePageVO.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/HandTdenginePageVO.java @@ -15,5 +15,7 @@ public class HandTdenginePageVO extends PageParam { private Timestamp endTime; + private Long tenantId; + } diff --git a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/TdengineDataVo.java b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/TdengineDataVo.java index 8cdfff9..c9a80c2 100644 --- a/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/TdengineDataVo.java +++ b/cc-admin-master/yudao-module-hand/src/main/java/cn/iocoder/yudao/module/hand/vo/TdengineDataVo.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.hand.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import lombok.Getter; import java.math.BigDecimal; import java.sql.Timestamp; diff --git a/cc-admin-master/yudao-module-hand/src/main/resources/mapper/HandDetectorMapper.xml b/cc-admin-master/yudao-module-hand/src/main/resources/mapper/HandDetectorMapper.xml index e29b7eb..5a64013 100644 --- a/cc-admin-master/yudao-module-hand/src/main/resources/mapper/HandDetectorMapper.xml +++ b/cc-admin-master/yudao-module-hand/src/main/resources/mapper/HandDetectorMapper.xml @@ -11,8 +11,7 @@ \ No newline at end of file diff --git a/cc-admin-master/yudao-module-hand/src/main/resources/mapper/TdengineMapper.xml b/cc-admin-master/yudao-module-hand/src/main/resources/mapper/TdengineMapper.xml index 3ff60cf..20a6a30 100644 --- a/cc-admin-master/yudao-module-hand/src/main/resources/mapper/TdengineMapper.xml +++ b/cc-admin-master/yudao-module-hand/src/main/resources/mapper/TdengineMapper.xml @@ -35,7 +35,7 @@ SELECT - ts, sn, tenant_id, payload + ts, sn, payload, tenantId FROM hand_original_log @@ -65,8 +68,11 @@ AND sn = #{vo.sn} + + AND tenant_id = #{vo.tenantId} + - AND ts >= #{startTime} + AND ts >= #{vo.startTime} diff --git a/cc-admin-master/yudao-server/pom.xml b/cc-admin-master/yudao-server/pom.xml index 1bf2069..f5d3782 100644 --- a/cc-admin-master/yudao-server/pom.xml +++ b/cc-admin-master/yudao-server/pom.xml @@ -81,7 +81,7 @@ - lock-server + cc-admin-mobile diff --git a/cc-admin-master/yudao-server/src/main/java/cn/iocoder/yudao/server/YudaoServerApplication.java b/cc-admin-master/yudao-server/src/main/java/cn/iocoder/yudao/server/YudaoServerApplication.java index 4e4fb77..2867aa3 100644 --- a/cc-admin-master/yudao-server/src/main/java/cn/iocoder/yudao/server/YudaoServerApplication.java +++ b/cc-admin-master/yudao-server/src/main/java/cn/iocoder/yudao/server/YudaoServerApplication.java @@ -2,6 +2,8 @@ package cn.iocoder.yudao.server; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; /** * 项目的启动类 @@ -14,7 +16,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; */ @SuppressWarnings("SpringComponentScan") // 忽略 IDEA 无法识别 ${yudao.info.base-package} @SpringBootApplication(scanBasePackages = {"${yudao.info.base-package}.server", "${yudao.info.base-package}.module",}) -public class YudaoServerApplication { +public class YudaoServerApplication extends SpringBootServletInitializer { public static void main(String[] args) { // 如果你碰到启动的问题,请认真阅读 https://doc.iocoder.cn/quick-start/ 文章 @@ -30,5 +32,11 @@ public class YudaoServerApplication { // 如果你碰到启动的问题,请认真阅读 https://doc.iocoder.cn/quick-start/ 文章 // 如果你碰到启动的问题,请认真阅读 https://doc.iocoder.cn/quick-start/ 文章 } - +/* *//** + * 用于 WAR 包部署到外部 Tomcat + *//* + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(YudaoServerApplication.class); + }*/ } diff --git a/cc-admin-master/yudao-server/src/main/resources/application-dev.yaml b/cc-admin-master/yudao-server/src/main/resources/application-dev.yaml index 344e97e..05afbaa 100644 --- a/cc-admin-master/yudao-server/src/main/resources/application-dev.yaml +++ b/cc-admin-master/yudao-server/src/main/resources/application-dev.yaml @@ -222,4 +222,26 @@ iot: # 插件配置 pf4j: - pluginsDir: ${user.home}/plugins # 插件目录 \ No newline at end of file + pluginsDir: ${user.home}/plugins # 插件目录 + +mqtt: + enable: true + url: tcp://127.0.0.1:1883 + username: root + password: roomasd111 + client: + id: cc-admin-qg-dev44 + connectionTimeout: 10 + keepAliveInterval: 60 + cleanSession: true + subscribe: + # $share/hand_alarm/+/zds_up //MQTT 共享订阅,不是多台服务器的情况下不要开启 + topic: +/up,+/ups,+/will,$share/hand_alarm/+/zds_up + qos: 1,1,1,1 + default: + publishQos: 1 + offlineTime: 180 # 超过 180 秒无数据则判为数据超时 + pool: + coreSize: 10 + maxSize: 20 + queueSize: 100 \ No newline at end of file diff --git a/cc-admin-master/yudao-server/src/main/resources/application-local.yaml b/cc-admin-master/yudao-server/src/main/resources/application-local.yaml index 07bd4cc..60421ab 100644 --- a/cc-admin-master/yudao-server/src/main/resources/application-local.yaml +++ b/cc-admin-master/yudao-server/src/main/resources/application-local.yaml @@ -1,5 +1,5 @@ server: - port: 48080 + port: 48081 --- #################### 数据库相关配置 #################### spring: @@ -114,7 +114,8 @@ spring: password: rabbit # RabbitMQ 服务的密码 # Kafka 配置项,对应 KafkaProperties 配置类 kafka: - bootstrap-servers: video.zdhlcn.com:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + bootstrap-servers: video.zdhlcn.com:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + #bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 --- #################### 服务保障相关配置 #################### @@ -159,7 +160,7 @@ logging: cn.iocoder.yudao.module.pay.dal.mysql: debug cn.iocoder.yudao.module.pay.dal.mysql.notify.PayNotifyTaskMapper: INFO # 配置 PayNotifyTaskMapper 的日志级别为 info cn.iocoder.yudao.module.system.dal.mysql: debug - cn.iocoder.yudao.module.mqtt: DEBUG + cn.iocoder.yudao.module.mqtt: WARN org.springframework.context.support.PostProcessorRegistrationDelegate: ERROR # TODO 芋艿:先禁用,Spring Boot 3.X 存在部分错误的 WARN 提示 # 打开 dynamic-datasource 框架的 DEBUG 日志 #com.baomidou.dynamic.datasource: DEBUG @@ -228,6 +229,7 @@ mqtt: keepAliveInterval: 60 cleanSession: true subscribe: + # $share/hand_alarm/+/zds_up //MQTT 共享订阅,不是多台服务器的情况下不要开启 topic: +/up,+/ups,+/will,$share/hand_alarm/+/zds_up qos: 1,1,1,1 default: diff --git a/cc-admin-master/yudao-server/src/main/resources/application-prod.yaml b/cc-admin-master/yudao-server/src/main/resources/application-prod.yaml index fba90de..cb352f9 100644 --- a/cc-admin-master/yudao-server/src/main/resources/application-prod.yaml +++ b/cc-admin-master/yudao-server/src/main/resources/application-prod.yaml @@ -48,25 +48,25 @@ spring: primary: master datasource: master: - url: jdbc:mysql://127.0.0.1:3306/cc-admin-lock?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例 - username: locksql - password: Zdhllock@2024 + url: jdbc:mysql://172.21.16.17:3306/cc-admin-mobile?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例 + username: mobilesql + password: Zdhlmobile@2025 driver-class-name: com.mysql.cj.jdbc.Driver # MySQL Connector/J 8.X 连接的示例 -# tdengine: -# url: jdbc:TAOS-RS://192.168.0.180:6041/test -# username: root -# password: root -# driver-class-name: com.taosdata.jdbc.rs.RestfulDriver # TDengine 连接的示例 -# druid: -# validation-query: SELECT 1 # TDengine 的验证 SQL + tdengine: + url: jdbc:TAOS-RS://172.21.16.17:6041/td_mobile + username: tdmobile + password: Mobile@2025 + driver-class-name: com.taosdata.jdbc.rs.RestfulDriver # TDengine 连接的示例 + druid: + validation-query: SELECT 1 # TDengine 的验证 SQL # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 data: redis: host: 127.0.0.1 # 地址 - port: 6377 # 端口 - database: 5 # 数据库索引 - password: 'Redislock@25' # 密码,建议生产环境开启 + port: 6373 # 端口 + database: 11 # 数据库索引 + password: 'Zdhlredis23!' # 密码,建议生产环境开启 --- #################### 定时任务相关配置 #################### @@ -77,7 +77,7 @@ spring: scheduler-name: schedulerName # Scheduler 名字。默认为 schedulerName job-store-type: jdbc # Job 存储器类型。默认为 memory 表示内存,可选 jdbc 使用数据库。 wait-for-jobs-to-complete-on-shutdown: true # 应用关闭时,是否等待定时任务执行完成。默认为 false ,建议设置为 true - properties: # 添加 Quartz Scheduler 附加属性,更多可以看 http://www.quartz-scheduler.org/documentation/2.4.0-SNAPSHOT/configuration.html 文档 + properties: # 添加 Quartz Scheduler 附加属性,更多可以看 http://www.quartz-scheduler.org/umentation/2.4.0-SNAPSHOT/configuration.html 文档 org: quartz: # Scheduler 相关配置 @@ -114,7 +114,7 @@ spring: password: rabbit # RabbitMQ 服务的密码 # Kafka 配置项,对应 KafkaProperties 配置类 kafka: - bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + bootstrap-servers: video.zdhlcn.com:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 --- #################### 服务保障相关配置 #################### @@ -148,7 +148,7 @@ spring: # 日志文件配置 logging: file: - name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径 + name: /var/log/tomcat_mobile/${spring.application.name}.log # 日志文件名,全路径 level: # 配置自己写的 MyBatis Mapper 打印日志 cn.iocoder.yudao.module.bpm.dal.mysql: debug @@ -213,7 +213,7 @@ yudao: env-version: develop # 小程序版本: 正式版为 "release";体验版为 "trial";开发版为 "develop" wxa-subscribe-message: miniprogram-state: developer # 跳转小程序类型:开发版为 “developer”;体验版为 “trial”为;正式版为 “formal” - tencent-lbs-key: TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E # QQ 地图的密钥 https://lbs.qq.com/service/staticV2/staticGuide/staticDoc + tencent-lbs-key: TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E # QQ 地图的密钥 https://lbs.qq.com/service/staticV2/staticGuide/static cache: @@ -228,7 +228,7 @@ pf4j: mqtt: enable: true - url: tcp://zdmq.zdhlcn.com:8883 + url: tcp://zdmq.zdhlcn.com:2883 username: mobileqt password: DVSwxQwY