feat: 新增风险图谱算法与系统仪表盘及操作反馈体系
后端新增风险图谱算法模块、风险观察与反馈服务、规则 DSL 校验器和可解释性引擎,完善系统仪表盘和财务仪表盘统计, 优化 agent 运行和编排执行链路,清理旧开发文档,前端新增 系统趋势、负载热力图等多种仪表盘图表组件,完善操作反馈 对话框和工作台日期选择器,优化报销创建和审批详情交互, 补充单元测试覆盖。
This commit is contained in:
@@ -27,6 +27,45 @@ class ExpenseClaimApplicationHandoffMixin:
|
||||
return normalized.removesuffix("_application") or "other"
|
||||
return normalized or "other"
|
||||
|
||||
@staticmethod
|
||||
def _resolve_application_detail(application_claim: ExpenseClaim) -> dict[str, str]:
|
||||
for flag in list(application_claim.risk_flags_json or []):
|
||||
if not isinstance(flag, dict) or str(flag.get("source") or "").strip() != "application_detail":
|
||||
continue
|
||||
detail = flag.get("application_detail") or flag.get("applicationDetail") or {}
|
||||
if isinstance(detail, dict):
|
||||
return {str(key): str(value or "").strip() for key, value in detail.items()}
|
||||
return {}
|
||||
|
||||
@staticmethod
|
||||
def _build_application_handoff_detail(application_claim: ExpenseClaim) -> dict[str, str]:
|
||||
detail = ExpenseClaimApplicationHandoffMixin._resolve_application_detail(application_claim)
|
||||
application_time = str(detail.get("time") or "").strip()
|
||||
if not application_time and application_claim.occurred_at is not None:
|
||||
application_time = application_claim.occurred_at.isoformat()
|
||||
|
||||
application_amount = str(detail.get("amount") or "").strip()
|
||||
if not application_amount:
|
||||
application_amount = str(application_claim.amount or Decimal("0.00"))
|
||||
|
||||
return {
|
||||
"application_type": str(detail.get("application_type") or application_claim.expense_type or "").strip(),
|
||||
"application_content": " / ".join(
|
||||
item
|
||||
for item in [
|
||||
str(detail.get("application_type") or application_claim.expense_type or "").strip(),
|
||||
str(detail.get("location") or application_claim.location or "").strip(),
|
||||
]
|
||||
if item
|
||||
),
|
||||
"application_reason": str(detail.get("reason") or application_claim.reason or "").strip(),
|
||||
"application_days": str(detail.get("days") or "").strip(),
|
||||
"application_location": str(detail.get("location") or application_claim.location or "").strip(),
|
||||
"application_amount": application_amount,
|
||||
"application_time": application_time,
|
||||
"application_transport_mode": str(detail.get("transport_mode") or "").strip(),
|
||||
}
|
||||
|
||||
def _create_reimbursement_draft_from_application(
|
||||
self,
|
||||
*,
|
||||
@@ -67,6 +106,7 @@ class ExpenseClaimApplicationHandoffMixin:
|
||||
"application_claim_id": application_claim.id,
|
||||
"application_claim_no": application_claim.claim_no,
|
||||
"application_budget_amount": str(application_claim.amount or Decimal("0.00")),
|
||||
"application_detail": self._build_application_handoff_detail(application_claim),
|
||||
"application_approval_event_id": str(approval_flag.get("approval_event_id") or ""),
|
||||
"leader_opinion": str(
|
||||
approval_flag.get("leader_opinion") or approval_flag.get("opinion") or ""
|
||||
|
||||
Reference in New Issue
Block a user