Files
Story-extractor/backend/app/api/matching.py
2026-04-24 16:02:16 +08:00

77 lines
2.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from typing import Annotated
from fastapi import APIRouter, HTTPException, Depends
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from app.database import get_db
from app.models.story import Story
from app.models.person import Person
from app.schemas.schemas import MatchCreate, MatchOut
router = APIRouter(prefix="/matches", tags=["匹配管理"])
# 特殊讲述者 ID暂无
UNKNOWN_PERSON_ID = "unknown"
UNKNOWN_PERSON_NAME = "暂无"
@router.post("")
async def create_match(data: MatchCreate, db: Annotated[AsyncSession, Depends(get_db)]):
"""创建匹配关系(支持 person_id='unknown' 表示暂无讲述者)"""
story = await db.get(Story, data.story_id)
if not story or story.match_status == "deleted":
raise HTTPException(404, "故事不存在")
if data.person_id == UNKNOWN_PERSON_ID:
person_name = UNKNOWN_PERSON_NAME
else:
person = await db.get(Person, data.person_id)
if not person:
raise HTTPException(404, "讲述者不存在")
person_name = person.name
story.person_id = data.person_id
story.match_status = "matched"
await db.commit()
await db.refresh(story)
return {"message": "匹配成功", "story_id": story.id, "person_id": data.person_id, "person_name": person_name}
@router.delete("/{story_id}")
async def remove_match(story_id: str, db: Annotated[AsyncSession, Depends(get_db)]):
"""取消匹配"""
story = await db.get(Story, story_id)
if not story:
raise HTTPException(404, "故事不存在")
story.person_id = None
story.match_status = "pending"
await db.commit()
return {"message": "已取消匹配"}
@router.get("", response_model=list[MatchOut])
async def list_matches(db: Annotated[AsyncSession, Depends(get_db)]):
"""获取所有匹配关系"""
result = await db.execute(
select(Story, Person)
.join(Person, Story.person_id == Person.id, isouter=True)
.where(Story.match_status == "matched")
)
matches = []
for story, person in result.all():
if story.person_id == UNKNOWN_PERSON_ID:
person_name = UNKNOWN_PERSON_NAME
elif person:
person_name = person.name
else:
person_name = UNKNOWN_PERSON_NAME
matches.append({
"story_id": story.id,
"person_id": story.person_id,
"person_name": person_name,
"story_title": story.title,
})
return matches