自动化立体仓库 - WMS系统
Junjie
2023-06-05 dc5d100c0008badd2717f93e2f958c070820d018
实时地图
9个文件已添加
1个文件已修改
1918 ■■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/BasMapController.java 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/MapController.java 136 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/BasMap.java 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/BasMapMapper.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/BasMapService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/BasMapServiceImpl.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/BasMapMapper.xml 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/basMap/basMap.js 260 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/basMap/basMap.html 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/home/map_realtime.html 1122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/BasMapController.java
New file
@@ -0,0 +1,125 @@
package com.zy.asrs.controller;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.core.common.DateUtils;
import com.zy.asrs.entity.BasMap;
import com.zy.asrs.service.BasMapService;
import com.core.annotations.ManagerAuth;
import com.core.common.BaseRes;
import com.core.common.Cools;
import com.core.common.R;
import com.zy.common.web.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.*;
@RestController
public class BasMapController extends BaseController {
    @Autowired
    private BasMapService basMapService;
    @RequestMapping(value = "/basMap/{id}/auth")
    @ManagerAuth
    public R get(@PathVariable("id") String id) {
        return R.ok(basMapService.selectById(String.valueOf(id)));
    }
    @RequestMapping(value = "/basMap/list/auth")
    @ManagerAuth
    public R list(@RequestParam(defaultValue = "1")Integer curr,
                  @RequestParam(defaultValue = "10")Integer limit,
                  @RequestParam(required = false)String orderByField,
                  @RequestParam(required = false)String orderByType,
                  @RequestParam(required = false)String condition,
                  @RequestParam Map<String, Object> param){
        EntityWrapper<BasMap> wrapper = new EntityWrapper<>();
        excludeTrash(param);
        convert(param, wrapper);
        allLike(BasMap.class, param.keySet(), wrapper, condition);
        if (!Cools.isEmpty(orderByField)){wrapper.orderBy(humpToLine(orderByField), "asc".equals(orderByType));}
        return R.ok(basMapService.selectPage(new Page<>(curr, limit), wrapper));
    }
    private <T> void convert(Map<String, Object> map, EntityWrapper<T> wrapper){
        for (Map.Entry<String, Object> entry : map.entrySet()){
            String val = String.valueOf(entry.getValue());
            if (val.contains(RANGE_TIME_LINK)){
                String[] dates = val.split(RANGE_TIME_LINK);
                wrapper.ge(entry.getKey(), DateUtils.convert(dates[0]));
                wrapper.le(entry.getKey(), DateUtils.convert(dates[1]));
            } else {
                wrapper.like(entry.getKey(), val);
            }
        }
    }
    @RequestMapping(value = "/basMap/add/auth")
    @ManagerAuth
    public R add(BasMap basMap) {
        basMapService.insert(basMap);
        return R.ok();
    }
    @RequestMapping(value = "/basMap/update/auth")
    @ManagerAuth
    public R update(BasMap basMap){
        if (Cools.isEmpty(basMap) || null==basMap.getId()){
            return R.error();
        }
        basMapService.updateById(basMap);
        return R.ok();
    }
    @RequestMapping(value = "/basMap/delete/auth")
    @ManagerAuth
    public R delete(@RequestParam(value="ids[]") Long[] ids){
         for (Long id : ids){
            basMapService.deleteById(id);
        }
        return R.ok();
    }
    @RequestMapping(value = "/basMap/export/auth")
    @ManagerAuth
    public R export(@RequestBody JSONObject param){
        EntityWrapper<BasMap> wrapper = new EntityWrapper<>();
        List<String> fields = JSONObject.parseArray(param.getJSONArray("fields").toJSONString(), String.class);
        Map<String, Object> map = excludeTrash(param.getJSONObject("basMap"));
        convert(map, wrapper);
        List<BasMap> list = basMapService.selectList(wrapper);
        return R.ok(exportSupport(list, fields));
    }
    @RequestMapping(value = "/basMapQuery/auth")
    @ManagerAuth
    public R query(String condition) {
        EntityWrapper<BasMap> wrapper = new EntityWrapper<>();
        wrapper.like("id", condition);
        Page<BasMap> page = basMapService.selectPage(new Page<>(0, 10), wrapper);
        List<Map<String, Object>> result = new ArrayList<>();
        for (BasMap basMap : page.getRecords()){
            Map<String, Object> map = new HashMap<>();
            map.put("id", basMap.getId());
            map.put("value", basMap.getId());
            result.add(map);
        }
        return R.ok(result);
    }
    @RequestMapping(value = "/basMap/check/column/auth")
    @ManagerAuth
    public R query(@RequestBody JSONObject param) {
        Wrapper<BasMap> wrapper = new EntityWrapper<BasMap>().eq(humpToLine(String.valueOf(param.get("key"))), param.get("val"));
        if (null != basMapService.selectOne(wrapper)){
            return R.parse(BaseRes.REPEAT).add(getComment(BasMap.class, String.valueOf(param.get("key"))));
        }
        return R.ok();
    }
}
src/main/java/com/zy/asrs/controller/MapController.java
@@ -4,8 +4,10 @@
import com.alibaba.fastjson.JSONObject;
import com.core.annotations.ManagerAuth;
import com.core.common.R;
import com.zy.asrs.entity.BasMap;
import com.zy.asrs.entity.LocDetl;
import com.zy.asrs.entity.LocMast;
import com.zy.asrs.service.BasMapService;
import com.zy.asrs.service.LocDetlService;
import com.zy.asrs.service.LocMastService;
import com.zy.asrs.utils.Utils;
@@ -25,6 +27,8 @@
    private LocMastService locMastService;
    @Autowired
    private LocDetlService locDetlService;
    @Autowired
    private BasMapService basMapService;
    private static final List<String> DISABLE_LOC_NO = new ArrayList<String>() {{
//        add("0200101");
@@ -59,46 +63,46 @@
                //解析json地图数据
                List<ArrayList> arrayLists = JSON.parseArray(stringBuffer.toString(), ArrayList.class);
                ArrayList<HashMap<String, Integer>> lineRows = new ArrayList<>();
                int dataRow = 0;
                int dataRowCount = 0;
                for (int i = 1; i < arrayLists.size(); i++) {
                    boolean flag = true;
                    ArrayList rows = arrayLists.get(i);
                    for (int j = 1; j < rows.size() - 1; j++) {
                        Object o = rows.get(j);
                        JSONObject jsonObject = JSON.parseObject(o.toString());
                        int value = Integer.parseInt(jsonObject.get("value").toString());
                        if (value >= 0 && value != 3) {
                            //只有该行中的任一一列有数据,则不需要创建空白行
                            flag = false;
                        }
                    }
                    if (flag) {
                        //空白行需要跳过
                        HashMap<String, Integer> map = new HashMap<>();
                        map.put("start", dataRow);
                        int end = i - 1 - dataRowCount;
                        map.put("end", end);
                        map.put("count", dataRowCount);
                        dataRow = end;
                        dataRowCount++;
                        lineRows.add(map);
                    }
                }
//                ArrayList<HashMap<String, Integer>> lineRows = new ArrayList<>();
//                int dataRow = 0;
//                int dataRowCount = 0;
//                for (int i = 1; i < arrayLists.size(); i++) {
//                    boolean flag = true;
//                    ArrayList rows = arrayLists.get(i);
//                    for (int j = 1; j < rows.size() - 1; j++) {
//                        Object o = rows.get(j);
//                        JSONObject jsonObject = JSON.parseObject(o.toString());
//                        int value = Integer.parseInt(jsonObject.get("value").toString());
//                        if (value >= 0 && value != 3) {
//                            //只有该行中的任一一列有数据,则不需要创建空白行
//                            flag = false;
//                        }
//                    }
//
//                    if (flag) {
//                        //空白行需要跳过
//                        HashMap<String, Integer> map = new HashMap<>();
//                        map.put("start", dataRow);
//                        int end = i - 1 - dataRowCount;
//                        map.put("end", end);
//                        map.put("count", dataRowCount);
//                        dataRow = end;
//                        dataRowCount++;
//                        lineRows.add(map);
//                    }
//                }
                //获取当前楼层库位数据
                List<LocMast> locMasts = locMastService.selectLocByLev(lev);
                for (LocMast locMast : locMasts) {
                    Integer row = locMast.getRow1();
                    Integer bay = locMast.getBay1();
                    for (HashMap<String, Integer> lineRow : lineRows) {
                        if (row > lineRow.get("start") && row <= lineRow.get("end")) {
                            row += lineRow.get("count");
                             break;
                        }
                    }
//                    for (HashMap<String, Integer> lineRow : lineRows) {
//                        if (row > lineRow.get("start") && row <= lineRow.get("end")) {
//                            row += lineRow.get("count");
//                             break;
//                        }
//                    }
                    ArrayList rowData = arrayLists.get(row);
                    Object o = rowData.get(bay);
@@ -152,4 +156,68 @@
        return R.ok().add(lists);
    }
    @GetMapping("/map/realtime/getData/{lev}/auth")
    @ManagerAuth
    public String getRealtimeMapData(@PathVariable("lev") Integer lev) {
        BasMap basMap = basMapService.selectLatestMap(lev);
        //解析json地图数据
        List<ArrayList> arrayLists = JSON.parseArray(basMap.getData(), ArrayList.class);
//        ArrayList<HashMap<String, Integer>> lineRows = new ArrayList<>();
//        int dataRow = 0;
//        int dataRowCount = 0;
//        for (int i = 1; i < arrayLists.size(); i++) {
//            boolean flag = true;
//            ArrayList rows = arrayLists.get(i);
//            for (int j = 1; j < rows.size() - 1; j++) {
//                Object o = rows.get(j);
//                JSONObject jsonObject = JSON.parseObject(o.toString());
//                int value = Integer.parseInt(jsonObject.get("value").toString());
//                if (value >= 0 && value != 3) {
//                    //只有该行中的任一一列有数据,则不需要创建空白行
//                    flag = false;
//                }
//            }
//
//            if (flag) {
//                //空白行需要跳过
//                HashMap<String, Integer> map = new HashMap<>();
//                map.put("start", dataRow);
//                int end = i - 1 - dataRowCount;
//                map.put("end", end);
//                map.put("count", dataRowCount);
//                dataRow = end;
//                dataRowCount++;
//                lineRows.add(map);
//            }
//        }
        //获取当前楼层库位数据
        List<LocMast> locMasts = locMastService.selectLocByLev(lev);
        for (LocMast locMast : locMasts) {
            Integer row = locMast.getRow1();
            Integer bay = locMast.getBay1();
//            for (HashMap<String, Integer> lineRow : lineRows) {
//                if (row > lineRow.get("start") && row <= lineRow.get("end")) {
//                    row += lineRow.get("count");
//                    break;
//                }
//            }
            ArrayList rowData = arrayLists.get(row);
            Object o = rowData.get(bay);
            JSONObject jsonObject = JSON.parseObject(o.toString());
            if (DISABLE_LOC_NO.contains(locMast.getLocNo())) {
                //禁止库位
                jsonObject.put("value", 10);//将禁用库位进行设置
            }
            jsonObject.put("locNo", locMast.getLocNo());//设置库位号
            jsonObject.put("locSts", locMast.getLocSts());//库位状态
            //更新list
            rowData.set(bay, jsonObject);
            arrayLists.set(row, rowData);
        }
        return JSONObject.toJSONString(arrayLists);
    }
}
src/main/java/com/zy/asrs/entity/BasMap.java
New file
@@ -0,0 +1,95 @@
package com.zy.asrs.entity;
import com.core.common.Cools;import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.enums.IdType;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.baomidou.mybatisplus.annotations.TableField;
import org.springframework.format.annotation.DateTimeFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import com.baomidou.mybatisplus.annotations.TableName;
import java.io.Serializable;
@Data
@TableName("asr_bas_map")
public class BasMap implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value= "")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 地图数据
     */
    @ApiModelProperty(value= "地图数据")
    private String data;
    /**
     * 创建时间
     */
    @ApiModelProperty(value= "创建时间")
    @TableField("create_time")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    /**
     * 更新时间
     */
    @ApiModelProperty(value= "更新时间")
    @TableField("update_time")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    /**
     * 更新前地图数据
     */
    @ApiModelProperty(value= "更新前地图数据")
    @TableField("last_data")
    private String lastData;
    /**
     * 楼层
     */
    @ApiModelProperty(value= "楼层")
    private Integer lev;
    public BasMap() {}
    public BasMap(String data,Date createTime,Date updateTime,String lastData,Integer lev) {
        this.data = data;
        this.createTime = createTime;
        this.updateTime = updateTime;
        this.lastData = lastData;
        this.lev = lev;
    }
//    BasMap basMap = new BasMap(
//            null,    // 地图数据
//            null,    // 创建时间
//            null,    // 更新时间
//            null,    // 更新前地图数据
//            null    // 楼层
//    );
    public String getCreateTime$(){
        if (Cools.isEmpty(this.createTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime);
    }
    public String getUpdateTime$(){
        if (Cools.isEmpty(this.updateTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime);
    }
}
src/main/java/com/zy/asrs/mapper/BasMapMapper.java
New file
@@ -0,0 +1,14 @@
package com.zy.asrs.mapper;
import com.zy.asrs.entity.BasMap;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface BasMapMapper extends BaseMapper<BasMap> {
    BasMap selectLatestMap(Integer lev);//获取最新地图数据
}
src/main/java/com/zy/asrs/service/BasMapService.java
New file
@@ -0,0 +1,10 @@
package com.zy.asrs.service;
import com.zy.asrs.entity.BasMap;
import com.baomidou.mybatisplus.service.IService;
public interface BasMapService extends IService<BasMap> {
    BasMap selectLatestMap(Integer lev);//获取最新地图数据
}
src/main/java/com/zy/asrs/service/impl/BasMapServiceImpl.java
New file
@@ -0,0 +1,17 @@
package com.zy.asrs.service.impl;
import com.zy.asrs.mapper.BasMapMapper;
import com.zy.asrs.entity.BasMap;
import com.zy.asrs.service.BasMapService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service("basMapService")
public class BasMapServiceImpl extends ServiceImpl<BasMapMapper, BasMap> implements BasMapService {
    @Override
    public BasMap selectLatestMap(Integer lev) {
        return this.baseMapper.selectLatestMap(lev);
    }
}
src/main/resources/mapper/BasMapMapper.xml
New file
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zy.asrs.mapper.BasMapMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.zy.asrs.entity.BasMap">
        <id column="id" property="id" />
        <result column="data" property="data" />
        <result column="create_time" property="createTime" />
        <result column="update_time" property="updateTime" />
        <result column="last_data" property="lastData" />
        <result column="lev" property="lev" />
    </resultMap>
    <select id="selectLatestMap" resultMap="BaseResultMap">
        select top 1 *
        from asr_bas_map
        where lev = #{lev}
        order by id desc
    </select>
</mapper>
src/main/webapp/static/js/basMap/basMap.js
New file
@@ -0,0 +1,260 @@
var pageCurr;
layui.config({
    base: baseUrl + "/static/layui/lay/modules/"
}).use(['table','laydate', 'form', 'admin'], function(){
    var table = layui.table;
    var $ = layui.jquery;
    var layer = layui.layer;
    var layDate = layui.laydate;
    var form = layui.form;
    var admin = layui.admin;
    // 数据渲染
    tableIns = table.render({
        elem: '#basMap',
        headers: {token: localStorage.getItem('token')},
        url: baseUrl+'/basMap/list/auth',
        page: true,
        limit: 15,
        limits: [15, 30, 50, 100, 200, 500],
        toolbar: '#toolbar',
        cellMinWidth: 50,
        height: 'full-120',
        cols: [[
            {type: 'checkbox'}
            ,{field: 'id', align: 'center',title: ''}
            ,{field: 'data', align: 'center',title: '地图数据'}
            ,{field: 'createTime$', align: 'center',title: '创建时间'}
            ,{field: 'updateTime$', align: 'center',title: '更新时间'}
            ,{field: 'lastData', align: 'center',title: '更新前地图数据'}
            ,{field: 'lev', align: 'center',title: '楼层'}
            ,{fixed: 'right', title:'操作', align: 'center', toolbar: '#operate', width:120}
        ]],
        request: {
            pageName: 'curr',
            pageSize: 'limit'
        },
        parseData: function (res) {
            return {
                'code': res.code,
                'msg': res.msg,
                'count': res.data.total,
                'data': res.data.records
            }
        },
        response: {
            statusCode: 200
        },
        done: function(res, curr, count) {
            if (res.code === 403) {
                top.location.href = baseUrl+"/";
            }
            pageCurr=curr;
            limit();
        }
    });
    // 监听排序事件
    table.on('sort(basMap)', function (obj) {
        var searchData = {};
        $.each($('#search-box [name]').serializeArray(), function() {
            searchData[this.name] = this.value;
        });
        searchData['orderByField'] = obj.field;
        searchData['orderByType'] = obj.type;
        tableIns.reload({
            where: searchData,
            page: {curr: 1}
        });
    });
    // 监听头工具栏事件
    table.on('toolbar(basMap)', function (obj) {
        var checkStatus = table.checkStatus(obj.config.id).data;
        switch(obj.event) {
            case 'addData':
                showEditModel();
                break;
            case 'deleteData':
               if (checkStatus.length === 0) {
                   layer.msg('请选择要删除的数据', {icon: 2});
                   return;
               }
               del(checkStatus.map(function (d) {
                   return d.id;
               }));
               break;
            case 'exportData':
                admin.confirm('确定导出Excel吗', {shadeClose: true}, function(){
                    var titles=[];
                    var fields=[];
                    obj.config.cols[0].map(function (col) {
                        if (col.type === 'normal' && col.hide === false && col.toolbar == null) {
                            titles.push(col.title);
                            fields.push(col.field);
                        }
                    });
                    var exportData = {};
                    $.each($('#search-box [name]').serializeArray(), function() {
                        exportData[this.name] = this.value;
                    });
                    var param = {
                        'basMap': exportData,
                        'fields': fields
                    };
                    $.ajax({
                        url: baseUrl+"/basMap/export/auth",
                        headers: {'token': localStorage.getItem('token')},
                        data: JSON.stringify(param),
                        dataType:'json',
                        contentType:'application/json;charset=UTF-8',
                        method: 'POST',
                        success: function (res) {
                            layer.closeAll();
                            if (res.code === 200) {
                                table.exportFile(titles,res.data,'xls');
                            } else if (res.code === 403) {
                                top.location.href = baseUrl+"/";
                            } else {
                                layer.msg(res.msg, {icon: 2})
                            }
                        }
                    });
                });
                break;
        }
    });
    // 监听行工具事件
    table.on('tool(basMap)', function(obj){
        var data = obj.data;
        switch (obj.event) {
            case 'edit':
                showEditModel(data);
                break;
            case "del":
                del([data.id]);
                break;
        }
    });
    /* 弹窗 - 新增、修改 */
    function showEditModel(mData) {
        admin.open({
            type: 1,
            area: '600px',
            title: (mData ? '修改' : '添加') + '订单状态',
            content: $('#editDialog').html(),
            success: function (layero, dIndex) {
                layDateRender(mData);
                form.val('detail', mData);
                form.on('submit(editSubmit)', function (data) {
                    var loadIndex = layer.load(2);
                    $.ajax({
                        url: baseUrl+"/basMap/"+(mData?'update':'add')+"/auth",
                        headers: {'token': localStorage.getItem('token')},
                        data: data.field,
                        method: 'POST',
                        success: function (res) {
                            layer.close(loadIndex);
                            if (res.code === 200){
                                layer.close(dIndex);
                                layer.msg(res.msg, {icon: 1});
                                tableReload();
                            } else if (res.code === 403){
                                top.location.href = baseUrl+"/";
                            }else {
                                layer.msg(res.msg, {icon: 2});
                            }
                        }
                    })
                    return false;
                });
                $(layero).children('.layui-layer-content').css('overflow', 'visible');
                layui.form.render('select');
            }
        });
    }
    /* 删除 */
    function del(ids) {
        layer.confirm('确定要删除选中数据吗?', {
            skin: 'layui-layer-admin',
            shade: .1
        }, function (i) {
            layer.close(i);
            var loadIndex = layer.load(2);
            $.ajax({
                url: baseUrl+"/basMap/delete/auth",
                headers: {'token': localStorage.getItem('token')},
                data: {ids: ids},
                method: 'POST',
                success: function (res) {
                    layer.close(loadIndex);
                    if (res.code === 200){
                        layer.msg(res.msg, {icon: 1});
                        tableReload();
                    } else if (res.code === 403){
                        top.location.href = baseUrl+"/";
                    } else {
                        layer.msg(res.msg, {icon: 2});
                    }
                }
            })
        });
    }
    // 搜索
    form.on('submit(search)', function (data) {
        pageCurr = 1;
        tableReload(false);
    });
    // 重置
    form.on('submit(reset)', function (data) {
        pageCurr = 1;
        clearFormVal($('#search-box'));
        tableReload(false);
    });
    // 时间选择器
    function layDateRender(data) {
        setTimeout(function () {
            layDate.render({
                elem: '.layui-laydate-range'
                ,type: 'datetime'
                ,range: true
            });
            layDate.render({
                elem: '#createTime\\$',
                type: 'datetime',
                value: data!==undefined?data['createTime\\$']:null
            });
            layDate.render({
                elem: '#updateTime\\$',
                type: 'datetime',
                value: data!==undefined?data['updateTime\\$']:null
            });
        }, 300);
    }
    layDateRender();
});
// 关闭动作
$(document).on('click','#data-detail-close', function () {
    parent.layer.closeAll();
});
function tableReload(child) {
    var searchData = {};
    $.each($('#search-box [name]').serializeArray(), function() {
        searchData[this.name] = this.value;
    });
    tableIns.reload({
        where: searchData,
        page: {curr: pageCurr}
     });
}
src/main/webapp/views/basMap/basMap.html
New file
@@ -0,0 +1,116 @@
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title></title>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <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">
</head>
<body>
<div class="layui-fluid">
    <div class="layui-card">
        <div class="layui-card-body">
            <div class="layui-form toolbar" id="search-box">
                <div class="layui-form-item">
                    <div class="layui-inline">
                        <div class="layui-input-inline">
                            <input class="layui-input" type="text" name="id" placeholder="编号" autocomplete="off">
                        </div>
                    </div>
                     <div class="layui-inline" style="width: 300px">
                        <div class="layui-input-inline">
                            <input class="layui-input layui-laydate-range" name="create_time" type="text" placeholder="起始时间 - 终止时间" autocomplete="off" style="width: 300px">
                        </div>
                    </div>
                    <div class="layui-inline">
                        <div class="layui-input-inline">
                            <input class="layui-input" type="text" name="condition" placeholder="请输入" autocomplete="off">
                        </div>
                    </div>
                    <div class="layui-inline">&emsp;
                        <button class="layui-btn icon-btn" lay-filter="search" lay-submit>
                            <i class="layui-icon">&#xe615;</i>搜索
                        </button>
                        <button class="layui-btn icon-btn" lay-filter="reset" lay-submit>
                            <i class="layui-icon">&#xe666;</i>重置
                        </button>
                    </div>
                </div>
            </div>
            <table class="layui-hide" id="basMap" lay-filter="basMap"></table>
        </div>
    </div>
</div>
<script type="text/html" id="toolbar">
    <div class="layui-btn-container">
        <button class="layui-btn layui-btn-sm" id="btn-add" lay-event="addData">新增</button>
        <button class="layui-btn layui-btn-sm layui-btn-danger" id="btn-delete" lay-event="deleteData">删除</button>
        <button class="layui-btn layui-btn-primary layui-btn-sm" id="btn-export" lay-event="exportData" style="float: right">导出</button>
    </div>
</script>
<script type="text/html" id="operate">
    <a class="layui-btn layui-btn-primary layui-btn-xs btn-edit" lay-event="edit">修改</a>
    <a class="layui-btn layui-btn-danger layui-btn-xs btn-edit" lay-event="del">删除</a>
</script>
<script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="../../static/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script>
<script type="text/javascript" src="../../static/js/cool.js" charset="utf-8"></script>
<script type="text/javascript" src="../../static/js/basMap/basMap.js" charset="utf-8"></script>
</body>
<!-- 表单弹窗 -->
<script type="text/html" id="editDialog">
    <form id="detail" lay-filter="detail" class="layui-form admin-form model-form">
        <input name="id" type="hidden">
        <div class="layui-row">
            <div class="layui-col-md12">
                <div class="layui-form-item">
                    <label class="layui-form-label">地图数据: </label>
                    <div class="layui-input-block">
                        <input class="layui-input" name="data" placeholder="请输入地图数据">
                    </div>
                </div>
                <div class="layui-form-item">
                    <label class="layui-form-label">创建时间: </label>
                    <div class="layui-input-block">
                        <input class="layui-input" name="createTime" id="createTime$" placeholder="请输入创建时间">
                    </div>
                </div>
                <div class="layui-form-item">
                    <label class="layui-form-label">更新时间: </label>
                    <div class="layui-input-block">
                        <input class="layui-input" name="updateTime" id="updateTime$" placeholder="请输入更新时间">
                    </div>
                </div>
                <div class="layui-form-item">
                    <label class="layui-form-label">更新前地图数据: </label>
                    <div class="layui-input-block">
                        <input class="layui-input" name="lastData" placeholder="请输入更新前地图数据">
                    </div>
                </div>
                <div class="layui-form-item">
                    <label class="layui-form-label">楼层: </label>
                    <div class="layui-input-block">
                        <input class="layui-input" name="lev" placeholder="请输入楼层">
                    </div>
                </div>
             </div>
        </div>
        <hr class="layui-bg-gray">
        <div class="layui-form-item text-right">
            <button class="layui-btn" lay-filter="editSubmit" lay-submit="">保存</button>
            <button class="layui-btn layui-btn-primary" type="button" ew-event="closeDialog">取消</button>
        </div>
    </form>
</script>
</html>
src/main/webapp/views/home/map_realtime.html
New file
@@ -0,0 +1,1122 @@
<!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: 12;display: flex;" :style="{scale:showScale/100.0,marginTop:(showScale-100)*0.7 + '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 && map[index][idx].value != -999" 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 pointBoxGreen" @contextmenu.prevent="rightEvent(index,idx,$event)"><></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 v-else-if="map[index][idx].value  == -999" class="pointBox pointBoxEnd"
                             @contextmenu.prevent="rightEvent(index,idx,$event)">{{ map[index][idx].locSts }}</div>
                    </div>
                </div>
                <div style="width: 40px;display: flex;justify-content: center;align-items: center;">
                    {{ getRealRowByX(index) }}
                </div>
            </div>
        </div>
    </div>
    <div style="padding: 40px 20px 10px 10px;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">
                <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 pointBoxEnd"></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>
            </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: 80, //控制地图显示大小比例
            showScaleMarks: {//比例滑动条显示标记
                0: "0%",
                50: {
                    style: {
                        color: '#1989FA'
                    },
                    label: "50%"
                },
                100: "100%",
            },
            locStsList: [],//库位状态列表
        },
        created(){
            this.init()
            this.getOutSite()
            setInterval((that) => {
                that.init()
            },1000,this)
        },
        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/realtime/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>