feat: 本体字段治理与风险规则模板执行器重构

- 新增本体字段注册表与字段治理审计脚本
- 重构风险规则模板执行器、DSL 验证与清单分类器
- 完善票据夹服务与差旅请求详情页交互
- 优化趋势图表与总览页数据展示
- 增强报销平台风险分级与模拟公司筛选
- 补充本体字段、风险规则生成与票据夹服务测试覆盖
This commit is contained in:
caoxiaozhu
2026-06-03 15:46:56 +08:00
parent e12b140508
commit 34457f9c3e
81 changed files with 4858 additions and 1073 deletions

View File

@@ -108,6 +108,7 @@ from app.services.expense_rule_runtime import (
build_default_expense_rule_catalog,
resolve_document_type_label,
)
from app.services.ontology_field_registry import normalize_ontology_form_values
from app.services.ocr import OcrService
@@ -204,11 +205,8 @@ class ExpenseClaimOntologyResolverMixin:
def _resolve_explicit_review_expense_type(context_json: dict[str, Any]) -> str | None:
review_form_values = context_json.get("review_form_values")
if isinstance(review_form_values, dict):
compact = str(
review_form_values.get("expense_type")
or review_form_values.get("reimbursement_type")
or ""
).replace(" ", "")
review_form_values = normalize_ontology_form_values(review_form_values)
compact = str(review_form_values.get("expense_type") or "").replace(" ", "")
if compact:
return resolve_expense_type_code_from_text(compact)
return None
@@ -238,10 +236,10 @@ class ExpenseClaimOntologyResolverMixin:
) -> str | None:
review_form_values = context_json.get("review_form_values")
if isinstance(review_form_values, dict):
for key in ("reason", "business_reason"):
value = str(review_form_values.get(key) or "").strip()
if value:
return ExpenseClaimOntologyResolverMixin._strip_leading_time_from_reason(value)
review_form_values = normalize_ontology_form_values(review_form_values)
value = str(review_form_values.get("reason") or "").strip()
if value:
return ExpenseClaimOntologyResolverMixin._strip_leading_time_from_reason(value)
explicit_text = context_json.get("user_input_text")
if isinstance(explicit_text, str):
@@ -281,10 +279,10 @@ class ExpenseClaimOntologyResolverMixin:
def _resolve_location(*, message: str, context_json: dict[str, Any]) -> str | None:
review_form_values = context_json.get("review_form_values")
if isinstance(review_form_values, dict):
for key in ("business_location", "location"):
value = str(review_form_values.get(key) or "").strip()
if value:
return value
review_form_values = normalize_ontology_form_values(review_form_values)
value = str(review_form_values.get("location") or "").strip()
if value:
return value
request_context = context_json.get("request_context")
if (
@@ -314,16 +312,9 @@ class ExpenseClaimOntologyResolverMixin:
) -> datetime | None:
review_form_values = context_json.get("review_form_values")
if isinstance(review_form_values, dict):
for key in (
"occurred_date",
"time_range",
"business_time",
"application_business_time",
"application_time",
):
value = str(review_form_values.get(key) or "").strip()
if not value:
continue
review_form_values = normalize_ontology_form_values(review_form_values)
value = str(review_form_values.get("time_range") or "").strip()
if value:
try:
parsed = date.fromisoformat(value)
return datetime(parsed.year, parsed.month, parsed.day, tzinfo=UTC)