This commit is contained in:
2026-08-21 11:20:09 +08:00
parent 595c998214
commit 6e9bb6e00c
45 changed files with 1051 additions and 329 deletions
@@ -2,7 +2,6 @@
import { computed, onMounted, ref } from 'vue'
import { Eye } from '@lucide/vue'
import { useRouter } from 'vue-router'
import { listPlatformTenants, type PlatformTenantResource } from '@/modules/iam'
import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
import AdminPage from '@/shared/components/AdminPage.vue'
import ApiErrorMeta from '@/shared/components/ApiErrorMeta.vue'
@@ -15,19 +14,15 @@ import { toLastMileOrderListItem } from '../lastMilePresentation'
import type { LastMileOrderListItem } from '../types'
const rows = ref<LastMileOrderListItem[]>([])
const customers = ref<PlatformTenantResource[]>([])
const loading = ref(false)
const customersLoading = ref(false)
const loadError = ref<ApiErrorDetails | null>(null)
const customersError = ref<ApiErrorDetails | null>(null)
const router = useRouter()
const page = ref(1)
const pageSize = ref(20)
const total = ref(0)
const statusTab = ref<'全部' | '待分配'>('全部')
const filters = ref<QueryModel>({ customerId: '', orderNo: '', inboundCode: '', warehouse: '', fbaWarehouse: '', orderType: '', owner: '', containerNo: '', status: '', consolidated: '', portEta: [] })
const filters = ref<QueryModel>({ orderNo: '', inboundCode: '', warehouse: '', fbaWarehouse: '', orderType: '', owner: '', containerNo: '', status: '', consolidated: '', portEta: [] })
const fields = computed<QueryField[]>(() => [
{ key: 'customerId', type: 'select', label: '客户名称', width: 240, placeholder: '请选择客户', props: { filterable: true, clearable: true, loading: customersLoading.value }, options: customers.value.map((item) => ({ label: item.tenantName, value: String(item.id) })) },
{ key: 'orderNo', type: 'input', label: '尾程单号', placeholder: '请输入尾程单号' },
{ key: 'inboundCode', type: 'input', label: '入仓码', placeholder: '请输入入仓码' },
{ key: 'warehouse', type: 'select', label: '海外仓', placeholder: '接口暂不支持', options: [], props: { disabled: true } },
@@ -55,7 +50,6 @@ const columns: DataTableColumn[] = [
{ key: 'transferWarehouse', prop: 'transferWarehouse', label: '转仓', minWidth: 140 },
{ key: 'fbaWarehouse', prop: 'fbaWarehouse', label: 'FBA仓库', minWidth: 130 },
{ key: 'containerNo', prop: 'containerNo', label: '集装箱号', minWidth: 150 },
{ key: 'containerStatus', prop: 'containerStatus', label: '货柜状态', width: 110 },
{ key: 'abnormal', prop: 'abnormal', label: '是否异常', width: 100 },
{ key: 'held', prop: 'held', label: '是否暂扣', width: 100 },
{ key: 'pallets', prop: 'pallets', label: '托数', width: 80, align: 'right' },
@@ -78,41 +72,12 @@ const columns: DataTableColumn[] = [
{ key: 'warehouseRemark', prop: 'warehouseRemark', label: '备注(仓库)', minWidth: 160 },
]
async function loadCustomers() {
customersLoading.value = true
customersError.value = null
try {
const records: PlatformTenantResource[] = []
let currentPage = 1
let pages = 1
do {
const result = await listPlatformTenants({ page: currentPage, size: 200, status: 'ACTIVE' })
records.push(...result.records)
pages = Math.max(1, result.pages)
currentPage += 1
} while (currentPage <= pages)
customers.value = records
} catch (error) {
customersError.value = getApiErrorDetails(error, '客户列表加载失败,请重试')
} finally {
customersLoading.value = false
}
}
async function load(model: QueryModel = filters.value) {
Object.assign(filters.value, model)
const customerId = String(filters.value.customerId || '').trim()
if (!customerId) {
rows.value = []
total.value = 0
loadError.value = null
return
}
loading.value = true
loadError.value = null
try {
const result = await listLastMileOrders({
customerId,
page: page.value,
size: pageSize.value,
orderNo: String(filters.value.orderNo || '').trim() || undefined,
@@ -120,12 +85,14 @@ async function load(model: QueryModel = filters.value) {
containerNo: String(filters.value.containerNo || '').trim() || undefined,
status: statusTab.value === '待分配' ? 'PENDING_ASSIGNMENT' : String(filters.value.status || '').trim() || undefined,
})
rows.value = result.records.map((item) => toLastMileOrderListItem(item, customerId))
rows.value = result.records.map(toLastMileOrderListItem)
total.value = result.total
} catch (error) {
rows.value = []
total.value = 0
loadError.value = getApiErrorDetails(error, '尾程订单加载失败,请重试')
loadError.value = error instanceof Error && error.message === '当前环境未签发海外访问令牌'
? { message: error.message }
: getApiErrorDetails(error, '尾程订单加载失败,请重试')
} finally {
loading.value = false
}
@@ -137,10 +104,10 @@ function changeStatusTab() { page.value = 1; void load() }
function openDetail(source: object) {
const row = source as LastMileOrderListItem
void router.push({ name: 'overseas-last-mile-order-detail', params: { orderId: row.id }, query: { customerId: row.customerId } })
void router.push({ name: 'overseas-last-mile-order-detail', params: { orderId: row.id } })
}
onMounted(loadCustomers)
onMounted(() => { void load() })
</script>
<template>
@@ -154,12 +121,12 @@ onMounted(loadCustomers)
<QueryToolbar v-model="filters" :fields="fields" :loading="loading" ariaLabel="尾程订单筛选" preference-key="overseas-last-mile-orders-query" @search="search" @reset="reset" />
</section>
</template>
<template v-if="customersError || loadError" #state>
<LoadErrorState title="尾程订单加载失败" :message="(customersError || loadError)?.message" :loading="customersLoading || loading" @retry="customersError ? loadCustomers() : load()">
<template #details><ApiErrorMeta :details="(customersError || loadError)!" /></template>
<template v-if="loadError" #state>
<LoadErrorState title="尾程订单加载失败" :message="loadError.message" :loading="loading" @retry="load">
<template #details><ApiErrorMeta :details="loadError" /></template>
</LoadErrorState>
</template>
<section v-if="!customersError && !loadError" class="surface-panel table-panel"><DataTable v-model:page="page" v-model:page-size="pageSize" :data="rows" :columns="columns" :loading="loading" :total="total" preference-key="overseas-last-mile-orders" row-key="id" :empty-text="filters.customerId ? '暂无尾程订单' : '请先选择客户后查询'" @update:page="load()" @update:page-size="page = 1; load()">
<section v-if="!loadError" class="surface-panel table-panel"><DataTable v-model:page="page" v-model:page-size="pageSize" :data="rows" :columns="columns" :loading="loading" :total="total" preference-key="overseas-last-mile-orders" row-key="id" empty-text="暂无尾程订单" @update:page="load()" @update:page-size="page = 1; load()">
<template #actions="{ row }"><el-button size="small" plain type="primary" @click="openDetail(row)"><Eye :size="15" />查看</el-button></template>
<template #pagination-left>共 {{ total }} 条尾程订单</template>
</DataTable></section>