package com.zy.asrs.service.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.core.common.Cools; import com.core.exception.CoolException; import com.zy.asrs.entity.LocMast; import com.zy.asrs.entity.WrkDetl; import com.zy.asrs.entity.WrkLastno; 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.*; 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 WrkLastnoService wrkLastnoService; @Autowired private RowLastnoService rowLastnoService; @Autowired private CommonService commonService; @Autowired private WrkMastService wrkMastService; @Autowired private WrkDetlService wrkDetlService; @Autowired private LocMastService locMastService; @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; } /** * 生成工作号 * * @param wrkMk * @return workNo(工作号) */ public int getWorkNo(Integer wrkMk) { WrkLastno wrkLastno = wrkLastnoService.selectById(wrkMk); if (Cools.isEmpty(wrkLastno)) { throw new CoolException("数据异常,请联系管理员"); } int workNo = wrkLastno.getWrkNo(); int sNo = wrkLastno.getSNo(); int eNo = wrkLastno.getENo(); workNo = workNo >= eNo ? sNo : workNo + 1; while (true) { WrkMast wrkMast = wrkMastService.selectById(workNo); if (null != wrkMast) { workNo = workNo >= eNo ? sNo : workNo + 1; } else { break; } } // 修改序号记录 if (workNo > 0) { wrkLastno.setWrkNo(workNo); wrkLastnoService.updateById(wrkLastno); } // 检验 if (workNo == 0) { throw new CoolException("生成工作号失败,请联系管理员"); } else { if (wrkMastService.selectById(workNo) != null) { throw new CoolException("生成工作号" + workNo + "在工作档中已存在"); } } return workNo; } @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;ioType = 101;break; case 2 : Inbound = true;ioType = 1;break; case 3: Inbound = false;ioType = 11;break; case 11: Inbound = false;ioType = 110;break; case 12: Inbound = true;ioType = 10;break; case 21: Inbound = false;ioType = 103;break; case 22: Inbound = true;ioType = 53;break; case 31: Inbound = false;ioType = 107;break; case 32: Inbound = true;ioType = 57;break; } // 2. 保存WrkMast WrkMast wrkMast = new WrkMast(); int workNo = getWorkNo(0); if(param.getIoType() == 2 || param.getIoType() == 12){ wrkMast.setWrkNo(workNo); wrkMast.setUserNo(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(workNo); wrkMast.setUserNo(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(workNo); wrkMast.setUserNo(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(workNo); wrkMast.setUserNo(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); } String locNo = null; if (param.getSourceLocNo() != null && !param.getSourceLocNo().isEmpty()) { locNo = param.getSourceLocNo(); } if (param.getTargetLocNo() != null && !param.getTargetLocNo().isEmpty()) { locNo = param.getTargetLocNo(); } // 取前两位 int rowNo = Integer.parseInt(locNo.substring(0, 2)); int crnNo; if (rowNo >= 1 && rowNo <= 4) { crnNo = 1; } else if (rowNo >= 5 && rowNo <= 8) { crnNo = 2; } else if (rowNo >= 9 && rowNo <= 10) { crnNo = 3; } else if (rowNo >= 11 && rowNo <= 14) { crnNo = 4; } else { throw new IllegalArgumentException("排号超出范围: " + rowNo); } wrkMast.setCrnNo(crnNo); wrkMast.setIoTime(new Date()); wrkMast.setModiTime(new Date()); wrkMast.setAppeTime(new Date()); wrkMast.setWrkDate(new Date()); if(param.getIoType() == 22 || param.getIoType() == 32){ wrkMastService.updateById(wrkMast); }else{ 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); } } if(param.getIoType() == 2 || param.getIoType() == 12){ locMastService.updateLocMast(param.getTargetLocNo(),"S"); }else if(param.getIoType() == 3){ locMastService.updateLocMast(param.getSourceLocNo(),"R"); locMastService.updateLocMast(param.getTargetLocNo(),"S"); }else if(param.getIoType() == 22 || param.getIoType() == 32){ locMastService.updateLocMast(param.getTargetLocNo(),"Q"); }else if(param.getIoType() == 1 || param.getIoType() == 11){ locMastService.updateLocMast(param.getSourceLocNo(),"R" ); }else{ locMastService.updateLocMast(param.getSourceLocNo(),"P" ); } // 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) { continue; } else { staProtocol = staProtocol.clone(); } if (staProtocol != null && staProtocol.getWorkNo() == 9999) { staProtocol.setWorkNo(wrkMast.getWrkNo()); if (wrkMast.getStaNo() != null) { staProtocol.setStaNo(wrkMast.getStaNo().shortValue()); } // 下发PLC指令 devpThread.setPakMk(staProtocol.getSiteId(), false, 9999); 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); } }