deliveryman-api/app/api/endpoints/user.py
2025-01-02 16:33:39 +08:00

92 lines
2.8 KiB
Python

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)