|
|
@@ -61,50 +61,72 @@ def get_card_details(
|
|
|
):
|
|
|
"""
|
|
|
获取卡牌元数据以及所有与之关联的图片信息,并将坐标转换为 xy 格式。
|
|
|
+ 同时返回上一张和下一张卡牌的ID。
|
|
|
|
|
|
- **current**: 查询 card_id 对应的卡牌。
|
|
|
- **next**: 查询 ID 比 card_id 大的第一张卡牌。
|
|
|
- **prev**: 查询 ID 比 card_id 小的第一张卡牌。
|
|
|
"""
|
|
|
target_id = card_id
|
|
|
+ cursor = None
|
|
|
|
|
|
- # 1. 如果是查询上一个或下一个,先计算目标ID
|
|
|
- if mode != QueryMode.current:
|
|
|
- try:
|
|
|
- with db_conn.cursor(dictionary=True) as cursor:
|
|
|
- if mode == QueryMode.next:
|
|
|
- query = (f"SELECT id FROM {settings.DB_CARD_TABLE_NAME} "
|
|
|
- f"WHERE id > %s ORDER BY id ASC LIMIT 1")
|
|
|
- else: # mode == QueryMode.prev
|
|
|
- query = (f"SELECT id FROM {settings.DB_CARD_TABLE_NAME} "
|
|
|
- f"WHERE id < %s ORDER BY id DESC LIMIT 1")
|
|
|
-
|
|
|
- cursor.execute(query, (card_id,))
|
|
|
- row = cursor.fetchone()
|
|
|
-
|
|
|
- if not row:
|
|
|
- # 按照项目习惯,找不到上/下一个时返回 200 + 提示信息,或根据需求改为 404
|
|
|
- msg = "没有下一张" if mode == QueryMode.next else "没有上一张"
|
|
|
- raise HTTPException(status_code=200, detail=msg)
|
|
|
-
|
|
|
- target_id = row['id']
|
|
|
- except HTTPException:
|
|
|
- raise
|
|
|
- except Exception as e:
|
|
|
- logger.error(f"查询卡牌ID失败 (Mode: {mode}, BaseID: {card_id}): {e}")
|
|
|
- raise HTTPException(status_code=500, detail="数据库查询失败")
|
|
|
+ try:
|
|
|
+ cursor = db_conn.cursor(dictionary=True)
|
|
|
+
|
|
|
+ # 1. 如果是查询上一个或下一个,先计算目标ID
|
|
|
+ if mode != QueryMode.current:
|
|
|
+ if mode == QueryMode.next:
|
|
|
+ query_target = (f"SELECT id FROM {settings.DB_CARD_TABLE_NAME} "
|
|
|
+ f"WHERE id > %s ORDER BY id ASC LIMIT 1")
|
|
|
+ else: # mode == QueryMode.prev
|
|
|
+ query_target = (f"SELECT id FROM {settings.DB_CARD_TABLE_NAME} "
|
|
|
+ f"WHERE id < %s ORDER BY id DESC LIMIT 1")
|
|
|
+
|
|
|
+ cursor.execute(query_target, (card_id,))
|
|
|
+ row = cursor.fetchone()
|
|
|
+
|
|
|
+ if not row:
|
|
|
+ msg = "没有下一张" if mode == QueryMode.next else "没有上一张"
|
|
|
+ raise HTTPException(status_code=200, detail=msg)
|
|
|
+
|
|
|
+ target_id = row['id']
|
|
|
|
|
|
- # 2. 获取目标卡牌的详细数据 (Dict 格式)
|
|
|
- card_data = crud_card.get_card_with_details(db_conn, target_id)
|
|
|
+ # 2. 获取目标卡牌的详细数据 (Dict 格式)
|
|
|
+ card_data = crud_card.get_card_with_details(db_conn, target_id)
|
|
|
|
|
|
- if not card_data:
|
|
|
- raise HTTPException(status_code=404, detail=f"ID为 {target_id} 的卡牌未找到。")
|
|
|
+ if not card_data:
|
|
|
+ raise HTTPException(status_code=404, detail=f"ID为 {target_id} 的卡牌未找到。")
|
|
|
|
|
|
- # 3. 遍历图片,转换格式 (使用抽取出的辅助函数)
|
|
|
- _process_images_to_xy_format(card_data)
|
|
|
+ # 3. 补充当前目标卡牌的 id_prev 和 id_next
|
|
|
+ # 注意:这里需要重新获取 cursor,或者使用 cursor (非 dict 模式可能更方便取值,但 dict 模式也行)
|
|
|
+ # 这里为了简单直接用 raw SQL
|
|
|
|
|
|
- # 4. 验证并返回
|
|
|
- return CardDetailResponse.model_validate(card_data)
|
|
|
+ # 查询上一个ID
|
|
|
+ sql_prev = f"SELECT id FROM {settings.DB_CARD_TABLE_NAME} WHERE id < %s ORDER BY id DESC LIMIT 1"
|
|
|
+ cursor.execute(sql_prev, (target_id,))
|
|
|
+ row_prev = cursor.fetchone()
|
|
|
+ card_data['id_prev'] = row_prev['id'] if row_prev else None
|
|
|
+
|
|
|
+ # 查询下一个ID
|
|
|
+ sql_next = f"SELECT id FROM {settings.DB_CARD_TABLE_NAME} WHERE id > %s ORDER BY id ASC LIMIT 1"
|
|
|
+ cursor.execute(sql_next, (target_id,))
|
|
|
+ row_next = cursor.fetchone()
|
|
|
+ card_data['id_next'] = row_next['id'] if row_next else None
|
|
|
+
|
|
|
+ # 4. 遍历图片,转换格式 (使用抽取出的辅助函数)
|
|
|
+ _process_images_to_xy_format(card_data)
|
|
|
+
|
|
|
+ # 5. 验证并返回
|
|
|
+ return CardDetailResponse.model_validate(card_data)
|
|
|
+
|
|
|
+ except HTTPException:
|
|
|
+ raise
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"查询卡牌详情失败 (Mode: {mode}, BaseID: {card_id}): {e}")
|
|
|
+ raise HTTPException(status_code=500, detail="数据库查询失败")
|
|
|
+ finally:
|
|
|
+ if cursor:
|
|
|
+ cursor.close()
|
|
|
|
|
|
|
|
|
@router.put("/update/json/{id}", status_code=200, summary="接收xy格式, 还原后重计算分数并保存")
|