package com.zy.common.web; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.baomidou.mybatisplus.mapper.Wrapper; import com.core.common.Cools; import com.core.common.R; import com.core.exception.CoolException; import com.zy.asrs.entity.*; import com.zy.asrs.entity.param.EmptyPlateOutParam; import com.zy.asrs.entity.result.FindLocNoAttributeVo; import com.zy.asrs.mapper.LocMastMapper; import com.zy.asrs.service.*; import com.zy.asrs.utils.Utils; import com.zy.common.CodeRes; import com.zy.common.model.LocTypeDto; import com.zy.common.model.StartupDto; import com.zy.common.model.enums.WorkNoType; import com.zy.common.service.CommonService; import com.zy.common.web.param.GetLocNoChangeParam; import com.zy.common.web.param.NotifyDto; import com.zy.common.web.param.SearchLocParam; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; /** * Created by vincent on 2020/10/30 */ @Slf4j @RestController @RequestMapping("/rpc") public class WcsController { @Autowired private WrkMastService wrkMastService; @Autowired private BasDevpService basDevpService; @Autowired private CommonService commonService; @Autowired private WrkDetlService wrkDetlService; @Autowired private LocMastService locMastService; @Autowired private WaitPakinService waitPakinService; @Autowired private LocDetlService locDetlService; @Autowired private RowLastnoService rowLastnoService; @Autowired private WorkService workService; @Resource private WrkMastLogService wrkMastLogService; @PostMapping("/pakin/loc/v1") @ResponseBody public synchronized R getLocNo(@RequestBody SearchLocParam param) { log.info("收到WCS入库接口请求====>>入参:{}", param); // if (Cools.isEmpty(param.getIoType())) { // return R.error("入出库类型不能为空"); // } if (Cools.isEmpty(param.getSourceStaNo())) { return R.error("源站编号不能为空"); } if (param.getRow().length == 0) { return R.error("WCS上报无可用设备"); } // //wcs调用此接口向组托表插入一条数据模拟组托 // WaitPakin waitPakin = new WaitPakin(); // waitPakin.setZpallet(param.getBarcode()); // waitPakin.setBatch("20260305002"); // waitPakin.setAnfme(100.0D); // waitPakin.setMatnr("YJ2026030509353203"); // waitPakin.setMaktx("上拉杆_左前右后毛坯"); // waitPakin.setSpecs("50001LR-71"); // waitPakin.setModel("skv"); // waitPakinService.insert(waitPakin); // // WaitPakin waitPakin2 = new WaitPakin(); // waitPakin2.setZpallet(param.getBarcode()); // waitPakin2.setBatch("20260305002"); // waitPakin2.setAnfme(100.0D); // waitPakin2.setMatnr("YJ2026030509494873"); // waitPakin2.setMaktx("螺杆先"); // waitPakin2.setSpecs("50001LR-71"); // waitPakin2.setModel("skv"); // waitPakinService.insert(waitPakin2); List waitPakins = waitPakinService.selectList(new EntityWrapper().eq("zpallet", param.getBarcode())); if (param.getIoType() == 1) { if (Cools.isEmpty(param.getBarcode())) { return R.error("条码不能为空"); } WrkMast wrkMast1 = wrkMastService.selectByBarcode(param.getBarcode()); if (wrkMast1 != null) { Integer ioType = wrkMast1.getIoType(); if ((ioType == 103 || ioType == 107) && wrkMast1.getWrkSts() == 14) { // 转换工作档 if (!wrkMastLogService.save(wrkMast1.getWrkNo())) { throw new CoolException("保存工作主档历史档失败"); } Date now = new Date(); // 更新工作档数据状态 wrkMast1.setIoType(wrkMast1.getIoType() - 50); // 入出库类型: 103->53,104->54,107->57 wrkMast1.setWrkSts(2L); // 工作状态: 2.设备上走 wrkMast1.setSourceStaNo(String.valueOf(param.getSourceStaNo())); // 源站 wrkMast1.setStaNo("0"); // 目标站 wrkMast1.setLocNo(wrkMast1.getSourceLocNo()); wrkMast1.setSourceLocNo(""); // 源库位清空 wrkMast1.setModiTime(now); if (!wrkMastService.updateById(wrkMast1)) { throw new CoolException("更新工作档数据状态失败"); } // 修改库位状态 Q.拣料/盘点/并板再入库 LocMast locMast = locMastService.selectById(wrkMast1.getLocNo()); locMast.setLocSts("Q"); locMast.setModiTime(now); if (!locMastService.updateById(locMast)) { throw new CoolException("修改库位状态失败"); } } StartupDto startupDto = new StartupDto(); startupDto.setTaskNo(wrkMast1.getWrkNo()); startupDto.setSourceStaNo(Integer.valueOf(wrkMast1.getSourceStaNo())); startupDto.setTaskPri(wrkMast1.getIoPri()); startupDto.setCrnNo(wrkMast1.getCrnNo()); startupDto.setLocNo(Utils.locToLocNo(wrkMast1.getLocNo())); return R.ok().add(startupDto); } if (Cools.isEmpty(waitPakins)) { WrkMast wrkMast = wrkMastService.selectByBarcode(param.getBarcode()); if (wrkMast != null && wrkMast.getIoType() == 103) { return R.parse(CodeRes.PICK_600); } return R.parse(CodeRes.NO_COMB_700); } int countLoc = locDetlService.selectCount(new EntityWrapper().eq("zpallet", param.getBarcode())); int countWrk = wrkDetlService.selectCount(new EntityWrapper().eq("zpallet", param.getBarcode())); if (countLoc > 0 || countWrk > 0) { return R.error(CodeRes.EXIST_500); } } if (Cools.isEmpty(param.getLocType1())) { return R.error("高低检测信号不能为空"); } // 源站点状态检测 // BasDevp sourceStaNo = basDevpService.checkSiteStatus(param.getSourceStaNo(), true); // sourceStaNo.setLocType1(param.getLocType1()); LocTypeDto locTypeDto = new LocTypeDto(); locTypeDto.setLocType1(param.getLocType1()); if(!waitPakins.isEmpty()) { // 判断是否是空托盘 if (waitPakins.get(0).getMatnr().equals("1") ) { param.setIoType(10); } } StartupDto dto = null; switch (param.getIoType()) { case 1://满托盘入库 assert waitPakins != null; dto = startupFullPutStore(param.getSourceStaNo(), param.getBarcode(), locTypeDto, waitPakins, param.getRow()); break; case 10://空托盘入库 dto = emptyPlateIn(param.getSourceStaNo(), locTypeDto, param.getBarcode(),param.getRow()); break; default: break; } log.info("WCS入库接口返参:{},托盘码:{}", dto, param.getBarcode()); return R.ok().add(dto); } @PostMapping("/taskWrk/state") @ResponseBody public R taskWrkState(@RequestBody(required = false) NotifyDto notifyDto){ log.info("收到WCS请求上报接口======>>工作号:{},入参:{}",notifyDto.getSuperTaskNo(),notifyDto); if (Cools.isEmpty(notifyDto.getNotifyType())){ return R.error("通知类型不能为空"); } if (Cools.isEmpty(notifyDto.getTaskNo())){ return R.error("任务号不能为空"); } WrkMast wrkMast = wrkMastService.selectById(notifyDto.getSuperTaskNo()); switch (notifyDto.getMsgType()){ case "task_complete": if (wrkMast != null && (wrkMast.getIoType() == 1 || wrkMast.getIoType() == 10 || wrkMast.getIoType() == 53 || wrkMast.getIoType() == 57 || wrkMast.getIoType() == 11)){ wrkMast.setWrkSts(4L); if (!wrkMastService.updateById(wrkMast)){ return R.error("修改工作档失败====>4"); } }else if (wrkMast != null && (wrkMast.getIoType() == 101 || wrkMast.getIoType() == 103 ||wrkMast.getIoType() == 107 || wrkMast.getIoType() == 110)){ wrkMast.setWrkSts(14L); if (!wrkMastService.updateById(wrkMast)){ return R.error("修改工作档失败====>14"); } } break; case "task_cancel": if(wrkMast == null) { return R.ok("任务不存在"); } workService.cancelWrkMast(notifyDto.getSuperTaskNo(), 9527L); } return R.ok(); } @PostMapping("/change/loc/v1") @ResponseBody @Transactional public synchronized R getLocNoChange(@RequestBody(required = false) GetLocNoChangeParam param) { log.info("收到WCS申请在库库位更换库位请求====>>入参:{}", param); StartupDto dto = applyChangeLocNo(param.getLocNo(), param.getRow()); log.info("WCS申请在库库位更换库位接口返参:{}", dto); return R.ok().add(dto); } @Transactional public StartupDto applyChangeLocNo(String wcsLocNo, int[] row) { if (row.length == 0) { throw new CoolException(wcsLocNo + "库位,WCS上报无可用设备"); } String sourceLocNo = loc(wcsLocNo); LocMast sourceLocMast = locMastService.selectOne(new EntityWrapper().eq("loc_no", sourceLocNo)); if (sourceLocMast == null) { throw new CoolException("源库位不存在"); } if(!sourceLocMast.getLocSts().equals("F")) { throw new CoolException("源库位不处于在库状态"); } List locDetlList = locDetlService.selectList(new EntityWrapper().eq("loc_no", sourceLocNo)); LocTypeDto locTypeDto = new LocTypeDto(); locTypeDto.setLocType1(sourceLocMast.getLocType1()); StartupDto dto = null; // 根据库位排映射堆垛机 for(int i = 0; i < row.length/4 ; i ++) { ArrayList rows = new ArrayList<>(); rows.add(row[i * 4]); rows.add(row[i * 4 + 1]); rows.add(row[i * 4 + 2]); rows.add(row[i * 4 + 3]); dto = commonService.getLocNoNew(1, 0, Integer.valueOf(locTypeDto.getLocType1()),rows); if (dto != null) { break; } } if (dto == null) { throw new CoolException("没有匹配到库位,检查可用库位/堆垛机报警"); } LocMast loc = locMastService.selectById(dto.getLocNo()); if (Cools.isEmpty(loc)){ throw new CoolException("未找到库位"); } Date now = new Date(); // 获取工作号 int workNo = commonService.getWorkNo(WorkNoType.PICK.type); dto.setTaskNo(workNo); // 保存工作档 WrkMast wrkMast = new WrkMast(); wrkMast.setWrkNo(workNo); wrkMast.setIoTime(now); wrkMast.setWrkSts(12L); // 工作状态 wrkMast.setIoType(11); // 入出库状态: 11.库格移载 wrkMast.setIoPri(10D); wrkMast.setSourceLocNo(sourceLocNo); // 源库位 wrkMast.setLocNo(dto.getLocNo()); // 目标库位 wrkMast.setFullPlt("Y"); // 满板:Y wrkMast.setPicking("N"); // 拣料 wrkMast.setExitMk("N"); // 退出 wrkMast.setBarcode(sourceLocMast.getBarcode()); // 托盘码 wrkMast.setEmptyMk(sourceLocMast.getLocSts().equals("D") ? "Y" : "N"); wrkMast.setLinkMis("N"); wrkMast.setAppeTime(now); wrkMast.setModiTime(now); boolean res = wrkMastService.insert(wrkMast); if (!res) { throw new CoolException("保存工作档失败"); } // 工作档明细保存 for (LocDetl locDetl : locDetlList) { WrkDetl wrkDetl = new WrkDetl(); wrkDetl.sync(locDetl); wrkDetl.setWrkNo(workNo); wrkDetl.setIoTime(now); wrkDetl.setAnfme(locDetl.getAnfme()); wrkDetl.setAppeTime(now); wrkDetl.setModiTime(now); if (!wrkDetlService.insert(wrkDetl)) { throw new CoolException("保存工作档明细失败"); } } // 修改源库位状态 if (sourceLocMast.getLocSts().equals("D") || sourceLocMast.getLocSts().equals("F")) { sourceLocMast.setLocSts("R"); // R.出库预约 sourceLocMast.setModiTime(now); if (!locMastService.updateById(sourceLocMast)){ throw new CoolException("更新源库位状态失败"); } } else { throw new CoolException("源库位出库失败,状态:" + sourceLocMast.getLocSts$()); } // 修改目标库位状态 if (loc.getLocSts().equals("O")) { loc.setLocSts("S"); // S.入库预约 loc.setModiTime(now); if (!locMastService.updateById(loc)) { throw new CoolException("更新目标库位状态失败"); } } else { throw new CoolException("移转失败,目标库位状态:"+loc.getLocSts$()); } dto.setLocNo(Utils.locToLocNo(dto.getLocNo())); return dto; } public String loc(String locNo){ String[] split = locNo.split("-"); return Utils.getLocNo(Integer.parseInt(split[0]),Integer.parseInt(split[1]),Integer.parseInt(split[2])); } @Resource private LocMastMapper locMastMapper; @RequestMapping("/auto21") public R auto21(@RequestBody List rows) { List locMastList = locMastMapper.selectLocByTypeAndRowsToList(1, rows); return R.ok(locMastList); } @PostMapping("/auto/emptyIn/v1") @ResponseBody public R autoEmptyIn(@RequestBody LocTypeDto locTypeDto) { // 源站点状态检测 BasDevp sourceStaNo = basDevpService.checkSiteStatus(12, true); // 检索库位 FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo(); StartupDto dto = commonService.getLocNo(10, 12, findLocNoAttributeVo, locTypeDto); Date now = new Date(); // 生成工作档 WrkMast wrkMast = new WrkMast(); wrkMast.setWrkNo(dto.getTaskNo()); wrkMast.setIoTime(now); wrkMast.setWrkSts(1L); wrkMast.setIoPri(13D); wrkMast.setIoType(10); wrkMast.setCrnNo(dto.getCrnNo()); wrkMast.setSourceStaNo(dto.getSourceStaNo() + ""); wrkMast.setStaNo(dto.getStaNo() + ""); wrkMast.setLocNo(dto.getLocNo()); wrkMast.setFullPlt("N"); // 满板:N wrkMast.setPicking("N"); // 拣料 wrkMast.setExitMk("N"); // 退出 wrkMast.setEmptyMk("Y"); // 空板 wrkMast.setLinkMis("Y"); wrkMast.setCtnType(sourceStaNo.getCtnType()); // 容器类型 // 操作人员数据 wrkMast.setAppeTime(now); wrkMast.setModiTime(now); wrkMast.setMemo("自动空托入库"); return wrkMastService.insert(wrkMast) ? R.ok("自动空托入库成功,工作号:" + wrkMast.getWrkNo()) : R.error("生成自动空托入库失败"); } @PostMapping("auto/emptyOut/v1") @ResponseBody public R autoEmptyOut() { LocMast locMast = locMastService.selectOne(new EntityWrapper() .eq("loc_sts", "D")); if (Cools.isEmpty(locMast)) { return R.error("库存没有空板"); } EmptyPlateOutParam emptyPlateOutParam = new EmptyPlateOutParam(); emptyPlateOutParam.setOutSite(12); emptyPlateOutParam.setLocNos(new ArrayList() {{ add(locMast.getLocNo() + ""); }}); WrkMast wrkMast = workService.emptyPlateOut(emptyPlateOutParam); return R.ok(!Cools.isEmpty(wrkMast) ? R.ok("自动空托出库成功,工作号:" + wrkMast.getWrkNo()) : R.error("生成自动空托出库失败")); } /** * 全板入库 */ @Transactional public StartupDto startupFullPutStore(Integer devpNo, String barcode, LocTypeDto locTypeDto, List waitPakins, int[] row) { // 源站点状态检测 // BasDevp sourceStaNo = basDevpService.checkSiteStatus(devpNo, true); // 检索库位 // FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo(waitPakins.get(0)); // StartupDto dto = commonService.getLocNo(1, devpNo, findLocNoAttributeVo, locTypeDto); StartupDto dto = null; // 根据库位排映射堆垛机 for(int i = 0; i < row.length/4 ; i ++) { ArrayList rows = new ArrayList<>(); rows.add(row[i * 4]); rows.add(row[i * 4 + 1]); rows.add(row[i * 4 + 2]); rows.add(row[i * 4 + 3]); dto = commonService.getLocNoNew(1, devpNo, Integer.valueOf(locTypeDto.getLocType1()),rows); if (dto != null) { break; } } if (dto == null) { throw new CoolException("没有匹配到库位,检查可用库位/堆垛机报警"); } int workNo = dto.getTaskNo(); Date now = new Date(); // 生成工作档 WrkMast wrkMast = new WrkMast(); wrkMast.setWrkNo(workNo); wrkMast.setIoTime(new Date()); wrkMast.setWrkSts(2L); // 工作状态:生成入库ID wrkMast.setIoType(1); // 入出库状态:1.入库 wrkMast.setIoPri(13D); // 优先级 wrkMast.setCrnNo(dto.getCrnNo()); wrkMast.setSourceStaNo(dto.getSourceStaNo() + ""); wrkMast.setStaNo(dto.getStaNo() + ""); wrkMast.setLocNo(dto.getLocNo()); wrkMast.setBarcode(barcode); // 托盘码 wrkMast.setFullPlt("Y"); // 满板:Y wrkMast.setPicking("N"); // 拣料 wrkMast.setExitMk("N"); // 退出 wrkMast.setEmptyMk("N"); // 空板 wrkMast.setLinkMis("Y"); // wrkMast.setCtnType(sourceStaNo.getCtnType()); // 容器类型 // 操作人员数据 wrkMast.setAppeTime(now); wrkMast.setModiTime(now); boolean res = wrkMastService.insert(wrkMast); if (!res) { throw new CoolException("保存工作档失败"); } // 生成工作档明细 waitPakins.forEach(waitPakin -> { WrkDetl wrkDetl = new WrkDetl(); wrkDetl.sync(waitPakin); wrkDetl.setWrkNo(wrkMast.getWrkNo()); wrkDetl.setIoTime(wrkMast.getIoTime()); wrkDetl.setAppeTime(now); wrkDetl.setModiTime(now); if (!wrkDetlService.insert(wrkDetl)) { throw new CoolException("保存工作明细失败"); } }); // 更新入库通知档 ioStatus ===>> Y Wrapper wrapper = new EntityWrapper() .eq("zpallet", barcode); WaitPakin setParam = new WaitPakin(); setParam.setLocNo(dto.getLocNo()); setParam.setIoStatus("Y"); setParam.setModiTime(now); if (!waitPakinService.update(setParam, wrapper)) { throw new CoolException("更新通知档失败"); } // 更新源站点信息 // sourceStaNo.setWrkNo(workNo); // sourceStaNo.setModiTime(now); // if (!basDevpService.updateById(sourceStaNo)) { // throw new CoolException("更新源站失败"); // } // 更新目标库位状态 LocMast locMast = locMastService.selectById(dto.getLocNo()); if (locMast.getLocSts().equals("O")) { locMast.setLocSts("S"); // S.入库预约 locMast.setModiTime(now); if (!locMastService.updateById(locMast)) { throw new CoolException("改变库位状态失败"); } } else { throw new CoolException(dto.getLocNo() + "目标库位已被占用"); } dto.setLocNo(Utils.locToLocNo(dto.getLocNo())); return dto; } @Transactional public StartupDto emptyPlateIn(Integer devpNo, LocTypeDto locTypeDto, String barcode, int[] row) { // 源站点状态检测 // BasDevp sourceStaNo = basDevpService.checkSiteStatus(devpNo, true); // 检索库位 // FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo(); // StartupDto dto = commonService.getLocNo(10, devpNo, findLocNoAttributeVo, locTypeDto); StartupDto dto = null; // 根据库位排映射堆垛机 for(int i = 0; i < row.length/4 ; i ++) { ArrayList rows = new ArrayList<>(); rows.add(row[i * 4]); rows.add(row[i * 4 + 1]); rows.add(row[i * 4 + 2]); rows.add(row[i * 4 + 3]); dto = commonService.getLocNoNew(1, devpNo, Integer.valueOf(locTypeDto.getLocType1()),rows); if (dto != null) { break; } } if (dto == null) { throw new CoolException("没有匹配到库位,检查可用库位/堆垛机报警"); } int workNo = dto.getTaskNo(); Date now = new Date(); // 生成工作档 WrkMast wrkMast = new WrkMast(); wrkMast.setWrkNo(workNo); wrkMast.setIoTime(now); wrkMast.setWrkSts(2L); // 工作状态:生成入库ID wrkMast.setIoType(10); // 入出库状态:10.空板入库 wrkMast.setIoPri(13D); // 优先级 wrkMast.setCrnNo(dto.getCrnNo()); wrkMast.setSourceStaNo(dto.getSourceStaNo() + ""); wrkMast.setStaNo(dto.getStaNo() + ""); wrkMast.setLocNo(dto.getLocNo()); wrkMast.setFullPlt("N"); // 满板 wrkMast.setPicking("N"); // 拣料 wrkMast.setExitMk("N"); // 退出 wrkMast.setEmptyMk("Y"); // 空板 wrkMast.setLinkMis("Y"); wrkMast.setBarcode(barcode); // wrkMast.setCtnType(sourceStaNo.getCtnType()); // 容器类型 // 操作人员数据 wrkMast.setAppeTime(now); wrkMast.setModiTime(now); boolean res = wrkMastService.insert(wrkMast); if (!res) { throw new CoolException("保存工作档失败"); } // 更新入库通知档 ioStatus ===>> Y Wrapper wrapper = new EntityWrapper() .eq("zpallet", barcode); WaitPakin setParam = new WaitPakin(); setParam.setLocNo(dto.getLocNo()); setParam.setIoStatus("Y"); setParam.setModiTime(now); if (!waitPakinService.update(setParam, wrapper)) { throw new CoolException("更新通知档失败"); } // 更新目标库位状态 LocMast locMast = locMastService.selectById(dto.getLocNo()); if (locMast.getLocSts().equals("O")) { locMast.setLocSts("S"); // S.入库预约 locMast.setModiTime(now); if (!locMastService.updateById(locMast)) { throw new CoolException("改变库位状态失败"); } } else { throw new CoolException(dto.getLocNo() + "目标库位已被占用"); } dto.setLocNo(Utils.locToLocNo(dto.getLocNo())); return dto; } }