作为一名长期从事智能停车系统开发的工程师,我深知传统停车场管理面临的痛点:人工成本高、效率低下、收费混乱。今天要分享的这套基于SpringBoot+Vue的无人值守停车场解决方案,正是我们团队经过两年实战打磨的成果。系统已在多个商业综合体落地,平均降低人力成本60%,通行效率提升3倍以上。
这套系统的核心价值在于"三高一低":高兼容性(适配90%主流车牌识别设备)、高智能化(AI识别+自动计费)、高可靠性(7×24小时无人值守)、低成本部署(无需更换原有硬件)。特别适合商场、写字楼、物流园区等需要降本增效的场景。
系统采用经典的前后端分离架构,这是我经过多个项目验证后的最佳实践方案:
code复制客户端层:Vue.js构建的Web管理端 + 商户APP + 车主小程序
接入层:Nginx负载均衡 + SpringCloud Gateway
服务层:SpringBoot微服务集群(认证服务/计费服务/识别服务)
数据层:MySQL主从集群 + Redis缓存 + MinIO文件存储
IoT层:车牌识别相机 + 道闸控制器 + 车位检测器
关键设计原则:模块间通过RESTful API通信,重要服务采用双机热备,所有接口都有熔断降级机制。这种架构既保证了扩展性,又能满足停车场业务的高可用要求。
前端技术栈:
后端技术栈:
数据库设计:
sql复制CREATE TABLE `park_order` (
`id` bigint NOT NULL AUTO_INCREMENT,
`plate_no` varchar(12) COMMENT '车牌号',
`entry_time` datetime COMMENT '入场时间',
`exit_time` datetime COMMENT '出场时间',
`duration` int COMMENT '停放分钟数',
`amount` decimal(10,2) COMMENT '应收金额',
`payment_status` tinyint COMMENT '0未付 1已付',
`channel_id` varchar(32) COMMENT '支付渠道ID',
PRIMARY KEY (`id`),
INDEX `idx_plate_no` (`plate_no`),
INDEX `idx_entry_time` (`entry_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
计费模块采用策略模式设计,支持六种计费方案自由切换:
java复制// 计费策略接口
public interface BillingStrategy {
BigDecimal calculateFee(LocalDateTime entry, LocalDateTime exit);
}
// 商场计费策略(首小时10元,后续每30分钟5元)
public class MallStrategy implements BillingStrategy {
@Override
public BigDecimal calculateFee(LocalDateTime entry, LocalDateTime exit) {
long minutes = Duration.between(entry, exit).toMinutes();
if(minutes <= 60) return new BigDecimal("10");
return new BigDecimal("10")
.add(new BigDecimal(Math.ceil((minutes-60)/30.0) * 5));
}
}
// 小区月卡策略
public class CommunityStrategy implements BillingStrategy {
//...省略实现
}
计费规则配置表:
| 规则ID | 规则类型 | 首时段(分钟) | 首段价格 | 后续时段 | 后续价格 | 封顶金额 |
|---|---|---|---|---|---|---|
| 1 | 商场 | 60 | 10.00 | 30 | 5.00 | 无 |
| 2 | 小区 | - | - | - | - | 300/月 |
通过百度AI接口实现车牌识别,关键处理逻辑:
java复制public class PlateRecognitionService {
// 百度AI客户端单例
private static final AipImageClassify client = new AipImageClassify(
"APP_ID", "API_KEY", "SECRET_KEY");
public String recognize(InputStream imageStream) {
// 图片预处理:压缩+增强对比度
byte[] processedImage = ImageProcessor.compress(imageStream);
// 调用百度API
JSONObject res = client.vehicleLicense(processedImage, new HashMap<>());
// 结果解析
if(res.has("words_result")) {
return res.getJSONObject("words_result")
.getString("plate_no");
}
throw new RecognitionException("识别失败");
}
}
性能优化点:
支付模块最易出现账务问题,我们的解决方案:
code复制1. 出场时生成支付二维码(含订单号+金额+时间戳)
2. 用户扫码后,系统轮询支付状态(每2秒一次)
3. 收到支付回调后:
- 校验签名
- 核对金额
- 更新订单状态
- 开闸放行
4. 每日凌晨2点跑对账任务,修复异常订单
对账SQL示例:
sql复制-- 查找支付成功但未放行的车辆
SELECT o.* FROM park_order o
LEFT JOIN gate_log g ON o.id = g.order_id
WHERE o.payment_status = 1
AND g.id IS NULL
AND o.exit_time > NOW() - INTERVAL 1 DAY;
| 设备类型 | 接口方式 | 通信协议 | 注意事项 |
|---|---|---|---|
| 车牌识别相机 | RS485/网口 | ONVIF | 需设置心跳包间隔<30秒 |
| 道闸控制器 | 继电器 | 干接点信号 | 要加装光电隔离模块 |
| 车位检测器 | LoRa | MQTT | 注意天线防雷 |
| 语音播报器 | 音频线 | - | 需做阻抗匹配 |
application-prod.properties关键配置:
properties复制# 数据库连接池
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.connection-timeout=30000
# Redis缓存
spring.redis.timeout=5000
spring.redis.lettuce.pool.max-active=32
# 线程池
spring.task.execution.pool.core-size=8
spring.task.execution.pool.max-size=16
# 支付接口超时
payment.wechat.timeout=8000
payment.alipay.timeout=8000
初期遇到雨雪天识别率骤降至70%的问题,通过以下措施提升到92%:
高峰期出现重复计费BUG,解决方案:
java复制RLock lock = redissonClient.getLock("plate_lock:" + plateNo);
lock.lock(5, TimeUnit.SECONDS);
try {
// 业务处理
} finally {
lock.unlock();
}
sql复制ALTER TABLE park_order ADD UNIQUE INDEX udx_plate_exit (plate_no, exit_time);
网络中断时的保障措施:
系统预留了三个重要扩展接口:
java复制public interface SpaceGuidanceService {
List<ParkingSpace> getAvailableSpaces();
void reserveSpace(String plateNo, int spaceId);
}
plantuml复制@startuml
车主 -> 小程序: 扫码充电
小程序 -> 后台: 请求开启充电
后台 -> 充电桩: 发送启动指令
充电桩 -> 后台: 实时上报电量
后台 -> 小程序: 更新充电状态
@enduml
这套系统在XX商场落地后,实现了以下效益指标:
开发过程中最深的体会是:停车场系统看似简单,实则处处暗藏玄机。比如计费模块要处理闰秒、跨天、节假日等边界情况;支付对账要考虑网络抖动、重复通知等异常场景。只有经过真实场景的反复打磨,才能做出真正可靠的系统。