@@ -186,6 +186,17 @@ def ensure_real_occurrence(template: RecurrenceTemplate, occurrence_at: datetime
|
||||
raise HTTPException(422, "occurrence_at 晚于该重复规则的有效截止时间")
|
||||
|
||||
|
||||
@router.get("/tasks/{task_id}/recurrence")
|
||||
async def get_task_recurrence(task_id: UUID, user: User = Depends(current_user), db: AsyncSession = Depends(get_db)):
|
||||
await owned_task(db, user.id, task_id)
|
||||
row = await db.scalar(select(RecurrenceTemplate).where(
|
||||
RecurrenceTemplate.task_id == task_id, RecurrenceTemplate.user_id == user.id
|
||||
))
|
||||
if row is None:
|
||||
return None
|
||||
return {"id": row.id, "task_id": row.task_id, "rrule": row.rrule, "starts_at": row.starts_at, "ends_at": row.ends_at}
|
||||
|
||||
|
||||
@router.post("/recurrences", status_code=201)
|
||||
async def create_recurrence(payload: RecurrenceCreate, user: User = Depends(current_user), db: AsyncSession = Depends(get_db)):
|
||||
task = await owned_task(db, user.id, payload.task_id)
|
||||
@@ -779,12 +790,14 @@ async def export_json(user: User = Depends(current_user), db: AsyncSession = Dep
|
||||
def serialize(row, fields):
|
||||
return {f: (str(v) if isinstance((v := getattr(row, f)), UUID) else v.isoformat() if isinstance(v, (date, datetime)) else v) for f in fields}
|
||||
folders = list((await db.scalars(select(Folder).where(Folder.user_id == user.id))).all()); lists = list((await db.scalars(select(TaskList).where(TaskList.user_id == user.id))).all()); tasks = list((await db.scalars(select(Task).where(Task.user_id == user.id))).all()); habits = list((await db.scalars(select(Habit).where(Habit.user_id == user.id))).all()); countdowns = list((await db.scalars(select(Countdown).where(Countdown.user_id == user.id))).all())
|
||||
recurrences = list((await db.scalars(select(RecurrenceTemplate).where(RecurrenceTemplate.user_id == user.id))).all())
|
||||
return {
|
||||
"version": 1,
|
||||
"exported_at": utcnow(),
|
||||
"folders": [serialize(x, ["id", "name", "position", "deleted_at"]) for x in folders],
|
||||
"lists": [serialize(x, ["id", "folder_id", "name", "is_inbox", "position", "deleted_at"]) for x in lists],
|
||||
"tasks": [serialize(x, ["id", "list_id", "parent_id", "title", "description", "priority", "completed", "due_at", "external_id", "deleted_at"]) for x in tasks],
|
||||
"recurrences": [serialize(x, ["id", "task_id", "rrule", "starts_at", "ends_at"]) for x in recurrences],
|
||||
"habits": [serialize(x, ["id", "name", "kind", "target", "max_value", "schedule_type", "weekdays", "month_days", "interval_days", "start_date", "archived_at", "position"]) for x in habits],
|
||||
"countdowns": [serialize(x, ["id", "title", "event_date", "calendar_mode", "lunar_month", "lunar_day", "ignore_year", "kind", "repeat_rule", "icon", "pinned", "archived_at", "created_at", "updated_at"]) for x in countdowns],
|
||||
}
|
||||
@@ -852,6 +865,17 @@ async def restore_json(payload: dict, mode: str = Query("merge", pattern="^(merg
|
||||
for task_id, old_parent_id in pending_tasks:
|
||||
if old_parent_id and old_parent_id in task_id_map:
|
||||
await db.execute(update(Task).where(Task.id == task_id, Task.user_id == user.id).values(parent_id=task_id_map[old_parent_id]))
|
||||
for raw in payload.get("recurrences", []):
|
||||
task_id = task_id_map.get(raw.get("task_id"))
|
||||
if not task_id:
|
||||
continue
|
||||
db.add(RecurrenceTemplate(
|
||||
user_id=user.id,
|
||||
task_id=task_id,
|
||||
rrule=raw["rrule"],
|
||||
starts_at=datetime.fromisoformat(raw["starts_at"]),
|
||||
ends_at=datetime.fromisoformat(raw["ends_at"]) if raw.get("ends_at") else None,
|
||||
))
|
||||
for raw in payload.get("habits", []):
|
||||
row = Habit(
|
||||
user_id=user.id,
|
||||
|
||||
Reference in New Issue
Block a user