生产制造
本页是一篇完整方案指南:以 production 插件(com.auraboot.production,命名空间 prd)为例,从用户场景一路讲到开发实施和典型错误。它是 config 型插件——5 个 model、14 条命令、8 个页面全部是 DSL JSON 声明,没有任何后端 Java;下面每个标识符你都能在插件里 grep 到、对运行实例调得通。
它覆盖的是制造的工单跟踪主线:工作中心、工艺路线、生产工单、车间日志,完成「计划 → 下达 → 开工 → 完工」这条受控的状态流。MRP/APS 排程、MES 派工报工、设备 IoT 这些更重的能力不在本插件,属于另一套 PCBA 制造插件(见对应用例),本页不涉及。
这个插件在
plugin.json里声明依赖product-catalog、inventory、org-management。解析器会拒绝在缺少这些插件时安装它——因为工单要引用产品(prd_po_product_id)、工艺路线挂在产品上、车间执行要对接库存。
1. 用户场景
一家离散制造厂,跨多产线、多工位、多产品。日常:
- 工程先把每个产品的工艺路线(
prd_routing)定下来——做几道工序、每道工序在哪个工作中心(prd_work_center)、setup/run 各多少分钟;路线先draft,审核后active,改版废弃的标deprecated。 - 计划员按销售单或预测开生产工单(
prd_production_order):工单自动拿到PO-{yyyyMMdd}-{seq}编号,状态从planned起。 - 计划确认后下达工单(
released),车间据此领料、排产;实际开工记录开工时间(in_progress),完工回填完工/报废数量(completed)。 - 车间作业实时记车间日志(
prd_shop_floor_log):开工、停工、报产、报废、停机、换线——按工单×工作中心记录产出与停机时长。
计划员、车间主管、操作员看到的视图和能做的操作各不相同。工艺改版随时会来,但已下达的工单要按它当时绑定的路线继续跑。
📷 截图位 —— 生产订单 / 工艺路线页(待 host-first 起栈抓真实页面截图,见 backlog)
2. 需求痛点
- 状态切换无授权无审计:谁在什么时候下达/开工/完工/取消了工单,事后查不到;Excel 里改个状态没人拦得住。
- 跨步骤对账靠人:计划、下达、领料、报产分散在多张表里,工单到底跑到哪一步、产出多少、报废多少,谁也对不齐。
- 编号与计数手工维护:工单号靠人编、完工/报废数量靠人加减,容易重号、错算。
- 集成困难:销售单想自动触发开工单、车间报工想回写工单进度,只能靠人工二次录入。
这些都不是「再加一张表」能解决的,而是受控状态变更的问题。
3. 常规解法 vs AuraBoot 的设计哲学
3.1 常规解法是怎样的
如果让一个团队从零做工单制造,通常是这条路:
- 领域建模:画实体和关系——工作中心、工艺路线、工序、生产工单、车间日志……
- 建表:把实体翻译成一堆
CREATE TABLE,加外键、状态字段、工单号列。 - 写 CRUD:每个实体一套 Repository / Service / Controller,增删改查全手写。
- 把业务规则 hard-code 进 service:工单号
PO-{yyyyMMdd}-{seq}怎么生成、状态怎么从 planned→released→in_progress→completed 流转、下达和开工分别需要什么权限、改一道工序要不要影响已下达工单——全写死在 Java 里。 - 各处补横切关注点:权限判断散落在每个 controller;谁在什么时候下达/取消了工单,审计靠手动插日志;想把工单进度发给排产或销售,再搭一套 MQ。
- 前端:每个页面手写表单、列表。
- 想接 AI / 自动化:对不起,得再包一层 API、再定义一遍权限和风险边界。
实务里更常见的是连第 2 步都省了——排产用 Excel、工序状态人肉维护、领料退料和库存两张皮对不齐。能跑,但业务规则散落在代码各处,改一条工艺规则要同时动 service + controller + 前端;并发计数、审计、事件、AI 入口每一样都得自己扛。三个月起步,而且越改越脆。
3.2 AuraBoot 的设计哲学
AuraBoot 把这件事反过来:业务的「是什么」用声明描述,「怎么执行」由运行时统一兜底。三条核心理念:
- 元数据驱动:model / field / command / page / permission 都是声明(DSL JSON),不是手写代码。平台据此自动建表、生成接口、渲染页面——上面第 2、3、6 步基本消失。工单号
PO-{yyyyMMdd}-{seq}、完工/报废数量初值靠命令的autoSetFields自动填,不用人手维护。 - 单一命令管道:每一次工单动作都是一条命令,走同一条 命令管道。鉴权、校验、事务、审计这些横切关注点由管道统一处理,不写进每个业务里——你声明
prd:release_production_order时只关心「planned→released」,谁能下达、何时下达的留痕是白送的(第 4、5 步从「自己扛」变成「平台默认」)。 - 命令即契约:同一条命令同时服务 UI 按钮、自动化规则、BPM 节点、AI agent(靠
permissions分权、风险/agent_hint分级)。「销售单确认后自动建工单」「主管节点确认下达」复用的是同一条prd:create_production_order/prd:release_production_order,AI 原生不是事后包 API(第 7 步免了)。
3.3 同一个功能,两种活法
于是普通做法里那些「自己扛」的事,在 AuraBoot 变成平台契约的默认能力。每一格的 AuraBoot 列都是下面能 grep 到的真实命令/模型,不是宣传话术:
| 能力 | 自己写(手写后端) | 打包 ERP / 典型低代码 | AuraBoot(本插件) |
|---|---|---|---|
| 工单状态机 | planned→released→in_progress→completed 的流转 + 权限写死在 service,改一处要二开 | 工单流程现成,但状态/字段写死,加一个状态要定制 | prd:release_production_order / prd:start_production_order / prd:complete_production_order,状态切换是声明,管道内统一鉴权审计 |
| 工单号 / 完工计数 | 手写序列生成,并发重号;完工/报废数量人肉加减 | 多有自动编号,但规则改不动 | prd:create_production_order 用 autoSetFields 自动出 PO-{yyyyMMdd}-{seq} + 完工/报废数量置 0 |
| 工艺路线版本 | 自建路线表 + 手写「已下达工单不受新版本影响」逻辑 | 有工艺,版本/改版常要加购 PLM 模块 | prd:create_routing(draft)→ prd:activate_routing(active),prd_routing 带 prd_rt_version,工单绑当时的路线 |
| 工作中心主数据 | 加产能/费率字段,到处手维护 | 有工位,产能/成本费率字段级常缺 | prd:create_work_center,prd_work_center 内建产能 prd_wc_capacity / 费率 prd_wc_cost_rate / 状态 active·maintenance·inactive |
| 车间产出 / 停机流水 | 没有事件流水,产出报废靠人对账 | 报工常是另一套 MES,难打通 | prd:create_shop_floor_log,prd_shop_floor_log 按事件类型(start/output/scrap/downtime…)记产出与停机时长 |
| 被自动化 / AI 调用 | 还要再包一层 API,且无权限/风险分级 | 基本无原生 AI 入口 | 同一条命令带 permissions + agent_hint,UI / 自动化 / BPM / AI agent 同一条路径,安全可控 |
| 权限 + 审计 | 散落在各 controller,易漏 | 角色粗粒度,执行/管理常不分 | 多层权限(prd.production.manage 下达 vs prd.production.execute 开工完工)+ 审计内建在命令管道,每次变更自动留痕 |
一句话:手写要三个月、还得自己扛并发编号和审计;打包 ERP 快但工艺一改就改不动;AuraBoot 用声明式配置就拿到一套 production 级的工单制造内核,而且每个能力都能被 AI 安全驱动、被你自由扩展。 下面看它具体怎么搭。
4. 功能设计
4.1 数据模型(5 个)
| Model | 用途 | 关键状态值 |
|---|---|---|
prd_work_center | 工作中心(机器/手工/装配/测试工位),带产能 prd_wc_capacity 与成本费率 prd_wc_cost_rate | prd_wc_status:active / maintenance / inactive(类型 prd_work_center_type:machine / manual / assembly / testing) |
prd_routing | 工艺路线,挂在产品上、带版本号 prd_rt_version | prd_routing_status:draft / active / deprecated |
prd_routing_operation | 工序,prd_routing 的子表(parentField = prd_rop_routing_id);每步含 setup/run 时间与工作中心 | —(子实体,无独立状态机) |
prd_production_order | 生产工单,编号 PO-{yyyyMMdd}-{seq} 自动生成 | prd_order_status:planned → released → in_progress → completed → closed / cancelled |
prd_shop_floor_log | 开工/停工/报产/报废/停机/换线事件流水,按工单×工作中心记录 | 事件类型 prd_sfl_event_type:start / stop / output / scrap / downtime / changeover |
prd_work_center与prd_routing/prd_routing_operation是长期主数据,本身没有 document 状态机;工单prd_production_order才是带documentConfig(statusField=prd_po_status、codePattern=PO-{yyyyMMdd}-{seq})的单据。
4.2 命令与状态机
命令命名是冒号格式 prd:<动词>_<名词>,不是点号。这个插件全是 config 命令,没有后端 handler——状态流转不是 state_transition 类型,而是 type: update + autoSetFields 把状态字段置成目标值(创建类是 type: create)。
14 条命令(4 条 create、9 条 update、1 条 delete)。下面这几条覆盖了工单主线的命令形态:
| 命令 | 类型 | 关键作用 |
|---|---|---|
prd:create_production_order | create | 自动生成 PO-{yyyyMMdd}-{seq} 编号,状态置 planned,完工/报废数量置 0 |
prd:release_production_order | update | planned → released,下达工单 |
prd:start_production_order | update | released → in_progress,回填实际开工时间 prd_po_actual_start |
prd:complete_production_order | update | in_progress → completed,回填完工/报废数量与实际完工时间 |
prd:cancel_production_order | update | 置 cancelled |
prd:create_work_center / prd:update_work_center / prd:delete_work_center | create / update / delete | 工作中心维护(创建时自动编号 WC-{yyyyMMdd}-{seq},状态置 active) |
prd:create_routing / prd:activate_routing / prd:update_routing | create / update | 建工艺路线(初始 draft)、启用置 active |
prd:create_shop_floor_log / prd:update_shop_floor_log | create / update | 记录/修正车间日志 |
每条命令都是一段声明。例如 prd:start_production_order(config/commands/prd_start_production_order.json)的真实定义:
{
"code": "prd:start_production_order",
"displayName:zh-CN": "开始生产",
"displayName:en": "Start Production",
"description": "Mark production order as in progress",
"type": "update",
"modelCode": "prd_production_order",
"inputFields": ["prd_po_actual_start"],
"autoSetFields": {
"prd_po_status": { "strategy": "fixed_value", "value": "in_progress" }
},
"permissions": ["prd.production.execute"]
}读出来的设计信息:这是一条 update 命令,作用在 prd_production_order 上;inputFields 只收一个实际开工时间 prd_po_actual_start(其余字段不在这步改);autoSetFields 把状态字段 prd_po_status 固定写成 in_progress;要求 prd.production.execute 权限(开工属于「执行」而非「管理」)。对比一下:prd:create_production_order 用 autoSetFields 把编号设为 auto_generate(pattern PO-{yyyyMMdd}-{seq})、状态置 planned、完工/报废数量初值置 0——这就是「编号与计数不靠人手」的实现。
4.3 权限与角色
4 个权限码(<模块>.<资源>.<动作> 形态),区分「管理 / 查看 / 执行 / 看板」:
prd.production.manage # 增删改工单、工作中心、工艺路线;下达、取消
prd.production.read # 查看工单、工作中心、路线、车间日志
prd.production.execute # 开工、完工、记车间日志
prd.dashboard.production # 查看生产看板
注意权限粒度的设计:下达/取消(prd.production.manage)和开工/完工(prd.production.execute)分属不同权限——计划员能下达但不一定上手开工,操作员能开工完工但不能随意取消工单。
角色只有 1 个,prd_production_planner(生产计划员),带 manage + read + execute + dashboard 四个权限。这个插件没有按主管/操作员再细分角色——细分留给落地时按 4 个权限码自由组合(比如建一个只带 read + execute 的车间操作员角色)。命令管道里的多层权限会对每条命令逐次求值。
4.4 页面
8 个页面:4 个 model(工单、工作中心、工艺路线、车间日志)各一个 list + form,用 Page Designer 出 DSL。
诚实说明两点:没有单独的 detail 页(列表 + 表单即可覆盖录入/查看),也没有 dashboard 页——prd.dashboard.production 权限码已经预留,但 config/pages/ 里没有看板页面,生产看板属于后续可补的能力。菜单 config/menus.json 把 4 个列表页挂到「生产管理」目录下,每项都用 prd.production.read 控制可见性。
5. 具体开发与实施
先掌握基础。本插件没有任何后端 Java,全靠平台的几个核心契约。动手前请先读:Model 与 Field · Command · 命令管道 · Permission · 插件清单 · 纯配置 Plugin · Page Designer。
落地一个像 production 这样的 config 插件,步骤是:
- 定义 model 与字段 ——
config/models.json+config/fields/,字段类型用平台dataType(string/integer/decimal/date…),不要写string(120)这种内联长度(长度是单独字段属性);单据型 model(prd_production_order)在extension.documentConfig里声明statusField、codePattern,子表(prd_routing_operation)在extension里声明parentModel/parentField。详见 Model 与 Field。 - 声明命令 —— 每个动作一个
config/commands/<...>.json;创建用type: create+autoSetFields(自动编号、初始状态/计数),状态推进用type: update+autoSetFields把状态字段写成目标值,并在permissions绑权限码。详见 Command。 - 配 model-field binding ——
config/bindings/(每个 model 一个文件,声明字段顺序、是否 required/editable/searchable),并在plugin.json的resourceDirs.modelFieldBindings注册(见「典型错误」)。 - 设计页面 ——
config/pages/,列表/表单用 Page Designer 出 DSL。 - 权限、角色、字典、菜单 ——
config/permissions.json/roles.json/dicts.json/menus.json。 - 打包导入 —— 用
auraCLI 的import-directory-sync(参数是目录 path)或平台导入接口;校验返回success:true才算导入成功。详见 插件清单。
6. 常见配置
- 工单生命周期:
prd:create_production_order(planned)→prd:release_production_order(released)→prd:start_production_order(in_progress)→prd:complete_production_order(completed);中途可prd:cancel_production_order置 cancelled。完工命令的inputFields收prd_po_qty_completed/prd_po_qty_scrap/prd_po_actual_end,回填真实产出。 - 工艺路线版本:路线带
prd_rt_version,prd:create_routing初始置draft,审核后prd:activate_routing置active,改版后旧路线手动改deprecated。已下达工单引用的是它当时绑的路线,不受新版本影响。 - 工作中心产能与成本:
prd_work_center上prd_wc_capacity(产能)、prd_wc_cost_rate(成本费率)、prd_wc_type(machine/manual/assembly/testing)是排产和成本核算的基础数据;prd_wc_status标 active/maintenance/inactive。 - 车间事件流水:
prd:create_shop_floor_log按prd_sfl_event_type(start/stop/output/scrap/downtime/changeover)记一条事件,带产出量prd_sfl_qty_output、报废量prd_sfl_qty_scrap、停机时长prd_sfl_downtime_min——做产出与停机分析的明细来源。
7. 典型错误
- 命令码用点号:写成
prd.production.start或prd.start.order跑不通——真实是冒号 + 动词_名词:prd:start_production_order。注意prd.production.manage这种点号串是权限码,不是命令码,两者形态不同别混。 - 绕过命令直接改工单表:直接 UPDATE 工单
prd_po_status会跳过命令管道的鉴权、校验、审计,也跳过autoSetFields的自动编号/计数,导致状态、产出、报废对不齐。一切状态变更都走命令。 - 以为状态流转是
state_transition:这个 config 插件没有 handler、没有state_transition类型——状态推进是type: update+autoSetFields写状态字段。需要在状态切换上挂写库副作用(如自动建领料单)才需要 hybrid 插件 + 后端 jar,那是另一套 PCBA 制造插件的事,不是production。 - bindingRules 写进 commands.json 内联:不会被导入;binding 必须独立放
config/bindings/并在resourceDirs.modelFieldBindings注册,否则报[S-EXT-HANDLER] references unregistered handler。详见 纯配置 Plugin。 - 命令执行 payload 结构:字段放在
{ "payload": { ... }, "operationType": ... },目标记录用targetRecordId(不是recordId)——放错位会出现「执行成功却字段为空」的迷惑性报错(命令明明跑通,工单字段却是空的)。 - 漏装依赖插件:
production依赖product-catalog/inventory/org-management,缺任一解析器会拒装(工单的prd_po_product_id引用的是产品目录里的产品)。