生产退库单同步策略实战:从 MySQL 到金蝶云星空的端到端集成
这个策略解决什么问题
生产退库是车间把已入库的成品或半成品退回到仓库的逆向动作。某制造企业的 MES 在某张接口表里持续写入退库记录,财务和库存的口径却在金蝶云星空。表面上看只是「新增一张单」,但单据需要带生产订单号、生产订单行号、原入库单号、退库数量、生产车间等一长串关联字段,任何一个映射错位,目标端就会拒收或生成「孤儿单」。我们这次的目标,就是把这条 MySQL → 金蝶云星空 的链路在轻易云数据集成平台(Qeasy)上做成一条可调度、可追溯、可重跑的策略。
数据流向与字段映射
整体链路分三段:源端 MySQL(业务中间库)→ 轻易云平台 → 目标金蝶云星空。源端用一条聚合 SQL 把多张接口表拼接出来,目标端按金蝶云星空的 batchSave 接口写入。
关键字段对照:
| 源端 MySQL 字段 | 中间层表达式 | 目标金蝶云星空字段 | 说明 |
|---|---|---|---|
| t1.header_id | sourceid | 内部幂等键 | 用作查重与日志 |
| CONCAT('MSCTK', DATE_FORMAT(...), t1.header_id) | 单据编号 | FBillNo | 退库单唯一编号 |
| ifnull(会计期间,aft_quiet_time, t1.transaction_date) | 单据日期 | FDate | 未结账则取业务日期 |
| SUBSTRING_INDEX(t1.wo_number,'_',1) | 生产订单号 | FMoBillNo | 截取生产订单头 |
| SUBSTRING_INDEX(t1.wo_number,'_',-1) | 生产订单行号 | FMoEntryNo | 截取生产订单行 |
| ABS(t1.ok_qty) | 退库数量 | FQty | 退库数量取绝对值 |
| t2.material_code | 物料编码 | FMaterialId | 通过编码映射 |
| t3.attribute9 | 生产入库单号 | FInStockBillNo | 关联原入库单 |
| ifnull(t4.value,'15040501') | 生产车间 | FWorkShopId | LOV 兜底映射 |
| t2.manufacturing_site_code | 生产组织 | FPrdOrgId / FStockOrgId | 退库组织同生产组织 |
| 固定值 | 单据类型 | FBillType | 取 SCTK01_SYS |
注:表头与表体分阶段写入是轻易云客户常见的应对模式。
在轻易云上如何配置
我们在 Qeasy 上把这条策略拆成「源读取 → 字段映射 → 目标写入」三个组件,整体串成一个数据流。
源端:选 MySQL 适配器,API 类型选 select / WebAPI(POST),执行主 SQL。main_params 传入分页参数 :limit、:offset,做分页拉取,避免一次性拉爆。idCheck 关闭,sourceid 作为幂等键,由平台去重。
目标端:选金蝶云星空适配器,API 选 batchSave(POST)。把单据编号作为 idCheck 字段,开启按 FBillNo 查重,单据已存在则跳过不重写,避免重复入库。固定值如 FBillType=SCTK01_SYS、货主类型 BD_OwnerOrg 直接写常量。
字段映射:物料编码、生产车间、生产组织这三类基础资料最容易出问题。我们在 Qeasy 的映射面板里集中维护「编码映射表」——物料用编码对齐、组织用 code 对齐、车间走 LOV 翻译,源端没有命中就兜底成默认车间。这是轻易云客户常见的应对模式之一:把易变的基础资料映射集中在一处管理,源端结构改了不用动 SQL。
写入策略:表头和表体分两条子流写入。表头先写,拿到目标端返回的单据内码后,再回填到表体的 FParentId 字段发起二次提交。这样表头失败时不会留下「孤儿表体」。
实施步骤
第一阶段:建立增量起点。源 SQL 默认按 t1.STATUS in ('N','E') 拉取新增/异常记录,第一次执行时强制 where 1=1 拉全量做基线,之后切回增量。基线跑完后写一条「首跑完成」标记。
第二阶段:配置双轨调度。源端读取 cron 设为 */10 8-23 * * *,每 10 分钟拉一次;目标端写入 cron 设为 */4 8-23 * * *,更密集地把积压写入。轻易云常见做法是「源稀目标密」,让目标端追平源端积压。
第三阶段:上线灰度。先用 limit 10 offset 0 小批量跑通,核对金蝶端单据状态、库存流水、会计期间是否正确,再放开分页。
第四阶段:监控告警。配置失败重试 3 次、间隔 30 秒;连续两次失败触发告警到企业微信。每日 23:30 做一次「源-目标对账」,比对两端的单据编号集合,差异超过阈值即停跑并人工介入。
踩坑复盘
-
生产订单号带下划线。源端
wo_number形如MO123456_2,直接整串写入会被金蝶当成一个未知单号。稳妥的做法是用SUBSTRING_INDEX拆出头与行,分别写入FMoBillNo和FMoEntryNo。 -
会计期间未结账。单据日期直接取
transaction_date,会导致跨期报错。我们加了ifnull取aft_quait_time(结账后第一天)兜底,避免月初第一天的单据被拒。 -
生产入库单为空。
t3.attribute10 is null的记录必须过滤,否则金蝶端会因为找不到原入库单而拒收。我们在源 SQL 里加and t3.attribute10 is not null。 -
退库数量方向。源端
ok_qty是带符号的(正数表示入库、负数表示退库),写入金蝶前必须ABS(),否则金蝶会把数字按正向入库处理。 -
重复写入。idCheck 只在源端关闭是不够的,目标端 batchSave 必须按 FBillNo 做幂等,否则断点续传会把同一张单写两次。
适用场景与不适用场景
适用于:MES 已生成生产退库接口表、金蝶云星空作为唯一财务/库存口径的离散制造企业;车间-仓库-财务三方需要实时对齐的场景。
不适用于:源端没有稳定的接口中间表、所有数据靠业务系统直接 SELECT;以及金蝶云星空做主、MES 做从的场景——那种更应该让金蝶发起同步,而不是把反向链路搭成「读不到就补不上」的脆弱管道。