| <!DOCTYPE html> | 
| <html lang="en"> | 
| <head> | 
|     <meta charset="UTF-8"> | 
|     <title>库位地图</title> | 
|     <link rel="stylesheet" href="../../static/layui/css/layui.css" media="all"> | 
|     <link rel="stylesheet" href="../../static/css/admin.css?v=318" media="all"> | 
|     <link rel="stylesheet" href="../../static/css/cool.css" media="all"> | 
|     <link rel="stylesheet" href="../../static/css/element.css"> | 
|     <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script> | 
|     <script type="text/javascript" src="../../static/layui/layui.js"></script> | 
|     <script type="text/javascript" src="../../static/js/handlebars/handlebars-v4.5.3.js"></script> | 
|     <script type="text/javascript" src="../../static/js/common.js"></script> | 
|     <script type="text/javascript" src="../../static/js/vue.min.js"></script> | 
|     <script type="text/javascript" src="../../static/js/element.js"></script> | 
|     <style> | 
|         .pointContainer { | 
|             display: flex; | 
|             justify-content: center; | 
|             /*margin-top: 1px;*/ | 
|         } | 
|   | 
|         .pointBox { | 
|             background: #bababa; | 
|             width: 40px; | 
|             height: 40px; | 
|             /*margin-right: 1px;*/ | 
|             display: flex; | 
|             justify-content: center; | 
|             align-items: center; | 
|             font-size: 14px; | 
|             user-select: none; | 
|             color: #fff; | 
|         } | 
|   | 
|         .pointBox:hover{ | 
|             background: #00ff7f; | 
|         } | 
|   | 
|         .pointBoxEmpty { | 
|             background: #c2c934; | 
|         } | 
|   | 
|         .pointBoxOut { | 
|             background: #f1aa19; | 
|         } | 
|   | 
|         .pointBoxOutYy { | 
|             background: #618593; | 
|         } | 
|   | 
|         .pointBoxInYy { | 
|             background: #fa736f; | 
|         } | 
|   | 
|         .pointBoxGreen { | 
|             background: #00ff7f; | 
|         } | 
|   | 
|         .pointBoxBlue { | 
|             background: #55aaff; | 
|         } | 
|   | 
|         .pointBoxRed { | 
|             background: #ff0000; | 
|         } | 
|   | 
|         .pointBoxStart { | 
|             background: #ffaa00; | 
|         } | 
|   | 
|         .pointBoxEnd { | 
|             background: #ff55ff; | 
|         } | 
|   | 
|         .pointBoxStation { | 
|             background: #ffff00; | 
|         } | 
|   | 
|         .chargeStation { | 
|             background: #ffaa7f; | 
|         } | 
|   | 
|         .pointBoxDefault { | 
|             background: #86779d; | 
|         } | 
|   | 
|         .pointBoxSelected { | 
|             background: #00ff7f !important; | 
|         } | 
|   | 
|         .pointBoxSearch { | 
|             background: #9900ff; | 
|         } | 
|   | 
|         .crnLine{ | 
|             width: auto; | 
|             height: 2px; | 
|             margin: 10px 0; | 
|             background: #000; | 
|             position: relative; | 
|         } | 
|   | 
|         .popBox { | 
|             position: absolute; | 
|         } | 
|   | 
|         /*卡片样式start*/ | 
|         .apple-card { | 
|             width: 190px; | 
|             height: 254px; | 
|             margin: 0 auto; | 
|             background-color: #011522; | 
|             border-radius: 8px; | 
|             z-index: 1; | 
|             animation:fadeInOut 0.5s 1; | 
|         } | 
|   | 
|         .apple-card .tools { | 
|             display: flex; | 
|             align-items: center; | 
|             padding: 9px; | 
|         } | 
|   | 
|         .apple-card .circle { | 
|             padding: 0 4px; | 
|         } | 
|   | 
|         .apple-card .box { | 
|             display: inline-block; | 
|             align-items: center; | 
|             width: 10px; | 
|             height: 10px; | 
|             padding: 1px; | 
|             border-radius: 50%; | 
|         } | 
|   | 
|         .apple-card .red { | 
|             background-color: #ff605c; | 
|             position: relative; | 
|         } | 
|   | 
|         .apple-card .red:hover{ | 
|             background-color: #ff0300; | 
|         } | 
|   | 
|         .apple-card .red:hover::before { | 
|             content: "x"; | 
|             font-size: 11px; | 
|             color: #fff; | 
|             width: 10px; | 
|             height: 10px; | 
|             display: flex; | 
|             justify-content: center; | 
|             align-items: center; | 
|             position: absolute; | 
|             animation:fadeInOut 0.5s 1; | 
|         } | 
|   | 
|         .apple-card .yellow { | 
|             background-color: #ffbd44; | 
|         } | 
|   | 
|         .apple-card .green { | 
|             background-color: #00ca4e; | 
|         } | 
|   | 
|         .apple-card .card-content{ | 
|             color: #fff; | 
|             padding: 10px; | 
|         } | 
|         /*卡片样式end*/ | 
|   | 
|         /*滑动卡片start*/ | 
|         .hoverCard { | 
|             width: 150px; | 
|             height: 224px; | 
|             border-radius: 20px; | 
|             background: #f5f5f5; | 
|             position: relative; | 
|             padding: 1.8rem; | 
|             border: 2px solid #c3c6ce; | 
|             transition: 0.5s ease-out; | 
|             overflow: visible; | 
|             margin-top: 30px; | 
|         } | 
|   | 
|         .hoverCard .card-details { | 
|             color: black; | 
|             height: 100%; | 
|             gap: .5em; | 
|             display: grid; | 
|             place-content: center; | 
|         } | 
|   | 
|         .hoverCard .card-button { | 
|             transform: translate(-50%, 125%); | 
|             width: 60%; | 
|             border-radius: 1rem; | 
|             border: none; | 
|             background-color: #008bf8; | 
|             color: #fff; | 
|             font-size: 1rem; | 
|             padding: .5rem 1rem; | 
|             position: absolute; | 
|             left: 50%; | 
|             bottom: 0; | 
|             opacity: 0; | 
|             transition: 0.3s ease-out; | 
|         } | 
|   | 
|         .hoverCard .text-body { | 
|             color: rgb(134, 134, 134); | 
|         } | 
|   | 
|         /*Text*/ | 
|         .hoverCard .text-title { | 
|             font-size: 1.5em; | 
|             font-weight: bold; | 
|         } | 
|   | 
|         /*Hover*/ | 
|         .hoverCard:hover { | 
|             border-color: #008bf8; | 
|             box-shadow: 0 4px 18px 0 rgba(0, 0, 0, 0.25); | 
|         } | 
|   | 
|         .hoverCard:hover .card-button { | 
|             transform: translate(-50%, 50%); | 
|             opacity: 1; | 
|         } | 
|         /*滑动卡片end*/ | 
|   | 
|         /*楼层控制start*/ | 
|         .floorSelect { | 
|             --text: #414856; | 
|             --radio: #7C96B2; | 
|             --radio-checked: #4F29F0; | 
|             --radio-size: 20px; | 
|             --width: 150px; | 
|             --height: 200px; | 
|             --border-radius: 10px; | 
|             width: var(--width); | 
|             height: var(--height); | 
|             border-radius: var(--border-radius); | 
|             color: var(--text); | 
|             position: relative; | 
|             box-shadow: 0 10px 30px rgba(65, 72, 86, 0.05); | 
|             display: grid; | 
|             grid-template-columns: auto var(--radio-size); | 
|             align-items: center; | 
|         } | 
|   | 
|         .floorSelect label { | 
|             cursor: pointer; | 
|         } | 
|   | 
|         .floorSelect input[type="radio"] { | 
|             -webkit-appearance: none; | 
|             -moz-appearance: none; | 
|             position: relative; | 
|             height: var(--radio-size); | 
|             width: var(--radio-size); | 
|             outline: none; | 
|             margin: 0; | 
|             cursor: pointer; | 
|             border: 2px solid var(--radio); | 
|             background: transparent; | 
|             border-radius: 50%; | 
|             display: grid; | 
|             justify-self: end; | 
|             justify-items: center; | 
|             align-items: center; | 
|             overflow: hidden; | 
|             transition: border .5s ease; | 
|         } | 
|   | 
|         .floorSelect input[type="radio"]::before, .floorSelect input[type="radio"]::after { | 
|             content: ""; | 
|             display: flex; | 
|             justify-self: center; | 
|             border-radius: 50%; | 
|         } | 
|   | 
|         .floorSelect input[type="radio"]::before { | 
|             position: absolute; | 
|             width: 100%; | 
|             height: 100%; | 
|             z-index: 1; | 
|             opacity: var(--opacity, 1); | 
|         } | 
|   | 
|         .floorSelect input[type="radio"]::after { | 
|             position: relative; | 
|             width: calc(100% /2); | 
|             height: calc(100% /2); | 
|             background: var(--radio-checked); | 
|             top: var(--y, 100%); | 
|             transition: top 0.5s cubic-bezier(0.48, 1.97, 0.5, 0.63); | 
|         } | 
|   | 
|         .floorSelect input[type="radio"]:checked { | 
|             --radio: var(--radio-checked); | 
|         } | 
|   | 
|         .floorSelect input[type="radio"]:checked::after { | 
|             --y: 0%; | 
|             animation: stretch-animate .3s ease-out .17s; | 
|         } | 
|   | 
|         .floorSelect input[type="radio"]:checked::before { | 
|             --opacity: 0; | 
|         } | 
|   | 
|         .floorSelect input[type="radio"]:checked ~ input[type="radio"]::after { | 
|             --y: -100%; | 
|         } | 
|   | 
|         .floorSelect input[type="radio"]:not(:checked)::before { | 
|             --opacity: 1; | 
|             transition: opacity 0s linear .5s; | 
|         } | 
|   | 
|         @keyframes stretch-animate { | 
|             0% { | 
|                 transform: scale(1, 1); | 
|             } | 
|   | 
|             28% { | 
|                 transform: scale(1.15, 0.85); | 
|             } | 
|   | 
|             50% { | 
|                 transform: scale(0.9, 1.1); | 
|             } | 
|   | 
|             100% { | 
|                 transform: scale(1, 1); | 
|             } | 
|         } | 
|         /*楼层控制end*/ | 
|   | 
|         /*搜索start*/ | 
|         .search-input { | 
|             line-height: 28px; | 
|             border: 2px solid transparent; | 
|             border-bottom-color: #777; | 
|             padding: .2rem 0; | 
|             outline: none; | 
|             background-color: transparent; | 
|             color: #0d0c22; | 
|             transition: .3s cubic-bezier(0.645, 0.045, 0.355, 1); | 
|         } | 
|   | 
|         .search-input:focus, .search-input:hover { | 
|             outline: none; | 
|             padding: .2rem 1rem; | 
|             border-radius: 1rem; | 
|             border-color: #7a9cc6; | 
|         } | 
|   | 
|         .search-input::placeholder { | 
|             color: #777; | 
|         } | 
|   | 
|         .search-input:focus::placeholder { | 
|             opacity: 0; | 
|             transition: opacity .3s; | 
|         } | 
|         /*搜索end*/ | 
|   | 
|         @keyframes fadeInOut { | 
|             0%{ | 
|                 opacity: 0; | 
|             } | 
|             100%{ | 
|                 opacity: 1; | 
|             } | 
|         } | 
|     </style> | 
| </head> | 
| <body> | 
| <div id="app" style="display: flex;justify-content: space-around;margin-top: 50px;flex-wrap: wrap;" @click="bgClick()"> | 
|     <div style="flex: 18;display: flex;justify-content: center;" :style="{zoom:showScale/100.0,marginTop:(showScale)*4 + 'px'}"> | 
|         <div style="margin-top: -110px;"> | 
|             <div class="pointContainer" v-for="(x,index) in map" :key="index"> | 
|                 <div v-if="index != 0 && (index != map.length-1)" v-for="(y,idx) in x" :key="idx"> | 
|                     <div v-if="idx != 0 && (idx != map[index].length-1)"> | 
|                         <div v-if="map[index][idx].value < 0" style="visibility: hidden;" class="pointBox"></div> | 
|   | 
|                         <!--库位--> | 
|                         <div v-else-if="map[index][idx].value  == 0" @contextmenu.prevent="rightEvent(index,idx,$event)"> | 
|                             <div v-if="map[index][idx].locSts == 'O'" :class="{'pointBoxSearch':map[index][idx].searchStatus}" class="pointBox pointBoxBlue">{{ map[index][idx].locSts }}</div> | 
|                             <div v-else-if="map[index][idx].locSts == 'F'" @click.left="selectLoc(index,idx)" :class="{'pointBoxSelected':map[index][idx].locOutSelected,'pointBoxSearch':map[index][idx].searchStatus}" class="pointBox pointBoxRed">{{ map[index][idx].locSts }}</div> | 
|                             <div v-else-if="map[index][idx].locSts == 'D'" :class="{'pointBoxSearch':map[index][idx].searchStatus}" class="pointBox pointBoxEmpty">{{ map[index][idx].locSts }}</div> | 
|                             <div v-else-if="map[index][idx].locSts == 'P'" :class="{'pointBoxSearch':map[index][idx].searchStatus}" class="pointBox pointBoxOut">{{ map[index][idx].locSts }}</div> | 
|                             <div v-else-if="map[index][idx].locSts == 'R'" :class="{'pointBoxSearch':map[index][idx].searchStatus}" class="pointBox pointBoxOutYy">{{ map[index][idx].locSts }}</div> | 
|                             <div v-else-if="map[index][idx].locSts == 'S'" class="pointBox pointBoxInYy">{{ map[index][idx].locSts }}</div> | 
|                             <div v-else class="pointBox pointBoxDefault" :class="{'pointBoxSearch':map[index][idx].searchStatus}">{{ map[index][idx].locSts }}</div> | 
|                         </div> | 
|   | 
|                         <!--母轨道--> | 
|                         <div v-else-if="map[index][idx].value  == 3"> | 
|                             <div class="pointBox" style="visibility: hidden;"></div> | 
|                         </div> | 
|   | 
|                         <!--站点--> | 
|                         <div v-else-if="map[index][idx].value  == 4" class="pointBox pointBoxStation" style="visibility: hidden;"></div> | 
|                         <div v-else-if="map[index][idx].value  == 5" class="pointBox chargeStation" | 
|                              @contextmenu.prevent="rightEvent(index,idx,$event)"></div> | 
|                         <div v-else-if="map[index][idx].value  == 9" class="pointBox pointBoxRed" | 
|                              @contextmenu.prevent="rightEvent(index,idx,$event)"></div> | 
|   | 
|                     </div> | 
|                 </div> | 
|   | 
|                 <div style="width: 40px;display: flex;justify-content: center;align-items: center;"> | 
|                     {{ getRealRowByX(index) }} | 
|                 </div> | 
|   | 
|             </div> | 
|         </div> | 
|   | 
|         <div> | 
|             <div style="margin-top: 20px;"><button class="layui-btn" @click="currentLev = 1" :style="{background: currentLev==1?'red':''}">1F</button></div> | 
|             <div style="margin-top: 20px;"><button class="layui-btn" @click="currentLev = 2" :style="{background: currentLev==2?'red':''}">2F</button></div> | 
|             <div style="margin-top: 20px;"><button class="layui-btn" @click="currentLev = 3" :style="{background: currentLev==3?'red':''}">3F</button></div> | 
|             <div style="margin-top: 20px;"><button class="layui-btn" @click="currentLev = 4" :style="{background: currentLev==4?'red':''}">4F</button></div> | 
|             <div style="margin-top: 20px;"><button class="layui-btn" @click="currentLev = 5" :style="{background: currentLev==5?'red':''}">5F</button></div> | 
|             <div style="margin-top: 20px;"><button class="layui-btn" @click="currentLev = 6" :style="{background: currentLev==6?'red':''}">6F</button></div> | 
|             <div style="margin-top: 20px;"><button class="layui-btn" @click="currentLev = 7" :style="{background: currentLev==7?'red':''}">7F</button></div> | 
|             <div style="margin-top: 20px;"><button class="layui-btn" @click="currentLev = 8" :style="{background: currentLev==8?'red':''}">8F</button></div> | 
|             <div style="margin-top: 20px;"><button class="layui-btn" @click="currentLev = 9" :style="{background: currentLev==9?'red':''}">9F</button></div> | 
|             <div style="margin-top: 20px;"><button class="layui-btn" @click="currentLev = 10" :style="{background: currentLev==10?'red':''}">10F</button></div> | 
|         </div> | 
|     </div> | 
|     <div style="padding: 40px 20px 10px 10px;" :style="window.innerWidth < 2100 ? 'margin-top: 0px;' : 'flex: 5;margin-top: -70px;'"> | 
|         <el-slider v-model="showScale" :marks="showScaleMarks"></el-slider> | 
|         <div style="display: flex;justify-content: space-between;flex-wrap: wrap;"> | 
|             <div class="hoverCard" style="width: 100%;"> | 
|                 <div class="card-details" style="place-content: normal;height: auto;"> | 
|                     <div class="text-body" style="display: flex;flex-wrap: wrap;"> | 
|                         <div style="width: 100%;margin-bottom: 20px;"> | 
|                             <div style="display: flex;justify-content: space-between;"> | 
|                                 <div><input v-model="searchMatnr" placeholder="物料号" type="text" class="search-input"></div> | 
|                                 <div><input v-model="searchOrderNo" placeholder="订单号" type="text" class="search-input"></div> | 
|                             </div> | 
|                             <div style="display: flex;justify-content: space-between;margin-top: 10px;"> | 
|                                 <div><input style="width: 110px;" v-model="searchMaktx" placeholder="物料名称" type="text" class="search-input"></div> | 
|                                 <div><input style="width: 110px;" v-model="searchSpecs" placeholder="规格" type="text" class="search-input"></div> | 
|                                 <div><input style="width: 110px;" v-model="searchLocNo" placeholder="库位号" type="text" class="search-input"></div> | 
|                             </div> | 
|                             <button style="width: 100%;margin-top: 10px;" @click="searchLoc" class="layui-btn layui-btn-sm">搜索</button> | 
|                         </div> | 
| <!--                        <div>--> | 
| <!--                            <button @click="locToLoc2" class="layui-btn layui-btn-sm">侧边移库</button>--> | 
| <!--                        </div>--> | 
|                         <div> | 
|                             <button @click="init" class="layui-btn layui-btn-sm">刷新</button> | 
|                         </div> | 
|                         <div style="margin-left: 10px;"> | 
|                             <button @click="resetSearch" class="layui-btn layui-btn-sm">重置</button> | 
|                         </div> | 
|                         <div v-if="!locOutStatus" style="margin-left: 10px;"> | 
|                             <button @click="locOutStatus = true" class="layui-btn layui-btn-sm">出库选择</button> | 
|                         </div> | 
|                         <div v-else style="margin-left: 10px;border: 1px red solid;display: flex;"> | 
|                             <div> | 
|                                 <button @click="cancelSelectLoc" class="layui-btn layui-btn-sm">取消选择</button> | 
|                             </div> | 
|                             <div style="display: flex;justify-content: center;align-items: center;"> | 
|                                 <select v-model="outSite"> | 
|                                     <option v-for="(item,index) in outSites" :key="index" :value="item.siteId">{{ item.desc }}</option> | 
|                                 </select> | 
|                             </div> | 
|                             <div> | 
|                                 <button @click="locOut" class="layui-btn layui-btn-sm">出库</button> | 
|                             </div> | 
|                         </div> | 
|                     </div> | 
|                 </div> | 
|                 <button class="card-button">功能区</button> | 
|             </div> | 
|   | 
|             <div class="hoverCard"> | 
|                 <div class="card-details"> | 
|                     <div class="text-body" style="display: flex;justify-content: space-around;flex-wrap: wrap;"> | 
|                         <div style="flex: 1;margin-top: 10px;"> | 
|                             <div style="font-size: 10px;">空库位</div><div class="pointBox pointBoxBlue">O</div> | 
|                         </div> | 
|                         <div style="flex: 1;margin-top: 10px;"> | 
|                             <div style="font-size: 10px;">在库</div><div class="pointBox pointBoxRed">F</div> | 
|                         </div> | 
|                         <div style="flex: 1;margin-top: 10px;"> | 
|                             <div style="font-size: 10px;">空板</div><div class="pointBox pointBoxEmpty">D</div> | 
|                         </div> | 
|                         <div style="flex: 1;margin-top: 10px;"> | 
|                             <div style="font-size: 10px;">出库中</div><div class="pointBox pointBoxOut">P</div> | 
|                         </div> | 
|                         <div style="flex: 1;margin-top: 10px;"> | 
|                             <div style="font-size: 10px;">出库预约</div><div class="pointBox pointBoxOutYy">R</div> | 
|                         </div> | 
|                         <div style="flex: 1;margin-top: 10px;"> | 
|                             <div style="font-size: 10px;">入库预约</div><div class="pointBox pointBoxInYy">S</div> | 
|                         </div> | 
|                         <div style="flex: 1;margin-top: 10px;"> | 
|                             <div style="font-size: 10px;">搜索结果</div><div class="pointBox pointBoxSearch"></div> | 
|                         </div> | 
|                         <div style="flex: 1;margin-top: 10px;"> | 
|                             <div style="font-size: 10px;">选择结果</div><div class="pointBox pointBoxSelected"></div> | 
|                         </div> | 
|                         <div style="flex: 1;margin-top: 10px;"> | 
|                             <div style="font-size: 10px;">其他</div><div class="pointBox pointBoxDefault">其他</div> | 
|                         </div> | 
|                     </div> | 
|                 </div> | 
|                 <button class="card-button">库位状态</button> | 
|             </div> | 
|   | 
| <!--            <div class="hoverCard">--> | 
| <!--                <div class="card-details">--> | 
| <!--                    <p class="text-title" style="text-align: center;">楼层 {{currentLev}}F</p>--> | 
| <!--                    <div class="text-body" style="display: flex;">--> | 
| <!--                        <div class="floorSelect">--> | 
| <!--                            <label for="01">1F</label>--> | 
| <!--                            <input id="01" type="radio" name="r" v-model="currentLev" value="1" checked="">--> | 
| <!--                            <label for="02">2F</label>--> | 
| <!--                            <input id="02" type="radio" v-model="currentLev" name="r" value="2">--> | 
| <!--                            <label for="03">3F</label>--> | 
| <!--                            <input id="03" type="radio" v-model="currentLev" name="r" value="3">--> | 
| <!--                            <label for="04">4F</label>--> | 
| <!--                            <input id="04" type="radio" v-model="currentLev" name="r" value="4">--> | 
| <!--                        </div>--> | 
| <!--                    </div>--> | 
| <!--                </div>--> | 
| <!--                <button class="card-button">楼层 {{currentLev}}F</button>--> | 
| <!--            </div>--> | 
|   | 
|         </div> | 
|     </div> | 
|   | 
|     <div v-if="rightBox" @click.stop="" :style="{left: rightBoxLeft,top: rightBoxTop}" class="popBox"> | 
|         <div class="apple-card"> | 
|             <div class="tools"> | 
|                 <div class="circle" @click.stop="rightBox = false"> | 
|                     <span class="red box"></span> | 
|                 </div> | 
|                 <div class="circle"> | 
|                     <span class="yellow box"></span> | 
|                 </div> | 
|                 <div class="circle"> | 
|                     <span class="green box"></span> | 
|                 </div> | 
|             </div> | 
|             <div class="card-content"> | 
|                 <div> | 
|                     库位号: {{ map[mapI][mapJ].locNo }} | 
|                 </div> | 
|                 <div style="margin-top: 10px;"> | 
|                     库位状态: {{ getLocSts(map[mapI][mapJ].locSts) }} | 
|                 </div> | 
|                 <div style="margin-top: 10px;display: flex;justify-content: space-between;flex-wrap: wrap;"> | 
|                     <div style="margin-top: 5px;"> | 
|                         <button class="layui-btn layui-btn-sm" @click="openLocDetail(map[mapI][mapJ].locNo)">库位详情</button> | 
|                     </div> | 
| <!--                    <div style="margin-top: 5px;">--> | 
| <!--                        <button v-if="map[mapI][mapJ].locSts == 'F'" class="layui-btn layui-btn-sm" @click="locMove(map[mapI][mapJ].locNo)">库位移转</button>--> | 
| <!--                        <button v-else-if="map[mapI][mapJ].locSts == 'D'" class="layui-btn layui-btn-sm" @click="locMove(map[mapI][mapJ].locNo)">库位移转</button>--> | 
| <!--                        <button v-else class="layui-btn layui-btn-sm layui-btn-disabled" disabled>库位移转</button>--> | 
| <!--                    </div>--> | 
|                 </div> | 
|             </div> | 
|         </div> | 
|     </div> | 
|   | 
|     <div v-if="crnBox" @click.stop="" :style="{left: crnBoxLeft,top: crnBoxTop}" class="popBox"> | 
|         <div class="apple-card"> | 
|             <div class="tools"> | 
|                 <div class="circle" @click.stop="crnBox = false"> | 
|                     <span class="red box"></span> | 
|                 </div> | 
|                 <div class="circle"> | 
|                     <span class="yellow box"></span> | 
|                 </div> | 
|                 <div class="circle"> | 
|                     <span class="green box"></span> | 
|                 </div> | 
|             </div> | 
|             <div class="card-content"> | 
|                 <div>堆垛机号:{{crnList[crnBox - 1].crnNo}}</div> | 
|                 <div>工作号:{{crnList[crnBox - 1].wrkNo}}</div> | 
|                 <div>源库位:{{crnList[crnBox - 1].frmLocno}}</div> | 
|                 <div>目标库位:{{crnList[crnBox - 1].toLocno}}</div> | 
|                 <div>可入:{{crnList[crnBox - 1].inEnable}}</div> | 
|                 <div>可出:{{crnList[crnBox - 1].outEnable}}</div> | 
|                 <div>状态:{{crnList[crnBox - 1].crnSts$}}</div> | 
|                 <div>异常:{{crnList[crnBox - 1].crnErr$}}</div> | 
|             </div> | 
|         </div> | 
|     </div> | 
|   | 
| </div> | 
| <script> | 
|   | 
|     var $layui = layui.config({ | 
|         base: baseUrl + "/static/layui/lay/modules/" | 
|     }).use(['layer','form'], function () {}) | 
|   | 
|     var app = new Vue({ | 
|         el: '#app', | 
|         data: { | 
|             map: [], | 
|             mapData: "", | 
|             importData: null, | 
|             startPosition: "0500501", | 
|             endPosition: "0802501", | 
|             mapI: 0, | 
|             mapJ: 0, | 
|             rightBox: false, | 
|             rightBoxTop: "0px", | 
|             rightBoxLeft: "0px", | 
|             pointContainerWidth: 0, | 
|             currentLev: 1, | 
|             crnList: null, | 
|             crnBox: false, | 
|             crnBoxTop: "0px", | 
|             crnBoxLeft: "0px", | 
|             locOutStatus: false, | 
|             locOutLocNo: [], | 
|             searchMatnr: "", | 
|             searchOrderNo: "", | 
|             searchSpecs: "", | 
|             searchMaktx: "", | 
|             searchLocNo: "", | 
|             outSite: null, | 
|             outSites: null, | 
|             showScale: 65, //控制地图显示大小比例 | 
|             showScaleMarks: {//比例滑动条显示标记 | 
|                 0: "0%", | 
|                 50: { | 
|                     style: { | 
|                         color: '#1989FA' | 
|                     }, | 
|                     label: "50%" | 
|                 }, | 
|                 100: "100%", | 
|             }, | 
|             locStsList: [],//库位状态列表 | 
|         }, | 
|         created(){ | 
|             this.init() | 
|   | 
|             // this.getOutSite() | 
|         }, | 
|         watch: { | 
|             map: { | 
|                 deep: true, | 
|                 handler(val) { | 
|                     this.printData() | 
|                 } | 
|             }, | 
|             currentLev: { | 
|                 deep: true, | 
|                 handler(val) { | 
|                     this.init() | 
|                     if (this.searchMatnr != "" | 
|                         || this.searchOrderNo != "" | 
|                         || this.searchSpecs != "" | 
|                         || this.searchMaktx != "" | 
|                         || this.searchLocNo != "") { | 
|                         this.searchLoc() | 
|                     } | 
|                 } | 
|             } | 
|         }, | 
|         methods: { | 
|             init(){ | 
|                 let that = this | 
|                 $.ajax({ | 
|                     url: baseUrl + "/map/getData/" + this.currentLev + "/auth", | 
|                     headers: {'token': localStorage.getItem('token')}, | 
|                     method: "get", | 
|                     success: (data) => { | 
|                         that.importDataClick(data) | 
|                     } | 
|                 }) | 
|   | 
|                 this.locOutStatus = false | 
|                 this.locOutLocNo = [] | 
|   | 
|                 this.getLocStsList();//获取库位状态列表 | 
|             }, | 
|             resetSearch(){ | 
|                 this.searchMatnr = "" | 
|                 this.searchOrderNo = "" | 
|                 this.searchSpecs = "" | 
|                 this.searchMaktx = "" | 
|                 this.searchLocNo = "" | 
|                 this.searchLoc() | 
|             }, | 
|             printData() { | 
|                 this.mapData = JSON.stringify(this.map) | 
|             }, | 
|             importDataClick(mapData) { | 
|                 let tmp = JSON.parse(mapData); | 
|                 let data = [] | 
|                 tmp.forEach((item, index) => { | 
|                     let data2 = [] | 
|                     item.forEach((val, idx) => { | 
|                         val.searchStatus = false//搜索标记 | 
|                         data2.push(val) | 
|                     }) | 
|                     this.pointContainerWidth = item.length * (40+1) | 
|                     data.push(data2) | 
|                 }) | 
|                 this.map = data | 
|                 this.printData() | 
|             }, | 
|             getRealRowByX(x) { | 
|                 //获取真实库位行号,通过坐标x | 
|                 let data = this.map | 
|                 let rowData = data[x] | 
|                 for (var i = 1; i < rowData.length; i++) { | 
|                     if (rowData[i].locNo != undefined) { | 
|                         let locNo = rowData[i].locNo; | 
|                         return "#" + parseInt(locNo.substr(0, 2)); | 
|                     } | 
|                 } | 
|   | 
|                 return ""; | 
|             }, | 
|             rightEvent(x, y, e) { | 
|                 this.rightBox = true | 
|                 this.mapI = x | 
|                 this.mapJ = y | 
|                 this.rightBoxTop = e.y + "px" | 
|                 this.rightBoxLeft = e.x + "px" | 
|             }, | 
|             bgClick() { | 
|                 this.rightBox = false | 
|                 this.crnBox = false | 
|             }, | 
|             openLocDetail(locNo) { | 
|                 $layui.layer.open({ | 
|                     type: 2, | 
|                     title: '库位物料', | 
|                     maxmin: true, | 
|                     area: [top.detailWidth, top.detailHeight], | 
|                     shadeClose: true, | 
|                     content: '../report/locDetl.html?locNo=' + locNo, | 
|                     success: function(layero, index){ | 
|                     } | 
|                 }); | 
|             }, | 
|             getLocStsList() { | 
|                 //获取库位状态列表 | 
|                 let that = this | 
|                 $.ajax({ | 
|                     url: baseUrl + "/basLocSts/list/auth", | 
|                     headers: {'token': localStorage.getItem('token')}, | 
|                     method: "get", | 
|                     success: (res) => { | 
|                         that.locStsList = res.data.records | 
|                     } | 
|                 }) | 
|             }, | 
|             getLocSts(locSts) { | 
|                 //获取库位状态 | 
|                 let locStsList = this.locStsList | 
|                 let locDesc = "" | 
|                 locStsList.forEach((item,index) => { | 
|                     if (item.locSts == locSts) { | 
|                         locDesc = item.locDesc | 
|                     } | 
|                 }) | 
|                 return locDesc | 
|             }, | 
|             locMove(locNo) { | 
|                 //库位移转 | 
|                 let that = this | 
|                 $.ajax({ | 
|                     url: baseUrl + "/loc/move/start", | 
|                     headers: {'token': localStorage.getItem('token')}, | 
|                     dataType: 'json', | 
|                     data: { | 
|                         sourceLocNo: locNo | 
|                     }, | 
|                     method: 'POST', | 
|                     success: function (res) { | 
|                         if (res.code === 200) { | 
|                             $layui.layer.msg(res.msg); | 
|                             that.init() | 
|                         } else if (res.code === 403) { | 
|                             top.location.href = baseUrl + "/"; | 
|                         } else { | 
|                             $layui.layer.msg(res.msg); | 
|                         } | 
|                     } | 
|                 }) | 
|             }, | 
|             getCrnData() { | 
|                 //获取堆垛机数据 | 
|                 let that = this | 
|                 $.ajax({ | 
|                     url: baseUrl + "/basCrnp/list/auth", | 
|                     headers: {'token': localStorage.getItem('token')}, | 
|                     dataType: 'json', | 
|                     data: {}, | 
|                     method: 'POST', | 
|                     success: function (res) { | 
|                         if (res.code === 200) { | 
|                             let tmp = []; | 
|                             res.data.records.forEach((item,index) => { | 
|                                 if (item.endLoc != null && item.endLoc != "") { | 
|                                     let locNo = item.endLoc | 
|                                     item.bay = parseInt(locNo.substr(2,3)) | 
|                                     item.lev = parseInt(locNo.substr(5,2)) | 
|                                 }else { | 
|                                     item.bay = 0 | 
|                                     item.lev = 1 | 
|                                 } | 
|                                 //计算移动路径 | 
|                                 item.left = item.bay * 41 - 80; | 
|                                 item.sameLev = item.lev == that.currentLev ? true : false//是否为同一层 | 
|                                 tmp[item.crnNo - 1] = item; | 
|                             }) | 
|   | 
|                             console.log(tmp) | 
|                             that.crnList = tmp; | 
|                         } else if (res.code === 403) { | 
|                             top.location.href = baseUrl + "/"; | 
|                         } else { | 
|                             $layui.layer.msg(res.msg); | 
|                         } | 
|                     } | 
|                 }) | 
|             }, | 
|             clickCrnBox(e,crnNo) { | 
|                 this.crnBox = crnNo | 
|                 this.crnBoxTop = e.y + "px" | 
|                 this.crnBoxLeft = e.x + "px" | 
|             }, | 
|             locToLoc2(){ | 
|                 //侧边入库 | 
|                 let that = this | 
|                 $.ajax({ | 
|                     url: baseUrl + "/loc/locToLoc2/start", | 
|                     headers: {'token': localStorage.getItem('token')}, | 
|                     dataType: 'json', | 
|                     data: {}, | 
|                     method: 'POST', | 
|                     success: function (res) { | 
|                         if (res.code === 200) { | 
|                             $layui.layer.msg(res.msg); | 
|                             that.init() | 
|                         } else if (res.code === 403) { | 
|                             top.location.href = baseUrl + "/"; | 
|                         } else { | 
|                             $layui.layer.msg(res.msg); | 
|                         } | 
|                     } | 
|                 }) | 
|             }, | 
|             locOut() { | 
|                 //出库 | 
|                 let that = this | 
|                 let locOutLocNo = this.locOutLocNo | 
|                 if (locOutLocNo.length == 0) { | 
|                     $layui.layer.msg("请先选择库位"); | 
|                     return; | 
|                 } | 
|   | 
|                 let map = this.map | 
|                 //巷道list | 
|                 let bayList = [] | 
|                 // 将用户选定的库位通过巷道进行分组 | 
|                 locOutLocNo.forEach((item,index) => { | 
|                     let obj = { | 
|                         x: item.x, | 
|                         y: item.y, | 
|                         locNo: map[item.x][item.y].locNo | 
|                     } | 
|   | 
|                     if (bayList[item.y] == undefined) { | 
|                         bayList[item.y] = [obj] | 
|                     }else { | 
|                         bayList[item.y].push(obj) | 
|                     } | 
|                 }) | 
|   | 
|                 //进行排序 | 
|                 bayList.forEach((item,index) => { | 
|                     for (var i = 0; i < item.length; i++) { | 
|                         for (var j = i+1; j < item.length; j++) { | 
|                             if (item[i].x > item[j].x) { | 
|                                 //交换 | 
|                                 let tmp = item[j]; | 
|                                 item[j] = item[i] | 
|                                 item[i] = tmp | 
|                             } | 
|                         } | 
|                     } | 
|                 }) | 
|   | 
|                 // let result = true;//最终结果 | 
|                 // //检测库位是否缺少选择导致不完整 | 
|                 // bayList.forEach((item,index) => { | 
|                 //     //搜索当前巷道有效在库list | 
|                 //     //上半部分,巷道 | 
|                 //     let topList = [] | 
|                 //     for (var i = 8; i >= 3; i--) { | 
|                 //         let obj = { | 
|                 //             x: i, | 
|                 //             y: index, | 
|                 //             status: false, | 
|                 //             locNo: map[i][index].locNo | 
|                 //         } | 
|                 // | 
|                 //         if (map[i][index].locSts == 'F') { | 
|                 //             //在库状态,存入巷道在库list | 
|                 //             topList.push(obj) | 
|                 //         } | 
|                 //     } | 
|                 // | 
|                 //     //下半部分,巷道 | 
|                 //     let bottomList = [] | 
|                 //     for (var i = 9; i < 14; i++) { | 
|                 //         let obj = { | 
|                 //             x: i, | 
|                 //             y: index, | 
|                 //             status: false, | 
|                 //             locNo: map[i][index].locNo | 
|                 //         } | 
|                 // | 
|                 //         if (map[i][index].locSts == 'F') { | 
|                 //             //在库状态,存入巷道在库list | 
|                 //             bottomList.push(obj) | 
|                 //         } | 
|                 //     } | 
|                 // | 
|                 //     // if (topList.length == 0 && bottomList.length == 0) { | 
|                 //     //     result = false; | 
|                 //     // } | 
|                 // | 
|                 //     for (var i = 0; i < item.length; i++) { | 
|                 //         if (item[i].x > 8) { | 
|                 //             //下半部分数据 | 
|                 //             let index = this.searchDataIndex(item[i],bottomList) | 
|                 //             // console.log(item[i],bottomList,index) | 
|                 //             if (index == -1) { | 
|                 //                 continue | 
|                 //             } | 
|                 //             bottomList[index].status = true | 
|                 //         }else { | 
|                 //             //上半部分数据 | 
|                 //             let index = this.searchDataIndex(item[i],topList) | 
|                 //             // console.log(item[i],topList,index) | 
|                 //             if (index == -1) { | 
|                 //                 continue | 
|                 //             } | 
|                 //             topList[index].status = true | 
|                 //         } | 
|                 // | 
|                 //     } | 
|                 // | 
|                 //     let tmp1 = [] | 
|                 //     let tmp2 = [] | 
|                 //     for (var i = item.length - 1; i >= 0; i--) { | 
|                 //         if (item[i].x < 9) { | 
|                 //             tmp1.push(item[i]); | 
|                 //         } | 
|                 //     } | 
|                 //     for (var i = 0; i < item.length; i++) { | 
|                 //         if (item[i].x > 8) { | 
|                 //             tmp2.push(item[i]); | 
|                 //         } | 
|                 //     } | 
|                 // | 
|                 //     if (tmp1.length > 0) { | 
|                 //         //判断上半部分出库是否选择完整 | 
|                 //         let topIndex = this.searchDataIndex(tmp1[0],topList); | 
|                 //         if (topIndex != -1) { | 
|                 //             for (var i = topIndex; i < topList.length; i++) { | 
|                 //                 if (topList[i].status != true) { | 
|                 //                     result = false; | 
|                 //                 } | 
|                 //             } | 
|                 //         } | 
|                 //     } | 
|                 // | 
|                 //     if (tmp2.length > 0) { | 
|                 //         //判断下半部分出库是否选择完整 | 
|                 //         let bottomIndex = this.searchDataIndex(tmp2[0],bottomList) | 
|                 //         if (bottomIndex != -1) { | 
|                 //             for (var i = bottomIndex; i < bottomList.length; i++) { | 
|                 //                 if (bottomList[i].status != true) { | 
|                 //                     result = false; | 
|                 //                 } | 
|                 //             } | 
|                 //             console.log(tmp2[0],bottomList,bottomIndex) | 
|                 //         } | 
|                 //     } | 
|                 // }) | 
|                 // | 
|                 // if (!result) { | 
|                 //     $layui.layer.msg("出库路径选择有误"); | 
|                 //     return; | 
|                 // } | 
|   | 
|                 //准备出库 | 
|                 if (this.outSite == null) { | 
|                     $layui.layer.msg("请选择出库站点"); | 
|                     return; | 
|                 } | 
|   | 
|                 let locNos = [] | 
|                 bayList.forEach((item,index) => { | 
|                     item.forEach((val,idx) => { | 
|                         locNos.push(val.locNo) | 
|                     }) | 
|                 }) | 
|   | 
|                 let locDetls = [] | 
|                 $.ajax({ | 
|                     url: baseUrl+"/locDetl/auth", | 
|                     headers: {'token': localStorage.getItem('token')}, | 
|                     data: {locNos:locNos}, | 
|                     method: 'POST', | 
|                     async: false, | 
|                     success: function (res) { | 
|                         if (res.code === 200) { | 
|                             locDetls = res.data | 
|                         } else if (res.code === 403) { | 
|                             top.location.href = baseUrl + "/"; | 
|                         } else { | 
|                             layer.msg(res.msg) | 
|                         } | 
|                     } | 
|                 }) | 
|   | 
|                 locDetls.forEach((item,index) => { | 
|                     item.count = item.anfme | 
|                 }) | 
|   | 
|                 $.ajax({ | 
|                     url: baseUrl + "/plate/out/start", | 
|                     headers: {'token': localStorage.getItem('token')}, | 
|                     data: JSON.stringify({ | 
|                         outSite: this.outSite, | 
|                         locDetls: locDetls | 
|                     }), | 
|                     contentType:'application/json;charset=UTF-8', | 
|                     method: 'POST', | 
|                     success: function (res) { | 
|                         if (res.code === 200){ | 
|                             $layui.layer.msg(res.msg); | 
|                             that.init() | 
|                         } else if (res.code === 403){ | 
|                             top.location.href = baseUrl+"/"; | 
|                         } else { | 
|                             $layui.layer.msg(res.msg) | 
|                         } | 
|                     } | 
|                 }); | 
|             }, | 
|             searchDataIndex(data,dist) { | 
|                 //搜索起始点 | 
|                 let searchStartPoint = -1; | 
|                 dist.forEach((val,idx) => { | 
|                     if (val.x == data.x && val.y == data.y) { | 
|                         //找到点位 | 
|                         searchStartPoint = idx | 
|                     } | 
|                 }) | 
|                 return searchStartPoint; | 
|             }, | 
|             selectLoc(x, y) { | 
|                 //选择库位 | 
|                 if (this.locOutStatus) { | 
|                     let tmp = this.map | 
|                     let selected = tmp[x][y].locOutSelected ? 0 : 1 | 
|                     tmp[x][y].locOutSelected = selected | 
|   | 
|                     if (selected) { | 
|                         this.locOutLocNo.push({ | 
|                             x: x, | 
|                             y: y | 
|                         }); | 
|                     }else { | 
|                         //剔除掉不选择元素 | 
|                         let locOutLocNo = this.locOutLocNo | 
|                         let tmp = [] | 
|                         locOutLocNo.forEach((item,index) => { | 
|                             if (item.x !== x || item.y !== y) { | 
|                                 tmp.push(item) | 
|                             } | 
|                         }) | 
|                         this.locOutLocNo = tmp | 
|                     } | 
|   | 
|                     this.map = tmp | 
|                     this.$forceUpdate() | 
|                 } | 
|             }, | 
|             cancelSelectLoc() { | 
|                 //取消选择库位 | 
|                 let data = this.locOutLocNo | 
|                 let tmp = this.map | 
|                 data.forEach((item,index) => { | 
|                     tmp[item.x][item.y].locOutSelected = 0; | 
|                 }) | 
|                 this.locOutLocNo = [] | 
|                 this.map = tmp | 
|                 this.locOutStatus = false | 
|             }, | 
|             searchLoc() { | 
|                 //通过物料编号搜索库位号 | 
|                 // if (this.searchValue == "") { | 
|                 //     $layui.layer.msg("请输入物料编号或订单号"); | 
|                 //     return; | 
|                 // } | 
|   | 
|                 let that = this; | 
|                 $.ajax({ | 
|                     url: baseUrl + "/map/searchData/auth", | 
|                     headers: {'token': localStorage.getItem('token')}, | 
|                     dataType: 'json', | 
|                     data: { | 
|                         lev: this.currentLev, | 
|                         locNo: this.searchLocNo, | 
|                         orderNo: this.searchOrderNo, | 
|                         specs: this.searchSpecs, | 
|                         matnr: this.searchMatnr, | 
|                         maktx: this.searchMaktx | 
|                     }, | 
|                     method: 'POST', | 
|                     success: function (res) { | 
|                         if (res.code === 200) { | 
|                             let tmp = that.map | 
|                             let data = res.data | 
|                             tmp.forEach((item,index) => {//清空之前的搜索结果 | 
|                                 item.forEach((val,idx) => { | 
|                                     if (tmp[index][idx].searchStatus != undefined) { | 
|                                         tmp[index][idx].searchStatus = false;//搜索标记 | 
|                                     } | 
|   | 
|                                 }) | 
|                             }) | 
|   | 
|                             tmp.forEach((item,index) => {//清空之前的搜索结果 | 
|                                 item.forEach((val,idx) => { | 
|                                     if (tmp[index][idx].searchStatus != undefined) { | 
|                                         tmp[index][idx].searchStatus = false;//搜索标记 | 
|                                     } | 
|   | 
|                                 }) | 
|                             }) | 
|   | 
|                             data.forEach((item,i) => { | 
|                                 let locNo = item.locNo | 
|                                 tmp.forEach((item,index) => { | 
|                                     item.forEach((val,idx) => { | 
|                                         if (tmp[index][idx].locNo == locNo) { | 
|                                             tmp[index][idx].searchStatus = true//搜索标记 | 
|                                         } | 
|                                     }) | 
|                                 }) | 
|                             }) | 
|                             that.map = tmp | 
|                             $layui.layer.msg("搜索成功"); | 
|                         } else if (res.code === 403) { | 
|                             top.location.href = baseUrl + "/"; | 
|                         } else { | 
|                             $layui.layer.msg(res.msg); | 
|                         } | 
|                     } | 
|                 }) | 
|             }, | 
|             getOutSite() { | 
|                 let that = this | 
|                 $.ajax({ | 
|                     url: baseUrl + "/available/take/site", | 
|                     headers: {'token': localStorage.getItem('token')}, | 
|                     dataType: 'json', | 
|                     data: {}, | 
|                     method: 'POST', | 
|                     success: function (res) { | 
|                         if (res.code === 200) { | 
|                             that.outSites = res.data | 
|                             that.outSite = res.data[0].siteId | 
|                         } else if (res.code === 403) { | 
|                             top.location.href = baseUrl + "/"; | 
|                         } else { | 
|                             $layui.layer.msg(res.msg); | 
|                         } | 
|                     } | 
|                 }) | 
|             }, | 
|         } | 
|     }) | 
|   | 
| </script> | 
| </body> | 
| </html> |