package com.gaotao.modules.dashboard.task;
import com.beust.ah.A;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gaotao.common.utils.HttpUtils;
import com.gaotao.modules.automatedWarehouse.entity.tusk.AgvStatus;
import com.gaotao.modules.automatedWarehouse.entity.tusk.TuskResponse;
import com.gaotao.modules.automatedWarehouse.service.TuskClientService;
import com.gaotao.modules.dashboard.service.DashboardWebSocketService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.*;
/**
* 看板数据推送定时任务
*
*
功能说明:
*
* - 定时从WCS Board API获取最新数据
* - 检测到数据变更后通过WebSocket推送到前端
* - 相比轮询,只在数据变更时推送,减少无效传输
*
*
* 推送策略:
*
* - 每5秒检查一次机械臂拣选数据
* - 数据有变化时立即推送
* - 推送失败时记录日志,不影响下次推送
*
*
* @author System
* @since 2025-01-23
*/
@Slf4j
@Component
public class DashboardPushTask {
@Autowired
private DashboardWebSocketService webSocketService;
@Value("${custom.wcs-board-api}")
private String wcsBoardApi;
// 看板推送任务开关配置(所有看板共用一个开关)
@Value("${dashboard.push.enabled:true}")
private boolean dashboardPushEnabled;
/**
* 上次推送的数据哈希值(用于检测数据变更)
*/
private Map lastDataHash = new HashMap<>();
@Autowired
private com.gaotao.modules.dashboard.dao.DashboardDao dashboardDao;
@Autowired(required = false)
private TuskClientService tuskClientService;
/**
* 每5秒检查机械臂拣选数据并推送
*
* 注意:这个间隔可以根据实际需求调整
*
* - 如果数据变化频繁,可以缩短间隔(如2-3秒)
* - 如果数据变化不频繁,可以延长间隔(如10-15秒)
*
*
* 配置开关:
*
* - dashboard.push.enabled - 看板推送总开关
*
*/
@Scheduled(fixedRate = 5000)
public void pushRobotPickingData() {
// 检查总开关
if (!dashboardPushEnabled) {
log.trace("看板推送已禁用");
return;
}
try {
// 从WCS Board API获取机械臂拣选数据
Map data = getRobotPickingDataFromWcs();
// 如果返回null,转换为空数据(避免前端显示过期数据)
if (data == null) {
data = createEmptyData();
}
// 计算数据哈希值
int currentHash = data.hashCode();
webSocketService.pushRobotPickingData(data);
lastDataHash.put("robot-picking", currentHash);
} catch (Exception e) {
log.error("推送机械臂拣选数据失败,推送空数据清空前端列表: {}", e.getMessage(), e);
// 异常时推送空数据,避免前端显示过期数据
try {
Map emptyData = createEmptyData();
webSocketService.pushRobotPickingData(emptyData);
lastDataHash.put("robot-picking", emptyData.hashCode());
} catch (Exception ex) {
log.error("推送空数据失败: {}", ex.getMessage());
}
}
}
/**
* 从WCS Board API获取机械臂拣选数据
*
* @return 机械臂拣选数据
*/
private Map getRobotPickingDataFromWcs() {
try {
// 调用WCS Board API
String url = wcsBoardApi + "WmsDashboard/auto-sorting-info";
String wcsResponse = HttpUtils.doGet(url, null, null);
// 解析JSON数据
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readTree(wcsResponse);
// 检查返回码
int resCode = rootNode.get("resCode").asInt();
if (resCode != 200) {
log.warn("WCS API返回错误: code={}", resCode);
return null;
}
// 获取sortingStations数组
JsonNode resData = rootNode.get("resData");
if (resData == null || !resData.has("sortingStations")) {
log.warn("WCS返回数据中没有sortingStations");
return createEmptyData();
}
JsonNode sortingStations = resData.get("sortingStations");
// 按照sortingStation分类处理数据
List