From f44b15684b6d07d6b941ac7f6edae4ba3bc26d6d Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Wed, 16 Sep 2026 08:29:24 +0800 Subject: [PATCH] =?UTF-8?q?fix(push):=20=E9=80=9A=E7=9F=A5=E5=BC=80?= =?UTF-8?q?=E5=85=B3=E9=BB=98=E8=AE=A4=E6=94=B9=E5=BC=80=EF=BC=88=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=E8=AF=AF=E8=A7=A3=E3=80=8C=E5=8F=AF=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E9=A1=B9=3D=E9=BB=98=E8=AE=A4=E5=85=B3=E3=80=8D=E8=87=B4=20tok?= =?UTF-8?q?en=20=E4=BB=8E=E4=B8=8D=E4=B8=8A=E6=8A=A5=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ★ 功能性硬伤修复:用户实测「新邮件根本没有通知」。 根因:我上一版把 PushService.isEnabled 默认设成关(读不到即 false), 误解了「接入系统通知是可配置项」的本意 —— 用户要的是「服务端没配凭证时 客户端优雅降级」(enabled:false 是正常态,不报错不阻塞),不是「默认关掉 推送功能」。结果 reportToken 最前 gate 直接 return,device token 从未上报, DB 里 0 个 token,NotifyNewMail 在 len(tokens)==0 时静默返回 ⇒ 永远发不出。 修正: - PushContract.DEFAULT_PUSH_ENABLED: false → true(契约层默认开) - PushService.isEnabled: getSync 默认值用 DEFAULT_PUSH_ENABLED(true), catch 也返回 true —— 只有用户显式关才不上报 - 判据同步:harmony-push-optin ①② 改默认开口径 验证(服务端→HMS 链路实打已通): - OAuth access_token 取得(app_secret 有效) - POST /v1/{appId}/messages:send + test_message 调通, HMS 回 80300007 "All tokens are invalid"(假 token 无效,但凭证/形状/认证全被接受) ⇒ 只要 DB 有真实 device token 就能送达(token 由客户端上报) --- client/electron/test/harmony-push-optin.test.mjs | 12 ++++++------ .../harmony/entry/src/main/ets/api/PushService.ets | 10 ++++++---- .../harmony/entry/src/main/ets/model/PushContract.ts | 7 ++++--- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/client/electron/test/harmony-push-optin.test.mjs b/client/electron/test/harmony-push-optin.test.mjs index 01aca63..3ad2daf 100644 --- a/client/electron/test/harmony-push-optin.test.mjs +++ b/client/electron/test/harmony-push-optin.test.mjs @@ -27,21 +27,21 @@ const read = p => prose(join(HARMONY_ETS, p)); const C = await import(join(HARMONY_ETS, 'model/PushContract.ts')); -test('① 契约默认关:DEFAULT_PUSH_ENABLED = false(自部署零开销的契约)', () => { - assert.equal(C.DEFAULT_PUSH_ENABLED, false, - '默认必须关 —— 自部署用户没配服务端推送凭证时不应被默认裹进推送链'); +test('① 契约默认开:DEFAULT_PUSH_ENABLED = true(用户要能默认收到通知)', () => { + assert.equal(C.DEFAULT_PUSH_ENABLED, true, + '默认必须开 —— 接入系统通知是"服务端没配凭证时优雅降级",不是"默认关掉推送"(2026-09-16 用户实测收不到通知的根因)'); // 标签:关 ⇒ 'off'、开 ⇒ 'on'(口径稳定,给设置页用) assert.equal(C.pushEnabledLabel(false), 'off'); assert.equal(C.pushEnabledLabel(true), 'on'); }); -test('② PushService.isEnabled 读不到即 false(默认关落点) + setEnabled 存在', () => { +test('② PushService.isEnabled 读不到即开(默认开落点) + setEnabled 存在', () => { const svc = read('api/PushService.ets'); const code_ = stripComments(svc); assert.match(code_, /static isEnabled\(context: common\.Context\): boolean \{/, '要有静态 isEnabled(ability 阶段 onCreate 要读它,不能是实例方法)'); - assert.match(code_, /return v === true;/, - '读到 true 才返回 true —— 其它(首次/异常)都 false(默认关)'); + assert.match(code_, /getSync\(SETTING_KEY, DEFAULT_PUSH_ENABLED\)/, + '读不到时用 DEFAULT_PUSH_ENABLED(默认开)—— 只有显式存了 false 才关'); assert.match(code_, /static setEnabled\(context: common\.Context, enabled: boolean\): void \{/, '要有静态 setEnabled(设置页 Toggle 回调用)'); }); diff --git a/client/harmony/entry/src/main/ets/api/PushService.ets b/client/harmony/entry/src/main/ets/api/PushService.ets index 609e47f..c05e36d 100644 --- a/client/harmony/entry/src/main/ets/api/PushService.ets +++ b/client/harmony/entry/src/main/ets/api/PushService.ets @@ -24,6 +24,7 @@ import { ApiClient } from './ApiClient'; import { AccountManager } from './AccountManager'; import { PROVIDER_HMS, + DEFAULT_PUSH_ENABLED, PushRegisterBody, PushNotificationData, buildTokenBody, @@ -81,16 +82,17 @@ export class PushService { } /** - * 读「接入系统通知」开关(**默认关** —— 自部署/无凭证时零开销)。 - * 读不到(首次/异常)都返回 false:宁可不开,也不要"默认就把用户裹进来"。 + * 读「接入系统通知」开关(**默认开** —— 见 PushContract.DEFAULT_PUSH_ENABLED)。 + * 读不到(首次/异常)都返回开:推送是用户要能默认收到的功能, + * 降级发生在服务端回 enabled:false 时(通道未配),不是由客户端默认关掉。 */ static isEnabled(context: common.Context): boolean { try { const store = preferences.getPreferencesSync(context, { name: STORE }); - const v = store.getSync(SETTING_KEY, false); + const v = store.getSync(SETTING_KEY, DEFAULT_PUSH_ENABLED); return v === true; } catch (e) { - return false; + return DEFAULT_PUSH_ENABLED; } } diff --git a/client/harmony/entry/src/main/ets/model/PushContract.ts b/client/harmony/entry/src/main/ets/model/PushContract.ts index 7453059..5d47d5a 100644 --- a/client/harmony/entry/src/main/ets/model/PushContract.ts +++ b/client/harmony/entry/src/main/ets/model/PushContract.ts @@ -14,10 +14,11 @@ export const PROVIDER_HMS: string = 'hms'; /* * ★ 2026-09-15:接入系统通知 = **可配置项**(用户强调多次——“用户可以自由部署自己的 agentmail”)。 - * 默认 **关**:自部署/无服务端推送凭证时,客户端不取 token、不弹权限、不上报、不打网关。 - * 这个常量是**契约**(判据跑它),实际落点在 PushService.isEnabled 的读不到即 false。 + * 含义是:**服务端没配推送凭证时客户端优雅降级**(enabled:false 是正常态,不报错、不阻塞、不弹窗), + * **不是**默认关掉推送功能。默认 **开** —— 用户要能收到新邮件通知;降级发生在服务端回 enabled:false 时。 + * 这个常量是**契约**(判据跑它),实际落点在 PushService.isEnabled 的读不到即开。 */ -export const DEFAULT_PUSH_ENABLED: boolean = false; +export const DEFAULT_PUSH_ENABLED: boolean = true; /** 签名:'on' | 'off'(开关的显示口径;无服务器状态时显示 'server-unknown') */ export function pushEnabledLabel(enabled: boolean): string {