fix:批量修复了一些问题
This commit is contained in:
+108
-4
@@ -4,13 +4,13 @@ from __future__ import annotations
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy import or_, select
|
||||
from sqlalchemy.orm import selectinload
|
||||
|
||||
from src.api.deps import require_admin
|
||||
from src.api.schemas import MatchListOut, MatchOut
|
||||
from src.api.schemas import MatchListOut, MatchOut, PredictionOut
|
||||
from src.db.base import AsyncSession, get_db_read
|
||||
from src.db.models import League, Match
|
||||
from src.db.models import League, Match, Prediction
|
||||
|
||||
router = APIRouter(prefix="/api/v1", tags=["data"])
|
||||
|
||||
@@ -114,12 +114,26 @@ async def list_matches(
|
||||
async def get_match(match_id: int, db: AsyncSession = Depends(get_db_read)):
|
||||
stmt = (
|
||||
select(Match)
|
||||
.options(selectinload(Match.league), selectinload(Match.home_team), selectinload(Match.away_team))
|
||||
.options(
|
||||
selectinload(Match.league),
|
||||
selectinload(Match.home_team),
|
||||
selectinload(Match.away_team),
|
||||
selectinload(Match.stats),
|
||||
)
|
||||
.where(Match.id == match_id)
|
||||
)
|
||||
m = (await db.execute(stmt)).scalar_one_or_none()
|
||||
if m is None:
|
||||
raise HTTPException(404, "match not found")
|
||||
# 最近预测(倒序,最多 5 条)——复用 PredictionOut 结构,只读,不触发 LLM
|
||||
preds = (
|
||||
await db.execute(
|
||||
select(Prediction)
|
||||
.where(Prediction.match_id == match_id)
|
||||
.order_by(Prediction.created_at.desc())
|
||||
.limit(5)
|
||||
)
|
||||
).scalars().all()
|
||||
return MatchOut(
|
||||
id=m.id,
|
||||
league_code=m.league.code if m.league else None,
|
||||
@@ -135,4 +149,94 @@ async def get_match(match_id: int, db: AsyncSession = Depends(get_db_read)):
|
||||
match_stage=m.match_stage,
|
||||
home_xg=m.stats.home_xg if m.stats else None,
|
||||
away_xg=m.stats.away_xg if m.stats else None,
|
||||
recent_predictions=[
|
||||
PredictionOut(
|
||||
id=p.id, match_id=p.match_id, provider=p.provider, model=p.model,
|
||||
prompt_version=p.prompt_version, mode=p.mode or "single",
|
||||
pred_home_goals=p.pred_home_goals, pred_away_goals=p.pred_away_goals,
|
||||
alt_pred_home_goals=p.alt_pred_home_goals, alt_pred_away_goals=p.alt_pred_away_goals,
|
||||
pred_1x2=p.pred_1x2, subjective_confidence=p.subjective_confidence,
|
||||
reasoning=p.reasoning, status=p.status or "success",
|
||||
agent_outputs=p.agent_outputs, agent_weights=p.agent_weights,
|
||||
created_at=p.created_at, actual_home_goals=p.actual_home_goals,
|
||||
actual_away_goals=p.actual_away_goals, settled=p.settled,
|
||||
)
|
||||
for p in preds
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@router.get("/matches/{match_id}/context", dependencies=[Depends(require_admin)])
|
||||
async def match_context(match_id: int, db: AsyncSession = Depends(get_db_read)):
|
||||
"""比赛上下文(只读,不触发 LLM):双方近况 + 历史交锋。
|
||||
|
||||
全部基于现有数据聚合:
|
||||
- recent_home / recent客队:该队最近 5 场已完赛(进球/结果)
|
||||
- h2h:双方最近 5 次交手
|
||||
若数据不足,对应列表为空(前端展示空态)。
|
||||
"""
|
||||
m = (
|
||||
await db.execute(
|
||||
select(Match)
|
||||
.options(selectinload(Match.home_team), selectinload(Match.away_team))
|
||||
.where(Match.id == match_id)
|
||||
)
|
||||
).scalar_one_or_none()
|
||||
if m is None:
|
||||
raise HTTPException(404, "match not found")
|
||||
home_id = m.home_team_id
|
||||
away_id = m.away_team_id
|
||||
|
||||
def _row_to_dict(row):
|
||||
return {
|
||||
"match_date": row.match_date.isoformat() if row.match_date else None,
|
||||
"home_team": row.home_team.name_zh or row.home_team.name if row.home_team else None,
|
||||
"away_team": row.away_team.name_zh or row.away_team.name if row.away_team else None,
|
||||
"home_goals": row.home_goals,
|
||||
"away_goals": row.away_goals,
|
||||
}
|
||||
|
||||
# 主队近况(已完赛,含主/客场)
|
||||
home_recent = (
|
||||
await db.execute(
|
||||
select(Match)
|
||||
.where(Match.match_status == "finished", Match.home_team_id == home_id)
|
||||
.order_by(Match.match_date.desc())
|
||||
.limit(5)
|
||||
.options(selectinload(Match.home_team), selectinload(Match.away_team))
|
||||
)
|
||||
).scalars().all()
|
||||
|
||||
# 客队近况
|
||||
away_recent = (
|
||||
await db.execute(
|
||||
select(Match)
|
||||
.where(Match.match_status == "finished", Match.away_team_id == away_id)
|
||||
.order_by(Match.match_date.desc())
|
||||
.limit(5)
|
||||
.options(selectinload(Match.home_team), selectinload(Match.away_team))
|
||||
)
|
||||
).scalars().all()
|
||||
|
||||
# 历史交锋(双方已完赛)
|
||||
h2h = (
|
||||
await db.execute(
|
||||
select(Match)
|
||||
.where(
|
||||
Match.match_status == "finished",
|
||||
or_(
|
||||
(Match.home_team_id == home_id) & (Match.away_team_id == away_id),
|
||||
(Match.home_team_id == away_id) & (Match.away_team_id == home_id),
|
||||
),
|
||||
)
|
||||
.order_by(Match.match_date.desc())
|
||||
.limit(5)
|
||||
.options(selectinload(Match.home_team), selectinload(Match.away_team))
|
||||
)
|
||||
).scalars().all()
|
||||
|
||||
return {
|
||||
"home_recent": [_row_to_dict(r) for r in home_recent],
|
||||
"away_recent": [_row_to_dict(r) for r in away_recent],
|
||||
"h2h": [_row_to_dict(r) for r in h2h],
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user