This commit is contained in:
2026-09-04 11:50:34 +08:00
parent e390b88b6c
commit d5662230d5
4 changed files with 84 additions and 44 deletions
@@ -129,6 +129,7 @@ const detailError = ref<ApiErrorDetails | null>(null)
const declarationEditorOpen = ref(false)
const activeDetailTab = ref('basic')
const automaticFee = ref<AutomaticFeeSummary | null>(null)
const feePanelRevision = ref(0)
const otherFeeSummary = ref<OtherFeeSummary>({ currency: 'CNY', approvedReceivable: 0, approvedPayable: 0 })
const customerFeeTotal = computed(() => (
(automaticFee.value?.feeStatus === 'SENT' ? Number(automaticFee.value.totalAmount || 0) : 0)
@@ -197,9 +198,13 @@ const feeConfirmWeight = ref<number | null>(null)
const feeConfirmVolume = ref<number | null>(null)
const feeConfirmRows = computed(() => {
const summary = detail.value?.summary
const measurement = summary?.measurement
const actualWeight = Number(measurement?.actualGrossWeightKg)
const actualVolume = Number(measurement?.actualVolumeCbm)
const measuredGrossWeight = Number(measurementDetail.value?.actualGrossWeightKg)
const measuredNetWeight = Number(measurementDetail.value?.actualNetWeightKg)
const measuredVolume = Number(measurementDetail.value?.actualVolumeCbm)
const actualWeight = measuredGrossWeight > 0
? measuredGrossWeight
: measuredNetWeight > 0 ? measuredNetWeight : null
const actualVolume = measuredVolume > 0 ? measuredVolume : null
const customerTotals = measurementTotals(customerMeasurementRows.value)
return [
{ source: '客户下单数据', count: customerTotals.count, weight: customerTotals.gross, volume: customerTotals.volume ?? summary?.expectedVolumeCbm },
@@ -434,11 +439,6 @@ const actualMeasurementRows = computed(() => (measurementDetail.value?.items ||
calculatedMeasurementRow(row as unknown as Record<string, unknown>, measurementSectionModes.actual, false, false)
)))
const hasActualMeasurementData = computed(() => (measurementDetail.value?.items?.length ?? 0) > 0)
const feeSendEditableStatuses = new Set([
'WAIT_MEASURE', 'MEASURING', 'MEASURE_PENDING', 'MEASURE_REJECTED',
'WAIT_PRICING', 'FEE_CONFIRMING', 'WAIT_SPLIT',
])
const canSendFeeForCurrentStatus = computed(() => feeSendEditableStatuses.has(String(detail.value?.summary?.mainStatus || '')))
function updateMeasurementSectionMode(section: MeasurementSection, mode: MeasurementCalculationMode) {
if (mode === 'MULTIPLY' && !activeMeasurementChargeRule.value) {
@@ -1180,7 +1180,7 @@ async function loadMeasurementDetails() {
measurementLoadedKey.value = key
} catch (error) {
if (serial !== measurementRequestSerial) return
measurementDetail.value = null
if (!measurementDetail.value) measurementDetail.value = null
measurementError.value = getApiErrorDetails(error, '测量数据加载失败,请稍后重试')
} finally {
if (serial === measurementRequestSerial) measurementLoading.value = false
@@ -1414,10 +1414,6 @@ async function openFeeConfirmDialog() {
ElMessage.warning('暂无实际测量数据,不能确认并发送费用')
return
}
if (!canSendFeeForCurrentStatus.value) {
ElMessage.warning('订单已进入装柜流程,不能再修改或发送费用')
return
}
if (confirmFeeSending.value) {
return
}
@@ -1431,12 +1427,17 @@ async function openFeeConfirmDialog() {
return
}
const actualTotals = measurementTotals(actualMeasurementRows.value)
const customerTotals = measurementTotals(customerMeasurementRows.value)
const defaultWeight = Number(outerTotals.gross) > 0 ? Number(outerTotals.gross)
: Number(actualTotals.gross) > 0 ? Number(actualTotals.gross)
: Number(customerTotals.gross) > 0 ? Number(customerTotals.gross) : null
feeConfirmWeight.value = defaultWeight
feeConfirmVolume.value = Number(outerTotals.volume)
const measuredGrossWeight = Number(measurementDetail.value?.actualGrossWeightKg)
const measuredNetWeight = Number(measurementDetail.value?.actualNetWeightKg)
const actualVolume = Number(measurementDetail.value?.actualVolumeCbm)
feeConfirmWeight.value = measuredGrossWeight > 0
? measuredGrossWeight
: measuredNetWeight > 0
? measuredNetWeight
: Number(actualTotals.gross) > 0 ? Number(actualTotals.gross) : null
feeConfirmVolume.value = actualVolume > 0
? actualVolume
: Number(actualTotals.volume) > 0 ? Number(actualTotals.volume) : null
feeConfirmOpen.value = true
}
@@ -1456,13 +1457,15 @@ async function executeConfirmAndSendFee() {
let snapshot = await calculateInboundFee(tenantId, inboundId, {
selectedWeightKg,
selectedVolumeCbm,
weightSource: 'OUTER',
volumeSource: 'OUTER',
weightSource: 'ACTUAL',
volumeSource: 'ACTUAL',
}, createFeeActionIdempotencyKey('calculate'))
snapshot = await confirmInboundFee(tenantId, inboundId, createFeeActionIdempotencyKey('confirm'))
if (snapshot.feeStatus === 'CONFIRMED') {
await sendInboundFee(tenantId, inboundId, createFeeActionIdempotencyKey('send'))
ElMessage.success('费用已确认并发送给客户')
const sent = await sendInboundFee(tenantId, inboundId, createFeeActionIdempotencyKey('send'))
automaticFee.value = { feeStatus: sent.feeStatus, totalAmount: Number(sent.totalAmount || 0) }
feePanelRevision.value += 1
ElMessage.success('计费重已确认并发送给客户')
feeConfirmOpen.value = false
await loadDetail(true)
return
@@ -1799,7 +1802,9 @@ async function loadDetail(force = false) {
const serial = ++detailRequestSerial
detailLoadingKey = requestKey
measurementRequestSerial += 1
measurementDetail.value = null
measurementLoading.value = false
// 刷新详情时保留现有测量数据,避免请求期间列表被清空。
if (!force) measurementDetail.value = null
measurementError.value = null
measurementLoadedKey.value = ''
measurementSectionModes.customer = 'ACTUAL'
@@ -2024,11 +2029,12 @@ onBeforeUnmount(() => {
</dl>
<h3 class="fee-section-title">头程自动初算</h3>
<InboundFeePanel
:key="`fee-${normalizedInboundId}-${feePanelRevision}`"
:customer-id="String(detail.summary.tenantId)"
:inbound-id="normalizedInboundId"
compact
display-only
@loaded="automaticFee = $event"
@changed="loadDetail(true)"
/>
<h3 class="fee-section-title fee-section-title--secondary">其他费用明细</h3>
<InboundFeeDetailManager
@@ -2091,11 +2097,10 @@ onBeforeUnmount(() => {
v-if="can('firstleg:inbound:confirm-send-fee')"
type="primary"
:loading="confirmFeeSending"
:disabled="confirmFeeSending || measurementLoading || !hasActualMeasurementData || !canSendFeeForCurrentStatus"
title="确认并发送费用"
data-testid="confirm-send-fee-button"
@click="openFeeConfirmDialog"
><Send :size="15" />确认费用发送</el-button>
><Send :size="15" />确认计费重发送</el-button>
</div>
</div>
<el-alert v-if="!can('platform:firstleg:inbound:measure:view')" title="当前账号缺少测量查看权限" type="warning" :closable="false" show-icon />