feat: migrate cross review to v3 leaudit flow
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
"""交叉评查控制器(第一阶段骨架)。"""
|
||||
|
||||
from typing import Any
|
||||
|
||||
from fastapi import Depends, File, Query, UploadFile
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from fastapi_common.fastapi_common_security.security import verify_access_token
|
||||
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.crossReviewDto import (
|
||||
CrossReviewProposalCreateDTO,
|
||||
CrossReviewProposalVoteDTO,
|
||||
CrossReviewTaskCreateDTO,
|
||||
CrossReviewTaskDocumentQueryDTO,
|
||||
CrossReviewTaskQueryDTO,
|
||||
)
|
||||
from fastapi_modules.fastapi_leaudit.domian.vo.crossReviewVo import (
|
||||
CrossReviewPendingVotesVO,
|
||||
CrossReviewPermissionVO,
|
||||
CrossReviewProposalCancelVO,
|
||||
CrossReviewProposalCreateVO,
|
||||
CrossReviewProposalPageVO,
|
||||
CrossReviewProposalVoteVO,
|
||||
CrossReviewTaskCompleteVO,
|
||||
CrossReviewTaskCreateVO,
|
||||
CrossReviewTaskDocumentPageVO,
|
||||
CrossReviewTaskDocumentUploadVO,
|
||||
CrossReviewTaskPageVO,
|
||||
CrossReviewTaskProgressVO,
|
||||
)
|
||||
from fastapi_modules.fastapi_leaudit.services.crossReviewService import ICrossReviewService
|
||||
from fastapi_modules.fastapi_leaudit.services.impl.crossReviewServiceImpl import CrossReviewServiceImpl
|
||||
from fastapi_modules.fastapi_leaudit.services.impl.permissionServiceImpl import PermissionServiceImpl
|
||||
from fastapi_modules.fastapi_leaudit.services.permissionService import IPermissionService
|
||||
|
||||
|
||||
class CrossReviewController(BaseController):
|
||||
"""交叉评查控制器。"""
|
||||
|
||||
_PERMISSIONS = {
|
||||
"task_create": "cross_review:task:create",
|
||||
"task_read": "cross_review:task:read",
|
||||
"progress_view": "cross_review:progress:view",
|
||||
"document_read": "cross_review:document:read",
|
||||
"document_complete": "cross_review:document:complete",
|
||||
"proposal_create": "cross_review:proposal:create",
|
||||
"proposal_read": "cross_review:proposal:read",
|
||||
"proposal_delete": "cross_review:proposal:delete",
|
||||
"proposal_vote": "cross_review:proposal:vote",
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(prefix="/v3/cross-review", tags=["交叉评查"])
|
||||
self.CrossReviewService: ICrossReviewService = CrossReviewServiceImpl()
|
||||
self.PermissionService: IPermissionService = PermissionServiceImpl()
|
||||
|
||||
@self.router.post("/tasks", response_model=Result[CrossReviewTaskCreateVO])
|
||||
async def CreateTask(
|
||||
Body: CrossReviewTaskCreateDTO,
|
||||
payload: dict[str, Any] = Depends(verify_access_token),
|
||||
):
|
||||
"""创建交叉评查任务。"""
|
||||
if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["task_create"]]):
|
||||
return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有创建交叉评查任务权限", "data": None})
|
||||
Data = await self.CrossReviewService.CreateTask(CurrentUserId=int(payload["user_id"]), Body=Body)
|
||||
return Result.success(data=Data, message="交叉评查任务创建成功")
|
||||
|
||||
@self.router.post("/tasks/query", response_model=Result[CrossReviewTaskPageVO])
|
||||
async def GetUserTasks(
|
||||
Body: CrossReviewTaskQueryDTO,
|
||||
payload: dict[str, Any] = Depends(verify_access_token),
|
||||
):
|
||||
"""查询当前用户参与的交叉评查任务。"""
|
||||
if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["task_read"]]):
|
||||
return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有查看交叉评查任务权限", "data": None})
|
||||
Data = await self.CrossReviewService.GetUserTasks(CurrentUserId=int(payload["user_id"]), Body=Body)
|
||||
return Result.success(data=Data)
|
||||
|
||||
@self.router.get("/tasks/{TaskId}/progress", response_model=Result[CrossReviewTaskProgressVO])
|
||||
async def GetTaskProgress(
|
||||
TaskId: int,
|
||||
payload: dict[str, Any] = Depends(verify_access_token),
|
||||
):
|
||||
"""查询任务进度。"""
|
||||
if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["progress_view"]]):
|
||||
return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有查看交叉评查任务进度权限", "data": None})
|
||||
Data = await self.CrossReviewService.GetTaskProgress(CurrentUserId=int(payload["user_id"]), TaskId=TaskId)
|
||||
return Result.success(data=Data)
|
||||
|
||||
@self.router.get("/tasks/{TaskId}/documents", response_model=Result[CrossReviewTaskDocumentPageVO])
|
||||
async def GetTaskDocuments(
|
||||
TaskId: int,
|
||||
page: int = Query(1, ge=1, description="页码"),
|
||||
pageSize: int = Query(20, ge=1, le=100, description="每页大小"),
|
||||
keyword: str | None = Query(None, description="关键字"),
|
||||
payload: dict[str, Any] = Depends(verify_access_token),
|
||||
):
|
||||
"""查询任务文档列表。"""
|
||||
if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["task_read"], self._PERMISSIONS["document_read"]]):
|
||||
return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有查看交叉评查任务文档权限", "data": None})
|
||||
Body = CrossReviewTaskDocumentQueryDTO(page=page, pageSize=pageSize, keyword=keyword)
|
||||
Data = await self.CrossReviewService.GetTaskDocuments(
|
||||
CurrentUserId=int(payload["user_id"]),
|
||||
TaskId=TaskId,
|
||||
Body=Body,
|
||||
)
|
||||
return Result.success(data=Data)
|
||||
|
||||
@self.router.get("/tasks/{TaskId}/can-confirm", response_model=Result[CrossReviewPermissionVO])
|
||||
async def CanConfirmTaskDocument(
|
||||
TaskId: int,
|
||||
payload: dict[str, Any] = Depends(verify_access_token),
|
||||
):
|
||||
"""查询当前用户是否可确认完成。"""
|
||||
if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["document_complete"]]):
|
||||
return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有确认交叉评查文档完成权限", "data": None})
|
||||
Data = await self.CrossReviewService.CanConfirmTaskDocument(CurrentUserId=int(payload["user_id"]), TaskId=TaskId)
|
||||
return Result.success(data=Data)
|
||||
|
||||
@self.router.post("/tasks/{TaskId}/documents/{DocumentId}/complete", response_model=Result[CrossReviewTaskCompleteVO])
|
||||
async def CompleteTaskDocument(
|
||||
TaskId: int,
|
||||
DocumentId: int,
|
||||
payload: dict[str, Any] = Depends(verify_access_token),
|
||||
):
|
||||
"""确认任务文档完成。"""
|
||||
if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["document_complete"]]):
|
||||
return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有确认交叉评查文档完成权限", "data": None})
|
||||
Data = await self.CrossReviewService.CompleteTaskDocument(
|
||||
CurrentUserId=int(payload["user_id"]),
|
||||
TaskId=TaskId,
|
||||
DocumentId=DocumentId,
|
||||
)
|
||||
return Result.success(data=Data, message="交叉评查文档已确认完成")
|
||||
|
||||
@self.router.post("/tasks/{TaskId}/documents/upload", response_model=Result[CrossReviewTaskDocumentUploadVO])
|
||||
async def UploadTaskDocument(
|
||||
TaskId: int,
|
||||
file: UploadFile = File(..., description="上传文档"),
|
||||
payload: dict[str, Any] = Depends(verify_access_token),
|
||||
):
|
||||
"""向交叉评查任务补传文档。"""
|
||||
if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["document_complete"]]):
|
||||
return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有交叉评查任务补传文档权限", "data": None})
|
||||
content = await file.read()
|
||||
Data = await self.CrossReviewService.UploadTaskDocument(
|
||||
CurrentUserId=int(payload["user_id"]),
|
||||
TaskId=TaskId,
|
||||
FileName=file.filename or "upload.bin",
|
||||
FileContent=content,
|
||||
ContentType=file.content_type,
|
||||
)
|
||||
return Result.success(data=Data, message="交叉评查任务文档上传成功")
|
||||
|
||||
@self.router.post("/proposals", response_model=Result[CrossReviewProposalCreateVO])
|
||||
async def CreateProposal(
|
||||
Body: CrossReviewProposalCreateDTO,
|
||||
payload: dict[str, Any] = Depends(verify_access_token),
|
||||
):
|
||||
"""创建交叉评查提案。"""
|
||||
if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["proposal_create"]]):
|
||||
return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有创建交叉评查提案权限", "data": None})
|
||||
Data = await self.CrossReviewService.CreateProposal(CurrentUserId=int(payload["user_id"]), Body=Body)
|
||||
return Result.success(data=Data, message="交叉评查提案创建成功")
|
||||
|
||||
@self.router.post("/proposals/{ProposalId}/votes", response_model=Result[CrossReviewProposalVoteVO])
|
||||
async def VoteProposal(
|
||||
ProposalId: int,
|
||||
Body: CrossReviewProposalVoteDTO,
|
||||
payload: dict[str, Any] = Depends(verify_access_token),
|
||||
):
|
||||
"""对交叉评查提案投票。"""
|
||||
if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["proposal_vote"]]):
|
||||
return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有交叉评查提案投票权限", "data": None})
|
||||
Data = await self.CrossReviewService.VoteProposal(CurrentUserId=int(payload["user_id"]), ProposalId=ProposalId, Body=Body)
|
||||
return Result.success(data=Data, message="交叉评查提案投票成功")
|
||||
|
||||
@self.router.delete("/proposals/{ProposalId}", response_model=Result[CrossReviewProposalCancelVO])
|
||||
async def CancelProposal(
|
||||
ProposalId: int,
|
||||
payload: dict[str, Any] = Depends(verify_access_token),
|
||||
):
|
||||
"""撤销交叉评查提案。"""
|
||||
if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["proposal_delete"]]):
|
||||
return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有撤销交叉评查提案权限", "data": None})
|
||||
Data = await self.CrossReviewService.CancelProposal(CurrentUserId=int(payload["user_id"]), ProposalId=ProposalId)
|
||||
return Result.success(data=Data, message="交叉评查提案已撤销")
|
||||
|
||||
@self.router.get("/documents/{DocumentId}/proposals", response_model=Result[CrossReviewProposalPageVO])
|
||||
async def GetDocumentProposals(
|
||||
DocumentId: int,
|
||||
page: int = Query(1, ge=1, description="页码"),
|
||||
pageSize: int = Query(20, ge=1, le=100, description="每页大小"),
|
||||
payload: dict[str, Any] = Depends(verify_access_token),
|
||||
):
|
||||
"""获取文档提案列表。"""
|
||||
if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["proposal_read"]]):
|
||||
return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有查看交叉评查提案权限", "data": None})
|
||||
Data = await self.CrossReviewService.GetDocumentProposals(
|
||||
CurrentUserId=int(payload["user_id"]),
|
||||
DocumentId=DocumentId,
|
||||
Page=page,
|
||||
PageSize=pageSize,
|
||||
)
|
||||
return Result.success(data=Data)
|
||||
|
||||
@self.router.get("/documents/{DocumentId}/pending-votes", response_model=Result[CrossReviewPendingVotesVO])
|
||||
async def GetDocumentPendingVotes(
|
||||
DocumentId: int,
|
||||
payload: dict[str, Any] = Depends(verify_access_token),
|
||||
):
|
||||
"""获取文档待投票摘要。"""
|
||||
if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["proposal_read"], self._PERMISSIONS["document_complete"]]):
|
||||
return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有查看待投票信息权限", "data": None})
|
||||
Data = await self.CrossReviewService.GetDocumentPendingVotes(CurrentUserId=int(payload["user_id"]), DocumentId=DocumentId)
|
||||
return Result.success(data=Data)
|
||||
|
||||
async def _check_permission(self, user_id: int, permission_keys: list[str]) -> bool:
|
||||
"""OR 逻辑权限校验。"""
|
||||
for permission_key in permission_keys:
|
||||
if await self.PermissionService.CheckPermission(user_id, permission_key):
|
||||
return True
|
||||
return False
|
||||
Reference in New Issue
Block a user