Files
workspace/code/container-ocr/ocr-uniapp/test.html
T
2026-03-18 17:29:39 +08:00

957 lines
33 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="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Microsoft YaHei', Arial, sans-serif;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: #f0f2f5;
padding: 20px;
}
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.6);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.modal-container {
width: 90%;
max-width: 1300px;
height: 85vh;
background-color: #fff;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
display: flex;
flex-direction: column;
overflow: hidden;
position: relative;
}
/* 模态框头部 */
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px;
height: 56px;
background: #2c3e50;
color: white;
border-bottom: 1px solid #1a252f;
}
.modal-title {
display: flex;
align-items: center;
gap: 10px;
font-size: 16px;
font-weight: 500;
}
.modal-title i {
font-size: 1.3rem;
}
.modal-actions {
display: flex;
gap: 8px;
}
/* 模态框内容区 */
.modal-content {
display: flex;
flex: 1;
overflow: hidden;
}
/* 左侧信息区 */
.info-panel {
flex: 0 0 42%;
max-width: 42%;
padding: 0;
overflow-y: auto;
border-right: 1px solid #e8e8e8;
display: flex;
flex-direction: column;
background: #fafafa;
}
/* 右侧地图区 */
.map-panel {
flex: 1;
position: relative;
overflow: hidden;
}
.map-container {
width: 100%;
height: 100%;
background: #e8f4fd;
position: relative;
}
/* 搜索条件区域 */
.search-section {
background: #fff;
padding: 16px 20px;
border-bottom: 1px solid #e8e8e8;
}
.search-title {
font-size: 15px;
font-weight: 600;
color: #2c3e50;
margin-bottom: 16px;
display: flex;
align-items: center;
gap: 8px;
}
.search-controls {
display: flex;
flex-direction: column;
gap: 12px;
}
.filter-row {
display: flex;
align-items: center;
gap: 12px;
}
.filter-label {
font-size: 13px;
font-weight: 500;
color: #595959;
min-width: 60px;
text-align: right;
}
.search-actions {
display: flex;
justify-content: flex-end;
margin-top: 8px;
}
/* 车辆信息区域 */
.vehicle-section {
background: #fff;
padding: 16px 20px;
border-bottom: 1px solid #e8e8e8;
}
.section-title {
font-size: 15px;
font-weight: 600;
color: #2c3e50;
margin-bottom: 16px;
display: flex;
align-items: center;
gap: 8px;
}
.info-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px 20px;
}
.info-item {
display: flex;
flex-direction: column;
}
.info-label {
font-size: 12px;
color: #8c8c8c;
margin-bottom: 4px;
}
.info-value {
font-size: 13px;
font-weight: 500;
color: #262626;
padding: 4px 0;
}
.status-active {
color: #52c41a;
font-weight: 500;
}
.status-inactive {
color: #f5222d;
font-weight: 500;
}
/* 历史轨迹区域 */
.history-section {
flex: 1;
display: flex;
flex-direction: column;
background: #fff;
padding: 16px 20px;
}
.history-list {
flex: 1;
overflow-y: auto;
border: 1px solid #f0f0f0;
}
.history-header {
display: flex;
background: #fafafa;
border-bottom: 1px solid #f0f0f0;
font-size: 12px;
font-weight: 500;
color: #595959;
}
.history-header-cell {
padding: 10px 12px;
border-right: 1px solid #f0f0f0;
}
.history-header-cell:last-child {
border-right: none;
}
.history-header-cell.time {
width: 160px;
}
.history-header-cell.driver {
width: 100px;
}
.history-header-cell.location {
flex: 1;
}
.history-item {
display: flex;
border-bottom: 1px solid #f0f0f0;
transition: background-color 0.2s;
}
.history-item:hover {
background-color: #fafafa;
}
.history-item:last-child {
border-bottom: none;
}
.history-cell {
padding: 10px 12px;
font-size: 12px;
border-right: 1px solid #f0f0f0;
}
.history-cell:last-child {
border-right: none;
}
.history-time {
color: #262626;
font-family: 'Consolas', 'Monaco', monospace;
}
.history-location {
color: #262626;
}
.history-driver {
color: #595959;
}
/* 地图上的模拟元素 */
.map-marker {
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
width: 16px;
height: 16px;
background-color: #1890ff;
border: 2px solid white;
border-radius: 50%;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
}
.map-marker::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
width: 0;
height: 0;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 8px solid #1890ff;
}
.route-line {
position: absolute;
top: 30%;
left: 20%;
width: 60%;
height: 2px;
background-color: #1890ff;
}
.route-line::before {
content: "";
position: absolute;
width: 10px;
height: 10px;
background-color: #fa8c16;
border-radius: 50%;
top: -4px;
left: 0;
}
.route-line::after {
content: "";
position: absolute;
width: 10px;
height: 10px;
background-color: #52c41a;
border-radius: 50%;
top: -4px;
right: 0;
}
/* 按钮样式 */
.btn {
padding: 6px 12px;
border: 1px solid #d9d9d9;
border-radius: 2px;
cursor: pointer;
font-size: 13px;
font-weight: 400;
display: flex;
align-items: center;
gap: 6px;
transition: all 0.2s;
background: #fff;
}
.btn-primary {
background-color: #1890ff;
border-color: #1890ff;
color: white;
}
.btn-primary:hover {
background-color: #40a9ff;
border-color: #40a9ff;
}
.btn-secondary {
background-color: #fff;
color: #262626;
}
.btn-secondary:hover {
background-color: #f5f5f5;
}
.btn-close {
background-color: transparent;
color: white;
border: none;
font-size: 1.2rem;
padding: 0;
width: 28px;
height: 28px;
justify-content: center;
}
.btn-close:hover {
background-color: rgba(255, 255, 255, 0.1);
}
.btn-fullscreen {
background-color: transparent;
color: white;
border: none;
}
.btn-fullscreen:hover {
background-color: rgba(255, 255, 255, 0.1);
}
/* 表单控件样式 */
.search-input, .select-input {
flex: 1;
padding: 6px 10px;
border: 1px solid #d9d9d9;
border-radius: 2px;
font-size: 13px;
transition: border-color 0.2s;
background: #fff;
}
.search-input:focus, .select-input:focus {
outline: none;
border-color: #1890ff;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
/* 统计信息 */
.stats-info {
display: flex;
justify-content: space-between;
margin-top: 12px;
padding: 8px 0;
border-top: 1px solid #f0f0f0;
font-size: 12px;
color: #8c8c8c;
}
/* 全屏样式 */
.modal-container.fullscreen {
width: 100%;
height: 100%;
max-width: 100%;
}
/* 响应式设计 */
@media (max-width: 1100px) {
.modal-container {
width: 95%;
height: 90vh;
}
.info-panel {
flex: 0 0 50%;
max-width: 50%;
}
.filter-row {
flex-direction: column;
align-items: flex-start;
}
}
@media (max-width: 768px) {
.modal-content {
flex-direction: column;
}
.info-panel, .map-panel {
flex: none;
max-width: 100%;
}
.info-panel {
height: 50%;
border-right: none;
border-bottom: 1px solid #e8e8e8;
}
.map-panel {
height: 50%;
}
.info-grid {
grid-template-columns: 1fr;
}
}
/* 动画效果 */
@keyframes fadeIn {
from { opacity: 0; transform: translateY(-10px); }
to { opacity: 1; transform: translateY(0); }
}
.modal-container {
animation: fadeIn 0.2s ease-out;
}
/* 滚动条样式 */
::-webkit-scrollbar {
width: 6px;
}
::-webkit-scrollbar-track {
background: #f5f5f5;
}
::-webkit-scrollbar-thumb {
background: #d9d9d9;
border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
background: #bfbfbf;
}
/* 图标颜色 */
.icon-blue {
color: #1890ff;
}
.icon-green {
color: #52c41a;
}
/* 地图标注 */
.map-label {
position: absolute;
background: rgba(255, 255, 255, 0.95);
padding: 4px 8px;
border-radius: 2px;
font-size: 11px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
border: 1px solid #f0f0f0;
}
</style>
</head>
<body>
<!-- 触发按钮 -->
<button id="openModalBtn" class="btn btn-primary">
<i class="fas fa-map-marked-alt"></i> 打开车辆地图对话框
</button>
<!-- 对话框 -->
<div id="modalOverlay" class="modal-overlay" style="display: none;">
<div class="modal-container" id="modalContainer">
<!-- 对话框头部 -->
<div class="modal-header">
<div class="modal-title">
<i class="fas fa-map-marked-alt"></i>
<h2>车辆位置追踪系统</h2>
</div>
<div class="modal-actions">
<button id="fullscreenBtn" class="btn btn-fullscreen" title="全屏">
<i class="fas fa-expand"></i>
</button>
<button id="closeModalBtn" class="btn btn-close" title="关闭">
<i class="fas fa-times"></i>
</button>
</div>
</div>
<!-- 对话框内容 -->
<div class="modal-content">
<!-- 左侧信息面板 -->
<div class="info-panel">
<!-- 搜索条件区域 -->
<div class="search-section">
<h3 class="search-title">
<i class="fas fa-search icon-blue"></i> 搜索条件
</h3>
<div class="search-controls">
<div class="filter-row">
<label for="driverSelect" class="filter-label">司机:</label>
<select id="driverSelect" class="select-input">
<!-- 司机选项将通过JS动态生成 -->
</select>
</div>
<div class="filter-row">
<label for="startDate" class="filter-label">开始日期:</label>
<input type="date" id="startDate" class="search-input">
<label for="endDate" class="filter-label" style="margin-left: 10px;">结束日期:</label>
<input type="date" id="endDate" class="search-input">
</div>
<div class="search-actions">
<button id="searchHistoryBtn" class="btn btn-primary">
<i class="fas fa-search"></i> 搜索轨迹
</button>
</div>
</div>
<div class="stats-info">
<span id="statsCount">共0条记录</span>
<span id="statsTimeRange">时间范围:-</span>
</div>
</div>
<!-- 车辆信息 -->
<div class="vehicle-section">
<h3 class="section-title">
<i class="fas fa-car icon-blue"></i> 车辆信息
</h3>
<div class="info-grid">
<div class="info-item">
<span class="info-label">车号</span>
<span class="info-value" id="vehicleNumber">沪A-12345</span>
</div>
<div class="info-item">
<span class="info-label">车辆状态</span>
<span class="info-value status-active" id="vehicleStatus">在线行驶</span>
</div>
<div class="info-item">
<span class="info-label">当前位置</span>
<span class="info-value" id="currentLocation">上海市浦东新区陆家嘴环路</span>
</div>
<div class="info-item">
<span class="info-label">最新位置时间</span>
<span class="info-value" id="lastUpdateTime">2023-10-15 14:30:25</span>
</div>
<div class="info-item">
<span class="info-label">驾驶员</span>
<span class="info-value" id="driverName">张师傅</span>
</div>
<div class="info-item">
<span class="info-label">联系电话</span>
<span class="info-value" id="driverPhone">138****5678</span>
</div>
</div>
</div>
<!-- 历史轨迹 -->
<div class="history-section">
<h3 class="section-title">
<i class="fas fa-route icon-green"></i> 历史轨迹
</h3>
<div class="history-list" id="historyList">
<div class="history-header">
<div class="history-header-cell time">时间</div>
<div class="history-header-cell driver">司机</div>
<div class="history-header-cell location">位置</div>
</div>
<!-- 历史轨迹项将通过JS动态生成 -->
</div>
</div>
</div>
<!-- 右侧地图面板 -->
<div class="map-panel">
<div class="map-container" id="mapContainer">
<!-- 模拟地图元素 -->
<div class="route-line"></div>
<div class="map-marker"></div>
<!-- 模拟地图标注 -->
<div class="map-label" style="top: 20px; left: 20px;">
<i class="fas fa-map-marker-alt" style="color: #1890ff; margin-right: 4px;"></i>
<span>车辆当前位置</span>
</div>
<div class="map-label" style="top: 30%; left: 20%;">
<i class="fas fa-flag" style="color: #fa8c16; margin-right: 4px;"></i>
<span>轨迹起点</span>
</div>
<div class="map-label" style="top: 30%; right: 20%;">
<i class="fas fa-flag-checkered" style="color: #52c41a; margin-right: 4px;"></i>
<span>轨迹终点</span>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
// 模拟历史轨迹数据
const historyData = [
{ date: "2023-10-15", time: "14:30:25", location: "上海市浦东新区陆家嘴环路", driver: "张师傅" },
{ date: "2023-10-15", time: "14:15:10", location: "上海市浦东新区世纪大道", driver: "张师傅" },
{ date: "2023-10-15", time: "13:45:33", location: "上海市黄浦区南京东路", driver: "张师傅" },
{ date: "2023-10-15", time: "13:20:18", location: "上海市静安区南京西路", driver: "张师傅" },
{ date: "2023-10-15", time: "12:55:42", location: "上海市徐汇区淮海中路", driver: "张师傅" },
{ date: "2023-10-15", time: "12:30:05", location: "上海市长宁区虹桥路", driver: "王师傅" },
{ date: "2023-10-15", time: "12:05:29", location: "上海市普陀区中山北路", driver: "王师傅" },
{ date: "2023-10-15", time: "11:40:12", location: "上海市虹口区四川北路", driver: "王师傅" },
{ date: "2023-10-15", time: "11:15:37", location: "上海市杨浦区四平路", driver: "李师傅" },
{ date: "2023-10-15", time: "10:50:21", location: "上海市宝山区同济路", driver: "李师傅" },
{ date: "2023-10-14", time: "16:20:15", location: "上海市松江区人民北路", driver: "张师傅" },
{ date: "2023-10-14", time: "15:45:30", location: "上海市青浦区公园路", driver: "张师傅" },
{ date: "2023-10-14", time: "15:10:22", location: "上海市嘉定区博乐路", driver: "王师傅" },
{ date: "2023-10-14", time: "14:35:18", location: "上海市金山区卫零路", driver: "王师傅" },
{ date: "2023-10-14", time: "13:50:45", location: "上海市奉贤区南奉公路", driver: "李师傅" },
{ date: "2023-10-13", time: "17:30:10", location: "上海市崇明区陈海公路", driver: "张师傅" },
{ date: "2023-10-13", time: "16:45:25", location: "上海市浦东新区张杨路", driver: "王师傅" },
{ date: "2023-10-13", time: "16:10:40", location: "上海市黄浦区西藏中路", driver: "李师傅" },
{ date: "2023-10-13", time: "15:35:55", location: "上海市徐汇区衡山路", driver: "李师傅" },
{ date: "2023-10-12", time: "14:20:30", location: "上海市静安区北京西路", driver: "张师傅" },
{ date: "2023-10-12", time: "13:45:15", location: "上海市长宁区延安西路", driver: "王师傅" },
{ date: "2023-10-12", time: "12:30:45", location: "上海市徐汇区漕溪北路", driver: "李师傅" }
];
// DOM元素
const modalOverlay = document.getElementById('modalOverlay');
const modalContainer = document.getElementById('modalContainer');
const openModalBtn = document.getElementById('openModalBtn');
const closeModalBtn = document.getElementById('closeModalBtn');
const fullscreenBtn = document.getElementById('fullscreenBtn');
const driverSelect = document.getElementById('driverSelect');
const startDate = document.getElementById('startDate');
const endDate = document.getElementById('endDate');
const searchHistoryBtn = document.getElementById('searchHistoryBtn');
const historyList = document.getElementById('historyList');
const statsCount = document.getElementById('statsCount');
const statsTimeRange = document.getElementById('statsTimeRange');
const mapContainer = document.getElementById('mapContainer');
// 获取所有司机
const drivers = [...new Set(historyData.map(item => item.driver))];
// 初始化日期范围
const today = new Date();
const sevenDaysAgo = new Date();
sevenDaysAgo.setDate(today.getDate() - 7);
const todayStr = today.toISOString().split('T')[0];
const sevenDaysAgoStr = sevenDaysAgo.toISOString().split('T')[0];
startDate.value = sevenDaysAgoStr;
endDate.value = todayStr;
// 初始化司机下拉框
function initDriverSelect() {
driverSelect.innerHTML = '';
// 添加"全部司机"选项
const allOption = document.createElement('option');
allOption.value = 'all';
allOption.textContent = '全部司机';
driverSelect.appendChild(allOption);
// 添加各个司机选项
drivers.forEach(driver => {
const option = document.createElement('option');
option.value = driver;
option.textContent = driver;
driverSelect.appendChild(option);
});
}
// 初始化历史轨迹列表
function initHistoryList() {
const selectedDriver = driverSelect.value;
const startDateValue = startDate.value;
const endDateValue = endDate.value;
renderHistoryList(selectedDriver, startDateValue, endDateValue);
}
// 渲染历史轨迹列表
function renderHistoryList(driverFilter, startDateFilter, endDateFilter) {
// 清空历史列表(保留表头)
const historyItems = historyList.querySelectorAll('.history-item');
historyItems.forEach(item => item.remove());
// 过滤数据
let filteredData = historyData.filter(item => {
// 按司机过滤
if (driverFilter !== 'all' && item.driver !== driverFilter) {
return false;
}
// 按日期范围过滤
const itemDate = new Date(item.date);
const start = new Date(startDateFilter);
const end = new Date(endDateFilter);
return itemDate >= start && itemDate <= end;
});
// 按日期和时间排序
filteredData.sort((a, b) => {
const dateTimeA = new Date(`${a.date} ${a.time}`);
const dateTimeB = new Date(`${b.date} ${b.time}`);
return dateTimeB - dateTimeA; // 从新到旧排序
});
if (filteredData.length === 0) {
const emptyItem = document.createElement('div');
emptyItem.className = 'history-item';
emptyItem.style.textAlign = 'center';
emptyItem.style.padding = '20px';
emptyItem.style.fontSize = '12px';
emptyItem.style.color = '#8c8c8c';
emptyItem.innerHTML = `
<div style="width: 100%;">
<i class="fas fa-inbox" style="font-size: 1.5rem; margin-bottom: 8px; display: block;"></i>
<div>暂无轨迹数据</div>
</div>
`;
historyList.appendChild(emptyItem);
// 更新统计信息
statsCount.textContent = '共0条记录';
statsTimeRange.textContent = '时间范围:-';
} else {
filteredData.forEach(item => {
const historyItem = document.createElement('div');
historyItem.className = 'history-item';
historyItem.innerHTML = `
<div class="history-cell time">${item.date} ${item.time}</div>
<div class="history-cell driver">${item.driver}</div>
<div class="history-cell location">${item.location}</div>
`;
historyList.appendChild(historyItem);
});
// 更新统计信息
statsCount.textContent = `共${filteredData.length}条记录`;
// 获取时间范围
const dates = filteredData.map(item => new Date(`${item.date} ${item.time}`));
const minDate = new Date(Math.min(...dates));
const maxDate = new Date(Math.max(...dates));
const formatDate = (date) => {
return `${date.getFullYear()}-${(date.getMonth()+1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`;
};
statsTimeRange.textContent = `时间范围:${formatDate(minDate)} 至 ${formatDate(maxDate)}`;
}
// 更新车辆信息
if (filteredData.length > 0) {
const latestData = filteredData[0]; // 最新的一条数据
document.getElementById('currentLocation').textContent = latestData.location;
document.getElementById('lastUpdateTime').textContent = `${latestData.date} ${latestData.time}`;
document.getElementById('driverName').textContent = latestData.driver;
}
}
// 打开对话框
openModalBtn.addEventListener('click', () => {
modalOverlay.style.display = 'flex';
document.body.style.overflow = 'hidden'; // 防止背景滚动
initDriverSelect();
initHistoryList();
});
// 关闭对话框
closeModalBtn.addEventListener('click', () => {
modalOverlay.style.display = 'none';
document.body.style.overflow = 'auto';
});
// 点击背景关闭对话框
modalOverlay.addEventListener('click', (e) => {
if (e.target === modalOverlay) {
modalOverlay.style.display = 'none';
document.body.style.overflow = 'auto';
}
});
// 全屏切换
let isFullscreen = false;
fullscreenBtn.addEventListener('click', () => {
isFullscreen = !isFullscreen;
if (isFullscreen) {
modalContainer.classList.add('fullscreen');
fullscreenBtn.innerHTML = '<i class="fas fa-compress"></i>';
fullscreenBtn.title = "退出全屏";
} else {
modalContainer.classList.remove('fullscreen');
fullscreenBtn.innerHTML = '<i class="fas fa-expand"></i>';
fullscreenBtn.title = "全屏";
}
});
// 搜索历史轨迹
searchHistoryBtn.addEventListener('click', () => {
const selectedDriver = driverSelect.value;
const startDateValue = startDate.value;
const endDateValue = endDate.value;
// 验证日期范围
if (startDateValue && endDateValue && new Date(startDateValue) > new Date(endDateValue)) {
alert('开始日期不能晚于结束日期');
return;
}
renderHistoryList(selectedDriver, startDateValue, endDateValue);
});
// 模拟地图交互
mapContainer.addEventListener('click', (e) => {
if (e.target === mapContainer) {
// 在点击位置添加一个临时标记
const x = e.offsetX;
const y = e.offsetY;
const marker = document.createElement('div');
marker.style.position = 'absolute';
marker.style.left = `${x}px`;
marker.style.top = `${y}px`;
marker.style.width = '10px';
marker.style.height = '10px';
marker.style.backgroundColor = '#1890ff';
marker.style.border = '2px solid white';
marker.style.borderRadius = '50%';
marker.style.boxShadow = '0 0 4px rgba(0,0,0,0.2)';
marker.style.zIndex = '10';
mapContainer.appendChild(marker);
// 3秒后移除标记
setTimeout(() => {
marker.remove();
}, 3000);
}
});
// 添加键盘事件支持
document.addEventListener('keydown', (e) => {
// ESC键关闭对话框
if (e.key === 'Escape' && modalOverlay.style.display === 'flex') {
modalOverlay.style.display = 'none';
document.body.style.overflow = 'auto';
}
// F键切换全屏
if (e.key === 'f' && modalOverlay.style.display === 'flex') {
e.preventDefault();
fullscreenBtn.click();
}
// Enter键触发搜索
if (e.key === 'Enter' && modalOverlay.style.display === 'flex') {
e.preventDefault();
searchHistoryBtn.click();
}
});
// 初始化日期输入框的最大值
startDate.max = todayStr;
endDate.max = todayStr;
// 当开始日期变化时,自动设置结束日期的最小值
startDate.addEventListener('change', function() {
endDate.min = this.value;
});
// 当结束日期变化时,自动设置开始日期的最大值
endDate.addEventListener('change', function() {
startDate.max = this.value;
});
</script>
</body>
</html>