118 lines
3.4 KiB
Python
118 lines
3.4 KiB
Python
"""Card-related API routes"""
|
||
from typing import List
|
||
from fastapi import APIRouter, HTTPException, Depends
|
||
from sqlalchemy.ext.asyncio import AsyncSession
|
||
|
||
from app.models.card import Card, CardDraw, CardDrawResult
|
||
from app.services.gacha import GachaService
|
||
from app.repositories.user import UserRepository
|
||
from app.repositories.card import CardRepository, UniqueCardRepository
|
||
from app.db.base import get_db
|
||
|
||
router = APIRouter(prefix="/cards", tags=["cards"])
|
||
|
||
|
||
@router.post("/draw", response_model=CardDrawResult)
|
||
async def draw_card(
|
||
draw_request: CardDraw,
|
||
db: AsyncSession = Depends(get_db)
|
||
):
|
||
"""
|
||
カードを抽選する
|
||
|
||
- **user_did**: ユーザーのatproto DID
|
||
- **is_paid**: 課金ガチャかどうか
|
||
"""
|
||
try:
|
||
gacha_service = GachaService(db)
|
||
card, is_unique = await gacha_service.draw_card(
|
||
user_did=draw_request.user_did,
|
||
is_paid=draw_request.is_paid
|
||
)
|
||
|
||
# 演出タイプを決定
|
||
animation_type = "normal"
|
||
if is_unique:
|
||
animation_type = "unique"
|
||
elif card.status.value == "kira":
|
||
animation_type = "kira"
|
||
elif card.status.value in ["super_rare", "rare"]:
|
||
animation_type = "rare"
|
||
|
||
# 新規取得かチェック
|
||
user_repo = UserRepository(db)
|
||
card_repo = CardRepository(db)
|
||
user = await user_repo.get_by_did(draw_request.user_did)
|
||
count = await card_repo.count_user_cards(user.id, card.id)
|
||
is_new = count == 1 # 今引いたカードが初めてなら1枚
|
||
|
||
result = CardDrawResult(
|
||
card=card,
|
||
is_new=is_new,
|
||
animation_type=animation_type
|
||
)
|
||
|
||
await db.commit()
|
||
return result
|
||
|
||
except Exception as e:
|
||
await db.rollback()
|
||
raise HTTPException(status_code=500, detail=str(e))
|
||
|
||
|
||
@router.get("/user/{user_did}", response_model=List[Card])
|
||
async def get_user_cards(
|
||
user_did: str,
|
||
skip: int = 0,
|
||
limit: int = 100,
|
||
db: AsyncSession = Depends(get_db)
|
||
):
|
||
"""
|
||
ユーザーの所有カード一覧を取得
|
||
|
||
- **user_did**: ユーザーのatproto DID
|
||
"""
|
||
user_repo = UserRepository(db)
|
||
card_repo = CardRepository(db)
|
||
|
||
user = await user_repo.get_by_did(user_did)
|
||
if not user:
|
||
raise HTTPException(status_code=404, detail="User not found")
|
||
|
||
user_cards = await card_repo.get_user_cards(user.id, skip=skip, limit=limit)
|
||
|
||
# Convert to API model
|
||
cards = []
|
||
for uc in user_cards:
|
||
card = Card(
|
||
id=uc.card_id,
|
||
cp=uc.cp,
|
||
status=uc.status,
|
||
skill=uc.skill,
|
||
owner_did=user_did,
|
||
obtained_at=uc.obtained_at,
|
||
is_unique=uc.is_unique,
|
||
unique_id=str(uc.unique_id) if uc.unique_id else None
|
||
)
|
||
cards.append(card)
|
||
|
||
return cards
|
||
|
||
|
||
@router.get("/unique")
|
||
async def get_unique_cards(db: AsyncSession = Depends(get_db)):
|
||
"""
|
||
全てのuniqueカード一覧を取得(所有者情報付き)
|
||
"""
|
||
unique_repo = UniqueCardRepository(db)
|
||
unique_cards = await unique_repo.get_all_unique_cards()
|
||
|
||
return [
|
||
{
|
||
"card_id": uc.card_id,
|
||
"owner_did": uc.owner_did,
|
||
"obtained_at": uc.obtained_at,
|
||
"unique_id": str(uc.unique_id)
|
||
}
|
||
for uc in unique_cards
|
||
] |