*
lsh
2025-11-25 af2ebb4ebbcb69f6385947aa322a508464388494
*
5个文件已添加
4个文件已修改
2344 ■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/RgvController.java 759 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/domain/param/RingThroughParam.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/config/AdminInterceptor.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/config/WebConfig.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/RgvModeType.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/deviceOperate/crnOperate.html 399 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/deviceOperate/devpOperate.html 228 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/deviceOperate/rgvOperate.html 212 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/deviceOperate/wcsOperate.html 678 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/RgvController.java
@@ -2,381 +2,444 @@
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.annotations.ManagerAuth;
import com.core.common.Cools;
import com.core.common.R;
import com.core.exception.CoolException;
import com.zy.asrs.domain.enums.RgvStatusType;
import com.zy.asrs.domain.param.CrnOperatorParam;
import com.zy.asrs.domain.param.RgvOperatorParam;
import com.zy.asrs.domain.vo.RgvMsgTableVo;
import com.zy.asrs.domain.vo.RgvStateTableVo;
import com.zy.asrs.entity.BasRgv;
import com.zy.asrs.entity.BasRgvErr;
import com.zy.asrs.entity.BasRgvMap;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.mapper.BasRgvErrMapper;
import com.zy.asrs.mapper.BasRgvMapMapper;
import com.zy.asrs.service.BasRgvService;
import com.zy.asrs.service.LocMastService;
import com.zy.asrs.service.WrkMastService;
import com.zy.asrs.service.impl.MainServiceImpl;
import com.zy.core.cache.MessageQueue;
import com.zy.core.cache.OutputQueue;
import com.zy.asrs.domain.param.RingThroughParam;
import com.zy.asrs.entity.BasDevpPosition;
import com.zy.asrs.service.BasDevpPositionService;
import com.zy.core.cache.RgvErrCache;
import com.zy.core.cache.RgvStatusCache;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.RgvModeType;
import com.zy.core.enums.RgvTaskModeType;
import com.zy.core.enums.RgvTaskStatusType;
import com.zy.core.cache.TaskProtocolCache;
import com.zy.core.enums.SlaveType;
import com.zy.core.model.RgvSlave;
import com.zy.core.model.Task;
import com.zy.core.model.command.RgvCommand;
import com.zy.core.model.protocol.RgvProtocol;
import com.zy.core.properties.SlaveProperties;
import com.zy.core.model.protocol.TaskProtocol;
import com.zy.core.thread.RgvThread;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
 * RGV接口
 * 输送设备接口
 * Created by vincent on 2020-06-01
 */
@Slf4j
@RestController
@RequestMapping("/rgv")
public class RgvController {
    @Autowired
    private SlaveProperties slaveProperties;
    @Autowired
    private WrkMastService wrkMastService;
    @Autowired
    private BasRgvErrMapper basRgvErrMapper;
    @Autowired
    private BasRgvService basRgvService;
    @Autowired
    private MainServiceImpl mainService;
    @Autowired
    private LocMastService locMastService;
    @Autowired
    private BasRgvMapMapper basRgvMapMapper;
//    @ManagerAuth(memo = "解锁小车")
//    @PostMapping("/lock")
//    public R lock(CrnOperatorParam param){
//        RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, param.getRgvNo());
//        rgvThread.setPakMk(true);
//        return R.ok();
//    }
//
//    @PostMapping("/table/rgv/state")
//    @ManagerAuth(memo = "RGV信息表")
//    public R rgvStateTable() {
//        List<RgvStateTableVo> list = new ArrayList<>();
//        List<BasRgv> rgvs = basRgvService.selectList(new EntityWrapper<BasRgv>().orderBy("rgv_no"));
//
//        for (BasRgv basRgv : rgvs) {
//            RgvStateTableVo vo = new RgvStateTableVo();
//            vo.setRgvNo(basRgv.getRgvNo());   //  RGV号
//            list.add(vo);
//
//            // 获取RGV信息
//            RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, basRgv.getRgvNo());
//            if (rgvThread == null) continue;
//
//            RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
//            if (rgvProtocol == null) continue;
//            BasRgvMap basRgvMap = basRgvMapMapper.selectById(rgvProtocol.getRgvNo());
//
//            vo.setStatusType(rgvProtocol.modeType.desc);   // 模式状态
//            vo.setStatus(String.valueOf(rgvProtocol.getMode())); // 状态
//            vo.setWorkNo1(rgvProtocol.getTaskNo1());      // 工位1任务号
//            vo.setStatus1(rgvProtocol.getStatusType1().desc); // 工位1状态
//            vo.setLoading1(rgvProtocol.getLoaded1() ? "有物" : "无物"); // 工位1有物
//            vo.setRgvPos(basRgvMap != null?basRgvMap.getNowRoute():0);
//            vo.setRgvPos1(rgvProtocol.getRgvPosI2());
//            vo.setWalkPos(Objects.equals(rgvProtocol.getWalkPos(), 1) ? "在定位" : "不在定位");
//            vo.setPakMk(rgvThread.isPakMk() ? "无锁" : "锁定");
////            vo.setPakIn(rgvThread.isPakIn() ? "可入" : "不可入");
////            vo.setPakOut(rgvThread.isPakOut() ? "可出" : "不可出");
////            vo.setPakRgv(rgvThread.isPakRgv() ? "无锁" : "锁定");
//            vo.setPaking(rgvThread.isPaking()? "无锁" : "锁定");
////            vo.setPakAll(rgvThread.isPakAll() ? "无锁" : "锁定");
////            vo.setPakToCrn(rgvThread.isPakToCrn() ? "无锁" : "锁定");
//
//
//            vo.setWorkNo2(rgvProtocol.getTaskNo2());      // 工位2任务号
////            vo.setStatus2(rgvProtocol.getStatusType2().desc); // 工位2状态
//            vo.setLoading2(rgvProtocol.getLoaded2() ? "有物" : "无物"); // 工位2有物
//
//            // --- 遍历 errX 字段生成 warnCode 和 alarm ---
//            List<String> alarms = new ArrayList<>();
//            List<String> warnCodes = new ArrayList<>();
//            Field[] fields = rgvProtocol.getClass().getDeclaredFields();
//            for (Field field : fields) {
//                if (field.getName().startsWith("err") && field.getType().equals(Boolean.class)) {
//                    field.setAccessible(true);
//                    try {
//                        Boolean value = (Boolean) field.get(rgvProtocol);
//                        if (Boolean.TRUE.equals(value)) {
//                            String numPart = field.getName().substring(3);
//                            int errId = Integer.parseInt(numPart);
//                            warnCodes.add(String.valueOf(errId));
//
//                            BasRgvErr rgvErr = basRgvErrMapper.selectById(errId);
//                            alarms.add(rgvErr == null ? "未知异常(" + errId + ")" : rgvErr.getErrName());
//                        }
//                    } catch (IllegalAccessException e) {
//                        e.printStackTrace();
//                    }
//                }
//            }
//
//            vo.setWarnCode(String.join(",", warnCodes));
//            vo.setAlarm(alarms.isEmpty() ? "" : String.join(",", alarms));
//        }
//
//        return R.ok().add(list);
//    }
    private BasDevpPositionService basDevpPositionService;
//    @PostMapping("/table/rgv/msg")
//    @ManagerAuth(memo = "RGV数据表")
//    public R rgvMsgTable(){
//        List<RgvMsgTableVo> list = new ArrayList<>();
//        List<BasRgv> rgvs = basRgvService.selectList(new EntityWrapper<BasRgv>().orderBy("rgv_no"));
//        for (BasRgv basRgv : rgvs) {
//            // 表格行
//            RgvMsgTableVo vo = new RgvMsgTableVo();
//            vo.setRgvNo(basRgv.getRgvNo());   //  RGV号
//            list.add(vo);
//            // 获取RGV信息
//            RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, basRgv.getRgvNo());
//            if (rgvThread == null) {
//                continue;
//            }
//            RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
//            if (rgvProtocol == null) {
//                continue;
//            }
//
//            vo.setWorkNo1(rgvProtocol.getTaskNo1());  //  工位1工作号
//            vo.setWorkNo2(rgvProtocol.getTaskNo2()); //工位2 工作号
//            vo.setStaNo(String.valueOf(rgvProtocol.getRgvPosDestination())); //小车目标站
//            vo.setStatus(rgvProtocol.modeType.equals(RgvModeType.AUTO)? rgvProtocol.modeType.desc: RgvModeType.HAND.desc);   //  模式状态
//
//        }
//        return R.ok().add(list);
//    }
    @PostMapping("/output/site")
    @ManagerAuth(memo = "RGV报文日志输出")
    public R rgvOutput(){
        StringBuilder str = new StringBuilder();
        String s;
        int i = 0;
        while((s = OutputQueue.RGV.poll()) != null && i <=10) {
            str.append("\n").append(s);
            i++;
    @GetMapping("/status/all")
//    @ManagerAuth(memo = "全部信息")
    public R allStatus(){
        List<Map<String, Object>> res = new ArrayList<>();
        ConcurrentHashMap<Integer, RgvProtocol> allRgvStatus = RgvStatusCache.getAllRgvStatus();
        for (RgvProtocol rgvProtocol : allRgvStatus.values()){
            Map<String, Object> map2 = new HashMap<>();
            map2.put("rgvNo", rgvProtocol.getRgvNo());
            map2.put("taskNo", rgvProtocol.getTaskNo());
            map2.put("mode", rgvProtocol.getModeType().desc);
            map2.put("status", rgvProtocol.getStatusType().desc);
            map2.put("rgvPos", rgvProtocol.getRgvPos());
            map2.put("rgvPosDestination", rgvProtocol.getRgvPosDestination());
            map2.put("loaded", rgvProtocol.getLoaded().equals((short)-1)? "未知":rgvProtocol.getLoaded()==1? "有物":"无物");
            map2.put("errorRgv", RgvErrCache.getErrorDev(rgvProtocol.getRgvNo()));
            res.add(map2);
        }
        return R.ok().add(str.toString());
        return R.ok().add(res);
    }
//    /****************************************************************/
//    /************************** 手动操作 ******************************/
//    /****************************************************************/
//
//    @ManagerAuth(memo = "取放货")
//    @PostMapping("/operator/put")
//    public R rgvFetchPut(RgvOperatorParam param){
//        RgvCommand command = new RgvCommand();
//        command.setRgvNo(param.getRgvNo()); // RGV编号
//        command.setAckFinish1(false);  // 任务完成确认位
//        command.setTaskNo(0); // 工作号
//        command.setTaskMode1(RgvTaskModeType.FETCH_PUT); // 任务模式: 取放货
//        command.setSourceStaNo1(param.getSourceStaNo1()); // 源站
////        command.setDestinationStaNo1(param.getStaNo1());  // 目标站
//        command.setAckFinish2(false);  // 任务完成确认位
//        command.setTaskNo2(0); // 工作号
//        command.setTaskMode2(RgvTaskModeType.FETCH_PUT); // 任务模式: 取放货
//        command.setSourceStaNo2(param.getSourceStaNo2()); // 源站
////        command.setDestinationStaNo2(param.getStaNo2());  // 目标站
//        command.setCommand(true);
//
//        return rgvControl(command)? R.ok(): R.error();
//    }
    @PostMapping("/task/cache/all")
//    @ManagerAuth(memo = "全部信息")
    public R allTaskCache(@RequestParam(defaultValue = "0")  Integer rgvNo){
        List<Map<String, Object>> res = new ArrayList<>();
        try{
            RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgvNo);
            TaskProtocolCache taskProtocolCache = rgvThread.getTaskProtocolCache();
            ConcurrentHashMap<String, TaskProtocol> allTaskProtocol = taskProtocolCache.getAllTaskProtocol();
            for (TaskProtocol taskProtocol : allTaskProtocol.values()){
                Map<String, Object> map2 = new HashMap<>();
                map2.put("rgvNo", rgvNo);
                map2.put("taskNo", taskProtocol.getTaskNo());
                map2.put("targetPosition", taskProtocol.getTargetPosition());
                map2.put("isRunning", taskProtocol.getIsRunning());
                map2.put("taskStatus", taskProtocol.getTaskStatus());
                map2.put("direction", taskProtocol.isDirection());
                res.add(map2);
            }
        } catch (Exception e){
//            return R.error("异常"+e.getMessage());
        }
        return R.ok().add(res);
    }
//    @ManagerAuth(memo = "取货")
//    @PostMapping("/operator/take")
//    public R rgvFetch(RgvOperatorParam param){
//        RgvCommand command = new RgvCommand();
//        command.setRgvNo(param.getRgvNo()); // RGV编号
//        command.setWrkTaskPri(param.getWorkSta());  //执行工位
//        command.setTaskNo(Math.toIntExact(param.getWorkNo())); // 工作号
//        command.setTaskStatus(RgvTaskStatusType.FETCH); // 任务模式: 取货
//        command.setTargetPosition(Integer.valueOf(param.getStaNo()));  // 目标站
////        command.setTaskMode2(RgvTaskModeType.FETCH); // 任务模式: 取放货
////        command.setAckFinish1(false);  // 任务完成确认位
////        command.setSourceStaNo1(param.getSourceStaNo1()); // 源站
////        command.setAckFinish2(false);  // 任务完成确认位
////        command.setTaskNo2( 0); // 工作号
////        command.setSourceStaNo2(param.getSourceStaNo2()); // 源站
////        command.setDestinationStaNo2(param.getStaNo2());  // 目标站
//        command.setCommand(true);
//
//        return rgvControl(command)? R.ok(): R.error();
//    }
    @PostMapping("/run/del")//Take  Put  Walk
//    @ManagerAuth(memo = "清空任务")
    public R rgvRunDel(@RequestParam(defaultValue = "0")  Integer rgvNo
    ) {
        if (rgvNo==null || rgvNo==0){
            return R.error("请选择小车");
        }
        RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgvNo);
        TaskProtocolCache taskProtocolCache = rgvThread.getTaskProtocolCache();
//    @ManagerAuth(memo = "放货")
//    @PostMapping("/operator/stockMove")
//    public R rgvPut(RgvOperatorParam param){
//        RgvCommand command = new RgvCommand();
//        command.setRgvNo(param.getRgvNo()); // RGV编号
//        command.setWrkTaskPri(param.getWorkSta());  //执行工位
//        command.setTaskNo(Math.toIntExact(param.getWorkNo())); // 工作号
//        command.setTaskStatus(RgvTaskStatusType.PUT); // 任务模式: 取货
//        command.setTargetPosition(Integer.valueOf(param.getStaNo()));  // 目标站
////        command.setAckFinish1(false);  // 任务完成确认位
////        command.setSourceStaNo1(param.getSourceStaNo1()); // 源站
////        command.setAckFinish2(false);  // 任务完成确认位
////        command.setTaskNo2( 0); // 工作号
////        command.setTaskMode2(RgvTaskModeType.FETCH); // 任务模式: 取放货
////        command.setSourceStaNo2(param.getSourceStaNo2()); // 源站
////        command.setDestinationStaNo2(param.getStaNo2());  // 目标站
//        command.setCommand(true);
//
//        return rgvControl(command)? R.ok(): R.error();
//    }
        try {
            ConcurrentHashMap<String, TaskProtocol> allTaskProtocol = taskProtocolCache.getAllTaskProtocol();
            for (TaskProtocol taskProtocol : allTaskProtocol.values()){
                taskProtocolCache.removeTaskProtocol(taskProtocol.getTaskNoDirection());
            }
        } catch (Exception e) {
            return R.error("任务删除失败"+e.getMessage());
        }
        return R.ok("任务清空成功");
    }
    @PostMapping("/run/del2")//Take  Put  Walk
//    @ManagerAuth(memo = "清除作业启动中")
    public R rgvRunDel2(@RequestParam(defaultValue = "0")  Integer rgvNo
    ) {
        if (rgvNo==null || rgvNo==0){
            return R.error("请选择小车");
        }
        RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgvNo);
        try {
            rgvThread.setWrkSign();
        } catch (Exception e) {
            return R.error("清除作业启动中失败"+e.getMessage());
        }
        return R.ok("任务清空成功");
    }
    @PostMapping("/run/walk")//Take  Put  Walk
//    @ManagerAuth(memo = "小车行走")
    public R rgvRunWalk(@RequestParam(defaultValue = "0")  Integer rgvNo,
                        @RequestParam(defaultValue = "9999")  Integer taskNo,
                        @RequestParam(defaultValue = "0")  Integer rgvStaNoPut,
                        @RequestParam(defaultValue = "0")  Long rgvPosDestination
    ) {
        if (rgvNo==null || rgvNo==0){
            return R.error("请选择小车");
        }
        if ((rgvStaNoPut == null || rgvStaNoPut == 0) && (rgvPosDestination==null || rgvPosDestination==0L)){
            return R.error("目标站点请填写");
        }
        if (rgvPosDestination == null || rgvPosDestination == 0){
            BasDevpPosition basDevpPosition = basDevpPositionService.selectOne(new EntityWrapper<BasDevpPosition>().eq("DEV_NO", rgvStaNoPut));
            if (Cools.isEmpty(basDevpPosition)){
                return R.error("目标站点不存在");
            }
            rgvPosDestination = basDevpPosition.getPlcPosition();
        }
        RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgvNo);
        TaskProtocolCache taskProtocolCache = rgvThread.getTaskProtocolCache();
        TaskProtocol issued = new TaskProtocol();
        try {
            ConcurrentHashMap<String, TaskProtocol> allTaskProtocol = taskProtocolCache.getAllTaskProtocol();
            if (allTaskProtocol.size() > 0) {
                return R.error("存在执行中任务,请先处理!!!");
            }
            //执行
            issued.setTaskNo(Long.valueOf(taskNo));
            issued.setTaskStatus(1);
            issued.setTaskNoDirection(issued.gettaskNoDirection$(issued.getTaskNo(), issued.getTaskStatus()));
            issued.setTargetPosition(rgvPosDestination);
            issued.setIsRunning(1);
            issued.setDirection(true);
            taskProtocolCache.updateTaskProtocol(issued);
        } catch (Exception e) {
            return R.error("任务生成失败"+e.getMessage());
        }
        return R.ok("任务生成成功");
    }
    @PostMapping("/run/put")//Take  Put  Walk
//    @ManagerAuth(memo = "小车放货")
    public R rgvPutWalk(@RequestParam(defaultValue = "0")  Integer rgvNo,
                        @RequestParam(defaultValue = "9999")  Integer taskNo,
                        @RequestParam(defaultValue = "0")  Integer rgvStaNoPut,
                        @RequestParam(defaultValue = "0")  Long rgvPosDestination
    ) {
        if (rgvNo==null || rgvNo==0){
            return R.error("请选择小车");
        }
        if (rgvStaNoPut == null || rgvStaNoPut == 0){
            return R.error("目标站点请填写");
        }
        RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgvNo);
        TaskProtocolCache taskProtocolCache = rgvThread.getTaskProtocolCache();
        TaskProtocol issuedPut = new TaskProtocol();
        try {
            ConcurrentHashMap<String, TaskProtocol> allTaskProtocol = taskProtocolCache.getAllTaskProtocol();
            if (allTaskProtocol.size() > 0) {
                return R.error("存在执行中任务,请先处理!!!");
            }
            BasDevpPosition basDevpPosition = basDevpPositionService.selectOne(new EntityWrapper<BasDevpPosition>().eq("DEV_NO", rgvStaNoPut));
            if (Cools.isEmpty(basDevpPosition)){
                return R.error("目标站点不存在");
            }
            //执行
            issuedPut.setTaskNo(Long.valueOf(taskNo));
            issuedPut.setTaskStatus(3);
            issuedPut.setTargetPositionStaNo(basDevpPosition.getDevNo());
            issuedPut.setTargetPositionStaNoPlcId(basDevpPosition.getPlcId());
            issuedPut.setTaskNoDirection(issuedPut.gettaskNoDirection$(issuedPut.getTaskNo(), issuedPut.getTaskStatus()));
            issuedPut.setTargetPosition(basDevpPosition.getPlcPosition());
            issuedPut.setIsRunning(1);
            issuedPut.setDirection(basDevpPosition.getRgvSign()==1);
            taskProtocolCache.updateTaskProtocol(issuedPut);
        } catch (Exception e) {
            return R.error("任务生成失败"+e.getMessage());
        }
        return R.ok("任务生成成功");
    }
    @PostMapping("/run/take")//Take  Put  Walk
//    @ManagerAuth(memo = "小车取货")
    public R rgvTakeWalk(@RequestParam(defaultValue = "0") Integer rgvNo,
                         @RequestParam(defaultValue = "9999") Integer taskNo,
                         @RequestParam(defaultValue = "0") Integer rgvStaNoTake,
                         @RequestParam(defaultValue = "0") Long rgvPosDestination
    ) {
        if (rgvNo==null || rgvNo==0){
            return R.error("请选择小车");
        }
        if (rgvStaNoTake == null || rgvStaNoTake == 0){
            return R.error("取货站点请填写");
        }
        RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgvNo);
        TaskProtocolCache taskProtocolCache = rgvThread.getTaskProtocolCache();
        TaskProtocol issuedTake = new TaskProtocol();
        try {
            ConcurrentHashMap<String, TaskProtocol> allTaskProtocol = taskProtocolCache.getAllTaskProtocol();
            if (allTaskProtocol.size() > 0) {
                return R.error("存在执行中任务,请先处理!!!");
            }
            BasDevpPosition basDevpPosition = basDevpPositionService.selectOne(new EntityWrapper<BasDevpPosition>().eq("DEV_NO", rgvStaNoTake));
            if (Cools.isEmpty(basDevpPosition)){
                return R.error("取货站点不存在");
            }
            //执行
            issuedTake.setTaskNo(Long.valueOf(taskNo));
            issuedTake.setTaskStatus(2);
            issuedTake.setTargetPositionStaNo(basDevpPosition.getDevNo());
            issuedTake.setTargetPositionStaNoPlcId(basDevpPosition.getPlcId());
            issuedTake.setTaskNoDirection(issuedTake.gettaskNoDirection$(issuedTake.getTaskNo(), issuedTake.getTaskStatus()));
            issuedTake.setTargetPosition(basDevpPosition.getPlcPosition());
            issuedTake.setIsRunning(1);
            issuedTake.setDirection(basDevpPosition.getRgvSign()==1);
            taskProtocolCache.updateTaskProtocol(issuedTake);
        } catch (Exception e) {
            return R.error("任务生成失败"+e.getMessage());
        }
        return R.ok("任务生成成功");
    }
    @PostMapping("/run/TakeAndPut")//Take  Put  Walk
//    @ManagerAuth(memo = "小车取货")
    public R rgvTakeAndPut(@RequestParam(defaultValue = "0") Integer rgvNo,
                           @RequestParam(defaultValue = "9999") Integer taskNo,
                           @RequestParam(defaultValue = "0") Integer rgvStaNoTake,
                           @RequestParam(defaultValue = "0") Integer rgvStaNoPut,
                           @RequestParam(defaultValue = "0") Long rgvPosDestination
    ) {
        if (rgvNo==null || rgvNo==0){
            return R.error("请选择小车");
        }
        if (rgvStaNoTake == null || rgvStaNoTake == 0){
            return R.error("取货站点请填写");
        }
        if (rgvStaNoPut == null || rgvStaNoPut == 0){
            return R.error("放货站点请填写");
        }
        RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgvNo);
        TaskProtocolCache taskProtocolCache = rgvThread.getTaskProtocolCache();
        TaskProtocol issuedTake = new TaskProtocol();
        TaskProtocol issuedPut = new TaskProtocol();
        try {
            ConcurrentHashMap<String, TaskProtocol> allTaskProtocol = taskProtocolCache.getAllTaskProtocol();
            if (allTaskProtocol.size() > 0) {
                return R.error("存在执行中任务,请先处理!!!");
            }
            BasDevpPosition basDevpPositionTake = basDevpPositionService.selectOne(new EntityWrapper<BasDevpPosition>().eq("DEV_NO", rgvStaNoTake));
            if (Cools.isEmpty(basDevpPositionTake)){
                return R.error("取货站点不存在");
            }
            //执行
            issuedTake.setTaskNo(Long.valueOf(taskNo));
            issuedTake.setTaskStatus(2);
            issuedTake.setTargetPositionStaNo(basDevpPositionTake.getDevNo());
            issuedTake.setTargetPositionStaNoPlcId(basDevpPositionTake.getPlcId());
            issuedTake.setTaskNoDirection(issuedTake.gettaskNoDirection$(issuedTake.getTaskNo(), issuedTake.getTaskStatus()));
            issuedTake.setTargetPosition(basDevpPositionTake.getPlcPosition());
            issuedTake.setIsRunning(1);
            issuedTake.setDirection(basDevpPositionTake.getRgvSign()==1);
            BasDevpPosition basDevpPositionPut = basDevpPositionService.selectOne(new EntityWrapper<BasDevpPosition>().eq("DEV_NO", rgvStaNoPut));
            if (Cools.isEmpty(basDevpPositionPut)){
                return R.error("目标站点不存在");
            }
            //执行
            issuedPut.setTaskNo(Long.valueOf(taskNo));
            issuedPut.setTaskStatus(3);
            issuedPut.setTargetPositionStaNo(basDevpPositionPut.getDevNo());
            issuedPut.setTargetPositionStaNoPlcId(basDevpPositionPut.getPlcId());
            issuedPut.setTaskNoDirection(issuedPut.gettaskNoDirection$(issuedPut.getTaskNo(), issuedPut.getTaskStatus()));
            issuedPut.setTargetPosition(basDevpPositionPut.getPlcPosition());
            issuedPut.setIsRunning(1);
            issuedPut.setDirection(basDevpPositionPut.getRgvSign()==1);
            taskProtocolCache.updateTaskProtocol(issuedTake);
            taskProtocolCache.updateTaskProtocol(issuedPut);
        } catch (Exception e) {
            return R.error("任务生成失败"+e.getMessage());
        }
        return R.ok("任务生成成功");
    }
    @PostMapping("/run/delRgvTask")//Take  Put  Walk
//    @ManagerAuth(memo = "小车取货")
    public R rgvDelRgvTask(@RequestParam(defaultValue = "0") Integer rgvNo
    ) {
        if (rgvNo==null || rgvNo==0){
            return R.error("请选择小车");
        }
        try {
            RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgvNo);
            rgvThread.setDelRgvTask();
        } catch (Exception e) {
            return R.error("任务生成失败"+e.getMessage());
        }
        return R.ok("任务生成成功");
    }
//    @ManagerAuth(memo = "任务完成")
//    @PostMapping("/operator/taskComplete")
//    public R rgvTaskComplete(RgvOperatorParam param){
//        RgvCommand command = new RgvCommand();
//        command.setRgvNo(param.getRgvNo()); // RGV编号
//        command.setAckFinish1(true);  // 任务完成确认位
////        command.setTaskNo1(0); // 工作号
//        command.setTaskMode1(RgvTaskModeType.NONE); // 任务模式
//        command.setSourceStaNo1((short) 0); // 源站
//        command.setDestinationStaNo1((short) 0);  // 目标站
//        command.setAckFinish2(true);  // 任务完成确认位
//        command.setTaskNo2( 0); // 工作号
//        command.setTaskMode2(RgvTaskModeType.NONE); // 任务模式
//        command.setSourceStaNo2((short) 0); // 源站
//        command.setDestinationStaNo2((short) 0);  // 目标站
//        command.setCommand(true);
//
//        return rgvControl(command)? R.ok(): R.error();
//    }
    @PostMapping("/ring/through/rgv/position/data")
//    @ManagerAuth(memo = "小车位置信息")
    public R ringThroughRgv(){
        List<RingThroughParam> result = new ArrayList<>();
//    @ManagerAuth(memo = "清除命令")
//    @PostMapping("/operator/clearCommand")
//    public R rgvClearCommand(RgvOperatorParam param){
//        if (param.getRgvNo() == null) {
//            throw new CoolException("请选择RGV号");
//        }
//        RgvCommand command = new RgvCommand();
//        command.setRgvNo(param.getRgvNo()); // RGV编号
//        command.setWrkTaskPri(0);  //执行工位
//        command.setTaskNo(Math.toIntExact(0)); // 工作号
//        command.setTaskStatus((short)0); // 任务模式: 取货
//        command.setTargetPosition(0);  // 目标站
//
//        return rgvClear(command)? R.ok(): R.error();
//    }
        ConcurrentHashMap<Integer, RgvProtocol> allRgvStatus = RgvStatusCache.getAllRgvStatus();
        for (RgvProtocol rgvProtocol : allRgvStatus.values()){
            RingThroughParam ringThroughParam = new RingThroughParam();
//    @ManagerAuth(memo = "手动复位")
//    @PostMapping("/operator/handleReset")
//    public R handleReset(RgvOperatorParam param) throws Exception {
//        if (param.getRgvNo() == null) {
//            throw new CoolException("请选择RGV");
//        }
//        // 获取RGV缓存
//        for (RgvSlave rgv : slaveProperties.getRgv()) {
//            // 获取RGV信息
//            if (param.getRgvNo().equals(rgv.getId())) {
//                RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgv.getId());
//                if (rgvThread == null) {
//                    throw new CoolException("RGV不在线");
//                }
//                RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
//                if (rgvProtocol == null) {
//                    throw new CoolException("RGV不在线");
//                }
//                RgvCommand Command = new RgvCommand();
//                Command.setRgvNo(rgv.getId()); // RGV编号
//                Command.setTaskMode1(RgvTaskModeType.NONE);
//                Command.setAckFinish1(true);  // 任务完成确认位
//                Command.setAckFinish2(true);  // 任务完成确认位
//                Command.setCommand(true);  // 任务完成确认位
//                // 延时发送
//                Thread.sleep(1000L);
//                if (MessageQueue.offer(SlaveType.Rgv, rgv.getId(), new Task(4, Command))) {
//                    return R.ok();
//                } else {
//                    throw new CoolException("命令下发失败");
//                }
//
//            }
//        }
//        return R.error();
//    }
//
//    private boolean rgvControl(RgvCommand command){
//        if (command.getRgvNo() == null) {
//            throw new CoolException("请选择RGV");
//        }
//        for (RgvSlave rgv : slaveProperties.getRgv()) {
//            // 获取RGV信息
//            if (command.getRgvNo().equals(rgv.getId())) {
//                RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgv.getId());
//                if (rgvThread == null) {
//                    throw new CoolException("RGV不在线");
//                }
//                RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
//                if (rgvProtocol == null) {
//                    throw new CoolException("RGV不在线");
//                }
//                if (MessageQueue.offer(SlaveType.Rgv, rgv.getId(), new Task(2, command))) {
//                    return true;
//                } else {
//                    throw new CoolException("命令下发失败");
//                }
//            }
//        }
//        return false;
//    }
//
//    private boolean rgvClear(RgvCommand command){
//        if (command.getRgvNo() == null) {
//            throw new CoolException("请选择RGV");
//        }
//        for (RgvSlave rgv : slaveProperties.getRgv()) {
//            // 获取RGV信息
//            if (command.getRgvNo().equals(rgv.getId())) {
//                RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgv.getId());
//                if (rgvThread == null) {
//                    throw new CoolException("RGV不在线");
//                }
//                RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
//                if (rgvProtocol == null) {
//                    throw new CoolException("RGV不在线");
//                }
//                if (MessageQueue.offer(SlaveType.Rgv, rgv.getId(), new Task(3, command))) {
//                    return true;
//                } else {
//                    throw new CoolException("命令下发失败");
//                }
//            }
//        }
//        return false;
//
//    }
            ringThroughParam.setIndex(rgvProtocol.getRgvNo());
//            ringThroughParam.setIndex(i);
//            double[] doubles = Utils.RingThroughXY2(perimeter, NumUtils.GetRandomIntInRange(183));
//            double[] doubles = Utils.RingThroughXYRgv(perimeter, perimeter-rgvProtocol.RgvPos.doubleValue());
//            double[] doubles = Utils.getRgvPosNew(perimeter, rgvProtocol.RgvPos.doubleValue());
//            double[] doubles = Utils.RingThroughXY2(183.0, 100*i );
}
            ringThroughParam.setValueX(rgvProtocol.getRgvNo()*100*1D);
            ringThroughParam.setValueY(rgvProtocol.getRgvNo()*100*2D);
            ringThroughParam.setModeColor(rgvProtocol.modeType.color);
            ringThroughParam.setStatusColor(rgvProtocol.statusType.color);
            result.add(ringThroughParam);
        }
        return R.ok().add(result);
    }
    @PostMapping("/ring/through/dev/position/data")
//    @ManagerAuth(memo = "站点信息")
    //  站点位置信息
    public R ringThroughDev(){
        List<RingThroughParam> result = new ArrayList<>();
        ArrayList<Integer> arrayList = new ArrayList<Integer>() {{
            add(1001);
            add(1002);
            add(1003);
            add(1004);
            add(1005);
            add(1006);
            add(1007);
            add(1008);
            add(1009);
            add(1010);
            add(1011);
            add(1012);
            add(1013);
            add(1014);
            add(1015);
            add(1016);
            add(1017);
            add(1018);
            add(1019);
            add(1020);
            add(1021);
            add(1022);
            add(1023);
        }};
        for (Integer staNo : arrayList){
            RingThroughParam ringThroughParam = new RingThroughParam();
            ringThroughParam.setIndex(staNo);
//            double[] doubles = Utils.RingThroughXYSta(perimeter, perimeter-basDevpPosition.getPlcPosition());
//            ringThroughParam.setValueX(doubles[0]>50? doubles[0]+6:doubles[0]-1);
//            ringThroughParam.setValueY(doubles[1]>50? doubles[1]+6:doubles[1]-1);
//            double[] doubles = Utils.getRgvPosNew(basDevpPosition.getDevNo(),perimeter, basDevpPosition.getPlcPosition());
            ringThroughParam.setValueX(staNo*100*1D);
            ringThroughParam.setValueY(staNo*100*2D);
            result.add(ringThroughParam);
        }
        return R.ok().add(result);
    }
    @PostMapping("/ring/through/track/position/data")
//    @ManagerAuth(memo = "轨道PLC状态信息")
    public R wnergyGatheringRingParamTrack(){
        return R.ok();
    }
    @PostMapping("/ring/through/task/wrk/mast/position/data")
//    @ManagerAuth(memo = "作业信息")
    public R ringThroughTaskWrkMast(){
        return R.ok();
    }
    @PostMapping("/ring/through/task/wrk/mast/position/data/v1")
//    @ManagerAuth(memo = "作业信息")
    public R ringThroughTaskWrkMastV1(){
        return R.ok();
    }
    @PostMapping("/task/rgv/circular/shuttle/mast/position/data")
//    @ManagerAuth(memo = "作业信息")
    public R rgvCircularShuttle(){
        return R.ok();
    }
    @PostMapping("/task/rgv/circular/shuttle/mast/position/data/v1")
//    @ManagerAuth(memo = "作业信息")
    public R rgvCircularShuttleV1(){
        return R.ok();
    }
}
src/main/java/com/zy/asrs/domain/param/RingThroughParam.java
New file
@@ -0,0 +1,17 @@
package com.zy.asrs.domain.param;
import lombok.Data;
@Data
public class RingThroughParam {
    // RGV号
    private Integer index;
    private Double valueX;
    private Double valueY;
    private String modeColor;
    private String statusColor;
}
src/main/java/com/zy/common/config/AdminInterceptor.java
@@ -43,6 +43,21 @@
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("=== 拦截器收到请求 ===");
        System.out.println("方法: " + request.getMethod());
        System.out.println("URI: " + request.getRequestURI());
        // 关键修复:必须放行 OPTIONS 预检请求
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            System.out.println("✅ 放行 OPTIONS 预检请求");
            // 手动设置 CORS 头
            response.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:8080");
            response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
            response.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Token, token");
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setStatus(HttpServletResponse.SC_OK);
            return false; // OPTIONS 请求不需要继续后续处理
        }
        cors(response);
        if (handler instanceof org.springframework.web.servlet.resource.ResourceHttpRequestHandler) {
            return true;
src/main/java/com/zy/common/config/WebConfig.java
@@ -2,6 +2,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@@ -20,5 +21,16 @@
                .addPathPatterns("/**")
                ;
    }
//                .excludePathPatterns("/rgv/**");
//    @Override
//    public void addCorsMappings(CorsRegistry registry) {
//        registry.addMapping("/**") // 对所有接口生效
//                .allowedOrigins("http://127.0.0.1:8080") // 关键:指定您的前地址
//                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的请求方法
//                .allowedHeaders("*") // 允许所有请求头
//                .allowCredentials(true) // 若前端请求需要携带Cookie等认证信息,此项设为true
//                .maxAge(3600); // 预检请求的缓存时间(秒)
//    }
}
src/main/java/com/zy/core/enums/RgvModeType.java
@@ -2,42 +2,44 @@
public enum RgvModeType {
    NONE(-1, "离线"),
    STOP(0, "关机"),
    HAND(1, "手动"),
//    HALF_AUTO(2, "半自动"),
    AUTO(2, "自动"),
    AUTO2(100, "其它"),
    NONE(-1, "离线","ffffff"),
    STOP(2, "维修","ffffff"),
    HAND(0, "手动","ffffff"),
    HALF_AUTO(3, "半自动","ffffff"),
    AUTO(1, "自动","ffffff"),
    OTHER(100, "其它","ffffff"),
    ;
    public Integer id;
    public String desc;
    RgvModeType(Integer id, String desc) {
    public String color;
    RgvModeType(Integer id, String desc, String color) {
        this.id = id;
        this.desc = desc;
        this.color = color;
    }
    public static RgvModeType get(Short id) {
        if (null == id) {
            return null;
            return OTHER;
        }
        for (RgvModeType type : RgvModeType.values()) {
            if (type.id.equals(id.intValue())) {
                return type;
            }
        }
        return null;
        return OTHER;
    }
    public static RgvModeType get(RgvModeType type) {
        if (null == type) {
            return null;
            return OTHER;
        }
        for (RgvModeType rgvModeType : RgvModeType.values()) {
            if (rgvModeType == type) {
                return rgvModeType;
            }
        }
        return null;
        return OTHER;
    }
}
src/main/webapp/views/deviceOperate/crnOperate.html
New file
@@ -0,0 +1,399 @@
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>堆垛机设备</title>
    <link rel="stylesheet" href="../../static/wcs/css/element.css">
    <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="../../static/js/common.js"></script>
    <script type="text/javascript" src="../../static/wcs/js/vue.min.js"></script>
    <script type="text/javascript" src="../../static/wcs/js/element.js"></script>
</head>
<body>
    <div id="app" style="display: flex;justify-content: center;flex-wrap: wrap;">
        <div style="width: 100%;">
            <el-table ref="singleTable" :data="tableData" highlight-current-row @row-click="handleRowClick"
                max-height="350" style="width: 100%">
                <el-table-column property="crnNo" label="堆垛机">
                </el-table-column>
                <el-table-column property="laneNo" label="巷道号">
                </el-table-column>
                <el-table-column property="workNo" label="工作号">
                </el-table-column>
                <el-table-column property="statusType" label="模式">
                </el-table-column>
                <el-table-column property="wrkStatus$" label="任务状态">
                </el-table-column>
                <el-table-column property="deviceStatus" label="设备状态">
                </el-table-column>
                <el-table-column property="taskComplete" label="任务完成指令">
                </el-table-column>
                <el-table-column property="errorCrn" label="异常提示">
                </el-table-column>
                <el-table-column property="demo" label="演示">
                </el-table-column>
                <el-table-column property="demoValue$" label="演示状态">
                </el-table-column>
            </el-table>
        </div>
        <div style="width: 100%;display: flex;justify-content: center;margin-top: 10px;">
            <div style="width: 55%;margin-right: 10px;">
                <el-card class="box-card">
                    <div slot="header" class="clearfix">
                        <span>设备调试</span>
                    </div>
                    <div>
                        <el-form :model="formParam" label-position="top" :inline="true" class="demo-form-inline">
<!--                            <el-form-item label="源站/源库位">-->
<!--                                <el-input v-model="formParam.sourceStaNo" placeholder="源站/源库位"></el-input>-->
<!--                            </el-form-item>-->
                            <el-form-item label="排">
                                <el-input v-model="formParam.sourceRow" placeholder="排"></el-input>
                            </el-form-item>
                            <el-form-item label="列">
                                <el-input v-model="formParam.sourceBay" placeholder="列"></el-input>
                            </el-form-item>
                            <el-form-item label="层">
                                <el-input v-model="formParam.sourceLev" placeholder="层"></el-input>
                            </el-form-item>
                        </el-form>
                        <el-form :model="formParam" label-position="top" :inline="true" class="demo-form-inline">
<!--                            <el-form-item label="目标站/目标库位">-->
<!--                                <el-input v-model="formParam.staNo" placeholder="目标站/目标库位"></el-input>-->
<!--                            </el-form-item>-->
                            <el-form-item label="排">
                                <el-input v-model="formParam.row" placeholder="排"></el-input>
                            </el-form-item>
                            <el-form-item label="列">
                                <el-input v-model="formParam.bay" placeholder="列"></el-input>
                            </el-form-item>
                            <el-form-item label="层">
                                <el-input v-model="formParam.lev" placeholder="层"></el-input>
                            </el-form-item>
                        </el-form>
                        <el-form :model="formParam" label-position="top" :inline="true" class="demo-form-inline">
                            <el-form-item label="测试库位数量">
                                <el-input v-model="formParam.locMastDemoCount" placeholder="测试库位数量"></el-input>
                            </el-form-item>
                            <el-form-item label="原始出库库位">
                                <el-input v-model="formParam.locMastDemoF" placeholder="原始有物库位"></el-input>
                            </el-form-item>
                            <el-form-item label="原始空库位">
                                <el-input v-model="formParam.locMastDemoE" placeholder="原始有物库位"></el-input>
                            </el-form-item>
                            <el-form-item label="堆垛机放货站点">
                                <el-input v-model="formParam.staOutDemo" placeholder="堆垛机放货站点"></el-input>
                            </el-form-item>
                            <el-form-item label="堆垛机取货站点">
                                <el-input v-model="formParam.staIntDemo" placeholder="堆垛机取货站点"></el-input>
                            </el-form-item>
                        </el-form>
                        <el-form label-position="top" :inline="true" class="demo-form-inline">
                            <el-form-item label="">
                                <el-checkbox @change="updateEnableInOut('in')" v-model="enableIn">可入</el-checkbox>
                            </el-form-item>
                            <el-form-item label="">
                                <el-checkbox @change="updateEnableInOut('out')" v-model="enableOut">可出</el-checkbox>
                            </el-form-item>
                            <el-form-item label="">
                                <el-checkbox @change="updateDemo('demo')" v-model="hpMkDemo">演示</el-checkbox>
                            </el-form-item>
                        </el-form>
                        <div>
<!--                            <el-button @click="requestOperate('put')" type="primary">入库</el-button>-->
<!--                            <el-button @click="requestOperate('take')" type="primary">出库</el-button>-->
                            <el-button @click="requestOperate('stockMove')" type="primary">库位转移</el-button>
                            <div style="margin-top: 10px">
                                <el-button @click="requestOperate('taskComplete')" type="primary">任务完成</el-button>
                                <el-button @click="requestOperate('taskCompleteClearCommand')" type="primary">任务完成指令清除</el-button>
                            </div>
<!--                            <el-button @click="requestOperate('siteMove')" type="primary">站到站</el-button>-->
<!--                            <el-button @click="requestOperate('clearCommand')" type="primary">清除命令</el-button>-->
<!--                            <el-button @click="requestOperate('reset')" type="primary">复位</el-button>-->
                            <br/>
                            <br/>
<!--                            <el-button @click="requestOperate('auto')" type="warning">联机</el-button>-->
<!--                            <el-button @click="requestOperate('semiAutomatic')" type="warning">半自动</el-button>-->
<!--                            <el-button @click="requestOperate('hand')" type="warning">手动</el-button>-->
<!--                            <el-button @click="requestOperate('onlineWrk4')" type="warning">恢复联机任务</el-button>-->
<!--                            <el-button @click="requestOperate('onlineWrk3')" type="warning">清除联机任务</el-button>-->
<!--                            <el-button @click="requestOperate('onlineWrk1')" type="warning">申请完成任务</el-button>-->
                            <br/>
                            <br/>
<!--                            <el-button @click="requestOperate('onlineWrk2')" type="warning">申请取消任务</el-button>-->
                        </div>
                    </div>
                </el-card>
            </div>
            <div style="width: 45%;">
                <el-card class="box-card">
                    <div slot="header" class="clearfix">
                        <span>设备状态</span>
                    </div>
                    <div>
                        <div v-if="currentIndex == null">
                            <el-empty description="请选择设备"></el-empty>
                        </div>
                        <div v-else>
                            <el-descriptions :title="currentTitle" direction="vertical" :column="4" border>
                                <el-descriptions-item label="堆垛机">{{ tableData[currentIndex].crnNo }}
                                </el-descriptions-item>
                                <el-descriptions-item label="工作号">
                                    {{ tableData[currentIndex].workNo }}
                                </el-descriptions-item>
                                <el-descriptions-item label="模式">
                                    <el-tag>{{ tableData[currentIndex].statusType }}</el-tag>
                                </el-descriptions-item>
                                <el-descriptions-item label="任务状态">
                                    <div v-if="tableData[currentIndex].wrkStatus == 0">
                                        <el-tag>{{ tableData[currentIndex].wrkStatus$ }}</el-tag>
                                    </div>
                                    <div v-else>
                                        <el-tag type="success">{{ tableData[currentIndex].wrkStatus$ }}</el-tag>
                                    </div>
                                </el-descriptions-item>
                                <el-descriptions-item label="设备状态">
                                    <el-tag>{{ tableData[currentIndex].deviceStatus }}</el-tag>
                                </el-descriptions-item>
                                <el-descriptions-item label="有物">
                                    <el-tag>{{ tableData[currentIndex].loading }}</el-tag>
                                </el-descriptions-item>
                                <el-descriptions-item label="列">{{ tableData[currentIndex].bay }}
                                </el-descriptions-item>
                                <el-descriptions-item label="层">{{ tableData[currentIndex].lev }}
                                </el-descriptions-item>
                                <el-descriptions-item label="故障代码">{{ tableData[currentIndex].warnCode }}
                                </el-descriptions-item>
                                <el-descriptions-item label="故障描述">{{ tableData[currentIndex].lev }}
                                </el-descriptions-item>
                                <el-descriptions-item label="源站">{{ tableData[currentIndex].sourceStaNo }}
                                </el-descriptions-item>
                                <el-descriptions-item label="目标站">{{ tableData[currentIndex].staNo }}
                                </el-descriptions-item>
                                <el-descriptions-item label="源库位">{{ tableData[currentIndex].sourceLocNo }}
                                </el-descriptions-item>
                                <el-descriptions-item label="目标库位">{{ tableData[currentIndex].locNo }}
                                </el-descriptions-item>
                                <el-descriptions-item label="货叉定位">{{ tableData[currentIndex].forkOffset }}
                                </el-descriptions-item>
                                <el-descriptions-item label="载货台定位">{{ tableData[currentIndex].liftPos }}
                                </el-descriptions-item>
                                <el-descriptions-item label="走行在定位">{{ tableData[currentIndex].walkPos }}
                                </el-descriptions-item>
                                <el-descriptions-item label="走行速度(m/min)">{{ tableData[currentIndex].xspeed }}
                                </el-descriptions-item>
                                <el-descriptions-item label="升降速度(m/min)">{{ tableData[currentIndex].yspeed }}
                                </el-descriptions-item>
                                <el-descriptions-item label="叉牙速度(m/min)">{{ tableData[currentIndex].zspeed }}
                                </el-descriptions-item>
                                <el-descriptions-item label="走行距离(Km)">{{ tableData[currentIndex].xdistance }}
                                </el-descriptions-item>
                                <el-descriptions-item label="升降距离(Km)">{{ tableData[currentIndex].ydistance }}
                                </el-descriptions-item>
                                <el-descriptions-item label="走行时长(H)">{{ tableData[currentIndex].xduration }}
                                </el-descriptions-item>
                                <el-descriptions-item label="升降时长(H)">{{ tableData[currentIndex].yduration }}
                                </el-descriptions-item>
                                <el-descriptions-item label="异常提示">{{ tableData[currentIndex].errorCrn }}
                                </el-descriptions-item>
                            </el-descriptions>
                        </div>
                    </div>
                </el-card>
            </div>
        </div>
    </div>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                tableData: [],
                currentRow: null,
                currentTitle: "未选择设备",
                currentIndex: null,
                formParam: {
                    crnNo: null,
                    sourceStaNo: null,
                    sourceRow: 1,
                    sourceBay: 0,
                    sourceLev: 1,
                    staNo: null,
                    locMastDemoCount: 3,
                    locMastDemoF: null,
                    locMastDemoE: null,
                    staOutDemo: null,
                    staIntDemo: null,
                    row: 1,
                    bay: 0,
                    lev: 1
                },
                enableIn: false,
                enableOut: false,
                hpMkDemo: false
            },
            created() {
                this.init()
            },
            watch: {
            },
            methods: {
                init() {
                    this.getTableData()
                    setInterval(() => {
                        this.getTableData()
                    }, 1000)
                },
                handleRowClick(row, col, event) {
                    const index = this.tableData.indexOf(row)
                    this.currentRow = row;
                    this.currentIndex = index
                    this.currentTitle = row.crnNo + "号堆垛机"
                    this.formParam.crnNo = row.crnNo
                    this.enableIn = row.inEnable == "Y" ? true : false
                    this.enableOut = row.outEnable == "Y" ? true : false
                    this.hpMkDemo = row.hpMk == "Y" ? true : false
                },
                getTableData() {
                    let that = this;
                    $.ajax({
                        url: baseUrl + "/crn/list/auth",
                        headers: {
                            'token': localStorage.getItem('token')
                        },
                        data: {},
                        dataType: 'json',
                        contentType: 'application/json;charset=UTF-8',
                        method: 'GET',
                        success: function (res) {
                            that.tableData = res.data
                        }
                    });
                },
                requestOperate(method) {
                    let that = this
                    that.$confirm('此操作存在风险,是否继续','提示',{
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning'
                    }).then(()=>{
                        $.ajax({
                            url: baseUrl + "/crn/operator/" + method,
                            headers: {
                                'token': localStorage.getItem('token')
                            },
                            data: this.formParam,
                            method: 'POST',
                            success: function (res) {
                                if (res.code == 200) {
                                    that.$message({
                                        message: res.msg,
                                        type: 'success'
                                    });
                                } else {
                                    that.$message({
                                        message: res.msg,
                                        type: 'error'
                                    });
                                }
                            }
                        });
                    })
                },
                updateEnableInOut(type) {
                    let that = this
                    let param = {}
                    if (type == "in") {
                        param = {
                            inEnable: this.enableIn ? "Y" : "N",
                            crnNo: this.formParam.crnNo
                        }
                    } else {
                        param = {
                            outEnable: this.enableOut ? "Y" : "N",
                            crnNo: this.formParam.crnNo
                        }
                    }
                    $.ajax({
                        url: baseUrl + "/basCrnp/update/auth",
                        headers: {
                            'token': localStorage.getItem('token')
                        },
                        data: param,
                        method: 'POST',
                        success: function (res) {
                            if (res.code == 200) {
                                that.$message({
                                    message: res.msg,
                                    type: 'success'
                                });
                            } else {
                                that.$message({
                                    message: res.msg,
                                    type: 'error'
                                });
                            }
                        }
                    });
                },
                updateDemo(type) {
                    let that = this
                    let param = {}
                    that.$confirm('将启动演示模式,是否继续','提示',{
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning'
                    }).then(()=>{
                        if (type == "demo") {
                            param = {
                                hpMk: this.hpMkDemo ? "Y" : "N",
                                staOutDemo: this.formParam.staOutDemo,
                                staIntDemo: this.formParam.staIntDemo,
                                locMastDemoF: this.formParam.locMastDemoF,
                                locMastDemoE: this.formParam.locMastDemoE,
                                locMastDemoCount: this.formParam.locMastDemoCount,
                                crnNo: this.formParam.crnNo
                            }
                        } else {
                            param = {
                                crnNo: this.formParam.crnNo
                            }
                        }
                        $.ajax({
                            url: baseUrl + "/basCrnp/update/demo/auth",
                            headers: {
                                'token': localStorage.getItem('token')
                            },
                            data: param,
                            method: 'POST',
                            success: function (res) {
                                if (res.code == 200) {
                                    that.$message({
                                        message: res.msg,
                                        type: 'success'
                                    });
                                } else {
                                    that.$message({
                                        message: res.msg,
                                        type: 'error'
                                    });
                                }
                            }
                        });
                    })
                }
            }
        })
    </script>
</body>
</html>
src/main/webapp/views/deviceOperate/devpOperate.html
New file
@@ -0,0 +1,228 @@
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>输送站点设备</title>
    <link rel="stylesheet" href="../../static/wcs/css/element.css">
    <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="../../static/js/common.js"></script>
    <script type="text/javascript" src="../../static/wcs/js/vue.min.js"></script>
    <script type="text/javascript" src="../../static/wcs/js/element.js"></script>
</head>
<body>
    <div id="app" style="display: flex;justify-content: center;flex-wrap: wrap;">
        <div style="width: 100%;">
            <el-table ref="singleTable" :data="tableData" highlight-current-row @row-click="handleRowClick"
                max-height="450" style="width: 100%">
                <el-table-column property="devNo" label="站号">
                </el-table-column>
                <el-table-column property="workNo" label="工作号">
                </el-table-column>
<!--                <el-table-column property="locType1" label="高低库位">-->
<!--                </el-table-column>-->
                <el-table-column property="pakMk" label="入库标记">
                </el-table-column>
                <el-table-column property="pakMkRun" label="退回标记">
                </el-table-column>
                <el-table-column property="pakMkTask" label="小车任务下发标记">
                </el-table-column>
                <el-table-column property="weight" label="称重">
                </el-table-column>
                <el-table-column property="barcode" label="条码">
                </el-table-column>
                <el-table-column property="errorDev" label="异常提示">
                </el-table-column>
            </el-table>
        </div>
        <div style="width: 100%;display: flex;justify-content: center;margin-top: 10px;">
            <div style="width: 55%;margin-right: 10px;">
                <el-card class="box-card">
                    <div slot="header" class="clearfix">
                        <span>设备调试</span>
                    </div>
                    <div>
                        <el-form :model="formParam" label-position="top" :inline="true" class="demo-form-inline">
                            <el-form-item label="工作号">
                                <el-input v-model="formParam.workNo" placeholder="工作号"></el-input>
                            </el-form-item>
                            <el-form-item label="目标站">
                                <el-input v-model="formParam.staNo" placeholder="目标站"></el-input>
                            </el-form-item>
                        </el-form>
                        <el-form label-position="top" :inline="true" class="demo-form-inline">
                            <el-form-item label="">
                                <el-checkbox v-model="formParam.inEnable">可入</el-checkbox>
                            </el-form-item>
                            <el-form-item label="">
                                <el-checkbox v-model="formParam.outEnable">可出</el-checkbox>
                            </el-form-item>
                        </el-form>
                        <div>
                            <el-button @click="requestOperate('update')" type="primary">更新站点信息</el-button>
<!--                            <el-button @click="requestOperate('in')" type="warning">放货完成</el-button>-->
                        </div>
                        <div style="margin-top: 10px">
                            <el-button @click="requestOperate('pakMk')" type="warning">入库标记复位</el-button>
                            <el-button @click="requestOperate('pakMkRun')" type="warning">退库标记复位</el-button>
                            <el-button @click="requestOperate('pakMkTask')" type="warning">小车任务下发标记复位</el-button>
                            <el-button @click="requestOperate('pakMkWalk')" type="warning">WMS任务下发标记复位</el-button>
                        </div>
                    </div>
                </el-card>
            </div>
            <div style="width: 45%;">
                <el-card class="box-card">
                    <div slot="header" class="clearfix">
                        <span>设备状态</span>
                    </div>
                    <div>
                        <div v-if="currentIndex == null">
                            <el-empty description="请选择设备"></el-empty>
                        </div>
                        <div v-else>
                            <el-descriptions :title="currentTitle" direction="vertical" :column="4" border>
                                <el-descriptions-item label="站点">{{ tableData[currentIndex].devNo }}
                                </el-descriptions-item>
                                <el-descriptions-item label="工作号">
                                    {{ tableData[currentIndex].workNo }}
                                </el-descriptions-item>
                                <el-descriptions-item label="自动">
                                    <el-tag>{{ tableData[currentIndex].autoing }}</el-tag>
                                </el-descriptions-item>
                                <el-descriptions-item label="有物">
                                    <el-tag>{{ tableData[currentIndex].loading }}</el-tag>
                                </el-descriptions-item>
                                <el-descriptions-item label="可入">
                                    <el-tag>{{ tableData[currentIndex].inEnable }}</el-tag>
                                </el-descriptions-item>
                                <el-descriptions-item label="可出">
                                    <el-tag>{{ tableData[currentIndex].outEnable }}</el-tag>
                                </el-descriptions-item>
                                <el-descriptions-item label="空板信号">
                                    <el-tag>{{ tableData[currentIndex].emptyMk }}</el-tag>
                                </el-descriptions-item>
                                <el-descriptions-item label="目标站">{{ tableData[currentIndex].staNo }}
                                </el-descriptions-item>
                                <el-descriptions-item label="高低库位">{{ tableData[currentIndex].locType1 }}
                                </el-descriptions-item>
                                <el-descriptions-item label="重量">{{ tableData[currentIndex].weight }}
                                </el-descriptions-item>
                                <el-descriptions-item label="条码">{{ tableData[currentIndex].barcode }}
                                </el-descriptions-item>
                                <el-descriptions-item label="入库标记">{{ tableData[currentIndex].pakMk }}
                                </el-descriptions-item>
                                <el-descriptions-item label="入库回退标记">{{ tableData[currentIndex].pakMkRun }}
                                </el-descriptions-item>
                                <el-descriptions-item label="入库小车任务下发标记">{{ tableData[currentIndex].pakMkTask }}
                                </el-descriptions-item>
                                <el-descriptions-item label="入库wms任务下发标记">{{ tableData[currentIndex].pakMkWalk }}
                                </el-descriptions-item>
                                <el-descriptions-item label="异常提示">{{ tableData[currentIndex].errorDev }}
                                </el-descriptions-item>
                            </el-descriptions>
                        </div>
                    </div>
                </el-card>
            </div>
        </div>
    </div>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                tableData: [],
                currentRow: null,
                currentTitle: "未选择设备",
                currentIndex: null,
                formParam: {
                    devNo: null,
                    workNo: null,
                    staNo: null,
                    pakMk: null,
                    inEnable: false,
                    outEnable: false
                }
            },
            created() {
                this.init()
            },
            watch: {
            },
            methods: {
                init() {
                    this.getTableData()
                    setInterval(() => {
                        this.getTableData()
                    }, 1000)
                },
                handleRowClick(row, col, event) {
                    const index = this.tableData.indexOf(row)
                    this.currentRow = row;
                    this.currentIndex = index
                    this.currentTitle = row.devNo + "站点"
                    this.formParam.devNo = row.devNo
                    this.formParam.workNo = row.workNo
                    this.formParam.staNo = row.staNo
                    this.formParam.pakMk = row.pakMk
                    this.formParam.inEnable = row.inEnable == "Y" ? true : false
                    this.formParam.outEnable = row.outEnable == "Y" ? true : false
                },
                getTableData() {
                    let that = this;
                    $.ajax({
                        url: baseUrl + "/site/list/auth",
                        headers: {
                            'token': localStorage.getItem('token')
                        },
                        data: {},
                        dataType: 'json',
                        contentType: 'application/json;charset=UTF-8',
                        method: 'GET',
                        success: function (res) {
                            that.tableData = res.data
                        }
                    });
                },
                requestOperate(method) {
                    let that = this
                    that.$confirm('此操作存在风险,是否继续','提示',{
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning'
                    }).then(()=>{
                        $.ajax({
                            url: baseUrl + "/site/detl/"+method,
                            headers: {
                                'token': localStorage.getItem('token')
                            },
                            data: this.formParam,
                            method: 'POST',
                            success: function (res) {
                                if (res.code == 200) {
                                    that.$message({
                                        message: res.msg,
                                        type: 'success'
                                    });
                                } else {
                                    that.$message({
                                        message: res.msg,
                                        type: 'error'
                                    });
                                }
                            }
                        });
                    })
                }
            }
        })
    </script>
</body>
</html>
src/main/webapp/views/deviceOperate/rgvOperate.html
New file
@@ -0,0 +1,212 @@
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>输送站点设备</title>
    <link rel="stylesheet" href="../../static/wcs/css/element.css">
    <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="../../static/js/common.js"></script>
    <script type="text/javascript" src="../../static/wcs/js/vue.min.js"></script>
    <script type="text/javascript" src="../../static/wcs/js/element.js"></script>
</head>
<body>
    <div id="app" style="display: flex;justify-content: center;flex-wrap: wrap;">
        <div style="width: 100%;">
            <el-table ref="singleTable" :data="tableData" highlight-current-row @row-click="handleRowClick"
                max-height="450" style="width: 100%">
                <el-table-column property="rgvNo" label="小车号">
                </el-table-column>
                <el-table-column property="taskNo" label="工作号">
                </el-table-column>
                <el-table-column property="mode" label="作业模式">
                </el-table-column>
                <el-table-column property="status" label="状态">
                </el-table-column>
                <el-table-column property="rgvPos" label="当前定位值">
                </el-table-column>
                <el-table-column property="rgvPosDestination" label="目标定位置">
                </el-table-column>
                <el-table-column property="loaded" label="探物">
                </el-table-column>
                <el-table-column property="errorRgv" label="提示">
                </el-table-column>
            </el-table>
        </div>
        <div style="width: 100%;display: flex;justify-content: center;margin-top: 10px;">
            <div style="width: 55%;margin-right: 10px;">
                <el-card class="box-card">
                    <div slot="header" class="clearfix">
                        <span>设备调试</span>
                    </div>
                    <div>
                        <el-form :model="formParam" label-position="top" :inline="true" class="demo-form-inline">
                            <el-form-item label="目标定位置">
                                <el-input v-model="formParam.rgvPosDestination" placeholder="目标定位置"></el-input>
                            </el-form-item>
                            <el-form-item label="取货站点">
                                <el-input v-model="formParam.rgvStaNoTake" placeholder="目标站点"></el-input>
                            </el-form-item>
                            <el-form-item label="目标站点">
                                <el-input v-model="formParam.rgvStaNoPut" placeholder="目标站点"></el-input>
                            </el-form-item>
                        </el-form>
                        <div>
                            <el-button @click="requestOperate('take')" type="primary">取货</el-button>
                            <el-button @click="requestOperate('put')" type="primary">放货</el-button>
                            <el-button @click="requestOperate('TakeAndPut')" type="primary">取放货</el-button>
                            <el-button @click="requestOperate('walk')" type="warning">行走</el-button>
                        </div>
                        <div style="margin-top: 10px">
                            <el-button @click="requestOperate('del')" type="warning">任务清空</el-button>
                            <el-button @click="requestOperate('del2')" type="warning">作业启动中状态复位</el-button>
                        </div>
                        <div style="margin-top: 10px">
                            <el-button @click="requestOperate('delRgvTask')" type="warning">清空wcs下发数据(运行数据需要硬件复位9S)</el-button>
                        </div>
                    </div>
                </el-card>
            </div>
            <div style="width: 45%;">
                <el-card class="box-card">
                    <div slot="header" class="clearfix">
                        <span>设备当前任务</span>
                    </div>
                    <div>
                        <div v-if="currentIndex == null">
                            <el-empty description="请选择设备"></el-empty>
                        </div>
                        <div v-else>
                            <el-table ref="singleTable" :data="taskAllData" highlight-current-row @row-click="handleRowClick"
                                      max-height="450" style="width: 100%">
                                <el-table-column property="rgvNo" label="小车号">
                                </el-table-column>
                                <el-table-column property="taskNo" label="工作号">
                                </el-table-column>
                                <el-table-column property="taskStatus" label="作业模式">
                                </el-table-column>
                                <el-table-column property="isRunning" label="状态">
                                </el-table-column>
                                <el-table-column property="targetPosition" label="目标定位置">
                                </el-table-column>
                                <el-table-column property="direction" label="方向">
                                </el-table-column>
                            </el-table>
                        </div>
                    </div>
                </el-card>
            </div>
        </div>
    </div>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                tableData: [],
                taskAllData: [],
                currentRow: null,
                currentTitle: "未选择设备",
                currentIndex: null,
                formParam: {
                    rgvNo: 0,
                    rgvStaNoTake: 0,
                    rgvStaNoPut: 0,
                    rgvPosDestination: 0
                }
            },
            created() {
                this.init()
            },
            watch: {
            },
            methods: {
                init() {
                    this.getTableData()
                    setInterval(() => {
                        this.getTableData()
                    }, 1000)
                },
                handleRowClick(row, col, event) {
                    const index = this.tableData.indexOf(row)
                    this.currentRow = row;
                    this.currentIndex = index
                    this.currentTitle = row.rgvNo + "小车"
                    this.formParam.rgvNo = row.rgvNo
                    this.formParam.rgvStaNoTake = row.rgvStaNoTake
                    this.formParam.rgvStaNoPut = row.rgvStaNoPut
                    this.formParam.rgvPosDestination = row.rgvPosDestination
                    this.getTaskAllData(index+1)
                },
                getTaskAllData(index) {
                    let that = this;
                    $.ajax({
                        url: baseUrl + "/rgv/task/cache/all",
                        headers: {
                            'token': localStorage.getItem('token')
                        },
                        data: {rgvNo: index},
                        method: 'POST',
                        success: function (res) {
                            that.taskAllData = res.data
                        }
                    });
                },
                getTableData() {
                    let that = this;
                    $.ajax({
                        url: baseUrl + "/rgv/status/all",
                        headers: {
                            'token': localStorage.getItem('token')
                        },
                        data: {},
                        dataType: 'json',
                        contentType: 'application/json;charset=UTF-8',
                        method: 'GET',
                        success: function (res) {
                            that.tableData = res.data
                        }
                    });
                },
                requestOperate(method) {
                    let that = this
                    that.$confirm('此操作存在风险,是否继续','提示',{
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning'
                    }).then(()=>{
                        $.ajax({
                            url: baseUrl + "/rgv/run/"+method,
                            headers: {
                                'token': localStorage.getItem('token')
                            },
                            data: this.formParam,
                            method: 'POST',
                            success: function (res) {
                                if (res.code == 200) {
                                    that.$message({
                                        message: res.msg,
                                        type: 'success'
                                    });
                                } else {
                                    that.$message({
                                        message: res.msg,
                                        type: 'error'
                                    });
                                }
                            }
                        });
                    })
                }
            }
        })
    </script>
</body>
</html>
src/main/webapp/views/deviceOperate/wcsOperate.html
New file
@@ -0,0 +1,678 @@
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>环形穿梭车智能系统</title>
    <link rel="stylesheet" href="../../static/wcs/css/element.css">
    <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="../../static/js/common.js"></script>
    <script type="text/javascript" src="../../static/wcs/js/vue.min.js"></script>
    <script type="text/javascript" src="../../static/wcs/js/element.js"></script>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #a0d2eb;
            color: #ffffff;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
        }
        header {
            background-color: #2196F3;
            color: white;
            padding: 15px 20px;
            text-align: center;
            font-size: 24px;
            letter-spacing: 1px;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
        }
        .map {
            position: relative;
            width: 52vw;
            height: 80vh;
            border-radius: 50%;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .inner-ring, .outer-ring {
            position: absolute;
            border-radius: 50%;
        }
        .inner-ring {
            width: 72vh;
            height: 72vh;
            border: 4px solid #00E676;
            box-shadow: inset 0 0 30px rgba(0, 230, 118, 0.5), 0 0 20px rgba(0, 230, 118, 0.5);
        }
        .outer-ring {
            width: 80vh;
            height: 80vh;
            border: 4px solid #00E676;
            box-shadow: inset 0 0 30px rgba(0, 230, 118, 0.5), 0 0 20px rgba(0, 230, 118, 0.5);
        }
        .station {
            position: absolute;
            width: 20px;
            height: 14px;
            text-align: center;
            line-height: 1.5; /* 调整行高与字体大小的比值 */
            font-size: 10px; /* 设置更小的字体 */
            font-weight: bold;
            transition: transform 0.3s ease;
            background-color: #ab1839;
            transform: scale(1); /* 可选:如果不需要放大效果 */
        }
        .bus {
            font-size: 10px;
            background-color: #2196F3;
            border: 10px solid #ffffff;
            position: absolute;
            width: 15px;
            height: 15px;
            border-radius: 50%;
            text-align: center;
            line-height: 15px;
            font-weight: bold;
            transition: transform 0.3s ease;
        }
        .station:hover, .bus:hover {
            transform: scale(1.4);
            z-index: 999;
        }
        .task-bar-left {
            position: fixed;
            top: 1%;
            /*transform: translateY(-50%);*/
            width: 25%; /* 设置宽度 */
            background-color: rgba(255, 255, 255, 0); /* 半透明背景 */
            border-radius: 5px;
            padding: 10px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0);
            z-index: 1000; /* 确保在其他元素之上 */
        }
        .task-bar-left1 {
            position: fixed;
            top: 8%;
            /*transform: translateY(-50%);*/
            width: 25%; /* 设置宽度 */
            background-color: rgba(255, 255, 255, 0); /* 半透明背景 */
            border-radius: 5px;
            padding: 10px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0);
            z-index: 1000; /* 确保在其他元素之上 */
        }
        .task-bar-right {
            position: fixed;
            top: 1%;
            /*transform: translateY(-50%);*/
            width: 25%; /* 设置宽度 */
            background-color: rgba(255, 255, 255, 0); /* 半透明背景 */
            border-radius: 5px;
            padding: 10px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0);
            z-index: 1000; /* 确保在其他元素之上 */
        }
        .task-bar-right1 {
            position: fixed;
            top: 5%;
            /*transform: translateY(-50%);*/
            width: 25%; /* 设置宽度 */
            background-color: rgba(255, 255, 255, 0); /* 半透明背景 */
            border-radius: 5px;
            padding: 10px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0);
            z-index: 1000; /* 确保在其他元素之上 */
        }
        .task-bar-div1 {
            /*width: 100%; !* 设置宽度 *!*/
            background-color: rgba(255, 255, 255, 0.8); /* 半透明背景 */
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
        }
        .left-task-bar {
            left: 20px; /* 距离左边的距离 */
            /*bottom: 100px;*/
        }
        .right-task-bar {
            /*bottom: 100px;*/
            right: 20px; /* 距离右边的距离 */
        }
        .el-table .warning-row {
            background: oldlace;
        }
        .el-table .success-row {
            background: #f0f9eb;
        }
        .container {
            width: 100vh;
            height: 72vh;
            position: absolute;
            /*background: #8c939d;*/
        }
        .bus-station {
            width: 100vh;
            height: 72vh;
            position: absolute;
            display: flex;
            /*background: #8c939d;*/
        }
        .bus-item-top {
            background: red;
            position: relative;
            width: 40px;
            height: 60px;
            line-height: 60px;
            top: 880px;
            text-align: center;
        }
        .bus-item-left {
            background: red;
            position: relative;
            width: 60px;
            height: 40px;
            line-height: 40px;
            left: 1230px;
            text-align: center;
        }
        .bus-item-left2 {
            background: red;
            position: relative;
            width: 60px;
            height: 40px;
            line-height: 40px;
            left: 1000px;
            text-align: center;
        }
    </style>
</head>
<body>
<!--<header>-->
<!--    环形穿梭车智能系统-->
<!--</header>-->
<div id="app">
    <div  class="map">
        <div v-if="licenseDayI <=30 ">
            <div style="color: red">{{licenseDay}}</div>
        </div>
        <svg class="container">
            <path d="M 1200,750
                        L 1200,100
                        C 1200,100 1200,50 1150,50
                        C 1150,50 1100,50 1100,100
                        L 1100,700
                        C 1100,700 1100,750 1050,750
                        L 60,750
                        C 60,750 10,750 10,800
                        C 10,800 10,850 60,850
                        L 1100,850
                        C 1100,850 1200,850 1200,750
"
                  style="fill:none; stroke:blue; stroke-width:4;" />
        </svg>
        <div v-for="station in tableDataDev" class="station" :style="{ top: station.valueY + 'px', left: station.valueX + 'px' }">{{ station.index }}</div>
        <div>
            <el-switch
                    style="display: block"
                    v-model="valueSystem"
                    active-color="#13ce66"
                    inactive-color="#A64036"
                    active-text="系统运行中..."
                    inactive-text="系统已停止!"
                    @change='upDateValueSystem'>
            </el-switch>
        </div>
        <div v-for="bus in tableDataRgv" class="bus" :style="{ top: bus.valueY + 'px', left: bus.valueX + 'px' , borderColor: bus.modeColor, backgroundColor: bus.statusColor}">{{ bus.index }}</div>
    </div>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            activeNames: ['1'],
            valueLeft: '0',
            valueLeft1: '0',
            valueRight: '0',
            valueRight1: '0',
            licenseDay: '已过期',
            licenseDayI: 100,
            valueSystem: false,
            tableDataRgv: [],
            tableDataDev: [],
            energyGatheringRing: [],
            tableDataLeft: [],
            tableDataLeft1: [],
            tableDataRight: [],
            tableDataRight1: [],
            devpPos1:[
                {dev_no: 116,pos:633980},
                {dev_no: 117,pos:604043},
                {dev_no: 118,pos:574323},
                {dev_no: 119,pos:559534},
                {dev_no: 120,pos:544682},
                {dev_no: 121,pos:514912},
                {dev_no: 122,pos:485227},
                {dev_no: 123,pos:470367},
                {dev_no: 124,pos:455514},
                {dev_no: 125,pos:425768},
                {dev_no: 126,pos:396268},
                {dev_no: 127,pos:381106},
                {dev_no: 128,pos:366311},
                {dev_no: 129,pos:336638},
                {dev_no: 130,pos:306820},
                {dev_no: 131,pos:277067},
                {dev_no: 132,pos:257418},
                {dev_no: 133,pos:217730},
            ],
            devpPos2:[
                {dev_no: 112,pos:891000},
                {dev_no: 113,pos:865000},
                {dev_no: 114,pos:800000},
                {dev_no: 115,pos:780000},
            ],
            devpPos3:[
                {dev_no: 101,pos:1269958},
                {dev_no: 102,pos:1243454},
                {dev_no: 103,pos:1229081},
                {dev_no: 104,pos:1202099},
                {dev_no: 105,pos:1187564},
                {dev_no: 106,pos:1160630},
                {dev_no: 107,pos:1146152},
                {dev_no: 108,pos:1119463},
                {dev_no: 109,pos:1105038},
                {dev_no: 110,pos:1077961},
                {dev_no: 111,pos:1063813},
            ],
        },
        created(){
            this.init();
            this.devpPos1.reverse()
            this.devpPos3.reverse()
        },
        watch: {
        },
        methods: {
            init(){
                this.getTableDataRgv()
                this.getTableDataDev()
                this.getTableDataTrack()
                this.getTableDataLeft()
                this.getTableDataLeft1()
                this.getTableDataRight()
                this.getTableDataRight1()
                this.getValueSystem()
                this.getLicenseDays()
                setInterval(() => {
                    this.getTableDataRgv()
                    this.getTableDataDev()
                    this.getTableDataTrack()
                    this.getTableDataLeft()
                    this.getTableDataLeft1()
                    this.getTableDataRight()
                    this.getTableDataRight1()
                    this.getValueSystem()
                    this.getLicenseDays()
                }, 1000)
            },
            verifyPassword(callback) {
                this.$prompt('请输入管理员密码: root', '验证', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    inputType: 'password',
                    inputPattern: /^root$/,
                    inputErrorMessage: '密码错误'
                }).then(({ value }) => {
                    if (value === 'root') {
                        callback();
                    }
                }).catch(() => {
                    this.$message.info('已取消操作');
                });
            },
            handleChange(val) {
                console.log(val);
                if (val.length === 0){
                    valueRight = '0';
                } else {
                    console.log("2222"+val);
                    if (val.length >= 1){
                        this.handleChangeValueRight(1)
                    }
                }
            },
            handleChange1(val) {
                console.log(val);
                if (val.length === 0){
                    valueRight1 = '0';
                } else {
                    console.log("2222"+val);
                    if (val.length >= 1){
                        this.handleChangeValueRight1(1)
                    }
                }
            },
            taskDelete(row) {
                let that = this;
                that.$confirm('确认要删除该任务吗?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    $.ajax({
                        url: baseUrl + "/rgv/disable/task/delete",
                        headers: {'token': localStorage.getItem('token')},
                        method: 'POST',
                        data: {
                            wrkNo: row.wrkNo
                        },
                        success: function (res) {
                            if (res.code === 200) {
                                that.$message.success('删除成功');
                                // 删除当前行
                                that.tableDataRight.splice(that.tableDataRight.indexOf(row), 1);
                            } else {
                                that.$message.error('删除失败');
                            }
                        }
                    });
                });
            },
            taskDelete1(row) {
                let that = this;
                that.$confirm('确认要初始化该任务吗?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    $.ajax({
                        url: baseUrl + "/rgv/disable/task/delete1",
                        headers: {'token': localStorage.getItem('token')},
                        method: 'POST',
                        data: {
                            wrkNo: row.wrkNo
                        },
                        success: function (res) {
                            if (res.code === 200) {
                                that.$message.success('初始化成功');
                                // 删除当前行
                                // that.tableDataRight.splice(that.tableDataRight.indexOf(row), 1);
                            } else {
                                that.$message.error('初始化失败');
                            }
                        }
                    });
                });
            },
            toggleStatus(index, row) {
                let that = this;
                const currentStatus = row.status;
                const targetStatus = currentStatus === 0 ? 1 : 0;
                that.$confirm(`确认要${currentStatus === 0 ? '禁用' : '启用'}该设备吗?`, '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    $.ajax({
                        url: baseUrl + "/rgv/disable/rgv/status",
                        headers: {'token': localStorage.getItem('token')},
                        method: 'POST',
                        data: {
                            rgvNo: row.rgvNo,
                            status: targetStatus
                        },
                        success: function (res) {
                            if (res.code === 200) {
                                that.$message.success(`状态更新成功`);
                                row.status$ = targetStatus; // 更新前端状态
                            } else {
                                that.$message.error('状态更新失败');
                            }
                        }
                    });
                });
            },
            handleChangeValueRight(val) {
                console.log("33333"+val);
                switch (val){
                    case 1:
                        valueRight = '100';
                    case 2:
                        valueRight = '100';
                    case 3:
                        valueRight = '100';
                    case 4:
                        valueRight = '100';
                    default:
                        valueRight = '0';
                }
            },
            handleChangeValueRight1(val) {
                console.log("33333"+val);
                switch (val){
                    case 1:
                        valueRight1 = '100';
                    case 2:
                        valueRight1 = '100';
                    case 3:
                        valueRight1 = '100';
                    case 4:
                        valueRight1 = '100';
                    default:
                        valueRight1 = '0';
                }
            },
            tableRowClassName({row, rowIndex}) {
                if (rowIndex === 1) {
                    return 'warning-row';
                } else if (rowIndex === 3) {
                    return 'success-row';
                }
                return '';
            },
            getLicenseDays(){
                let that = this;
                $.ajax({
                    url: baseUrl + "/license/getLicenseDays",
                    headers: {'token': localStorage.getItem('token')},
                    method: 'POST',
                    success: function (res) {
                        if (res.code == 200) {
                            if (res.data.day<0){
                                that.licenseDay = "已过期"+res.data.day+"天";
                                that.licenseDayI = -1;
                            } else {
                                that.licenseDay = "许可证有效期"+res.data.day+"天";
                                that.licenseDayI = res.data.day;
                            }
                        }else {
                            that.licenseDay = "已过期";
                            that.licenseDayI = -1;
                        }
                    }
                });
                // setTimeout(function() {
                //
                // }, 1000);
            },
            getValueSystem() {
                let that = this;
                $.ajax({
                    url: baseUrl + "/console/system/running/status",
                    headers: {
                        'token': localStorage.getItem('token')
                    },
                    data: {},
                    dataType: 'json',
                    contentType: 'application/json;charset=UTF-8',
                    method: 'post',
                    success: function (res) {
                        that.valueSystem = res.data.status
                    }
                });
            },
            upDateValueSystem(){
                let that = this;
                let operatorTypeI = 0;
                if (that.valueSystem){
                    operatorTypeI = 1;
                }
                this.verifyPassword(() => {
                    $.ajax({
                        url: baseUrl + "/console/system/switch",
                        headers: {'token': localStorage.getItem('token')},
                        data: {operatorType : operatorTypeI},
                        method: 'POST',
                        success: function (res) {
                            if (res.code === 200) {
                                that.valueSystem = res.data.status;
                            }
                        }
                    });
                });
            },
            getTableDataLeft() {
                let that = this;
                $.ajax({
                    url: baseUrl + "/rgv/ring/through/task/wrk/mast/position/data",
                    headers: {
                        'token': localStorage.getItem('token')
                    },
                    data: {},
                    dataType: 'json',
                    contentType: 'application/json;charset=UTF-8',
                    method: 'post',
                    success: function (res) {
                        that.tableDataLeft = res.data
                    }
                });
            },
            getTableDataLeft1() {
                let that = this;
                $.ajax({
                    url: baseUrl + "/rgv/ring/through/task/wrk/mast/position/data/v1",
                    headers: {
                        'token': localStorage.getItem('token')
                    },
                    data: {},
                    dataType: 'json',
                    contentType: 'application/json;charset=UTF-8',
                    method: 'post',
                    success: function (res) {
                        that.tableDataLeft1 = res.data
                    }
                });
            },
            getTableDataRight() {
                let that = this;
                $.ajax({
                    url: baseUrl + "/rgv/task/rgv/circular/shuttle/mast/position/data",
                    headers: {
                        'token': localStorage.getItem('token')
                    },
                    data: {},
                    dataType: 'json',
                    contentType: 'application/json;charset=UTF-8',
                    method: 'post',
                    success: function (res) {
                        that.tableDataRight = res.data
                    }
                });
            },
            getTableDataRight1() {
                let that = this;
                $.ajax({
                    url: baseUrl + "/rgv/task/rgv/circular/shuttle/mast/position/data/v1",
                    headers: {
                        'token': localStorage.getItem('token')
                    },
                    data: {},
                    dataType: 'json',
                    contentType: 'application/json;charset=UTF-8',
                    method: 'post',
                    success: function (res) {
                        that.tableDataRight1 = res.data
                    }
                });
            },
            getTableDataRgv() {
                let that = this;
                // that.tableDataRgv = busPsto
                // return
                $.ajax({
                    url: baseUrl + "/rgv/ring/through/rgv/position/data",
                    headers: {
                        'token': localStorage.getItem('token')
                    },
                    data: {},
                    dataType: 'json',
                    contentType: 'application/json;charset=UTF-8',
                    method: 'post',
                    success: function (res) {
                        that.tableDataRgv = res.data
                    }
                });
            },
            getTableDataDev() {
                let that = this;
                $.ajax({
                    url: baseUrl + "/rgv/ring/through/dev/position/data",
                    headers: {
                        'token': localStorage.getItem('token')
                    },
                    data: {},
                    dataType: 'json',
                    contentType: 'application/json;charset=UTF-8',
                    method: 'post',
                    success: function (res) {
                        that.tableDataDev = res.data
                    }
                });
            },
            getTableDataTrack() {
                let that = this;
                $.ajax({
                    url: baseUrl + "/rgv/ring/through/track/position/data",
                    headers: {
                        'token': localStorage.getItem('token')
                    },
                    data: {},
                    dataType: 'json',
                    contentType: 'application/json;charset=UTF-8',
                    method: 'post',
                    success: function (res) {
                        that.energyGatheringRing = res.data
                    }
                });
            }
        }
    })
</script>
</body>
</html>