# USB 小票照片复刻设计 > 日期:2026-07-31 > 范围:仅调整 USB/CSN 打印路径,串口打印路径保持不变 ## 目标 将 USB 热敏打印小票复刻为参考照片中的信息层级和视觉结构。保留现有业务字段来源、数字票生成流程和二维码内容,不修改车辆入场、结算或扫码出场逻辑。 ## 票面结构 USB 小票自上而下按以下顺序打印: ```text Parking Ticket Font A、双宽、加粗、居中 {lotName} Font B、居中 ------------------------------------------ Font B、42 字符 PARK AT YOUR OWN RISK Font B、居中 {lotName} A-General Car Font B、左对齐 In-Time::{entryTime} Font A、左对齐 InGate::{channelCode} Font A、左对齐,可选 Slip No::{ticketID} Font A、左对齐 Veh No::{plateNo} Font A、双宽、加粗、可选 [二维码] 居中,宽度参数 12 SCAN AND PAY WITH NEW Font B、居中 THE CANADIA BANK APP Font B、居中 [全切纸] ``` 现场打印确认 USB 模组按发送顺序排列票面内容。程序必须按上方从标题到支付提示的正常顺序发送字段,并保持字形方向正常;不能通过倒序发送模拟 180 度旋转。 ## 字段映射 | 票面字段 | 数据来源 | 规则 | |---|---|---| | 停车场名称 | `parking_lot.lot_name` | 标题下方显示一次,并在车型行再次显示 | | 车型 | 固定文本 | `A-General Car` | | 入场时间 | 打印时的本地时间 | 格式 `02-01-2006 15:04:05` | | 入口 | API 请求的 `channel_code` | 空值时省略整行 | | 票号 | `digital_ticket.id` | `Slip No::{id}` | | 车牌 | API 请求的 `plate_number` | 空值时省略整行 | | 二维码 | `digital_ticket.ticket_no` | 保留现有 32 位十六进制票号内容 | ## 排版指令 - 初始化后使用原始 ESC/POS 指令打印文字,继续绕开参数传递不稳定的 `Pos_Text`。 - 标题使用 Font A、双宽、加粗、居中;双宽使用标准 ESC/POS `GS ! 0x10`,打印后使用 `GS ! 0x00` 恢复正常尺寸并关闭粗体。 - 副标题、风险提示、停车场车型行和支付提示使用 Font B。 - 时间、入口和票号使用 Font A 正常尺寸。 - 车牌使用 Font A、`GS ! 0x10` 双宽和加粗;打印后立即恢复正常尺寸和粗细。 - 顶部分隔线使用 42 个短横线,以 Font B 打印,匹配 80mm 票纸有效宽度。 - 移除当前 USB 票面中信息块之间的额外分隔线。 - 二维码调用 CSN SDK 的 `Pos_EscQrcode`,宽度参数调整为 12,使二维码宽度接近参考票纸宽度的一半。 - 现场测试确认 `ESC { 1` 只旋转字形,不反转整张票的纵向坐标;字段继续按票面从上至下发送。 - 初始化后发送 `ESC { 0`,并在 `Pos_EscQrcode` 后再次发送 `ESC { 0`,防止 SDK 改变文字方向状态。 - 支付提示和二维码之间使用紧凑走纸;支付提示发送后走纸 8 行,覆盖打印头到切刀的机械距离,再执行全切。 ## 代码结构 将 USB 票面的排版定义从设备调用中抽离为可测试的操作序列: - 纯布局函数负责生成文字、对齐、字号、二维码、走纸和切纸操作的有序列表。 - CSN 执行器负责把操作映射到 `Csn_WriteData`、`csn_QRCode`、走纸和切纸函数。 - `PrintTicket` 仍负责读取打印机配置、打开端口、执行票面和更新设备状态。 - 串口分支不调用新的 USB 布局函数,行为保持不变。 ## 错误处理 - 本次不改变现有端口打开和 DLL 加载策略。 - USB 原始字节写入返回 0 或短写时,执行器返回错误,不把打印机状态更新为 `online`。 - 二维码 SDK 返回失败时立即返回打印错误,不更新打印机在线状态;走纸和切纸继续使用现有无返回值调用。 - 串口打印路径不启用 USB 方向补偿,保持原有行为。 ## 测试 新增 USB 布局单元测试,至少验证: - 字段严格按照票面从上至下的正常顺序出现。 - 标题和车牌前后包含正确的字号、粗体和复位指令。 - 入口和车牌为空时对应行被省略。 - 只生成一条 42 字符分隔线。 - 二维码操作位于车牌之后、支付提示之前,宽度为 12。 - 支付提示按 `SCAN AND PAY WITH NEW`、`THE CANADIA BANK APP` 的发送顺序生成。 - 初始化后和二维码后均发送正常文字方向 `ESC { 0`,且不发送 `ESC { 1`。 - 切纸前走纸 8 行,避免最后一段内容残留到下一张票。 - 串口路径不受 USB 布局改动影响。 ## 不在本次范围内 - 串口票面同步改版。 - 打印机配置管理页面。 - DLL 路径配置化。 - 中文字符集转换。 - 入场记录与打印失败的事务补偿。