Files
2026-08-17 15:29:55 +08:00

94 lines
3.1 KiB
Dart
Raw Permalink 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.
// 唯一手写的接口契约文件。来源: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);
}