|
|
|
@ -379,9 +379,8 @@ public class DashboardPushTask { |
|
|
|
Map<String, Object> taskStats = dashboardDao.queryWarehouseTaskStats(); |
|
|
|
log.debug("任务统计数据: {}", taskStats); |
|
|
|
|
|
|
|
// 查询库位利用率数据 |
|
|
|
//Map<String, Object> storageUtilization = dashboardDao.queryWarehouseStorageUtilization(); |
|
|
|
Map<String, Object> storageUtilization = new HashMap<>(); |
|
|
|
// 查询库位利用率数据(从WCS Board API获取) |
|
|
|
Map<String, Object> storageUtilization = getInventoryStatsFromWcs(); |
|
|
|
log.debug("库位利用率数据: {}", storageUtilization); |
|
|
|
|
|
|
|
// 查询机器人状态数据 |
|
|
|
@ -436,6 +435,117 @@ public class DashboardPushTask { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 从WCS Board API获取库存统计数据 |
|
|
|
* |
|
|
|
* <p><b>API说明:</b></p> |
|
|
|
* <ul> |
|
|
|
* <li>接口地址: /api/WmsDashboard/inventory-stats</li> |
|
|
|
* <li>返回托盘库存统计:平托、框架托、钢托</li> |
|
|
|
* <li>返回空容器库存数量</li> |
|
|
|
* </ul> |
|
|
|
* |
|
|
|
* <p><b>数据转换:</b></p> |
|
|
|
* <ul> |
|
|
|
* <li>flatPallet(平托) -> flatPallet</li> |
|
|
|
* <li>framePallet(框架托) -> guardPallet(围挡托盘)</li> |
|
|
|
* <li>steelPallet(钢托) -> steelPallet</li> |
|
|
|
* <li>emptyContainerInventory -> otherPallet(其他)</li> |
|
|
|
* </ul> |
|
|
|
* |
|
|
|
* @return 库存统计数据 |
|
|
|
*/ |
|
|
|
private Map<String, Object> getInventoryStatsFromWcs() { |
|
|
|
try { |
|
|
|
// 调用WCS Board API |
|
|
|
String url = wcsBoardApi + "WmsDashboard/inventory-stats"; |
|
|
|
log.debug("调用WCS库存统计API: {}", url); |
|
|
|
|
|
|
|
String wcsResponse = HttpUtils.doGet(url, null, null); |
|
|
|
log.debug("WCS API返回数据: {}", wcsResponse); |
|
|
|
|
|
|
|
// 解析JSON数据 |
|
|
|
ObjectMapper mapper = new ObjectMapper(); |
|
|
|
JsonNode rootNode = mapper.readTree(wcsResponse); |
|
|
|
|
|
|
|
// 检查返回码 |
|
|
|
int resCode = rootNode.get("resCode").asInt(); |
|
|
|
if (resCode != 200) { |
|
|
|
String resMsg = rootNode.has("resMsg") ? rootNode.get("resMsg").asText() : "未知错误"; |
|
|
|
log.warn("WCS API返回错误: code={}, msg={}", resCode, resMsg); |
|
|
|
return createEmptyStorageData(); |
|
|
|
} |
|
|
|
|
|
|
|
// 获取resData数据 |
|
|
|
JsonNode resData = rootNode.get("resData"); |
|
|
|
if (resData == null || resData.isNull()) { |
|
|
|
log.warn("WCS返回数据中没有resData"); |
|
|
|
return createEmptyStorageData(); |
|
|
|
} |
|
|
|
|
|
|
|
// 获取materialInventory(物料库存) |
|
|
|
JsonNode materialInventory = resData.get("materialInventory"); |
|
|
|
if (materialInventory == null || materialInventory.isNull()) { |
|
|
|
log.warn("WCS返回数据中没有materialInventory"); |
|
|
|
return createEmptyStorageData(); |
|
|
|
} |
|
|
|
|
|
|
|
// 提取各类托盘数量 |
|
|
|
int flatPallet = materialInventory.has("flatPallet") ? |
|
|
|
materialInventory.get("flatPallet").asInt() : 0; |
|
|
|
int framePallet = materialInventory.has("framePallet") ? |
|
|
|
materialInventory.get("framePallet").asInt() : 0; |
|
|
|
int steelPallet = materialInventory.has("steelPallet") ? |
|
|
|
materialInventory.get("steelPallet").asInt() : 0; |
|
|
|
|
|
|
|
// 提取空容器库存 |
|
|
|
int emptyContainer = resData.has("emptyContainerInventory") ? |
|
|
|
resData.get("emptyContainerInventory").asInt() : 0; |
|
|
|
|
|
|
|
// 计算总使用库位和利用率 |
|
|
|
int usedSlots = flatPallet + framePallet + steelPallet; |
|
|
|
int totalSlots = 1960; // 固定值 |
|
|
|
double utilizationRate = totalSlots > 0 ? |
|
|
|
Math.round((double) usedSlots / totalSlots * 1000.0) / 10.0 : 0.0; |
|
|
|
|
|
|
|
// 构造返回数据 |
|
|
|
Map<String, Object> storageData = new HashMap<>(); |
|
|
|
storageData.put("totalSlots", totalSlots); // 总库位数 |
|
|
|
storageData.put("usedSlots", usedSlots); // 已使用库位数 |
|
|
|
storageData.put("utilizationRate", utilizationRate); // 利用率 |
|
|
|
storageData.put("flatPallet", flatPallet); // 平托 |
|
|
|
storageData.put("guardPallet", framePallet); // 围挡托盘(对应framePallet) |
|
|
|
storageData.put("steelPallet", steelPallet); // 钢托盘 |
|
|
|
storageData.put("otherPallet", emptyContainer); // 其他(空容器) |
|
|
|
|
|
|
|
log.info("库存统计数据获取成功 - 平托:{}, 框架托:{}, 钢托:{}, 空容器:{}, 总使用:{}, 利用率:{}%", |
|
|
|
flatPallet, framePallet, steelPallet, emptyContainer, usedSlots, utilizationRate); |
|
|
|
|
|
|
|
return storageData; |
|
|
|
|
|
|
|
} catch (Exception e) { |
|
|
|
log.error("从WCS获取库存统计数据失败: {}", e.getMessage(), e); |
|
|
|
return createEmptyStorageData(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 创建空的库存统计数据 |
|
|
|
* |
|
|
|
* @return 空的库存统计数据结构 |
|
|
|
*/ |
|
|
|
private Map<String, Object> createEmptyStorageData() { |
|
|
|
Map<String, Object> emptyData = new HashMap<>(); |
|
|
|
emptyData.put("totalSlots", 1960); |
|
|
|
emptyData.put("usedSlots", 0); |
|
|
|
emptyData.put("utilizationRate", 0.0); |
|
|
|
emptyData.put("flatPallet", 0); |
|
|
|
emptyData.put("guardPallet", 0); |
|
|
|
emptyData.put("steelPallet", 0); |
|
|
|
emptyData.put("otherPallet", 0); |
|
|
|
return emptyData; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 创建空的智能立体仓库数据 |
|
|
|
* |
|
|
|
|