GZMachinesWeb/WebContent/static/js/projectCost/projectCostEdit.js

1105 lines
111 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

layui.define(['table', 'form', 'layer', 'laytpl', 'laydate'], function(exports){
var $ = layui.$,
table = layui.table,
form = layui.form,
layer = layui.layer,
laytpl = layui.laytpl,
laydate = layui.laydate;
var baseUrl = window.bonuspath || './';
// 全局修改记录存储
window.modifiedRows = {
lease: {}, // 领料修改记录
return: {} // 退料修改记录
};
// 【新增】全局原始数据存储(页面初始化时从服务端获取,作为永久对比基准)
window.originalTableData = {
lease: [], // 领料原始数据
return: [] // 退料原始数据
};
// 【核心新增】全局列配置抽离leaseCols/returnCols解决作用域问题所有方法可访问
window.tableColumnConfig = {
leaseCols: [], // 领料表格列配置
returnCols: [] // 退料表格列配置
};
// 字段标签映射
var fieldLabels = {
'leaseNum': '领料数量',
'returnNum': '退料数量',
'operateTime': '操作时间',
'price': '单价',
'amount': '金额',
'remark': '备注',
'machineTypeName': '物资名称',
'machineModel': '规格型号',
'machineUnit': '单位',
'leaseUnit': '使用单位',
'operatePersonName': '操作人',
'taskCode': '任务编号',
'projectName': '工程名称'
};
// 设置Layui全局配置解决乱码问题
layui.config({
lang: 'zh-CN'
});
var projectCost = {
// 标记字段被修改
markModified: function(type, rowId, field, oldVal, newVal, rowData) {
if (!window.modifiedRows[type][rowId]) {
window.modifiedRows[type][rowId] = {
rowData: $.extend(true, {}, rowData),
fields: {}
};
}
// 记录修改
window.modifiedRows[type][rowId].fields[field] = {
old: oldVal,
val: newVal,
label: fieldLabels[field] || field
};
// 更新rowData
window.modifiedRows[type][rowId].rowData[field] = newVal;
console.log('标记修改:', type, rowId, field, oldVal, '->', newVal);
},
// 检查字段是否被修改
// 检查字段是否被修改
isFieldModified: function(type, rowId, field) {
// 【优化】增加多层空值判断,兼容记录已被删除的情况
return window.modifiedRows[type] && window.modifiedRows[type][rowId]
&& window.modifiedRows[type][rowId].fields
&& window.modifiedRows[type][rowId].fields[field];
},
// 获取所有修改的数据
getAllModifiedData: function() {
var result = {
leaseModified: [],
returnModified: [],
totalCount: 0
};
// 处理领料修改(过滤掉无字段的空记录)
for (var rowId in window.modifiedRows.lease) {
var item = window.modifiedRows.lease[rowId];
var fieldKeys = Object.keys(item.fields || {});
if (fieldKeys.length > 0) { // 仅保留有实际修改字段的记录
result.leaseModified.push({
id: rowId,
machineTypeName: item.rowData.machineTypeName || '',
fields: item.fields
});
result.totalCount += fieldKeys.length;
}
}
// 处理退料修改(过滤掉无字段的空记录)
for (var rowId in window.modifiedRows.return) {
var item = window.modifiedRows.return[rowId];
var fieldKeys = Object.keys(item.fields || {});
if (fieldKeys.length > 0) { // 仅保留有实际修改字段的记录
result.returnModified.push({
id: rowId,
machineTypeName: item.rowData.machineTypeName || '',
fields: item.fields
});
result.totalCount += fieldKeys.length;
}
}
return result;
},
// 显示确认修改弹框
showConfirmModal: function() {
var modifiedData = this.getAllModifiedData();
if (modifiedData.totalCount === 0) {
layer.msg('暂无修改的数据');
return;
}
var content = laytpl($('#confirmModalTpl').html()).render(modifiedData);
layer.open({
type: 1,
title: '确认修改',
content: content,
area: ['700px', '500px'],
btn: ['确认修改', '取消'],
yes: function(index, layero) {
projectCost.submitAllModifications();
layer.close(index);
},
btn2: function(index, layero) {
layer.close(index);
}
});
},
// 提交所有修改到后台
submitAllModifications: function() {
// 【修复未定义变量】添加allModifications声明
var allModifications = [];
if (!window.editPageField || !window.editPageField.projectId) {
layer.msg('请选择工程后再提交修改', {icon: 2});
return;
}
// 收集领料修改
for (var rowId in window.modifiedRows.lease) {
var item = window.modifiedRows.lease[rowId];
if (Object.keys(item.fields).length > 0) {
var modification = {
id:rowId,
newNum:item.rowData.leaseNum,
operateTime:item.rowData.operateTime,
operateType:item.rowData.operateType,
};
// // 恢复原始数据用于对比
// for (var field in item.fields) {
// modification.originalData[field] = item.fields[field].old;
// }
allModifications.push(modification);
}
}
// 收集退料修改
for (var rowId in window.modifiedRows.return) {
var item = window.modifiedRows.return[rowId];
if (Object.keys(item.fields).length > 0) {
var modification = {
id:rowId,
newNum:item.rowData.returnNum,
operateTime:item.rowData.operateTime,
operateType:item.rowData.operateType,
};
// // 恢复原始数据用于对比
// for (var field in item.fields) {
// modification.originalData[field] = item.fields[field].old;
// }
allModifications.push(modification);
}
}
if (allModifications.length === 0) {
layer.msg('没有需要提交的修改');
return;
}
// 显示加载中
var loadIndex = layer.load(2);
// 准备提交数据
var submitData = {
calculationId: window.editPageField.calculationId,
projectId: window.editPageField.projectId,
startTime: window.editPageField.startTime,
endTime: window.editPageField.endTime,
modifications: allModifications
};
console.log('提交的修改数据:', submitData);
// 调用后台接口
$.ajax({
url: baseUrl + '/backstage/projectCost/submitModifications',
type: 'post',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(submitData),
dataType: 'json',
success: function(res) {
layer.close(loadIndex);
if (typeof res === 'string') {
try {
res = JSON.parse(res);
} catch(e) {
console.error("无法解析JSON:", e);
layer.msg('提交失败,请检查网络连接');
return;
}
}
if (res.res === 1 || res.success) {
layer.msg('修改提交成功', {icon: 1, time: 1500}); // 成功提示1.5秒后执行后续操作
// 核心1清空修改记录保留原有逻辑
window.modifiedRows = {
lease: {},
return: {}
};
// 核心2关闭Layui打开的所有弹窗包括编辑页、确认框等所有层级弹窗
// 核心3跳转到list.jsp并强制刷新解决浏览器缓存问题
// 拼接list.jsp的完整路径与你项目的URL规则保持一致
var listUrl = baseUrl+'/backstage/projectCost/list';
// 方式1最稳妥 - 关闭当前标签页刷新父级list.jsp推荐适配Layui弹窗打开的编辑页
if (window.parent) {
window.parent.location.href = listUrl + '?t=' + new Date().getTime(); // 加时间戳防缓存
window.close(); // 关闭当前编辑页标签
} else {
// 方式2直接刷新当前页为list.jsp备用
window.location.href = listUrl + '?t=' + new Date().getTime();
}
} else {
layer.msg(res.resMsg || res.msg || '提交失败', {icon: 2});
}
},
error: function(xhr, status, error) {
layer.close(loadIndex);
console.error('提交失败:', status, error);
layer.msg('网络错误,提交失败', {icon: 2});
}
});
},
// 渲染表格,添加修改标记 - 保证改回原始值后无红色标记
// 渲染表格,添加修改标记 - 保留金额模板+仅核心字段用修改记录值
renderTableWithModifications: function(elem, data, cols, type) {
console.log('渲染表格:', elem, '数据长度:', data.length, '类型:', type);
// 适配二维数组cols双层map遍历行→列
var fixedCols = cols.map(function(colRow) {
return colRow.map(function(col) {
if (col.field) {
var originalTemplet = col.templet; // 保留原始模板
col.templet = function(d) {
var rowId = type === 'lease' ? (d.supId || d.id) : d.id;
var value = '';
// 仅数量、操作时间字段使用修改记录值(核心:避免覆盖金额模板)
var useModifyValue = ['leaseNum', 'returnNum', 'operateTime'].includes(col.field);
// 取值优先级:修改记录(指定字段)→ 行对象本身 → 空值
if (useModifyValue && rowId && projectCost.isFieldModified(type, rowId, col.field)) {
value = window.modifiedRows[type][rowId].fields[col.field].val;
} else if (d[col.field] !== undefined && d[col.field] !== null) {
value = d[col.field];
}
// 强制保留原有模板逻辑(关键:金额格式化、字段映射不丢失)
if (originalTemplet) {
if (typeof originalTemplet === 'function') {
try {
value = originalTemplet(d); // 执行原始模板(如金额计算)
} catch(e) {
console.warn('模板函数执行失败:', e, '字段:', col.field);
}
} else if (typeof originalTemplet === 'string') {
try {
value = laytpl(originalTemplet).render(d);
} catch(e) {
console.warn('模板渲染失败:', e, '字段:', col.field);
}
}
}
// 仅当字段有未删除的修改记录时,添加红色标记
if (rowId && projectCost.isFieldModified(type, rowId, col.field)) {
return '<span class="modified-cell">' + (value || '') + '</span>';
}
return value || '';
};
}
return col;
});
});
// 渲染表格
table.render({
elem: elem,
data: data,
cols: fixedCols,
page: false,
height: 'auto',
limit: 1000,
lang: 'zh-CN',
skin: 'line',
even: true,
text: { none: '暂无数据' },
done: function(res) {
console.log('表格渲染完成:', elem, '数据量:', res.count);
},
error: function(msg) {
console.error('表格渲染错误:', msg);
layer.msg('表格渲染出错,请刷新重试');
}
});
},
// 打开编辑弹窗
openEditModal: function(row, type, tableObj) {
var isLease = type === 'lease';
var rowId = isLease ? (row.supId || row.id) : row.id;
var quantityField = isLease ? 'leaseNum' : 'returnNum';
console.log('打开编辑弹窗:', row, '类型:', type, 'rowId:', rowId);
// 获取原始数据
var originalRow = $.extend(true, {}, row);
layer.open({
type: 1,
title: '修改' + (isLease ? '领料' : '退料') + '信息',
area: ['500px', '350px'],
content: `
<div style="padding: 20px;">
<form class="layui-form" lay-filter="editForm">
<div class="layui-form-item">
<label class="layui-form-label">物资名称</label>
<div class="layui-input-block">
<input type="text" value="${row.machineTypeName || ''}" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">${isLease ? '领料' : '退料'}数量</label>
<div class="layui-input-block">
<input type="number" id="editQuantity" value="${row[quantityField] || 0}" disabled
class="layui-input" lay-verify="required|number|integer" step="1" min="0">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">操作时间</label>
<div class="layui-input-block">
<input type="text" id="editOperateTime" value="${row.operateTime || ''}"
class="layui-input" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<button type="button" class="layui-btn" id="saveEditBtn">保存修改</button>
<button type="button" class="layui-btn layui-btn-primary" id="cancelEdit">取消</button>
</div>
</form>
</div>
`,
success: function(layero, index) {
// 渲染表单
form.render();
// 【新增】自定义整数验证规则(限制数量为非负整数)
form.verify({
integer: function(value, item){
if(!/^\d+$/.test(value)){
return '数量必须为非负整数!';
}
}
});
// 初始化时间选择器
laydate.render({
elem: '#editOperateTime',
type: 'datetime',
format: 'yyyy-MM-dd HH:mm:ss',
lang: 'zh-CN'
});
$('#saveEditBtn').on('click', function () {
var newQuantity = parseInt($('#editQuantity').val()) || 0;
var newTime = $('#editOperateTime').val();
var hasChange = false;
var modifiedFields = [];
// 统一获取唯一标识和字段名(避免重复代码)
var idField = isLease ? 'supId' : 'id';
var quantityField = isLease ? 'leaseNum' : 'returnNum';
// 从原始数据中获取永久基准值(核心:对比服务端初始值)
var originalDataList = isLease ? window.originalTableData.lease : window.originalTableData.return;
var originalSourceRow = originalDataList.find(item => item[idField] == rowId) || row;
var originalQuantity = parseFloat(originalSourceRow[quantityField]) || 0;
var originalOperateTime = originalSourceRow.operateTime || '';
// 1. 处理数量字段(对比原始值,修复改回逻辑)
if (newQuantity !== originalQuantity) {
projectCost.markModified(type, rowId, quantityField, originalQuantity, newQuantity, row);
row[quantityField] = newQuantity;
// 【新增核心】自动计算金额:单价 × 新数量保留2位小数
var unitPrice = parseFloat(row.price || row.unitPrice || 0);
row.amount = (unitPrice * newQuantity).toFixed(2);
hasChange = true;
modifiedFields.push(quantityField);
} else if (projectCost.isFieldModified(type, rowId, quantityField)) {
// 改回原始值:删除该字段修改记录(字段名加引号,避免变量解析)
delete window.modifiedRows[type][rowId].fields[quantityField];
// 同步行对象值为原始值(关键:保证数据源与原始值一致)
row[quantityField] = originalQuantity;
// 【新增】改回原始值时同步恢复原始金额
row.amount = (parseFloat(row.price || row.unitPrice || 0) * originalQuantity).toFixed(2);
hasChange = true; // 标记变更,触发后续数据源更新和表格重渲染
}
// 2. 处理操作时间字段修复operateTime未加引号问题+改回逻辑)
if (newTime !== originalOperateTime) {
projectCost.markModified(type, rowId, 'operateTime', originalOperateTime, newTime, row);
row.operateTime = newTime;
hasChange = true;
modifiedFields.push('operateTime');
} else if (projectCost.isFieldModified(type, rowId, 'operateTime')) {
// 【核心修复】operateTime加引号作为字符串字段名解决未定义报错
delete window.modifiedRows[type][rowId].fields['operateTime'];
// 同步行对象值为原始值(关键:保证数据源与原始值一致)
row.operateTime = originalOperateTime;
hasChange = true; // 标记变更,触发后续数据源更新和表格重渲染
}
// 3. 清理无字段的空修改记录(避免冗余数据)
if (window.modifiedRows[type][rowId] && Object.keys(window.modifiedRows[type][rowId].fields).length === 0) {
delete window.modifiedRows[type][rowId];
}
// 4. 统一处理:只要有字段变更/还原,就更新全局数据源+重渲染表格
if (hasChange) {
// 同步更新全局数据源window.currentLeaseData / window.currentReturnData
var globalData = isLease ? window.currentLeaseData : window.currentReturnData;
for (var i = 0; i < globalData.length; i++) {
if (globalData[i][idField] == rowId) {
globalData[i] = row;
break;
}
}
// 【核心修改】调用全局列配置,解决未定义错误
var tableId = isLease ? '#leaseTable' : '#returnTable';
var tableData = isLease ? window.currentLeaseData : window.currentReturnData;
var tableCols = isLease ? window.tableColumnConfig.leaseCols : window.tableColumnConfig.returnCols;
// 重新渲染表格(关键:改回原始值时也会执行,保证数据同步)
projectCost.renderTableWithModifications(tableId, tableData, tableCols, type);
layer.msg('修改已保存(本地)');
} else {
// 无任何变更(包括未修改/已改回原始值),提示无修改
layer.msg('没有需要修改任何内容');
}
layer.close(index);
});
// 取消按钮
$('#cancelEdit').click(function() {
layer.close(index);
});
}
});
},
// 初始化列表页
init: function() {
// 初始化日期选择器
laydate.render({
elem: '#startDate',
lang: 'zh-CN'
});
laydate.render({
elem: '#endDate',
lang: 'zh-CN'
});
// 监听工具条事件
table.on('tool(LAY-project-cost-list)', function(obj){
var data = obj.data;
if(obj.event === 'edit'){
var editUrl = baseUrl + '/backstage/projectCost/calculation_edit'
+ '?id=' + data.id
+ '&projectId=' + data.projectId
+ '&startTime=' + data.startTime
+ '&endTime=' + data.endTime;
layer.open({
type: 2,
title: '修改',
content: editUrl,
area: ['90%', '90%'],
maxmin: true
});
}
});
},
// 生成结算数据 - 修复字段匹配问题
generateSettlement: function(data) {
window.editPageField = {
calculationId: data.calculationId,
projectId: data.projectId,
startTime: data.startTime,
endTime: data.endTime
};
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;
} else if(res.res === 1) {
isSuccess = true;
} else if(res.code === 200 || res.code === 0 || res.code === '0') {
isSuccess = true;
} else if(res.status === 'success' || res.status === 200 || res.status === 0) {
isSuccess = true;
}
}
console.log("判断是否成功: ", isSuccess, "响应结构:", JSON.stringify(res).substring(0, 100) + "...");
if(isSuccess) {
$('#data-container').empty().show();
let responseData = {};
if(res.data) {
responseData = res.data;
} else if(res.obj) {
responseData = res.obj;
} else {
responseData = res;
}
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(", "));
}
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) {
console.log("未能根据operateType分离数据显示所有明细作为领料");
leaseData = details;
}
} else {
console.warn("未找到预期的数据结构,尝试深度查找数据");
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;
}
}
}
if(!foundData && res.res === 1) {
console.log("检测到res.res===1格式的API尝试从res.obj中提取数据");
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;
// 【新增】初始化原始数据(深拷贝,防止后续修改全局数据源时污染原始值)
window.originalTableData.lease = $.extend(true, [], leaseData);
window.originalTableData.return = $.extend(true, [], 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(
'<div class="layui-row">' +
'<div class="layui-col-md12">' +
'<div style="text-align: right; padding: 10px; font-weight: bold; color: #FF5722; font-size: 16px;">' +
'总金额: <span id="totalAmountDisplay">' + totalAmount.toFixed(2) + '</span> 元' +
'</div>' +
'</div>' +
'</div>' +
'<div id="resultTableContainer" style="margin-bottom: 40px; border: 1px solid #e6e6e6; padding: 15px; background-color: #fff; box-shadow: 0 2px 5px rgba(0,0,0,0.05);">' +
'<h3 style="font-size: 16px; font-weight: bold; margin-bottom: 15px;">费用计算及领退差缺表</h3>' +
'<table class="layui-table" id="calculationTable" lay-filter="calculationTable"></table>' +
'</div>' +
'<div id="leaseTableContainer" style="margin-bottom: 40px; border: 1px solid #e6e6e6; padding: 15px; background-color: #fff; box-shadow: 0 2px 5px rgba(0,0,0,0.05);">' +
'<h3 style="font-size: 16px; font-weight: bold; margin-bottom: 15px;">物资领料明细</h3>' +
'<table class="layui-table" id="leaseTable" lay-filter="leaseTable"></table>' +
'</div>' +
'<div id="returnTableContainer" style="margin-bottom: 40px; border: 1px solid #e6e6e6; padding: 15px; background-color: #fff; box-shadow: 0 2px 5px rgba(0,0,0,0.05);">' +
'<h3 style="font-size: 16px; font-weight: bold; margin-bottom: 15px;">物资退料明细</h3>' +
'<table class="layui-table" id="returnTable" lay-filter="returnTable"></table>' +
'</div>'
);
var calcTableHeight = function(dataLength) {
if (dataLength <= 3) return 220;
if (dataLength <= 6) return 240;
return 300;
};
if(calculationResults.length > 0) {
var calcHeight = calcTableHeight(calculationResults.length);
// 检查calculationResults的字段
console.log('calculationResults字段:', calculationResults.length > 0 ? Object.keys(calculationResults[0]) : '无数据');
table.render({
elem: '#calculationTable',
data: calculationResults,
cols: [[
{field: 'machineTypeId', title: '物资ID', width: '10%', hide: true},
{field: 'machineTypeName', title: '物资名称', width: '20%'},
{field: 'machineModel', title: '规格型号', width: '20%'},
{field: 'machineUnit', title: '单位', width: '10%'},
{field: 'currentCount', title: '未退还数量', width: '10%', templet: function(d){
return d.currentCount || 0;
}},
{field: 'price', title: '单价(元/天)', width: '10%', templet: function(d){
return d.price ? d.price.toFixed(2) : '0.00';
}},
{field: 'amount', title: '金额(元)', width: '10%', templet: function(d){
return d.amount ? d.amount.toFixed(2) : '0.00';
}},
{title: '操作', width: '9%', templet: function(d){
return '<a class="layui-btn layui-btn-xs" lay-event="viewDetail">查看明细</a>';
}}
]],
page: false,
height: calcHeight,
limit: 1000,
lang: 'zh-CN'
});
table.on('tool(calculationTable)', function(obj){
let i;
const data = obj.data;
if(obj.event === 'viewDetail'){
let detailHtml = '<div style="padding: 15px;">';
detailHtml += '<div class="layui-tab layui-tab-brief" lay-filter="detailTab">';
detailHtml += '<ul class="layui-tab-title">';
detailHtml += '<li class="layui-this">使用时间段</li>';
detailHtml += '<li>物资领退记录</li>';
detailHtml += '</ul>';
detailHtml += '<div class="layui-tab-content">';
detailHtml += '<div class="layui-tab-item layui-show">';
detailHtml += '<table class="layui-table">';
detailHtml += '<thead><tr><th>开始时间</th><th>结束时间</th><th>使用天数</th><th>使用数量</th><th>金额(元)</th></tr></thead>';
detailHtml += '<tbody>';
const segments = data.segments || [];
console.log("时段计算数据:", segments);
if (segments.length === 0) {
detailHtml += '<tr><td colspan="5" style="text-align: center;">没有详细的时段计算数据,显示汇总信息</td></tr>';
var amount = data.amount || 0;
var count = data.currentCount || 0;
detailHtml += '<tr style="font-weight: bold;">';
detailHtml += '<td>--</td>';
detailHtml += '<td>--</td>';
detailHtml += '<td>--</td>';
detailHtml += '<td>' + count + '</td>';
detailHtml += '<td>' + (amount ? amount.toFixed(2) : '0.00') + '</td>';
detailHtml += '</tr>';
} else {
var totalDays = 0;
var totalAmount = 0;
for(i = 0; i < segments.length; i++){
var segment = segments[i];
var startTime = formatDateTime(segment.startTime);
var endTime = formatDateTime(segment.endTime);
var days = segment.days || 0;
var count = segment.count || 0;
var amount = segment.amount || 0;
totalDays += days;
totalAmount += amount;
detailHtml += '<tr>';
detailHtml += '<td>' + startTime + '</td>';
detailHtml += '<td>' + endTime + '</td>';
detailHtml += '<td>' + days + '</td>';
detailHtml += '<td>' + count + '</td>';
detailHtml += '<td>' + amount.toFixed(2) + '</td>';
detailHtml += '</tr>';
}
detailHtml += '<tr style="font-weight: bold; background-color: #f2f2f2;">';
detailHtml += '<td colspan="2">合计</td>';
detailHtml += '<td>' + totalDays + '</td>';
detailHtml += '<td>-</td>';
detailHtml += '<td>' + totalAmount.toFixed(2) + '</td>';
detailHtml += '</tr>';
}
detailHtml += '</tbody></table>';
detailHtml += '</div>';
detailHtml += '<div class="layui-tab-item">';
detailHtml += '<div style="margin-bottom: 10px; text-align: right;">';
detailHtml += '<span style="display: inline-block; padding: 2px 8px; margin-right: 10px; background-color: #e8f5e9; color: #388e3c; border-radius: 2px;">领料</span>';
detailHtml += '<span style="display: inline-block; padding: 2px 8px; background-color: #ffebee; color: #d32f2f; border-radius: 2px;">退料</span>';
detailHtml += '</div>';
detailHtml += '<table class="layui-table">';
detailHtml += '<thead><tr style="background-color: #f2f2f2; font-weight: bold;"><th>操作时间</th><th>操作类型</th><th>数量</th><th>现场剩余数量</th></tr></thead>';
detailHtml += '<tbody>';
var details = data.details || [];
var timeline = data.timeline || {};
console.log("明细详情数据:", details);
console.log("时间线数据:", timeline);
details.sort(function(a, b){
var timeA = a.operateTime ? new Date(a.operateTime) : new Date(0);
var timeB = b.operateTime ? new Date(b.operateTime) : new Date(0);
return timeA - timeB;
});
if (details.length === 0) {
detailHtml += '<tr><td colspan="4" style="text-align: center;">暂无操作记录数据</td></tr>';
} else {
var totalLeaseQuantity = 0;
var totalReturnQuantity = 0;
var finalCount = 0;
for(i = 0; i < details.length; i++){
var item = details[i];
var operateTimeStr = item.operateTime || '';
var operateTime = formatDateTime(operateTimeStr);
let operateType = '未知';
if (item.operateType === 1 || item.operateType === '1') {
operateType = '领料';
} else if (item.operateType === 2 || item.operateType === '2') {
operateType = '退料';
} else {
operateType = String(item.operateType || '');
}
var quantity = 0;
if (operateType === '领料') {
quantity = item.leaseNum || item.quantity || item.count || item.num || 0;
totalLeaseQuantity += parseFloat(quantity);
} else if (operateType === '退料') {
quantity = item.returnNum || item.quantity || item.count || item.num || 0;
totalReturnQuantity += parseFloat(quantity);
}
var currentCount = timeline[operateTimeStr] || 0;
if (currentCount === 0 && operateTimeStr) {
for (var timeKey in timeline) {
if (timeKey && operateTimeStr.substring(0, 10) === timeKey.substring(0, 10)) {
currentCount = timeline[timeKey];
console.log("找到匹配的时间线数据:", timeKey, currentCount);
break;
}
}
}
finalCount = currentCount;
var rowStyle = '';
if (operateType === '领料') {
rowStyle = 'background-color: #e8f5e9; color: #388e3c;';
} else if (operateType === '退料') {
rowStyle = 'background-color: #ffebee; color: #d32f2f;';
}
detailHtml += '<tr style="' + rowStyle + '">';
detailHtml += '<td>' + operateTime + '</td>';
detailHtml += '<td>' + operateType + '</td>';
detailHtml += '<td>' + quantity + '</td>';
detailHtml += '<td>' + currentCount + '</td>';
detailHtml += '</tr>';
}
detailHtml += '<tr style="font-weight: bold; background-color: #f2f2f2;">';
detailHtml += '<td colspan="2">汇总</td>';
detailHtml += '<td><span style="color: #388e3c;">领料: ' + totalLeaseQuantity + '</span><br><span style="color: #d32f2f;">退料: ' + totalReturnQuantity + '</span></td>';
detailHtml += '<td>' + finalCount + '</td>';
detailHtml += '</tr>';
}
detailHtml += '</tbody></table>';
detailHtml += '</div>';
detailHtml += '</div>';
detailHtml += '</div>';
detailHtml += '</div>';
const layerIndex = layer.open({
type: 1,
title: data.machineTypeName + ' 使用明细',
content: detailHtml,
area: ['800px', '500px'],
shadeClose: true,
success: function () {
layui.element.render('tab');
}
});
}
});
} else {
$('#resultTableContainer').html('<div style="padding: 20px; text-align: center;">暂无租赁费用计算结果</div>');
}
// 渲染领料表格 - 修复字段匹配问题
if (leaseData && leaseData.length > 0) {
console.log('领料数据字段:', Object.keys(leaseData[0]));
// 【修改】赋值给全局列配置替换原有局部var leaseCols
window.tableColumnConfig.leaseCols = [[
{field: 'supId', title: 'ID', hide: true},
{field: 'machineTypeName', title: '物资名称', width: 150, templet: function(d){
return d.machineTypeName || d.machineName || d.materialName || '';
}},
{field: 'machineModel', title: '规格型号', width: 120, templet: function(d){
return d.machineModel || d.specification || '';
}},
{field: 'machineUnit', title: '单位', width: 70, templet: function(d){
return d.machineUnit || d.unit || '';
}},
{field: 'leaseNum', title: '数量', width: 80, templet: function(d){
return d.leaseNum || d.quantity || d.count || d.num || 0;
}},
{field: 'price', title: '单价(元)', width: 100, templet: function(d){
return d.price || d.unitPrice || '0.00';
}},
{field: 'amount', title: '金额(元)', width: 100, templet: function(d){
var amount = d.amount || d.totalPrice || d.money || 0;
if(amount === 0 && d.leaseNum) {
var price = d.price || d.unitPrice || 0;
if(price > 0) {
amount = (parseFloat(d.leaseNum) * parseFloat(price)).toFixed(2);
}
}
return amount || '0.00';
}},
{field: 'leaseUnit', title: '使用单位', width: 120, templet: function(d){
return d.leaseUnit || '';
}},
{field: 'operatePersonName', title: '操作人', width: 100, templet: function(d){
return d.operatePersonName || '';
}},
{field: 'operateTime', title: '操作时间', width: 180, templet: function(d){
return d.operateTime || '';
}},
{field: 'taskCode', title: '任务编号', width: 120, templet: function(d){
return d.taskCode || '';
}},
{field: 'projectName', title: '工程名称', width: 200, templet: function(d){
return d.projectName || '';
}},
{field: 'operateType', title: '操作类型', width: 80, templet: function(d){
return d.operateType === 1 ? '<span style="color: #2f952d">领料</span>' : (d.operateType === 2 ? '<span style="color: #bc412b">退料</span>' : d.operateType || '');
}},
{field: 'remark', title: '备注', width: 120, templet: function(d){
return d.remark || '';
}},
{title: '操作', width: 100, align: 'center', fixed: 'right', templet: function(d){
return '<button class="layui-btn layui-btn-xs layui-btn-normal" lay-event="editLease">修改</button>';
}}
]];
projectCost.renderTableWithModifications('#leaseTable', leaseData, window.tableColumnConfig.leaseCols, 'lease');
// 监听修改事件
table.on('tool(leaseTable)', function(obj) {
if (obj.event === 'editLease') {
projectCost.openEditModal(obj.data, 'lease', obj);
}
});
} else {
$('#leaseTableContainer').html('<div style="padding: 20px; text-align: center;">暂无物资领料明细</div>');
}
// 渲染退料表格 - 修复字段匹配问题
// 渲染退料表格 - 修复字段匹配问题
if (returnData && returnData.length > 0) {
console.log('退料数据字段:', Object.keys(returnData[0]));
// 【修改】赋值给全局列配置替换原有局部var returnCols
window.tableColumnConfig.returnCols = [[
{field: 'id', title: 'ID', hide: true},
{field: 'machineTypeName', title: '物资名称', width: 150, templet: function(d){
return d.machineTypeName || d.machineName || d.materialName || '';
}},
{field: 'machineModel', title: '规格型号', width: 120, templet: function(d){
return d.machineModel || d.specification || '';
}},
{field: 'machineUnit', title: '单位', width: 70, templet: function(d){
return d.machineUnit || d.unit || '';
}},
{field: 'returnNum', title: '数量', width: 80, templet: function(d){
return d.returnNum || d.quantity || d.count || d.num || 0;
}},
{field: 'price', title: '单价(元)', width: 100, templet: function(d){
return d.price || d.unitPrice || '0.00';
}},
{field: 'amount', title: '金额(元)', width: 100, templet: function(d){
var amount = d.amount || d.totalPrice || d.money || 0;
if(amount === 0 && d.returnNum) {
var price = d.price || d.unitPrice || 0;
if(price > 0) {
amount = (parseFloat(d.returnNum) * parseFloat(price)).toFixed(2);
}
}
return amount || '0.00';
}},
{field: 'leaseUnit', title: '使用单位', width: 120, templet: function(d){
return d.leaseUnit || '';
}},
{field: 'operatePersonName', title: '操作人', width: 100, templet: function(d){
return d.operatePersonName || '';
}},
{field: 'operateTime', title: '操作时间', width: 180, templet: function(d){
return d.operateTime || '';
}},
{field: 'taskCode', title: '任务编号', width: 120, templet: function(d){
return d.taskCode || '';
}},
{field: 'projectName', title: '工程名称', width: 200, templet: function(d){
return d.projectName || '';
}},
{field: 'operateType', title: '操作类型', width: 80, templet: function(d){
return d.operateType === 1 ? '<span style="color: #2f952d">领料</span>' : (d.operateType === 2 ? '<span style="color: #bc412b">退料</span>' : d.operateType || '');
}},
{field: 'remark', title: '备注', width: 120, templet: function(d){
return d.remark || '';
}},
{title: '操作', width: 100, align: 'center', fixed: 'right', templet: function(d){
return '<button class="layui-btn layui-btn-xs layui-btn-normal" lay-event="editReturn">修改</button>';
}}
]];
projectCost.renderTableWithModifications('#returnTable', returnData, window.tableColumnConfig.returnCols, 'return');
// 监听修改事件
table.on('tool(returnTable)', function(obj) {
if (obj.event === 'editReturn') {
projectCost.openEditModal(obj.data, 'return', obj);
}
});
} else {
$('#returnTableContainer').html('<div style="padding: 20px; text-align: center;">暂无物资退料明细</div>');
}
$('html, body').animate({
scrollTop: $('#data-container').offset().top - 20
}, 500);
} else {
layer.msg(res.msg || res.resMsg || '数据加载失败');
}
},
error: function(xhr, status, error) {
$('#data-loading').hide();
console.error('请求失败:', status, error);
console.log('XHR对象:', xhr);
layer.msg('网络错误,请重试');
}
});
},
};
// 输出接口
exports('projectCost', projectCost);
});
// 添加日期格式化函数
function formatDateTime(dateTimeStr) {
if(!dateTimeStr) return '';
try {
var date = new Date(dateTimeStr);
if(isNaN(date.getTime())) return dateTimeStr;
return date.getFullYear() + '-' +
padZero(date.getMonth() + 1) + '-' +
padZero(date.getDate()) + ' ' +
padZero(date.getHours()) + ':' +
padZero(date.getMinutes());
} catch(e) {
return dateTimeStr;
}
}
function padZero(num) {
return (num < 10 ? '0' : '') + num;
}