This commit is contained in:
2026-09-11 16:17:24 +08:00
parent 80e83a6668
commit ec7f76fede
18 changed files with 263 additions and 31 deletions
@@ -8,7 +8,16 @@ test('loads real dashboard data allowed by the current permissions', () => {
assert.match(source, /auth\.hasPermission\('company:profile:view'\).*tenant\.loadCompanyContext\(\)/)
assert.match(source, /auth\.hasPermission\('company:member:list'\).*tenant\.loadMembers\(\)/)
assert.match(source, /auth\.hasPermission\('order:first-leg:list'\).*orders\.load\(\)/)
assert.match(source, /onMounted\(\(\) => void loadDashboardData\(\)\)/)
assert.match(source, /onMounted\(async \(\) => \{\s*await loadDashboardData\(\)\s*showQualificationReminderOnce\(\)\s*\}\)/)
})
test('prompts once per session for incomplete company qualification and opens the upload dialog', () => {
assert.match(source, /\['PROFILE_REQUIRED', 'REJECTED'\]\.includes\(tenant\.company\.auditStatus\)/)
assert.match(source, /sessionStorage\.getItem\(reminderKey\)/)
assert.match(source, /sessionStorage\.setItem\(reminderKey, 'shown'\)/)
assert.match(source, /title="完善企业认证资料"/)
assert.match(source, /立即上传认证资料/)
assert.match(source, /router\.push\(\{ path: '\/company\/profile', query: \{ qualification: 'upload' \} \}\)/)
})
test('isolates recoverable dashboard failures without hiding successful sections', () => {
+25 -1
View File
@@ -22,6 +22,7 @@ const orders = useFirstLegOrdersStore()
const tenant = useTenantAdministrationStore()
const auth = useAuthStore()
const loading = ref(false)
const qualificationReminderOpen = ref(false)
type DashboardDataSource = 'company' | 'members' | 'orders'
const loadErrors = ref<Partial<Record<DashboardDataSource, string>>>({})
const dataSourceLabels: Record<DashboardDataSource, string> = {
@@ -116,6 +117,20 @@ async function loadDashboardData() {
}
}
function showQualificationReminderOnce() {
if (companyUnavailable.value || !auth.hasPermission('company:qualification:upload')) return
if (!['PROFILE_REQUIRED', 'REJECTED'].includes(tenant.company.auditStatus)) return
const reminderKey = `client-qualification-reminder:${auth.user?.id ?? 'current'}`
if (sessionStorage.getItem(reminderKey)) return
sessionStorage.setItem(reminderKey, 'shown')
qualificationReminderOpen.value = true
}
async function openQualificationUpload() {
qualificationReminderOpen.value = false
await router.push({ path: '/company/profile', query: { qualification: 'upload' } })
}
function openBusinessOrder(business: typeof businessCards[number]) {
if (auth.hasPermission(business.permission)) {
void router.push(business.route)
@@ -133,11 +148,18 @@ function showSupportMessage(type: 'service' | 'faq' | 'quote') {
ElMessage.info(messages[type])
}
onMounted(() => void loadDashboardData())
onMounted(async () => {
await loadDashboardData()
showQualificationReminderOnce()
})
</script>
<template>
<div v-loading="loading" class="client-dashboard" :aria-busy="loading">
<el-dialog v-model="qualificationReminderOpen" title="完善企业认证资料" width="min(520px, 92vw)" append-to-body>
<p class="qualification-reminder-copy">请先上传营业执照和统一社会信用代码并提交审核;法人身份证及其他资质可选填。审核通过后即可提交头程订单。</p>
<template #footer><el-button @click="qualificationReminderOpen = false">稍后处理</el-button><el-button type="primary" @click="openQualificationUpload">立即上传认证资料</el-button></template>
</el-dialog>
<div v-if="loadErrorItems.length" class="dashboard-load-error" role="alert">
<AlertTriangle :size="20" aria-hidden="true" />
<div>
@@ -237,6 +259,8 @@ onMounted(() => void loadDashboardData())
margin-bottom: 20px;
}
.qualification-reminder-copy { margin: 0; color: #475467; font-size: 14px; line-height: 1.75; }
.dashboard-load-error ul {
display: grid;
gap: 3px;