@@ -1,5 +1,5 @@
< script setup lang = "ts" >
import { computed , onMounted , reactive , ref , watch } from 'vue'
import { computed , nextTick , onMounted , reactive , ref , watch } from 'vue'
import { ElMessage , ElMessageBox } from 'element-plus'
import { ArrowLeft , Download , Eye , Plus , Printer , Search , Trash2 , Upload } from '@lucide/vue'
import SingleLineText from '@/components/common/SingleLineText.vue'
@@ -18,6 +18,7 @@ import {
type MerchantWarehouse ,
type MerchantWarehouseDetail ,
} from '@/modules/first-leg/api/firstLeg'
import { loadAllWarehouseRecords } from '@/modules/first-leg/utils/warehousePagination'
type ServiceType = 'labeling' | 'transfer' | 'disposal' | 'relabel'
type PageMode = 'list' | 'create' | 'detail'
@@ -112,7 +113,17 @@ watch(() => form.relabel, (value) => {
}
} )
watch ( labelingMode , ( value ) => { if ( value !== 'carton' && ! skuRelabelRows . value . length ) addSkuRelabelRow ( ) } )
onMounted ( ( ) => { void load ( ) } )
function refreshWarehouseMarkLabels ( ) {
if ( props . service !== 'labeling' ) return
const root = document . querySelector ( '.warehouse-service-page' )
if ( ! root ) return
const walker = document . createTreeWalker ( root , NodeFilter . SHOW _TEXT )
const nodes : Text [ ] = [ ]
let node : Node | null
while ( ( node = walker . nextNode ( ) ) ) nodes . push ( node as Text )
for ( const text of nodes ) text . nodeValue = text . nodeValue ? . replaceAll ( '旧箱唛' , '仓库唛头' ) . replaceAll ( '旧唛头' , '仓库唛头' ) || text . nodeValue
}
onMounted ( ( ) => { void load ( ) ; if ( props . service === 'labeling' || props . service === 'relabel' || props . service === 'transfer' || props . service === 'disposal' ) void loadWarehouses ( ) ; void nextTick ( refreshWarehouseMarkLabels ) } )
function resetFilters ( ) { Object . assign ( filters , { number : '' , inboundNo : '' , warehouse : '' , destination : '' , status : '' , start : '' , end : '' } ) }
function resetForm ( ) {
Object . assign ( form , { customerNo : '' , inboundNo : '' , sourceWarehouse : '' , warehouse : '' , destination : '' , address : '' , contact : '' , phone : '' , deliveryMethod : '' , relabelDeliveryMethod : '' , trackingNo : '' , reason : '' , requirement : '' , relabel : false , remark : '' , labelDeadline : '' , estimatedArrivalAt : '' , estimatedShipAt : '' , fbaShipmentNo : '' , volumeCbm : 0.01 , chargeAmount : 0 } )
@@ -253,7 +264,7 @@ async function importTransferCartonMarks(event: Event) {
if ( ! file ) return
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 headers = parseCsvLine ( lines [ 0 ] ) . map ( ( name ) => name === '仓库唛头' || name === '旧唛头' ? '旧箱唛' : name )
if ( ! headers . includes ( 'SKU' ) || ! headers . includes ( '客户箱唛号' ) ) { ElMessage . error ( '客户箱唛模板格式不正确,请重新下载模板' ) ; return }
const imported = lines . slice ( 1 ) . map ( parseCsvLine ) . map ( ( values ) => Object . fromEntries ( headers . map ( ( key , index ) => [ key , values [ index ] || '' ] ) ) ) . filter ( ( item ) => item . SKU || item [ '客户箱唛号' ] )
if ( ! imported . length || imported . some ( ( item ) => ! item . SKU || ! item [ '客户箱唛号' ] ) ) { ElMessage . error ( 'SKU 和客户箱唛号必须填写完整' ) ; return }
@@ -273,8 +284,8 @@ function downloadRelabelTemplate(templateType: RelabelTemplateType) {
const cartonTemplate = templateType === 'carton'
const mixedTemplate = templateType === 'mixed'
const header = cartonTemplate
? [ '明细行标识' , '旧箱唛 ' , '新FBA箱唛' , 'FBA目的仓' , 'FBA货件编号' , '备注' ]
: [ '明细行标识' , '旧箱唛 ' , '旧SKU标签' , '新SKU标签' , '换标数量(件)' ,
? [ '明细行标识' , '仓库唛头 ' , '新FBA箱唛' , 'FBA目的仓' , 'FBA货件编号' , '备注' ]
: [ '明细行标识' , '仓库唛头 ' , '旧SKU标签' , '新SKU标签' , '换标数量(件)' ,
... ( mixedTemplate ? [ '新FBA箱唛' , 'FBA目的仓' , 'FBA货件编号' ] : [ ] ) , '备注' ]
const rows = cargoRows . value . map ( ( item ) => cartonTemplate
? [ item . id , item . cartonMark , item . fbaCartonMark , item . destinationWarehouseId , item . shipmentNo , item . remark ]
@@ -303,7 +314,8 @@ async function importRelabelTemplate(event: Event, templateType: RelabelTemplate
if ( ! file ) return
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 ] )
// Accept both the current display name and legacy template header while keeping the internal key stable.
const headers = parseCsvLine ( lines [ 0 ] ) . map ( ( name ) => name === '仓库唛头' || name === '旧唛头' ? '旧箱唛' : name )
if ( templateType !== 'carton' ) {
const mixedTemplate = templateType === 'mixed'
const required = [ '明细行标识' , '旧箱唛' , '旧SKU标签' , '新SKU标签' , '换标数量(件)' ,
@@ -315,13 +327,13 @@ async function importRelabelTemplate(event: Event, templateType: RelabelTemplate
. map ( ( values ) => Object . fromEntries ( headers . map ( ( key , index ) => [ key , values [ index ] || '' ] ) ) )
. filter ( ( item ) => item [ '旧箱唛' ] || item [ '新SKU标签' ] || item [ '新FBA箱唛' ] )
if ( ! imported . length || imported . some ( ( item ) => required . some ( ( key ) => ! item [ key ] ) ) ) {
ElMessage . error ( '旧箱唛 、旧 SKU 标签、新 SKU 标签和换标数量必须填写完整' ) ; return
ElMessage . error ( '仓库唛头 、旧 SKU 标签、新 SKU 标签和换标数量必须填写完整' ) ; return
}
const rows : ImportedRelabelBinding [ ] = [ ]
for ( const item of imported ) {
const quantity = Number ( item [ '换标数量(件)' ] )
if ( ! Number . isInteger ( quantity ) || quantity < 1 ) {
ElMessage . error ( ` 箱唛 ${ item [ '旧箱唛' ] } 的换标数量必须是大于 0 的整数 ` ) ; return
ElMessage . error ( ` 仓库唛头 ${ item [ '旧箱唛' ] } 的换标数量必须是大于 0 的整数 ` ) ; return
}
const source = cargoRows . value . find ( ( row ) => String ( row . id ) === item [ '明细行标识' ] )
if ( ! source ) { ElMessage . error ( ` 明细行 ${ item [ '明细行标识' ] } 不属于当前库存,请重新下载模板 ` ) ; return }
@@ -350,7 +362,7 @@ async function importRelabelTemplate(event: Event, templateType: RelabelTemplate
. map ( ( values ) => Object . fromEntries ( headers . map ( ( key , index ) => [ key , values [ index ] || '' ] ) ) )
. filter ( ( item ) => item [ '旧箱唛' ] || item [ '新FBA箱唛' ] )
if ( ! imported . length || imported . some ( ( item ) => required . some ( ( key ) => ! item [ key ] ) ) ) {
ElMessage . error ( '模板中的明细行、旧箱唛 、新 FBA 箱唛、FBA 目的仓和货件编号必须填写完整' ) ; return
ElMessage . error ( '模板中的明细行、仓库唛头 、新 FBA 箱唛、FBA 目的仓和货件编号必须填写完整' ) ; return
}
if ( new Set ( imported . map ( ( item ) => item [ '明细行标识' ] ) ) . size !== imported . length ) {
ElMessage . error ( '模板中的明细行标识不能重复' ) ; return
@@ -461,7 +473,7 @@ async function load() {
const result = await listDiscards ( { page : 1 , size : 20 , discardNo : filters . number || undefined , inboundCode : filters . inboundNo || undefined , overseasWarehouseId : filters . warehouse || undefined , status : filters . status || undefined , createdFrom : dateTime ( filters . start ) , createdTo : dateTime ( filters . end , true ) } )
submittedRows . value = result . records . map ( ( item ) => row ( [ item . discardNo , item . inboundCodes , item . overseasWarehouseName || '—' , '—' , item . totalPackages , ` ${ item . currency } ${ item . totalFee } ` , statusLabel ( item . status ) , formatDateTime ( item . createdAt ) ] ) )
} else {
const result = await listTransfers ( { page : 1 , size : 20 , transferNo : filters . number || undefined , inboundCode : filters . inboundNo || undefined , operatingWarehouseId : filters . warehouse || undefined , fbaWarehouseCode : filters . destination || undefined , status : filters . status || undefined , needRelabel : props . service === 'relabel' , createdFrom : dateTime ( filters . start ) , createdTo : dateTime ( filters . end , true ) } )
const result = await listTransfers ( { page : 1 , size : 20 , transferNo : filters . number || undefined , inboundCode : filters . inboundNo || undefined , operatingWarehouseId : filters . warehouse || undefined , fbaWarehouseCode : filters . destination || undefined , status : filters . status || undefined , ... ( props . service === 'relabel' ? { needRelabel : true } : { } ) , createdFrom : dateTime ( filters . start ) , createdTo : dateTime ( filters . end , true ) } )
submittedRows . value = result . records . map ( ( item ) => props . service === 'transfer'
? row ( [ item . transferNo , item . packageCount , '—' , item . fbaWarehouseCode , deliveryMethodLabel ( item . deliveryMethod ) , item . needRelabel ? '是 · 待绑定换标单' : '否' , statusLabel ( item . status ) , formatDateTime ( item . createdAt ) ] )
: row ( [ item . transferNo , '—' , item . fbaWarehouseCode , '—' , item . packageCount , '是' , item . relabelNo ? '已生成' : '待生成' , statusLabel ( item . status ) , formatDateTime ( item . createdAt ) ] ) )
@@ -506,8 +518,8 @@ async function submit() {
if ( props . service === 'relabel' && ( ! form . destination || ! form . address || ! form . deliveryMethod || ! form . estimatedArrivalAt || ! form . fbaShipmentNo || form . volumeCbm <= 0 ) ) {
ElMessage . warning ( '请填写完整的派送信息、体积、预计到达时间和 FBA 货件号' ) ; return
}
if ( props . service === 'transfer' && ( ! form . warehouse || ! form . deliveryMethod || ! form . address || ! form . estimatedArrivalAt || ! form . estimatedShipAt || form . volumeCbm < 0 ) ) {
const missing = [ ! form . warehouse && '中转仓' , ! form . deliveryMethod && '送货方式' , ! form . address && '地址' , ! form . estimatedArrivalAt && '预计入仓时间' , ! form . estimatedShipAt && '预计发货时间' , form . volumeCbm < 0 && '预估总体积' ] . filter ( Boolean ) . join ( '、' )
if ( props . service === 'transfer' && ( ! form . warehouse || ! form . deliveryMethod || ! form . address || ! form . estimatedArrivalAt || ! form . estimatedShipAt || form . volumeCbm < 0 || ( form . deliveryMethod === 'WAREHOUSE_PICKUP' && ( ! form . contact || ! form . phone ) ) ) ) {
const missing = [ ! form . warehouse && '中转仓' , ! form . deliveryMethod && '送货方式' , ! form . address && '地址' , form . deliveryMethod === 'WAREHOUSE_PICKUP' && ! form . contact && '提货联系人' , form . deliveryMethod === 'WAREHOUSE_PICKUP' && ! form . phone && '联系人电话' , ! form . estimatedArrivalAt && '预计入仓时间' , ! form . estimatedShipAt && '预计发货时间' , form . volumeCbm < 0 && '预估总体积' ] . filter ( Boolean ) . join ( '、' )
ElMessage . warning ( ` 请填写: ${ missing || '必填信息' } ` ) ; return
}
if ( props . service === 'transfer' && transferHasFbaDestination . value && ( ! form . destination || ! form . fbaShipmentNo ) ) {
@@ -548,7 +560,7 @@ async function submit() {
const customerCartonMarks = ( form . relabel ? transferRelabelRows . value : cargoRows . value ) . flatMap ( transferCustomerMarks )
const transferRemark = [ form . remark , form . relabel && form . requirement ? ` 换标要求: ${ form . requirement } ` : '' ] . filter ( Boolean ) . join ( '; ' )
const operationType = labelingMode . value === 'carton' ? 'CARTON_LABEL' : labelingMode . value === 'sku' ? 'SKU_LABEL' : 'CARTON_AND_SKU'
await createTransfer ( { operatingWarehouseId : primaryWarehouse , fbaWarehouseCode : form . destination || undefined , deliveryAddress : form . address , packageCount , volumeCbm : form . volumeCbm , deliveryMethod : form . deliveryMethod , estimatedArrivalAt : form . estimatedArrivalAt , estimatedShipAt : form . estimatedShipAt || undefined , fbaShipmentNo : form . fbaShipmentNo || undefined , trackingNo : form . deliveryMethod === 'CUSTOMER_DELIVERY' ? form . trackingNo || undefined : undefined , fbaBoxNos : customerCartonMarks . length ? customerCartonMarks . join ( ',' ) : undefined , remark : transferRemark || undefined , needRelabel : props . service === 'relabel' || form . relabel , labelDeadline : form . relabel ? form . labelDeadline : undefined , relabelContactName : form . relabel ? form . contact : undefined , relabelContactPhone : form . relabel ? form . phone : undefined , relabelChargeAmount : form . relabel ? form . chargeAmount : undefined , relabelDeliveryMethod : form . relabel && labelingMode . value !== 'sku' ? form . relabelDeliveryMethod as 'TRUCK' | 'EXPRESS' | 'TRUCK_PICKUP' | 'EXPRESS_PICKUP' : undefined , idempotencyKey , items : cargoRows . value . map ( ( item ) => ( { skuCode : item . sku , productNameZh : item . name , packageCount : item . quantity , shippingMark : transferCustomerMarks ( item ) . join ( ',' ) || undefined } ) ) , relabelItems : form . relabel ? transferRelabelRows . value . map ( ( item ) => ( { operationType , customerCartonMarks : transferCustomerMarks ( item ) , originalSku : item . sku , newSku : item . newSkuCode || undefined , quantity : item . quantity , fbaCartonMark : item . fbaCartonMark || undefined , destinationWarehouseCode : item . destinationWarehouseId || undefined , remark : item . remark || undefined } ) ) : undefined } )
await createTransfer ( { operatingWarehouseId : primaryWarehouse , fbaWarehouseCode : form . destination || undefined , deliveryAddress : form . address , packageCount , volumeCbm : form . volumeCbm , deliveryMethod : form . deliveryMethod , estimatedArrivalAt : form . estimatedArrivalAt , estimatedShipAt : form . estimatedShipAt || undefined , fbaShipmentNo : form . fbaShipmentNo || undefined , trackingNo : form . deliveryMethod === 'CUSTOMER_DELIVERY' ? form . trackingNo || undefined : undefined , fbaBoxNos : customerCartonMarks . length ? customerCartonMarks . join ( ',' ) : undefined , remark : transferRemark || undefined , needRelabel : props . service === 'relabel' || form . relabel , labelDeadline : form . relabel ? form . labelDeadline : undefined , relabelContactName : ( form . relabel || form . deliveryMethod === 'WAREHOUSE_PICKUP' ) ? form . contact : undefined , relabelContactPhone : ( form . relabel || form . deliveryMethod === 'WAREHOUSE_PICKUP' ) ? form . phone : undefined , relabelChargeAmount : form . relabel ? form . chargeAmount : undefined , relabelDeliveryMethod : form . relabel && labelingMode . value !== 'sku' ? form . relabelDeliveryMethod as 'TRUCK' | 'EXPRESS' | 'TRUCK_PICKUP' | 'EXPRESS_PICKUP' : undefined , idempotencyKey , items : cargoRows . value . map ( ( item ) => ( { skuCode : item . sku , productNameZh : item . name , packageCount : item . quantity , shippingMark : transferCustomerMarks ( item ) . join ( ',' ) || undefined } ) ) , relabelItems : form . relabel ? transferRelabelRows . value . map ( ( item ) => ( { operationType , customerCartonMarks : transferCustomerMarks ( item ) , originalSku : item . sku , newSku : item . newSkuCode || undefined , quantity : item . quantity , fbaCartonMark : item . fbaCartonMark || undefined , destinationWarehouseCode : item . destinationWarehouseId || undefined , remark : item . remark || undefined } ) ) : undefined } )
}
ElMessage . success ( ` ${ config . value . title } 提交成功 ` ) ; mode . value = 'list' ; await load ( )
} catch ( error ) { ElMessage . error ( error instanceof Error ? error . message : '提交失败' ) }
@@ -606,11 +618,17 @@ async function loadWarehouses() {
operationWarehousesError . value = ''
try {
const [ fbaResult , operationResult ] = await Promise . allSettled ( [
getMerchantWarehouses ( { warehouseType : 'FBA' } ) ,
getMerchantWarehouses ( { warehouseType : 'OVERSEAS' } ) ,
loadAllWarehouseRecords ( 'FBA' , getMerchantWarehouses ) ,
// The warehouse master uses OVERSEAS_PARTNER for managed overseas transit warehouses
// (including Los Angeles and New York). Query the active catalogue without a type
// restriction, then accept both supported overseas warehouse types.
loadAllWarehouseRecords ( 'OVERSEAS' , ( query ) => getMerchantWarehouses ( { page : query . page , size : query . size } ) ) ,
] )
fbaWarehouses . value = fbaResult . status === 'fulfilled' ? fbaResult . value . records : [ ]
operationWarehouses . value = operationResult . status === 'fulfilled' ? operationResult . value . records : [ ]
fbaWarehouses . value = fbaResult . status === 'fulfilled' ? fbaResult . value . filter ( ( item ) => item . status === 'ACTIVE' && item . warehouseType === 'FBA' ) : [ ]
operationWarehouses . value = operationResult . status === 'fulfilled'
? operationResult . value . filter ( ( item ) => item . status === 'ACTIVE' && [ 'OVERSEAS' , 'OVERSEAS_PARTNER' ] . includes ( item . warehouseType ) )
: [ ]
if ( fbaResult . status === 'rejected' ) fbaWarehousesError . value = 'FBA 目的仓候选加载失败,请检查仓库主数据或权限'
if ( operationResult . status === 'rejected' ) operationWarehousesError . value = '海外仓候选加载失败,请检查仓库主数据或数据库迁移'
} catch ( error ) {
fbaWarehouses . value = [ ]
@@ -690,7 +708,7 @@ function selectRelabelInventory(inboundOrderId: string) {
< div class = "warehouse-filter-grid" >
< label > < span > { { config . numberLabel } } < / span > < el-input v-model = "filters.number" :placeholder="`请输入${config.numberLabel}`" clearable / > < / label >
< label v-if = "props.service !== 'labeling' && props.service !== 'relabel'"><span>进仓编号</span><el-input v-model="filters.inboundNo" placeholder="请输入进仓编号" clearable / > < / label >
< label > < span > { { props . service === 'relabel' ? '来源 FBA 仓' : '操作仓' } } < / span > < el-select v-model = "filters.warehouse" placeholder="全部"><el-option label="美西洛杉矶仓 " value="LAX " /><el-option label="美东新泽西仓" value="EWR" /><el-option label="美中芝加哥仓 " value="ORD " / > < / el-select > < / label >
< label > < span > { { props . service === 'relabel' ? '来源 FBA 仓' : '操作仓' } } < / span > < el-select v-model = "filters.warehouse" clearable :loading="fbaWarehousesLoading" placeholder="全部"><el-option label="全部 " value="" /><el-option v-for="warehouse in (props.service === 'relabel' ? fbaWarehouses : operationWarehouses)" :key="warehouse.id" :label="warehouseLabel(warehouse) " : value="String(warehouse.id) " / > < / el-select > < / label >
< label v-if = "props.service === 'transfer' || props.service === 'relabel'"><span>目的 FBA 仓</span><el-input v-model="filters.destination" placeholder="请输入仓代码" clearable / > < / label >
< label > < span > 订单状态 < / span > < el-select v-model = "filters.status" placeholder="全部状态" clearable><el-option v-for="option in statusOptions" :key="option.value" :label="option.label" :value="option.value" / > < / el-select > < / label >
< label > < span > 创建时间 < / span > < el-date-picker v-model = "filters.start" type="date" placeholder="开始日期" value-format="YYYY-MM-DD" / > < / label >
@@ -718,7 +736,9 @@ function selectRelabelInventory(inboundOrderId: string) {
< label v-if = "props.service === 'labeling'" class="warehouse-span-2"><span><i>*</i>选择有库存的历史入仓单</span><el-select v-model="selectedRelabelInboundOrderId" filterable clearable :loading="relabelCandidatesLoading" :disabled="!form.warehouse" no-data-text="当前中转仓暂无已入库可用库存" placeholder="请选择曾经下单且当前仍有库存的入仓单" @change="selectRelabelInventory"><el-option v-for="option in relabelInboundOptions" :key="option.value" :label="`${option.inboundOrderNo}|入仓码 ${option.inboundCode}|可用 ${option.availablePackages} 箱`" :value="option.value" /></el-select><small class="warehouse-hint" > 仅显示当前客户在所选中转仓已经完成入库且仍有可用库存的历史入仓单 。 < / small > < / label >
< label v-if = "props.service === 'disposal'"><span>操作仓</span><el-input :model-value="discardCandidates.find((item) => item.orderId === selectedDiscardOrderId)?.overseasWarehouseName || form.warehouse" readonly / > < / label >
< div v-if = "props.service === 'transfer'" class="warehouse-choice-field warehouse-span-2"><span><i>*</i>货物如何送到中转仓</span><el-radio-group v-model="form.deliveryMethod" @change="selectTransferInboundMethod"><el-radio-button value="WAREHOUSE_PICKUP">仓库上门提货</el-radio-button><el-radio-button value="CUSTOMER_DELIVERY" > 客户送货到仓 < / el -radio -button > < / el-radio-group > < small > 仓库上门提货 : 填写货物当前地址 ; 客户送货到仓 : 下方自动展示中转仓收货信息 。 < / small > < / div >
< label v-if = "props.service === 'transfer' && form.deliveryMethod === 'WAREHOUSE_PICKUP'" class="warehouse-span-2 "><span><i>*</i>提货地址</span><el-input v-model="form.address" placeholder="请输入仓库上门提货的详细地址" / > < / label >
< label v-if = "props.service === 'transfer' && form.deliveryMethod === 'WAREHOUSE_PICKUP'" class="pickup-address-field "><span><i>*</i>提货地址</span><el-input v-model="form.address" placeholder="请输入仓库上门提货的详细地址" / > < / label >
< label v-if = "props.service === 'transfer' && form.deliveryMethod === 'WAREHOUSE_PICKUP'"><span><i>*</i>提货联系人</span><el-input v-model="form.contact" placeholder="请输入提货联系人" maxlength="128" / > < / label >
< label v-if = "props.service === 'transfer' && form.deliveryMethod === 'WAREHOUSE_PICKUP'"><span><i>*</i>联系人电话</span><el-input v-model="form.phone" placeholder="请输入联系人电话" maxlength="64" / > < / label >
< div v-if = "props.service === 'transfer' && form.deliveryMethod === 'CUSTOMER_DELIVERY'" v-loading="operationWarehouseDetailLoading" class="warehouse-receiving-card warehouse-span-2" >
< div > < span > 仓库收货信息 < / span > < strong > { { operationWarehouseAddress || '该中转仓暂未维护收货地址' } } < / strong > < / div >
< label class = "warehouse-span-2" > < span > < i > * < / i > 送货地址 < / span > < el-input v-model = "form.address" placeholder="请输入实际送货地址" / > < / label >
@@ -776,15 +796,15 @@ function selectRelabelInventory(inboundOrderId: string) {
< / div >
< div v-if = "importedRelabelBindings.length" class="warehouse-import-preview" >
< div class = "warehouse-section-heading" > < div > < strong > 待导入绑定关系 < / strong > < p > 可只勾选本次需要换标的部分 , 也可以全选后一次导入 。 < / p > < / div > < div > < el-checkbox : model -value = " importedRelabelBindings.every ( ( item ) = > item . selected ) " @change=" selectAllImportedBindings ( Boolean ( $event ) ) ">全选</el-checkbox><el-button type=" primary " size=" small " @click=" importSelectedBindingsToDetails ">导入到明细</el-button></div></div>
<div class=" warehouse - table - scroll "><table class=" warehouse - binding - preview - table "><thead><tr><th>选择</th><th>关系类型</th><th>旧箱唛 </th><th>旧 SKU</th><th>新 SKU</th><th>数量</th><th>新 FBA 箱唛</th><th>FBA 目的仓</th></tr></thead><tbody><tr v-for=" item in importedRelabelBindings " :key=" item . id "><td><el-checkbox v-model=" item . selected " /></td><td>{{ item.templateType === 'mixed' ? 'SKU 混箱换标' : item.templateType === 'carton' ? '箱号关联' : 'SKU 关联' }}</td><td>{{ item.cartonMark }}</td><td>{{ item.originalSku || '—' }}</td><td>{{ item.newSku || '—' }}</td><td>{{ item.quantity }}</td><td>{{ item.fbaCartonMark || '—' }}</td><td>{{ warehouseDisplay(item.destinationWarehouseId) }}</td></tr></tbody></table></div>
<div class=" warehouse - table - scroll "><table class=" warehouse - binding - preview - table "><thead><tr><th>选择</th><th>关系类型</th><th>仓库唛头 </th><th>旧 SKU</th><th>新 SKU</th><th>数量</th><th>新 FBA 箱唛</th><th>FBA 目的仓</th></tr></thead><tbody><tr v-for=" item in importedRelabelBindings " :key=" item . id "><td><el-checkbox v-model=" item . selected " /></td><td>{{ item.templateType === 'mixed' ? 'SKU 混箱换标' : item.templateType === 'carton' ? '箱号关联' : 'SKU 关联' }}</td><td>{{ item.cartonMark }}</td><td>{{ item.originalSku || '—' }}</td><td>{{ item.newSku || '—' }}</td><td>{{ item.quantity }}</td><td>{{ item.fbaCartonMark || '—' }}</td><td>{{ warehouseDisplay(item.destinationWarehouseId) }}</td></tr></tbody></table></div>
</div>
<div class=" warehouse - section - heading warehouse - tab - actions ">
<div><strong>绑定明细</strong><p>上传后在下方回显,也可以手动添加;SKU 与箱号关联通过旧箱唛 合并。系统只提供大概库存位置,不代表箱唛已绑定具体托盘。</p></div>
<div><strong>绑定明细</strong><p>上传后在下方回显,也可以手动添加;SKU 与箱号关联通过仓库唛头 合并。系统只提供大概库存位置,不代表箱唛已绑定具体托盘。</p></div>
<div v-if=" labelingMode === 'carton' "><el-button type=" primary " size=" small " @click=" addRelabelCargoRow "><Plus :size=" 15 " />手动添加行</el-button><el-button size=" small " @click=" clearRelabelRows ">清空</el-button></div>
<div v-else><el-button type=" primary " size=" small " @click=" addSkuRelabelRow "><Plus :size=" 15 " />添加 SKU 明细</el-button><el-button size=" small " @click=" skuRelabelRows = [ ] ">清空</el-button></div>
</div>
<div v-if=" labelingMode === 'carton' " class=" warehouse - table - scroll "><table class=" warehouse - edit - table warehouse - label - table "><thead><tr><th>商品 SKU</th><th>中文品名 *</th><th>FBA 货件编号 *</th><th>箱数</th><th>旧箱唛 *</th><th>新 FBA 箱唛 *</th><th>FBA 目的仓 *</th><th>备注</th><th>操作</th></tr></thead><tbody><tr v-for=" row in cartonDetailRows " :key=" row . id "><td><el-input v-model=" row . sku " placeholder=" 选填 " /></td><td><el-input v-model=" row . name " placeholder=" 请输入中文品名 " /></td><td><el-input v-model=" row . shipmentNo " placeholder=" 请输入FBA货件编号 " /></td><td><strong>1 箱</strong></td><td><el-input v-model=" row . cartonMark " placeholder=" 请输入旧箱唛 " /></td><td><el-input v-model=" row . fbaCartonMark " placeholder=" 请输入新的 FBA 箱唛 " /></td><td><el-select v-model=" row . destinationWarehouseId " :loading=" fbaWarehousesLoading " :disabled=" Boolean ( fbaWarehousesError ) " placeholder=" 请选择 FBA 目的仓 "><el-option v-for=" warehouse in fbaWarehouses " :key=" warehouse . id " :label=" warehouseLabel ( warehouse ) " :value=" warehouse . warehouseCode " /></el-select></td><td><el-input v-model=" row . remark " type=" textarea " :rows=" 2 " maxlength=" 1000 " show-word-limit placeholder=" 请输入明细备注 " /></td><td><button type=" button " class=" warehouse - delete " title=" 移出本次明细 " @click=" removeCargoRow ( row . id ) "><Trash2 :size=" 16 " />移出</button></td></tr><tr v-if=" cartonDetailRows . length === 0 "><td colspan=" 9 "><div class=" warehouse - empty ">暂无本次换标明细,请上传关系后导入或手动添加</div></td></tr></tbody></table></div>
<div v-else class=" warehouse - table - scroll "><table class=" warehouse - edit - table warehouse - sku - label - table "><thead><tr><th>旧箱唛 *</th><th>旧 SKU *</th><th>新 SKU *</th><th>换标数量(件)*</th><th v-if=" labelingMode === 'carton_and_sku' ">新 FBA 箱唛 *</th><th v-if=" labelingMode === 'carton_and_sku' ">FBA 目的仓 *</th><th>备注</th><th>操作</th></tr></thead><tbody><tr v-for=" row in skuRelabelRows " :key=" row . id "><td><el-input v-model=" row . cartonMark " placeholder=" 请输入旧箱唛 " @change=" applyExistingCartonBinding ( row ) " /></td><td><el-input v-model=" row . originalSku " placeholder=" 请输入旧 SKU " @change=" applyExistingSkuBinding ( row ) " /></td><td><el-input v-model=" row . newSku " placeholder=" 请输入新 SKU " /></td><td><el-input-number v-model=" row . quantity " :min=" 1 " :precision=" 0 " controls-position=" right " placeholder=" 请输入件数 " /></td><td v-if=" labelingMode === 'carton_and_sku' "><el-input v-model=" row . fbaCartonMark " placeholder=" 请输入新的 FBA 箱唛 " /></td><td v-if=" labelingMode === 'carton_and_sku' "><el-select v-model=" row . destinationWarehouseId " :loading=" fbaWarehousesLoading " :disabled=" Boolean ( fbaWarehousesError ) " placeholder=" 请选择 FBA 目的仓 "><el-option v-for=" warehouse in fbaWarehouses " :key=" warehouse . id " :label=" warehouseLabel ( warehouse ) " :value=" warehouse . warehouseCode " /></el-select></td><td><el-input v-model=" row . remark " placeholder=" 请输入备注 " /></td><td><button type=" button " class=" warehouse - delete " title=" 删除 " @click=" removeSkuRelabelRow ( row . id ) "><Trash2 :size=" 16 " />删除</button></td></tr><tr v-if=" skuRelabelRows . length === 0 "><td :colspan=" labelingMode === 'carton_and_sku' ? 8 : 6 "><div class=" warehouse - empty ">暂无绑定明细,请点击“添加 SKU 明细”</div></td></tr></tbody></table></div>
<div v-if=" labelingMode === 'carton' " class=" warehouse - table - scroll "><table class=" warehouse - edit - table warehouse - label - table "><thead><tr><th>商品 SKU</th><th>中文品名 *</th><th>FBA 货件编号 *</th><th>箱数</th><th>仓库唛头 *</th><th>新 FBA 箱唛 *</th><th>FBA 目的仓 *</th><th>备注</th><th>操作</th></tr></thead><tbody><tr v-for=" row in cartonDetailRows " :key=" row . id "><td><el-input v-model=" row . sku " placeholder=" 选填 " /></td><td><el-input v-model=" row . name " placeholder=" 请输入中文品名 " /></td><td><el-input v-model=" row . shipmentNo " placeholder=" 请输入FBA货件编号 " /></td><td><strong>1 箱</strong></td><td><el-input v-model=" row . cartonMark " placeholder=" 请输入仓库唛头 " /></td><td><el-input v-model=" row . fbaCartonMark " placeholder=" 请输入新的 FBA 箱唛 " /></td><td><el-select v-model=" row . destinationWarehouseId " :loading=" fbaWarehousesLoading " :disabled=" Boolean ( fbaWarehousesError ) " placeholder=" 请选择 FBA 目的仓 "><el-option v-for=" warehouse in fbaWarehouses " :key=" warehouse . id " :label=" warehouseLabel ( warehouse ) " :value=" warehouse . warehouseCode " /></el-select></td><td><el-input v-model=" row . remark " type=" textarea " :rows=" 2 " maxlength=" 1000 " show-word-limit placeholder=" 请输入明细备注 " /></td><td><button type=" button " class=" warehouse - delete " title=" 移出本次明细 " @click=" removeCargoRow ( row . id ) "><Trash2 :size=" 16 " />移出</button></td></tr><tr v-if=" cartonDetailRows . length === 0 "><td colspan=" 9 "><div class=" warehouse - empty ">暂无本次换标明细,请上传关系后导入或手动添加</div></td></tr></tbody></table></div>
<div v-else class=" warehouse - table - scroll "><table class=" warehouse - edit - table warehouse - sku - label - table "><thead><tr><th>仓库唛头 *</th><th>旧 SKU *</th><th>新 SKU *</th><th>换标数量(件)*</th><th v-if=" labelingMode === 'carton_and_sku' ">新 FBA 箱唛 *</th><th v-if=" labelingMode === 'carton_and_sku' ">FBA 目的仓 *</th><th>备注</th><th>操作</th></tr></thead><tbody><tr v-for=" row in skuRelabelRows " :key=" row . id "><td><el-input v-model=" row . cartonMark " placeholder=" 请输入仓库唛头 " @change=" applyExistingCartonBinding ( row ) " /></td><td><el-input v-model=" row . originalSku " placeholder=" 请输入旧 SKU " @change=" applyExistingSkuBinding ( row ) " /></td><td><el-input v-model=" row . newSku " placeholder=" 请输入新 SKU " /></td><td><el-input-number v-model=" row . quantity " :min=" 1 " :precision=" 0 " controls-position=" right " placeholder=" 请输入件数 " /></td><td v-if=" labelingMode === 'carton_and_sku' "><el-input v-model=" row . fbaCartonMark " placeholder=" 请输入新的 FBA 箱唛 " /></td><td v-if=" labelingMode === 'carton_and_sku' "><el-select v-model=" row . destinationWarehouseId " :loading=" fbaWarehousesLoading " :disabled=" Boolean ( fbaWarehousesError ) " placeholder=" 请选择 FBA 目的仓 "><el-option v-for=" warehouse in fbaWarehouses " :key=" warehouse . id " :label=" warehouseLabel ( warehouse ) " :value=" warehouse . warehouseCode " /></el-select></td><td><el-input v-model=" row . remark " placeholder=" 请输入备注 " /></td><td><button type=" button " class=" warehouse - delete " title=" 删除 " @click=" removeSkuRelabelRow ( row . id ) "><Trash2 :size=" 16 " />删除</button></td></tr><tr v-if=" skuRelabelRows . length === 0 "><td :colspan=" labelingMode === 'carton_and_sku' ? 8 : 6 "><div class=" warehouse - empty ">暂无绑定明细,请点击“添加 SKU 明细”</div></td></tr></tbody></table></div>
</template>
<template v-else>
<div class=" warehouse - section - heading "><h3>货物明细</h3><div v-if=" props . service !== 'disposal' "><el-button type=" primary " size=" small " @click=" addCargoRow "><Plus :size=" 15 " />添加行</el-button><el-button size=" small " @click=" cargoRows = [ ] ">清空</el-button></div></div>
@@ -795,8 +815,8 @@ function selectRelabelInventory(inboundOrderId: string) {
<div class=" warehouse - section - heading warehouse - labeling - heading "><div><h3>货物明细</h3><p>换标明细与贴标申请保持一致;客户只填写自己的箱唛,我方箱唛由系统生成。</p></div><div class=" warehouse - template - actions "><el-button size=" small " :disabled=" ! cargoRows . length " @click=" downloadRelabelTemplate ( 'sku' ) "><Download :size=" 15 " />下载 SKU 关联模板</el-button><el-button size=" small " :disabled=" ! cargoRows . length " @click=" skuTemplateInput ? . click ( ) "><Upload :size=" 15 " />上传 SKU 关联</el-button><el-button size=" small " :disabled=" ! cargoRows . length " @click=" downloadRelabelTemplate ( 'carton' ) "><Download :size=" 15 " />下载箱号关联模板</el-button><el-button size=" small " :disabled=" ! cargoRows . length " @click=" cartonTemplateInput ? . click ( ) "><Upload :size=" 15 " />上传箱号关联</el-button><el-button size=" small " :disabled=" ! cargoRows . length " @click=" downloadRelabelTemplate ( 'mixed' ) "><Download :size=" 15 " />下载 SKU 混箱模板</el-button><el-button size=" small " :disabled=" ! cargoRows . length " @click=" mixedTemplateInput ? . click ( ) "><Upload :size=" 15 " />上传 SKU 混箱</el-button><input ref=" skuTemplateInput " class=" warehouse - hidden - input " type=" file " accept=" . csv , text / csv " @change=" importRelabelTemplate ( $event , 'sku' ) "><input ref=" cartonTemplateInput " class=" warehouse - hidden - input " type=" file " accept=" . csv , text / csv " @change=" importRelabelTemplate ( $event , 'carton' ) "><input ref=" mixedTemplateInput " class=" warehouse - hidden - input " type=" file " accept=" . csv , text / csv " @change=" importRelabelTemplate ( $event , 'mixed' ) "></div></div>
<div class=" warehouse - form - grid warehouse - transfer - relabel - fields "><label><span><i>*</i>换标截止时间</span><el-date-picker v-model=" form . labelDeadline " type=" datetime " value-format=" YYYY - MM - DDTHH : mm : ss " placeholder=" 请选择截止时间 " /></label><label><span><i>*</i>联系人</span><el-input v-model=" form . contact " placeholder=" 请输入联系人 " /></label><label><span><i>*</i>联系电话</span><el-input v-model=" form . phone " placeholder=" 请输入联系电话 " /></label><label><span><i>*</i>换标费用(CNY) </span><el-input-number v-model=" form . chargeAmount " :min=" 0.01 " :precision=" 2 " :step=" 0.01 " controls-position=" right " placeholder=" 请输入服务费用 " /></label><label v-if=" labelingMode !== 'sku' "><span><i>*</i>换标后派送方式</span><el-select v-model=" form . relabelDeliveryMethod " placeholder=" 请选择派送方式 "><el-option label=" 卡车派送 " value=" TRUCK " /><el-option label=" 快递派送 " value=" EXPRESS " /><el-option label=" 卡车自提 " value=" TRUCK _PICKUP " /><el-option label=" 快递自提 " value=" EXPRESS _PICKUP " /></el-select></label><label><span>FBA 货件编号</span><el-input v-model=" form . fbaShipmentNo " placeholder=" 选填 , 未填则使用转运单号 " /></label><label class=" warehouse - span - 2 "><span>贴标要求</span><el-input v-model=" form . requirement " type=" textarea " :rows=" 2 " maxlength=" 1000 " show-word-limit placeholder=" 请输入贴标要求 ( 选填 ) " /></label></div>
<div class=" warehouse - labeling - mode "><span>换标类型</span><el-radio-group v-model=" labelingMode " aria-label=" 换标类型 "><el-radio-button value=" carton ">只换箱唛</el-radio-button><el-radio-button value=" sku ">只换 SKU 标签</el-radio-button><el-radio-button value=" carton _and _sku ">SKU 和箱唛都换</el-radio-button></el-radio-group><p>{{ labelingModeHint }}</p></div>
<div v-if=" importedRelabelBindings . length " class=" warehouse - import - preview "><div class=" warehouse - section - heading "><div><strong>待导入绑定关系</strong><p>可只勾选本次需要换标的部分,也可以全选后一次导入。</p></div><div><el-checkbox :model-value=" importedRelabelBindings . every ( ( item ) => item . selected ) " @change=" selectAllImportedBindings ( Boolean ( $event ) ) ">全选</el-checkbox><el-button type=" primary " size=" small " @click=" importSelectedBindingsToDetails ">导入到明细</el-button></div></div><div class=" warehouse - table - scroll "><table class=" warehouse - binding - preview - table "><thead><tr><th>选择</th><th>关系类型</th><th>旧箱唛 </th><th>旧 SKU</th><th>新 SKU</th><th>数量</th><th>新 FBA 箱唛</th><th>FBA 目的仓</th></tr></thead><tbody><tr v-for=" item in importedRelabelBindings " :key=" item . id "><td><el-checkbox v-model=" item . selected " /></td><td>{{ item.templateType === 'mixed' ? 'SKU 混箱换标' : item.templateType === 'carton' ? '箱号关联' : 'SKU 关联' }}</td><td>{{ item.cartonMark }}</td><td>{{ item.originalSku || '—' }}</td><td>{{ item.newSku || '—' }}</td><td>{{ item.quantity }}</td><td>{{ item.fbaCartonMark || '—' }}</td><td>{{ warehouseDisplay(item.destinationWarehouseId) }}</td></tr></tbody></table></div></div>
<div class=" warehouse - section - heading warehouse - tab - actions "><div><strong>绑定明细</strong><p>上传后在下方回显,也可以手动添加;客户箱唛作为旧箱唛 来源,系统我方箱唛不需要手填。</p></div><div><el-button type=" primary " size=" small " @click=" addTransferRelabelRow "><Plus :size=" 15 " />添加 SKU 明细</el-button><el-button size=" small " @click=" clearTransferRelabelRows ">清空</el-button></div></div>
<div v-if=" importedRelabelBindings . length " class=" warehouse - import - preview "><div class=" warehouse - section - heading "><div><strong>待导入绑定关系</strong><p>可只勾选本次需要换标的部分,也可以全选后一次导入。</p></div><div><el-checkbox :model-value=" importedRelabelBindings . every ( ( item ) => item . selected ) " @change=" selectAllImportedBindings ( Boolean ( $event ) ) ">全选</el-checkbox><el-button type=" primary " size=" small " @click=" importSelectedBindingsToDetails ">导入到明细</el-button></div></div><div class=" warehouse - table - scroll "><table class=" warehouse - binding - preview - table "><thead><tr><th>选择</th><th>关系类型</th><th>仓库唛头 </th><th>旧 SKU</th><th>新 SKU</th><th>数量</th><th>新 FBA 箱唛</th><th>FBA 目的仓</th></tr></thead><tbody><tr v-for=" item in importedRelabelBindings " :key=" item . id "><td><el-checkbox v-model=" item . selected " /></td><td>{{ item.templateType === 'mixed' ? 'SKU 混箱换标' : item.templateType === 'carton' ? '箱号关联' : 'SKU 关联' }}</td><td>{{ item.cartonMark }}</td><td>{{ item.originalSku || '—' }}</td><td>{{ item.newSku || '—' }}</td><td>{{ item.quantity }}</td><td>{{ item.fbaCartonMark || '—' }}</td><td>{{ warehouseDisplay(item.destinationWarehouseId) }}</td></tr></tbody></table></div></div>
<div class=" warehouse - section - heading warehouse - tab - actions "><div><strong>绑定明细</strong><p>上传后在下方回显,也可以手动添加;客户箱唛作为仓库唛头 来源,系统我方箱唛不需要手填。</p></div><div><el-button type=" primary " size=" small " @click=" addTransferRelabelRow "><Plus :size=" 15 " />添加 SKU 明细</el-button><el-button size=" small " @click=" clearTransferRelabelRows ">清空</el-button></div></div>
<div v-if=" labelingMode === 'carton' " class=" warehouse - table - scroll "><table class=" warehouse - edit - table warehouse - transfer - mark - table "><thead><tr><th>客户箱唛号 *</th><th>旧 SKU</th><th>新 FBA 箱唛 *</th><th>FBA 目的仓 *</th><th>备注</th><th>操作</th></tr></thead><tbody><tr v-for=" row in transferRelabelRows " :key=" row . id "><td><el-input v-model=" row . customerCartonMarks " type=" textarea " :rows=" 2 " placeholder=" 请输入客户箱唛号 " /></td><td><el-input :model-value=" row . sku " readonly /></td><td><el-input v-model=" row . fbaCartonMark " placeholder=" 请输入新的 FBA 箱唛 " /></td><td><el-select v-model=" row . destinationWarehouseId " :loading=" fbaWarehousesLoading " :disabled=" Boolean ( fbaWarehousesError ) " filterable placeholder=" 请选择 FBA 目的仓 "><el-option v-for=" warehouse in fbaWarehouses " :key=" warehouse . id " :label=" warehouseLabel ( warehouse ) " :value=" warehouse . warehouseCode " /></el-select></td><td><el-input v-model=" row . remark " type=" textarea " :rows=" 2 " placeholder=" 请输入备注 " /></td><td><button type=" button " class=" warehouse - delete " title=" 删除该明细 " @click=" transferRelabelRows = transferRelabelRows . filter ( ( item ) => item . id !== row . id ) "><Trash2 :size=" 16 " />删除</button></td></tr><tr v-if=" transferRelabelRows . length === 0 "><td colspan=" 6 "><div class=" warehouse - empty ">暂无绑定明细,请点击“添加 SKU 明细”</div></td></tr></tbody></table></div>
<div v-else-if=" labelingMode === 'sku' " class=" warehouse - table - scroll "><table class=" warehouse - edit - table warehouse - transfer - mark - table "><thead><tr><th>客户箱唛号 *</th><th>旧 SKU *</th><th>新 SKU *</th><th>换标数量(件)*</th><th>备注</th><th>操作</th></tr></thead><tbody><tr v-for=" row in transferRelabelRows " :key=" row . id "><td><el-input v-model=" row . customerCartonMarks " type=" textarea " :rows=" 2 " placeholder=" 请输入客户箱唛号 " /></td><td><el-input :model-value=" row . sku " readonly /></td><td><el-input v-model=" row . newSkuCode " placeholder=" 请输入新 SKU " /></td><td><el-input-number v-model=" row . quantity " :min=" 1 " :precision=" 0 " controls-position=" right " placeholder=" 请输入箱数 " /></td><td><el-input v-model=" row . remark " type=" textarea " :rows=" 2 " placeholder=" 请输入备注 " /></td><td><button type=" button " class=" warehouse - delete " title=" 删除该明细 " @click=" transferRelabelRows = transferRelabelRows . filter ( ( item ) => item . id !== row . id ) "><Trash2 :size=" 16 " />删除</button></td></tr><tr v-if=" transferRelabelRows . length === 0 "><td colspan=" 6 "><div class=" warehouse - empty ">暂无绑定明细,请点击“添加 SKU 明细”</div></td></tr></tbody></table></div>
<div v-else class=" warehouse - table - scroll "><table class=" warehouse - edit - table warehouse - transfer - mark - table "><thead><tr><th>客户箱唛号 *</th><th>旧 SKU *</th><th>新 SKU *</th><th>换标数量(件)*</th><th>新 FBA 箱唛 *</th><th>FBA 目的仓 *</th><th>备注</th><th>操作</th></tr></thead><tbody><tr v-for=" row in transferRelabelRows " :key=" row . id "><td><el-input v-model=" row . customerCartonMarks " type=" textarea " :rows=" 2 " placeholder=" 请输入客户箱唛号 " /></td><td><el-input :model-value=" row . sku " readonly /></td><td><el-input v-model=" row . newSkuCode " placeholder=" 请输入新 SKU " /></td><td><el-input-number v-model=" row . quantity " :min=" 1 " :precision=" 0 " controls-position=" right " placeholder=" 请输入数量 " /></td><td><el-input v-model=" row . fbaCartonMark " placeholder=" 请输入新的 FBA 箱唛 " /></td><td><el-select v-model=" row . destinationWarehouseId " :loading=" fbaWarehousesLoading " :disabled=" Boolean ( fbaWarehousesError ) " filterable placeholder=" 请选择 FBA 目的仓 "><el-option v-for=" warehouse in fbaWarehouses " :key=" warehouse . id " :label=" warehouseLabel ( warehouse ) " :value=" warehouse . warehouseCode " /></el-select></td><td><el-input v-model=" row . remark " type=" textarea " :rows=" 2 " placeholder=" 请输入备注 " /></td><td><button type=" button " class=" warehouse - delete " title=" 删除该明细 " @click=" transferRelabelRows = transferRelabelRows . filter ( ( item ) => item . id !== row . id ) "><Trash2 :size=" 16 " />删除</button></td></tr><tr v-if=" transferRelabelRows . length === 0 "><td colspan=" 8 "><div class=" warehouse - empty ">暂无绑定明细,请点击“添加 SKU 明细”</div></td></tr></tbody></table></div>
@@ -851,4 +871,5 @@ function selectRelabelInventory(inboundOrderId: string) {
. warehouse - transfer - relabel . warehouse - labeling - heading > div : first - child { min - width : 0 } . warehouse - transfer - relabel . warehouse - labeling - heading h3 { margin - bottom : 6 px } . warehouse - transfer - relabel . warehouse - labeling - heading p { margin : 0 0 16 px ; color : # 7 d8797 ; font - size : 12 px } . warehouse - transfer - relabel - fields { margin - bottom : 18 px } . warehouse - transfer - mark - table { min - width : 1420 px } . warehouse - transfer - mark - table td { vertical - align : top } . warehouse - transfer - mark - table : deep ( . el - textarea ) { min - width : 220 px } . warehouse - transfer - mark - table : deep ( . el - input - number ) { width : 150 px } . warehouse - count - error { color : # d64545 }
. warehouse - transfer - form { display : grid ; grid - template - columns : minmax ( 0 , 1 fr ) ; gap : 12 px } . warehouse - transfer - form -- relabel { grid - template - columns : minmax ( 0 , 1 fr ) minmax ( 0 , 1.35 fr ) ; align - items : start } . warehouse - transfer - form -- relabel . warehouse - transfer - main - card { grid - column : 1 ; grid - row : 1 } . warehouse - transfer - form -- relabel . warehouse - transfer - cargo - card { grid - column : 1 ; grid - row : 2 } . warehouse - transfer - form -- relabel . warehouse - transfer - relabel { grid - column : 2 ; grid - row : 1 / span 2 ; margin - bottom : 0 } . warehouse - transfer - form -- relabel . warehouse - transfer - submit - bar { grid - column : 1 / - 1 } . warehouse - transfer - form : deep ( . el - input _ _wrapper ) , . warehouse - transfer - form : deep ( . el - textarea _ _inner ) , . warehouse - transfer - form : deep ( . el - select _ _wrapper ) , . warehouse - transfer - form : deep ( . el - date - editor . el - input _ _wrapper ) { min - height : 32 px } . warehouse - transfer - form . warehouse - form - section { padding : 16 px } . warehouse - transfer - form . warehouse - form - section h3 { margin - bottom : 12 px ; padding - bottom : 9 px ; font - size : 14 px } . warehouse - transfer - form . warehouse - form - grid { gap : 12 px 16 px } . warehouse - transfer - form . warehouse - choice - field { min - height : 34 px ; padding : 8 px 10 px ; grid - template - columns : 118 px auto 1 fr ; gap : 10 px } . warehouse - transfer - form . warehouse - choice - field > span { font - size : 12 px } . warehouse - transfer - form . warehouse - choice - field small { font - size : 11 px } . warehouse - transfer - form . warehouse - receiving - card { gap : 12 px ; padding : 10 px 12 px } . warehouse - transfer - form . warehouse - section - heading { margin - bottom : 8 px } . warehouse - transfer - form . warehouse - edit - table { font - size : 11 px } . warehouse - transfer - form . warehouse - edit - table th { height : 36 px ; padding : 0 9 px } . warehouse - transfer - form . warehouse - edit - table td { height : 42 px ; padding : 6 px 7 px } . warehouse - transfer - form . warehouse - transfer - mark - table : deep ( . el - textarea ) { min - width : 150 px } . warehouse - transfer - form . warehouse - transfer - mark - table : deep ( . el - input - number ) { width : 112 px } . warehouse - transfer - form . warehouse - hint { margin - top : 5 px ; font - size : 11 px } . warehouse - transfer - form . warehouse - labeling - mode { gap : 9 px ; margin - bottom : 10 px ; padding : 9 px 10 px } . warehouse - transfer - form . warehouse - labeling - mode > span { font - size : 12 px } . warehouse - transfer - form . warehouse - labeling - mode p { font - size : 11 px } . warehouse - transfer - form . warehouse - labeling - mode : deep ( . el - radio - button _ _inner ) { padding : 6 px 9 px } . warehouse - transfer - form . warehouse - template - actions { gap : 5 px ; padding - bottom : 8 px } . warehouse - transfer - form . warehouse - template - actions : deep ( . el - button ) { padding : 6 px 8 px ; font - size : 11 px } . warehouse - transfer - form . warehouse - submit - bar { padding : 4 px 0 18 px } . warehouse - transfer - form . warehouse - submit - bar : deep ( . el - button ) { min - height : 32 px ; padding : 7 px 14 px } . warehouse - transfer - form . warehouse - transfer - relabel { overflow : hidden } . warehouse - transfer - form . warehouse - transfer - relabel - fields { margin - bottom : 10 px }
@ media ( max - width : 1250 px ) { . warehouse - transfer - form -- relabel { grid - template - columns : minmax ( 0 , 1 fr ) minmax ( 0 , 1 fr ) } . warehouse - transfer - form . warehouse - template - actions { justify - content : flex - start } . warehouse - transfer - form . warehouse - labeling - heading { align - items : flex - start ; flex - direction : column } }
. warehouse - transfer - form . pickup - address - field { grid - column : span 1 }
< / style >