from fastapi import APIRouter, HTTPException, Depends from sqlalchemy.orm import Session from app.models.user import UserLogin, UserInfo, VerifyCodeRequest, UserDB from app.models.database import get_db import random import string import redis from app.core.config import settings from unisdk.sms import UniSMS from unisdk.exception import UniException router = APIRouter() # Redis 连接 redis_client = redis.Redis( host=settings.REDIS_HOST, port=settings.REDIS_PORT, db=settings.REDIS_DB, password=settings.REDIS_PASSWORD, decode_responses=True ) # 初始化短信客户端 client = UniSMS(settings.UNI_APP_ID) @router.post("/send-code") async def send_verify_code(request: VerifyCodeRequest): """发送验证码""" phone = request.phone code = ''.join(random.choices(string.digits, k=6)) try: # 发送短信 res = client.send({ "to": phone, "signature": settings.UNI_SMS_SIGN, "templateId": settings.UNI_SMS_TEMPLATE_ID, "templateData": { "code": code } }) if res.code != "0": # 0 表示发送成功 raise HTTPException(status_code=500, detail=f"短信发送失败: {res.message}") # 存储验证码到 Redis redis_client.setex( f"verify_code:{phone}", settings.VERIFICATION_CODE_EXPIRE_SECONDS, code ) return {"message": "验证码已发送"} except UniException as e: raise HTTPException(status_code=500, detail=f"发送验证码失败: {str(e)}") @router.post("/login") async def login(user_login: UserLogin, db: Session = Depends(get_db)): """用户登录""" phone = user_login.phone verify_code = user_login.verify_code # 验证验证码 stored_code = redis_client.get(f"verify_code:{phone}") if not stored_code or stored_code != verify_code: raise HTTPException(status_code=400, detail="验证码错误或已过期") redis_client.delete(f"verify_code:{phone}") # 查找或创建用户 user = db.query(UserDB).filter(UserDB.phone == phone).first() if not user: # 创建新用户 user = UserDB( username=f"user_{phone[-4:]}", phone=phone ) db.add(user) db.commit() db.refresh(user) return {"message": "登录成功", "user": UserInfo.model_validate(user)} @router.get("/info") async def get_user_info(phone: str, db: Session = Depends(get_db)): """获取用户信息""" user = db.query(UserDB).filter(UserDB.phone == phone).first() if not user: raise HTTPException(status_code=404, detail="用户不存在") return UserInfo.model_validate(user)