feat: 增强风险规则生成引擎与预算中心页面
后端拆分风险规则生成为解释器、语义分析、本体对齐等子模块, 优化模板执行和流程图生成,完善员工种子数据和导入逻辑,增强 报销单权限策略和草稿持久化,前端新增预算中心视图和趋势图 组件,重构审计页面和风险规则测试对话框交互,完善文档中心 和报销创建页面细节,补充单元测试覆盖。
This commit is contained in:
@@ -264,6 +264,7 @@ import { mapExpenseClaimToRequest } from '../composables/useRequests.js'
|
||||
import { fetchApprovalExpenseClaims, fetchArchivedExpenseClaims } from '../services/reimbursements.js'
|
||||
import { countNewDocuments, isNewDocument, markDocumentViewed, readDocumentScope, readViewedDocumentKeys, writeDocumentScope } from '../utils/documentCenterNewState.js'
|
||||
import { extractDateText, formatDocumentListTime, resolveDocumentSortTime, resolveDocumentStayTimeDisplay } from '../utils/documentCenterTime.js'
|
||||
import { excludeArchivedDocumentRows, isArchivedDocumentRow } from '../utils/documentCenterRows.js'
|
||||
import { normalizeRequestForUi } from '../utils/requestViewModel.js'
|
||||
|
||||
const DOCUMENT_TYPE_ALL = 'all'
|
||||
@@ -388,9 +389,11 @@ const dateRangeLabel = computed(() => {
|
||||
})
|
||||
|
||||
const ownedRows = computed(() =>
|
||||
props.filteredRequests
|
||||
.map((item) => buildDocumentRow(item, { source: 'owned' }))
|
||||
.filter(Boolean)
|
||||
excludeArchivedDocumentRows(
|
||||
props.filteredRequests
|
||||
.map((item) => buildDocumentRow(item, { source: 'owned' }))
|
||||
.filter(Boolean)
|
||||
)
|
||||
)
|
||||
|
||||
const nonArchivedRows = computed(() => mergeDocumentRows([...ownedRows.value, ...approvalRows.value]))
|
||||
@@ -518,7 +521,7 @@ const emptyState = computed(() => {
|
||||
actionIcon: '',
|
||||
tone: 'emerald',
|
||||
artLabel: 'APPLY',
|
||||
tips: ['旧报销中心仍保留', '申请批准后可继续发起报销']
|
||||
tips: ['申请、报销、审批与归档统一在此查看', '申请批准后可继续发起报销']
|
||||
}
|
||||
}
|
||||
|
||||
@@ -533,10 +536,17 @@ const emptyState = computed(() => {
|
||||
actionIcon: '',
|
||||
tone: 'emerald',
|
||||
artLabel: filtered ? 'FILTER' : 'DOCS',
|
||||
tips: ['单据中心已接入当前报销单据', '归档视角会同步归档中心数据']
|
||||
tips: ['单据中心已接入当前报销单据', '归档视角会同步已归档数据']
|
||||
}
|
||||
})
|
||||
|
||||
function resolveArchivedDocumentNode(normalized, documentTypeCode) {
|
||||
if (documentTypeCode === DOCUMENT_TYPE_APPLICATION) {
|
||||
return '申请归档'
|
||||
}
|
||||
return normalized.node || normalized.workflowNode || '财务归档'
|
||||
}
|
||||
|
||||
function buildDocumentRow(request, options = {}) {
|
||||
const normalized = normalizeRequestForUi(request)
|
||||
if (!normalized) {
|
||||
@@ -563,7 +573,7 @@ function buildDocumentRow(request, options = {}) {
|
||||
documentTypeLabel,
|
||||
claimId,
|
||||
documentNo,
|
||||
node: archived ? '财务归档' : (normalized.node || normalized.workflowNode || '待提交'),
|
||||
node: archived ? resolveArchivedDocumentNode(normalized, documentTypeCode) : (normalized.node || normalized.workflowNode || '待提交'),
|
||||
statusGroup,
|
||||
statusLabel,
|
||||
statusTone: archived ? 'archived' : resolveStatusTone(normalized, statusGroup),
|
||||
@@ -598,6 +608,10 @@ function resolveStatusTone(row, statusGroup) {
|
||||
}
|
||||
|
||||
function matchesStatusTab(row, tab) {
|
||||
if (activeScopeTab.value !== DOCUMENT_SCOPE_ARCHIVE && isArchivedDocumentRow(row)) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (tab === '全部') return true
|
||||
if (tab === '草稿') return row.statusGroup === 'draft'
|
||||
if (tab === '待提交') return row.statusGroup === 'pending_submit'
|
||||
@@ -730,12 +744,14 @@ async function loadSupportingRows() {
|
||||
])
|
||||
|
||||
if (approvalResult.status === 'fulfilled') {
|
||||
approvalRows.value = Array.isArray(approvalResult.value)
|
||||
? approvalResult.value
|
||||
.map((item) => mapExpenseClaimToRequest(item))
|
||||
.map((item) => buildDocumentRow(item, { source: 'approval' }))
|
||||
.filter(Boolean)
|
||||
: []
|
||||
approvalRows.value = excludeArchivedDocumentRows(
|
||||
Array.isArray(approvalResult.value)
|
||||
? approvalResult.value
|
||||
.map((item) => mapExpenseClaimToRequest(item))
|
||||
.map((item) => buildDocumentRow(item, { source: 'approval' }))
|
||||
.filter(Boolean)
|
||||
: []
|
||||
)
|
||||
} else {
|
||||
approvalRows.value = []
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user