发布:将已验 TEST 功能更新至既有生产灰度(2026-10-23) #15
@@ -2,7 +2,7 @@ import { apiRequest, apiBlobRequest } from '@/api/http'
|
||||
import type { PageResult } from './warehouseServices'
|
||||
|
||||
export interface ReturnOrderSummary {
|
||||
relabelApplications?: Array<{ relabelNo: string; status: string; quantity: number; createdAt: string }>
|
||||
relabelApplications?: Array<{ relabelNo: string; status: string; quantity: number; quantityUnit?: string; createdAt: string }>
|
||||
returnNo: string; overseasWarehouseId: string; warehouseContactName?: string; warehouseContactPhone?: string; customerReferenceNo?: string; status: string
|
||||
skuTypes: number; expectedQuantity: number; receivedQuantity: number; needRelabel: boolean; relabelNo?: string; relabelStatus?: string; createdAt: string
|
||||
}
|
||||
@@ -13,13 +13,13 @@ export interface ReturnReceipt {
|
||||
receiptNo: string; receiptBatchNo: string; palletCode?: string; trackingNo?: string; startedBy: 'RETURN_NO' | 'SKU'
|
||||
receivedQuantity: number; operatorName?: string; signedAt: string; unitType: 'PALLET' | 'BOX' | 'PARCEL'; unitCode?: string; boxCount: number
|
||||
items: Array<{ skuCode: string; productNameZh?: string; quantity: number; boxCount: number }>; cartonMark?: string; printableHtml?: string
|
||||
labels?: Array<{ cartonMark: string; printableHtml: string }>
|
||||
labels?: Array<{ cartonMark: string; printableHtml: string }>; length?: number | null; width?: number | null; height?: number | null; weight?: number | null
|
||||
labelRepairRequired?: boolean
|
||||
}
|
||||
export interface ReturnPallet { palletCode: string; unitType: 'PALLET' | 'BOX'; unitCode: string; skuTypes: number; totalQuantity: number; totalBoxCount: number; length?: number; width?: number; height?: number; weight?: number; volumeCbm?: number; items: Array<{ skuCode: string; productNameZh?: string; quantity: number; boxCount: number }> }
|
||||
export interface ReturnPhoto { fileId: number; fileName: string; contentType: string; sizeBytes: number }
|
||||
export interface ReturnPackingDetail { sourceCartonMark: string; targetCartonMark: string; returnNo: string; skuCode: string; quantity: number; createdAt: string }
|
||||
export interface ReturnReceiptCarton { receiptNo: string; palletCode?: string; cartonMark: string; countStatus: 'PENDING' | 'CONFIRMED' | 'UNRECORDED'; countedAt?: string; items: ReturnReceipt['items'] }
|
||||
export interface ReturnReceiptCarton { receiptNo: string; palletCode?: string; cartonMark: string; countStatus: 'PENDING' | 'CONFIRMED' | 'UNRECORDED'; countedAt?: string; items: ReturnReceipt['items']; length?: number | null; width?: number | null; height?: number | null; weight?: number | null }
|
||||
export interface ReturnOrderDetail { order: ReturnOrderSummary; remark?: string; items: ReturnOrderItem[]; receipts: ReturnReceipt[]; pallets: ReturnPallet[]; photos: ReturnPhoto[]; packingDetails?: ReturnPackingDetail[]; cartons?: ReturnReceiptCarton[] }
|
||||
export interface ReturnOrderCreate {
|
||||
overseasWarehouseId: string; warehouseContactName: string; warehouseContactPhone: string; customerReferenceNo?: string; remark?: string; needRelabel: boolean; idempotencyKey: string
|
||||
|
||||
@@ -30,7 +30,7 @@ const parcelDetailsExpanded = ref(true)
|
||||
const receiptBatchesExpanded = ref(true)
|
||||
const signedBoxDetails = computed(() => receiptBoxDetails(selected.value?.receipts || [], selected.value?.cartons || []).map(box => ({
|
||||
...box,
|
||||
measurements: selected.value?.pallets.find(unit => unit.unitType === 'BOX' && (unit.unitCode || unit.palletCode) === box.cartonMark),
|
||||
measurements: selected.value?.pallets.find(unit => unit.unitType === 'BOX' && (unit.unitCode || unit.palletCode) === box.cartonMark) || (box.length != null || box.width != null || box.height != null || box.weight != null ? { ...box, volumeCbm: box.length != null && box.width != null && box.height != null ? Number(box.length) * Number(box.width) * Number(box.height) / 1_000_000 : null } : undefined),
|
||||
})))
|
||||
const physicalDetails = computed(() => receiptPhysicalDetails(selected.value?.pallets || [], signedBoxDetails.value))
|
||||
const printableReceipts = computed(() => selected.value?.receipts.filter(item => item.unitType !== 'PARCEL' && (item.cartonMark || item.labels?.length)) || [])
|
||||
@@ -260,10 +260,13 @@ function statusLabel(status: string, needRelabel = false) {
|
||||
return ({ PENDING_REVIEW: '待审核', PENDING_RECEIPT: '待签收', PARTIALLY_RECEIVED: '部分签收', REJECTED: '已驳回', CANCELLED: '已取消' } as Record<string, string>)[status] ?? (status || '未知状态')
|
||||
}
|
||||
function relabelStatusType(status?: string) {
|
||||
return ({ PENDING_REVIEW: 'warning', PENDING_PROCESSING: 'primary', PROCESSING: 'primary', CUSTOMER_CONFIRM_PENDING: 'warning', COMPLETED: 'success', REJECTED: 'danger', CANCELLED: 'info' } as Record<string, 'primary' | 'success' | 'warning' | 'danger' | 'info'>)[status || ''] || 'info'
|
||||
return ({ PENDING_REVIEW: 'warning', PENDING_PROCESSING: 'primary', PROCESSING: 'primary', CUSTOMER_CONFIRM_PENDING: 'warning', READY_FOR_OUTBOUND: 'success', COMPLETED: 'success', REJECTED: 'danger', CANCELLED: 'info' } as Record<string, 'primary' | 'success' | 'warning' | 'danger' | 'info'>)[status || ''] || 'info'
|
||||
}
|
||||
function relabelStatusLabel(status?: string) {
|
||||
return ({ PENDING_REVIEW: '待审核', PENDING_PROCESSING: '待处理', PROCESSING: '处理中', CUSTOMER_CONFIRM_PENDING: '待客户确认', COMPLETED: '已完成', REJECTED: '已驳回', CANCELLED: '已取消' } as Record<string, string>)[status || ''] ?? (status || '—')
|
||||
return ({ PENDING_REVIEW: '待审核', PENDING_PROCESSING: '待处理', PROCESSING: '处理中', CUSTOMER_CONFIRM_PENDING: '待客户确认', READY_FOR_OUTBOUND: '换标完成', COMPLETED: '已完成', REJECTED: '已驳回', CANCELLED: '已取消' } as Record<string, string>)[status || ''] ?? (status || '—')
|
||||
}
|
||||
function relabelQuantityUnit(unit?: string) {
|
||||
return unit === '箱' ? '箱' : '件'
|
||||
}
|
||||
function startedByLabel(startedBy: ReturnReceipt['startedBy']) { return startedBy === 'SKU' ? 'SKU 查询' : '退货单号' }
|
||||
function formatDateTime(value?: string | null) {
|
||||
@@ -322,7 +325,7 @@ onBeforeUnmount(clearPhotoUrls)
|
||||
<template #warehouse="{ row }">{{ operationWarehouseLabel(row.overseasWarehouseId) }}</template>
|
||||
<template #relabel="{ row }"><el-tag v-if="row.needRelabel" type="warning" effect="light">需要换标</el-tag><span v-else>否</span></template>
|
||||
<template #status="{ row }"><el-tag :type="statusType(row.status, row.needRelabel)" :class="statusClass(row.status, row.needRelabel)" effect="light">{{ statusLabel(row.status, row.needRelabel) }}</el-tag></template>
|
||||
<template #relabelApplications="{ row }"><div v-for="application in row.relabelApplications || []" :key="application.relabelNo" class="relabel-suborder"><span>{{ application.relabelNo }}</span><el-tag :type="relabelStatusType(application.status)" effect="light">{{ relabelStatusLabel(application.status) }}</el-tag><span>{{ application.quantity }} 件</span></div><span v-if="!row.relabelApplications?.length">—</span></template>
|
||||
<template #relabelApplications="{ row }"><div v-for="application in row.relabelApplications || []" :key="application.relabelNo" class="relabel-suborder"><span>{{ application.relabelNo }}</span><el-tag :type="relabelStatusType(application.status)" effect="light">{{ relabelStatusLabel(application.status) }}</el-tag><span>{{ application.quantity }} {{ relabelQuantityUnit(application.quantityUnit) }}</span></div><span v-if="!row.relabelApplications?.length">—</span></template>
|
||||
<template #createdAt="{ row }">{{ formatDateTime(row.createdAt) }}</template>
|
||||
</DataTable>
|
||||
</div>
|
||||
@@ -373,7 +376,7 @@ onBeforeUnmount(clearPhotoUrls)
|
||||
<el-table class="return-aligned-table" :data="selected.order.relabelApplications || []" empty-text="暂无换标申请">
|
||||
<el-table-column prop="relabelNo" label="换标单号" width="300" />
|
||||
<el-table-column label="状态" width="300"><template #default="{ row }"><el-tag :type="relabelStatusType(row.status)">{{ relabelStatusLabel(row.status) }}</el-tag></template></el-table-column>
|
||||
<el-table-column prop="quantity" label="本次换标数量(件)" width="200" />
|
||||
<el-table-column label="本次换标数量" width="200"><template #default="{ row }">{{ row.quantity }} {{ relabelQuantityUnit(row.quantityUnit) }}</template></el-table-column>
|
||||
<el-table-column min-width="1" />
|
||||
</el-table>
|
||||
</section>
|
||||
@@ -397,6 +400,7 @@ onBeforeUnmount(clearPhotoUrls)
|
||||
<div v-show="parcelDetailsExpanded" id="return-parcel-details">
|
||||
<details v-for="receipt in parcelReceipts" :key="`${receipt.receiptNo}-items`" class="return-parcel-items" open>
|
||||
<summary class="return-parcel-items__head"><strong>包裹 {{ receipt.unitCode || receipt.trackingNo || receipt.receiptNo }}</strong><span class="return-parcel-items__summary">{{ receipt.receivedQuantity }} 件<ChevronDown :size="16" aria-hidden="true" /></span></summary>
|
||||
<div v-if="receipt.length != null || receipt.width != null || receipt.height != null || receipt.weight != null" class="return-pallet-measurements">长 {{ receipt.length ?? '—' }} cm · 宽 {{ receipt.width ?? '—' }} cm · 高 {{ receipt.height ?? '—' }} cm · 重量 {{ receipt.weight ?? '—' }} kg</div>
|
||||
<div class="return-parcel-items__list"><div v-for="item in receipt.items" :key="item.skuCode" class="return-parcel-item"><span class="return-parcel-item__sku">{{ item.skuCode }}</span><span class="return-parcel-item__name">{{ item.productNameZh || '中文品名未填写' }}</span><strong>{{ item.quantity }} 件</strong></div></div>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user