From b6b91297ae2fc9dc099d5148836d1619523001ff Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Thu, 10 Sep 2026 22:12:27 +0800 Subject: [PATCH] fix(customers): wait for billing defaults before loading --- .../CustomerBillingRulesPanel.test.ts | 18 +++++++ .../components/CustomerBillingRulesPanel.vue | 53 +++++++++++++++---- .../customers/pages/CustomerDetailView.vue | 2 +- src/modules/iam/api/platformIam.ts | 1 + 4 files changed, 62 insertions(+), 12 deletions(-) diff --git a/src/modules/customers/components/CustomerBillingRulesPanel.test.ts b/src/modules/customers/components/CustomerBillingRulesPanel.test.ts index 7a7472e3..62ab5d2d 100644 --- a/src/modules/customers/components/CustomerBillingRulesPanel.test.ts +++ b/src/modules/customers/components/CustomerBillingRulesPanel.test.ts @@ -93,6 +93,24 @@ describe('CustomerBillingRulesPanel', () => { expect(getCustomerDimensionConfig).not.toHaveBeenCalled() }) + it('does not request billing rules before customer defaults are ready', async () => { + mount(CustomerBillingRulesPanel, { + attachTo: document.body, + props: { + customerId: '8', + customerName: '柏悦物流', + dimensionInitializationStatus: 'PENDING', + }, + global: { plugins: [ElementPlus] }, + }) + await flushPromises() + + expect(document.body.textContent).toContain('客户计费规则正在初始化') + expect(document.body.textContent).not.toContain('箱规尺寸规则加载失败') + expect(getCustomerDimensionConfig).not.toHaveBeenCalled() + expect(listCustomerChargeRules).not.toHaveBeenCalled() + }) + it('submits all four rows in one update request', async () => { const wrapper = mount(CustomerBillingRulesPanel, { attachTo: document.body, props: { customerId: '8', customerName: '柏悦物流' }, global: { plugins: [ElementPlus] } }) await flushPromises() diff --git a/src/modules/customers/components/CustomerBillingRulesPanel.vue b/src/modules/customers/components/CustomerBillingRulesPanel.vue index 0129872a..c8ba7178 100644 --- a/src/modules/customers/components/CustomerBillingRulesPanel.vue +++ b/src/modules/customers/components/CustomerBillingRulesPanel.vue @@ -19,12 +19,21 @@ import AppDialog from '@/shared/components/AppDialog.vue' import DataTable, { type DataTableColumn } from '@/shared/components/DataTable.vue' import { createCustomerChargeRule, listCustomerChargeRules, setCustomerChargeRuleDefault, type CustomerChargeRule, type CreateCustomerChargeRuleRequest } from '@/modules/fba-pricing' -const props = defineProps<{ customerId: string; customerName: string; customerCode?: string }>() +const props = defineProps<{ + customerId: string + customerName: string + customerCode?: string + dimensionInitializationStatus?: string +}>() const access = useAccessPreviewStore() const canView = computed(() => access.can('firstleg:dimension-config:view')) const canEdit = computed(() => canView.value && access.can('firstleg:dimension-config:edit')) const canChargeView = computed(() => access.can('firstleg:fba-pricing:rule:view')) const canChargeEdit = computed(() => canChargeView.value && access.can('firstleg:fba-pricing:rule:edit')) +const initializationStatus = computed(() => props.dimensionInitializationStatus?.trim().toUpperCase() || 'READY') +const initializationPending = computed(() => ['PENDING', 'SENDING'].includes(initializationStatus.value)) +const initializationFailed = computed(() => initializationStatus.value === 'FAILED') +const initializationReady = computed(() => !initializationPending.value && !initializationFailed.value) const config = ref(null) const loading = ref(false) const loadError = ref(null) @@ -92,7 +101,17 @@ watch(form, () => { watch(() => props.customerId, () => { editorVisible.value = false defaultCalculationMode.value = 'ACTUAL' - void loadConfig() + if (initializationReady.value) { + void loadConfig() + void loadChargeRules() + } +}) + +watch(initializationReady, (ready, previous) => { + if (ready && !previous) { + void loadConfig() + void loadChargeRules() + } }) function sortRules(rules: CustomerDimensionRule[]) { @@ -101,7 +120,7 @@ function sortRules(rules: CustomerDimensionRule[]) { } async function loadConfig() { - if (!canView.value) return + if (!canView.value || !initializationReady.value) return loading.value = true loadError.value = null try { @@ -266,7 +285,7 @@ function formatDate(value: string | null) { } async function loadChargeRules() { - if (!canChargeView.value) return + if (!canChargeView.value || !initializationReady.value) return chargeLoading.value = true try { chargeRules.value = await listCustomerChargeRules(props.customerId) @@ -287,17 +306,29 @@ async function loadChargeRules() { finally { chargeLoading.value = false } } -onMounted(() => { void loadConfig(); void loadChargeRules() }) +onMounted(() => { + if (!initializationReady.value) return + void loadConfig() + void loadChargeRules() +})