@@ -7,7 +7,7 @@
< view v-if = "current" class="detail-toolbar"><view><text class="detail-kicker">当前任务</text><text class="detail-title">出库作业详情</text></view><button :disabled="busy" @tap="closeTask" > ‹ 返回列表 < / button > < / view >
< view class = "fulfillment-card" >
< ScanTargetInput name = "outbound" :model-value = "scanCode" :label = "scanLabel" :placeholder = "scanPlaceholder" :active = "true" @ update :modelValue = "updateScanCode" @submit ="handleScan" / >
< button class = "secondary-button" : disabled = "!scanCode || loading || busy || discardLoading || discardBusy" @tap ="handleScan(scanCode)" > {{ discardCurrent ? ' 打开废弃托盘 ' : current ? ' 匹配出库货物 ' : ' 打开出库任务 ' }} < / button >
< button class = "secondary-button" : disabled = "!scanCode || loading || busy || discardLoading || discardBusy" @tap ="handleScan(scanCode)" > {{ discardCurrent ? ( discardTask ? .scanMode = = = ' CARTON ' ? ' 核对废弃箱唛 ' : ' 打开废弃托盘 ' ) : current ? ' 匹配出库货物 ' : ' 打开出库任务 ' }} < / button >
< text class = "scan-help" > 任务号直接恢复 ; 退货整托出库扫托盘码 , 散箱出库扫箱唛 。 < / text >
< / view >
@@ -20,7 +20,7 @@
< button v-for = "task in tasks" :key="task.taskNo" class="task-card" @tap="openTask(task.taskNo)"><view class="task-head"><view class="task-code-row"><text class="business-code">{{ task.taskNo || '—' }}</text><text v-if="task.taskNo === recentTaskNo" class="recent-badge">上次作业</text></view><text class="status-badge">{{ statusLabel(task.status) }}</text></view><text class="task-meta">出库单 {{ task.outboundNo || '—' }} · {{ taskType(task) }}</text><text class="task-enter" > 查看并开始出库 › < / text > < / button >
< / view >
< view v-else-if = "!error && !discardTasks.length" class="fulfillment-state"><text class="state-title" > 暂无出库任务 < / text > < text > 可刷新列表 , 或扫描任务号恢复未完成作业 。 < / text > < / view >
< view v-if = "discardTasks.length" class="discard-section"><view class="list-toolbar"><view><text class="list-title">废弃订单</text><text class="list-count">{{ discardOrderCount }} 个订单</text></view></view><view class="task-list"><button v-for="order in discardOrders" :key="order.discardNo" class="task-card" @tap="openDiscardOrder(order.discardNo)"><view class="task-head"><view class="task-code-row"><text class="business-code">{{ order.discardNo || '—' }}</text></view><text class="status-badge">废弃订单</text></view><text class="task-meta">托盘 {{ order.palletCount }} 个 · 待作业 {{ order.pendingPalletCount }} 个</text><text class="task-enter" > 点击进入 , 扫描对应托盘 › < / text > < / button > < / view > < / view >
< view v-if = "discardTasks.length" class="discard-section"><view class="list-toolbar"><view><text class="list-title">废弃订单</text><text class="list-count">{{ discardOrderCount }} 个订单</text></view></view><view class="task-list"><button v-for="order in discardOrders" :key="order.discardNo" class="task-card" @tap="openDiscardOrder(order.discardNo)"><view class="task-head"><view class="task-code-row"><text class="business-code">{{ order.discardNo || '—' }}</text></view><text class="status-badge">废弃订单</text></view><text v-if="order.outboundNo" class="task-meta">出库单 {{ order.outboundNo }} · 废弃出库</text><text class="task-meta">托盘 {{ order.palletCount }} 个 · 按箱废弃 {{ order.cartonCount }} 箱 · 待作业 {{ order.pendingPalletCount }} 个</text><text class="task-enter" > 点击进入废弃出库作业 › < / text > < / button > < / view > < / view >
< / template >
< template v-if = "current" >
@@ -44,9 +44,9 @@
< / template >
< template v-else-if = "discardCurrent" >
< view class = "detail-toolbar" > < view > < text class = "detail-kicker" > 废弃订单 < / text > < text class = "detail-title" > { { discardCurrent . discardNo } } < / text > < / view > < button :disabled = "discardBusy" @tap ="closeDiscard" > ‹ 返回列表 < / button > < / view >
< view class = "fulfillment-card" > < ScanTargetInput name = "cargo-discard" :model-value = "discardPalletCode" label = "废弃托盘码" placeholder = "扫描对应托盘码" :active = "true" @ update :modelValue = "updateDiscardPalletCode" @submit ="resolveDiscardPallet" / > < button class = "secondary-button" : disabled = "!discardPalletCode || discardLoading || discardBusy" @tap ="resolveDiscardPallet" > {{ discardLoading ? ' 读取中 … ' : ' 打开托盘废弃作业 ' }} < / button > < text class = "scan-help" > 扫描该废弃订单对应的托盘 , 再填写每个 SKU 的实际废弃数量 。 < / text > < / view >
< view v-if = "discardTask" class="fulfillment-card item-card"><view class="task-head"><text class="business-code">托盘 {{ discardTask.palletNo }}</text><text class="status-badge">{{ discardTask.status === 'COMPLETED' ? '已完成' : '待废弃' }}</text></view><view v-for="sku in discardTask.skus" :key="sku.itemId" class="outbound-line"><text class="line-code">{{ sku.skuCode || '—' }}</text><text class="line-meta">{{ sku.productName || '—' }} · 计划 {{ sku.plannedPackages }} 箱</text><view class="count-row"><text>实际废弃数量</text><input type="number" :value="discardActuals[sku.itemId]" :disabled ="discardTask.status = == 'COMPLETED'" :placeholder="`请输入 0-${sku.plannedPackages} 箱`" @input="updateDiscardActual(sku.itemId, $event)" /><text>最多 {{ sku.plannedPackages }} 箱</text></view ></view><view class="discard-photo-section"><text class="business-code">废弃现场照片(至少 1 张)</text><text class="scan-help">照片关联当前托盘 ,完成出库后可在废弃单详情查看。</text><view class="discard-photo-grid"><view v-for="photo in discardPhotos" :key="photo.fileId" class="discard-photo-tile"><image v-if="discardPhotoUrls[photo.fileId]" :src="discardPhotoUrls[photo.fileId]" mode="aspectFill" @tap="previewDiscardPhoto(photo.fileId)" /><button v-else class="secondary-button" @tap="loadDiscardPhoto(photo.fileId)">{{ discardPhotoErrors[photo.fileId] ? '加载失败,点击重试' : '加载照片' }}</button></view></view><button v-if="discardTask.status !== 'COMPLETED'" class="secondary-button" :disabled="discardLoading || discardBusy || discardPhotoBusy || !discardPhotoReady || discardPhotos.length >= 20" @tap="takeDiscardPhoto">{{ discardPhotoBusy ? '照片上传中…' : '拍摄废弃现场照片' }}( {{ discardPhotos.length }}/20) </button><button v-if="!discardPhotoReady" class="secondary-button" :disabled="discardLoading || discardPhotoBusy" @tap="restoreDiscardPhotos">重试读取照片</button></view><button class="primary-button" :disabled="!canConfirmDiscard || discardBusy" @tap="confirmDiscard" > {{ discardBusy ? ' 提交中 … ' : ' 废弃出库 ' }} < / button > < / view >
< view class = "detail-toolbar" > < view > < text class = "detail-kicker" > 废弃订单 < / text > < text class = "detail-title" > { { discardCurrent . discardNo } } < / text > < text v-if = "discardCurrent.outboundNo" class="task-meta">出库单 {{ discardCurrent.outboundNo }}</text></view><button :disabled= "discardBusy" @tap="closeDiscard"> ‹ 返回列表 < / button > < / view >
< view class = "fulfillment-card" > < ScanTargetInput name = "cargo-discard" :model-value = "discardPalletCode" : label = "discardTask?.scanMode === 'CARTON' ? '废弃箱唛' : ' 废弃托盘码' " : placeholder = "discardTask?.scanMode === 'CARTON' ? '扫描本单所选箱唛' : ' 扫描对应托盘码' " :active = "true" @ update :modelValue = "updateDiscardPalletCode" @submit ="resolveDiscardPallet" / > < button class = "secondary-button" : disabled = "!discardPalletCode || discardLoading || discardBusy" @tap ="resolveDiscardPallet" > {{ discardLoading ? ' 读取中 … ' : discardTask ? .scanMode = = = ' CARTON ' ? ' 核对箱唛 ' : ' 打开托盘废弃作业 ' }} < / button > < text class = "scan-help" > 整托废弃扫描托盘号 ; 部分箱子废弃或散箱作业 , 核对本单所选箱唛 , 也可一键废弃所选箱子 。 未选箱子保留库存 。 < / text > < / view >
< view v-if = "discardTask" class="fulfillment-card item-card"><view class="task-head"><text class="business-code">{{ discardTask.scanMode === 'CARTON' ? (discardTask.palletNo === '散箱' ? '散箱废弃' : '按箱废弃 · ' + discardTask.palletNo) : '托盘 ' + discardTask.palletNo }}</text><text class="status-badge">{{ discardTask.status === 'COMPLETED' ? '已完成' : '待废弃' }}</text></view><view v-for="sku in discardTask.skus" :key="sku.itemId" class="outbound-line"><text class="line-code">{{ sku.skuCode || '—' }}</text><text class="line-meta">{{ sku.productName || '—' }} · 计划 {{ sku.plannedPackages }} 箱</text><view class="count-row"><text>本单所选废弃 {{ sku.plannedPackages }} 箱</text></view></view><view v-if="discardTask.scanMode === 'CARTON'"><text class="scan-help">已核对 {{ discardScannedMarks.length }}/{{ discardTask.cartonMarks.length }} 箱</text><view v-for="mark in discardTask.cartonMarks" :key="mark" class="outbound-line"><text>{{ mark }}</text><text>{{ discardAllCartons ? '全部废弃' : discardScannedMarks.includes(mark) ? '已扫描' : '待扫描' }}</text></view><button v-if ="discardTask.status ! == 'COMPLETED'" class="secondary-button" :disabled="discardBusy || discardLoading || discardPhotoBusy" @tap="discardAllCartons = true">一键废弃本单所选箱子({{ discardTask.cartonMarks.length }} 箱)</button><text v-if="discardAllCartons" class="scan-help">已确认本单所选箱子全部废弃,拍照后点击废弃出库完成。</text ></view><view class="discard-photo-section"><text class="business-code">废弃现场照片(至少 1 张)</text><text class="scan-help">照片关联当前废弃作业 ,完成出库后可在废弃单详情查看。</text><view class="discard-photo-grid"><view v-for="photo in discardPhotos" :key="photo.fileId" class="discard-photo-tile"><image v-if="discardPhotoUrls[photo.fileId]" :src="discardPhotoUrls[photo.fileId]" mode="aspectFill" @tap="previewDiscardPhoto(photo.fileId)" /><button v-else class="secondary-button" @tap="loadDiscardPhoto(photo.fileId)">{{ discardPhotoErrors[photo.fileId] ? '加载失败,点击重试' : '加载照片' }}</button></view></view><button v-if="discardTask.status !== 'COMPLETED'" class="secondary-button" :disabled="discardLoading || discardBusy || discardPhotoBusy || !discardPhotoReady || discardPhotos.length >= 20" @tap="takeDiscardPhoto">{{ discardPhotoBusy ? '照片上传中…' : '拍摄废弃现场照片' }}( {{ discardPhotos.length }}/20) </button><button v-if="!discardPhotoReady" class="secondary-button" :disabled="discardLoading || discardPhotoBusy" @tap="restoreDiscardPhotos">重试读取照片</button></view><button class="primary-button" :disabled="!canConfirmDiscard || discardBusy" @tap="confirmDiscard" > {{ discardBusy ? ' 提交中 … ' : ' 废弃出库 ' }} < / button > < / view >
< / template >
< view v-if = "successMessage" class="fulfillment-success" role="status" > < text > { { successMessage } } < / text > < / view >
@@ -66,7 +66,7 @@
export default {
components : { PortalHeader , ScanTargetInput } ,
data ( ) { return { user : session . currentUser , tasks : [ ] , discardTasks : [ ] , current : null , discardCurrent : null , discardTask : null , discardActuals : { } , discardPhotos : [ ] , discardPhotoUrls : { } , discardPhotoErrors : { } , discardPhotoBusy : false , discardPhotoReady : false , discardPalletCode : '' , discardLoading : false , discardBusy : false , selectedItem : null , selectedPosition : null , selectedScanCode : '' , scanCode : '' , loading : false , busy : false , busyAction : '' , error : null , successMessage : '' , bootstrapped : false } } ,
data ( ) { return { user : session . currentUser , tasks : [ ] , discardTasks : [ ] , current : null , discardCurrent : null , discardTask : null , discardActuals : { } , discardScannedMarks : [ ] , discardAllCartons : false , discardPhotos : [ ] , discardPhotoUrls : { } , discardPhotoErrors : { } , discardPhotoBusy : false , discardPhotoReady : false , discardPalletCode : '' , discardLoading : false , discardBusy : false , selectedItem : null , selectedPosition : null , selectedScanCode : '' , scanCode : '' , loading : false , busy : false , busyAction : '' , error : null , successMessage : '' , bootstrapped : false } } ,
computed : {
displayItems ( ) {
const items = this . current ? . items || [ ]
@@ -88,8 +88,8 @@
return rows
} ,
hasReturnPallet ( ) { return this . current ? . outboundType === 'RETURN_OUTBOUND' && ( this . current . items || [ ] ) . some ( item => item . palletNo ) } ,
scanLabel ( ) { return this . discardCurrent ? '废弃订单托盘码' : this . hasReturnPallet ? '扫描托盘号(退货整托出库)' : '任务号、出库单号、排车单号、托盘号或箱码' } ,
scanPlaceholder ( ) { return this . discardCurrent ? '扫描废弃订单对应托盘码' : this . hasReturnPallet ? '扫描托盘号;散箱扫描箱唛' : '扫描任务号 / 出库单号 / 排车单号 / 托盘号 / 箱码' } ,
scanLabel ( ) { return this . discardCurrent ? ( this . discardTask ? . scanMode === 'CARTON' ? '废弃箱唛' : '废弃订单托盘码' ) : this . hasReturnPallet ? '扫描托盘号(退货整托出库)' : '任务号、出库单号、排车单号、托盘号或箱码' } ,
scanPlaceholder ( ) { return this . discardCurrent ? ( this . discardTask ? . scanMode === 'CARTON' ? '扫描本单所选箱唛' : '扫描废弃订单对应托盘码' ) : this . hasReturnPallet ? '扫描托盘号;散箱扫描箱唛' : '扫描任务号 / 出库单号 / 排车单号 / 托盘号 / 箱码' } ,
recentTaskNo ( ) { return fulfillment . outbound . currentTaskNo || '' } ,
packages ( ) { return fulfillment . outbound . packages } ,
plannedPackages ( ) { return ( this . current ? . items || [ ] ) . reduce ( ( total , item ) => total + item . plannedPackages , 0 ) } ,
@@ -99,9 +99,9 @@
taskOperable ( ) { return [ 'PENDING' , 'IN_PROGRESS' ] . includes ( this . current ? . status ) } ,
canPick ( ) { return this . taskOperable && this . selectedItem && this . selectedPosition && Number ( this . packages ) > 0 && Number ( this . packages ) <= this . selectedRemaining } ,
canComplete ( ) { return this . plannedPackages > 0 && this . remainingPackages === 0 && this . taskOperable } ,
discardOrders ( ) { const groups = new Map ( ) ; for ( const task of this . discardTasks ) { const current = groups . get ( task . discardNo ) || { discardNo : task . discardNo , palletCount : 0 , pendingPalletCount : 0 } ; current . palletCount += 1 ; if ( task . status !== 'COMPLETED' ) current . pendingPalletCount += 1 ; groups . set ( task . discardNo , current ) } return [ ... groups . values ( ) ] } ,
discardOrders ( ) { const groups = new Map ( ) ; for ( const task of this . discardTasks ) { const current = groups . get ( task . discardNo ) || { discardNo : task . discardNo , outboundNo : task . outboundNo , palletCount : 0 , cartonCount : 0 , pendingPalletCount : 0 } ; if ( task . scanMode === 'CARTON' ) current . cartonCount += ( task . cartonMarks || [ ] ) . length ; else current . palletCount += 1 ; if ( task . status !== 'COMPLETED' ) current . pendingPalletCount += 1 ; groups . set ( task . discardNo , current ) } return [ ... groups . values ( ) ] } ,
discardOrderCount ( ) { return this . discardOrders . length } ,
canConfirmDiscard ( ) { return Boolean ( this . discardPhotoReady && this . discardPhotos . length > 0 && ! this . discardPhotoBusy && ! this . discardLoading && ! this . discardBusy && this . discardTask && this . discardTask . status !== 'COMPLETED' && this . discardTask . skus . length && this . discardTask . skus . every ( ( sku ) => Number . isInteger ( Number ( this . discardActuals [ sku . itemId ] ) ) && Number ( this . discardActuals [ sku . itemId ] ) >= 0 && Number ( this . discardActuals [ sku . itemId ] ) <= sku . plannedPackages ) ) }
canConfirmDiscard ( ) { const task = this . discardTask ; return Boolean ( this . discardPhotoReady && this . discardPhotos . length > 0 && ! this . discardPhotoBusy && ! this . discardLoading && ! this . discardBusy && task && task . status !== 'COMPLETED' && task . skus . length && task . skus . every ( sku => Number ( this . discardActuals [ sku . itemId ] ) === sku . plannedPackages ) && ( task . scanMode !== 'CARTON' || ( task . cartonMarks ? . length && ( this . discardAllCartons || task . cartonMarks . every ( mark => this . discardScannedMarks . includes ( mark ) ) ) ) ) ) }
} ,
onShow ( ) { if ( ! requireSession ( ) ) return ; this . user = session . currentUser ; restoreFulfillmentDraft ( ` ${ this . user ? . id || '' } : ${ this . user ? . warehouseId || '' } ` ) ; this . startScanner ( ) ; if ( this . discardPhotoBusy || this . discardBusy ) return ; if ( this . discardCurrent ) { if ( this . discardTask ) this . restoreDiscardPhotos ( ) ; return } if ( ! this . bootstrapped ) { this . bootstrapped = true ; this . scanCode = '' ; this . loadTasks ( ) ; return } if ( this . current ? . taskNo ) this . openTask ( this . current . taskNo ) ; else this . loadTasks ( ) } ,
onHide ( ) { this . stopScanner ( ) } ,
@@ -129,19 +129,22 @@
} , true )
} ,
closeTask ( ) { this . current = null ; this . selectedItem = null ; this . selectedPosition = null ; this . error = null ; this . successMessage = '' ; updateFulfillmentDraft ( 'outbound' , { currentTaskNo : '' , scanCode : '' , packages : 1 } ) ; this . loadTasks ( ) } ,
openDiscardOrder ( discardNo ) { if ( this . discardPhotoBusy ) return ; this . resetDiscardPhotos ( ) ; const code = String ( discardNo || '' ) . trim ( ) ; if ( ! code || this . discardBusy || this . busy || this . loading ) return ; this . current = null ; this . discardLoading = false ; this . discardCurrent = { discardNo : code } ; this . discardTask = null ; this . discardPalletCode = '' ; this . discardActuals = { } ; this . error = null } ,
openDiscardOrder ( discardNo ) { if ( this . discardPhotoBusy ) return ; this . resetDiscardPhotos ( ) ; const code = String ( discardNo || '' ) . trim ( ) ; if ( ! code || this . discardBusy || this . busy || this . loading ) return ; this . current = null ; this . discardLoading = false ; this . discardCurrent = { discardNo : code , outboundNo : this . discardOrders . find ( order => order . discardNo === code ) ? . outboundNo || '' } ; this . discardTask = null ; this . discardPalletCode = '' ; this . discardActuals = { } ; this . discardScannedMarks = [ ] ; this . discardAllCartons = false ; this . error = null ; const loose = this . discardTasks . find ( task => task . discardNo === code && task . scanMode === 'CARTON' && task . status !== 'COMPLETED' ) ; if ( loose ) { this . discardTask = normalizeCargoDiscardTask ( loose ) ; this . discardActuals = Object . fromEntries ( this . discardTask . skus . map ( sku => [ sku . itemId , sku . plannedPackages ] ) ) ; this . restoreDiscardPhotos ( ) } } ,
closeDiscard ( ) { if ( this . discardBusy || this . discardPhotoBusy ) return ; this . resetDiscardPhotos ( ) ; this . discardLoading = false ; this . discardCurrent = null ; this . discardTask = null ; this . discardPalletCode = '' ; this . discardActuals = { } ; this . loadTasks ( ) } ,
updateDiscardPalletCode ( value ) { this . discardPalletCode = value } ,
async resolveDiscardPallet ( raw ) {
const code = String ( raw ? . detail ? . value ? ? raw ? ? this . discardPalletCode ) . trim ( )
if ( ! code || ! this . discardCurrent || this . discardBusy || this . discardLoading || this . discardPhotoBusy ) return
if ( this . discardTask ? . scanMode === 'CARTON' && this . discardTask . cartonMarks . includes ( code ) ) { if ( ! this . discardScannedMarks . includes ( code ) ) this . discardScannedMarks = [ ... this . discardScannedMarks , code ] ; this . error = null ; playSuccessSound ( ) ; return }
if ( this . discardTask ? . scanMode === 'CARTON' && ! this . discardTasks . some ( task => task . discardNo === this . discardCurrent . discardNo && task . scanMode !== 'CARTON' && task . palletNo === code ) ) { this . setError ( new Error ( '箱唛不属于当前废弃作业' ) , '箱唛核对失败' ) ; return }
const order = this . discardCurrent
this . resetDiscardPhotos ( ) ; this . discardPalletCode = code ; this . discardLoading = true ; this . discardTask = null ; this . discardActuals = { } ; this . error = null
this . resetDiscardPhotos ( ) ; this . discardScannedMarks = [ ] ; this . discardAllCartons = false ; this . discardPalletCode = code ; this . discardLoading = true ; this . discardTask = null ; this . discardActuals = { } ; this . error = null
try {
const task = await resolveCargoDiscardPallet ( code )
const task = await resolveCargoDiscardPallet ( code , order . discardNo )
if ( this . discardCurrent !== order ) return
if ( task . discardNo !== order . discardNo ) throw new Error ( '扫描的托盘不属于当前废弃订单' )
this . discardTask = normalizeCargoDiscardTask ( task )
if ( this . discardTask . scanMode === 'CARTON' && this . discardTask . cartonMarks . includes ( code ) ) this . discardScannedMarks = [ code ]
this . discardActuals = Object . fromEntries ( this . discardTask . skus . map ( ( sku ) => [ sku . itemId , sku . actualPackages == null ? sku . plannedPackages : sku . actualPackages ] ) ) ; await this . restoreDiscardPhotos ( )
} catch ( error ) { if ( this . discardCurrent === order ) this . setError ( error , '废弃托盘读取失败' ) }
finally { if ( this . discardCurrent === order ) this . discardLoading = false }
@@ -181,11 +184,13 @@
} , fail : ( ) => { this . discardPhotoBusy = false } } )
} ,
updateDiscardActual ( itemId , event ) { const value = Math . max ( 0 , Math . trunc ( Number ( event . detail . value || 0 ) ) ) ; this . discardActuals = { ... this . discardActuals , [ itemId ] : value } } ,
async confirmDiscard ( ) { if ( this . discardBusy || this . discardLoading || ! this . canConfirmDiscard || ! this . discardTask || ! this . discardCurrent ) return ; this . discardBusy = true ; try { const lines = this . discardTask . skus . map ( ( sku ) => ( { itemId : sku . itemId , actualPackages : Number ( this . discardActuals [ sku . itemId ] ) } ) ) ; await confirmCargoDiscard ( this . discardCurrent . discardNo , this . discardTask . palletNo , lines , this . discardPhotos . map ( photo => String ( photo . fileId ) ) ) ; this . successMessage = '废弃出库作业及照片已提交,等待仓库确认 ' ; this . resetDiscardPhotos ( ) ; this . discardPalletCode = '' ; this . discardTask = null ; this . discardTasks = await listCargoDiscardTasks ( ) ; playSuccessSound ( ) } catch ( error ) { this . setError ( error , '废弃出库失败' ) } finally { this . discardBusy = false } } ,
async confirmDiscard ( ) { if ( this . discardBusy || this . discardLoading || ! this . canConfirmDiscard || ! this . discardTask || ! this . discardCurrent ) return ; this . discardBusy = true ; try { const lines = this . discardTask . skus . map ( ( sku ) => ( { itemId : sku . itemId , actualPackages : sku . plannedPackages } ) ) ; await confirmCargoDiscard ( this . discardCurrent . discardNo , this . discardTask . palletNo , lines , this . discardPhotos . map ( photo => String ( photo . fileId ) ) , this . discardScannedMarks , this . discardAllCartons ) ; this . successMessage = '废弃出库作业及照片已提交,已完成 ' ; this . resetDiscardPhotos ( ) ; this . discardPalletCode = '' ; this . discardTask = null ; this . discardTasks = await listCargoDiscardTasks ( ) ; playSuccessSound ( ) } catch ( error ) { this . setError ( error , '废弃出库失败' ) } finally { this . discardBusy = false } } ,
handleScan ( raw ) {
const code = String ( raw ? . detail ? . value ? ? raw ? ? this . scanCode ) . trim ( ) ; if ( ! code || this . busy || this . loading || this . discardBusy || this . discardLoading ) return
console . info ( '[Overseas PDA outbound] scan' , { code , task : this . current ? . taskNo || '' , discard : this . discardCurrent ? . discardNo || '' } ) ; this . scanCode = code ; updateFulfillmentDraft ( 'outbound' , { scanCode : code } )
if ( this . discardCurrent ) return this . resolveDiscardPallet ( code )
const discardOrder = ! this . current && this . discardOrders . find ( order => order . discardNo === code || order . outboundNo === code )
if ( discardOrder ) return this . openDiscardOrder ( discardOrder . discardNo )
if ( ! this . current ) return this . openScannedTask ( code )
if ( code === this . current . taskNo || code === this . current . outboundNo ) return this . openTask ( this . current . taskNo )
if ( ! this . taskOperable ) return