@@ -23,6 +23,7 @@ import ApiErrorMeta from '@/shared/components/ApiErrorMeta.vue'
import AppDialog from '@/shared/components/AppDialog.vue'
import DataTable , { type DataTableColumn } from '@/shared/components/DataTable.vue'
import LoadErrorState from '@/shared/components/LoadErrorState.vue'
import LineClampText from '@/shared/components/LineClampText.vue'
import QueryToolbar , { type QueryField , type QueryModel } from '@/shared/components/QueryToolbar.vue'
import StatusBadge from '@/shared/components/StatusBadge.vue'
import {
@@ -33,8 +34,6 @@ import {
type FilterModel = QueryModel & {
tenantId : string
keyword : string
orderNo : string
mainStatus : UnifiedOrderMainStatus | ''
receivingWarehouseId : string
destinationWarehouseId : string
@@ -127,24 +126,6 @@ const receivingWarehouseOptions = computed(() => warehouses.value
. map ( ( warehouse ) => ( { value : String ( warehouse . id ) , label : ` ${ warehouse . warehouseName } ( ${ warehouse . warehouseCode } ) ` } ) ) )
const primaryQueryFields = computed < QueryField [ ] > ( ( ) => [
{
key : 'tenantId' ,
type : 'select' ,
width : 220 ,
label : '公司' ,
placeholder : customerLoadError . value ? '客户列表加载失败' : customerLoading . value ? '正在加载客户' : '全部客户' ,
options : customers . value . map ( ( customer ) => ( {
value : String ( customer . id ) ,
label : ` ${ customer . legalName ? . trim ( ) || customer . tenantName } ( ${ customer . tenantCode || '无客户编码' } ) ` ,
} ) ) ,
props : { 'aria-label' : '客户' , filterable : true , loading : customerLoading . value , disabled : Boolean ( customerLoadError . value ) } ,
} ,
{ key : 'keyword' , type : 'input' , width : 260 , label : '综合搜索' , placeholder : '请输入订单号' , props : { 'aria-label' : '订单号关键词' } } ,
{ key : 'orderNo' , type : 'input' , width : 220 , label : '订单号' , placeholder : '请输入订单号' , props : { 'aria-label' : '订单号' } } ,
{ key : 'createdRange' , type : 'daterange' , width : 300 , label : '创建日期' , placeholder : '创建日期范围' , props : { 'aria-label' : '创建日期范围' } } ,
] )
const advancedQueryFields = computed < QueryField [ ] > ( ( ) => [
{ key : 'receivingWarehouseId' , type : 'select' , width : 220 , label : '定位仓库' , placeholder : warehouseLoadError . value ? '仓库加载失败' : '请选择定位仓库' , options : receivingWarehouseOptions . value , props : { 'aria-label' : '定位仓库' , filterable : true , loading : warehouseLoading . value , disabled : Boolean ( warehouseLoadError . value ) } } ,
{ key : 'destinationWarehouseId' , type : 'select' , width : 220 , label : '交货仓' , placeholder : warehouseLoadError . value ? '仓库加载失败' : '请选择交货仓' , options : warehouseOptions . value , props : { 'aria-label' : '交货仓' , filterable : true , loading : warehouseLoading . value , disabled : Boolean ( warehouseLoadError . value ) } } ,
{ key : 'inboundCode' , type : 'input' , width : 220 , label : '入仓码' , placeholder : '请输入入仓码' , props : { 'aria-label' : '入仓码' } } ,
@@ -152,11 +133,26 @@ const advancedQueryFields = computed<QueryField[]>(() => [
{ value : 'SUBMITTED' , label : '待审核' } , { value : 'APPROVED' , label : '已审核' } ,
{ value : 'ACCEPTED' , label : '已受理' } , { value : 'PROCESSING' , label : '处理中' } , { value : 'COMPLETED' , label : '已完成' } ,
] , props : { 'aria-label' : '订单状态' } } ,
] )
const advancedQueryFields = computed < QueryField [ ] > ( ( ) => [
{ key : 'expectedArrivalDate' , type : 'date' , width : 190 , label : '预计到达时间' , placeholder : '请选择预计到达日期' , props : { 'aria-label' : '预计到达时间' } } ,
{ key : 'feeReviewStatus' , type : 'select' , width : 190 , label : '费用审核状态' , placeholder : '请选择费用审核状态' , options : [
{ value : 'UNRECORDED' , label : '未录入' } , { value : 'PENDING' , label : '待审核' } ,
{ value : 'APPROVED' , label : '审核通过' } , { value : 'REJECTED' , label : '审核驳回' } ,
] , props : { 'aria-label' : '费用审核状态' } } ,
{
key : 'tenantId' ,
type : 'select' ,
width : 220 ,
label : '公司' ,
placeholder : customerLoadError . value ? '客户列表加载失败' : customerLoading . value ? '正在加载客户' : '请选择公司' ,
options : customers . value . map ( ( customer ) => ( {
value : String ( customer . id ) ,
label : ` ${ customer . legalName ? . trim ( ) || customer . tenantName } ( ${ customer . tenantCode || '无客户编码' } ) ` ,
} ) ) ,
props : { 'aria-label' : '公司' , filterable : true , loading : customerLoading . value , disabled : Boolean ( customerLoadError . value ) } ,
} ,
{ key : 'containerNo' , type : 'input' , width : 210 , label : '集装箱号' , placeholder : '请输入集装箱号' , props : { 'aria-label' : '集装箱号' } } ,
{ key : 'cabinetNo' , type : 'input' , width : 190 , label : '柜号' , placeholder : '请输入柜号' , props : { 'aria-label' : '柜号' } } ,
{ key : 'channelName' , type : 'input' , width : 210 , label : '渠道' , placeholder : '请输入渠道名称' , props : { 'aria-label' : '渠道' } } ,
@@ -168,6 +164,7 @@ const advancedQueryFields = computed<QueryField[]>(() => [
{ value : 'APPROVED' , label : '审核通过' } , { value : 'REJECTED' , label : '审核驳回' } ,
] , props : { 'aria-label' : '测量数据审核状态' } } ,
{ key : 'fbaCode' , type : 'input' , width : 220 , label : '商品 FBA 编码' , placeholder : '请输入商品 FBA 编码' , props : { 'aria-label' : '商品 FBA 编码' } } ,
{ key : 'createdRange' , type : 'daterange' , width : 300 , label : '创建日期' , placeholder : '创建日期范围' , props : { 'aria-label' : '创建日期范围' } } ,
] )
const allQueryFields = computed ( ( ) => [ ... primaryQueryFields . value , ... advancedQueryFields . value ] )
@@ -234,7 +231,7 @@ const columns: DataTableColumn[] = [
function emptyFilters ( ) : FilterModel {
return {
tenantId : '' , keyword : '' , orderNo : '' , mainStatus : '' , receivingWarehouseId : '' , destinationWarehouseId : '' ,
tenantId : '' , mainStatus : '' , receivingWarehouseId : '' , destinationWarehouseId : '' ,
inboundCode : '' , internalOrderStatus : '' , expectedArrivalDate : '' , feeReviewStatus : '' , channelName : '' ,
containerNo : '' , cabinetNo : '' , sailingDate : '' , loaded : '' , fullContainer : '' , measurementReviewStatus : '' ,
fbaCode : '' , createdRange : [ ] ,
@@ -622,8 +619,6 @@ async function loadOrders() {
const range = filters . value . createdRange
const result = await listPlatformUnifiedOrders ( {
tenantId : filters . value . tenantId || undefined ,
keyword : trimmed ( filters . value . keyword ) ,
orderNo : trimmed ( filters . value . orderNo ) ,
mainStatus : filters . value . mainStatus || undefined ,
receivingWarehouseId : filters . value . receivingWarehouseId || undefined ,
destinationWarehouseId : filters . value . destinationWarehouseId || undefined ,
@@ -918,21 +913,21 @@ onMounted(() => {
< section class = "measurement-section" >
< button type = "button" class = "measurement-section-title" :aria-expanded = "!measurementCollapsed.customer" @click ="toggleMeasurementSection('customer')" > < h3 > 一 、 客户下单数据 < / h3 > < span class = "measurement-section-summary" > < span > 总件数 : { { measurementTotals ( detail . order . cargoes , true ) . count ? ? '—' } } < / span > < span > 总毛重 : { { formatNumber ( measurementTotals ( detail . order . cargoes , true ) . gross ) } } < / span > < span > 总体积 : { { formatNumber ( measurementTotals ( detail . order . cargoes , true ) . volume , 6 ) } } < / span > < span > 总材积重 : { { formatNumber ( measurementTotals ( detail . order . cargoes , true ) . volumetric ) } } < / span > < span > 重量体积 : { { formatNumber ( measurementTotals ( detail . order . cargoes , true ) . weightVolume , 6 ) } } < / span > < / span > < ChevronUp v-if = "!measurementCollapsed.customer" :size="18" /><ChevronDown v-else :size="18" / > < / button >
< div v-if = "!measurementCollapsed.customer" >
< div class = "detail-table-wrap" > < el-table :data = "detail.order.cargoes" empty -text = " 暂无客户下单数据 " > < el-table-column v-for = "column in customerMeasurementColumns" :key="column.key" :label="column.label" :prop="column.key" min-width="120"><template #default="{ row }" > {{ measurementValue ( row as Record < string , unknown > , column . key , true ) } } < / template > < / el-table-column > < / el-table > < / div >
< div class = "detail-table-wrap" > < el-table :data = "detail.order.cargoes" empty -text = " 暂无客户下单数据 " > < el-table-column v-for = "column in customerMeasurementColumns" :key="column.key" :label="column.label" :prop="column.key" min-width="120"><template #default="{ row }"><LineClampText v-if="column.key === 'remark'" :content="measurementValue(row as Record<string, unknown>, column.key, true)" / > < template v-else > {{ measurementValue ( row as Record < string , unknown > , column . key , true ) } } < / template > < / template > < / el-table-column > < / el-table > < / div >
< div class = "measurement-total" > < strong > 合计 < / strong > < span > 箱数 : { { measurementTotals ( detail . order . cargoes , true ) . count ? ? '—' } } < / span > < span > 总毛重 : { { formatNumber ( measurementTotals ( detail . order . cargoes , true ) . gross ) } } < / span > < span > 总体积 : { { formatNumber ( measurementTotals ( detail . order . cargoes , true ) . volume , 6 ) } } < / span > < span > 总材积 : { { formatNumber ( measurementTotals ( detail . order . cargoes , true ) . volumetric ) } } < / span > < / div >
< / div >
< / section >
< section class = "measurement-section" >
< button type = "button" class = "measurement-section-title" :aria-expanded = "!measurementCollapsed.outer" @click ="toggleMeasurementSection('outer')" > < h3 > 二 、 外箱规数据 < / h3 > < span class = "measurement-section-summary" > < span > 总件数 : { { measurementTotals ( ( measurementDetail ? . items || [ ] ) as unknown as Record < string , unknown > [ ] ) . count ? ? '—' } } < / span > < span > 总毛重 : { { formatNumber ( measurementTotals ( ( measurementDetail ? . items || [ ] ) as unknown as Record < string , unknown > [ ] ) . gross ) } } < / span > < span > 总体积 : { { formatNumber ( measurementTotals ( ( measurementDetail ? . items || [ ] ) as unknown as Record < string , unknown > [ ] ) . volume , 6 ) } } < / span > < span > 总材积重 : { { formatNumber ( measurementTotals ( ( measurementDetail ? . items || [ ] ) as unknown as Record < string , unknown > [ ] ) . volumetric ) } } < / span > < span > 重量体积 : { { formatNumber ( measurementTotals ( ( measurementDetail ? . items || [ ] ) as unknown as Record < string , unknown > [ ] ) . weightVolume , 6 ) } } < / span > < / span > < ChevronUp v-if = "!measurementCollapsed.outer" :size="18" /><ChevronDown v-else :size="18" / > < / button >
< div v-if = "!measurementCollapsed.outer" >
< div v-loading = "measurementLoading" class="detail-table-wrap"><el-table :data="measurementDetail?.items || []" empty-text="暂无外箱规数据"><el-table-column v-for="column in measuredColumns" :key="column.key" :label="column.label" :prop="column.key" min-width="120"><template #default="{ row }" > {{ measurementValue ( row as Record < string , unknown > , column . key ) } } < / template > < / el-table-column > < / el-table > < / div >
< div v-loading = "measurementLoading" class="detail-table-wrap"><el-table :data="measurementDetail?.items || []" empty-text="暂无外箱规数据"><el-table-column v-for="column in measuredColumns" :key="column.key" :label="column.label" :prop="column.key" min-width="120"><template #default="{ row }"><LineClampText v-if="column.key === 'remark'" :content="measurementValue(row as Record<string, unknown>, column.key)" / > < template v-else > {{ measurementValue ( row as Record < string , unknown > , column . key ) } } < / template > < / template > < / el-table-column > < / el-table > < / div >
< div class = "measurement-total" > < strong > 合计 < / strong > < span > 箱数 : { { measurementTotals ( ( measurementDetail ? . items || [ ] ) as unknown as Record < string , unknown > [ ] ) . count ? ? '—' } } < / span > < span > 总毛重 : { { formatNumber ( measurementTotals ( ( measurementDetail ? . items || [ ] ) as unknown as Record < string , unknown > [ ] ) . gross ) } } < / span > < span > 总体积 : { { formatNumber ( measurementTotals ( ( measurementDetail ? . items || [ ] ) as unknown as Record < string , unknown > [ ] ) . volume , 6 ) } } < / span > < span > 总材积 : { { formatNumber ( measurementTotals ( ( measurementDetail ? . items || [ ] ) as unknown as Record < string , unknown > [ ] ) . volumetric ) } } < / span > < / div >
< / div >
< / section >
< section class = "measurement-section" >
< button type = "button" class = "measurement-section-title" :aria-expanded = "!measurementCollapsed.actual" @click ="toggleMeasurementSection('actual')" > < h3 > 三 、 实际测量数据 < / h3 > < span class = "measurement-section-summary" > < span > 总件数 : { { measurementDetail ? . actualPackageCount ? ? '—' } } < / span > < span > 总毛重 : { { formatNumber ( measurementDetail ? . actualGrossWeightKg ) } } < / span > < span > 总体积 : { { formatNumber ( measurementDetail ? . actualVolumeCbm , 6 ) } } < / span > < span > 总材积重 : { { formatNumber ( measurementDetail ? . volumeWeightKg ) } } < / span > < span > 重量体积 : { { formatNumber ( measurementDetail ? . actualVolumeCbm , 6 ) } } < / span > < / span > < ChevronUp v-if = "!measurementCollapsed.actual" :size="18" /><ChevronDown v-else :size="18" / > < / button >
< div v-if = "!measurementCollapsed.actual" >
< div v-loading = "measurementLoading" class="detail-table-wrap"><el-table :data="measurementDetail?.items || []" empty-text="暂无实际测量数据"><el-table-column v-for="column in measuredColumns" :key="column.key" :label="column.label" :prop="column.key" min-width="120"><template #default="{ row }" > {{ measurementValue ( row as Record < string , unknown > , column . key ) } } < / template > < / el-table-column > < / el-table > < / div >
< div v-loading = "measurementLoading" class="detail-table-wrap"><el-table :data="measurementDetail?.items || []" empty-text="暂无实际测量数据"><el-table-column v-for="column in measuredColumns" :key="column.key" :label="column.label" :prop="column.key" min-width="120"><template #default="{ row }"><LineClampText v-if="column.key === 'remark'" :content="measurementValue(row as Record<string, unknown>, column.key)" / > < template v-else > {{ measurementValue ( row as Record < string , unknown > , column . key ) } } < / template > < / template > < / el-table-column > < / el-table > < / div >
< div class = "measurement-total" > < strong > 合计 < / strong > < span > 箱数 : { { measurementDetail ? . actualPackageCount ? ? '—' } } < / span > < span > 总毛重 : { { formatNumber ( measurementDetail ? . actualGrossWeightKg ) } } < / span > < span > 总体积 : { { formatNumber ( measurementDetail ? . actualVolumeCbm , 6 ) } } < / span > < span > 总材积 : { { formatNumber ( measurementDetail ? . volumeWeightKg ) } } < / span > < / div >
< div class = "measurement-media" > < h4 > 测量图片 < / h4 > < div v-if = "measurementImageUrls.length" class="measurement-media-grid"><el-image v-for="url in measurementImageUrls" :key="url" :src="url" fit="contain" :preview-src-list="measurementImageUrls" class="measurement-media-image" /></div><el-empty v-else description="暂无测量图片" :image-size="48" /><h4>测量视频</h4><el-empty description="暂无测量视频" :image-size="48" / > < / div >
< / div >
@@ -966,7 +961,7 @@ onMounted(() => {
> { { tab . label } } < / button >
< / div >
< QueryToolbar id = "unified-orders-advanced-filters" v-model = "filters" ariaLabel="订单列表筛选" :fields="queryFields" :available-fields="allQueryFields" preference-key="unified-orders-query" :search-on-reset="false" @search="search" @reset="reset" >
< QueryToolbar id = "unified-orders-advanced-filters" v-model = "filters" ariaLabel="订单列表筛选" :fields="queryFields" :available-fields="allQueryFields" preference-key="unified-orders-query-v2 " :search-on-reset="false" @search="search" @reset="reset" >
< template # actions >
< el-button :aria-expanded = "showAdvancedFilters" aria -controls = " unified -orders -advanced -filters " @click ="showAdvancedFilters = !showAdvancedFilters" >
< SlidersHorizontal :size = "16" / > { { showAdvancedFilters ? '收起筛选' : '高级筛选' } }
@@ -1004,7 +999,7 @@ onMounted(() => {
< / template >
< template # orderStatus = "{ row }" > < StatusBadge : status = "orderStatusLabel((row as UnifiedOrderResource).internalOrderStatus || (row as UnifiedOrderResource).mainStatus)" / > < / template >
< template # measurementReviewStatus = "{ row }" > < StatusBadge : status = "measurementStatusLabel((row as UnifiedOrderResource).measurement?.reviewStatus)" / > < / template >
< template # field = "{ row, column }" > { { displayField ( row as UnifiedOrderResource , column . property ) } } < / template >
< template # field = "{ row, column }" > < LineClampText v-if = "['customerRemark', 'latestInternalNote'].includes(String(column.property))" :content="displayField(row as UnifiedOrderResource, column.property)" :lines="2" / > < template v-else > {{ displayField ( row as UnifiedOrderResource , column.property ) }} < / template > < / template >
< template # order = "{ row }" > < div class = "primary-cell" > < strong > { { ( row as UnifiedOrderResource ) . orderNo || ` 订单 ${ ( row as UnifiedOrderResource ) . orderId } ` } } < / strong > < span v-if = "(row as UnifiedOrderResource).inboundCode" > 入仓码 {{ ( row as UnifiedOrderResource ) .inboundCode }} < / span > < / div > < / template >
< template # mainStatus = "{ row }" > < StatusBadge : status = "statusLabel((row as UnifiedOrderResource).mainStatus)" / > < / template >
< template # customer = "{ row }" > < div class = "primary-cell" > < strong > { { customerName ( row as UnifiedOrderResource ) } } < / strong > < span > 客户 ID { { ( row as UnifiedOrderResource ) . tenantId } } < / span > < / div > < / template >