From 5c8b56430d79476bfb436ebf57a25c1a438a9803 Mon Sep 17 00:00:00 2001 From: lianlonggang Date: Thu, 3 Sep 2026 10:40:02 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat(db):=20watch=5Fmonitor=5Fdata=20?= =?UTF-8?q?=E8=A1=A8=E6=96=B0=E5=A2=9E=20EVENT=5FID=20=E4=B8=8E=20LOCATE?= =?UTF-8?q?=5FTIME=20=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为支持手表告警事件与定时GPS位置上报的关联,新增两个字段: - EVENT_ID(事件ID,用于告警事件与GPS位置更新关联) - LOCATE_TIME(定位时间,手表定时上报的GPS定位时间) 同时新增 IDX_EVENT_ID 单列索引与 IDX_WATCH_NO_EVENT_ID 联合索引, 优化 watchNo + eventId 联合定位查询性能。 数据库:118-DM 达梦数据库,SQL 全大写规范。 --- db/updatesql/20260903-watch_monitor_data新增字段.sql | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 db/updatesql/20260903-watch_monitor_data新增字段.sql diff --git a/db/updatesql/20260903-watch_monitor_data新增字段.sql b/db/updatesql/20260903-watch_monitor_data新增字段.sql new file mode 100644 index 0000000..35f2c09 --- /dev/null +++ b/db/updatesql/20260903-watch_monitor_data新增字段.sql @@ -0,0 +1,10 @@ +-- WATCH_MONITOR_DATA 新增 EVENT_ID(事件ID)和 LOCATE_TIME(定位时间)字段 +-- 数据库:118-DM 达梦数据库,SQL 全大写规范 +ALTER TABLE "WATCH_MONITOR_DATA" ADD "EVENT_ID" VARCHAR(64) DEFAULT NULL; +ALTER TABLE "WATCH_MONITOR_DATA" ADD "LOCATE_TIME" DATETIME DEFAULT NULL; + +COMMENT ON COLUMN "WATCH_MONITOR_DATA"."EVENT_ID" IS '事件ID'; +COMMENT ON COLUMN "WATCH_MONITOR_DATA"."LOCATE_TIME" IS '定位时间'; + +CREATE INDEX "IDX_EVENT_ID" ON "WATCH_MONITOR_DATA"("EVENT_ID"); +CREATE INDEX "IDX_WATCH_NO_EVENT_ID" ON "WATCH_MONITOR_DATA"("WATCH_NO", "EVENT_ID"); From 41bce5c0b2f7cc6e1d188143e9737bb7cb003b31 Mon Sep 17 00:00:00 2001 From: lianlonggang Date: Thu, 3 Sep 2026 10:40:14 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat(watch):=20notice=20=E5=85=A5=E5=8F=82?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=20eventId=E3=80=81locateTime=EF=BC=9B?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=20updateMonitorGps=20=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. WatchNotifyVo、WatchMonitorData 新增 eventId 与 locateTime 字段 2. 新增 POST /watchApi/updateMonitorGps 接口 3. watchNo + eventId 联合定位告警数据,任一缺失则忽略 4. 已存在 lon/lat 数据则忽略本次更新,避免覆盖 5. GPS84 → GCJ02 坐标转换 + 高德地址反查(参考 createMonitorData 逻辑) 6. 仅更新 GPS 相关字段,不推送大屏与短信 --- .../watch/entity/WatchMonitorData.java | 14 +++ .../com/renkang/watch/vo/WatchNotifyVo.java | 11 +++ .../watch/controller/WatchApiController.java | 15 +++ .../service/IWatchMonitorDataService.java | 11 +++ .../impl/WatchMonitorDataServiceImpl.java | 97 +++++++++++++++++++ 5 files changed, 148 insertions(+) diff --git a/health-watch/health-watch-api/src/main/java/com/renkang/watch/entity/WatchMonitorData.java b/health-watch/health-watch-api/src/main/java/com/renkang/watch/entity/WatchMonitorData.java index 8b98c54..b7d21b5 100644 --- a/health-watch/health-watch-api/src/main/java/com/renkang/watch/entity/WatchMonitorData.java +++ b/health-watch/health-watch-api/src/main/java/com/renkang/watch/entity/WatchMonitorData.java @@ -151,6 +151,20 @@ public class WatchMonitorData implements Serializable { @Excel(name = "部门编码", width = 15) @Schema(title = "部门编码") private java.lang.String orgCode; + /** + * 事件ID(用于告警事件与GPS位置更新关联的唯一标识) + */ + @Excel(name = "事件ID", width = 32) + @Schema(title = "事件ID") + private java.lang.String eventId; + /** + * 定位时间(手表上报的GPS定位时间,定时上报场景使用) + */ + @Excel(name = "定位时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Schema(title = "定位时间") + private java.util.Date locateTime; @Schema(title = "员工编号") @TableField(exist = false) diff --git a/health-watch/health-watch-api/src/main/java/com/renkang/watch/vo/WatchNotifyVo.java b/health-watch/health-watch-api/src/main/java/com/renkang/watch/vo/WatchNotifyVo.java index af48e22..f441de1 100644 --- a/health-watch/health-watch-api/src/main/java/com/renkang/watch/vo/WatchNotifyVo.java +++ b/health-watch/health-watch-api/src/main/java/com/renkang/watch/vo/WatchNotifyVo.java @@ -45,4 +45,15 @@ public class WatchNotifyVo implements Serializable { private Date warnTime; private String gpsErrorMsg; + + /** + * 事件ID(用于告警事件与GPS位置更新关联的唯一标识) + */ + private String eventId; + + /** + * 定位时间(手表上报的GPS定位时间,定时上报场景使用) + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + private Date locateTime; } diff --git a/health-watch/health-watch-biz/src/main/java/com/renkang/watch/controller/WatchApiController.java b/health-watch/health-watch-biz/src/main/java/com/renkang/watch/controller/WatchApiController.java index ab07ab2..53cd471 100644 --- a/health-watch/health-watch-biz/src/main/java/com/renkang/watch/controller/WatchApiController.java +++ b/health-watch/health-watch-biz/src/main/java/com/renkang/watch/controller/WatchApiController.java @@ -44,6 +44,21 @@ public class WatchApiController { return watchMonitorDataService.notice(json); } + /** + * 更新告警事件GPS位置信息接口 + * 根据 watchNo + eventId 联合定位已有告警数据; + * 仅更新GPS相关字段,不推送大屏与短信; + * 内部会调用高德接口进行GPS84→GCJ02坐标转换与地址反查。 + * + * @param json 入参(watchNo、eventId、lon、lat、address、locateTime、gpsErrorMsg) + * @return 处理结果 + */ + @PostMapping("/updateMonitorGps") + @Operation(summary = "更新告警事件GPS位置信息") + public AjaxJson updateMonitorGps(@RequestBody JSONObject json) { + return watchMonitorDataService.updateMonitorGps(json); + } + @GetMapping("/setData") public AjaxJson setData() { AjaxJson ajaxJson = new AjaxJson(); diff --git a/health-watch/health-watch-biz/src/main/java/com/renkang/watch/service/IWatchMonitorDataService.java b/health-watch/health-watch-biz/src/main/java/com/renkang/watch/service/IWatchMonitorDataService.java index 481af2e..044ff3d 100644 --- a/health-watch/health-watch-biz/src/main/java/com/renkang/watch/service/IWatchMonitorDataService.java +++ b/health-watch/health-watch-biz/src/main/java/com/renkang/watch/service/IWatchMonitorDataService.java @@ -38,6 +38,17 @@ public interface IWatchMonitorDataService extends IService { */ AjaxJson notice(JSONObject jsonObject); + /** + * 更新告警事件GPS位置信息 + * 根据 watchNo + eventId 联合定位已有告警数据; + * 缺失任一定位字段则忽略;已存在GPS信息则忽略; + * 仅更新数据,不推送大屏与短信。 + * + * @param jsonObject 入参(含 watchNo、eventId、lon、lat、address、locateTime、gpsErrorMsg 等) + * @return 处理结果 + */ + AjaxJson updateMonitorGps(JSONObject jsonObject); + /** * 处理历史数据 orgCode为空的问题 * @return diff --git a/health-watch/health-watch-biz/src/main/java/com/renkang/watch/service/impl/WatchMonitorDataServiceImpl.java b/health-watch/health-watch-biz/src/main/java/com/renkang/watch/service/impl/WatchMonitorDataServiceImpl.java index e21ec63..a11662c 100644 --- a/health-watch/health-watch-biz/src/main/java/com/renkang/watch/service/impl/WatchMonitorDataServiceImpl.java +++ b/health-watch/health-watch-biz/src/main/java/com/renkang/watch/service/impl/WatchMonitorDataServiceImpl.java @@ -265,6 +265,102 @@ public class WatchMonitorDataServiceImpl extends ServiceImpl queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(WatchMonitorData::getWatchNo, data.getWatchNo()) + .eq(WatchMonitorData::getEventId, data.getEventId()); + List existList = this.list(queryWrapper); + if (CollUtil.isEmpty(existList)) { + logger.warn("更新GPS信息失败,未匹配到告警记录 watchNo={}, eventId={}", data.getWatchNo(), data.getEventId()); + ajaxJson.setSuccess(true); + return ajaxJson; + } + + // 已存在GPS信息则忽略本次更新,避免覆盖已有有效坐标 + boolean hasGps = existList.stream().anyMatch(m -> m.getLon() != null && m.getLat() != null); + if (hasGps) { + logger.info("告警记录已有GPS信息,忽略本次更新 watchNo={}, eventId={}", data.getWatchNo(), data.getEventId()); + ajaxJson.setSuccess(true); + return ajaxJson; + } + + // 计算高德坐标与高德地址(参考 createMonitorData 逻辑) + WatchMonitorData updateEntity = new WatchMonitorData(); + updateEntity.setLon(data.getLon()); + updateEntity.setLat(data.getLat()); + updateEntity.setAddress(data.getAddress()); + updateEntity.setGpsErrorMsg(data.getGpsErrorMsg()); + updateEntity.setLocateTime(data.getLocateTime()); + + if (Stream.of(data.getLon(), data.getLat()).allMatch(value -> ObjUtil.isNotEmpty(value) && value != 0)) { + Gps gps = GPS84ToGCJ02(data.getLon(), data.getLat()); + if (null != gps) { + // 写入高德坐标 + updateEntity.setLonGd(BigDecimal.valueOf(gps.getLongitude())); + updateEntity.setLatGd(BigDecimal.valueOf(gps.getLatitude())); + // 调用高德接口获取地址信息 + AmapResultVo amapResultVo = amapService.getFormattedAddress(gps.getLongitude(), gps.getLatitude(), 5000); + if (amapResultVo.isSuccess()) { + updateEntity.setAddressGd(amapResultVo.getAddress()); + updateEntity.setAddress(amapResultVo.getAddress()); + } else { + String originError = StrUtil.isBlank(updateEntity.getGpsErrorMsg()) ? "" : updateEntity.getGpsErrorMsg() + ";"; + updateEntity.setGpsErrorMsg(originError + amapResultVo.getErrorMsg()); + } + } + } + + // 仅更新 GPS 相关字段,不推送大屏、不发短信 + boolean updated = this.lambdaUpdate() + .eq(WatchMonitorData::getWatchNo, data.getWatchNo()) + .eq(WatchMonitorData::getEventId, data.getEventId()) + .set(WatchMonitorData::getLon, updateEntity.getLon()) + .set(WatchMonitorData::getLat, updateEntity.getLat()) + .set(WatchMonitorData::getAddress, updateEntity.getAddress()) + .set(WatchMonitorData::getLonGd, updateEntity.getLonGd()) + .set(WatchMonitorData::getLatGd, updateEntity.getLatGd()) + .set(WatchMonitorData::getAddressGd, updateEntity.getAddressGd()) + .set(WatchMonitorData::getGpsErrorMsg, updateEntity.getGpsErrorMsg()) + .set(WatchMonitorData::getLocateTime, updateEntity.getLocateTime()) + .update(); + + if (!updated) { + logger.warn("更新GPS信息失败 watchNo={}, eventId={}", data.getWatchNo(), data.getEventId()); + } else { + logger.info("更新GPS信息成功 watchNo={}, eventId={}, 共更新{}条", data.getWatchNo(), data.getEventId(), existList.size()); + } + + ajaxJson.setSuccess(true); + return ajaxJson; + } + /** * 构建异常数据 * @@ -272,6 +368,7 @@ public class WatchMonitorDataServiceImpl extends ServiceImpl {}", JSONObject.toJSONString(data)); WatchMonitorData monitorDataEntity = new WatchMonitorData(); monitorDataEntity.setAddress(data.getAddress()); From 2f5712a67867f4dcd38b404b7d36c7db256579e4 Mon Sep 17 00:00:00 2001 From: lianlonggang Date: Thu, 3 Sep 2026 13:43:09 +0800 Subject: [PATCH 3/3] =?UTF-8?q?feat(watch):=20listCustom=20=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E4=B8=8E=E5=AF=BC=E5=87=BA=E5=A2=9E=E5=8A=A0=20eventI?= =?UTF-8?q?d=E3=80=81locateTime=20=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. AbnormalEvent 新增 eventId、locateTime 字段 2. listCustom/largeScreenListCustom/listCustomForMap 三个接口返回新字段 3. 导出 Excel 通过 @Excel 注解自动支持新字段(顺序 12、13) 4. locateTime 时间格式化为 yyyy-MM-dd HH:mm:ss 5. 修正 createMonitorData 中遗漏的 eventId 与 locateTime 字段赋值 6. DDL 表名修正为 QH_WAT_MONITOR_DATA(项目实际表名) --- .../20260903-watch_monitor_data新增字段.sql | 14 +++++++------- .../renkang/watch/bean/response/AbnormalEvent.java | 14 ++++++++++++++ .../service/impl/WatchMonitorDataServiceImpl.java | 2 ++ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/db/updatesql/20260903-watch_monitor_data新增字段.sql b/db/updatesql/20260903-watch_monitor_data新增字段.sql index 35f2c09..bb38e87 100644 --- a/db/updatesql/20260903-watch_monitor_data新增字段.sql +++ b/db/updatesql/20260903-watch_monitor_data新增字段.sql @@ -1,10 +1,10 @@ --- WATCH_MONITOR_DATA 新增 EVENT_ID(事件ID)和 LOCATE_TIME(定位时间)字段 +-- QH_WAT_MONITOR_DATA 新增 EVENT_ID(事件ID)和 LOCATE_TIME(定位时间)字段 -- 数据库:118-DM 达梦数据库,SQL 全大写规范 -ALTER TABLE "WATCH_MONITOR_DATA" ADD "EVENT_ID" VARCHAR(64) DEFAULT NULL; -ALTER TABLE "WATCH_MONITOR_DATA" ADD "LOCATE_TIME" DATETIME DEFAULT NULL; +ALTER TABLE "QH_WAT_MONITOR_DATA" ADD "EVENT_ID" VARCHAR(64) DEFAULT NULL; +ALTER TABLE "QH_WAT_MONITOR_DATA" ADD "LOCATE_TIME" DATETIME DEFAULT NULL; -COMMENT ON COLUMN "WATCH_MONITOR_DATA"."EVENT_ID" IS '事件ID'; -COMMENT ON COLUMN "WATCH_MONITOR_DATA"."LOCATE_TIME" IS '定位时间'; +COMMENT ON COLUMN "QH_WAT_MONITOR_DATA"."EVENT_ID" IS '事件ID'; +COMMENT ON COLUMN "QH_WAT_MONITOR_DATA"."LOCATE_TIME" IS '定位时间'; -CREATE INDEX "IDX_EVENT_ID" ON "WATCH_MONITOR_DATA"("EVENT_ID"); -CREATE INDEX "IDX_WATCH_NO_EVENT_ID" ON "WATCH_MONITOR_DATA"("WATCH_NO", "EVENT_ID"); +CREATE INDEX "IDX_EVENT_ID" ON "QH_WAT_MONITOR_DATA"("EVENT_ID"); +CREATE INDEX "IDX_WATCH_NO_EVENT_ID" ON "QH_WAT_MONITOR_DATA"("WATCH_NO", "EVENT_ID"); \ No newline at end of file diff --git a/health-watch/health-watch-api/src/main/java/com/renkang/watch/bean/response/AbnormalEvent.java b/health-watch/health-watch-api/src/main/java/com/renkang/watch/bean/response/AbnormalEvent.java index 907c586..7d5d777 100644 --- a/health-watch/health-watch-api/src/main/java/com/renkang/watch/bean/response/AbnormalEvent.java +++ b/health-watch/health-watch-api/src/main/java/com/renkang/watch/bean/response/AbnormalEvent.java @@ -52,4 +52,18 @@ public class AbnormalEvent extends BaseUser { private Date bindDate; @Schema(title = "重点指标用户(0:非重点指标用户 1:大病异常 2:慢病异常 3:指标异常)") private List keyUserList; + /** + * 事件ID(用于告警事件与GPS位置更新关联的唯一标识) + */ + @Excel(name = "事件ID", width = 32, orderNum = "12") + @Schema(title = "事件ID") + private String eventId; + /** + * 定位时间(手表定时上报的GPS定位时间) + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "定位时间", format = "yyyy-MM-dd HH:mm:ss", width = 20, orderNum = "13") + @Schema(title = "定位时间") + private Date locateTime; } diff --git a/health-watch/health-watch-biz/src/main/java/com/renkang/watch/service/impl/WatchMonitorDataServiceImpl.java b/health-watch/health-watch-biz/src/main/java/com/renkang/watch/service/impl/WatchMonitorDataServiceImpl.java index a11662c..8c34442 100644 --- a/health-watch/health-watch-biz/src/main/java/com/renkang/watch/service/impl/WatchMonitorDataServiceImpl.java +++ b/health-watch/health-watch-biz/src/main/java/com/renkang/watch/service/impl/WatchMonitorDataServiceImpl.java @@ -375,7 +375,9 @@ public class WatchMonitorDataServiceImpl extends ServiceImpl