feat: 完善头程审核与计费信息
This commit is contained in:
@@ -86,11 +86,17 @@ const normalizedInboundId = computed(() => {
|
||||
return identifier && identifier !== 'null' && identifier !== 'undefined' ? identifier : ''
|
||||
})
|
||||
const adjustmentEligible = computed(() => (
|
||||
snapshot.value?.feeStatus === 'CALCULATED'
|
||||
['CALCULATED', 'CONFIRMED', 'SENT'].includes(snapshot.value?.feeStatus || '')
|
||||
&& snapshot.value?.nextProcessStatus === 'WAIT_SPLIT'
|
||||
&& snapshot.value?.customerConfirmationStatus !== 'CONFIRMED'
|
||||
))
|
||||
const chargeModeLabel = computed(() => snapshot.value?.chargeMode === 'KG' ? '按重量计费' : '按体积计费')
|
||||
const chargeUnitLabel = computed(() => snapshot.value?.chargeUnit === 'KG' ? 'KG' : 'CBM')
|
||||
const convertedQuantityLabel = computed(() => snapshot.value?.chargeMode === 'KG' ? '体积重量' : '重量折算体积')
|
||||
const adjustmentBaseline = computed(() => Number(snapshot.value?.baselineChargeableQuantity || 0))
|
||||
const adjustmentMinimum = computed(() => Number(snapshot.value?.lowerChargeableQuantity || 0))
|
||||
const adjustmentMaximum = computed(() => Number(snapshot.value?.upperChargeableQuantity || 0))
|
||||
const adjustmentQuantityChanged = computed(() => Math.abs(Number(adjustmentForm.chargeableQuantity) - adjustmentBaseline.value) > 1e-8)
|
||||
const statusInfo = computed(() => feeStatusInfo(snapshot.value?.feeStatus))
|
||||
const sourceOptions = computed(() => {
|
||||
const value = measurement.value
|
||||
@@ -145,6 +151,12 @@ function taxModeLabel(value: string) {
|
||||
return firstLegTaxModeLabel(value)
|
||||
}
|
||||
|
||||
function pricingTaxModeLabel(value: string | null | undefined) {
|
||||
if (value === 'TAX_INCLUDED') return '包税'
|
||||
if (value === 'TAX_EXCLUDED') return '不包税'
|
||||
return '—'
|
||||
}
|
||||
|
||||
function roundingModeLabel(value: string) {
|
||||
const labels: Record<string, string> = {
|
||||
UP: '远离零方向', DOWN: '向零方向', CEILING: '向上', FLOOR: '向下',
|
||||
@@ -275,6 +287,7 @@ function adjustmentPayload(): AdjustPublishedInboundFeeRequest {
|
||||
unitPrice: Number(adjustmentForm.unitPrice),
|
||||
additionalAmount: Number(adjustmentForm.additionalAmount),
|
||||
reason: adjustmentForm.reason.trim(),
|
||||
toleranceConfirmed: true,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,6 +304,22 @@ async function submitAdjustment() {
|
||||
if (!snapshot.value) return
|
||||
const valid = await adjustFormRef.value?.validate().catch(() => false)
|
||||
if (!valid) return
|
||||
const nextQuantity = Number(adjustmentForm.chargeableQuantity)
|
||||
if (nextQuantity < adjustmentMinimum.value || nextQuantity > adjustmentMaximum.value) {
|
||||
ElMessage.warning(`调整后计费量须在基准值的 ±10% 范围内(${formatNumber(adjustmentMinimum.value, 4)}–${formatNumber(adjustmentMaximum.value, 4)} ${chargeUnitLabel.value})`)
|
||||
return
|
||||
}
|
||||
if (adjustmentQuantityChanged.value) {
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`计费量将由 ${formatNumber(adjustmentBaseline.value, 4)} 调整为 ${formatNumber(nextQuantity, 4)} ${chargeUnitLabel.value},并生成新费用版本。是否继续?`,
|
||||
'再次确认计费量调整',
|
||||
{ type: 'warning', confirmButtonText: '确认调整', cancelButtonText: '返回检查' },
|
||||
)
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
}
|
||||
const payload = adjustmentPayload()
|
||||
adjustmentError.value = null
|
||||
conflictRefreshed.value = false
|
||||
@@ -364,7 +393,7 @@ defineExpose({ reload: loadFee })
|
||||
data-testid="adjust-fee-button"
|
||||
type="primary"
|
||||
@click="openAdjustment"
|
||||
><PencilLine :size="16" />调整初算费用</el-button>
|
||||
><PencilLine :size="16" />{{ snapshot?.feeStatus === 'CALCULATED' ? '调整初算费用' : '调整已发布费用' }}</el-button>
|
||||
<el-button
|
||||
v-if="!displayOnly && canConfirm && snapshot?.feeStatus === 'CALCULATED'"
|
||||
data-testid="confirm-fee-button"
|
||||
@@ -452,12 +481,15 @@ defineExpose({ reload: loadFee })
|
||||
<section class="calculation-section" aria-labelledby="calculation-title">
|
||||
<div class="section-title">
|
||||
<div><h4 id="calculation-title">计费依据</h4><p v-if="!compact">实际重量与体积重量取大后计费,金额以服务端快照为准。</p></div>
|
||||
<el-tag effect="plain">{{ taxModeLabel(snapshot.taxMode) }}</el-tag>
|
||||
<div class="calculation-tags">
|
||||
<el-tag effect="plain">订单报关:{{ taxModeLabel(snapshot.taxMode) }}</el-tag>
|
||||
<el-tag effect="plain">报价税制:{{ pricingTaxModeLabel(snapshot.pricingTaxMode) }}</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
<div class="calculation-flow">
|
||||
<div><span>实际重量</span><strong>{{ formatNumber(snapshot.actualWeightKg, 3) }} KG</strong></div>
|
||||
<div><span>实际体积</span><strong>{{ formatNumber(snapshot.actualVolumeCbm, 4) }} CBM</strong></div>
|
||||
<div><span>体积重量</span><strong>{{ formatNumber(snapshot.convertedQuantity, snapshot.roundingScale) }} {{ chargeUnitLabel }}</strong><small>系数 {{ formatNumber(snapshot.conversionFactor, 4) }}</small></div>
|
||||
<div><span>{{ convertedQuantityLabel }}</span><strong>{{ formatNumber(snapshot.convertedQuantity, snapshot.roundingScale) }} {{ chargeUnitLabel }}</strong><small>系数 {{ formatNumber(snapshot.conversionFactor, 4) }}</small></div>
|
||||
<div class="is-chargeable"><span>取大后的计费量</span><strong>{{ formatNumber(snapshot.chargeableQuantity, snapshot.roundingScale) }} {{ chargeUnitLabel }}</strong></div>
|
||||
</div>
|
||||
<div class="amount-equation" aria-label="费用计算公式">
|
||||
@@ -517,6 +549,10 @@ defineExpose({ reload: loadFee })
|
||||
@confirm="submitAdjustment"
|
||||
>
|
||||
<el-alert type="warning" :closable="false" show-icon title="调整会生成新的费用版本;小计和总额由服务端按计费量、单价和附加费重算。" />
|
||||
<el-alert class="adjustment-alert" type="info" :closable="false" show-icon>
|
||||
<template #title>计费量允许在系统原始基准值 ±{{ formatNumber(snapshot?.tolerancePercent, 2) }}% 内调整</template>
|
||||
<p>系统基准 {{ formatNumber(adjustmentBaseline, 4) }} {{ chargeUnitLabel }},服务端允许范围 {{ formatNumber(adjustmentMinimum, 4) }}–{{ formatNumber(adjustmentMaximum, 4) }} {{ chargeUnitLabel }}(包含边界);超出范围将无法提交。</p>
|
||||
</el-alert>
|
||||
<el-alert v-if="conflictRefreshed" class="adjustment-alert" type="warning" :closable="false" show-icon>
|
||||
<template #title>费用已被其他操作员更新,系统已刷新最新快照</template>
|
||||
<p>当前输入仍保留,请先核对最新版本后再提交。</p>
|
||||
@@ -524,7 +560,7 @@ defineExpose({ reload: loadFee })
|
||||
<el-form ref="adjustFormRef" :model="adjustmentForm" :rules="adjustmentRules" label-position="top" class="adjustment-form" :disabled="adjusting">
|
||||
<div class="adjustment-amounts">
|
||||
<el-form-item label="调整后计费量" prop="chargeableQuantity" required>
|
||||
<el-input-number v-model="adjustmentForm.chargeableQuantity" aria-label="调整后计费量" :min="0.0001" :max="999999999999.9999" :precision="4" :step="1" controls-position="right" placeholder="请输入调整后计费量" />
|
||||
<el-input-number v-model="adjustmentForm.chargeableQuantity" aria-label="调整后计费量" :min="adjustmentMinimum" :max="adjustmentMaximum" :precision="4" :step="1" controls-position="right" placeholder="请输入调整后计费量" />
|
||||
<span class="adjustment-unit">{{ chargeUnitLabel }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="调整后单价" prop="unitPrice" required>
|
||||
@@ -571,6 +607,7 @@ defineExpose({ reload: loadFee })
|
||||
.version-status { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
|
||||
.calculation-section, .fee-timeline { padding: 10px 0; border-bottom: 1px solid var(--cc-border); }
|
||||
.section-title { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
|
||||
.calculation-tags { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; }
|
||||
.section-title h4 { font-size: 14px; }
|
||||
.calculation-flow { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); margin-top: 7px; border-top: 1px solid var(--cc-border); border-bottom: 1px solid var(--cc-border); }
|
||||
.calculation-flow > div { display: flex; min-width: 0; min-height: 46px; flex-direction: row; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 10px; border-right: 1px solid var(--cc-border); }
|
||||
|
||||
Reference in New Issue
Block a user