/** * 项目结算模块 */ layui.define(['table', 'form', 'layer'], function(exports){ var $ = layui.$, table = layui.table, form = layui.form, layer = layui.layer; var baseUrl = window.bonuspath || './'; // 设置Layui全局配置,解决乱码问题 layui.config({ lang: 'zh-CN' }); // 添加CSS修复乱码问题 (function fixLayuiCss() { // 基本 CSS 样式 var style = document.createElement('style'); style.type = 'text/css'; var css = '.layui-laypage-skip em{font-style:normal !important;} ' + '.layui-laydate-content td, .layui-laydate-content th{font-family:"Microsoft YaHei", sans-serif !important;} ' + '.layui-laydate-footer span{font-family:"Microsoft YaHei", sans-serif !important;}'; if(style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } document.head.appendChild(style); // 添加直接修复日期选择器显示的函数 window.fixDatepicker = function() { setTimeout(function() { try { // 修复星期标题 $('.layui-laydate-content th').eq(0).text('日'); $('.layui-laydate-content th').eq(1).text('一'); $('.layui-laydate-content th').eq(2).text('二'); $('.layui-laydate-content th').eq(3).text('三'); $('.layui-laydate-content th').eq(4).text('四'); $('.layui-laydate-content th').eq(5).text('五'); $('.layui-laydate-content th').eq(6).text('六'); // 修复按钮提示文字 $('.laydate-prev-m').attr('title', '上个月'); $('.laydate-next-m').attr('title', '下个月'); $('.laydate-prev-y').attr('title', '上一年'); $('.laydate-next-y').attr('title', '下一年'); // 修复底部按钮文字 $('.laydate-btns-now').text('今天'); $('.laydate-btns-clear').text('清空'); $('.laydate-btns-confirm').text('确定'); // 修复年月选择器中的文字 $('.laydate-set-ym span').each(function() { var text = $(this).text(); text = text.replace('骞', '年').replace('鏈', '月'); $(this).text(text); }); console.log('日期选择器文字已修复'); } catch(e) { console.warn('修复日期选择器文字时出错:', e); } }, 50); }; // 在日期选择器打开时自动修复 $(document).on('click', 'input[lay-key]', function() { window.fixDatepicker(); }); console.log('添加CSS样式修复和日期选择器监听'); })(); // 初始化Layui组件,确保使用中文 (function initLayuiLanguage() { try { // 修复可能的编码问题 if(layui.device('ie')) { try { // 解决IE浏览器下的乱码问题 document.charset = 'UTF-8'; } catch(e) { console.warn('无法设置文档编码:', e); } } // 修复分页组件的乱码问题 if(layui.laypage && layui.laypage.config) { try { // 尝试直接修改laypage的默认文本 layui.laypage.config({ lang: { first: '首页', last: '尾页', prev: '上一页', next: '下一页', skip: '跳至', total: '共', item: '条', pagesize: '条/页', jump: '确定' } }); } catch(e) { console.warn('无法设置laypage配置:', e); } } // 不再尝试全局配置laydate,改为在每次创建时设置 console.log('Layui组件语言初始化完成'); } catch(e) { console.error('初始化Layui组件时出错:', e); } })(); // 创建日期选择器配置函数,确保所有日期选择器使用中文 function createDatePicker(elem, options) { // 检查页面编码,若非 UTF-8 则尝试设置 var metaCharset = document.querySelector('meta[charset]'); if(metaCharset && metaCharset.getAttribute('charset').toLowerCase() !== 'utf-8') { try { metaCharset.setAttribute('charset', 'UTF-8'); console.log("页面编码已设置为 UTF-8"); } catch(e) { console.warn("无法设置页面编码:", e); } } var defaultOptions = { elem: elem, lang: 'cn', // 设置中文 format: 'yyyy-MM-dd', // 设置日期格式 theme: 'molv', // 使用墨绿主题,更美观 // 添加事件回调,在每次打开日期选择器时修复文字 ready: function() { if(window.fixDatepicker) { window.fixDatepicker(); } }, change: function() { if(window.fixDatepicker) { window.fixDatepicker(); } } }; // 合并配置 var finalOptions = $.extend({}, defaultOptions, options || {}); try { // 渲染日期选择器 var dateInstance = layui.laydate.render(finalOptions); // 在渲染后尝试修复日期文本编码问题 setTimeout(function() { if(window.fixDatepicker) { window.fixDatepicker(); } }, 100); // 延迟100ms执行,确保元素已渲染 return dateInstance; } catch (e) { console.warn('创建日期选择器失败,尝试简化配置:', e); // 如果失败,尝试使用最基本的配置 return layui.laydate.render({ elem: elem }); } } var projectCost = { // 初始化列表页 init: function() { // 初始化日期选择器 createDatePicker('#startDate'); createDatePicker('#endDate'); // 初始化表格 - 改为手动加载数据 var tableIns = table.render({ elem: '#LAY-project-cost-list', // 不使用url自动请求 cols: [[ {field: 'id', title: 'ID', hide: true, width: 80}, {field: 'projectName', title: '工程名称', minWidth: 400}, {field: 'startTime', title: '开始日期', width: 120}, {field: 'endTime', title: '结束日期', width: 120}, {field: 'totalAmount', title: '总金额(元)', width: 120, templet: function(d) { return d.totalAmount ? d.totalAmount.toFixed(2) : '0.00'; }}, {field: 'createTime', title: '创建时间', minWidth: 160}, {field: 'createUser', title: '创建人', width: 120}, {title: '操作', width: 150, align: 'center', fixed: 'right', toolbar: '#table-project-cost-list'} ]], data: [], // 初始为空数组 page: false, limit: 1000, height: 'full-220', even: true, // 开启隔行背景 size: 'lg', // 大尺寸 autoSort: false, // 关闭自动排序 cellMinWidth: 80, // 最小单元格宽度 text: { none: '暂无数据' }, // 添加语言配置,修复乱码问题 lang: 'zh-CN', i18n: { 'zh-CN': { page: { first: '首页', last: '尾页', prev: '上一页', next: '下一页', skip: '跳至', total: '共', item: '条', pagesize: '条/页', jump: '确定' } } } }); // 手动加载数据函数 function loadTableData(params) { // 显示加载指示器 layer.load(2); // 默认参数 var defaultParams = { page: 1, limit: 1000 }; // 合并参数 params = $.extend({}, defaultParams, params || {}); $.ajax({ url: baseUrl + '/backstage/projectCost/queryCalculationList', type: 'post', dataType: 'json', contentType: 'application/json; charset=utf-8', data: JSON.stringify(params), success: function(res) { // 关闭加载指示器 layer.closeAll('loading'); console.log("原始响应:", res); // 处理可能是字符串的响应 if (typeof res === 'string') { try { res = JSON.parse(res); console.log("解析字符串响应为对象:", res); } catch(e) { console.error("无法解析JSON:", e); // 尝试处理编码问题 try { var decodedString = decodeURIComponent(escape(res)); res = JSON.parse(decodedString); console.log("编码转换后成功解析:", res); } catch(e2) { console.error("编码转换尝试失败:", e2); layer.msg('获取数据失败,请检查网络连接'); return; } } } // 更新表格数据 if (res && res.res === 1 && res.obj) { // 渲染表格 tableIns.reload({ data: res.obj.data || [] // 移除分页配置,因为我们已取消分页功能 }); console.log("表格数据已更新, 总数:", res.obj.count); } else { // 显示错误消息 var errorMsg = (res && res.resMsg) ? res.resMsg : '数据接口请求异常'; // 尝试修复可能的编码问题 try { errorMsg = decodeURIComponent(escape(errorMsg)); } catch(e) { console.error("修复错误消息编码失败:", e); } layer.msg(errorMsg); console.error("请求失败:", res); // 清空表格 tableIns.reload({ data: [] // 移除分页配置,因为我们已取消分页功能 }); } }, error: function(xhr, status, error) { // 关闭加载指示器 layer.closeAll('loading'); // 显示错误信息 layer.msg('网络请求失败'); console.error("请求失败:", status, error); console.log("XHR对象:", xhr); // 清空表格 tableIns.reload({ data: [] // 移除分页配置,因为我们已取消分页功能 }); } }); } // 初始加载数据 loadTableData(); // 监听工具条事件 table.on('tool(LAY-project-cost-list)', function(obj){ var data = obj.data; if(obj.event === 'detail'){ // 打开详情页 layer.open({ type: 2, title: '计算结果详情', content: baseUrl + '/backstage/projectCost/calculation_detail?id=' + data.id, area: ['90%', '90%'], maxmin: true }); } else if(obj.event === 'delete'){ // 删除操作 layer.confirm('确定删除该计算结果吗?', function(index){ $.ajax({ url: baseUrl + '/backstage/projectCost/deleteCalculation', type: 'post', data: {id: data.id}, success: function(res){ if (typeof res === 'string') { try { res = JSON.parse(res); } catch(e) { console.error("无法解析JSON:", e); layer.msg('删除失败,请检查网络连接'); return; } } if(res.res === 1){ layer.msg('删除成功'); // 删除当前行并重新加载数据,确保表格状态正确 loadTableData(); } else { layer.msg('删除失败'); } }, error: function(){ layer.msg('网络错误,删除失败'); } }); layer.close(index); }); } }); // 监听搜索 form.on('submit(LAY-project-cost-search)', function(data){ var field = data.field; // 处理中文编码问题不再需要,因为我们使用JSON提交 console.log("搜索参数:", field); // 使用自定义加载函数 loadTableData({ projectName: field.projectName, startDate: field.startDate, endDate: field.endDate }); return false; }); // 注释掉这个事件绑定,因为在list.jsp中已经有同样的代码 // 添加按钮点击事件 /* $('.layui-btn[data-type="add"]').on('click', function(){ layer.open({ type: 2, title: '新增结算计算', content: baseUrl + '/backstage/projectCost/calculation_form', area: ['90%', '90%'], maxmin: true }); }); */ }, // 加载项目下拉框数据 loadProjects: function() { console.log('开始加载工程列表...'); $.ajax({ url: baseUrl + '/backstage/projectCost/getProjects', type: 'get', dataType: 'json', success: function(res) { //console.log('工程列表API响应:', res); // 检查响应是否存在且不为空 if(!res) { console.error('响应为空'); layer.msg('加载工程列表失败: 响应为空'); return; } try { var projects = []; // 检查不同可能的数据结构 // 注意:AjaxRes使用res=1表示成功,而不是success=true if(res.res === 1 || res.success === true) { console.log('响应成功标志正确 - res:' + res.res); if(Array.isArray(res.data)) { projects = res.data; console.log('从res.data获取数据,数量:', projects.length); } else if(res.obj && Array.isArray(res.obj)) { projects = res.obj; console.log('从res.obj获取数据,数量:', projects.length); } else if(res.obj && res.obj.list && Array.isArray(res.obj.list)) { projects = res.obj.list; console.log('从res.obj.list获取数据,数量:', projects.length); } else { console.warn('响应中未找到有效数组数据'); } } else { // 请求不成功,但尝试从响应中提取数据 if(Array.isArray(res)) { projects = res; console.log('响应本身是数组,数量:', projects.length); } else { console.error('请求不成功且未找到数据:', res.resMsg || res.msg || '未知错误'); layer.msg('加载工程列表失败: ' + (res.resMsg || res.msg || '服务器返回未知错误')); } } if(projects.length === 0) { console.warn('未获取到工程数据或数据为空'); } // 生成HTML,即使没有数据也会创建下拉框 var html = ''; for(var i = 0; i < projects.length; i++) { // 兼容不同返回结构 var id = projects[i].id || projects[i].ID || ''; var name = projects[i].name || projects[i].NAME || projects[i].projectName || ''; console.log('工程数据:', i, id, name); html += ''; } console.log('生成的HTML:', html); // 更新下拉框并重新渲染 $('select[name="projectId"]').html(html); if(typeof form !== 'undefined' && form.render) { form.render('select'); // 重新渲染select console.log('下拉框渲染完成'); } else { console.error('form对象不存在或不包含render方法'); } // 如果没有数据,显示提示 if(projects.length === 0) { layer.msg('未获取到工程数据,请检查系统配置'); } } catch(error) { console.error('处理工程数据时出错:', error); layer.msg('加载工程列表失败: 数据处理错误'); } }, error: function(xhr, status, error) { console.error('请求工程列表失败:', status, error); console.log('XHR对象:', xhr); layer.msg('网络错误,无法加载工程列表'); } }); }, // 生成结算数据 generateSettlement: function(data) { if(!data.projectId) { layer.msg('请选择工程'); return; } if(!data.startTime || !data.endTime) { layer.msg('请选择统计时间范围'); return; } $('#data-loading').show(); $('#data-container').hide(); // 清除旧的表格容器内容,防止多次渲染 if($('#calculationResultSection').length > 0) { $('#calculationResultSection').remove(); } $.ajax({ url: baseUrl + '/backstage/projectCost/calculateSettlement', type: 'post', data: data, success: function(res) { $('#data-loading').hide(); // 打印响应以进行问题排查 console.log("API响应:", res); console.log("响应类型:", typeof res); // 处理可能是字符串的响应 if (typeof res === 'string') { try { res = JSON.parse(res); console.log("已将字符串响应解析为对象:", res); } catch(e) { console.error("响应无法解析为JSON:", e); } } // 检查响应是否成功,兼容不同的返回格式 let isSuccess = false; if (res) { if(res.success === true) { isSuccess = true; console.log("通过res.success判断成功"); } else if(res.res === 1) { isSuccess = true; console.log("通过res.res判断成功"); } else if(res.code === 200 || res.code === 0 || res.code === '0') { isSuccess = true; console.log("通过res.code判断成功"); } else if(res.status === 'success' || res.status === 200 || res.status === 0) { isSuccess = true; console.log("通过res.status判断成功"); } } console.log("判断是否成功: ", isSuccess, "响应结构:", JSON.stringify(res).substring(0, 100) + "..."); if(isSuccess) { // 清空并重建容器结构 $('#data-container').empty().show(); // 获取正确的数据,兼容不同的数据结构 let responseData = {}; if(res.data) { responseData = res.data; console.log("从res.data获取数据"); } else if(res.obj) { responseData = res.obj; console.log("从res.obj获取数据"); } else { // 尝试直接使用响应本身 responseData = res; console.log("直接使用整个响应作为数据"); } console.log("提取的响应数据:", responseData); // 从详情数据中提取领料和退料明细 let leaseData = []; let returnData = []; // 检查返回的数据结构 if(responseData.leaseMaterials) { // 使用原来的数据结构 leaseData = responseData.leaseMaterials || []; returnData = responseData.returnMaterials || []; } else if(responseData.details) { // 使用后端返回的新数据结构 var details = responseData.details || []; console.log("发现details数组,长度:", details.length); // 尝试预览第一条数据 if(details.length > 0) { console.log("第一条数据样例:", details[0]); // 打印所有字段名,便于排查 console.log("数据字段列表:", Object.keys(details[0]).join(", ")); } // 按类型分离明细(假设operateType=1为领料,operateType=2为退料) leaseData = details.filter(function(item) { return item.operateType !== 2 && item.operateType !== '2'; }); returnData = details.filter(function(item) { return item.operateType === 2 || item.operateType === '2'; }); if(leaseData.length === 0 && returnData.length === 0 && details.length > 0) { // 如果没有按类型分离出数据,可能是后端没有设置operateType字段,则尝试直接使用details console.log("未能根据operateType分离数据,显示所有明细作为领料"); leaseData = details; } } else { // 尝试寻找其他可能的数据结构 console.warn("未找到预期的数据结构,尝试深度查找数据"); // 处理res对象中可能的嵌套数据 var foundData = false; // 检查是否有任何直接可用的数组 for(var key in responseData) { if(Array.isArray(responseData[key])) { console.log("发现数组数据在字段:", key, "长度:", responseData[key].length); if(responseData[key].length > 0) { leaseData = responseData[key]; foundData = true; break; } } } // 如果是res.res===1格式的API,特殊处理 if(!foundData && res.res === 1) { console.log("检测到res.res===1格式的API,尝试从res.obj中提取数据"); // 如果responseData已经是res.obj,查找里面的数组 if(res.obj === responseData) { // 已经在上面处理过 } // 尝试直接将整个res.obj作为数据源(如果是数组) else if(Array.isArray(res.obj)) { console.log("res.obj是数组,直接用作数据源"); leaseData = res.obj; foundData = true; } } // 最后尝试使用整个响应作为数据源 if(!foundData) { if(Array.isArray(responseData)) { console.log("responseData本身是数组,直接用作数据源"); leaseData = responseData; } else if(Array.isArray(res)) { console.log("整个res是数组,直接用作数据源"); leaseData = res; } else { console.warn("未找到可用的数组数据"); } } } console.log("处理后的领料数据:", leaseData); console.log("处理后的退料数据:", returnData); // 保存当前的领料和退料数据,以便在明细视图中使用 window.currentLeaseData = leaseData; window.currentReturnData = returnData; // 获取计算结果数据 let calculationResults = responseData.calculationResults || []; let totalAmount = responseData.totalAmount || 0; console.log("计算结果数据:", calculationResults); console.log("总金额:", totalAmount); // 保存到全局变量,供保存方法使用 window.calculationResults = calculationResults; window.totalAmount = totalAmount; // 创建新的容器结构,使用更明确的方式分隔表格 $('#data-container').html( '
| 开始时间 | 结束时间 | 使用天数 | 使用数量 | 金额(元) |
|---|---|---|---|---|
| 没有详细的时段计算数据,显示汇总信息 | ||||
| -- | '; detailHtml += '-- | '; detailHtml += '-- | '; detailHtml += '' + count + ' | '; detailHtml += '' + (amount ? amount.toFixed(2) : '0.00') + ' | '; detailHtml += '
| ' + startTime + ' | '; detailHtml += '' + endTime + ' | '; detailHtml += '' + days + ' | '; detailHtml += '' + count + ' | '; detailHtml += '' + amount.toFixed(2) + ' | '; detailHtml += '
| 合计 | '; detailHtml += '' + totalDays + ' | '; detailHtml += '- | '; detailHtml += '' + totalAmount.toFixed(2) + ' | '; detailHtml += '|
| 操作时间 | 操作类型 | 数量 | 现场剩余数量 |
|---|---|---|---|
| 暂无操作记录数据 | |||
| ' + operateTime + ' | '; detailHtml += '' + operateType + ' | '; detailHtml += '' + quantity + ' | '; detailHtml += '' + currentCount + ' | '; detailHtml += '
| 汇总 | '; detailHtml += '领料: ' + totalLeaseQuantity + ' 退料: ' + totalReturnQuantity + ' | ';
detailHtml += '' + finalCount + ' | '; detailHtml += '|