|
|
|
@ -1,16 +1,23 @@ |
|
|
|
package com.gaotao.modules.api.controller; |
|
|
|
|
|
|
|
import com.fasterxml.jackson.databind.JsonNode; |
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper; |
|
|
|
import com.gaotao.common.utils.HttpUtils; |
|
|
|
import com.gaotao.common.utils.R; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.springframework.beans.factory.annotation.Value; |
|
|
|
import org.springframework.web.bind.annotation.*; |
|
|
|
|
|
|
|
import java.util.Map; |
|
|
|
import java.util.*; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
@Slf4j |
|
|
|
@RestController |
|
|
|
@RequestMapping("/api/dashboard") |
|
|
|
public class DashboardController { |
|
|
|
|
|
|
|
@Value("${custom.wcs-board-api}") |
|
|
|
private String wcsBoardApi; |
|
|
|
/** |
|
|
|
* 人工拣选 |
|
|
|
*/ |
|
|
|
@ -36,29 +43,151 @@ public class DashboardController { |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 机械臂拣选 |
|
|
|
* 机械臂拣选看板数据获取 |
|
|
|
* |
|
|
|
* <p><b>功能说明:</b>从WCS系统获取机械臂自动分拣信息</p> |
|
|
|
* |
|
|
|
* <p><b>数据来源:</b>WCS Board API - WmsDashboard/auto-sorting-info</p> |
|
|
|
* |
|
|
|
* <p><b>返回数据说明:</b></p> |
|
|
|
* <ul> |
|
|
|
* <li><b>containerList</b>:周转箱拣选数据(sortingStation=1071)</li> |
|
|
|
* <li><b>materialList</b>:原材拣选数据(sortingStation=1060)</li> |
|
|
|
* </ul> |
|
|
|
* |
|
|
|
* @param data 请求参数 |
|
|
|
* @return 机械臂拣选数据 |
|
|
|
*/ |
|
|
|
@PostMapping("/robotPicking") |
|
|
|
@ResponseBody |
|
|
|
public R robotPicking(@RequestBody Map<String, Object> data) { |
|
|
|
try { |
|
|
|
log.info("机械臂拣选看板接口接收到请求:{}", data); |
|
|
|
String result = "SUCCESS"; |
|
|
|
if ("SUCCESS".equals(result)) { |
|
|
|
R r=new R(); |
|
|
|
r.put("code",200); |
|
|
|
r.put("msg","success"); |
|
|
|
r.put("data","机械臂拣选数据"); |
|
|
|
log.info("=== 开始获取机械臂拣选看板数据 ==="); |
|
|
|
|
|
|
|
// 1. 调用WCS Board API获取数据 |
|
|
|
String url = wcsBoardApi + "WmsDashboard/auto-sorting-info"; |
|
|
|
log.info("调用WCS API: {}", url); |
|
|
|
|
|
|
|
String wcsResponse = HttpUtils.doGet(url, null, null); |
|
|
|
log.info("WCS API返回数据: {}", wcsResponse); |
|
|
|
|
|
|
|
// 2. 解析返回的JSON数据 |
|
|
|
ObjectMapper mapper = new ObjectMapper(); |
|
|
|
JsonNode rootNode = mapper.readTree(wcsResponse); |
|
|
|
|
|
|
|
// 检查返回码 |
|
|
|
int resCode = rootNode.get("resCode").asInt(); |
|
|
|
String resMsg = rootNode.get("resMsg").asText(); |
|
|
|
|
|
|
|
if (resCode != 200) { |
|
|
|
log.error("WCS API返回错误: code={}, msg={}", resCode, resMsg); |
|
|
|
return R.error(500, "获取WCS数据失败: " + resMsg); |
|
|
|
} |
|
|
|
|
|
|
|
// 3. 获取sortingStations数组 |
|
|
|
JsonNode resData = rootNode.get("resData"); |
|
|
|
if (resData == null || !resData.has("sortingStations")) { |
|
|
|
log.warn("WCS返回数据中没有sortingStations"); |
|
|
|
R r = new R(); |
|
|
|
r.put("code", 200); |
|
|
|
r.put("msg", "success"); |
|
|
|
r.put("data", createEmptyData()); |
|
|
|
return r; |
|
|
|
} else { |
|
|
|
return R.error(500, result); |
|
|
|
} |
|
|
|
|
|
|
|
JsonNode sortingStations = resData.get("sortingStations"); |
|
|
|
|
|
|
|
// 4. 按照sortingStation分类处理数据 |
|
|
|
List<Map<String, Object>> containerList = new ArrayList<>(); // 1071-周转箱 |
|
|
|
List<Map<String, Object>> materialList = new ArrayList<>(); // 1060-原材 |
|
|
|
|
|
|
|
for (JsonNode station : sortingStations) { |
|
|
|
String sortingStation = station.get("sortingStation").asText(); |
|
|
|
JsonNode materials = station.get("materials"); |
|
|
|
|
|
|
|
if (materials != null && materials.isArray()) { |
|
|
|
for (JsonNode material : materials) { |
|
|
|
Map<String, Object> item = convertMaterialToItem(material, sortingStation); |
|
|
|
|
|
|
|
// 根据工作站分类 |
|
|
|
if ("1071".equals(sortingStation)) { |
|
|
|
containerList.add(item); |
|
|
|
} else if ("1060".equals(sortingStation)) { |
|
|
|
materialList.add(item); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 5. 构造返回数据 |
|
|
|
Map<String, Object> resultData = new HashMap<>(); |
|
|
|
resultData.put("containerList", containerList); |
|
|
|
resultData.put("materialList", materialList); |
|
|
|
|
|
|
|
log.info("=== 机械臂拣选数据处理完成 === 周转箱:{}条, 原材:{}条", |
|
|
|
containerList.size(), materialList.size()); |
|
|
|
|
|
|
|
R r = new R(); |
|
|
|
r.put("code", 200); |
|
|
|
r.put("msg", "success"); |
|
|
|
r.put("data", resultData); |
|
|
|
return r; |
|
|
|
|
|
|
|
} catch (Exception e) { |
|
|
|
log.error("机械臂拣选看板接口异常: {}", e.getMessage()); |
|
|
|
return R.error(500, e.getMessage()); |
|
|
|
log.error("=== 机械臂拣选看板接口异常 === 错误信息: {}", e.getMessage(), e); |
|
|
|
return R.error(500, "获取机械臂拣选数据失败: " + e.getMessage()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 将WCS返回的material数据转换为前端需要的格式 |
|
|
|
* |
|
|
|
* @param material WCS返回的物料数据 |
|
|
|
* @param sortingStation 工作站编号 |
|
|
|
* @return 前端表格数据格式 |
|
|
|
*/ |
|
|
|
private Map<String, Object> convertMaterialToItem(JsonNode material, String sortingStation) { |
|
|
|
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() : ""); |
|
|
|
|
|
|
|
// 拣选数量 (默认值,WCS数据中没有提供) |
|
|
|
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("storageBatchNo", material.has("targetPalletCode") ? |
|
|
|
material.get("targetPalletCode").asText() : ""); |
|
|
|
|
|
|
|
// 存放位置 (工作站编号) |
|
|
|
item.put("storageLocation", material.has("sortingStation") ? |
|
|
|
material.get("sortingStation").asText() : ""); |
|
|
|
|
|
|
|
return item; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 创建空数据 |
|
|
|
* |
|
|
|
* @return 空的数据结构 |
|
|
|
*/ |
|
|
|
private Map<String, Object> createEmptyData() { |
|
|
|
Map<String, Object> emptyData = new HashMap<>(); |
|
|
|
emptyData.put("containerList", new ArrayList<>()); |
|
|
|
emptyData.put("materialList", new ArrayList<>()); |
|
|
|
return emptyData; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 分切区看板 |
|
|
|
*/ |
|
|
|
|