zy-acs-flow/src/i18n/en.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
zy-acs-flow/src/i18n/zh.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
zy-acs-flow/src/map/http.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
zy-acs-flow/src/map/insight/agv/AgvMain.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
zy-acs-manager/src/main/java/com/zy/acs/manager/core/HandlerController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
zy-acs-manager/src/main/java/com/zy/acs/manager/core/PatrolService.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/controller/MapController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/controller/result/MapAgvVo.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
zy-acs-flow/src/i18n/en.js
@@ -647,6 +647,8 @@ enable: 'ENABLE', reset: 'RESET', restoreALl: 'Restore All', startPatrol: 'START PATROL', stopPatrol: 'STOP PATROL', }, mode: { observer: 'OBSERVER', zy-acs-flow/src/i18n/zh.js
@@ -646,6 +646,8 @@ enable: '启用', reset: '重置', restoreALl: '恢复所有', startPatrol: '开启巡逻', stopPatrol: '停止巡逻', }, mode: { observer: '观察模式', zy-acs-flow/src/map/http.js
@@ -283,3 +283,24 @@ console.error(error.message); }) } export const handleAgvPatrol = async (param) => { try { const res = await request.post('/handler/agv/patrol', 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; } zy-acs-flow/src/map/insight/agv/AgvMain.jsx
@@ -14,7 +14,7 @@ } from '@mui/material'; import { useNotification } from '../../Notification'; import AgvThree from './AgvThree'; import { handleRestoreAgvAll } from '../../http'; import { handleRestoreAgvAll, handleAgvPatrol } from '../../http'; import BoolValueIcon from '../BoolValueIcon'; import ConfirmButton from '../../../page/components/ConfirmButton'; import { grey } from '@mui/material/colors'; @@ -122,6 +122,13 @@ }); } const patrolControl = async () => { const res = await handleAgvPatrol({ agvNo: info.agvNo }) if (res) { fetchAgvInfo(curAgvNo); } } return ( <Box display="flex" height="100%"> <Box @@ -193,7 +200,8 @@ }}> <Grid container spacing={2} style={{ marginTop: '0px' }}> <Grid item xs={12}> <Stack spacing={2} mt={2}> <Stack spacing={1} mt={2}> {/* more */} <Button color="primary" variant="contained" @@ -203,8 +211,33 @@ > {translate('page.map.settings.map.more.title')} </Button> {/* patrol */} {info && ( info.status === 1 info.patrol ? <Button variant="contained" color="error" fullWidth onClick={() => { patrolControl(); }}> {translate('page.map.action.stopPatrol')} </Button> : // <Button variant="contained" fullWidth onClick={() => { // patrolControl(); // }}> // {translate('page.map.action.startPatrol')} // </Button> <ConfirmButton label="page.map.action.startPatrol" color="primary" variant="contained" onConfirm={() => { patrolControl(); }} /> )} {/* status */} {info && ( info.status === 0 ? <Button variant="contained" color="error" fullWidth onClick={() => { updateStatus(); }}> @@ -216,6 +249,7 @@ {translate('page.map.action.enable')} </Button> )} {/* restore all */} <ConfirmButton label="page.map.action.restoreALl" color="inherit" zy-acs-manager/src/main/java/com/zy/acs/manager/core/HandlerController.java
@@ -65,6 +65,8 @@ private MapDataDispatcher mapDataDispatcher; @Autowired private AvoidWaveCalculator avoidWaveCalculator; @Autowired private PatrolService patrolService; @RequestMapping(value = "/control/agv", method = {RequestMethod.GET, RequestMethod.POST}) @Transactional @@ -277,4 +279,21 @@ return R.ok(); } @RequestMapping(value = "/agv/patrol", method = {RequestMethod.GET, RequestMethod.POST}) public R agvPatrol(@RequestHeader String appKey, @RequestBody HandlerPublishParam param) throws ExecutionException, InterruptedException { if (Cools.isEmpty(param.getAgvNo(), appKey)) { return R.error(); } if (!APP_KEY.equals(appKey)) { return R.error(); } String agvNo = param.getAgvNo(); if (patrolService.isPatrolling(agvNo)) { return patrolService.shutdownPatrol(agvNo); } else { return patrolService.startupPatrol(agvNo); } } } zy-acs-manager/src/main/java/com/zy/acs/manager/core/PatrolService.java
New file @@ -0,0 +1,103 @@ package com.zy.acs.manager.core; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zy.acs.framework.common.R; import com.zy.acs.manager.manager.entity.Agv; import com.zy.acs.manager.manager.enums.StatusType; import com.zy.acs.manager.manager.service.AgvService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.util.Map; import java.util.concurrent.*; /** * Created by vincent on 11/9/2024 */ @Slf4j @Service public class PatrolService { private static final int SCHEDULE_TIME_INTERVAL = 1; private static final Map<String, ScheduledFuture<?>> AGV_PATROL_MAP = new ConcurrentHashMap<>(); private ScheduledExecutorService scheduler = null; @Autowired private AgvService agvService; public boolean isPatrolling(String agvNo) { ScheduledFuture<?> scheduledFuture = AGV_PATROL_MAP.get(agvNo); if (scheduledFuture == null) { return false; } return !scheduledFuture.isCancelled() && !scheduledFuture.isDone(); } public R startupPatrol(String agvNo) { if (AGV_PATROL_MAP.containsKey(agvNo)) { return R.error("AGV " + agvNo + " 的跑库任务已经在运行中。"); } Runnable patrolTask = () -> { try { executePatrolLogic(agvNo); } catch (Exception e) { log.error("执行AGV " + agvNo + " 跑库任务时发生异常: " + e.getMessage()); e.printStackTrace(); } }; ScheduledFuture<?> scheduledFuture = scheduler.scheduleAtFixedRate(patrolTask, 0, SCHEDULE_TIME_INTERVAL, TimeUnit.SECONDS); AGV_PATROL_MAP.put(agvNo, scheduledFuture); log.info("已启动AGV " + agvNo + " 的跑库任务。"); return R.ok(); } public R shutdownPatrol(String agvNo) { ScheduledFuture<?> scheduledFuture = AGV_PATROL_MAP.get(agvNo); if (scheduledFuture == null) { return R.error("AGV " + agvNo + " 没有正在运行的跑库任务。"); } boolean cancelled = scheduledFuture.cancel(true); if (cancelled) { AGV_PATROL_MAP.remove(agvNo); log.info("已停止AGV " + agvNo + " 的跑库任务。"); return R.ok("已停止AGV " + agvNo + " 的跑库任务。"); } else { log.error("未能成功停止AGV " + agvNo + " 的跑库任务。"); return R.error("未能成功停止AGV " + agvNo + " 的跑库任务。"); } } private void executePatrolLogic(String agvNo) { // TODO: 在这里实现具体的跑库业务逻辑 log.info("执行AGV " + agvNo + " 的跑库任务。"); } @PostConstruct public void init() { int count = agvService.count(new LambdaQueryWrapper<Agv>().eq(Agv::getStatus, StatusType.ENABLE.val)); if (count > 0) { this.scheduler = Executors.newScheduledThreadPool(count); } } @PreDestroy public void destroy() throws InterruptedException { for (Map.Entry<String, ScheduledFuture<?>> entry : AGV_PATROL_MAP.entrySet()) { entry.getValue().cancel(true); } scheduler.shutdown(); if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) { scheduler.shutdownNow(); } } } zy-acs-manager/src/main/java/com/zy/acs/manager/manager/controller/MapController.java
@@ -13,6 +13,7 @@ import com.zy.acs.manager.common.domain.MapDto; import com.zy.acs.manager.common.domain.MapRouteDto; import com.zy.acs.manager.common.exception.BusinessException; import com.zy.acs.manager.core.PatrolService; import com.zy.acs.manager.core.domain.BackpackDto; import com.zy.acs.manager.core.service.MapService; import com.zy.acs.manager.core.service.floyd.FloydNavigateService; @@ -68,6 +69,8 @@ private LocService locService; @Autowired private ConfigService configService; @Autowired private PatrolService patrolService; @PreAuthorize("hasAuthority('manager:loc:update')") @PostMapping("/startupOrShutdown") @@ -160,6 +163,7 @@ vo.setCode(codeService.getById(agvDetail.getRecentCode()).getData()); vo.setDirection(agvDetail.getAgvAngle()); vo.setBackpack(GsonUtils.fromJsonToList(agvDetail.getBackpack(), BackpackDto.class)); vo.setPatrol(patrolService.isPatrolling(agvNo)); } List<Task> tasks = taskService.selectInSts(agv.getId(), TaskStsType.WAITING, TaskStsType.ASSIGN, TaskStsType.PROGRESS); if (!Cools.isEmpty(tasks)) { zy-acs-manager/src/main/java/com/zy/acs/manager/manager/controller/result/MapAgvVo.java
@@ -36,4 +36,6 @@ private List<Long> taskIds = new ArrayList<>(); private Boolean patrol; }