from fastapi import APIRouter, HTTPException, Query from typing import Dict, Any, List, Optional from datetime import datetime from core.load import all_data, flag1_data, flag2_data from core.history import history_manager from core.db import db from models.question import Question router = APIRouter() @router.get("/questions") async def get_question(t: str) -> Dict[str, Any]: """ 根据题型生成问题 参数: t: 题目类型,可选值为 A, B, C, D, E A - 推理未知数 B - 一题多解1(两个解答) C - 一题多解2(三个或以上解答) D - 一星题目 E - 二星题目 返回: 包含问题内容、数字和答案的字典 """ try: # 创建问题实例并生成题目 question = Question(t) result = question.generate() # 记录历史(只有生成题目时记录) record_id = history_manager.record_question(result) result["record_id"]=record_id return result except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) except Exception as e: raise HTTPException(status_code=500, detail=f"生成题目时发生错误: {str(e)}") @router.get("/solutions") async def get_solutions(num1: int, num2: int, num3: int, num4: int): """ 根据4个数字查询所有可能的解法 参数: num1: 第一个数字 (1-13) num2: 第二个数字 (1-13) num3: 第三个数字 (1-13) num4: 第四个数字 (1-13) 返回: 包含所有解法的列表 """ # 验证输入 for num, name in [(num1, "num1"), (num2, "num2"), (num3, "num3"), (num4, "num4")]: if not 1 <= num <= 13: raise HTTPException(status_code=400, detail=f"{name}必须在1到13之间") # 查找匹配的游戏数据 matching_games = [ game for game in all_data if sorted([game.num1, game.num2, game.num3, game.num4]) == sorted([num1, num2, num3, num4]) ] if not matching_games: result = {"solutions": [], "message": "没有找到匹配的解法"} # 不再记录解法查询历史 # history_manager.record_solutions([num1, num2, num3, num4], result) return result # 提取所有解法 solutions = [] for game in matching_games: for solution in game.solutions: solutions.append({ "expression": solution.expression, "flag": solution.flag }) result = { "solutions": solutions, "count": len(solutions), "flag1_count": sum(1 for s in solutions if s["flag"] == 1), "flag2_count": sum(1 for s in solutions if s["flag"] == 2) } # 不再记录解法查询历史 # history_manager.record_solutions([num1, num2, num3, num4], result) return result @router.get("/flag") async def get_flag(flag: int, min_num: Optional[str] = None, max_num: Optional[str] = None): """ 获取指定flag的游戏数据 参数: flag: 解法标志,1表示一星,2表示二星 min_num: 最小数字过滤 max_num: 最大数字过滤 返回: 匹配的游戏数据列表 """ flag_data = flag1_data if flag == 1 else flag2_data data = [] if min_num and min_num != "0" or max_num and max_num != "0": for item in flag_data: if min_num and item.no.startswith(min_num + "_") or max_num and item.no.startswith("_" + max_num): data.append(item) continue else: data = flag_data # 不再记录flag查询历史 # history_manager.record_flag_query(flag, min_num, max_num, data) return data @router.get("/history") async def get_history( game_type: Optional[str] = Query(None, description="游戏类型,可选值为A, B, C, D, E"), start_date: Optional[str] = Query(None, description="开始日期,格式为YYYY-MM-DD"), end_date: Optional[str] = Query(None, description="结束日期,格式为YYYY-MM-DD"), page: int = Query(1, description="页码,从1开始"), page_size: int = Query(10, description="每页记录数"), only_favorite: bool = Query(False, description="是否只查询收藏的记录"), include_deleted: bool = Query(False, description="是否包含已删除的记录") ): """ 获取历史记录 参数: game_type: 游戏类型,可选值为A, B, C, D, E start_date: 开始日期,格式为YYYY-MM-DD end_date: 结束日期,格式为YYYY-MM-DD page: 页码,从1开始 page_size: 每页记录数 only_favorite: 是否只查询收藏的记录 include_deleted: 是否包含已删除的记录 返回: 历史记录列表 """ try: # 使用分页直接从数据库获取当前页的历史记录 current_page_items, total_count = history_manager.get_history( game_type, start_date, end_date, page, page_size, only_favorite, include_deleted ) return { "history": current_page_items, "count": total_count, "page": page, "page_size": page_size, "total_pages": (total_count + page_size - 1) // page_size } except Exception as e: raise HTTPException(status_code=500, detail=f"获取历史记录失败: {str(e)}") @router.post("/history/{history_id}/favorite") async def toggle_favorite(history_id: int): """ 切换历史记录的收藏状态 参数: history_id: 历史记录ID 返回: 操作结果 """ try: success = history_manager.toggle_favorite(history_id) if success: return {"success": True, "message": "收藏状态已更新"} else: raise HTTPException(status_code=404, detail="历史记录不存在或操作失败") except Exception as e: raise HTTPException(status_code=500, detail=f"更新收藏状态失败: {str(e)}") @router.post("/history/{history_id}/delete") async def toggle_delete(history_id: int): """ 切换历史记录的收藏状态 参数: history_id: 历史记录ID 返回: 操作结果 """ try: success = history_manager.toggle_delete(history_id) if success: return {"success": True, "message": "删除状态已更新"} else: raise HTTPException(status_code=404, detail="历史记录不存在或操作失败") except Exception as e: raise HTTPException(status_code=500, detail=f"更新删除状态失败: {str(e)}") @router.delete("/history/{history_id}") async def delete_history(history_id: int): """ 软删除历史记录 参数: history_id: 历史记录ID 返回: 操作结果 """ try: success = history_manager.soft_delete(history_id) if success: return {"success": True, "message": "历史记录已删除"} else: raise HTTPException(status_code=404, detail="历史记录不存在或操作失败") except Exception as e: raise HTTPException(status_code=500, detail=f"删除历史记录失败: {str(e)}")