""" 任务相关 Schema """ from typing import Optional, List from datetime import datetime from pydantic import BaseModel, Field from app.models.task import TaskStage, TaskStatus # ===== 通用 ===== class AIReviewResult(BaseModel): """AI 审核结果""" score: int = Field(..., ge=0, le=100) violations: List[dict] = [] soft_warnings: List[dict] = [] summary: Optional[str] = None class ReviewAction(BaseModel): """审核操作""" action: str = Field(..., pattern="^(pass|reject|force_pass)$") comment: Optional[str] = None # ===== 请求 ===== class TaskCreateRequest(BaseModel): """创建任务请求(代理商操作)""" project_id: str creator_id: str name: Optional[str] = None # 不传则自动生成 "宣传任务(N)" class TaskScriptUploadRequest(BaseModel): """上传脚本请求""" file_url: str file_name: str class TaskVideoUploadRequest(BaseModel): """上传视频请求""" file_url: str file_name: str duration: Optional[int] = None # 秒 thumbnail_url: Optional[str] = None class TaskReviewRequest(BaseModel): """审核请求""" action: str = Field(..., pattern="^(pass|reject|force_pass)$") comment: Optional[str] = None class AppealRequest(BaseModel): """申诉请求""" reason: str = Field(..., min_length=1) class AppealCountRequest(BaseModel): """申请增加申诉次数请求""" task_id: str class AppealCountActionRequest(BaseModel): """处理申诉次数请求""" action: str = Field(..., pattern="^(approve|reject)$") # ===== 响应 ===== class CreatorInfo(BaseModel): """达人信息""" id: str name: str avatar: Optional[str] = None class AgencyInfo(BaseModel): """代理商信息""" id: str name: str class ProjectInfo(BaseModel): """项目信息""" id: str name: str brand_name: Optional[str] = None platform: Optional[str] = None class TaskResponse(BaseModel): """任务响应""" id: str name: str sequence: int stage: TaskStage # 关联信息 project: ProjectInfo agency: AgencyInfo creator: CreatorInfo # 脚本信息 script_file_url: Optional[str] = None script_file_name: Optional[str] = None script_uploaded_at: Optional[datetime] = None script_ai_score: Optional[int] = None script_ai_result: Optional[dict] = None script_agency_status: Optional[TaskStatus] = None script_agency_comment: Optional[str] = None script_brand_status: Optional[TaskStatus] = None script_brand_comment: Optional[str] = None # 视频信息 video_file_url: Optional[str] = None video_file_name: Optional[str] = None video_duration: Optional[int] = None video_thumbnail_url: Optional[str] = None video_uploaded_at: Optional[datetime] = None video_ai_score: Optional[int] = None video_ai_result: Optional[dict] = None video_agency_status: Optional[TaskStatus] = None video_agency_comment: Optional[str] = None video_brand_status: Optional[TaskStatus] = None video_brand_comment: Optional[str] = None # 申诉 appeal_count: int = 1 is_appeal: bool = False appeal_reason: Optional[str] = None # 时间 created_at: datetime updated_at: datetime class Config: from_attributes = True class TaskListResponse(BaseModel): """任务列表响应""" items: List[TaskResponse] total: int page: int page_size: int class TaskSummary(BaseModel): """任务摘要(用于列表)""" id: str name: str stage: TaskStage creator_name: str creator_avatar: Optional[str] = None project_name: str is_appeal: bool = False appeal_reason: Optional[str] = None created_at: datetime updated_at: datetime class Config: from_attributes = True class ReviewTaskListResponse(BaseModel): """待审核任务列表响应""" items: List[TaskSummary] total: int page: int page_size: int