自动化立体仓库 - WMS系统
chen.llin
2026-01-18 0406c675e143bbb08284fd55381261afcc587afc
src/main/webapp/static/js/monthlySettle/monthlySettle.js
@@ -1,7 +1,7 @@
var pageCurr;
layui.config({
    base: baseUrl + "/static/layui/lay/modules/"
}).use(['layer', 'form', 'table', 'util', 'admin', 'laydate', 'laytpl'], function () {
}).use(['layer', 'form', 'table', 'util', 'admin', 'laydate', 'laytpl', 'element'], function () {
    var $ = layui.jquery;
    var layer = layui.layer;
    var form = layui.form;
@@ -10,6 +10,7 @@
    var admin = layui.admin;
    var layDate = layui.laydate;
    var laytpl = layui.laytpl;
    var element = layui.element;
    // 渲染表格
    tableIns = table.render({
@@ -52,6 +53,7 @@
            }
            pageCurr = curr;
            // 延迟调用权限控制,确保表格操作列的按钮已经渲染完成
            // 改为异步请求,避免阻塞页面渲染
            setTimeout(function() {
                var param = window.location.href.split("?")[1];
                if (null != param) {
@@ -60,7 +62,7 @@
                        url: baseUrl+"/power/menu/"+resourceId+"/auth",
                        headers: {'token': localStorage.getItem('token')},
                        method: 'GET',
                        async: false,
                        async: true, // 改为异步,不阻塞页面渲染
                        success: function (res) {
                            if (res.code === 200){
                                for(var i = 0, len = res.data.length; i < len; i++) {
@@ -412,7 +414,8 @@
                layer.closeAll('loading');
                if (res.code === 200) {
                    var settle = res.data.settle;
                    var details = res.data.details;
                    var details = res.data.details || [];
                    var detailFlows = res.data.detailFlows || [];
                    
                    // 先渲染模板
                    var template = $('#detailDialog').html();
@@ -424,7 +427,41 @@
                        content: html,
                        area: ['90%', '80%'],
                        success: function (layero, dIndex) {
                            // 渲染明细表格(对账单格式)
                            // 初始化tab组件,使其可以切换
                            element.render('tab', 'monthlySettleDetailTab');
                            // 渲染明细流水表格(第一页)
                            table.render({
                                elem: '#detailFlowTable',
                                data: detailFlows,
                                page: true,
                                cellMinWidth: 100,
                                width: '100%',
                                cols: [[
                                    {type: 'numbers', title: '序号', width: 60, align: 'center'},
                                    {field: 'orderNo', title: '订单编号', width: 150},
                                    {field: 'orderTime', title: '业务时间', width: 180},
                                    {field: 'pakinPakoutStatusName', title: '类型', width: 80, align: 'center'},
                                    {field: 'matnr', title: '物料编码', width: 150},
                                    {field: 'maktx', title: '物料名称', width: 200},
                                    {field: 'batch', title: '批次', width: 120},
                                    {field: 'brand', title: '品牌', width: 120},
                                    {field: 'specs', title: '规格', width: 120},
                                    {
                                        field: 'qty',
                                        align: 'right',
                                        title: '数量',
                                        width: 120,
                                        templet: function (d) {
                                            var qty = parseFloat(d.qty || 0);
                                            return qty.toFixed(2);
                                        }
                                    },
                                    {field: 'unit', title: '单位', width: 80}
                                ]]
                            });
                            // 渲染汇总表格(第二页)
                            table.render({
                                elem: '#detailTable',
                                data: details,
@@ -506,6 +543,46 @@
        });
    }
    // 动态加载 xlsx.js 库
    function loadXLSXLibrary(callback) {
        // 如果已经加载,直接执行回调
        if (typeof XLSX !== 'undefined') {
            callback();
            return;
        }
        // 检查是否正在加载
        if (window._xlsxLoading) {
            // 如果正在加载,等待加载完成
            var checkInterval = setInterval(function() {
                if (typeof XLSX !== 'undefined') {
                    clearInterval(checkInterval);
                    callback();
                }
            }, 100);
            return;
        }
        // 开始加载
        window._xlsxLoading = true;
        layer.load(2, {content: '正在加载导出库...'});
        var script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = 'https://cdn.sheetjs.com/xlsx-0.20.1/package/dist/xlsx.full.min.js';
        script.onload = function() {
            window._xlsxLoading = false;
            layer.closeAll('loading');
            callback();
        };
        script.onerror = function() {
            window._xlsxLoading = false;
            layer.closeAll('loading');
            layer.msg('加载导出库失败,请检查网络连接', {icon: 2});
        };
        document.head.appendChild(script);
    }
    // 导出月结明细
    function exportDetail(data) {
        layer.confirm('确定导出月结明细 "' + data.settleNo + '" 吗?', {
@@ -513,39 +590,57 @@
            skin: 'layui-layer-admin'
        }, function (i) {
            layer.close(i);
            layer.load(2);
            $.ajax({
                url: baseUrl + '/monthlySettle/detail/export/' + data.id + '/auth',
                headers: {'token': localStorage.getItem('token')},
                method: 'POST',
                success: function (res) {
                    layer.closeAll('loading');
                    if (res.code === 200) {
                        // 定义表头
                        var titles = [
                            '物料编码',
                            '物料名称',
                            '批次',
                            '品牌',
                            '期初库存',
                            '期末库存',
                            '差异数量',
                            '本期入库',
                            '本期出库'
                        ];
                        // 使用 table.exportFile 导出
                        table.exportFile(titles, res.data, 'xls');
                        layer.msg('导出成功', {icon: 1});
                    } else if (res.code === 403) {
                        top.location.href = baseUrl + "/";
                    } else {
                        layer.msg(res.msg || '导出失败', {icon: 2});
            // 先加载 xlsx.js 库,然后再执行导出
            loadXLSXLibrary(function() {
                layer.load(2);
                $.ajax({
                    url: baseUrl + '/monthlySettle/detail/export/' + data.id + '/auth',
                    headers: {'token': localStorage.getItem('token')},
                    method: 'POST',
                    success: function (res) {
                        layer.closeAll('loading');
                        if (res.code === 200) {
                            var exportData = res.data;
                            // 第一页:明细流水
                            var flowTitles = exportData.flowTitles || ['订单编号', '业务时间', '类型', '物料编码', '物料名称', '批次', '品牌', '规格', '数量', '单位'];
                            var flowData = exportData.detailFlows || [];
                            // 第二页:汇总
                            var summaryTitles = exportData.summaryTitles || ['物料编码', '物料名称', '批次', '品牌', '期初库存', '期末库存', '差异数量', '本期入库', '本期出库'];
                            var summaryData = exportData.details || [];
                            try {
                                // 使用 xlsx.js 创建包含两个sheet的Excel文件
                                var wb = XLSX.utils.book_new();
                                // 创建明细流水sheet
                                var flowWS = XLSX.utils.aoa_to_sheet([flowTitles].concat(flowData));
                                XLSX.utils.book_append_sheet(wb, flowWS, "明细流水");
                                // 创建汇总sheet
                                var summaryWS = XLSX.utils.aoa_to_sheet([summaryTitles].concat(summaryData));
                                XLSX.utils.book_append_sheet(wb, summaryWS, "汇总");
                                // 导出Excel文件
                                var fileName = '月结明细_' + data.settleNo + '.xlsx';
                                XLSX.writeFile(wb, fileName);
                                layer.msg('导出成功', {icon: 1, time: 2000});
                            } catch (e) {
                                console.error('导出失败:', e);
                                layer.msg('导出失败:' + (e.message || '未知错误'), {icon: 2});
                            }
                        } else if (res.code === 403) {
                            top.location.href = baseUrl + "/";
                        } else {
                            layer.msg(res.msg || '导出失败', {icon: 2});
                        }
                    },
                    error: function() {
                        layer.closeAll('loading');
                        layer.msg('导出失败', {icon: 2});
                    }
                },
                error: function() {
                    layer.closeAll('loading');
                    layer.msg('导出失败', {icon: 2});
                }
                });
            });
        });
    }
@@ -663,6 +758,7 @@
            }
            pageCurr=curr;
            // 延迟调用权限控制,确保表格操作列的按钮已经渲染完成
            // 改为异步请求,避免阻塞页面渲染
            setTimeout(function() {
                var param = window.location.href.split("?")[1];
                if (null != param) {
@@ -671,7 +767,7 @@
                        url: baseUrl+"/power/menu/"+resourceId+"/auth",
                        headers: {'token': localStorage.getItem('token')},
                        method: 'GET',
                        async: false,
                        async: true, // 改为异步,不阻塞页面渲染
                        success: function (res) {
                            if (res.code === 200){
                                for(var i = 0, len = res.data.length; i < len; i++) {