From 3c700a42f907bb3f9e1b6d8106071abfcd276669 Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Thu, 25 Sep 2025 15:32:09 +0800 Subject: [PATCH] =?UTF-8?q?feat(device):=20=E6=B7=BB=E5=8A=A0=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E5=9C=A8=E7=BA=BF=E7=8A=B6=E6=80=81=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E5=8A=9F=E8=83=BD-=20=E5=9C=A8DeviceV2Controller=E4=B8=AD?= =?UTF-8?q?=E6=96=B0=E5=A2=9EgetDeviceOnlineStatus=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=EF=BC=8C=E7=94=A8=E4=BA=8E=E6=A0=B9=E6=8D=AE=E8=AE=BE=E5=A4=87?= =?UTF-8?q?ID=E6=9F=A5=E8=AF=A2=E8=AE=BE=E5=A4=87=E5=9C=A8=E7=BA=BF?= =?UTF-8?q?=E7=8A=B6=E6=80=81=20-=20=E5=BC=95=E5=85=A5DeviceStatusDTO?= =?UTF-8?q?=E5=92=8CDeviceStatusIntegrationService=E4=BB=A5=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=AE=BE=E5=A4=87=E7=8A=B6=E6=80=81=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?-=20=E4=BF=AE=E6=94=B9DeviceStatusDTO=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E5=AD=97=E6=AE=B5=E7=B1=BB=E5=9E=8B=E4=B8=BA?= =?UTF-8?q?Date=EF=BC=8C=E5=B9=B6=E8=B0=83=E6=95=B4JSON=E5=BA=8F=E5=88=97?= =?UTF-8?q?=E5=8C=96=E6=A0=BC=E5=BC=8F-=20=E5=9C=A8DeviceRepository?= =?UTF-8?q?=E4=B8=AD=E5=A2=9E=E5=8A=A0convertToEntityWithStatus=E6=96=B9?= =?UTF-8?q?=E6=B3=95=EF=BC=8C=E7=94=A8=E4=BA=8E=E5=90=88=E5=B9=B6=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E4=BF=A1=E6=81=AF=E4=B8=8E=E7=8A=B6=E6=80=81=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=20-=20=E4=BC=98=E5=8C=96DeviceRepository=E4=B8=AD?= =?UTF-8?q?=E7=9A=84getOnlineStatus=E6=96=B9=E6=B3=95=EF=BC=8C=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=BC=82=E5=B8=B8=E5=A4=84=E7=90=86=E5=92=8C=E9=99=8D?= =?UTF-8?q?=E7=BA=A7=E6=9C=BA=E5=88=B6-=20=E5=AE=8C=E5=96=84=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E5=9C=A8=E7=BA=BF=E7=8A=B6=E6=80=81=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E7=9A=84=E6=97=A5=E5=BF=97=E8=AE=B0=E5=BD=95=E5=92=8C=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/pc/DeviceV2Controller.java | 25 ++++++++ .../device/dto/status/DeviceStatusDTO.java | 9 +-- .../basic/repository/DeviceRepository.java | 57 +++++++++++++++++-- 3 files changed, 83 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/ycwl/basic/controller/pc/DeviceV2Controller.java b/src/main/java/com/ycwl/basic/controller/pc/DeviceV2Controller.java index d97ecf76..f90679af 100644 --- a/src/main/java/com/ycwl/basic/controller/pc/DeviceV2Controller.java +++ b/src/main/java/com/ycwl/basic/controller/pc/DeviceV2Controller.java @@ -3,8 +3,10 @@ package com.ycwl.basic.controller.pc; import com.ycwl.basic.integration.device.dto.config.*; import com.ycwl.basic.integration.common.response.PageResponse; import com.ycwl.basic.integration.device.dto.device.*; +import com.ycwl.basic.integration.device.dto.status.DeviceStatusDTO; import com.ycwl.basic.integration.device.service.DeviceConfigIntegrationService; import com.ycwl.basic.integration.device.service.DeviceIntegrationService; +import com.ycwl.basic.integration.device.service.DeviceStatusIntegrationService; import com.ycwl.basic.utils.ApiResponse; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -29,6 +31,7 @@ public class DeviceV2Controller { private final DeviceIntegrationService deviceIntegrationService; private final DeviceConfigIntegrationService deviceConfigIntegrationService; + private final DeviceStatusIntegrationService deviceStatusIntegrationService; // ========== 设备基础 CRUD 操作 ========== @@ -144,6 +147,28 @@ public class DeviceV2Controller { } } + /** + * 根据设备ID获取设备在线状态 + */ + @GetMapping("/{id}/status") + public ApiResponse getDeviceOnlineStatus(@PathVariable Long id) { + log.info("获取设备在线状态, deviceId: {}", id); + try { + // 首先获取设备信息以获得设备编号 + DeviceV2DTO device = deviceIntegrationService.getDevice(id); + if (device == null) { + return ApiResponse.fail("设备不存在"); + } + + // 使用设备编号查询在线状态 + DeviceStatusDTO onlineStatus = deviceStatusIntegrationService.getDeviceStatus(device.getNo()); + return ApiResponse.success(onlineStatus); + } catch (Exception e) { + log.error("获取设备在线状态失败, deviceId: {}", id, e); + return ApiResponse.fail("获取设备在线状态失败: " + e.getMessage()); + } + } + /** * 创建设备 */ diff --git a/src/main/java/com/ycwl/basic/integration/device/dto/status/DeviceStatusDTO.java b/src/main/java/com/ycwl/basic/integration/device/dto/status/DeviceStatusDTO.java index 26807ab9..981f0a0a 100644 --- a/src/main/java/com/ycwl/basic/integration/device/dto/status/DeviceStatusDTO.java +++ b/src/main/java/com/ycwl/basic/integration/device/dto/status/DeviceStatusDTO.java @@ -6,6 +6,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import java.time.LocalDateTime; +import java.util.Date; /** * 设备状态信息 @@ -28,8 +29,8 @@ public class DeviceStatusDTO { /** * 最后活动时间 */ - @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'") - private LocalDateTime lastActiveTime; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date lastActiveTime; /** * 最后动作(register/keepalive/unregister) @@ -44,6 +45,6 @@ public class DeviceStatusDTO { /** * 状态更新时间 */ - @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'") - private LocalDateTime updateTime; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; } \ No newline at end of file diff --git a/src/main/java/com/ycwl/basic/repository/DeviceRepository.java b/src/main/java/com/ycwl/basic/repository/DeviceRepository.java index 8b6f3b5b..e18890bd 100644 --- a/src/main/java/com/ycwl/basic/repository/DeviceRepository.java +++ b/src/main/java/com/ycwl/basic/repository/DeviceRepository.java @@ -7,7 +7,9 @@ import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity; import com.ycwl.basic.model.pc.device.entity.DeviceEntity; import com.ycwl.basic.utils.SnowFlakeUtil; import com.ycwl.basic.integration.device.service.DeviceIntegrationService; +import com.ycwl.basic.integration.device.service.DeviceStatusIntegrationService; import com.ycwl.basic.integration.device.dto.device.DeviceV2DTO; +import com.ycwl.basic.integration.device.dto.status.DeviceStatusDTO; import com.ycwl.basic.integration.common.manager.DeviceConfigManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; @@ -33,6 +35,8 @@ public class DeviceRepository { public static final String DEVICE_CACHE_KEY = "device:%s"; @Autowired private DeviceConfigIntegrationService deviceConfigIntegrationService; + @Autowired + private DeviceStatusIntegrationService deviceStatusIntegrationService; /** * 将DeviceV2DTO转换为DeviceEntity @@ -57,6 +61,30 @@ public class DeviceRepository { return entity; } + /** + * 将DeviceV2DTO和DeviceStatusDTO合并转换为DeviceEntity + */ + private DeviceEntity convertToEntityWithStatus(DeviceV2DTO deviceDto, DeviceStatusDTO statusDto) { + if (deviceDto == null) { + return null; + } + + DeviceEntity entity = convertToEntity(deviceDto); + + // 合并状态信息 + if (statusDto != null) { + // Boolean转Integer: true→1, false→0 + entity.setOnline(statusDto.getIsOnline() != null && statusDto.getIsOnline() ? 1 : 0); + entity.setKeepaliveAt(statusDto.getLastActiveTime()); + entity.setIpAddr(statusDto.getClientIP()); + } else { + // 默认离线状态 + entity.setOnline(0); + } + + return entity; + } + public DeviceEntity getDevice(Long deviceId) { log.debug("获取设备信息, deviceId: {}", deviceId); DeviceV2DTO deviceDto = deviceIntegrationService.getDevice(deviceId); @@ -144,10 +172,31 @@ public class DeviceRepository { } public DeviceEntity getOnlineStatus(Long deviceId) { - if (redisTemplate.hasKey(String.format(DEVICE_ONLINE_CACHE_KEY, deviceId))) { - return JacksonUtil.parseObject(redisTemplate.opsForValue().get(String.format(DEVICE_ONLINE_CACHE_KEY, deviceId)), DeviceEntity.class); - } else { - return null; + log.debug("获取设备在线状态, deviceId: {}", deviceId); + try { + // 首先获取设备基本信息 + DeviceV2DTO deviceDto = deviceIntegrationService.getDevice(deviceId); + if (deviceDto == null) { + log.warn("设备不存在, deviceId: {}", deviceId); + return null; + } + + // 通过设备编号获取设备状态 + DeviceStatusDTO statusDto = deviceStatusIntegrationService.getDeviceStatus(deviceDto.getNo()); + + // 合并设备信息和状态信息 + return convertToEntityWithStatus(deviceDto, statusDto); + + } catch (Exception e) { + log.error("获取设备在线状态异常, deviceId: {}", deviceId, e); + // 降级处理:尝试仅返回设备基本信息 + try { + DeviceV2DTO deviceDto = deviceIntegrationService.getDevice(deviceId); + return convertToEntityWithStatus(deviceDto, null); + } catch (Exception fallbackException) { + log.error("降级获取设备信息也失败, deviceId: {}", deviceId, fallbackException); + return null; + } } }