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

158 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 打印机插件设计文档
**日期:** 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<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) | 项目实际硬件需求 |
| 状态回调 | 暂不需要 | 最小实现,后续可扩展 |