feat(govdoc): 新增内部公文模块全链路(后端58+前端11文件)

This commit is contained in:
wren
2026-05-13 14:37:12 +08:00
parent 99699e20e1
commit 5d777599bf
63 changed files with 7608 additions and 0 deletions
@@ -16,6 +16,7 @@ from fastapi_modules.fastapi_leaudit.services.ruleConfigService import IRuleConf
from fastapi_modules.fastapi_leaudit.services.ruleService import IRuleService
from fastapi_modules.fastapi_leaudit.services.ragDatasetService import IRagDatasetService
from fastapi_modules.fastapi_leaudit.services.ragChatService import IRagChatService
from fastapi_modules.fastapi_leaudit.services.govdocService import IGovdocService
from fastapi_modules.fastapi_leaudit.services.usageStatsService import IUsageStatsService
__all__ = [
@@ -36,4 +37,5 @@ __all__ = [
"IRagDatasetService",
"IRagChatService",
"IUsageStatsService",
"IGovdocService",
]
@@ -0,0 +1,121 @@
"""Govdoc 公文模块服务接口。"""
from abc import ABC, abstractmethod
from typing import Any
from fastapi import UploadFile
class IGovdocService(ABC):
"""公文处理与格式审查服务抽象接口。"""
# ── 文档 ──────────────────────────────────────────────
@abstractmethod
async def UploadDocument(
self,
file: UploadFile,
typeId: int | None = None,
region: str = "default",
autoRun: bool = False,
speed: str = "normal",
ruleVersionId: int | None = None,
createdBy: int | None = None,
) -> dict[str, Any]:
"""上传公文文档,创建主档记录,可选自动触发审查。"""
...
@abstractmethod
async def ListDocuments(
self,
page: int = 1,
pageSize: int = 20,
keyword: str | None = None,
region: str | None = None,
status: str | None = None,
resultStatus: str | None = None,
createdBy: int | None = None,
dateFrom: str | None = None,
dateTo: str | None = None,
userId: int | None = None,
) -> dict[str, Any]:
"""获取公文模块文档列表,自动限制 engine_type='govdoc'"""
...
@abstractmethod
async def GetDocumentDetail(self, documentId: int, userId: int | None = None) -> dict[str, Any]:
"""获取公文详情:文档基础信息 + 最新 run 摘要 + 报告引用。"""
...
@abstractmethod
async def UpdateDocument(self, documentId: int, body: dict[str, Any], userId: int | None = None) -> dict[str, Any]:
"""修改公文标题、文号、备注等基础信息。"""
...
@abstractmethod
async def DeleteDocument(self, documentId: int, userId: int | None = None) -> dict[str, Any]:
"""软删除文档。"""
...
# ── 审查运行 ──────────────────────────────────────────
@abstractmethod
async def CreateRun(
self,
documentId: int,
ruleVersionId: int | None = None,
speed: str = "normal",
force: bool = False,
triggerUserId: int | None = None,
) -> dict[str, Any]:
"""对已存在文档发起一次公文审查 run。"""
...
@abstractmethod
async def GetRunStatus(self, runId: int) -> dict[str, Any]:
"""查询 run 状态、阶段、耗时、错误摘要。"""
...
# ── 结果与报告 ────────────────────────────────────────
@abstractmethod
async def GetRunResult(self, runId: int) -> dict[str, Any]:
"""获取审查结果摘要:summary + checked rules + findings 统计 + entities 摘要。"""
...
@abstractmethod
async def GetRunFindings(self, runId: int) -> dict[str, Any]:
"""获取段落级 findings 明细列表。"""
...
@abstractmethod
async def GetRunEntities(self, runId: int) -> dict[str, Any]:
"""获取识别出的标题、文号、署名等实体。"""
...
@abstractmethod
async def GetRunParagraphs(self, runId: int) -> dict[str, Any]:
"""获取前端文档联动视图所需的段落 HTML。"""
...
@abstractmethod
async def GetReportHtml(self, runId: int) -> dict[str, Any]:
"""获取 HTML 报告内容或下载地址。"""
...
@abstractmethod
async def GetReportDocx(self, runId: int) -> dict[str, Any]:
"""获取批注 DOCX 下载地址。"""
...
@abstractmethod
async def DownloadOriginal(self, documentId: int) -> dict[str, Any]:
"""获取原始上传文档下载地址。"""
...
# ── 规则 ──────────────────────────────────────────────
@abstractmethod
async def ListRules(self) -> dict[str, Any]:
"""获取当前生效规则集摘要。"""
...
@@ -0,0 +1,130 @@
"""Govdoc 公文模块服务实现(阶段骨架)。
本文件为 Phase 1 骨架实现,所有方法暂返回占位结果。
后续步骤将逐步接入:
- govdoc_bridge 执行桥接
- govdoc_engine 引擎内核
- 文档主档复用
- OSS / Celery 集成
"""
from __future__ import annotations
from typing import Any
from fastapi import UploadFile
from fastapi_common.fastapi_common_logger import logger
from fastapi_modules.fastapi_leaudit.services import IGovdocService
class GovdocServiceImpl(IGovdocService):
"""公文处理与格式审查服务实现。"""
# ── 文档 ──────────────────────────────────────────────
async def UploadDocument(
self,
file: UploadFile,
typeId: int | None = None,
region: str = "default",
autoRun: bool = False,
speed: str = "normal",
ruleVersionId: int | None = None,
createdBy: int | None = None,
) -> dict[str, Any]:
logger.info("[Govdoc] UploadDocument placeholder — file=%s region=%s", file.filename, region)
return {
"documentId": 0,
"fileId": 0,
"fileName": file.filename,
"region": region,
"engineType": "govdoc",
"autoRunTriggered": autoRun,
}
async def ListDocuments(
self,
page: int = 1,
pageSize: int = 20,
keyword: str | None = None,
region: str | None = None,
status: str | None = None,
resultStatus: str | None = None,
createdBy: int | None = None,
dateFrom: str | None = None,
dateTo: str | None = None,
userId: int | None = None,
) -> dict[str, Any]:
logger.info("[Govdoc] ListDocuments placeholder — page=%s pageSize=%s", page, pageSize)
return {"items": [], "total": 0, "page": page, "pageSize": pageSize}
async def GetDocumentDetail(self, documentId: int, userId: int | None = None) -> dict[str, Any]:
logger.info("[Govdoc] GetDocumentDetail placeholder — id=%s", documentId)
return {"documentId": documentId}
async def UpdateDocument(self, documentId: int, body: dict[str, Any], userId: int | None = None) -> dict[str, Any]:
logger.info("[Govdoc] UpdateDocument placeholder — id=%s", documentId)
return {"documentId": documentId, **body}
async def DeleteDocument(self, documentId: int, userId: int | None = None) -> dict[str, Any]:
logger.info("[Govdoc] DeleteDocument placeholder — id=%s", documentId)
return {"documentId": documentId, "deleted": True}
# ── 审查运行 ──────────────────────────────────────────
async def CreateRun(
self,
documentId: int,
ruleVersionId: int | None = None,
speed: str = "normal",
force: bool = False,
triggerUserId: int | None = None,
) -> dict[str, Any]:
logger.info("[Govdoc] CreateRun placeholder — documentId=%s", documentId)
return {
"runId": 0,
"documentId": documentId,
"status": "queued",
"phase": "dispatch",
}
async def GetRunStatus(self, runId: int) -> dict[str, Any]:
logger.info("[Govdoc] GetRunStatus placeholder — runId=%s", runId)
return {"runId": runId, "status": "pending"}
# ── 结果与报告 ────────────────────────────────────────
async def GetRunResult(self, runId: int) -> dict[str, Any]:
logger.info("[Govdoc] GetRunResult placeholder — runId=%s", runId)
return {"runId": runId, "summary": {}}
async def GetRunFindings(self, runId: int) -> dict[str, Any]:
logger.info("[Govdoc] GetRunFindings placeholder — runId=%s", runId)
return {"runId": runId, "findings": []}
async def GetRunEntities(self, runId: int) -> dict[str, Any]:
logger.info("[Govdoc] GetRunEntities placeholder — runId=%s", runId)
return {"runId": runId, "entities": []}
async def GetRunParagraphs(self, runId: int) -> dict[str, Any]:
logger.info("[Govdoc] GetRunParagraphs placeholder — runId=%s", runId)
return {"runId": runId, "paragraphs": []}
async def GetReportHtml(self, runId: int) -> dict[str, Any]:
logger.info("[Govdoc] GetReportHtml placeholder — runId=%s", runId)
return {"runId": runId, "htmlUrl": ""}
async def GetReportDocx(self, runId: int) -> dict[str, Any]:
logger.info("[Govdoc] GetReportDocx placeholder — runId=%s", runId)
return {"runId": runId, "docxUrl": ""}
async def DownloadOriginal(self, documentId: int) -> dict[str, Any]:
logger.info("[Govdoc] DownloadOriginal placeholder — documentId=%s", documentId)
return {"documentId": documentId, "downloadUrl": ""}
# ── 规则 ──────────────────────────────────────────────
async def ListRules(self) -> dict[str, Any]:
logger.info("[Govdoc] ListRules placeholder")
return {"rules": []}