Your Name 0ab58b7e6e fix: 代理商平台显示 + Brief 下载预览功能
- 后端 TaskResponse.ProjectInfo 新增 platform 字段
- 修复代理商 6 个页面硬编码 platform='douyin' 的问题,改为读取实际值
- Brief 预览弹窗:占位符改为 iframe/img 实际展示文件内容
  - PDF 用 iframe 在线预览
  - 图片直接展示
  - 其他类型提示下载
- Brief 下载:改用 a 标签触发下载

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 19:15:03 +08:00

173 lines
3.9 KiB
Python

"""
任务相关 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