feat: 增强风险规则生成引擎与预算中心页面
后端拆分风险规则生成为解释器、语义分析、本体对齐等子模块, 优化模板执行和流程图生成,完善员工种子数据和导入逻辑,增强 报销单权限策略和草稿持久化,前端新增预算中心视图和趋势图 组件,重构审计页面和风险规则测试对话框交互,完善文档中心 和报销创建页面细节,补充单元测试覆盖。
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
>
|
||||
<span class="nav-icon" v-html="item.icon"></span>
|
||||
<span class="nav-label">{{ item.displayLabel }}</span>
|
||||
<span v-if="item.hasNewMessage" class="nav-unread-dot" aria-hidden="true"></span>
|
||||
<span v-if="item.badge" class="nav-badge">{{ item.badge }}</span>
|
||||
</button>
|
||||
</nav>
|
||||
@@ -83,7 +84,7 @@
|
||||
<script setup>
|
||||
import { computed, onBeforeUnmount, onMounted, reactive, ref, watch } from 'vue'
|
||||
|
||||
import { useApprovalInbox } from '../../composables/useApprovalInbox.js'
|
||||
import { useDocumentCenterInbox } from '../../composables/useDocumentCenterInbox.js'
|
||||
|
||||
const props = defineProps({
|
||||
navItems: { type: Array, required: true },
|
||||
@@ -113,19 +114,17 @@ const props = defineProps({
|
||||
const emit = defineEmits(['navigate', 'openChat', 'logout', 'toggle-collapse'])
|
||||
|
||||
const {
|
||||
badgeLabel: approvalBadgeLabel,
|
||||
refreshApprovalInbox,
|
||||
startApprovalInboxPolling,
|
||||
stopApprovalInboxPolling
|
||||
} = useApprovalInbox()
|
||||
hasUnread: documentInboxHasUnread,
|
||||
refreshDocumentInbox,
|
||||
startDocumentInboxPolling,
|
||||
stopDocumentInboxPolling
|
||||
} = useDocumentCenterInbox()
|
||||
|
||||
const sidebarMeta = {
|
||||
overview: { label: '财务总览' },
|
||||
workbench: { label: '个人工作台' },
|
||||
documents: { label: '单据中心' },
|
||||
requests: { label: '报销中心' },
|
||||
approval: { label: '审批中心' },
|
||||
archive: { label: '归档中心' },
|
||||
budget: { label: '预算中心' },
|
||||
policies: { label: '知识管理' },
|
||||
audit: { label: '任务规则中心' },
|
||||
logs: { label: '日志管理' },
|
||||
@@ -137,13 +136,14 @@ const decoratedNavItems = computed(() =>
|
||||
props.navItems.map((item) => ({
|
||||
...item,
|
||||
displayLabel: sidebarMeta[item.id]?.label ?? item.label,
|
||||
badge: item.id === 'approval' ? approvalBadgeLabel.value : sidebarMeta[item.id]?.badge
|
||||
hasNewMessage: item.id === 'documents' ? documentInboxHasUnread.value : false,
|
||||
badge: sidebarMeta[item.id]?.badge
|
||||
}))
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
void refreshApprovalInbox()
|
||||
startApprovalInboxPolling()
|
||||
void refreshDocumentInbox()
|
||||
startDocumentInboxPolling()
|
||||
})
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ watch(
|
||||
)
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
stopApprovalInboxPolling()
|
||||
stopDocumentInboxPolling()
|
||||
closeCollapsedUserMenuNow()
|
||||
})
|
||||
</script>
|
||||
@@ -463,6 +463,16 @@ onBeforeUnmount(() => {
|
||||
opacity var(--rail-fade-duration) var(--rail-motion-ease);
|
||||
}
|
||||
|
||||
.nav-unread-dot {
|
||||
flex: 0 0 auto;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border: 2px solid #fff;
|
||||
border-radius: 999px;
|
||||
background: #ef4444;
|
||||
box-shadow: 0 6px 14px rgba(239, 68, 68, 0.26);
|
||||
}
|
||||
|
||||
.rail-user {
|
||||
position: relative;
|
||||
min-width: 0;
|
||||
@@ -668,6 +678,14 @@ onBeforeUnmount(() => {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.rail-collapsed .nav-unread-dot {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 11px;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
}
|
||||
|
||||
.rail-collapsed {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user