From 5677fd88b56cd69e416b52144734f3997ef8f8f4 Mon Sep 17 00:00:00 2001
From: cl <1442464845@qq.com>
Date: 星期二, 28 四月 2026 16:29:12 +0800
Subject: [PATCH] 找库位

---
 src/main/java/com/zy/api/service/impl/WcsApiServiceImpl.java |  219 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 218 insertions(+), 1 deletions(-)

diff --git a/src/main/java/com/zy/api/service/impl/WcsApiServiceImpl.java b/src/main/java/com/zy/api/service/impl/WcsApiServiceImpl.java
index ae42e87..1315844 100644
--- a/src/main/java/com/zy/api/service/impl/WcsApiServiceImpl.java
+++ b/src/main/java/com/zy/api/service/impl/WcsApiServiceImpl.java
@@ -7,6 +7,7 @@
 import com.core.common.Cools;
 import com.core.common.R;
 import com.core.exception.CoolException;
+import com.zy.api.controller.params.ChangeLocParams;
 import com.zy.api.controller.params.ReassignLocParams;
 import com.zy.api.controller.params.ReceviceTaskParams;
 import com.zy.api.controller.params.StopOutTaskParams;
@@ -22,6 +23,8 @@
 import com.zy.common.constant.MesConstant;
 import com.zy.common.model.LocTypeDto;
 import com.zy.common.model.StartupDto;
+import com.zy.common.model.CrnDepthRuleProfile;
+import com.zy.common.model.enums.WorkNoType;
 import com.zy.common.service.CommonService;
 import com.zy.common.utils.HttpHandler;
 import lombok.extern.slf4j.Slf4j;
@@ -60,6 +63,7 @@
     private static final int EMPTY_PALLET_REASSIGN_TARGET_LEVEL = 8;
     private static final short EMPTY_PALLET_REASSIGN_LOC_TYPE1 = 3;
     private static final short EMPTY_PALLET_REASSIGN_LOC_TYPE2 = 0;
+    private static final int CHANGE_LOC_IO_TYPE = 5;
 
     private static class ReassignCrnPool {
         private final List<Integer> crnNos;
@@ -116,6 +120,10 @@
     private ApiLogService apiLogService;
     @Autowired
     private OutboundBatchSeqReleaseGuard outboundBatchSeqReleaseGuard;
+    @Autowired
+    private BasCrnDepthRuleService basCrnDepthRuleService;
+    @Autowired
+    private RowLastnoService rowLastnoService;
 
 
     /**
@@ -718,7 +726,7 @@
             //浠诲姟
             if ("task_complete".equalsIgnoreCase(params.getMsgType())) {
 
-                if (mast.getIoType() == 1 || mast.getIoType() == 2 ||mast.getIoType() == 10) {
+                if (mast.getIoType() == 1 || mast.getIoType() == 2 || mast.getIoType() == 10 || mast.getIoType() == CHANGE_LOC_IO_TYPE) {
                     mast.setWrkSts(4L);
                 } else if (isOutboundTask(mast) && canMarkOutboundTaskComplete(mast)) {
                     mast.setWrkSts(14L);
@@ -898,6 +906,215 @@
         return R.ok("鎿嶄綔鎴愬姛").add(result);
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public R changeLoc(ChangeLocParams params) {
+        if (params == null || Cools.isEmpty(params.getLocNo())) {
+            return R.error("locNo涓嶈兘涓虹┖");
+        }
+        LocMast sourceLoc = locMastService.selectById(params.getLocNo());
+        if (sourceLoc == null) {
+            return R.error("褰撳墠搴撲綅涓嶅瓨鍦�");
+        }
+        CrnDepthRuleProfile profile = resolveChangeLocProfile(sourceLoc);
+        String validateMsg = validateChangeLocSource(sourceLoc, profile);
+        if (!Cools.isEmpty(validateMsg)) {
+            return R.error(validateMsg);
+        }
+        List<Integer> candidateRows = resolveChangeLocRows(params.getRow(), profile);
+        LocMast targetLoc = selectChangeLocTarget(sourceLoc, profile, candidateRows);
+        if (targetLoc == null) {
+            return R.error("褰撳墠鍫嗗灈鏈烘棤鍙敤绉诲簱鐩爣浣�");
+        }
+        Integer workNo = commonService.getWorkNo(WorkNoType.PICK.type);
+        Date now = new Date();
+        createChangeLocTask(workNo, sourceLoc, targetLoc, now);
+        reserveChangeLocTargetLoc(targetLoc, sourceLoc, now);
+        reserveChangeLocSourceLoc(sourceLoc, now);
+        Map<String, Object> result = new LinkedHashMap<>();
+        result.put("locNo", Utils.WMSLocToWCSLoc(targetLoc.getLocNo()));
+        result.put("taskNo", String.valueOf(workNo));
+        return R.ok("鎿嶄綔鎴愬姛").add(result);
+    }
+
+    private CrnDepthRuleProfile resolveChangeLocProfile(LocMast sourceLoc) {
+        RowLastno rowLastno = rowLastnoService.selectById(sourceLoc.getWhsType());
+        return basCrnDepthRuleService.resolveProfile(rowLastno, sourceLoc.getCrnNo(), sourceLoc.getRow1());
+    }
+
+    private String validateChangeLocSource(LocMast sourceLoc, CrnDepthRuleProfile profile) {
+        if (sourceLoc.getCrnNo() == null) {
+            return "褰撳墠搴撲綅鏈粦瀹氬爢鍨涙満";
+        }
+        if (profile == null || !profile.isDoubleExtension()) {
+            return "褰撳墠鍫嗗灈鏈洪潪鍙屾繁搴撲綅锛屼笉鏀寔绉诲簱";
+        }
+        if (sourceLoc.getRow1() == null || profile == null || !profile.isShallowRow(sourceLoc.getRow1())) {
+            return "褰撳墠搴撲綅涓嶆槸娴呭簱浣�";
+        }
+        if (!isChangeLocInStockLocSts(sourceLoc.getLocSts())) {
+            return "褰撳墠搴撲綅鐘舵�佷笉鍏佽绉诲簱";
+        }
+        return null;
+    }
+
+    private List<Integer> resolveChangeLocRows(List<Integer> requestRows, CrnDepthRuleProfile profile) {
+        if (!Cools.isEmpty(requestRows)) {
+            return requestRows.stream()
+                    .filter(Objects::nonNull)
+                    .distinct()
+                    .collect(Collectors.toList());
+        }
+        return profile == null ? Collections.emptyList() : profile.getSearchRows();
+    }
+
+    private LocMast selectChangeLocTarget(LocMast sourceLoc, CrnDepthRuleProfile profile, List<Integer> candidateRows) {
+        List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>()
+                .eq("crn_no", sourceLoc.getCrnNo())
+                .eq("loc_type1",2)
+                .eq("loc_sts", "O")
+                .orderBy("row1", true)
+                .orderBy("lev1", true)
+                .orderBy("bay1", true));
+        if (Cools.isEmpty(locMasts)) {
+            return null;
+        }
+//        for (LocMast locMast : locMasts) {
+//            if (!isChangeLocRowAllowed(locMast, candidateRows)) {
+//                continue;
+//            }
+//            if (locMast.getRow1() != null && Utils.isDeepLoc(slaveProperties, locMast.getRow1())) {
+//                return locMast;
+//            }
+//        }
+//        for (LocMast locMast : locMasts) {
+//            if (!isChangeLocRowAllowed(locMast, candidateRows)) {
+//                continue;
+//            }
+//            if (locMast.getRow1() == null || !Utils.isShallowLoc(slaveProperties, locMast.getRow1())) {
+//                continue;
+//            }
+//            String deepLocNo = Utils.getDeepLoc(slaveProperties, locMast.getLocNo());
+//            LocMast deepLoc = locMastService.selectById(deepLocNo);
+//            if (deepLoc != null && ("F".equals(deepLoc.getLocSts()) || "D".equals(deepLoc.getLocSts()))) {
+//                return locMast;
+//            }
+//        }
+        LocMast shallowFallback = null;
+        for (LocMast locMast : locMasts) {
+            //鎺掕繃婊�
+            if (!isChangeLocRowAllowed(locMast, candidateRows)) {
+                continue;
+            }
+            //娣变綅浼樺厛
+            if (isChangeLocDeepCandidate(locMast, profile)) {
+                return locMast;
+            }
+            //娴呬綅鍏滃簳
+            if (shallowFallback == null && isChangeLocShallowFallbackCandidate(locMast, profile)) {
+                shallowFallback = locMast;
+            }
+        }
+        return shallowFallback;
+    }
+
+    private boolean isChangeLocRowAllowed(LocMast locMast, List<Integer> candidateRows) {
+        if (Cools.isEmpty(candidateRows)) {
+            return true;
+        }
+        return locMast.getRow1() != null && candidateRows.contains(locMast.getRow1());
+    }
+
+    private boolean isChangeLocDeepCandidate(LocMast locMast, CrnDepthRuleProfile profile) {
+        return locMast.getRow1() != null
+                && profile != null
+                && profile.isDeepRow(locMast.getRow1());
+    }
+
+    private boolean isChangeLocShallowFallbackCandidate(LocMast locMast, CrnDepthRuleProfile profile) {
+        if (locMast.getRow1() == null || profile == null || !profile.isShallowRow(locMast.getRow1())) {
+            return false;
+        }
+        Integer deepRow = profile.getPairedDeepRow(locMast.getRow1());
+        if (deepRow == null) {
+            return false;
+        }
+        LocMast deepLoc = locMastService.selectOne(new EntityWrapper<LocMast>()
+                .eq("crn_no", locMast.getCrnNo())
+                .eq("row1", deepRow)
+                .eq("bay1", locMast.getBay1())
+                .eq("lev1", locMast.getLev1()));
+        return deepLoc != null && isChangeLocInStockLocSts(deepLoc.getLocSts());
+    }
+
+    private boolean isChangeLocInStockLocSts(String locSts) {
+        return "F".equals(locSts) || "D".equals(locSts);
+    }
+
+    private void createChangeLocTask(Integer workNo, LocMast sourceLoc, LocMast targetLoc, Date now) {
+        List<LocDetl> sourceDetls = locDetlService.selectList(new EntityWrapper<LocDetl>().eq("loc_no", sourceLoc.getLocNo()));
+        WrkMast wrkMast = new WrkMast();
+        wrkMast.setWrkNo(workNo);
+        wrkMast.setIoTime(now);
+        wrkMast.setWrkSts(11L);
+        wrkMast.setIoType(CHANGE_LOC_IO_TYPE);
+        wrkMast.setIoPri(10D);
+        wrkMast.setCrnNo(sourceLoc.getCrnNo());
+        wrkMast.setSourceLocNo(sourceLoc.getLocNo());
+        wrkMast.setLocNo(targetLoc.getLocNo());
+        wrkMast.setFullPlt(Cools.isEmpty(sourceDetls) ? "N" : "Y");
+        wrkMast.setPicking("N");
+        wrkMast.setExitMk("N");
+        wrkMast.setEmptyMk("D".equals(sourceLoc.getLocSts()) ? "Y" : "N");
+        wrkMast.setBarcode(sourceLoc.getBarcode());
+        wrkMast.setLinkMis("N");
+        wrkMast.setMemo("CHANGE_LOC");
+        wrkMast.setAppeUser(WCS_SYNC_USER);
+        wrkMast.setAppeTime(now);
+        wrkMast.setModiUser(WCS_SYNC_USER);
+        wrkMast.setModiTime(now);
+        if (!wrkMastService.insert(wrkMast)) {
+            throw new CoolException("淇濆瓨宸ヤ綔妗eけ璐�");
+        }
+        if (Cools.isEmpty(sourceDetls)) {
+            return;
+        }
+        for (LocDetl sourceDetl : sourceDetls) {
+            WrkDetl wrkDetl = new WrkDetl();
+            wrkDetl.sync(sourceDetl);
+            wrkDetl.setWrkNo(workNo);
+            wrkDetl.setIoTime(now);
+            wrkDetl.setAnfme(sourceDetl.getAnfme());
+            wrkDetl.setAppeTime(now);
+            wrkDetl.setAppeUser(WCS_SYNC_USER);
+            wrkDetl.setModiTime(now);
+            wrkDetl.setModiUser(WCS_SYNC_USER);
+            if (!wrkDetlService.insert(wrkDetl)) {
+                throw new CoolException("淇濆瓨宸ヤ綔妗f槑缁嗗け璐�");
+            }
+        }
+    }
+
+    private void reserveChangeLocTargetLoc(LocMast targetLoc, LocMast sourceLoc, Date now) {
+        targetLoc.setLocSts("S");
+        targetLoc.setBarcode(sourceLoc.getBarcode());
+        targetLoc.setScWeight(sourceLoc.getScWeight() == null ? BigDecimal.ZERO : sourceLoc.getScWeight());
+        targetLoc.setModiUser(WCS_SYNC_USER);
+        targetLoc.setModiTime(now);
+        if (!locMastService.updateById(targetLoc)) {
+            throw new CoolException("鏇存柊鐩爣搴撲綅鐘舵�佸け璐�");
+        }
+    }
+
+    private void reserveChangeLocSourceLoc(LocMast sourceLoc, Date now) {
+        sourceLoc.setLocSts("R");
+        sourceLoc.setModiUser(WCS_SYNC_USER);
+        sourceLoc.setModiTime(now);
+        if (!locMastService.updateById(sourceLoc)) {
+            throw new CoolException("鏇存柊婧愬簱浣嶇姸鎬佸け璐�");
+        }
+    }
+
     private boolean requiresOutboundErpConfirm(WrkMast wrkMast) {
         Integer ioType = wrkMast == null ? null : wrkMast.getIoType();
         return ioType != null && (ioType == 101 || ioType == 103 || ioType == 104 || ioType == 107 || ioType == 110);

--
Gitblit v1.9.1