diff --git a/web-admin/scripts/quota-mobile-state.test.ts b/web-admin/scripts/quota-mobile-state.test.ts index 2851ed2b6..79daf5b37 100644 --- a/web-admin/scripts/quota-mobile-state.test.ts +++ b/web-admin/scripts/quota-mobile-state.test.ts @@ -350,3 +350,28 @@ test('plan expansion loads on demand, preserves total during refresh and ignores assert.deepEqual(Object.keys(s.details), []) h.stop() }) + +for (const status of [403, 404, 500, undefined]) + test(`plan expansion reports ${status || 'network'} failure without showing partial usage`, async () => { + const h = pageHarness('quota', { mobile: false }), + s = h.state + const pending = s.loadDetail('plan') + h.gets[0].reject(status ? { response: { status } } : new Error('network')) + await pending + assert.equal( + s.details.plan.error, + [403, 404].includes(status as number) + ? '计划或证件不可读取,无法展示完整用证详情' + : '段次用证加载失败,请重试' + ) + assert.equal(s.details.plan.data, undefined) + assert.equal(s.details.plan.loading, false) + if (status === 500) { + const retry = s.loadDetail('plan') + h.gets[1].resolve({ planId: 'plan', sourceOptions: [], usages: [] }) + await retry + assert.equal(s.details.plan.error, undefined) + assert.equal(s.details.plan.data.planId, 'plan') + } + h.stop() + }) diff --git a/web-admin/src/views/pl/plan-quota/index.vue b/web-admin/src/views/pl/plan-quota/index.vue index 9f0adc7e7..51761d6c1 100644 --- a/web-admin/src/views/pl/plan-quota/index.vue +++ b/web-admin/src/views/pl/plan-quota/index.vue @@ -78,7 +78,7 @@ > ([]) const dialog = ref>() const expandedIds = ref([]) - const details = reactive>( + const details = reactive>( {} ) function clearDetails() { @@ -230,15 +230,21 @@ } async function loadDetail(id: string) { const current = epoch - const state = reactive<{ loading: boolean; data?: PlanQuota; error?: boolean }>({ + const state = reactive<{ loading: boolean; data?: PlanQuota; error?: string }>({ loading: true }) details[id] = state try { const value = await planQuotaApi.get(id) if (current === epoch && details[id] === state) state.data = value - } catch { - if (current === epoch && details[id] === state) state.error = true + } catch (error) { + if (current === epoch && details[id] === state) { + const status = (error as { response?: { status?: number } })?.response?.status + state.error = + status === 403 || status === 404 + ? '计划或证件不可读取,无法展示完整用证详情' + : '段次用证加载失败,请重试' + } } finally { if (current === epoch && details[id] === state) state.loading = false }