生产制造

本页是一篇完整方案指南:以 production 插件(com.auraboot.production,命名空间 prd)为例,从用户场景一路讲到开发实施和典型错误。它是 config 型插件——5 个 model、14 条命令、8 个页面全部是 DSL JSON 声明,没有任何后端 Java;下面每个标识符你都能在插件里 grep 到、对运行实例调得通。

它覆盖的是制造的工单跟踪主线:工作中心、工艺路线、生产工单、车间日志,完成「计划 → 下达 → 开工 → 完工」这条受控的状态流。MRP/APS 排程、MES 派工报工、设备 IoT 这些更重的能力不在本插件,属于另一套 PCBA 制造插件(见对应用例),本页不涉及。

这个插件在 plugin.json 里声明依赖 product-cataloginventoryorg-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 常规解法是怎样的

如果让一个团队从零做工单制造,通常是这条路:

  1. 领域建模:画实体和关系——工作中心、工艺路线、工序、生产工单、车间日志……
  2. 建表:把实体翻译成一堆 CREATE TABLE,加外键、状态字段、工单号列。
  3. 写 CRUD:每个实体一套 Repository / Service / Controller,增删改查全手写。
  4. 把业务规则 hard-code 进 service:工单号 PO-{yyyyMMdd}-{seq} 怎么生成、状态怎么从 planned→released→in_progress→completed 流转、下达和开工分别需要什么权限、改一道工序要不要影响已下达工单——全写死在 Java 里。
  5. 各处补横切关注点:权限判断散落在每个 controller;谁在什么时候下达/取消了工单,审计靠手动插日志;想把工单进度发给排产或销售,再搭一套 MQ。
  6. 前端:每个页面手写表单、列表。
  7. 想接 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_orderautoSetFields 自动出 PO-{yyyyMMdd}-{seq} + 完工/报废数量置 0
工艺路线版本自建路线表 + 手写「已下达工单不受新版本影响」逻辑有工艺,版本/改版常要加购 PLM 模块prd:create_routing(draft)→ prd:activate_routing(active),prd_routingprd_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_rateprd_wc_status:active / maintenance / inactive(类型 prd_work_center_type:machine / manual / assembly / testing)
prd_routing工艺路线,挂在产品上、带版本号 prd_rt_versionprd_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_centerprd_routing/prd_routing_operation长期主数据,本身没有 document 状态机;工单 prd_production_order 才是带 documentConfig(statusField = prd_po_statuscodePattern = 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_ordercreate自动生成 PO-{yyyyMMdd}-{seq} 编号,状态置 planned,完工/报废数量置 0
prd:release_production_orderupdateplanned → released,下达工单
prd:start_production_orderupdatereleased → in_progress,回填实际开工时间 prd_po_actual_start
prd:complete_production_orderupdatein_progress → completed,回填完工/报废数量与实际完工时间
prd:cancel_production_orderupdatecancelled
prd:create_work_center / prd:update_work_center / prd:delete_work_centercreate / update / delete工作中心维护(创建时自动编号 WC-{yyyyMMdd}-{seq},状态置 active)
prd:create_routing / prd:activate_routing / prd:update_routingcreate / update建工艺路线(初始 draft)、启用置 active
prd:create_shop_floor_log / prd:update_shop_floor_logcreate / 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_orderautoSetFields 把编号设为 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 插件,步骤是:

  1. 定义 model 与字段 —— config/models.json + config/fields/,字段类型用平台 dataType(string / integer / decimal / date…),不要写 string(120) 这种内联长度(长度是单独字段属性);单据型 model(prd_production_order)在 extension.documentConfig 里声明 statusFieldcodePattern,子表(prd_routing_operation)在 extension 里声明 parentModel / parentField。详见 Model 与 Field
  2. 声明命令 —— 每个动作一个 config/commands/<...>.json;创建用 type: create + autoSetFields(自动编号、初始状态/计数),状态推进用 type: update + autoSetFields 把状态字段写成目标值,并在 permissions 绑权限码。详见 Command
  3. 配 model-field binding —— config/bindings/(每个 model 一个文件,声明字段顺序、是否 required/editable/searchable),并在 plugin.jsonresourceDirs.modelFieldBindings 注册(见「典型错误」)。
  4. 设计页面 —— config/pages/,列表/表单用 Page Designer 出 DSL。
  5. 权限、角色、字典、菜单 —— config/permissions.json / roles.json / dicts.json / menus.json
  6. 打包导入 —— 用 aura CLI 的 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。完工命令的 inputFieldsprd_po_qty_completed / prd_po_qty_scrap / prd_po_actual_end,回填真实产出。
  • 工艺路线版本:路线带 prd_rt_version,prd:create_routing 初始置 draft,审核后 prd:activate_routingactive,改版后旧路线手动改 deprecated。已下达工单引用的是它当时绑的路线,不受新版本影响。
  • 工作中心产能与成本:prd_work_centerprd_wc_capacity(产能)、prd_wc_cost_rate(成本费率)、prd_wc_type(machine/manual/assembly/testing)是排产和成本核算的基础数据;prd_wc_status 标 active/maintenance/inactive。
  • 车间事件流水:prd:create_shop_floor_logprd_sfl_event_type(start/stop/output/scrap/downtime/changeover)记一条事件,带产出量 prd_sfl_qty_output、报废量 prd_sfl_qty_scrap、停机时长 prd_sfl_downtime_min——做产出与停机分析的明细来源。

7. 典型错误

  • 命令码用点号:写成 prd.production.startprd.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 引用的是产品目录里的产品)。

下一步

  • 系统总览 —— 插件、命令与运行时如何拼到一起
  • 命令管道 —— 上面每条命令都走的执行契约
  • 权限 —— 上面角色背后的多层模型
  • 插件清单 —— production 如何声明对 product-catalog / inventory 的依赖
  • 价格 —— 各版本能力对比