da7ce69494
- 新增 POST /api/v1/ad/ecpm-report:激励视频展示后客户端上报本次 eCPM,落 ad_ecpm_record 做内部收益统计(model/repository/schema/alembic 迁移 + 接口文档) - 看广告冷却策略抽到 app/core/ad_cooldown.py 纯函数;ad_reward.today_status 只取数据,换策略只改这一处 - savings.dishes 改 JSON().with_variant(JSONB,"postgresql"):SQLite 无 visit_JSONB 会让 create_all 编译崩,修复后测试套件恢复 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: OuYingJun1024 <1034284404@qq.com> Reviewed-on: #8 Co-authored-by: ouzhou <ouzhou@wonderable.ai> Co-committed-by: ouzhou <ouzhou@wonderable.ai>
77 lines
2.4 KiB
Python
77 lines
2.4 KiB
Python
"""比价战绩里程碑 endpoint(福利页「记录比价战绩」)。
|
|
|
|
路由前缀 `/api/v1/compare`:
|
|
GET /milestones 进度与各档领取状态
|
|
POST /milestones/{milestone}/claim 领取某档奖励
|
|
|
|
**均需鉴权**。解锁进度 = 该用户 status='success' 的 comparison_record 条数;每档领一次。
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
|
|
from fastapi import APIRouter, HTTPException, status
|
|
|
|
from app.api.deps import CurrentUser, DbSession
|
|
from app.repositories import comparison_milestone as crud_milestone
|
|
from app.schemas.compare_record import (
|
|
MilestoneClaimResultOut,
|
|
MilestoneStateOut,
|
|
MilestoneStatusOut,
|
|
)
|
|
|
|
logger = logging.getLogger("shagua.compare_milestone")
|
|
|
|
router = APIRouter(prefix="/api/v1/compare", tags=["compare-milestone"])
|
|
|
|
|
|
@router.get(
|
|
"/milestones",
|
|
response_model=MilestoneStatusOut,
|
|
summary="比价战绩里程碑进度",
|
|
)
|
|
def get_milestones(user: CurrentUser, db: DbSession) -> MilestoneStatusOut:
|
|
st = crud_milestone.get_status(db, user.id)
|
|
return MilestoneStatusOut(
|
|
success_count=st.success_count,
|
|
claimable_count=st.claimable_count,
|
|
milestones=[
|
|
MilestoneStateOut(milestone=m.milestone, coin=m.coin, state=m.state)
|
|
for m in st.milestones
|
|
],
|
|
)
|
|
|
|
|
|
@router.post(
|
|
"/milestones/{milestone}/claim",
|
|
response_model=MilestoneClaimResultOut,
|
|
summary="领取比价战绩里程碑奖励",
|
|
)
|
|
def claim_milestone(
|
|
milestone: int, user: CurrentUser, db: DbSession
|
|
) -> MilestoneClaimResultOut:
|
|
try:
|
|
coin, balance = crud_milestone.claim(db, user.id, milestone)
|
|
except crud_milestone.UnknownMilestoneError as e:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND, detail="unknown milestone"
|
|
) from e
|
|
except crud_milestone.MilestoneLockedError as e:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_409_CONFLICT, detail="milestone locked"
|
|
) from e
|
|
except crud_milestone.AlreadyClaimedError as e:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_409_CONFLICT, detail="milestone already claimed"
|
|
) from e
|
|
|
|
logger.info(
|
|
"compare milestone claimed user_id=%d milestone=%d coin=%d",
|
|
user.id,
|
|
milestone,
|
|
coin,
|
|
)
|
|
return MilestoneClaimResultOut(
|
|
milestone=milestone, coin_awarded=coin, coin_balance=balance
|
|
)
|