perf: implement optimistic UI for scanner, disable auto-camera, and sort excel by SKU

This commit is contained in:
DXC
2026-03-23 09:51:59 +08:00
parent 13e910645d
commit 7c9331d78a
2 changed files with 42 additions and 15 deletions

View File

@ -869,32 +869,43 @@ const handleManualConfirm = () => {
if (!currentItem.value) return
const val = inputQty.value === undefined ? 0 : inputQty.value
updateAndSync(currentItem.value, val, inputRemark.value)
// ★★★ 乐观更新:立即本地更新 UI不等待后端响应 ★★★
currentItem.value.scanned = true
currentItem.value.qty_actual = val
scannedMap.value.set(currentItem.value.uuid, val)
// 保存备注用于异步提交
const remark = inputRemark.value
showQtyDialog.value = false
// 重置备注
inputRemark.value = ''
ElMessage.success(`已记录实盘: ${val}`)
// ★★★ 核心修改:确认数量后自动重新打开全屏扫码,实现无缝闭环
nextTick(() => {
if (hasPermission) {
showCamera.value = true
}
})
// ★★★ 取消自动弹摄像头,把开启摄像头的控制权完全交还给用户
// 用户需主动点击才能开启摄像头
// ★★★ 异步保存到后端,不阻塞 UIfire-and-forget★★★
syncToBackend(currentItem.value.uuid, val, remark)
}
// ★★★ 乐观更新:异步保存到后端,不阻塞 UI ★★★
const syncToBackend = (uuid: string, quantity: number, remark: string) => {
syncStatus.value = 'syncing'
api.addDraft({ uuid, quantity, remark })
.then(() => {
syncStatus.value = 'success'
})
.catch(() => {
syncStatus.value = 'failed'
})
}
const updateAndSync = async (item: StockItem, quantity: number, remark: string = '') => {
// ★★★ 保留原有逻辑用于兼容性,但不再使用 ★★★
item.scanned = true
item.qty_actual = quantity
scannedMap.value.set(item.uuid, quantity)
syncStatus.value = 'syncing'
try {
await api.addDraft({ uuid: item.uuid, quantity: quantity, remark: remark })
syncStatus.value = 'success'
} catch (e) {
syncStatus.value = 'failed'
}
}
const closeOverlays = () => {