""" SQLModel 表模型:关系库实体定义,与业务模块一一对应。 """ from __future__ import annotations from datetime import datetime from enum import Enum from typing import Optional from uuid import UUID, uuid4 from sqlalchemy import Column, Text from sqlmodel import Field, SQLModel #角色枚举:教师/学生 class UserRole(str, Enum): teacher = "teacher" student = "student" #用户表 class User(SQLModel, table=True): id: UUID = Field(default_factory=uuid4, primary_key=True) username: str = Field(index=True, unique=True) password_hash: str role: UserRole = Field(index=True) created_at: datetime = Field(default_factory=datetime.utcnow) #知识点表 class KnowledgePoint(SQLModel, table=True): id: UUID = Field(default_factory=uuid4, primary_key=True) subject: str = Field(default="math", index=True) #学科 grade: str = Field(default="junior", index=True) #年级 name: str = Field(index=True) #知识点名称 code: str = Field(index=True, unique=True) #知识点编码(唯一) #习题表 class Exercise(SQLModel, table=True): id: UUID = Field(default_factory=uuid4, primary_key=True) title: str body: str # 题目元数据(教师维护) question_type: Optional[str] = Field(default=None, index=True) # "选择" | "填空" | "计算" | "判断" correct_answer: Optional[str] = Field(default=None, sa_column=Column(Text, nullable=True)) resolution: Optional[str] = Field(default=None, sa_column=Column(Text, nullable=True)) # 题目解析 # 由主knowledge_code从Neo4j回填,便于筛选与学情统计 knowledge_grade: Optional[str] = Field(default=None, index=True) knowledge_category: Optional[str] = Field(default=None, index=True) knowledge_point_name: Optional[str] = Field(default=None, index=True) knowledge_code: Optional[str] = Field(default=None, index=True) difficulty: Optional[int] = Field(default=None, index=True) # 1-5 # 个性化权重:答错+1,答对-1(不低于 0),供推荐排序 weight: int = Field(default=0, index=True) #做题记录表 class ExerciseAttempt(SQLModel, table=True): id: UUID = Field(default_factory=uuid4, primary_key=True) user_id: UUID = Field(index=True) exercise_id: UUID = Field(index=True) answer: str is_correct: Optional[bool] = Field(default=None, index=True) score: Optional[float] = Field(default=None) created_at: datetime = Field(default_factory=datetime.utcnow, index=True) #数字人会话记录表 class ChatSession(SQLModel, table=True): id: UUID = Field(default_factory=uuid4, primary_key=True) user_id: UUID = Field(index=True) topic: Optional[str] = Field(default=None, index=True) created_at: datetime = Field(default_factory=datetime.utcnow, index=True) class ChatMessage(SQLModel, table=True): """会话消息表。""" id: UUID = Field(default_factory=uuid4, primary_key=True) session_id: UUID = Field(index=True) sender: str = Field(index=True) content: str = Field(sa_column=Column(Text, nullable=False)) created_at: datetime = Field(default_factory=datetime.utcnow, index=True) #推荐记录表 class RecommendationItem(SQLModel, table=True): id: UUID = Field(default_factory=uuid4, primary_key=True) user_id: UUID = Field(index=True) item_type: str = Field(index=True) item_ref: str = Field(index=True) reason: Optional[str] = None created_at: datetime = Field(default_factory=datetime.utcnow, index=True) #错题本 class WrongBookItem(SQLModel, table=True): id: UUID = Field(default_factory=uuid4, primary_key=True) user_id: UUID = Field(index=True) exercise_id: UUID = Field(index=True) knowledge_code: str = Field(index=True) wrong_answer: str correct_answer: Optional[str] = None created_at: datetime = Field(default_factory=datetime.utcnow, index=True) #模块登记表 class ModuleService(SQLModel, table=True): id: UUID = Field(default_factory=uuid4, primary_key=True) name: str = Field(index=True, unique=True) base_url: str is_enabled: bool = Field(default=True, index=True) updated_at: datetime = Field(default_factory=datetime.utcnow, index=True)