<!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="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.4.3/echarts.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
display: flex;
background-color: #f5f7fa;
color: #333;
min-height: 100vh;
}
.sidebar {
background-color: #2c3e50;
color: white;
width: 250px;
height: 100vh;
padding: 20px;
position: fixed;
left: 0;
top: 0;
}
.logo {
margin-bottom: 30px;
font-size: 20px;
font-weight: bold;
display: flex;
align-items: center;
padding: 10px;
border-bottom: 1px solid #34495e;
}
.sidebar ul {
list-style: none;
padding: 0;
}
.sidebar li {
padding: 12px 15px;
margin-bottom: 5px;
cursor: pointer;
border-radius: 4px;
transition: all 0.3s ease;
display: flex;
align-items: center;
}
.sidebar li:hover {
background-color: #34495e;
}
.sidebar li.active {
background-color: #3498db;
}
.sidebar li i {
width: 25px;
text-align: center;
}
.main-content {
flex: 1;
margin-left: 250px;
padding: 25px;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 25px;
padding-bottom: 15px;
border-bottom: 1px solid #e0e6ed;
}
.header h1 {
color: #2c3e50;
font-size: 24px;
display: flex;
align-items: center;
gap: 10px;
}
.header-info {
display: flex;
align-items: center;
gap: 15px;
}
.stats-card {
background: white;
border-radius: 8px;
padding: 15px;
box-shadow: 0 2px 10px rgba(0,0,0,0.05);
display: flex;
align-items: center;
gap: 10px;
}
.stats-card i {
font-size: 24px;
width: 50px;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
}
.card-content {
flex: 1;
}
.card-content h3 {
font-size: 14px;
color: #7f8c8d;
margin-bottom: 5px;
}
.card-content p {
font-size: 22px;
font-weight: bold;
color: #2c3e50;
}
.online i { background-color: rgba(46, 204, 113, 0.2); color: #2ecc71; }
.offline i { background-color: rgba(231, 76, 60, 0.2); color: #e74c3c; }
.busy i { background-color: rgba(241, 196, 15, 0.2); color: #f1c40f; }
.idle i { background-color: rgba(52, 152, 219, 0.2); color: #3498db; }
.dashboard {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 25px;
margin-bottom: 25px;
}
.panel {
background: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 10px rgba(0,0,0,0.05);
}
.panel-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid #eee;
}
.panel-header h2 {
font-size: 18px;
color: #2c3e50;
display: flex;
align-items: center;
gap: 10px;
}
.map-container {
height: 500px;
width: 100%;
}
.controls {
display: flex;
gap: 15px;
margin-bottom: 20px;
}
.filter-group {
display: flex;
gap: 10px;
align-items: center;
}
select, input, button {
padding: 10px 15px;
border: 1px solid #ddd;
border-radius: 4px;
background: white;
}
button {
background-color: #3498db;
color: white;
border: none;
cursor: pointer;
transition: background 0.3s;
}
button:hover {
background-color: #2980b9;
}
.vehicle-list {
max-height: 500px;
overflow-y: auto;
}
.vehicle-item {
display: flex;
align-items: center;
padding: 15px;
border-bottom: 1px solid #eee;
cursor: pointer;
transition: background 0.3s;
}
.vehicle-item:hover {
background-color: #f9f9f9;
}
.vehicle-item.active {
background-color: #ebf5fb;
}
.status-indicator {
width: 12px;
height: 12px;
border-radius: 50%;
margin-right: 15px;
}
.online-status { background-color: #2ecc71; }
.offline-status { background-color: #e74c3c; }
.busy-status { background-color: #f1c40f; }
.idle-status { background-color: #3498db; }
.vehicle-info {
flex: 1;
}
.vehicle-info h3 {
font-size: 16px;
margin-bottom: 5px;
}
.vehicle-info p {
font-size: 14px;
color: #7f8c8d;
}
.vehicle-stats {
display: flex;
gap: 15px;
}
.stat-item {
text-align: center;
}
.stat-item .value {
font-weight: bold;
font-size: 16px;
color: #2c3e50;
}
.stat-item .label {
font-size: 12px;
color: #7f8c8d;
}
.timeline-controls {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 15px;
padding-top: 15px;
border-top: 1px solid #eee;
}
.time-display {
font-size: 14px;
color: #7f8c8d;
}
</style>
</head>
<body>
<!-- 侧边栏 -->
<div class='sidebar'>
<div class='logo'>
<i class='fas fa-truck'></i>智能物流系统
</div>
<ul>
<li><i class='fas fa-home'></i>首页</li>
<li><i class='fas fa-map-marked-alt'></i>路径规划</li>
<li><i class='fas fa-chart-line'></i>数据分析</li>
<li class="active"><i class='fas fa-truck-moving'></i>车辆监控</li>
<li><i class='fas fa-exclamation-triangle'></i>异常处理</li>
<li><i class='fas fa-cog'></i>系统设置</li>
<li><i class='fas fa-user'></i>个人中心</li>
<li><i class='fas fa-sign-out-alt'></i>退出登录</li>
</ul>
</div>
<!-- 主内容区 -->
<div class="main-content">
<div class="header">
<h1><i class="fas fa-truck-moving"></i> 车辆实时监控</h1>
<div class="header-info">
<div class="time-display">
<i class="far fa-clock"></i> 系统时间: <span id="current-time"></span>
</div>
</div>
</div>
<!-- 统计卡片 -->
<div class="stats-container">
<div class="stats-grid">
<div class="stats-card online">
<i class="fas fa-check-circle"></i>
<div class="card-content">
<h3>在线车辆</h3>
<p>28</p>
</div>
</div>
<div class="stats-card offline">
<i class="fas fa-times-circle"></i>
<div class="card-content">
<h3>离线车辆</h3>
<p>5</p>
</div>
</div>
<div class="stats-card busy">
<i class="fas fa-truck-loading"></i>
<div class="card-content">
<h3>运输中</h3>
<p>22</p>
</div>
</div>
<div class="stats-card idle">
<i class="fas fa-parking"></i>
<div class="card-content">
<h3>待命车辆</h3>
<p>6</p>
</div>
</div>
</div>
</div>
<!-- 控制面板 -->
<div class="controls">
<div class="filter-group">
<label>状态筛选:</label>
<select>
<option>全部车辆</option>
<option>在线</option>
<option>离线</option>
<option>运输中</option>
<option>待命</option>
</select>
</div>
<div class="filter-group">
<label>车牌号:</label>
<input type="text" placeholder="输入车牌号">
</div>
<button><i class="fas fa-search"></i> 搜索</button>
<button><i class="fas fa-sync-alt"></i> 刷新数据</button>
</div>
<!-- 主面板 -->
<div class="dashboard">
<!-- 地图面板 -->
<div class="panel">
<div class="panel-header">
<h2><i class="fas fa-map-marked-alt"></i> 车辆位置监控</h2>
<div class="time-display">
<i class="far fa-clock"></i> 最后更新: <span id="map-update-time"></span>
</div>
</div>
<div id="map-container" class="map-container"></div>
</div>
<!-- 车辆列表 -->
<div class="panel">
<div class="panel-header">
<h2><i class="fas fa-list"></i> 车辆状态列表</h2>
<span>共33辆</span>
</div>
<div class="vehicle-list">
<!-- 车辆项 1 -->
<div class="vehicle-item active">
<div class="status-indicator online-status"></div>
<div class="vehicle-info">
<h3>沪A·12345</h3>
<p>上海市浦东新区张江路</p>
</div>
<div class="vehicle-stats">
<div class="stat-item">
<div class="value">65km/h</div>
<div class="label">速度</div>
</div>
<div class="stat-item">
<div class="value">82%</div>
<div class="label">载重</div>
</div>
</div>
</div>
<!-- 车辆项 2 -->
<div class="vehicle-item">
<div class="status-indicator busy-status"></div>
<div class="vehicle-info">
<h3>沪B·67890</h3>
<p>上海市徐汇区漕宝路</p>
</div>
<div class="vehicle-stats">
<div class="stat-item">
<div class="value">42km/h</div>
<div class="label">速度</div>
</div>
<div class="stat-item">
<div class="value">45%</div>
<div class="label">载重</div>
</div>
</div>
</div>
<!-- 车辆项 3 -->
<div class="vehicle-item">
<div class="status-indicator idle-status"></div>
<div class="vehicle-info">
<h3>沪C·54321</h3>
<p>物流中心停车场</p>
</div>
<div class="vehicle-stats">
<div class="stat-item">
<div class="value">0km/h</div>
<div class="label">速度</div>
</div>
<div class="stat-item">
<div class="value">0%</div>
<div class="label">载重</div>
</div>
</div>
</div>
<!-- 车辆项 4 -->
<div class="vehicle-item">
<div class="status-indicator offline-status"></div>
<div class="vehicle-info">
<h3>沪D·13579</h3>
<p>离线</p>
</div>
<div class="vehicle-stats">
<div class="stat-item">
<div class="value">--</div>
<div class="label">速度</div>
</div>
<div class="stat-item">
<div class="value">--</div>
<div class="label">载重</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 轨迹回放面板 -->
<div class="panel">
<div class="panel-header">
<h2><i class="fas fa-route"></i> 轨迹回放</h2>
<div class="filter-group">
<select id="vehicle-select">
<option>沪A·12345</option>
<option>沪B·67890</option>
<option>沪C·54321</option>
</select>
</div>
</div>
<div id="route-container" class="map-container" style="height: 400px;"></div>
<div class="timeline-controls">
<div class="time-display">
回放时段: <span id="playback-time">2023-05-15 08:00 至 2023-05-15 18:00</span>
</div>
<div class="controls">
<button><i class="fas fa-step-backward"></i></button>
<button><i class="fas fa-play"></i></button>
<button><i class="fas fa-pause"></i></button>
<button><i class="fas fa-step-forward"></i></button>
</div>
</div>
</div>
</div>
<script>
// 设置时间(提前一个月)
function setDateTime() {
const now = new Date();
now.setMonth(now.getMonth() - 1);
const dateStr = now.toLocaleDateString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit'
});
const timeStr = now.toLocaleTimeString('zh-CN', {
hour: '2-digit',
minute: '2-digit'
});
document.getElementById('current-time').textContent = `${dateStr} ${timeStr}`;
document.getElementById('map-update-time').textContent = `${dateStr} ${timeStr}`;
}
// 初始化地图
function initMap() {
const mapChart = echarts.init(document.getElementById('map-container'));
const routeChart = echarts.init(document.getElementById('route-container'));
// 模拟上海地图数据
const mapOption = {
title: {
text: '上海市物流车辆实时分布',
left: 'center',
textStyle: {
color: '#2c3e50'
}
},
tooltip: {
trigger: 'item',
formatter: function(params) {
return `${params.name}<br/>状态: ${params.data.status}<br/>速度: ${params.data.speed}km/h`;
}
},
geo: {
map: 'china',
roam: true,
zoom: 10,
center: [121.47, 31.23],
label: {
emphasis: {
show: false
}
},
itemStyle: {
areaColor: '#e0e6ed',
borderColor: '#ccc'
},
emphasis: {
itemStyle: {
areaColor: '#d5e8ff'
}
}
},
series: [{
type: 'scatter',
coordinateSystem: 'geo',
symbolSize: 15,
data: [
{name: '沪A·12345', value: [121.48, 31.24, 65], status: '运输中', speed: 65},
{name: '沪B·67890', value: [121.43, 31.18, 42], status: '运输中', speed: 42},
{name: '沪C·54321', value: [121.52, 31.28, 0], status: '待命', speed: 0},
{name: '沪D·24680', value: [121.40, 31.20, 38], status: '运输中', speed: 38},
{name: '沪E·13579', value: [121.55, 31.25, 0], status: '待命', speed: 0}
],
itemStyle: {
color: function(params) {
const speed = params.data.speed;
if (speed === 0) return '#3498db'; // 待命
if (speed < 30) return '#f1c40f'; // 低速
return '#2ecc71'; // 正常
}
}
}]
};
// 轨迹回放数据
const routeOption = {
title: {
text: '沪A·12345 运输轨迹',
left: 'center',
textStyle: {
color: '#2c3e50'
}
},
tooltip: {
trigger: 'item',
formatter: function(params) {
return `时间: ${params.data.time}<br/>位置: ${params.name}`;
}
},
geo: {
map: 'china',
roam: true,
zoom: 10,
center: [121.47, 31.23],
itemStyle: {
areaColor: '#e0e6ed',
borderColor: '#ccc'
}
},
series: [{
type: 'lines',
coordinateSystem: 'geo',
polyline: true,
lineStyle: {
color: '#e74c3c',
width: 2
},
data: [{
coords: [
[121.30, 31.15],
[121.35, 31.18],
[121.40, 31.20],
[121.45, 31.22],
[121.48, 31.24]
],
time: '08:00 - 10:30'
}]
}, {
type: 'scatter',
coordinateSystem: 'geo',
symbolSize: 8,
data: [
{name: '起点', value: [121.30, 31.15], time: '08:00'},
{name: '途径点1', value: [121.35, 31.18], time: '09:15'},
{name: '途径点2', value: [121.40, 31.20], time: '10:00'},
{name: '终点', value: [121.48, 31.24], time: '10:30'}
],
itemStyle: {
color: '#3498db'
}
}]
};
mapChart.setOption(mapOption);
routeChart.setOption(routeOption);
// 响应窗口大小变化
window.addEventListener('resize', function() {
mapChart.resize();
routeChart.resize();
});
}
// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', function() {
setDateTime();
initMap();
// 更新地图时间
setInterval(() => {
const now = new Date();
now.setMonth(now.getMonth() - 1);
const timeStr = now.toLocaleTimeString('zh-CN', {
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
document.getElementById('map-update-time').textContent = timeStr;
}, 1000);
});
</script>
</body>
</html>