一次性完成待办模块的 5 项缺口。 ## #38 待办提醒 `ReminderService` 原本只服务 `kind='event'`,待办完全不提醒。 - `EventDb.queryRemindableTodos`:查未完成待办,**额外要求 `completed=0`** (否则做完的待办到期还会弹) - `refreshReminders` 合并日程 + 待办两路查询,文案按 kind 分支: 待办是「将在 X 分钟后到期」/`该待办已到期`,日程仍为「开始」 - `IcsUtil.buildTodo` 写 VALARM;`rewriteTodoFields` 编辑时整段重建 VALARM (逐行改 TRIGGER 容易漏 ACTION/DESCRIPTION) - 待办弹层加提醒芯片(不提醒 / 5 / 15 / 30 分钟 / 1 小时 / 1 天,多选) - 三个写操作后调 `refreshReminders`,保证改完立刻重排 协议要点:VTODO 的 VALARM `TRIGGER` 相对 **DUE**(RFC 5545 §3.8.6.3), 所以 `TRIGGER:-PT5M` 就是"到期前 5 分钟",无需额外写 RELATED=END。 ## #39 待办列表左滑删除 `swipeAction` 只能挂 ListItem,而原结构是 `Scroll + Column + ForEach`。 - 外层 Scroll → List,分组改用 `ListItemGroup`(保留"色点+本名+条数"分组头) - 每个 ListItem 挂 `swipeAction({ end: ... })`,滑出红底「删除」 - 点击复用现有 `askDeleteTodo`(二次确认)→ `doDeleteTodo`(软删 + 服务器 DELETE) - 未完成 / 已完成两个清单都支持 ## #40 优先级 / 标签 / 地点 - 表加 `priority`(INTEGER) / `categories`(TEXT);`location` 本来就有 - PRIORITY 存 **iCal 原生值**(1 最高 … 9 最低,0 未设置),写回零转换 - ICS:`parseTodos` 读 PRIORITY/CATEGORIES,`buildTodo` 与 `rewriteTodoFields` 写 - 新增 `todoExtras()` 供新建与改写共用,避免两处生成结构不一致 - `rewriteTodoFields` 用 `priority=-1` 做"不改"哨兵(0 是合法语义:清空) - 弹层加优先级芯片(高/中/低)、标签输入、地点输入 ## #41 重复待办打勾推进 核查结论:**已实现且完整**。`toggleTodo` 已按 `recurRule !== ''` 分流到 `completeRecurringRound`,且该方法会保留"基准→DUE 偏移"、复位 STATUS 后推进。 本次未改逻辑,仅补了完成后刷新卡片与提醒。 ## #42 编辑入口热区 内容区 `Column` 原来高度只到文字高度,行内上下留白点不到。 加 `.height('100%')` + `justifyContent(Center)` 撑满行高。 勾选圈仍是独立 onClick(ArkUI 不冒泡),点圈只切完成态、不进编辑。 ## 顺带修复(共性遗漏) `toggleTodo` / `saveTodoEdit` / `saveNewTodo` / `doDeleteTodo` 四处 改完库只刷 `this.todos`,**都没推送桌面卡片** —— 卡片停在旧数据。 四处统一补 `CardDataService.pushToAllForms`。 ## 验证 - 编译 `BUILD SUCCESSFUL` - 真机 dump 确认弹层新 UI 全部渲染:优先级(高/中/低)、 提醒(不提醒/提前5分钟/15/30/1小时/1天)、标签、地点 - ICS 生成逻辑用等价实现校验:PRIORITY、CATEGORIES(逗号转义 \, LOCATION、VALARM(TRIGGER:-PT5M 位于 VTODO 内、结构闭合)全部通过 ## 未验证 端到端「填字段→创建→查服务器 ICS」未跑通:`uitest inputText` 按坐标输入时 多个输入框会累积到同一个(把标签/地点内容追加进了标题框),是自动化限制而非代码问题。 需人工建一条带各字段的待办,确认服务器端 ICS 与上述结构一致。 提醒能否实际弹出依赖代理提醒权限(此前有配额为 0 的记录)。
This commit is contained in:
@@ -161,8 +161,13 @@ export class ReminderService {
|
||||
LogUtil.write(`取消全部提醒后系统仍剩 ${before} 条`);
|
||||
}
|
||||
const now: number = Date.now();
|
||||
const rows: LocalEvent[] =
|
||||
// ⭐ #38 日程 + 待办一起排提醒。两类分别查(过滤条件不同:
|
||||
// 待办要求 completed=0,日程无此概念),合并后统一处理。
|
||||
const eventRows: LocalEvent[] =
|
||||
await EventDb.queryRemindable(context, now, now + ReminderService.WINDOW);
|
||||
const todoRows: LocalEvent[] =
|
||||
await EventDb.queryRemindableTodos(context, now, now + ReminderService.WINDOW);
|
||||
const rows: LocalEvent[] = eventRows.concat(todoRows);
|
||||
// 提醒静音的日历本(如别人分享的本):其中所有日程都不再提醒
|
||||
const muted: string[] = await AppSettings.getMutedReminderKeys(context);
|
||||
// ⭐⭐ 已镜像到系统日历的本:由系统日历负责提醒,App 不再重复排(消除"提醒两次")
|
||||
@@ -193,6 +198,8 @@ export class ReminderService {
|
||||
}
|
||||
const d = new Date(remindAt);
|
||||
const calName: string = await ReminderService.calName(context, e.calKey);
|
||||
// #38 文案按类型区分:待办是"到期",日程是"开始"
|
||||
const isTodo: boolean = e.kind === 'todo';
|
||||
const request: reminderAgentManager.ReminderRequestCalendar = {
|
||||
reminderType: reminderAgentManager.ReminderType.REMINDER_TYPE_CALENDAR,
|
||||
dateTime: {
|
||||
@@ -203,10 +210,14 @@ export class ReminderService {
|
||||
minute: d.getMinutes(),
|
||||
second: 0
|
||||
},
|
||||
title: '日程提醒',
|
||||
content: `「${calName}」中的「${e.title}」将在 ${rem} 分钟后开始`,
|
||||
title: isTodo ? '待办提醒' : '日程提醒',
|
||||
content: isTodo
|
||||
? `「${calName}」中的待办「${e.title}」将在 ${rem} 分钟后到期`
|
||||
: `「${calName}」中的「${e.title}」将在 ${rem} 分钟后开始`,
|
||||
// ⚠️ 通知 id 必须唯一:日程与待办的 id 来自同一张表(自增主键),
|
||||
// 天然不冲突,所以这里不用额外加偏移,否则会与 rem 的乘加混淆。
|
||||
notificationId: (e.id * 10 + rem) % 100000,
|
||||
expiredContent: '该日程已开始',
|
||||
expiredContent: isTodo ? '该待办已到期' : '该日程已开始',
|
||||
ringDuration: 5,
|
||||
snoozeTimes: 0,
|
||||
timeInterval: 0
|
||||
|
||||
Reference in New Issue
Block a user