feat: add repeating tasks
ci / docker (push) Successful in 4m13s

This commit is contained in:
2026-09-08 08:16:57 +08:00
parent fde37de0fc
commit 0a3b959cb8
7 changed files with 179 additions and 10 deletions
+25 -8
View File
@@ -3,7 +3,7 @@ import json
import time
from collections import defaultdict, deque
from contextlib import asynccontextmanager
from datetime import datetime
from datetime import datetime, timedelta
from pathlib import Path
from uuid import UUID
@@ -26,8 +26,8 @@ from .auth import (
verify_password,
)
from .db import create_schema, get_db
from .models import AppState, Folder, Session, Task, TaskList, User, utcnow
from .mvp import audit
from .models import AppState, Folder, RecurrenceTemplate, Session, Task, TaskList, User, utcnow
from .mvp import audit, occurrences
from .mvp import router as mvp_router
from .schemas import (
BatchResult,
@@ -624,16 +624,33 @@ async def update_task(
user: User = Depends(current_user),
db: AsyncSession = Depends(get_db),
):
task = await db.scalar(select(Task).where(Task.id == task_id, Task.user_id == user.id, Task.deleted_at.is_(None)))
if task is None:
raise HTTPException(status_code=404, detail="任务不存在")
data = payload.model_dump(exclude_unset=True)
expected_version = data.pop("version")
recurrence = None
if data.get("completed") is True:
recurrence = await db.scalar(select(RecurrenceTemplate).where(
RecurrenceTemplate.task_id == task_id, RecurrenceTemplate.user_id == user.id
))
if recurrence:
next_items = occurrences(
recurrence.rrule,
recurrence.starts_at,
recurrence.starts_at + timedelta(microseconds=1),
recurrence.starts_at + timedelta(days=3660),
recurrence.ends_at,
)
if next_items:
data["completed"] = False
data["due_at"] = next_items[0]
recurrence.starts_at = next_items[0]
if "list_id" in data:
await _owned_list(db, user.id, data["list_id"])
parent_id = await db.scalar(
select(Task.parent_id).where(Task.id == task_id, Task.user_id == user.id)
)
if parent_id:
if task.parent_id:
parent_list = await db.scalar(
select(Task.list_id).where(Task.id == parent_id, Task.user_id == user.id)
select(Task.list_id).where(Task.id == task.parent_id, Task.user_id == user.id)
)
if parent_list != data["list_id"]:
raise HTTPException(status_code=400, detail="子任务必须与父任务属于同一清单")