个人 ERP 经验分享
首页 / 技术随笔 / 实施方法

给塑料加工厂做 ERP:先把业务口径钉死,再谈写代码

一个人给自家塑料加工厂做 ERP 的起步复盘——最贵的不是技术,是「想当然」。

实施方法2026-10-09约 9 分钟

一、起点:不是选框架,是先听懂工厂怎么算账

接手加工行业的系统,最先做的不是挑 Vue 还是 React,而是把业务口径钉死。一家塑料包装厂的账,本质是每张单据:金额怎么构成、重量按什么单位、单号怎么归零、时间以谁为准。这些事在白板上吵清楚的代价,远低于上线之后改代码——尤其是时间口径,页面、数据库、报表三处一旦不一致,对账永远差一天。

复刻期真正造成返工的,没有一次是因为技术难,几乎全是「我替用户做了假设」。下面四类最典型。

二、坑一:选品数量语义被我想当然

我以为「件数」就是数量,直接拿它当主数量字段。用户一句话纠正:老系统的「数量」另有含义。结果全部重做。类似还有明细列序——我按「逻辑顺序」排了列,用户要求逐字对齐老系统一屏的列序;打印金额取整——我按财务习惯保留两位小数,老系统是 Math.round 取整,用户真机截图对比后打回。

判据:动手前先问自己「这一条,老系统页面上是怎么呈现的?」答不上来就去读源码或翻截图,不要设计。凡偏离老系统,必须当场问用户,不得以「反直觉」为由私自改语义。

三、坑二:金额口径,折扣为 0 被悄悄吞掉

金额构成是(材料费 + 加工费)× 折扣% + 其他费用。代码里写了折扣默认值兜底:

// 错误示范:discount_rate 为 0 时当 falsy,被 || 100 顶成「不打折」
const rate = order.discount_rate || 100;

客户明确「这单不要折扣、折扣就是 0」,系统却算出 100% 折扣——金额直接归零。根因是把「0」当成了「没填」。正确做法是显式判断 null/undefined,而不是用逻辑或兜底。另一处是统计报表把已作废的单据混进了求和,欠款、业绩一夜数倍膨胀。

口径写进文档,不写进脑子:金额、折扣、作废状态、单位,每一类字段的语义和边界都落到书面,新加任何一个数值字段先定口径再写代码。

四、坑三:时间口径三处不齐,对账差一天

页面显示北京时间,MySQL 列存 UTC,「今日」指的是北京自然日。三套口径只要有一处没对齐,月底对账就永远差一天。比如列表「处理日期」用 handle_time,明细「开单时间」用 created_at,两者时区来源不同;order_date 字段类型更是不敢动(全系统 187 处引用)。

解法不是临时换算,而是把时间口径收敛成一条真源函数,所有页面、报表、接口都调它,谁也不准自己 new Date() 硬算。

五、坑四:编号按天归零,删了单就撞号

单据编号每天从 1 重新开始(SC20261009xxxx)。早期「取当前最大编号 +1」的实现,在有人删单后,新单会复用被删的号,造成「两个不同单同一个号」的硬冲突。修正:nextCode 必须把已删除的行也算进序号,编号一经发出不复用。

六、复盘:先钉死,再写代码

这套纪律是在返工里换来的。技术栈随便换,但「先听懂工厂怎么算账,再写代码」这一条,跨行业都成立。