Browse Source

手工拣选看板

master
han\hanst 2 months ago
parent
commit
dc8f662267
  1. 188
      src/main/java/com/gaotao/modules/dashboard/task/DashboardPushTask.java

188
src/main/java/com/gaotao/modules/dashboard/task/DashboardPushTask.java

@ -61,6 +61,194 @@ public class DashboardPushTask {
@Autowired(required = false) @Autowired(required = false)
private TuskClientService tuskClientService; private TuskClientService tuskClientService;
@Value("${custom.wcs-url}")
private String wcsUrl;
/**
* 每10秒检查人工拣选数据并推送
*
* <p><b>数据来源</b>WCS系统 - /api/wms/query-auto-sorting-info</p>
*
* <p><b>数据说明</b></p>
* <ul>
* <li>sortingStation=1043 - 第一个表格人工拣选1</li>
* <li>sortingStation=1028 - 第二个表格人工拣选2</li>
* </ul>
*
* <p><b>配置开关</b></p>
* <ul>
* <li>dashboard.push.enabled - 看板推送总开关</li>
* </ul>
*/
@Scheduled(fixedRate = 10000)
public void pushManualPickingData() {
// 检查总开关
if (!dashboardPushEnabled) {
log.trace("看板推送已禁用");
return;
}
try {
log.debug("=== 开始获取人工拣选看板数据 ===");
// 从WCS获取人工拣选数据
Map<String, Object> data = getManualPickingDataFromWcs();
// 如果返回null转换为空数据
if (data == null) {
data = createEmptyManualPickingData();
}
// 计算数据哈希值并推送
int currentHash = data.hashCode();
webSocketService.pushManualPickingData(data);
lastDataHash.put("manual-picking", currentHash);
log.debug("=== 人工拣选数据推送完成 ===");
} catch (Exception e) {
log.error("推送人工拣选数据失败,推送空数据清空前端列表: {}", e.getMessage(), e);
// 异常时推送空数据避免前端显示过期数据
try {
Map<String, Object> emptyData = createEmptyManualPickingData();
webSocketService.pushManualPickingData(emptyData);
lastDataHash.put("manual-picking", emptyData.hashCode());
} catch (Exception ex) {
log.error("推送空数据失败: {}", ex.getMessage());
}
}
}
/**
* 从WCS获取人工拣选数据
*
* @return 人工拣选数据
*/
private Map<String, Object> getManualPickingDataFromWcs() {
try {
String url = wcsUrl + "query-auto-sorting-info";
ObjectMapper mapper = new ObjectMapper();
// 请求1043站数据
log.info("调用WCS人工拣选API (1043站): {}", url);
List<Map<String, Object>> station1043List = getStationData(url, "1043", mapper);
log.info("1043站数据获取完成: {}条", station1043List.size());
// 请求1028站数据
log.info("调用WCS人工拣选API (1028站): {}", url);
List<Map<String, Object>> station1028List = getStationData(url, "1028", mapper);
log.info("1028站数据获取完成: {}条", station1028List.size());
// 构造返回数据
Map<String, Object> resultData = new HashMap<>();
resultData.put("station1043List", station1043List);
resultData.put("station1028List", station1028List);
log.info("=== 人工拣选数据处理完成 === 1043站:{}条, 1028站:{}条",
station1043List.size(), station1028List.size());
return resultData;
} catch (Exception e) {
log.error("从WCS获取人工拣选数据失败: {}", e.getMessage(), e);
return null;
}
}
/**
* 获取指定工作站的数据
*
* @param url WCS API地址
* @param devCode 设备编码工作站号
* @param mapper JSON解析器
* @return 工作站数据列表
*/
private List<Map<String, Object>> getStationData(String url, String devCode, ObjectMapper mapper) {
List<Map<String, Object>> stationList = new ArrayList<>();
try {
// 构造POST请求参数 - 直接传devCode字符串
String jsonBody = "\"" + devCode + "\"";
String wcsResponse = HttpUtils.doPost(url, jsonBody, null);
log.debug("WCS API返回数据 ({}站): {}", devCode, wcsResponse);
// 解析JSON数据
JsonNode rootNode = mapper.readTree(wcsResponse);
// 获取sortingStations数组
if (!rootNode.has("sortingStations")) {
log.warn("WCS返回数据中没有sortingStations ({}站)", devCode);
return stationList;
}
JsonNode sortingStations = rootNode.get("sortingStations");
// 处理返回的数据
for (JsonNode station : sortingStations) {
String sortingStation = station.get("sortingStation").asText();
JsonNode materials = station.get("materials");
// 只处理匹配的工作站数据
if (devCode.equals(sortingStation) && materials != null && materials.isArray()) {
for (JsonNode material : materials) {
Map<String, Object> item = convertWcsMaterialToPickingItem(material);
stationList.add(item);
}
}
}
} catch (Exception e) {
log.error("获取{}站数据失败: {}", devCode, e.getMessage(), e);
}
return stationList;
}
/**
* 将WCS返回的material数据转换为人工拣选前端需要的格式
*
* @param material WCS返回的物料数据
* @return 前端表格数据格式
*/
private Map<String, Object> convertWcsMaterialToPickingItem(JsonNode material) {
Map<String, Object> item = new HashMap<>();
// 拣选托盘码 (源托盘)
item.put("pickingBatchNo", material.has("sourcePalletCode") ?
material.get("sourcePalletCode").asText() : "");
// 拣选物料名称 (SKU)
item.put("pickingMaterialName", material.has("sku") ?
material.get("sku").asText() : "");
// RFID条码
item.put("rfidBarcode", material.has("rfidBarcode") ?
material.get("rfidBarcode").asText() : "");
// 状态 (根据isCompleted判断)
boolean isCompleted = material.has("isCompleted") && material.get("isCompleted").asBoolean();
item.put("status", isCompleted ? "完成" : "等待分拣");
// 存放位置 (工作站编号)
item.put("storageLocation", material.has("sortingStation") ?
material.get("sortingStation").asText() : "");
return item;
}
/**
* 创建空的人工拣选数据
*
* @return 空的人工拣选数据结构
*/
private Map<String, Object> createEmptyManualPickingData() {
Map<String, Object> emptyData = new HashMap<>();
emptyData.put("station1043List", new ArrayList<>());
emptyData.put("station1028List", new ArrayList<>());
return emptyData;
}
/** /**
* 每5秒检查机械臂拣选数据并推送 * 每5秒检查机械臂拣选数据并推送
* *

Loading…
Cancel
Save