Files
printer/docs/superpowers/specs/2026-04-22-printer-plugin-design.md
Developer cae04eead5 init
2026-05-18 17:52:16 +08:00

5.6 KiB
Raw Blame History

打印机插件设计文档

日期: 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 设计

使用示例

// 打开端口
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<Integer, Pointer> 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) 项目实际硬件需求
状态回调 暂不需要 最小实现,后续可扩展