# 取票打印 + 扫码出场 — 设计文档 > 日期:2026-07-30 | 优先级:P0-4 ## 1. 目标 实现临时车取票入场、扫码出场。入场时票机按钮触发打印二维码小票,出场时扫码枪扫描小票二维码查询数字票并结算。 ## 2. 硬件架构 ``` 入场:打印机按钮 → 串口 → PC → 后端 → ESC/POS 打印 出场:扫码枪(USB键盘) → PC → entryExit.vue → 后端查询 ticket ``` ## 3. 数据模型 ### printer 设备配置表 | 字段 | 类型 | 说明 | |------|------|------| | id | uint | 主键 | | name | string | 打印机名称 | | port_name | string | COM端口名(如 COM3) | | baud_rate | int | 波特率(默认 9600) | | status | string | online / offline | | location | string | 安装位置(入口/出口) | 复用现有 `vehicle_record` + `digital_ticket`(无车牌,trigger_mode=ticket_machine)。 ## 4. 入场流程 ``` 驾驶员按票机按钮 → 串口接收 → POST /ticket-machine/button ├─ 创建 vehicle_record(无车牌) ├─ 创建 digital_ticket (trigger_mode=ticket_machine) ├─ ESC/POS 打印小票 │ 内容:停车场名称 / 入场时间 / 票号 / ticket_no 二维码 └─ GateOpener 抬杆 ``` ## 5. 出场流程 ``` 扫码枪扫小票 → entryExit.vue 监听输入 → 自动填入 ticket_no ├─ GET /digital-ticket/{ticketNo} ├─ ExitPreview → 计费 ├─ 支付(现金/POS/扫码) └─ ExitConfirm → 抬杆 ``` ## 6. 后端新增 | 文件 | 说明 | |------|------| | `internal/dao/printer.go` | 打印机设备 DAO | | `internal/modules/printer/api.go` | 打印机管理 + 按钮事件 API | | `internal/modules/printer/service/service.go` | ESC/POS 指令封装 + 串口通信 | | `internal/modules/printer/service/escpos.go` | ESC/POS 协议常量与指令构建 | ## 7. 小票模板 ``` ┌──────────────────────────────┐ │ PARKING TICKET │ │ 停车票 │ │ │ │ {parking_lot.lot_name} │ │ {parking_lot.type_text} │ │ │ │ PARK AT YOUR OWN RISK │ │──────────────────────────────│ │ In-Time::{entry_time} │ │ InGate::{channel.code} │ │ Veh No::{plate_number} │ ← 识别到则印,未识别留空 │──────────────────────────────│ │ Slip No::{ticket_id} │ ← digital_ticket.id 短流水号 │──────────────────────────────│ │ [二维码] │ ← 编码 ticket_no(full UUID) │──────────────────────────────│ │ {payment_hint} │ ← 配置项,如 "SCAN AND PAY..." └──────────────────────────────┘ ``` 数据来源: | 字段 | 来源 | |------|------| | parking_lot | `parking_lot.lot_name` | | type_text | `parking_lot.remark` 或写死 "A-General Car" | | entry_time | `time.Now().Format("02-01-2006 15:04:05")` | | in_gate | `channel.channel_code`(按钮事件时指定通道) | | veh_no | 车牌识别结果,无则空 | | slip_no | `digital_ticket.id`(自增整数) | | 二维码 | `digital_ticket.ticket_no`(32位UUID) | | payment_hint | 系统配置表或写死 | ## 8. 文件变更 | 文件 | 操作 | |------|------| | `internal/dao/printer.go` | 新建 | | `internal/modules/printer/api.go` | 新建 | | `internal/modules/printer/service/service.go` | 新建 | | `internal/modules/printer/service/escpos.go` | 新建 | | `internal/initialize/gorm.go` | 修改 | | `internal/initialize/router.go` | 修改 | | `frontend/src/view/parking/entryExit.vue` | 修改(出场监听扫码枪输入) |