fix(stocktake): 未扫码的行不允许直接填实盘数
【问题】盘点明细抽屉列出全部在范围内的物料,其中尚未扫码的行也可以 直接在「实盘数」列填数字。填完前端发 POST /stocktake/update-quantity, 后端只会 UPDATE 已存在的草稿行、找不到就返回 404「未找到盘点记录」, 于是工人填的数字根本没保存,只弹一句「更新失败」。 【为什么不改成 UPSERT】那等于允许不扫码就填数 —— 任何人照账面抄一遍 就能"完成"盘点,扫码这道工序形同虚设,盘盈盘亏也无从查起。 所以这里保持"必须先有草稿行"的语义,改为在 UI 上把这条路堵住。 【改动】 - 前端:draft_id 为空的行不再渲染 el-input-number,改显示灰色「未扫」; 已扫行照常可改。失败时提示改为透传后端 msg,并 fetchInventoryList() 回滚本地被 v-model 改动的值。 - 后端:404 文案由「未找到盘点记录」改为 「该物料尚未扫码,请先扫描条码后再修改实盘数」,作为绕过前端时的兜底。 实测: draft_id 已扫行=11379 → 可编辑;未扫行=None → 不可编辑 绕过前端直接改未扫行 → 404 该物料尚未扫码,请先扫描条码后再修改实盘数
This commit is contained in:
@ -2390,7 +2390,14 @@ def update_stocktake_quantity():
|
|||||||
draft = query.first()
|
draft = query.first()
|
||||||
|
|
||||||
if not draft:
|
if not draft:
|
||||||
return jsonify({'code': 404, 'msg': '未找到盘点记录'}), 404
|
# 该物料在本会话尚未扫码 → 没有草稿行可改。
|
||||||
|
# 前端已把未扫行的实盘数置为不可编辑,这里是兜底(例如页面未刷新、
|
||||||
|
# 或有人直接调接口)。刻意**不**在此处补建草稿 —— 一旦允许不扫码
|
||||||
|
# 就能填数,扫码这道工序就形同虚设,盘盈盘亏也无从查起。
|
||||||
|
return jsonify({
|
||||||
|
'code': 404,
|
||||||
|
'msg': '该物料尚未扫码,请先扫描条码后再修改实盘数'
|
||||||
|
}), 404
|
||||||
|
|
||||||
# 更新数量
|
# 更新数量
|
||||||
draft.quantity = quantity
|
draft.quantity = quantity
|
||||||
|
|||||||
@ -454,9 +454,16 @@
|
|||||||
<span v-else>{{ row.stock_qty }}</span>
|
<span v-else>{{ row.stock_qty }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<!-- ★ 实盘数只允许修改**已扫过**的行(draft_id 非空)。
|
||||||
|
若放开未扫行直接填数,任何人都能照着账面抄一遍交差 ——
|
||||||
|
扫码这道工序就形同虚设,盘盈盘亏也查不出来。 -->
|
||||||
<el-table-column label="实盘数" width="100" align="center">
|
<el-table-column label="实盘数" width="100" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
|
<span v-if="!row.draft_id" class="not-scanned-hint" title="尚未扫码,请先扫描该物料条码">
|
||||||
|
未扫
|
||||||
|
</span>
|
||||||
<el-input-number
|
<el-input-number
|
||||||
|
v-else
|
||||||
v-model="row.quantity"
|
v-model="row.quantity"
|
||||||
:min="0"
|
:min="0"
|
||||||
:step="1"
|
:step="1"
|
||||||
@ -1647,10 +1654,10 @@ const handleQuantityChange = async (row: any, val: number) => {
|
|||||||
session_id: currentSessionId.value // ★ 传入会话ID,后端按会话隔离更新
|
session_id: currentSessionId.value // ★ 传入会话ID,后端按会话隔离更新
|
||||||
}, selectedCompany.value || undefined)
|
}, selectedCompany.value || undefined)
|
||||||
ElMessage.success('实盘数已更新')
|
ElMessage.success('实盘数已更新')
|
||||||
} catch (e) {
|
} catch (e: any) {
|
||||||
console.error('更新实盘数失败', e)
|
console.error('更新实盘数失败', e)
|
||||||
ElMessage.error('更新失败')
|
ElMessage.error(e?.response?.data?.msg || e?.msg || '实盘数更新失败,已还原为服务端数据')
|
||||||
// 重新获取列表数据
|
// 拉回服务端最新数据,覆盖掉本地已被 v-model 改动的值
|
||||||
fetchInventoryList()
|
fetchInventoryList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1841,6 +1848,13 @@ const goToVarianceReview = () => {
|
|||||||
/* 盲盘时后端不下发账面数/差异,用「—」表示未下发(区别于真实的 0) */
|
/* 盲盘时后端不下发账面数/差异,用「—」表示未下发(区别于真实的 0) */
|
||||||
.cell-blinded { color: #c0c4cc; }
|
.cell-blinded { color: #c0c4cc; }
|
||||||
|
|
||||||
|
/* 未扫过的行不给填数,只给一个提示 —— 引导工人去扫码而不是抄账面 */
|
||||||
|
.not-scanned-hint {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #c0c4cc;
|
||||||
|
cursor: help;
|
||||||
|
}
|
||||||
|
|
||||||
/* ★ 创建盘点任务表单(模式 / 范围) */
|
/* ★ 创建盘点任务表单(模式 / 范围) */
|
||||||
.task-form {
|
.task-form {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
Reference in New Issue
Block a user