From ae6e248abee1211e2c4d0af4a13974d000ca3ab5 Mon Sep 17 00:00:00 2001
From: lty <876263681@qq.com>
Date: 星期二, 20 一月 2026 10:31:04 +0800
Subject: [PATCH] #移库规则

---
 src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java |  581 +++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 453 insertions(+), 128 deletions(-)

diff --git a/src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java b/src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java
index 131caf8..eba6e34 100644
--- a/src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java
+++ b/src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java
@@ -11,6 +11,7 @@
 import com.core.exception.CoolException;
 import com.zy.asrs.entity.*;
 import com.zy.asrs.entity.param.*;
+import com.zy.asrs.entity.result.FindLocNoAttributeVo;
 import com.zy.asrs.entity.result.WrkCancel;
 import com.zy.asrs.service.*;
 import com.zy.asrs.utils.Utils;
@@ -31,6 +32,7 @@
 import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
 
 /**
@@ -254,16 +256,83 @@
             throw new CoolException("鍒嗙粍鍐呮湭鎵惧埌鐩爣搴撲綅锛岃妫�鏌ユ暟鎹竴鑷存��: " + locNo);
         }
     }
+    private boolean isInNormalRule(LocMast lm) {
+        List<LocGroupOrder> locGroupAscOrder = slaveProperties.getLocGroupAscOrder();
+        if (locGroupAscOrder == null || locGroupAscOrder.isEmpty()) {
+            return false;
+        }
+        Integer row = lm.getRow1();
+        if (row == null) return false;
 
+        return locGroupAscOrder.stream()
+                .anyMatch(group ->
+                        group.getRowList() != null &&
+                                group.getRowList().contains(row)
+                );
+    }
+    /**
+     * 妫�鏌ユ甯稿簱浣嶅墠鏂规槸鍚﹀牭濉烇紙娣卞簱浣嶈鍒欙細鍓嶆柟鎺掓槸鍚︽湁璐ф垨鍏ュ簱浠诲姟锛�
+     *
+     * 鍙灞炰簬鍑哄簱鍒嗙粍瑙勫垯鍐呯殑搴撲綅杩涜妫�鏌�
+     * 濡傛灉搴撲綅涓嶅湪鍒嗙粍瑙勫垯鍐咃紝鍒欒涓轰笉闇�瑕佷弗鏍兼鏌ワ紙杩斿洖 false锛屼笉瑙﹀彂琛ラ綈锛�
+     *
+     * @param normalMasts 闇�瑕佹鏌ョ殑姝e父搴撲綅鍒楄〃锛堝凡閫氳繃 isInNormalRule 杩囨护锛�
+     * @return true = 鍓嶆柟鏈夊牭濉烇紙闇�瑕佽ˉ榻愶級锛宖alse = 鍓嶆柟娓呯┖鎴栨棤闇�妫�鏌�
+     */
+    private boolean checkDeepLocationBlocked(List<LocMast> normalMasts) {
+        if (normalMasts == null || normalMasts.isEmpty()) {
+            return false;
+        }
+        // 鑾峰彇鍑哄簱鍒嗙粍閰嶇疆锛堢敤浜庣‘璁よ鍒欒寖鍥达級
+        List<LocGroupOrder> locGroupAscOrder = slaveProperties.getLocGroupAscOrder();
+        if (locGroupAscOrder == null || locGroupAscOrder.isEmpty()) {
+            return false; // 鏃犻厤缃椂榛樿涓嶆鏌�
+        }
+
+        // 閬嶅巻姣忎釜姝e父搴撲綅
+        for (LocMast lm : normalMasts) {
+            Integer currentRow = lm.getRow1();
+            Integer bay1 = lm.getBay1();
+            Integer lev1 = lm.getLev1();
+
+            if (currentRow == null || bay1 == null || lev1 == null) {
+                continue;
+            }
+
+            // 娣卞簱浣嶆鏌ユ柟鍚戯細鍋囪 row 瓒婂ぇ瓒婃繁锛堝墠鏂规槸鏇村ぇ row 鐨勪綅缃級
+            // 浣犲彲浠ユ牴鎹疄闄呭嚭搴撴柟鍚戣皟鏁村惊鐜潯浠讹紙渚嬪浠庡皬 row 鍒板ぇ row 鎴栧弽涔嬶級
+            for (int row = currentRow + 1; row <= 5; row++) { // 鍋囪娣卞簱浣嶈寖鍥村埌 5 鎺掞紝鍙皟鏁�
+                LocMast front = getLocMastByRow(row, bay1, lev1);
+                if (front == null) {
+                    continue;
+                }
+
+                // 鏈夎揣锛團鐘舵�侊級 鈫� 鍫靛
+                if ("F".equals(front.getLocSts())) {
+                    return true;
+                }
+
+                // 鏈夊叆搴撲换鍔� 鈫� 鍫靛
+                WrkMast frontTask = wrkMastService.selectOne(
+                        new EntityWrapper<WrkMast>()
+                                .eq("source_loc_no", front.getLocNo())
+                                .eq("io_type", 100) // 鍋囪 100 涓哄叆搴撶被鍨嬶紝鍙皟鏁�
+                );
+                if (frontTask != null) {
+                    return true;
+                }
+            }
+        }
+
+        // 鎵�鏈夋甯稿簱浣嶅墠鏂归兘娓呯┖锛堟垨鏃犲墠鏂癸級
+        return false;
+    }
     @Override
     @Transactional
     public void stockOut(BasDevp staNo, List<LocDetlDto> locDetlDtos, IoWorkType ioWorkType, Long userId) {
         Date now = new Date();
 
-        // 浠庨厤缃幏鍙栧垎缁勶紙鍜岀┖鏉垮嚭搴撲繚鎸佷竴鑷达級
-        List<LocGroupOrder> locGroupAscOrder = slaveProperties.getLocGroupAscOrder();
-
-        // 鍚堝苟鍚岀被椤癸紙鐩稿悓 locNo 鐨勬槑缁嗗悎骞讹級
+        // 淇濈暀锛氬悎骞跺悓绫婚」锛堝悓涓�搴撲綅鍚堝苟鏄庣粏锛�
         Set<String> locNos = new HashSet<>();
         List<OutLocDto> dtos = new ArrayList<>();
         for (LocDetlDto locDetlDto : locDetlDtos) {
@@ -280,67 +349,106 @@
                 dtos.add(new OutLocDto(locNo, locDetlDto));
             }
         }
+        // 浣跨敤鍑哄簱涓撶敤鍒嗙粍閰嶇疆
+        List<LocGroupOrder> locGroupAscOrder = slaveProperties.getLocGroupAscOrder();
+        // 纭畾姝e父鍑哄簱绫诲瀷锛堝拰鍘熸潵淇濇寔绫讳技锛�
+        int ioTypeNormal = 101; // 榛樿鏁存墭鍑哄簱
+        if (ioWorkType != null && ioWorkType.equals(IoWorkType.CHECK_OUT)) {
+            ioTypeNormal = 107;
+        } else if (!dtos.isEmpty() && !dtos.get(0).isAll()) {
+            ioTypeNormal = 103; // 閮ㄥ垎鍑哄簱
+        }
 
-        Integer ioType = null;
+        // 1. 鏌ヨ鎵�鏈夐�変腑鐨勫簱浣嶄富淇℃伅
+        List<LocMast> allSelectedMasts = locMastService.selectList(
+                new EntityWrapper<LocMast>().in("loc_no", locNos)
+        );
 
-        // 鎸夊垪鍜屽眰鍒嗙粍搴撲綅锛坆ay + lev锛�
-        Map<String, List<OutLocDto>> locGroups = dtos.stream()
-                .collect(Collectors.groupingBy(dto -> {
-                    String column = dto.getLocNo().substring(3, 6); // 鍒楀彿
-                    String level = dto.getLocNo().substring(6);     // 灞傚彿
-                    return column + "-" + level;
-                }));
+        if (allSelectedMasts.size() != locNos.size()) {
+            throw new CoolException("閮ㄥ垎閫変腑搴撲綅涓嶅瓨鍦ㄦ垨鏁版嵁寮傚父");
+        }
 
-        // 閬嶅巻姣忕粍
-        for (Map.Entry<String, List<OutLocDto>> entry : locGroups.entrySet()) {
-            List<OutLocDto> groupDtos = entry.getValue();
+        // 2. 鍖哄垎姝e父搴撲綅锛堥渶瑕佷弗鏍兼繁搴撲綅妫�鏌ワ級涓庤ˉ鍏呭簱浣�
+        List<LocMast> normalMasts = new ArrayList<>();
+        List<LocMast> supplementMasts = new ArrayList<>();
 
-            // 缁勫唴浼樺厛绾ч噸鏂颁粠100寮�濮嬶紙鍘熸湁閫昏緫锛�
-            double priority = 100;
+        // 鍋囪鎴戜滑鏈夋煇绉嶁�滃垎缁勮鍒欌�濓紙濡傛寜鍒楀眰鎴栨帓鑼冨洿锛夛紝杩欓噷绠�鍖栫敤涓�涓ず渚嬪垽鏂�
+        // 浣犲彲浠ユ浛鎹㈡垚瀹為檯鐨勮鍒欙紙濡� getLocGroupOrderOut() 鎴栧叾浠栵級
+        for (LocMast lm : allSelectedMasts) {
+            boolean isNormal = isInNormalRule(lm); // 鈫� 浣犻渶瑕佸疄鐜拌繖涓垽鏂柟娉�
+            if (isNormal) {
+                normalMasts.add(lm);
+            } else {
+                supplementMasts.add(lm);
+            }
+        }
 
-            // 鎺掑簭缁勫唴搴撲綅锛堟帓鍙峰�掑簭锛屽師鏈夐�昏緫锛�
-            groupDtos.sort(Comparator.comparing((OutLocDto dto) -> Integer.valueOf(dto.getLocNo().substring(0, 2))).reversed());
+        // 3. 瀵规甯稿簱浣嶈繘琛屾繁搴撲綅鍓嶆柟妫�鏌ワ紙绫讳技涔嬪墠鐨勮繛缁 + 娓呯┖锛�
+        AtomicReference<Boolean> isLeftSideSupplement = new AtomicReference<>(false);
 
-            for (OutLocDto dto : groupDtos) {
-                String locNo = dto.getLocNo();
+        if (!normalMasts.isEmpty()) {
+            // 杩欓噷妯℃嫙娣卞簱浣嶅墠鏂规鏌ワ紙浣犲彲浠ユ浛鎹㈡垚浣犲疄闄呯殑妫�鏌ユ柟娉曪級
+            boolean hasBlockage = checkDeepLocationBlocked(normalMasts);
 
-                // 鑾峰彇搴撲綅淇℃伅锛堟彁鍓嶈幏鍙栵紝鐢ㄤ簬妫�鏌ュ拰鍚庣画浣跨敤锛�
-                LocMast locMast = locMastService.selectById(locNo);
-                if (Cools.isEmpty(locMast)) {
-                    throw new CoolException(locNo + "搴撲綅涓嶅瓨鍦�");
+            if (hasBlockage) {
+                // 鍓嶆柟鍫靛 鈫� 鑷姩琛ュ厖鏈�灏戜竴渚�
+                supplementBothSidesBlocked(normalMasts, locGroupAscOrder, supplementMasts, isLeftSideSupplement);
+            }
+        }
+
+        // 4. 鍚堝苟鎵�鏈夎鍑哄簱鐨勫簱浣�
+        List<LocMast> allMasts = new ArrayList<>();
+        allMasts.addAll(normalMasts);
+        allMasts.addAll(supplementMasts);
+
+        if (allMasts.isEmpty()) {
+            throw new CoolException("娌℃湁鏈夋晥鐨勫嚭搴撳簱浣�");
+        }
+
+        // 5. 缁熶竴鎸夋帓鍙凤紙row锛夊�掑簭鎺掑簭锛堥珮鎺掑厛鍑猴級
+        List<LocMast> sortedAll = allMasts.stream()
+                .sorted(Comparator.comparing(LocMast::getRow1, Comparator.reverseOrder()))
+                .collect(Collectors.toList());
+
+        // 6. 鐢熸垚浠诲姟锛堜粠鍚庡線鍓嶉亶鍘嗭級
+        double basePriority = 100.0;
+        for (int index = sortedAll.size() - 1; index >= 0; index--) {
+            LocMast locMast = sortedAll.get(index);
+            String locNo = locMast.getLocNo();
+
+            boolean isSupplement = supplementMasts.contains(locMast);
+            int ioType = isSupplement ? 11 : ioTypeNormal;
+            // 浼樺厛绾ц绠�
+            double priority;
+            if (isSupplement) {
+                if (Boolean.TRUE.equals(isLeftSideSupplement.get())) {
+                    // 宸︿晶琛ュ厖 鈫� 鏅氬嚭
+                    priority = basePriority - index * 1.0;
+                } else {
+                    // 鍙充晶琛ュ厖 鈫� 鏃╁嚭
+                    priority = basePriority + index * 1.0;
                 }
-                if (!locMast.getLocSts().equals("F")) {
-                    throw new CoolException(locNo + "鎵樼洏闈炲湪搴撶姸鎬�");
-                }
-
-                // =====================================
-                // 娣卞簱浣嶅墠鏂瑰牭濉炴鏌ワ紙鏂伴�昏緫锛屾寜鍒嗙粍椤哄簭锛�
-                checkDeepPositionBlocking(locMast, locNo, locGroupAscOrder);
-                // =====================================
-
-                // 璁$畻浼樺厛绾э紙鍘熸湁閫昏緫锛�
-                dto.setPriority(priority);
-                priority--;
-
-                // 鍒ゆ柇鍏ュ嚭搴撶被鍨�
-                if (ioWorkType == null) {
-                    ioType = dto.isAll() ? 101 : 103;
-                } else if (ioWorkType.equals(IoWorkType.CHECK_OUT)) {
-                    ioType = 107;
-                }
-                assert ioType != null;
-
-                Integer outSta = staNo.getDevNo();
-
-                // 鑾峰彇璺緞
-                StaDesc staDesc = staDescService.queryCrnStn(ioType, locMast.getCrnNo(), outSta);
-
-                // 鐢熸垚宸ヤ綔鍙�
-                int workNo = commonService.getWorkNo(WorkNoType.getWorkNoType(ioType));
-                String pick = ioType == 101 ? "N" : "Y";
-
+            } else {
+                priority = basePriority - index * 1.0;
+            }
+            OutLocDto dto;
+            Integer outSta = staNo.getDevNo();
+            StaDesc staDesc = null;
+            if(ioType != 11){
+                staDesc = staDescService.queryCrnStn(ioType, locMast.getCrnNo(), outSta);
+            }
+            LocMast locMastNew = null;
+            WrkMast wrkMast = new WrkMast();
+            String locSts;
+            int workNo = commonService.getWorkNo(WorkNoType.getWorkNoType(ioType));
+            String pick = (ioType == 101) ? "N" : "Y";
+            if((ioType == 101 || ioType == 103 || ioType == 107) && staDesc != null) {
+                // 鎵惧埌瀵瑰簲鐨� OutLocDto
+                dto = dtos.stream()
+                        .filter(d -> d.getLocNo().equals(locNo))
+                        .findFirst()
+                        .orElseThrow(() -> new CoolException("鎵句笉鍒板搴旂殑鍑哄簱鏄庣粏锛�" + locNo));
                 // 鐢熸垚宸ヤ綔妗�
-                WrkMast wrkMast = new WrkMast();
                 wrkMast.setWrkNo(workNo);
                 wrkMast.setIoTime(now);
                 wrkMast.setWrkSts(0L);
@@ -360,11 +468,8 @@
                 wrkMast.setAppeTime(now);
                 wrkMast.setModiUser(userId);
                 wrkMast.setModiTime(now);
-                if (!wrkMastService.insert(wrkMast)) {
-                    throw new CoolException("淇濆瓨宸ヤ綔妗eけ璐ワ紝鍑哄簱搴撲綅鍙凤細" + locNo);
-                }
-
-                // 鐢熸垚宸ヤ綔妗f槑缁�
+                locSts = ioType != 101? "R" : "P";
+                // 鐢熸垚宸ヤ綔妗f槑缁嗭紙淇濈暀鍘熼�昏緫锛�
                 for (LocDetlDto detlDto : dto.getLocDetlDtos()) {
                     if (detlDto.getCount() == null || detlDto.getCount() <= 0.0D) {
                         continue;
@@ -384,19 +489,81 @@
                         throw new CoolException("淇濆瓨宸ヤ綔妗f槑缁嗗け璐�");
                     }
                 }
+            }else{
+                List<LocDetl> locDetls = locDetlService.selectList(new EntityWrapper<LocDetl>().eq("loc_no",locNo));
+                FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo();
+                findLocNoAttributeVo.setMatnr(locDetls.get(0).getMatnr());
+                findLocNoAttributeVo.setBatch(locDetls.get(0).getBatch());
+                LocTypeDto locTypeDto = new LocTypeDto();
+                locTypeDto.setLocType1(locMast.getLocType1());
+                locMastNew = commonService.searchMaxPallet(findLocNoAttributeVo,locTypeDto);
+                // 鐢熸垚宸ヤ綔妗�
+                wrkMast.setWrkNo(workNo);
+                wrkMast.setIoTime(now);
+                wrkMast.setWrkSts(0L);
+                wrkMast.setIoType(ioType);
+                wrkMast.setIoPri(priority);
+                wrkMast.setCrnNo(locMast.getCrnNo());
+                wrkMast.setSourceStaNo(null);
+                wrkMast.setStaNo(null);
+                wrkMast.setSourceLocNo(locNo);
+                wrkMast.setLocNo(locMastNew.getLocNo());
+                wrkMast.setFullPlt("Y");
+                wrkMast.setPicking(pick);
+                wrkMast.setExitMk("N");
+                wrkMast.setEmptyMk("N");
+                wrkMast.setLinkMis("N");
+                wrkMast.setBarcode(locMast.getBarcode());
+                wrkMast.setAppeUser(userId);
+                wrkMast.setAppeTime(now);
+                wrkMast.setModiUser(userId);
+                wrkMast.setModiTime(now);
+                locSts = "R";
+                // 鐢熸垚宸ヤ綔妗f槑缁嗭紙淇濈暀鍘熼�昏緫锛�
+                if(locDetls != null && locDetls.size() > 0) {
+                    for (LocDetl locDetl : locDetls) {
+                        WrkDetl wrkDetl = new WrkDetl();
+                        wrkDetl.sync(locDetl);
+                        wrkDetl.setWrkNo(workNo);
+                        wrkDetl.setIoTime(now);
 
-                // 淇敼搴撲綅鐘舵��
-                locMast = locMastService.selectById(locNo);  // 閲嶆柊鑾峰彇鏈�鏂扮姸鎬�
-                if (locMast.getLocSts().equals("F")) {
-                    locMast.setLocSts(ioType == 101 ? "R" : "P");
-                    locMast.setModiUser(userId);
-                    locMast.setModiTime(now);
-                    if (!locMastService.updateById(locMast)) {
-                        throw new CoolException("棰勭害搴撲綅鐘舵�佸け璐ワ紝搴撲綅鍙凤細" + locNo);
+                        wrkDetl.setAppeTime(now);
+                        wrkDetl.setAppeUser(userId);
+                        wrkDetl.setModiTime(now);
+                        wrkDetl.setModiUser(userId);
+                        if (!wrkDetlService.insert(wrkDetl)) {
+                            throw new CoolException("淇濆瓨宸ヤ綔妗f槑缁嗗け璐�");
+                        }
+                    }
+                }
+            }
+            if (!wrkMastService.insert(wrkMast)) {
+                throw new CoolException("淇濆瓨宸ヤ綔妗eけ璐ワ紝搴撲綅锛�" + locNo);
+            }
+
+            if(locMastNew != null){
+                if ("O".equals(locMastNew.getLocSts())) {
+                    locMastNew.setLocSts("S");
+                    locMastNew.setModiUser(userId);
+                    locMastNew.setModiTime(now);
+                    if (!locMastService.updateById(locMastNew)) {
+                        throw new CoolException("鏇存柊搴撲綅鐘舵�佸け璐ワ紝搴撲綅锛�" + locNo);
                     }
                 } else {
-                    throw new CoolException(locNo + "搴撲綅涓嶆槸鍦ㄥ簱鐘舵��");
+                    throw new CoolException("搴撲綅鐘舵�佸紓甯革紝闈炵┖鏉跨姸鎬侊細" + locNo);
                 }
+            }
+            // 鏇存柊搴撲綅鐘舵��
+            locMast = locMastService.selectById(locNo);
+            if ("F".equals(locMast.getLocSts())) {
+                locMast.setLocSts(locSts);
+                locMast.setModiUser(userId);
+                locMast.setModiTime(now);
+                if (!locMastService.updateById(locMast)) {
+                    throw new CoolException("棰勭害搴撲綅鐘舵�佸け璐ワ紝搴撲綅鍙凤細" + locNo);
+                }
+            } else {
+                throw new CoolException(locNo + " 搴撲綅涓嶆槸鍦ㄥ簱鐘舵��");
             }
         }
     }
@@ -628,7 +795,7 @@
                 }
             }
 
-            // 4. 鑷冲皯鏈変竴渚ф竻绌烘墠鍏佽鍑哄簱
+            // 4. 鑷冲皯鏈変竴渚ф竻绌烘墠鍏佽鍑哄簱锛堜慨鏀癸細鏀惧锛屽鏋滀袱渚ч兘鍫碉紝杩斿洖鐗瑰畾閿欒鐮佹垨缁х画锛�
             if (!leftClear && !rightClear) {
                 return LockingCheckResultParam.fail(
                         "閫変腑娈� " + fullRows.get(minIndex) + "~" + fullRows.get(maxIndex) +
@@ -674,6 +841,83 @@
                 .eq("lev1", lev1)
                 .eq("row1", row));
     }
+
+    /**
+     * 褰撻�変腑娈典袱渚у墠鏂归兘鍫靛鏃讹紝鍒ゆ柇琛ュ摢涓�渚ч渶瑕佺殑绌烘澘鏈�灏戯紝骞舵妸閭d簺搴撲綅鍔犲叆琛ュ厖鍒楄〃
+     */
+    private void supplementBothSidesBlocked(
+            List<LocMast> normalMasts,
+            List<LocGroupOrder> locGroupAscOrder,
+            List<LocMast> supplementMasts,
+    AtomicReference<Boolean> isLeftSideSupplement) {
+
+        // 鍋囪鎵�鏈� normalMasts 鍦ㄥ悓涓�涓垎缁勶紙濡傛灉澶氬垎缁勶紝鍙惊鐜鐞嗘瘡涓垎缁勶級
+        LocGroupOrder group = locGroupAscOrder.stream()
+                .filter(g -> g.getRowList().contains(normalMasts.get(0).getRow1()))
+                .findFirst()
+                .orElseThrow(() -> new CoolException("鍒嗙粍寮傚父"));
+
+        List<Integer> fullRows = group.getRowList();
+
+        // 鍙栭�変腑娈电殑 min/max row
+        Set<Integer> selectedRowSet = normalMasts.stream()
+                .map(LocMast::getRow1)
+                .collect(Collectors.toSet());
+
+        int minRow = Collections.min(selectedRowSet);
+        int maxRow = Collections.max(selectedRowSet);
+
+        int minIndex = fullRows.indexOf(minRow);
+        int maxIndex = fullRows.indexOf(maxRow);
+
+        // 鍋囪鎵�鏈夊簱浣嶅湪鍚� bay 鍜� lev
+        Integer bay1 = normalMasts.get(0).getBay1();
+        Integer lev1 = normalMasts.get(0).getLev1();
+
+        // 璁$畻宸︿晶鍓嶆柟闇�瑕佽ˉ鍏呯殑 D 鐘舵�佸簱浣嶆暟閲忥紙浠� 0 鍒� minIndex-1 鐨� D 鐘舵�佸簱浣嶏級
+        int leftSupplementCount = 0;
+        List<LocMast> leftSupplementLocs = new ArrayList<>();
+        for (int i = 0; i < minIndex; i++) {
+            LocMast loc = getLocMastByRow(fullRows.get(i), bay1, lev1);
+            if (loc != null && "D".equals(loc.getLocSts())) {
+                leftSupplementCount++;
+                leftSupplementLocs.add(loc);
+            }
+        }
+
+        // 璁$畻鍙充晶鍓嶆柟闇�瑕佽ˉ鍏呯殑 D 鐘舵�佸簱浣嶆暟閲忥紙浠� maxIndex+1 鍒� end 鐨� D 鐘舵�佸簱浣嶏級
+        int rightSupplementCount = 0;
+        List<LocMast> rightSupplementLocs = new ArrayList<>();
+        for (int i = maxIndex + 1; i < fullRows.size(); i++) {
+            LocMast loc = getLocMastByRow(fullRows.get(i), bay1, lev1);
+            if (loc != null && "D".equals(loc.getLocSts())) {
+                rightSupplementCount++;
+                rightSupplementLocs.add(loc);
+            }
+        }
+
+        // 閫夋嫨闇�瑕佽ˉ鍏呮渶灏戠殑涓�渚э紙濡傛灉鐩哥瓑锛屼紭鍏堝乏渚э級
+        List<LocMast> chosenSupplementLocs;
+        boolean isLeft = false;
+        if (leftSupplementCount <= rightSupplementCount) {
+            chosenSupplementLocs = leftSupplementLocs;
+            isLeft = true;
+            log.info("閫夋嫨琛ュ厖宸︿晶鍓嶆柟锛屽叡 {} 涓簱浣�", leftSupplementCount);
+        } else {
+            chosenSupplementLocs = rightSupplementLocs;
+            isLeft = false;
+            log.info("閫夋嫨琛ュ厖鍙充晶鍓嶆柟锛屽叡 {} 涓簱浣�", rightSupplementCount);
+        }
+        // 璁板綍閫夋嫨鐨勪晶
+        isLeftSideSupplement.set(isLeft);
+        // 娣诲姞鍒� supplementMasts锛堥伩鍏嶉噸澶嶆坊鍔狅級
+        for (LocMast supp : chosenSupplementLocs) {
+            if (!supplementMasts.contains(supp) && !normalMasts.contains(supp)) {
+                supplementMasts.add(supp);
+            }
+        }
+    }
+
     @Override
     @Transactional
     public void emptyPlateOut(EmptyPlateOutParam param, Long userId) {
@@ -681,30 +925,83 @@
             throw new CoolException("绔欑偣涓嶅瓨鍦�");
         }
 
-        // 浣跨敤鏂扮殑鍑哄簱涓撶敤鍒嗙粍閰嶇疆
+        // 浣跨敤鍑哄簱涓撶敤鍒嗙粍閰嶇疆
         List<LocGroupOrder> locGroupAscOrder = slaveProperties.getLocGroupAscOrderOut();
 
-        // 1. 鍏堣繘琛屾暣浣撻樆濉炴鏌ワ紙鍖呭惈杩炵画鎬� + 鍙屽悜鍓嶆柟娓呯┖鏍¢獙锛�
-        LockingCheckResultParam checkResult = checkEmptyPlateBlocking(param.getLocNos(), locGroupAscOrder);
+        // 1. 鏌ヨ鎵�鏈夐�変腑鐨勫簱浣嶄俊鎭�
+        List<LocMast> selectedMasts = locMastService.selectList(
+                new EntityWrapper<LocMast>().in("loc_no", param.getLocNos())
+        );
 
-        if (!checkResult.isSuccess()) {
-            throw new CoolException(checkResult.getErrorMessage());
+        if (selectedMasts.size() != param.getLocNos().size()) {
+            throw new CoolException("閮ㄥ垎閫変腑搴撲綅涓嶅瓨鍦ㄦ垨鏁版嵁寮傚父");
         }
 
-        // 2. 鑾峰彇鎸夊嚭搴撴柟鍚戞帓搴忓ソ鐨勫簱浣嶅垪琛�
-        List<LocMast> orderedLocMasts = checkResult.getSortedSelected();
+        // 2. 鍖哄垎姝e父鍒嗙粍鍐呯殑搴撲綅 鍜� 闇�瑕佽ˉ鍏呯殑搴撲綅锛堣鍒欏鐨勶級
+        List<LocMast> normalMasts = new ArrayList<>();
+        List<LocMast> supplementMasts = new ArrayList<>();
+        for (LocMast lm : selectedMasts) {
+            boolean inAnyGroup = locGroupAscOrder.stream()
+                    .anyMatch(g -> g.getRowList().contains(lm.getRow1()));
+            if (inAnyGroup) {
+                normalMasts.add(lm);
+            } else {
+                supplementMasts.add(lm);
+            }
+        }
+        // 鏂板锛氳褰曟槸鍚﹀洜涓哄乏渚у墠鏂硅琛ュ厖
+        AtomicReference<Boolean> isLeftSideSupplement = new AtomicReference<>(false);
+        // 3. 瀵规甯稿垎缁勫唴鐨勫簱浣嶈繘琛屾鏌ワ紙鏀惧涓や晶鍫靛瑙勫垯锛�
+        if (!normalMasts.isEmpty()) {
+            List<String> normalLocNos = normalMasts.stream()
+                    .map(LocMast::getLocNo)
+                    .collect(Collectors.toList());
 
-        // 3. 浼樺厛绾у熀纭�鍙傛暟锛堟暟鍊艰秺澶т紭鍏堢骇瓒婇珮锛�
-        double BASE_PRI = 10.0;          // 鏈�浣庝紭鍏堢骇缁勫熀鍑嗭紙鏁板�兼渶澶э級
-        double GROUP_STEP = 100.0;       // 缁勯棿宸窛
-        double IN_GROUP_STEP = 1.0;      // 缁勫唴浣嶇疆宸窛
+            LockingCheckResultParam checkResult = checkEmptyPlateBlocking(
+                    normalLocNos,
+                    locGroupAscOrder
+            );
+
+            if (!checkResult.isSuccess()) {
+                String errMsg = checkResult.getErrorMessage();
+                if (errMsg.contains("涓や晶鍓嶆柟閮芥湁绌烘澘/鏁呴殰")) {
+                    // 涓や晶閮藉牭 鈫� 杩涘叆琛ラ綈閫昏緫
+                    supplementBothSidesBlocked(normalMasts, locGroupAscOrder, supplementMasts, isLeftSideSupplement);
+                } else {
+                    // 鍏朵粬閿欒锛堝涓嶈繛缁�侀潪D鐘舵�侊級鎶涘嚭
+                    throw new CoolException(errMsg);
+                }
+            }
+            // 濡傛灉鏈変竴渚ф竻绌猴紝鍒欐甯哥户缁�
+        }
+
+        // 4. 鍚堝苟鎵�鏈夊簱浣嶏紙姝e父 + 琛ュ厖鐨勶紝鍖呮嫭瑙勫垯澶栫殑鍜屽墠鏂硅ˉ鐨勶級
+        List<LocMast> allMasts = new ArrayList<>();
+        allMasts.addAll(normalMasts);
+        allMasts.addAll(supplementMasts);
+
+        if (allMasts.isEmpty()) {
+            throw new CoolException("娌℃湁鏈夋晥鐨勭┖鏉垮簱浣嶅彲鍑哄簱");
+        }
+
+        // 5. 缁熶竴鎸� row 鈫� bay 鈫� lev 鎺掑簭锛堜粠灏忓埌澶э級
+        List<LocMast> sortedAll = allMasts.stream()
+                .sorted(Comparator.comparing(LocMast::getRow1)
+                        .thenComparing(LocMast::getBay1)
+                        .thenComparing(LocMast::getLev1))
+                .collect(Collectors.toList());
 
         Date now = new Date();
 
-        // 4. 閫愪釜澶勭悊鎺掑簭鍚庣殑搴撲綅锛岀敓鎴愬嚭搴撲换鍔�
-        for (int index = orderedLocMasts.size(); index > 0; index--) {
-            LocMast locMast = orderedLocMasts.get(index);
+        // 6. 鎸夋帓搴忓悗鐨勯『搴忕敓鎴愬嚭搴撲换鍔★紙浠庡悗寰�鍓嶇敓鎴愶級
+        for (int index = 0; index <sortedAll.size() ; index ++) {
+            LocMast locMast = sortedAll.get(index);
             String locNo = locMast.getLocNo();
+
+            // 鍒ゆ柇鏄惁涓鸿ˉ鍏呭簱浣嶏紙瑙勫垯澶栫殑 鎴� 鍓嶆柟琛ョ殑锛�
+            boolean isSupplement = supplementMasts.contains(locMast);
+
+            int ioType = isSupplement ? 11 : 110;
 
             // 鑾峰彇宸ヤ綔鍙�
             int workNo = commonService.getWorkNo(WorkNoType.PAKOUT.type);
@@ -715,58 +1012,86 @@
                     .eq("stn_no", param.getOutSite())
                     .eq("crn_no", locMast.getCrnNo());
             StaDesc staDesc = staDescService.selectOne(wrapper);
-            Integer sourceStaNo = staDesc.getCrnStn();
+            Integer sourceStaNo = staDesc != null ? staDesc.getCrnStn() : null;
+
             if (Cools.isEmpty(sourceStaNo)) {
                 throw new CoolException("妫�绱㈡簮绔欏け璐ワ紝搴撲綅锛�" + locNo);
             }
 
-            // 璁$畻鍔ㄦ�佷紭鍏堢骇锛堢粍浼樺厛绾� + 缁勫唴椤哄簭鍋忕Щ锛�
-            // 杩欓噷鍋囪鎵�鏈夐�変腑鐨勫簱浣嶅湪鍚屼竴涓垎缁勶紙澶氬垎缁勫彲鍐嶇粏鍒嗭級
-            int groupIndex = locGroupAscOrder.indexOf(
-                    locGroupAscOrder.stream()
-                            .filter(g -> g.getRowList().contains(locMast.getRow1()))
-                            .findFirst()
-                            .orElse(null)
-            );
-
-            if (groupIndex == -1) {
-                throw new CoolException("鍒嗙粍绱㈠紩寮傚父: " + locNo);
-            }
-
-            double groupBasePri = BASE_PRI + (locGroupAscOrder.size() + 1 - groupIndex) * GROUP_STEP;
-
-            // 缁勫唴鍋忕Щ锛氭寜鍑哄簱椤哄簭锛坕ndex瓒婂皬瓒婂厛鍑猴紝浼樺厛绾ц秺楂� 鈫� 鏁板�艰秺澶э級
-            // 濡傛灉鏄� DESC 鏂瑰悜锛宨ndex 宸茬粡鏄�掑簭鐨勶紝鎵�浠ョ洿鎺ョ敤
-            double inGroupOffset = index * IN_GROUP_STEP;
-
-            double ioPri = groupBasePri + inGroupOffset;  // 鏁板�艰秺澶т紭鍏堢骇瓒婇珮
-
-            // 鐢熸垚宸ヤ綔妗�
+            // 璁$畻浼樺厛绾э紙绀轰緥锛氳ˉ鍏呯殑浼樺厛绾х◢浣庯級
+            double BASE_PRI = 200.0;
+            double ioPri;
             WrkMast wrkMast = new WrkMast();
-            wrkMast.setWrkNo(workNo);
-            wrkMast.setIoTime(now);
-            wrkMast.setWrkSts(0L);           // 寰呭彂閫�
-            wrkMast.setIoType(110);          // 绌烘澘鍑哄簱
-            wrkMast.setIoPri(ioPri);
-            wrkMast.setSourceStaNo(sourceStaNo);
-            wrkMast.setStaNo(param.getOutSite());
-            wrkMast.setCrnNo(locMast.getCrnNo());
-            wrkMast.setSourceLocNo(locNo);
-            wrkMast.setFullPlt("N");
-            wrkMast.setPicking("N");
-            wrkMast.setExitMk("N");
-            wrkMast.setEmptyMk("Y");
-            wrkMast.setLinkMis("N");
-            wrkMast.setAppeUser(userId);
-            wrkMast.setAppeTime(now);
-            wrkMast.setModiUser(userId);
-            wrkMast.setModiTime(now);
+            LocMast locMastNew = null;
+            if(isSupplement){
+                // 琛ュ厖鐨勫簱浣嶏細鏍规嵁鏄乏渚ц繕鏄彸渚цˉ鍏咃紝鍐冲畾浼樺厛绾ф柟鍚�
+                if (Boolean.TRUE.equals(isLeftSideSupplement.get())) {
+                    // 宸︿晶琛ュ厖 鈫� 浼樺厛绾ц緝浣庯紙鏅氬嚭锛�
+                    ioPri = BASE_PRI - index * 1.0;
+                } else {
+                    // 鍙充晶琛ュ厖 鈫� 浼樺厛绾ц緝楂橈紙鏃╁嚭锛�
+                    ioPri = BASE_PRI + index * 1.0;
+                }
+                locMastNew = commonService.searchEmptyPallet(null);
+                wrkMast.setWrkNo(workNo);
+                wrkMast.setIoTime(now);
+                wrkMast.setWrkSts(0L);
+                wrkMast.setIoType(ioType);
+                wrkMast.setIoPri(ioPri);
+                wrkMast.setSourceStaNo(null);
+                wrkMast.setLocNo(locMastNew.getLocNo());
+                wrkMast.setStaNo(null);
+                wrkMast.setCrnNo(locMast.getCrnNo());
+                wrkMast.setSourceLocNo(locNo);
+                wrkMast.setFullPlt("N");
+                wrkMast.setPicking("N");
+                wrkMast.setExitMk("N");
+                wrkMast.setEmptyMk("Y");
+                wrkMast.setLinkMis("N");
+                wrkMast.setAppeUser(userId);
+                wrkMast.setAppeTime(now);
+                wrkMast.setModiUser(userId);
+                wrkMast.setModiTime(now);
+            }else{
+                ioPri = BASE_PRI + index * 1.0;
+                wrkMast.setWrkNo(workNo);
+                wrkMast.setIoTime(now);
+                wrkMast.setWrkSts(0L);
+                wrkMast.setIoType(ioType);
+                wrkMast.setIoPri(ioPri);
+                wrkMast.setSourceStaNo(sourceStaNo);
+                wrkMast.setStaNo(param.getOutSite());
+                wrkMast.setCrnNo(locMast.getCrnNo());
+                wrkMast.setSourceLocNo(locNo);
+                wrkMast.setFullPlt("N");
+                wrkMast.setPicking("N");
+                wrkMast.setExitMk("N");
+                wrkMast.setEmptyMk("Y");
+                wrkMast.setLinkMis("N");
+                wrkMast.setAppeUser(userId);
+                wrkMast.setAppeTime(now);
+                wrkMast.setModiUser(userId);
+                wrkMast.setModiTime(now);
+            }
 
             if (!wrkMastService.insert(wrkMast)) {
                 throw new CoolException("淇濆瓨宸ヤ綔妗eけ璐ワ紝搴撲綅锛�" + locNo);
             }
 
-            // 鏇存柊搴撲綅鐘舵�� D 鈫� R锛堝嚭搴撻绾︼級
+            if(locMastNew != null){
+                if ("O".equals(locMastNew.getLocSts())) {
+                    locMastNew.setLocSts("S");
+                    locMastNew.setModiUser(userId);
+                    locMastNew.setModiTime(now);
+                    if (!locMastService.updateById(locMastNew)) {
+                        throw new CoolException("鏇存柊搴撲綅鐘舵�佸け璐ワ紝搴撲綅锛�" + locNo);
+                    }
+                } else {
+                    throw new CoolException("搴撲綅鐘舵�佸紓甯革紝闈炵┖鏉跨姸鎬侊細" + locNo);
+                }
+            }
+
+            // 鏇存柊搴撲綅鐘舵�� D 鈫� R
             if ("D".equals(locMast.getLocSts())) {
                 locMast.setLocSts("R");
                 locMast.setModiUser(userId);
@@ -1135,7 +1460,7 @@
         } else if (wrkMast.getIoType() > 100 && wrkMast.getWrkSts() != 14) {
             locNo = wrkMast.getSourceLocNo();
             // 鍑哄簱 ===>> F.鍦ㄥ簱
-            if (wrkMast.getIoType() == 101 || wrkMast.getIoType() == 103) {
+            if (wrkMast.getIoType() == 101 || wrkMast.getIoType() == 103 || wrkMast.getIoType() == 107) {
                 locSts = "F";
             // 绌烘澘鍑哄簱 ===>> D.绌烘《/绌烘爤鏉�
             } else if (wrkMast.getIoType() == 110) {

--
Gitblit v1.9.1