Files
012-kaopeilian/backend/app/models/practice.py
111 998211c483 feat: 初始化考培练系统项目
- 从服务器拉取完整代码
- 按框架规范整理项目结构
- 配置 Drone CI 测试环境部署
- 包含后端(FastAPI)、前端(Vue3)、管理端

技术栈: Vue3 + TypeScript + FastAPI + MySQL
2026-01-24 19:33:28 +08:00

110 lines
5.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
陪练场景模型
"""
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})>"