feat(orders): show actual pooled freight fulfillment
This commit is contained in:
@@ -18,6 +18,7 @@ import {
|
||||
type TransportSummary,
|
||||
} from '../api/businessOrders'
|
||||
import { CONTAINER_SPECIFICATIONS, DEFAULT_CONTAINER_TYPE } from '../containerSpecifications'
|
||||
import { poolOrderStatusLabels } from '../fleetArrangement'
|
||||
|
||||
const props = withDefaults(defineProps<{ kind: CrossBorderBusinessKind; createPage?: boolean; detailPage?: boolean }>(), { createPage: false, detailPage: false })
|
||||
const auth = useAuthStore()
|
||||
@@ -105,6 +106,7 @@ function transportColumns(looseboard: boolean): ColumnDefinition[] {
|
||||
{ key: 'budgetAmount', label: '预算总价', width: 110 },
|
||||
{ key: 'requestedDate', label: '要求时间', width: 120 },
|
||||
{ key: 'status', label: '状态', width: 130 },
|
||||
{ key: 'fleetArrangement', label: '承运安排', width: 190 },
|
||||
]
|
||||
}
|
||||
|
||||
@@ -115,6 +117,7 @@ const submitKey = ref('')
|
||||
const error = ref('')
|
||||
const rows = ref<BusinessRow[]>([])
|
||||
const detail = ref<BusinessDetail | null>(null)
|
||||
const fleetArrangement = computed(() => detail.value && props.kind !== 'procurement' ? (detail.value as TransportDetail).summary.fleetArrangement : null)
|
||||
const formRef = ref<FormInstance>()
|
||||
const query = reactive({ page: 1, size: 20, orderNo: '', routeKeyword: '', status: '', productName: '', purchaseCategory: '' })
|
||||
const total = ref(0)
|
||||
@@ -157,6 +160,7 @@ const queryFields = computed<QueryField[]>(() => [
|
||||
{ label: '部分出库', value: 'PARTIALLY_OUTBOUND' },
|
||||
{ label: '全部出库', value: 'OUTBOUNDED' },
|
||||
{ label: '待接单', value: 'PENDING_ACCEPTANCE' },
|
||||
...(props.kind === 'procurement' ? [] : Object.entries(poolOrderStatusLabels).filter(([value]) => !['IN_TRANSIT', 'COMPLETED', 'CANCELLED'].includes(value)).map(([value, label]) => ({ value, label }))),
|
||||
{ label: '处理中', value: 'PROCESSING' },
|
||||
{ label: '运输中', value: 'IN_TRANSIT' },
|
||||
{ label: '已完成', value: 'COMPLETED' },
|
||||
@@ -215,7 +219,7 @@ const tableColumns = computed<DataTableColumn[]>(() => [
|
||||
...configuration.value.columns.map((column) => ({
|
||||
...column,
|
||||
prop: column.key,
|
||||
slotName: ['orderNo', 'status'].includes(column.key) ? column.key : undefined,
|
||||
slotName: ['orderNo', 'status', 'fleetArrangement'].includes(column.key) ? column.key : undefined,
|
||||
formatter: (row: object) => displayCell(row, column.key),
|
||||
})),
|
||||
])
|
||||
@@ -242,6 +246,7 @@ function yesNo(value: unknown) { return value === 'YES' ? '是' : value === 'NO'
|
||||
function transportTypeLabel(value: unknown) { return ({ PORT_PICKUP: '港口提柜', WAREHOUSE_TO_WAREHOUSE: '仓到仓', WAREHOUSE_TO_DOOR: '仓到门' } as Record<string, string>)[String(value)] || text(value) }
|
||||
function transportModeLabel(value: unknown) { return ({ SHARED_TRUCK: '拼车', PRIORITY_CONSOLIDATION: '优先拼载' } as Record<string, string>)[String(value)] || text(value) }
|
||||
function statusLabel(value: unknown) {
|
||||
if (poolOrderStatusLabels[String(value)]) return poolOrderStatusLabels[String(value)]
|
||||
return ({ PENDING_REVIEW: '待审核', APPROVED: '已通过', REJECTED: '已拒绝', PENDING_OUTBOUND: '待出库', PARTIALLY_OUTBOUND: '部分出库', OUTBOUNDED: '全部出库', PENDING_ACCEPTANCE: '待接单', PROCESSING: '处理中', IN_TRANSIT: '运输中', COMPLETED: '已完成', CANCELLED: '已取消' } as Record<string, string>)[String(value)] || text(value)
|
||||
}
|
||||
function statusTone(value: unknown) {
|
||||
@@ -283,13 +288,14 @@ async function load() {
|
||||
}
|
||||
|
||||
function resetQuery() {
|
||||
const reloadDirectly = query.page === 1
|
||||
Object.assign(query, { page: 1, orderNo: '', routeKeyword: '', status: '', productName: '', purchaseCategory: '' })
|
||||
void load()
|
||||
if (reloadDirectly) void load()
|
||||
}
|
||||
|
||||
function searchOrders() {
|
||||
query.page = 1
|
||||
void load()
|
||||
if (query.page !== 1) query.page = 1
|
||||
else void load()
|
||||
}
|
||||
|
||||
function getRowActions(candidate: object): TableAction[] {
|
||||
@@ -397,6 +403,7 @@ onMounted(() => { if (props.detailPage) void loadDetail(); else if (!props.creat
|
||||
<template v-if="error" #error><div class="business-load-error" role="alert"><span>{{ error }}</span><el-button size="small" @click="load">重新加载</el-button></div></template>
|
||||
<template #orderNo="{ row }"><button class="business-order-link" type="button" @click="openDetail(row)">{{ (row as BusinessRow).orderNo }}</button></template>
|
||||
<template #status="{ row }"><el-tag :type="statusTone((row as BusinessRow).status)" effect="light" size="small">{{ statusLabel((row as BusinessRow).status) }}</el-tag></template>
|
||||
<template #fleetArrangement="{ row }"><template v-if="(row as TransportSummary).fleetArrangement"><div>{{ poolOrderStatusLabels[(row as TransportSummary).fleetArrangement!.fulfillmentStage] || '待核对履约进度' }}</div><small>{{ dateTime((row as TransportSummary).fleetArrangement!.plannedDepartureAt) }}</small></template><span v-else>—</span></template>
|
||||
</DataTable>
|
||||
</div>
|
||||
</template>
|
||||
@@ -413,6 +420,24 @@ onMounted(() => { if (props.detailPage) void loadDetail(); else if (!props.creat
|
||||
<div v-for="field in detailFields" :key="String(field[0])" :class="detailFieldClass(field[0])"><dt>{{ field[0] }}</dt><dd>{{ text(field[1]) }}</dd></div>
|
||||
</dl>
|
||||
</section>
|
||||
<section v-if="!error && fleetArrangement" class="business-detail-section" aria-label="承运安排">
|
||||
<h3>承运安排</h3><p>{{ fleetArrangement.readOnlyReason }}</p>
|
||||
<dl class="detail-grid">
|
||||
<div><dt>预订号</dt><dd>{{ fleetArrangement.bookingNo }}</dd></div>
|
||||
<div><dt>计划发车</dt><dd>{{ dateTime(fleetArrangement.plannedDepartureAt) }}</dd></div>
|
||||
<div><dt>起运仓</dt><dd>{{ text(fleetArrangement.originWarehouseName) }}</dd></div>
|
||||
<div><dt>目的地</dt><dd>{{ text(fleetArrangement.destinationLabel) }}</dd></div>
|
||||
<div><dt>交货方式</dt><dd>{{ fleetArrangement.deliveryMode === 'SELF_DELIVERY' ? '自行送至起运仓' : '线下安排提货至起运仓' }}</dd></div>
|
||||
<div><dt>履约进度</dt><dd>{{ poolOrderStatusLabels[fleetArrangement.fulfillmentStage] || '待核对履约进度' }}</dd></div>
|
||||
<div><dt>更新时间</dt><dd>{{ dateTime(fleetArrangement.stageOccurredAt) }}</dd></div>
|
||||
<div><dt>约定运费(非实收)</dt><dd>{{ money(fleetArrangement.agreedFreightAmount, fleetArrangement.currency) }}</dd></div>
|
||||
<div><dt>来货单号</dt><dd>{{ text(fleetArrangement.incomingNo) }}</dd></div>
|
||||
<div><dt>派送单号</dt><dd>{{ text(fleetArrangement.deliveryNo) }}</dd></div>
|
||||
<div><dt>已签 / 未签 / 退回箱数</dt><dd>{{ fleetArrangement.signedPackages ?? '—' }} / {{ fleetArrangement.unsignedPackages ?? '—' }} / {{ fleetArrangement.returnedPackages ?? '—' }}</dd></div>
|
||||
<div class="is-wide"><dt>交货说明</dt><dd>{{ text(fleetArrangement.deliveryInstructions) }}</dd></div>
|
||||
<div v-if="fleetArrangement.exceptionSummary" class="is-wide"><dt>履约说明</dt><dd>{{ fleetArrangement.exceptionSummary }}</dd></div>
|
||||
</dl>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<el-card v-else shadow="never" class="form-card">
|
||||
|
||||
Reference in New Issue
Block a user