SMT 产线上,贴片机、回流焊、AOI/SPI 等工序的扫码枪把"工单号+托盘号+过站动作"推给 MES 后端。手持终端弱网重扫、设备端心跳补传、异常回退重过站,都会让同一个业务事件多次到达服务端。过站扫码接口如果只按"收到就写",WIP 台账必然出现重复行、在制品数量虚增、工序进度前后颠倒。幂等与台账更新的配合,是接口设计的第一道门槛。 一、结论先行 - 过站扫码接口的幂等,必须落在业务唯一键(工单+托盘+过站工序+结果)上,仅靠消息 ID 或请求时间戳扛不住设备重扫与多枪并行。 - WIP 台账不要用"append-only 再汇总"的裸做法:同一工序重复扫描要原地覆盖状态与时间,数量变更用"delta+旧值回滚"避免并发写丢失。 - 接口返回结构区分"本次幂等命中/本次实际过站";命中幂等时,返回该笔过站记录的当前状态,现场才知道这条托盘到底到哪一站。 二、过站事件的业务唯一键 SMT 过站一次完整业务事件包含:哪条工单、哪个托盘(或 SN)、经过哪道工序、结果合格还是拒收、谁/哪把枪报的。接口幂等的核心是把这组要素合成唯一键,落在入参校验与持久化两个层面。 入参建议的最小集合(用"字段 xx:说明"列出,不用表格): - 字段 work_order_no:工单号,MES 工单主键关联。 - 字段 tray_code:托盘码,同一托盘多板时可对应多个 SN;托盘级过站用此字段。 - 字段 serial_no:单板序列号,可选。当过站到单板粒度(如 AOI 单板判异)时必填,与 tray_code 二选一或并存。 - 字段 station_code:工序/站点编码,对应工艺路线上的节点,如 REFLOW_OVEN、AOI_POST_REFLOW。 - 字段 pass_result:过站结果,枚举 PASS / FAIL / HOLD,决定 WIP 状态走向。 - 字段 operator:报工操作员编号。 - 字段 scanner_id:扫码枪/终端编号,用于问题定位与排重审计,不参与业务唯一键。 - 字段 event_time:事件发生时间,ISO8601,时区带偏移;用于乱序校验与台账 time_in 更新。 - 字段 idempotency_key:客户端幂等键,建议由 scanner_id + event_time 毫秒 + 随机后缀拼接,服务端用它做前置排重,但不作为业务唯一依据。 业务唯一键建议定义为:work_order_no + tray_code(或 serial_no)+ station_code + pass_result + event_time 所在的最小时间窗(如 30 秒去重窗)。event_time 带窗口的原因是:同一托盘在 30 秒内被同一枪多次扫入同一站,属于重扫;超过窗口则视为可能的二次过站或返工重过,需要走返工分支而不是静默去重。 三、接口契约与幂等落盘 1)请求与路由 - 方法建议 POST,路径 /api/smt/pass-station。 - 不依赖 HTTP 缓存语义(GET/PUT 缓存不可靠),幂等由业务键保障。 - 对弱网终端做超时重传时,要求终端携带相同 idempotency_key 与 event_time,不要递增时间戳。 2)服务端排重流程 到达请求后,按顺序执行: - 校验入参完整性(work_order_no / tray_code 或 serial_no / station_code / pass_result / event_time 非空)。 - 校验工单与托盘绑定关系:同一托盘的 tray_code 必须在当前工单的已发放托盘集合中,且工单状态允许过站(如 RELEASING / RUNNING,关闭/报废工单拒绝)。 - 按业务唯一键查询过站记录表 smt_pass_record:若存在同键且 event_time 落在去重窗内,判定为幂等命中。 - 幂等命中时,返回 HTTP 200 + 标志 idempotent=true,并附带该笔过站记录的 station_code、pass_result、processed_at;不修改 WIP 台账。 - 非命中时,写入 smt_pass_record 新行,并触发 WIP 台账更新(见下一节)。 smt_pass_record 表的关键字段: - 字段 id:主键,自增或雪花。 - 字段 work_order_no:工单号。 - 字段 tray_code:托盘码。 - 字段 serial_no:序列号,可选。 - 字段 station_code:过站工序。 - 字段 pass_result:PASS / FAIL / HOLD。 - 字段 event_time:事件时间。 - 字段 processed_at:服务端处理时间。 - 字段 scanner_id:扫码终端编号。 - 字段 operator:操作员。 - 字段 unique_key:业务唯一键哈希或拼接串,建唯一索引用于幂等排重。 - 字段 version:乐观锁版本号,防止并发更新。 3)错误与重试语义 - 工单/托盘不存在、工单已关闭、station_code 不在该工单工艺路线上,返回 4xx,客户端不应重试(业务不成立)。 - 5xx 时客户端按指数退避重试,且重试请求必须携带相同 idempotency_key 和 event_time;服务端保证最终写入一条过站记录和一次 WIP 更新。 四、WIP 台账的更新设计 WIP 台账是"在制品到了哪、数量多少、停留多久"的实时视图。过站接口的幂等只解决"同一事件不重录",台账更新要解决三件事:数量正确、位置正确、时间正确。 1)台账表结构建议 - 字段 work_order_no:工单号。 - 字段 station_code:当前所在工序。 - 字段 qty_on_station:该工序在制品数量。 - 字段 qty_started:已开工数量(本工序及后续工序累计)。 - 字段 qty_completed:本工序已完成数量(PASS)。 - 字段 qty_hold:本工序待判/隔离数量(HOLD)。 - 字段 qty_failed:本工序不合格数量(FAIL)。 - 字段 latest_pass_at:最近一次有效过站时间。 - 字段 latest_tray_list:最近过站托盘号列表(JSON 数组,用于现场核对,非计数依据)。 - 字段 version:乐观锁版本号。 2)从"过站记录"到"台账 delta" 过站记录写入后,由同事务或紧随的轻量流程计算 delta,再应用至台账。核心规则: - 同一托盘在同一个 station_code 上,第二次以 PASS 过站属于"状态刷新",不增加 qty_on_station,只更新 latest_pass_at 与该托盘的位置(若前一次是 HOLD,则 qty_hold -1、qty_completed +1)。 - 跨工序过站(例如从 REFLOW 到 AOI):前工序 qty_on_station -1、qty_completed 按 pass_result 分流;后工序 qty_on_station +1。 - FAIL/HOLD 不过站到下一工序,只在本站改变状态与计数。 - 并发保护:更新台账用 UPDATE ... SET version = version + 1 WHERE work_order_no = ? AND station_code = ? AND version = ?,失败则重试读最新行重算 delta,避免"数量先减到负数再被另一条加回来"的瞬态异常。 3)去重窗与返工回流 去重窗内命中幂等,不碰台账。超过窗口再次到达同一 station_code: - 若工艺路线允许返工重过(如 AOI 复检),则视为新过站:写入新 pass_record 行,台账按"本站状态刷新"处理。 - 若不允许返工重过同一站(路线节点有向且不可逆),则拒绝并报业务异常,不写记录、不碰台账,让现场人工确认。 - 现场经常遇到的"漏扫补扫":漏扫不是重复事件,而是"中间工序从未发生过"。补扫接口应走单独的补录接口 /api/smt/backfill-pass,携带 backfill=true,由工单+工艺路线校验合法插入位置,不进入过站幂等去重窗,但同样落 pass_record 与台账 delta。 五、现场可观测与排障 幂等与台账的正确性,靠三条可观测指标与一个审计视图: - 接口侧返回 idempotent=true 的比例:持续偏高说明终端重传策略有问题(退避不够、时间戳跳变),应回到终端配置。 - 台账 qty_on_station 与 pass_record 分组统计的差异:每日对账脚本拉两边计数,差值应恒为 0;有差值说明 delta 应用丢失或并发覆盖未重试。 - 过站事件时间 vs 处理时间的偏移分布:偏移突增通常对应网络拥塞或消息队列积压,去重窗可能在此刻吞掉合法临近事件,可按站点动态拉长窗口并记录告警。 审计视图建议:按 work_order_no + tray_code 拉出该托盘在工艺路线上的 pass_record 序列,展示 station_code、pass_result、event_time、processed_at、idempotent 标志。现场核对"到底到哪一站、有没有被当作重复吃掉"时,一个序列比一堆总数更有用。 六、常见坑 - 把 idempotency_key 当业务唯一键:终端不同、枪不同、重传生成不同 key,幂等直接失效。业务唯一键必须包含工单+托盘/SN+站点+结果+时间窗。 - 仅用 event_time 秒级去重:设备时钟抖动或多枪并行会把不同托盘的合法扫描当成重复。去重窗要配合 tray_code/serial_no,且窗口不宜过长(20–30 秒)。 - 台账 append-only 不覆盖:同站重复扫描会让 qty_on_station 越扫越多,日报与看板全是虚数。同站重复是状态刷新,不是数量叠加。 - 补录/返工和正常过站在同一个接口且同一套去重规则:漏扫补录会被去重窗吃掉,返工重过会被当作重复。用不同接口或 backfill/rework 标志分流。 - 并发写台账不用乐观锁:两条几乎同时到达的过站在同一工单-站点上各自读到旧 version,后提交覆盖前提交,丢失一次 delta。version 校验+重试是最低成本解法。 七、小结 SMT 过站扫码接口的幂等不是"请求去重按钮",而是工单-托盘-站点-结果-时间窗组成的业务唯一键;WIP 台账也不是一张汇总表,而是按 delta 规则原地更新、带乐观锁的状态视图。两者配合到位,现场重扫、弱网补传、返工回流都不会把在制品台账扫虚。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。