自动化立体仓库 - WMS系统
zwl
2026-01-15 2b80cfa1ea7b8f177cc53e1ed3299e4db3ecac1d
src/main/webapp/views/order/outLocDetlQuery.html
@@ -75,6 +75,11 @@
        .over-limit #selectedTotal {
            color: #FF5722 !important; /* 红色警告 */
        }
        /* 订单完成状态 */
        .order-completed {
            background: #5FB878 !important;
        }
    </style>
</head>
<body>
@@ -149,6 +154,7 @@
<script type="text/html" id="toolbar">
    <div class="layui-btn-container">
        <button class="layui-btn" id="btn-auto-select" lay-event="autoSelect">自动勾选</button>
        <button class="layui-btn" id="btn-confirm" lay-event="confirm" style="">提取</button>
    </div>
</script>
@@ -177,6 +183,32 @@
                lay-submit style="display: block;float: right;margin-right: 1rem">
            批量修改
        </button>
    </div>
</script>
<!-- 批量选择出库站弹窗模板 -->
<script type="text/html" id="staBatchSelectDialog">
    <div style="padding: 20px;">
        <form class="layui-form" id="batchSelectStaBox">
            <!-- 下拉框将通过Handlebars模板动态渲染 -->
        </form>
        <div style="text-align: center; margin-top: 20px;">
            <button class="layui-btn layui-btn-sm" lay-submit lay-filter="staBatchSelectConfirm">确认</button>
        </div>
    </div>
</script>
<!-- 批量选择出库站下拉框模板 -->
<script type="text/html" id="batchStaSelectTpl">
    <div class="layui-form-item">
        <label class="layui-form-label">出库站</label>
        <div class="layui-input-block">
            <select name="batchSta" lay-filter="batchSta" lay-search>
                {{#each list}}
                <option value="{{this}}">{{this}}</option>
                {{/each}}
            </select>
        </div>
    </div>
</script>
@@ -261,7 +293,7 @@
                url: baseUrl + '/stock/out/list/auth',
                where: {matnr: parent.matnR[0]},
                page: true,
                limits: [16, 30, 50, 100, 200, 500],
                limits: [50, 100, 200, 500],
                limit: 16,
                even: true,
                toolbar: '#toolbar',
@@ -290,6 +322,14 @@
                    // 初始化选中数量
                    selectedTotal = 0;
                    updateSelectedTotal();
                    // 从后端获取数据后,默认自动勾选数据,勾选到和订单数量一致
                    if (res.data.length > 0 && orderTotal > 0) {
                        // 延迟执行,确保表格渲染完成
                        setTimeout(function() {
                            autoSelectItems();
                        }, 100);
                    }
                }
            });
@@ -298,7 +338,7 @@
                var data = obj.data;
                var checked = obj.checked;
                var type = obj.type;
                console.log("data"+data.batch)
                if (type === 'one') {
                    // 单个选择
                    if (checked) {
@@ -333,13 +373,20 @@
            // 监听头工具栏事件
            table.on('toolbar(stockOut)', function (obj) {
                var checkStatus = table.checkStatus(obj.config.id);
                var data = checkStatus.data;
                var data = checkStatus.data; // 这里只获取实际勾选的数据
                switch (obj.event) {
                    case 'autoSelect':
                        // 自动勾选功能
                        autoSelectItems();
                        break;
                    case 'confirm':
                        // 只使用界面上实际勾选的数据,不再额外整合window.autoSelectedData
                        // 检查是否有数据可提取
                        if (data.length === 0) {
                            layer.msg("请选择数据");
                            return;
                        }
                        // 检查选中的数量是否超过订单数量
                        if (selectedTotal > orderTotal) {
                            layer.confirm('选中的数量已超过订单数量,是否继续?', {
@@ -356,6 +403,117 @@
                }
            });
            // 自动勾选函数 - 勾选库存明细,数量累加不超过订单数量
            function autoSelectItems() {
                // 获取当前页所有数据
                var allData = table.cache.stockOut;
                if (!allData || allData.length === 0) {
                    layer.msg("没有可勾选的数据", {icon: 2});
                    return;
                }
                // 如果订单数量为0,不需要勾选
                if (orderTotal <= 0) {
                    layer.msg("订单数量为0,无需勾选", {icon: 2});
                    return;
                }
                // 先取消所有已选中的项
                for (var i = 0; i < allData.length; i++) {
                    allData[i].LAY_CHECKED = false;
                }
                // 重置选中数量
                selectedTotal = 0;
                // 初始化自动选中数据
                window.autoSelectedData = [];
                // 按顺序勾选库存明细,直到累计数量达到订单数量
                var remaining = orderTotal;
                var selectedCount = 0;
                // 使用原始顺序的副本,从第一页第一个开始勾选
                var sortedData = allData.slice();
                // 选择集合(使用唯一键避免索引错乱)
                var selectionKeys = {};
                for (var i = 0; i < sortedData.length; i++) {
                    var item = sortedData[i];
                    var itemAnfme = parseFloat(item.anfme || 0);
                    if (itemAnfme <= 0) continue;
                    var key = (item.locNo || '') + '|' + (item.batch || '') + '|' + (item.matnr || '') + '|' + (item.anfme || 0);
                    if (remaining >= itemAnfme) {
                        selectionKeys[key] = true;
                        remaining -= itemAnfme;
                        selectedCount++;
                        window.autoSelectedData.push(item);
                    } else if (remaining > 0) {
                        selectionKeys[key] = true;
                        remaining = 0;
                        selectedCount++;
                        window.autoSelectedData.push(item);
                        break;
                    } else {
                        break;
                    }
                }
                // 根据选择集合同步原始数据的勾选标记,并重新计算选中数量
                selectedTotal = 0;
                for (var i = 0; i < allData.length; i++) {
                    var k = (allData[i].locNo || '') + '|' + (allData[i].batch || '') + '|' + (allData[i].matnr || '') + '|' + (allData[i].anfme || 0);
                    allData[i].LAY_CHECKED = !!selectionKeys[k];
                    if (allData[i].LAY_CHECKED) {
                        selectedTotal += parseFloat(allData[i].anfme || 0);
                    }
                }
                // 不重新加载表格,直接更新表格的勾选状态
                var checkStatus = table.checkStatus('stockOut');
                // 遍历表格行并设置勾选状态
                $('.layui-table-box tr').each(function(index, tr) {
                    var rowIndex = $(tr).data('index');
                    if (rowIndex !== undefined && allData[rowIndex]) {
                        var checkbox = $(tr).find('input[type="checkbox"]');
                        checkbox.prop('checked', allData[rowIndex].LAY_CHECKED);
                        // 同步layui的勾选状态样式
                        if (allData[rowIndex].LAY_CHECKED) {
                            $(tr).addClass('layui-table-click');
                            checkbox.next().addClass('layui-form-checked');
                        } else {
                            $(tr).removeClass('layui-table-click');
                            checkbox.next().removeClass('layui-form-checked');
                        }
                    }
                });
                // 同步全选框状态
                var headerCheckbox = $('.layui-table-header input[type="checkbox"]');
                var allChecked = allData.length > 0;
                for (var i = 0; i < allData.length; i++) {
                    if (!allData[i].LAY_CHECKED) {
                        allChecked = false;
                        break;
                    }
                }
                headerCheckbox.prop('checked', allChecked);
                if (allChecked) {
                    headerCheckbox.next().addClass('layui-form-checked');
                } else {
                    headerCheckbox.next().removeClass('layui-form-checked');
                }
                // 更新显示选中的数量
                updateSelectedTotal();
                // 如果没有勾选足够的数据,给出提示
                if (selectedTotal < orderTotal && selectedCount > 0) {
                    layer.msg('已选择全部可用库存,但仍未满足订单数量!', {icon: 2, time: 3000});
                } else if (selectedCount === 0) {
                    layer.msg('没有可勾选的数据,请检查库存!', {icon: 2, time: 3000});
                } else {
                    layer.msg('自动勾选完成,已勾选 ' + selectedCount + ' 条记录!', {icon: 1, time: 2000});
                }
            }
            conditionXmSelect = xmSelect.render({
                el: '#condition',
                style: {
@@ -401,11 +559,20 @@
            }
            function pakoutPreview(id, data) {
                // 确保传入的数据有效
                if (!data || data.length === 0) {
                    layer.msg("请选择数据");
                    return;
                }
                // 存储实际勾选的数据到全局变量,用于出库操作
                window.selectedDataForPakout = data;
                console.log("id=" + id)
                let loadIndex = layer.load(2);
                var da = {
                    "id": JSON.stringify(id),
                    "list": data
                    "list": data // 只使用实际勾选的数据
                }
                $.ajax({
                    url: baseUrl + "/out/pakout/preview/auth1",
@@ -430,9 +597,6 @@
                                , moveType: 1 //拖拽模式,0或者1
                                , content: $('#pakoutPreviewBox').html()
                                , success: function (layero, index) {
                                    res.data.forEach((item, index) => {
                                        console.log(`项 ${index + 1}:`, item);
                                    });
                                    stoPreTabIdx = table.render({
                                        elem: '#stoPreTab1',
                                        data: res.data,
@@ -440,8 +604,10 @@
                                        page: false,
                                        limit: Number.MAX_VALUE,
                                        cellMinWidth: 100,
                                        // cols必须使用二维数组格式,这是layui table的标准配置
                                        cols: [[
                                            // {type: 'checkbox', merge: ['orderNo']},
                                            // 将复选框列放在第一列,便于用户操作和tableMerge处理
                                            {field: 'orderNo', title: '单据编号', merge: true, align: 'center'},
                                            {field: 'title', title: '商品', merge: true, align: 'center', width: 350},
                                            {field: 'batch', title: '批号', align: 'center'},
@@ -457,6 +623,7 @@
                                                title: '货位',
                                                align: 'center',
                                                width: 100,
                                                merge: ['locNo'],
                                                templet: '#locNoTpl'
                                            },
                                            {
@@ -466,7 +633,7 @@
                                                merge: ['locNo'],
                                                templet: '#tbBasicTbStaNos'
                                            },
                                            {type: 'checkbox', merge: ['locNo']},
                                            {type: 'checkbox'}
                                        ]],
                                        done: function (res) {
                                            tableMerge.render(this);
@@ -488,7 +655,30 @@
                                    });
                                    // 批量修改出库站
                                    form.on('submit(batchModifySta)', function () {
                                        let stoPreTabData = layui.table.checkStatus('stoPreTab1').data;
                                        // 获取选中的数据,兼容合并行的情况
                                        let checkStatus = table.checkStatus('stoPreTab1');
                                        let stoPreTabData = checkStatus.data;
                                        // 如果checkStatus返回的数据为空,尝试从tableCache中获取
                                        if (stoPreTabData.length === 0) {
                                            // 遍历tableCache,找出所有选中的行及其合并行
                                            let checkedLocNos = [];
                                            // 首先找出所有被选中的行的locNo
                                            tableCache.forEach(function(item) {
                                                if (item.LAY_CHECKED === true) {
                                                    checkedLocNos.push(item.locNo);
                                                }
                                            });
                                            // 去重
                                            checkedLocNos = [...new Set(checkedLocNos)];
                                            // 根据locNo过滤出所有相关的行
                                            stoPreTabData = tableCache.filter(function(item) {
                                                return checkedLocNos.includes(item.locNo);
                                            });
                                        }
                                        if (stoPreTabData.length < 1) {
                                            layer.msg("请至少选择一条以上合并数据", {icon: 7});
                                            return false;
@@ -513,6 +703,11 @@
                                                }
                                            }
                                        }
                                        // 添加调试信息
                                        console.log('staBatchSelectVal:', staBatchSelectVal);
                                        console.log('staBatchSelectVal类型:', Array.isArray(staBatchSelectVal) ? '数组' : '非数组');
                                        console.log('staBatchSelectVal长度:', staBatchSelectVal.length);
                                        if (staBatchSelectVal.length === 0) {
                                            layer.msg("出库站没有交集,无法批量修改", {icon: 2});
                                            return;
@@ -524,21 +719,56 @@
                                            title: '请选择站点',
                                            content: $('#staBatchSelectDialog').html(),
                                            success: function (layero, ddIndex) {
                                                // 渲染下拉框
                                                let template = Handlebars.compile($('#batchStaSelectTpl').html());
                                                $('#batchSelectStaBox').html(template({list: staBatchSelectVal}));
                                                // 直接使用原生方式创建select元素,不依赖Handlebars模板
                                                let selectHtml = '<div class="layui-form-item">';
                                                selectHtml += '<label class="layui-form-label">出库站</label>';
                                                selectHtml += '<div class="layui-input-block">';
                                                selectHtml += '<select name="batchSta" lay-filter="batchSta" lay-search>';
                                                // 手动遍历数组创建option
                                                staBatchSelectVal.forEach(function(staNo) {
                                                    selectHtml += '<option value="' + staNo + '">' + staNo + '</option>';
                                                });
                                                selectHtml += '</select>';
                                                selectHtml += '</div>';
                                                selectHtml += '</div>';
                                                // 直接插入HTML
                                                $(layero).find('#batchSelectStaBox').html(selectHtml);
                                                // 渲染表单
                                                layui.form.render('select');
                                                // 确认
                                                form.on('submit(staBatchSelectConfirm)', function (obj) {
                                                    let loadIdx = layer.load(2);
                                                    let batchSta = Number(obj.field.batchSta);
                                                    // 直接从DOM中获取选中的站点值,确保能正确获取到
                                                    let batchSta = $(layero).find('select[name="batchSta"]').val();
                                                    console.log('批量修改的站点值:', batchSta);
                                                    let arr = [];
                                                    for (let j = 0; j < stoPreTabData.length; j++) {
                                                    // 简化更新逻辑,直接更新所有选中的数据
                                                    stoPreTabData.forEach(function(preItem) {
                                                        for (let i = 0; i < tableCache.length; i++) {
                                                            if (tableCache[i].orderNo === stoPreTabData[j].orderNo
                                                                && tableCache[i].matnr === stoPreTabData[j].matnr
                                                                && tableCache[i].locNo === stoPreTabData[j].locNo) {
                                                            // 只根据locNo进行匹配,因为表格中locNo是合并单元格的关键字段
                                                            if (tableCache[i].locNo === preItem.locNo) {
                                                                tableCache[i]['staNo'] = batchSta;
                                                                arr.push(i);
                                                                console.log('更新了数据索引:', i, '站点值:', batchSta);
                                                            }
                                                        }
                                                    });
                                                    // 如果没有找到匹配项,尝试直接更新选中的数据
                                                    if (arr.length === 0) {
                                                        console.log('未找到匹配项,尝试直接更新');
                                                        // 直接遍历tableCache,更新所有LAY_CHECKED为true的项
                                                        for (let i = 0; i < tableCache.length; i++) {
                                                            if (tableCache[i].LAY_CHECKED === true) {
                                                                tableCache[i]['staNo'] = batchSta;
                                                                arr.push(i);
                                                                console.log('直接更新了选中的数据索引:', i);
                                                            }
                                                        }
                                                    }
@@ -556,7 +786,6 @@
                                                });
                                                // 弹窗不出现滚动条
                                                $(layero).children('.layui-layer-content').css('overflow', 'visible');
                                                layui.form.render('select');
                                            },
                                        })
                                    }
@@ -564,11 +793,15 @@
                                }
                                , yes: function (index, layero) {
                                    //按钮【立即出库】的回调
                                    pakout(tableCache, index);
                                    // 不再传递tableCache,pakout函数将使用window.selectedDataForPakout
                                    window.selectedDataForPakout = tableCache;
                                    pakout(index);
                                }
                                , btn2: function (index, layero) {
                                    //按钮【稍后处理】的回调
                                    layer.close(index)
                                    // 清理全局变量
                                    window.selectedDataForPakout = null;
                                    //return false 开启该代码可禁止点击该按钮关闭
                                }
                            });
@@ -581,7 +814,19 @@
                })
            }
            function pakout(tableCache, layerIndex) {
            function pakout(layerIndex) {
                // 获取存储的实际勾选数据
                var tableCache = window.selectedDataForPakout;
                // 确保传入的数据有效
                if (!tableCache || tableCache.length === 0) {
                    layer.msg("没有有效的数据可处理", {icon: 2});
                    return;
                }
                // 重置自动选中的数据,避免数据残留
                window.autoSelectedData = [];
                // let loadIndex = layer.load(2);
                notice.msg('正在生成出库任务......', {icon: 4});
                $.ajax({
@@ -632,11 +877,20 @@
                        } else {
                            layer.msg(res.msg, {icon: 2})
                        }
                    },
                    error: function () {
                        notice.destroy();
                        layer.msg('网络错误,请稍后重试', {icon: 2});
                    }
                });
                // 清理全局变量
                window.selectedDataForPakout = null;
            }
            window.pakoutPreview = pakoutPreview;
            // 初始化自动选中数据变量,确保页面加载时被正确初始化
            window.autoSelectedData = null;
        })
</script>
</html>
</html>