From 4b81cc671814355c769e9c4c67ccb6e2ebf6321d Mon Sep 17 00:00:00 2001
From: vincentlu <t1341870251@gmail.com>
Date: 星期一, 21 四月 2025 10:02:13 +0800
Subject: [PATCH] #

---
 zy-acs-flow/src/map/http.js                                                        |   44 ++++++++++++++
 zy-acs-flow/src/i18n/en.js                                                         |    2 
 zy-acs-flow/src/map/header/MoreOperate.jsx                                         |   60 +++++++++++++++----
 zy-acs-manager/src/main/java/com/zy/acs/manager/core/HandlerController.java        |   26 ++++++++
 zy-acs-flow/src/i18n/zh.js                                                         |    2 
 zy-acs-manager/src/main/java/com/zy/acs/manager/core/constant/MapDataConstant.java |    2 
 6 files changed, 119 insertions(+), 17 deletions(-)

diff --git a/zy-acs-flow/src/i18n/en.js b/zy-acs-flow/src/i18n/en.js
index 0c1ce05..13ebef0 100644
--- a/zy-acs-flow/src/i18n/en.js
+++ b/zy-acs-flow/src/i18n/en.js
@@ -657,6 +657,8 @@
                 stopPatrol: 'STOP PATROL',
                 moreOperation: 'More Operation',
                 oneClickLocate: 'One-click Locate',
+                oneClickPatrol: 'One-click Patrol',
+                cancelPatrol: 'Cancel Patrol',
             },
             mode: {
                 observer: 'OBSERVER',
diff --git a/zy-acs-flow/src/i18n/zh.js b/zy-acs-flow/src/i18n/zh.js
index 4900ef1..09310d7 100644
--- a/zy-acs-flow/src/i18n/zh.js
+++ b/zy-acs-flow/src/i18n/zh.js
@@ -657,6 +657,8 @@
                 stopPatrol: '鍋滄 宸¢��',
                 moreOperation: '鏇村鎿嶄綔',
                 oneClickLocate: '涓�閿畾浣�',
+                oneClickPatrol: '涓�閿贰閫�',
+                cancelPatrol: '鍙栨秷宸¢��',
             },
             mode: {
                 observer: '瑙傚療妯″紡',
diff --git a/zy-acs-flow/src/map/header/MoreOperate.jsx b/zy-acs-flow/src/map/header/MoreOperate.jsx
index 49c7d9c..c210132 100644
--- a/zy-acs-flow/src/map/header/MoreOperate.jsx
+++ b/zy-acs-flow/src/map/header/MoreOperate.jsx
@@ -10,9 +10,11 @@
     ListItemText,
     CircularProgress,
 } from '@mui/material';
-import { handleLocateAllAgv } from "../http";
+import { locateAllAgv, startPatrolBatch, cancelPatrolBatch } from "../http";
 import GpsFixedIcon from '@mui/icons-material/GpsFixed';
 import { VERIFY_PASSWORD } from '@/config/setting';
+import TimelineIcon from '@mui/icons-material/Timeline';
+import CloseIcon from '@mui/icons-material/Close';
 
 const MoreOperate = ({ }) => {
     const translate = useTranslate();
@@ -37,13 +39,25 @@
         }
     }
 
-    const handleLocateAll = async () => {
-        setLoading(true)
+    const debounced = async (fn) => {
+        setLoading(true);
         try {
-            await handleLocateAllAgv();
+            await fn();
         } finally {
             setLoading(false);
         }
+    }
+
+    const handleLocateAll = () => {
+        debounced(locateAllAgv);
+    }
+
+    const handleStartPatrolBatch = () => {
+        debounced(startPatrolBatch);
+    }
+
+    const handleCancelPatrolBatch = () => {
+        debounced(cancelPatrolBatch);
     }
 
     return (
@@ -51,7 +65,6 @@
             <Select
                 value={translate('page.map.action.moreOperation')}
                 onChange={(event) => {
-                    console.log(event.target.value);
                 }}
                 renderValue={() => (
                     <Box sx={{ display: 'flex', alignItems: 'center' }}>
@@ -86,17 +99,36 @@
                     </ListItemIcon>
                     <ListItemText>{translate('page.map.action.oneClickLocate')}</ListItemText>
                 </MenuItem>
+                <MenuItem
+                    onClick={() => {
+                        verifyPassword(handleStartPatrolBatch);
+                    }}
+                    disabled={loading}
+                >
+                    <ListItemIcon>
+                        {loading
+                            ? <CircularProgress size={20} />
+                            : <TimelineIcon fontSize="small" />
+                        }
+                    </ListItemIcon>
+                    <ListItemText>{translate('page.map.action.oneClickPatrol')}</ListItemText>
+                </MenuItem>
+                <MenuItem
+                    onClick={() => {
+                        verifyPassword(handleCancelPatrolBatch);
+                    }}
+                    disabled={loading}
+                >
+                    <ListItemIcon>
+                        {loading
+                            ? <CircularProgress size={20} />
+                            : <CloseIcon fontSize="small" />
+                        }
+                    </ListItemIcon>
+                    <ListItemText>{translate('page.map.action.cancelPatrol')}</ListItemText>
+                </MenuItem>
             </Select>
-            {/* <Button
-                variant="contained"
-                color="primary"
-                onClick={handleToggle}
-                sx={{ mr: 2 }}
-            >
-                閲嶆柊瀹氫綅
-            </Button> */}
         </>
-
     );
 }
 
diff --git a/zy-acs-flow/src/map/http.js b/zy-acs-flow/src/map/http.js
index 640a9a5..b126eed 100644
--- a/zy-acs-flow/src/map/http.js
+++ b/zy-acs-flow/src/map/http.js
@@ -311,7 +311,7 @@
     return false;
 }
 
-export const handleLocateAllAgv = async (param) => {
+export const locateAllAgv = async (param) => {
     try {
         const res = await request.post('/handler/locateAllAgv', param, {
             headers: {
@@ -330,4 +330,46 @@
         console.error(error.message);
     }
     return false;
+}
+
+export const startPatrolBatch = async (param) => {
+    try {
+        const res = await request.post('/handler/patrol/batch/startup', param, {
+            headers: {
+                'appKey': HANDLE_APP_KEY
+            }
+        });
+        const { code, msg, data } = res.data;
+        if (code === 200) {
+            notify.success(msg);
+            return true;
+        } else {
+            notify.error(msg);
+        }
+    } catch (error) {
+        notify.error(error.message);
+        console.error(error.message);
+    }
+    return false;
+}
+
+export const cancelPatrolBatch = async (param) => {
+    try {
+        const res = await request.post('/handler/patrol/batch/shutdown', param, {
+            headers: {
+                'appKey': HANDLE_APP_KEY
+            }
+        });
+        const { code, msg, data } = res.data;
+        if (code === 200) {
+            notify.success(msg);
+            return true;
+        } else {
+            notify.error(msg);
+        }
+    } catch (error) {
+        notify.error(error.message);
+        console.error(error.message);
+    }
+    return false;
 }
\ No newline at end of file
diff --git a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/HandlerController.java b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/HandlerController.java
index 9b744ed..8f6a78e 100644
--- a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/HandlerController.java
+++ b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/HandlerController.java
@@ -28,6 +28,7 @@
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
+import java.util.stream.Collectors;
 
 /**
  * Created by vincent on 8/1/2024
@@ -75,13 +76,36 @@
     @PreAuthorize("hasAuthority('manager:agv:update')")
     @OperationLog("Locate All Agv")
     @PostMapping("/locateAllAgv")
-    public synchronized R locateAllAgv() throws InterruptedException {
+    public synchronized R locateAllAgv() {
         final Integer MAP_DEFAULT_LEV = 1;
         redis.deleteValue(RedisConstant.AGV_MAP_ASTAR_DYNAMIC_FLAG, String.valueOf(MAP_DEFAULT_LEV));
         avoidWaveCalculator.calcDynamicNodeWhenBoot();
         return R.ok();
     }
 
+    @PreAuthorize("hasAuthority('manager:agv:update')")
+    @PostMapping("/patrol/batch/startup")
+    public synchronized R patrolBatchStartup() {
+        List<Agv> list = agvService.list(new LambdaQueryWrapper<Agv>().eq(Agv::getStatus, StatusType.ENABLE.val));
+        int result = 0;
+        for (Agv agv : list) {
+            patrolService.startupPatrol(agv.getUuid());
+            result++;
+        }
+        return R.ok().add(result);
+    }
+
+    @PreAuthorize("hasAuthority('manager:agv:update')")
+    @PostMapping("/patrol/batch/shutdown")
+    public synchronized R patrolBatchShutdown() {
+        List<Agv> list = agvService.list(new LambdaQueryWrapper<Agv>());
+        for (String agvNo : list.stream().map(Agv::getUuid).collect(Collectors.toList())) {
+            if (patrolService.isPatrolling(agvNo)) {
+                patrolService.shutdownPatrol(agvNo);
+            }
+        }
+        return R.ok();
+    }
 
     @RequestMapping(value = "/control/agv", method = {RequestMethod.GET, RequestMethod.POST})
     @Transactional
diff --git a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/constant/MapDataConstant.java b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/constant/MapDataConstant.java
index 5b29c2c..5c4ad50 100644
--- a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/constant/MapDataConstant.java
+++ b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/constant/MapDataConstant.java
@@ -11,7 +11,7 @@
 
     public static final Integer MIN_SLICE_PATH_LENGTH = 3;
 
-    public static final Integer MAX_JAM_TIMEOUT = 2 * 1000;
+    public static final Integer MAX_JAM_TIMEOUT = 3 * 1000;
 
     public static final String EMPTY_OF_ERROR = "EMPTY";
 

--
Gitblit v1.9.1