|
|
@@ -0,0 +1,328 @@
|
|
|
+# 智慧停车 — 进出场流程详解
|
|
|
+
|
|
|
+> 日期:2026-07-30
|
|
|
+
|
|
|
+本文档详细描述车辆进出场完整流程,涵盖车辆类型区分、入场方式、收费结算方式。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 1. 车辆类型体系
|
|
|
+
|
|
|
+系统通过 `vehicle_type` 表 + `shortlist` 名单 + `monthly_card` 包月卡三层结构区分车辆身份。
|
|
|
+
|
|
|
+### 1.1 类型分类
|
|
|
+
|
|
|
+```
|
|
|
+车辆
|
|
|
+ │
|
|
|
+ ├─ 临时车 (vehicle_type.is_system = true)
|
|
|
+ │ └─ 首次进场自动创建,无车主
|
|
|
+ │
|
|
|
+ ├─ 固定车 (vehicle_type.is_system = false,已注册)
|
|
|
+ │ ├─ VIP 车 (owner.is_vip = true 且未过期)
|
|
|
+ │ │ └─ 享受 VIP 折扣 / 免费
|
|
|
+ │ │
|
|
|
+ │ └─ 普通固定车
|
|
|
+ │ └─ 按对应 vehicle_type 计费
|
|
|
+ │
|
|
|
+ ├─ 月租车 (monthly_card 有效记录)
|
|
|
+ │ └─ 自动加入白名单,有效期内免费通行
|
|
|
+ │
|
|
|
+ ├─ 白名单车 (shortlist.list_type = "白名单")
|
|
|
+ │ └─ 放行,不拦截
|
|
|
+ │
|
|
|
+ └─ 黑名单车 (shortlist.list_type = "黑名单")
|
|
|
+ └─ 拦截,禁止进出
|
|
|
+```
|
|
|
+
|
|
|
+### 1.2 优先级判断
|
|
|
+
|
|
|
+进出场时判断顺序:
|
|
|
+
|
|
|
+```
|
|
|
+1. 黑名单 → 拦截,禁止通行
|
|
|
+2. 白名单 → 放行(月租车在此层)
|
|
|
+3. 余额/支付 → 按车辆类型计费规则
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 2. 入场流程
|
|
|
+
|
|
|
+### 2.1 入场方式
|
|
|
+
|
|
|
+| 方式 | 触发 | 场景 | 当前状态 |
|
|
|
+|------|------|------|:--:|
|
|
|
+| RFID 自动 | UHF 读卡器读取标签 | 有标签车辆 | ✅ |
|
|
|
+| 车牌识别 | 摄像头 OCR | 无标签车辆 | ❌ P0-5 |
|
|
|
+| 手动录入 | 操作员在 entryExit.vue 输入 | 无标签/系统故障兜底 | ✅ |
|
|
|
+| 二维码扫码 | 扫描预约/月卡二维码 | 线上预约 | 🔜 规划中 |
|
|
|
+
|
|
|
+### 2.2 入场判断流程
|
|
|
+
|
|
|
+```
|
|
|
+车辆到达入口
|
|
|
+ │
|
|
|
+ ├─ 触发识别 (RFID / 车牌 / 手动)
|
|
|
+ │
|
|
|
+ ▼
|
|
|
+┌─────────────────────────────────────────────────┐
|
|
|
+│ ① 黑名单检查 │
|
|
|
+│ CheckVehicleShortlist(plate, rfid) │
|
|
|
+│ └─ 黑名单 → 🚫 拦截 │
|
|
|
+│ │
|
|
|
+│ ② 车辆查询/创建 │
|
|
|
+│ 存在 → 使用现有记录 │
|
|
|
+│ 不存在 → 自动创建 (临时车类型) │
|
|
|
+│ │
|
|
|
+│ ③ 重复入场检查 │
|
|
|
+│ 有未出场记录 → "车辆已入场" │
|
|
|
+│ │
|
|
|
+│ ④ 入场方式判断 │
|
|
|
+│ ┌─ 月租车 (白名单+未过期) → 🟢 直接放行 │
|
|
|
+│ ├─ 固定车/VIP → 🟢 直接放行 │
|
|
|
+│ └─ 临时车 → 通道判断 │
|
|
|
+│ ├─ 通道允许临停 → 🟡 取票/二维码放行 │
|
|
|
+│ └─ 通道不允许 → 🚫 拦截 │
|
|
|
+│ │
|
|
|
+│ ⑤ 创建入场记录 + 数字票 │
|
|
|
+│ INSERT vehicle_record │
|
|
|
+│ INSERT digital_ticket (state=pending_payment) │
|
|
|
+│ ┌─ RFID → GateOpener 抬杆 │
|
|
|
+│ └─ 手动 → 仅记录,人工抬杆 │
|
|
|
+└─────────────────────────────────────────────────┘
|
|
|
+```
|
|
|
+
|
|
|
+### 2.3 放行策略
|
|
|
+
|
|
|
+| 车辆类型 | 放行方式 | 说明 |
|
|
|
+|---------|---------|------|
|
|
|
+| 月租车(有效期内) | **直接放行** | RFID 识别→白名单验证→抬杆,无需任何操作 |
|
|
|
+| VIP/固定车 | **直接放行** | 已注册车辆,自动抬杆 |
|
|
|
+| 临时车(允许临停通道) | **取票放行** | 按票机按钮出纸质小票/或系统生成数字票,抬杆入场 |
|
|
|
+| 临时车(禁止临停通道) | **拦截** | 提示"临时车禁止入场" |
|
|
|
+| 黑名单 | **拦截** | 任何通道均不放行 |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 3. 出场流程
|
|
|
+
|
|
|
+### 3.1 计费引擎
|
|
|
+
|
|
|
+```
|
|
|
+calculateFee(vehicle, stayTime)
|
|
|
+ │
|
|
|
+ ├─ 1. 查 fee_config WHERE vehicle_type_id = ?
|
|
|
+ │ 未找到/全零 → 默认费率 0.1元/分钟
|
|
|
+ │
|
|
|
+ ├─ 2. VIP 判断
|
|
|
+ │ isVip=true && 过期时间未到 && 非零值
|
|
|
+ │
|
|
|
+ ├─ 3. VIP 免费(isVip && IsVIPFree)→ fee=0
|
|
|
+ │
|
|
|
+ ├─ 4. 免费时长内 (stayTime ≤ StartTime) → fee=0
|
|
|
+ │
|
|
|
+ ├─ 5. 超时计费
|
|
|
+ │ extraUnits = ceil((stayTime - StartTime) / UnitTime)
|
|
|
+ │ fee = StartFee + extraUnits × UnitFee
|
|
|
+ │
|
|
|
+ ├─ 6. 每日封顶 (DailyMaxFee)
|
|
|
+ │
|
|
|
+ └─ 7. VIP 折扣 (fee ×= VIPDiscount)
|
|
|
+```
|
|
|
+
|
|
|
+### 3.2 出场判断流程
|
|
|
+
|
|
|
+```
|
|
|
+车辆到达出口
|
|
|
+ │
|
|
|
+ ├─ 触发识别 (RFID / 车牌 / 手动 / 扫码)
|
|
|
+ │
|
|
|
+ ▼
|
|
|
+┌─────────────────────────────────────────────────┐
|
|
|
+│ ① 黑名单检查 │
|
|
|
+│ └─ 黑名单 → 🚫 拦截 │
|
|
|
+│ │
|
|
|
+│ ② 查询未出场记录 │
|
|
|
+│ 无记录 → "车辆未入场" │
|
|
|
+│ │
|
|
|
+│ ③ 计费 │
|
|
|
+│ calculateFee() → 算出金额 │
|
|
|
+│ │
|
|
|
+│ ④ 结算方式判断 │
|
|
|
+│ ┌─ 月租车 (白名单+未过期) → 🟢 直接放行(免费) │
|
|
|
+│ ├─ VIP (免费策略) → 🟢 直接放行(免费) │
|
|
|
+│ ├─ 临时车 fee=0 → 🟢 直接放行 │
|
|
|
+│ └─ 临时车 fee>0 → 需结算 │
|
|
|
+│ ├─ 人工现金收费 → 收费员收款 → 放行 │
|
|
|
+│ ├─ 出口 POS 刷卡 → 刷卡支付 → 放行 │
|
|
|
+│ └─ 中央缴费机 → 提前扫码支付 → 出口验证 │
|
|
|
+│ │
|
|
|
+│ ⑤ 创建支付记录 + 更新数字票状态 │
|
|
|
+│ INSERT payment_record │
|
|
|
+│ UPDATE digital_ticket (state=paid) │
|
|
|
+│ ┌─ RFID → GateOpener 抬杆 │
|
|
|
+│ └─ 手动 → 仅记录,人工抬杆 │
|
|
|
+└─────────────────────────────────────────────────┘
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 4. 交易结算方式
|
|
|
+
|
|
|
+### 4.1 结算方式对比
|
|
|
+
|
|
|
+| 结算方式 | 适用场景 | 费用归属 | 当前状态 |
|
|
|
+|---------|---------|---------|:--:|
|
|
|
+| **人工收费** | 岗亭操作员收现金 | 记录到 payment_record + shift_record | ✅ |
|
|
|
+| **免密放行** | 月租/VIP/免费车辆 | payment_method=free | ✅ |
|
|
|
+| **出口 POS 机** | 临时车出口刷卡 | 银行卡/会员卡扣款 | 🔜 P0-4 |
|
|
|
+| **中央缴费机** | 车主出场前在机器扫码支付 | 与中央缴费系统对接 | 🔜 规划中 |
|
|
|
+| **线上支付** | APP/小程序预支付 | 微信/支付宝 | 🔜 规划中 |
|
|
|
+
|
|
|
+### 4.2 人工收费流程(当前)
|
|
|
+
|
|
|
+```
|
|
|
+临时车到达出口
|
|
|
+ │
|
|
|
+ ├─ 操作员在 entryExit.vue 输入车牌 → 查询
|
|
|
+ │
|
|
|
+ ├─ ExitPreview → 显示费用/停留时长/车型
|
|
|
+ │
|
|
|
+ ├─ 临时车:弹出支付界面
|
|
|
+ │ ├─ 选择支付方式 [现金] [扫码(预留)] [POS(预留)]
|
|
|
+ │ └─ 选现金 → 输入实收金额 → 显示找零
|
|
|
+ │
|
|
|
+ ├─ 点击"确认收款并放行"
|
|
|
+ │ └─ ExitConfirm(payment_method=cash, paid_amount, operator_id)
|
|
|
+ │
|
|
|
+ └─ 创建 payment_record + 抬杆
|
|
|
+```
|
|
|
+
|
|
|
+### 4.3 中央缴费机流程(规划中)
|
|
|
+
|
|
|
+```
|
|
|
+出场前车主操作流程:
|
|
|
+
|
|
|
+ 车主在自助缴费机 → 输入车牌 或 扫描数字票二维码
|
|
|
+ │
|
|
|
+ ├─ 系统查询 digital_ticket 表
|
|
|
+ │ └─ 找到未支付票 → 显示费用
|
|
|
+ │
|
|
|
+ ├─ 车主选择支付方式
|
|
|
+ │ ├─ 微信/支付宝扫码 → 调支付网关 → 支付成功回调
|
|
|
+ │ └─ 现金/硬币 → 机内识别 → 确认收款
|
|
|
+ │
|
|
|
+ ├─ 支付成功
|
|
|
+ │ └─ digital_ticket.state → paid
|
|
|
+ │ └─ INSERT payment_record
|
|
|
+ │
|
|
|
+ └─ 打印收据(可选)
|
|
|
+
|
|
|
+ 车主开车到出口
|
|
|
+ │
|
|
|
+ ├─ RFID/车牌识别 → 查到 digital_ticket
|
|
|
+ │ └─ state=paid → 🟢 直接抬杆放行
|
|
|
+ │
|
|
|
+ └─ 超时未离场(如缴费后15分钟未到出口)
|
|
|
+ └─ 加收超时费 或 自动过期
|
|
|
+```
|
|
|
+
|
|
|
+### 4.4 出口 POS 机流程(规划中)
|
|
|
+
|
|
|
+```
|
|
|
+临时车到达出口 → 识别车牌
|
|
|
+ │
|
|
|
+ ├─ 计费 → 屏幕显示金额
|
|
|
+ │
|
|
|
+ ├─ POS 机进入待支付状态
|
|
|
+ │ └─ 车主刷卡/闪付/扫码(银行卡或会员卡)
|
|
|
+ │
|
|
|
+ ├─ POS 返回支付成功
|
|
|
+ │
|
|
|
+ └─ 系统记录 payment_record → 抬杆放行
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 5. 月租车完整流程
|
|
|
+
|
|
|
+### 5.1 办卡
|
|
|
+
|
|
|
+```
|
|
|
+操作员 → 包月车管理 → 选择车辆 → 选卡类型(月/季/年)
|
|
|
+ │
|
|
|
+ ├─ INSERT monthly_card (start_date, end_date, fee)
|
|
|
+ │
|
|
|
+ ├─ INSERT shortlist (list_type=白名单, expiration_time=end_date)
|
|
|
+ │
|
|
|
+ └─ INSERT payment_record (card fee)
|
|
|
+```
|
|
|
+
|
|
|
+### 5.2 进出场
|
|
|
+
|
|
|
+```
|
|
|
+月租车到达入口
|
|
|
+ │
|
|
|
+ ├─ RFID/车牌识别
|
|
|
+ │
|
|
|
+ ├─ CheckVehicleShortlist → 白名单 + 未过期
|
|
|
+ │ └─ 🟢 直接抬杆放行(零费用)
|
|
|
+ │
|
|
|
+ └─ 创建 vehicle_record + digital_ticket(记录进出时间)
|
|
|
+
|
|
|
+月租车到达出口
|
|
|
+ │
|
|
|
+ ├─ 白名单 + 未过期
|
|
|
+ │ └─ 🟢 直接抬杆放行
|
|
|
+ │
|
|
|
+ └─ 创建 payment_record(payment_method=free)
|
|
|
+```
|
|
|
+
|
|
|
+### 5.3 到期处理
|
|
|
+
|
|
|
+```
|
|
|
+月租到期 → shortlist.expiration_time < now
|
|
|
+ │
|
|
|
+ ├─ 进场时:白名单过期 → 按车辆原类型计费(如临时车)
|
|
|
+ │
|
|
|
+ ├─ 出场时:白名单过期 → 按普通费率收费
|
|
|
+ │
|
|
|
+ └─ 续费:操作员在包月车管理中点击续费
|
|
|
+ └─ end_date 延长 → shortlist 同步更新
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 6. 数字票状态跟踪
|
|
|
+
|
|
|
+```
|
|
|
+车辆入场
|
|
|
+ │
|
|
|
+ └─ digital_ticket.Create()
|
|
|
+ state: pending_payment
|
|
|
+ │
|
|
|
+ ├─ 月租/VIP/免费 → 直接 paid → exited
|
|
|
+ │
|
|
|
+ └─ 临时车需付费
|
|
|
+ │
|
|
|
+ ├─ 人工收费 → paid → exited
|
|
|
+ ├─ POS 刷卡 → paid → exited(规划)
|
|
|
+ └─ 中央缴费 → paid → exited(规划)
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 7. 代码入口汇总
|
|
|
+
|
|
|
+| 流程节点 | 函数 | 文件 |
|
|
|
+|---------|------|------|
|
|
|
+| RFID 入场 | `HandlePassage()` | `internal/service/parking/passage.go` |
|
|
|
+| 手动入场 | `VehicleEntry()` | `internal/service/vehicle/vehicle.go` |
|
|
|
+| 计费引擎 | `calculateFee()` | `internal/service/vehicle/vehicle.go` |
|
|
|
+| 出场预览 | `ExitPreview()` | `internal/service/vehicle/vehicle.go` |
|
|
|
+| 出场确认 | `ExitConfirm()` | `internal/service/vehicle/vehicle.go` |
|
|
|
+| 名单检查 | `CheckVehicleShortlist()` | `internal/service/vehicle/shortlist.go` |
|
|
|
+| 数字票 | `TicketService.Create()` | `internal/modules/digital-ticket/service/service.go` |
|
|
|
+| 支付处理 | `ProcessPayment()` | `internal/modules/payment/service/service.go` |
|
|
|
+| 通道事件 | `PushChannelEvent()` | `internal/service/uhf/reader.go` |
|