fix(customs): expose clearance query failure with scoped retry
This commit is contained in:
@@ -46,8 +46,12 @@ const replaceInput = ref<HTMLInputElement>()
|
||||
const mutating = ref(false)
|
||||
const downloadingKey = ref('')
|
||||
const clearanceResults = ref<MerchantClearanceResult[]>([])
|
||||
const clearanceError = ref('')
|
||||
const clearanceLoading = ref(false)
|
||||
let clearanceRequest = 0
|
||||
let disposed = false
|
||||
let detailRequest = 0
|
||||
onBeforeUnmount(() => { detailRequest += 1 })
|
||||
onBeforeUnmount(() => { disposed = true; detailRequest += 1; resetClearanceResults() })
|
||||
|
||||
const taxRefundInbounds = computed(() => detail.value?.inbounds.filter((item) => item.taxMode === 'TAX_REFUND') ?? [])
|
||||
const locked = computed(() => Boolean(detail.value?.startedAt) || detail.value?.status === 'DECLARING' || detail.value?.status === 'COMPLETED')
|
||||
@@ -68,9 +72,40 @@ function initializeSelection(value: MerchantCustomsContainer) {
|
||||
selectedInboundIds.value = currentOrderIds
|
||||
}
|
||||
|
||||
function resetClearanceResults() {
|
||||
clearanceRequest += 1
|
||||
clearanceResults.value = []
|
||||
clearanceError.value = ''
|
||||
clearanceLoading.value = false
|
||||
}
|
||||
|
||||
async function loadClearanceResults() {
|
||||
if (disposed || !props.modelValue || !props.orderId || !detail.value || clearanceLoading.value) return
|
||||
const request = ++clearanceRequest
|
||||
const parentRequest = detailRequest
|
||||
const orderId = props.orderId
|
||||
const isCurrent = () => !disposed && request === clearanceRequest && parentRequest === detailRequest && props.modelValue && props.orderId === orderId
|
||||
clearanceLoading.value = true
|
||||
clearanceError.value = ''
|
||||
try {
|
||||
const results = await getMerchantClearanceResults(orderId)
|
||||
if (isCurrent()) clearanceResults.value = results
|
||||
} catch (error) {
|
||||
if (isCurrent()) clearanceError.value = merchantCustomsErrorMessage(error, '海关申报结果加载失败')
|
||||
} finally {
|
||||
if (isCurrent()) clearanceLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function retryClearanceResults() {
|
||||
if (loading.value) return
|
||||
await loadClearanceResults()
|
||||
}
|
||||
|
||||
async function loadDetail() {
|
||||
if (!props.modelValue || !props.orderId) return
|
||||
if (disposed || !props.modelValue || !props.orderId) return
|
||||
const request = ++detailRequest
|
||||
resetClearanceResults()
|
||||
const orderId = props.orderId
|
||||
const isCurrent = () => request === detailRequest && props.modelValue && props.orderId === orderId
|
||||
loading.value = true
|
||||
@@ -80,10 +115,8 @@ async function loadDetail() {
|
||||
if (!isCurrent()) return
|
||||
detail.value = result
|
||||
initializeSelection(result)
|
||||
let results: MerchantClearanceResult[] = []
|
||||
try { results = await getMerchantClearanceResults(orderId) } catch { /* Detail remains available for a failed result query. */ }
|
||||
await loadClearanceResults()
|
||||
if (!isCurrent()) return
|
||||
clearanceResults.value = results
|
||||
emit('updated', result)
|
||||
} catch (error) {
|
||||
if (!isCurrent()) return
|
||||
@@ -97,7 +130,7 @@ async function loadDetail() {
|
||||
watch(() => [props.modelValue, props.orderId] as const, ([open]) => {
|
||||
detailRequest += 1
|
||||
detail.value = null
|
||||
clearanceResults.value = []
|
||||
resetClearanceResults()
|
||||
selectedInboundIds.value = []
|
||||
editingDocument.value = null
|
||||
replacingDocument.value = null
|
||||
@@ -111,6 +144,8 @@ watch(() => [props.modelValue, props.orderId] as const, ([open]) => {
|
||||
}, { immediate: true })
|
||||
|
||||
function close() {
|
||||
detailRequest += 1
|
||||
resetClearanceResults()
|
||||
emit('update:modelValue', false)
|
||||
}
|
||||
|
||||
@@ -345,7 +380,13 @@ function clearanceResultStatusLabel(value: MerchantClearanceResult) {
|
||||
<div class="customs-section-title">
|
||||
<div><h3>海关申报结果</h3><p>平台完成正式申报后,客户可查看与本订单相关的查验、补充资料和放行结果。</p></div>
|
||||
</div>
|
||||
<el-empty v-if="!clearanceResults.length" description="暂无海关结果" :image-size="48" />
|
||||
<div v-if="clearanceError" class="customs-error" role="alert">
|
||||
<strong>海关申报结果加载失败</strong>
|
||||
<span>{{ clearanceError }}</span>
|
||||
<el-button :loading="clearanceLoading" @click="retryClearanceResults">重新加载</el-button>
|
||||
</div>
|
||||
<el-skeleton v-else-if="clearanceLoading" :rows="2" animated />
|
||||
<el-empty v-else-if="!clearanceResults.length" description="暂无海关结果" :image-size="48" />
|
||||
<div v-else class="clearance-result-list">
|
||||
<div v-for="item in clearanceResults" :key="item.id" class="clearance-result-row">
|
||||
<div><strong>{{ clearanceResultLabel(item) }}</strong><span>{{ formatDateTime(item.occurredAt) }} · 报关单号 {{ item.customsEntryNo || '—' }}</span></div>
|
||||
|
||||
Reference in New Issue
Block a user