feat: 新增风险图谱算法与系统仪表盘及操作反馈体系
后端新增风险图谱算法模块、风险观察与反馈服务、规则 DSL 校验器和可解释性引擎,完善系统仪表盘和财务仪表盘统计, 优化 agent 运行和编排执行链路,清理旧开发文档,前端新增 系统趋势、负载热力图等多种仪表盘图表组件,完善操作反馈 对话框和工作台日期选择器,优化报销创建和审批详情交互, 补充单元测试覆盖。
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<header class="topbar" :class="{ 'chat-mode': isChat }">
|
||||
<div class="title-group">
|
||||
<div class="eyebrow">{{ isChat ? 'Smart Finance Q&A' : 'Smart Expense Operations' }}</div>
|
||||
<div class="eyebrow">{{ eyebrowLabel }}</div>
|
||||
<h1>{{ currentView.title }}</h1>
|
||||
<p>{{ currentView.desc }}</p>
|
||||
</div>
|
||||
@@ -40,10 +40,10 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="custom-range-wrap">
|
||||
<button
|
||||
class="custom-range-btn"
|
||||
type="button"
|
||||
<div class="custom-range-wrap">
|
||||
<button
|
||||
class="custom-range-btn"
|
||||
type="button"
|
||||
:class="{ active: isCustomRange }"
|
||||
:aria-expanded="calendarOpen"
|
||||
aria-haspopup="dialog"
|
||||
@@ -77,10 +77,20 @@
|
||||
<button class="apply-btn" type="button" :disabled="!canApplyCustomRange" @click="applyCustomRange">
|
||||
应用
|
||||
</button>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dashboard-switch-wrap">
|
||||
<EnterpriseSelect
|
||||
v-model="overviewDashboardValue"
|
||||
class="dashboard-switch-select"
|
||||
:options="overviewDashboardOptions"
|
||||
aria-label="选择看板类型"
|
||||
size="default"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-else-if="isRequestDetail">
|
||||
@@ -202,8 +212,10 @@
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, ref, watch } from 'vue'
|
||||
<script setup>
|
||||
import { computed, ref, watch } from 'vue'
|
||||
|
||||
import EnterpriseSelect from '../shared/EnterpriseSelect.vue'
|
||||
|
||||
const props = defineProps({
|
||||
currentView: { type: Object, required: true },
|
||||
@@ -247,31 +259,39 @@ const props = defineProps({
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
customRange: {
|
||||
type: Object,
|
||||
default: () => ({ start: '2024-07-06', end: '2024-07-12' })
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits([
|
||||
'update:search',
|
||||
'update:activeRange',
|
||||
'update:customRange',
|
||||
'batchApprove',
|
||||
'openChat',
|
||||
'newApplication'
|
||||
])
|
||||
|
||||
const isChat = computed(() => props.activeView === 'chat')
|
||||
const isOverview = computed(() => props.activeView === 'overview')
|
||||
const isWorkbench = computed(() => props.activeView === 'workbench')
|
||||
const isRequestDetail = computed(() => ['requests', 'documents', 'audit', 'digitalEmployees'].includes(props.activeView) && props.detailMode)
|
||||
customRange: {
|
||||
type: Object,
|
||||
default: () => ({ start: '2024-07-06', end: '2024-07-12' })
|
||||
},
|
||||
overviewDashboard: {
|
||||
type: String,
|
||||
default: 'finance'
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits([
|
||||
'update:search',
|
||||
'update:activeRange',
|
||||
'update:customRange',
|
||||
'update:overviewDashboard',
|
||||
'batchApprove',
|
||||
'openChat',
|
||||
'newApplication'
|
||||
])
|
||||
const isChat = computed(() => props.activeView === 'chat')
|
||||
const isOverview = computed(() => props.activeView === 'overview')
|
||||
const isWorkbench = computed(() => props.activeView === 'workbench')
|
||||
const isRequestDetail = computed(() => ['requests', 'documents', 'audit', 'digitalEmployees', 'receiptFolder'].includes(props.activeView) && props.detailMode)
|
||||
const isDocuments = computed(() => props.activeView === 'documents' && !props.detailMode)
|
||||
const isRequests = computed(() => props.activeView === 'requests')
|
||||
const isDigitalEmployees = computed(() => props.activeView === 'digitalEmployees')
|
||||
const isApproval = computed(() => props.activeView === 'approval')
|
||||
const isPolicies = computed(() => props.activeView === 'policies')
|
||||
const isEmployees = computed(() => props.activeView === 'employees')
|
||||
const isPolicies = computed(() => props.activeView === 'policies')
|
||||
const isEmployees = computed(() => props.activeView === 'employees')
|
||||
const eyebrowLabel = computed(() => (
|
||||
String(props.currentView?.eyebrow || '').trim()
|
||||
|| (isChat.value ? 'Smart Finance Q&A' : 'Smart Expense Operations')
|
||||
))
|
||||
const displayCompanyName = computed(() => String(props.companyName || '远光软件股份有限公司').trim() || '远光软件股份有限公司')
|
||||
const topbarNotificationCount = computed(() => {
|
||||
const summary = props.documentSummary ?? {}
|
||||
@@ -421,11 +441,20 @@ const employeeKpis = computed(() => {
|
||||
}
|
||||
]
|
||||
})
|
||||
const calendarOpen = ref(false)
|
||||
const draftStart = ref(props.customRange.start)
|
||||
const draftEnd = ref(props.customRange.end)
|
||||
|
||||
const rangeOptions = computed(() =>
|
||||
const calendarOpen = ref(false)
|
||||
const draftStart = ref(props.customRange.start)
|
||||
const draftEnd = ref(props.customRange.end)
|
||||
const overviewDashboardOptions = [
|
||||
{ label: '财务看板', value: 'finance' },
|
||||
{ label: '风险看板', value: 'risk' },
|
||||
{ label: '系统看板', value: 'system' }
|
||||
]
|
||||
const overviewDashboardValue = computed({
|
||||
get: () => props.overviewDashboard,
|
||||
set: (value) => emit('update:overviewDashboard', value)
|
||||
})
|
||||
|
||||
const rangeOptions = computed(() =>
|
||||
props.ranges.map((range, index) => ({
|
||||
value: range,
|
||||
label: String(range)
|
||||
|
||||
Reference in New Issue
Block a user