feat: 初始化考培练系统项目
- 从服务器拉取完整代码 - 按框架规范整理项目结构 - 配置 Drone CI 测试环境部署 - 包含后端(FastAPI)、前端(Vue3)、管理端 技术栈: Vue3 + TypeScript + FastAPI + MySQL
This commit is contained in:
260
backend/app/schemas/training.py
Normal file
260
backend/app/schemas/training.py
Normal file
@@ -0,0 +1,260 @@
|
||||
"""陪练模块Pydantic模式"""
|
||||
from typing import Optional, List, Dict, Any, Generic, TypeVar
|
||||
from datetime import datetime
|
||||
from pydantic import BaseModel, Field, ConfigDict
|
||||
|
||||
# 定义泛型类型变量
|
||||
DataT = TypeVar("DataT")
|
||||
|
||||
from app.models.training import (
|
||||
TrainingSceneStatus,
|
||||
TrainingSessionStatus,
|
||||
MessageType,
|
||||
MessageRole,
|
||||
)
|
||||
from app.schemas.base import BaseSchema, TimestampMixin, IDMixin
|
||||
|
||||
|
||||
# ========== 陪练场景相关 ==========
|
||||
|
||||
|
||||
class TrainingSceneBase(BaseSchema):
|
||||
"""陪练场景基础模式"""
|
||||
|
||||
name: str = Field(..., max_length=100, description="场景名称")
|
||||
description: Optional[str] = Field(None, description="场景描述")
|
||||
category: str = Field(..., max_length=50, description="场景分类")
|
||||
ai_config: Optional[Dict[str, Any]] = Field(None, description="AI配置")
|
||||
prompt_template: Optional[str] = Field(None, description="提示词模板")
|
||||
evaluation_criteria: Optional[Dict[str, Any]] = Field(None, description="评估标准")
|
||||
is_public: bool = Field(True, description="是否公开")
|
||||
required_level: Optional[int] = Field(None, description="所需用户等级")
|
||||
|
||||
|
||||
class TrainingSceneCreate(TrainingSceneBase):
|
||||
"""创建陪练场景模式"""
|
||||
|
||||
status: TrainingSceneStatus = Field(
|
||||
default=TrainingSceneStatus.DRAFT, description="场景状态"
|
||||
)
|
||||
|
||||
|
||||
class TrainingSceneUpdate(BaseSchema):
|
||||
"""更新陪练场景模式"""
|
||||
|
||||
name: Optional[str] = Field(None, max_length=100)
|
||||
description: Optional[str] = None
|
||||
category: Optional[str] = Field(None, max_length=50)
|
||||
ai_config: Optional[Dict[str, Any]] = None
|
||||
prompt_template: Optional[str] = None
|
||||
evaluation_criteria: Optional[Dict[str, Any]] = None
|
||||
status: Optional[TrainingSceneStatus] = None
|
||||
is_public: Optional[bool] = None
|
||||
required_level: Optional[int] = None
|
||||
|
||||
|
||||
class TrainingSceneInDB(TrainingSceneBase, IDMixin, TimestampMixin):
|
||||
"""数据库中的陪练场景模式"""
|
||||
|
||||
status: TrainingSceneStatus
|
||||
is_deleted: bool = False
|
||||
created_by: Optional[int] = None
|
||||
updated_by: Optional[int] = None
|
||||
|
||||
|
||||
class TrainingSceneResponse(TrainingSceneInDB):
|
||||
"""陪练场景响应模式"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
# ========== 陪练会话相关 ==========
|
||||
|
||||
|
||||
class TrainingSessionBase(BaseSchema):
|
||||
"""陪练会话基础模式"""
|
||||
|
||||
scene_id: int = Field(..., description="场景ID")
|
||||
session_config: Optional[Dict[str, Any]] = Field(None, description="会话配置")
|
||||
|
||||
|
||||
class TrainingSessionCreate(TrainingSessionBase):
|
||||
"""创建陪练会话模式"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class TrainingSessionUpdate(BaseSchema):
|
||||
"""更新陪练会话模式"""
|
||||
|
||||
status: Optional[TrainingSessionStatus] = None
|
||||
end_time: Optional[datetime] = None
|
||||
duration_seconds: Optional[int] = None
|
||||
total_score: Optional[float] = None
|
||||
evaluation_result: Optional[Dict[str, Any]] = None
|
||||
|
||||
|
||||
class TrainingSessionInDB(TrainingSessionBase, IDMixin, TimestampMixin):
|
||||
"""数据库中的陪练会话模式"""
|
||||
|
||||
user_id: int
|
||||
coze_conversation_id: Optional[str] = None
|
||||
start_time: datetime
|
||||
end_time: Optional[datetime] = None
|
||||
duration_seconds: Optional[int] = None
|
||||
status: TrainingSessionStatus
|
||||
total_score: Optional[float] = None
|
||||
evaluation_result: Optional[Dict[str, Any]] = None
|
||||
created_by: Optional[int] = None
|
||||
updated_by: Optional[int] = None
|
||||
|
||||
|
||||
class TrainingSessionResponse(TrainingSessionInDB):
|
||||
"""陪练会话响应模式"""
|
||||
|
||||
scene: Optional["TrainingSceneResponse"] = None
|
||||
message_count: Optional[int] = Field(None, description="消息数量")
|
||||
|
||||
|
||||
# ========== 消息相关 ==========
|
||||
|
||||
|
||||
class TrainingMessageBase(BaseSchema):
|
||||
"""陪练消息基础模式"""
|
||||
|
||||
role: MessageRole = Field(..., description="消息角色")
|
||||
type: MessageType = Field(..., description="消息类型")
|
||||
content: str = Field(..., description="消息内容")
|
||||
voice_url: Optional[str] = Field(None, max_length=500, description="语音文件URL")
|
||||
voice_duration: Optional[float] = Field(None, description="语音时长(秒)")
|
||||
metadata: Optional[Dict[str, Any]] = Field(None, description="消息元数据")
|
||||
|
||||
|
||||
class TrainingMessageCreate(TrainingMessageBase):
|
||||
"""创建陪练消息模式"""
|
||||
|
||||
session_id: int = Field(..., description="会话ID")
|
||||
coze_message_id: Optional[str] = Field(None, max_length=100, description="Coze消息ID")
|
||||
|
||||
|
||||
class TrainingMessageInDB(TrainingMessageBase, IDMixin, TimestampMixin):
|
||||
"""数据库中的陪练消息模式"""
|
||||
|
||||
session_id: int
|
||||
coze_message_id: Optional[str] = None
|
||||
|
||||
|
||||
class TrainingMessageResponse(TrainingMessageInDB):
|
||||
"""陪练消息响应模式"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
# ========== 报告相关 ==========
|
||||
|
||||
|
||||
class TrainingReportBase(BaseSchema):
|
||||
"""陪练报告基础模式"""
|
||||
|
||||
overall_score: float = Field(..., ge=0, le=100, description="总体得分")
|
||||
dimension_scores: Dict[str, float] = Field(..., description="各维度得分")
|
||||
strengths: List[str] = Field(..., description="优势点")
|
||||
weaknesses: List[str] = Field(..., description="待改进点")
|
||||
suggestions: List[str] = Field(..., description="改进建议")
|
||||
detailed_analysis: Optional[str] = Field(None, description="详细分析")
|
||||
transcript: Optional[str] = Field(None, description="对话文本记录")
|
||||
statistics: Optional[Dict[str, Any]] = Field(None, description="统计数据")
|
||||
|
||||
|
||||
class TrainingReportCreate(TrainingReportBase):
|
||||
"""创建陪练报告模式"""
|
||||
|
||||
session_id: int = Field(..., description="会话ID")
|
||||
user_id: int = Field(..., description="用户ID")
|
||||
|
||||
|
||||
class TrainingReportInDB(TrainingReportBase, IDMixin, TimestampMixin):
|
||||
"""数据库中的陪练报告模式"""
|
||||
|
||||
session_id: int
|
||||
user_id: int
|
||||
created_by: Optional[int] = None
|
||||
updated_by: Optional[int] = None
|
||||
|
||||
|
||||
class TrainingReportResponse(TrainingReportInDB):
|
||||
"""陪练报告响应模式"""
|
||||
|
||||
session: Optional[TrainingSessionResponse] = None
|
||||
|
||||
|
||||
# ========== 会话操作相关 ==========
|
||||
|
||||
|
||||
class StartTrainingRequest(BaseSchema):
|
||||
"""开始陪练请求"""
|
||||
|
||||
scene_id: int = Field(..., description="场景ID")
|
||||
config: Optional[Dict[str, Any]] = Field(None, description="会话配置")
|
||||
|
||||
|
||||
class StartTrainingResponse(BaseSchema):
|
||||
"""开始陪练响应"""
|
||||
|
||||
session_id: int = Field(..., description="会话ID")
|
||||
coze_conversation_id: Optional[str] = Field(None, description="Coze会话ID")
|
||||
scene: TrainingSceneResponse = Field(..., description="场景信息")
|
||||
websocket_url: Optional[str] = Field(None, description="WebSocket连接URL")
|
||||
|
||||
|
||||
class EndTrainingRequest(BaseSchema):
|
||||
"""结束陪练请求"""
|
||||
|
||||
generate_report: bool = Field(True, description="是否生成报告")
|
||||
|
||||
|
||||
class EndTrainingResponse(BaseSchema):
|
||||
"""结束陪练响应"""
|
||||
|
||||
session: TrainingSessionResponse = Field(..., description="会话信息")
|
||||
report: Optional[TrainingReportResponse] = Field(None, description="陪练报告")
|
||||
|
||||
|
||||
# ========== 列表查询相关 ==========
|
||||
|
||||
|
||||
class TrainingSceneListQuery(BaseSchema):
|
||||
"""陪练场景列表查询参数"""
|
||||
|
||||
category: Optional[str] = Field(None, description="场景分类")
|
||||
status: Optional[TrainingSceneStatus] = Field(None, description="场景状态")
|
||||
is_public: Optional[bool] = Field(None, description="是否公开")
|
||||
search: Optional[str] = Field(None, description="搜索关键词")
|
||||
page: int = Field(1, ge=1, description="页码")
|
||||
page_size: int = Field(20, ge=1, le=100, description="每页数量")
|
||||
|
||||
|
||||
class TrainingSessionListQuery(BaseSchema):
|
||||
"""陪练会话列表查询参数"""
|
||||
|
||||
scene_id: Optional[int] = Field(None, description="场景ID")
|
||||
status: Optional[TrainingSessionStatus] = Field(None, description="会话状态")
|
||||
start_date: Optional[datetime] = Field(None, description="开始日期")
|
||||
end_date: Optional[datetime] = Field(None, description="结束日期")
|
||||
page: int = Field(1, ge=1, description="页码")
|
||||
page_size: int = Field(20, ge=1, le=100, description="每页数量")
|
||||
|
||||
|
||||
class PaginatedResponse(BaseModel, Generic[DataT]):
|
||||
"""分页响应模式"""
|
||||
|
||||
items: List[DataT] = Field(..., description="数据列表")
|
||||
total: int = Field(..., description="总数量")
|
||||
page: int = Field(..., description="当前页码")
|
||||
page_size: int = Field(..., description="每页数量")
|
||||
pages: int = Field(..., description="总页数")
|
||||
|
||||
|
||||
# 更新前向引用
|
||||
TrainingSessionResponse.model_rebuild()
|
||||
TrainingReportResponse.model_rebuild()
|
||||
Reference in New Issue
Block a user