#
Junjie
2025-11-07 b890d1c574d3d8332def7f4590508a7918139ae0
src/main/webapp/views/console.html
@@ -13,75 +13,52 @@
      <script type="text/javascript" src="../static/js/common.js"></script>
      <script type="text/javascript" src="../static/vue/js/vue.min.js"></script>
      <script type="text/javascript" src="../static/vue/element/element.js"></script>
      <style>
      </style>
   </head>
   <body>
      <div id="app">
         <div style="display: flex;justify-content: center;align-items: center;width: 100%;margin-top: 150px;">
            <div id="mapDataId" style="zoom: 0.7;position: relative;">
               <div class="pointContainer" v-for="(row,index) in map" :key="index">
                  <div v-for="(col,idx) in row" :key="idx">
                     <div v-if="col.value == 0">
                        <!-- 子轨道 路径为穿梭车预计路径则显示穿梭车颜色和穿梭车号 -->
                        <div :style="{background: checkAdvancePath(index,idx).length == 0 ? '':shuttleColorList[checkAdvancePath(index,idx)[0]]}" class="item" v-if="col.data.length > 0">{{col.data}}</div>
                        <div :style="{background: checkAdvancePath(index,idx).length == 0 ? '':shuttleColorList[checkAdvancePath(index,idx)[0]]}" class="item" v-else>{{checkAdvancePath(index,idx).length == 0 ? idx:checkAdvancePath(index,idx)}}</div>
                     </div>
                     <div v-else-if="col.value == 3">
                        <!-- 母轨道 路径为穿梭车预计路径则显示穿梭车颜色和穿梭车号 -->
                        <div :style="{background: checkAdvancePath(index,idx).length == 0 ? '#5af':shuttleColorList[checkAdvancePath(index,idx)[0]]}" class="item">{{checkAdvancePath(index,idx).length == 0 ? '&#x21c5;&#x21c4;':checkAdvancePath(index,idx)}}</div>
                     </div>
                     <div v-else-if="col.value == 4">
                        <!-- 站点 -->
                        <div class="site" :id="'site-' + col.data" @click="openSite(col.data)">{{col.data}}</div>
                     </div>
                     <div v-else-if="col.value == 5">
                        <!-- 充电桩 -->
                        <div class="item" style="font-size: 24px">&#9889;</div>
                     </div>
                     <div v-else-if="col.value == -999">
                        <!-- 路径占用区域 -->
                        <div class="item" style="background:#f83333;color: #fff;">{{idx}}</div>
                     </div>
                     <div v-else-if="col.value < 0">
                        <!-- 禁止显示区域 -->
                        <div class="item" style="visibility: hidden">{{idx}}</div>
                     </div>
                     <div v-else>
                        <div class="item" v-if="col.data.length > 0">{{col.data}}</div>
                        <div class="item" v-else>{{idx}}-{{col.value}}</div>
                     </div>
                  </div>
         <div style="display: flex;justify-content: center;align-items: center;width: 100%;margin-top: 30px;">
            <div id="mapDataId" style="zoom: 0.6;position: relative;">
               <table class="excel-table">
                  <tr v-for="(row,index) in map" :key="index">
                     <td
                           v-for="(col,idx) in row" :key="idx"
                           :rowspan="col.rowSpan"
                           :colspan="col.colSpan"
                           :style="{width: col.width}"
                           v-if="col.type != 'merge'"
                     >
                        <div v-if="col.type == 'none'">
                           <div class="item" style="visibility: hidden">{{idx}}</div>
                        </div>
                        <div v-else-if="col.type == 'shelf'">
                           <div class="shelf">{{col.shelfIdx}}</div>
                        </div>
                        <div v-else-if="col.type == 'devp'">
                           <div class="site" :style="{height: col.rowPx}" :id="'site-' + col.value" @click="openSite(col.value)">{{col.value}}</div>
                        </div>
                        <div v-else-if="col.type == 'rgv'" style="position: relative;">
                           <div class="rgv-item" v-if="getDeviceNo(col.value) != -1" :style="{width: col.width}" :id="'rgv-' + getDeviceNo(col.value)" @click="openRgv(getDeviceNo(col.value))">{{getDeviceNo(col.value)}}</div>
                           <div class="track-item" v-if="getTrackSiteNo(col.value) == -1"></div>
                           <div class="track-item" v-else :id="'rgvTrackSiteNo-' + getTrackSiteNo(col.value)"></div>
                        </div>
                        <div v-else-if="col.type == 'crn'">
                           <div class="crn-item" v-if="getDeviceNo(col.value) != -1" :style="{width: col.width}" :id="'crn-' + getDeviceNo(col.value)" @click="openCrn(getDeviceNo(col.value))">{{getDeviceNo(col.value)}}</div>
                           <div class="track-item" v-if="getTrackSiteNo(col.value) == -1"></div>
                           <div class="track-item" v-else :id="'crnTrackSiteNo-' + getTrackSiteNo(col.value)"></div>
                        </div>
                     </td>
                  <div>
                     <!-- 显示行号 -->
                     <div class="item" style="background: none;color: #000;">#{{index+1}}</div>
                  </div>
               </div>
               <!--输出小车-->
               <div v-for="(car,idx) in currentLevShuttleList"
                   :style="{
                   left: getCarPosition(car.point.x,car.point.y)[1]
                   ,top: getCarPosition(car.point.x,car.point.y)[0]
                   ,color: shuttleColorList[car.shuttleNo]
                   }"
                   class="sxcar" :id="'sxcar-' + car.shuttleNo">
                  {{car.shuttleNo}}
               </div>
                     <td>
                        <!-- 显示行号 -->
                        <div class="item" style="background: none;color: #000;">#{{index+1}}</div>
                     </td>
                  </tr>
               </table>
            </div>
            <!--输出楼层-->
            <div style="height: 100%;">
               <div class="floorBtnBox" v-for="(lev,idx) in floorList">
                  <el-button :style="{background:currentLev === lev ? '#7DCDFF':''}" @click="changFloor(lev)">{{lev}}F</el-button>
               </div>
               <div>
<!--                  <el-button @click="testMove()">测试移动车</el-button>-->
                  <el-button @click="resetMap()">重置地图</el-button>
                  <el-button @click="checkTask()">任务检测</el-button>
<!--                  <el-button @click="initLoc()">初始化库位</el-button>-->
               </div>
            </div>
         </div>
         <div class="footer">
@@ -106,63 +83,41 @@
                  </div>
               </div>
            </div>
            <!-- 四向穿梭车状态 -->
            <!-- 堆垛机状态 -->
            <div class="line-status">
               <div class="body-head">穿梭车状态</div>
               <div class="body-head">堆垛机状态</div>
               <div class="shuttle-status-box">
                  <div v-for="(item,idx) in shuttleList" class="state">
                     <span :style="{color: shuttleColorList[item.shuttleNo]}">四向穿梭车 {{item.shuttleNo}}</span>
                     <span v-if="item.protocolStatus == 1"
                        class="state-ss shuttle-idle">{{item.protocolStatus$}}</span>
                     <span v-else-if="item.protocolStatus == 2"
                        class="state-ss shuttle-working">{{item.protocolStatus$}}</span>
                     <span v-else-if="item.protocolStatus == 3"
                        class="state-ss shuttle-waiting">{{item.protocolStatus$}}</span>
                     <span v-else-if="item.protocolStatus == 4"
                        class="state-ss shuttle-charging">{{item.protocolStatus$}}</span>
                     <span v-else-if="item.protocolStatus == 5"
                        class="state-ss shuttle-charging-waiting">{{item.protocolStatus$}}</span>
                     <span v-else-if="item.protocolStatus == 6"
                        class="state-ss shuttle-fixing">{{item.protocolStatus$}}</span>
                     <span v-else-if="item.protocolStatus == 7"
                        class="state-ss shuttle-offline">{{item.protocolStatus$}}</span>
                     <span v-else class="state-ss shuttle-offline">{{item.protocolStatus$}}</span>
                  <div v-for="(item,idx) in crnList" class="state">
                     <span>堆垛机 {{item.crnNo}}</span>
                     <span v-if="item.crnStatus == 'machine-auto'"
                        class="state-ss machine-auto-flag">自动</span>
                     <span v-else-if="item.crnStatus == 'machine-un-auto'"
                        class="state-ss machine-unauto-flag">非自动/手动</span>
                     <span v-else-if="item.crnStatus == 'machine-error'"
                        class="state-ss machine-error-flag">异常</span>
                     <span v-else-if="item.crnStatus == 'machine-p-move'"
                        class="state-ss machine-p-move-flag">PToP</span>
                     <span v-else-if="item.crnStatus == 'machine-site-move'"
                        class="state-ss machine-site-move-flag">站到站</span>
                     <span v-else-if="item.crnStatus == 'machine-stock-move'"
                        class="state-ss machine-stock-move-flag">库到库</span>
                     <span v-else-if="item.crnStatus == 'machine-pakout'"
                        class="state-ss machine-take-flag">出库</span>
                     <span v-else-if="item.crnStatus == 'machine-pakin'"
                          class="state-ss machine-put-flag">入库</span>
                     <span v-else class="state-ss">{{item.crnStatus}}</span>
                  </div>
               </div>
               <div class="allStatus"><span>所有状态</span></div>
               <div class="allStatus item-group">
                  <span class="shuttle-idle">空闲</span>
                  <span class="shuttle-working">作业中</span>
                  <span class="shuttle-waiting">等待确认</span>
                  <span class="shuttle-charging">充电中</span>
                  <span class="shuttle-charging-waiting">充电任务等待确认</span>
                  <span class="shuttle-fixing">故障修复中</span>
                  <span class="shuttle-offline">离线</span>
               </div>
            </div>
            <!-- 提升机状态 -->
            <div class="line-status">
               <div class="body-head">提升机状态</div>
               <div class="lift-status-box">
                  <div v-for="(item,idx) in liftList" class="state states">
                     <span>提升机 {{item.liftNo}}</span>
                     <span v-if="item.protocolStatus == 1"
                        class="state-ss lift-idle">{{item.protocolStatus$}}</span>
                     <span v-else-if="item.protocolStatus == 2"
                        class="state-ss lift-working">{{item.protocolStatus$}}</span>
                     <span v-else-if="item.protocolStatus == 3"
                        class="state-ss lift-waiting">{{item.protocolStatus$}}</span>
                     <span v-else-if="item.protocolStatus == 4"
                        class="state-ss lift-offline">{{item.protocolStatus$}}</span>
                     <span v-else class="state-ss lift-offline">{{item.protocolStatus$}}</span>
                  </div>
               </div>
               <div class="allStatus"><span>所有状态</span></div>
               <div class="allStatus item-group">
                  <span class="lift-idle">空闲</span>
                  <span class="lift-working">作业中</span>
                  <span class="lift-waiting">等待确认</span>
                  <span class="lift-offline">离线</span>
                  <span class="machine-put-flag">入库</span>
                  <span class="machine-take-flag">出库</span>
                  <span class="machine-stock-move-flag">库到库</span>
                  <span class="machine-site-move-flag">站到站</span>
                  <span class="machine-p-move-flag">PToP</span>
                  <span class="machine-error-flag">异常</span>
                  <span class="machine-auto-flag">自动</span>
                  <span class="machine-unauto-flag">非自动/手动</span>
               </div>
            </div>
            <!-- 输送线状态 -->
@@ -204,7 +159,7 @@
         </div>
         <!-- 输送设备弹窗 -->
         <div id="siteWindow" :style="{display:siteWindow?'block':'none'}" class="animate__animated animate__fadeIn">
         <div id="siteWindow" :style="{display:siteWindow?'block':'none',zIndex: 999}" class="animate__animated animate__fadeIn">
            <!-- 表头 -->
            <div id="siteWindow-head">
               <div class="detailed"></div>
@@ -327,24 +282,223 @@
            </div>
         </div>
         <!-- 堆垛机弹窗 -->
         <div id="crnWindow" :style="{display:crnWindow?'block':'none',zIndex: 999}" class="animate__animated animate__fadeIn">
            <div id="crnWindow-head">
               <div class='detailed'></div>
               <button @click="crnWindow = false"></button>
            </div>
            <form>
               <!-- 堆垛机号 -->
               <div class="form-item">
                  <div class="form-item-label" style>
                     <span>堆垛机号:</span>
                  </div>
                  <div class="form-item-input">
                     <input type="text" name="crnNo" value="">
                  </div>
               </div>
               <!-- 工作号 -->
               <div class="form-item">
                  <div class="form-item-label">
                     <span>工作号:</span>
                  </div>
                  <div class="form-item-input">
                     <input type="text" name="workNo" value="">
                  </div>
               </div>
               <!-- 站源 -->
               <div class="form-item">
                  <div class="form-item-label">
                     <span>站源:</span>
                  </div>
                  <div class="form-item-input">
                     <input type="text" name="sourceStaNo" value="">
                  </div>
               </div>
               <!-- 目标站 -->
               <div class="form-item">
                  <div class="form-item-label">
                     <span>目标站:</span>
                  </div>
                  <div class="form-item-input">
                     <input type="text" name="staNo" value="">
                  </div>
               </div>
               <!-- 工作状态 -->
               <div class="form-item">
                  <div class="form-item-label">
                     <span>工作状态:</span>
                  </div>
                  <div class="form-item-input">
                     <input type="text" name="wrkSts" value="">
                  </div>
               </div>
               <!-- 出入类型 -->
               <div class="form-item">
                  <div class="form-item-label">
                     <span>出入类型:</span>
                  </div>
                  <div class="form-item-input">
                     <input type="text" name="ioType" value="">
                  </div>
               </div>
               <!-- 源库位 -->
               <div class="form-item">
                  <div class="form-item-label">
                     <span>源库位:</span>
                  </div>
                  <div class="form-item-input">
                     <input type="text" name="sourceLocNo" value="">
                  </div>
               </div>
               <!-- 目标库位 -->
               <div class="form-item">
                  <div class="form-item-label">
                     <span>目标库位:</span>
                  </div>
                  <div class="form-item-input">
                     <input type="text" name="locNo" value="">
                  </div>
               </div>
               <!-- 堆垛机状态 -->
               <div class="form-item">
                  <div class="form-item-label">
                     <span>堆垛机状态:</span>
                  </div>
                  <div class="form-item-input">
                     <input type="text" name="crnStatus" value="">
                  </div>
               </div>
               <!-- 异常 -->
               <div class="form-item">
                  <div class="form-item-label">
                     <span>异常:</span>
                  </div>
                  <div class="form-item-input">
                     <input type="text" name="error" value="">
                  </div>
               </div>
            </form>
         </div>
         <!-- RGV弹窗 -->
         <div id="rgvWindow" :style="{display:rgvWindow?'block':'none',zIndex: 999}" class="animate__animated animate__fadeIn">
            <div id="rgvWindow-head">
               <div class='detailed'></div>
               <button @click="rgvWindow = false"></button>
            </div>
            <form>
               <!-- RGV号 -->
               <div class="form-item">
                  <div class="form-item-label" style>
                     <span>RGV号:</span>
                  </div>
                  <div class="form-item-input">
                     <input type="text" name="rgvNo" value="">
                  </div>
               </div>
               <!-- 工作号 -->
               <div class="form-item">
                  <div class="form-item-label">
                     <span>工作号:</span>
                  </div>
                  <div class="form-item-input">
                     <input type="text" name="workNo" value="">
                  </div>
               </div>
               <!-- 站源 -->
               <div class="form-item">
                  <div class="form-item-label">
                     <span>站源:</span>
                  </div>
                  <div class="form-item-input">
                     <input type="text" name="sourceStaNo" value="">
                  </div>
               </div>
               <!-- 目标站 -->
               <div class="form-item">
                  <div class="form-item-label">
                     <span>目标站:</span>
                  </div>
                  <div class="form-item-input">
                     <input type="text" name="staNo" value="">
                  </div>
               </div>
               <!-- 工作状态 -->
               <div class="form-item">
                  <div class="form-item-label">
                     <span>工作状态:</span>
                  </div>
                  <div class="form-item-input">
                     <input type="text" name="wrkSts" value="">
                  </div>
               </div>
               <!-- 出入类型 -->
               <div class="form-item">
                  <div class="form-item-label">
                     <span>出入类型:</span>
                  </div>
                  <div class="form-item-input">
                     <input type="text" name="ioType" value="">
                  </div>
               </div>
               <!-- 源库位 -->
               <div class="form-item">
                  <div class="form-item-label">
                     <span>源库位:</span>
                  </div>
                  <div class="form-item-input">
                     <input type="text" name="sourceLocNo" value="">
                  </div>
               </div>
               <!-- 目标库位 -->
               <div class="form-item">
                  <div class="form-item-label">
                     <span>目标库位:</span>
                  </div>
                  <div class="form-item-input">
                     <input type="text" name="locNo" value="">
                  </div>
               </div>
               <!-- RGV状态 -->
               <div class="form-item">
                  <div class="form-item-label">
                     <span>RGV状态:</span>
                  </div>
                  <div class="form-item-input">
                     <input type="text" name="rgvStatus" value="">
                  </div>
               </div>
               <!-- 异常 -->
               <div class="form-item">
                  <div class="form-item-label">
                     <span>异常:</span>
                  </div>
                  <div class="form-item-input">
                     <input type="text" name="error" value="">
                  </div>
               </div>
            </form>
         </div>
      </div>
      <script>
         var app = new Vue({
            el: '#app',
            data: {
               map: [],//地图数据
               currentLev: 1,//地图当前楼层
               siteWindow: false, //站点弹窗显示默认不显示
               floorList: [], //当前项目楼层
               shuttleList: [], //四向穿梭车集合
               currentLevShuttleList: [],//当前楼层四向穿梭车集合
               shuttleColorList: [],//四向穿梭车颜色集合
               crnWindow: false, //堆垛机弹窗显示默认不显示
               rgvWindow: false, //rgv弹窗显示默认不显示
               crnList: [], //堆垛机集合
               liftList: [], //提升机集合
               systemStatus: true,//系统运行状态
               consoleInterval: null,//定时器存储变量
               codeList1: [],//条码List
               codeList2: [],//条码List
               ws: null,
               crnInitPosition: [],
               rgvPosition: [],
            },
            created() {
               this.init()
@@ -354,40 +508,95 @@
            },
            methods: {
               init() {
                  this.ws = new WebSocket("ws://" + window.location.host + baseUrl + "/console/websocket");
                  this.ws.onopen = this.webSocketOnOpen
                  this.ws.onerror = this.webSocketOnError
                  this.ws.onmessage = this.webSocketOnMessage
                  this.ws.onclose = this.webSocketClose
                  this.getMap(this.currentLev)
                  this.getMap()
                  this.getSystemRunningStatus() //获取系统运行状态
                  this.initLev()//初始化楼层信息
                  this.consoleInterval = setInterval(() => {
                     this.getShuttleStateInfo() //获取四向穿梭车信息
                     this.getLiftStateInfo() //获取提升机信息
                     this.getCrnInfo() //获取堆垛机数据
                     this.getSiteInfo() //获取输送站点数据
                     this.getMap(this.currentLev) //获取实时地图数据
                     this.getCodeData()//获取条码
                     this.getRgvInfo() //获取RGV数据
                     // this.getCodeData()//获取条码
                  }, 1000)
               },
               //获取地图数据
               getMap(lev) {
                  this.sendWs(JSON.stringify({
                     "url": "/console/map/auth",
                     "data": lev
                  }))
               getMap() {
                  let rowPx = 35;
                  let colPx = 35;
                  $.ajax({
                     url: "./test.json",
                     method: "get",
                     success: (res) => {
                        let data = res.data;
                        let mapData = JSON.parse(data)
                        mapData.forEach((row) => {
                           let shelfIdx = 1;
                           row.forEach((col) => {
                              if (col.type == 'shelf') {
                                 col.shelfIdx = shelfIdx;
                                 shelfIdx++;
                              }
                              col.rowPx = (col.rowSpan * rowPx) + "px";
                              col.colPx = (col.colSpan * colPx) + "px";
                              col.width = (col.cellWidth / 30) + "px";
                           })
                        })
                        this.map = mapData;
                     }
                  })
               },
               setMap(res) {
                  //获取地图数据
                  let data = res.data
                  let tmp = []
                  for (let i = 1; i < data.length - 1; i++) {
                     tmp.push(data[i])
                  }
                  // console.log(tmp)
                  this.map = tmp
               openCrn(id) {
                  this.crnWindow = true; //打开站点信息弹窗
                  $(".detailed").empty();
                  $('.detailed').append(id + '号堆垛机');
                  $.ajax({
                     url: baseUrl + "/console/crn/detail",
                     headers: {
                        'token': localStorage.getItem('token')
                     },
                     data: {
                        crnNo: id
                     },
                     method: 'post',
                     success: function(res) {
                        for (var val in res.data) {
                           var find = $("#crnWindow").find(":input[name='" + val + "']");
                           if (find[0].type === 'text') {
                              find.val(res.data[val]);
                           } else if (find[0].type === 'checkbox') {
                              find.attr("checked", res.data[val] === 'Y');
                           }
                        }
                     }
                  })
               },
               openRgv(id) {
                  this.rgvWindow = true; //打开RGV信息弹窗
                  $(".detailed").empty();
                  $('.detailed').append(id + '号RGV');
                  $.ajax({
                     url: baseUrl + "/console/rgv/detail",
                     headers: {
                        'token': localStorage.getItem('token')
                     },
                     data: {
                        rgvNo: id
                     },
                     method: 'post',
                     success: function(res) {
                        for (var val in res.data) {
                           var find = $("#rgvWindow").find(":input[name='" + val + "']");
                           if (find[0].type === 'text') {
                              find.val(res.data[val]);
                           } else if (find[0].type === 'checkbox') {
                              find.attr("checked", res.data[val] === 'Y');
                           }
                        }
                     }
                  })
               },
               openSite(id) {
                  this.siteWindow = true; //打开站点信息弹窗
@@ -417,77 +626,168 @@
               },
               getSiteInfo() {
                  //获取输送站点数据
                  this.sendWs(JSON.stringify({
                     "url": "/console/latest/data/site",
                     "data": {}
                  }))
               },
               setSiteInfo(res) {
                  //获取输送站点数据
                  if (res.code === 200){
                     var sites = res.data;
                     for (var i = 0; i < sites.length; i++){
                        var siteEl = $("#site-"+sites[i].siteId);
                        siteEl.attr("class", "site " + sites[i].siteStatus);
                        if (sites[i].workNo != null && sites[i].workNo>0) {
                           siteEl.html(sites[i].siteId + "[" + sites[i].workNo + "]");
                        } else {
                           siteEl.html(sites[i].siteId);
                        }
                     }
                  } else if (res.code === 403){
                     parent.location.href = baseUrl+"/login";
                  }  else {
                     console.log(res.msg);
                  }
               },
               changFloor(lev) {
                  this.currentLev = lev
                  this.currentLevShuttleList = []
                  this.getMap(lev)
               },
               getShuttleStateInfo() {
                  this.sendWs(JSON.stringify({
                     "url": "/shuttle/table/shuttle/state",
                     "data": {}
                  }))
               },
               setShuttleStateInfo(res) {
                  // 四向穿梭车信息表获取
                  let that = this
                  if (res.code == 200) {
                     let currentLevShuttle = []//当前楼层小车集合
                     res.data.forEach((item,idx) => {
                        if (item != null && item.point != undefined && item.point != null) {
                           if (item.point.z == that.currentLev) {
                              currentLevShuttle.push(item);
                  $.ajax({
                     url: baseUrl + "/console/latest/data/site",
                     headers: {'token': localStorage.getItem('token')},
                     method: 'POST',
                     success: function (res) {
                        if (res.code === 200) {
                           var sites = res.data;
                           for (var i = 0; i < sites.length; i++){
                              var siteEl = $("#site-"+sites[i].siteId);
                              siteEl.attr("class", "site " + sites[i].siteStatus);
                              if (sites[i].workNo != null && sites[i].workNo>0) {
                                 siteEl.html(sites[i].siteId + "[" + sites[i].workNo + "]");
                              } else {
                                 siteEl.html(sites[i].siteId);
                              }
                           }
                        } else if (res.code === 403) {
                           parent.location.href = baseUrl + "/login";
                        } else {
                           console.log(res.msg);
                        }
                     })
                     that.currentLevShuttleList = currentLevShuttle
                     that.shuttleList = res.data
                     if (that.shuttleColorList.length == 0) {
                        let colorList = []//随机小车颜色
                        res.data.forEach((item,idx) => {
                           colorList[item.shuttleNo] = that.colorRGB()
                        })
                        that.shuttleColorList = colorList
                     }
                  }
                  });
               },
               getLiftStateInfo() {
                  // 提升机信息表获取
                  this.sendWs(JSON.stringify({
                     "url": "/lift/table/lift/state",
                     "data": {}
                  }))
               getCrnInfo() {
                  let that = this
                  //获取堆垛机数据
                  $.ajax({
                     url: baseUrl + "/console/latest/data/crn",
                     headers: {'token': localStorage.getItem('token')},
                     method: 'POST',
                     success: function (res) {
                        if (res.code === 200) {
                           var crns = res.data;
                           if (that.crnInitPosition.length == 0) {
                              let position = []
                              for (var i = 0; i < crns.length; i++) {
                                 var crnEl = $("#crn-" + crns[i].crnId);
                                 position.push({
                                    id: crns[i].crnId,
                                    left: crnEl.offset().left + crnEl.width()
                                 })
                              }
                              that.crnInitPosition = position
                              return;
                           }
                           let crnList = []
                           for (var i = 0; i < crns.length; i++) {
                              var crnEl = $("#crn-" + crns[i].crnId);
                              crnEl.attr("class", "crn-item " + crns[i].crnStatus);
                              if (crns[i].bay < 0 || crns[i].bay === -2) {
                                 crns[i].bay = 1
                              }
                              let basePosition = 0;
                              that.crnInitPosition.forEach((item) => {
                                 if (item.id == crns[i].crnId) {
                                    basePosition = item.left
                                 }
                              })
                              var offSet = crns[i].offset;
                              let finalOffset = basePosition + offSet;
                              if (finalOffset < basePosition) {
                                 finalOffset = basePosition;
                              }
                              crnEl.animate({left: finalOffset + 'px'}, 1000);
                              crnList.push({
                                 crnNo: crns[i].crnId,
                                 crnStatus: crns[i].crnStatus
                              })
                           }
                           that.crnList = crnList;
                        } else if (res.code === 403) {
                           parent.location.href = baseUrl + "/login";
                        } else {
                           console.log(res.msg);
                        }
                     }
                  });
               },
               setLiftStateInfo(res) {
                  // 提升机信息表获取
                  if (res.code == 200) {
                     this.liftList = res.data
                  }
               getRgvInfo() {
                  let that = this
                  //获取RGV数据
                  $.ajax({
                     url: baseUrl + "/console/latest/data/rgv",
                     headers: {'token': localStorage.getItem('token')},
                     method: 'POST',
                     success: function (res) {
                        if (res.code === 200) {
                           var rgvs = res.data;
                           if (that.rgvPosition.length == 0) {
                              let position = []
                              for (var i = 0; i < rgvs.length; i++) {
                                 var rgvEl = $("#rgv-" + rgvs[i].rgvId);
                                 position.push({
                                    id: rgvs[i].rgvId,
                                    trackSiteNo: rgvs[i].trackSiteNo,
                                    initLeft: rgvEl.offset().left
                                 })
                              }
                              that.rgvPosition = position
                              return;
                           }
                           for (var i = 0; i < rgvs.length; i++) {
                              var rgvEl = $("#rgv-" + rgvs[i].rgvId);
                              if (rgvs[i].rgvStatus == 'IDLE') {
                                 rgvEl.attr("class", "rgv-item");
                              }else if (rgvs[i].rgvStatus == 'WORKING') {
                                 rgvEl.attr("class", "rgv-item machine-working");
                              }
                              let trackSiteNo = rgvs[i].trackSiteNo;
                              let trackSiteEl = $("#rgvTrackSiteNo-" + trackSiteNo);
                              let flag = false;
                              that.rgvPosition.forEach((item) => {
                                 if (item.id == rgvs[i].rgvId) {
                                    if (item.trackSiteNo != trackSiteNo) {
                                       flag = true
                                    }
                                 }
                              })
                              if (flag) {
                                 let finalOffset = 0;
                                 let targetPosition = trackSiteEl.parent().parent().position().left;
                                 let rgvPosition = rgvEl.position().left;
                                 let calcResult = targetPosition - rgvPosition
                                 if (calcResult > 0) {
                                    finalOffset = targetPosition + trackSiteEl.width();
                                 }else {
                                    finalOffset = targetPosition;
                                 }
                                 rgvEl.animate({left: finalOffset + "px"}, 500);
                                 let position = []
                                 that.rgvPosition.forEach((item) => {
                                    if (item.id == rgvs[i].rgvId) {
                                       item.trackSiteNo = trackSiteNo
                                    }
                                    position.push(item)
                                 })
                                 that.rgvPosition = position
                              }
                           }
                        } else if (res.code === 403) {
                           parent.location.href = baseUrl + "/login";
                        } else {
                           console.log(res.msg);
                        }
                     }
                  });
               },
               systemSwitch() {
                  // 系统开关
@@ -576,147 +876,87 @@
                     }
                  });
               },
               getCarPosition(x,y) {
                  //计算四向穿梭车图标位置
                  let top = (x * 35 - 35) + "px" //需要减去小车自己所占高度
                  let left = (y * 35) + "px" //需要减去小车自己所占宽度
                  return [top,left];
               },
               testMove() {
                  let that = this
                  clearInterval(this.consoleInterval)//清理定时器
                  let shuttleList = this.currentLevShuttleList
                  $.ajax({
                     url: baseUrl + "/static/testMoveData.json",
                     headers: {
                        'token': localStorage.getItem('token')
                     },
                     method: 'GET',
                     success: function(res) {
                        shuttleList[0].moveAdvancePath = res
                        that.currentLevShuttleList = shuttleList
                        let index = 0
                        let tmp = null
                        tmp = setInterval(() => {
                           if (index < res.length) {
                              that.currentLevShuttleList[0].point.y = res[index].y
                              that.currentLevShuttleList[0].point.x = res[index].x
                              index++
                           }else {
                              clearInterval(tmp)
                              that.init()
                           }
                        },1000)
                     }
                  });
               },
               colorRGB(){
                  //随机颜色
                  const r = Math.floor(Math.random()*256);
                  const g = Math.floor(Math.random()*256);
                  const b = Math.floor(Math.random()*256);
                  return `rgb(${r},${g},${b})`;
               },
               checkAdvancePath(x,y) {
                  //检测路径是否为穿梭车预计路径,如x和y路径是穿梭车预计路径,则返回小车号
                  this.currentLevShuttleList.forEach((item,idx) => {
                     if (item.moveAdvancePath != null) {
                        item.moveAdvancePath.forEach((path,index) => {
                           if (path.x === x && path.y === y) {
                              return item.shuttleNo;
                           }
                        })
                     }
                  })
                  let data = []
                  let shuttleList = this.currentLevShuttleList;
                  for (var i = 0; i < shuttleList.length; i++) {
                     let shuttle = shuttleList[i]
                     let moveAdvancePath = shuttle.moveAdvancePath
                     if (moveAdvancePath != null) {
                        for (var j = 0; j < moveAdvancePath.length; j++) {
                           let path = moveAdvancePath[j]
                           if (path.x-1 === x && path.y === y) {//路径符合
                              data.push(shuttle.shuttleNo)
                              continue;
                           }
                        }
                     }
                  }
                  return data;//返回小车号集合
               },
               resetMap() {
                  //重置地图
                  let that = this
                  $.ajax({
                     url:baseUrl+"/console/map/resetMap/" + this.currentLev,
                     headers:{
                        'token': localStorage.getItem('token')
                     },
                     data:{},
                     method:'get',
                     success:function (res) {
                        that.$message({
                           message: that.currentLev + '层地图重置完成',
                           type: 'success'
                        });
                     }
                  })
               },
               checkTask() {
                  let that = this
                  $.ajax({
                     url:baseUrl+"/console/checkTask",
                     headers:{
                        'token': localStorage.getItem('token')
                     },
                     data:{},
                     method:'get',
                     success:function (res) {
                        if (res.code === 200) {
                           that.$message({
                              message: res.msg,
                              type: 'success'
                           });
                        } else {
                           that.$message({
                              message: res.msg,
                              type: 'error'
                           });
                        }
                     }
                  })
               },
               initLev(){
                  let that = this
                  $.ajax({
                     url: baseUrl + "/console/map/lev/list",
                     headers: {
                        'token': localStorage.getItem('token')
                     },
                     data: {},
                     method: 'get',
                     success: function(res) {
                        if (res.code === 200) {
                           that.floorList = res.data;
                        } else if (res.code === 403) {
                           parent.location.href = baseUrl + "/login";
                        } else {
                           that.$message({
                              message: res.msg,
                              type: 'error'
                           });
                        }
                     }
                  });
               },
               getCodeData(){
                  this.sendWs(JSON.stringify({
                     "url": "/console/barcode/output/site",
                     "data": {}
                  }))
                  let that = this
                  //获取RGV数据
                  $.ajax({
                     url: baseUrl + "/console/barcode/output/site",
                     headers: {'token': localStorage.getItem('token')},
                     method: 'POST',
                     success: function (res) {
                        if (res.code === 200) {
                           var rgvs = res.data;
                           if (that.rgvPosition.length == 0) {
                              let position = []
                              for (var i = 0; i < rgvs.length; i++) {
                                 var rgvEl = $("#rgv-" + rgvs[i].rgvId);
                                 position.push({
                                    id: rgvs[i].rgvId,
                                    trackSiteNo: rgvs[i].trackSiteNo,
                                    initLeft: rgvEl.offset().left
                                 })
                              }
                              that.rgvPosition = position
                              return;
                           }
                           for (var i = 0; i < rgvs.length; i++) {
                              var rgvEl = $("#rgv-" + rgvs[i].rgvId);
                              if (rgvs[i].rgvStatus == 'IDLE') {
                                 rgvEl.attr("class", "rgv-item");
                              }else if (rgvs[i].rgvStatus == 'WORKING') {
                                 rgvEl.attr("class", "rgv-item machine-working");
                              }
                              let trackSiteNo = rgvs[i].trackSiteNo;
                              let trackSiteEl = $("#rgvTrackSiteNo-" + trackSiteNo);
                              let flag = false;
                              that.rgvPosition.forEach((item) => {
                                 if (item.id == rgvs[i].rgvId) {
                                    if (item.trackSiteNo != trackSiteNo) {
                                       flag = true
                                    }
                                 }
                              })
                              if (flag) {
                                 let finalOffset = 0;
                                 let targetPosition = trackSiteEl.parent().parent().position().left;
                                 let rgvPosition = rgvEl.position().left;
                                 let calcResult = targetPosition - rgvPosition
                                 if (calcResult > 0) {
                                    finalOffset = targetPosition + trackSiteEl.width();
                                 }else {
                                    finalOffset = targetPosition;
                                 }
                                 rgvEl.animate({left: finalOffset + "px"}, 500);
                                 let position = []
                                 that.rgvPosition.forEach((item) => {
                                    if (item.id == rgvs[i].rgvId) {
                                       item.trackSiteNo = trackSiteNo
                                    }
                                    position.push(item)
                                 })
                                 that.rgvPosition = position
                              }
                           }
                        } else if (res.code === 403) {
                           parent.location.href = baseUrl + "/login";
                        } else {
                           console.log(res.msg);
                        }
                     }
                  });
               },
               setCodeData(res) {
                  if(res.code === 200){
@@ -729,32 +969,34 @@
                     }
                  }
               },
               webSocketOnOpen(e) {
                  console.log("open");
               },
               webSocketOnError(e) {
                  console.log(e);
               },
               webSocketOnMessage(e) {
                  const result = JSON.parse(e.data);
                  if (result.url == "/shuttle/table/shuttle/state") {
                     this.setShuttleStateInfo(JSON.parse(result.data))
                  }else if (result.url == "/lift/table/lift/state") {
                     this.setLiftStateInfo(JSON.parse(result.data))
                  }else if (result.url == "/console/latest/data/site") {
                     this.setSiteInfo(JSON.parse(result.data))
                  }else if (result.url == "/console/map/auth") {
                     this.setMap(JSON.parse(result.data))
                  }else if (result.url == "/console/barcode/output/site") {
                     this.setCodeData(JSON.parse(result.data))
               getDeviceNo(obj) {
                  if (this.isJson(obj)) {
                     let data = JSON.parse(obj)
                     if (data.deviceNo == null || data.deviceNo == undefined) {
                        return -1;
                     }
                     return data.deviceNo;
                  }else {
                     return -1;
                  }
               },
               webSocketClose(e) {
                  console.log("close");
               getTrackSiteNo(obj) {
                  if (this.isJson(obj)) {
                     let data = JSON.parse(obj)
                     if (data.trackSiteNo == null || data.trackSiteNo == undefined) {
                        return -1;
                     }
                     return data.trackSiteNo;
                  }else {
                     return -1;
                  }
               },
               sendWs(message) {
                  if (this.ws.readyState == WebSocket.OPEN) {
                     this.ws.send(message)
               isJson(str) {
                  try {
                     JSON.parse(str);
                     return true;
                  } catch (e) {
                     return false;
                  }
               }
            }