package com.ruoyi.tcp; import com.fasterxml.jackson.databind.ObjectMapper; import com.ruoyi.common.utils.DictUtils; import com.ruoyi.device.tsj.domain.DeviceTsj; import com.ruoyi.job.domain.MydoJob; import com.ruoyi.job.service.IMydoJobService; import com.ruoyi.schedule.plcRead.tsj.PlcTsjRead; import lombok.Data; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; 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; import java.util.Map; @Component public class GetDeviceTsjMap { private final TcpServerManager manager; private final ObjectMapper objectMapper = new ObjectMapper(); private final IMydoJobService mydoJobService; /** * 构造函数:注入 TCP 管理器与作业服务,用于管理 4444 端口广播并根据任务号补全物料信息 */ public GetDeviceTsjMap(TcpServerManager manager, IMydoJobService mydoJobService) { this.manager = manager; this.mydoJobService = mydoJobService; } /** * 初始化:注册 4444 端口的客户端连接监听,客户端第一次连接时立即发送提升机数据 */ @PostConstruct public void init() { manager.setClientListener("port4444", this::handleConnect); } /** * 客户端连接处理:构建提升机数据并写入到 Socket 输出流 */ private void handleConnect(Socket socket) { try { String payload = buildTsjPayload(); OutputStream os = socket.getOutputStream(); os.write(((payload == null ? "" : payload) + "\n").getBytes(StandardCharsets.UTF_8)); os.flush(); } catch (Exception ignored) { } } /** * 周期发送:每 2 秒检查 4444 端口是否有连接,有则广播提升机数据,无连接不发送 */ @Scheduled(fixedRate = 2000) public void send() { Integer count = manager.status().getOrDefault("port4444", 0); if (count != null && count > 0) { String payload = buildTsjPayload(); manager.broadcast("port4444", payload == null ? "" : payload); } } /** * 构建提升机数据:从 PLC 缓存读取提升机状态并组装 JSON * - 工作模式转换为中文标签 * - 报警码与文案:使用字典 tsj_alarm * - 当任务号有效时,查询 MydoJob 补齐托盘与物料信息 * 返回 JSON 字符串格式:{"tsj":[{...}]} */ private String buildTsjPayload() { Map map = PlcTsjRead.deviceTsjMap; List list = new ArrayList<>(); if (map != null) { for (Map.Entry entry : map.entrySet()) { String code = entry.getKey(); DeviceTsj d = entry.getValue(); TsjDto dto = new TsjDto(); dto.setId(String.valueOf(d.getId())); dto.setLayer(d.getDqcs() == null ? "" : String.valueOf(d.getDqcs())); dto.setTaskNo(d.getRwh() == null ? "" : String.valueOf(d.getRwh())); dto.setZxjd(d.getJdbz() == null ? "" : String.valueOf(d.getJdbz())); Integer cf = d.getCzfs(); String mode = "0"; if (cf != null) { if (cf == 1) { mode = "手动"; }else if (cf == 2) { mode = "自动"; }else { mode = String.valueOf(cf); } } dto.setWorkingMode(mode); dto.setSourceLayer(d.getYch() == null ? "" : String.valueOf(d.getYch())); dto.setTargetLayer(d.getMbch() == null ? "" : String.valueOf(d.getMbch())); dto.setAlarm(d.getSbzt() == null ? "" : String.valueOf(d.getSbzt())); dto.setAlarmMsg(DictUtils.getDictLabel("tsj_alarm", d.getSbzt() == null ? "" : String.valueOf(d.getSbzt()))); if (d.getRwh() != null && d.getRwh() > 0) { try { MydoJob job = mydoJobService.selectMydoJobByTaskNo(Long.valueOf(d.getRwh())); dto.setTrayCode(job == null || job.getTrayCode() == null ? "" : job.getTrayCode()); dto.setProductCode(job == null || job.getProductId() == null ? "" : job.getProductId()); dto.setProductName(job == null || job.getProductName() == null ? "" : job.getProductName()); } catch (Exception e) { dto.setTrayCode(""); dto.setProductCode(""); dto.setProductName(""); } } else { dto.setTrayCode(""); dto.setProductCode(""); dto.setProductName(""); } list.add(dto); } } try { Wrapper w = new Wrapper(); w.setTsj(list); return objectMapper.writeValueAsString(w); } catch (Exception e) { return "{\"tsj\":[]}"; } } @Data private static class Wrapper { private List tsj; } @Data private static class TsjDto { private String id; private String taskNo; private String zxjd; private String workingMode; private String sourceLayer; private String targetLayer; private String alarm; private String alarmMsg; private String trayCode; private String productCode; private String productName; private String layer; } }