fix(first-leg): show cancelled orders as terminal details
This commit is contained in:
@@ -245,7 +245,7 @@ test('uses only fields present on C02 rows before loading full detail', () => {
|
||||
assert.doesNotMatch(source, /key: 'operator'/)
|
||||
assert.doesNotMatch(source, /key: 'transportMode', type: 'select'/)
|
||||
assert.match(source, /store\.draftLoadError/)
|
||||
assert.match(source, /mainStatus: statusValue && statusValue !== 'DRAFT' \? statusValue : undefined/)
|
||||
assert.match(source, /mainStatus: statusValue && statusValue !== 'DRAFT' && statusValue !== 'CANCELLED' \? statusValue : undefined/)
|
||||
assert.match(source, /draftOnly: statusValue === 'DRAFT'/)
|
||||
assert.match(source, /createdFrom: range\[0\] \? `\$\{range\[0\]\}T00:00:00`/)
|
||||
})
|
||||
|
||||
@@ -137,7 +137,7 @@ const queryFields = computed<QueryField[]>(() => [
|
||||
{ key: 'receivingWarehouseId', label: '收货仓', type: 'select', placeholder: '全部', options: availableWarehouses.value.map((item) => ({ label: item.name, value: item.id })), props: { 'aria-label': '收货仓' } },
|
||||
{ key: 'channelName', label: '渠道名称', type: 'select', placeholder: '全部', options: [...new Set(store.orders.map((item) => item.channelName).filter(Boolean))].map((name) => ({ label: name, value: name })), props: { 'aria-label': '渠道名称' } },
|
||||
{ key: 'createdRange', label: '创建时间', type: 'daterange', placeholder: '请选择创建时间', props: { 'aria-label': '创建时间' } },
|
||||
{ key: 'status', label: '当前状态', type: 'select', placeholder: '全部', options: FIRST_LEG_ORDER_STATUSES.map((item) => ({ label: item.label, value: item.code })), props: { 'aria-label': '当前状态' } },
|
||||
{ key: 'status', label: '当前状态', type: 'select', placeholder: '全部', options: FIRST_LEG_ORDER_STATUSES.filter(item => item.code !== 'CANCELLED').map((item) => ({ label: item.label, value: item.code })), props: { 'aria-label': '当前状态' } },
|
||||
{ key: 'destinationType', label: '目的仓类型', type: 'select', placeholder: '全部', options: [{ label: 'FBA 仓', value: 'FBA' }, { label: '海外仓', value: 'OVERSEAS' }, { label: '私人地址', value: 'PRIVATE' }], props: { 'aria-label': '目的仓类型' } },
|
||||
{ key: 'trackingNumber', label: '快递单号', type: 'input', placeholder: '请输入快递单号', props: { 'aria-label': '快递单号' } },
|
||||
])
|
||||
@@ -597,7 +597,7 @@ const pagedDetailCargoItems = computed(() => {
|
||||
})
|
||||
const progressSummaryItems = computed(() => {
|
||||
const order = detailOrder.value
|
||||
if (!order) return []
|
||||
if (!order || order.status === 'CANCELLED') return []
|
||||
const inbound = inboundBilling.value?.inbound.summary
|
||||
const summary = order.businessSummary
|
||||
const formatMetric = (value: number | null | undefined, unit = '') => value == null ? '待更新' : `${value.toLocaleString()}${unit ? ` ${unit}` : ''}`
|
||||
@@ -1445,7 +1445,8 @@ async function loadDetailPage(orderId: string) {
|
||||
detailError.value = ''
|
||||
try {
|
||||
const detailedOrder = await store.loadDetail(orderId)
|
||||
void loadInboundBilling(detailedOrder)
|
||||
if (detailedOrder.status === 'CANCELLED') resetInboundBillingState()
|
||||
else void loadInboundBilling(detailedOrder)
|
||||
// Load previews from the persisted file IDs after the store has replaced the detail row.
|
||||
await Promise.all((detailOrder.value?.items ?? detailedOrder.items).map(ensureProductImagePreview))
|
||||
} catch (error) {
|
||||
@@ -2084,7 +2085,7 @@ async function searchOrders(model: QueryModel) {
|
||||
keyword: undefined,
|
||||
inboundCode: cargoKeyword || undefined,
|
||||
receivingWarehouseId: typeof model.receivingWarehouseId === 'string' && model.receivingWarehouseId ? model.receivingWarehouseId : undefined,
|
||||
mainStatus: statusValue && statusValue !== 'DRAFT' ? statusValue : undefined,
|
||||
mainStatus: statusValue && statusValue !== 'DRAFT' && statusValue !== 'CANCELLED' ? statusValue : undefined,
|
||||
draftOnly: statusValue === 'DRAFT',
|
||||
includeDrafts: !statusValue,
|
||||
createdFrom: range[0] ? `${range[0]}T00:00:00` : undefined,
|
||||
@@ -2411,16 +2412,16 @@ async function searchOrders(model: QueryModel) {
|
||||
<div class="order-detail-heading">
|
||||
<div class="detail-heading-main">
|
||||
<el-button link type="primary" class="detail-back-action" @click="router.push({ name: 'first-leg-orders' })">← 返回列表</el-button>
|
||||
<div><h2>{{ detailOrder.businessSummary.inboundCode || (detailOrder.status === 'DRAFT' ? '入仓码提交后生成' : '入仓码待生成') }}</h2><p>{{ getFirstLegTransportModeLabel(detailOrder.transportMode) }} · {{ detailOrder.origin || '起运地待更新' }} → {{ detailOrder.destination || '目的地待更新' }}</p></div>
|
||||
<div><h2>{{ detailOrder.businessSummary.inboundCode || (detailOrder.status === 'CANCELLED' ? (detailOrder.orderNo || '—') : detailOrder.status === 'DRAFT' ? '入仓码提交后生成' : '入仓码待生成') }}</h2><p v-if="detailOrder.status === 'CANCELLED'">订单已取消。</p><p v-else>{{ getFirstLegTransportModeLabel(detailOrder.transportMode) }} · {{ detailOrder.origin || '起运地待更新' }} → {{ detailOrder.destination || '目的地待更新' }}</p></div>
|
||||
</div>
|
||||
<div class="detail-heading-actions"><el-tag :type="getFirstLegStatusTone(detailOrder.status)" effect="light">{{ getFirstLegStatusLabel(detailOrder.status) }}</el-tag><el-button v-if="canEditOrder && canClientEditFirstLegOrder(detailOrder.status)" type="primary" plain :loading="openingEditor" @click="openEdit(detailOrder)"><Pencil :size="16" />编辑草稿</el-button><el-button v-if="canOfferCancellation(detailOrder)" type="danger" plain :loading="cancellingOrderId === detailOrder.id" :disabled="!!cancellingOrderId" @click="cancelOrder(detailOrder)">{{ pendingCancellation?.id === detailOrder.id ? '重试取消' : '取消订单' }}</el-button></div>
|
||||
</div>
|
||||
<section class="detail-section">
|
||||
<h3>订单与运输</h3>
|
||||
<dl class="order-detail-grid">
|
||||
<div><dt>入仓码</dt><dd><button v-if="detailOrder.businessSummary.inboundCode" class="inbound-code-link table-code" type="button" @click="openInboundCodeAssociation(detailOrder.businessSummary.inboundCode)">{{ detailOrder.businessSummary.inboundCode }}</button><span v-else>{{ detailOrder.status === 'DRAFT' ? '提交后生成' : '待生成' }}</span></dd></div>
|
||||
<div><dt>入仓码</dt><dd><button v-if="detailOrder.businessSummary.inboundCode" class="inbound-code-link table-code" type="button" @click="openInboundCodeAssociation(detailOrder.businessSummary.inboundCode)">{{ detailOrder.businessSummary.inboundCode }}</button><span v-else>{{ detailOrder.status === 'CANCELLED' ? '—' : detailOrder.status === 'DRAFT' ? '提交后生成' : '待生成' }}</span></dd></div>
|
||||
<div><dt>创建时间</dt><dd>{{ formatDateTime(detailOrder.createdAt) }}</dd></div>
|
||||
<div><dt>运输方式</dt><dd>{{ getFirstLegTransportModeLabel(detailOrder.transportMode) }}</dd></div>
|
||||
<div><dt>运输方式</dt><dd>{{ detailOrder.status === 'CANCELLED' && !detailOrder.transportMode ? '—' : getFirstLegTransportModeLabel(detailOrder.transportMode) }}</dd></div>
|
||||
<div><dt>贸易条款</dt><dd>{{ displayValue(detailOrder.tradeTerm) }}</dd></div>
|
||||
<div><dt>发货方式</dt><dd>{{ pickupMethodLabels[detailOrder.pickupMethod] }}</dd></div>
|
||||
<div><dt>预约提货时间</dt><dd>{{ detailOrder.pickupMethod === 'PICKUP' && detailOrder.requestedPickupAt ? formatDateTime(detailOrder.requestedPickupAt) : '-' }}</dd></div>
|
||||
@@ -2445,7 +2446,7 @@ async function searchOrders(model: QueryModel) {
|
||||
</dl>
|
||||
<div v-if="detailOrder.customerRemark" class="customer-remark"><strong>客户备注</strong><p>{{ detailOrder.customerRemark }}</p></div>
|
||||
</section>
|
||||
<section v-if="detailOrder.status !== 'DRAFT'" class="detail-section">
|
||||
<section v-if="detailOrder.status !== 'DRAFT' && detailOrder.status !== 'CANCELLED'" class="detail-section">
|
||||
<h3>关键业务摘要</h3>
|
||||
<dl class="fulfillment-summary">
|
||||
<div v-for="item in progressSummaryItems" :key="item.label"><dt>{{ item.label }}</dt><dd>{{ item.value }}</dd></div>
|
||||
@@ -2465,9 +2466,9 @@ async function searchOrders(model: QueryModel) {
|
||||
</div>
|
||||
</template>
|
||||
</OrderProgressPanel>
|
||||
<section class="detail-section">
|
||||
<section v-if="detailOrder.status !== 'CANCELLED' || detailOrder.expressCompanyName || detailOrder.trackingNumber" class="detail-section">
|
||||
<h3>履约快递信息</h3>
|
||||
<dl v-if="detailOrder.expressCompanyName || detailOrder.trackingNumber" class="express-information"><div><dt>快递公司</dt><dd>{{ detailOrder.expressCompanyName || '待平台补充' }}</dd></div><div><dt>快递单号</dt><dd class="table-code">{{ detailOrder.trackingNumber || '待平台补充' }}</dd></div></dl>
|
||||
<dl v-if="detailOrder.expressCompanyName || detailOrder.trackingNumber" class="express-information"><div><dt>快递公司</dt><dd>{{ detailOrder.expressCompanyName || (detailOrder.status === 'CANCELLED' ? '—' : '待平台补充') }}</dd></div><div><dt>快递单号</dt><dd class="table-code">{{ detailOrder.trackingNumber || (detailOrder.status === 'CANCELLED' ? '—' : '待平台补充') }}</dd></div></dl>
|
||||
<div v-else class="express-empty"><PackageCheck :size="20" /><div><strong>平台尚未维护快递信息</strong><span>快递公司和快递单号由平台后台维护,客户端仅只读展示。</span></div></div>
|
||||
</section>
|
||||
<section class="detail-section">
|
||||
@@ -2517,6 +2518,7 @@ async function searchOrders(model: QueryModel) {
|
||||
<el-empty v-else description="暂无货物明细" :image-size="56" />
|
||||
</section>
|
||||
<InboundBillingPanel
|
||||
v-if="detailOrder.status !== 'CANCELLED'"
|
||||
:data="inboundBilling"
|
||||
:loading="inboundBillingLoading"
|
||||
:unavailable="inboundBillingUnavailable"
|
||||
|
||||
Reference in New Issue
Block a user