- 从服务器拉取完整代码 - 按框架规范整理项目结构 - 配置 Drone CI 测试环境部署 - 包含后端(FastAPI)、前端(Vue3)、管理端 技术栈: Vue3 + TypeScript + FastAPI + MySQL
110 lines
5.4 KiB
Python
110 lines
5.4 KiB
Python
"""
|
||
陪练场景模型
|
||
"""
|
||
from sqlalchemy import Column, Integer, String, Text, JSON, DECIMAL, Boolean, DateTime, ForeignKey
|
||
from sqlalchemy.sql import func
|
||
from app.models.base import Base
|
||
|
||
|
||
class PracticeScene(Base):
|
||
"""陪练场景模型"""
|
||
__tablename__ = "practice_scenes"
|
||
|
||
id = Column(Integer, primary_key=True, index=True, comment="场景ID")
|
||
name = Column(String(200), nullable=False, comment="场景名称")
|
||
description = Column(Text, comment="场景描述")
|
||
type = Column(String(50), nullable=False, index=True, comment="场景类型: phone/face/complaint/after-sales/product-intro")
|
||
difficulty = Column(String(50), nullable=False, index=True, comment="难度等级: beginner/junior/intermediate/senior/expert")
|
||
status = Column(String(20), default="active", index=True, comment="状态: active/inactive")
|
||
background = Column(Text, comment="场景背景设定")
|
||
ai_role = Column(Text, comment="AI角色描述")
|
||
objectives = Column(JSON, comment="练习目标数组")
|
||
keywords = Column(JSON, comment="关键词数组")
|
||
duration = Column(Integer, default=10, comment="预计时长(分钟)")
|
||
usage_count = Column(Integer, default=0, comment="使用次数")
|
||
rating = Column(DECIMAL(3, 1), default=0.0, comment="评分")
|
||
|
||
# 审计字段
|
||
created_by = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"), comment="创建人ID")
|
||
updated_by = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"), comment="更新人ID")
|
||
created_at = Column(DateTime, server_default=func.now(), comment="创建时间")
|
||
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now(), comment="更新时间")
|
||
|
||
# 软删除字段
|
||
is_deleted = Column(Boolean, default=False, index=True, comment="是否删除")
|
||
deleted_at = Column(DateTime, comment="删除时间")
|
||
|
||
def __repr__(self):
|
||
return f"<PracticeScene(id={self.id}, name='{self.name}', type='{self.type}', difficulty='{self.difficulty}')>"
|
||
|
||
|
||
class PracticeSession(Base):
|
||
"""陪练会话模型"""
|
||
__tablename__ = "practice_sessions"
|
||
|
||
id = Column(Integer, primary_key=True, index=True, comment="会话ID")
|
||
session_id = Column(String(50), unique=True, nullable=False, index=True, comment="会话唯一标识")
|
||
user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True, comment="学员ID")
|
||
scene_id = Column(Integer, ForeignKey("practice_scenes.id", ondelete="SET NULL"), comment="场景ID")
|
||
scene_name = Column(String(200), comment="场景名称")
|
||
scene_type = Column(String(50), comment="场景类型")
|
||
conversation_id = Column(String(100), comment="Coze对话ID")
|
||
|
||
# 会话时间信息
|
||
start_time = Column(DateTime, nullable=False, index=True, comment="开始时间")
|
||
end_time = Column(DateTime, comment="结束时间")
|
||
duration_seconds = Column(Integer, default=0, comment="时长(秒)")
|
||
turns = Column(Integer, default=0, comment="对话轮次")
|
||
status = Column(String(20), default="in_progress", index=True, comment="状态: in_progress/completed/canceled")
|
||
|
||
# 审计字段
|
||
created_at = Column(DateTime, server_default=func.now(), comment="创建时间")
|
||
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now(), comment="更新时间")
|
||
is_deleted = Column(Boolean, default=False, comment="是否删除")
|
||
|
||
def __repr__(self):
|
||
return f"<PracticeSession(session_id='{self.session_id}', scene='{self.scene_name}', status='{self.status}')>"
|
||
|
||
|
||
class PracticeDialogue(Base):
|
||
"""陪练对话记录模型"""
|
||
__tablename__ = "practice_dialogues"
|
||
|
||
id = Column(Integer, primary_key=True, index=True, comment="对话ID")
|
||
session_id = Column(String(50), nullable=False, index=True, comment="会话ID")
|
||
speaker = Column(String(20), nullable=False, comment="说话人: user/ai")
|
||
content = Column(Text, nullable=False, comment="对话内容")
|
||
timestamp = Column(DateTime, nullable=False, comment="时间戳")
|
||
sequence = Column(Integer, nullable=False, comment="顺序号")
|
||
|
||
created_at = Column(DateTime, server_default=func.now(), comment="创建时间")
|
||
|
||
def __repr__(self):
|
||
return f"<PracticeDialogue(session_id='{self.session_id}', speaker='{self.speaker}', seq={self.sequence})>"
|
||
|
||
|
||
class PracticeReport(Base):
|
||
"""陪练分析报告模型"""
|
||
__tablename__ = "practice_reports"
|
||
|
||
id = Column(Integer, primary_key=True, index=True, comment="报告ID")
|
||
session_id = Column(String(50), unique=True, nullable=False, index=True, comment="会话ID")
|
||
|
||
# AI分析结果
|
||
total_score = Column(Integer, comment="综合得分(0-100)")
|
||
score_breakdown = Column(JSON, comment="分数细分")
|
||
ability_dimensions = Column(JSON, comment="能力维度")
|
||
dialogue_review = Column(JSON, comment="对话复盘")
|
||
suggestions = Column(JSON, comment="改进建议")
|
||
|
||
# AI分析元数据
|
||
workflow_run_id = Column(String(100), comment="AI分析运行ID")
|
||
task_id = Column(String(100), comment="AI分析任务ID")
|
||
|
||
created_at = Column(DateTime, server_default=func.now(), comment="创建时间")
|
||
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now(), comment="更新时间")
|
||
|
||
def __repr__(self):
|
||
return f"<PracticeReport(session_id='{self.session_id}', total_score={self.total_score})>"
|
||
|