From 7a3ffd8ba5a766815becc3b133f43f488cfa5871 Mon Sep 17 00:00:00 2001 From: yueli Date: Mon, 31 Aug 2026 15:13:52 +0800 Subject: [PATCH] =?UTF-8?q?feat(stocktake):=20=E9=87=8D=E5=A4=8D=E6=89=AB?= =?UTF-8?q?=E7=A0=81=E6=8F=90=E7=A4=BA=E5=B9=B6=E7=A1=AE=E8=AE=A4=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题: 同一个码扫两遍输入两个数,后端 draft/add 直接覆盖,无任何提示 可能误改已盘数量 改进: - 后端 draft/list 支持 uuid 过滤,可精确查某物料是否已盘 - 扫码弹输入框前,先精确查询该物料是否已盘 - 已盘过 → 弹窗提示『当前实盘为 X,是否修改?』 确认后预填旧值供修改,取消则不改变 --- inventory-backend/app/api/v1/inbound/stock.py | 5 ++ .../src/views/stock/stocktake/index.vue | 59 ++++++++++++++++--- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/inventory-backend/app/api/v1/inbound/stock.py b/inventory-backend/app/api/v1/inbound/stock.py index 71d8b93..5b683ec 100644 --- a/inventory-backend/app/api/v1/inbound/stock.py +++ b/inventory-backend/app/api/v1/inbound/stock.py @@ -477,12 +477,17 @@ def get_drafts(): limit = request.args.get('limit', 20, type=int) keyword = request.args.get('keyword', '', type=str) session_id = request.args.get('session_id') + uuid = request.args.get('uuid', '', type=str) query = StocktakeDraft.query if session_id: query = query.filter_by(session_id=session_id) + # ★ 按 uuid 精确过滤(扫码时检测该物料是否已盘) + if uuid: + query = query.filter_by(uuid=uuid) + # 先执行查询获取所有记录 drafts = query.all() diff --git a/inventory-web/src/views/stock/stocktake/index.vue b/inventory-web/src/views/stock/stocktake/index.vue index 2b5c3ba..464077e 100644 --- a/inventory-web/src/views/stock/stocktake/index.vue +++ b/inventory-web/src/views/stock/stocktake/index.vue @@ -861,15 +861,58 @@ const handleManualInput = async () => { } } -const openQtyDialog = (item: StockItem) => { - currentItem.value = item - inputQty.value = item.scanned ? item.qty_actual : 1 - showQtyDialog.value = true +const openQtyDialog = async (item: StockItem) => { + // ★ 重复扫码检测:精确查该物料是否已在本 session 盘过 + let existingQty: number | null = null + try { + const uuidForQuery = item.uuid || item.sku || '' + const dupRes: any = await request({ + url: '/v1/inbound/stock/draft/list', + method: 'get', + params: { session_id: currentSessionId.value, uuid: uuidForQuery, limit: 1 } + }) + const dupItems = dupRes?.items || dupRes?.data?.items || [] + if (dupItems.length > 0 && dupItems[0].quantity !== undefined) { + existingQty = Number(dupItems[0].quantity) + } + } catch (e) { + // 查询失败不阻断,视为未盘过 + } - nextTick(() => { - const inputEl = document.querySelector('.qty-dialog input') as HTMLInputElement - if(inputEl) inputEl.focus() - }) + if (existingQty !== null) { + // 已盘过 → 提示当前值,询问是否修改 + try { + await ElMessageBox.confirm( + `⚠️ 【${item.name} × ${item.standard}】已盘过,当前实盘为 ${existingQty}。\n\n是否修改本次盘点的数量?`, + '重复扫码提示', + { + confirmButtonText: '修改数量', + cancelButtonText: '取消', + type: 'warning' + } + ) + // 用户确认修改 → 预填当前值,弹输入框 + currentItem.value = item + inputQty.value = existingQty || 1 + showQtyDialog.value = true + nextTick(() => { + const inputEl = document.querySelector('.qty-dialog input') as HTMLInputElement + if(inputEl) inputEl.focus() + }) + } catch (e) { + // 用户取消,不修改 + return + } + } else { + // 未盘过 → 正常弹输入框 + currentItem.value = item + inputQty.value = item.scanned ? item.qty_actual : 1 + showQtyDialog.value = true + nextTick(() => { + const inputEl = document.querySelector('.qty-dialog input') as HTMLInputElement + if(inputEl) inputEl.focus() + }) + } } const handleManualConfirm = () => {