自动化立体仓库 - WMS系统
cl
2026-03-23 9245059bbd1202e8e59486e5f124d7819760818a
热力图
1个文件已添加
6个文件已修改
404 ■■■■■ 已修改文件
src/main/java/com/zy/asrs/entity/ViewLocMapDto.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/ReportQueryMapper.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ReportQueryMapper.xml 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/pakStore/emptyOut.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/pakStore/stockOut.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/report/locMap.js 202 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/report/viewLocMap.html 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/ViewLocMapDto.java
@@ -11,6 +11,11 @@
    private Integer bay1;
    // 库位状态
    private String locSts;
    // 库存明细商品名称(多品逗号拼接)
    private String maktx;
    // private String barcodes;
    private String itemBarcodes;
    private String pltBarcodes;
    // 背景色
    private String bgc = "#fff";
    // 字体颜色
@@ -45,6 +50,30 @@
        return locSts;
    }
    public String getMaktx() {
        return maktx;
    }
    public void setMaktx(String maktx) {
        this.maktx = maktx;
    }
    public String getItemBarcodes() {
        return itemBarcodes;
    }
    public void setItemBarcodes(String itemBarcodes) {
        this.itemBarcodes = itemBarcodes;
    }
    public String getPltBarcodes() {
        return pltBarcodes;
    }
    public void setPltBarcodes(String pltBarcodes) {
        this.pltBarcodes = pltBarcodes;
    }
    public void setLocSts(String locSts) {
        this.locSts = locSts;
        switch (locSts){
src/main/java/com/zy/asrs/mapper/ReportQueryMapper.java
@@ -70,8 +70,8 @@
    @Select("select distinct lev1 from asr_loc_mast where row1=#{row1} order by lev1 desc")
    public List<String> getViewLocLevCount(@Param("row1") int row1);
    //
    @Select("select loc_no as locNo, bay1,loc_sts as locSts from asr_loc_mast where row1=#{row1} and lev1=#{lev1} order by bay1")
    public List<ViewLocMapDto> getViewLocBays(@Param("row1") int row1, @Param("lev1") int lev1);
    // @Select("select loc_no as locNo, bay1,loc_sts as locSts from asr_loc_mast where row1=#{row1} and lev1=#{lev1} order by bay1")
    List<ViewLocMapDto> getViewLocBays(@Param("row1") int row1, @Param("lev1") int lev1);
    // 库位Map
    @Select("select distinct bay1 from asr_loc_mast where row1=#{row1} order by bay1")
src/main/resources/mapper/ReportQueryMapper.xml
New file
@@ -0,0 +1,55 @@
<?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.ReportQueryMapper">
    <!-- 库位图:商品名称、条码(D 态条码取 asr_loc_mast.barcode;否则 detl) -->
    <select id="getViewLocBays" resultType="com.zy.asrs.entity.ViewLocMapDto">
        SELECT m.loc_no  AS locNo,
               m.bay1    AS bay1,
               m.loc_sts AS locSts,
               STUFF((
                   SELECT ',' + t.maktx
                   FROM (
                            SELECT DISTINCT LTRIM(RTRIM(ISNULL(d.maktx, ''))) AS maktx
                            FROM asr_loc_detl d
                            WHERE d.loc_no = m.loc_no
                              AND LTRIM(RTRIM(ISNULL(d.maktx, ''))) &lt;&gt; ''
                        ) t
                   FOR XML PATH(''), TYPE
               ).value('.', 'nvarchar(max)'), 1, 1, '') AS maktx,
               CASE WHEN m.loc_sts = 'D'
                    THEN NULLIF(LTRIM(RTRIM(ISNULL(m.barcode, ''))), '')
                    ELSE STUFF((
                             SELECT ',' + t.code
                             FROM (
                                      SELECT DISTINCT LTRIM(RTRIM(ISNULL(d.barcode, ''))) AS code
                                      FROM asr_loc_detl d
                                      WHERE d.loc_no = m.loc_no
                                        AND LTRIM(RTRIM(ISNULL(d.barcode, ''))) &lt;&gt; ''
                                        AND NOT (LEN(LTRIM(RTRIM(ISNULL(d.barcode, '')))) = 6
                                             AND LTRIM(RTRIM(d.barcode)) LIKE 'Z__-__')
                                  ) t
                             FOR XML PATH(''), TYPE
                         ).value('.', 'nvarchar(max)'), 1, 1, '')
               END AS itemBarcodes,
               CASE WHEN m.loc_sts = 'D'
                    THEN NULL
                    ELSE STUFF((
                             SELECT ',' + t.code
                             FROM (
                                      SELECT DISTINCT LTRIM(RTRIM(ISNULL(d.zpallet, ''))) AS code
                                      FROM asr_loc_detl d
                                      WHERE d.loc_no = m.loc_no
                                        AND LTRIM(RTRIM(ISNULL(d.zpallet, ''))) &lt;&gt; ''
                                        AND NOT (LEN(LTRIM(RTRIM(ISNULL(d.zpallet, '')))) = 6
                                             AND LTRIM(RTRIM(d.zpallet)) LIKE 'Z__-__')
                                  ) t
                             FOR XML PATH(''), TYPE
                         ).value('.', 'nvarchar(max)'), 1, 1, '')
               END AS pltBarcodes
        FROM asr_loc_mast m
        WHERE m.row1 = #{row1}
          AND m.lev1 = #{lev1}
        ORDER BY m.bay1
    </select>
</mapper>
src/main/webapp/static/js/pakStore/emptyOut.js
@@ -23,6 +23,10 @@
                    var template = Handlebars.compile(tpl);
                    var html = template(res);
                    $('#staNoSelect').append(html);
                    var $sta = $('#staNoSelect');
                    if ($sta.find('option[value="101"]').length) {
                        $sta.val('101');
                    }
                    form.render('select');
                } else if (res.code === 403){
                    top.location.href = baseUrl+"/";
src/main/webapp/static/js/pakStore/stockOut.js
@@ -126,6 +126,10 @@
                    var template = Handlebars.compile(tpl);
                    var html = template(res);
                    $('#staNoSelect').append(html);
                    var $sta = $('#staNoSelect');
                    if ($sta.find('option[value="101"]').length) {
                        $sta.val('101');
                    }
                    form.render('select');
                } else if (res.code === 403){
                    top.location.href = baseUrl+"/";
src/main/webapp/static/js/report/locMap.js
@@ -2,9 +2,93 @@
    var $ = layui.jquery;
    var layer = layui.layer;
    var form = layui.form;
    var locMapRefreshTimer = null;
    var locMapDocVisible = !document.hidden;
    var locMapFrameVisible = true;
    function locMapIframeUsable() {
        try {
            var fe = window.frameElement;
            if (!fe) {
                return true;
            }
            var doc = fe.ownerDocument;
            var win = doc.defaultView || window.parent;
            var el = fe;
            while (el) {
                var st = win.getComputedStyle(el);
                if (st.display === 'none' || st.visibility === 'hidden' || Number(st.opacity) === 0) {
                    return false;
                }
                el = el.parentElement;
            }
            var r = fe.getBoundingClientRect();
            return r.width >= 1 && r.height >= 1;
        } catch (e) {
            return true;
        }
    }
    function locMapHeatmapPageActive() {
        return locMapDocVisible && locMapFrameVisible && locMapIframeUsable();
    }
    function clearLocMapRefresh() {
        if (locMapRefreshTimer) {
            clearInterval(locMapRefreshTimer);
            locMapRefreshTimer = null;
        }
    }
    function updateLocMapRefreshTimer() {
        clearLocMapRefresh();
        var ms = parseInt($('#locMapRefreshSelect').val(), 10) || 0;
        if (ms <= 0 || !locMapHeatmapPageActive()) {
            return;
        }
        locMapRefreshTimer = setInterval(function () {
            if (!locMapHeatmapPageActive()) {
                return;
            }
            var row = $('#rowSelect').val();
            if (row) {
                getLocTable(row);
            }
        }, ms);
    }
    function resumeLocMapAutoRefresh() {
        var ms = parseInt($('#locMapRefreshSelect').val(), 10) || 0;
        var row = $('#rowSelect').val();
        if (ms > 0 && row && locMapHeatmapPageActive()) {
            getLocTable(row, true);
        }
        updateLocMapRefreshTimer();
    }
    getLocMapRows();
    getLocTable(1);
    getLocTable(1, true);
    updateLocMapRefreshTimer();
    if (typeof IntersectionObserver !== 'undefined') {
        var locMapIo = new IntersectionObserver(function (entries) {
            var e = entries[0];
            var next = !!(e && e.isIntersecting && e.intersectionRatio > 0);
            if (next === locMapFrameVisible) {
                return;
            }
            locMapFrameVisible = next;
            if (locMapFrameVisible) {
                resumeLocMapAutoRefresh();
            } else {
                updateLocMapRefreshTimer();
            }
        }, { threshold: [0, 0.01, 1] });
        var locMapHold = document.getElementById('locMapContain');
        if (locMapHold) {
            locMapIo.observe(locMapHold);
        }
    }
    function getLocMapRows() {
        $.ajax({
@@ -28,7 +112,10 @@
        });
    }
    function getLocTable(row){
    function getLocTable(row, force) {
        if (!force && !locMapHeatmapPageActive()) {
            return;
        }
        $.ajax({
            url: baseUrl+"/report/viewLocMapList.action",
            headers: {'token': localStorage.getItem('token')},
@@ -50,35 +137,98 @@
    }
    form.on('select(row)', function (data) {
        getLocTable(data.value);
        getLocTable(data.value, true);
    });
    form.on('select(locMapRefresh)', function () {
        updateLocMapRefreshTimer();
    });
    $(window).on('beforeunload', function () {
        clearLocMapRefresh();
    });
    document.addEventListener('visibilitychange', function () {
        locMapDocVisible = !document.hidden;
        if (locMapDocVisible) {
            resumeLocMapAutoRefresh();
        } else {
            updateLocMapRefreshTimer();
        }
    });
    function copyLocMapText(text) {
        if (!text) {
            return;
        }
        if (navigator.clipboard && navigator.clipboard.writeText) {
            navigator.clipboard.writeText(text).then(function () {
                layer.msg('已复制');
            }, function () {
                copyLocMapTextLegacy(text);
            });
        } else {
            copyLocMapTextLegacy(text);
        }
    }
    function copyLocMapTextLegacy(text) {
        var ta = document.createElement('textarea');
        ta.value = text;
        ta.style.position = 'fixed';
        ta.style.left = '-9999px';
        document.body.appendChild(ta);
        ta.select();
        try {
            document.execCommand('copy');
            layer.msg('已复制');
        } catch (e) {
            layer.msg('复制失败');
        }
        document.body.removeChild(ta);
    }
    $(document).on('click', '#locMapContain .loc-map-locno-badge', function (e) {
        e.stopPropagation();
        e.preventDefault();
        copyLocMapText($(this).attr('data-copy-loc'));
    });
    $(document).on('click', '#locMapContain .loc-map-bar', function (e) {
        e.stopPropagation();
        e.preventDefault();
        copyLocMapText($(this).attr('data-copy-bar'));
    });
    $(document).on('click', '#locMapContain .loc-map-maktx', function (e) {
        e.stopPropagation();
        e.preventDefault();
        var $td = $(this).closest('td.a-loc');
        var no = ($(this).attr('data-loc-no') || $td.attr('title') || '').trim();
        var sts = ($td.attr('data-loc-sts') || '').trim();
        locDetlOpen(no, sts);
    });
});
var locNo = '';
function locDetl(el) {
    var value = $(el).attr('title');
    var html = $(el).html();
    if (value===null
        ||value === undefined
        || value.trim()===''
        || html.trim()==='S'
        || html.trim()==='D'
        || html.trim()==='O'
        || html.trim()==='Z'
    ){
    } else {
        layer.open({
            type: 2,
            title: '库位物料',
            maxmin: true,
            area: [top.detailWidth, top.detailHeight],
            shadeClose: true,
            content: 'locDetl.html',
            success: function(layero, index){
                locNo = value;
            }
        });
function locDetlOpen(value, sts) {
    if (value === null || value === undefined || String(value).trim() === ''
        || sts === 'S' || sts === 'D' || sts === 'O' || sts === 'Z') {
        return;
    }
    layer.open({
        type: 2,
        title: '库位物料',
        maxmin: true,
        area: [top.detailWidth, top.detailHeight],
        shadeClose: true,
        content: 'locDetl.html',
        success: function (layero, index) {
            locNo = value;
        }
    });
}
function locDetl(el) {
    locDetlOpen($(el).attr('title'), ($(el).attr('data-loc-sts') || '').trim());
}
src/main/webapp/views/report/viewLocMap.html
@@ -16,10 +16,97 @@
            height:700px
        }
        .a-loc {
            cursor: pointer;
            font-size: 18px;
            cursor: default;
            font-size: 12px;
            font-weight: bold;
            text-align: left;
            max-width: 220px;
            overflow-wrap: anywhere;
            word-break: break-word;
            white-space: normal;
            vertical-align: middle;
            line-height: 1.25;
        }
        .loc-map-inner {
            display: grid;
            grid-template-columns: auto 1fr;
            align-items: center;
            column-gap: 8px;
        }
        .loc-map-col1 {
            display: grid;
            grid-template-columns: minmax(0, max-content);
            row-gap: 4px;
            justify-items: stretch;
            width: max-content;
            max-width: 100%;
            min-width: 0;
        }
        .loc-map-top-left {
            display: flex;
            align-items: center;
            gap: 4px;
            flex-wrap: nowrap;
            width: max-content;
            max-width: 100%;
        }
        .loc-map-bars {
            min-width: 0;
            width: 100%;
            max-width: 100%;
            box-sizing: border-box;
        }
        .loc-map-maktx-wrap {
            justify-self: center;
            text-align: center;
            min-width: 0;
            max-width: 100%;
        }
        .loc-map-sts {
            flex: 0 0 auto;
            padding: 1px 6px;
            border-radius: 4px;
            border: 1px solid currentColor;
            font-size: 13px;
            font-weight: 800;
            line-height: 1.2;
            opacity: 0.95;
        }
        .loc-map-locno-badge {
            cursor: pointer;
            flex: 0 1 auto;
            padding: 0;
            font-size: 14px;
            font-weight: normal;
            white-space: nowrap;
            max-width: 100%;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        .loc-map-maktx {
            cursor: pointer;
            font-weight: 600;
            display: inline-block;
            text-align: center;
            max-width: 140px;
            word-break: break-word;
            vertical-align: middle;
        }
        .loc-map-bar {
            cursor: pointer;
            margin-top: 4px;
            font-size: 14px;
            font-weight: normal;
            line-height: 1.35;
            word-break: break-all;
            overflow-wrap: anywhere;
            text-align: left;
            opacity: 0.92;
            max-width: 100%;
            box-sizing: border-box;
        }
        .loc-map-bar:first-child {
            margin-top: 0;
        }
        .layui-table, .layui-table-view {
            margin: 0;
@@ -69,6 +156,19 @@
            </select>
        </div>
    </div>
    <div class="layui-inline" style="margin-left: 16px">
        <label class="layui-form-label" style="width:auto;padding:9px 8px;">自动刷新</label>
        <div class="layui-input-inline" style="width:130px">
            <select id="locMapRefreshSelect" name="locMapRefresh" lay-filter="locMapRefresh">
                <option value="0">不刷新</option>
                <option value="5000">5秒</option>
                <option value="10000" selected>10秒</option>
                <option value="20000">20秒</option>
                <option value="30000">30秒</option>
                <option value="60000">1分钟</option>
            </select>
        </div>
    </div>
</div>
<div id="locMapContain">
    <table class="layui-table" id="locMap" lay-filter="locMap"></table>
@@ -89,7 +189,7 @@
        {{#each body}}
        <tr>
            {{#each loc}}
                <td class="a-loc" title="{{locNo}}" onclick="locDetl(this)" style="background-color:{{bgc}};color:{{color}}">{{locSts}}</td>
                <td class="a-loc" title="{{locNo}}" data-loc-sts="{{locSts}}" style="background-color:{{bgc}};color:{{color}}">{{#if locNo}}<div class="loc-map-inner"><div class="loc-map-col1"><div class="loc-map-top-left"><span class="loc-map-sts">{{locSts}}</span><span class="loc-map-locno-badge" data-copy-loc="{{locNo}}">库位:{{locNo}}</span></div><div class="loc-map-bars">{{#if itemBarcodes}}<div class="loc-map-bar" data-copy-bar="{{itemBarcodes}}">条码:{{itemBarcodes}}</div>{{/if}}{{#if pltBarcodes}}<div class="loc-map-bar" data-copy-bar="{{pltBarcodes}}">条码:{{pltBarcodes}}</div>{{/if}}</div></div><div class="loc-map-maktx-wrap">{{#if maktx}}<span class="loc-map-maktx" data-loc-no="{{locNo}}">{{maktx}}</span>{{/if}}</div></div>{{else}}{{locSts}}{{/if}}</td>
            {{/each}}
        </tr>
        {{/each}}