重复计划显示异常

## 1. 问题背景

by 于尘 ·
知与行 CloudBase

1. 问题背景

用户在"行"页面创建了一个每日重复的计划(5月10日上午9点创建"每天下午2点运动")。

  • 数据库中:scheduled_time = 2026-05-10 09:00repeat_days = 127(每天)
  • 5月10日时间格正确显示下午2点的计划
  • 5月11日时间格不显示(问题)

核心问题:时间格显示逻辑只比较 scheduled_time 的日期是否等于"今天",没有考虑重复计划的实际显示日期应基于 repeat_days 计算。

2. 问题列表

2.1 时间格不显示历史创建的重复计划

根因分析

  • TimeGrid.tsx 第144行(修改前):if (planStartDateStr !== todayStr) return false
  • 当前逻辑要求计划的 scheduled_time 日期必须等于"今天"
  • 但对于重复计划,正确逻辑应该是:根据 repeat_days 计算该计划在"今天"是否应该显示

why1: 为什么重复计划在跨天后不显示? 因为 getSlotPlans 函数中 planStartDateStr !== todayStr 直接返回 false,而 planStartDateStr 是数据库中 stored scheduled_time 的日期(5月10日),与"今天"(5月11日)不相等。

why3: 为什么函数会在5月10日返回? 函数逻辑是从 baseTime 开始每10分钟扫描一次,找到第一个 dow & repeatDays 匹配的日子就返回。这个逻辑对"当天完成当天重新创建"场景是正确的,但对"跨天完成"场景有缺陷。

方案

  • 短期方案:修改 getSlotPlanscurrentActivePlan,使用 getPlanDateForDisplay 函数计算重复计划在今天的实际显示日期。
  • 长远方案:统一重复计划的日期计算逻辑。

采纳方案: 采用短期方案,新增 getPlanDateForDisplay 辅助函数,计算重复计划在指定日期是否应显示,并相应修改 getSlotPlanscurrentActivePlan 的日期过滤和时间计算逻辑。

实际改动

  1. TimeGrid.tsx 新增 getPlanDateForDisplay 函数(第58-89行):

    • 非重复计划:直接返回 scheduled_time 的日期
    • 重复计划且 scheduled_time 在今天之前:从今天往前扫描最多7天,找到第一个符合 repeat_days 的日期
    • 重复计划且 scheduled_time 在今天或之后:返回 scheduled_time 的日期
  2. TimeGrid.tsx 修改 currentActivePlan(第99-132行):

    • 使用 getPlanDateForDisplay 过滤计划
    • 对跨天重复计划,计算在今天的实际显示时间(保留原计划的小时和分钟)
  3. TimeGrid.tsx 修改 getSlotPlans(第182行之后):

    • 使用 getPlanDateForDisplay 过滤计划
    • 对跨天重复计划,计算在今天的实际显示时间

补充用例

  1. 5月10日上午9点创建"每天下午2点运动" → 5月11日时间格应显示下午2点的计划
  2. 5月10日完成计划 → 应创建下一个重复计划(5月11日下午2点)

2.2 完成重复计划后再创建下一个计划日期错误

根因分析

  • calculateNextRepeatTime 函数从 base + 10分钟 开始扫描
  • 当 baseTime 为5月10日09:00时,扫描从5月10日09:10开始,5月10日当天就满足"每天重复"条件,函数提前返回

方案:从"明天"开始扫描,而非从 base + 10分钟。

实际改动xing/index.tsxcalculateNextRepeatTime 函数(第175-192行):

  • 改为从"明天"开始扫描最多7天
  • 保持原计划的小时和分钟(如原计划14:00,新计划也是14:00)

额外改动getNextOccurrenceDisplayTime 函数(第194行之后)增加了判断:如果 scheduledTime 已经是未来的日期,直接返回,不再扫描。

2.3 完成计划时增加验证

实际改动xing/index.tsxhandleCompletePlan 函数(第578行之后)增加了验证:

  • 检查计划的 scheduled_time 是否为今天或之前
  • 如果 scheduled_time 是明天或之后,弹出提示"这不是今天的计划,当天再来完成吧~"

2.4 插入重复计划后增加错误处理

实际改动confirmCompletePlan 函数(第592行之后)增加了插入结果检查:

  • 使用 .select().single() 获取插入后的完整数据
  • 检查 insertError,如有错误则打印日志
  • 避免插入失败时仍尝试使用不完整的数据更新状态

2.5 数据库查询增加 user_id 字段

实际改动: 多处 SQL 查询增加 user_id 字段,确保返回完整数据:

  • activeRes 查询
  • todayRes 查询
  • allRes 查询
  • 历史计划查询

3. 小结

修复了两个核心问题:

  1. TimeGrid.tsx:新增 getPlanDateForDisplay 函数,修复重复计划在时间格中的显示逻辑
  2. xing/index.tsxcalculateNextRepeatTime 函数从"明天"开始扫描,确保跨天完成重复计划时新计划日期正确

同时增加了健壮性改进:

  • 完成计划前验证是否为今天的计划
  • 插入重复计划时的错误处理和日志
  • 数据库查询返回完整的 user_id 字段
← 所有文章