diff --git a/.idea/claudeCodeTabState.xml b/.idea/claudeCodeTabState.xml
index 08b9482..9ad4cd3 100644
--- a/.idea/claudeCodeTabState.xml
+++ b/.idea/claudeCodeTabState.xml
@@ -8,7 +8,7 @@
-
+
diff --git a/api/router.py b/api/router.py
index dd4ab2a..f39101e 100644
--- a/api/router.py
+++ b/api/router.py
@@ -3,8 +3,7 @@
"""
from fastapi import APIRouter
-from api.routers import auth, health
+from api.routers import auth
api_router = APIRouter()
-api_router.include_router(health.router, prefix="/api", tags=["系统"])
api_router.include_router(auth.router, prefix="/api", tags=["认证"])
\ No newline at end of file
diff --git a/api/routers/auth.py b/api/routers/auth.py
index 358ae82..df51975 100644
--- a/api/routers/auth.py
+++ b/api/routers/auth.py
@@ -1,38 +1,21 @@
-"""认证路由:登录签发 JWT + 当前用户信息(get_current_user 依赖注入示例)。"""
+"""认证路由:登录 + 当前用户(业务在 service/auth.py,路由只做编排)。"""
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 schemas.auth import LoginReq
+from service.auth import login as auth_login
+from service.auth import user_payload
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)})
+ return success(await auth_login(db, body.username, body.password))
@router.get("/auth/me")
diff --git a/api/routers/health.py b/api/routers/health.py
deleted file mode 100644
index 526fa25..0000000
--- a/api/routers/health.py
+++ /dev/null
@@ -1,17 +0,0 @@
-"""系统健康检查:四库就绪状态 + 各库探测耗时(任一失败返回 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},
- )
\ No newline at end of file
diff --git a/service/auth.py b/service/auth.py
index 9e2060d..3ca1a2e 100644
--- a/service/auth.py
+++ b/service/auth.py
@@ -1,4 +1,4 @@
-"""认证服务:JWT 签发/校验(HS256)+ 密码哈希/校验。
+"""认证服务:登录业务 + JWT 签发/校验(HS256)+ 密码哈希/校验。
密码用 stdlib PBKDF2(免 bcrypt 依赖),存储格式自描述:
pbkdf2_sha256$600000$$
@@ -9,8 +9,12 @@ import secrets
import time
import jwt
+from sqlalchemy.ext.asyncio import AsyncSession
from config.settings import settings
+from model.sys_user import SysUser
+from repositories.sys_user import SysUserRepo
+from utils.exceptions import ForbiddenError, ParamError
_ITERATIONS = 600_000
@@ -43,4 +47,27 @@ def verify_password(password: str, stored: str) -> bool:
except ValueError:
return False
calc = hashlib.pbkdf2_hmac("sha256", password.encode(), bytes.fromhex(salt), int(iters))
- return hmac.compare_digest(calc.hex(), digest)
\ No newline at end of file
+ return hmac.compare_digest(calc.hex(), digest)
+
+
+# ---- 登录业务(路由层只编排,不碰数据/逻辑) ----
+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,
+ }
+
+
+async def login(db: AsyncSession, username: str, password: str) -> dict:
+ """校验账号密码与状态,成功签发 token 并返回用户信息;失败抛业务异常。"""
+ user = await SysUserRepo(db).get_by_username(username)
+ if user is None or not verify_password(password, user.password_hash):
+ raise ParamError("用户名或密码错误")
+ if user.status != "正常":
+ raise ForbiddenError("账号状态异常,无法登录")
+ return {"token": create_token(user.id), "user": user_payload(user)}
\ No newline at end of file