You've already forked FrameTour-BE
feat(device): 新增设备状态管理集成服务
- 添加设备状态客户端接口,支持设备在线状态查询与设置 - 创建设备状态相关 DTO,包括设备状态、在线状态和状态动作枚举 - 实现设备状态集成服务,封装设备状态操作与异常处理逻辑 - 支持单个及批量设备在线状态检查与设置功能 - 提供
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
package com.ycwl.basic.integration.device.client;
|
||||
|
||||
import com.ycwl.basic.integration.common.response.CommonResponse;
|
||||
import com.ycwl.basic.integration.device.dto.status.DeviceStatusDTO;
|
||||
import com.ycwl.basic.integration.device.dto.status.OnlineStatusResponseDTO;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@FeignClient(name = "zt-device", contextId = "deviceStatusClient", path = "/api/device/status")
|
||||
public interface DeviceStatusClient {
|
||||
|
||||
/**
|
||||
* 获取设备状态
|
||||
*/
|
||||
@GetMapping("/{deviceNo}")
|
||||
CommonResponse<DeviceStatusDTO> getDeviceStatus(@PathVariable("deviceNo") String deviceNo);
|
||||
|
||||
/**
|
||||
* 检查设备是否在线
|
||||
*/
|
||||
@GetMapping("/{deviceNo}/online")
|
||||
CommonResponse<OnlineStatusResponseDTO> isDeviceOnline(@PathVariable("deviceNo") String deviceNo);
|
||||
|
||||
/**
|
||||
* 获取所有在线设备
|
||||
*/
|
||||
@GetMapping("/online")
|
||||
CommonResponse<List<DeviceStatusDTO>> getAllOnlineDevices();
|
||||
|
||||
/**
|
||||
* 设置设备离线
|
||||
*/
|
||||
@PostMapping("/{deviceNo}/offline")
|
||||
CommonResponse<String> setDeviceOffline(@PathVariable("deviceNo") String deviceNo);
|
||||
|
||||
/**
|
||||
* 设置设备在线
|
||||
*/
|
||||
@PostMapping("/{deviceNo}/online")
|
||||
CommonResponse<String> setDeviceOnline(@PathVariable("deviceNo") String deviceNo);
|
||||
|
||||
/**
|
||||
* 清理过期设备状态
|
||||
*/
|
||||
@PostMapping("/clean")
|
||||
CommonResponse<String> cleanExpiredDevices();
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
package com.ycwl.basic.integration.device.dto.status;
|
||||
|
||||
/**
|
||||
* 设备状态动作枚举
|
||||
*/
|
||||
public enum DeviceStatusActionEnum {
|
||||
|
||||
/**
|
||||
* 设备注册
|
||||
*/
|
||||
REGISTER("register"),
|
||||
|
||||
/**
|
||||
* 设备保活
|
||||
*/
|
||||
KEEPALIVE("keepalive"),
|
||||
|
||||
/**
|
||||
* 设备注销
|
||||
*/
|
||||
UNREGISTER("unregister");
|
||||
|
||||
private final String action;
|
||||
|
||||
DeviceStatusActionEnum(String action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public static DeviceStatusActionEnum fromString(String action) {
|
||||
for (DeviceStatusActionEnum statusAction : values()) {
|
||||
if (statusAction.action.equalsIgnoreCase(action)) {
|
||||
return statusAction;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown device status action: " + action);
|
||||
}
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
package com.ycwl.basic.integration.device.dto.status;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 设备状态信息
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class DeviceStatusDTO {
|
||||
|
||||
/**
|
||||
* 设备编号
|
||||
*/
|
||||
private String deviceNo;
|
||||
|
||||
/**
|
||||
* 是否在线
|
||||
*/
|
||||
private Boolean isOnline;
|
||||
|
||||
/**
|
||||
* 最后活动时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'")
|
||||
private LocalDateTime lastActiveTime;
|
||||
|
||||
/**
|
||||
* 最后动作(register/keepalive/unregister)
|
||||
*/
|
||||
private String lastAction;
|
||||
|
||||
/**
|
||||
* 客户端IP
|
||||
*/
|
||||
private String clientIP;
|
||||
|
||||
/**
|
||||
* 状态更新时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'")
|
||||
private LocalDateTime updateTime;
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
package com.ycwl.basic.integration.device.dto.status;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 在线状态响应
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class OnlineStatusResponseDTO {
|
||||
|
||||
/**
|
||||
* 设备编号
|
||||
*/
|
||||
private String deviceNo;
|
||||
|
||||
/**
|
||||
* 是否在线
|
||||
*/
|
||||
private Boolean isOnline;
|
||||
}
|
@@ -0,0 +1,211 @@
|
||||
package com.ycwl.basic.integration.device.service;
|
||||
|
||||
import com.ycwl.basic.integration.common.exception.IntegrationException;
|
||||
import com.ycwl.basic.integration.common.response.CommonResponse;
|
||||
import com.ycwl.basic.integration.common.service.IntegrationFallbackService;
|
||||
import com.ycwl.basic.integration.device.client.DeviceStatusClient;
|
||||
import com.ycwl.basic.integration.device.dto.status.DeviceStatusDTO;
|
||||
import com.ycwl.basic.integration.device.dto.status.OnlineStatusResponseDTO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class DeviceStatusIntegrationService {
|
||||
|
||||
private final DeviceStatusClient deviceStatusClient;
|
||||
private final IntegrationFallbackService fallbackService;
|
||||
|
||||
private static final String SERVICE_NAME = "zt-device";
|
||||
|
||||
public DeviceStatusDTO getDeviceStatus(String deviceNo) {
|
||||
log.debug("获取设备状态, deviceNo: {}", deviceNo);
|
||||
return fallbackService.executeWithFallback(
|
||||
SERVICE_NAME,
|
||||
"device:status:" + deviceNo,
|
||||
() -> {
|
||||
CommonResponse<DeviceStatusDTO> response = deviceStatusClient.getDeviceStatus(deviceNo);
|
||||
return handleResponse(response, "获取设备状态失败");
|
||||
},
|
||||
DeviceStatusDTO.class
|
||||
);
|
||||
}
|
||||
|
||||
public OnlineStatusResponseDTO isDeviceOnline(String deviceNo) {
|
||||
log.debug("检查设备是否在线, deviceNo: {}", deviceNo);
|
||||
return fallbackService.executeWithFallback(
|
||||
SERVICE_NAME,
|
||||
"device:online:" + deviceNo,
|
||||
() -> {
|
||||
CommonResponse<OnlineStatusResponseDTO> response = deviceStatusClient.isDeviceOnline(deviceNo);
|
||||
return handleResponse(response, "检查设备在线状态失败");
|
||||
},
|
||||
OnlineStatusResponseDTO.class
|
||||
);
|
||||
}
|
||||
|
||||
public List<DeviceStatusDTO> getAllOnlineDevices() {
|
||||
log.debug("获取所有在线设备");
|
||||
return fallbackService.executeWithFallback(
|
||||
SERVICE_NAME,
|
||||
"devices:online:all",
|
||||
() -> {
|
||||
CommonResponse<List<DeviceStatusDTO>> response = deviceStatusClient.getAllOnlineDevices();
|
||||
return handleResponse(response, "获取所有在线设备失败");
|
||||
},
|
||||
List.class
|
||||
);
|
||||
}
|
||||
|
||||
public void setDeviceOffline(String deviceNo) {
|
||||
log.debug("设置设备离线, deviceNo: {}", deviceNo);
|
||||
CommonResponse<String> response = deviceStatusClient.setDeviceOffline(deviceNo);
|
||||
handleResponse(response, "设置设备离线失败");
|
||||
}
|
||||
|
||||
public void setDeviceOnline(String deviceNo) {
|
||||
log.debug("设置设备在线, deviceNo: {}", deviceNo);
|
||||
CommonResponse<String> response = deviceStatusClient.setDeviceOnline(deviceNo);
|
||||
handleResponse(response, "设置设备在线失败");
|
||||
}
|
||||
|
||||
public void cleanExpiredDevices() {
|
||||
log.debug("清理过期设备状态");
|
||||
CommonResponse<String> response = deviceStatusClient.cleanExpiredDevices();
|
||||
handleResponse(response, "清理过期设备状态失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全地获取设备状态
|
||||
*/
|
||||
public Optional<DeviceStatusDTO> getDeviceStatusSafely(String deviceNo) {
|
||||
try {
|
||||
DeviceStatusDTO status = getDeviceStatus(deviceNo);
|
||||
return Optional.ofNullable(status);
|
||||
} catch (Exception e) {
|
||||
log.warn("获取设备状态异常: deviceNo={}, error={}", deviceNo, e.getMessage());
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全地检查设备是否在线
|
||||
*/
|
||||
public boolean isDeviceOnlineSafely(String deviceNo) {
|
||||
try {
|
||||
OnlineStatusResponseDTO response = isDeviceOnline(deviceNo);
|
||||
return response != null && Boolean.TRUE.equals(response.getIsOnline());
|
||||
} catch (Exception e) {
|
||||
log.warn("检查设备在线状态异常: deviceNo={}, error={}", deviceNo, e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量检查设备是否在线
|
||||
*/
|
||||
public boolean areAllDevicesOnline(List<String> deviceNos) {
|
||||
if (deviceNos == null || deviceNos.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
log.debug("批量检查设备在线状态, deviceNos: {}", deviceNos);
|
||||
for (String deviceNo : deviceNos) {
|
||||
if (!isDeviceOnlineSafely(deviceNo)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量设置设备离线
|
||||
*/
|
||||
public void setDevicesOffline(List<String> deviceNos) {
|
||||
if (deviceNos == null || deviceNos.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug("批量设置设备离线, deviceNos: {}", deviceNos);
|
||||
for (String deviceNo : deviceNos) {
|
||||
try {
|
||||
setDeviceOffline(deviceNo);
|
||||
} catch (Exception e) {
|
||||
log.error("设置设备离线失败: deviceNo={}, error={}", deviceNo, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量设置设备在线
|
||||
*/
|
||||
public void setDevicesOnline(List<String> deviceNos) {
|
||||
if (deviceNos == null || deviceNos.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug("批量设置设备在线, deviceNos: {}", deviceNos);
|
||||
for (String deviceNo : deviceNos) {
|
||||
try {
|
||||
setDeviceOnline(deviceNo);
|
||||
} catch (Exception e) {
|
||||
log.error("设置设备在线失败: deviceNo={}, error={}", deviceNo, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取在线设备数量
|
||||
*/
|
||||
public int getOnlineDeviceCount() {
|
||||
try {
|
||||
List<DeviceStatusDTO> onlineDevices = getAllOnlineDevices();
|
||||
return onlineDevices != null ? onlineDevices.size() : 0;
|
||||
} catch (Exception e) {
|
||||
log.warn("获取在线设备数量失败: {}", e.getMessage());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定设备编号列表中的在线设备
|
||||
*/
|
||||
public List<String> getOnlineDeviceNos(List<String> deviceNos) {
|
||||
if (deviceNos == null || deviceNos.isEmpty()) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
return deviceNos.stream()
|
||||
.filter(this::isDeviceOnlineSafely)
|
||||
.toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定设备编号列表中的离线设备
|
||||
*/
|
||||
public List<String> getOfflineDeviceNos(List<String> deviceNos) {
|
||||
if (deviceNos == null || deviceNos.isEmpty()) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
return deviceNos.stream()
|
||||
.filter(deviceNo -> !isDeviceOnlineSafely(deviceNo))
|
||||
.toList();
|
||||
}
|
||||
|
||||
private <T> T handleResponse(CommonResponse<T> response, String errorMessage) {
|
||||
if (response == null || !response.isSuccess()) {
|
||||
String msg = response != null && response.getMessage() != null
|
||||
? response.getMessage()
|
||||
: errorMessage;
|
||||
Integer code = response != null ? response.getCode() : 5000;
|
||||
throw new IntegrationException(code, msg, SERVICE_NAME);
|
||||
}
|
||||
return response.getData();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user