package com.zy.asrs.service.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.zy.asrs.entity.WrkDetl; import com.zy.asrs.entity.WrkMast; import com.zy.asrs.entity.param.TaskCreateParam; import com.zy.asrs.entity.param.TaskStatusFeedbackParam; import com.zy.asrs.service.ApiLogService; import com.zy.asrs.service.OpenService; import com.zy.asrs.service.WrkDetlService; import com.zy.asrs.service.WrkMastService; import com.zy.common.service.CommonService; import com.zy.common.utils.HttpHandler; import com.zy.core.cache.MessageQueue; import com.zy.core.cache.SlaveConnection; import com.zy.core.enums.SlaveType; import com.zy.core.model.Task; import com.zy.core.model.protocol.StaProtocol; import com.zy.core.properties.SlaveProperties; import com.zy.core.thread.SiemensDevpThread; import com.zy.core.model.DevpSlave; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * Created by vincent on 2022/4/9 */ @Slf4j @Service public class OpenServiceImpl implements OpenService { @Value("${wms.url}") private String wmsUrl; @Autowired private ApiLogService apiLogService; @Autowired private CommonService commonService; @Autowired private WrkMastService wrkMastService; @Autowired private WrkDetlService wrkDetlService; @Autowired private SlaveProperties slaveProperties; @Override public boolean reportTaskStatus(String taskNo, Integer status, Integer ioType, String barcode) { try { TaskStatusFeedbackParam param = new TaskStatusFeedbackParam(); param.setTaskNo(taskNo); param.setStatus(status); param.setIoType(ioType); param.setBarcode(barcode); param.setReportTime(new Date()); Map headers = new HashMap<>(); headers.put("appkey", "ea1f0459efc02a79f046f982767939ae"); String response = new HttpHandler.Builder() .setUri(wmsUrl) .setPath("/taskStatusFeedback") .setJson(JSON.toJSONString(param)) .setHeaders(headers) .build() .doPost(); boolean success = false; log.info("任务状态反馈上报结果:{}", response); if (response != null) { try { JSONObject jsonObject = JSON.parseObject(response); // 假设返回code为200表示成功 if (jsonObject != null && jsonObject.containsKey("code") && jsonObject.getInteger("code") == 200) { success = true; } } catch (Exception e) { log.warn("解析响应失败", e); } } // 记录日志 try { apiLogService.save("任务状态反馈上报", "/taskStatusFeedback", "ea1f0459efc02a79f046f982767939ae", wmsUrl, JSON.toJSONString(param), response, success); } catch (Exception e) { log.error("保存API日志异常", e); } return success; } catch (Exception e) { log.error("任务状态反馈上报异常", e); } return false; } @Override @Transactional(rollbackFor = Exception.class) public boolean taskCreate(TaskCreateParam param) { try { Integer ioType = 0; boolean Inbound = true; //1:出库,2:入库 3:移库 //11:空板出库,12:空板入库 //21:拣选出库 22:拣选入库 //31:盘点出库 32:盘点入库 switch (param.getIoType()){ case 1: Inbound = false;break; case 2 : Inbound = true;break; case 3: Inbound = false;break; case 11: Inbound = false;ioType = 110;break; case 12: Inbound = true;break; case 21: Inbound = false;ioType = 103;break; case 22: Inbound = true;break; case 31: Inbound = false;ioType = 107;break; case 32: Inbound = true;break; } // 2. 保存WrkMast WrkMast wrkMast = new WrkMast(); if(param.getIoType() == 2 || param.getIoType() == 12){ wrkMast.setWrkNo(Integer.valueOf(param.getTaskNo())); wrkMast.setIoType(param.getIoType() != 2?10:1); wrkMast.setIoPri(param.getTaskPriority() != null ? param.getTaskPriority().doubleValue() : 11.0); wrkMast.setBarcode(param.getBarcode()); wrkMast.setMemo(param.getMemo()); wrkMast.setSourceStaNo(Integer.valueOf(param.getStartPoint())); wrkMast.setStaNo(Integer.valueOf(param.getTargetPoint())); wrkMast.setLocNo(param.getTargetLocNo()); wrkMast.setSourceLocNo(param.getSourceLocNo()); }else if(param.getIoType() == 22 || param.getIoType() == 32){ wrkMast = wrkMastService.selectOne(new EntityWrapper().eq("barcode",param.getBarcode())); wrkMast.setWrkSts(param.getIoType() != 32 ? 53L: 57L); wrkMast.setWrkNo(Integer.valueOf(param.getTaskNo())); wrkMast.setIoPri(param.getTaskPriority() != null ? param.getTaskPriority().doubleValue() : 11.0); wrkMast.setBarcode(param.getBarcode()); wrkMast.setMemo(param.getMemo()); wrkMast.setSourceStaNo(Integer.valueOf(param.getStartPoint())); wrkMast.setStaNo(Integer.valueOf(param.getTargetPoint())); wrkMast.setLocNo(param.getTargetLocNo()); wrkMast.setSourceLocNo(param.getSourceLocNo()); }else if(param.getIoType() == 3){ wrkMast.setWrkNo(Integer.valueOf(param.getTaskNo())); wrkMast.setIoType(11); wrkMast.setIoPri(param.getTaskPriority() != null ? param.getTaskPriority().doubleValue() : 12.0); wrkMast.setBarcode(param.getBarcode()); wrkMast.setMemo(param.getMemo()); wrkMast.setSourceStaNo(Integer.valueOf(param.getStartPoint())); wrkMast.setStaNo(Integer.valueOf(param.getTargetPoint())); wrkMast.setLocNo(param.getTargetLocNo()); wrkMast.setSourceLocNo(param.getSourceLocNo()); }else{ wrkMast.setWrkNo(Integer.valueOf(param.getTaskNo())); wrkMast.setIoType(ioType); wrkMast.setIoPri(param.getTaskPriority() != null ? param.getTaskPriority().doubleValue() : 11.0); wrkMast.setBarcode(param.getBarcode()); wrkMast.setMemo(param.getMemo()); wrkMast.setSourceStaNo(Integer.valueOf(param.getStartPoint())); wrkMast.setStaNo(Integer.valueOf(param.getTargetPoint())); wrkMast.setLocNo(param.getTargetLocNo()); wrkMast.setSourceLocNo(param.getSourceLocNo()); } if(Inbound){ wrkMast.setWrkSts(2L); }else{ wrkMast.setWrkSts(11L); } wrkMast.setAppeTime(new Date()); wrkMast.setWrkDate(new Date()); wrkMastService.insert(wrkMast); // 3. 保存WrkDetl if (param.getDetlList() != null && !param.getDetlList().isEmpty()) { for (TaskCreateParam.Detl detl : param.getDetlList()) { WrkDetl wrkDetl = new WrkDetl(); wrkDetl.setWrkNo(wrkMast.getWrkNo()); wrkDetl.setZpallet(detl.getBarcode()); wrkDetl.setMatnr(detl.getMatnr()); wrkDetl.setBatch(detl.getBatch()); if (detl.getAnfme() != null) { wrkDetl.setAnfme(detl.getAnfme().doubleValue()); } wrkDetlService.insert(wrkDetl); } } // 4. 下发给PLC if(Inbound){ writeToPlc(wrkMast); } // 记录日志 try { apiLogService.save("任务下发", "/taskCreate", "ea1f0459efc02a79f046f982767939ae", "LOCAL", JSON.toJSONString(param), "SUCCESS", true); } catch (Exception e) { log.error("保存API日志异常", e); } return true; } catch (Exception e) { log.error("任务下发异常", e); try { apiLogService.save("任务下发", "/taskCreate", "ea1f0459efc02a79f046f982767939ae", "LOCAL", JSON.toJSONString(param), "FAIL: " + e.getMessage(), false); } catch (Exception ex) { // ignore } throw new RuntimeException(e); // 触发事务回滚 } } private void writeToPlc(WrkMast wrkMast) { if (wrkMast.getSourceStaNo() == null) { log.warn("任务下发缺少源站点: wrkNo={}", wrkMast.getWrkNo()); return; } Integer sourceStaNo = wrkMast.getSourceStaNo(); for (DevpSlave devp : slaveProperties.getDevp()) { SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId()); if (devpThread == null) continue; // 检查该PLC是否管理该站点 if (devpThread.getStation().containsKey(sourceStaNo.shortValue())) { StaProtocol staProtocol = devpThread.getStation().get(sourceStaNo.shortValue()); if (staProtocol != null && staProtocol.getWorkNo() == 9998) { staProtocol.setWorkNo(wrkMast.getWrkNo()); if (wrkMast.getStaNo() != null) { staProtocol.setStaNo(wrkMast.getStaNo().shortValue()); } // 下发PLC指令 devpThread.setPakMk(staProtocol.getSiteId(), false, 283); boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol)); if (result) { log.info("任务下发成功,已写入PLC。WrkNo: {}, Source: {}, Target: {}", wrkMast.getWrkNo(), wrkMast.getSourceStaNo(), wrkMast.getStaNo()); } else { log.error("任务下发失败,写入PLC队列失败。WrkNo: {}", wrkMast.getWrkNo()); } return; } } } log.warn("未找到对应的PLC站点或线程: {}", sourceStaNo); } }