diff --git a/check_total_amount.py b/check_total_amount.py deleted file mode 100644 index 75e6a1f..0000000 --- a/check_total_amount.py +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -检查对账单含税金额是否正确更新 -""" - -import sqlite3 -import sys -import os - -def check_total_amount(): - """检查含税金额更新情况""" - - # 连接数据库 - conn = sqlite3.connect('server/data.db') - c = conn.cursor() - - print("=== 检查对账单含税金额更新情况 ===\n") - - # 查询所有对账单记录 - c.execute('SELECT id, contract_no, material_name, quantity, unit_price, total_amount FROM reconciliations ORDER BY id DESC LIMIT 20') - records = c.fetchall() - - print("最近20条对账单记录:") - print("-" * 80) - print(f"{'ID':<5} {'合同号':<15} {'物料名称':<30} {'数量':<8} {'单价':<8} {'含税金额':<10} {'应计算金额':<10}") - print("-" * 80) - - incorrect_count = 0 - for record in records: - recon_id, contract_no, material_name, quantity, unit_price, total_amount = record - - # 计算应有的含税金额 - calculated_amount = quantity * unit_price - - # 检查是否一致(考虑浮点数精度) - if abs(total_amount - calculated_amount) > 0.01: - incorrect_count += 1 - status = "❌" - else: - status = "✓" - - print(f"{recon_id:<5} {contract_no:<15} {material_name[:28]:<30} {quantity:<8} {unit_price:<8} {total_amount:<10} {calculated_amount:<10} {status}") - - print("-" * 80) - print(f"\n发现 {incorrect_count} 条记录的含税金额不正确") - - # 修复不正确的记录 - if incorrect_count > 0: - print("\n正在修复不正确的记录...") - c.execute('SELECT id, quantity, unit_price FROM reconciliations') - all_records = c.fetchall() - - fixed_count = 0 - for record in all_records: - recon_id, quantity, unit_price = record - correct_amount = quantity * unit_price - - # 更新含税金额 - c.execute('UPDATE reconciliations SET total_amount=? WHERE id=?', (correct_amount, recon_id)) - fixed_count += 1 - - conn.commit() - print(f"已修复 {fixed_count} 条记录的含税金额") - - # 测试刷新单价功能 - print("\n\n=== 测试刷新单价功能 ===") - - # 找一个有客户订单的合同号进行测试 - c.execute("SELECT DISTINCT contract_no FROM reconciliations LIMIT 1") - test_contract = c.fetchone() - - if test_contract: - test_contract_no = test_contract[0] - print(f"测试合同号: {test_contract_no}") - - # 查看该合同号的对账单记录 - c.execute('SELECT id, material_name, unit_price, total_amount, quantity FROM reconciliations WHERE contract_no=?', (test_contract_no,)) - test_records = c.fetchall() - - print("\n刷新前的记录:") - for record in test_records: - recon_id, material_name, unit_price, total_amount, quantity = record - print(f" ID={recon_id}, 物料={material_name[:30]}..., 单价={unit_price}, 金额={total_amount}, 数量={quantity}") - - # 模拟刷新单价(这里只是检查逻辑) - print("\n注意:实际的刷新单价功能需要通过API调用") - - conn.close() - - print("\n=== 建议检查事项 ===") - print("1. 确认后端刷新单价的SQL语句是否正确") - print("2. 检查前端是否正确调用了calculateTotal函数") - print("3. 验证数据库中的total_amount字段是否被正确更新") - print("4. 查看浏览器控制台是否有JavaScript错误") - -if __name__ == '__main__': - check_total_amount() diff --git a/frontend/assets/styles.css b/frontend/assets/styles.css index 106eba2..3e95478 100644 --- a/frontend/assets/styles.css +++ b/frontend/assets/styles.css @@ -1869,7 +1869,58 @@ input[type="date"]::-webkit-calendar-picker-indicator:hover{ .filter-actions{display:flex;gap:8px;align-items:flex-end} .filter-actions .btn{padding:10px 20px;font-size:14px} -.table-container{background:var(--surface);border:1px solid var(--border);border-radius:12px;overflow:auto;margin-bottom:20px;max-height:calc(100vh - 280px)} +/* 表格容器滚动条样式 - 重新设计 */ +.table-container { + background: var(--surface); + border: 1px solid var(--border); + border-radius: 12px; + overflow: scroll; + margin-bottom: 20px; + max-height: calc(100vh - 280px); + /* 为滚动条预留空间,防止布局跳动 */ + padding-right: 8px; + padding-bottom: 8px; +} + +/* 滚动条整体样式 */ +.table-container::-webkit-scrollbar { + width: 14px; + height: 14px; + background: transparent; +} + +/* 滚动条轨道 */ +.table-container::-webkit-scrollbar-track { + background: var(--surface-2); + border-radius: 7px; + border: 1px solid var(--border); +} + +/* 滚动条滑块 */ +.table-container::-webkit-scrollbar-thumb { + background: var(--primary); + border-radius: 7px; + border: 2px solid var(--surface-2); + /* 确保滑块始终可见 */ + min-height: 20px; + min-width: 20px; +} + +/* 滑块悬停效果 */ +.table-container::-webkit-scrollbar-thumb:hover { + background: var(--primary-dark); +} + +/* 滑块激活效果 */ +.table-container::-webkit-scrollbar-thumb:active { + background: var(--primary-darker); +} + +/* 滚动条角落 */ +.table-container::-webkit-scrollbar-corner { + background: var(--surface-2); + border: 1px solid var(--border); +} .data-table{width:100%;border-collapse:collapse;font-size:13px} .data-table thead{background:var(--surface-2);position:sticky;top:0;z-index:1} .data-table th{padding:12px 16px;text-align:left;font-weight:600;color:var(--text);border-bottom:2px solid var(--border);white-space:nowrap} @@ -1988,9 +2039,52 @@ input[type="date"]::-webkit-calendar-picker-indicator:hover{ background: var(--surface); border: 1px solid var(--border); border-radius: 12px; - overflow: auto; + overflow: scroll; margin-bottom: 20px; max-height: calc(100vh - 250px); + /* 为滚动条预留空间,防止布局跳动 */ + padding-right: 8px; + padding-bottom: 8px; +} + +/* 滚动条整体样式 */ +.table-container::-webkit-scrollbar { + width: 14px; + height: 14px; + background: transparent; +} + +/* 滚动条轨道 */ +.table-container::-webkit-scrollbar-track { + background: var(--surface-2); + border-radius: 7px; + border: 1px solid var(--border); +} + +/* 滚动条滑块 */ +.table-container::-webkit-scrollbar-thumb { + background: var(--primary); + border-radius: 7px; + border: 2px solid var(--surface-2); + /* 确保滑块始终可见 */ + min-height: 20px; + min-width: 20px; +} + +/* 滑块悬停效果 */ +.table-container::-webkit-scrollbar-thumb:hover { + background: var(--primary-dark); +} + +/* 滑块激活效果 */ +.table-container::-webkit-scrollbar-thumb:active { + background: var(--primary-darker); +} + +/* 滚动条角落 */ +.table-container::-webkit-scrollbar-corner { + background: var(--surface-2); + border: 1px solid var(--border); } .data-table { diff --git a/frontend/index.html b/frontend/index.html index 131e751..7784c3a 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -114,6 +114,7 @@
详细记录查询 汇总信息查询 + 审计查询
@@ -145,7 +146,6 @@
- BOM物料清单 期初库存 采购需求清单 客户订单 @@ -307,6 +307,7 @@ + @@ -315,6 +316,7 @@ + @@ -324,7 +326,7 @@ - + diff --git a/frontend/js/api.js b/frontend/js/api.js index aba98d7..ea322b9 100644 --- a/frontend/js/api.js +++ b/frontend/js/api.js @@ -107,53 +107,11 @@ const API = (() => { xhr.send(formData); }); } - // 存储当前的toast定时器 -let toastTimer = null; - -function toast(msg, type = 'info', duration = 2000) { + function toast(msg) { const t = document.getElementById('toast'); - - // 清除之前的定时器 - if (toastTimer) { - clearTimeout(toastTimer); - toastTimer = null; - } - t.textContent = msg; - - // 添加类型样式 - if (type === 'success') { - t.style.backgroundColor = '#10b981'; - t.style.color = 'white'; - } else if (type === 'error') { - t.style.backgroundColor = '#ef4444'; - t.style.color = 'white'; - } else if (type === 'warning') { - t.style.backgroundColor = '#f59e0b'; - t.style.color = 'white'; - } else { - t.style.backgroundColor = '#3b82f6'; - t.style.color = 'white'; - } - - // 支持多行文本 - t.style.whiteSpace = 'pre-line'; - - // 添加show类来显示toast t.classList.add('show'); - - // 调试信息 - console.log(`Toast显示: 类型=${type}, 持续时间=${duration}ms, 消息长度=${msg.length}`); - - toastTimer = setTimeout(() => { - t.classList.remove('show'); - // 重置样式 - t.style.backgroundColor = ''; - t.style.color = ''; - t.style.whiteSpace = ''; - toastTimer = null; - console.log('Toast已隐藏'); - }, duration); + setTimeout(() => t.classList.remove('show'), 2000); } return { // 通用HTTP方法 diff --git a/frontend/js/components/customer-order.js b/frontend/js/components/customer-order.js index b7ee158..81f9647 100644 --- a/frontend/js/components/customer-order.js +++ b/frontend/js/components/customer-order.js @@ -227,10 +227,36 @@ } let materialRowIndex = 0; + let productList = []; // 缓存BOM产品列表 + + async function loadProductList() { + try { + const res = await fetch('/api/bom/products'); + const data = await res.json(); + productList = (data.list || []).map(p => p.product_name).filter(Boolean); + // 同时从已有订单中提取物料名称(去重) + const orderRes = await fetch('/api/customer-orders'); + const orderData = await orderRes.json(); + if (orderData.list) { + for (const o of orderData.list) { + if (o.material && !productList.includes(o.material)) { + productList.push(o.material); + } + } + } + } catch (e) { + console.error('加载产品列表失败:', e); + } + } + + function buildMaterialOptions() { + return productList.map(name => `