- 从服务器拉取完整代码 - 按框架规范整理项目结构 - 配置 Drone CI 测试环境部署 - 包含后端(FastAPI)、前端(Vue3)、管理端 技术栈: Vue3 + TypeScript + FastAPI + MySQL
261 lines
8.3 KiB
Python
261 lines
8.3 KiB
Python
"""陪练模块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()
|