丢弃过期托盘校验响应并防止错误实收
This commit is contained in:
@@ -181,7 +181,23 @@
|
||||
drainScanQueue() { if (!this._pageActive || this.loading || this.busy || this.activeTarget === 'quantity' || !this.scanQueue.length || this.phase !== 'receive') return; const next = this.scanQueue.shift(); this.dispatchHardwareScan(next) },
|
||||
suspendReceiving() { this._pageActive = false; this._scanEpoch = (this._scanEpoch || 0) + 1; this._resumeReceiving = true; clearTimeout(this._drainTimer); clearTimeout(this._toastTimer); this.scanQueue = []; this.stopScanner() },
|
||||
scheduleScanDrain() { clearTimeout(this._drainTimer); if (!this._pageActive) return; const epoch = this._scanEpoch || 0; this._drainTimer = setTimeout(() => { if (this._pageActive && epoch === (this._scanEpoch || 0)) this.drainScanQueue() }, 0) },
|
||||
async run(action, work) { if (this.busy || !this._pageActive) throw new Error('当前页面未就绪,请返回作业页重试'); this.busy = true; this.error = null; try { const result = await work(); this.showToast(`${action}成功`, 'success'); return result } catch (error) { const mappedError = toReceivingError(error, `${action}失败`); this.error = mappedError; playErrorSound(); this.showToast(mappedError.message, 'error'); throw mappedError } finally { this.busy = false; if (this._pageActive && this._resumeReceiving) { this._resumeReceiving = false; this.bootstrap() } else this.scheduleScanDrain() } },
|
||||
async run(action, work, isCurrent = () => true) {
|
||||
if (this.busy || !this._pageActive) throw new Error('当前页面未就绪,请返回作业页重试')
|
||||
this.busy = true; this.error = null
|
||||
try {
|
||||
const result = await work()
|
||||
// 只读校验失效后不再回写结果,也不提示旧请求成功或失败。
|
||||
if (!isCurrent()) return null
|
||||
this.showToast(`${action}成功`, 'success'); return result
|
||||
} catch (error) {
|
||||
if (!isCurrent()) return null
|
||||
const mappedError = toReceivingError(error, `${action}失败`)
|
||||
this.error = mappedError; playErrorSound(); this.showToast(mappedError.message, 'error'); throw mappedError
|
||||
} finally {
|
||||
this.busy = false
|
||||
if (this._pageActive && this._resumeReceiving) { this._resumeReceiving = false; this.bootstrap() } else this.scheduleScanDrain()
|
||||
}
|
||||
},
|
||||
setScanTargetForCurrent(value) { receiving.activeScanTarget = value?.status === 'WAIT_SIGN' ? 'container' : 'carton' },
|
||||
async restorePhotoPreviews() { await Promise.all(receiving.photoSlots.filter((photo) => photo?.downloadPath && !photo.localPath).map(async (photo) => { try { await restoreReceivingPhoto(photo, downloadCurrentUnloadPhoto) } catch (error) { this.error = error } })) },
|
||||
async restoreDomesticPhotoPreviews() { if (this.phase !== 'sign' && !this.domesticPhotosExpanded) return; await Promise.all(this.domesticLoadingPhotos.filter((photo) => photo.downloadPath && !photo.localPath).map((photo) => this.loadDomesticPhoto(photo))) },
|
||||
@@ -205,13 +221,21 @@
|
||||
async resolvePallet(raw) {
|
||||
const palletCode = String(raw?.detail?.value ?? raw ?? this.palletInput).trim()
|
||||
if (!palletCode || !this.activeInbound || this.busy) return
|
||||
const inbound = this.activeInbound, current = this.current, inboundCode = inbound.inboundCode
|
||||
const scanEpoch = this._scanEpoch || 0, operatorId = session.currentUser?.id, warehouseId = session.currentUser?.warehouseId, tenantId = session.tenantId
|
||||
// 响应只属于发起时的输入、入仓单、柜会话和作业身份;离开再返回也必须重验。
|
||||
const isCurrent = () => this._pageActive && scanEpoch === (this._scanEpoch || 0)
|
||||
&& this.current === current && this.activeInbound === inbound && this.activeInbound.inboundCode === inboundCode
|
||||
&& session.currentUser?.id === operatorId && session.currentUser?.warehouseId === warehouseId && session.tenantId === tenantId
|
||||
&& this.palletInput.trim() === palletCode
|
||||
receiving.resolvedPallet = null; this.palletInput = palletCode; this.packageCount = ''; receiving.activeScanTarget = 'pallet'
|
||||
try {
|
||||
const value = await this.run('校验托盘', async () => {
|
||||
const result = await resolveCurrentPallet(palletCode, this.activeInbound.inboundCode)
|
||||
const result = await resolveCurrentPallet(palletCode, inboundCode)
|
||||
if (!result.compatible) throw Object.assign(new Error('托盘不匹配,请重扫'), { code: 'PALLET_INCOMPATIBLE' })
|
||||
return result
|
||||
})
|
||||
}, isCurrent)
|
||||
if (!value || !isCurrent()) return
|
||||
receiving.resolvedPallet = value; this.palletInput = value.palletCode; this.packageCount = Number(value.currentReceivedPackages || 0) || ''
|
||||
receiving.activeScanTarget = this.activeInbound.destinationType === 'FBA' ? 'quantity' : 'carton'; playSuccessSound()
|
||||
} catch (error) { if (!this.error) this.error = error }
|
||||
|
||||
Reference in New Issue
Block a user