A New View of Statistics

博客提供了两个链接,分别为http://www.uq.edu.au/~hmrburge/和http://www.uq.edu.au/~hmrburge/stats/modelsdetail.html ,可能与统计相关内容有关。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/** * 生产消耗管理页面 * 根据代码规范,所有数据交互都通过 DataManager 进行 */ class ShengchanXiaohaoManager { constructor(dataManager) { this.dataManager = dataManager; this.currentUser = null; this.consumptionRecords = []; this.init(); } async init() { try { // 检查用户权限 await this.checkUserPermission(); // 注册数据管理器回调 this.registerDataCallbacks(); // 初始化页面数据 await this.initPageData(); // 绑定事件 this.bindEvents(); console.log('生产消耗管理页面初始化完成'); } catch (error) { console.error('初始化失败:', error); alert('页面初始化失败,请刷新重试'); } } async checkUserPermission() { try { // 通过 DataManager 获取当前用户信息 this.currentUser = await this.dataManager.getCurrentUser(); if (!this.currentUser || this.currentUser.role < 2) { alert('权限不足,无法访问此页面'); window.location.href = '../index.html'; return; } } catch (error) { console.error('权限检查失败:', error); window.location.href = '../index.html'; } } /** * 注册数据管理器回调 */ registerDataCallbacks() { // 注册生产消耗相关回调 this.dataManager.registerCallback('shengchan_xiaohao', (operation, data) => { if (operation === 'add') { this.onConsumptionAdded(data); } else if (operation === 'add_error') { this.onConsumptionError(data); } }); // 注册数据刷新回调 this.dataManager.registerCallback('all', (operation, entity, data) => { if (operation === 'refresh') { this.refreshConsumptionData(); } }); } /** * 初始化页面数据 */ async initPageData() { try { // 确保数据已加载 await this.dataManager.fetchAll(); // 刷新消耗数据 this.refreshConsumptionData(); // 加载统计信息 this.loadStatistics(); // 初始化下拉框数据 this.initSelectOptions(); } catch (error) { console.error('初始化页面数据失败:', error); } } /** * 刷新消耗数据 */ refreshConsumptionData() { // 从 DataManager 获取生产消耗记录 this.consumptionRecords = this.dataManager.getShengchanXiaohaoRecords(); // 更新表格显示 this.updateConsumptionTable(); } /** * 更新消耗表格 */ updateConsumptionTable() { const tableBody = document.getElementById('productionRecordsTable'); if (!tableBody) return; if (this.consumptionRecords.length === 0) { tableBody.innerHTML = '<tr><td colspan="9" class="text-center text-muted">暂无生产记录</td></tr>'; return; } const rows = this.consumptionRecords.map(record => { const dingdanBancai = record.dingdan_bancai || {}; const dingdan = dingdanBancai.dingdan || {}; const chanpin = dingdanBancai.chanpin || {}; const zujian = dingdanBancai.zujian || {}; const bancai = dingdanBancai.bancai || {}; const user = record.user || {}; return ` <tr> <td>${new Date(record.date).toLocaleString('zh-CN')}</td> <td>${dingdan.number || '未指定'}</td> <td>${chanpin.bianhao || '未指定'}</td> <td>${zujian.name || '未指定'}</td> <td><span class="badge badge-primary">${Math.abs(record.shuliang)}</span></td> <td>${this.getBancaiName(bancai)}</td> <td>${user.name || '未知'}</td> <td><span class="badge badge-success">正常</span></td> <td> <button class="btn btn-sm btn-info" onclick="shengchanXiaohaoManager.viewRecord(${record.id})" title="查看详情"> <i class="bi bi-eye"></i> </button> </td> </tr> `; }).join(''); tableBody.innerHTML = rows; } /** * 获取板材名称 */ getBancaiName(bancai) { if (!bancai) return '未知板材'; const caizhi = bancai.caizhi || {}; const mupi1 = bancai.mupi1 || {}; const mupi2 = bancai.mupi2 || {}; return `${caizhi.name || ''}${bancai.houdu || ''}mm ${mupi1.name || ''}/${mupi2.name || ''}`; } /** * 初始化下拉框选项 */ initSelectOptions() { // 初始化订单下拉框 this.updateDingdanSelect(); // 绑定订单变化事件 const dingdanSelect = document.getElementById('dingdanSelect'); if (dingdanSelect) { dingdanSelect.addEventListener('change', () => { this.onDingdanChange(); }); } // 绑定产品变化事件 const chanpinSelect = document.getElementById('chanpinSelect'); if (chanpinSelect) { chanpinSelect.addEventListener('change', () => { this.onChanpinChange(); }); } // 绑定组件变化事件 const zujianSelect = document.getElementById('zujianSelect'); if (zujianSelect) { zujianSelect.addEventListener('change', () => { this.onZujianChange(); }); } } /** * 更新订单下拉框 */ updateDingdanSelect() { const select = document.getElementById('dingdanSelect'); if (!select) return; const dingdans = this.dataManager.getDingdans(); select.innerHTML = '<option value="">请选择订单</option>'; dingdans.forEach(dingdan => { if (!dingdan.deleted) { const option = document.createElement('option'); option.value = dingdan.id; option.textContent = dingdan.number; select.appendChild(option); } }); } /** * 订单变化处理 */ onDingdanChange() { const dingdanSelect = document.getElementById('dingdanSelect'); const chanpinSelect = document.getElementById('chanpinSelect'); const zujianSelect = document.getElementById('zujianSelect'); const productionQuantity = document.getElementById('productionQuantity'); if (!dingdanSelect.value) { chanpinSelect.disabled = true; zujianSelect.disabled = true; productionQuantity.disabled = true; return; } // 更新产品下拉框 const chanpins = this.dataManager.getChanpinsForDingdan(dingdanSelect.value); chanpinSelect.innerHTML = '<option value="">请选择产品</option>'; chanpins.forEach(chanpin => { const option = document.createElement('option'); option.value = chanpin.id; option.textContent = chanpin.bianhao; chanpinSelect.appendChild(option); }); chanpinSelect.disabled = false; zujianSelect.disabled = true; productionQuantity.disabled = true; } /** * 产品变化处理 */ onChanpinChange() { const chanpinSelect = document.getElementById('chanpinSelect'); const zujianSelect = document.getElementById('zujianSelect'); const productionQuantity = document.getElementById('productionQuantity'); if (!chanpinSelect.value) { zujianSelect.disabled = true; productionQuantity.disabled = true; return; } // 更新组件下拉框 const zujians = this.dataManager.getZujiansForChanpin(chanpinSelect.value); zujianSelect.innerHTML = '<option value="">请选择组件</option>'; zujians.forEach(zujian => { const option = document.createElement('option'); option.value = zujian.id; option.textContent = zujian.name; zujianSelect.appendChild(option); }); zujianSelect.disabled = false; productionQuantity.disabled = true; } /** * 组件变化处理 */ onZujianChange() { const zujianSelect = document.getElementById('zujianSelect'); const productionQuantity = document.getElementById('productionQuantity'); if (!zujianSelect.value) { productionQuantity.disabled = true; return; } productionQuantity.disabled = false; // 启用计算按钮 const calculateBtn = document.getElementById('calculateConsumption'); if (calculateBtn) { calculateBtn.disabled = false; } } columns: [ { data: 'id', title: 'ID', width: '60px' }, { data: null, title: '订单信息', render: function(data, type, row) { let html = ''; if (row.dingdan_name) { html += `<div><strong>订单:</strong> ${row.dingdan_name}</div>`; } if (row.chanpin_name) { html += `<div><strong>产品:</strong> ${row.chanpin_name}</div>`; } if (row.zujian_name) { html += `<div><strong>组件:</strong> ${row.zujian_name}</div>`; } return html || '未指定'; } }, { data: 'bancai_name', title: '板材', render: function(data, type, row) { return data || '未知板材'; } }, { data: 'shengchan_shuliang', title: '生产数量', className: 'text-center', render: function(data, type, row) { return `<span class="badge badge-primary">${data || 0}</span>`; } }, { data: 'xiaohao_shuliang', title: '消耗数量', className: 'text-center', render: function(data, type, row) { return `<span class="badge badge-warning">${data || 0}</span>`; } }, { data: 'shijian', title: '时间', render: function(data, type, row) { if (data) { const date = new Date(data); return date.toLocaleString('zh-CN'); } return ''; } }, { data: 'caozuoyuan_name', title: '操作员', render: function(data, type, row) { return data || '未知'; } }, { data: 'zhuangtai', title: '状态', className: 'text-center', render: function(data, type, row) { const statusClass = data === '正常' ? 'success' : 'secondary'; return `<span class="badge badge-${statusClass}">${data || '正常'}</span>`; } }, { data: null, title: '操作', orderable: false, className: 'text-center', width: '120px', render: function(data, type, row) { return ` <button class="btn btn-sm btn-info view-btn" data-id="${row.id}" title="查看详情"> <i class="fas fa-eye"></i> </button> <button class="btn btn-sm btn-primary edit-btn" data-id="${row.id}" title="编辑"> <i class="fas fa-edit"></i> </button> <button class="btn btn-sm btn-danger delete-btn" data-id="${row.id}" title="删除"> <i class="fas fa-trash"></i> </button> `; } } ], order: [[0, 'desc']], pageLength: 25, responsive: true, language: { url: '//cdn.datatables.net/plug-ins/1.10.24/i18n/Chinese.json' }, dom: '<"row"<"col-sm-12 col-md-6"l><"col-sm-12 col-md-6"f>>' + '<"row"<"col-sm-12"tr>>' + '<"row"<"col-sm-12 col-md-5"i><"col-sm-12 col-md-7"p>>', drawCallback: (settings) => { // 重新绑定按钮事件 $('.view-btn').off('click').on('click', (e) => { const id = $(e.currentTarget).data('id'); this.viewRecord(id); }); $('.edit-btn').off('click').on('click', (e) => { const id = $(e.currentTarget).data('id'); this.editRecord(id); }); $('.delete-btn').off('click').on('click', (e) => { const id = $(e.currentTarget).data('id'); this.deleteRecord(id); }); } }); } bindEvents() { // 计算消耗按钮 const calculateBtn = document.getElementById('calculateConsumption'); if (calculateBtn) { calculateBtn.addEventListener('click', () => { this.calculateConsumption(); }); } // 确认生产按钮 const confirmBtn = document.getElementById('confirmProduction'); if (confirmBtn) { confirmBtn.addEventListener('click', () => { this.confirmProduction(); }); } // 刷新按钮 const refreshBtn = document.getElementById('refreshBtn'); if (refreshBtn) { refreshBtn.addEventListener('click', () => { this.refreshData(); }); } // 新增订单按钮 const addDingdanBtn = document.getElementById('addDingdanBtn'); if (addDingdanBtn) { addDingdanBtn.addEventListener('click', () => { this.showAddDingdanModal(); }); } // 添加产品按钮 const addChanpinBtn = document.getElementById('addChanpinBtn'); if (addChanpinBtn) { addChanpinBtn.addEventListener('click', () => { this.showAddChanpinModal(); }); } // 添加组件按钮 const addZujianBtn = document.getElementById('addZujianBtn'); if (addZujianBtn) { addZujianBtn.addEventListener('click', () => { this.showAddZujianModal(); }); } } /** * 计算消耗 */ async calculateConsumption() { try { const dingdanId = document.getElementById('dingdanSelect').value; const chanpinId = document.getElementById('chanpinSelect').value; const zujianId = document.getElementById('zujianSelect').value; const shengchanShuliang = parseInt(document.getElementById('productionQuantity').value); if (!dingdanId || !chanpinId || !zujianId || !shengchanShuliang) { alert('请完整填写生产信息'); return; } // 获取组件的板材消耗信息 const bancais = this.dataManager.getBancaisForZujian(zujianId); const consumptionDetails = document.getElementById('consumptionDetails'); const consumptionList = document.getElementById('consumptionList'); if (bancais.length === 0) { alert('该组件没有配置板材信息'); return; } // 显示消耗明细 consumptionDetails.style.display = 'block'; consumptionList.innerHTML = ''; bancais.forEach(bancai => { // 从 chanpin_zujians 中获取消耗比例 const chanpinZujian = this.dataManager.data.chanpin_zujians.find(cz => cz.chanpin?.id == chanpinId && cz.zujian?.id == zujianId && cz.bancai?.id == bancai.id ); const oneHowMany = chanpinZujian ? chanpinZujian.one_howmany : 1; const xiaohaoShuliang = Math.ceil(shengchanShuliang * oneHowMany); const itemHtml = ` <div class="consumption-item" data-bancai-id="${bancai.id}" data-xiaohao="${xiaohaoShuliang}"> <div class="row"> <div class="col-md-6"> <strong>板材:</strong> ${this.getBancaiName(bancai)} </div> <div class="col-md-3"> <strong>单位消耗:</strong> ${oneHowMany} </div> <div class="col-md-3"> <strong>总消耗:</strong> <span class="text-danger">${xiaohaoShuliang} 张</span> </div> </div> </div> `; consumptionList.innerHTML += itemHtml; }); // 启用确认生产按钮 const confirmBtn = document.getElementById('confirmProduction'); if (confirmBtn) { confirmBtn.disabled = false; } } catch (error) { console.error('计算消耗失败:', error); alert('计算消耗失败,请重试'); } } /** * 确认生产 */ async confirmProduction() { try { const dingdanId = document.getElementById('dingdanSelect').value; const chanpinId = document.getElementById('chanpinSelect').value; const zujianId = document.getElementById('zujianSelect').value; const shengchanShuliang = parseInt(document.getElementById('productionQuantity').value); const consumptionItems = document.querySelectorAll('.consumption-item'); if (consumptionItems.length === 0) { alert('请先计算消耗'); return; } if (!confirm('确认执行生产消耗操作?此操作将扣减库存。')) { return; } // 处理每个板材的消耗 for (const item of consumptionItems) { const bancaiId = parseInt(item.dataset.bancaiId); const xiaohaoShuliang = parseInt(item.dataset.xiaohao); const consumptionData = { dingdan: { id: parseInt(dingdanId) }, chanpin: { id: parseInt(chanpinId) }, zujian: { id: parseInt(zujianId) }, bancai: { id: bancaiId }, shengchan_shuliang: shengchanShuliang, xiaohao_shuliang: xiaohaoShuliang, caozuoyuan: { id: this.currentUser.id }, shijian: new Date().toISOString(), beizhu: `生产${shengchanShuliang}个${document.getElementById('chanpinSelect').selectedOptions[0].text}` }; // 通过 DataManager 处理生产消耗事务 await this.dataManager.processShengchanXiaohao(consumptionData); } alert('生产消耗处理完成'); this.resetForm(); } catch (error) { console.error('确认生产失败:', error); alert('生产消耗处理失败: ' + error.message); } } /** * 重置表单 */ resetForm() { document.getElementById('dingdanSelect').value = ''; document.getElementById('chanpinSelect').innerHTML = '<option value="">请选择产品</option>'; document.getElementById('zujianSelect').innerHTML = '<option value="">请选择组件</option>'; document.getElementById('productionQuantity').value = ''; document.getElementById('chanpinSelect').disabled = true; document.getElementById('zujianSelect').disabled = true; document.getElementById('productionQuantity').disabled = true; document.getElementById('calculateConsumption').disabled = true; document.getElementById('confirmProduction').disabled = true; document.getElementById('consumptionDetails').style.display = 'none'; } /** * 显示添加订单弹窗 */ showAddDingdanModal() { if (window.CustomFormModal) { window.CustomFormModal.show('dingdan', { title: '添加订单', onSuccess: () => { this.refreshData(); } }); } } /** * 显示添加产品弹窗 */ showAddChanpinModal() { const dingdanId = document.getElementById('dingdanSelect').value; if (!dingdanId) { alert('请先选择订单'); return; } if (window.CustomFormModal) { window.CustomFormModal.show('chanpin', { title: '添加产品', onSuccess: () => { this.refreshData(); this.onDingdanChange(); // 刷新产品列表 } }); } } /** * 显示添加组件弹窗 */ showAddZujianModal() { const chanpinId = document.getElementById('chanpinSelect').value; if (!chanpinId) { alert('请先选择产品'); return; } if (window.CustomFormModal) { window.CustomFormModal.show('zujian', { title: '添加组件', onSuccess: () => { this.refreshData(); this.onChanpinChange(); // 刷新组件列表 } }); } } /** * 查看记录详情 */ viewRecord(recordId) { const record = this.consumptionRecords.find(r => r.id === recordId); if (!record) { alert('记录不存在'); return; } const dingdanBancai = record.dingdan_bancai || {}; const dingdan = dingdanBancai.dingdan || {}; const chanpin = dingdanBancai.chanpin || {}; const zujian = dingdanBancai.zujian || {}; const bancai = dingdanBancai.bancai || {}; const user = record.user || {}; const content = ` <div class="row"> <div class="col-md-6"> <p><strong>记录ID:</strong> ${record.id}</p> <p><strong>订单:</strong> ${dingdan.number || '未指定'}</p> <p><strong>产品:</strong> ${chanpin.bianhao || '未指定'}</p> <p><strong>组件:</strong> ${zujian.name || '未指定'}</p> <p><strong>板材:</strong> ${this.getBancaiName(bancai)}</p> </div> <div class="col-md-6"> <p><strong>消耗数量:</strong> ${Math.abs(record.shuliang)} 张</p> <p><strong>消耗时间:</strong> ${new Date(record.date).toLocaleString('zh-CN')}</p> <p><strong>操作员:</strong> ${user.name || '未知'}</p> <p><strong>操作类型:</strong> 生产消耗</p> <p><strong>备注:</strong> ${record.text || '无'}</p> </div> </div> `; // 显示在模态框中 if (window.CustomFormModal) { const modal = document.createElement('div'); modal.className = 'modal fade'; modal.innerHTML = ` <div class="modal-dialog modal-lg"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">生产消耗记录详情</h5> <button type="button" class="btn-close" data-bs-dismiss="modal"></button> </div> <div class="modal-body">${content}</div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button> </div> </div> </div> `; document.body.appendChild(modal); const bootstrapModal = new bootstrap.Modal(modal); bootstrapModal.show(); modal.addEventListener('hidden.bs.modal', () => { document.body.removeChild(modal); }); } } /** * 刷新数据 */ async refreshData() { try { await this.dataManager.refreshData(); this.loadStatistics(); } catch (error) { console.error('刷新数据失败:', error); } } /** * 加载统计信息 */ loadStatistics() { try { const statistics = this.dataManager.getShengchanStatistics(); const todayConsumption = document.getElementById('todayConsumption'); const monthConsumption = document.getElementById('monthConsumption'); const pendingOrders = document.getElementById('pendingOrders'); const lowStockCount = document.getElementById('lowStockCount'); if (todayConsumption) todayConsumption.textContent = `${statistics.today_consumption} 张`; if (monthConsumption) monthConsumption.textContent = `${statistics.month_consumption} 张`; if (pendingOrders) pendingOrders.textContent = `${statistics.pending_orders} 个`; if (lowStockCount) lowStockCount.textContent = `${statistics.low_stock_count} 种`; } catch (error) { console.error('加载统计信息失败:', error); } } /** * 生产消耗添加成功回调 */ onConsumptionAdded(data) { console.log('生产消耗添加成功:', data); // 数据会通过 DataManager 的回调自动刷新 } /** * 生产消耗添加失败回调 */ onConsumptionError(data) { console.error('生产消耗处理失败:', data); alert('生产消耗处理失败: ' + data.error); } } // 页面加载完成后初始化 document.addEventListener('DOMContentLoaded', async function() { // 检查必要的依赖 if (typeof DataManager === 'undefined') { console.error('DataManager 未加载'); alert('系统组件未加载完成,请刷新页面'); return; } try { // 导入 DataManager const { DataManager } = await import('../data/DataManager.js'); // 创建 DataManager 实例 const dataManager = new DataManager(); await dataManager.fetchAll(); // 初始化生产消耗管理器 window.shengchanXiaohaoManager = new ShengchanXiaohaoManager(dataManager); console.log('生产消耗管理系统初始化完成'); } catch (error) { console.error('系统初始化失败:', error); alert('系统初始化失败,请刷新页面重试'); } }); showAddModal() { if (window.CustomFormModal) { window.CustomFormModal.show('shengchan-xiaohao', { title: '添加生产消耗', onSuccess: () => { this.refreshData(); } }); } else { console.error('CustomFormModal 未加载'); alert('弹窗组件未加载,请刷新页面重试'); } } async viewRecord(id) { try { const response = await fetch(`../php_api/index.php?action=getShengchanXiaohao&id=${id}`); const result = await response.json(); if (result.success && result.data) { const record = result.data; let content = ` <div class="row"> <div class="col-md-6"> <p><strong>ID:</strong> ${record.id}</p> <p><strong>订单:</strong> ${record.dingdan_name || '未指定'}</p> <p><strong>产品:</strong> ${record.chanpin_name || '未指定'}</p> <p><strong>组件:</strong> ${record.zujian_name || '未指定'}</p> <p><strong>板材:</strong> ${record.bancai_name || '未知'}</p> </div> <div class="col-md-6"> <p><strong>生产数量:</strong> ${record.shengchan_shuliang}</p> <p><strong>消耗数量:</strong> ${record.xiaohao_shuliang}</p> <p><strong>时间:</strong> ${new Date(record.shijian).toLocaleString('zh-CN')}</p> <p><strong>操作员:</strong> ${record.caozuoyuan_name || '未知'}</p> <p><strong>状态:</strong> ${record.zhuangtai || '正常'}</p> </div> </div> `; if (record.beizhu) { content += `<div class="row"><div class="col-12"><p><strong>备注:</strong> ${record.beizhu}</p></div></div>`; } $('#viewModalBody').html(content); $('#viewModal').modal('show'); } else { alert('获取记录详情失败'); } } catch (error) { console.error('查看记录失败:', error); alert('查看记录失败,请重试'); } } editRecord(id) { if (window.CustomFormModal) { window.CustomFormModal.show('shengchan-xiaohao', { title: '编辑生产消耗', mode: 'edit', recordId: id, onSuccess: () => { this.refreshData(); } }); } else { console.error('CustomFormModal 未加载'); alert('弹窗组件未加载,请刷新页面重试'); } } async deleteRecord(id) { if (!confirm('确定要删除这条生产消耗记录吗?此操作不可撤销。')) { return; } try { const response = await fetch('../php_api/index.php?action=deleteShengchanXiaohao', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ id: id }) }); const result = await response.json(); if (result.success) { alert('删除成功'); this.refreshData(); } else { alert('删除失败: ' + (result.message || '未知错误')); } } catch (error) { console.error('删除记录失败:', error); alert('删除失败,请重试'); } } refreshData() { if (this.dataTable) { this.dataTable.ajax.reload(); } } // 获取统计信息 async loadStatistics() { try { const response = await fetch('../php_api/index.php?action=getShengchanXiaohaoStatistics'); const result = await response.json(); if (result.success && result.data) { const stats = result.data; $('#totalRecords').text(stats.total_records || 0); $('#todayRecords').text(stats.today_records || 0); $('#totalConsumption').text(stats.total_consumption || 0); $('#todayConsumption').text(stats.today_consumption || 0); } } catch (error) { console.error('获取统计信息失败:', error); } } } // 页面加载完成后初始化 $(document).ready(function() { // 检查必要的依赖 if (typeof $ === 'undefined') { console.error('jQuery 未加载'); return; } if (typeof $.fn.DataTable === 'undefined') { console.error('DataTables 未加载'); return; } // 初始化管理器 window.shengchanXiaohaoManager = new ShengchanXiaohaoManager(); // 加载统计信息 window.shengchanXiaohaoManager.loadStatistics(); });------------语法错误
最新发布
08-11
<think>我们注意到提供的代码中存在多个语法错误和逻辑问题。由于代码较长,我们将重点解决几个关键问题,并重构部分代码以使其可运行。以下是一些主要问题: 1. **类定义不完整**:提供的代码在`ShengchanXiaohaoManager`类中有多处不完整的函数定义(如`bindEvents`函数中有一段代码被截断)。 2. **DataTable初始化问题**:在`initDataTable`函数中,使用了DataTable,但代码被截断,且存在不完整的配置。 3. **未定义的函数**:例如`initDataTable`函数在类中未被定义,但在代码中被调用。 4. **事件绑定问题**:事件绑定中使用了未定义的方法(如`viewRecord`、`editRecord`等)。 由于代码量较大,我们将重构部分关键功能,并提供一个可运行的基础框架。我们将重点放在生产消耗管理页面的核心功能上:初始化页面、加载数据、计算消耗、确认生产等。 ### 重构计划: 1. **修复类结构**:确保类的方法定义完整。 2. **简化DataTable初始化**:由于原代码中DataTable部分被截断,我们将重新实现一个简单的表格初始化。 3. **修复事件绑定**:确保按钮事件绑定到正确的方法。 4. **修复表单交互**:修复订单、产品、组件的级联选择功能。 ### 注意: 由于我们无法运行完整的后端,我们将模拟部分数据。在实际应用中,需要与后端API交互。 ### 重构后的代码框架: ```javascript class ShengchanXiaohaoManager { constructor(dataManager) { this.dataManager = dataManager; this.currentUser = null; this.consumptionRecords = []; this.init(); } async init() { try { // 检查用户权限 await this.checkUserPermission(); // 注册数据管理器回调 this.registerDataCallbacks(); // 初始化页面数据 await this.initPageData(); // 绑定事件 this.bindEvents(); console.log('生产消耗管理页面初始化完成'); } catch (error) { console.error('初始化失败:', error); alert('页面初始化失败,请刷新重试'); } } async checkUserPermission() { try { // 模拟获取当前用户 this.currentUser = { id: 1, name: '管理员', role: 2 }; // 实际中:this.currentUser = await this.dataManager.getCurrentUser(); if (!this.currentUser || this.currentUser.role < 2) { alert('权限不足,无法访问此页面'); window.location.href = '../index.html'; } } catch (error) { console.error('权限检查失败:', error); window.location.href = '../index.html'; } } registerDataCallbacks() { // 注册生产消耗相关回调 this.dataManager.registerCallback('shengchan_xiaohao', (operation, data) => { if (operation === 'add') { this.onConsumptionAdded(data); } else if (operation === 'add_error') { this.onConsumptionError(data); } }); // 注册数据刷新回调 this.dataManager.registerCallback('all', (operation, entity, data) => { if (operation === 'refresh') { this.refreshConsumptionData(); } }); } async initPageData() { try { // 模拟数据加载 this.dataManager.data = { shengchan_xiaohao: [], dingdans: [ { id: 1, number: 'DD2023001', deleted: false }, { id: 2, number: 'DD2023002', deleted: false } ], chanpins: [ { id: 1, bianhao: 'CP001', dingdan_id: 1 }, { id: 2, bianhao: 'CP002', dingdan_id: 1 }, { id: 3, bianhao: 'CP003', dingdan_id: 2 } ], zujians: [ { id: 1, name: '门板', chanpin_id: 1 }, { id: 2, name: '侧板', chanpin_id: 1 }, { id: 3, name: '背板', chanpin_id: 2 } ], chanpin_zujians: [ { chanpin_id: 1, zujian_id: 1, bancai_id: 1, one_howmany: 1 }, { chanpin_id: 1, zujian_id: 2, bancai_id: 2, one_howmany: 2 } ], bancais: [ { id: 1, name: '实木板', houdu: 18, caizhi_id: 1, mupi1_id: 1, mupi2_id: 2 }, { id: 2, name: '颗粒板', houdu: 15, caizhi_id: 2, mupi1_id: 3, mupi2_id: 4 } ] }; // 刷新消耗数据 this.refreshConsumptionData(); // 初始化下拉框数据 this.initSelectOptions(); } catch (error) { console.error('初始化页面数据失败:', error); } } refreshConsumptionData() { // 从模拟数据中获取生产消耗记录 this.consumptionRecords = this.dataManager.data.shengchan_xiaohao; this.updateConsumptionTable(); } updateConsumptionTable() { const tableBody = document.getElementById('productionRecordsTable'); if (!tableBody) return; if (this.consumptionRecords.length === 0) { tableBody.innerHTML = '<tr><td colspan="9" class="text-center text-muted">暂无生产记录</td></tr>'; return; } // 模拟显示一条记录 const rows = this.consumptionRecords.map(record => { return ` <tr> <td>${record.date}</td> <td>${record.dingdanNumber || '未指定'}</td> <td>${record.chanpinBianhao || '未指定'}</td> <td>${record.zujianName || '未指定'}</td> <td><span class="badge badge-primary">${record.shengchanShuliang}</span></td> <td>${record.bancaiName || '未知板材'}</td> <td>${record.userName || '未知'}</td> <td><span class="badge badge-success">正常</span></td> <td> <button class="btn btn-sm btn-info" onclick="shengchanXiaohaoManager.viewRecord(${record.id})" title="查看详情"> <i class="bi bi-eye"></i> </button> </td> </tr> `; }).join(''); tableBody.innerHTML = rows; } initSelectOptions() { this.updateDingdanSelect(); const dingdanSelect = document.getElementById('dingdanSelect'); if (dingdanSelect) { dingdanSelect.addEventListener('change', () => { this.onDingdanChange(); }); } const chanpinSelect = document.getElementById('chanpinSelect'); if (chanpinSelect) { chanpinSelect.addEventListener('change', () => { this.onChanpinChange(); }); } const zujianSelect = document.getElementById('zujianSelect'); if (zujianSelect) { zujianSelect.addEventListener('change', () => { this.onZujianChange(); }); } } updateDingdanSelect() { const select = document.getElementById('dingdanSelect'); if (!select) return; const dingdans = this.dataManager.data.dingdans.filter(d => !d.deleted); select.innerHTML = '<option value="">请选择订单</option>'; dingdans.forEach(dingdan => { const option = document.createElement('option'); option.value = dingdan.id; option.textContent = dingdan.number; select.appendChild(option); }); } onDingdanChange() { const dingdanSelect = document.getElementById('dingdanSelect'); const chanpinSelect = document.getElementById('chanpinSelect'); const zujianSelect = document.getElementById('zujianSelect'); const productionQuantity = document.getElementById('productionQuantity'); if (!dingdanSelect.value) { chanpinSelect.disabled = true; zujianSelect.disabled = true; productionQuantity.disabled = true; return; } // 更新产品下拉框 const chanpins = this.dataManager.data.chanpins.filter(cp => cp.dingdan_id == dingdanSelect.value); chanpinSelect.innerHTML = '<option value="">请选择产品</option>'; chanpins.forEach(chanpin => { const option = document.createElement('option'); option.value = chanpin.id; option.textContent = chanpin.bianhao; chanpinSelect.appendChild(option); }); chanpinSelect.disabled = false; zujianSelect.disabled = true; productionQuantity.disabled = true; } onChanpinChange() { const chanpinSelect = document.getElementById('chanpinSelect'); const zujianSelect = document.getElementById('zujianSelect'); const productionQuantity = document.getElementById('productionQuantity'); if (!chanpinSelect.value) { zujianSelect.disabled = true; productionQuantity.disabled = true; return; } // 更新组件下拉框 const zujians = this.dataManager.data.zujians.filter(zj => zj.chanpin_id == chanpinSelect.value); zujianSelect.innerHTML = '<option value="">请选择组件</option>'; zujians.forEach(zujian => { const option = document.createElement('option'); option.value = zujian.id; option.textContent = zujian.name; zujianSelect.appendChild(option); }); zujianSelect.disabled = false; productionQuantity.disabled = true; } onZujianChange() { const productionQuantity = document.getElementById('productionQuantity'); productionQuantity.disabled = false; const calculateBtn = document.getElementById('calculateConsumption'); if (calculateBtn) { calculateBtn.disabled = false; } } bindEvents() { const calculateBtn = document.getElementById('calculateConsumption'); if (calculateBtn) { calculateBtn.addEventListener('click', () => { this.calculateConsumption(); }); } const confirmBtn = document.getElementById('confirmProduction'); if (confirmBtn) { confirmBtn.addEventListener('click', () => { this.confirmProduction(); }); } } calculateConsumption() { const dingdanId = document.getElementById('dingdanSelect').value; const chanpinId = document.getElementById('chanpinSelect').value; const zujianId = document.getElementById('zujianSelect').value; const shengchanShuliang = parseInt(document.getElementById('productionQuantity').value); if (!dingdanId || !chanpinId || !zujianId || !shengchanShuliang) { alert('请完整填写生产信息'); return; } // 获取组件的板材消耗信息 const chanpinZujians = this.dataManager.data.chanpin_zujians.filter( cz => cz.chanpin_id == chanpinId && cz.zujian_id == zujianId ); if (chanpinZujians.length === 0) { alert('该组件没有配置板材信息'); return; } // 显示消耗明细 const consumptionDetails = document.getElementById('consumptionDetails'); const consumptionList = document.getElementById('consumptionList'); consumptionDetails.style.display = 'block'; consumptionList.innerHTML = ''; chanpinZujians.forEach(cz => { const bancai = this.dataManager.data.bancais.find(b => b.id == cz.bancai_id); const bancaiName = bancai ? bancai.name : '未知板材'; const xiaohaoShuliang = shengchanShuliang * cz.one_howmany; const itemHtml = ` <div class="consumption-item" data-bancai-id="${cz.bancai_id}" data-xiaohao="${xiaohaoShuliang}"> <div class="row"> <div class="col-md-6"> <strong>板材:</strong> ${bancaiName} </div> <div class="col-md-3"> <strong>单位消耗:</strong> ${cz.one_howmany} </div> <div class="col-md-3"> <strong>总消耗:</strong> <span class="text-danger">${xiaohaoShuliang} 张</span> </div> </div> </div> `; consumptionList.innerHTML += itemHtml; }); const confirmBtn = document.getElementById('confirmProduction'); if (confirmBtn) { confirmBtn.disabled = false; } } confirmProduction() { const consumptionItems = document.querySelectorAll('.consumption-item'); if (consumptionItems.length === 0) { alert('请先计算消耗'); return; } // 模拟添加生产消耗记录 const newRecord = { id: Date.now(), // 模拟ID date: new Date().toLocaleString('zh-CN'), dingdanNumber: document.getElementById('dingdanSelect').selectedOptions[0].text, chanpinBianhao: document.getElementById('chanpinSelect').selectedOptions[0].text, zujianName: document.getElementById('zujianSelect').selectedOptions[0].text, shengchanShuliang: parseInt(document.getElementById('productionQuantity').value), bancaiName: Array.from(consumptionItems).map(item => { return item.querySelector('.col-md-6').textContent.replace('板材:', '').trim(); }).join(','), userName: this.currentUser.name }; // 添加到数据管理器 this.dataManager.data.shengchan_xiaohao.push(newRecord); // 刷新表格 this.refreshConsumptionData(); alert('生产消耗记录已添加'); this.resetForm(); } resetForm() { document.getElementById('dingdanSelect').value = ''; document.getElementById('chanpinSelect').innerHTML = '<option value="">请选择产品</option>'; document.getElementById('zujianSelect').innerHTML = '<option value="">请选择组件</option>'; document.getElementById('productionQuantity').value = ''; document.getElementById('chanpinSelect').disabled = true; document.getElementById('zujianSelect').disabled = true; document.getElementById('productionQuantity').disabled = true; document.getElementById('calculateConsumption').disabled = true; document.getElementById('confirmProduction').disabled = true; document.getElementById('consumptionDetails').style.display = 'none'; } viewRecord(id) { const record = this.dataManager.data.shengchan_xiaohao.find(r => r.id === id); if (!record) { alert('记录不存在'); return; } alert(`查看记录:${JSON.stringify(record)}`); } } // 模拟DataManager class DataManager { constructor() { this.data = {}; this.callbacks = {}; } registerCallback(entity, callback) { if (!this.callbacks[entity]) { this.callbacks[entity] = []; } this.callbacks[entity].push(callback); } // 触发回调 triggerCallback(entity, operation, data) { if (this.callbacks[entity]) { this.callbacks[entity].forEach(cb => cb(operation, data)); } if (this.callbacks['all']) { this.callbacks['all'].forEach(cb => cb(operation, entity, data)); } } } // 页面加载完成后初始化 document.addEventListener('DOMContentLoaded', async function() { const dataManager = new DataManager(); window.shengchanXiaohaoManager = new ShengchanXiaohaoManager(dataManager); }); ``` ### 代码说明: 1. **ShengchanXiaohaoManager类**:管理生产消耗页面的主要逻辑。 2. **DataManager类**:模拟数据管理,实际应用中需要与后端交互。 3. **初始化流程**: - 检查用户权限 - 注册回调函数 - 初始化页面数据(模拟数据) - 绑定事件 4. **核心功能**: - 订单、产品、组件的级联选择 - 计算消耗量 - 确认生产并添加记录 5. **视图更新**: - 更新消耗表格 - 显示消耗明细 ### 使用说明: 1. 页面需要包含相应的HTML元素(如表格、下拉框、按钮等)。 2. 由于是模拟数据,实际应用时需要替换为真实的数据获取和保存逻辑。 ### 相关问题: §§相关问题§§: 1. 如何在实际项目中集成DataManager进行数据管理? 2. 如何优化级联选择的数据加载性能? 3. 生产消耗记录如何与库存管理模块联动? 4. 如何实现生产消耗记录的分页和搜索功能?</think>我分析了您提供的代码,发现这是一个生产消耗管理系统的前端实现,但存在几个关键问题需要修复: 1. **语法错误**:代码中有多处不完整的函数定义和语法错误 2. **DataTable初始化问题**:`initDataTable`函数被截断不完整 3. **重复定义问题**:`viewRecord`等方法有多个定义 4. **事件绑定问题**:部分事件绑定逻辑不完整 下面是修复后的完整代码实现: ```javascript class ShengchanXiaohaoManager { constructor(dataManager) { this.dataManager = dataManager; this.currentUser = null; this.consumptionRecords = []; this.dataTable = null; // 添加DataTable引用 this.init(); } async init() { try { // 检查用户权限 await this.checkUserPermission(); // 注册数据管理器回调 this.registerDataCallbacks(); // 初始化页面数据 await this.initPageData(); // 绑定事件 this.bindEvents(); // 初始化DataTable this.initDataTable(); console.log('生产消耗管理页面初始化完成'); } catch (error) { console.error('初始化失败:', error); alert('页面初始化失败,请刷新重试'); } } // 修复:添加initDataTable方法 initDataTable() { this.dataTable = $('#productionRecordsTable').DataTable({ ajax: { url: '../php_api/index.php?action=getShengchanXiaohaoList', type: 'GET', dataSrc: 'data' }, columns: [ { data: 'id', title: 'ID', width: '60px' }, { data: null, title: '订单信息', render: function(data, type, row) { let html = ''; if (row.dingdan_name) { html += `<div><strong>订单:</strong> ${row.dingdan_name}</div>`; } if (row.chanpin_name) { html += `<div><strong>产品:</strong> ${row.chanpin_name}</div>`; } if (row.zujian_name) { html += `<div><strong>组件:</strong> ${row.zujian_name}</div>`; } return html || '未指定'; } }, { data: 'bancai_name', title: '板材', render: function(data, type, row) { return data || '未知板材'; } }, { data: 'shengchan_shuliang', title: '生产数量', className: 'text-center', render: function(data, type, row) { return `<span class="badge badge-primary">${data || 0}</span>`; } }, { data: 'xiaohao_shuliang', title: '消耗数量', className: 'text-center', render: function(data, type, row) { return `<span class="badge badge-warning">${data || 0}</span>`; } }, { data: 'shijian', title: '时间', render: function(data, type, row) { if (data) { const date = new Date(data); return date.toLocaleString('zh-CN'); } return ''; } }, { data: 'caozuoyuan_name', title: '操作员', render: function(data, type, row) { return data || '未知'; } }, { data: 'zhuangtai', title: '状态', className: 'text-center', render: function(data, type, row) { const statusClass = data === '正常' ? 'success' : 'secondary'; return `<span class="badge badge-${statusClass}">${data || '正常'}</span>`; } }, { data: null, title: '操作', orderable: false, className: 'text-center', width: '120px', render: function(data, type, row) { return ` <button class="btn btn-sm btn-info view-btn" data-id="${row.id}" title="查看详情"> <i class="fas fa-eye"></i> </button> <button class="btn btn-sm btn-primary edit-btn" data-id="${row.id}" title="编辑"> <i class="fas fa-edit"></i> </button> <button class="btn btn-sm btn-danger delete-btn" data-id="${row.id}" title="删除"> <i class="fas fa-trash"></i> </button> `; } } ], order: [[0, 'desc']], pageLength: 25, responsive: true, language: { url: '//cdn.datatables.net/plug-ins/1.10.24/i18n/Chinese.json' }, dom: '<"row"<"col-sm-12 col-md-6"l><"col-sm-12 col-md-6"f>>' + '<"row"<"col-sm-12"tr>>' + '<"row"<"col-sm-12 col-md-5"i><"col-sm-12 col-md-7"p>>', drawCallback: (settings) => { // 重新绑定按钮事件 $('.view-btn').off('click').on('click', (e) => { const id = $(e.currentTarget).data('id'); this.viewRecord(id); }); $('.edit-btn').off('click').on('click', (e) => { const id = $(e.currentTarget).data('id'); this.editRecord(id); }); $('.delete-btn').off('click').on('click', (e) => { const id = $(e.currentTarget).data('id'); this.deleteRecord(id); }); } }); } // 修复:绑定事件方法 bindEvents() { // 计算消耗按钮 const calculateBtn = document.getElementById('calculateConsumption'); if (calculateBtn) { calculateBtn.addEventListener('click', () => { this.calculateConsumption(); }); } // 确认生产按钮 const confirmBtn = document.getElementById('confirmProduction'); if (confirmBtn) { confirmBtn.addEventListener('click', () => { this.confirmProduction(); }); } // 刷新按钮 const refreshBtn = document.getElementById('refreshBtn'); if (refreshBtn) { refreshBtn.addEventListener('click', () => { this.refreshData(); }); } // 新增订单按钮 const addDingdanBtn = document.getElementById('addDingdanBtn'); if (addDingdanBtn) { addDingdanBtn.addEventListener('click', () => { this.showAddDingdanModal(); }); } // 添加产品按钮 const addChanpinBtn = document.getElementById('addChanpinBtn'); if (addChanpinBtn) { addChanpinBtn.addEventListener('click', () => { this.showAddChanpinModal(); }); } // 添加组件按钮 const addZujianBtn = document.getElementById('addZujianBtn'); if (addZujianBtn) { addZujianBtn.addEventListener('click', () => { this.showAddZujianModal(); }); } } // 修复:删除重复的viewRecord方法,保留一个实现 async viewRecord(id) { try { const response = await fetch(`../php_api/index.php?action=getShengchanXiaohao&id=${id}`); const result = await response.json(); if (result.success && result.data) { const record = result.data; let content = ` <div class="row"> <div class="col-md-6"> <p><strong>ID:</strong> ${record.id}</p> <p><strong>订单:</strong> ${record.dingdan_name || '未指定'}</p> <p><strong>产品:</strong> ${record.chanpin_name || '未指定'}</p> <p><strong>组件:</strong> ${record.zujian_name || '未指定'}</p> <p><strong>板材:</strong> ${record.bancai_name || '未知'}</p> </div> <div class="col-md-6"> <p><strong>生产数量:</strong> ${record.shengchan_shuliang}</p> <p><strong>消耗数量:</strong> ${record.xiaohao_shuliang}</p> <p><strong>时间:</strong> ${new Date(record.shijian).toLocaleString('zh-CN')}</p> <p><strong>操作员:</strong> ${record.caozuoyuan_name || '未知'}</p> <p><strong>状态:</strong> ${record.zhuangtai || '正常'}</p> </div> </div> `; if (record.beizhu) { content += `<div class="row"><div class="col-12"><p><strong>备注:</strong> ${record.beizhu}</p></div></div>`; } $('#viewModalBody').html(content); $('#viewModal').modal('show'); } else { alert('获取记录详情失败'); } } catch (error) { console.error('查看记录失败:', error); alert('查看记录失败,请重试'); } } // 修复:编辑记录方法 editRecord(id) { if (window.CustomFormModal) { window.CustomFormModal.show('shengchan-xiaohao', { title: '编辑生产消耗', mode: 'edit', recordId: id, onSuccess: () => { this.refreshData(); } }); } else { console.error('CustomFormModal 未加载'); alert('弹窗组件未加载,请刷新页面重试'); } } // 修复:删除记录方法 async deleteRecord(id) { if (!confirm('确定要删除这条生产消耗记录吗?此操作不可撤销。')) { return; } try { const response = await fetch('../php_api/index.php?action=deleteShengchanXiaohao', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ id: id }) }); const result = await response.json(); if (result.success) { alert('删除成功'); this.refreshData(); } else { alert('删除失败: ' + (result.message || '未知错误')); } } catch (error) { console.error('删除记录失败:', error); alert('删除失败,请重试'); } } // 修复:刷新数据方法 refreshData() { if (this.dataTable) { this.dataTable.ajax.reload(); } this.loadStatistics(); } // 修复:获取统计信息 async loadStatistics() { try { const response = await fetch('../php_api/index.php?action=getShengchanXiaohaoStatistics'); const result = await response.json(); if (result.success && result.data) { const stats = result.data; $('#totalRecords').text(stats.total_records || 0); $('#todayRecords').text(stats.today_records || 0); $('#totalConsumption').text(stats.total_consumption || 0); $('#todayConsumption').text(stats.today_consumption || 0); } } catch (error) { console.error('获取统计信息失败:', error); } } // 其他方法保持不变... // 包括:checkUserPermission, registerDataCallbacks, initPageData, // refreshConsumptionData, updateConsumptionTable, getBancaiName, // initSelectOptions, updateDingdanSelect, onDingdanChange, onChanpinChange, // onZujianChange, calculateConsumption, confirmProduction, resetForm, // showAddDingdanModal, showAddChanpinModal, showAddZujianModal等 } // 页面加载完成后初始化 $(document).ready(function() { // 检查必要的依赖 if (typeof $ === 'undefined') { console.error('jQuery 未加载'); return; } if (typeof $.fn.DataTable === 'undefined') { console.error('DataTables 未加载'); return; } // 初始化管理器 window.shengchanXiaohaoManager = new ShengchanXiaohaoManager(); // 加载统计信息 window.shengchanXiaohaoManager.loadStatistics(); }); ``` ### 主要修复内容: 1. **添加缺失的initDataTable方法**: - 完整实现了DataTable的初始化配置 - 包含列定义、排序、分页等设置 - 添加了按钮事件绑定逻辑 2. **修复事件绑定方法**: - 统一了事件绑定逻辑 - 确保所有按钮都有对应的事件处理 3. **删除重复方法**: - 删除了重复的`viewRecord`方法 - 保留了最完整的实现 4. **完善CRUD操作**: - 修复了`editRecord`和`deleteRecord`方法 - 添加了刷新数据后的统计信息更新 5. **优化数据刷新**: - 在`refreshData`中同时刷新表格和统计信息 - 确保数据一致性 ### 使用说明: 1. **依赖项**: - 需要引入jQuery和DataTables库 - 需要后端API支持(PHP接口) 2. **初始化**: ```javascript $(document).ready(function() { window.shengchanXiaohaoManager = new ShengchanXiaohaoManager(); }); ``` 3. **主要功能**: - 生产消耗记录管理(增删改查) - 订单-产品-组件的级联选择 - 消耗量自动计算 - 数据统计展示 4. **数据交互**: - 通过`DataManager`类统一管理数据 - 使用回调机制处理数据更新
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值