"""后台管理 API 请求/响应模型""" from datetime import datetime from typing import Any, Dict, List, Optional from pydantic import BaseModel, EmailStr, Field class EnterpriseResponse(BaseModel): id: int name: str code: Optional[str] = None ai_display_name: str = Field(..., description="AI 助手对外展示名称(系统提示词等)") created_at: Optional[datetime] = None class EnterpriseUpdate(BaseModel): name: str = Field(..., min_length=1, max_length=255) ai_display_name: str = Field( ..., min_length=1, max_length=128, description="AI 助手名称,将进入各模式系统提示词", ) class DepartmentCreate(BaseModel): name: str = Field(..., min_length=1, max_length=255) parent_id: Optional[int] = None class DepartmentUpdate(BaseModel): name: Optional[str] = Field(None, min_length=1, max_length=255) parent_id: Optional[int] = None class DepartmentSetLeader(BaseModel): leader_user_id: Optional[int] = Field(None, description="负责人 user_id,传 null 表示清除") class DepartmentResponse(BaseModel): id: int enterprise_id: int name: str parent_id: Optional[int] = None leader_user_id: Optional[int] = None leader_name: Optional[str] = None created_at: Optional[datetime] = None class AdminUserCreate(BaseModel): username: str = Field(..., max_length=50) email: EmailStr phone: str = Field(..., max_length=255) password: str = Field(..., min_length=6) display_name: Optional[str] = Field(None, max_length=100) department_id: Optional[int] = None role: str = Field("employee", description="admin | leader | employee") class AdminUserUpdate(BaseModel): email: Optional[EmailStr] = None phone: Optional[str] = Field(None, max_length=255) display_name: Optional[str] = Field(None, max_length=100) department_id: Optional[int] = None role: Optional[str] = Field(None, description="admin | leader | employee") is_active: Optional[bool] = None password: Optional[str] = Field(None, min_length=6) allow_kb_upload: Optional[bool] = None class UserPermissionUpdate(BaseModel): """领导更新下属权限(仅 allow_kb_upload)""" allow_kb_upload: bool class AdminUserListItem(BaseModel): id: int username: str email: str phone: str display_name: Optional[str] = None enterprise_id: int department_id: Optional[int] = None role: str is_active: bool is_first_login: bool = True allow_kb_upload: bool = True created_at: Optional[datetime] = None last_login_at: Optional[datetime] = None class AdminUserListResponse(BaseModel): total: int items: list[AdminUserListItem] # ── 审计日志 ────────────────────────────────── class AuditLogItem(BaseModel): id: int enterprise_id: int actor_id: int actor_name: Optional[str] = None action: str target_user_id: Optional[int] = None target_name: Optional[str] = None department_id: Optional[int] = None department_name: Optional[str] = None kb_id: Optional[int] = None kb_name: Optional[str] = None file_id: Optional[int] = None file_name: Optional[str] = None ip: Optional[str] = None metadata: Optional[Any] = None created_at: Optional[datetime] = None class AuditLogListResponse(BaseModel): total: int items: List[AuditLogItem] # ── 团队成员(领导视角) ────────────────────── class TeamMemberItem(BaseModel): id: int username: str display_name: Optional[str] = None department_id: Optional[int] = None department_name: Optional[str] = None role: str is_active: bool allow_kb_upload: bool created_at: Optional[datetime] = None