from __future__ import annotations from pydantic import BaseModel, ConfigDict, Field from app.enums.recent_generation import RecentGenerationModuleEnum, RecentGenerationResourceTypeEnum from app.schemas.common import NaiveDatetimeOptional class RecentGenerationItemOut(BaseModel): """最近生成记录响应项。""" model_config = ConfigDict( json_schema_extra={ "example": { "generated_time": "2026-06-26T14:30:00", "result_url": "https://example.com/generate/video/demo.mp4?exp=1780000000&sign=xxxx", "cover_url": "https://example.com/generate/cover/demo.jpg?exp=1780000000&sign=xxxx", "module": "shot_replicate", "shot_task_set_id": "0019ef0000000000001", "shot_segment_id": "0019ef0000000000002", "module_project_id": "0019ef0000000000003", "module_step_id": "0019ef0000000000004", "generation_id": "0019ef0000000000005", "resource_type": "video", } } ) generated_time: NaiveDatetimeOptional = Field( None, description="生成完成时间。优先使用 generated_at;历史数据 generated_at 为空时回退 updated_at,再回退 created_at。", ) result_url: str | None = Field( None, description="生成结果链接。resource_type=image 时为图片链接;resource_type=video 时为视频链接。返回前会按项目资源签名规则追加 exp/sign。", ) cover_url: str | None = Field( None, description="视频封面链接。仅视频资源通常有值;图片资源或历史无封面数据时返回 null。返回前会按项目资源签名规则追加 exp/sign。", ) module: RecentGenerationModuleEnum = Field( ..., description=( "数据模块枚举:" "project=项目生成 GenerationRecord;" "chat_ai=AI创作 ChatGenerationTask.generation_mode=chatapi_async;" "hot_opening_replicate=爆款开头复刻 ChatGenerationTask.generation_mode=hot_opening_replicate;" "shot_replicate=拆镜复刻 ChatGenerationTask.generation_mode=shot_replicate。" ), ) shot_task_set_id: str | None = Field( None, description="关联拆镜总任务ID。仅 shot_replicate 模块可能有值,来源 shot_replicate_segments.task_set_id;其他模块返回 null。", ) shot_segment_id: str | None = Field( None, description="关联拆镜片段ID。仅 shot_replicate 模块可能有值,来源 shot_replicate_segments.id;其他模块返回 null。", ) module_project_flow_version: str | None = Field( None, description="关联模块项目流程版本。hot_opening_replicate/shot_replicate 返回 v1/v2;其他模块返回 null。", ) module_project_id: str | None = Field( None, description="通用模块项目ID。hot_opening_replicate/shot_replicate 模块可能有值,来源 module_generation_steps.project_id;project/chat_ai 返回 null。", ) module_step_id: str | None = Field( None, description="通用模块步骤ID。hot_opening_replicate/shot_replicate 模块可能有值,来源 module_generation_steps.id;project/chat_ai 返回 null。", ) generation_id: str = Field( ..., description="生成ID。project 模块为 generation_records.id;chat_ai/hot_opening_replicate/shot_replicate 模块为 chat_generation_tasks.id。", ) resource_type: RecentGenerationResourceTypeEnum = Field( ..., description="资源类型枚举:image=图片资源;video=视频资源。前端可据此决定预览组件。", ) class RecentGenerationGroupOut(BaseModel): """最近生成记录固定分组响应。""" model_config = ConfigDict( json_schema_extra={ "example": { "project": [], "chat_ai": [ { "generated_time": "2026-06-26T14:30:00", "result_url": "https://example.com/generate/image/demo.png?exp=1780000000&sign=xxxx", "cover_url": None, "module": "chat_ai", "shot_task_set_id": None, "shot_segment_id": None, "module_project_id": None, "module_step_id": None, "generation_id": "0019ef0000000000010", "resource_type": "image", } ], "hot_opening_replicate": [], "shot_replicate": [], } } ) project: list[RecentGenerationItemOut] = Field( default_factory=list, description="项目生成最近记录数组,来源 generation_records。未查询该模块或无数据时返回空数组。", ) chat_ai: list[RecentGenerationItemOut] = Field( default_factory=list, description="AI创作最近记录数组,来源 chat_generation_tasks,条件 generation_mode=chatapi_async。未查询该模块或无数据时返回空数组。", ) hot_opening_replicate: list[RecentGenerationItemOut] = Field( default_factory=list, description="爆款开头复刻最近记录数组,来源 chat_generation_tasks,条件 generation_mode=hot_opening_replicate。未查询该模块或无数据时返回空数组。", ) shot_replicate: list[RecentGenerationItemOut] = Field( default_factory=list, description="拆镜复刻最近记录数组,来源 chat_generation_tasks,条件 generation_mode=shot_replicate。未查询该模块或无数据时返回空数组。", )