package com.ruoyi.device.websocket; import com.alibaba.fastjson2.JSON; import com.ruoyi.device.api.domain.StatisticsVO; import com.ruoyi.device.service.api.IBufferDeviceService; import com.ruoyi.device.service.api.IAircraftService; import com.ruoyi.device.service.api.IDockService; import com.ruoyi.device.service.api.IPayloadService; import com.ruoyi.device.service.dto.AircraftDTO; import com.ruoyi.device.service.dto.AircraftDetailDTO; import com.ruoyi.device.service.dto.DockDTO; import com.ruoyi.device.service.dto.DockDetailDTO; import com.ruoyi.device.service.dto.PayloadDTO; import com.ruoyi.device.api.enums.AircraftStatusEnum; import com.ruoyi.device.api.enums.DockStatusEnum; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import jakarta.websocket.*; import jakarta.websocket.server.PathParam; import jakarta.websocket.server.ServerEndpoint; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; import java.util.stream.Collectors; @Component @ServerEndpoint("/websocket/statistics/{type}") public class StatisticsWebSocket { private static final Logger log = LoggerFactory.getLogger(StatisticsWebSocket.class); private static IBufferDeviceService bufferDeviceService; private static IAircraftService aircraftService; private static IDockService dockService; private static IPayloadService payloadService; private Session session; private static final Map> sessions = new ConcurrentHashMap<>(); @Autowired public void setBufferDeviceService(IBufferDeviceService bufferDeviceService) { StatisticsWebSocket.bufferDeviceService = bufferDeviceService; } @Autowired public void setAircraftService(IAircraftService aircraftService) { StatisticsWebSocket.aircraftService = aircraftService; } @Autowired public void setDockService(IDockService dockService) { StatisticsWebSocket.dockService = dockService; } @Autowired public void setPayloadService(IPayloadService payloadService) { StatisticsWebSocket.payloadService = payloadService; } @OnOpen public void onOpen(Session session, @PathParam("type") String type) { this.session = session; sessions.computeIfAbsent(type, k -> new CopyOnWriteArraySet<>()).add(this); log.info("WebSocket连接建立: sessionId={}, type={}", session.getId(), type); sendCurrentStatistics(type); } @OnClose public void onClose(@PathParam("type") String type) { CopyOnWriteArraySet typeSessions = sessions.get(type); if (typeSessions != null) { typeSessions.remove(this); if (typeSessions.isEmpty()) { sessions.remove(type); } } log.info("WebSocket连接关闭: sessionId={}, type={}", session.getId(), type); } @OnMessage public void onMessage(String message, @PathParam("type") String type) { log.info("收到WebSocket消息: sessionId={}, type={}, message={}", session.getId(), type, message); if ("refresh".equals(message)) { sendCurrentStatistics(type); } } @OnError public void onError(Session session, Throwable error, @PathParam("type") String type) { log.error("WebSocket错误: sessionId={}, type={}, error={}", session.getId(), type, error.getMessage(), error); } private void sendCurrentStatistics(String type) { try { StatisticsVO statistics = buildStatistics(type); sendMessage(JSON.toJSONString(statistics)); } catch (Exception e) { log.error("发送统计数据失败: type={}, error={}", type, e.getMessage(), e); } } private StatisticsVO buildStatistics(String type) { if ("th".equals(type)) { return buildThStatistics(); } else { return buildDjiStatistics(); } } private StatisticsVO buildDjiStatistics() { StatisticsVO vo = new StatisticsVO(); List docks = dockService.selectDockList(new DockDTO()); vo.setDockCount(docks != null ? docks.size() : 0); Map dockDetailsMap = null; if (docks != null && !docks.isEmpty()) { List dockIds = docks.stream() .map(DockDTO::getDockId) .collect(Collectors.toList()); dockDetailsMap = bufferDeviceService.getDockDetailsByIds(dockIds); } int idleCount = 0; int workingCount = 0; int debuggingCount = 0; int offlineCount = 0; if (docks != null && dockDetailsMap != null) { for (DockDTO dock : docks) { DockDetailDTO dockDetail = dockDetailsMap.get(dock.getDockId()); if (dockDetail != null && dockDetail.getDockStatus() != null) { String status = dockDetail.getDockStatus(); if (DockStatusEnum.IDLE.getCode().equals(status)) { idleCount++; } else if (DockStatusEnum.WORKING.getCode().equals(status)) { workingCount++; } else if (DockStatusEnum.Debugging.getCode().equals(status)) { debuggingCount++; } else { offlineCount++; } } } } vo.setIdleDockCount(idleCount); vo.setWorkingDockCount(workingCount); vo.setDebuggingDockCount(debuggingCount); vo.setOfflineDockCount(offlineCount); List aircrafts = aircraftService.selectAircraftList(new AircraftDTO()); vo.setAircraftCount(aircrafts != null ? aircrafts.size() : 0); Map aircraftDetailsMap = null; if (aircrafts != null && !aircrafts.isEmpty()) { List aircraftIds = aircrafts.stream() .map(AircraftDTO::getAircraftId) .collect(Collectors.toList()); aircraftDetailsMap = bufferDeviceService.getAircraftDetailsByIds(aircraftIds); } int powerOnInCabinCount = 0; int powerOffInCabinCount = 0; int inMissionCount = 0; int debuggingAircraftCount = 0; int offlineAircraftCount = 0; if (aircrafts != null && aircraftDetailsMap != null) { for (AircraftDTO aircraft : aircrafts) { AircraftDetailDTO aircraftDetail = aircraftDetailsMap.get(aircraft.getAircraftId()); if (aircraftDetail != null && aircraftDetail.getAircraftStatus() != null) { String status = aircraftDetail.getAircraftStatus(); if (AircraftStatusEnum.POWER_ON_IN_CABIN.getCode().equals(status)) { powerOnInCabinCount++; } else if (AircraftStatusEnum.POWER_OFF_IN_CABIN.getCode().equals(status)) { powerOffInCabinCount++; } else if (AircraftStatusEnum.IN_MISSION.getCode().equals(status)) { inMissionCount++; } else if (AircraftStatusEnum.DEBUGGING.getCode().equals(status)) { debuggingAircraftCount++; } else if (AircraftStatusEnum.OFFLINE.getCode().equals(status)) { offlineAircraftCount++; } else { offlineAircraftCount++; } } } } vo.setPowerOnInCabinCount(powerOnInCabinCount); vo.setPowerOffInCabinCount(powerOffInCabinCount); vo.setInMissionCount(inMissionCount); vo.setDebuggingAircraftCount(debuggingAircraftCount); vo.setOfflineAircraftCount(offlineAircraftCount); List payloads = payloadService.selectPayloadList(new PayloadDTO()); vo.setPayloadCount(payloads != null ? payloads.size() : 0); vo.setOfflinePayloadCount(0); return vo; } private StatisticsVO buildThStatistics() { StatisticsVO vo = new StatisticsVO(); vo.setDockCount(0); vo.setIdleDockCount(0); vo.setWorkingDockCount(0); vo.setDebuggingDockCount(0); vo.setOfflineDockCount(0); vo.setAircraftCount(0); vo.setPowerOnInCabinCount(0); vo.setPowerOffInCabinCount(0); vo.setInMissionCount(0); vo.setDebuggingAircraftCount(0); vo.setOfflineAircraftCount(0); vo.setPayloadCount(0); vo.setOfflinePayloadCount(0); return vo; } private void sendMessage(String message) { try { if (session != null && session.isOpen()) { session.getBasicRemote().sendText(message); } } catch (Exception e) { log.error("发送WebSocket消息失败: error={}", e.getMessage(), e); } } public static void broadcastToType(String type, String message) { CopyOnWriteArraySet typeSessions = sessions.get(type); if (typeSessions != null) { for (StatisticsWebSocket ws : typeSessions) { ws.sendMessage(message); } } } public static void broadcastDjiStatistics() { StatisticsVO statistics = new StatisticsWebSocket().buildDjiStatistics(); broadcastToType("dji", JSON.toJSONString(statistics)); } public static void broadcastThStatistics() { StatisticsVO statistics = new StatisticsWebSocket().buildThStatistics(); broadcastToType("th", JSON.toJSONString(statistics)); } }