feature:基本框架
This commit is contained in:
+27
@@ -0,0 +1,27 @@
|
||||
"""路由级鉴权依赖:Bearer JWT → 校验 token → 按 user_id 回查 sys_user → 注入用户。"""
|
||||
from fastapi import Depends, Request
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from config.deps import get_db
|
||||
from model.sys_user import SysUser
|
||||
from repositories.sys_user import SysUserRepo
|
||||
from service.auth import decode_token
|
||||
from utils.exceptions import AuthError, ForbiddenError
|
||||
|
||||
|
||||
async def get_current_user(
|
||||
request: Request, db: AsyncSession = Depends(get_db)
|
||||
) -> SysUser:
|
||||
header = request.headers.get("Authorization", "")
|
||||
if not header.startswith("Bearer "):
|
||||
raise AuthError()
|
||||
try:
|
||||
user_id = int(decode_token(header.removeprefix("Bearer "))["user_id"])
|
||||
except Exception:
|
||||
raise AuthError("Token 无效或已过期")
|
||||
user = await SysUserRepo(db).get(user_id)
|
||||
if user is None:
|
||||
raise AuthError("用户不存在")
|
||||
if user.status != "正常":
|
||||
raise ForbiddenError("账号已被禁用或冻结")
|
||||
return user
|
||||
@@ -0,0 +1,10 @@
|
||||
"""路由汇总。各业务模块在对应 Phase 落地后按模块加入:
|
||||
- auth / product / trade / profile / memory / knowledge / risk / advisor / workorder / admin
|
||||
"""
|
||||
from fastapi import APIRouter
|
||||
|
||||
from api.routers import auth, health
|
||||
|
||||
api_router = APIRouter()
|
||||
api_router.include_router(health.router, prefix="/api", tags=["系统"])
|
||||
api_router.include_router(auth.router, prefix="/api", tags=["认证"])
|
||||
@@ -0,0 +1,41 @@
|
||||
"""认证路由:登录签发 JWT + 当前用户信息(get_current_user 依赖注入示例)。"""
|
||||
from fastapi import APIRouter, Depends
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from api.deps import get_current_user
|
||||
from config.deps import get_db
|
||||
from schemas.auth import LoginReq
|
||||
from model.sys_user import SysUser
|
||||
from repositories.sys_user import SysUserRepo
|
||||
from service.auth import create_token, verify_password
|
||||
from utils.exceptions import ForbiddenError, ParamError
|
||||
from utils.response import success
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
def user_payload(u: SysUser) -> dict:
|
||||
return {
|
||||
"id": u.id,
|
||||
"username": u.username,
|
||||
"user_type": u.user_type,
|
||||
"employee_role": u.employee_role,
|
||||
"customer_level": u.customer_level,
|
||||
"status": u.status,
|
||||
}
|
||||
|
||||
|
||||
@router.post("/auth/login")
|
||||
async def login(body: LoginReq, db: AsyncSession = Depends(get_db)):
|
||||
user = await SysUserRepo(db).get_by_username(body.username)
|
||||
if user is None or not verify_password(body.password, user.password_hash):
|
||||
raise ParamError("用户名或密码错误")
|
||||
if user.status != "正常":
|
||||
raise ForbiddenError("账号状态异常,无法登录")
|
||||
return success({"token": create_token(user.id), "user": user_payload(user)})
|
||||
|
||||
|
||||
@router.get("/auth/me")
|
||||
async def me(user: SysUser = Depends(get_current_user)):
|
||||
"""受保护示例路由:任意接口加 Depends(get_current_user) 即获得当前用户。"""
|
||||
return success({"user": user_payload(user)})
|
||||
@@ -0,0 +1,17 @@
|
||||
"""系统健康检查:四库就绪状态 + 各库探测耗时(任一失败返回 503 + 明细)。"""
|
||||
from fastapi import APIRouter
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from config.database import check_ready_detail
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/health/ready")
|
||||
async def health_ready():
|
||||
dbs = await check_ready_detail()
|
||||
all_ok = all(v["status"] == "ok" for v in dbs.values())
|
||||
return JSONResponse(
|
||||
status_code=200 if all_ok else 503,
|
||||
content={"status": "ready" if all_ok else "degraded", "dbs": dbs},
|
||||
)
|
||||
Reference in New Issue
Block a user