feat: 新增预算中心本体与风险规则评分回填

后端新增预算本体解析模块和风险规则评分回填服务,优化规则
生成本体对齐和提示词构建,增强费用类型关键词和本体验证,
完善报销查询和审计接口,前端预算中心页面增加对话框和本
体工具函数,重构审计页面元数据和视图模型,补充单元测试。
This commit is contained in:
caoxiaozhu
2026-05-26 12:16:20 +08:00
parent 0e861d8fa6
commit e1e515ecae
53 changed files with 4350 additions and 921 deletions

View File

@@ -148,11 +148,12 @@ class AgentAssetRiskRuleTestingMixin:
if not body.confirm_passed:
raise ValueError("请确认测试通过后再保存测试报告。")
summary = "测试报告已确认,当前版本可提交审核"
summary = "测试报告已确认,当前版本可上线"
if scenario is None:
summary = "快速样例测试已确认通过,真实场景试运行未执行。"
elif not scenario.passed:
summary = "快速样例测试已确认通过,真实场景试运行未找到可测样本。"
self._mark_risk_rule_operation(asset, action="test", actor=actor)
return self._create_test_run(
asset,
version=version,
@@ -162,9 +163,9 @@ class AgentAssetRiskRuleTestingMixin:
input_json={"confirm_passed": True, "note": body.note or ""},
result_json={
"sample_test_run_id": sample.id,
"scenario_test_run_id": scenario.id,
"scenario_test_run_id": scenario.id if scenario else "",
"sample_summary": sample.summary,
"scenario_summary": scenario.summary,
"scenario_summary": scenario.summary if scenario else "",
},
actor=actor,
request_id=request_id,
@@ -308,6 +309,11 @@ class AgentAssetRiskRuleTestingMixin:
config_json = dict(asset.config_json or {})
config_json["enabled"] = bool(enabled)
self._set_risk_rule_status_for_online_toggle(asset, enabled=enabled, actor=actor)
config_json["last_operation"] = self._build_last_operation(
action="online" if enabled else "offline",
actor=actor,
)
asset.config_json = config_json
updated = self.repository.save_asset(asset)
self.audit_service.log_action(
@@ -321,6 +327,50 @@ class AgentAssetRiskRuleTestingMixin:
)
return updated
def _set_risk_rule_status_for_online_toggle(
self,
asset: AgentAsset,
*,
enabled: bool,
actor: str,
) -> None:
if enabled:
version = self._resolve_target_version(asset, None)
approved_review = self.repository.get_review(
asset.id, version, AgentReviewStatus.APPROVED.value
)
if approved_review is None:
self.db.add(
AgentAssetReview(
asset_id=asset.id,
version=version,
reviewer=actor,
review_status=AgentReviewStatus.APPROVED.value,
review_note="直接上线风险规则。",
reviewed_at=datetime.now(UTC),
)
)
asset.published_version = version
asset.reviewer = actor
asset.status = AgentAssetStatus.ACTIVE.value
return
asset.status = AgentAssetStatus.DISABLED.value
def _mark_risk_rule_operation(self, asset: AgentAsset, *, action: str, actor: str) -> None:
config_json = dict(asset.config_json or {})
config_json["last_operation"] = self._build_last_operation(action=action, actor=actor)
asset.config_json = config_json
self.db.add(asset)
@staticmethod
def _build_last_operation(*, action: str, actor: str) -> dict[str, str]:
return {
"action": action,
"actor": str(actor or "system").strip() or "system",
"at": datetime.now(UTC).isoformat(),
}
def _load_risk_rule_for_test(
self, asset_id: str, version: str | None
) -> tuple[AgentAsset, str, dict[str, Any]]: