feat(web): update TopBar component and useAppShell composable

This commit is contained in:
caoxiaozhu
2026-05-14 07:10:31 +00:00
parent 64ea1bc5fd
commit 476d5fdf93
3 changed files with 160 additions and 19 deletions

View File

@@ -6,6 +6,79 @@ import { useRequests } from './useRequests.js'
import { useToast } from './useToast.js'
import { normalizeRequestForUi } from '../utils/requestViewModel.js'
function isPlaceholderValue(value) {
const text = String(value || '').trim()
if (!text) {
return true
}
return ['待补充', '暂无', '无', '未知', '处理中'].includes(text.replace(/\s+/g, ''))
}
function hasMissingAttachment(request) {
const expenseItems = Array.isArray(request?.expenseItems) ? request.expenseItems : []
if (expenseItems.length) {
return expenseItems.some((item) => !String(item?.invoiceId || item?.invoice_id || '').trim())
}
const attachmentSummary = String(request?.attachmentSummary || '').trim()
const secondaryStatusValue = String(request?.secondaryStatusValue || '').trim()
return /待|缺|未/.test(attachmentSummary) || /待|缺|未/.test(secondaryStatusValue)
}
function hasPendingInfo(request) {
if (!request) {
return false
}
if (request.approvalKey === 'draft' || request.approvalKey === 'supplement') {
return true
}
if (!Number.isFinite(Number(request.amountValue)) || Number(request.amountValue) <= 0) {
return true
}
return [
request.profileDepartment,
request.profilePosition,
request.profileGrade,
request.profileManager,
request.reason,
request.occurredDisplay
].some(isPlaceholderValue)
}
function resolveDetailAlertTone(request) {
if (request?.approvalKey === 'completed') return 'success'
if (request?.approvalKey === 'rejected') return 'danger'
return 'warning'
}
function buildDetailAlerts(request) {
if (!request) {
return []
}
const alerts = []
const nodeLabel = String(request.node || request.approval || '').trim()
if (nodeLabel) {
alerts.push({ label: nodeLabel, tone: resolveDetailAlertTone(request) })
}
if (hasMissingAttachment(request)) {
alerts.push({ label: '缺少票据', tone: 'warning' })
}
if (hasPendingInfo(request)) {
alerts.push({ label: '待补信息', tone: 'warning' })
}
return alerts.filter((item, index, list) => list.findIndex((entry) => entry.label === item.label) === index).slice(0, 3)
}
export function useAppShell() {
const route = useRoute()
const router = useRouter()
@@ -46,6 +119,7 @@ export function useAppShell() {
})
const detailMode = computed(() => route.name === 'app-request-detail')
const detailAlerts = computed(() => (detailMode.value ? buildDetailAlerts(selectedRequest.value) : []))
const topBarView = computed(() => {
if (detailMode.value) {
@@ -182,6 +256,7 @@ export function useAppShell() {
smartEntryContext,
smartEntryOpen,
smartEntrySessionId,
detailAlerts,
toast,
topBarView
}