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,468 @@
// 管理员仪表板JavaScript
// 检查登录状态和权限
if (!utils.checkAuth() || !utils.hasRole('admin')) {
window.location.href = '../login.html';
}
// 页面加载时初始化
window.addEventListener('DOMContentLoaded', () => {
initializeDashboard();
loadOverviewData();
});
// 初始化仪表板
function initializeDashboard() {
const user = utils.getCurrentUser();
if (user) {
document.getElementById('userName').textContent = user.realName;
document.getElementById('userAvatar').textContent = user.realName.charAt(0);
}
}
// 切换显示区域
function showSection(sectionName) {
// 隐藏所有区域
const sections = document.querySelectorAll('.section');
sections.forEach(section => section.style.display = 'none');
// 移除所有菜单项的活动状态
const menuItems = document.querySelectorAll('.menu-item');
menuItems.forEach(item => item.classList.remove('active'));
// 显示选中的区域
document.getElementById(`${sectionName}-section`).style.display = 'block';
// 设置对应菜单项为活动状态
event.currentTarget.classList.add('active');
// 加载对应数据
switch(sectionName) {
case 'overview':
loadOverviewData();
break;
case 'users':
loadUsers();
break;
case 'vehicles':
loadVehicles();
break;
case 'orders':
loadOrders();
break;
case 'parts':
loadParts();
break;
case 'appointments':
loadAppointments();
break;
}
}
// 加载概览数据
async function loadOverviewData() {
try {
// 加载统计数据
const [usersRes, vehiclesRes, ordersRes, partsRes] = await Promise.all([
api.get(API_ENDPOINTS.USERS),
api.get(API_ENDPOINTS.VEHICLES),
api.get(API_ENDPOINTS.ORDERS),
api.get(API_ENDPOINTS.PARTS_LOW_STOCK)
]);
document.getElementById('totalUsers').textContent = usersRes.data?.length || 0;
document.getElementById('totalVehicles').textContent = vehiclesRes.data?.length || 0;
document.getElementById('totalOrders').textContent = ordersRes.data?.length || 0;
document.getElementById('lowStockParts').textContent = partsRes.data?.length || 0;
// 加载最近工单
if (ordersRes.data && ordersRes.data.length > 0) {
const recentOrders = ordersRes.data.slice(0, 5);
displayRecentOrders(recentOrders);
}
} catch (error) {
console.error('加载概览数据失败:', error);
}
}
// 显示最近工单
async function displayRecentOrders(orders) {
const tbody = document.getElementById('recentOrdersBody');
if (orders.length === 0) {
tbody.innerHTML = '<tr><td colspan="5" class="empty-state">暂无数据</td></tr>';
return;
}
// 获取所有车辆信息
const vehiclesRes = await api.get(API_ENDPOINTS.VEHICLES);
const vehicles = vehiclesRes.data || [];
tbody.innerHTML = orders.map(order => {
const vehicle = vehicles.find(v => v.vehicleId === order.vehicleId);
return `
<tr>
<td>${order.orderNo}</td>
<td>${utils.getServiceTypeText(order.serviceType)}</td>
<td>${vehicle ? vehicle.licensePlate : '-'}</td>
<td>${utils.getStatusBadge(order.status)}</td>
<td>${utils.formatDateTime(order.createTime)}</td>
</tr>
`;
}).join('');
}
// 加载用户列表
async function loadUsers() {
try {
const response = await api.get(API_ENDPOINTS.USERS);
if (response.code === 200 && response.data) {
displayUsers(response.data);
}
} catch (error) {
console.error('加载用户列表失败:', error);
utils.showError('加载用户列表失败');
}
}
// 显示用户列表
function displayUsers(users) {
const tbody = document.getElementById('usersTableBody');
if (users.length === 0) {
tbody.innerHTML = '<tr><td colspan="7" class="empty-state">暂无数据</td></tr>';
return;
}
tbody.innerHTML = users.map(user => `
<tr>
<td>${user.userId}</td>
<td>${user.username}</td>
<td>${user.realName}</td>
<td>${user.phone}</td>
<td>${utils.getRoleText(user.role)}</td>
<td>${user.status === 1 ? '<span class="badge badge-success">启用</span>' : '<span class="badge badge-secondary">禁用</span>'}</td>
<td class="table-actions">
<button class="btn btn-info" onclick="viewUser(${user.userId})">查看</button>
<button class="btn btn-warning" onclick="editUser(${user.userId})">编辑</button>
<button class="btn btn-danger" onclick="deleteUser(${user.userId})">删除</button>
</td>
</tr>
`).join('');
}
// 加载车辆列表
async function loadVehicles() {
try {
const response = await api.get(API_ENDPOINTS.VEHICLES);
if (response.code === 200 && response.data) {
displayVehicles(response.data);
}
} catch (error) {
console.error('加载车辆列表失败:', error);
utils.showError('加载车辆列表失败');
}
}
// 显示车辆列表
function displayVehicles(vehicles) {
const tbody = document.getElementById('vehiclesTableBody');
if (vehicles.length === 0) {
tbody.innerHTML = '<tr><td colspan="6" class="empty-state">暂无数据</td></tr>';
return;
}
tbody.innerHTML = vehicles.map(vehicle => `
<tr>
<td>${vehicle.licensePlate}</td>
<td>${vehicle.brand} ${vehicle.model}</td>
<td>${vehicle.color || '-'}</td>
<td>${vehicle.mileage || 0} 公里</td>
<td>${utils.getStatusBadge(vehicle.status)}</td>
<td class="table-actions">
<button class="btn btn-info" onclick="viewVehicle(${vehicle.vehicleId})">查看</button>
<button class="btn btn-warning" onclick="editVehicle(${vehicle.vehicleId})">编辑</button>
<button class="btn btn-danger" onclick="deleteVehicle(${vehicle.vehicleId})">删除</button>
</td>
</tr>
`).join('');
}
// 加载工单列表
async function loadOrders(status = '') {
try {
const url = status ? API_ENDPOINTS.ORDERS_BY_STATUS(status) : API_ENDPOINTS.ORDERS;
const response = await api.get(url);
if (response.code === 200 && response.data) {
displayOrders(response.data);
}
} catch (error) {
console.error('加载工单列表失败:', error);
utils.showError('加载工单列表失败');
}
}
// 显示工单列表
async function displayOrders(orders) {
const tbody = document.getElementById('ordersTableBody');
if (orders.length === 0) {
tbody.innerHTML = '<tr><td colspan="7" class="empty-state">暂无数据</td></tr>';
return;
}
const vehiclesRes = await api.get(API_ENDPOINTS.VEHICLES);
const vehicles = vehiclesRes.data || [];
tbody.innerHTML = orders.map(order => {
const vehicle = vehicles.find(v => v.vehicleId === order.vehicleId);
return `
<tr>
<td>${order.orderNo}</td>
<td>${utils.getServiceTypeText(order.serviceType)}</td>
<td>${vehicle ? vehicle.licensePlate : '-'}</td>
<td>¥${order.totalCost || 0}</td>
<td>${utils.getStatusBadge(order.status)}</td>
<td>${utils.formatDateTime(order.createTime)}</td>
<td class="table-actions">
<button class="btn btn-info" onclick="viewOrder(${order.orderId})">查看</button>
<button class="btn btn-warning" onclick="editOrder(${order.orderId})">编辑</button>
<button class="btn btn-danger" onclick="deleteOrder(${order.orderId})">删除</button>
</td>
</tr>
`;
}).join('');
}
// 加载配件列表
async function loadParts() {
try {
const response = await api.get(API_ENDPOINTS.PARTS);
if (response.code === 200 && response.data) {
displayParts(response.data);
}
} catch (error) {
console.error('加载配件列表失败:', error);
utils.showError('加载配件列表失败');
}
}
// 显示配件列表
function displayParts(parts) {
const tbody = document.getElementById('partsTableBody');
if (parts.length === 0) {
tbody.innerHTML = '<tr><td colspan="7" class="empty-state">暂无数据</td></tr>';
return;
}
tbody.innerHTML = parts.map(part => {
const isLowStock = part.stockQuantity <= part.minStock;
return `
<tr ${isLowStock ? 'style="background-color: #fff1f0;"' : ''}>
<td>${part.partNo}</td>
<td>${part.partName}</td>
<td>${part.category || '-'}</td>
<td>${part.stockQuantity} ${part.unit}${isLowStock ? ' <span class="badge badge-danger">预警</span>' : ''}</td>
<td>¥${part.unitPrice}</td>
<td>${part.status === 1 ? '<span class="badge badge-success">正常</span>' : '<span class="badge badge-secondary">停用</span>'}</td>
<td class="table-actions">
<button class="btn btn-info" onclick="viewPart(${part.partId})">查看</button>
<button class="btn btn-warning" onclick="editPart(${part.partId})">编辑</button>
<button class="btn btn-danger" onclick="deletePart(${part.partId})">删除</button>
</td>
</tr>
`;
}).join('');
}
// 加载预约列表
async function loadAppointments(status = '') {
try {
const url = status ? API_ENDPOINTS.APPOINTMENTS_BY_STATUS(status) : API_ENDPOINTS.APPOINTMENTS;
const response = await api.get(url);
if (response.code === 200 && response.data) {
displayAppointments(response.data);
}
} catch (error) {
console.error('加载预约列表失败:', error);
utils.showError('加载预约列表失败');
}
}
// 显示预约列表
async function displayAppointments(appointments) {
const tbody = document.getElementById('appointmentsTableBody');
if (appointments.length === 0) {
tbody.innerHTML = '<tr><td colspan="7" class="empty-state">暂无数据</td></tr>';
return;
}
const vehiclesRes = await api.get(API_ENDPOINTS.VEHICLES);
const vehicles = vehiclesRes.data || [];
tbody.innerHTML = appointments.map(appointment => {
const vehicle = vehicles.find(v => v.vehicleId === appointment.vehicleId);
return `
<tr>
<td>${appointment.appointmentId}</td>
<td>${utils.getServiceTypeText(appointment.serviceType)}</td>
<td>${vehicle ? vehicle.licensePlate : '-'}</td>
<td>${utils.formatDateTime(appointment.appointmentTime)}</td>
<td>${appointment.contactPhone}</td>
<td>${utils.getStatusBadge(appointment.status)}</td>
<td class="table-actions">
<button class="btn btn-success" onclick="confirmAppointment(${appointment.appointmentId})">确认</button>
<button class="btn btn-danger" onclick="cancelAppointment(${appointment.appointmentId})">取消</button>
</td>
</tr>
`;
}).join('');
}
// 过滤工单
function filterOrders() {
const status = document.getElementById('orderStatusFilter').value;
loadOrders(status);
}
// 过滤预约
function filterAppointments() {
const status = document.getElementById('appointmentStatusFilter').value;
loadAppointments(status);
}
// 搜索用户
function searchUsers() {
const keyword = document.getElementById('searchUser').value.toLowerCase();
// 实现搜索逻辑
}
// 搜索车辆
function searchVehicles() {
const keyword = document.getElementById('searchVehicle').value.toLowerCase();
// 实现搜索逻辑
}
// 搜索配件
function searchParts() {
const keyword = document.getElementById('searchPart').value.toLowerCase();
// 实现搜索逻辑
}
// 显示低库存配件
async function showLowStockParts() {
try {
const response = await api.get(API_ENDPOINTS.PARTS_LOW_STOCK);
if (response.code === 200 && response.data) {
displayParts(response.data);
utils.showSuccess(`找到 ${response.data.length} 个库存预警配件`);
}
} catch (error) {
console.error('加载库存预警失败:', error);
utils.showError('加载库存预警失败');
}
}
// 占位函数 - 实际项目中需要实现完整功能
function showAddUserModal() { alert('添加用户功能'); }
function viewUser(id) { alert('查看用户: ' + id); }
function editUser(id) { alert('编辑用户: ' + id); }
async function deleteUser(id) {
if (utils.confirm('确定要删除此用户吗?')) {
try {
const response = await api.delete(API_ENDPOINTS.USER_BY_ID(id));
if (response.code === 200) {
utils.showSuccess('删除成功');
loadUsers();
} else {
utils.showError(response.message);
}
} catch (error) {
utils.showError('删除失败');
}
}
}
function showAddVehicleModal() { alert('添加车辆功能'); }
function viewVehicle(id) { alert('查看车辆: ' + id); }
function editVehicle(id) { alert('编辑车辆: ' + id); }
async function deleteVehicle(id) {
if (utils.confirm('确定要删除此车辆吗?')) {
try {
const response = await api.delete(API_ENDPOINTS.VEHICLE_BY_ID(id));
if (response.code === 200) {
utils.showSuccess('删除成功');
loadVehicles();
} else {
utils.showError(response.message);
}
} catch (error) {
utils.showError('删除失败');
}
}
}
function showAddOrderModal() { alert('创建工单功能'); }
function viewOrder(id) { alert('查看工单: ' + id); }
function editOrder(id) { alert('编辑工单: ' + id); }
async function deleteOrder(id) {
if (utils.confirm('确定要删除此工单吗?')) {
try {
const response = await api.delete(API_ENDPOINTS.ORDER_BY_ID(id));
if (response.code === 200) {
utils.showSuccess('删除成功');
loadOrders();
} else {
utils.showError(response.message);
}
} catch (error) {
utils.showError('删除失败');
}
}
}
function showAddPartModal() { alert('添加配件功能'); }
function viewPart(id) { alert('查看配件: ' + id); }
function editPart(id) { alert('编辑配件: ' + id); }
async function deletePart(id) {
if (utils.confirm('确定要删除此配件吗?')) {
try {
const response = await api.delete(API_ENDPOINTS.PART_BY_ID(id));
if (response.code === 200) {
utils.showSuccess('删除成功');
loadParts();
} else {
utils.showError(response.message);
}
} catch (error) {
utils.showError('删除失败');
}
}
}
async function confirmAppointment(id) {
try {
const response = await api.put(API_ENDPOINTS.APPOINTMENT_BY_ID(id), { status: 'confirmed' });
if (response.code === 200) {
utils.showSuccess('预约已确认');
loadAppointments();
} else {
utils.showError(response.message);
}
} catch (error) {
utils.showError('操作失败');
}
}
async function cancelAppointment(id) {
if (utils.confirm('确定要取消此预约吗?')) {
try {
const response = await api.put(API_ENDPOINTS.CANCEL_APPOINTMENT(id));
if (response.code === 200) {
utils.showSuccess('预约已取消');
loadAppointments();
} else {
utils.showError(response.message);
}
} catch (error) {
utils.showError('操作失败');
}
}
}