From 4c66319211f9f7e496dfc32718dbd7aefed4ca88 Mon Sep 17 00:00:00 2001
From: chen.lin <1442464845@qq.com>
Date: 星期四, 12 三月 2026 10:46:47 +0800
Subject: [PATCH] 任务管理完结、取消按钮

---
 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java |  186 ++++++++++++++++++++++++++++++++++++---------
 1 files changed, 147 insertions(+), 39 deletions(-)

diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java
index 9e8ca7d..9d52495 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java
@@ -404,7 +404,9 @@
             if (Objects.isNull(station) || !station.getUseStatus().equals(LocStsType.LOC_STS_TYPE_O.type)) {
                 throw new CoolException("绔欑偣涓嶅瓨鍦ㄦ垨绔欑偣涓嶅浜庣┖搴撶姸鎬侊紒锛�");
             }
-            station.setUseStatus(LocStsType.LOC_STS_TYPE_R.type);
+            if (!station.getType().equals(0)){
+                station.setUseStatus(LocStsType.LOC_STS_TYPE_R.type);
+            }
 
             if (!basStationService.updateById(station)) {
                  throw new CoolException("绔欑偣鐘舵�佹洿鏂板け璐ワ紒锛�");
@@ -854,40 +856,86 @@
                 || TaskType.TASK_TYPE_CHECK_IN.type.equals(task.getTaskType())
                 || TaskType.TASK_TYPE_EMPTY_IN.type.equals(task.getTaskType())
                 || TaskType.TASK_TYPE_MERGE_IN.type.equals(task.getTaskType())
-                || TaskType.TASK_TYPE_LOC_MOVE.type.equals(task.getTaskType())) {
-            task.setTaskStatus(TaskStsType.COMPLETE_IN.id);
-        } else if (TaskType.TASK_TYPE_OUT.type.equals(task.getTaskType())) {
-            task.setTaskStatus(TaskStsType.COMPLETE_OUT.id);
-        } else if (TaskType.TASK_TYPE_PICK_AGAIN_OUT.type.equals(task.getTaskType())
-                || TaskType.TASK_TYPE_CHECK_OUT.type.equals(task.getTaskType())) {
-            task.setTaskStatus(TaskStsType.AWAIT.id);
-        } else if (TaskType.TASK_TYPE_MERGE_OUT.type.equals(task.getTaskType())) {
-            task.setTaskStatus(TaskStsType.MISSION_TRANSFER.id);
-        } else if (TaskType.TASK_TYPE_CROSS_DOCKING_OUT.type.equals(task.getTaskType())
+                || TaskType.TASK_TYPE_LOC_MOVE.type.equals(task.getTaskType())
+                || TaskType.TASK_TYPE_OUT.type.equals(task.getTaskType())
+                || TaskType.TASK_TYPE_PICK_AGAIN_OUT.type.equals(task.getTaskType())
+                || TaskType.TASK_TYPE_MERGE_OUT.type.equals(task.getTaskType())
+                || TaskType.TASK_TYPE_CHECK_OUT.type.equals(task.getTaskType())
+                || TaskType.TASK_TYPE_CROSS_DOCKING_OUT.type.equals(task.getTaskType())
                 || TaskType.TASK_TYPE_EMPTY_OUT.type.equals(task.getTaskType())) {
-            task.setTaskStatus(TaskStsType.COMPLETE_OUT.id);
+            task.setTaskStatus(TaskStsType.MISSION_TRANSFER.id);
         } else {
             return;
         }
         updateById(task);
     }
 
-    /** 缁堟�佹垨绛夊緟瀹氭椂浠诲姟鏇存柊搴撳瓨鐨勭姸鎬侊紝涓嶅睍绀哄畬鎴愭寜閽� */
+    /** 缁堟�佹垨绛夊緟瀹氭椂浠诲姟鏇存柊搴撳瓨鐨勭姸鎬併��9999锛屼笉灞曠ず瀹岀粨鎸夐挳 */
     private static final Set<Integer> TERMINAL_OR_WAITING_STATUS = new HashSet<>(Arrays.asList(
             TaskStsType.COMPLETE_IN.id, TaskStsType.REPORT_IN.id, TaskStsType.UPDATED_IN.id,
             TaskStsType.COMPLETE_OUT.id, TaskStsType.WAVE_SEED.id, TaskStsType.UPDATED_OUT.id,
-            TaskStsType.MISSION_TRANSFER_END.id));
+            TaskStsType.MISSION_TRANSFER.id, TaskStsType.MISSION_TRANSFER_END.id));
 
-    /** 瀹岀粨涓嶄緷璧栨祦绋嬫楠わ紝浠呮湭缁堟�佷换鍔″睍绀哄畬鎴愭寜閽� */
+    /** 缁堟��/9999 鏃犳寜閽紱鐘舵�佸湪姝ラ涓壘涓嶅埌鎴栨棤涓嬩竴姝ワ紙鏈�鍚庝竴姝ワ級鍒欐棤瀹岀粨鎸夐挳 */
     @Override
     public void fillCanComplete(List<Task> tasks) {
         if (tasks == null || tasks.isEmpty()) {
             return;
         }
-        for (Task task : tasks) {
-            boolean terminal = task.getTaskStatus() != null && TERMINAL_OR_WAITING_STATUS.contains(task.getTaskStatus());
-            task.setCanComplete(!terminal);
+        Set<Integer> terminalSet = TERMINAL_OR_WAITING_STATUS;
+        List<String> codes = tasks.stream().map(Task::getTaskCode).filter(Objects::nonNull).distinct().collect(Collectors.toList());
+        if (codes.isEmpty()) {
+            tasks.forEach(t -> {
+                t.setCanComplete(Boolean.FALSE);
+                t.setCanCancel(Boolean.FALSE);
+                if (t.getTaskStatus() != null && t.getTaskStatus().equals(TaskStsType.MISSION_INITIAL.id) && !isPhase2InboundType(t.getTaskType())) {
+                    t.setCanCancel(Boolean.TRUE);
+                }
+            });
+            return;
         }
+        List<FlowStepInstance> steps = codes.size() == 1
+                ? flowStepInstanceService.list(new LambdaQueryWrapper<FlowStepInstance>().eq(FlowStepInstance::getTaskNo, codes.get(0)).orderByAsc(FlowStepInstance::getStepOrder))
+                : flowStepInstanceService.list(new LambdaQueryWrapper<FlowStepInstance>().in(FlowStepInstance::getTaskNo, codes).orderByAsc(FlowStepInstance::getStepOrder));
+        Map<String, List<FlowStepInstance>> stepsByTaskNo = steps.stream().collect(Collectors.groupingBy(FlowStepInstance::getTaskNo));
+        for (Task task : tasks) {
+            if (task.getTaskStatus() != null && terminalSet.contains(task.getTaskStatus())) {
+                task.setCanComplete(Boolean.FALSE);
+                task.setCanCancel(Boolean.FALSE);
+                continue;
+            }
+            // taskStatus=0锛堣矾寰勮鍒掍腑锛夊彲鍙栨秷锛涗簩闃舵鍏ュ簱锛堟嫞鏂�/鐩樼偣/骞舵澘鍏ュ簱锛変笉鍙彇娑�
+            if (task.getTaskStatus() != null && task.getTaskStatus().equals(TaskStsType.MISSION_INITIAL.id)) {
+                task.setCanCancel(!isPhase2InboundType(task.getTaskType()));
+                task.setCanComplete(Boolean.FALSE);
+                continue;
+            }
+            List<FlowStepInstance> taskSteps = stepsByTaskNo.get(task.getTaskCode());
+            if (taskSteps == null || taskSteps.isEmpty()) {
+                task.setCanComplete(Boolean.FALSE);
+                task.setCanCancel(Boolean.FALSE);
+                continue;
+            }
+            FlowStepInstance match = taskSteps.stream()
+                    .filter(s -> s.getWmsNowTaskStatus() != null && s.getWmsNowTaskStatus().equals(task.getTaskStatus()))
+                    .findFirst().orElse(null);
+            if (match == null) {
+                task.setCanComplete(Boolean.FALSE);
+                task.setCanCancel(Boolean.FALSE);
+                continue;
+            }
+            boolean isLastStep = match.getWmsNextTaskStatus() == null || match.getWmsNextTaskStatus().equals(TaskStsType.MISSION_TRANSFER.id);
+            task.setCanComplete(!isLastStep);
+            task.setCanCancel(!isLastStep && !isPhase2InboundType(task.getTaskType()));
+        }
+    }
+
+    /** 浜岄樁娈靛叆搴擄細鎷f枡鍏ュ簱銆佺洏鐐瑰叆搴撱�佸苟鏉垮叆搴擄紝涓嶅彲鍙栨秷 */
+    private boolean isPhase2InboundType(Integer taskType) {
+        if (taskType == null) return false;
+        return taskType.equals(TaskType.TASK_TYPE_PICK_IN.type)
+                || taskType.equals(TaskType.TASK_TYPE_CHECK_IN.type)
+                || taskType.equals(TaskType.TASK_TYPE_MERGE_IN.type);
     }
 
     /**
@@ -1203,28 +1251,43 @@
     }
 
     /**
-     * 鐩樼偣鍐嶅叆搴撳畬鎴愬悗锛屽皢鍏宠仈鐨勭洏鐐瑰樊寮傚崟缃负宸插鏍革紙鏈夊崟鎸� orderId锛屾棤鍗曟寜 鍑哄簱浠诲姟鍙� orderCode锛�
+     * 鐩樼偣鍐嶅叆搴撳畬鎴愬悗锛屽皢鏈崟瀵瑰簲鐨勫樊寮傛槑缁嗙疆涓哄凡瀹℃牳锛屽叏閮ㄦ槑缁嗗凡瀹℃牳鍚庡樊寮傚崟鏈韩缃负宸插鏍革紙鏈夊崟鎸� orderId锛屾棤鍗曟寜 鍑哄簱浠诲姟鍙� orderCode锛�
      */
     @Override
     public void markCheckDiffApprovedWhenCheckInDone(Task checkInTask) {
-        List<TaskItem> items = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, checkInTask.getId()).last("limit 1"));
-        Long orderId = items.isEmpty() ? null : items.get(0).getOrderId();
+        Task outTask = taskService.getOne(new LambdaQueryWrapper<Task>()
+                .eq(Task::getBarcode, checkInTask.getBarcode())
+                .eq(Task::getTaskType, TaskType.TASK_TYPE_CHECK_OUT.type)
+                .last("limit 1"));
+        if (outTask == null) {
+            return;
+        }
+        List<TaskItem> inItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, checkInTask.getId()));
+        Long orderId = inItems.isEmpty() ? null : inItems.get(0).getOrderId();
         CheckDiff checkDiff = null;
         if (orderId != null && !orderId.equals(0L)) {
             checkDiff = checkDiffService.getOne(new LambdaQueryWrapper<CheckDiff>().eq(CheckDiff::getOrderId, orderId).last("limit 1"));
         } else {
-            Task outTask = taskService.getOne(new LambdaQueryWrapper<Task>()
-                    .eq(Task::getBarcode, checkInTask.getBarcode())
-                    .eq(Task::getTaskType, TaskType.TASK_TYPE_CHECK_OUT.type)
+            checkDiff = checkDiffService.getOne(new LambdaQueryWrapper<CheckDiff>()
+                    .eq(CheckDiff::getOrderCode, outTask.getTaskCode())
+                    .and(w -> w.isNull(CheckDiff::getOrderId).or().eq(CheckDiff::getOrderId, 0))
                     .last("limit 1"));
-            if (outTask != null) {
-                checkDiff = checkDiffService.getOne(new LambdaQueryWrapper<CheckDiff>()
-                        .eq(CheckDiff::getOrderCode, outTask.getTaskCode())
-                        .and(w -> w.isNull(CheckDiff::getOrderId).or().eq(CheckDiff::getOrderId, 0))
-                        .last("limit 1"));
-            }
         }
-        if (checkDiff != null && !CheckDiffExceStatus.CHECK_DIFF_EXCE_STATUS_END.val.equals(checkDiff.getExceStatus())) {
+        if (checkDiff == null) {
+            return;
+        }
+        List<TaskItem> outItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, outTask.getId()));
+        List<Long> outTaskItemIds = outItems.stream().map(TaskItem::getId).filter(Objects::nonNull).collect(Collectors.toList());
+        if (!outTaskItemIds.isEmpty()) {
+            checkDiffItemService.update(new LambdaUpdateWrapper<CheckDiffItem>()
+                    .eq(CheckDiffItem::getCheckId, checkDiff.getId())
+                    .in(CheckDiffItem::getTaskItemId, outTaskItemIds)
+                    .set(CheckDiffItem::getExceStatus, CheckDiffExceStatus.CHECK_DIFF_EXCE_STATUS_END.val));
+        }
+        long unApprovedCount = checkDiffItemService.count(new LambdaQueryWrapper<CheckDiffItem>()
+                .eq(CheckDiffItem::getCheckId, checkDiff.getId())
+                .ne(CheckDiffItem::getExceStatus, CheckDiffExceStatus.CHECK_DIFF_EXCE_STATUS_END.val));
+        if (unApprovedCount == 0 && !CheckDiffExceStatus.CHECK_DIFF_EXCE_STATUS_END.val.equals(checkDiff.getExceStatus())) {
             checkDiffService.update(new LambdaUpdateWrapper<CheckDiff>()
                     .eq(CheckDiff::getId, checkDiff.getId())
                     .set(CheckDiff::getExceStatus, CheckDiffExceStatus.CHECK_DIFF_EXCE_STATUS_END.val));
@@ -1241,16 +1304,20 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public R removeTask(Long[] ids, Long loginUserId) {
-        List<Integer> longs = Arrays.asList(TaskStsType.GENERATE_IN.id, TaskStsType.GENERATE_OUT.id);
         List<Integer> list = Arrays.asList(TaskType.TASK_TYPE_IN.type, TaskType.TASK_TYPE_OUT.type, TaskType.TASK_TYPE_PICK_AGAIN_OUT.type,
                 TaskType.TASK_TYPE_CHECK_OUT.type, TaskType.TASK_TYPE_EMPTY_IN.type, TaskType.TASK_TYPE_LOC_MOVE.type,
-                TaskType.TASK_TYPE_EMPTY_OUT.type, TaskType.TASK_TYPE_MERGE_OUT.type);
+                TaskType.TASK_TYPE_EMPTY_OUT.type, TaskType.TASK_TYPE_MERGE_OUT.type,
+                TaskType.TASK_TYPE_PICK_IN.type, TaskType.TASK_TYPE_CHECK_IN.type);
         List<Task> tasks = this.list(new LambdaQueryWrapper<Task>()
                 .in(Task::getTaskType, list)
-                .in(Task::getId, ids)
-                .in(Task::getTaskStatus, longs));
+                .in(Task::getId, ids));
         if (tasks.isEmpty()) {
-            throw new CoolException("浠诲姟宸插鎵ц鐘舵�佷笉鍙彇娑堬紒锛�");
+            throw new CoolException("浠诲姟涓嶅瓨鍦ㄦ垨绫诲瀷涓嶅厑璁稿彇娑堬紒锛�");
+        }
+        fillCanComplete(tasks);
+        List<Task> notCancelable = tasks.stream().filter(t -> !Boolean.TRUE.equals(t.getCanCancel())).collect(Collectors.toList());
+        if (!notCancelable.isEmpty()) {
+            throw new CoolException("閮ㄥ垎浠诲姟涓嶅彲鍙栨秷锛堟嫞鏂�/鐩樼偣/骞舵澘鍏ュ簱涓轰簩闃舵浠诲姟涓嶅彲鍙栨秷锛涘叾浠栦粎 taskStatus=0 鎴栨祦绋嬫湭鍒� 9999 鏃跺彲鍙栨秷锛夛紒锛�");
         }
         for (Task task : tasks) {
             //鍙栨秷绉诲簱浠诲姟
@@ -1307,12 +1374,47 @@
                             }
                         }
                     });
+                    List<Long> orderIds = taskItems.stream()
+                            .map(TaskItem::getOrderId)
+                            .filter(Objects::nonNull)
+                            .filter(id -> !id.equals(0L))
+                            .distinct()
+                            .collect(Collectors.toList());
+                    for (Long orderId : orderIds) {
+                        checkOrderService.update(new LambdaUpdateWrapper<WkOrder>()
+                                .eq(WkOrder::getId, orderId)
+                                .set(WkOrder::getExceStatus, CheckExceStatus.CHECK_ORDER_STATUS_UN_EXCE.val));
+                    }
                 }
 
                 if (!locService.update(new LambdaUpdateWrapper<Loc>()
                         .eq(Loc::getCode, task.getOrgLoc())
                         .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_F.type))) {
                     throw new CoolException("婧愬簱浣嶇姸鎬佷慨鏀瑰け璐ワ紒锛�");
+                }
+            }
+
+            // 鍑哄簱绫讳换鍔″彇娑堟椂锛屽洖閫�璺緞瑙勫垝闃舵鍗犵敤鐨勭洰鏍囩珯鐐癸紙S鈫扥锛�
+            if (task.getTaskType().equals(TaskType.TASK_TYPE_OUT.type)
+                    || task.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)
+                    || task.getTaskType().equals(TaskType.TASK_TYPE_MERGE_OUT.type)
+                    || task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type)
+                    || task.getTaskType().equals(TaskType.TASK_TYPE_EMPTY_OUT.type)) {
+                if (!Cools.isEmpty(task.getTargSite())) {
+                    LambdaQueryWrapper<BasStation> stationWrapper = new LambdaQueryWrapper<BasStation>()
+                            .eq(BasStation::getStationName, task.getTargSite())
+                            .eq(BasStation::getUseStatus, LocStsType.LOC_STS_TYPE_S.type);
+                    if (!Cools.isEmpty(task.getBarcode())) {
+                        stationWrapper.eq(BasStation::getBarcode, task.getBarcode());
+                    }
+                    BasStation targStation = basStationService.getOne(stationWrapper);
+                    if (targStation != null) {
+                        targStation.setUseStatus(LocStsType.LOC_STS_TYPE_O.type);
+                        targStation.setBarcode(null);
+                        if (!basStationService.updateById(targStation)) {
+                            throw new CoolException("閲婃斁鐩爣绔欑偣澶辫触锛侊紒");
+                        }
+                    }
                 }
             }
 
@@ -1334,7 +1436,9 @@
                 if (null == basStation) {
                     throw new CoolException("绔欑偣鐘舵�侀敊璇紒锛�");
                 }
-                basStation.setUseStatus(LocStsType.LOC_STS_TYPE_F.type);
+                if (!basStation.getType().equals(0)){
+                    basStation.setUseStatus(LocStsType.LOC_STS_TYPE_F.type);
+                }
                 if (!basStationService.updateById(basStation)) {
                     throw new CoolException("鏇存柊绔欑偣鐘舵�佸け璐ワ紒锛�");
                 }
@@ -2159,12 +2263,16 @@
             /**鍒ゆ柇鏄惁鍏夌數绔欑偣锛岄潪鍏夊簵绔欑偣闇�绠℃帶绔欑偣鐘舵��*/
             if (!Objects.isNull(station) && station.getType().equals(StationTypeEnum.STATION_TYPE_NORMAL.type)) {
                 if (task.getTaskType() <= TaskType.TASK_TYPE_CHECK_IN.type && !task.getTaskType().equals(TaskType.TASK_TYPE_LOC_MOVE.type)) {
-                    station.setUseStatus(LocStsType.LOC_STS_TYPE_R.type);
+                    if (!station.getType().equals(0)){
+                        station.setUseStatus(LocStsType.LOC_STS_TYPE_R.type);
+                    }
                     if (!basStationService.updateById(station)) {
                         throw new CoolException("绔欑偣鐘舵�佹洿鏂板け璐ワ紒锛�");
                     }
                 } else if (task.getTaskType() >= TaskType.TASK_TYPE_OUT.type) {
-                    station.setUseStatus(LocStsType.LOC_STS_TYPE_S.type);
+                    if (!station.getType().equals(0)){
+                        station.setUseStatus(LocStsType.LOC_STS_TYPE_S.type);
+                    }
                     if (!basStationService.updateById(station)) {
                         throw new CoolException("绔欑偣鐘舵�佹洿鏂板け璐ワ紒锛�");
                     }

--
Gitblit v1.9.1