跨端对齐:授权栏 navigator_only + 组件按页拆分 + 服务器补 permission_options

用户两项裁定落地(均为 ask_user 明确选择):

① 授权栏口径 = navigator_only(照 WebUI 架构)
   · 新建 pages/PermissionPanel.ets —— 详情页的决策面板,
     对应 MailView.tsx:693 的 PermissionPanel(审批型 / 主动提问 / 已处理 三态)
   · 决策入口从授权栏移到 MailDetailPage;MailDetailPage 原来只显示一个
     「权限请求」小标签、根本没有决策入口(比 WebUI 少一整块,且反了:
     栏里能决策、点进详情反而不能)
   · PermissionTab 删掉内联「同意/拒绝」+ 备注框 + decide():
     整卡可点 → onOpenMail(对齐 WebUI PermissionList.tsx:81 的 pick())
   · PermissionRequest 补 source_account_id(客户端侧记来源,跳详情要定位网关)

② 服务器补 permission_options —— 修一条真实的、跨端共有的缺口
   · mails.permission_options 从 INSERT 起就写进去,但**从来没有任何读路径
     选过它** ⇒ 详情端点永远返回空。WebUI 的决策面板读 mail.permission_options,
     所以提问型的预设选项**两端全部落空**(审批型靠 ['同意','拒绝'] 兜底蒙混)
   · GetMailByID 补选该列 + JSON 反序列化(与 cc_list 同款)

③ 组件按页封装(用户要求「以便与 WebUI 一一对应」)
   MainPage.ets 4592 → 3192 行
   · pages/PermissionTab.ets    720 行  ↔ PermissionList.tsx
   · pages/ContactsTab.ets      796 行  ↔ ContactPanel.tsx
   · pages/NavDestinations.ets  181 行  ↔ Navigation 壳
   · pages/NavShared.ets         65 行  ↔ 跨栏共用件

④ 判据跟着组件搬家(否则静默失效,不是红)
   harmony-logic 的 pageCode / harmony-nav 的 navSrc 改为显式文件名单;
   harmony-appearance 的 PANE_SOURCES 补 ContactsTab;harmony-contacts 三个
   test 并入 ContactsTab;harmony-logic 的决策断言改指 PermissionPanel,
   并新增「授权栏不许再有内联决策」两条(navigator_only 的正形状)。

   animation-audit:共享元素转场判据从「同文件共址」改为「按 id 找驱动」。
   旧形状把 in/out 端必须在同一文件当成代理,而两端**天然在两处**;
   抽出写信页(NavDestinations 持有 in 端)后误报。新判据仍要求每个 id
   都有 Motion.morph 驱动 —— 变异实测:把驱动换成裸 animateTo 仍判红。

判据:files=34 checks=556 red=1(仅 build-stamp,产物待重构建)
This commit is contained in:
2026-09-24 10:10:32 +08:00
parent 487c1c222b
commit 65de1c3884
31 changed files with 4147 additions and 1684 deletions

View File

@ -145,10 +145,20 @@
# ⇒ 这是同一形状的第 N 次:**"清单没跟上代码"不会自己报警**,
# 得靠 `hits=0` 那条判据;而它本次确实报出来了(`diag=mutant-anchor-stale`)。
# 2026-09-23 09:5x baseline 重算(第 11 次)—— 用户:「修改密码也应该做成弹窗吧」一批弹层迁移。
# ① 三个文件漂移,**两类成因已分别取证**(这一步不能省 —— 底本过期与变异残留在 sha256 眼里一样):
# · AdminUsersPage.ets、BackgroundPicker.ets —— `git diff --quiet HEAD` ⇒ **空**(与 HEAD 逐字节相同),
# 最近提交 `aa10427` / `9064ead` ⇒ **底本过期(stale)**,不是残留。
# · SettingsPage.ets —— `git diff --quiet HEAD` ⇒ **非空** ⇒ **我的有意编辑**,逐块核过 diff 只有重构、无半截/占位。
# ② 有意编辑的内容(用户:「修改密码也应该做成弹窗吧」):
# 修改密码 / 新增账号 → 官方 `bindSheet`(`FIT_CONTENT` + `showClose: true`,两者同形);
# 删掉自绘遮罩(该文件里 `Theme.overlay` 只剩注释引用);
# 候选列表补 `Theme.menuIn()`(WebUI `AddressInput.tsx:261` 同款,鸿蒙此前是硬弹)。
# ③ 复算后 `sha256sum -c baseline.sha` 应全 OK(11/11)。
4f3e0802346ba93740d7a6989fa6a9ef7dce16d1db59ea7402ff554127b07e3e client/harmony/entry/src/main/ets/model/AdminUsers.ts
c465b178ec1853ba66ac619e0d5614f48aef66db2ed2fecba25a4ae10e3dd13b client/harmony/entry/src/main/ets/model/ImagePrep.ts
d774fc494c21d4f68314b2a4953ba5a369744d75574c7f88f679497ff27a5ce0 client/harmony/entry/src/main/ets/pages/AdminUsersPage.ets
73c66c7045f579c3eb8b8e0aa07803e7c9363b7ae8375972b251633d3ce969be client/harmony/entry/src/main/ets/common/BackgroundPicker.ets
399d3a67ac78cb02bd6fafe73c0aec27122a2b02154d30f9f94e7d20ce942a19 client/harmony/entry/src/main/ets/pages/SettingsPage.ets
54458e8010b10dc8b057fd399f0ad2b33149c5f051ee120580faa154a6ad0771 client/harmony/entry/src/main/ets/pages/AdminUsersPage.ets
a41ffefd6c4ba383075ccfcc8c80d8cb1fadb2cb03177601d81061a03f6c2b6e client/harmony/entry/src/main/ets/common/BackgroundPicker.ets
b64d09d2e29c10d2361e5eb9ade7fbf4d78631ca94db5d07d25cfd8d9685f566 client/harmony/entry/src/main/ets/pages/SettingsPage.ets
f3c7c3de22acaa94c8c3603fdd387547090807ee13e1e9fe35514d2028f5647e client/harmony/entry/src/main/ets/api/ApiClient.ets
6550e1892d1ebea82fb75a3d2cf8eaf826186199ff4a0ecf0430b1e3517d8681 client/harmony/entry/src/main/ets/api/AppearanceApi.ets

View File

@ -36,8 +36,8 @@
},
{
"file": "client/harmony/entry/src/main/ets/common/Theme.ets",
"pat": " return TransitionEffect\\.opacity\\(0\\)\\.combine\\(\\n TransitionEffect\\.translate\\(\\{ y: Theme\\.riseInOffset \\}\\)\\n \\)\\.animation\\(\\{ duration: Motion\\.dur\\(Theme\\.durRise\\), curve: Theme\\.easeRise \\}\\);",
"repl": " return TransitionEffect.asymmetric(TransitionEffect.opacity(0).combine(TransitionEffect.translate({ y: Theme.riseInOffset })).animation({ duration: Motion.dur(Theme.durRise), curve: Theme.easeRise }), 0, 0, 0, 0);",
"pat": " return TransitionEffect\\.opacity\\(0\\)\\.combine\\(\\n TransitionEffect\\.translate\\(\\{ y: Theme\\.riseInOffset \\}\\)\\n \\)\\.animation\\(Motion\\.effectAnim\\(Theme\\.springIn\\)\\);",
"repl": " return TransitionEffect.asymmetric(TransitionEffect.opacity(0).combine(TransitionEffect.translate({ y: Theme.riseInOffset })).animation(Motion.effectAnim(Theme.springIn)), 0, 0, 0, 0);",
"test": "nav",
"why": "★ paneRiseIn 改回 asymmetric(与 WebUI 的 both 不一致,判据该红)"
},