@@ -21,7 +21,7 @@
< view class = "work-card" >
< text class = "card-title" > 本次实物单元 < / text >
< view class = "unit-tabs" > < button v-for = "item in unitOptions" :key="item.value" :class="['unit-tab', {active: unitType === item.value}]" @tap="selectUnitType(item.value)" > {{ item.label }} < / button > < / view >
< view v-if = "unitType === 'PARCEL'"><text class="field-label">包裹码/快递单号</text><ScanTargetInput name="unit" v-model="unitCode" label="包裹码/快递单号" placeholder="扫描快递面单 " :active="activeTarget === 'unit'" @activate="activeTarget = 'unit'" @submit="acceptUnit" / > < / view >
< view v-if = "unitType === 'PARCEL'"><text class="field-label">包裹码/快递单号(选填) </text><ScanTargetInput name="unit" v-model="unitCode" label="包裹码/快递单号(选填) " placeholder="可 扫描,留空将自动生成 " :active="activeTarget === 'unit'" @activate="activeTarget = 'unit'" @submit="acceptUnit" / > < / view >
< template v-else >
< view > < text class = "field-label" > 托盘码 ( { { unitType === 'BOX' ? '选填' : '必填' } } ) < / text > < ScanTargetInput name = "pallet" v-model = "palletCode" label="托盘码" placeholder="扫描已有托盘或新托盘标签" :active="activeTarget === 'pallet'" @activate="activeTarget = 'pallet'" @submit="acceptPallet" /><text v-if="palletCheck" class="scan-hint">{{ palletCheck.empty ? '空托盘,可绑定当前退货单和 SKU' : `当前单托盘,已有 ${palletCheck.skuCodes.join('、')},共 ${palletCheck.quantity} 件` }}</text><button class="secondary pallet-generate" :disabled="busy" @tap="generatePallet" > 生成新托盘 < / button > < / view >
< view v-if = "unitType === 'PALLET'" class="dimension-grid"><label><text>托盘长(cm) </text><input class="number-input" type="digit" v-model="palletLength" placeholder="请输入长度(cm) " /></label><label><view class="dimension-label"><text>托盘宽(cm) </text><text class="volume-text">体积 {{ palletVolume }} cm³</text></view><input class="number-input" type="digit" v-model="palletWidth" placeholder="请输入宽度(cm) " /></label><label><text>托盘高(cm) </text><input class="number-input" type="digit" v-model="palletHeight" placeholder="请输入高度(cm) " /></label><label><text>托盘重量(kg) </text><input class="number-input" type="digit" v-model="palletWeight" placeholder="请输入重量(kg) " / > < / label > < / view >
@@ -30,7 +30,7 @@
< / view >
< view class = "work-card" > < view class = "row-head" > < text class = "card-title" > { { unitType === 'PARCEL' ? '本次实收数量' : ( unitType === 'PALLET' ? '本托实收数量' : '逐箱实收数量' ) } } < / text > < button v-if = "unitType !== 'BOX'" class="link-button" @tap="fillRemaining">全部填入</button></view><view v-if="unitType === 'PALLET'" class="quantity-row"><text>本托箱数合计</text><strong class="auto-count">{{ palletBoxCount }}</strong></view><template v-if="unitType === 'BOX'"><view class="quantity-row"><text>本次箱数</text><input class="number-input" type="number" :value="boxRows.length" placeholder="箱数" @input="resizeBoxRows($event.detail.value)" /></view><view v-for="(box,index) in boxRows" :key="index" class="item-card"><text class="business-code">第 {{ index + 1 }} 箱</text><view v-for="item in selectedItems" :key="item.skuCode" class="quantity-row"><text>{{ item.skuCode }} · 数量</text><input class="number-input" type="number" :value="box.items[item.skuCode] || ''" placeholder="0" @input="setBoxQuantity(index, item.skuCode, $event.detail.value)" /></view></view></template><view v-else class="item-list receipt-sku-list"><view v-for="item in selectedItems" :key="item.skuCode" class="item-card"><view class="row-head"><view><text class="business-code">{{ item.skuCode }}</text><text class="meta-line">{{ item.productNameZh || '商品名称未填写' }}</text></view><text class="remaining-copy">剩余 {{ remaining(item) }}</text></view><view class="sku-quantity-fields"><view class="quantity-row"><text>数量</text><input class="number-input" type="number" :value="quantity(item.skuCode)" placeholder="0" @input="setQuantity(item, $event.detail.value)" /></view><view v-if="unitType === 'PALLET'" class="quantity-row"><text>SKU 箱数</text><input class="number-input" type="number" :value="boxCount(item.skuCode)" placeholder="0" @input="setBoxCount(item, $event.detail.value)" / > < / view > < / view > < / view > < / view > < / view >
< view class = "summary-bar" > < view > < text class = "summary-label" > 本托合计 < / text > < text class = "summary-value" > { { receiptQuantity } } < / text > < / view > < button class = "primary submit-button" : disabled = "!canConfirm || busy" @tap ="confirmReceipt" > {{ busy ? ' 提交中 … ' : ' 确认签收并入托 ' }} < / button > < / view >
< view class = "summary-bar" > < view > < text class = "summary-label" > { { unitType === 'PARCEL' ? '本次合计' : '本托合计' } } < / text > < text class = "summary-value" > { { receiptQuantity } } < / text > < / view > < button class = "primary submit-button" : disabled = "!canConfirm || busy" @tap ="confirmReceipt" > {{ busy ? ' 提交中 … ' : unitType = = = ' PARCEL ' ? ' 确认包裹签收 ' : ' 确认签收并入托 ' }} < / button > < / view >
< view class = "work-card" > < view class = "row-head" > < view > < text class = "card-title" > 退货打托照片 < / text > < text class = "hint" > 签收过程中可随时拍照 < / text > < / view > < text class = "status-pill" > { { photoFileIds . length } } / 20 张 < / text > < / view > < button class = "secondary" : disabled = "busy || photoFileIds.length >= 20" @tap ="choosePhoto" > 拍照或从相册选择 < / button > < view v-if = "photoFileIds.length" class="photo-grid"><view v-for="(fileId,index) in photoFileIds" :key="fileId" class="photo-tile"><image class="photo-thumbnail" :src="photoUrls[fileId]" mode="aspectFill" @tap="previewPhoto(fileId)" /><text class="photo-name">{{ photoNames[index] || '退货打托照片' }}</text><button class="link-button" :disabled="busy" @tap="removePhoto(index)" > 移除 < / button > < / view > < / view > < / view >
< button v-if = "current.status === 'PARTIALLY_RECEIVED'" class="secondary manual-complete" :disabled="busy" @tap="manualComplete" > 缺货手动完结 < / button >
< view v-if = "current.completedPallets?.length" class="work-card"><text class="card-title">本单已完成打托</text><view class="item-list"><view v-for="pallet in current.completedPallets" :key="pallet.palletCode" class="item-card"><text class="business-code">{{ pallet.palletCode }}</text><text class="meta-line">{{ pallet.skuCode }} · {{ pallet.quantity }} 件</text><text class="meta-line" > 签收批次 : {{ pallet.receiptBatchNo }} < / text > < / view > < / view > < / view >
@@ -66,7 +66,7 @@
palletBoxCount ( ) { return this . selectedItems . reduce ( ( sum , item ) => sum + this . boxCount ( item . skuCode ) , 0 ) } ,
activeSkuCode ( ) { return this . selectedItems . find ( item => item . skuCode === this . selectedSku ) ? . skuCode || this . selectedItems [ 0 ] ? . skuCode || '' } ,
receiptQuantity ( ) { return this . unitType === 'BOX' ? this . boxRows . reduce ( ( sum , box ) => sum + Object . values ( box . items ) . reduce ( ( n , quantity ) => n + ( Number ( quantity ) || 0 ) , 0 ) , 0 ) : Object . values ( warehouseWork . returnReceipt . quantities || { } ) . reduce ( ( total , value ) => total + ( Number ( value ) || 0 ) , 0 ) } ,
canConfirm ( ) { if ( ! this . current || ! this . selectedItems . length || this . receiptQuantity <= 0 ) return false ; if ( this . unitType === 'BOX' ) return this . boxRows . length > 0 && this . boxRows . every ( box => Object . values ( box . items ) . some ( quantity => Number ( quantity ) > 0 ) ) && this . selectedItems . every ( item => this . boxRows . reduce ( ( sum , box ) => sum + ( Number ( box . items [ item . skuCode ] ) || 0 ) , 0 ) <= this . remaining ( item ) ) ; return ( this . unitType === 'PARCEL' ? this . unitCode . trim ( ) : this . palletCode . trim ( ) && this . palletCheck && Number ( this . palletLength ) > 0 && Number ( this . palletWidth ) > 0 && Number ( this . palletHeight ) > 0 && Number ( this . palletWeight ) > 0 && ( this . unitType !== 'PALLET' || this . palletBoxCount > 0 ) ) && this . selectedItems . every ( ( item ) => this . quantity ( item . skuCode ) <= this . remaining ( item ) && ( this . unitType !== 'PALLET' || this . quantity ( item . skuCode ) === 0 || this . boxCount ( item . skuCode ) > 0 ) ) ; } ,
canConfirm ( ) { if ( ! this . current || ! this . selectedItems . length || this . receiptQuantity <= 0 ) return false ; if ( this . unitType === 'BOX' ) return this . boxRows . length > 0 && this . boxRows . every ( box => Object . values ( box . items ) . some ( quantity => Number ( quantity ) > 0 ) ) && this . selectedItems . every ( item => this . boxRows . reduce ( ( sum , box ) => sum + ( Number ( box . items [ item . skuCode ] ) || 0 ) , 0 ) <= this . remaining ( item ) ) ; return ( this . unitType === 'PARCEL' || ( this . palletCode . trim ( ) && this . palletCheck && Number ( this . palletLength ) > 0 && Number ( this . palletWidth ) > 0 && Number ( this . palletHeight ) > 0 && Number ( this . palletWeight ) > 0 && ( this . unitType !== 'PALLET' || this . palletBoxCount > 0 ) ) ) && this . selectedItems . every ( ( item ) => this . quantity ( item . skuCode ) <= this . remaining ( item ) && ( this . unitType !== 'PALLET' || this . quantity ( item . skuCode ) === 0 || this . boxCount ( item . skuCode ) > 0 ) ) ; } ,
unitLabel ( ) { return this . unitType === 'PALLET' ? '托盘码' : this . unitType === 'BOX' ? '箱号/箱唛' : '包裹码/快递单号' } ,
unitPlaceholder ( ) { return this . unitType === 'PALLET' ? '扫描托盘标签' : this . unitType === 'BOX' ? '扫描箱唛或录入箱号' : '扫描包裹面单或录入包裹码' }
, palletVolume ( ) { const l = Number ( this . palletLength ) || 0 ; const w = Number ( this . palletWidth ) || 0 ; const h = Number ( this . palletHeight ) || 0 ; return l > 0 && w > 0 && h > 0 ? ( l * w * h ) . toFixed ( 2 ) : '—' }