function parseNumber(value) { const nextValue = Number(value) return Number.isFinite(nextValue) ? nextValue : 0 } function toDate(value) { if (!value) { return null } const nextDate = new Date(value) return Number.isNaN(nextDate.getTime()) ? null : nextDate } function isCurrentMonth(dateValue) { const date = toDate(dateValue) if (!date) { return false } const now = new Date() return date.getFullYear() === now.getFullYear() && date.getMonth() === now.getMonth() } function resolveClaimDate(request) { return request?.submittedAt || request?.createdAt || request?.occurredAt || '' } export function belongsToCurrentUser(request, currentUser) { const person = String(request?.person || request?.employeeName || '').trim() if (!person) { return false } const names = [ String(currentUser?.name || '').trim(), String(currentUser?.username || '').trim() ].filter(Boolean) return names.some((name) => name === person) } export function hasHighRiskFlag(request) { const riskFlags = Array.isArray(request?.riskFlags) ? request.riskFlags : [] if (riskFlags.some((item) => String(item?.severity || '').trim().toLowerCase() === 'high')) { return true } const summary = String(request?.riskSummary || '').trim() return summary.includes('高') } function formatCurrency(value) { return new Intl.NumberFormat('zh-CN', { style: 'currency', currency: 'CNY', minimumFractionDigits: 0, maximumFractionDigits: Number.isInteger(value) ? 0 : 2 }).format(parseNumber(value)) } export function buildWorkbenchSummary(requests, currentUser) { const ownedRequests = Array.isArray(requests) ? requests.filter((item) => belongsToCurrentUser(item, currentUser)) : [] const monthlyClaims = ownedRequests.filter((item) => isCurrentMonth(resolveClaimDate(item))) const monthlyCount = monthlyClaims.length const monthlyAmount = monthlyClaims.reduce((sum, item) => sum + parseNumber(item.amount), 0) const totalCount = ownedRequests.length const totalAmount = ownedRequests.reduce((sum, item) => sum + parseNumber(item.amount), 0) const inReviewCount = ownedRequests.filter((item) => item.approvalKey === 'in_progress').length const pendingPaymentCount = ownedRequests.filter((item) => { const status = String(item.status || item.approvalStatus || '').trim() return status.includes('待付款') || status.includes('待支付') }).length const completedCount = ownedRequests.filter((item) => item.approvalKey === 'completed').length const returnCount = ownedRequests.filter((item) => item.approvalKey === 'rejected').length const highRiskCount = monthlyClaims.filter((item) => hasHighRiskFlag(item)).length return { monthlyCount, monthlyAmount, monthlyAmountLabel: formatCurrency(monthlyAmount), totalCount, totalAmount, totalAmountLabel: formatCurrency(totalAmount), inReviewCount, pendingPaymentCount, completedCount, returnCount, highRiskCount } }