Files
pj_supermarket_cloud/docs/face-payment-readiness.md
2026-10-23 15:53:43 +08:00

4.3 KiB
Raw Permalink Blame History

人脸支付前置检查与启动准备

原先的提示在做什么

收银弹框 _dispatchFace 显示“正在检查人脸库与摄像头状态”后,依次执行:

  1. Floor 查询本地人脸表总行数,空库进入就地注册引导。
  2. 读取本地设备人脸参数和 SDK 授权文件,必要时初始化 FaceServer。
  3. 原生 SQLite 扫描所有有效样本编号,再获取 SDK 内存库中的样本编号,比较两个集合是否一致。
  4. 申请相机权限,再创建业务识别会话。

这段检查不下载人脸,也不在线重新激活 SDK。提示期间尚未实际打开摄像头;真正的识别引擎和 Camera 启动由后续原生会话执行。RGB/IR 色度探测只在设置页枚举摄像头时运行。

虽然原生集合查询只返回 sampleId,SQL 中判断有效特征的 TRIM(COALESCE(faceModel, '')) 仍需访问所有记录的特征 JSON。因此磁盘读取、页缓存和同时运行的人脸任务会影响耗时。状态查询还与其他人脸操作共用单线程执行器,可能等待队列。现场 1 秒和 3–4 秒的具体占比需要分段日志确认。

当前流程

  • Load 完成激活、整库装载和残缺行清理后,进行一次完整核对并保存当前进程的健康准备结果,同时提前申请相机权限并检查是否枚举到摄像头。
  • 正常支付复用准备结果,不再重复执行 Floor 计数和原生整库集合比较。
  • 同步、删除、重建、SDK 激活会使结果失效。操作覆盖数据库、SDK 和失败补偿的整个边界,最外层收尾后统一核对;批量删除也只在整批结束时核对。
  • 配置变化和原生启动异常使结果失效。占线、异常或不健康结果不会长期缓存;旧查询不能覆盖新一代结果。
  • 设置页诊断仍然实时读取完整状态。
  • 每次会话继续读取相机权限和处理真实开相机失败;硬件状态不永久缓存。

Load 的摄像头检查是权限与设备枚举,不预开 Camera。原生原有的 Camera/识别引擎 20 分钟热保持继续使用;首次识别、长时间空闲释放、相机配置切换等情况仍需冷启动。

识别成功后立即继续

原先虹软比对通过后,要等 Java 的 1.5 秒提示清空定时器才通知会话;Flutter 收到结果后又固定展示成功画面 1 秒,合计约 2.5 秒。

现在成功结果直接投递主线程,不再等待提示展示。原生仍先保存成功帧现场图片,再向 Flutter 回传结果;Flutter 收到结果后立即结束当前原生会话,完成后再通知收银业务读取人员与钱包信息。

结果锁、会话代次校验、过期回调拦截和关闭界面后的回调保护均保留。失败提示保留时间与失败重试间隔不变。正常成功流程不再使用固定展示延迟,但现场图片处理、会话收尾及后续业务接口仍有实际耗时。

排查日志

FacePaymentPerf:

  • readinessMs、cacheHit:支付准备耗时和是否复用结果。
  • cameraPermissionMs:当前会话读取/申请相机权限的耗时。

FaceStatusPerf:

  • queueMs:完整核对在原生执行器中的排队时间。
  • authInitMs:授权文件读取和 FaceServer 初始化。
  • sqliteScanMs:有效样本编号扫描。
  • sdkCompareMs:SDK 数量、内存编号集合读取和集合比较。
  • totalMs:完整原生核对耗时,不包含队列等待。

FaceSessionManager 原有日志继续记录识别引擎初始化及 Camera.open 耗时。上述新增日志只包含计时、计数或状态,不记录激活密钥和人脸特征。

验证边界

2026-10-23:69 项 Flutter 测试通过,包含缓存并发/失效、数量不变的样本替换、同步失败回滚,以及成功后不推进时间即可继续、必须等待会话结束、取消/销毁保护和结果幂等。17 项 Android JVM 单元测试通过,覆盖成功立即调度、失败提示保持 1.5 秒、旧通知替换与切换会话后的通知取消。静态分析没有 error,仍有项目已有的 warning/info;本次修改涉及的 Dart 文件单独分析无问题。

包含本次成功延迟移除的 Debug 和 Release 均编译通过,最新 Release 安装包为 build/app/outputs/flutter-apk/app-release.apk。

尚未把本次改动安装到现场设备,未声称真机支付耗时或真人活体识别已验证。