schemas.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. """
  2. 定义前后端之间传输的数据格式
  3. """
  4. from __future__ import annotations
  5. from datetime import datetime
  6. from typing import Optional
  7. from uuid import UUID
  8. from pydantic import BaseModel
  9. from app.models import UserRole
  10. #认证模块(auth)
  11. class TokenResponse(BaseModel):
  12. access_token: str
  13. token_type: str = "bearer"
  14. class RegisterRequest(BaseModel):
  15. username: str
  16. password: str
  17. role: UserRole
  18. #用户模块(users)
  19. class UserPublic(BaseModel):
  20. id: UUID
  21. username: str
  22. role: UserRole
  23. created_at: datetime
  24. #知识图谱模块(knowledge_graph)
  25. class KnowledgeQueryResponse(BaseModel):
  26. knowledge_code: str
  27. name: Optional[str] = None
  28. grade: Optional[str] = None
  29. category: Optional[str] = None
  30. definition: Optional[str] = None
  31. related: list[str] = []
  32. # 递进:(前置)-[:PREREQUISITE]->(后置)
  33. prerequisites: list[str] = [] # 必须先掌握的前置(指向当前知识点)
  34. next_steps: list[str] = [] # 以当前知识点为前置的后续知识点
  35. class PrerequisiteLinkRequest(BaseModel): # 创建/删除递进关系
  36. prerequisite_code: str
  37. dependent_code: str
  38. class KnowledgePointInGraph(BaseModel): # 图中知识点列表项
  39. code: str
  40. name: Optional[str] = None
  41. grade: Optional[str] = None
  42. class GraphBackfillResponse(BaseModel):
  43. total: int
  44. updated: int
  45. skipped: int
  46. class GraphSeedResponse(BaseModel):
  47. upserted: int
  48. #习题/测评模块(assessment)
  49. class ExerciseImportSummary(BaseModel):
  50. total: int
  51. created: int
  52. skipped: int
  53. errors: list[str] = []
  54. class ExerciseImportPreviewItem(BaseModel):
  55. title: str
  56. body: str
  57. knowledge_code: Optional[str] = None
  58. difficulty: Optional[int] = None
  59. question_type: Optional[str] = None
  60. correct_answer: Optional[str] = None
  61. resolution: Optional[str] = None
  62. class ExerciseImportPreviewResponse(BaseModel):
  63. total: int
  64. valid: int
  65. invalid: int
  66. sample: list[ExerciseImportPreviewItem]
  67. errors: list[str] = []
  68. class ExerciseCreateRequest(BaseModel): #创建/查询题目
  69. title: str
  70. body: str
  71. knowledge_code: Optional[str] = None
  72. difficulty: Optional[int] = None
  73. question_type: Optional[str] = None
  74. correct_answer: Optional[str] = None
  75. resolution: Optional[str] = None
  76. weight: int = 0
  77. class ExerciseBatchRequest(BaseModel):
  78. ids: list[UUID]
  79. class ExercisePublic(BaseModel): #前端创建题目时传的数据
  80. id: UUID
  81. title: str
  82. body: str
  83. knowledge_code: Optional[str] = None
  84. difficulty: Optional[int] = None
  85. question_type: Optional[str] = None
  86. correct_answer: Optional[str] = None
  87. resolution: Optional[str] = None
  88. knowledge_grade: Optional[str] = None
  89. knowledge_category: Optional[str] = None
  90. knowledge_point_name: Optional[str] = None
  91. weight: Optional[int] = None
  92. class AttemptSubmitRequest(BaseModel): #返回给前端的完整题目信息
  93. answer: str
  94. class AttemptPublic(BaseModel):
  95. id: UUID
  96. user_id: UUID
  97. exercise_id: UUID
  98. answer: str
  99. is_correct: Optional[bool] = None
  100. score: Optional[float] = None
  101. created_at: datetime
  102. #AI数字人模块(digital_human)
  103. class AskRequest(BaseModel):
  104. session_id: Optional[UUID] = None
  105. question: str
  106. knowledge_code: Optional[str] = None
  107. model_name: Optional[str] = None
  108. model_provider: Optional[str] = None
  109. model_id: Optional[str] = None
  110. class AskResponse(BaseModel):
  111. session_id: UUID
  112. answer: str
  113. sources: list[str] = []
  114. tts_status: Optional[str] = None
  115. audio_base64: Optional[str] = None
  116. audio_mime: Optional[str] = None
  117. class VoiceAssetItem(BaseModel):
  118. name: str
  119. size: int
  120. url: str
  121. #推荐系统模块(recommendation)
  122. class RecommendRequest(BaseModel):
  123. knowledge_code: Optional[str] = None
  124. limit: int = 10
  125. # topic_weight=开始组卷(按勾选知识点 + 权重);personalized=个性推荐(错题优先,忽略知识点)
  126. mode: Optional[str] = None
  127. # 组卷题量补足时限定范围,避免从全库随机混入其他类别(如代数组卷出现几何题)
  128. knowledge_grade: Optional[str] = None
  129. knowledge_category: Optional[str] = None
  130. class RecommendItem(BaseModel):
  131. item_type: str
  132. item_ref: str
  133. reason: Optional[str] = None
  134. class RecommendResponse(BaseModel):
  135. items: list[RecommendItem]
  136. #学习分析模块(learning_analytics)
  137. class LearningStatsResponse(BaseModel):
  138. user_id: UUID
  139. attempts_total: int
  140. correct_total: int
  141. accuracy: float
  142. class LearningBreakdownResponse(BaseModel):
  143. by_grade: list[GradeBreakdownItem]
  144. by_category: list[CategoryBreakdownItem]
  145. by_topic: list[TopicBreakdownItem]
  146. class GradeBreakdownItem(BaseModel): #按年级统计做题情况
  147. grade: str
  148. attempts: int
  149. correct: int
  150. wrong: int
  151. accuracy: float
  152. class CategoryBreakdownItem(BaseModel): #按知识分类统计
  153. grade: str
  154. category: str
  155. attempts: int
  156. correct: int
  157. wrong: int
  158. accuracy: float
  159. class TopicBreakdownItem(BaseModel): #按知识点统计
  160. knowledge_code: str
  161. knowledge_point_name: Optional[str] = None
  162. knowledge_grade: Optional[str] = None
  163. knowledge_category: Optional[str] = None
  164. attempts: int
  165. correct: int
  166. wrong: int
  167. accuracy: float
  168. class StudentLearningStatsItem(BaseModel):
  169. user_id: UUID
  170. username: str
  171. attempts_total: int
  172. correct_total: int
  173. accuracy: float
  174. #错题本模块(assessment)
  175. class WrongBookItemPublic(BaseModel):
  176. id: UUID
  177. user_id: UUID
  178. exercise_id: UUID
  179. knowledge_code: str
  180. wrong_answer: str
  181. correct_answer: Optional[str] = None
  182. created_at: datetime
  183. # 关联习题展示(与习题测评一致)
  184. title: Optional[str] = None
  185. body: Optional[str] = None
  186. question_type: Optional[str] = None
  187. resolution: Optional[str] = None
  188. knowledge_grade: Optional[str] = None
  189. knowledge_category: Optional[str] = None
  190. knowledge_point_name: Optional[str] = None
  191. class WrongBookSummaryItem(BaseModel):
  192. knowledge_code: str
  193. wrong_count: int
  194. #模块管理模块(modules)
  195. class ModuleRegisterRequest(BaseModel):
  196. name: str
  197. base_url: str
  198. is_enabled: bool = True
  199. class ModulePublic(BaseModel):
  200. id: UUID
  201. name: str
  202. base_url: str
  203. is_enabled: bool
  204. updated_at: datetime