You've already forked FrameTour-BE
feat(device): 添加设备在线状态查询功能- 在DeviceV2Controller中新增getDeviceOnlineStatus接口,用于根据设备ID查询设备在线状态
All checks were successful
ZhenTu-BE/pipeline/head This commit looks good
All checks were successful
ZhenTu-BE/pipeline/head This commit looks good
- 引入DeviceStatusDTO和DeviceStatusIntegrationService以支持设备状态查询- 修改DeviceStatusDTO中的时间字段类型为Date,并调整JSON序列化格式- 在DeviceRepository中增加convertToEntityWithStatus方法,用于合并设备信息与状态信息 - 优化DeviceRepository中的getOnlineStatus方法,增加异常处理和降级机制- 完善设备在线状态查询的日志记录和错误处理逻辑
This commit is contained in:
@@ -3,8 +3,10 @@ package com.ycwl.basic.controller.pc;
|
|||||||
import com.ycwl.basic.integration.device.dto.config.*;
|
import com.ycwl.basic.integration.device.dto.config.*;
|
||||||
import com.ycwl.basic.integration.common.response.PageResponse;
|
import com.ycwl.basic.integration.common.response.PageResponse;
|
||||||
import com.ycwl.basic.integration.device.dto.device.*;
|
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.DeviceConfigIntegrationService;
|
||||||
import com.ycwl.basic.integration.device.service.DeviceIntegrationService;
|
import com.ycwl.basic.integration.device.service.DeviceIntegrationService;
|
||||||
|
import com.ycwl.basic.integration.device.service.DeviceStatusIntegrationService;
|
||||||
import com.ycwl.basic.utils.ApiResponse;
|
import com.ycwl.basic.utils.ApiResponse;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@@ -29,6 +31,7 @@ public class DeviceV2Controller {
|
|||||||
|
|
||||||
private final DeviceIntegrationService deviceIntegrationService;
|
private final DeviceIntegrationService deviceIntegrationService;
|
||||||
private final DeviceConfigIntegrationService deviceConfigIntegrationService;
|
private final DeviceConfigIntegrationService deviceConfigIntegrationService;
|
||||||
|
private final DeviceStatusIntegrationService deviceStatusIntegrationService;
|
||||||
|
|
||||||
// ========== 设备基础 CRUD 操作 ==========
|
// ========== 设备基础 CRUD 操作 ==========
|
||||||
|
|
||||||
@@ -144,6 +147,28 @@ public class DeviceV2Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据设备ID获取设备在线状态
|
||||||
|
*/
|
||||||
|
@GetMapping("/{id}/status")
|
||||||
|
public ApiResponse<DeviceStatusDTO> 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建设备
|
* 创建设备
|
||||||
*/
|
*/
|
||||||
|
@@ -6,6 +6,7 @@ import lombok.Data;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
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'")
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
private LocalDateTime lastActiveTime;
|
private Date lastActiveTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 最后动作(register/keepalive/unregister)
|
* 最后动作(register/keepalive/unregister)
|
||||||
@@ -44,6 +45,6 @@ public class DeviceStatusDTO {
|
|||||||
/**
|
/**
|
||||||
* 状态更新时间
|
* 状态更新时间
|
||||||
*/
|
*/
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'")
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
private LocalDateTime updateTime;
|
private Date updateTime;
|
||||||
}
|
}
|
@@ -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.model.pc.device.entity.DeviceEntity;
|
||||||
import com.ycwl.basic.utils.SnowFlakeUtil;
|
import com.ycwl.basic.utils.SnowFlakeUtil;
|
||||||
import com.ycwl.basic.integration.device.service.DeviceIntegrationService;
|
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.device.DeviceV2DTO;
|
||||||
|
import com.ycwl.basic.integration.device.dto.status.DeviceStatusDTO;
|
||||||
import com.ycwl.basic.integration.common.manager.DeviceConfigManager;
|
import com.ycwl.basic.integration.common.manager.DeviceConfigManager;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
@@ -33,6 +35,8 @@ public class DeviceRepository {
|
|||||||
public static final String DEVICE_CACHE_KEY = "device:%s";
|
public static final String DEVICE_CACHE_KEY = "device:%s";
|
||||||
@Autowired
|
@Autowired
|
||||||
private DeviceConfigIntegrationService deviceConfigIntegrationService;
|
private DeviceConfigIntegrationService deviceConfigIntegrationService;
|
||||||
|
@Autowired
|
||||||
|
private DeviceStatusIntegrationService deviceStatusIntegrationService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将DeviceV2DTO转换为DeviceEntity
|
* 将DeviceV2DTO转换为DeviceEntity
|
||||||
@@ -57,6 +61,30 @@ public class DeviceRepository {
|
|||||||
return entity;
|
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) {
|
public DeviceEntity getDevice(Long deviceId) {
|
||||||
log.debug("获取设备信息, deviceId: {}", deviceId);
|
log.debug("获取设备信息, deviceId: {}", deviceId);
|
||||||
DeviceV2DTO deviceDto = deviceIntegrationService.getDevice(deviceId);
|
DeviceV2DTO deviceDto = deviceIntegrationService.getDevice(deviceId);
|
||||||
@@ -144,10 +172,31 @@ public class DeviceRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public DeviceEntity getOnlineStatus(Long deviceId) {
|
public DeviceEntity getOnlineStatus(Long deviceId) {
|
||||||
if (redisTemplate.hasKey(String.format(DEVICE_ONLINE_CACHE_KEY, deviceId))) {
|
log.debug("获取设备在线状态, deviceId: {}", deviceId);
|
||||||
return JacksonUtil.parseObject(redisTemplate.opsForValue().get(String.format(DEVICE_ONLINE_CACHE_KEY, deviceId)), DeviceEntity.class);
|
try {
|
||||||
} else {
|
// 首先获取设备基本信息
|
||||||
return null;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user