Initial project commit
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.core.deps import get_current_active_user, get_db
|
||||
from app.models.membership import MembershipPlan, UserMembership
|
||||
from app.models.user import User
|
||||
from app.schemas.membership import MembershipPlanOut, PurchaseMembership, UserMembershipOut
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/plans", response_model=list[MembershipPlanOut])
|
||||
async def list_plans(db: AsyncSession = Depends(get_db)):
|
||||
result = await db.execute(
|
||||
select(MembershipPlan)
|
||||
.where(MembershipPlan.is_active == True)
|
||||
.order_by(MembershipPlan.sort_order.asc())
|
||||
)
|
||||
return result.scalars().all()
|
||||
|
||||
|
||||
@router.get("/me", response_model=UserMembershipOut | None)
|
||||
async def get_my_membership(
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
now = datetime.now(timezone.utc)
|
||||
result = await db.execute(
|
||||
select(UserMembership).where(
|
||||
UserMembership.user_id == current_user.id,
|
||||
UserMembership.is_active == True,
|
||||
UserMembership.end_date >= now,
|
||||
).order_by(UserMembership.end_date.desc()).limit(1)
|
||||
)
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
|
||||
@router.post("/purchase", response_model=UserMembershipOut)
|
||||
async def purchase_membership(
|
||||
payload: PurchaseMembership,
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
plan_result = await db.execute(
|
||||
select(MembershipPlan).where(
|
||||
MembershipPlan.id == payload.plan_id,
|
||||
MembershipPlan.is_active == True,
|
||||
)
|
||||
)
|
||||
plan = plan_result.scalar_one_or_none()
|
||||
if not plan:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="会员方案不存在或已下架")
|
||||
|
||||
now = datetime.now(timezone.utc)
|
||||
|
||||
existing = await db.execute(
|
||||
select(UserMembership).where(
|
||||
UserMembership.user_id == current_user.id,
|
||||
UserMembership.is_active == True,
|
||||
UserMembership.end_date >= now,
|
||||
).order_by(UserMembership.end_date.desc()).limit(1)
|
||||
)
|
||||
current_membership = existing.scalar_one_or_none()
|
||||
|
||||
start = current_membership.end_date if current_membership else now
|
||||
end = start + timedelta(days=plan.duration_days)
|
||||
|
||||
membership = UserMembership(
|
||||
user_id=current_user.id,
|
||||
plan_id=plan.id,
|
||||
start_date=start,
|
||||
end_date=end,
|
||||
is_active=True,
|
||||
)
|
||||
db.add(membership)
|
||||
await db.commit()
|
||||
await db.refresh(membership)
|
||||
return membership
|
||||
Reference in New Issue
Block a user