变更日期:2026-09-01
项目仓库:/Users/liang/AndroidStudioProjects/CusumptionMachine
当前分支:fix_pay_by_face
代码基线:804e617 加一期未提交变更
变更状态:自动验证完成,真机待验
一期已经把模型、相机和弹框职责拆分,但 7 个业务页面仍各自查找 Fragment、创建 FaceRecognitionPop、设置 Tag 和组装参数,共有 8 个直接构造分支。
二期将这部分重复入口代码收敛到统一 Launcher,同时保持所有页面原支付、核验、订单和结果回调逻辑不变。
新增 faceRecognition/launcher/:
FaceRecognitionLauncher.java
FaceRecognitionLaunchGate.java
FaceRecognitionRequest.java
FaceRecognitionScene.java
实现内容:
统一 Activity 生命周期和 Fragment 状态保存检查。
使用相同 Tag 的现有 Fragment 防止重复展示。
统一创建 FaceRecognitionPop。
统一组装金额、副屏、确认文案和 Tag。
为 7 个页面建立明确场景枚举。
返回 LaunchResult 表示弹框已展示、已存在或被安全拒绝。
记录场景和展示结果,不记录人脸图像或特征数据。
Launcher 不保存页面对象,不调用业务接口。
修改:
MainActivity.java
FreeActivity.java
FreeNoKeyboardActivity.java
QuotaActivity.java
QuotaNoKeyboardActivity.java
GuoxinFacePayActivity.java
OrderVerifyActivity.java
迁移内容:
删除页面内人脸弹框查找、直接构造、Tag 和监听器装配代码。
改为构建 FaceRecognitionRequest 并调用 FaceRecognitionLauncher.launch()。
MainActivity 保留当前金额、副屏预览和副屏显示隐藏业务。
四个自由或定额消费页面保留 paymentIndex 和原支付逻辑。
国信页面保留独立 Tag、“去消费”文案和原支付接口。
核验页面保留“去核销”文案和原核验接口。
7 个页面原 FaceRecognitionResultListener 内容未修改。
Launcher 拒绝展示并且没有活动弹框时:
MainActivity 隐藏已经打开的副屏人脸区域。
自由和定额消费页面恢复 paymentIndex,允许用户再次点击支付。
国信和核验页面没有预先锁定支付状态,不需要额外恢复。
重复弹框结果 ALREADY_SHOWN 视为已有活动弹框,不执行上述恢复,继续由现有弹框回调收尾。
新增:
faceRecognition/launcher/FaceRecognitionLaunchGateTest.java
faceRecognition/launcher/FaceRecognitionRequestTest.java
覆盖 8 个测试:
宿主不可用时拒绝展示。
Fragment 状态已保存时拒绝展示。
相同 Tag 弹框存在时拒绝重复创建。
正常宿主允许展示。
已展示和已存在结果表示活动弹框存在。
拒绝结果表示没有活动弹框。
请求缺省金额和场景安全归一化。
显式业务场景保持不变。
门禁和场景字段均先运行缺失实现测试并确认编译失败,再完成实现并转为通过。
执行命令:
JAVA_HOME=/Users/liang/Library/Java/JavaVirtualMachines/corretto-1.8.0_482/Contents/Home \ sh ./gradlew :app:testDebugUnitTest :app:assembleDebug
结果:
BUILD SUCCESSFUL。
Debug 单元测试:49 个。
失败:0。
错误:0。
跳过:0。
Debug APK 构建成功。
静态检查:
7 个业务页面均使用 Launcher。
7 个 Launcher 调用点。
7 个场景映射。
页面内直接 FaceRecognitionPop 构造位置:0。
Launcher 内统一构造位置:1。
页面原业务监听器:7 个。
Launcher 内支付、核验、订单清空调用:0。
人脸弹框 UI 和按钮交互不变。
Runtime、Session 和 Pop 一期职责不变。
成功、结束和取消仍回到页面原监听器。
各页面原支付或核验接口、参数和结果处理不变。
菜单菜品、自定义金额和订单状态不由 Launcher 修改。
快速重复点击增加统一防重复保护。
Activity 生命周期不允许展示时改为安全拒绝,不抛出弹框事务异常。
7 个页面逐一验证成功、重试、超时和取消。
菜单消费单屏和双屏预览与副屏收尾。
快速连续点击只显示一个弹框。
弹框关闭后立即再次点击可以重新打开。
生命周期切换后支付按钮不会被锁定。
国信支付和订单核验的确认文案与业务请求保持原样。
未执行 Git 暂存。
未执行 Git 提交。
未执行 Git 推送。
未创建或切换分支。