70 lines
4.8 KiB
HTML
70 lines
4.8 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>订单进度追踪 - 智能排产系统</title>
|
||
<link rel="stylesheet" href="../css/common.css">
|
||
</head>
|
||
<body>
|
||
<div id="app">
|
||
<header class="header" id="header"></header>
|
||
<div class="body">
|
||
<aside class="sidebar" id="sidebar"></aside>
|
||
<main class="main">
|
||
<h1 class="page-title">订单进度追踪</h1>
|
||
<div class="row">
|
||
<div class="col-3"><div class="card kpi-card"><div class="kpi-icon" style="background:#ffedd5;color:#c2410c"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg></div><div><div class="kpi-value" id="totalOrders">0</div><div class="kpi-label">跟踪订单</div></div></div></div>
|
||
<div class="col-3"><div class="card kpi-card"><div class="kpi-icon" style="background:#dcfce7;color:#15803d"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="20 6 9 17 4 12"/></svg></div><div><div class="kpi-value" id="completedOrders">0</div><div class="kpi-label">已完成</div></div></div></div>
|
||
<div class="col-3"><div class="card kpi-card"><div class="kpi-icon" style="background:#fee2e2;color:#dc2626"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg></div><div><div class="kpi-value" id="delayedOrders">0</div><div class="kpi-label">延迟预警</div></div></div></div>
|
||
<div class="col-3"><div class="card kpi-card"><div class="kpi-icon" style="background:#e0f2fe;color:#0369a1"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg></div><div><div class="kpi-value" id="avgProgress">0%</div><div class="kpi-label">平均进度</div></div></div></div>
|
||
</div>
|
||
<div class="card">
|
||
<div class="card-header">订单执行进度</div>
|
||
<div class="card-body table-wrap">
|
||
<table id="progressTable">
|
||
<thead><tr><th>订单号</th><th>客户</th><th>产品</th><th>交期</th><th>工单进度</th><th>整体进度</th><th>状态</th></tr></thead>
|
||
<tbody></tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
</div>
|
||
</div>
|
||
<script src="../js/data.js"></script>
|
||
<script src="../js/common.js"></script>
|
||
<script>
|
||
initPage('order-progress');
|
||
function render() {
|
||
const rows = apsData.salesOrders.filter(o => o.status !== 'CANCELLED');
|
||
document.getElementById('totalOrders').textContent = rows.length;
|
||
document.getElementById('completedOrders').textContent = rows.filter(o => o.status === 'COMPLETED').length;
|
||
const delayed = rows.filter(o => {
|
||
const pos = apsData.productionOrders.filter(po => po.salesOrderId == o.id);
|
||
return pos.some(po => po.plannedEndDate && po.plannedEndDate.slice(0,10) > o.deliveryDate);
|
||
}).length;
|
||
document.getElementById('delayedOrders').textContent = delayed;
|
||
let totalProgress = 0;
|
||
const tbody = document.querySelector('#progressTable tbody');
|
||
tbody.innerHTML = rows.map(o => {
|
||
const wos = apsData.workOrders.filter(wo => {
|
||
const po = findById(apsData.productionOrders, wo.productionOrderId);
|
||
return po && po.salesOrderId == o.id;
|
||
});
|
||
const progress = wos.length ? Math.round(wos.reduce((a, b) => a + b.progressPercent, 0) / wos.length) : 0;
|
||
totalProgress += progress;
|
||
const status = progress >= 100 ? 'COMPLETED' : (progress > 0 ? 'IN_PROGRESS' : o.status);
|
||
return `<tr>
|
||
<td>${o.orderNo}</td><td>${o.customerName}</td><td>${o.items[0].productName} × ${o.items[0].quantity}</td><td>${o.deliveryDate}</td>
|
||
<td>${wos.length} 个工单</td>
|
||
<td><div class="progress"><div class="progress-bar ${progress>=100?'success':(progress>0?'warning':'')}" style="width:${progress}%"></div></div>${progress}%</td>
|
||
<td>${statusBadge(status, { COMPLETED:'success', IN_PROGRESS:'warning', CONFIRMED:'primary', DRAFT:'default', SUBMITTED:'warning' })}</td>
|
||
</tr>`;
|
||
}).join('') || '<tr><td colspan="7" class="text-center text-muted">无数据</td></tr>';
|
||
document.getElementById('avgProgress').textContent = (rows.length ? Math.round(totalProgress / rows.length) : 0) + '%';
|
||
}
|
||
render();
|
||
</script>
|
||
</body>
|
||
</html>
|