app scaffold

This commit is contained in:
Guangfei.Zhao
2026-08-17 15:29:55 +08:00
commit 681688dfae
301 changed files with 18414 additions and 0 deletions
@@ -0,0 +1,93 @@
// 唯一手写的接口契约文件。来源: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);
}