# 打印机插件设计文档 **日期:** 2026-04-22 **状态:** 已确认 **目标:** 将 printer 插件开发为完整的打印插件,支持通过 CH34 串口 + autoreplyprint.aar 进行打印 ## 1. 项目概述 ### 用途 公司内部多个 Flutter 项目共用的打印插件,用于打印拉曼检测结果(简单文字票据)。 ### 技术架构 - CH34 插件提供串口通道 - 本项目 Android 原生层集成 autoreplyprint.aar - Dart 层通过 MethodChannel 调用原生层 - 底层指令式 API:调用方控制打开→打印→关闭全流程 ## 2. 整体架构 ``` ┌─────────────────────────────────────────────┐ │ 调用方 Flutter 项目 │ │ Printer.openComPort() → PrinterPortHandle │ │ handle.printText() → handle.close() │ └──────────────┬───────────────────────────────┘ │ MethodChannel 调用 ┌──────────────▼───────────────────────────────┐ │ Flutter 插件 Dart 层 │ │ Printer → PrinterPlatform │ │ → MethodChannelPrinterPort │ │ → PrinterPortHandle │ └──────────────┬───────────────────────────────┐ │ MethodChannel + portHandle ┌──────────────▼───────────────────────────────┐ │ Android 原生层 (Java) │ │ PrinterPlugin (MethodCallHandler) │ │ → PortHandleManager │ │ → autoreplyprint.aar │ └───────────────────────────────────────────────┘ ``` ## 3. API 设计 ### 使用示例 ```dart // 打开端口 PrinterPortHandle port = await Printer.openComPort( portName: 'COM3', baudRate: 9600, dataBits: 8, parity: Parity.none, stopBits: StopBits.one, flowControl: FlowControl.none, ); // 设置编码 await port.setMultiByteMode(); await port.setMultiByteEncoding(MultiByteEncoding.utf8); // 打印 await port.setAlignment(Alignment.center); await port.setTextScale(width: 2, height: 2); await port.printText('拉曼检测结果报告'); // 走纸切纸 await port.feedLine(3); await port.halfCutPaper(); // 关闭 await port.close(); ``` ### API 分类 | 类别 | 方法 | |------|------| | 端口管理 | `openComPort`, `close` | | 打印文本 | `printText`, `printTextInUtf8`, `printTextInGbk` | | 格式控制 | `setAlignment`, `setTextScale`, `setTextBold`, `setTextUnderline` | | 走纸切纸 | `feedLine`, `feedDot`, `halfCutPaper`, `fullCutPaper` | | 编码模式 | `setMultiByteMode`, `setSingleByteMode`, `setMultiByteEncoding` | | 条码/二维码 | `printBarcode`, `printQRCode` | | 图片 | `printRasterImageFromData` | | 其他 | `resetPrinter`, `kickOutDrawer`, `beep` | ## 4. MethodChannel 协议 ### 协议格式 ``` MethodChannel 名称: "printer" Method: "openComPort" Args: { portName, baudRate, dataBits, parity, stopBits, flowControl, autoReplyMode } Return: { success: bool, portHandle: int?, error: String? } Method: "closePort" Args: { portHandle } Return: { success: bool, error: String? } Method: "printText" Args: { portHandle, text } Return: { success: bool, error: String? } ... // 每个操作对应一个 method call ``` ### 错误处理 - 原生层异常通过 `result.error()` 返回 - Dart 层统一包装为 `PrinterException` ## 5. 原生层设计 ### 端口句柄管理 - `PrinterPlugin.java` 维护 `Map portHandles` - `openComPort` 调用 `CP_Port_OpenCom` 返回 Pointer 存入 map - 生成递增 int 作为 Dart 层 portHandle - 每个 method call 从 map 中取出 Pointer,调用对应 AAR 函数 ### AAR 集成 - 将 `docs/autoreplyprint.aar` 移至 `android/libs/` - `build.gradle.kts` 配置 `implementation files('libs/autoreplyprint.aar')` ## 6. 项目结构 ``` printer/ ├── lib/ │ ├── printer.dart # 主入口 │ ├── printer_platform_interface.dart # 平台接口 │ ├── printer_method_channel.dart # MethodChannel 实现 │ └── src/ │ ├── models/ │ │ ├── parity.dart # 串口校验枚举 │ │ ├── alignment.dart # 对齐枚举 │ │ ├── encoding.dart # 字符编码枚举 │ │ └── printer_exception.dart # 自定义异常 │ └── port_handle.dart # 端口句柄封装 ├── android/ │ ├── build.gradle.kts │ ├── libs/ │ │ └── autoreplyprint.aar │ └── src/main/java/com/xiarui/printer/ │ ├── PrinterPlugin.java │ └── PortHandleManager.java └── test/ └── printer_test.dart ``` ## 7. 关键决策 | 决策 | 选择 | 理由 | |------|------|------| | SDK 集成方式 | 原生层调用 AAR | 利用已有封装,可靠 | | API 风格 | 底层指令式 | 灵活,调用方控制流程 | | 字符编码 | UTF8 | 中文支持,现代标准 | | 连接方式 | 串口 (通过 CH34) | 项目实际硬件需求 | | 状态回调 | 暂不需要 | 最小实现,后续可扩展 |