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, )