Router.register('/upload/shipments', async () => { setTimeout(() => { const manualStatus = document.getElementById('ship-manual-status'); // 设置默认日期为今天 const dateInput = document.getElementById('ship-date'); if (dateInput && !dateInput.value) { const today = new Date().toISOString().split('T')[0]; dateInput.value = today; } // 手动录入提交 const btn = document.getElementById('ship-upload'); btn?.addEventListener('click', async () => { const date = document.getElementById('ship-date').value; const qty = parseInt(document.getElementById('ship-qty').value || '0', 10); const to = document.getElementById('ship-to').value; const platform = document.getElementById('ship-manual-platform').value; const boxNo = document.getElementById('ship-box-no').value.trim(); // 验证必填字段 if (!date) { manualStatus.textContent = '✗ 请选择发货日期'; manualStatus.className = 'error'; return; } if (!platform) { manualStatus.textContent = '✗ 请选择机种类型'; manualStatus.className = 'error'; return; } if (!to) { manualStatus.textContent = '✗ 请输入接收方'; manualStatus.className = 'error'; return; } if (qty <= 0) { manualStatus.textContent = '✗ 数量必须大于0'; manualStatus.className = 'error'; return; } try { manualStatus.textContent = '提交中...'; manualStatus.className = ''; const payload = { date, qty, to, platform }; if (boxNo) { payload.box_no = boxNo; } await API.uploadShipments(payload); const platformName = {pdd: '拼多多', yt: '圆通', tx: '兔喜'}[platform] || platform; manualStatus.textContent = `✓ 录入成功!机种:${platformName},数量:${qty}`; manualStatus.className = 'success'; // 清空表单(保留日期和机种) document.getElementById('ship-qty').value = ''; document.getElementById('ship-to').value = ''; document.getElementById('ship-box-no').value = ''; } catch(e) { manualStatus.textContent = '✗ 录入失败:' + (e.message || '未知错误'); manualStatus.className = 'error'; } }); const fileInput = document.getElementById('ship-file'); const validateBtn = document.getElementById('ship-validate'); const uploadFileBtn = document.getElementById('ship-upload-file'); const fileStatus = document.getElementById('ship-file-status'); fileInput?.addEventListener('change', () => { fileStatus.textContent = ''; fileStatus.className = ''; }); validateBtn?.addEventListener('click', async () => { const file = fileInput?.files?.[0]; if (!file) { fileStatus.textContent = '请先选择文件'; fileStatus.className = 'error'; return; } const formData = new FormData(); formData.append('file', file); try { const res = await fetch('/api/validate/shipments-file', { method: 'POST', body: formData, credentials: 'include' }); if (!res.ok) { const text = await res.text(); throw new Error(`HTTP ${res.status}: ${text}`); } const data = await res.json(); if (data.valid) { fileStatus.textContent = '✓ ' + data.message; fileStatus.className = 'success'; } else { fileStatus.textContent = '✗ ' + data.message; fileStatus.className = 'error'; } } catch (e) { fileStatus.textContent = '验证失败:' + e.message; fileStatus.className = 'error'; } }); uploadFileBtn?.addEventListener('click', async () => { const file = fileInput?.files?.[0]; const platform = document.getElementById('ship-platform')?.value; if (!platform) { fileStatus.textContent = '✗ 请选择机种类型'; fileStatus.className = 'error'; return; } if (!file) { fileStatus.textContent = '✗ 请先选择文件'; fileStatus.className = 'error'; return; } const formData = new FormData(); formData.append('file', file); formData.append('platform', platform); try { fileStatus.textContent = '上传中...'; fileStatus.className = ''; const res = await fetch('/api/upload/shipments-file', { method: 'POST', body: formData, credentials: 'include' }); if (!res.ok) { const text = await res.text(); throw new Error(`HTTP ${res.status}: ${text}`); } const data = await res.json(); if (data.ok) { const platformName = {pdd: '拼多多', yt: '圆通', tx: '兔喜'}[platform] || platform; fileStatus.textContent = `✓ 上传成功!机种:${platformName},共导入${data.count}个箱次,${data.total_qty}个SN`; fileStatus.className = 'success'; fileInput.value = ''; document.getElementById('ship-platform').value = ''; } else { fileStatus.textContent = '✗ ' + (data.error || '上传失败'); fileStatus.className = 'error'; } } catch (e) { fileStatus.textContent = '上传失败:' + e.message; fileStatus.className = 'error'; } }); }, 0); return `