feat: 新增预算费控模型与报销审批流引擎

后端新增预算费控服务和报销单审批流模块,引入申请人费用画像
算法,优化知识库 RAG 运行时和同步逻辑,完善报销单工作流常
量和明细同步,更新差旅报销规则电子表格,前端新增预算分析
组件和数字员工模型,完善审批对话框和洞察面板交互,优化侧
边栏和顶栏样式,补充单元测试。
This commit is contained in:
caoxiaozhu
2026-05-27 17:31:27 +08:00
parent cbb98f4469
commit d4d5d40569
75 changed files with 5393 additions and 686 deletions

View File

@@ -14,6 +14,7 @@ from app.core import admin_secret
from app.core import secret_box
from app.core.secret_box import encrypt_secret
from app.db.base import Base
from app.models.hermes_config import HermesTaskConfig, HermesTaskExecutionLog
from app.models.system_model_setting import SystemModelSetting
from app.models.system_setting import SystemSetting
from app.models.system_setting_secret import SystemSettingSecret
@@ -27,9 +28,11 @@ def build_session(db_file: Path) -> Session:
f"sqlite+pysqlite:///{db_file.as_posix()}",
connect_args={"check_same_thread": False},
)
SystemSetting.__table__.create(bind=engine)
SystemSettingSecret.__table__.create(bind=engine)
SystemModelSetting.__table__.create(bind=engine)
SystemSetting.__table__.create(bind=engine)
SystemSettingSecret.__table__.create(bind=engine)
SystemModelSetting.__table__.create(bind=engine)
HermesTaskConfig.__table__.create(bind=engine)
HermesTaskExecutionLog.__table__.create(bind=engine)
session_factory = sessionmaker(bind=engine, autoflush=False, autocommit=False)
return session_factory()
@@ -45,9 +48,12 @@ def test_settings_service_persists_non_secret_and_secret_fields(monkeypatch) ->
monkeypatch.setenv("HERMES_HOME", str(temp_dir / ".hermes"))
with build_session(temp_dir / "settings.db") as db:
service = SettingsService(db)
initial_snapshot = service.get_settings_snapshot()
payload = initial_snapshot.model_dump()
service = SettingsService(db)
initial_snapshot = service.get_settings_snapshot()
assert initial_snapshot.llmForm.mainModel == "codex-mini-latest"
assert initial_snapshot.llmForm.mainEndpoint == "https://api.openai.com/v1"
assert initial_snapshot.llmForm.mainApiKey == ""
payload = initial_snapshot.model_dump()
payload["companyForm"]["companyName"] = "YGSOFT"
payload["companyForm"]["displayName"] = "云广软件"