From c39a48e95f14522b98d784cb0769524aea19df52 Mon Sep 17 00:00:00 2001 From: laoyang Date: Mon, 2 Nov 2026 22:43:10 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E5=BE=85=E5=8A=9E):=20=E6=A0=87=E7=AD=BE?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E5=8F=AA=E7=9C=8B=E6=95=B0=E6=8D=AE=E4=BA=8B?= =?UTF-8?q?=E5=AE=9E=EF=BC=8C=E4=B8=8D=E4=BE=9D=E8=B5=96=E5=8F=AF=E8=83=BD?= =?UTF-8?q?=E7=BC=BA=E5=A4=B1=E7=9A=84=20comps=20=E5=85=83=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=20#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 现象 上一版把 VTODO 同步接进同步循环后,待办数据**确实拉回来了** (日志:家庭计划3条 / 工作任务2条 / 个人成长2条), 但待办标签仍然不显示。 ## 根因:判定挂在元数据上,而元数据拿不到 `shouldShowTodoTab()` 是 `hasTodoBook() && todos.length > 0`。 `hasTodoBook()` 读 `acc.calendarComps`,而这个字段来自服务器的 `supported-calendar-component-set`。 实测:日志里**完全没有**"日历本组件类型 ..."这条记录, 说明该解析路径根本没执行 / 服务器不返回这个属性 ⇒ `calendarComps` 恒为空 ⇒ `hasTodoBook()` 恒 false ⇒ 明明有待办也不显示标签。 ## 修法:改看事实 直接 `return this.todos.length > 0;` 因为 `CalendarDataService.loadTodos` 内部**已经按 visibleKeys(用户勾选的 日历本)过滤**过了,所以 `todos.length > 0` 本身就等价于 "用户勾选范围内确实有待办"。用户一个待办本都没勾时,这个值必然是 0 —— `hasTodoBook()` 原本想防的场景天然被覆盖,它是多余的。 ## 原需求仍然满足 用户要求"没勾选任何待办本 → 标签不显示": 没勾选 ⇒ loadTodos 按 visibleKeys 过滤后为空 ⇒ 标签不显示。✓ "勾选了但没待办数据 → 也不显示":0 条 ⇒ 不显示。✓ ## comps 还留着,但只给图标用 账号页用 comps 区分日历/待办图标 —— 那里判断错了只是图标不准, 不影响功能可用性;功能判定不能挂在这种"可能缺失"的元数据上。 ## 验证(真机) 日志: 日历本[5]「家庭计划」REPORT 返回 0 个资源 → 待办同步:3 条 日历本[6]「工作任务」REPORT 返回 0 个资源 → 待办同步:2 条 日历本[7]「个人成长」REPORT 返回 0 个资源 → 待办同步:2 条 界面 dump:顶部标签 同步日历|今天|月|周|列表|**待办**|2026年11月 待办标签存在 = True ✓ (另注意:这几个本 VEVENT 为 0、只有 VTODO,正是纯待办本。) ## 教训 功能可见性判定必须挂在**数据事实**上,不能挂在"可能缺失的元数据"上。 服务器不保证返回 supported-calendar-component-set,用它做开关会制造假阴性。 --- entry/src/main/ets/pages/Index.ets | 37 +++++++++++------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/entry/src/main/ets/pages/Index.ets b/entry/src/main/ets/pages/Index.ets index 3fa5c47..ff7c4e9 100644 --- a/entry/src/main/ets/pages/Index.ets +++ b/entry/src/main/ets/pages/Index.ets @@ -2072,33 +2072,24 @@ struct Index { } /** - * ⭐ HAS_TODO_BOOK 是否勾选了"待办本"。 + * ⭐ TODO_TAB_FACT 待办标签是否显示 —— 只看**事实**,不看声明。 * - * 判定:该账号的 calendarComps 里,**被选中**的日历本中存在 'todo' 或 'both'。 - * 一个都没选 ⇒ 必然没有待办,待办标签直接不显示。 + * 判定:`this.todos` 里是否有数据。 * - * 兼容:calendarComps 为空(旧账号数据没这个字段)或值 'unknown' - * 时不判定为待办本,退回由"待办条数>0"来决定,避免误隐藏。 + * 为什么不再判断"有没有勾选待办本": + * 那个判定依赖 CalendarDataService.loadTodos 之外的 comps 字段, + * 而 comps 来自服务器的 supported-calendar-component-set —— 实测本环境 + * **拿不到这个属性**,字段恒为空 ⇒ 判定恒 false ⇒ 明明有待办也不显示标签。 + * (这个 bug 就是这样产生的:数据同步成功了,标签却被前面的判定挡掉。) + * + * 而 `loadTodos` 内部已经按 `visibleKeys`(用户勾选的日历本)过滤过, + * 所以 `todos.length > 0` 本身就等价于"用户勾选的范围内确实有待办", + * 用户没勾任何待办本时这个值必然是 0 —— 原本想防的场景天然被覆盖。 + * + * 结论:功能判定必须挂在**数据事实**上,不能挂在可能缺失的元数据上。 */ - private hasTodoBook(): boolean { - for (const acc of this.accounts) { - const comps: string[] = acc.calendarComps; - if (comps === undefined || comps.length === 0) { - continue; // 旧数据:交给条数判定 - } - for (let i = 0; i < acc.calendarHrefs.length && i < comps.length; i++) { - const c: string = comps[i]; - if (c === 'todo' || c === 'both') { - return true; - } - } - } - return false; - } - - /** 待办标签是否该显示:必须"选了待办本" **且** "确实有待办数据" */ private shouldShowTodoTab(): boolean { - return this.hasTodoBook() && this.todos.length > 0; + return this.todos.length > 0; } /** 当前选中日是否就是今天(用于「今天」按钮的视觉状态) */