#
luxiaotao1123
2024-11-09 87fda255732e4709e923f5b4c1e6b401e20c6002
#
7个文件已修改
1个文件已添加
193 ■■■■■ 已修改文件
zy-acs-flow/src/i18n/en.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/i18n/zh.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/map/http.js 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/map/insight/agv/AgvMain.jsx 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/HandlerController.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/PatrolService.java 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/controller/MapController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/controller/result/MapAgvVo.java 2 ●●●●● 补丁 | 查看 | 原始文档 | 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;
}