| | |
| | | import com.zy.common.model.StartupDto; |
| | | import com.zy.common.service.CommonService; |
| | | import com.zy.common.web.param.SearchLocParam; |
| | | import com.alibaba.fastjson.JSON; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | |
| | | private WorkService workService; |
| | | @Autowired |
| | | private StaDescService staDescService; |
| | | @Autowired |
| | | private InboundCameraCaptureService inboundCameraCaptureService; |
| | | |
| | | @PostMapping("/pakin/loc/v1") |
| | | @ResponseBody |
| | | public synchronized R getLocNo(@RequestBody SearchLocParam param, HttpServletRequest request) { |
| | | long startTime = System.currentTimeMillis(); |
| | | if (param != null && request != null) { |
| | | log.info("[getLocNo] cache: {}", JSON.toJSONString(param)); |
| | | request.setAttribute("cache", param); |
| | | } |
| | | String barcode = param == null ? null : param.getBarcode(); |
| | |
| | | } |
| | | WrkMast wrkMast1 = wrkMastService.selectByBarcode(param.getBarcode()); |
| | | if (!Cools.isEmpty(wrkMast1) && wrkMast1.getWrkSts() == 2) { |
| | | triggerInboundCaptureAfterLocAssigned(wrkMast1); |
| | | StartupDto dto1 = new StartupDto(); |
| | | dto1.setBarcode(param.getBarcode()); |
| | | dto1.setStaNo(Integer.valueOf(wrkMast1.getStaNo())); |
| | |
| | | // } |
| | | waitPakins = waitPakinService.selectList(new EntityWrapper<WaitPakin>().eq("zpallet", param.getBarcode())); |
| | | if (Cools.isEmpty(waitPakins)) { |
| | | return R.error("请先添加入库通知档"); |
| | | return R.error("请先收货后再入库"); |
| | | // WrkMast wrkMast = wrkMastService.selectByBarcode(param.getBarcode()); |
| | | // if (wrkMast != null && wrkMast.getIoType() == 103) { |
| | | // return R.parse(CodeRes.PICK_600); |
| | |
| | | |
| | | // 源站点状态检测 |
| | | BasDevp sourceStaNoEntity = basDevpService.checkSiteStatus(param.getSourceStaNo(), true); |
| | | sourceStaNoEntity.setLocType1(param.getLocType1()); |
| | | sourceStaNoEntity.setLocType1((short) (param.getLocType1()!=1?2:1)); |
| | | LocTypeDto locTypeDto = new LocTypeDto(sourceStaNoEntity); |
| | | if (waitPakins.get(0).getMatnr().equals("emptyPallet")) { |
| | | // 空托盘由组托档 matnr=emptyPallet 标识;后续 CommonService 会按窄库位优先、locType1=3 兜底规则找库位。 |
| | | locTypeDto.setLocType2((short) 1); |
| | | } |
| | | |
| | | // 入参重量最多两位小数 |
| | | if (param.getWeight() != null) { |
| | | param.setWeight(param.getWeight().setScale(2, RoundingMode.HALF_UP)); |
| | | } |
| | | |
| | | StartupDto dto = startupFullPutStore(param.getSourceStaNo(), param.getBarcode(), locTypeDto, waitPakins,param.getWeight()); |
| | |
| | | } |
| | | sourceStaNo.setLocType1(param.getLocType1()); |
| | | LocTypeDto locTypeDto = new LocTypeDto(sourceStaNo); |
| | | // AGV 空托盘直入库固定走 staDescId=10,最终由 CommonService.getLocNo 统一执行找位规则。 |
| | | param.setIoType(10); |
| | | StartupDto dto = null; |
| | | switch (param.getIoType()) { |
| | |
| | | public StartupDto startupFullPutStoreAgv(Integer devpNo, String barcode, LocTypeDto locTypeDto, Integer outArea, Integer staDescId) { |
| | | // 源站点状态检测 |
| | | // BasDevp sourceStaNo = basDevpService.checkSiteStatus(devpNo, true); |
| | | // 检索库位 |
| | | // 检索库位;staDescId=10 时按空托盘入口识别,进入 CommonService 的优先池 + locType1=3 兜底找位规则。 |
| | | FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo(); |
| | | findLocNoAttributeVo.setOutArea(outArea); |
| | | // FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo(waitPakins.get(0)); |
| | |
| | | try { |
| | | // 源站点状态检测 |
| | | BasDevp sourceStaNo = basDevpService.checkSiteStatus(devpNo, true); |
| | | // 检索库位 |
| | | List<String> matnrs = waitPakins.stream().map(WaitPakin::getMatnr).distinct().collect(Collectors.toList()); |
| | | List<String> batchs = waitPakins.stream().map(WaitPakin::getBatch).distinct().collect(Collectors.toList()); |
| | | FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo(matnrs.get(0), batchs.get(0)); |
| | | // FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo(waitPakins.get(0)); |
| | | // 检索库位;如果组托档是 emptyPallet,即使 staDescId=1,也会在 CommonService 内切换为空托盘找位规则。 |
| | | FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo(waitPakins.get(0)); |
| | | // IoT 指定了目标库位时优先尝试该库位;不可用时再退回现有自动找位规则。 |
| | | StartupDto dto = buildPreferredStartupDto(devpNo, extractPreferredInboundLoc(waitPakins)); |
| | | if (dto == null) { |
| | |
| | | wrkMast.setScWeight(weight); |
| | | // 把 referenceId/orderNo 透传到工作主档,便于作业完成后继续回传给 IoT。 |
| | | wrkMast.setUserNo(waitPakins.get(0).getOrderNo()); |
| | | wrkMast.setCubeNumber(waitPakins.get(0).getCubeNumber()); |
| | | wrkMast.setCtnType(sourceStaNo.getCtnType()); // 容器类型 |
| | | // WCS申请入库时,WMS找到库位后立即拍照;定时任务只作为未处理状态的兜底。 |
| | | wrkMast.setMemo(InboundCameraCaptureService.CAPTURE_PENDING); |
| | | wrkMast.setPlateNo(waitPakins.get(0).getPlateNo()); |
| | | wrkMast.setTrainNo(waitPakins.get(0).getTrainNo()); |
| | | // 操作人员数据 |
| | | wrkMast.setAppeTime(now); |
| | | wrkMast.setModiTime(now); |
| | |
| | | String wcsLoc = Utils.WMSLocToWCSLoc(dto.getLocNo()); |
| | | dto.setLocNo(wcsLoc); |
| | | dto.setTaskNo(workNo + ""); |
| | | triggerInboundCaptureAfterLocAssigned(wrkMast); |
| | | return dto; |
| | | } finally { |
| | | log.info("startupFullPutStore耗时:{}ms, sourceStaNo:{}, barcode:{}", System.currentTimeMillis() - startTime, devpNo, barcode); |
| | | } |
| | | } |
| | | |
| | | private void triggerInboundCaptureAfterLocAssigned(WrkMast wrkMast) { |
| | | if (!shouldTriggerInboundCapture(wrkMast)) { |
| | | return; |
| | | } |
| | | try { |
| | | ensureInboundCapturePending(wrkMast); |
| | | inboundCameraCaptureService.processPendingCapture(wrkMast); |
| | | } catch (Exception e) { |
| | | log.warn("WCS申请入库后触发拍照失败:workNo={}, sourceStaNo={}, locNo={}, barcode={}", |
| | | wrkMast.getWrkNo(), wrkMast.getSourceStaNo(), wrkMast.getLocNo(), wrkMast.getBarcode(), e); |
| | | } |
| | | } |
| | | |
| | | private boolean shouldTriggerInboundCapture(WrkMast wrkMast) { |
| | | if (wrkMast == null || wrkMast.getWrkNo() == null) { |
| | | return false; |
| | | } |
| | | if (wrkMast.getIoType() == null || wrkMast.getIoType() != 1) { |
| | | return false; |
| | | } |
| | | if (Cools.isEmpty(wrkMast.getSourceStaNo(), wrkMast.getLocNo(), wrkMast.getBarcode())) { |
| | | return false; |
| | | } |
| | | if (InboundCameraCaptureService.CAPTURE_RUNNING.equals(wrkMast.getMemo())) { |
| | | return false; |
| | | } |
| | | List<WrkDetl> wrkDetls = wrkDetlService.selectList(new EntityWrapper<WrkDetl>().eq("wrk_no", wrkMast.getWrkNo())); |
| | | if (Cools.isEmpty(wrkDetls)) { |
| | | return true; |
| | | } |
| | | for (WrkDetl wrkDetl : wrkDetls) { |
| | | if (wrkDetl != null && !Cools.isEmpty(wrkDetl.getPic())) { |
| | | return false; |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | private void ensureInboundCapturePending(WrkMast wrkMast) { |
| | | if (!Cools.isEmpty(wrkMast.getMemo())) { |
| | | return; |
| | | } |
| | | WrkMast update = new WrkMast(); |
| | | update.setMemo(InboundCameraCaptureService.CAPTURE_PENDING); |
| | | update.setModiTime(new Date()); |
| | | wrkMastService.update(update, new EntityWrapper<WrkMast>().eq("wrk_no", wrkMast.getWrkNo())); |
| | | wrkMast.setMemo(InboundCameraCaptureService.CAPTURE_PENDING); |
| | | } |
| | | |
| | | /** |
| | |
| | | public StartupDto emptyPlateIn(Integer devpNo, LocTypeDto locTypeDto, String barcode) { |
| | | // 源站点状态检测 |
| | | BasDevp sourceStaNo = basDevpService.checkSiteStatus(devpNo, true); |
| | | // 检索库位 |
| | | // 检索库位;旧空托盘入库入口固定传 staDescId=10,仍复用 CommonService 的统一空托盘找位规则。 |
| | | FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo(); |
| | | |
| | | StartupDto dto = commonService.getLocNo(10, devpNo, findLocNoAttributeVo, locTypeDto); |