api.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. from fastapi import APIRouter, HTTPException, Query
  2. from typing import Dict, Any, List, Optional
  3. from datetime import datetime
  4. from core.load import all_data, flag1_data, flag2_data
  5. from core.history import history_manager
  6. from core.db import db
  7. from models.question import Question
  8. router = APIRouter()
  9. @router.get("/questions")
  10. async def get_question(t: str) -> Dict[str, Any]:
  11. """
  12. 根据题型生成问题
  13. 参数:
  14. t: 题目类型,可选值为 A, B, C, D, E
  15. A - 推理未知数
  16. B - 一题多解1(两个解答)
  17. C - 一题多解2(三个或以上解答)
  18. D - 一星题目
  19. E - 二星题目
  20. 返回:
  21. 包含问题内容、数字和答案的字典
  22. """
  23. try:
  24. # 创建问题实例并生成题目
  25. question = Question(t)
  26. result = question.generate()
  27. # 记录历史(只有生成题目时记录)
  28. record_id = history_manager.record_question(result)
  29. result["record_id"]=record_id
  30. return result
  31. except ValueError as e:
  32. raise HTTPException(status_code=400, detail=str(e))
  33. except Exception as e:
  34. raise HTTPException(status_code=500, detail=f"生成题目时发生错误: {str(e)}")
  35. @router.get("/solutions")
  36. async def get_solutions(num1: int, num2: int, num3: int, num4: int):
  37. """
  38. 根据4个数字查询所有可能的解法
  39. 参数:
  40. num1: 第一个数字 (1-13)
  41. num2: 第二个数字 (1-13)
  42. num3: 第三个数字 (1-13)
  43. num4: 第四个数字 (1-13)
  44. 返回:
  45. 包含所有解法的列表
  46. """
  47. # 验证输入
  48. for num, name in [(num1, "num1"), (num2, "num2"), (num3, "num3"), (num4, "num4")]:
  49. if not 1 <= num <= 13:
  50. raise HTTPException(status_code=400, detail=f"{name}必须在1到13之间")
  51. # 查找匹配的游戏数据
  52. matching_games = [
  53. game for game in all_data
  54. if sorted([game.num1, game.num2, game.num3, game.num4]) == sorted([num1, num2, num3, num4])
  55. ]
  56. if not matching_games:
  57. result = {"solutions": [], "message": "没有找到匹配的解法"}
  58. # 不再记录解法查询历史
  59. # history_manager.record_solutions([num1, num2, num3, num4], result)
  60. return result
  61. # 提取所有解法
  62. solutions = []
  63. for game in matching_games:
  64. for solution in game.solutions:
  65. solutions.append({
  66. "expression": solution.expression,
  67. "flag": solution.flag
  68. })
  69. result = {
  70. "solutions": solutions,
  71. "count": len(solutions),
  72. "flag1_count": sum(1 for s in solutions if s["flag"] == 1),
  73. "flag2_count": sum(1 for s in solutions if s["flag"] == 2)
  74. }
  75. # 不再记录解法查询历史
  76. # history_manager.record_solutions([num1, num2, num3, num4], result)
  77. return result
  78. @router.get("/flag")
  79. async def get_flag(flag: int, min_num: Optional[str] = None, max_num: Optional[str] = None):
  80. """
  81. 获取指定flag的游戏数据
  82. 参数:
  83. flag: 解法标志,1表示一星,2表示二星
  84. min_num: 最小数字过滤
  85. max_num: 最大数字过滤
  86. 返回:
  87. 匹配的游戏数据列表
  88. """
  89. flag_data = flag1_data if flag == 1 else flag2_data
  90. data = []
  91. if min_num and min_num != "0" or max_num and max_num != "0":
  92. for item in flag_data:
  93. if min_num and item.no.startswith(min_num + "_") or max_num and item.no.startswith("_" + max_num):
  94. data.append(item)
  95. continue
  96. else:
  97. data = flag_data
  98. # 不再记录flag查询历史
  99. # history_manager.record_flag_query(flag, min_num, max_num, data)
  100. return data
  101. @router.get("/history")
  102. async def get_history(
  103. game_type: Optional[str] = Query(None, description="游戏类型,可选值为A, B, C, D, E"),
  104. start_date: Optional[str] = Query(None, description="开始日期,格式为YYYY-MM-DD"),
  105. end_date: Optional[str] = Query(None, description="结束日期,格式为YYYY-MM-DD"),
  106. page: int = Query(1, description="页码,从1开始"),
  107. page_size: int = Query(10, description="每页记录数"),
  108. only_favorite: bool = Query(False, description="是否只查询收藏的记录"),
  109. include_deleted: bool = Query(False, description="是否包含已删除的记录")
  110. ):
  111. """
  112. 获取历史记录
  113. 参数:
  114. game_type: 游戏类型,可选值为A, B, C, D, E
  115. start_date: 开始日期,格式为YYYY-MM-DD
  116. end_date: 结束日期,格式为YYYY-MM-DD
  117. page: 页码,从1开始
  118. page_size: 每页记录数
  119. only_favorite: 是否只查询收藏的记录
  120. include_deleted: 是否包含已删除的记录
  121. 返回:
  122. 历史记录列表
  123. """
  124. try:
  125. # 使用分页直接从数据库获取当前页的历史记录
  126. current_page_items, total_count = history_manager.get_history(
  127. game_type, start_date, end_date, page, page_size, only_favorite, include_deleted
  128. )
  129. return {
  130. "history": current_page_items,
  131. "count": total_count,
  132. "page": page,
  133. "page_size": page_size,
  134. "total_pages": (total_count + page_size - 1) // page_size
  135. }
  136. except Exception as e:
  137. raise HTTPException(status_code=500, detail=f"获取历史记录失败: {str(e)}")
  138. @router.post("/history/{history_id}/favorite")
  139. async def toggle_favorite(history_id: int):
  140. """
  141. 切换历史记录的收藏状态
  142. 参数:
  143. history_id: 历史记录ID
  144. 返回:
  145. 操作结果
  146. """
  147. try:
  148. success = history_manager.toggle_favorite(history_id)
  149. if success:
  150. return {"success": True, "message": "收藏状态已更新"}
  151. else:
  152. raise HTTPException(status_code=404, detail="历史记录不存在或操作失败")
  153. except Exception as e:
  154. raise HTTPException(status_code=500, detail=f"更新收藏状态失败: {str(e)}")
  155. @router.post("/history/{history_id}/delete")
  156. async def toggle_delete(history_id: int):
  157. """
  158. 切换历史记录的收藏状态
  159. 参数:
  160. history_id: 历史记录ID
  161. 返回:
  162. 操作结果
  163. """
  164. try:
  165. success = history_manager.toggle_delete(history_id)
  166. if success:
  167. return {"success": True, "message": "删除状态已更新"}
  168. else:
  169. raise HTTPException(status_code=404, detail="历史记录不存在或操作失败")
  170. except Exception as e:
  171. raise HTTPException(status_code=500, detail=f"更新删除状态失败: {str(e)}")
  172. @router.delete("/history/{history_id}")
  173. async def delete_history(history_id: int):
  174. """
  175. 软删除历史记录
  176. 参数:
  177. history_id: 历史记录ID
  178. 返回:
  179. 操作结果
  180. """
  181. try:
  182. success = history_manager.soft_delete(history_id)
  183. if success:
  184. return {"success": True, "message": "历史记录已删除"}
  185. else:
  186. raise HTTPException(status_code=404, detail="历史记录不存在或操作失败")
  187. except Exception as e:
  188. raise HTTPException(status_code=500, detail=f"删除历史记录失败: {str(e)}")