feat(lastleg): expose commercial source and booking references

This commit is contained in:
2026-10-09 16:11:59 +08:00
parent 3a917324f1
commit 00a186b37c
13 changed files with 134 additions and 14 deletions
@@ -16,6 +16,7 @@ import { createLastMileOrderFee, getLastMileOrder, type LastMileOrderDetailDto }
import { relabelApplicationStatusLabel, relabelBusinessStatusLabel, formatOverseasDateTime, lastMileOrderReference, lastMileOrderTypeLabel, lastMileStatusLabel, packageDifferenceText } from '../lastMilePresentation'
import { overseasWarehousePermissions as permission } from '../permissions'
import OverseasDetailShell from '../components/OverseasDetailShell.vue'
import { businessOrderLink } from '../businessOrderLink'
import OrderReferenceText from '../components/OrderReferenceText.vue'
import WarehouseTransferFulfillmentPanel from '../components/WarehouseTransferFulfillmentPanel.vue'
@@ -58,7 +59,7 @@ const referenceValue = computed(() => lastMileOrderReference(detail.value?.order
const orderFields = computed<DetailField[]>(() => {
const order = detail.value?.order
const fields: DetailField[] = [
{ label: '订单类型', value: text(order?.orderTypeName || lastMileOrderTypeLabel(order?.orderType)) },
{ label: '履约类型', value: text(order?.orderTypeName || lastMileOrderTypeLabel(order?.orderType)) },
{ label: '入仓码', value: text(order?.inboundCode) },
{ label: '货主', value: text(order?.customerName) },
{ label: '海外仓', value: text(order?.overseasWarehouseName) },
@@ -94,6 +95,7 @@ const containerFields = computed<DetailField[]>(() => {
{ label: '货柜节点', value: containerNodeLabel(order?.containerNode) },
]
})
const commercialLink = computed(() => businessOrderLink(detail.value?.order.businessSource?.businessType, detail.value?.order.businessSource?.businessOrderNo, access.can))
const basicFields = computed(() => [...orderFields.value, ...containerFields.value])
const overviewFields = computed(() => {
const order = detail.value?.order
@@ -211,6 +213,15 @@ onMounted(load)
<section v-else v-loading="loading" class="detail-surface" :aria-busy="loading">
<el-tabs v-model="activeTab" class="detail-tabs density-element-tabs density-contained-tabs">
<el-tab-pane name="basic"><template #label><span class="density-tab-icon" aria-hidden="true">📋</span><span>基本信息</span></template>
<section aria-label="商业来源与关联单据">
<h2 class="source-heading">关联单据</h2>
<dl class="detail-fields density-fields">
<div class="wide"><dt>业务来源</dt><dd>{{ text(detail?.order.businessSource?.label) }}</dd></div>
<div class="wide"><dt>关联商业单号</dt><dd><el-button v-if="commercialLink" link type="primary" @click="router.push(commercialLink)">{{ detail?.order.businessSource?.businessOrderNo }}</el-button><span v-else>{{ text(detail?.order.businessSource?.businessOrderNo) }}</span></dd></div>
<div class="wide"><dt>外接预订号</dt><dd>{{ text(detail?.order.businessSource?.externalBookingNo) }}</dd></div>
<div class="wide"><dt>来源单号</dt><dd>{{ text(detail?.order.sourceOrderNo) }}</dd></div>
</dl>
</section>
<dl class="detail-fields density-fields" aria-label="基本信息">
<div v-for="field in basicFields" :key="field.label" :class="{ wide: field.wide }"><dt>{{ field.label }}</dt><dd :class="{ 'detail-field-value--business': isSingleLineBusinessField(field), 'package-difference--nonzero': isNonzeroDifference(field) }" :title="isSingleLineBusinessField(field) ? String(field.value) : undefined">{{ field.value }}</dd></div>
</dl>
@@ -241,6 +252,7 @@ onMounted(load)
</template>
<style scoped>
.source-heading { margin: 0; padding: var(--admin-space-3); font-size: var(--admin-font-section); font-weight: 600; }
.detail-fields > div.wide { grid-column: span 2; }
.detail-field-value--business { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.package-difference--nonzero { color: var(--el-color-danger); font-weight: 600; }