背景
一个运行在 PHP 5.6 + MySQL 5.7 上的 WMS(仓储管理系统)中有一个工单模块,用于管理仓库内的加工作业——贴标、换包装、质检等。问题是”添加工单”只有 5 个字段:工单号、客户、账号、收货方、Release 号。创建后只是一个空壳,所有数据需要去编辑页逐步补充。团队觉得应该有一个全新的、一步到位的工单表单。
从哪里开始
团队给了一个 Demo 前端页面——一个制造工单的 HTML 表单,包含客户信息、产品明细、QA 清单、自动定价和手写签名。
但要把这个 Demo 集成到 WMS 里,需要做几个关键决定。
第一个决定:替换还是并存
旧系统是仓库加工导向的,Demo 是制造导向的。两个方向不同,但面向同一个业务入口。团队确认:替换。
这意味着旧表 work_order_detail 及其 50+ 列全部弃用,历史数据不再保留。
第二个决定:新表用什么结构
Demo 用了 5 张规范化表(work_orders + 4 个子表),旧系统是 50+ 列的单表。最终采用规范化设计,适配了几点:
- 去掉外键约束(旧 WMS 没有用 FK 的习惯)
DATETIME替代TIMESTAMP(系统惯例)- 存储签名 JSON 数据
第三个决定:PHP 8.0 还是 5.6
Demo 的 submit.php 用 PDO + 事务 + 预编译,干净漂亮。但 WMS 跑在 PHP 5.6 上。
最终决定:保持 5.6 兼容。用 mysqli,不用 PDO;不用短数组语法。
架构设计
最终方案是三层分离:
workorder/ ← 后端逻辑层(save/data/autocomplete/print)
template/workorder/ ← UI 展示层(list/add/view/edit)
menu 表 ← 路由层(顶层菜单 cat=workorder)
数据流
用户填写表单 → jQuery UI autocomplete(从数据库中检索客户和产品)→ 前端 JS 自动计算定价 → POST 到后端 → 事务写入 5 张表 → 返回 JSON → DataTable 刷新
自动补全的细节
客户名输入时从 customer 表检索,选中后自动填充电话、邮箱、地址。SKU 输入时从 products 表检索,选中后自动填充规格、材质、颜色。两个都是用 jQuery UI autocomplete,前后端加起来不到 50 行。
签名系统复用
Demo 中说”需要一个签名功能”,但 WMS 其实已经有 jQuery signaturePad 库了。前端画签名 → 存 JSON → PDF 时用 GD 函数转 PNG。一步都没有自己写。
PDF 每页显示工单号
mPDF 的 SetHTMLHeader() 直接解决。真正的问题是把签名 JSON 渲染为图像插入 PDF——而系统里恰好已经有这个转换函数。
总结
这此重构最大的收获是几个观察:
- Demo 到生产环境的距离比看起来远得多——技术栈、数据库版本、团队分工都是约束
- 复用前提是知道你有什么——signaturePad 和 autocomplete 都是现成的,只是没人告诉 AI
- 设计文档的核心价值是接口契约,不是观赏文档