优化
This commit is contained in:
@@ -623,7 +623,7 @@ test('loads merchant inbound billing as an isolated read-only detail section', (
|
||||
assert.match(source, /error instanceof ApiError && error\.code === 'A0404'/)
|
||||
assert.match(source, /error\.message \|\| unavailableMessage/)
|
||||
assert.match(source, /order\.status === 'DRAFT'/)
|
||||
assert.match(source, /feeConfirmationOpen\.value[\s\S]*\? '未推送计费重'[\s\S]*: '订单提交后可查看入库结果'/)
|
||||
assert.match(source, /feeConfirmationOpen\.value[\s\S]*\? '未推送费用'[\s\S]*: '订单提交后可查看入库结果'/)
|
||||
assert.match(source, /订单提交后可查看入库结果/)
|
||||
assert.doesNotMatch(source, /confirmMerchantInbound|adjustMerchantInbound|sendMerchantInbound/)
|
||||
})
|
||||
@@ -636,10 +636,10 @@ test('keeps platform enterprise scope and tenant terminology out of the customer
|
||||
test('opens billing-weight confirmation independently from order details', () => {
|
||||
const handler = source.slice(source.indexOf('function openFeeConfirmation'), source.indexOf('async function retryDetail'))
|
||||
assert.match(handler, /feeConfirmationOpen\.value = true/)
|
||||
assert.match(handler, /loadInboundBilling\(order, '未推送计费重'\)/)
|
||||
assert.match(handler, /loadInboundBilling\(order, '未推送费用'\)/)
|
||||
assert.doesNotMatch(handler, /openDetail\(/)
|
||||
assert.match(source, /v-if="feeConfirmationOpen"[\s\S]*dialog-only[\s\S]*auto-open/)
|
||||
assert.match(source, /unavailable-message="未推送计费重"/)
|
||||
assert.match(source, /unavailable-message="未推送费用"/)
|
||||
})
|
||||
|
||||
test('shows billing-weight confirmation only when the backend marks it pending', () => {
|
||||
|
||||
@@ -9,6 +9,7 @@ import DataTable, { type DataTableColumn } from '@/components/common/DataTable.v
|
||||
import type { TableAction } from '@/components/common/tableActions'
|
||||
import { ApiError } from '@/api/http'
|
||||
import FirstLegOrderEditorShell from '@/modules/first-leg/components/FirstLegOrderEditorShell.vue'
|
||||
import ChargeableWeightDialog from '@/modules/first-leg/components/ChargeableWeightDialog.vue'
|
||||
import InboundBillingPanel from '@/modules/first-leg/components/InboundBillingPanel.vue'
|
||||
import InboundCodeAssociationDialog from '@/modules/first-leg/components/InboundCodeAssociationDialog.vue'
|
||||
import OrderProgressPanel from '@/modules/first-leg/components/OrderProgressPanel.vue'
|
||||
@@ -267,6 +268,7 @@ const inboundBillingUnavailableMessage = ref('还未测量推送')
|
||||
const inboundBillingError = ref('')
|
||||
const inboundBillingOrderId = ref('')
|
||||
const feeConfirmationOpen = ref(false)
|
||||
const weightConfirmationOrderId = ref('')
|
||||
const customsByOrder = reactive<Record<string, MerchantCustomsContainer | null | undefined>>({})
|
||||
const customsEligibilityPending = new Set<string>()
|
||||
const customsDialogOpen = ref(false)
|
||||
@@ -1361,8 +1363,11 @@ function getOrderRowActions(row: object): TableAction[] {
|
||||
if (canCreateOrder.value) {
|
||||
actions.push({ key: 'copy', label: '复制下单', loading: copyingOrderId.value === order.id, run: () => copyOrder(order) })
|
||||
}
|
||||
if (canConfirmInboundFee.value && !['DRAFT', 'CANCELLED', 'REJECTED', 'SUBMITTED'].includes(order.status)) {
|
||||
actions.push({ key: 'weight', label: '确认计费重', run: () => { weightConfirmationOrderId.value = order.id } })
|
||||
}
|
||||
if (canConfirmInboundFee.value && order.businessSummary.customerFeeConfirmationRequired) {
|
||||
actions.push({ key: 'fee', label: '确认计费重', run: () => openFeeConfirmation(order) })
|
||||
actions.push({ key: 'fee', label: '确认费用', run: () => openFeeConfirmation(order) })
|
||||
}
|
||||
if (canEditOrder.value && canClientEditFirstLegOrder(order.status)) {
|
||||
actions.push({ key: 'edit', label: '编辑', loading: openingEditor.value, run: () => openEdit(order) })
|
||||
@@ -1471,9 +1476,9 @@ async function loadDetailPage(orderId: string) {
|
||||
|
||||
function openFeeConfirmation(order: FirstLegOrder) {
|
||||
resetInboundBillingState()
|
||||
inboundBillingUnavailableMessage.value = '未推送计费重'
|
||||
inboundBillingUnavailableMessage.value = '未推送费用'
|
||||
feeConfirmationOpen.value = true
|
||||
void loadInboundBilling(order, '未推送计费重')
|
||||
void loadInboundBilling(order, '未推送费用')
|
||||
}
|
||||
|
||||
async function retryDetail() {
|
||||
@@ -1508,7 +1513,7 @@ async function loadInboundBilling(order: FirstLegOrder, unavailableMessage = '
|
||||
if (order.status === 'DRAFT') {
|
||||
inboundBillingUnavailable.value = true
|
||||
inboundBillingUnavailableMessage.value = feeConfirmationOpen.value
|
||||
? '未推送计费重'
|
||||
? '未推送费用'
|
||||
: '订单提交后可查看入库结果'
|
||||
return
|
||||
}
|
||||
@@ -1523,7 +1528,7 @@ async function loadInboundBilling(order: FirstLegOrder, unavailableMessage = '
|
||||
if (error instanceof ApiError && error.code === 'A0404') {
|
||||
inboundBillingUnavailable.value = true
|
||||
inboundBillingUnavailableMessage.value = feeConfirmationOpen.value
|
||||
? '未推送计费重'
|
||||
? '未推送费用'
|
||||
: error.message || unavailableMessage
|
||||
} else {
|
||||
inboundBillingError.value = error instanceof Error ? error.message : '入库与费用加载失败'
|
||||
@@ -1535,7 +1540,7 @@ async function loadInboundBilling(order: FirstLegOrder, unavailableMessage = '
|
||||
|
||||
async function retryInboundBilling() {
|
||||
const order = inboundBillingOrderId.value ? store.getById(inboundBillingOrderId.value) : undefined
|
||||
if (order) await loadInboundBilling(order, feeConfirmationOpen.value ? '未推送计费重' : '还未测量推送')
|
||||
if (order) await loadInboundBilling(order, feeConfirmationOpen.value ? '未推送费用' : '还未测量推送')
|
||||
}
|
||||
|
||||
function handleInboundFeeConfirmed() {
|
||||
@@ -2548,13 +2553,14 @@ async function searchOrders(model: QueryModel) {
|
||||
:data="inboundBilling"
|
||||
:loading="inboundBillingLoading"
|
||||
:unavailable="inboundBillingUnavailable"
|
||||
unavailable-message="未推送计费重"
|
||||
unavailable-message="未推送费用"
|
||||
:error="inboundBillingError"
|
||||
:can-confirm="canConfirmInboundFee"
|
||||
@retry="retryInboundBilling"
|
||||
@confirmed="handleInboundFeeConfirmed"
|
||||
@closed="feeConfirmationOpen = false"
|
||||
/>
|
||||
<ChargeableWeightDialog v-if="weightConfirmationOrderId" :order-id="weightConfirmationOrderId" :can-confirm="canConfirmInboundFee" @close="weightConfirmationOrderId = ''" @confirmed="handleInboundFeeConfirmed" />
|
||||
<CustomsDocumentsDialog
|
||||
v-model="customsDialogOpen"
|
||||
:order-id="customsDialogOrderId"
|
||||
|
||||
@@ -76,7 +76,7 @@ watch(originWarehouseId, (value, previous) => { if (!value || previous === '') r
|
||||
<template>
|
||||
<div class="pricing-page"><section class="pricing-inquiry"><div class="inquiry-copy"><span>SAILING PRICE INQUIRY</span><h2>船期价格查询</h2><p>重量或体积填写一项即可,系统会按计价规则自动换算</p></div><el-form class="pricing-form" label-position="top"><el-form-item label="起运仓"><el-select v-model="originWarehouseId" filterable :loading="loading" placeholder="选择起运仓"><el-option v-for="item in warehouses" :key="String(item.id)" :label="`${item.warehouseName} · ${item.warehouseCode}`" :value="item.id" /></el-select></el-form-item><el-form-item label="货物重量"><div class="unit-input"><el-input v-model.number="weight" type="number" min="0" placeholder="可选,输入重量" /><span>KG</span></div></el-form-item><el-form-item label="货物立方数"><div class="unit-input"><el-input v-model.number="volume" type="number" min="0" placeholder="可选,输入体积" /><span>CBM</span></div></el-form-item><el-form-item label="目的 FBA 仓"><el-select v-model="destinationWarehouseId" filterable :loading="loading" placeholder="输入或选择仓库代码"><el-option v-for="item in destinationWarehouses" :key="String(item.id)" :label="item.warehouseCode" :value="item.id" /></el-select></el-form-item><el-form-item label="报价方式"><el-radio-group v-model="taxMode"><el-radio-button value="TAX_INCLUDED" label="包税" /><el-radio-button value="TAX_EXCLUDED" label="不包税" /></el-radio-group></el-form-item><el-form-item class="query-item"><el-button type="primary" :loading="querying" @click="query"><Search :size="16" />立即查询</el-button></el-form-item></el-form>
|
||||
<el-dialog v-model="quoteDialogOpen" class="quote-dialog" :show-close="false" :lock-scroll="false" width="min(1080px, calc(100vw - 48px))" top="6vh"><template #header><div class="quote-dialog-head"><div><h3>查询结果</h3><span>{{ resultSummary }}</span></div><button type="button" class="quote-close" aria-label="关闭" @click="quoteDialogOpen = false">×</button></div></template><div class="quote-grid"><article v-for="item in quoteCards" :key="item.quote.channelCode" class="quote-card" :class="recommendation(item)?.className"><div v-if="recommendation(item)" class="quote-ribbon">{{ recommendation(item)?.label }}</div><div class="quote-card-title"><strong>{{ item.channel.channelName }}</strong><span>{{ item.quote.pricingTaxMode === 'TAX_INCLUDED' ? '包税' : '不包税' }} / {{ item.quote.chargeUnit || 'CBM' }}</span></div><div class="quote-price"><b>{{ formatMoney(item.quote) }}</b><small>预估运费</small></div><div class="quote-meta"><div><span>单价</span><strong>{{ formatUnitPrice(item.quote) }}</strong></div><div><span>参考时效</span><strong>{{ item.channel.referenceTransit || '待更新' }}</strong></div><div><span>最晚进仓</span><strong>{{ item.channel.latestWarehouseEntry || '—' }}</strong></div><div><span>船期</span><strong>{{ item.channel.estimatedDepartureText || item.channel.estimatedDepartureDate || '待更新' }}</strong></div></div><el-button type="primary" plain class="quote-order" @click="placeOrder(item.quote.channelCode, item.channel.channelName)">下单</el-button></article></div></el-dialog></section>
|
||||
<section class="pricing-results"><div class="section-title"><div><h2>匹配渠道</h2><span>{{ channels.length }} 个渠道 · 参考价格以服务端估价为准</span></div><Calculator :size="20" /></div><el-skeleton v-if="loading || querying" :rows="4" animated /><el-alert v-else-if="errorMessage" :title="errorMessage" type="error" show-icon /><el-empty v-else-if="!channels.length" description="暂无可用船期价格" /><el-table v-else :data="channels" stripe><el-table-column label="渠道" min-width="160"><template #default="{ row }"><strong>{{ row.channelName }}</strong><small>{{ row.channelCode }}</small></template></el-table-column><el-table-column label="参考船期" min-width="150"><template #default="{ row }">{{ row.estimatedDepartureText || row.estimatedDepartureDate || '待更新' }}</template></el-table-column><el-table-column label="最晚进仓" min-width="130"><template #default="{ row }">{{ row.latestWarehouseEntry || '—' }}</template></el-table-column><el-table-column label="参考时效" width="120"><template #default="{ row }">{{ row.referenceTransit || '—' }}</template></el-table-column><el-table-column label="预估运费" width="150"><template #default="{ row }"><span v-if="quotes.find((quote) => quote.channelCode === row.channelCode)">{{ formatMoney(quotes.find((quote) => quote.channelCode === row.channelCode)!) }}</span><span v-else class="muted">查询后显示</span></template></el-table-column><el-table-column label="附加费说明" min-width="180" prop="surchargeDescription" /><el-table-column label="操作" width="100" fixed="right"><template #default="{ row }"><el-button link type="primary" :disabled="!quotes.some((quote) => quote.channelCode === row.channelCode)" @click="placeOrder(row.channelCode, row.channelName)">下单</el-button></template></el-table-column></el-table></section>
|
||||
<section class="pricing-results"><div class="section-title"><div><h2>匹配渠道</h2><span>{{ channels.length }} 个渠道 · 参考价格以服务端估价为准</span></div><Calculator :size="20" /></div><el-skeleton v-if="loading || querying" :rows="4" animated /><el-alert v-else-if="errorMessage" :title="errorMessage" type="error" show-icon /><el-empty v-else-if="!channels.length" description="暂无可用船期价格" /><el-table v-else :data="channels" stripe><el-table-column label="渠道" min-width="160"><template #default="{ row }"><strong>{{ row.channelName }}</strong><small>{{ row.channelCode }}</small></template></el-table-column><el-table-column label="参考船期" min-width="150"><template #default="{ row }">{{ row.estimatedDepartureText || row.estimatedDepartureDate || '待更新' }}</template></el-table-column><el-table-column label="最晚进仓" min-width="130"><template #default="{ row }">{{ row.latestWarehouseEntry || '—' }}</template></el-table-column><el-table-column label="参考时效" width="120"><template #default="{ row }">{{ row.referenceTransit || '—' }}</template></el-table-column><el-table-column label="预估运费" width="150"><template #default="{ row }"><span v-if="quotes.find((quote) => quote.channelCode === row.channelCode)">{{ formatMoney(quotes.find((quote) => quote.channelCode === row.channelCode)!) }}</span><span v-else class="muted">查询后显示</span></template></el-table-column><el-table-column label="附加费说明" min-width="180" prop="surchargeDescription" /></el-table></section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user