ERP/frontend/js/components/shipments.js

250 lines
8.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

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.

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 `<div class="card">
<div style="font-weight:600;margin-bottom:16px">发货记录</div>
<div style="margin-bottom:24px;padding-bottom:24px;border-bottom:1px solid var(--border)">
<div style="font-weight:500;margin-bottom:12px">手动录入</div>
<div style="font-size:13px;color:var(--text-secondary);margin-bottom:12px">
用于快速录入发货汇总信息不含详细SN
</div>
<div class="row">
<div class="col">
<div class="field">
<label>发货日期 <span style="color:var(--danger)">*</span></label>
<input id="ship-date" type="date" class="input" />
</div>
</div>
<div class="col">
<div class="field">
<label>机种类型 <span style="color:var(--danger)">*</span></label>
<select id="ship-manual-platform" class="input">
<option value="">请选择机种</option>
<option value="pdd">拼多多</option>
<option value="yt">圆通</option>
<option value="tx">兔喜</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="field">
<label>接收方 <span style="color:var(--danger)">*</span></label>
<input id="ship-to" class="input" placeholder="客户名称" />
</div>
</div>
<div class="col">
<div class="field">
<label>数量 <span style="color:var(--danger)">*</span></label>
<input id="ship-qty" type="number" min="1" class="input" placeholder="发货数量" />
</div>
</div>
</div>
<div class="field">
<label>箱号(可选)</label>
<input id="ship-box-no" class="input" placeholder="例如BOX001" />
</div>
<div id="ship-manual-status" style="margin:8px 0;font-size:13px"></div>
<div class="actions"><button class="btn" id="ship-upload">提交录入</button></div>
</div>
<div>
<div style="font-weight:500;margin-bottom:12px">详细记录批量导入</div>
<div class="format-requirements">
<div style="font-weight:500;margin-bottom:4px">文件格式要求:</div>
<div>• 必需列出货日期、箱号、SN1、SN2、...、SN20</div>
<div>• 出货日期列支持合并单元格</div>
<div>• 支持格式Excel (.xlsx, .xls) 或 CSV</div>
</div>
<div class="field">
<label>机种类型 <span style="color:var(--danger)">*</span></label>
<select id="ship-platform" class="input">
<option value="">请选择机种</option>
<option value="pdd">拼多多</option>
<option value="yt">圆通</option>
<option value="tx">兔喜</option>
</select>
</div>
<div class="field">
<label>选择文件</label>
<input type="file" id="ship-file" accept=".xlsx,.xls,.csv" class="input" style="padding:6px" />
</div>
<div id="ship-file-status" style="margin:8px 0;font-size:13px"></div>
<div class="actions">
<button class="btn" id="ship-validate" style="background:#6c757d">验证文件</button>
<button class="btn" id="ship-upload-file">导入数据</button>
</div>
</div>
</div>`;
});