feat(dashboard): polish risk and digital employee boards
This commit is contained in:
@@ -89,3 +89,16 @@ test('digital employee dashboard renders enterprise dashboard panels with chart
|
||||
assert.match(dailyChartComponent, /name: '业务产出'/)
|
||||
assert.doesNotMatch(dashboardComponent, /hermes/i)
|
||||
})
|
||||
|
||||
test('digital employee dashboard uses filled card layout for charts and rows', () => {
|
||||
assert.match(dashboardComponent, /digital-chart-fill digital-trend-fill/)
|
||||
assert.match(dashboardComponent, /digital-chart-fill digital-donut-fill/)
|
||||
assert.match(dashboardComponent, /digital-chart-fill digital-bar-fill/)
|
||||
assert.match(dashboardComponent, /digital-output-grid digital-card-fill/)
|
||||
assert.match(dashboardComponent, /grid-auto-rows: minmax\(300px, auto\)/)
|
||||
assert.match(dashboardComponent, /\.digital-work-trend-panel \{\s*grid-column: span 7/s)
|
||||
assert.match(dashboardComponent, /\.digital-work-day-panel \{\s*grid-column: span 5/s)
|
||||
assert.match(dashboardComponent, /\.digital-recent-panel \{\s*grid-column: span 12/s)
|
||||
assert.match(dailyChartComponent, /height: 100%/)
|
||||
assert.match(dailyChartComponent, /min-height: 280px/)
|
||||
})
|
||||
|
||||
@@ -4,6 +4,13 @@ import test from 'node:test'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
import { normalizeRiskObservationDashboard } from '../src/services/riskObservations.js'
|
||||
import {
|
||||
formatExpenseTypeLabel,
|
||||
formatRiskDimensionLabel,
|
||||
formatRiskObservationTitle,
|
||||
formatRiskSignalLabel,
|
||||
formatRiskSourceLabel
|
||||
} from '../src/utils/riskLabels.js'
|
||||
|
||||
const dashboardComponent = readFileSync(
|
||||
fileURLToPath(new URL('../src/components/dashboard/RiskObservationDashboard.vue', import.meta.url)),
|
||||
@@ -17,6 +24,10 @@ const overviewTemplate = readFileSync(
|
||||
fileURLToPath(new URL('../src/views/OverviewView.vue', import.meta.url)),
|
||||
'utf8'
|
||||
)
|
||||
const riskLabels = readFileSync(
|
||||
fileURLToPath(new URL('../src/utils/riskLabels.js', import.meta.url)),
|
||||
'utf8'
|
||||
)
|
||||
|
||||
test('risk dashboard normalizes amount, distributions, and ranking fields', () => {
|
||||
const dashboard = normalizeRiskObservationDashboard({
|
||||
@@ -68,6 +79,35 @@ test('risk dashboard renders overview amount and multi-dimension panels', () =>
|
||||
assert.match(dashboardComponent, /topRules/)
|
||||
})
|
||||
|
||||
test('risk dashboard localizes backend metric keys before rendering', () => {
|
||||
assert.equal(formatRiskSignalLabel('duplicate_invoice'), '重复发票')
|
||||
assert.equal(formatRiskSignalLabel('policy.duplicate_invoice'), '重复发票')
|
||||
assert.equal(formatExpenseTypeLabel('travel'), '差旅费')
|
||||
assert.equal(formatRiskSourceLabel('rule_center'), '规则中心')
|
||||
assert.equal(formatRiskSourceLabel('financial_risk_graph'), '风险图谱')
|
||||
assert.equal(formatRiskDimensionLabel('policy.duplicate_invoice', 'rule'), '重复发票规则')
|
||||
assert.equal(
|
||||
formatRiskObservationTitle({ title: 'policy.duplicate_invoice', riskSignal: 'duplicate_invoice' }),
|
||||
'重复发票'
|
||||
)
|
||||
assert.match(riskLabels, /travel: '差旅费'/)
|
||||
assert.match(riskLabels, /rule_center: '规则中心'/)
|
||||
assert.match(overviewViewModel, /formatRiskSignalLabel/)
|
||||
assert.match(overviewViewModel, /formatRiskSourceLabel/)
|
||||
assert.match(dashboardComponent, /formatRiskObservationTitle/)
|
||||
assert.doesNotMatch(dashboardComponent, /text\.replace\(\s*\/_\/g/)
|
||||
})
|
||||
|
||||
test('risk dashboard renders exception ranking as chart-led visual summary', () => {
|
||||
assert.match(dashboardComponent, /rankingChartItems/)
|
||||
assert.match(dashboardComponent, /rankingDetailGroups/)
|
||||
assert.match(dashboardComponent, /risk-ranking-visual/)
|
||||
assert.match(dashboardComponent, /risk-ranking-detail-grid/)
|
||||
assert.match(dashboardComponent, /:items="rankingChartItems"/)
|
||||
assert.match(dashboardComponent, /value-suffix="项"/)
|
||||
assert.doesNotMatch(dashboardComponent, /risk-ranking-grid/)
|
||||
})
|
||||
|
||||
test('risk dashboard wires window filter to trend, ranking, and cards data source', () => {
|
||||
assert.match(overviewViewModel, /const activeRiskWindowDays = ref\(30\)/)
|
||||
assert.match(overviewViewModel, /windowDays: activeRiskWindowDays\.value/)
|
||||
@@ -84,6 +124,8 @@ test('risk dashboard wires window filter to trend, ranking, and cards data sourc
|
||||
})
|
||||
|
||||
test('risk dashboard shows loading overlay and realtime refresh status', () => {
|
||||
assert.match(overviewTemplate, /dashboard-loading-overlay/)
|
||||
assert.match(overviewTemplate, /activeDashboardLoadingText/)
|
||||
assert.match(dashboardComponent, /risk-dashboard-loading-overlay/)
|
||||
assert.match(dashboardComponent, /loadingLabel/)
|
||||
assert.match(dashboardComponent, /lastUpdatedLabel/)
|
||||
@@ -95,3 +137,16 @@ test('risk dashboard shows loading overlay and realtime refresh status', () => {
|
||||
assert.match(overviewViewModel, /riskDashboardRequestSeq/)
|
||||
assert.match(overviewTemplate, /:last-updated-at="riskDashboardLastUpdatedAt"/)
|
||||
})
|
||||
|
||||
test('overview dashboards are loaded on demand instead of all at once', () => {
|
||||
assert.match(overviewViewModel, /const activeDashboardKey = computed/)
|
||||
assert.match(overviewViewModel, /const loadActiveDashboard = \(\) =>/)
|
||||
assert.doesNotMatch(
|
||||
overviewViewModel,
|
||||
/onMounted\(\(\) => \{\s*void loadFinanceDashboard\(\)\s*void loadSystemDashboard\(\)\s*void loadRiskDashboard\(\)\s*void loadDigitalEmployeeDashboard\(\)/
|
||||
)
|
||||
assert.match(overviewViewModel, /watch\(activeDashboardKey/)
|
||||
assert.match(overviewViewModel, /activeDashboardKey\.value === 'risk'/)
|
||||
assert.match(overviewViewModel, /startRiskDashboardRealtimeRefresh\(\)/)
|
||||
assert.match(overviewViewModel, /stopRiskDashboardRealtimeRefresh\(\)/)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user