重复计划显示异常
## 1. 问题背景
1. 问题背景
用户在"行"页面创建了一个每日重复的计划(5月10日上午9点创建"每天下午2点运动")。
- 数据库中:
scheduled_time = 2026-05-10 09:00,repeat_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 匹配的日子就返回。这个逻辑对"当天完成当天重新创建"场景是正确的,但对"跨天完成"场景有缺陷。
方案:
- 短期方案:修改
getSlotPlans和currentActivePlan,使用getPlanDateForDisplay函数计算重复计划在今天的实际显示日期。 - 长远方案:统一重复计划的日期计算逻辑。
采纳方案:
采用短期方案,新增 getPlanDateForDisplay 辅助函数,计算重复计划在指定日期是否应显示,并相应修改 getSlotPlans 和 currentActivePlan 的日期过滤和时间计算逻辑。
实际改动:
TimeGrid.tsx新增getPlanDateForDisplay函数(第58-89行):- 非重复计划:直接返回 scheduled_time 的日期
- 重复计划且 scheduled_time 在今天之前:从今天往前扫描最多7天,找到第一个符合 repeat_days 的日期
- 重复计划且 scheduled_time 在今天或之后:返回 scheduled_time 的日期
TimeGrid.tsx修改currentActivePlan(第99-132行):- 使用
getPlanDateForDisplay过滤计划 - 对跨天重复计划,计算在今天的实际显示时间(保留原计划的小时和分钟)
- 使用
TimeGrid.tsx修改getSlotPlans(第182行之后):- 使用
getPlanDateForDisplay过滤计划 - 对跨天重复计划,计算在今天的实际显示时间
- 使用
补充用例:
- 5月10日上午9点创建"每天下午2点运动" → 5月11日时间格应显示下午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.tsx 的 calculateNextRepeatTime 函数(第175-192行):
- 改为从"明天"开始扫描最多7天
- 保持原计划的小时和分钟(如原计划14:00,新计划也是14:00)
额外改动:
getNextOccurrenceDisplayTime 函数(第194行之后)增加了判断:如果 scheduledTime 已经是未来的日期,直接返回,不再扫描。
2.3 完成计划时增加验证
实际改动:
xing/index.tsx 的 handleCompletePlan 函数(第578行之后)增加了验证:
- 检查计划的 scheduled_time 是否为今天或之前
- 如果 scheduled_time 是明天或之后,弹出提示"这不是今天的计划,当天再来完成吧~"
2.4 插入重复计划后增加错误处理
实际改动:
confirmCompletePlan 函数(第592行之后)增加了插入结果检查:
- 使用
.select().single()获取插入后的完整数据 - 检查 insertError,如有错误则打印日志
- 避免插入失败时仍尝试使用不完整的数据更新状态
2.5 数据库查询增加 user_id 字段
实际改动:
多处 SQL 查询增加 user_id 字段,确保返回完整数据:
activeRes查询todayRes查询allRes查询- 历史计划查询
3. 小结
修复了两个核心问题:
TimeGrid.tsx:新增getPlanDateForDisplay函数,修复重复计划在时间格中的显示逻辑xing/index.tsx:calculateNextRepeatTime函数从"明天"开始扫描,确保跨天完成重复计划时新计划日期正确
同时增加了健壮性改进:
- 完成计划前验证是否为今天的计划
- 插入重复计划时的错误处理和日志
- 数据库查询返回完整的 user_id 字段