This commit is contained in:
2026-04-24 16:02:16 +08:00
commit 1d6f0cc370
66 changed files with 9990 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
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