187 lines
4.6 KiB
HTML
187 lines
4.6 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<title>数据看板</title>
|
|
|
|
<!-- Tailwind -->
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
|
|
<!-- ECharts -->
|
|
<script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
|
|
</head>
|
|
|
|
<body class="bg-gray-100">
|
|
|
|
<div class="p-4">
|
|
|
|
<!-- 顶部 -->
|
|
<div class="flex justify-between items-center mb-4">
|
|
<h1 class="text-xl font-bold">数据看板</h1>
|
|
<button id="refreshBtn"
|
|
class="bg-blue-500 text-white px-3 py-1 rounded"
|
|
onclick="refreshData()">
|
|
🔄 刷新
|
|
</button>
|
|
</div>
|
|
|
|
<!-- KPI -->
|
|
<div id="kpi" class="grid grid-cols-6 gap-3 mb-4"></div>
|
|
|
|
<!-- 趋势 -->
|
|
<div class="bg-white p-4 rounded shadow mb-4">
|
|
<div class="mb-2 font-semibold">近7天上传趋势</div>
|
|
<div id="trend" style="height:260px;"></div>
|
|
</div>
|
|
|
|
<!-- 中间区域 -->
|
|
<div class="grid grid-cols-3 gap-4 mb-4">
|
|
|
|
<!-- 排行 -->
|
|
<div class="bg-white p-4 rounded shadow col-span-2">
|
|
<div class="mb-2 font-semibold">操作员上传排行</div>
|
|
<div id="rank" style="height:260px;"></div>
|
|
</div>
|
|
|
|
<!-- 右侧 -->
|
|
<div class="flex flex-col gap-4">
|
|
|
|
<!-- 最新上传 -->
|
|
<div class="bg-white p-4 rounded shadow">
|
|
<div class="mb-2 font-semibold">最新上传</div>
|
|
<table class="w-full text-sm">
|
|
<thead>
|
|
<tr class="text-gray-500">
|
|
<th>箱号</th><th>操作员</th><th>时间</th><th>数量</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="table"></tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- 企业公告 -->
|
|
<div class="bg-white p-4 rounded shadow">
|
|
<div class="mb-2 font-semibold">📢 企业公告</div>
|
|
<div id="notice" class="text-sm space-y-2 max-h-[120px] overflow-auto"></div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- 异常 -->
|
|
<div class="bg-white p-4 rounded shadow">
|
|
<div class="mb-2 font-semibold text-red-500">⚠️ 数据异常</div>
|
|
<div id="warn" class="text-sm text-red-500 space-y-1"></div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<script>
|
|
// ===== 模拟数据 =====
|
|
function getData() {
|
|
return {
|
|
kpi: [
|
|
["今日箱数", rand(80,150)],
|
|
["照片总数", rand(300,800)],
|
|
["活跃操作员", rand(5,20)],
|
|
["最近上传", "10:" + rand(10,59)],
|
|
["异常箱数", rand(0,10)],
|
|
["待处理", rand(0,5)],
|
|
],
|
|
trend: Array.from({length:7},()=>rand(50,150)),
|
|
rank: Array.from({length:5},()=>rand(40,120)),
|
|
users: ["张三","李四","王五","赵六","钱七"],
|
|
list: [
|
|
["MSCU1234567","张三","10:30",5],
|
|
["TEMU7654321","李四","10:20",4],
|
|
["CMAU9988776","王五","10:10",6],
|
|
],
|
|
notice: [
|
|
"📌 今日起必须上传封条照片",
|
|
"📌 晚班请补录遗漏数据",
|
|
"📌 周五晚系统维护"
|
|
],
|
|
warn: [
|
|
"图片少于3张:" + rand(0,5),
|
|
"箱号为空:" + rand(0,3),
|
|
"OCR失败:" + rand(0,3)
|
|
]
|
|
}
|
|
}
|
|
|
|
function rand(min,max){return Math.floor(Math.random()*(max-min)+min)}
|
|
|
|
// ===== 渲染 =====
|
|
let trendChart = echarts.init(document.getElementById('trend'));
|
|
let rankChart = echarts.init(document.getElementById('rank'));
|
|
|
|
function render() {
|
|
const data = getData();
|
|
|
|
// KPI
|
|
document.getElementById("kpi").innerHTML = data.kpi.map(i=>`
|
|
<div class="bg-white p-3 rounded shadow">
|
|
<div class="text-gray-400 text-xs">${i[0]}</div>
|
|
<div class="text-xl font-bold mt-1">${i[1]}</div>
|
|
</div>
|
|
`).join("");
|
|
|
|
// 表格
|
|
document.getElementById("table").innerHTML = data.list.map(i=>`
|
|
<tr class="border-t">
|
|
<td>${i[0]}</td>
|
|
<td>${i[1]}</td>
|
|
<td>${i[2]}</td>
|
|
<td>${i[3]}</td>
|
|
</tr>
|
|
`).join("");
|
|
|
|
// 公告
|
|
document.getElementById("notice").innerHTML =
|
|
data.notice.map(i=>`<div>${i}</div>`).join("");
|
|
|
|
// 异常
|
|
document.getElementById("warn").innerHTML =
|
|
data.warn.map(i=>`<div>${i}</div>`).join("");
|
|
|
|
// 趋势图
|
|
trendChart.setOption({
|
|
xAxis: { type: 'category', data: ['一','二','三','四','五','六','日'] },
|
|
yAxis: { type: 'value' },
|
|
series: [{
|
|
data: data.trend,
|
|
type: 'line',
|
|
smooth: true
|
|
}]
|
|
});
|
|
|
|
// 排行
|
|
rankChart.setOption({
|
|
xAxis: { type: 'category', data: data.users },
|
|
yAxis: { type: 'value' },
|
|
series: [{
|
|
data: data.rank,
|
|
type: 'bar'
|
|
}]
|
|
});
|
|
}
|
|
|
|
// ===== 刷新 =====
|
|
function refreshData() {
|
|
const btn = document.getElementById("refreshBtn");
|
|
btn.innerText = "刷新中...";
|
|
btn.disabled = true;
|
|
|
|
setTimeout(()=>{
|
|
render();
|
|
btn.innerText = "🔄 刷新";
|
|
btn.disabled = false;
|
|
}, 800);
|
|
}
|
|
|
|
render();
|
|
</script>
|
|
|
|
</body>
|
|
</html> |