仓储团队买手持机,理由很朴素:库存所在的地方没有网络。货架挡住 Wi-Fi,冷库把信号杀掉,货场根本没有覆盖。于是设备离线采集、之后再同步——而库存准确率的胜负,恰恰就在这里。
设备不是难点,导入才是。
批量采集是设计决定,不是缺陷
批量采集是一种有意的取舍,把它讲清楚,设计才不会走偏。
- 离线采集保证了盘点能做完,代价是数据来晚。
- 数据来晚意味着 ERP 已经往前走了:盘点与上传之间发生了收货、销售与调拨。
- 一批数据不是「此刻的快照」,而是几小时甚至几天里取得的一组观测。
- 所以导入必须携带时间,并且必须声明意图:设定、增加、减少,还是确认。
- 忽略这一点的系统,会造出货道里正确、总账里错误的盘点。
三种载荷形态,三种行为
大部分导入缺陷,都来自把这三者混进一个文件,然后指望导入器自己猜。
- 盘点是一个绝对陈述:这个库位在这个时刻存有该物料的这个数量。
- 事件是一次移动:一件从 A 移到 B,或被消耗,或被收货。
- 增量是一次调整:加上或减去这个数量,因为之前的记录是错的。
- 盘点与增量不能共用一条冲突规则,因为一个替换事实,另一个主张变化。
- 按流程选型:循环盘点适合盘点,拣货确认适合事件,纠错适合增量。
先全部落到暂存表
暂存表是整条流水线里最有价值的部件,也最常被跳过。
- 把每条收到的记录原样写入暂存表,附带原始载荷、设备号、操作员与设备时间。
- 在暂存表里做校验,而不是在入口处:被拒绝的记录也必须可见,才能诊断。
- 绝不要让导入器直接从用户选的文件写库存;文件是输入,不是权威。
- 处理之后保留暂存行与状态,这样争议可以追溯回原始扫描。
- 把暂存表当收件箱:未处理、已处理、已拒绝、人工解决,是四个不同状态。
幂等是唯一能挡住重放的防线
手持机同步失败后重试,会把同一批数据发两次,这属于正常现象。
- 给每批数据一个确定性标识,由设备、操作员与时间窗构成。
- 给每条记录一个重发时不变的记录键;每次尝试都生成随机 UUID 会直接破坏幂等。
- 把已应用的键存进数据库,遇到重复就以明确状态拒绝,而不是抛错。
- 有意识地测试重试路径:中途掐断同步、重发、验证库存没有变化。
- 如果流水线做不到幂等,就把导入改成人工复核步骤,而不是自动写入。
说得清的冲突规则
当观测之后 ERP 发生了变化,冲突就存在,每条规则都必须明示。
- 用设备时间与该物料、该库位的最近一次库存移动做比较。
- 如果 ERP 的变化早于观测,接受盘点值,因为它是更晚测到的。
- 如果 ERP 的变化晚于观测,就要标记;这个盘点值可能已经过时几小时。
- 绝不悄悄取较大值或较小值;「保守者胜」的规则会掩盖真实损失。
- 把每个被标记的冲突送进一个短队列,附上两个值与造成差异的移动单据。
时间是所有人都忘掉的字段
设备时钟会漂移,时区会不同,而没有时间戳的盘点无法对账。
- 存两个时间:设备观测到该标签的时间,以及服务器收到它的时间。
- 每次会话开始强制设备对时,并拒绝时间戳明显不合理的记录。
- 设备时钟统一用 UTC,只在显示时转换;本地时间会带来每年两次的 bug。
- 冲突逻辑使用观测时间,接收时间只用于审计。
- 晚到一周的盘点仍然是数据,但它不该覆盖这一周的移动。
写之前先校验
最便宜的纠错,发生在库存移动被创建之前。
- 校验物料、库位与批次存在,遇到未知条码就拒绝,而不是顺手新建物料。
- 显式校验计量单位换算;箱与件的错配是悄无声息的百倍误差。
- 校验操作员是否有该库位权限,多公司环境下尤其重要。
- 用配置好的区间校验数量合理性,离群值送复核而不是直接阻断。
- 逐条记录校验结果,让操作员能看到拒绝原因。
告诉手持机发生了什么
只回一个总数的导入,现场团队很快就会不用它。
- 下次同步时按记录键把逐条状态回传给设备。
- 区分「已接受」「接受但有调整」「已拒绝」,并各给一行理由。
- 让操作员在设备上直接改被拒记录,而不是回办公室重打。
- 给主管一份不需要打开表格就能读的会话摘要。
- 盯住拒绝原因的分布;「库位未知」上升,通常意味着映射出了问题。
财务愿意接受的核对报告
盘点必须可解释,而不只是正确。
- 逐行报告「原数量、观测数量、产生的调整」。
- 把每笔调整归因到设备、操作员、会话与时间窗。
- 把「盘点错误造成的调整」与「未记录移动造成的调整」分开。
- 把调整金额与当期库存金额对比,让漂移可见。
- 报告要不可篡改地留存,因为审计会在几个月后来要它。
上线顺序与先测什么
把上线顺序排好,让失败发生在代价最低的地方。
- 先选一类库位、一种机型,用影子模式:只导入到暂存表做比对,不写库存。
- 再对一个低值、高周转的品类开启写入。
- 然后扩展到完整循环盘点,保留人工复盘作为仲裁。
- 尽早测试那些难看的场景:没信号、中途没电、重复同步、时区错误。
- 发布一页纸的操作规程,因为大多数「系统错误」其实是顺序错误。






