- 从服务器拉取完整代码 - 按框架规范整理项目结构 - 配置 Drone CI 测试环境部署 - 包含后端(FastAPI)、前端(Vue3)、管理端 技术栈: Vue3 + TypeScript + FastAPI + MySQL
353 lines
8.5 KiB
Python
353 lines
8.5 KiB
Python
"""
|
|
管理后台数据模型
|
|
"""
|
|
|
|
from datetime import datetime
|
|
from typing import Optional, List, Any, Dict
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
# ============================================
|
|
# 通用模型
|
|
# ============================================
|
|
|
|
class ResponseModel(BaseModel):
|
|
"""通用响应模型"""
|
|
code: int = 0
|
|
message: str = "success"
|
|
data: Optional[Any] = None
|
|
|
|
|
|
class PaginationParams(BaseModel):
|
|
"""分页参数"""
|
|
page: int = Field(default=1, ge=1)
|
|
page_size: int = Field(default=20, ge=1, le=100)
|
|
|
|
|
|
class PaginatedResponse(BaseModel):
|
|
"""分页响应"""
|
|
items: List[Any]
|
|
total: int
|
|
page: int
|
|
page_size: int
|
|
total_pages: int
|
|
|
|
|
|
# ============================================
|
|
# 认证相关
|
|
# ============================================
|
|
|
|
class AdminLoginRequest(BaseModel):
|
|
"""管理员登录请求"""
|
|
username: str = Field(..., min_length=1, max_length=50)
|
|
password: str = Field(..., min_length=6)
|
|
|
|
|
|
class AdminLoginResponse(BaseModel):
|
|
"""管理员登录响应"""
|
|
access_token: str
|
|
token_type: str = "bearer"
|
|
expires_in: int
|
|
admin_user: "AdminUserInfo"
|
|
|
|
|
|
class AdminUserInfo(BaseModel):
|
|
"""管理员信息"""
|
|
id: int
|
|
username: str
|
|
email: Optional[str]
|
|
full_name: Optional[str]
|
|
role: str
|
|
last_login_at: Optional[datetime]
|
|
|
|
|
|
class AdminChangePasswordRequest(BaseModel):
|
|
"""修改密码请求"""
|
|
old_password: str = Field(..., min_length=6)
|
|
new_password: str = Field(..., min_length=6)
|
|
|
|
|
|
# ============================================
|
|
# 租户相关
|
|
# ============================================
|
|
|
|
class TenantBase(BaseModel):
|
|
"""租户基础信息"""
|
|
code: str = Field(..., min_length=2, max_length=20, pattern=r'^[a-z0-9_]+$')
|
|
name: str = Field(..., min_length=1, max_length=100)
|
|
display_name: Optional[str] = Field(None, max_length=200)
|
|
domain: str = Field(..., min_length=1, max_length=200)
|
|
logo_url: Optional[str] = None
|
|
favicon_url: Optional[str] = None
|
|
contact_name: Optional[str] = None
|
|
contact_phone: Optional[str] = None
|
|
contact_email: Optional[str] = None
|
|
industry: str = Field(default="medical_beauty")
|
|
remarks: Optional[str] = None
|
|
|
|
|
|
class TenantCreate(TenantBase):
|
|
"""创建租户请求"""
|
|
pass
|
|
|
|
|
|
class TenantUpdate(BaseModel):
|
|
"""更新租户请求"""
|
|
name: Optional[str] = Field(None, min_length=1, max_length=100)
|
|
display_name: Optional[str] = Field(None, max_length=200)
|
|
domain: Optional[str] = Field(None, min_length=1, max_length=200)
|
|
logo_url: Optional[str] = None
|
|
favicon_url: Optional[str] = None
|
|
contact_name: Optional[str] = None
|
|
contact_phone: Optional[str] = None
|
|
contact_email: Optional[str] = None
|
|
industry: Optional[str] = None
|
|
status: Optional[str] = None
|
|
expire_at: Optional[datetime] = None
|
|
remarks: Optional[str] = None
|
|
|
|
|
|
class TenantResponse(TenantBase):
|
|
"""租户响应"""
|
|
id: int
|
|
status: str
|
|
expire_at: Optional[datetime]
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
config_count: int = 0 # 配置项数量
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class TenantListResponse(BaseModel):
|
|
"""租户列表响应"""
|
|
items: List[TenantResponse]
|
|
total: int
|
|
page: int
|
|
page_size: int
|
|
|
|
|
|
# ============================================
|
|
# 配置相关
|
|
# ============================================
|
|
|
|
class ConfigTemplateResponse(BaseModel):
|
|
"""配置模板响应"""
|
|
id: int
|
|
config_group: str
|
|
config_key: str
|
|
display_name: str
|
|
description: Optional[str]
|
|
value_type: str
|
|
default_value: Optional[str]
|
|
is_required: bool
|
|
is_secret: bool
|
|
options: Optional[List[str]]
|
|
sort_order: int
|
|
|
|
|
|
class TenantConfigBase(BaseModel):
|
|
"""租户配置基础"""
|
|
config_group: str
|
|
config_key: str
|
|
config_value: Optional[str] = None
|
|
|
|
|
|
class TenantConfigCreate(TenantConfigBase):
|
|
"""创建租户配置请求"""
|
|
pass
|
|
|
|
|
|
class TenantConfigUpdate(BaseModel):
|
|
"""更新租户配置请求"""
|
|
config_value: Optional[str] = None
|
|
|
|
|
|
class TenantConfigResponse(TenantConfigBase):
|
|
"""租户配置响应"""
|
|
id: int
|
|
value_type: str
|
|
is_encrypted: bool
|
|
description: Optional[str]
|
|
created_at: Optional[datetime] = None
|
|
updated_at: Optional[datetime] = None
|
|
# 从模板获取的额外信息
|
|
display_name: Optional[str] = None
|
|
is_required: bool = False
|
|
is_secret: bool = False
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class TenantConfigGroupResponse(BaseModel):
|
|
"""租户配置分组响应"""
|
|
group_name: str
|
|
group_display_name: str
|
|
configs: List[TenantConfigResponse]
|
|
|
|
|
|
class ConfigBatchUpdate(BaseModel):
|
|
"""批量更新配置请求"""
|
|
configs: List[TenantConfigCreate]
|
|
|
|
|
|
# ============================================
|
|
# 提示词相关
|
|
# ============================================
|
|
|
|
class AIPromptBase(BaseModel):
|
|
"""AI提示词基础"""
|
|
code: str = Field(..., min_length=1, max_length=50)
|
|
name: str = Field(..., min_length=1, max_length=100)
|
|
description: Optional[str] = None
|
|
module: str
|
|
system_prompt: str
|
|
user_prompt_template: Optional[str] = None
|
|
variables: Optional[List[str]] = None
|
|
output_schema: Optional[Dict] = None
|
|
model_recommendation: Optional[str] = None
|
|
max_tokens: int = 4096
|
|
temperature: float = 0.7
|
|
|
|
|
|
class AIPromptCreate(AIPromptBase):
|
|
"""创建提示词请求"""
|
|
pass
|
|
|
|
|
|
class AIPromptUpdate(BaseModel):
|
|
"""更新提示词请求"""
|
|
name: Optional[str] = Field(None, min_length=1, max_length=100)
|
|
description: Optional[str] = None
|
|
system_prompt: Optional[str] = None
|
|
user_prompt_template: Optional[str] = None
|
|
variables: Optional[List[str]] = None
|
|
output_schema: Optional[Dict] = None
|
|
model_recommendation: Optional[str] = None
|
|
max_tokens: Optional[int] = None
|
|
temperature: Optional[float] = None
|
|
is_active: Optional[bool] = None
|
|
|
|
|
|
class AIPromptResponse(AIPromptBase):
|
|
"""提示词响应"""
|
|
id: int
|
|
is_system: bool
|
|
is_active: bool
|
|
version: int
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class AIPromptVersionResponse(BaseModel):
|
|
"""提示词版本响应"""
|
|
id: int
|
|
prompt_id: int
|
|
version: int
|
|
system_prompt: str
|
|
user_prompt_template: Optional[str]
|
|
variables: Optional[List[str]]
|
|
change_summary: Optional[str]
|
|
created_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class TenantPromptResponse(BaseModel):
|
|
"""租户自定义提示词响应"""
|
|
id: int
|
|
tenant_id: int
|
|
prompt_id: int
|
|
prompt_code: str
|
|
prompt_name: str
|
|
system_prompt: Optional[str]
|
|
user_prompt_template: Optional[str]
|
|
is_active: bool
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class TenantPromptUpdate(BaseModel):
|
|
"""更新租户自定义提示词"""
|
|
system_prompt: Optional[str] = None
|
|
user_prompt_template: Optional[str] = None
|
|
is_active: Optional[bool] = None
|
|
|
|
|
|
# ============================================
|
|
# 功能开关相关
|
|
# ============================================
|
|
|
|
class FeatureSwitchBase(BaseModel):
|
|
"""功能开关基础"""
|
|
feature_code: str
|
|
feature_name: str
|
|
feature_group: Optional[str] = None
|
|
is_enabled: bool = True
|
|
config: Optional[Dict] = None
|
|
description: Optional[str] = None
|
|
|
|
|
|
class FeatureSwitchCreate(FeatureSwitchBase):
|
|
"""创建功能开关请求"""
|
|
pass
|
|
|
|
|
|
class FeatureSwitchUpdate(BaseModel):
|
|
"""更新功能开关请求"""
|
|
is_enabled: Optional[bool] = None
|
|
config: Optional[Dict] = None
|
|
|
|
|
|
class FeatureSwitchResponse(FeatureSwitchBase):
|
|
"""功能开关响应"""
|
|
id: int
|
|
tenant_id: Optional[int]
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class FeatureSwitchGroupResponse(BaseModel):
|
|
"""功能开关分组响应"""
|
|
group_name: str
|
|
group_display_name: str
|
|
features: List[FeatureSwitchResponse]
|
|
|
|
|
|
# ============================================
|
|
# 操作日志相关
|
|
# ============================================
|
|
|
|
class OperationLogResponse(BaseModel):
|
|
"""操作日志响应"""
|
|
id: int
|
|
admin_username: Optional[str]
|
|
tenant_code: Optional[str]
|
|
operation_type: str
|
|
resource_type: str
|
|
resource_name: Optional[str]
|
|
old_value: Optional[Dict]
|
|
new_value: Optional[Dict]
|
|
ip_address: Optional[str]
|
|
created_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
# 更新前向引用
|
|
AdminLoginResponse.model_rebuild()
|
|
|