// 唯一手写的接口契约文件。来源:07 §「Pigeon 的工程化」。 // // 这不是可执行代码,只是给 pigeon 生成器读的 schema。改需求就改这里重新生成, // **生成产物不手动修改**: // dart run pigeon --input pigeons/scan_api.dart // (或 melos run gen:pigeon) @ConfigurePigeon( PigeonOptions( dartOut: 'lib/src/generated/scan_api.g.dart', dartOptions: DartOptions(), kotlinOut: 'android/src/main/kotlin/com/conti/native_scan/ScanApi.g.kt', kotlinOptions: KotlinOptions(package: 'com.conti.native_scan'), swiftOut: 'ios/native_scan/Sources/native_scan/ScanApi.g.swift', swiftOptions: SwiftOptions(), dartPackageName: 'native_scan', ), ) library; import 'package:pigeon/pigeon.dart'; /// 识别类型。 /// /// **即使首版只做条码,这个参数也必须先留出来**(07 §「待确认:VIN 码与车牌 /// 识别的技术路径」):车牌走的是专用 OCR、VIN 印刷字符走通用 OCR + 校验位 /// 过滤,技术路径还没定。参数先在 schema 里占好位,后面加识别类型就不用改 /// 接口签名——改签名意味着三端生成物和所有调用点一起动。 enum ScanMode { /// 二维码 / 条形码(商品、库位)。 barcode, /// VIN 码。可能是 Code 39 条码,也可能只有印刷字符。 vin, /// 车牌。 plate, } /// 扫码入参。 class ScanOptions { ScanOptions({required this.mode, this.timeoutMs, this.torchEnabled, this.title}); /// 识别类型。 ScanMode mode; /// 超时毫秒数。null 表示不超时,由用户手动取消。 int? timeoutMs; /// 是否默认打开闪光灯。 bool? torchEnabled; /// 扫码页标题。由调用方传,`native_scan` 不依赖任何 i18n 资源。 String? title; } /// 扫码结果。 class ScanResult { ScanResult({required this.mode, required this.value, required this.durationMs, this.rawFormat}); /// 实际生效的识别类型。 ScanMode mode; /// 识别到的文本。 String value; /// 从打开扫码页到出结果的耗时,供埋点用(见 13 的 `scan_succeeded`)。 int durationMs; /// 原始码制(如 `CODE_39` / `QR_CODE`)。OCR 路径下为 null。 String? rawFormat; } /// Dart → 原生。 /// /// 用户取消、权限拒绝、平台未实现这三类都通过 `FlutterError` 抛出, /// 由 Dart 侧的公共 API 转成 `NativeScanException`——**原生异常类型 /// (`PlatformException`)不允许直接抛到业务代码里**(07 §使用规则)。 @HostApi() abstract class ScanHostApi { /// 打开扫码页并等待一次结果。 /// /// 用户取消时抛 code 为 `CANCELLED` 的错误,而不是返回 null—— /// 「取消」和「扫到了空字符串」必须能区分开。 @async ScanResult startScan(ScanOptions options); /// 当前平台是否支持指定识别类型。 /// /// 车牌识别的技术路径未定(见上),首版可能只有部分平台支持; /// 调用方应当先查这个再决定要不要显示入口,而不是等 `startScan` 抛错。 bool isModeSupported(ScanMode mode); }