From d2d0a435a373304a27976cb63be3d3f7e136886e Mon Sep 17 00:00:00 2001 From: laoyang Date: Fri, 30 Oct 2026 15:41:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=97=A5=E7=A8=8B=E7=BC=96=E8=BE=91=EF=BC=9A?= =?UTF-8?q?=E7=82=B9=E3=80=8C=E5=BC=80=E5=A7=8B=E3=80=8D=E5=8D=B4=E6=94=B9?= =?UTF-8?q?=E4=BA=86=E7=BB=93=E6=9D=9F=E6=97=B6=E9=97=B4=20laoyang/FamilyB?= =?UTF-8?q?ook#34?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户 2026-10-30:「鸿蒙端,日程添加时,选择时间,点上面, 修改的反而是结束时间,这个是 bug。」 根因:openPicker 的参数语义与调用方相反。 · 调用方 dateTimeRow(label, isStart) 传的是 **isStart** · 被调用方签名却是 openPicker(isEnd),内部直接 pickIsEnd = isEnd ⇒ isStart=true(点开始)→ isEnd=true → 整条链路按"结束"处理。 错得很"自洽"所以一直没被发现: · 弹层初值读的是结束时间 · 确认后写回的也是结束时间 · 连标题都显示「选择结束时间」 三处一起错,"弹出来的值"和"改完的值"是一致的,看着不像坏。 修法:参数统一成 isStart(与调用方同名同义),内部自己取反。 没在调用处写 openPicker(!isStart) —— 双重否定更容易再错一次。 对照:观影表单 FbMovieNewSheet 用同一个 FbDateTimePicker 组件, 但 pickIsEnd 是显式赋 false/true,没有正反颠倒的空间,不受影响。 验证: · 编译 BUILD SUCCESSFUL(33 tasks / 17 executed) · 从真实源码提取三条映射做断言:pickIsEnd=!isStart、 读日期/读时间均在 isStart 时取 fStart* —— 全部通过 · 真值表:点开始→读fStart*→写fStart*→标题「选择开始时间」, 点结束→读fEnd*→写fEnd*→标题「选择结束时间」 · 反向验证:拿修复前的代码跑同一判据,正确转红 (旧版点开始时读写都是 fEnd*),证明判据不是恒真 · 全仓库排查 isStart/isEnd 用法,无同类问题 --- .../main/ets/components/FbEventEditSheet.ets | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/entry/src/main/ets/components/FbEventEditSheet.ets b/entry/src/main/ets/components/FbEventEditSheet.ets index 5e1d187..77d8044 100644 --- a/entry/src/main/ets/components/FbEventEditSheet.ets +++ b/entry/src/main/ets/components/FbEventEditSheet.ets @@ -647,13 +647,25 @@ export struct FbEventEditSheet { * * ⚠️ 草稿的意义:用户滚了一半又点「取消」⇒ **不写回**(`fStartXxx` 保持原样)。 * 若直接改 `fStartXxx`,"取消"就没法撤销了。 + * + * 🔴🔴 v88(工单 #34,用户 2026-10-30):「日程添加时,选择时间,点上面, + * 修改的反而是结束时间。」 + * + * 根因:这个参数**原来叫 `isEnd`**,而调用方 `dateTimeRow(label, isStart)` + * 传进来的是 `isStart`。名字一换、语义就反了: + * isStart=true(点「开始」)→ isEnd=true → 整条链路按"结束"处理。 + * 而且错得很"自洽"——弹层初值读的是结束时间、写回也写给结束时间、 + * 连标题都显示「选择结束时间」,三个地方一起错,所以看着不像坏。 + * + * ⇒ 参数统一成 `isStart`(**与调用方同名同义**),内部自己取反。 + * 不要图省事在调用处写 `openPicker(!isStart)` —— 双重否定更容易再错一次。 */ - private openPicker(isEnd: boolean): void { - this.pickIsEnd = isEnd; + private openPicker(isStart: boolean): void { + this.pickIsEnd = !isStart; // ⚠️ 草稿值放在宿主,弹层组件 `aboutToAppear` 时从这里读初值 —— // 组件每次挂载都会重新读一次,所以"点开始 → 取消 → 点结束"拿到的是各自的值。 - this.pickDate = fbParseDate(isEnd ? this.fEndDate : this.fStartDate); - const tm: Date = fbParseTime(isEnd ? this.fEndTime : this.fStartTime); + this.pickDate = fbParseDate(isStart ? this.fStartDate : this.fEndDate); + const tm: Date = fbParseTime(isStart ? this.fStartTime : this.fEndTime); this.pickHour = tm.getHours(); this.pickMin = tm.getMinutes(); this.pickOpen = true;