From 7dc02d832797f0413b94003b28cc2a197c7c10b1 Mon Sep 17 00:00:00 2001 From: liuyihe <2513762445@qq.com> Date: Wed, 9 Sep 2026 13:35:51 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 2 +- .../overseas-warehouse/api/returnOrders.ts | 4 +- src/modules/overseas-warehouse/routes.ts | 2 +- .../views/ReturnOrdersView.vue | 8 +- .../views/WarehouseServiceView.vue | 113 ++++++++++-------- src/navigation/clientNavigation.test.mjs | 2 +- 6 files changed, 71 insertions(+), 60 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 4f7a9d2..bc3c597 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -54,7 +54,7 @@ | 客户资金账户、授信与充值申请 | `src/modules/finance/views/FinanceAccountView.vue`、`api/account.ts` | 显示当前企业 CNY 实际余额、冻结金额、授信额度、已用授信、冻结授信、总可用余额和不可变流水;数据加载前显示“—”,不得先伪装为零。充值只展示服务端启用的微信/支付宝静态收款码,客户上传 JPG/PNG 付款截图后进入待审核。客户范围只取登录态,无收款码时禁止提交,不模拟支付成功 | | 海外采购、美国本土卡与美本土散板 | `src/modules/cross-border/routes.ts`、`components/BusinessOrdersView.vue`、`api/businessOrders.ts` | 三个路由均为 `active`,客户范围只取 Token;采购创建的 `customerName` 只取当前认证会话企业名称,不允许自由输入或冒用其他客户。Backend `lastleg-service/` 的 `procurement/`、`trucking/`、`looseboard/` 客户接口 | | 海外仓入库订单 | `src/modules/order-management/routes.ts`、`views/InboundOrdersView.vue`、`api/inboundPlans.ts` | `orders/inbound` 为只读列表/详情,权限 `merchant:warehouse:inbound:list`;不展示或提交内部 ID | -| 海外仓贴标、仓储转运、货物废弃、退货换标 | `src/modules/overseas-warehouse/routes.ts`、`views/WarehouseServiceView.vue`、`api/warehouseServices.ts` | 四个路由均为 `active`;贴标申请先从共享仓库主数据选择国外中转仓,并自动带出海外仓签收联系人和联系电话,再从当前客户已经完成入库且仍有可用库存的历史入仓单中单选。货物明细支持箱唛换标、SKU 换标和同箱组合换标:SKU 明细按来源库存箱聚合为一个箱唛任务,整箱只冻结一次,SKU 数量按件保存为子明细;PDA 扫我方箱唛定位任务,返回新 FBA 箱唛和 SKU 子明细,照片完工并复核通过后释放原库存,后续仍进入既有排车出库。客户页面不暴露托盘、库位和内部库存 ID;换标申请必须提交正数 CNY `chargeAmount`,页面展示服务端钱包冻结/结算/释放状态及错误,不本地推导余额结果。Backend `lastleg-service/` 的 `relabel/`、`relabel/pda/`、`transfer/`、`discard/`,请求统一经 `src/api/overseasHttp.ts` 与 `gateway-overseas/` | +| 海外仓贴标、仓储转运、货物废弃、退货换标 | `src/modules/overseas-warehouse/routes.ts`、`views/WarehouseServiceView.vue`、`api/warehouseServices.ts` | 四个路由均为 `active`;贴标申请先从共享仓库主数据选择国外中转仓,并自动带出海外仓签收联系人和联系电话,再从当前客户已经完成入库且仍有可用库存的历史入仓单中单选。货物明细在同一页面通过“换标类型”单选区分只换 SKU 标签、只换箱唛、SKU+箱唛都换,避免两个 Tab 造成语义混淆:客户自行填写我方箱唛,同一箱唛的多条 SKU 明细聚合为一个箱任务,整箱只冻结一次,SKU 数量按件保存为子明细;历史入仓库存只提供大概位置和可用箱数,不能据此推断箱唛与具体托盘的绑定关系。PDA 扫我方箱唛定位任务,仓库人员在大概位置内找到实物后完成换标,返回新 FBA 箱唛和 SKU 子明细,照片完工并复核通过后释放原库存,后续仍进入既有排车出库。客户页面不暴露托盘、库位和内部库存 ID;换标申请必须提交正数 CNY `chargeAmount`,页面展示服务端钱包冻结/结算/释放状态及错误,不本地推导余额结果。Backend `lastleg-service/` 的 `relabel/`、`relabel/pda/`、`transfer/`、`discard/`,请求统一经 `src/api/overseasHttp.ts` 与 `gateway-overseas/` | ## 租户、认证与数据安全 diff --git a/src/modules/overseas-warehouse/api/returnOrders.ts b/src/modules/overseas-warehouse/api/returnOrders.ts index 70b354b..bbcad64 100644 --- a/src/modules/overseas-warehouse/api/returnOrders.ts +++ b/src/modules/overseas-warehouse/api/returnOrders.ts @@ -3,7 +3,7 @@ import type { PageResult } from './warehouseServices' export interface ReturnOrderSummary { returnNo: string; overseasWarehouseId: string; customerReferenceNo?: string; status: string - skuTypes: number; expectedQuantity: number; receivedQuantity: number; createdAt: string + skuTypes: number; expectedQuantity: number; receivedQuantity: number; needRelabel: boolean; createdAt: string } export interface ReturnOrderItem { skuCode: string; productNameZh?: string; expectedQuantity: number; receivedQuantity: number @@ -14,7 +14,7 @@ export interface ReturnReceipt { } export interface ReturnOrderDetail { order: ReturnOrderSummary; remark?: string; items: ReturnOrderItem[]; receipts: ReturnReceipt[] } export interface ReturnOrderCreate { - overseasWarehouseId: string; customerReferenceNo?: string; remark?: string; idempotencyKey: string + overseasWarehouseId: string; customerReferenceNo?: string; remark?: string; needRelabel: boolean; idempotencyKey: string items: Array<{ skuCode: string; productNameZh?: string; expectedQuantity: number }> } diff --git a/src/modules/overseas-warehouse/routes.ts b/src/modules/overseas-warehouse/routes.ts index 01ed1e6..12294d0 100644 --- a/src/modules/overseas-warehouse/routes.ts +++ b/src/modules/overseas-warehouse/routes.ts @@ -26,7 +26,7 @@ export const overseasWarehouseModule = { { path: 'overseas-warehouse/return-relabel', name: 'overseas-return-relabel', component: () => import('./views/ReturnOrdersView.vue'), release: 'active', - meta: { title: '退货签收', description: '创建退货预报并查看仓库签收结果', permission: 'dashboard:view' }, + meta: { title: '退货换标', description: '创建退货预报并查看仓库签收结果', permission: 'dashboard:view' }, navigation: { key: 'overseas-return-relabel', icon: RefreshCcw }, }, { diff --git a/src/modules/overseas-warehouse/views/ReturnOrdersView.vue b/src/modules/overseas-warehouse/views/ReturnOrdersView.vue index 443ac05..351b85d 100644 --- a/src/modules/overseas-warehouse/views/ReturnOrdersView.vue +++ b/src/modules/overseas-warehouse/views/ReturnOrdersView.vue @@ -19,7 +19,7 @@ const query = reactive({ page: 1, size: 20, returnNo: '', trackingNo: '', skuCod interface SkuDraft { id: number; skuCode: string; productNameZh: string; expectedQuantity: number } let skuSequence = 0 function emptySku(): SkuDraft { return { id: ++skuSequence, skuCode: '', productNameZh: '', expectedQuantity: 1 } } -const form = reactive({ overseasWarehouseId: '', customerReferenceNo: '', remark: '', items: [emptySku()] }) +const form = reactive({ overseasWarehouseId: '', customerReferenceNo: '', remark: '', needRelabel: false, items: [emptySku()] }) function normalizedSku(value: string) { return value.trim().toUpperCase() } const duplicateSkuIds = computed(() => { const grouped = new Map() @@ -29,7 +29,7 @@ const duplicateSkuIds = computed(() => { } return new Set([...grouped.values()].filter(ids => ids.length > 1).flat()) }) -function resetForm() { Object.assign(form, { overseasWarehouseId: '', customerReferenceNo: '', remark: '', items: [emptySku()] }) } +function resetForm() { Object.assign(form, { overseasWarehouseId: '', customerReferenceNo: '', remark: '', needRelabel: false, items: [emptySku()] }) } function warehouseLabel(warehouse: MerchantWarehouse) { return `${warehouse.warehouseName} · ${warehouse.warehouseCode}` } async function loadOperationWarehouses() { operationWarehousesLoading.value = true @@ -63,7 +63,7 @@ async function submit() { if (duplicateSkuIds.value.size) { ElMessage.warning('同一退货单不能重复填写相同 SKU'); return } creating.value = true try { - const detail = await createReturnOrder({ overseasWarehouseId: form.overseasWarehouseId, customerReferenceNo: form.customerReferenceNo || undefined, remark: form.remark || undefined, idempotencyKey: crypto.randomUUID(), items: items.map(item => ({ ...item, productNameZh: item.productNameZh || undefined })) }) + const detail = await createReturnOrder({ overseasWarehouseId: form.overseasWarehouseId, customerReferenceNo: form.customerReferenceNo || undefined, remark: form.remark || undefined, needRelabel: form.needRelabel, idempotencyKey: crypto.randomUUID(), items: items.map(item => ({ ...item, productNameZh: item.productNameZh || undefined })) }) ElMessage.success('退货预报已创建'); showCreate.value = false; resetForm(); await load(); await openDetail(detail.order.returnNo) } finally { creating.value = false } } @@ -85,6 +85,7 @@ onMounted(load) + @@ -97,6 +98,7 @@ onMounted(load)
{{ operationWarehousesError }}
SKU 预报明细添加 SKU
+
换标需要换标
客户只需填写预计退回的 SKU 和数量;快递单号由仓库签收时按实际包裹扫描绑定。
diff --git a/src/modules/overseas-warehouse/views/WarehouseServiceView.vue b/src/modules/overseas-warehouse/views/WarehouseServiceView.vue index 0be46fb..45ecb44 100644 --- a/src/modules/overseas-warehouse/views/WarehouseServiceView.vue +++ b/src/modules/overseas-warehouse/views/WarehouseServiceView.vue @@ -14,9 +14,9 @@ import { getMerchantWarehouses, type MerchantWarehouse } from '@/modules/first-l type ServiceType = 'labeling' | 'transfer' | 'disposal' | 'relabel' type PageMode = 'list' | 'create' | 'detail' -type LabelingMode = 'carton' | 'sku' +type LabelingMode = 'carton' | 'sku' | 'carton_and_sku' interface CargoRow { id: number; sku: string; name: string; quantity: number; availableQuantity?: number; sourceOrderId?: string; sourceInventoryBalanceId?: string; sourceInventoryPositionId?: string; sourceInboundOrderId?: string; sourceInboundOrderNo?: string; sourceInboundCode?: string; sourceWarehouseName?: string; palletNo?: string; warehouseLocationCode?: string; fnsku: string; shipmentNo: string; newSkuCode: string; shippingMark: string; cartonMark: string; fbaCartonMark: string; destinationWarehouseId: string; remark: string } -interface SkuRelabelRow { id: number; sourceRowId: number | null; cartonMark: string; originalSku: string; newSku: string; quantity: number; changeCarton: boolean; fbaCartonMark: string; destinationWarehouseId: string; remark: string } +interface SkuRelabelRow { id: number; sourceRowId: number | null; cartonMark: string; originalSku: string; newSku: string; quantity: number; fbaCartonMark: string; destinationWarehouseId: string; remark: string } interface ServiceConfig { title: string; createTitle: string; numberLabel: string; emptyText: string; columns: string[] } const props = defineProps<{ service: ServiceType }>() @@ -38,10 +38,11 @@ const form = reactive({ customerNo: '', inboundNo: '', sourceWarehouse: '', ware const cargoRows = ref([]) const labelingMode = ref('carton') const skuRelabelRows = ref([]) -const cartonMarkOptions = computed(() => cargoRows.value.map((item) => ({ - value: item.id, - label: `${item.cartonMark || item.sku || '库存货物'}|可用 ${item.availableQuantity || item.quantity} 箱`, -}))) +const labelingModeHint = computed(() => labelingMode.value === 'carton' + ? '只替换外箱箱唛,不修改箱内商品 SKU 标签;按箱填写新的 FBA 箱唛和目的仓。' + : labelingMode.value === 'sku' + ? '只替换箱内商品 SKU 标签,保留原箱唛;同一箱唛可以添加多条 SKU 明细。' + : '同一箱同时替换商品 SKU 标签和外箱箱唛;同一箱唛的多条 SKU 使用同一个新 FBA 箱唛和目的仓。') const submittedRows = ref[]>([]) const selectedDetail = ref | null>(null) const selectedRelabelDetail = ref(null) @@ -77,7 +78,7 @@ let cargoSequence = 0 let skuRelabelSequence = 0 watch(() => props.service, () => { mode.value = 'list'; resetFilters(); resetForm(); void load() }) -watch(labelingMode, (value) => { if (value === 'sku' && !skuRelabelRows.value.length) addSkuRelabelRow() }) +watch(labelingMode, (value) => { if (value !== 'carton' && !skuRelabelRows.value.length) addSkuRelabelRow() }) onMounted(() => { void load() }) function resetFilters() { Object.assign(filters, { number: '', inboundNo: '', warehouse: '', destination: '', status: '', start: '', end: '' }) } function resetForm() { @@ -101,36 +102,36 @@ async function openCreate() { finally { discardCandidatesLoading.value = false } } function addCargoRow() { cargoRows.value.push({ id: ++cargoSequence, sku: '', name: '', quantity: 1, fnsku: '', shipmentNo: '', newSkuCode: '', shippingMark: '', cartonMark: '', fbaCartonMark: '', destinationWarehouseId: '', remark: '' }) } -function addSkuRelabelRow() { skuRelabelRows.value.push({ id: ++skuRelabelSequence, sourceRowId: null, cartonMark: '', originalSku: '', newSku: '', quantity: 1, changeCarton: false, fbaCartonMark: '', destinationWarehouseId: '', remark: '' }) } -function removeSkuRelabelRow(id: number) { skuRelabelRows.value = skuRelabelRows.value.filter((row) => row.id !== id) } -function selectSkuSource(row: SkuRelabelRow) { - const source = cargoRows.value.find((item) => item.id === row.sourceRowId) - if (!source) return - row.cartonMark = source.cartonMark || '' - row.originalSku = row.originalSku || source.sku - row.destinationWarehouseId = row.destinationWarehouseId || source.destinationWarehouseId +function addSkuRelabelRow() { + const source = cargoRows.value[Math.min(skuRelabelRows.value.length, Math.max(0, cargoRows.value.length - 1))] + skuRelabelRows.value.push({ id: ++skuRelabelSequence, sourceRowId: source?.id || null, + cartonMark: '', originalSku: source?.sku || '', newSku: '', quantity: 1, + fbaCartonMark: '', destinationWarehouseId: source?.destinationWarehouseId || '', remark: '' }) } +function removeSkuRelabelRow(id: number) { skuRelabelRows.value = skuRelabelRows.value.filter((row) => row.id !== id) } function buildSkuRelabelItems(): RelabelCreate['items'] { - const groups = new Map() + const groups = new Map() for (const row of skuRelabelRows.value) { - if (row.sourceRowId == null) throw new Error('请选择每条 SKU 明细对应的来源库存箱') - const rows = groups.get(row.sourceRowId) || [] + const cartonMark = row.cartonMark.trim().toUpperCase() + if (!cartonMark) throw new Error('请填写每个箱子的我方箱唛') + const rows = groups.get(cartonMark) || [] rows.push(row) - groups.set(row.sourceRowId, rows) + groups.set(cartonMark, rows) } - return [...groups.entries()].map(([sourceRowId, rows]) => { - const source = cargoRows.value.find((item) => item.id === sourceRowId) + const anchors = cargoRows.value.flatMap((item) => Array.from( + { length: Number(item.availableQuantity || 0) }, () => item, + )) + if (!anchors.length) throw new Error('请先选择有库存的历史入仓单') + if (groups.size > anchors.length) { + throw new Error('填写的箱唛数量超过当前入仓单可用库存箱数') + } + return [...groups.entries()].map(([_, rows], groupIndex) => { + const source = anchors[groupIndex] if (!source?.sourceInventoryBalanceId || !source.sourceInventoryPositionId || !source.sourceInboundOrderId) { throw new Error('来源库存已变化,请重新选择有库存的历史入仓单') } const cartonMark = rows[0].cartonMark.trim() - if (!cartonMark || rows.some((row) => row.cartonMark.trim() !== cartonMark)) { - throw new Error('同一来源库存箱的 SKU 明细必须使用同一个我方箱唛') - } - const changeCarton = rows[0].changeCarton - if (rows.some((row) => row.changeCarton !== changeCarton)) { - throw new Error('同一我方箱唛的 SKU 明细必须统一是否同时更换箱唛') - } + const changeCarton = labelingMode.value === 'carton_and_sku' const fbaCartonMark = rows[0].fbaCartonMark.trim() const destinationWarehouseId = rows[0].destinationWarehouseId if (changeCarton && (!fbaCartonMark || !destinationWarehouseId @@ -143,8 +144,8 @@ function buildSkuRelabelItems(): RelabelCreate['items'] { sourceInboundOrderId: source.sourceInboundOrderId, skuCode: source.sku || rows[0].originalSku, productNameZh: source.name, - totalPackageCount: source.quantity, - notifiedPackageCount: source.quantity, + totalPackageCount: 1, + notifiedPackageCount: 1, shipmentNo: source.shipmentNo || cartonMark, trackingCode: form.trackingNo || undefined, newSkuCode: rows[0].newSku, @@ -169,8 +170,8 @@ function clearRelabelRows() { cargoRows.value = []; selectedRelabelInboundOrderI function csvCell(value: string | number | undefined) { return `"${String(value ?? '').replaceAll('"', '""')}"` } function downloadRelabelTemplate() { if (!cargoRows.value.length) { ElMessage.warning('请先选择有库存的历史入仓单'); return } - const header = ['明细行标识', '本次箱数', '商品SKU', '中文品名', 'FBA货件编号', '换标新SKU', '我方箱唛', 'FBA箱唛', 'FBA目的仓', '备注'] - const rows = cargoRows.value.map((item) => [item.id, item.quantity, item.sku, item.name, item.shipmentNo, item.newSkuCode, + const header = ['明细行标识', '本次箱数', '商品SKU', '中文品名', 'FBA货件编号', '我方箱唛', 'FBA箱唛', 'FBA目的仓', '备注'] + const rows = cargoRows.value.map((item) => [item.id, item.quantity, item.sku, item.name, item.shipmentNo, item.cartonMark, item.fbaCartonMark, item.destinationWarehouseId, item.remark]) const blob = new Blob([`\uFEFF${[header, ...rows].map((row) => row.map(csvCell).join(',')).join('\r\n')}\r\n`], { type: 'text/csv;charset=utf-8' }) const url = URL.createObjectURL(blob) @@ -193,13 +194,13 @@ async function importRelabelTemplate(event: Event) { const lines = (await file.text()).replace(/^\uFEFF/, '').split(/\r?\n/).filter((line) => line.trim()) if (lines.length < 2) { ElMessage.error('模板中没有可导入的明细'); return } const headers = parseCsvLine(lines[0]) - const required = ['明细行标识', '本次箱数', 'FBA货件编号', '换标新SKU', '我方箱唛', 'FBA箱唛', 'FBA目的仓'] + const required = ['明细行标识', '本次箱数', 'FBA货件编号', '我方箱唛', 'FBA箱唛', 'FBA目的仓'] if (required.some((name) => !headers.includes(name))) { ElMessage.error('模板格式不正确,请重新下载模板填写'); return } const imported = lines.slice(1).map(parseCsvLine) .map((values) => Object.fromEntries(headers.map((key, index) => [key, values[index] || '']))) .filter((item) => item['明细行标识']) if (!imported.length || imported.some((item) => required.some((key) => !item[key]))) { - ElMessage.error('模板中的明细行、箱数、货件、换标 SKU、箱唛和 FBA 目的仓必须填写完整'); return + ElMessage.error('模板中的明细行、箱数、货件、箱唛和 FBA 目的仓必须填写完整'); return } if (new Set(imported.map((item) => item['明细行标识'])).size !== imported.length) { ElMessage.error('模板中的明细行标识不能重复'); return @@ -216,7 +217,6 @@ async function importRelabelTemplate(event: Event) { } row.quantity = quantity row.shipmentNo = item['FBA货件编号'] - row.newSkuCode = item['换标新SKU'] row.cartonMark = item['我方箱唛'] row.fbaCartonMark = item['FBA箱唛'] row.destinationWarehouseId = item['FBA目的仓'] @@ -285,13 +285,13 @@ async function load() { function query() { void load() } async function submit() { const primaryWarehouse = props.service === 'relabel' ? form.sourceWarehouse : form.warehouse - const relabelRows = labelingMode.value === 'sku' ? skuRelabelRows.value : cargoRows.value + const relabelRows = labelingMode.value === 'carton' ? cargoRows.value : skuRelabelRows.value const invalidCargo = props.service === 'disposal' ? !selectedDiscardOrderId.value || cargoRows.value.every((item) => item.quantity < 1) || cargoRows.value.some((item) => item.quantity < 0 || item.quantity > Number(item.availableQuantity || 0)) - : relabelRows.length === 0 || (props.service === 'labeling' && labelingMode.value === 'sku' - ? skuRelabelRows.value.some((item) => !item.sourceRowId || !item.cartonMark || !item.originalSku || !item.newSku || item.quantity < 1 - || (item.changeCarton && (!item.fbaCartonMark || !item.destinationWarehouseId))) + : relabelRows.length === 0 || (props.service === 'labeling' && labelingMode.value !== 'carton' + ? skuRelabelRows.value.some((item) => !item.cartonMark || !item.originalSku || !item.newSku || item.quantity < 1 + || (labelingMode.value === 'carton_and_sku' && (!item.fbaCartonMark || !item.destinationWarehouseId))) : cargoRows.value.some((item) => (props.service !== 'labeling' && !item.sku) || !item.name || item.quantity < 1)) if ((props.service !== 'labeling' && !form.customerNo && !form.inboundNo) || (props.service !== 'disposal' && !primaryWarehouse) || invalidCargo) { ElMessage.warning('请填写必填信息和完整的货物明细'); return @@ -299,7 +299,7 @@ async function submit() { if (props.service === 'labeling' && (!form.labelDeadline || !form.contact || !form.phone || form.chargeAmount <= 0)) { ElMessage.warning('请填写贴标截止时间、联系人和贴标费用'); return } - if (props.service === 'labeling' && labelingMode.value === 'carton' && cargoRows.value.some((item) => !item.shipmentNo || !item.newSkuCode || !item.cartonMark || !item.fbaCartonMark)) { + if (props.service === 'labeling' && labelingMode.value === 'carton' && cargoRows.value.some((item) => !item.shipmentNo || !item.cartonMark || !item.fbaCartonMark)) { ElMessage.warning('请上传关联面单,确保每箱的我方箱唛和 FBA 箱唛完整'); return } if (props.service === 'labeling' && labelingMode.value === 'carton' && cargoRows.value.some((item) => !item.destinationWarehouseId || !item.sourceInventoryPositionId)) { @@ -318,7 +318,7 @@ async function submit() { if (props.service === 'labeling') { const sourceInboundOrders = [...new Set(cargoRows.value.map((item) => item.sourceInboundOrderNo || item.sourceInboundCode).filter((value): value is string => Boolean(value)))].join('、').slice(0, 128) const items = labelingMode.value === 'carton' - ? cargoRows.value.map((item) => ({ sourceInventoryBalanceId: item.sourceInventoryBalanceId!, sourceInventoryPositionId: item.sourceInventoryPositionId!, sourceInboundOrderId: item.sourceInboundOrderId!, skuCode: item.sku, productNameZh: item.name, totalPackageCount: item.quantity, notifiedPackageCount: item.quantity, shipmentNo: item.shipmentNo, trackingCode: form.trackingNo || undefined, newSkuCode: item.newSkuCode, labelRequirement: form.requirement || undefined, cartonMark: item.cartonMark, fbaCartonMark: item.fbaCartonMark, destinationFbaWarehouseCode: item.destinationWarehouseId, operationType: 'CARTON_LABEL' as const, skuItems: [], remark: item.remark || undefined })) + ? cargoRows.value.map((item) => ({ sourceInventoryBalanceId: item.sourceInventoryBalanceId!, sourceInventoryPositionId: item.sourceInventoryPositionId!, sourceInboundOrderId: item.sourceInboundOrderId!, skuCode: item.sku, productNameZh: item.name, totalPackageCount: item.quantity, notifiedPackageCount: item.quantity, shipmentNo: item.shipmentNo, trackingCode: form.trackingNo || undefined, newSkuCode: undefined, labelRequirement: form.requirement || undefined, cartonMark: item.cartonMark, fbaCartonMark: item.fbaCartonMark, destinationFbaWarehouseCode: item.destinationWarehouseId, operationType: 'CARTON_LABEL' as const, skuItems: [], remark: item.remark || undefined })) : buildSkuRelabelItems() await createRelabel({ customerOrderNo: sourceInboundOrders || '贴标申请', operationWarehouseId: form.warehouse, labelDeadline: form.labelDeadline, contactName: form.contact, contactPhone: form.phone, chargeAmount: form.chargeAmount, remark: form.remark || undefined, idempotencyKey, items }) } else if (props.service === 'disposal') { @@ -397,6 +397,7 @@ function selectRelabelInventory(inboundOrderId: string) { } })) skuRelabelRows.value = [] + if (labelingMode.value !== 'carton') addSkuRelabelRow() } @@ -450,21 +451,28 @@ function selectRelabelInventory(inboundOrderId: string) { +
是否换标需要换标