Files
car-maintenance-system/frontend/staff/dashboard.html
wangziqi ea9c94dfeb add
2026-01-07 16:18:56 +08:00

366 lines
17 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>工作人员仪表板 - 车管家4S店车辆维保管理系统</title>
<link href="/lib/bootstrap.min.css" rel="stylesheet">
<link href="/lib/bootstrap-icons.css" rel="stylesheet">
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<div class="dashboard-wrapper">
<nav class="sidebar">
<div class="sidebar-header">
<i class="bi bi-car-front-fill fs-1 d-block mb-2"></i>
<h5 class="mb-1">车管家系统</h5>
<small>工作人员控制台</small>
</div>
<div class="mt-4">
<a class="menu-item active" onclick="showSection('overview')">
<i class="bi bi-speedometer2"></i>
<span>工作概览</span>
</a>
<a class="menu-item" onclick="showSection('myorders')">
<i class="bi bi-clipboard-data"></i>
<span>我的工单</span>
</a>
<a class="menu-item" onclick="showSection('search-vehicle')">
<i class="bi bi-search"></i>
<span>车辆查询</span>
</a>
<a class="menu-item" onclick="showSection('search-parts')">
<i class="bi bi-box-seam"></i>
<span>配件查询</span>
</a>
</div>
</nav>
<main class="main-content">
<div class="top-navbar">
<div class="d-flex align-items-center">
<h5 class="mb-0 me-3">
<i class="bi bi-speedometer2"></i> 工作人员仪表板
</h5>
</div>
<div class="d-flex align-items-center gap-3">
<div class="dropdown">
<button class="btn btn-outline-light dropdown-toggle" type="button" data-bs-toggle="dropdown">
<i class="bi bi-person-circle"></i>
<span id="userName">工作人员</span>
</button>
<ul class="dropdown-menu dropdown-menu-end">
<li><h6 class="dropdown-header">当前角色</h6></li>
<li><span class="dropdown-item" id="userRole"></span></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#" onclick="Utils.logout()">
<i class="bi bi-box-arrow-right"></i> 退出登录
</a></li>
</ul>
</div>
</div>
</div>
<!-- 工作概览 -->
<div id="overview-section" class="content-section">
<div class="row g-4 mb-4">
<div class="col-md-4">
<div class="stat-card">
<div class="stat-icon blue">
<i class="bi bi-clipboard-data-fill"></i>
</div>
<div class="stat-value" id="myOrdersCount">0</div>
<div class="stat-label">我的工单</div>
</div>
</div>
<div class="col-md-4">
<div class="stat-card">
<div class="stat-icon orange">
<i class="bi bi-hourglass-split"></i>
</div>
<div class="stat-value" id="inProgressCount">0</div>
<div class="stat-label">进行中</div>
</div>
</div>
<div class="col-md-4">
<div class="stat-card">
<div class="stat-icon green">
<i class="bi bi-check-circle-fill"></i>
</div>
<div class="stat-value" id="completedCount">0</div>
<div class="stat-label">已完成</div>
</div>
</div>
</div>
<div class="content-card">
<div class="card-header">
<h6 class="mb-0"><i class="bi bi-clock-history"></i> 待处理工单</h6>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-custom">
<thead>
<tr>
<th>工单编号</th>
<th>服务类型</th>
<th>车牌号</th>
<th>状态</th>
<th>预约时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="pendingOrdersTableBody">
<tr>
<td colspan="6" class="text-center text-muted py-4">
<div class="spinner-border spinner-border-sm me-2"></div>
加载中...
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- 我的工单 -->
<div id="myorders-section" class="content-section" style="display: none;">
<div class="content-card">
<div class="card-header">
<h6 class="mb-0"><i class="bi bi-clipboard-data"></i> 我的工单列表</h6>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-custom">
<thead>
<tr>
<th>工单编号</th>
<th>服务类型</th>
<th>车牌号</th>
<th>客户姓名</th>
<th>状态</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="myOrdersTableBody">
<tr>
<td colspan="7" class="text-center text-muted py-4">加载中...</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- 车辆查询 -->
<div id="search-vehicle-section" class="content-section" style="display: none;">
<div class="content-card">
<div class="card-header">
<h6 class="mb-0"><i class="bi bi-search"></i> 车辆信息查询</h6>
</div>
<div class="card-body">
<div class="mb-4">
<div class="input-group">
<span class="input-group-text"><i class="bi bi-car-front"></i></span>
<input type="text" class="form-control" id="searchVehiclePlate" placeholder="请输入车牌号查询...">
<button class="btn btn-primary" onclick="searchVehicle()">
<i class="bi bi-search"></i> 查询
</button>
</div>
</div>
<div id="vehicleSearchResult">
<div class="empty-state">
<i class="bi bi-car-front"></i>
<p>请输入车牌号进行查询</p>
</div>
</div>
</div>
</div>
</div>
<!-- 配件查询 -->
<div id="search-parts-section" class="content-section" style="display: none;">
<div class="content-card">
<div class="card-header">
<h6 class="mb-0"><i class="bi bi-box-seam"></i> 配件库存查询</h6>
</div>
<div class="card-body">
<div class="mb-4">
<div class="input-group">
<span class="input-group-text"><i class="bi bi-search"></i></span>
<input type="text" class="form-control" id="searchPartKeyword" placeholder="请输入配件名称或编号...">
<button class="btn btn-primary" onclick="searchParts()">
<i class="bi bi-search"></i> 搜索
</button>
</div>
</div>
<div id="partsSearchResult">
<div class="empty-state">
<i class="bi bi-box-seam"></i>
<p>请输入关键词搜索配件</p>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
<!-- Toast 通知 -->
<div class="toast-container position-fixed top-0 end-0 p-3">
<div id="liveToast" class="toast" role="alert">
<div class="toast-header">
<i class="bi bi-bell me-2" id="toastIcon"></i>
<strong class="me-auto" id="toastTitle">提示</strong>
<button type="button" class="btn-close" data-bs-dismiss="toast"></button>
</div>
<div class="toast-body" id="toastMessage"></div>
</div>
</div>
<!-- Loading 遮罩 -->
<div id="loadingOverlay" class="loading-overlay d-none">
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<script src="/lib/bootstrap.bundle.min.js"></script>
<script src="../js/config.js"></script>
<script src="../js/api.js"></script>
<script>
// 车辆查询
async function searchVehicle() {
const plate = document.getElementById('searchVehiclePlate').value.trim();
if (!plate) {
Utils.showToast('请输入车牌号', 'warning');
return;
}
Utils.loading(true);
try {
const response = await http.get(API.VEHICLE_PLATE(plate));
const resultDiv = document.getElementById('vehicleSearchResult');
if (response.code === 200 && response.data) {
const v = response.data;
resultDiv.innerHTML = `
<div class="card border-primary mb-3">
<div class="card-header bg-primary text-white">
<i class="bi bi-car-front"></i> 车辆信息
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<p class="mb-2"><strong>车牌号:</strong> <span class="badge bg-primary fs-6">${v.licensePlate}</span></p>
<p class="mb-2"><strong>品牌型号:</strong> ${v.brand} ${v.model}</p>
<p class="mb-2"><strong>颜色:</strong> ${v.color || '-'}</p>
<p class="mb-2"><strong>车架号:</strong> ${v.vin || '-'}</p>
</div>
<div class="col-md-6">
<p class="mb-2"><strong>当前里程:</strong> ${v.mileage || 0} 公里</p>
<p class="mb-2"><strong>上次保养:</strong> ${Utils.formatDate(v.lastMaintenanceDate)}</p>
<p class="mb-2"><strong>下次保养:</strong> ${Utils.formatDate(v.nextMaintenanceDate)}</p>
<p class="mb-0"><strong>车辆状态:</strong> ${Utils.getStatusBadge(v.status)}</p>
</div>
</div>
</div>
</div>
`;
} else {
resultDiv.innerHTML = `
<div class="alert alert-warning">
<i class="bi bi-exclamation-triangle"></i> 未找到该车辆
</div>
`;
}
} catch (error) {
console.error('查询失败:', error);
Utils.showToast('查询失败', 'error');
} finally {
Utils.loading(false);
}
}
// 配件搜索
async function searchParts() {
const keyword = document.getElementById('searchPartKeyword').value.trim();
if (!keyword) {
Utils.showToast('请输入搜索关键词', 'warning');
return;
}
Utils.loading(true);
try {
const response = await http.get(API.PARTS);
const resultDiv = document.getElementById('partsSearchResult');
if (response.code === 200 && response.data) {
const filtered = response.data.filter(p =>
p.partName.toLowerCase().includes(keyword.toLowerCase()) ||
p.partNo.toLowerCase().includes(keyword.toLowerCase())
);
if (filtered.length === 0) {
resultDiv.innerHTML = `
<div class="alert alert-info">
<i class="bi bi-info-circle"></i> 未找到匹配的配件
</div>
`;
return;
}
resultDiv.innerHTML = `
<div class="table-responsive">
<table class="table table-custom">
<thead>
<tr>
<th>配件编号</th>
<th>配件名称</th>
<th>类别</th>
<th>库存数量</th>
<th>单价</th>
</tr>
</thead>
<tbody>
${filtered.map(p => `
<tr>
<td>${p.partNo}</td>
<td>${p.partName}</td>
<td>${p.category || '-'}</td>
<td>
${p.stockQuantity} ${p.unit}
${p.stockQuantity <= p.minStock ? '<span class="badge bg-danger ms-2">库存预警</span>' : ''}
</td>
<td>${Utils.formatMoney(p.unitPrice)}</td>
</tr>
`).join('')}
</tbody>
</table>
</div>
`;
}
} catch (error) {
console.error('搜索失败:', error);
Utils.showToast('搜索失败', 'error');
} finally {
Utils.loading(false);
}
}
// 回车搜索
document.getElementById('searchVehiclePlate')?.addEventListener('keypress', function(e) {
if (e.key === 'Enter') searchVehicle();
});
document.getElementById('searchPartKeyword')?.addEventListener('keypress', function(e) {
if (e.key === 'Enter') searchParts();
});
</script>
<script src="../js/app.js"></script>
</body>
</html>