From a4a9afb6db7b059fc88c47e52672ae6f2fa684cb Mon Sep 17 00:00:00 2001 From: yueli Date: Thu, 10 Sep 2026 17:21:24 +0800 Subject: [PATCH] =?UTF-8?q?feat(scan):=20=E5=87=BA=E5=BA=93/=E5=80=9F?= =?UTF-8?q?=E5=BA=93=E6=89=AB=E7=A0=81=E9=A1=B5=E6=8E=A5=E5=85=A5=E8=8D=89?= =?UTF-8?q?=E7=A8=BF=EF=BC=8C=E5=88=87=E6=8D=A2=E5=8D=95=E6=8D=AE=E4=B8=8D?= =?UTF-8?q?=E6=B8=85=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 交互 ---- 无需「暂停」按钮 —— 在下拉框切换单据这个动作本身就是暂停: 切走 → 自动存当前单据的进度 切回 → 自动恢复,并提示「已恢复上次的扫码进度(N 项)」 下拉框对扫到一半的单据显示橙色「已扫 N」徽标,不必逐个点开试。 提交成功后自动清除该单据的草稿。 修复的三个 bug -------------- 1) 切换时把 A 的内容存到了 B 名下 v-model="selectedRequestId" 的 computed setter 会**先于** @change 把 selectedRequest 改成新单,故 handleRequestChange 里读到的是新单。 新增 activeRequestId ref 记录「界面上真正显示的是哪张单」, 保存时显式传入离开的那张单的 ID。 2) 切回时把目标单的旧草稿删了 原先写了「购物车为空则清除草稿」,但切换瞬间购物车必然为空, 于是切回 A 时触发了清除。现改为空清单只跳过保存、不清除; 清理由「提交成功」或「用户点清空列表」显式触发。 3) 恢复后名称/规格为空、出库数显示 NaN draftPayload 只存了 4 个字段(stock_id/source_table/sku/quantity), 而购物车表格绑定的是 name/spec_model/available_quantity/out_quantity —— 全都没存。现保存完整快照,并在恢复时归一化 (out_quantity ?? quantity)以兼容已存在的旧草稿。 补充:恢复后刷新实时库存 ------------------------ 草稿里的 available_quantity 是扫描那一刻的快照,跨时间恢复可能已过期 (期间别人出库/借出会消耗可用量)。恢复后复用 /alternatives 端点拉一次 实时可用量:数量超了会明确提示「N 项物料的实际库存已少于你扫的数量」, 避免工人扫满后到提交时才被后端拒绝。失败不阻断,沿用草稿快照。 另:离开页面(路由跳转)时存草稿并弹确认;beforeunload 用 sendBeacon 尽力保存(该路径无法带 Authorization 头,可能失败,但防抖保存已覆盖 绝大部分内容)。 --- inventory-web/src/api/outbound.ts | 52 ++++ inventory-web/src/views/outbound/create.vue | 262 +++++++++++++++++- .../src/views/transaction/borrow.vue | 192 ++++++++++++- 3 files changed, 501 insertions(+), 5 deletions(-) diff --git a/inventory-web/src/api/outbound.ts b/inventory-web/src/api/outbound.ts index c20c83b..1ab1546 100644 --- a/inventory-web/src/api/outbound.ts +++ b/inventory-web/src/api/outbound.ts @@ -239,3 +239,55 @@ export function getMyRequests(params: { params }) } + +// ========================================== +// 扫码草稿(出库/借库作业中途暂停用) +// ========================================== + +export interface ScanDraftItem { + stock_id: number + source_table: string + sku?: string + quantity: number +} + +/** 读取草稿:返回该用户在这张单上已扫的内容 */ +export function getScanDraft(bizType: 'outbound' | 'borrow', requestId: number) { + return request({ + url: '/v1/scan-draft', + method: 'get', + params: { biz_type: bizType, request_id: requestId } + }) +} + +/** 保存草稿:全量覆盖(提交的 items 即当前完整清单) */ +export function saveScanDraft( + bizType: 'outbound' | 'borrow', + requestId: number, + items: ScanDraftItem[], + requestNo?: string +) { + return request({ + url: '/v1/scan-draft', + method: 'post', + data: { biz_type: bizType, request_id: requestId, request_no: requestNo || '', items } + }) +} + +/** 清除草稿:提交成功后调用 */ +export function clearScanDraft(bizType: 'outbound' | 'borrow', requestId: number) { + return request({ + url: '/v1/scan-draft', + method: 'delete', + params: { biz_type: bizType, request_id: requestId } + }) +} + +/** 草稿概览:供单据下拉显示「已扫 N 项」进度徽标 */ +export function getScanDraftOverview(bizType: 'outbound' | 'borrow') { + return request({ + url: '/v1/scan-draft/overview', + method: 'get', + params: { biz_type: bizType } + }) +} diff --git a/inventory-web/src/views/outbound/create.vue b/inventory-web/src/views/outbound/create.vue index 1509ccc..b690bdf 100644 --- a/inventory-web/src/views/outbound/create.vue +++ b/inventory-web/src/views/outbound/create.vue @@ -39,6 +39,10 @@ :label="req.request_no" > {{ req.request_no }} + + + 已扫 {{ draftProgress[req.id] }} + {{ req.applicant_name || '未知申请人' }} @@ -372,10 +376,14 @@