feat: 新增风险图谱算法与系统仪表盘及操作反馈体系

后端新增风险图谱算法模块、风险观察与反馈服务、规则 DSL
校验器和可解释性引擎,完善系统仪表盘和财务仪表盘统计,
优化 agent 运行和编排执行链路,清理旧开发文档,前端新增
系统趋势、负载热力图等多种仪表盘图表组件,完善操作反馈
对话框和工作台日期选择器,优化报销创建和审批详情交互,
补充单元测试覆盖。
This commit is contained in:
caoxiaozhu
2026-05-30 15:46:51 +08:00
parent 4c59941ec6
commit 7989f3a159
314 changed files with 30073 additions and 20626 deletions

View File

@@ -4,11 +4,10 @@ import { checkBackendHealth } from '../composables/useBackendHealth.js'
import { appViews } from '../composables/useNavigation.js'
import { useSystemState } from '../composables/useSystemState.js'
import { canAccessAppView } from '../utils/accessControl.js'
const AppShellRouteView = () => import('../views/AppShellRouteView.vue')
const BackendUnavailableRouteView = () => import('../views/BackendUnavailableRouteView.vue')
const LoginRouteView = () => import('../views/LoginRouteView.vue')
const SetupRouteView = () => import('../views/SetupRouteView.vue')
import AppShellRouteView from '../views/AppShellRouteView.vue'
import BackendUnavailableRouteView from '../views/BackendUnavailableRouteView.vue'
import LoginRouteView from '../views/LoginRouteView.vue'
import SetupRouteView from '../views/SetupRouteView.vue'
const appChildRoutes = appViews
.filter((view) => view !== 'documents')
@@ -124,6 +123,19 @@ const router = createRouter({
]
})
function isAuthenticatedAppNavigation(to, from) {
return Boolean(to.meta.requiresAuth && from.meta.requiresAuth && from.name !== 'backend-unavailable')
}
function scheduleBackgroundBackendHealthCheck() {
void checkBackendHealth({ allowStaleOnTimeout: true }).then((ok) => {
const currentRoute = router.currentRoute.value
if (!ok && currentRoute.meta.requiresAuth && currentRoute.name !== 'backend-unavailable') {
void router.replace({ name: 'backend-unavailable' })
}
})
}
router.beforeEach((to, from) => {
if (to.name === 'app-documents' && from.name !== 'app-document-detail') {
if (typeof window !== 'undefined' && window.localStorage) {
@@ -147,6 +159,15 @@ router.beforeEach((to, from) => {
}
if (authActive && to.meta.requiresAuth) {
if (typeof to.meta.appView === 'string' && !canAccessAppView(currentUser.value, to.meta.appView)) {
return resolveEntryRoute()
}
if (isAuthenticatedAppNavigation(to, from)) {
scheduleBackgroundBackendHealthCheck()
return true
}
return checkBackendHealth({ allowStaleOnTimeout: true }).then((ok) => {
if (!ok && to.name !== 'backend-unavailable') {
return { name: 'backend-unavailable' }
@@ -156,10 +177,6 @@ router.beforeEach((to, from) => {
return resolveEntryRoute()
}
if (ok && typeof to.meta.appView === 'string' && !canAccessAppView(currentUser.value, to.meta.appView)) {
return resolveEntryRoute()
}
return true
})
}