Port NomadCNA city_details/content/routes seeding into PocketBase and surface full destination pages with related meetups and discussions. Co-authored-by: Cursor <cursoragent@cursor.com>
87 lines
2.4 KiB
Python
87 lines
2.4 KiB
Python
"""Meetup auth helpers — NomadCNA check-user / ensure-user / complete-order."""
|
|
from __future__ import annotations
|
|
|
|
from fastapi import APIRouter, Header, HTTPException
|
|
from pydantic import BaseModel, EmailStr, Field
|
|
|
|
from app.services.auth import ensure_user_by_email, find_user_public_by_email, get_user_by_token
|
|
from app.services import social_store
|
|
|
|
router = APIRouter(prefix="/meetup", tags=["meetup-auth"])
|
|
|
|
|
|
class CheckUserPayload(BaseModel):
|
|
email: EmailStr
|
|
|
|
|
|
class EnsureUserPayload(BaseModel):
|
|
email: EmailStr
|
|
name: str = Field(default="", max_length=120)
|
|
|
|
|
|
class CompleteOrderPayload(BaseModel):
|
|
order_id: str = Field(min_length=4, max_length=160)
|
|
|
|
|
|
@router.post("/check-user")
|
|
async def check_user(payload: CheckUserPayload):
|
|
user = find_user_public_by_email(str(payload.email).lower())
|
|
vip = bool(user and social_store.is_vip(user["id"]))
|
|
return {
|
|
"ok": True,
|
|
"exists": bool(user),
|
|
"vip": vip,
|
|
"user_id": user["id"] if user else None,
|
|
}
|
|
|
|
|
|
@router.post("/ensure-user")
|
|
async def ensure_user(payload: EnsureUserPayload):
|
|
try:
|
|
result = ensure_user_by_email(str(payload.email).lower(), payload.name)
|
|
except Exception as exc:
|
|
raise HTTPException(500, f"创建用户失败: {exc}") from exc
|
|
user = result["user"]
|
|
vip = social_store.is_vip(user["id"])
|
|
return {
|
|
"ok": True,
|
|
"user_id": user["id"],
|
|
"record": user,
|
|
"token": result["token"],
|
|
"is_new": bool(result.get("is_new")),
|
|
"vip": vip,
|
|
}
|
|
|
|
|
|
@router.post("/complete-order")
|
|
async def complete_order(payload: CompleteOrderPayload, authorization: str | None = Header(None)):
|
|
order_id = payload.order_id.strip()
|
|
if not order_id:
|
|
raise HTTPException(400, "缺少 order_id")
|
|
order = social_store.get_order(order_id)
|
|
if not order:
|
|
raise HTTPException(404, "订单不存在")
|
|
if order.get("status") != "paid":
|
|
paid = social_store.mark_order_paid(order_id)
|
|
if not paid:
|
|
raise HTTPException(400, "订单未支付成功")
|
|
order = paid
|
|
|
|
user = None
|
|
token = None
|
|
if authorization and authorization.startswith("Bearer "):
|
|
user = get_user_by_token(authorization[7:])
|
|
token = authorization[7:]
|
|
if not user:
|
|
uid = order.get("userId") or order.get("user_id") or ""
|
|
if uid:
|
|
user = {"id": uid, "email": "", "name": "会员", "avatar": "🧑💻"}
|
|
return {
|
|
"ok": True,
|
|
"token": token,
|
|
"record": user,
|
|
"is_new": False,
|
|
"vip": True,
|
|
"order_id": order_id,
|
|
}
|