去年接手某物流园区信息化改造时,我深刻体会到传统Excel管理车辆的痛点——数据不同步、审批流程混乱、维保记录缺失。这正是我们开发这套车辆管理系统的初衷。系统采用SpringBoot+Vue的主流技术栈,实现了从车辆档案、调度分配到维修保养的全生命周期数字化管理。特别在高峰期调度场景下,系统吞吐量稳定保持在800+ TPS,MySQL查询响应时间始终低于50ms。
对于Java全栈开发者而言,这个项目涵盖了:
选择SpringBoot而非传统SSM框架,主要基于:
yaml复制management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: always
前端选用Vue3+TypeScript的组合,主要考虑:
车辆核心表的ER设计要点:
sql复制CREATE TABLE `t_vehicle` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '雪花算法ID',
`plate_no` VARCHAR(20) NOT NULL COMMENT '车牌号(加密存储)',
`gps_device_id` VARCHAR(64) COMMENT '物联网设备ID',
`maintain_cycle` INT DEFAULT 90 COMMENT '保养周期(天)',
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '1-待命 2-任务中 3-维修中',
`current_mileage` DECIMAL(10,2) COMMENT '当前里程(km)',
`gps_location` POINT SRID 4326 COMMENT 'GIS空间坐标',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_plate` (`plate_no`),
SPATIAL KEY `idx_gps` (`gps_location`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
关键设计决策:空间索引加速地理查询、车牌号采用AES加密存储、状态机设计避免非法状态流转
基于贪心算法的调度核心逻辑:
java复制public List<DispatchResult> autoDispatch(List<Vehicle> vehicles, List<TransportTask> tasks) {
// 1. 过滤可用车辆(状态=待命+剩余里程>任务里程)
List<Vehicle> candidates = vehicles.stream()
.filter(v -> v.getStatus() == VehicleStatus.IDLE)
.filter(v -> v.getCurrentMileage() < v.getMaxMileage())
.sorted(Comparator.comparingDouble(Vehicle::getCurrentMileage))
.collect(Collectors.toList());
// 2. 任务按优先级排序
tasks.sort(Comparator.comparing(TransportTask::getPriority).reversed());
// 3. 双指针匹配
List<DispatchResult> results = new ArrayList<>();
int vIdx = 0, tIdx = 0;
while (vIdx < candidates.size() && tIdx < tasks.size()) {
Vehicle vehicle = candidates.get(vIdx);
TransportTask task = tasks.get(tIdx);
if (checkFit(vehicle, task)) {
results.add(new DispatchResult(vehicle.getId(), task.getId()));
vIdx++;
tIdx++;
} else {
tIdx++;
}
}
return results;
}
性能优化点:
基于历史数据的预测模型:
python复制# Python脚本示例(通过Jython集成)
import pandas as pd
from sklearn.ensemble import RandomForestRegressor
def predict_maintenance(df):
X = df[['mileage', 'age', 'maintain_count']]
y = df['next_maintain_mileage']
model = RandomForestRegressor(n_estimators=100)
model.fit(X, y)
return model.predict([[current_mileage, vehicle_age, maintain_count]])
踩坑记录:初期直接使用MySQL计算导致性能瓶颈,后改为Spark批处理+Redis缓存结果
现象:车辆状态出现"任务中"和"待命"的脏数据
解决方案:
java复制@Update("UPDATE t_vehicle SET status=#{newStatus}, version=version+1
WHERE id=#{id} AND version=#{version}")
int updateWithLock(Vehicle vehicle);
java复制public enum VehicleStatus {
IDLE(1, Arrays.asList(MAINTAINING)),
ON_TASK(2, Arrays.asList(IDLE)),
MAINTAINING(3, Arrays.asList(IDLE));
private final int code;
private final List<VehicleStatus> allowedNext;
// 状态转移校验逻辑
public boolean canTransferTo(VehicleStatus next) {
return allowedNext.contains(next);
}
}
原始方案:MySQL单表存储导致查询性能骤降
改进方案:
sql复制-- 查找5公里内的车辆
SELECT id, ST_Distance_Sphere(gps_location, POINT(116.404, 39.915)) AS distance
FROM t_vehicle
WHERE ST_Contains(ST_Buffer(POINT(116.404, 39.915), 5000), gps_location)
ORDER BY distance;
Element Plus表格优化方案:
vue复制<el-table
:data="tableData"
height="600"
:row-key="row => row.id"
:virtual-scroll="true"
:estimated-row-height="54">
<el-table-column prop="plateNo" label="车牌号" width="120" />
<!-- 其他列 -->
</el-table>
关键配置:
高德地图集成要点:
javascript复制import AMapLoader from '@amap/amap-jsapi-loader';
const initMap = async () => {
const AMap = await AMapLoader.load({
key: '您的高德key',
version: '2.0',
plugins: ['AMap.MarkerClusterer']
});
const map = new AMap.Map('map-container', {
zoom: 10,
center: [116.397428, 39.90923]
});
// 实时车辆位置标记
watch(vehicles, (newVal) => {
newVal.forEach(v => {
new AMap.Marker({
position: [v.lng, v.lat],
content: `<div class="vehicle-marker">${v.plateNo}</div>`
}).addTo(map);
});
});
};
性能陷阱:
生产环境编排示例:
yaml复制version: '3.8'
services:
backend:
image: vehicle-backend:1.2.0
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
depends_on:
- redis
- mysql
frontend:
image: nginx:1.21
ports:
- "80:80"
volumes:
- ./dist:/usr/share/nginx/html
- ./nginx.conf:/etc/nginx/conf.d/default.conf
mysql:
image: mysql:8.0
command: --default-authentication-plugin=mysql_native_password
volumes:
- ./mysql-data:/var/lib/mysql
redis:
image: redis:6.2-alpine
SpringBoot暴露的监控指标:
java复制@Bean
public MeterRegistryCustomizer<PrometheusMeterRegistry> configureMetrics() {
return registry -> {
registry.config().commonTags("application", "vehicle-system");
new JvmMemoryMetrics().bindTo(registry);
new JvmGcMetrics().bindTo(registry);
};
}
Grafana监控看板关键指标:
在实际运营中我们持续迭代了这些功能:
源码中特别值得关注的工程实践:
这个项目让我深刻体会到:好的管理系统不是功能的堆砌,而是要在业务闭环(车辆使用-调度-维护)中形成数据驱动的正向循环。比如通过分析维保数据,我们优化了某车型的保养周期从90天调整为75天,直接降低了12%的故障率。