feat(regulatory): 增加风险归并与核查报告导出

This commit is contained in:
2026-06-07 00:39:33 +08:00
parent ec89e62661
commit 4c28466fe4
6 changed files with 401 additions and 0 deletions

View File

@@ -16,6 +16,13 @@ from review_agent.models import (
RegulatoryReviewBatch,
WorkflowNodeRun,
)
from review_agent.regulatory_review.services.completeness_check import run_completeness_check
from review_agent.regulatory_review.services.consistency_check import run_consistency_check
from review_agent.regulatory_review.services.export import build_assistant_summary, export_review_results
from review_agent.regulatory_review.services.risk_assess import persist_findings
from review_agent.regulatory_review.services.rule_loader import load_rule_file
from review_agent.regulatory_review.services.structure_check import run_structure_check
from review_agent.regulatory_review.services.text_extract import extract_text
from .events import record_event
@@ -89,6 +96,9 @@ def create_regulatory_review_batch(
class RegulatoryWorkflowExecutor:
def __init__(self, batch: RegulatoryReviewBatch):
self.batch = batch
self.rule_set: dict | None = None
self.findings = []
self.document_texts: dict[str, str] = {}
def run(self) -> None:
self.batch.status = RegulatoryReviewBatch.Status.RUNNING
@@ -131,6 +141,8 @@ class RegulatoryWorkflowExecutor:
{"node_code": node.node_code, "status": node.status, "progress": node.progress, "message": node.message},
)
self._execute_node(node.node_code)
node.status = WorkflowNodeRun.Status.SUCCESS
node.progress = 100
node.finished_at = timezone.now()
@@ -142,6 +154,51 @@ class RegulatoryWorkflowExecutor:
{"node_code": node.node_code, "status": node.status, "progress": node.progress, "message": node.message},
)
def _execute_node(self, node_code: str) -> None:
if node_code == "rule_scope":
self.rule_set = load_rule_file()
return
if node_code == "completeness_check":
self.findings.extend(run_completeness_check(self.batch.source_summary_batch, self._rules()))
return
if node_code == "text_extract":
self.document_texts = self._extract_source_texts()
return
if node_code == "structure_check":
self.findings.extend(run_structure_check(self.document_texts, self._rules()))
return
if node_code == "consistency_check":
self.findings.extend(run_consistency_check(self.document_texts))
return
if node_code == "risk_assess":
persist_findings(self.batch, self.findings)
return
if node_code == "report_export":
exports = export_review_results(self.batch)
Message.objects.create(
conversation=self.batch.conversation,
role=Message.Role.ASSISTANT,
content=build_assistant_summary(self.batch, exports),
)
def _rules(self) -> dict:
if self.rule_set is None:
self.rule_set = load_rule_file()
return self.rule_set
def _extract_source_texts(self) -> dict[str, str]:
texts = {}
for item in self.batch.source_summary_batch.items.order_by("file_index"):
path = Path(item.storage_path)
if not path.is_absolute():
path = Path(settings.MEDIA_ROOT) / item.storage_path
if not path.exists():
continue
result = extract_text(path)
if result.status == "success" and result.text:
texts[item.file_name] = result.text
return texts
def start_regulatory_review_workflow(batch: RegulatoryReviewBatch, *, async_run: bool = True) -> None:
executor = RegulatoryWorkflowExecutor(batch)