refactor(todo): 移除 due_at 字段,改用 order 字段管理象限内顺序
This commit is contained in:
@@ -13,7 +13,13 @@ from core.logging import get_logger
|
||||
from models.todos import Todo, TodoStatus
|
||||
from v1.schedule_items.repository import SQLAlchemyScheduleItemRepository
|
||||
from v1.todo.repository import TodoRepository
|
||||
from v1.todo.schemas import ScheduleItemBasic, TodoCreate, TodoResponse, TodoUpdate
|
||||
from v1.todo.schemas import (
|
||||
ScheduleItemBasic,
|
||||
TodoCreate,
|
||||
TodoReorderRequest,
|
||||
TodoResponse,
|
||||
TodoUpdate,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
@@ -52,12 +58,20 @@ class TodoService(BaseService):
|
||||
user_id = self.require_user_id()
|
||||
|
||||
try:
|
||||
order_value = request.order
|
||||
if order_value is None:
|
||||
todos_in_priority = await self._repository.list_by_owner(
|
||||
owner_id=user_id,
|
||||
priority=request.priority,
|
||||
)
|
||||
order_value = len(todos_in_priority)
|
||||
|
||||
todo = await self._repository.create(
|
||||
owner_id=user_id,
|
||||
title=request.title,
|
||||
description=request.description,
|
||||
due_at=request.due_at,
|
||||
priority=request.priority,
|
||||
order=order_value,
|
||||
created_by=user_id,
|
||||
)
|
||||
|
||||
@@ -144,8 +158,8 @@ class TodoService(BaseService):
|
||||
todo,
|
||||
title=request.title,
|
||||
description=request.description,
|
||||
due_at=request.due_at,
|
||||
priority=request.priority,
|
||||
order=request.order,
|
||||
status=status_enum,
|
||||
completed_at=completed_at,
|
||||
)
|
||||
@@ -253,6 +267,53 @@ class TodoService(BaseService):
|
||||
},
|
||||
)
|
||||
|
||||
async def reorder(self, request: TodoReorderRequest) -> None:
|
||||
user_id = self.require_user_id()
|
||||
|
||||
seen_ids: set[UUID] = set()
|
||||
original_priorities: set[int] = set()
|
||||
target_priorities: set[int] = set()
|
||||
|
||||
try:
|
||||
for item in request.items:
|
||||
if item.id in seen_ids:
|
||||
raise HTTPException(status_code=400, detail="Duplicate todo id")
|
||||
seen_ids.add(item.id)
|
||||
|
||||
todo = await self._repository.get_by_id(item.id)
|
||||
if todo is None:
|
||||
raise HTTPException(status_code=404, detail="Todo not found")
|
||||
if todo.owner_id != user_id:
|
||||
raise HTTPException(
|
||||
status_code=403, detail="Not authorized to reorder this todo"
|
||||
)
|
||||
|
||||
original_priorities.add(todo.priority)
|
||||
target_priorities.add(item.priority)
|
||||
|
||||
await self._repository.update(
|
||||
todo,
|
||||
priority=item.priority,
|
||||
order=item.order,
|
||||
)
|
||||
|
||||
affected_priorities = original_priorities.union(target_priorities)
|
||||
for priority in affected_priorities:
|
||||
todos = await self._repository.list_by_owner(
|
||||
owner_id=user_id,
|
||||
status=TodoStatus.PENDING,
|
||||
priority=priority,
|
||||
)
|
||||
todos.sort(key=lambda current: (current.order, current.created_at))
|
||||
for index, todo in enumerate(todos):
|
||||
if todo.order != index:
|
||||
await self._repository.update(todo, order=index)
|
||||
|
||||
await self._session.commit()
|
||||
except SQLAlchemyError:
|
||||
await self._session.rollback()
|
||||
raise HTTPException(status_code=503, detail="Todo service unavailable")
|
||||
|
||||
async def list_todos(
|
||||
self,
|
||||
status: str | None = None,
|
||||
@@ -287,7 +348,7 @@ class TodoService(BaseService):
|
||||
)
|
||||
|
||||
schedule_item_ids = await self._repository.get_schedule_items(todo.id)
|
||||
schedule_items = []
|
||||
schedule_items: list[ScheduleItemBasic] = []
|
||||
for item_id in schedule_item_ids:
|
||||
item = await self._schedule_item_repository.get_by_id(item_id)
|
||||
if item:
|
||||
@@ -305,8 +366,8 @@ class TodoService(BaseService):
|
||||
owner_id=todo.owner_id,
|
||||
title=todo.title,
|
||||
description=todo.description,
|
||||
due_at=todo.due_at,
|
||||
priority=todo.priority,
|
||||
order=todo.order,
|
||||
status=status_value,
|
||||
completed_at=todo.completed_at,
|
||||
created_at=todo.created_at,
|
||||
|
||||
Reference in New Issue
Block a user