Files
app_03_pregnancy/backend/app/routers/auth.py
Karlcarlo 409dabafb5 feat: 初始化孕育无忧全栈项目基础代码结构
完成项目初始搭建,包含后端FastAPI+MongoDB服务、前端React+Vite项目的完整基础结构,添加各类配置文件与依赖清单,涵盖核心业务初始框架。
2026-05-21 00:46:48 +08:00

88 lines
2.5 KiB
Python

import uuid
from fastapi import APIRouter, HTTPException
from pymongo.errors import DuplicateKeyError
from app.models.user import User
from app.schemas.auth import WechatLoginRequest, PhoneLoginRequest, TokenResponse
from app.middleware.auth import create_access_token
from app.services.wechat import code_to_session
router = APIRouter()
@router.post("/demo-login", response_model=TokenResponse)
async def demo_login():
"""Web 体验用的演示登录,每次创建独立的临时用户"""
demo_openid = f"demo_{uuid.uuid4().hex[:12]}"
user = User(
openid=demo_openid,
name="体验用户",
)
await user.insert()
token = create_access_token(str(user.id))
return TokenResponse(
access_token=token,
user_id=str(user.id),
is_new_user=True,
)
@router.post("/wechat-login", response_model=TokenResponse)
async def wechat_login(req: WechatLoginRequest):
"""微信小程序登录"""
try:
wechat_data = await code_to_session(req.code)
except Exception as e:
raise HTTPException(status_code=400, detail=str(e))
openid = wechat_data["openid"]
user = await User.find_one(User.openid == openid)
is_new = user is None
if not user:
user = User(
openid=openid,
session_key=wechat_data.get("session_key"),
union_id=wechat_data.get("unionid"),
)
await user.insert()
else:
user.session_key = wechat_data.get("session_key")
await user.save()
token = create_access_token(str(user.id))
return TokenResponse(
access_token=token,
user_id=str(user.id),
is_new_user=is_new,
)
@router.post("/phone-login", response_model=TokenResponse)
async def phone_login(req: PhoneLoginRequest):
"""手机号登录(简化版,生产环境需接入短信验证)"""
# TODO: 接入真实短信验证服务
if req.sms_code != "123456":
raise HTTPException(status_code=400, detail="验证码错误")
user = await User.find_one(User.phone == req.phone)
is_new = user is None
if not user:
try:
user = User(openid=f"phone_{req.phone}", phone=req.phone)
await user.insert()
except DuplicateKeyError:
# 并发竞态:另一个请求已创建该用户,回退查找
user = await User.find_one(User.phone == req.phone)
is_new = False
token = create_access_token(str(user.id))
return TokenResponse(
access_token=token,
user_id=str(user.id),
is_new_user=is_new,
)