This commit is contained in:
2026-08-07 20:07:37 +08:00
parent 28d0b81c5a
commit 99413ee155
27 changed files with 1065 additions and 595 deletions
@@ -76,6 +76,7 @@ describe('UnifiedOrdersView contract', () => {
it('keeps only confirmed business actions as explicit boundaries', () => {
expect(source).toContain('nextActionBoundary')
expect(source).not.toContain('class="action-boundary"')
expect(source).toContain("can('platform:firstleg:inbound:view')")
expect(source).toContain('openMeasurement')
expect(source).not.toContain('待接入:智能分柜')
@@ -128,6 +129,8 @@ describe('UnifiedOrdersView contract', () => {
expect(source).toContain("{ key: 'measurement', label: '测量数据'")
expect(source).not.toContain('<AppDrawer')
expect(source).not.toContain('detailOpen')
expect(source).toContain('watch(detailRouteKey,')
expect(source).toContain('requestKey !== detailRouteKey.value')
})
it('keeps the basic information compact and maps available order fields', () => {
@@ -89,9 +89,12 @@ const measurementLoadedKey = ref('')
const measurementImageUrls = ref<string[]>([])
const measurementCollapsed = reactive({ customer: false, outer: false, actual: false })
let detailLoadingKey = ''
let detailRequestSerial = 0
const showAdvancedFilters = ref(false)
const filters = ref<FilterModel>(emptyFilters())
const orderId = computed(() => typeof route.params.orderId === 'string' ? route.params.orderId : '')
const detailTenantId = computed(() => typeof route.query.tenantId === 'string' ? route.query.tenantId : '')
const detailRouteKey = computed(() => orderId.value ? `${detailTenantId.value}:${orderId.value}` : '')
const detailTabs = [
{ key: 'basic', label: '基本信息', icon: Box },
@@ -700,13 +703,14 @@ function closeDetail() {
async function loadDetail(force = false) {
if (!orderId.value) return
const tenantId = typeof route.query.tenantId === 'string' ? route.query.tenantId : ''
const tenantId = detailTenantId.value
if (!tenantId) {
detailError.value = { message: '订单详情缺少客户标识,请从订单列表重新打开' }
return
}
const requestKey = `${tenantId}:${orderId.value}`
if (!force && (detailLoadingKey === requestKey || detail.value?.summary.orderId === orderId.value && String(detail.value.summary.tenantId) === tenantId)) return
const serial = ++detailRequestSerial
detailLoadingKey = requestKey
feeDetails.value = []
feeLoadedKey.value = ''
@@ -716,21 +720,31 @@ async function loadDetail(force = false) {
detailLoading.value = true
detailError.value = null
try {
detail.value = await getPlatformUnifiedOrder(tenantId, orderId.value)
const response = await getPlatformUnifiedOrder(tenantId, orderId.value)
if (serial !== detailRequestSerial || requestKey !== detailRouteKey.value) return
detail.value = response
} catch (error) {
if (serial !== detailRequestSerial || requestKey !== detailRouteKey.value) return
detail.value = null
detailError.value = getApiErrorDetails(error, '统一订单详情加载失败,请检查 C02 统一详情接口和订单权限')
} finally {
detailLoading.value = false
if (detailLoadingKey === requestKey) detailLoadingKey = ''
if (serial === detailRequestSerial) detailLoading.value = false
if (serial === detailRequestSerial && detailLoadingKey === requestKey) detailLoadingKey = ''
}
}
watch([page, pageSize], () => { void loadOrders() })
watch(orderId, (value) => {
watch(detailRouteKey, (value) => {
if (value) {
activeDetailTab.value = 'basic'
detail.value = null
detailError.value = null
void loadDetail()
} else {
detailRequestSerial += 1
detail.value = null
detailError.value = null
detailLoading.value = false
}
}, { immediate: true })
onMounted(() => {
@@ -994,7 +1008,6 @@ onMounted(() => {
</el-dropdown-menu>
</template>
</el-dropdown>
<span v-if="nextActionBoundary(row as UnifiedOrderResource)" class="action-boundary">{{ nextActionBoundary(row as UnifiedOrderResource) }}</span>
</div>
</template>
<template #orderStatus="{ row }"><StatusBadge :status="orderStatusLabel((row as UnifiedOrderResource).internalOrderStatus || (row as UnifiedOrderResource).mainStatus)" /></template>