# Tasks: 可切换的原生业务推送通道 **Input**: `specs/033-native-push-routing/spec.md`、`plan.md` **Execution**: 当前 `test-202609v2` 分支;不创建新分支。每项先写并运行失败测试,再实现、验证、核对暂存范围并提交。默认模式始终为 `uni`。 ## Phase 1: 默认通道与配置(US1) - [x] T001 [US1] 在 `ruoyi-admin/src/main/java/com/ruoyi/app/push/` 定义接收端枚举、`business-push` 配置及原生模式启动校验;`ruoyi-admin/src/main/resources/application.yml` 仅设置默认 `uni` 与非秘密占位符。 - [x] T002 [US1] 在 `ruoyi-admin/src/test/java/com/ruoyi/app/push/BusinessPushPropertiesTest.java` 覆盖默认启动、原生凭据缺失/无效和三端配置。 ## Phase 2: 原生发送器(US2、US3) - [x] T003 [US2] 在 `FcmPushSender.java` 实现三命名 FirebaseApp 和按接收端 FCM 发送;在 `FcmPushSenderTest.java` 验证项目隔离、payload、失效错误与无敏感日志。 - [x] T004 [US3] 在 `ApnsPushSender.java` 实现三端证书型 APNs HTTP/2 发送及环境选择;在 `ApnsPushSenderTest.java` 验证 topic、payload、证书错误与响应分类。 ## Phase 3: 统一路由与业务集成(US1–US4) - [x] T005 [US1–US4] 在 `BusinessPushService.java` 实现 uni/native 选择、当前账号 token 读取、地址判定及异常隔离;在 `BusinessPushServiceTest.java` 覆盖默认 uni、六种原生组合及不自动回退。 - [x] T006 [US1–US4] 修改 `PayPush.java` 的普通业务包装方法委托 T005;保留低层 uniCloud 方法供 uni 模式及排除路径使用,验证消息中心不重复入库。 - [x] T007 [US2–US4] 将在用普通业务直连与 CID 前置过滤迁移到统一路由:`MerchantNotificationRouter.java`、`LinePayOrderNotificationService.java`、`OmgPaymentNotifyService.java` 和当前有效订单 Controller;同步更新相关测试。门店订单仍是分管账号优先、无符合条件分管账号时主账号兜底,不同时通知两类账号。不改音视频、废弃入口或临时测试推送接口。 ## Phase 4: 文档与验证 - [x] T008 在 `specs/033-native-push-routing/quickstart.md` 记录三端凭据配置、默认关闭、启用/回退、真机检查;更新 `specs/012-im-user-integration/code-status.md` 与 `docs/order-push-overview.md`。 - [x] T009 使用 JDK 21 运行定向测试和 `ruoyi-admin` 模块构建;核对完整 diff、暂存范围及未执行的外部 FCM/APNs 真机验证,再提交文档收口。 ## Dependencies T001–T002 → T003/T004 → T005–T006 → T007 → T008–T009。FCM 与 APNs 发送器可以独立评审,但本任务按当前会话顺序执行,不启动 Agent。 ## 2026-09-29 追加:随包凭据(默认通道不变) - [x] T010 更新三端资源命名和配置:每端一份独立 Firebase `server.json`、一份 APNs 普通证书、一份 `packetName/pwd` 配置,名称含 `user`/`merchant`/`rider`;实际文件提交 Git,默认 `uni` 不加载。 - [x] T011 测试先行支持 classpath 读取 FCM JSON、APNs 配置和 `.p12`,保持原有外部路径兼容;开发/正式只切换 APNs 网关。 - [x] T012 更新部署说明并运行 JDK 21 定向测试、模块构建和资源打包检查;仅暂存本功能代码、文档与三端凭据后提交,真机外发仍单独验证。 ## 2026-09-29 追加:仅原生通道的多骑手新单批量 - [x] T013 先写失败测试:骑手端 FCM multicast 保留业务 payload 与逐 token 结果;原生外卖、闪送新单进入批量分支,uni 仍逐骑手发送。 - [x] T014 Android 骑手按已本地化文案和 payload 分组批量发送,逐人发布消息中心事件;iOS 保留原有逐设备异步发送,失败不回退 uni。 - [x] T015 更新操作文档,运行 JDK 21 定向与回归测试、模块构建,核对变更及暂存范围。 ## 2026-10-23 追加:无需切换业务模式的原生测试 - [x] T016 先写失败测试:默认 `uni` 时只按需初始化目标端 FCM/APNs,iOS 测试固定发送到 APNs 正式网关。 - [x] T017 新增匿名 `POST /system/push/testNative`,直接使用请求提供的设备 Token,不查询账号;返回服务商接受或脱敏失败类别,保留普通业务推送模式。 - [x] T018 更新 ApiPost 示例与风险说明,完成差异检查、定向测试和模块构建;真实手机通知由部署后人工验证。 # 2026-10-26 本地固定配置 - [x] 去掉business-push所有显式环境变量占位符;三端路径、密码、topic按本地配套文件固定,保持uni/production当前默认,补充来源注释与使用说明。 - [x] APNs证书加载、配置校验、测试入口及发票鉴权定向回归通过;用户要求核对后分项中文提交并推送,提交状态及SHA以Git为准。 2026-10-26:本地JDK21合并定向测试39项通过,失败/错误均0,包含真实三端classpath证书加载、模拟APNs/FCM响应及发票鉴权;不代表真实设备投递成功。未执行服务器部署或真实外部推送,BadDeviceToken尚待实际安装包/当前token/部署配置联调验证。 ## 2026-10-26 追加:使用参考工程的 Pushy 发送方式 - [x] T019 对照 qtw-push-server,补充类型化 APNs 通知、苹果接受/拒绝测试;新增工厂签名在旧实现下编译失败,确认尚未具备 Pushy 发送能力。 - [x] T020 以 Pushy 0.13.10 替换 JDK HttpClient,保留原有证书/消息/铃声;按端和环境缓存客户端,等待苹果真实响应并脱敏分类,有限时关闭资源,添加说明注释。 - [x] T021 验证正式测试与开发业务客户端隔离、复用、关闭、超时/中断/异常及三端证书加载;完成推送定向测试、JDK 21 模块构建与 diff 检查,记录真实设备投递未验证。 验证记录:JDK 21 `mvn -pl ruoyi-admin -am -Dmaven.test.skip=true package dependency:build-classpath` 与随后本地 `install` 均退出 0,确认 JAR 包含 `pushy-0.13.10.jar` 和受项目统一版本管理的 Netty HTTP/2 依赖。本轮常规 reactor 测试被工作区并行新增的 `PosOrderImGroupMapperTest` 引用未实现的 `setImGroupId` 阻断,未修改这部分文件。为避免并行构建覆盖 `target/classes`,复制构建结果至 `target/apns-validation`,使用 JDK 21 javac 定向编译本轮推送源码和全部 `*Push*Test`,再以同版 JUnit Platform Console 1.10.5 执行:78 项成功,0 失败/中止/跳过。日志为 `ruoyi-admin/target/apns-pushy-console-tests.log`,报告在 `target/apns-validation/reports`。全量测试、服务器部署、真实 APNs/FCM 及 TestFlight/App Store 真机投递未执行,不能据此判定 BadDeviceToken 已解决。 ## 2026-10-26 追加:APNs 测试/正式网关按配置选择 以下任务覆盖历史记录中“测试入口固定正式网关”的规则。 - [x] T022 参数化复现旧实现错误:配置 development 且业务 uni 时,测试入口仍选 PRODUCTION;16 项 APNs 测试中该项失败,production 用例通过。 - [x] T023 测试发送改为 sendForTest 并读取现有 apns-environment;当前 YAML 设 development,补充正式签名包使用 production 的注释;不增加环境变量、请求字段或网关失败自动切换。 - [x] T024 更新规格、计划和接入说明,验证双环境原生测试、业务通道和客户端隔离,执行 JDK 21 推送定向测试、打包及差异检查;真实 APNs 投递单独验收。 验证记录:`mvn -pl ruoyi-admin -am -Dtest=*Push*Test -Dsurefire.failIfNoSpecifiedTests=false package` 在 JDK 21 下退出 0,79 项定向测试成功,0 失败/错误/跳过;包含 development 和 production 的测试入口用例及跨环境客户端隔离。`git diff --check` 通过。本轮未执行全量回归、服务器部署或真实 APNs 投递,测试证明配置路由已修正,不代表真机已收到通知。