开篇:为什么是 PLM——工程数据治理与变更协同的底座

一、一家机械厂的"图纸版本事故"
我朋友老 K 在一家做工业机械臂的厂里当研发主管。去年他们接了个汽车焊装线项目,6-DOF 机械臂 TDJ-25,从概念到量产 14 个月。项目过了 9 个月,客户突然提了个变更:底座负载能力不够,要从 3 公斤升到 4.2 公斤。
听起来是个小改动——底座加厚、材质从铝合金换成钢制——但实际改下去的事,让老 K 至今回忆起来都皱眉。
第一坑:图纸版本乱。底座的工程图在共享盘里有 7 个版本,文件名分别是 底座_v1.dwg / 底座_v2_final.dwg / 底座_v2_final_真的final.dwg / 底座_老王改.dwg。没人能说清哪个是当前发布的。车间拿错了图,加工出来 30 件底座,报废 28 件。
第二坑:EBOM-MBOM 脱节。设计 BOM 里底座下面挂的是"大臂组件",但工艺 BOM 里挂的是"大臂(含伺服电机)"——同名不同物。采购按 EBOM 买零件,工艺按 MBOM 装配,中间差了一个电机,到装配时才发现,停线 4 天。
第三坑:ECO(工程变更单)失控。底座要改,但底座的改动会牵连大臂的安装孔位、BOM 里大臂数量、装配工艺指导书、检验报告模板——5 个变更同时进行。当时他们的"ECO"是 Excel 表,5 个人各自填各自的 sheet,没人协调。等所有人改完才发现:大臂组件的安装孔改了 8mm,但底座的安装孔只改了 5mm,对不上。返工。
老 K 跟我吐槽:"我们不是没 PLM,我们装了 Aras Innovator,但没人用——配置太复杂、UI 太老、改个字段要找咨询顾问。最后大家还是用 Excel + 共享盘。"
我问他:"那你装 Aras 干嘛?"他说:"因为客户要求过 ISO 9001 认证,认证机构要 PLM 系统的截图。"
这就是中国大多数中小制造企业的 PLM 现状:装了不用,用了不深,深的少数还停留在"电子仓库"层面——把 PLM 当网盘用。
二、PLM 到底是什么
PLM 全称 Product Lifecycle Management,产品生命周期管理。但它不是"一个软件",而是一种工程数据治理 + 变更协同的方法论,落地为软件只是其中一环。
拆开看,PLM 至少要回答 5 个问题:
- 对象是谁:把现实世界的产品(零件、文档、BOM、变更单、需求、测试用例……)抽象成什么数据结构?
- 版本怎么管:一个零件从设计到量产,会经历多个版本,怎么记录历史、怎么知道当前生效?
- 变更怎么协同:一个变更会牵连哪些对象?多人同时改一个对象怎么不冲突?
- 审批怎么走:变更不是改完就生效,要走"草稿→评审→发布"的流程,怎么把流程固化下来?
- 数据怎么共享:设计 BOM / 工艺 BOM / 制造 BOM 之间怎么转换?CAD 文档怎么和零件关联?
这 5 个问题里,前两个是"数据治理",后三个是"变更协同"。很多 PLM 系统只做了前两个——把 PLM 当网盘用,就停在这里。真正难的是后三个。
PLM 和 PDM 的区别也在这里:PDM(Product Data Management)只管"文档 + 版本",是网盘的高级版;PLM 是 PDM + 变更协同 + 跨职能协同(设计、工艺、采购、质量、制造)。一句话:PDM 是"看历史",PLM 是"看历史 + 谁在改 + 改了之后谁会受影响"。
三、商业 PLM 三巨头:Aras / Teamcenter / Windchill
| 维度 | Aras Innovator | Siemens Teamcenter | PTC Windchill |
|---|---|---|---|
| 起源 | 美国 1996 | 美国 1963(最早叫 CV) | 美国 1989 |
| 数据库 | SQL Server / Oracle | Oracle / DB2 | Oracle |
| 类型系统 | UI 配置式 ItemType | 元数据驱动 | 元数据驱动 |
| 变更管理 | ECO + Lifecycle | ECO + Change Manager | ECO + CR/ECN |
| 二次开发 | AML(自研脚本)+ .NET | ITK / C / Java | Java / Info*Engine |
| 部署 | 单机 / 私有云 | 私有云 / 公有云 | 私有云 / 公有云 |
| 价格(中端项目) | 100-300 万 | 300-800 万 | 200-500 万 |
| 国内市占 | 中 | 高(汽车/装备) | 中(电子/医疗器械) |
| 适合行业 | 离散制造 | 大型装备 | 电子/医疗/汽车 |
这三家我都接触过。从用户视角看,它们的共同问题是:
- 太贵:一个 100 人的项目,年维护费就 50 万起。
- 太重:实施周期 6-18 个月,咨询顾问驻场是常态。
- 太专:二次开发要学自研脚本(AML/ITK/Java),招人难。
- 太"工程":UI 还停留在 Windows 95 风,年轻工程师上手就劝退。
更要命的是锁死:一旦数据进了 Aras,想迁出来要付大价钱;和公司既有 IT(ERP/MES)打通要靠中间件,价格另算。
中小制造企业要 PLM,但又用不起 Aras/Teamcenter/Windchill——这就是市场缺口。
四、开源 PLM 的现状
我做过一轮开源 PLM 调研,主要候选:
| 项目 | 技术栈 | 活跃度 | 评价 |
|---|---|---|---|
| OpenPLM | Python + Django | 几乎停更(2021 后无大版本) | 老旧,UI 像 2010 年 |
| DocDokuPLM | Java EE + GWT | 维护中但很慢 | 重,GWT 早就过时 |
| BCOMS PLM | .NET + Angular | 小众 | 国内无社区 |
| Cascadia PLM | TypeScript + Hono + Drizzle + PG18 | 100+ PRs,活跃 | 现代 stack,AGPL-3.0 |
| Aras Open Source | .NET | 活跃但被社区诟病"开源版本阉割" | 生态锁死 |
Cascadia PLM 跳出来有几个原因:
- 真开源:AGPL-3.0,所有源码在 GitHub(
Cascadia-PLM/Cascadia-App),不是"开源版本阉割"那种。 - 现代 stack:Hono + Vite + TanStack Router + Drizzle ORM + PostgreSQL 18 + RabbitMQ + Three.js + Python CAD Worker(pythonocc-core)。这些技术栈在 2026 年的招聘市场都好找人。
- 差异化创新:不是简单复刻 Aras,而是把 Git 工作流引入工程数据——叫 ECO-as-Branch。
- Code-First:类型定义走 TypeScript 代码 + Zod 校验,不走 Aras 那种 UI 配置式 ItemType。
- Two-Table Pattern:基表
items+ 类型专属表(parts/documents/change_orders)的混合模式,比纯宽表灵活、比纯 EAV 高效。 - CAD 原生支持:内置 Python CAD Worker 跑 pythonocc-core,能直接吃 STEP/IGES 文件生成 GLB 预览。
我对 Cascadia 的评价:这是 2026 年唯一一个"工程上能用、技术上现代、社区有活力"的开源 PLM。
五、Cascadia 的核心差异化:ECO-as-Branch
ECO 是 Engineering Change Order,工程变更单。传统 PLM 的 ECO 模型是这样的:
一个 ECO 是一条记录,关联 N 个受影响对象(item)。改完后把这 N 个对象的状态从 "In Work" 改成 "Released"。要追溯历史,得查 ECO 表 + item_history 表 + status_log 表的关联。
Cascadia 的 ECO 模型是这样的:
一个 ECO 对应一个 Git 风格的分支(
eco/ECO-001)。受影响对象从 main 分支"检出"(checkout)到 eco 分支,在 eco 分支里随便改。改完审批通过,把 eco 分支 merge 回 main,main 上的对象自动拿到新版本号(A→B→C)。
这一改带来几个直接好处:
- 变更隔离:一个 ECO 没合回 main 之前,对其他人是不可见的。可以同时开 5 个 ECO 互不干扰。
- 历史可追:要看某零件的演进,git-like log 就行——分支 + commit + field diff,比 PLM 传统的 audit log 直观。
- 回滚原子:ECO 不通过审批,直接弃用 eco 分支,main 一点没动。
- 冲突显式:两个 ECO 同时改一个零件,合并时 ConflictDetectionService 直接告诉你"main divergence"或"Cross-ECO conflict",强迫用户解决——而不是默默覆盖。
类比就一句话:Cascadia 把 Git 的心智模型搬到了工程数据上。对工程师来说,"分支 + 合并 + 冲突"这套语言已经刻在脑子里了,迁移成本极低。
六、Two-Table Pattern:基表 + 类型专属表
PLM 系统的另一个老大难:怎么存 14 种类型差异巨大的对象。
- Part 有 material / weight / cost
- Document 有 file_path / sha256 / size_bytes
- ChangeOrder 有 reason / scope / approver_id
- WorkOrder 有 quantity / due_date / priority
传统三种方案:
- 大宽表:所有字段塞一张表,几百列。问题:维护噩梦,加字段要改所有相关代码。
- EAV(Entity-Attribute-Value):items 表只存 id,所有属性走 item_attributes 表(item_id + attr_name + attr_value)。问题:查询要 JOIN N 次,性能炸。
- 每类型一张表:parts 表、documents 表、change_orders 表完全独立。问题:跨类型查询要 UNION ALL,item_type 新增要改 schema。
Cascadia 用 Two-Table Pattern:基表 items 存所有类型共有的字段(master_id / item_number / revision / lifecycle_state / branch_id),类型专属表只存类型特有字段。
plm_items (基表,所有类型共用)
├── plm_parts (Part 专属)
├── plm_documents (Document 专属)
├── plm_change_orders (ChangeOrder 专属)
├── plm_requirements (Requirement 专属)
└── ...
新增 Item Type 只要:① 加一个枚举值 ② 加一张表 ③ 在 ItemTypeRegistry 注册——基表零改动。查询跨类型走基表,查具体类型走 JOIN 类型表。
这套设计在关系数据库里算"折中但实用",比纯 EAV 性能好 10 倍,比纯宽表维护好 10 倍。
七、Cascadia 的 14 类 Item
| 分类 | 类型 | 说明 |
|---|---|---|
| 核心工程 | Part | 零件,物料编码 + BOM 节点 |
| 核心工程 | Document | 文档,挂在零件上(CAD / spec / report) |
| 核心工程 | ChangeOrder | ECO,工程变更单本身 |
| 需求验证 | Requirement | 需求条目 |
| 需求验证 | SystemElement | 系统元素(功能分解) |
| 需求验证 | TestPlan | 测试计划 |
| 需求验证 | TestCase | 测试用例 |
| 工艺制造 | WorkInstruction | 作业指导书 |
| 工艺制造 | WorkOrder | 工单 |
| 工艺制造 | Tool | 工装夹具 |
| 工艺制造 | PhysicalPart | 实物件(有 serial number 的) |
| 软件设计 | Software | 软件版本 |
| 软件设计 | Task | 任务(轻量项,不走 ECO) |
| 软件设计 | Issue | 问题/缺陷 |
这 14 类覆盖了一个产品从需求→设计→工艺→制造→售后的大部分数据对象。我后面会用 yudao/Spring Boot 把它们复刻成 ItemTypeEnum 枚举 + ItemTypeRegistry 注册中心。
八、我要做什么:用 yudao/Spring Boot 复刻 Cascadia 核心
Cascadia 是 TypeScript 写的,但国内大部分制造企业的 IT 团队是 Java 背景——招聘市场 Java 比 TS 多 5 倍。所以这一连载的设定是:
用 yudao-framework / Spring Boot 4 / Java 21 / MyBatis-Plus / PostgreSQL 把 Cascadia 的核心引擎复刻一份,让有 Java 团队的工厂可以直接落地。
复刻范围(10 章):
| 章节 | 主题 |
|---|---|
| 01 | 开篇:为什么是 PLM(本章) |
| 02 | 领域模型——14 类 Item 讲清 PLM |
| 03 | ECO-as-Branch 核心引擎:把 Git 工作流引入工程数据 |
| 04 | 适配层——TypeScript Code-First 与 yudao Java 复刻的桥 |
| 05 | 主流程——一个 ECO 从 Draft 到 Released 的完整链路 |
| 06 | 可视化——BOM 树 + 3D CAD 预览 + 提交图 |
| 07 | 边界场景——并发 ECO 冲突与 main 分支演进 |
| 08 | 并发与锁——乐观锁、隔离级别与 revision 分配原子性 |
| 09 | 配置与部署——Docker Compose + RabbitMQ + Python CAD Worker |
| 10 | 商用上线与复盘——从 TDJ-25 机械臂 demo 到客户场景 |
代码底座:https://github.com/sunrise314/plm-product-lifecycle,父工程 cn.iocoder:yudao:2.4.0-jdk8-snapshot,子模块 yudao-module-plm。
九、读者画像与阅读路线
适合谁读:
- 制造企业 IT/研发主管,正在评估开源 PLM 选型
- Java 后端工程师,需要在公司内部落地 PLM 系统
- 对"Git 工作流引入工程数据"好奇的工程师
- 写过 MES/ERP,想往 PLM 方向延伸的同行
前置知识:
- Java 基础(Spring Boot / MyBatis)
- 关系数据库 + SQL
- 大致了解 Git 命令(branch / commit / merge)
- 知道 PLM 是什么(不需要会用 Aras)
阅读路线:
- 想看选型决策:读 01 + 02 + 10。
- 想看核心引擎:读 03 + 04 + 05。
- 想看实战踩坑:读 06 + 07 + 08 + 09。
- 想完整落地:按顺序读,每章代码我都贴 GitHub 链接。
十、写给老 K
回到开篇那个故事。老 K 后来问我:"如果我用你们这套,能解决底座那件事吗?"
我给他算了一笔账:
- 用 Cascadia-as-Branch 模型,底座升级要走 ECO。ECO 一开,自动从 main 检出底座到 eco 分支,老王在 eco 分支改 weight 字段。改完点"submit",scope_locked=true,scope(受影响列表)锁定。
- 同事老张也想改底座?他得自己开 ECO-002,从 main 检出底座到他的 eco 分支。两人并行干活,互不干扰。
- 老王先 submit + approve,merge 回 main,底座 revision A→B。
- 老张再 submit 时,ConflictDetectionService 抛
Main divergence: baseItemId≠main HEAD——告诉他"你基于的底座已过期,请先 rebase"。老张 rebase 后,把老王的改动 pull 进来(main 赢策略),合并提交,底座 A→B→C。
整个过程没有任何"图纸版本乱"、没有"EBOM-MBOM 脱节"、没有"5 个人 5 个 sheet 各自改"。
老 K 听完只说了一句:"这就是 Git 思路啊。"
是的,这就是 Git 思路。Git 解决了代码的版本与协同问题,Cascadia 把它搬到工程数据上,解决零件、文档、BOM 的版本与协同问题。
接下来 9 章,我会一步步把这个思路拆给你看。下一章我们先从领域模型开始——14 类 Item 怎么落到 14 张表,Two-Table Pattern 怎么把基表和类型表串起来。
