修复发货记录页面看不到底部按钮
This commit is contained in:
parent
a12f769f15
commit
8edea28f69
@ -43,7 +43,7 @@ body{margin:0;background:var(--bg);color:var(--text);font-family:Inter,system-ui
|
|||||||
[data-theme="light"] .content-header{background:#f5f7fa !important}
|
[data-theme="light"] .content-header{background:#f5f7fa !important}
|
||||||
#breadcrumb{color:var(--text-2)}
|
#breadcrumb{color:var(--text-2)}
|
||||||
#actions{position:relative;z-index:999;display:flex;align-items:center;gap:8px}
|
#actions{position:relative;z-index:999;display:flex;align-items:center;gap:8px}
|
||||||
.view{position:relative;padding:20px;flex:1;overflow-y:auto;overflow-x:hidden;background:var(--bg);min-height:100%}
|
.view{position:relative;padding:20px;flex:1;overflow-y:auto;overflow-x:hidden;background:var(--bg);min-height:0}
|
||||||
.card{background:var(--surface-2);border:1px solid var(--border);border-radius:12px;padding:16px}
|
.card{background:var(--surface-2);border:1px solid var(--border);border-radius:12px;padding:16px}
|
||||||
.grid{display:grid;gap:12px}
|
.grid{display:grid;gap:12px}
|
||||||
.grid.cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}
|
.grid.cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}
|
||||||
|
|||||||
@ -128,6 +128,7 @@
|
|||||||
<td>${order.quantity || 0}</td>
|
<td>${order.quantity || 0}</td>
|
||||||
<td>${order.unit_price || 0}</td>
|
<td>${order.unit_price || 0}</td>
|
||||||
<td>
|
<td>
|
||||||
|
<button class="btn-text" onclick="window.CustomerOrder.editOrder(${order.id})">编辑</button>
|
||||||
<button class="btn-text btn-danger" onclick="window.CustomerOrder.deleteOrder(${order.id})">删除</button>
|
<button class="btn-text btn-danger" onclick="window.CustomerOrder.deleteOrder(${order.id})">删除</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -190,22 +191,41 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let currentEditId = null;
|
||||||
|
|
||||||
function openModal(order = null) {
|
function openModal(order = null) {
|
||||||
const modal = document.getElementById('order-modal');
|
const modal = document.getElementById('order-modal');
|
||||||
const title = document.getElementById('modal-title');
|
const title = document.getElementById('modal-title');
|
||||||
|
|
||||||
title.textContent = '新增订单';
|
// 清空物料列表
|
||||||
document.getElementById('order-form').reset();
|
|
||||||
|
|
||||||
// 设置默认日期为今天
|
|
||||||
const today = new Date().toISOString().split('T')[0];
|
|
||||||
document.getElementById('order-date').value = today;
|
|
||||||
|
|
||||||
// 清空物料列表并添加一行
|
|
||||||
const container = document.getElementById('materials-container');
|
const container = document.getElementById('materials-container');
|
||||||
container.innerHTML = '';
|
container.innerHTML = '';
|
||||||
materialRowIndex = 0;
|
materialRowIndex = 0;
|
||||||
addMaterialRow();
|
|
||||||
|
if (order) {
|
||||||
|
// 编辑模式
|
||||||
|
title.textContent = '编辑订单';
|
||||||
|
currentEditId = order.id;
|
||||||
|
|
||||||
|
document.getElementById('order-date').value = order.order_date || '';
|
||||||
|
document.getElementById('order-no').value = order.order_no || '';
|
||||||
|
document.getElementById('customer-name').value = order.customer_name || '';
|
||||||
|
|
||||||
|
// 添加物料信息
|
||||||
|
addMaterialRow(order.material || '', order.quantity || '', order.unit_price || '');
|
||||||
|
} else {
|
||||||
|
// 新增模式
|
||||||
|
title.textContent = '新增订单';
|
||||||
|
currentEditId = null;
|
||||||
|
document.getElementById('order-form').reset();
|
||||||
|
|
||||||
|
// 设置默认日期为今天
|
||||||
|
const today = new Date().toISOString().split('T')[0];
|
||||||
|
document.getElementById('order-date').value = today;
|
||||||
|
|
||||||
|
// 添加一行空物料
|
||||||
|
addMaterialRow();
|
||||||
|
}
|
||||||
|
|
||||||
modal.style.display = 'flex';
|
modal.style.display = 'flex';
|
||||||
}
|
}
|
||||||
@ -270,11 +290,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 为每个物料创建一条订单记录
|
if (currentEditId) {
|
||||||
let successCount = 0;
|
// 编辑模式:只能编辑单条记录
|
||||||
for (const mat of materials) {
|
if (materials.length !== 1) {
|
||||||
const res = await fetch('/api/customer-orders', {
|
API.toast('编辑模式下只能有一个物料', 'error');
|
||||||
method: 'POST',
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mat = materials[0];
|
||||||
|
const res = await fetch(`/api/customer-orders/${currentEditId}`, {
|
||||||
|
method: 'PUT',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
order_date: orderDate,
|
order_date: orderDate,
|
||||||
@ -289,22 +314,49 @@
|
|||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
|
|
||||||
if (res.ok && data.ok) {
|
if (res.ok && data.ok) {
|
||||||
successCount++;
|
API.toast('更新成功', 'success');
|
||||||
|
closeModal();
|
||||||
|
await loadOrders();
|
||||||
} else {
|
} else {
|
||||||
console.error('保存物料失败:', mat.material, data.error);
|
API.toast(data.error || '更新失败', 'error');
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (successCount === materials.length) {
|
|
||||||
API.toast(`订单保存成功,共 ${successCount} 个物料`, 'success');
|
|
||||||
closeModal();
|
|
||||||
await loadOrders();
|
|
||||||
} else if (successCount > 0) {
|
|
||||||
API.toast(`部分保存成功(${successCount}/${materials.length})`, 'warning');
|
|
||||||
closeModal();
|
|
||||||
await loadOrders();
|
|
||||||
} else {
|
} else {
|
||||||
API.toast('保存失败', 'error');
|
// 新增模式:为每个物料创建一条订单记录
|
||||||
|
let successCount = 0;
|
||||||
|
for (const mat of materials) {
|
||||||
|
const res = await fetch('/api/customer-orders', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({
|
||||||
|
order_date: orderDate,
|
||||||
|
order_no: orderNo,
|
||||||
|
customer_name: customerName,
|
||||||
|
material: mat.material,
|
||||||
|
quantity: mat.quantity,
|
||||||
|
unit_price: mat.unit_price
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await res.json();
|
||||||
|
|
||||||
|
if (res.ok && data.ok) {
|
||||||
|
successCount++;
|
||||||
|
} else {
|
||||||
|
console.error('保存物料失败:', mat.material, data.error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (successCount === materials.length) {
|
||||||
|
API.toast(`订单保存成功,共 ${successCount} 个物料`, 'success');
|
||||||
|
closeModal();
|
||||||
|
await loadOrders();
|
||||||
|
} else if (successCount > 0) {
|
||||||
|
API.toast(`部分保存成功(${successCount}/${materials.length})`, 'warning');
|
||||||
|
closeModal();
|
||||||
|
await loadOrders();
|
||||||
|
} else {
|
||||||
|
API.toast('保存失败', 'error');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('保存订单失败:', err);
|
console.error('保存订单失败:', err);
|
||||||
@ -336,11 +388,30 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function editOrder(id) {
|
||||||
|
try {
|
||||||
|
const res = await fetch('/api/customer-orders');
|
||||||
|
const data = await res.json();
|
||||||
|
|
||||||
|
const order = data.list.find(o => o.id === id);
|
||||||
|
if (!order) {
|
||||||
|
API.toast('订单不存在', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
openModal(order);
|
||||||
|
} catch (err) {
|
||||||
|
console.error('加载订单失败:', err);
|
||||||
|
API.toast('加载失败', 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 暴露给全局
|
// 暴露给全局
|
||||||
window.CustomerOrder = {
|
window.CustomerOrder = {
|
||||||
openModal,
|
openModal,
|
||||||
closeModal,
|
closeModal,
|
||||||
saveOrder,
|
saveOrder,
|
||||||
|
editOrder,
|
||||||
deleteOrder,
|
deleteOrder,
|
||||||
addMaterialRow,
|
addMaterialRow,
|
||||||
removeMaterialRow
|
removeMaterialRow
|
||||||
|
|||||||
@ -23,14 +23,12 @@ orders_data = [
|
|||||||
# 2025/4/28 - CGDD001695
|
# 2025/4/28 - CGDD001695
|
||||||
{'order_date': '2025-04-28', 'order_no': 'CGDD001695', 'customer_name': '易泰勒', 'material': 'ETAP05\n基站-5.0\nETAP05', 'quantity': 950, 'unit_price': 315.19},
|
{'order_date': '2025-04-28', 'order_no': 'CGDD001695', 'customer_name': '易泰勒', 'material': 'ETAP05\n基站-5.0\nETAP05', 'quantity': 950, 'unit_price': 315.19},
|
||||||
{'order_date': '2025-04-28', 'order_no': 'CGDD001695', 'customer_name': '易泰勒', 'material': 'WD1MK0SMD0551\n蓝牙模块\nPCBCOMPONENT_1_-_DUPLICATE', 'quantity': 950, 'unit_price': 1.3},
|
{'order_date': '2025-04-28', 'order_no': 'CGDD001695', 'customer_name': '易泰勒', 'material': 'WD1MK0SMD0551\n蓝牙模块\nPCBCOMPONENT_1_-_DUPLICATE', 'quantity': 950, 'unit_price': 1.3},
|
||||||
{'order_date': '2025-04-28', 'order_no': 'CGDD001695', 'customer_name': '易泰勒', 'material': 'WA0000000040\nPCBA', 'quantity': 4750, 'unit_price': 8.05},
|
{'order_date': '2025-04-28', 'order_no': 'CGDD001695', 'customer_name': '易泰勒', 'material': 'WA0000000040\nPCBA\nCH6121-MODULE-V14', 'quantity': 4750, 'unit_price': 8.05},
|
||||||
{'order_date': '2025-04-28', 'order_no': 'CGDD001695', 'customer_name': '易泰勒', 'material': 'CH6121-MODULE-V14', 'quantity': 4750, 'unit_price': 8.05},
|
|
||||||
|
|
||||||
# 2025/9/4 - CGDD002429
|
# 2025/9/4 - CGDD002429
|
||||||
{'order_date': '2025-09-04', 'order_no': 'CGDD002429', 'customer_name': '易泰勒', 'material': 'ETAP05\n基站-5.0\nETAP05', 'quantity': 1500, 'unit_price': 315.19},
|
{'order_date': '2025-09-04', 'order_no': 'CGDD002429', 'customer_name': '易泰勒', 'material': 'ETAP05\n基站-5.0\nETAP05', 'quantity': 1500, 'unit_price': 315.19},
|
||||||
{'order_date': '2025-09-04', 'order_no': 'CGDD002429', 'customer_name': '易泰勒', 'material': 'WD1MK0SMD0551\n蓝牙模块\nPCBCOMPONENT_1_-_DUPLICATE', 'quantity': 1500, 'unit_price': 1.3},
|
{'order_date': '2025-09-04', 'order_no': 'CGDD002429', 'customer_name': '易泰勒', 'material': 'WD1MK0SMD0551\n蓝牙模块\nPCBCOMPONENT_1_-_DUPLICATE', 'quantity': 1500, 'unit_price': 1.3},
|
||||||
{'order_date': '2025-09-04', 'order_no': 'CGDD002429', 'customer_name': '易泰勒', 'material': 'WA0000000040\nPCBA', 'quantity': 7500, 'unit_price': 8.05},
|
{'order_date': '2025-09-04', 'order_no': 'CGDD002429', 'customer_name': '易泰勒', 'material': 'WA0000000040\nPCBA\nCH6121-MODULE-V14', 'quantity': 7500, 'unit_price': 8.05},
|
||||||
{'order_date': '2025-09-04', 'order_no': 'CGDD002429', 'customer_name': '易泰勒', 'material': 'CH6121-MODULE-V14', 'quantity': 7500, 'unit_price': 8.05},
|
|
||||||
{'order_date': '2025-09-04', 'order_no': 'CGDD002429', 'customer_name': '易泰勒', 'material': 'AP-ET010\n基站-5.0\nETAP05', 'quantity': 500, 'unit_price': 315.19},
|
{'order_date': '2025-09-04', 'order_no': 'CGDD002429', 'customer_name': '易泰勒', 'material': 'AP-ET010\n基站-5.0\nETAP05', 'quantity': 500, 'unit_price': 315.19},
|
||||||
{'order_date': '2025-09-04', 'order_no': 'CGDD002429', 'customer_name': '易泰勒', 'material': 'WD1MK0SMD0551\n蓝牙模块\nPCBCOMPONENT_1_-_DUPLICATE', 'quantity': 500, 'unit_price': 1.3},
|
{'order_date': '2025-09-04', 'order_no': 'CGDD002429', 'customer_name': '易泰勒', 'material': 'WD1MK0SMD0551\n蓝牙模块\nPCBCOMPONENT_1_-_DUPLICATE', 'quantity': 500, 'unit_price': 1.3},
|
||||||
{'order_date': '2025-09-04', 'order_no': 'CGDD002429', 'customer_name': '易泰勒', 'material': 'WA0000000040\nPCBA\nCH6121-MODULE-V14', 'quantity': 2500, 'unit_price': 8.05},
|
{'order_date': '2025-09-04', 'order_no': 'CGDD002429', 'customer_name': '易泰勒', 'material': 'WA0000000040\nPCBA\nCH6121-MODULE-V14', 'quantity': 2500, 'unit_price': 8.05},
|
||||||
|
|||||||
@ -3683,6 +3683,61 @@ def create_customer_order():
|
|||||||
return jsonify({'ok': True, 'id': order_id, 'message': '订单创建成功'})
|
return jsonify({'ok': True, 'id': order_id, 'message': '订单创建成功'})
|
||||||
|
|
||||||
|
|
||||||
|
@app.put('/api/customer-orders/<int:order_id>')
|
||||||
|
@require_login
|
||||||
|
@require_any_role('superadmin')
|
||||||
|
def update_customer_order(order_id):
|
||||||
|
"""更新客户订单"""
|
||||||
|
data = request.get_json()
|
||||||
|
|
||||||
|
order_date = data.get('order_date', '').strip()
|
||||||
|
order_no = data.get('order_no', '').strip()
|
||||||
|
customer_name = data.get('customer_name', '').strip()
|
||||||
|
material = data.get('material', '').strip()
|
||||||
|
quantity = data.get('quantity')
|
||||||
|
unit_price = data.get('unit_price')
|
||||||
|
|
||||||
|
if not all([order_date, order_no, customer_name, material, quantity is not None, unit_price is not None]):
|
||||||
|
return jsonify({'error': '请填写所有必填项'}), 400
|
||||||
|
|
||||||
|
try:
|
||||||
|
quantity = int(quantity)
|
||||||
|
unit_price = float(unit_price)
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
return jsonify({'error': '数量和单价必须是有效数字'}), 400
|
||||||
|
|
||||||
|
if quantity <= 0:
|
||||||
|
return jsonify({'error': '数量必须大于0'}), 400
|
||||||
|
|
||||||
|
if unit_price < 0:
|
||||||
|
return jsonify({'error': '单价不能为负数'}), 400
|
||||||
|
|
||||||
|
conn = get_db()
|
||||||
|
c = conn.cursor()
|
||||||
|
|
||||||
|
# 检查订单是否存在
|
||||||
|
c.execute('SELECT id FROM customer_orders WHERE id=?', (order_id,))
|
||||||
|
if not c.fetchone():
|
||||||
|
conn.close()
|
||||||
|
return jsonify({'error': '订单不存在'}), 404
|
||||||
|
|
||||||
|
# 更新订单
|
||||||
|
c.execute('''UPDATE customer_orders
|
||||||
|
SET order_date=?, order_no=?, customer_name=?, material=?,
|
||||||
|
quantity=?, unit_price=?, updated_at=?, updated_by=?
|
||||||
|
WHERE id=?''',
|
||||||
|
(order_date, order_no, customer_name, material, quantity, unit_price,
|
||||||
|
datetime.now(timezone(timedelta(hours=8))).isoformat(),
|
||||||
|
session.get('username', 'unknown'), order_id))
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
log('update_customer_order', f'订单ID: {order_id}, 客户: {customer_name}, 订单号: {order_no}')
|
||||||
|
|
||||||
|
return jsonify({'ok': True, 'message': '订单更新成功'})
|
||||||
|
|
||||||
|
|
||||||
@app.delete('/api/customer-orders/<int:order_id>')
|
@app.delete('/api/customer-orders/<int:order_id>')
|
||||||
@require_login
|
@require_login
|
||||||
@require_any_role('superadmin')
|
@require_any_role('superadmin')
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user