数字孪生后台

This commit is contained in:
猫猫guowen
2025-12-24 13:06:04 +08:00
parent 36dfd23b13
commit fcfaf773c0
12 changed files with 1125 additions and 1 deletions

View File

@@ -0,0 +1,129 @@
package com.ruoyi.tcp;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.Constant;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import javax.annotation.PostConstruct;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
@Component
@Slf4j
public class Wcs2wmsgetEmptyCargoSpace {
private final TcpServerManager manager;
private final ObjectMapper objectMapper = new ObjectMapper();
private final RestTemplate restTemplate = new RestTemplate();
/**
* 构造函数:注入 TCP 管理器,用于在 1111 端口管理客户端与数据发送
*/
public Wcs2wmsgetEmptyCargoSpace(TcpServerManager manager) {
this.manager = manager;
}
/**
* 初始化:注册 1111 端口客户端监听,客户端首次连接时触发数据发送
*/
@PostConstruct
public void init() {
manager.setClientListener("port1111", this::handleConnect);
}
/**
* 客户端连接处理:调用 WMS 接口获取空货位数据,转换为统一 JSON 并写入到 Socket
*/
private void handleConnect(Socket socket) {
try {
String url = Constant.WMS_BASE_URL + "twin/getEmptyCargoSpace";
log.info("Fetching WMS data from {}", url);
String wmsResponse = restTemplate.getForObject(url, String.class);
JsonNode root = objectMapper.readTree(wmsResponse);
List<CargoDto> cargoList = new ArrayList<>();
// Handle if root is array or wrapped in "data" or "rows"
JsonNode arrayNode = null;
if (root.isArray()) {
arrayNode = root;
} else if (root.has("data") && root.get("data").isArray()) {
arrayNode = root.get("data");
} else if (root.has("rows") && root.get("rows").isArray()) {
arrayNode = root.get("rows");
}
if (arrayNode != null) {
for (JsonNode node : arrayNode) {
cargoList.add(mapToDto(node));
}
} else {
// If it's a single object, maybe treat as one item?
// Or maybe the format is different. For now, log warning if empty.
log.warn("WMS response is not an array: {}", wmsResponse);
}
CargoResponse response = new CargoResponse();
response.setCargo(cargoList);
String json = objectMapper.writeValueAsString(response);
OutputStream os = socket.getOutputStream();
os.write((json + "\n").getBytes(StandardCharsets.UTF_8));
os.flush();
log.info("Sent WMS data to client on port 1111");
} catch (Exception e) {
log.error("Failed to fetch WMS data or send to client", e);
}
}
/**
* 映射单条 WMS 返回记录为 DTO:优先取目标字段名,兼容 BasCargoSpace 字段名
*/
private CargoDto mapToDto(JsonNode node) {
CargoDto dto = new CargoDto();
// Mapping strategy: try user's target keys first, then BasCargoSpace keys
dto.setRow(getText(node, "row", "thePlatoon"));
dto.setColumn(getText(node, "column", "theColumn"));
dto.setLayer(getText(node, "layer", "theFloor"));
dto.setStatus(getText(node, "status"));
dto.setTrayCode(getText(node, "trayCode"));
dto.setProductCode(getText(node, "productCode"));
dto.setProductName(getText(node, "productName"));
return dto;
}
/**
* 读取节点文本:按给定字段名顺序查找首个存在且非空的值
*/
private String getText(JsonNode node, String... keys) {
for (String key : keys) {
if (node.has(key) && !node.get(key).isNull()) {
return node.get(key).asText();
}
}
return "";
}
@Data
private static class CargoResponse {
private List<CargoDto> cargo;
}
@Data
private static class CargoDto {
private String row;
private String column;
private String layer;
private String status;
private String trayCode;
private String productCode;
private String productName;
}
}