76 lines
2.6 KiB
Python
76 lines
2.6 KiB
Python
from fastapi import APIRouter, Depends, HTTPException
|
|
from sqlalchemy import select
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.core.security import create_access_token
|
|
from app.db import get_db
|
|
from app.deps import get_current_user
|
|
from app.integrations.sms_client import SmsClient
|
|
from app.models import Permission, User
|
|
from app.schemas.auth import CurrentUserResponse, LoginRequest, SmsCodeRequest, TokenResponse
|
|
from app.services.audit_service import write_audit
|
|
from app.services.user_service import get_or_create_login_user
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
def _build_current_user(db: Session, user: User) -> CurrentUserResponse:
|
|
if user.is_superuser:
|
|
permissions = sorted(db.scalars(select(Permission.code)).all())
|
|
else:
|
|
permissions = sorted({
|
|
p.code
|
|
for role in user.roles
|
|
for p in role.permissions
|
|
})
|
|
return CurrentUserResponse(
|
|
id=user.id,
|
|
phone=user.phone,
|
|
name=user.name,
|
|
department=user.department,
|
|
unit_id=user.unit_id,
|
|
unit_name=user.unit.name if user.unit else None,
|
|
status=user.status,
|
|
roles=[role.code for role in user.roles],
|
|
permissions=permissions,
|
|
is_superuser=user.is_superuser,
|
|
)
|
|
|
|
|
|
@router.post("/sms-code")
|
|
def send_sms_code(payload: SmsCodeRequest) -> dict:
|
|
code = "123456"
|
|
SmsClient().send_code(payload.phone, code)
|
|
return {"message": "验证码已发送", "mock_code": code}
|
|
|
|
|
|
@router.post("/login", response_model=TokenResponse)
|
|
def login(payload: LoginRequest, db: Session = Depends(get_db)) -> TokenResponse:
|
|
if payload.code != "123456":
|
|
raise HTTPException(status_code=400, detail="验证码错误或已过期")
|
|
user = get_or_create_login_user(db, payload.phone)
|
|
if user.status != "active":
|
|
raise HTTPException(status_code=403, detail="账号已禁用")
|
|
write_audit(db, "auth.login", actor_id=user.id, target_type="user", target_id=str(user.id))
|
|
db.commit()
|
|
db.refresh(user)
|
|
return TokenResponse(
|
|
access_token=create_access_token(str(user.id)),
|
|
user=_build_current_user(db, user),
|
|
)
|
|
|
|
|
|
@router.post("/logout")
|
|
def logout(current_user: User = Depends(get_current_user), db: Session = Depends(get_db)) -> dict:
|
|
write_audit(db, "auth.logout", actor_id=current_user.id, target_type="user", target_id=str(current_user.id))
|
|
db.commit()
|
|
return {"message": "已退出"}
|
|
|
|
|
|
@router.get("/me", response_model=CurrentUserResponse)
|
|
def me(
|
|
current_user: User = Depends(get_current_user),
|
|
db: Session = Depends(get_db),
|
|
) -> CurrentUserResponse:
|
|
return _build_current_user(db, current_user)
|