跨端: feat(推送客户端) 收尾两处接线(pi 邮件 66bbd929 分工)+ 换账号补报
`PushService.ets` 与 `pendingRoute` 都早就写好了,但**没人调用/没人读** —— 而"写好了"与"接上了"是两件事:ArkTS 只编译可达模块,往一个无人 import 的 文件里放必然报错的类型错误,`assembleHap` 照样 BUILD SUCCESSFUL (pi 与我各复现过一个方向)。这次补的是**边**,不是点。 ① 登录成功补报(LoginPage):`EntryAbility.onCreate` 那次在**登录之前**跑, 那时 `ApiClient` 还没有 token ⇒ 服务端 401,而 `reportToken` 的失败是静默的 ⇒ "启动时报过"不等于"这个账号登记过"。补三条登录路径,一条都不能漏: 快速路径(已有账号直接进主界面,老用户走这条)/ tryRestore / doLogin。 ② 换账号补报(SettingsPage.switchTo,**我加的第三处**):服务端语义是同一 token 换账号**转移**而非并存 ⇒ 新账号其实没登记过。幂等标记按 `accountKey|token` 存,所以这里调一次必然重发,不会被"我报过"挡掉。 不补的症状:切完账号,通知仍推给上一个账号。 ③ pendingRoute 消费端(MainPage.CommPage):`EntryAbility` 已把通知 data 解析成 `pendingRoute`(冷启 onCreate / 热启 onNewWant 都写了), **但没有任何东西读它** ⇒ 点通知只拉起 App、停在列表页。 在 CommPage 消费(详情页是这个 Navigation 的 navPathStack 上的路由, 栈只有它持有),消费后**立刻清空**(它是"待处理"不是"当前页", 不清则返回列表再进来会被反复跳走)。 判据:`harmony-push.test.mjs` 15 → 18 条,三条新判据钉的就是上面这三条边, **三条都做了变异验证**(各自删掉对应接线即红、恢复即绿)。 `LoginPage` 那条数**恰好 3 处**调用:少了快速路径=老用户永远不补报, 多了要问清是哪条路径。 编译验证(不是"命令成功",是"它真读了这个文件"):三处改动各植入一次必然 类型错误 ⇒ BUILD FAILED 且 `At File:` 指到**新代码那一行**(MainPage:1173 / LoginPage:108 / SettingsPage:456),恢复后 BUILD SUCCESSFUL。 产物侧证:`modules.abc` 里能查到 `consumePendingRoute`(2) / `reportPushToken`(2)。
This commit is contained in:
@ -52,6 +52,7 @@ import {
|
||||
emptyHint
|
||||
} from '../model/CommTabs';
|
||||
import { MailDetailParams, ComposeParams } from '../model/RouteParams';
|
||||
import { PushService, PushRoute } from '../api/PushService';
|
||||
/*
|
||||
* ⚠️ **`import` 必须在这一行的位置**:ArkTS 要求所有 import 都在**任何其它语句之前**
|
||||
* (`arkts-no-misplaced-imports`),与它们之间隔的是常量、表还是别的语句无关。
|
||||
@ -1142,6 +1143,46 @@ struct CommPage {
|
||||
|
||||
aboutToAppear(): void {
|
||||
this.refreshCounts();
|
||||
this.consumePendingRoute();
|
||||
}
|
||||
|
||||
/**
|
||||
* 消费「点通知进来」的待处理跳转(收尾项,pi 邮件 `66bbd929` §三)。
|
||||
*
|
||||
* 断链在哪:`EntryAbility` 已经把通知的 `data` 解析成 `PushService.pendingRoute`
|
||||
* (冷启在 `onCreate`、热启在 `onNewWant`),**但没有任何东西读它** ——
|
||||
* 于是"点通知打开那封信"这三件的最后一件是空的:通知会拉起 App,
|
||||
* 然后停在列表页,用户还得自己找那封信。
|
||||
*
|
||||
* 为什么在这里消费:跳转的落点是**邮件详情**,而详情页是这个
|
||||
* `Navigation` 的 `navPathStack` 上的路由 —— 这个栈只有 `CommPage` 持有
|
||||
* (`openMail` 就是往它上面 push)。在别处消费就得跨组件去够这个栈。
|
||||
*
|
||||
* 三条边界:
|
||||
* ① 没有待处理目标(正常启动)⇒ 什么都不做,**不清栈、不跳转**;
|
||||
* ② 解析不出目标的 want 在 `EntryAbility` 那层就已经被丢掉了(静默),
|
||||
* 所以到这里一定有 mail_id;
|
||||
* ③ 消费后**立刻清空**那个静态格子:它是"待处理"而不是"当前页" ——
|
||||
* 不清的话,用户返回列表再进这一页时会被再跳一次(永远回不到列表)。
|
||||
*/
|
||||
private consumePendingRoute(): void {
|
||||
const route: PushRoute | undefined = PushService.pendingRoute;
|
||||
if (route === undefined) {
|
||||
return;
|
||||
}
|
||||
PushService.pendingRoute = undefined;
|
||||
/*
|
||||
* 账号:通知的 `data` 里只有 mail_id/session_id(服务端契约如此),没有 account_id。
|
||||
* 所以用**当前活跃账号** —— 点通知的人就是本机正在用的那个人。
|
||||
*/
|
||||
const ctx = this.getUIContext().getHostContext();
|
||||
let accountId: string = '';
|
||||
if (ctx !== undefined) {
|
||||
accountId = AccountManager.getInstance(ctx).getActiveId();
|
||||
}
|
||||
// 通知落的就是收件箱里那封信 ⇒ 先把栏切回收件箱,再压详情页
|
||||
this.commTab = 'inbox';
|
||||
this.openMail(route.mailId, accountId);
|
||||
}
|
||||
|
||||
/** 徽标数字:未读(收件箱里**要读的**那些)+ 待决策(授权栏) */
|
||||
|
||||
Reference in New Issue
Block a user