v68 真机验收:修两处真机才暴露的问题(账本权限标签 / 查看行程点不动)

设备接上后第一次真机验收(5NC0225B27004718),25 条断言里抓到两个**真 bug**:

## ① 主人账本也挂一颗「可写」
账本切换条的判据是 `if (b.myPerm !== 'owner')`,而服务端 `Ledger::mine/find`
**从来不给 `owner`**(主人也是 `write`)⇒ 这个 if 恒成立,自己建的账本
也被贴上「可写」,看着像"只是别人共享给我的"。
v68 上一批已经把共享浮层改成 `isOwner`,但这处列表标签漏了 ——
同一批里 `myPerm` 的注释还写着 `owner/read/write`,属于照着错误注释抄。
⇒ 改 `if (!b.isOwner)`,并把那段过期注释纠正。

## ② 卡尾「查看行程」是一颗点不动的字
屏幕上明明写着「查看行程」,点它**什么都不发生** —— 因为展开逻辑只挂在
**卡片主体**的 onClick 上,卡尾这颗 Text 是纯文本,没有 onClick。
用户看不到"要点头像/标题",只会去点这三个字。
⇒ 展开逻辑抽成 `toggleExpand(trip)`,卡片主体与卡尾文字共用;
   卡尾那颗补 onClick 并加内边距(fontTiny 的纯文字热区太小,真机不好点)。

## 验证
- 真机验收 `_fb_v68_verify.py`(v66~v68 三批):**25 通过 / 0 失败**
  (改前 19/6 → 修完 25/0;A2、C2/C3/C4 由红转绿)
- `_fb_arkts_guard.js` → **832 / 0**(新增 v68 ③ 两条、v66 ⑫ 三条)
- `_fb_v59d_falsify.py` → **141 / 0**(新增 2 条注入,都能让守卫变红)
  ⚠️ 「查看行程」那条注入第一次写的是"往后 500 字符内找 .onClick",删掉 onClick
     守卫**照样绿**(500 字符内还有「编辑」那颗)⇒ 改成按段切(Text → 下一个 Column())。
This commit is contained in:
2026-10-20 21:35:38 +08:00
parent 2ff90519fa
commit 030a9c7fbb
2 changed files with 34 additions and 7 deletions
@@ -280,7 +280,13 @@ export struct FbLedgerPage {
.fontSize(FbMetric.fontSmall)
.fontColor(this.isCurrent(b.id) ? Color.White : FbColors.muted)
.maxLines(1)
if (b.myPerm !== 'owner') {
/* 🔴 v68 真机验收补漏(2026-10-20):判据原来是 `myPerm !== 'owner'`,
而服务端 `Ledger::find` **从来不给 `owner`**(主人也是 `write`)
⇒ 这个 if **永远成立**,自己建的那本也被贴了颗「可写」,
看上去像"这本账只是被共享给我的"。
主人身份只能看服务端新补的 `is_owner`(`FbLedgerBook.isOwner`)。
⚠️ 同一批里 `myPerm` 的注释也写着 `owner/read/write`,同样是错的,别再照着抄。 */
if (!b.isOwner) {
FbTag({
text: b.myPerm === 'write' ? '可写' : '只读',
tone: this.isCurrent(b.id) ? 'brand' : 'muted'
@@ -539,7 +545,8 @@ export struct FbLedgerPage {
accent: this.accent,
ledgerId: this.currentId(),
ledgerName: this.currentBook().name,
// 主人才能改共享:`myPerm` 是服务端 `Ledger::find` 给的
/* 主人才能改共享:身份看 `is_owner`(服务端 `Ledger::find` 新补的布尔)。
⚠️ 别用 `myPerm === 'owner'` —— 服务端枚举里根本没有 `owner` 这个值。 */
isOwner: this.currentBook().isOwner,
onClose: (): void => {
this.shareOpen = false;
+25 -5
View File
@@ -541,18 +541,21 @@ export struct FbTripsPage {
.onClick((): void => {
// 点卡片主体 = 展开/收起行程(网页版是"进详情",手机上一屏放不下,
// 就地展开更顺手;编辑走下面那颗小按钮)
const was: boolean = this.isExpanded(t.id);
this.expandedId = was ? 0 : t.id;
if (!was) {
this.loadNodes(t.id);
}
this.toggleExpand(t);
})
// ---- 卡尾操作条:编辑(网页版进详情页才有编辑,这里给个显式入口)----
Row({ space: 14 }) {
/* 🔴 这颗原来只是「字」,没有 `onClick` —— 屏幕上写着"查看行程"却点不动。
现在接上 `toggleExpand`(与卡片主体同一份逻辑),并加内边距把热区做大
(字号只有 fontTiny,纯文字热区太小,真机上不好点)。 */
Text(this.isExpanded(t.id) ? '收起行程' : '查看行程')
.fontSize(FbMetric.fontTiny)
.fontColor(this.accent)
.padding({ left: 6, right: 10, top: 8, bottom: 8 })
.onClick((): void => {
this.toggleExpand(t);
})
Column().layoutWeight(1)
Text('编辑')
.fontSize(FbMetric.fontTiny)
@@ -821,6 +824,23 @@ export struct FbTripsPage {
return this.expandedId === id;
}
/**
* 展开 / 收起某个旅程的行程时间轴。
*
* 🔴 v66 真机验收补漏(2026-10-20):原来这段逻辑**只写在卡片主体的 onClick 里**,
* 而卡尾那颗「查看行程 / 收起行程」是一颗**没有任何 onClick 的纯 Text**
* ⇒ 屏幕上明明写着「查看行程」,点它却什么都不发生(真机验收 C2/C3/C4 就是这么红的)。
* 这类"看得见、点不动"的入口是本项目的红线,必须两处都能点。
* ⇒ 抽成一个方法,卡片主体与卡尾文字共用,行为不会漂。
*/
private toggleExpand(trip: FbTripItem): void {
const was: boolean = this.isExpanded(trip.id);
this.expandedId = was ? 0 : trip.id;
if (!was) {
this.loadNodes(trip.id);
}
}
private nodesOf(stage: string): FbTripNode[] {
return this.nodes.filter((n: FbTripNode): boolean => n.stage === stage);
}