From e643e4c346976a7a7543364b324d5c5cee982aad Mon Sep 17 00:00:00 2001
From: vincentlu <t1341870251@gmail.com>
Date: 星期四, 26 二月 2026 16:07:01 +0800
Subject: [PATCH] #

---
 /dev/null                                                                                 |  161 --------------------------
 zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/GuaranteeRuntimeService.java |  165 ++++++++++++++++++++++++---
 zy-acs-manager/src/main/java/com/zy/acs/manager/core/scheduler/GuaranteeScheduler.java    |    1 
 3 files changed, 144 insertions(+), 183 deletions(-)

diff --git a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/scheduler/GuaranteeScheduler.java b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/scheduler/GuaranteeScheduler.java
index c2e7601..509a8b6 100644
--- a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/scheduler/GuaranteeScheduler.java
+++ b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/scheduler/GuaranteeScheduler.java
@@ -49,7 +49,6 @@
             return;
         }
         List<Guarantee> plans = guaranteeService.list(new LambdaQueryWrapper<Guarantee>()
-                .eq(Guarantee::getDeleted, 0)
                 .eq(Guarantee::getStatus, StatusType.ENABLE.val));
         syncCache(plans);
         LocalDateTime now = LocalDateTime.now();
diff --git a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/GuaranteeRuntimeService.java b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/GuaranteeRuntimeService.java
index 5c5abec..0a38972 100644
--- a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/GuaranteeRuntimeService.java
+++ b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/GuaranteeRuntimeService.java
@@ -1,32 +1,155 @@
 package com.zy.acs.manager.core.service;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.zy.acs.common.enums.AgvStatusType;
+import com.zy.acs.manager.manager.entity.Agv;
+import com.zy.acs.manager.manager.entity.AgvDetail;
 import com.zy.acs.manager.manager.entity.Guarantee;
+import com.zy.acs.manager.manager.entity.Task;
+import com.zy.acs.manager.manager.enums.StatusType;
+import com.zy.acs.manager.manager.enums.TaskStsType;
+import com.zy.acs.manager.manager.enums.TaskTypeType;
+import com.zy.acs.manager.manager.service.AgvDetailService;
+import com.zy.acs.manager.manager.service.AgvService;
+import com.zy.acs.manager.manager.service.TaskService;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
 
 import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
 
-/**
- * Runtime guarantee orchestration entry.
- */
-public interface GuaranteeRuntimeService {
+@Slf4j
+@Service
+public class GuaranteeRuntimeService {
 
-    /**
-     * Lead time entrance: make sure enough vehicles can reach the target window.
-     */
-    void prepare(Guarantee plan, LocalDateTime targetTime);
+    private final AgvService agvService;
+    private final AgvDetailService agvDetailService;
+    private final TaskService taskService;
+    private final MainLockWrapService mainLockWrapService;
 
-    /**
-     * Lock stage: restrict non-essential dispatching for reserve vehicles.
-     */
-    void lock(Guarantee plan, LocalDateTime targetTime);
+    public GuaranteeRuntimeService(AgvService agvService,
+                                   AgvDetailService agvDetailService,
+                                   TaskService taskService,
+                                   MainLockWrapService mainLockWrapService) {
+        this.agvService = agvService;
+        this.agvDetailService = agvDetailService;
+        this.taskService = taskService;
+        this.mainLockWrapService = mainLockWrapService;
+    }
 
-    /**
-     * Executed repeatedly during the guarantee window to keep SLA.
-     */
-    void checkWindow(Guarantee plan, LocalDateTime targetTime);
+    public void prepare(Guarantee plan, LocalDateTime targetTime) {
+        CapacitySnapshot snapshot = evaluate(plan);
+        if (snapshot.availableCount >= plan.getRequiredCount()) {
+            log.debug("Guarantee[{}] already has {} available vehicles for {}",
+                    plan.getName(), snapshot.availableCount, targetTime);
+            return;
+        }
+        int shortage = plan.getRequiredCount() - snapshot.availableCount;
+        log.info("Guarantee[{}] shortage {} vehicles for {} (minSoc={}%), scheduling charge.",
+                plan.getName(), shortage, targetTime, plan.getMinSoc());
+        dispatchChargeTasks(snapshot, shortage);
+    }
 
-    /**
-     * Called once after the window ends to release state/records.
-     */
-    void finish(Guarantee plan, LocalDateTime targetTime);
+    public void lock(Guarantee plan, LocalDateTime targetTime) {
+        log.info("Guarantee[{}] entering lock stage for {}", plan.getName(), targetTime);
+        // TODO persist lock state / inform dispatcher once integration is ready
+    }
+
+    public void checkWindow(Guarantee plan, LocalDateTime targetTime) {
+        CapacitySnapshot snapshot = evaluate(plan);
+        if (snapshot.availableCount < plan.getRequiredCount()) {
+            int shortage = plan.getRequiredCount() - snapshot.availableCount;
+            log.warn("Guarantee[{}] window shortage {} vehicles for {}. Trigger quick recharge.",
+                    plan.getName(), shortage, targetTime);
+            dispatchChargeTasks(snapshot, shortage);
+        }
+    }
+
+    public void finish(Guarantee plan, LocalDateTime targetTime) {
+        log.info("Guarantee[{}] finished window for {}", plan.getName(), targetTime);
+        // TODO release any lock/flag once detail implementation is defined
+    }
+
+    private CapacitySnapshot evaluate(Guarantee plan) {
+        int minSoc = Optional.ofNullable(plan.getMinSoc()).orElse(50);
+        List<Agv> scopedAgvs = findScopedAgvs(plan);
+        int available = 0;
+        List<ChargeCandidate> candidates = new ArrayList<>();
+        for (Agv agv : scopedAgvs) {
+            AgvDetail detail = agvDetailService.selectByAgvId(agv.getId());
+            if (detail == null || detail.getSoc() == null) {
+                continue;
+            }
+            if (detail.getSoc() >= minSoc && isAvailable(agv, detail)) {
+                available++;
+            } else {
+                candidates.add(new ChargeCandidate(agv, detail));
+            }
+        }
+        candidates.sort(Comparator.comparingInt(o -> Optional.ofNullable(o.detail.getSoc()).orElse(0)));
+        return new CapacitySnapshot(available, candidates);
+    }
+
+    private boolean isAvailable(Agv agv, AgvDetail detail) {
+        if (!Objects.equals(agv.getStatus(), StatusType.ENABLE.val)) {
+            return false;
+        }
+        if (detail.getAgvStatus() != null && detail.getAgvStatus().equals(AgvStatusType.CHARGE)) {
+            return false;
+        }
+        boolean busy = taskService.count(new LambdaQueryWrapper<Task>()
+                .eq(Task::getAgvId, agv.getId())
+                .in(Task::getTaskSts,
+                        TaskStsType.WAITING.val(),
+                        TaskStsType.ASSIGN.val(),
+                        TaskStsType.PROGRESS.val())) > 0;
+        return !busy;
+    }
+
+    private void dispatchChargeTasks(CapacitySnapshot snapshot, int shortage) {
+        if (shortage <= 0) {
+            return;
+        }
+        int scheduled = 0;
+        for (ChargeCandidate candidate : snapshot.candidates) {
+            if (scheduled >= shortage) {
+                break;
+            }
+            log.info("Scheduling AGV [{}] for charging to support guarantee", candidate.agv.getName());
+            mainLockWrapService.buildMinorTask(candidate.agv.getId(), TaskTypeType.TO_CHARGE, null, null);
+            scheduled++;
+        }
+    }
+
+    private List<Agv> findScopedAgvs(Guarantee plan) {
+        LambdaQueryWrapper<Agv> wrapper = new LambdaQueryWrapper<Agv>()
+                .eq(Agv::getStatus, StatusType.ENABLE.val);
+        if ("MODEL".equalsIgnoreCase(plan.getScopeType()) && plan.getScopeValue() != null) {
+            try {
+                wrapper.eq(Agv::getAgvModel, Long.valueOf(plan.getScopeValue()));
+            } catch (NumberFormatException ignore) {
+                log.warn("Guarantee[{}] invalid scopeValue {}", plan.getName(), plan.getScopeValue());
+            }
+        }
+        return agvService.list(wrapper);
+    }
+
+    @Data
+    private static class CapacitySnapshot {
+        private final int availableCount;
+        private final List<ChargeCandidate> candidates;
+    }
+
+    @Data
+    @AllArgsConstructor
+    private static class ChargeCandidate {
+        private Agv agv;
+        private AgvDetail detail;
+    }
 }
-
diff --git a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/impl/GuaranteeRuntimeServiceImpl.java b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/impl/GuaranteeRuntimeServiceImpl.java
deleted file mode 100644
index 04163fa..0000000
--- a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/impl/GuaranteeRuntimeServiceImpl.java
+++ /dev/null
@@ -1,161 +0,0 @@
-package com.zy.acs.manager.core.service.impl;
-
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.zy.acs.common.enums.AgvStatusType;
-import com.zy.acs.manager.core.service.GuaranteeRuntimeService;
-import com.zy.acs.manager.core.service.MainLockWrapService;
-import com.zy.acs.manager.manager.entity.Agv;
-import com.zy.acs.manager.manager.entity.AgvDetail;
-import com.zy.acs.manager.manager.entity.Guarantee;
-import com.zy.acs.manager.manager.entity.Task;
-import com.zy.acs.manager.manager.enums.StatusType;
-import com.zy.acs.manager.manager.enums.TaskStsType;
-import com.zy.acs.manager.manager.enums.TaskTypeType;
-import com.zy.acs.manager.manager.service.AgvDetailService;
-import com.zy.acs.manager.manager.service.AgvService;
-import com.zy.acs.manager.manager.service.TaskService;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-
-import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
-
-@Slf4j
-@Service
-public class GuaranteeRuntimeServiceImpl implements GuaranteeRuntimeService {
-
-    private final AgvService agvService;
-    private final AgvDetailService agvDetailService;
-    private final TaskService taskService;
-    private final MainLockWrapService mainLockWrapService;
-
-    public GuaranteeRuntimeServiceImpl(AgvService agvService,
-                                       AgvDetailService agvDetailService,
-                                       TaskService taskService,
-                                       MainLockWrapService mainLockWrapService) {
-        this.agvService = agvService;
-        this.agvDetailService = agvDetailService;
-        this.taskService = taskService;
-        this.mainLockWrapService = mainLockWrapService;
-    }
-
-    @Override
-    public void prepare(Guarantee plan, LocalDateTime targetTime) {
-        CapacitySnapshot snapshot = evaluate(plan);
-        if (snapshot.availableCount >= plan.getRequiredCount()) {
-            log.debug("Guarantee[{}] already has {} available vehicles for {}",
-                    plan.getName(), snapshot.availableCount, targetTime);
-            return;
-        }
-        int shortage = plan.getRequiredCount() - snapshot.availableCount;
-        log.info("Guarantee[{}] shortage {} vehicles for {} (minSoc={}%), scheduling charge.",
-                plan.getName(), shortage, targetTime, plan.getMinSoc());
-        dispatchChargeTasks(snapshot, shortage);
-    }
-
-    @Override
-    public void lock(Guarantee plan, LocalDateTime targetTime) {
-        log.info("Guarantee[{}] entering lock stage for {}", plan.getName(), targetTime);
-        // TODO persist lock state / inform dispatcher once integration is ready
-    }
-
-    @Override
-    public void checkWindow(Guarantee plan, LocalDateTime targetTime) {
-        CapacitySnapshot snapshot = evaluate(plan);
-        if (snapshot.availableCount < plan.getRequiredCount()) {
-            int shortage = plan.getRequiredCount() - snapshot.availableCount;
-            log.warn("Guarantee[{}] window shortage {} vehicles for {}. Trigger quick recharge.",
-                    plan.getName(), shortage, targetTime);
-            dispatchChargeTasks(snapshot, shortage);
-        }
-    }
-
-    @Override
-    public void finish(Guarantee plan, LocalDateTime targetTime) {
-        log.info("Guarantee[{}] finished window for {}", plan.getName(), targetTime);
-        // TODO release any lock/flag once detail implementation is defined
-    }
-
-    private CapacitySnapshot evaluate(Guarantee plan) {
-        int minSoc = Optional.ofNullable(plan.getMinSoc()).orElse(50);
-        List<Agv> scopedAgvs = findScopedAgvs(plan);
-        int available = 0;
-        List<ChargeCandidate> candidates = new ArrayList<>();
-        for (Agv agv : scopedAgvs) {
-            AgvDetail detail = agvDetailService.selectByAgvId(agv.getId());
-            if (detail == null || detail.getSoc() == null) {
-                continue;
-            }
-            if (detail.getSoc() >= minSoc && isAvailable(agv, detail)) {
-                available++;
-            } else {
-                candidates.add(new ChargeCandidate(agv, detail));
-            }
-        }
-        candidates.sort(Comparator.comparingInt(o -> Optional.ofNullable(o.detail.getSoc()).orElse(0)));
-        return new CapacitySnapshot(available, candidates);
-    }
-
-    private boolean isAvailable(Agv agv, AgvDetail detail) {
-        if (!Objects.equals(agv.getStatus(), StatusType.ENABLE.val)) {
-            return false;
-        }
-        if (detail.getAgvStatus() != null && detail.getAgvStatus().equals(AgvStatusType.CHARGE)) {
-            return false;
-        }
-        boolean busy = taskService.count(new LambdaQueryWrapper<Task>()
-                .eq(Task::getAgvId, agv.getId())
-                .in(Task::getTaskSts,
-                        TaskStsType.WAITING.val(),
-                        TaskStsType.ASSIGN.val(),
-                        TaskStsType.PROGRESS.val())) > 0;
-        return !busy;
-    }
-
-    private void dispatchChargeTasks(CapacitySnapshot snapshot, int shortage) {
-        if (shortage <= 0) {
-            return;
-        }
-        int scheduled = 0;
-        for (ChargeCandidate candidate : snapshot.candidates) {
-            if (scheduled >= shortage) {
-                break;
-            }
-            log.info("Scheduling AGV [{}] for charging to support guarantee", candidate.agv.getName());
-            mainLockWrapService.buildMinorTask(candidate.agv.getId(), TaskTypeType.TO_CHARGE, null, null);
-            scheduled++;
-        }
-    }
-
-    private List<Agv> findScopedAgvs(Guarantee plan) {
-        LambdaQueryWrapper<Agv> wrapper = new LambdaQueryWrapper<Agv>()
-                .eq(Agv::getStatus, StatusType.ENABLE.val);
-        if ("MODEL".equalsIgnoreCase(plan.getScopeType()) && plan.getScopeValue() != null) {
-            try {
-                wrapper.eq(Agv::getAgvModel, Long.valueOf(plan.getScopeValue()));
-            } catch (NumberFormatException ignore) {
-                log.warn("Guarantee[{}] invalid scopeValue {}", plan.getName(), plan.getScopeValue());
-            }
-        }
-        return agvService.list(wrapper);
-    }
-
-    @Data
-    private static class CapacitySnapshot {
-        private final int availableCount;
-        private final List<ChargeCandidate> candidates;
-    }
-
-    @Data
-    @AllArgsConstructor
-    private static class ChargeCandidate {
-        private Agv agv;
-        private AgvDetail detail;
-    }
-}

--
Gitblit v1.9.1