feat: 增强风险规则生成引擎与预算中心页面

后端拆分风险规则生成为解释器、语义分析、本体对齐等子模块,
优化模板执行和流程图生成,完善员工种子数据和导入逻辑,增强
报销单权限策略和草稿持久化,前端新增预算中心视图和趋势图
组件,重构审计页面和风险规则测试对话框交互,完善文档中心
和报销创建页面细节,补充单元测试覆盖。
This commit is contained in:
caoxiaozhu
2026-05-26 09:15:14 +08:00
parent d0e946cf47
commit 0e861d8fa6
150 changed files with 14953 additions and 4099 deletions

View File

@@ -2,7 +2,7 @@ from __future__ import annotations
from typing import Annotated
from fastapi import APIRouter, Body, Depends, Header, HTTPException, Query, status
from fastapi import APIRouter, BackgroundTasks, Body, Depends, Header, HTTPException, Query, status
from fastapi.responses import FileResponse
from sqlalchemy.orm import Session
@@ -14,6 +14,7 @@ from app.api.deps import (
require_rule_editor_user,
require_rule_reviewer_user,
)
from app.db.session import get_session_factory
from app.schemas.agent_asset import (
AgentAssetCreate,
AgentAssetListItem,
@@ -26,6 +27,7 @@ from app.schemas.agent_asset import (
AgentAssetRiskRuleEnabledUpdate,
AgentAssetRiskRuleGenerateRequest,
AgentAssetRiskRuleLatestTestSummary,
AgentAssetRiskRuleLevelUpdate,
AgentAssetRiskRuleReportRequest,
AgentAssetRiskRuleReturnRequest,
AgentAssetRiskRuleSampleTestRequest,
@@ -43,7 +45,7 @@ from app.schemas.agent_asset import (
)
from app.schemas.common import ErrorResponse
from app.services.agent_assets import AgentAssetService
from app.services.risk_rule_generation import RiskRuleGenerationService
from app.services.risk_rule_generation_jobs import RiskRuleGenerationJobService
router = APIRouter(prefix="/agent-assets")
DbSession = Annotated[Session, Depends(get_db)]
@@ -71,6 +73,25 @@ def _handle_asset_error(exc: Exception) -> None:
raise exc
def _complete_risk_rule_generation_task(
asset_id: str,
payload: dict,
actor: str,
request_id: str | None,
) -> None:
db = get_session_factory()()
try:
body = AgentAssetRiskRuleGenerateRequest.model_validate(payload)
RiskRuleGenerationJobService(db).complete_rule_asset_generation(
asset_id,
body,
actor=actor,
request_id=request_id,
)
finally:
db.close()
@router.get(
"",
response_model=list[AgentAssetListItem],
@@ -284,6 +305,7 @@ def save_agent_asset_rule_json(
)
def generate_agent_asset_risk_rule(
payload: AgentAssetRiskRuleGenerateRequest,
background_tasks: BackgroundTasks,
current_user: RuleEditorUser,
db: DbSession,
x_actor: ActorHeader = None,
@@ -291,11 +313,18 @@ def generate_agent_asset_risk_rule(
) -> AgentAssetRead:
try:
actor = (x_actor or current_user.name or "system").strip() or "system"
asset_id = RiskRuleGenerationService(db).generate_rule_asset(
asset_id = RiskRuleGenerationJobService(db).enqueue_rule_asset_generation(
payload,
actor=actor,
request_id=x_request_id,
)
background_tasks.add_task(
_complete_risk_rule_generation_task,
asset_id,
payload.model_dump(mode="json"),
actor,
x_request_id,
)
asset = AgentAssetService(db).get_asset(asset_id)
if asset is None:
raise LookupError("Asset not found")
@@ -736,6 +765,27 @@ def set_agent_asset_risk_rule_enabled(
_handle_asset_error(exc)
@router.post(
"/{asset_id}/risk-rule-level",
response_model=AgentAssetRead,
summary="风险规则风险等级已由评分模型接管",
description="风险规则等级和分数由自然语言规则评分模型生成,不再允许人工调整。",
)
def set_agent_asset_risk_rule_level(
asset_id: str,
payload: AgentAssetRiskRuleLevelUpdate,
current_user: RuleEditorUser,
db: DbSession,
x_actor: ActorHeader = None,
x_request_id: RequestIdHeader = None,
) -> AgentAssetRead:
try:
del asset_id, payload, current_user, db, x_actor, x_request_id
raise ValueError("风险等级和分数由评分模型自动计算,不能手动修改。")
except Exception as exc:
_handle_asset_error(exc)
@router.post(
"/{asset_id}/return",
response_model=AgentAssetRiskRuleLatestTestSummary,