chore: initial commit — leaudit-platform project skeleton
17-table PostgreSQL schema with full Chinese column comments, FastAPI project structure (admin/common/modules), DSL rule files, and schema migration scripts.
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
"""控制器包(需要 JWT 鉴权)。"""
|
||||
|
||||
from typing import Any
|
||||
|
||||
from fastapi import APIRouter, Depends, Request
|
||||
|
||||
from fastapi_common.fastapi_common_security.security import verify_access_token
|
||||
|
||||
|
||||
async def jwt_auth_dependency(RequestObj: Request) -> dict[str, Any]:
|
||||
"""JWT 鉴权依赖。"""
|
||||
return verify_access_token(RequestObj)
|
||||
|
||||
|
||||
router = APIRouter(dependencies=[Depends(jwt_auth_dependency)])
|
||||
@@ -0,0 +1,42 @@
|
||||
"""评查控制器。"""
|
||||
|
||||
from fastapi_common.fastapi_common_web.controller import BaseController
|
||||
from fastapi_common.fastapi_common_web.domain.responses import Result
|
||||
|
||||
from fastapi_modules.fastapi_leaudit.domian.Dto.auditDto import AuditRunDTO
|
||||
from fastapi_modules.fastapi_leaudit.domian.vo.auditVo import AuditRunVO, AuditResultVO
|
||||
from fastapi_modules.fastapi_leaudit.services import IAuditService
|
||||
from fastapi_modules.fastapi_leaudit.services.impl.auditServiceImpl import AuditServiceImpl
|
||||
|
||||
|
||||
class AuditController(BaseController):
|
||||
"""评查控制器。"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(prefix="/audit", tags=["评查"])
|
||||
self.AuditService: IAuditService = AuditServiceImpl()
|
||||
|
||||
@self.router.post("/run", response_model=Result[AuditRunVO])
|
||||
async def RunAudit(body: AuditRunDTO):
|
||||
"""触发文档评查
|
||||
|
||||
对指定文档执行 LeAudit 完整评查链路。
|
||||
"""
|
||||
run = await self.AuditService.Run(
|
||||
DocumentId=body.documentId,
|
||||
RuleType=body.ruleType,
|
||||
Force=body.force,
|
||||
)
|
||||
return Result.success(data=run)
|
||||
|
||||
@self.router.get("/run/{RunId}", response_model=Result[AuditRunVO])
|
||||
async def GetRunStatus(RunId: int):
|
||||
"""查询评查运行状态。"""
|
||||
run = await self.AuditService.GetRunStatus(RunId)
|
||||
return Result.success(data=run)
|
||||
|
||||
@self.router.get("/result/{RunId}", response_model=Result[AuditResultVO])
|
||||
async def GetResult(RunId: int):
|
||||
"""获取评查结果。"""
|
||||
result = await self.AuditService.GetResult(RunId)
|
||||
return Result.success(data=result)
|
||||
@@ -0,0 +1,5 @@
|
||||
"""认证控制器包(无鉴权)。"""
|
||||
|
||||
from fastapi import APIRouter
|
||||
|
||||
router = APIRouter()
|
||||
@@ -0,0 +1,97 @@
|
||||
"""认证控制器。
|
||||
|
||||
路由路径与旧项目完全一致:
|
||||
POST /auth/login — 统一登录(OAuth + 密码自动检测)
|
||||
POST /auth/password_login — 账密登录
|
||||
|
||||
响应格式按新项目规范使用 Result。
|
||||
"""
|
||||
|
||||
from fastapi import Request
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from fastapi_common.fastapi_common_web.controller import BaseController
|
||||
from fastapi_common.fastapi_common_web.domain.responses import Result
|
||||
from fastapi_common.fastapi_common_logger import logger
|
||||
|
||||
from fastapi_modules.fastapi_leaudit.domian.Dto.auth.loginDto import PasswordLoginDTO, OAuthLoginDTO
|
||||
from fastapi_modules.fastapi_leaudit.domian.vo.auth.loginTokenVo import LoginTokenVO
|
||||
from fastapi_modules.fastapi_leaudit.services import IAuthService
|
||||
from fastapi_modules.fastapi_leaudit.services.impl.authServiceImpl import AuthServiceImpl
|
||||
|
||||
|
||||
class AuthController(BaseController):
|
||||
"""认证控制器。"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(prefix="/auth", tags=["认证"])
|
||||
self.AuthService: IAuthService = AuthServiceImpl()
|
||||
|
||||
@self.router.post("/login")
|
||||
async def Login(RequestObj: Request):
|
||||
"""统一登录接口。
|
||||
|
||||
自动检测登录方式:
|
||||
- 含 userInfo.sub → OAuth 登录
|
||||
- 含 username + password → 密码登录
|
||||
"""
|
||||
try:
|
||||
requestData = await RequestObj.json()
|
||||
|
||||
if "userInfo" in requestData and isinstance(requestData["userInfo"], dict) and "sub" in requestData["userInfo"]:
|
||||
logger.info("检测到 OAuth 登录请求")
|
||||
ui = requestData["userInfo"]
|
||||
vo = await self.AuthService.OAuthLogin(
|
||||
Sub=ui["sub"],
|
||||
Username=ui.get("username"),
|
||||
Nickname=ui.get("nickname"),
|
||||
Email=ui.get("email"),
|
||||
PhoneNumber=ui.get("phone_number"),
|
||||
OuId=ui.get("ou_id"),
|
||||
OuName=ui.get("ou_name"),
|
||||
IsLeader=ui.get("is_leader"),
|
||||
Area=requestData.get("area"),
|
||||
ExpiresIn=requestData.get("expiresIn", 3600),
|
||||
)
|
||||
elif "username" in requestData and "password" in requestData:
|
||||
logger.info(f"检测到密码登录请求 - username={requestData['username']}")
|
||||
vo = await self.AuthService.PasswordLogin(
|
||||
Sub=requestData["username"],
|
||||
Password=requestData["password"],
|
||||
)
|
||||
else:
|
||||
return JSONResponse(status_code=400, content={"code": 400, "message": "无效的登录请求格式", "data": None})
|
||||
|
||||
return JSONResponse(status_code=200, content={
|
||||
"code": 200,
|
||||
"message": "ok",
|
||||
"data": {
|
||||
"access_token": vo.access_token,
|
||||
"token_type": vo.token_type,
|
||||
"expires_in": vo.expires_in,
|
||||
"issued_time": vo.issued_time,
|
||||
"user_info": vo.user_info,
|
||||
},
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"登录失败: {e}")
|
||||
return JSONResponse(status_code=401, content={
|
||||
"code": 401, "message": str(e), "data": None,
|
||||
})
|
||||
|
||||
@self.router.post("/password_login")
|
||||
async def PasswordLogin(RequestObj: Request):
|
||||
"""账密登录。校验 sso_users 表 sub + password。"""
|
||||
try:
|
||||
requestData = await RequestObj.json()
|
||||
dto = PasswordLoginDTO(**requestData)
|
||||
vo = await self.AuthService.PasswordLogin(Sub=dto.sub, Password=dto.password)
|
||||
return JSONResponse(status_code=200, content={
|
||||
"code": 200, "message": "ok", "data": vo.model_dump(),
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"密码登录失败: {e}")
|
||||
return JSONResponse(status_code=401, content={
|
||||
"code": 401, "message": str(e), "data": None,
|
||||
})
|
||||
Reference in New Issue
Block a user