Files
JARVIS/backend/app/routers/schedule_center.py

161 lines
5.4 KiB
Python

from calendar import monthrange
from datetime import UTC, date, datetime
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.database import get_db
from app.models.goal import Goal
from app.models.reminder import Reminder
from app.models.task import Task, TaskPriority
from app.models.todo import DailyTodo
from app.models.user import User
from app.routers.auth import get_current_user
from app.schemas.schedule_center import (
ScheduleCenterDateOut,
ScheduleCenterDaySummary,
ScheduleCenterMonthOut,
)
router = APIRouter(prefix="/api/schedule-center", tags=["调度中心"])
def _build_summary(
target_date: str,
todos: list[DailyTodo],
tasks: list[Task],
reminders: list[Reminder],
goals: list[Goal],
) -> ScheduleCenterDaySummary:
return ScheduleCenterDaySummary(
date=target_date,
todo_total=len(todos),
todo_completed=sum(1 for item in todos if item.is_completed),
task_due_total=len(tasks),
high_priority_total=sum(1 for item in tasks if item.priority in {TaskPriority.HIGH, TaskPriority.URGENT}),
reminder_total=len(reminders),
goal_total=len(goals),
)
@router.get("/month", response_model=ScheduleCenterMonthOut)
async def get_month_schedule(
year: int = Query(..., ge=2000, le=2100),
month: int = Query(..., ge=1, le=12),
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
):
month_start = date(year, month, 1)
days_in_month = monthrange(month_start.year, month_start.month)[1]
start_key = month_start.isoformat()
end_key = month_start.replace(day=days_in_month).isoformat()
start_dt = datetime.combine(month_start, datetime.min.time())
end_dt = datetime.combine(month_start.replace(day=days_in_month), datetime.max.time())
todos = (await db.execute(
select(DailyTodo).where(DailyTodo.user_id == current_user.id, DailyTodo.todo_date >= start_key, DailyTodo.todo_date <= end_key)
)).scalars().all()
tasks = (await db.execute(
select(Task).where(
Task.user_id == current_user.id,
Task.due_date.is_not(None),
Task.due_date >= start_dt,
Task.due_date <= end_dt,
)
)).scalars().all()
reminders = (await db.execute(
select(Reminder).where(
Reminder.user_id == current_user.id,
Reminder.reminder_at >= start_dt,
Reminder.reminder_at <= end_dt,
)
)).scalars().all()
goals = (await db.execute(
select(Goal).where(Goal.user_id == current_user.id, Goal.goal_date >= start_key, Goal.goal_date <= end_key)
)).scalars().all()
todo_map: dict[str, list[DailyTodo]] = {}
for item in todos:
todo_map.setdefault(item.todo_date, []).append(item)
task_map: dict[str, list[Task]] = {}
for item in tasks:
key = item.due_date.date().isoformat()
task_map.setdefault(key, []).append(item)
reminder_map: dict[str, list[Reminder]] = {}
for item in reminders:
key = item.reminder_at.date().isoformat()
reminder_map.setdefault(key, []).append(item)
goal_map: dict[str, list[Goal]] = {}
for item in goals:
goal_map.setdefault(item.goal_date, []).append(item)
days = []
for day in range(1, days_in_month + 1):
date_key = month_start.replace(day=day).isoformat()
days.append(_build_summary(
date_key,
todo_map.get(date_key, []),
task_map.get(date_key, []),
reminder_map.get(date_key, []),
goal_map.get(date_key, []),
))
return ScheduleCenterMonthOut(month=f"{year:04d}-{month:02d}", days=days)
@router.get("/date", response_model=ScheduleCenterDateOut)
async def get_date_schedule(
date_str: date = Query(...),
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
):
target_date = date_str
start_dt = datetime.combine(target_date, datetime.min.time())
end_dt = datetime.combine(target_date, datetime.max.time())
date_key = target_date.isoformat()
todos = (await db.execute(
select(DailyTodo)
.where(DailyTodo.user_id == current_user.id, DailyTodo.todo_date == date_key)
.order_by(DailyTodo.created_at.desc())
)).scalars().all()
tasks = (await db.execute(
select(Task)
.where(
Task.user_id == current_user.id,
Task.due_date.is_not(None),
Task.due_date >= start_dt,
Task.due_date <= end_dt,
)
.order_by(Task.created_at.desc())
)).scalars().all()
reminders = (await db.execute(
select(Reminder)
.where(
Reminder.user_id == current_user.id,
Reminder.reminder_at >= start_dt,
Reminder.reminder_at <= end_dt,
)
.order_by(Reminder.reminder_at.asc(), Reminder.created_at.asc())
)).scalars().all()
goals = (await db.execute(
select(Goal)
.where(Goal.user_id == current_user.id, Goal.goal_date == date_key)
.order_by(Goal.created_at.desc())
)).scalars().all()
summary = _build_summary(date_key, todos, tasks, reminders, goals)
return ScheduleCenterDateOut(
date=date_key,
todos=todos,
tasks=tasks,
reminders=reminders,
goals=goals,
summary=summary,
generated_at=datetime.now(UTC),
)