"""Pydantic数据模型 - 请求/响应模式""" from datetime import datetime from typing import Optional, List, Any from pydantic import BaseModel, Field # ===== 通用响应 ===== class ApiResponse(BaseModel): code: int = 200 message: str = "success" data: Any = None class PageResult(BaseModel): total: int page: int page_size: int items: List[Any] # ===== 虚拟用户 ===== class UserCreateRequest(BaseModel): # 必填 account: str = Field(..., min_length=1, max_length=128, description="新闻平台账号(必填)") password: str = Field(..., min_length=6, max_length=64, description="登录密码(必填)") # 选填 nickname: Optional[str] = Field(None, max_length=64, description="昵称(选填,为空自动生成)") avatar_url: Optional[str] = None activity_level: int = Field(default=1, ge=0, le=2) daily_comment_limit: int = Field(default=10, ge=1, le=100) daily_like_limit: int = Field(default=30, ge=1, le=200) remark: Optional[str] = None class UserUpdateRequest(BaseModel): nickname: Optional[str] = Field(None, min_length=1, max_length=64) password: Optional[str] = Field(None, min_length=6, max_length=64) avatar_url: Optional[str] = None activity_level: Optional[int] = Field(None, ge=0, le=2) daily_comment_limit: Optional[int] = Field(None, ge=1, le=100) daily_like_limit: Optional[int] = Field(None, ge=1, le=200) remark: Optional[str] = None is_enabled: Optional[int] = None class UserResponse(BaseModel): id: int nickname: str account: str avatar_url: Optional[str] real_name: Optional[str] = None sex: int = 0 platform_uid: Optional[str] = None status: int status_label: str activity_level: int activity_label: str daily_comment_limit: int daily_like_limit: int today_comment_count: int today_like_count: int total_interactions: int last_login_at: Optional[datetime] last_interact_at: Optional[datetime] remark: Optional[str] is_enabled: int created_at: datetime personality: Optional[dict] = None class Config: from_attributes = True class UserBatchRequest(BaseModel): user_ids: List[int] action: str # enable/disable/logout/delete # ===== 人格 ===== class PersonalityUpdateRequest(BaseModel): character_type: Optional[str] = None language_style: Optional[str] = None interest_tags: Optional[List[str]] = None interact_tendency: Optional[str] = None word_count_min: Optional[int] = Field(None, ge=10, le=500) word_count_max: Optional[int] = Field(None, ge=10, le=1000) personality_desc: Optional[str] = None class PersonalityResponse(BaseModel): id: int user_id: int character_type: Optional[str] language_style: Optional[str] interest_tags: Optional[List[str]] interact_tendency: Optional[str] word_count_min: int word_count_max: int personality_desc: Optional[str] updated_at: datetime class Config: from_attributes = True # ===== 互动记录 ===== class InteractionQueryParams(BaseModel): page: int = Field(default=1, ge=1) page_size: int = Field(default=20, ge=1, le=100) user_id: Optional[int] = None interact_type: Optional[str] = None status: Optional[int] = None start_date: Optional[str] = None end_date: Optional[str] = None keyword: Optional[str] = None class InteractionResponse(BaseModel): id: int user_id: int user_nickname: Optional[str] user_account: Optional[str] article_id: Optional[str] article_title: Optional[str] interact_type: str interact_type_label: str content: Optional[str] token_consumed: int status: int status_label: str error_msg: Optional[str] retry_count: int executed_at: datetime class Config: from_attributes = True # ===== AI模型配置 ===== class AIModelCreateRequest(BaseModel): model_name: str = Field(..., min_length=1, max_length=64) provider: str = Field(..., pattern="^(openai|zhipu|wenxin|qianwen|local)$") api_base_url: Optional[str] = None api_key: Optional[str] = None model_version: Optional[str] = None temperature: float = Field(default=0.7, ge=0.0, le=2.0) max_tokens: int = Field(default=1000, ge=1, le=32000) timeout_seconds: int = Field(default=30, ge=5, le=300) is_default: int = Field(default=0, ge=0, le=1) class AIModelUpdateRequest(BaseModel): model_name: Optional[str] = None api_base_url: Optional[str] = None api_key: Optional[str] = None model_version: Optional[str] = None temperature: Optional[float] = Field(None, ge=0.0, le=2.0) max_tokens: Optional[int] = Field(None, ge=1, le=32000) timeout_seconds: Optional[int] = Field(None, ge=5, le=300) is_default: Optional[int] = None is_enabled: Optional[int] = None class AIModelResponse(BaseModel): id: int model_name: str provider: str api_base_url: Optional[str] has_api_key: bool model_version: Optional[str] temperature: float max_tokens: int timeout_seconds: int is_default: int is_enabled: int created_at: datetime class Config: from_attributes = True class AIModelTestRequest(BaseModel): model_id: int test_prompt: str = "你好,请简单介绍一下自己。" # ===== 系统配置 ===== class SystemConfigUpdateRequest(BaseModel): configs: dict # ===== 数据统计 ===== class DashboardResponse(BaseModel): user_stats: dict today_interactions: dict monthly_stats: dict token_stats: dict system_status: dict online_users: int # ===== 调度配置 ===== class SchedulerConfigRequest(BaseModel): interact_time_start: Optional[str] = None interact_time_end: Optional[str] = None interact_interval_min: Optional[int] = None interact_interval_max: Optional[int] = None max_concurrent_users: Optional[int] = None daily_token_limit: Optional[int] = None comment_probability: Optional[float] = None reply_probability: Optional[float] = None like_probability: Optional[float] = None collect_probability: Optional[float] = None forward_probability: Optional[float] = None scheduler_enabled: Optional[bool] = None