diff --git a/entry/src/main/ets/common/ReminderService.ets b/entry/src/main/ets/common/ReminderService.ets index 5557c0d..9dcf3bd 100644 --- a/entry/src/main/ets/common/ReminderService.ets +++ b/entry/src/main/ets/common/ReminderService.ets @@ -12,7 +12,7 @@ import { BusinessError } from '@kit.BasicServicesKit'; import { EventDb, LocalEvent } from './EventDb'; import { AppSettings } from './AppSettings'; import { AccountStore } from './AccountStore'; -import { SystemCalendarMirror, BookRef } from './SystemCalendarMirror'; +import { SystemCalendarMirror } from './SystemCalendarMirror'; import { LogUtil } from './LogUtil'; export class ReminderService { @@ -34,32 +34,21 @@ export class ReminderService { /** * ⭐⭐ 取"已镜像到系统日历"的日历本 calKey 集合(0.0.8 修复双通道重复提醒)。 * - * 背景:镜像到系统日历后,**系统日历自己会提醒**(条目的 reminderTime)。 - * 若 App 再为同一个本排代理提醒 → 同一条日程提醒两次。 - * 因此这里返回"该由系统日历负责提醒"的本,App 侧跳过它们。 + * 镜像到系统日历后,**系统日历自己会提醒**(条目的 reminderTime); + * 若 App 再为同一个本排代理提醒 → 同一条日程提醒两次。 + * 因此这里返回"该由系统日历负责提醒"的本,App 侧**完全不再提醒**它们。 * + * ⚠️ 判据是"**镜像账户真实存在**"(`SystemCalendarMirror.mirroredCalKeys`), + * 而不是"用户勾选了要镜像"—— 后者只是意图,本可能还没被真正写进系统日历; + * 按意图跳过会导致"两边都不提醒"(漏提醒)。 * ⚠️ 返回空集 = 不跳过任何本(保守:宁可多提醒,不可漏提醒)。 - * 仅在「镜像开关已开 + 有系统日历权限 + 有选中本」时才真正跳过。 */ private static async mirroredKeys(context: common.Context): Promise> { if (Date.now() - ReminderService.mirroredLoadedAt < 30000 && ReminderService.mirroredCalKeys.size > 0) { return ReminderService.mirroredCalKeys; } - const out: Set = new Set(); - try { - const on: boolean = await AppSettings.getMirrorEnabled(context); - if (on && await SystemCalendarMirror.hasPermission()) { - const refs: BookRef[] = await SystemCalendarMirror.selectedBookRefs(context); - for (const r of refs) { - if (r.calKey !== '') { - out.add(r.calKey); - } - } - } - } catch (err) { - // 判定失败 → 返回空集(不跳过,避免漏提醒) - } + const out: Set = await SystemCalendarMirror.mirroredCalKeys(context); ReminderService.mirroredCalKeys = out; ReminderService.mirroredLoadedAt = Date.now(); return out; diff --git a/entry/src/main/ets/common/SystemCalendarMirror.ets b/entry/src/main/ets/common/SystemCalendarMirror.ets index 2b50ff4..0458727 100644 --- a/entry/src/main/ets/common/SystemCalendarMirror.ets +++ b/entry/src/main/ets/common/SystemCalendarMirror.ets @@ -239,6 +239,56 @@ export class SystemCalendarMirror { return name.startsWith(SystemCalendarMirror.ACCOUNT_PREFIX); } + /** + * ⭐⭐ 取"**确实已经镜像到系统日历**"的日历本 calKey 集合(按镜像账户的**真实存在性**判定)。 + * + * 与"用户勾选了要镜像的本"不同 —— 后者只是**意图**,本可能还没被真正写进系统日历 + * (如刚勾选但没点「立即执行镜像」、或根本没开镜像开关)。 + * 若按"意图"跳过 App 提醒,而系统日历里其实还没有 → **两边都不提醒 = 漏提醒**。 + * 故这里只认**镜像账户真实存在**这一条。 + * + * ⚠️ 返回**空集**=不跳过任何本(读不到账户时保守处理,宁可多提醒)。 + * ⚠️ 未开启镜像开关时直接返回空集(省一次系统查询)。 + */ + static async mirroredCalKeys(context: common.Context): Promise> { + const out: Set = new Set(); + try { + if (!await AppSettings.getMirrorEnabled(context)) { + return out; // 未开启镜像 → 没有任何本由系统日历负责 + } + if (!await SystemCalendarMirror.hasPermission()) { + return out; // 无权限 → 系统日历里不可能有我们的条目 + } + const cm: calendarManager.CalendarManager = calendarManager.getCalendarManager(context); + const all: calendarManager.Calendar[] = []; + const cals: calendarManager.Calendar[] = await cm.getAllCalendars(); + for (const c of cals) { + all.push(c); + } + // 存在镜像账户 → 其 bookId 对应的本由系统日历负责 + const presentBookIds: Set = new Set(); + for (const c of all) { + const name: string = c.getAccount().name; + if (name.startsWith(SystemCalendarMirror.ACCOUNT_PREFIX)) { + presentBookIds.add(name.substring(SystemCalendarMirror.ACCOUNT_PREFIX.length)); + } + } + if (presentBookIds.size === 0) { + return out; + } + // bookId → calKey(从当前账号配置解析) + const refs: BookRef[] = await SystemCalendarMirror.listBooks(context); + for (const r of refs) { + if (presentBookIds.has(r.bookId) && r.calKey !== '') { + out.add(r.calKey); + } + } + } catch (err) { + LogUtil.write(`判定"已镜像本"失败(按未镜像处理): ${(err as BusinessError).message}`); + } + return out; + } + /* ==================== 账户身份判定(0.0.8) ==================== */ /**