自动化立体仓库 - WCS系统
#
Junjie
2023-09-28 3909c3583e8fc2057715ca20ac16b14072f32b14
#
1个文件已添加
15个文件已修改
1145 ■■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/RobotController.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/ShuttleController.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/domain/param/RobotReportActionStatusParam.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/LocMastMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/LocMastService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/LocMastServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/utils/Utils.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/utils/RobotUtils.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/utils/ShuttleDispatchUtils.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/MainProcess.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/protocol/NyShuttleProtocol.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/NyShuttleThread.java 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 137 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/LocMastMapper.xml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/shuttle2.html 626 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/RobotController.java
@@ -2,7 +2,19 @@
import com.zy.asrs.domain.param.RobotReportActionStatusParam;
import com.zy.asrs.domain.param.ReportExceptionParam;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.mapper.WrkMastMapper;
import com.zy.common.utils.RobotUtils;
import com.zy.core.DevpThread;
import com.zy.core.cache.MessageQueue;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.SlaveType;
import com.zy.core.model.DevpSlave;
import com.zy.core.model.Task;
import com.zy.core.model.protocol.StaProtocol;
import com.zy.core.properties.SlaveProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@@ -11,6 +23,11 @@
@RestController
public class RobotController {
    @Autowired
    private WrkMastMapper wrkMastMapper;
    @Autowired
    private SlaveProperties slaveProperties;
    //机械手向WCS回报任务结果完成
    @PostMapping("/request/wcs/report_task_status")
@@ -21,6 +38,17 @@
        Integer pickNum = param.getPick_num();
        Integer targetNum = param.getTarget_num();
        String message = param.getMessage();
        Integer staNo = param.getFrom_ws();//目标站
        //给目标站写入出库站344
        for (DevpSlave devp : slaveProperties.getDevp()) {
            // 获取入库站信息
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
            StaProtocol staProtocol = devpThread.getStation().get(staNo);//机械手臂拣料站
            staProtocol = staProtocol.clone();
            staProtocol.setStaNo((short) 344);//空托盘出库站
            boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
        }
        System.out.println(param);
        map.put("error", 0);
@@ -43,4 +71,14 @@
        return map;
    }
    @GetMapping("/test")
    public void test() {
        boolean systemStatus = RobotUtils.getSystemStatus();
    }
    @GetMapping("/test2")
    public void test2() {
        RobotUtils.sendTask("9994", 4, "317");
    }
}
src/main/java/com/zy/asrs/controller/ShuttleController.java
@@ -338,6 +338,15 @@
                    shuttleProtocol.setToken(0);//令牌清空
                    shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.IDLE);//任务状态-空闲
                    shuttleProtocol.setPakMk(false);//作业标记复位
                    shuttleProtocol.setMoveLoc(false);
                    shuttleProtocol.setMoveType(0);
                    shuttleProtocol.setXStart(0);
                    shuttleProtocol.setXTarget(0);
                    shuttleProtocol.setXCurrent(0);
                    shuttleProtocol.setYStart(0);
                    shuttleProtocol.setYTarget(0);
                    shuttleProtocol.setYCurrent(0);
                    return R.ok();
                } else if (shuttleTaskModeType == ShuttleTaskModeType.SHUTTLE_CONTROL) {
                    //小车管制
@@ -410,4 +419,40 @@
        return R.ok();
    }
    /**
     * 跑库程序
     */
    @PostMapping("/moveLoc")
    @ManagerAuth
    public R moveLoc(@RequestParam Integer shuttleNo,
                     @RequestParam Integer moveType,
                     @RequestParam Integer xStart,
                     @RequestParam Integer xTarget,
                     @RequestParam Integer yStart,
                     @RequestParam Integer yTarget) {
        NyShuttleThread shuttleThread = (NyShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
        if (shuttleThread == null) {
            return R.error();
        }
        NyShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol();
        if (shuttleProtocol == null) {
            return R.error();
        }
        if (!shuttleProtocol.isIdle()) {
            return R.error("小车忙碌中");
        }
        shuttleProtocol.setMoveLoc(true);//开启跑库
        shuttleProtocol.setMoveType(moveType);
        shuttleProtocol.setXStart(xStart);
        shuttleProtocol.setXTarget(xTarget);
        shuttleProtocol.setXCurrent(xStart);
        shuttleProtocol.setYStart(yStart);
        shuttleProtocol.setYTarget(yTarget);
        shuttleProtocol.setYCurrent(yStart);
        return R.ok();
    }
}
src/main/java/com/zy/asrs/domain/param/RobotReportActionStatusParam.java
@@ -23,4 +23,6 @@
    //结果讯息
    private String message;
    private Integer from_ws;
}
src/main/java/com/zy/asrs/mapper/LocMastMapper.java
@@ -39,4 +39,6 @@
    LocMast queryByQrCode(String qrCodeValue);
    List<LocMast> selectLocByLev(Integer lev);
    List<LocMast> selectEmptyLocNos(@Param("locNos") List<String> locNos);
}
src/main/java/com/zy/asrs/service/LocMastService.java
@@ -70,4 +70,6 @@
    //查询指定楼层的库位数据
    List<LocMast> selectLocByLev(Integer lev);
    List<LocMast> selectEmptyLocNos(List<String> locNos);
}
src/main/java/com/zy/asrs/service/impl/LocMastServiceImpl.java
@@ -91,4 +91,9 @@
    public List<LocMast> selectLocByLev(Integer lev) {
        return this.baseMapper.selectLocByLev(lev);
    }
    @Override
    public List<LocMast> selectEmptyLocNos(List<String> locNos) {
        return this.baseMapper.selectEmptyLocNos(locNos);
    }
}
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -1946,6 +1946,90 @@
    }
    /**
     * AGV补货 => 机械臂拣料
     */
    public void agvRestockByRobot() {
        //检测300站是否自动、有物、工作号
        for (DevpSlave devp : slaveProperties.getDevp()) {
            // 获取入库站信息
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
            StaProtocol staProtocol = devpThread.getStation().get(300);
            if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.getWorkNo() != 0) {
                //查询是否有工作档
                WrkMast wrkMast = wrkMastMapper.selectByWorkNo(staProtocol.getWorkNo().intValue());
                if (wrkMast == null) {
                    continue;
                }
                if (wrkMast.getWrkSts() != 25) {//25.提升机搬运完成
                    continue;
                }
                if (wrkMast.getMk().equals("Y")) {//标记为Y表示需要用到机械臂拣料
                    Short targetSta = null;//目标站
                    //判断机械臂拣料站是否空闲
                    StaProtocol staProtocol303 = devpThread.getStation().get(303);
                    StaProtocol staProtocol317 = devpThread.getStation().get(317);
                    if (staProtocol303.isAutoing() && !staProtocol303.isLoading()) {
                        //自动、无物
                        targetSta = (short) 303;
                    } else if (staProtocol317.isAutoing() && !staProtocol317.isLoading()) {
                        //自动、无物
                        targetSta = (short) 317;
                    }else {
                        continue;//没有空闲站点
                    }
                    targetSta = (short) 317;
                    //覆盖工作档目标站
                    wrkMast.setStaNo(targetSta.intValue());
                    if (wrkMastMapper.updateById(wrkMast) > 0) {
                        //向300站写入目标站
                        staProtocol = staProtocol.clone();
                        staProtocol.setStaNo(targetSta);//移动到目标站
                        boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                        try {
                            Thread.sleep(500);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        continue;
                    }
                }
            }
            StaProtocol staProtocol303 = devpThread.getStation().get(303);
            StaProtocol staProtocol317 = devpThread.getStation().get(317);
            if (staProtocol303.isAutoing() && staProtocol303.isLoading() && staProtocol303.getWorkNo() != 0) {
                //调度机械臂
                //查询是否有工作档
                WrkMast wrkMast = wrkMastMapper.selectByWorkNo(staProtocol303.getWorkNo().intValue());
                if (wrkMast == null) {
                    continue;
                }
                WrkDetl wrkDetl = wrkDetlService.selectById(wrkMast.getWrkNo());
                if (wrkDetl == null) {
                    continue;
                }
                RobotUtils.sendTask(staProtocol303.getWorkNo().toString(), wrkDetl.getAnfme().intValue(), "303");
            }else if (staProtocol317.isAutoing() && staProtocol317.isLoading() && staProtocol317.getWorkNo() != 0) {
                //调度机械臂
                //查询是否有工作档
                WrkMast wrkMast = wrkMastMapper.selectByWorkNo(staProtocol317.getWorkNo().intValue());
                if (wrkMast == null) {
                    continue;
                }
                WrkDetl wrkDetl = wrkDetlService.selectById(wrkMast.getWrkNo());
                if (wrkDetl == null) {
                    continue;
                }
                RobotUtils.sendTask(staProtocol303.getWorkNo().toString(), wrkDetl.getAnfme().intValue(), "317");
            }
        }
    }
    /**
     * 出库  ===>> 工作档信息写入led显示器
     */
    public void ledExecute() {
@@ -2240,7 +2324,7 @@
                }
            } else if (wrkCharge.getWrkSts() == 52) {
                //检测小车是否满电
                int maxPower = 85;
                int maxPower = 95;
                if (shuttleProtocol.getPowerPercent() < maxPower) {
                    continue;
                }
@@ -2257,22 +2341,32 @@
                assignCommand.setSourceLocNo(shuttleProtocol.getCurrentLocNo());//源库位(小车当前位置)
                assignCommand.setCommands(commands);//运行命令
                //下发任务
                MessageQueue.offer(SlaveType.Shuttle, assignCommand.getShuttleNo().intValue(), new Task(3, assignCommand));
                try {
                    Thread.sleep(3000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                wrkCharge.setWrkSts(53L);//52.小车去充电中 => 53.小车充电完成
                wrkCharge.setModiTime(new Date());
                if (wrkChargeMapper.updateById(wrkCharge) > 0) {
                    //下发任务
                    MessageQueue.offer(SlaveType.Shuttle, assignCommand.getShuttleNo().intValue(), new Task(3, assignCommand));
                    shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.IDLE.id);
                    shuttleProtocol.setTaskNo(0);
                    shuttleProtocol.setPakMk(false);
                }
            } else if (wrkCharge.getWrkSts() == 53) {
                if (shuttleProtocol.getChargState() == 0) {//小车处于未充电状态
                    boolean result = Utils.searchEmptyGroupToMoveShuttle(Utils.getLev(wrkCharge.getLocNo()), shuttleThread.getSlave().getId(), shuttleThread);
                    if (result) {
                        wrkCharge.setWrkSts(60L);//53.小车充电完成 => 60.充电任务完成
                        wrkCharge.setModiTime(new Date());
                        if (wrkChargeMapper.updateById(wrkCharge) > 0) {
                            shuttleProtocol.setProtocolStatusType(ShuttleProtocolStatusType.IDLE);
                            shuttleProtocol.setTaskNo(0);
                        }
                    if (!result) {
                        continue;
                    }
                    wrkCharge.setWrkSts(60L);//53.小车充电完成 => 60.充电任务完成
                    wrkCharge.setModiTime(new Date());
                    if (wrkChargeMapper.updateById(wrkCharge) > 0) {
                    }
                }
            }
src/main/java/com/zy/asrs/utils/Utils.java
@@ -505,11 +505,11 @@
        SlaveProperties slaveProperties = SpringUtils.getBean(SlaveProperties.class);
        for (ShuttleSlave shuttle : slaveProperties.getShuttle()) {
            //获取四向穿梭车线程
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttle.getId());
            NyShuttleThread shuttleThread = (NyShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttle.getId());
            if (shuttleThread == null) {
                continue;
            }
            ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol();
            NyShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol();
            if (shuttleProtocol == null) {
                continue;
            }
src/main/java/com/zy/common/utils/RobotUtils.java
@@ -23,7 +23,7 @@
        try {
            String response = new HttpHandler.Builder()
                    .setUri(robotUrl)
                    .setPath("/api/wcs/is_system_ready")
                    .setPath("/adaptor/api/wcs/is_vp_ready")
                    .setJson(JSON.toJSONString(map))
                    .build()
                    .doPost();
@@ -40,9 +40,22 @@
    }
    //WCS向机械臂下发单拆任务
    public static boolean sendTask(String taskId, Map<String, Object> skuInfo, String from, String to) {
    public static boolean sendTask(String taskId, Integer skuNum, String from) {
        Environment environment = SpringUtils.getBean(Environment.class);
        String robotUrl = environment.getProperty("robot.url");
        Map<String, Object> skuInfo = new HashMap<>();
        skuInfo.put("sku_id", "1");
        skuInfo.put("length", 500);
        skuInfo.put("width", 350);
        skuInfo.put("height", 200);
        skuInfo.put("weight", 1);
        skuInfo.put("sku_num", skuNum);
        String to = "307";
        if (from.equals("317")) {
            to = "310";
        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("task_id", taskId);
@@ -52,14 +65,15 @@
        try {
            String response = new HttpHandler.Builder()
                    .setUri(robotUrl)
                    .setPath("api/wcs/single_class_depal_task")
                    .setPath("/adaptor/api/wcs/task/single_depal")
                    .setJson(JSON.toJSONString(map))
                    .build()
                    .doPost();
            JSONObject data = JSON.parseObject(response);
            int error = Integer.parseInt(data.get("error").toString());
            if (error == 0) {
            int code = Integer.parseInt(data.get("code").toString());
            String msg = data.get("msg").toString();
            if (code == 0 && msg.equals("success")) {
                return true;//成功
            }
        } catch (IOException e) {
src/main/java/com/zy/common/utils/ShuttleDispatchUtils.java
@@ -203,6 +203,10 @@
                }
            }
            if (wrkCharge.getWrkSts() == 53) {
                toCharge = true;//充电结束,允许生成移库任务
            }
            if (!toCharge) {
                //不是去充电桩且存在充电任务,禁止生成新的移动任务
                return false;
src/main/java/com/zy/core/MainProcess.java
@@ -70,6 +70,8 @@
                    mainService.recErr();
                    // 入库  ===>> 空栈板初始化入库,叉车入库站放货
                    mainService.storeEmptyPlt();
                    // AGV补货(机械臂拣料)
                    mainService.agvRestockByRobot();
                    // 出库  ===>> 工作档信息写入led显示器
                    mainService.ledExecute();
                    // 其他  ===>> LED显示器复位,显示默认信息
src/main/java/com/zy/core/model/protocol/NyShuttleProtocol.java
@@ -204,6 +204,46 @@
     */
    private Integer token = 0;
    /**
     * 跑库状态
     */
    private Boolean moveLoc = false;
    /**
     * 跑库类型,0:跑轨道,1:跑库位
     */
    private Integer moveType = 0;
    /**
     * 跑库X起点
     */
    private Integer xStart = 0;
    /**
     * 跑库X终点
     */
    private Integer xTarget = 0;
    /**
     * 跑库X当前点位
     */
    private Integer xCurrent = 0;
    /**
     * 跑库Y起点
     */
    private Integer yStart = 0;
    /**
     * 跑库Y终点
     */
    private Integer yTarget = 0;
    /**
     * 跑库Y当前点位
     */
    private Integer yCurrent = 0;
    //总里程数
    @Data
    public static class StatusSumClass {
src/main/java/com/zy/core/thread/NyShuttleThread.java
@@ -11,6 +11,7 @@
import com.zy.asrs.utils.Utils;
import com.zy.common.model.NavigateNode;
import com.zy.common.model.NyShuttleOperaResult;
import com.zy.common.service.CommonService;
import com.zy.common.utils.*;
import com.zy.core.News;
import com.zy.core.ThreadHandler;
@@ -28,6 +29,7 @@
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import javax.swing.*;
import java.io.IOException;
import java.net.Socket;
import java.text.MessageFormat;
@@ -98,6 +100,11 @@
                    && !shuttleProtocol.getPakMk()) {
                //执行下一步指令
                executeWork(shuttleProtocol.getTaskNo().shortValue());
            }
            //小车空闲且有跑库程序
            if (shuttleProtocol.isIdle() && shuttleProtocol.getMoveLoc()) {
                moveLoc();
            }
        } catch (Exception e) {
            e.printStackTrace();
@@ -493,37 +500,6 @@
        //任务数据保存到redis
        redisUtil.set("shuttle_wrk_no_" + redisCommand.getWrkNo(), JSON.toJSONString(redisCommand));
//        //判断数据是否执行完成
//        if (commandStep < commands.size() - 1) {
//            commandStep++;
//            //更新redis数据
//            redisCommand.setCommandStep(commandStep);
//            //任务数据保存到redis
//            redisUtil.set("shuttle_wrk_no_" + redisCommand.getWrkNo(), JSON.toJSONString(redisCommand));
//        }else {
//            //已执行完成
//
//            commandStep = commands.size();
//            //更新redis数据
//            redisCommand.setCommandStep(commandStep);
//            //任务数据保存到redis
//            redisUtil.set("shuttle_wrk_no_" + redisCommand.getWrkNo(), JSON.toJSONString(redisCommand));
////            //最后一段命令为移动命令,则暂缓删除redis等待清除路径时一次性删除
////            //最后一段命令为不是移动命令,则删除redis
////            if (!command.getRequest().getBody().get("requestType").equals("move")) {
////                //删除redis
////                redisUtil.del("shuttle_wrk_no_" + redisCommand.getWrkNo());
////            }
////
////            if (!assignCommand.getCharge()) {
////                //对主线程抛出等待确认状态waiting
////                shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.WAITING);
////            }else {
////                shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.CHARGING_WAITING);
////            }
////            News.info("四向穿梭车任务执行下发完成等待执行结束,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command));
//        }
        return true;
    }
@@ -711,4 +687,56 @@
        return false;//不可行走
    }
    /**
     * 跑库程序
     */
    private void moveLoc() {
        LocMastService locMastService = SpringUtils.getBean(LocMastService.class);
        ShuttleDispatchUtils shuttleDispatchUtils = SpringUtils.getBean(ShuttleDispatchUtils.class);
        CommonService commonService = SpringUtils.getBean(CommonService.class);
        WrkMastMapper wrkMastMapper = SpringUtils.getBean(WrkMastMapper.class);
        int lev = Utils.getLev(shuttleProtocol.getCurrentLocNo());//小车当前楼层
        if (!shuttleProtocol.isIdle()) {
            return;
        }
        WrkMast wrkMast = wrkMastMapper.selectShuttleHasMoveWorking(shuttleProtocol.getShuttleNo().intValue());
        if (wrkMast != null) {
            return;
        }
        if (shuttleProtocol.getMoveType() == 0) {//跑轨道
            ArrayList<String> locs = new ArrayList<>();
            for (int i = shuttleProtocol.getXCurrent(); i <= shuttleProtocol.getXTarget(); i++) {
                String locNo = Utils.getLocNo(i, shuttleProtocol.getYCurrent(), lev);
                locs.add(locNo);
            }
            List<LocMast> locMasts = locMastService.selectEmptyLocNos(locs);
            if (locMasts.isEmpty()) {
                //空库位
                shuttleProtocol.setYCurrent(shuttleProtocol.getYCurrent() + 1);
                return;
            }
            LocMast start = locMasts.get(0);
            LocMast target = locMasts.get(locMasts.size() - 1);
            //判断小车是否在起点位置
            if (!shuttleProtocol.getCurrentLocNo().equals(start.getLocNo())) {//不在起点位置,调度去起点位置
                shuttleDispatchUtils.dispatchShuttle(commonService.getWorkNo(3), start.getLocNo());
            }else {
                //在起点位置,调度去目标位置
                if (shuttleProtocol.getCurrentLocNo().equals(target.getLocNo())) {
                    shuttleProtocol.setYCurrent(shuttleProtocol.getYCurrent() + 1);//小车和目标位置一致,跳过
                }else {
                    boolean result = shuttleDispatchUtils.dispatchShuttle(commonService.getWorkNo(3), target.getLocNo());
                    if (result) {//调度成功
                        shuttleProtocol.setYCurrent(shuttleProtocol.getYCurrent() + 1);
                    }
                }
            }
        }else {//跑库位
        }
    }
}
src/main/resources/application.yml
@@ -8,10 +8,10 @@
    name: @pom.build.finalName@
  datasource:
    driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
    url: jdbc:sqlserver://192.168.4.15:1433;databasename=tzskasrs
    url: jdbc:sqlserver://127.0.0.1:1433;databasename=tzskasrs
    username: sa
#    password: Zoneyung@zy56$
    password: sa@123
    password: sa
  mvc:
    static-path-pattern: /**
  redis:
@@ -41,7 +41,7 @@
  url: localhost:8081/tzskwms
robot:
  url: http://127.0.0.1:9090/tzskwcs
  url: http://10.10.10.41:7002
erp:
  db:
@@ -60,7 +60,7 @@
  # 输送线
  devp[0]:
    id: 1
    ip: 10.10.10.100
    ip: 10.10.10.51
    port: 102
    rack: 0
    slot: 0
@@ -74,37 +74,37 @@
    inSta[1]:
      staNo: 103
      backSta: 102
      barcode: ${wcs-slave.barcode[0].id}
      barcode: ${wcs-slave.barcode[1].id}
      led: ${wcs-slave.led[0].id}
    # 入库口3
    inSta[2]:
      staNo: 105
      backSta: 104
      barcode: ${wcs-slave.barcode[0].id}
      barcode: ${wcs-slave.barcode[2].id}
      led: ${wcs-slave.led[0].id}
    # 入库口4
    inSta[3]:
      staNo: 200
      backSta: 201
      barcode: ${wcs-slave.barcode[0].id}
      barcode: ${wcs-slave.barcode[3].id}
      led: ${wcs-slave.led[0].id}
    # 入库口5
    inSta[4]:
      staNo: 203
      backSta: 202
      barcode: ${wcs-slave.barcode[0].id}
      barcode: ${wcs-slave.barcode[4].id}
      led: ${wcs-slave.led[0].id}
    # 入库口6
    inSta[5]:
      staNo: 205
      backSta: 204
      barcode: ${wcs-slave.barcode[0].id}
      barcode: ${wcs-slave.barcode[5].id}
      led: ${wcs-slave.led[0].id}
    # 入库口7
    inSta[6]:
      staNo: 346
      backSta: 345
      barcode: ${wcs-slave.barcode[0].id}
      barcode: ${wcs-slave.barcode[8].id}
      led: ${wcs-slave.led[0].id}
    # 空板入库口1
    emptyInSta[0]:
@@ -116,37 +116,37 @@
    emptyInSta[1]:
      staNo: 103
      backSta: 102
      barcode: ${wcs-slave.barcode[0].id}
      barcode: ${wcs-slave.barcode[1].id}
      led: ${wcs-slave.led[0].id}
    # 空板入库口3
    emptyInSta[2]:
      staNo: 105
      backSta: 104
      barcode: ${wcs-slave.barcode[0].id}
      barcode: ${wcs-slave.barcode[2].id}
      led: ${wcs-slave.led[0].id}
    # 空板入库口4
    emptyInSta[3]:
      staNo: 200
      backSta: 201
      barcode: ${wcs-slave.barcode[0].id}
      barcode: ${wcs-slave.barcode[3].id}
      led: ${wcs-slave.led[0].id}
    # 空板入库口5
    emptyInSta[4]:
      staNo: 203
      backSta: 202
      barcode: ${wcs-slave.barcode[0].id}
      barcode: ${wcs-slave.barcode[4].id}
      led: ${wcs-slave.led[0].id}
    # 空板入库口6
    emptyInSta[5]:
      staNo: 205
      backSta: 204
      barcode: ${wcs-slave.barcode[0].id}
      barcode: ${wcs-slave.barcode[5].id}
      led: ${wcs-slave.led[0].id}
    # 空板入库口7
    emptyInSta[6]:
      staNo: 346
      backSta: 345
      barcode: ${wcs-slave.barcode[0].id}
      barcode: ${wcs-slave.barcode[8].id}
      led: ${wcs-slave.led[0].id}
    # 出库口1
    outSta[0]:
@@ -248,6 +248,51 @@
    id: 1
    ip: 10.10.10.102
    port: 51236
  # 条码扫描仪
  barcode[1]:
    id: 2
    ip: 10.10.10.102
    port: 51236
  # 条码扫描仪
  barcode[2]:
    id: 3
    ip: 10.10.10.102
    port: 51236
  # 条码扫描仪
  barcode[3]:
    id: 4
    ip: 10.10.10.102
    port: 51236
  # 条码扫描仪
  barcode[4]:
    id: 5
    ip: 10.10.10.102
    port: 51236
  # 条码扫描仪
  barcode[5]:
    id: 6
    ip: 10.10.10.102
    port: 51236
  # 条码扫描仪
  barcode[6]:
    id: 7
    ip: 10.10.10.102
    port: 51236
  # 条码扫描仪
  barcode[7]:
    id: 8
    ip: 10.10.10.102
    port: 51236
  # 条码扫描仪
  barcode[8]:
    id: 9
    ip: 10.10.10.102
    port: 51236
  # 条码扫描仪
  barcode[9]:
    id: 10
    ip: 10.10.10.102
    port: 51236
   # LED1
  led[0]:
@@ -267,14 +312,14 @@
  # 四向穿梭车1
  shuttle[0]:
    id: 1
    ip: 127.0.0.1
    ip: 10.10.10.101
    port: 8888
    rack: 0
    slot: 0
  # 四向穿梭车2
  shuttle[1]:
    id: 2
    ip: 192.168.4.15
    ip: 10.10.10.102
    port: 8888
    rack: 0
    slot: 0
@@ -337,111 +382,141 @@
  # 提升机1
  lift[0]:
    id: 1
    ip: 192.168.4.250
    port: 502
    row: 18
    bay: 2
    ip: 10.10.10.131
    port: 102
    staRow: 13
    staBay: 22
    sta[0]:
      staNo: 101
      lev: 1
      liftNo: ${wcs-slave.lift[0].id}
    sta[1]:
      staNo: 102
      lev: 2
      liftNo: ${wcs-slave.lift[0].id}
    sta[2]:
      staNo: 103
      lev: 3
      liftNo: ${wcs-slave.lift[0].id}
    sta[3]:
      staNo: 104
      lev: 4
      liftNo: ${wcs-slave.lift[0].id}
    sta[4]:
      staNo: 105
      lev: 5
      liftNo: ${wcs-slave.lift[0].id}
    sta[5]:
      staNo: 106
      lev: 6
      liftNo: ${wcs-slave.lift[0].id}
    sta[6]:
      staNo: 107
      lev: 7
      liftNo: ${wcs-slave.lift[0].id}
    sta[7]:
      staNo: 108
      lev: 8
      liftNo: ${wcs-slave.lift[0].id}
    sta[8]:
      staNo: 109
      lev: 9
      liftNo: ${wcs-slave.lift[0].id}
    sta[9]:
      staNo: 110
      lev: 10
      liftNo: ${wcs-slave.lift[0].id}
  # 提升机2
  lift[1]:
    id: 2
    ip: 127.0.0.1
    port: 502
    row: 18
    bay: 2
    ip: 10.10.10.132
    port: 102
    staRow: 13
    staBay: 38
    sta[0]:
      staNo: 201
      lev: 1
      liftNo: ${wcs-slave.lift[1].id}
    sta[1]:
      staNo: 202
      lev: 2
      liftNo: ${wcs-slave.lift[1].id}
    sta[2]:
      staNo: 203
      lev: 3
      liftNo: ${wcs-slave.lift[1].id}
    sta[3]:
      staNo: 204
      lev: 4
      liftNo: ${wcs-slave.lift[1].id}
    sta[4]:
      staNo: 205
      lev: 5
      liftNo: ${wcs-slave.lift[1].id}
    sta[5]:
      staNo: 206
      lev: 6
      liftNo: ${wcs-slave.lift[1].id}
    sta[6]:
      staNo: 207
      lev: 7
      liftNo: ${wcs-slave.lift[1].id}
    sta[7]:
      staNo: 208
      lev: 8
      liftNo: ${wcs-slave.lift[1].id}
    sta[8]:
      staNo: 209
      lev: 9
      liftNo: ${wcs-slave.lift[1].id}
    sta[9]:
      staNo: 210
      lev: 10
      liftNo: ${wcs-slave.lift[1].id}
  # 提升机3
  lift[2]:
    id: 3
    ip: 127.0.0.1
    port: 502
    row: 18
    bay: 2
    ip: 10.10.10.133
    port: 102
    staRow: 13
    staBay: 57
    sta[0]:
      staNo: 301
      lev: 1
      liftNo: ${wcs-slave.lift[2].id}
    sta[1]:
      staNo: 302
      lev: 2
      liftNo: ${wcs-slave.lift[2].id}
    sta[2]:
      staNo: 303
      lev: 3
      liftNo: ${wcs-slave.lift[2].id}
    sta[3]:
      staNo: 304
      lev: 4
      liftNo: ${wcs-slave.lift[2].id}
    sta[4]:
      staNo: 305
      lev: 5
      liftNo: ${wcs-slave.lift[2].id}
    sta[5]:
      staNo: 306
      lev: 6
      liftNo: ${wcs-slave.lift[2].id}
    sta[6]:
      staNo: 307
      lev: 7
      liftNo: ${wcs-slave.lift[2].id}
    sta[7]:
      staNo: 308
      lev: 8
      liftNo: ${wcs-slave.lift[2].id}
    sta[8]:
      staNo: 309
      lev: 9
      liftNo: ${wcs-slave.lift[2].id}
    sta[9]:
      staNo: 310
      lev: 10
      lev: 10
      liftNo: ${wcs-slave.lift[2].id}
src/main/resources/mapper/LocMastMapper.xml
@@ -73,4 +73,14 @@
    <select id="selectLocByLev" resultMap="BaseResultMap">
        SELECT * FROM asr_loc_mast WHERE lev1 = #{lev}
    </select>
    <select id="selectEmptyLocNos" resultMap="BaseResultMap">
        select * from asr_loc_mast
        where loc_no in
        <foreach item="loc" collection="locNos" index="index"  separator="," open="(" close=")">
            #{loc}
        </foreach>
        and loc_sts = 'O'
        order by row1
    </select>
</mapper>
src/main/webapp/views/shuttle2.html
New file
@@ -0,0 +1,626 @@
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>四向穿梭车监控管理</title>
    <link rel="stylesheet" type="text/css" href="../static/css/normalize.css">
    <link rel="stylesheet" type="text/css" href="../static/css/common.css">
    <link rel="stylesheet" type="text/css" href="../static/layui/css/layui.css">
    <link rel="stylesheet" href="../static/css/shuttle.css">
    <script type="text/javascript" src="../static/js/jquery/jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="../static/js/layer/layer.js"></script>
    <script type="text/javascript" src="../static/layui/layui.js"></script>
    <script type="text/javascript" src="../static/js/common.js"></script>
</head>
<body>
    <div style="padding: 10px;height: 100%;float: left;width: 6%">
        <div class="button-window"></div>
    </div>
    <div style="height: 100%;padding-left: 6%">
        <div style="padding: 10px;height: 100%">
            <!-- 日志监控板 -->
            <div class="log-board">
<!--                <div class="command-log" id="commandLogId" style="width: 5%;">-->
<!--&lt;!&ndash;                    <div data-shuttleNo="1" class="shuttle-command-item">&ndash;&gt;-->
<!--&lt;!&ndash;                        <label>1#</label>&ndash;&gt;-->
<!--&lt;!&ndash;                        <button class="demoBtn pos-btn">数据维护</button>&ndash;&gt;-->
<!--&lt;!&ndash;                        <button id="mode-1" class="demoBtn mode-btn" >设备信息</button>&ndash;&gt;-->
<!--&lt;!&ndash;                    </div>&ndash;&gt;-->
<!--                </div>-->
                <!-- 堆垛机状态位信息 -->
                <div class="shuttle-state" style="width: 100%;">
                    <table id="shuttle-state-table">
                        <thead>
                            <tr>
                                <th>四向穿梭车</th>
                                <th>任务状态</th>
                                <th>小车状态</th>
                                <th>工作模式</th>
                                <th>实际库位</th>
                                <th>实际坐标</th>
                                <th>电量</th>
                                <th>当前速度</th>
                                <th>负载状态</th>
                                <th>顶升位置</th>
                                <th>运行方向</th>
                                <th>运行方向2</th>
                                <th>充电状态</th>
                                <th>故障状态</th>
                                <th>故障码</th>
                                <th>管制状态</th>
                            </tr>
                        </thead>
                        <tbody>
                        </tbody>
                    </table>
                </div>
            </div>
            <!-- 穿梭车状态 -->
            <div class="shuttle-msg">
                <table id="shuttle-msg-table">
                    <thead>
                        <tr>
                            <th>四向穿梭车</th>
                            <th>工作号</th>
                            <th>源库位</th>
                            <th>目标库位</th>
                            <th>最高电芯电压</th>
                            <th>最低电芯电压</th>
                            <th>电池电压</th>
                            <th>充放电循环次数</th>
                            <th>剩余电量</th>
                            <th>总电量</th>
                            <th>总里程数</th>
                            <th>作业标记</th>
                            <th>当前库位</th>
                            <th>令牌</th>
                        </tr>
                    </thead>
                    <tbody>
                    </tbody>
                </table>
            </div>
            <!-- 手动操作 -->
            <div class="shuttle-operation">
                <!-- 遮罩层 -->
                <div class="shuttle-operation-shade">
                    <span class="shuttle-operation-shade-span">
                        WCS 系统运行中,请停止后操作
                    </span>
                </div>
                <!-- 设备任务选择 -->
                <div class="task-select">
                    <!-- 选择 -->
                    <div id="shuttle-select" class="operator-item" style="width: 100%;">
                        <span class="select-title">四向穿梭车号</span>
                        <div class="select-container" id="shuttleRadioBoxId" style="display: flex;flex-wrap: wrap;justify-content: center;align-items: center;">
<!--                            <label><input type="radio" name="shuttleSelect" value="1" checked>&nbsp;1号穿梭车</label>-->
                        </div>
                    </div>
                </div>
                <!-- 设备任务操作 -->
                <div class="task-operator">
                    <fieldset style="height: auto;padding-bottom: 20px;">
                        <legend>手动操作</legend>
                        <div style="display: flex;">
                            <div style="width: 30%;">
                                <div class="operator-item" style="height: auto;width: 100%;">
                                    <span class="select-title">源库位/目标库位</span>
                                    <div class="select-container" style="height: auto;padding: 30px 10px 20px 10px;">
                                        <div class="select-container-item">
                                            <span>源库位</span>
                                            <label><input id="sourceLocNo" type="text" name="sourceLocNo" /></label>
                                        </div>
                                        <div class="select-container-item">
                                            <span>目标库位</span>
                                            <label><input id="distLocNo" type="text" name="distLocNo" /></label>
                                        </div>
                                        <div style="margin-top: 10px;">
                                            <button class="item" onclick="shuttleOperator(18)">搬运货物</button>
                                            <button class="item" onclick="shuttleOperator(14)">移动到目标库位</button>
                                            <button class="item" onclick="shuttleOperator(23)">移动到目标库位(任务)</button>
<!--                                            <button class="item" onclick="shuttleOperator(16)">移动到提升机</button>-->
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div style="width: 40%;">
                                <div class="operator-item" style="height: auto;width: 100%;">
                                    <span class="select-title">相关指令</span>
                                    <div class="select-container" style="height: auto;padding: 30px 10px 10px 10px;">
                                        <div class="button-group">
                                            <button class="item" onclick="shuttleOperator(3)">托盘顶升</button>
                                            <button class="item" onclick="shuttleOperator(4)">托盘下降</button>
                                            <button class="item" onclick="shuttleOperator(15)">充电开关</button>
                                            <button class="item" onclick="shuttleOperator(9)">复位</button>
                                            <button class="item" onclick="shuttleOperator(21)">管制</button>
                                            <button class="item" onclick="shuttleOperator(22)">取消管制</button>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div style="width: 30%;">
                                <div class="operator-item" style="height: auto;width: 100%;">
                                    <span class="select-title">跑库系统</span>
                                    <div class="select-container" style="height: auto;padding: 30px 10px 20px 10px;">
                                        <div class="select-container-item">
                                            <span>X起点</span>
                                            <label><input id="xStart" type="text" name="xStart" /></label>
                                        </div>
                                        <div class="select-container-item">
                                            <span>X终点</span>
                                            <label><input id="xTarget" type="text" name="xTarget" /></label>
                                        </div>
                                        <div class="select-container-item">
                                            <span>Y起点</span>
                                            <label><input id="yStart" type="text" name="yStart" /></label>
                                        </div>
                                        <div class="select-container-item">
                                            <span>Y终点</span>
                                            <label><input id="yTarget" type="text" name="yTarget" /></label>
                                        </div>
                                        <div>
                                            <label><input type="radio" name="moveType" value="0">&nbsp;跑轨道</label>
                                            <label><input type="radio" name="moveType" value="1">&nbsp;跑库位</label>
                                        </div>
                                        <div style="margin-top: 10px;">
                                            <button class="item" onclick="moveLoc()">跑库</button>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </fieldset>
                </div>
            </div>
            <!-- 穿梭车日志输出 -->
            <div class="shuttle-output-board">
                <textarea id="shuttle-output"></textarea>
            </div>
        </div>
    </div>
    <div id="shuttle-detl" style="display: none">
        <div>
            <div class="form-item">
                <label class="form-label">穿梭车号:</label>
                <div class="form-input">
                    <input id="shuttleNo" name="shuttleNo" class="layui-input" lay-verify="required|number" autocomplete="off" disabled="disabled">
                </div>
            </div>
            <div class="form-item">
                <label class="form-label">工作号:</label>
                <div class="form-input">
                    <input id="workNo" name="workNo" type="number" class="layui-input" lay-verify="number" autocomplete="off">
                </div>
            </div>
            <div class="form-item">
                <label class="form-label">作业标记:</label>
                <div class="form-input">
                    <input id="pakMk" name="pakMk" type="text" class="layui-input" autocomplete="off">
                </div>
            </div>
            <div class="form-item">
                <label class="form-label">令牌:</label>
                <div class="form-input">
                    <input id="token" name="token" type="text" class="layui-input" autocomplete="off">
                </div>
            </div>
            <div class="form-item form-button-container">
                <button class="form-button" id="save">保存</button>
                <button class="form-button" id="cancel" style="background-color: #D0D0D0">取消</button>
            </div>
        </div>
    </div>
</body>
</html>
<script>
    // 空白行数
    var shuttleStateTableBlankRows = 0;
    var shuttleMsgTableBlankRows = 0;
    // 实际行数
    var shuttleStateTableFullRows = 0;
    var shuttleMsgTableFullRows = 0;
    // 初始化
    var shuttleOutputDom = document.getElementById("shuttle-output");
    $(document).ready(function() {
        initShuttleStateTable();
        getShuttleStateInfo();
        initShuttleMsgTable();
        getShuttleMsgInfo();
        operatorBlockShow();
        setShuttleRadio();
    });
    setInterval(function () {
        getShuttleStateInfo()
        getShuttleMsgInfo();
    },1000)
    setInterval(function () {
        getShuttleOutput();
        operatorBlockShow();
    },500);
    // 判断手动操作模块是否可用
    function operatorBlockShow() {
        if (parent.systemRunning) {
            $('.shuttle-operation').css("opacity", "0.5");
            $('.shuttle-operation-shade').show();
            $('.shuttle-operation-shade-span').show();
        }  else {
            $('.shuttle-operation').css("opacity", "1");
            $('.shuttle-operation-shade').hide();
            $('.shuttle-operation-shade-span').hide();
        }
    }
    function getColor(res,e){
        $(e).val(res?"✔":"—");
        if (res){
            $(e).attr("style", "color: #FD482C;");
        }else {
            $(e).attr("style", "color: #00FF00;");
        }
    }
    $(document).on('click ','#save', function () {
        http.post(baseUrl+ "/shuttle/detl/update", {
            shuttleNo: $('#shuttleNo').val(),
            workNo: $('#workNo').val(),
            pakMk: $('#pakMk').val(),
            token: $('#token').val(),
        }, function (res) {
            layer.msg("修改成功", {icon: 1,});
            layer.close(layerDetl);
        })
    })
    function setShuttleRadio() {
        $.ajax({
            url: baseUrl+ "/shuttle/table/shuttle/state",
            headers: {'token': localStorage.getItem('token')},
            method: 'POST',
            success: function (res) {
                if (res.code === 200){
                    let table = res.data;
                    for (let i=1;i<=table.length;i++){
                        //渲染四向穿梭车选项html
                        let shuttleRadioBox = '<label><input type="radio" name="shuttleSelect" ';
                        if (i === 1) {
                            shuttleRadioBox += 'checked '
                        }
                        shuttleRadioBox += 'value="' + table[i - 1].shuttleNo + '">&nbsp;' + table[i - 1].shuttleNo + '号穿梭车</label>'
                        $("#shuttleRadioBoxId").append(shuttleRadioBox)
                        //渲染四向穿梭车数据维护和设备信息html
                        let shuttleCommandLogBox = '<div class="shuttle-command-item" data-shuttleNo="' + table[i - 1].shuttleNo + '">\n' +
                            '<label>' + table[i - 1].shuttleNo + '#</label>\n' +
                            // '<button class="demoBtn pos-btn">数据维护</button>\n' +
                            // '<button class="demoBtn mode-btn" id="mode-' + table[i - 1].shuttleNo + '">设备信息</button>\n' +
                            '</div>'
                        $("#commandLogId").append(shuttleCommandLogBox);
                    }
                } else if (res.code === 403){
                    window.location.href = baseUrl+"/login";
                }  else {
                    console.log(res.msg);
                }
            }
        });
    }
    // 四向穿梭车信息表获取 ---- 表一
    function getShuttleStateInfo() {
        let tableEl = $('#shuttle-state-table');
        $.ajax({
            url: baseUrl+ "/shuttle/table/shuttle/state",
            headers: {'token': localStorage.getItem('token')},
            method: 'POST',
            success: function (res) {
                if (res.code === 200){
                    let table = res.data;
                    if (table.length > shuttleStateTableBlankRows && table.length !== shuttleStateTableFullRows) {
                        initShuttleStateTable(table.length-shuttleStateTableBlankRows);
                        shuttleStateTableFullRows = table.length;
                    }
                    for (let i=1;i<=table.length;i++){
                        // $("#mode-"+table[i-1].shuttleNo).html(table[i-1].statusVal===0?'联机':'脱机');
                        let tr = tableEl.find("tr").eq(i);
                        setVal(tr.children("td").eq(0), table[i-1].shuttleNo);
                        setVal(tr.children("td").eq(1), table[i-1].protocolStatus$);
                        setVal(tr.children("td").eq(2), table[i-1].free$);
                        setVal(tr.children("td").eq(3), table[i-1].workingMode$);
                        setVal(tr.children("td").eq(4), table[i-1].point$);
                        setVal(tr.children("td").eq(5), table[i-1].point$$);
                        setVal(tr.children("td").eq(6), table[i-1].powerPercent$);
                        setVal(tr.children("td").eq(7), table[i-1].speed);
                        setVal(tr.children("td").eq(8), table[i-1].loadState$);
                        setVal(tr.children("td").eq(9), table[i-1].liftPosition$);
                        setVal(tr.children("td").eq(10), table[i-1].runDir$);
                        setVal(tr.children("td").eq(11), table[i-1].runDir2$);
                        setVal(tr.children("td").eq(12), table[i-1].chargState$);
                        setVal(tr.children("td").eq(13), table[i-1].errState$);
                        setVal(tr.children("td").eq(14), table[i-1].errCode$);
                        setVal(tr.children("td").eq(15), table[i-1].suspendState$);
                    }
                } else if (res.code === 403){
                    window.location.href = baseUrl+"/login";
                }  else {
                    console.log(res.msg);
                }
            }
        });
    }
    // 四向穿梭车数据表获取 ---- 表二
    function getShuttleMsgInfo() {
        let tableEl = $('#shuttle-msg-table');
        $.ajax({
            url: baseUrl+ "/shuttle/table/shuttle/state",
            headers: {'token': localStorage.getItem('token')},
            method: 'POST',
            success: function (res) {
                if (res.code === 200){
                    var table = res.data;
                    if (table.length > shuttleMsgTableBlankRows && table.length !== shuttleMsgTableFullRows) {
                        initShuttleMsgTable(table.length-shuttleMsgTableBlankRows);
                        shuttleMsgTableFullRows = table.length;
                    }
                    for (var i=1;i<=table.length;i++){
                        var tr = tableEl.find("tr").eq(i);
                        setVal(tr.children("td").eq(0), table[i-1].shuttleNo);
                        setVal(tr.children("td").eq(1), table[i-1].taskNo);
                        setVal(tr.children("td").eq(2), table[i-1].sourceLocNo);
                        setVal(tr.children("td").eq(3), table[i-1].locNo);
                        setVal(tr.children("td").eq(4), table[i-1].maxCellVoltage$);
                        setVal(tr.children("td").eq(5), table[i-1].minCellVoltage$);
                        setVal(tr.children("td").eq(6), table[i-1].voltage$);
                        setVal(tr.children("td").eq(7), table[i-1].chargeCycleTimes);
                        setVal(tr.children("td").eq(8), table[i-1].surplusQuantity);
                        setVal(tr.children("td").eq(9), table[i-1].countQuantity);
                        setVal(tr.children("td").eq(10), table[i-1].statusSum.mileage);
                        setVal(tr.children("td").eq(11), table[i-1].pakMk$);
                        setVal(tr.children("td").eq(12), table[i-1].currentLocNo);
                        setVal(tr.children("td").eq(13), table[i-1].token);
                        if (table[i-1].shuttleNo == parseInt($('input[name="shuttleSelect"]:checked').val())) {
                            $("#runSpeedText").text(table[i-1].runSpeed)
                            $("#chargeLineText").text(table[i-1].chargeLine + "%")
                        }
                    }
                } else if (res.code === 403){
                    window.location.href = baseUrl+"/login";
                }  else {
                    console.log(res.msg);
                }
            }
        });
    }
    // 穿梭车日志输出 -----------------------------------------------------------------------
    function getShuttleOutput() {
        $.ajax({
            url: baseUrl + "/shuttle/output/shuttle",
            headers: {'token': localStorage.getItem('token')},
            method: 'POST',
            success: function (res) {
                if (res.code === 200) {
                    shuttleOutput(res.data);
                } else if (res.code === 403) {
                    window.location.href = baseUrl + "/login";
                } else {
                    console.log(res.msg);
                }
            }
        })
    }
    // 任务指令下发
    function shuttleOperator(shuttleTaskMode) {
        http.post(baseUrl+"/shuttle/operator/shuttle", {
            shuttleNo: $('input[name="shuttleSelect"]:checked').val(),
            shuttleTaskMode: shuttleTaskMode,
            sourceLocNo: $("#sourceLocNo").val(),
            distLocNo: $("#distLocNo").val()
        }, function (res) {
            layer.msg(res.msg, {icon: 1});
        });
    }
    // 跑库
    function moveLoc() {
        $.ajax({
            url: baseUrl + "/shuttle/moveLoc",
            headers: {'token': localStorage.getItem('token')},
            method: 'POST',
            data: {
                shuttleNo: $('input[name="shuttleSelect"]:checked').val(),
                xStart: $("#xStart").val(),
                xTarget: $("#xTarget").val(),
                yStart: $("#yStart").val(),
                yTarget: $("#yTarget").val(),
                moveType: $('input[name="moveType"]:checked').val()
            },
            success: function (res) {
                if (res.code === 200) {
                    layer.msg(res.msg, {icon: 1});
                } else if (res.code === 403) {
                    window.location.href = baseUrl + "/login";
                } else {
                    console.log(res.msg);
                }
            }
        })
    }
    // ------------------------------------------------------------------------------------------------
    // 四向穿梭车信息表获取  ----- 表一
    function initShuttleStateTable(row) {
        let line;
        if (row === undefined){
            let one = $('#shuttle-state-table thead').height();
            let total = $('.shuttle-state').height();
            let count = total / one;
            count = parseInt(count) - 1;
            shuttleStateTableBlankRows = count;
            line = count;
        } else {
            line = row;
        }
        let html = "";
        for (let i = 0; i < line; i ++){
            html += " <tr>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "     </tr>\n";
        }
        $('#shuttle-state-table tbody').after(html);
    }
    // 穿梭车数据表获取  ----- 表二
    function initShuttleMsgTable(row) {
        let line;
        if (row === undefined){
            let one = $('#shuttle-msg-table thead').height();
            let total = $('.shuttle-msg').height();
            let count = total / one;
            count = parseInt(count) - 1;
            shuttleMsgTableBlankRows = count;
            line = count;
        } else {
            line = row;
        }
        let html = "";
        for (let i = 0; i < line; i ++){
            html += " <tr>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "     </tr>\n";
        }
        $('#shuttle-msg-table tbody').after(html);
    }
    // 日志输出框
    function shuttleOutput(content){
        shuttleOutputDom.value += content;
        shuttleOutputDom.scrollTop = shuttleOutputDom.scrollHeight;
    }
    //四向穿梭车配置参数保存
    function shuttleParamSave() {
        $.ajax({
            url: baseUrl+ "/shuttle/runSpeed/" + $('input[name="shuttleSelect"]:checked').val(),
            headers: {'token': localStorage.getItem('token')},
            method: 'POST',
            data: {
                runSpeed: $("#runSpeed").val(),
                chargeLine: $("#chargeLine").val(),
            },
            success: function (res) {
                if (res.code === 200){
                    layer.msg("配置已保存", {icon: 1,});
                } else if (res.code === 403){
                    window.location.href = baseUrl+"/login";
                }  else {
                    console.log(res.msg);
                }
            }
        });
    }
    // 详情操作 -------------------------------------------------------------------------
    var layerDetl;
    $(document).on('dblclick ','#shuttle-msg-table tr', function () {
        var shuttleNo = $(this).children("td").eq(0).html();
        if (shuttleNo !== null && shuttleNo !== "") {
            layerDetl = layer.open({
                type: 1,
                title: false,
                shadeClose: true,
                offset: 'rt',
                anim: 5,
                shade: [0],
                area: ['340px', '255px'],
                closeBtn: 0,
                content: $("#shuttle-detl"),
                success: function(layero, index){
                    $.ajax({
                        url: baseUrl+ "/shuttle/table/shuttle/state",
                        headers: {'token': localStorage.getItem('token')},
                        method: 'POST',
                        success: function (res) {
                            if (res.code === 200){
                                var table = res.data;
                                for (var i=1;i<=table.length;i++){
                                    if (shuttleNo == table[i-1].shuttleNo) {
                                        $('#shuttleNo').val(shuttleNo);
                                        $('#workNo').val(table[i-1].taskNo);
                                        $('#pakMk').val(table[i-1].pakMk$);
                                        $('#token').val(table[i-1].token);
                                    }
                                }
                            } else if (res.code === 403){
                                window.location.href = baseUrl+"/login";
                            }  else {
                                console.log(res.msg);
                            }
                        }
                    });
                },
                end: function () {
                    $('#shuttleNo').val("");
                    $('#workNo').val("");
                    $('#pakMk').val("");
                    $('#token').val("");
                }
            })
        }
    });
    $(document).on('click ','#cancel', function () {
        $('#shuttleNo').val("");
        $('#workNo').val("");
        $('#pakMk').val("");
        $('#token').val("");
        layer.close(layerDetl);
    })
</script>