"""投顾待办服务(事件/定时/计算三类来源统一承载,advisor_todo)。""" from __future__ import annotations from datetime import datetime from sqlalchemy.ext.asyncio import AsyncSession from common_const import TODO_STATUS_DONE, TODO_STATUS_PENDING, TODO_STATUS_PROCESSING from model.advisor_todo import AdvisorTodo from model.sys_user import SysUser from repositories.advisor_todo import AdvisorTodoRepo from schemas.advisor import TodoHandleReq from utils.exceptions import ForbiddenError, NotFoundError, ParamError def _todo_item(t: AdvisorTodo) -> dict: return { "id": t.id, "todo_type": t.todo_type, "customer_id": t.customer_id, "advisor_id": t.advisor_id, "source": t.source, "biz_id": t.biz_id, "priority": t.priority, "status": t.status, "due_at": t.due_at.isoformat() if t.due_at else None, "create_time": t.create_time.isoformat() if t.create_time else None, "handle_time": t.handle_time.isoformat() if t.handle_time else None, } async def list_todos( db: AsyncSession, user: SysUser, *, status: str | None = None, todo_type: str | None = None, page: int = 1, page_size: int = 20, ) -> dict: repo = AdvisorTodoRepo(db) items = await repo.list_by_advisor( advisor_id=user.id, status=status, todo_type=todo_type, limit=page_size, offset=(page - 1) * page_size, ) total = await repo.count_by_advisor(advisor_id=user.id, status=status, todo_type=todo_type) return {"total": total, "page": page, "page_size": page_size, "items": [_todo_item(t) for t in items]} async def handle_todo(db: AsyncSession, user: SysUser, todo_id: int, req: TodoHandleReq) -> dict: """待办处理:process=开始处理 / done=完成;单向流转,重复提交同目标态幂等成功。""" todo = await AdvisorTodoRepo(db).get(todo_id) if todo is None: raise NotFoundError("待办不存在") if todo.advisor_id != user.id: raise ForbiddenError("无权操作该待办") if req.action == "process": if todo.status == TODO_STATUS_PROCESSING: return {"todo_id": todo.id, "status": todo.status} if todo.status != TODO_STATUS_PENDING: raise ParamError("仅待处理状态的待办可开始处理") todo.status = TODO_STATUS_PROCESSING else: # done if todo.status == TODO_STATUS_DONE: return {"todo_id": todo.id, "status": todo.status} todo.status = TODO_STATUS_DONE todo.handle_time = datetime.now() await db.commit() return {"todo_id": todo.id, "status": todo.status}