package com.zy.ai.mcp.service.impl; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.zy.ai.entity.DeviceConfigsData; import com.zy.ai.log.AiLogAppender; import com.zy.ai.mcp.service.WcsDataFacade; import com.zy.asrs.entity.BasCrnp; import com.zy.asrs.entity.BasDevp; import com.zy.asrs.entity.BasRgv; import com.zy.asrs.entity.WrkMast; import com.zy.asrs.service.BasCrnpService; import com.zy.asrs.service.BasDevpService; import com.zy.asrs.service.BasRgvService; import com.zy.asrs.service.WrkMastService; import com.zy.core.cache.SlaveConnection; import com.zy.core.enums.SlaveType; import com.zy.core.model.StationObjModel; import com.zy.core.model.protocol.CrnProtocol; import com.zy.core.model.protocol.RgvProtocol; import com.zy.core.model.protocol.StationProtocol; import com.zy.core.thread.CrnThread; import com.zy.core.thread.RgvThread; import com.zy.core.thread.StationThread; import com.zy.system.entity.Config; import com.zy.system.service.ConfigService; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.*; @Service("wcsDataFacade") @RequiredArgsConstructor public class WcsDataFacadeImpl implements WcsDataFacade { @Autowired private BasCrnpService basCrnpService; @Autowired private BasDevpService basDevpService; @Autowired private BasRgvService basRgvService; @Autowired private WrkMastService wrkMastService; @Autowired private ConfigService configService; @Override public Object getCrnDeviceStatus(JSONObject args) { List deviceNoList = optIntList(args, "crnNos"); EntityWrapper wrapper = new EntityWrapper<>(); if (deviceNoList != null && deviceNoList.size() > 0) { wrapper.in("crn_no", deviceNoList); } JSONObject data = new JSONObject(); List deviceList = new ArrayList<>(); List basCrnps = basCrnpService.selectList(wrapper); for (BasCrnp basCrnp : basCrnps) { CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo()); if (crnThread == null) { continue; } CrnProtocol protocol = crnThread.getStatus(); deviceList.add(protocol); } data.put("devices", deviceList); return data; } @Override public Object getStationDeviceStatus(JSONObject args) { List basDevps = basDevpService.selectList(new EntityWrapper<>()); JSONObject data = new JSONObject(); List stationList = new ArrayList<>(); for (BasDevp basDevp : basDevps) { StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getDevpNo()); if (stationThread == null) { continue; } Map map = stationThread.getStatusMap(); for (StationObjModel stationObjModel : basDevp.getStationList$()) { StationProtocol stationProtocol = map.get(stationObjModel.getStationId()); if (stationProtocol == null) { continue; } stationList.add(stationProtocol); } } data.put("stations", stationList); return data; } @Override public Object getRgvDeviceStatus(JSONObject args) { List deviceNoList = optIntList(args, "rgvNos"); EntityWrapper wrapper = new EntityWrapper<>(); if (deviceNoList != null && deviceNoList.size() > 0) { wrapper.in("rgv_no", deviceNoList); } JSONObject data = new JSONObject(); List deviceList = new ArrayList<>(); List basRgvs = basRgvService.selectList(wrapper); for (BasRgv basRgv : basRgvs) { RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, basRgv.getRgvNo()); if (rgvThread == null) { continue; } RgvProtocol rgvProtocol = rgvThread.getStatus(); deviceList.add(rgvProtocol); } data.put("devices", deviceList); return data; } @Override public Object getTasks(JSONObject args) { int crnNo = optInt(args, "crnNo", -1); int rgvNo = optInt(args, "rgvNo", -1); List taskNos = optIntList(args, "taskNos"); int limit = optInt(args, "limit", 200); EntityWrapper wrapper = new EntityWrapper<>(); if (taskNos != null && taskNos.size() > 0) { wrapper.in("wrk_no", taskNos); } if (crnNo != -1) { wrapper.eq("crn_no", crnNo); } if (rgvNo != -1) { wrapper.eq("rgv_no", rgvNo); } List tasks = wrkMastService.selectList(wrapper); JSONObject data = new JSONObject(); data.put("tasks", tasks); return data; } @Override public Object getLogs(JSONObject args) { int limit = optInt(args, "limit", 500); List logs = AiLogAppender.getRecentLogs(limit); JSONObject data = new JSONObject(); data.put("logs", logs); return data; } @Override public Object getDeviceConfig(JSONObject args) { JSONObject data = new JSONObject(); List deviceConfigsDataList = new ArrayList<>(); List crnNoList = optIntList(args, "crnNos"); EntityWrapper crnWrapper = new EntityWrapper<>(); if (crnNoList != null && crnNoList.size() > 0) { crnWrapper.in("crn_no", crnNoList); } List rgvNoList = optIntList(args, "rgvNos"); EntityWrapper rgvWrapper = new EntityWrapper<>(); if (rgvNoList != null && rgvNoList.size() > 0) { rgvWrapper.in("rgv_no", rgvNoList); } List devpNoList = optIntList(args, "devpNos"); EntityWrapper devpWrapper = new EntityWrapper<>(); if (devpNoList != null && devpNoList.size() > 0) { devpWrapper.in("devp_no", devpNoList); } List basCrnps = basCrnpService.selectList(crnWrapper); for (BasCrnp basCrnp : basCrnps) { DeviceConfigsData deviceConfigsData = new DeviceConfigsData(); deviceConfigsData.setDeviceNo(basCrnp.getCrnNo()); deviceConfigsData.setDeviceType(String.valueOf(SlaveType.Crn)); deviceConfigsData.setDeviceData(basCrnp); deviceConfigsDataList.add(deviceConfigsData); } List basRgvs = basRgvService.selectList(rgvWrapper); for (BasRgv basRgv : basRgvs) { DeviceConfigsData deviceConfigsData = new DeviceConfigsData(); deviceConfigsData.setDeviceNo(basRgv.getRgvNo()); deviceConfigsData.setDeviceType(String.valueOf(SlaveType.Rgv)); deviceConfigsData.setDeviceData(basRgv); deviceConfigsDataList.add(deviceConfigsData); } List basDevps = basDevpService.selectList(devpWrapper); for (BasDevp basDevp : basDevps) { DeviceConfigsData deviceConfigsData = new DeviceConfigsData(); deviceConfigsData.setDeviceNo(basDevp.getDevpNo()); deviceConfigsData.setDeviceType(String.valueOf(SlaveType.Devp)); deviceConfigsData.setDeviceData(basDevp); deviceConfigsDataList.add(deviceConfigsData); } data.put("deviceConfigs", deviceConfigsDataList); return data; } @Override public Object getSystemConfig(JSONObject args) { JSONObject data = new JSONObject(); List systemConfigList = configService.selectList(new EntityWrapper().notIn("dingdingReportUrl")); data.put("systemConfigs", systemConfigList); return data; } @Override public Object buildDiagnosisSnapshot(JSONObject args) { String wh = mustStr(args, "warehouseCode"); List crnDeviceNos = optStrList(args, "crnDeviceNos"); List taskIds = optStrList(args, "taskIds"); int lookbackSeconds = optInt(args, "lookbackSeconds", 300); int logMaxLines = optInt(args, "logMaxLines", 600); boolean includeConfig = optBool(args, "includeConfig", true); long now = System.currentTimeMillis(); long fromTs = now - lookbackSeconds * 1000L; // 1) crn devices JSONObject devArgs = new JSONObject(); devArgs.put("deviceNos", crnDeviceNos); JSONObject devices = (JSONObject) getCrnDeviceStatus(devArgs); // 2) tasks JSONObject taskArgs = new JSONObject(); taskArgs.put("warehouseCode", wh); taskArgs.put("taskIds", taskIds); taskArgs.put("limit", 200); JSONObject tasks = (JSONObject) getTasks(taskArgs); // 3) logs (一次性取回,然后做分桶+排序+截断) JSONObject logArgs = new JSONObject(); logArgs.put("warehouseCode", wh); logArgs.put("fromTs", fromTs); logArgs.put("toTs", now); // logArgs.put("deviceIds", deviceIds); logArgs.put("taskIds", taskIds); logArgs.put("maxLines", logMaxLines); JSONObject logs = (JSONObject) getLogs(logArgs); // 4) 结构化快照输出(建议:分桶) JSONObject snapshot = new JSONObject(); snapshot.put("warehouseCode", wh); snapshot.put("generatedTs", now); snapshot.put("timeRange", new JSONObject() .fluentPut("fromTs", fromTs) .fluentPut("toTs", now) .fluentPut("lookbackSeconds", lookbackSeconds)); snapshot.put("devices", devices); snapshot.put("tasks", tasks); snapshot.put("logs", logs); JSONArray hints = new JSONArray(); hints.add("Prefer diagnosing with snapshot.devices + snapshot.tasks + snapshot.logs"); hints.add("Logs are already filtered by time range; if missing, expand lookbackSeconds"); snapshot.put("hints", hints); JSONObject data = new JSONObject(); data.put("snapshot", snapshot); return data; } // --------- helpers --------- private String mustStr(JSONObject o, String key) { if (o == null || o.getString(key) == null || o.getString(key).trim().isEmpty()) throw new IllegalArgumentException(key + " is required"); return o.getString(key).trim(); } private long mustLong(JSONObject o, String key) { if (o == null || !o.containsKey(key)) throw new IllegalArgumentException(key + " is required"); return o.getLongValue(key); } private int optInt(JSONObject o, String key, int def) { if (o == null || !o.containsKey(key)) return def; return o.getIntValue(key); } private boolean optBool(JSONObject o, String key, boolean def) { if (o == null || !o.containsKey(key)) return def; return o.getBooleanValue(key); } private List optStrList(JSONObject o, String key) { if (o == null || !o.containsKey(key)) return Collections.emptyList(); JSONArray arr = o.getJSONArray(key); if (arr == null) return Collections.emptyList(); List list = new ArrayList<>(); for (int i = 0; i < arr.size(); i++) { String s = arr.getString(i); if (s != null && !s.trim().isEmpty()) list.add(s.trim()); } return list; } private List optIntList(JSONObject o, String key) { if (o == null || !o.containsKey(key)) return Collections.emptyList(); JSONArray arr = o.getJSONArray(key); if (arr == null) return Collections.emptyList(); List list = new ArrayList<>(); for (int i = 0; i < arr.size(); i++) { String s = arr.getString(i); if (s != null && !s.trim().isEmpty()) list.add(Integer.parseInt(s.trim())); } return list; } }