From 10d5363e29d5b53b2bc893cbd5e29804be7f8040 Mon Sep 17 00:00:00 2001 From: yuyx <237899745@qq.com> Date: Mon, 15 Dec 2025 13:30:40 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20schedules.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/schedules.py | 49 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/db/schedules.py b/db/schedules.py index 8e65058..4294169 100644 --- a/db/schedules.py +++ b/db/schedules.py @@ -145,20 +145,28 @@ def update_user_schedule(schedule_id, **kwargs): updates.append("updated_at = ?") params.append(now_str) - # enabled 状态下,关键字段变更后要重算 next_run_at,确保索引驱动不会跑偏 - should_recompute_next = will_enabled == 1 and any( - key in kwargs for key in ["enabled", "schedule_time", "weekdays", "random_delay"] - ) + # 关键字段变更后重算 next_run_at,确保索引驱动不会跑偏 + # + # 需求:当用户修改“执行时间/执行日期/随机±15分钟”后,即使今天已经执行过,也允许按新配置在今天再次触发。 + # 做法:这些关键字段发生变更时,重算 next_run_at 时忽略 last_run_at 的“同日仅一次”限制。 + config_changed = any(key in kwargs for key in ["schedule_time", "weekdays", "random_delay"]) + enabled_toggled = "enabled" in kwargs + should_recompute_next = config_changed or (enabled_toggled and will_enabled == 1) if should_recompute_next: next_dt = compute_next_run_at( now=now_dt, schedule_time=str(next_time or "08:00"), weekdays=str(next_weekdays or "1,2,3,4,5"), random_delay=int(next_random_delay or 0), - last_run_at=str(current_last_run_at or "") if current_last_run_at else None, + last_run_at=None if config_changed else (str(current_last_run_at or "") if current_last_run_at else None), ) updates.append("next_run_at = ?") params.append(format_cst(next_dt)) + + # 若本次显式禁用任务,则 next_run_at 清空(与 toggle 行为保持一致) + if enabled_toggled and will_enabled == 0: + updates.append("next_run_at = ?") + params.append(None) params.append(schedule_id) sql = f"UPDATE user_schedules SET {', '.join(updates)} WHERE id = ?" @@ -187,7 +195,7 @@ def toggle_user_schedule(schedule_id, enabled): if enabled: cursor.execute( """ - SELECT schedule_time, weekdays, random_delay, last_run_at + SELECT schedule_time, weekdays, random_delay, last_run_at, next_run_at FROM user_schedules WHERE id = ? """, @@ -195,15 +203,28 @@ def toggle_user_schedule(schedule_id, enabled): ) row = cursor.fetchone() if row: - schedule_time, weekdays, random_delay, last_run_at = row[0], row[1], row[2], row[3] - next_dt = compute_next_run_at( - now=now_dt, - schedule_time=str(schedule_time or "08:00"), - weekdays=str(weekdays or "1,2,3,4,5"), - random_delay=int(random_delay or 0), - last_run_at=str(last_run_at or "") if last_run_at else None, + schedule_time, weekdays, random_delay, last_run_at, existing_next_run_at = ( + row[0], + row[1], + row[2], + row[3], + row[4], ) - next_run_at = format_cst(next_dt) + + existing_next_run_at = str(existing_next_run_at or "").strip() or None + # 若 next_run_at 已经被“修改配置”逻辑预先计算好且仍在未来,则优先沿用, + # 避免 last_run_at 的“同日仅一次”限制阻塞用户把任务调整到今天再次触发。 + if existing_next_run_at and existing_next_run_at > now_str: + next_run_at = existing_next_run_at + else: + next_dt = compute_next_run_at( + now=now_dt, + schedule_time=str(schedule_time or "08:00"), + weekdays=str(weekdays or "1,2,3,4,5"), + random_delay=int(random_delay or 0), + last_run_at=str(last_run_at or "") if last_run_at else None, + ) + next_run_at = format_cst(next_dt) cursor.execute( """