Initial commit: Car Maintenance Management System

Author: Yang Lu

School: Liaoning Institute of Science and Technology

Major: Computer Science and Technology

Class: BZ246

Tech Stack:

- Backend: Spring Boot 2.7.18 + JPA + MySQL

- Frontend: HTML5 + CSS3 + JavaScript

Features:

- User Management (Admin/Staff/Customer roles)

- Vehicle Archive Management

- Service Order Management

- Parts Inventory Management

- Online Appointment Service

- Data Statistics and Analysis

Generated with Claude Code

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
wangziqi
2026-01-07 14:28:50 +08:00
commit cfae122685
45 changed files with 5447 additions and 0 deletions

View File

@@ -0,0 +1,270 @@
<!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 rel="stylesheet" href="../css/common.css">
<link rel="stylesheet" href="../css/dashboard.css">
</head>
<body>
<div class="dashboard-container">
<div class="sidebar">
<div class="sidebar-header">
<h2>车管家系统</h2>
<p>工作人员控制台</p>
</div>
<div class="sidebar-menu">
<div class="menu-item active" onclick="showSection('overview')">
<span class="menu-icon">📊</span>
<span>工作概览</span>
</div>
<div class="menu-item" onclick="showSection('myorders')">
<span class="menu-icon">📋</span>
<span>我的工单</span>
</div>
<div class="menu-item" onclick="showSection('vehicles')">
<span class="menu-icon">🚗</span>
<span>车辆查询</span>
</div>
<div class="menu-item" onclick="showSection('parts')">
<span class="menu-icon">🔧</span>
<span>配件查询</span>
</div>
</div>
</div>
<div class="main-content">
<div class="top-nav">
<div class="top-nav-left">
<h1>工作人员仪表板</h1>
</div>
<div class="top-nav-right">
<div class="user-info">
<div class="user-avatar" id="userAvatar">S</div>
<span class="user-name" id="userName">工作人员</span>
</div>
<button class="btn-logout" onclick="utils.logout()">退出登录</button>
</div>
</div>
<div id="overview-section" class="section">
<div class="stats-grid">
<div class="stat-card">
<div class="stat-icon blue">📋</div>
<div class="stat-info">
<h3 id="myOrdersCount">0</h3>
<p>我的工单</p>
</div>
</div>
<div class="stat-card">
<div class="stat-icon orange"></div>
<div class="stat-info">
<h3 id="inProgressCount">0</h3>
<p>进行中</p>
</div>
</div>
<div class="stat-card">
<div class="stat-icon green"></div>
<div class="stat-info">
<h3 id="completedCount">0</h3>
<p>已完成</p>
</div>
</div>
</div>
<div class="content-card">
<div class="content-header">
<h2>待处理工单</h2>
</div>
<div class="content-body">
<table class="table">
<thead>
<tr>
<th>工单编号</th>
<th>服务类型</th>
<th>车牌号</th>
<th>状态</th>
<th>预约时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="pendingOrdersBody">
<tr><td colspan="6" class="empty-state">暂无待处理工单</td></tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="myorders-section" class="section" style="display: none;">
<div class="content-card">
<div class="content-header">
<h2>我的工单列表</h2>
</div>
<div class="content-body">
<table class="table">
<thead>
<tr>
<th>工单编号</th>
<th>服务类型</th>
<th>车牌号</th>
<th>客户姓名</th>
<th>状态</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="myOrdersBody">
<tr><td colspan="7" class="empty-state">加载中...</td></tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="vehicles-section" class="section" style="display: none;">
<div class="toolbar">
<div class="search-box">
<input type="text" id="searchVehicle" placeholder="输入车牌号查询...">
<button onclick="searchVehicle()">🔍</button>
</div>
</div>
<div class="content-card">
<div class="content-body">
<div id="vehicleResult"></div>
</div>
</div>
</div>
<div id="parts-section" class="section" style="display: none;">
<div class="toolbar">
<div class="search-box">
<input type="text" id="searchPart" placeholder="搜索配件...">
<button onclick="searchParts()">🔍</button>
</div>
</div>
<div class="content-card">
<div class="content-body">
<table class="table">
<thead>
<tr>
<th>配件编号</th>
<th>配件名称</th>
<th>类别</th>
<th>库存数量</th>
<th>单价</th>
</tr>
</thead>
<tbody id="partsBody">
<tr><td colspan="5" class="empty-state">请输入关键词搜索配件</td></tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<script src="../js/config.js"></script>
<script src="../js/api.js"></script>
<script>
if (!utils.checkAuth() || !utils.hasRole('staff')) {
window.location.href = '../login.html';
}
window.addEventListener('DOMContentLoaded', () => {
const user = utils.getCurrentUser();
if (user) {
document.getElementById('userName').textContent = user.realName;
document.getElementById('userAvatar').textContent = user.realName.charAt(0);
loadStaffData(user.userId);
}
});
function showSection(name) {
document.querySelectorAll('.section').forEach(s => s.style.display = 'none');
document.querySelectorAll('.menu-item').forEach(m => m.classList.remove('active'));
event.currentTarget.classList.add('active');
document.getElementById(name + '-section').style.display = 'block';
}
async function loadStaffData(staffId) {
try {
const response = await api.get(API_ENDPOINTS.ORDERS);
if (response.code === 200 && response.data) {
const myOrders = response.data.filter(o => o.staffId === staffId);
const inProgress = myOrders.filter(o => o.status === 'in_progress');
const completed = myOrders.filter(o => o.status === 'completed');
document.getElementById('myOrdersCount').textContent = myOrders.length;
document.getElementById('inProgressCount').textContent = inProgress.length;
document.getElementById('completedCount').textContent = completed.length;
}
} catch (error) {
console.error('加载数据失败:', error);
}
}
async function searchVehicle() {
const plate = document.getElementById('searchVehicle').value.trim();
if (!plate) {
utils.showError('请输入车牌号');
return;
}
try {
const response = await api.get(API_ENDPOINTS.VEHICLE_BY_PLATE(plate));
if (response.code === 200 && response.data) {
const v = response.data;
document.getElementById('vehicleResult').innerHTML = `
<div class="card">
<h3>车辆信息</h3>
<p><strong>车牌号:</strong> ${v.licensePlate}</p>
<p><strong>品牌型号:</strong> ${v.brand} ${v.model}</p>
<p><strong>颜色:</strong> ${v.color || '-'}</p>
<p><strong>车架号:</strong> ${v.vin || '-'}</p>
<p><strong>里程数:</strong> ${v.mileage || 0} 公里</p>
<p><strong>状态:</strong> ${utils.getStatusBadge(v.status)}</p>
</div>
`;
} else {
document.getElementById('vehicleResult').innerHTML = '<p class="empty-state">未找到该车辆</p>';
}
} catch (error) {
utils.showError('查询失败');
}
}
async function searchParts() {
try {
const response = await api.get(API_ENDPOINTS.PARTS);
if (response.code === 200 && response.data) {
const tbody = document.getElementById('partsBody');
const keyword = document.getElementById('searchPart').value.toLowerCase();
const filtered = response.data.filter(p =>
p.partName.toLowerCase().includes(keyword) ||
p.partNo.toLowerCase().includes(keyword)
);
if (filtered.length === 0) {
tbody.innerHTML = '<tr><td colspan="5" class="empty-state">未找到配件</td></tr>';
return;
}
tbody.innerHTML = filtered.map(p => `
<tr>
<td>${p.partNo}</td>
<td>${p.partName}</td>
<td>${p.category || '-'}</td>
<td>${p.stockQuantity} ${p.unit}</td>
<td>¥${p.unitPrice}</td>
</tr>
`).join('');
}
} catch (error) {
utils.showError('搜索失败');
}
}
</script>
</body>
</html>