2026-06-15-process-equipment-link-design.md 9.8 KB

工艺设备关联设备管理 设计文档

日期: 2026-06-15
状态: 已实现
关联模块: 设备管理、工艺库管理、工艺路线管理、生产工单/生产任务


1. 业务背景

【生产基础信息】→【设备管理】维护租户内设备主数据(biz_equipment)。
【工艺库管理】→【工艺列表】中「设备名称」目前为自由文本(equipment_name),与设备主数据无关联,存在录入不一致、无法校验、无法追溯等问题。

工艺还会经【工艺路线】组合,并在【生产工单】→【生产任务】中作为步骤快照执行。设备字段在三层均采用快照复制模式(与工序名称等字段一致),改造需兼顾主数据关联与历史快照完整性。


2. 需求共识

# 决策 说明
1 步骤级可覆盖(选项 A) 工艺路线步骤、生产任务步骤的设备必须从设备管理选择,但允许与工艺主数据的默认设备不同
2 多设备逗号存储 三表新增 equipment_ids(逗号分隔 ID),equipment_name 扩展为逗号分隔名称快照(varchar 1000)
3 保留名称快照 equipment_name 保存当时设备名称列表(逗号分隔),列表/导出直接展示
4 不自动回写下游 修改工艺主数据的设备后,不自动更新已存在的路线步骤或生产任务步骤(与现有 process_name 等行为一致)
5 设备删除约束 被工艺/路线步骤引用的设备禁止软删除;停用(status=0)允许,下拉中过滤或标记异常
6 UI 控件 三处编辑界面:el-input 改为 el-select(filterable),数据源 fetchAllEquipments(),展示「设备编码 / 设备名称」

3. 数据流

biz_equipment(设备主数据)
       ↑ equipment_id 引用
biz_process(工艺默认设备)
       │ add_step / 拖入克隆:复制 equipment_id + equipment_name
       ↓
biz_process_route_step(路线步骤,可覆盖设备)
       │ _clone_route_to_task:复制 equipment_id + equipment_name
       ↓
biz_production_task_step(任务步骤,可覆盖设备)

复制触发点(均需同步 equipment_id + equipment_name):

触发场景 后端函数
工艺拖入路线 process_route.add_step()
路线步骤复制 process_route.copy_step()
路线克隆新版本 process_route 版本复制逻辑(如有)
任务选路线派工 production_task._clone_route_to_task()
任务手动加工艺步骤 production_task.add_task_step(process_id=...)
任务步骤复制 production_task.copy_task_step()

4. 数据库变更

4.1 变更表(3 张)

在以下表业务字段区(description 之后或同类位置)新增:

表 新增字段 类型 说明
biz_process equipment_id VARCHAR(64) DEFAULT NULL 关联 biz_equipment.id
biz_process_route_step equipment_id VARCHAR(64) DEFAULT NULL 步骤级设备,可覆盖工艺默认
biz_production_task_step equipment_id VARCHAR(64) DEFAULT NULL 任务步骤级设备,可覆盖路线/工艺

保留现有字段: 三表 equipment_name varchar(200) 不删除,作为快照冗余。

索引(可选,建议):

  • idx_process_equipment(equipment_id, del_flag) — 用于删除引用检查
  • 路线/任务步骤表可不建 FK 索引(引用检查走工艺主表即可)

4.2 不变表

  • biz_equipment — 结构不变,增加被引用校验逻辑
  • biz_process_route、biz_production_task 及所有子表(试剂/耗材/产出/采集)— 不涉及设备

4.3 迁移 SQL 示例

ALTER TABLE biz_process
  ADD COLUMN equipment_id varchar(64) DEFAULT NULL COMMENT '关联设备ID(biz_equipment.id)' AFTER description;

ALTER TABLE biz_process_route_step
  ADD COLUMN equipment_id varchar(64) DEFAULT NULL COMMENT '关联设备ID(biz_equipment.id)' AFTER description;

ALTER TABLE biz_production_task_step
  ADD COLUMN equipment_id varchar(64) DEFAULT NULL COMMENT '关联设备ID(biz_equipment.id)' AFTER description;

4.4 历史数据迁移

  1. 对三表现有 equipment_name 非空记录,按 tenant_no + 精确/trim 后匹配 biz_equipment.equipment_name 回填 equipment_id
  2. 无法匹配的记录:equipment_id 留 NULL,equipment_name 保留原值;列表/表单展示时提示「未关联设备(历史数据)」
  3. 匹配脚本放 backend/scripts/migrate_process_equipment_id.py,可 --dry-run

5. 后端设计

5.1 Model(backend/app/models/models.py)

三个 Model 各增加:

equipment_id = Column(String(64), nullable=True, comment="关联设备ID")

5.2 CRUD 约定

写入规则(统一 helper,建议 resolve_equipment_snapshot(db, equipment_id, tenant_no) -> (id, name)):

  • 传入 equipment_id 时:校验设备存在、未删除、同租户;写入 equipment_id 并将 equipment_name 设为当前 biz_equipment.equipment_name
  • 清空设备:equipment_id = None,equipment_name = None
  • 禁止仅传 equipment_name 字符串而不传 ID(API 层废弃纯文本写入,兼容读取旧数据)

_row_to_dict 扩展字段:

  • equipmentId
  • equipmentName(快照名称,已有)
  • 列表/详情可选 enrich:equipmentCode、equipmentStatus(join 设备表,仅展示)

设备删除(equipment.py soft_delete_equipment):

  • 删除前查询 biz_process、biz_process_route_step 是否存在 equipment_id = ? AND del_flag = 0
  • 存在则 raise ValueError("该设备已被工艺或工艺路线引用,无法删除")
  • 生产任务步骤不参与删除拦截(任务为历史快照,允许设备从主数据删除后任务仍显示快照名称;若需严格可扩展检查)

5.3 API Schema(backend/app/api/production.py 等)

ProcessCreateBody / ProcessUpdateBody:

equipment_id: Optional[str] = Field(None, alias="equipmentId")
# equipment_name 只读出参,Create/Update 不再接受客户端直传 equipmentName

ProcessRouteStepUpdateBody、ProductionTaskStepUpdateBody:

  • 同上,接受 equipmentId,服务端解析名称快照

响应: 继续返回 equipmentId + equipmentName;详情可增加 equipmentCode 便于展示。

5.4 复制逻辑改动清单

文件 函数 改动
crud/process_route.py add_step 复制 proc.equipment_id + proc.equipment_name
crud/process_route.py copy_step 复制 src.equipment_id + src.equipment_name
crud/process_route.py update_step 支持 equipment_id 参数,经 helper 写快照
crud/production_task.py _clone_route_to_task 复制 rs.equipment_id + rs.equipment_name
crud/production_task.py add_task_step 从工艺复制 equipment_id + equipment_name
crud/production_task.py update_task_step 支持 equipment_id
crud/production_task.py copy_task_step 复制 src.equipment_id + src.equipment_name

6. 前端设计

6.1 改动页面

页面 文件 改动
工艺列表/表单 views/production/process/index.vue 设备名称 → el-select,绑定 formData.equipmentId;列表列展示 equipmentName(或编码/名称)
工艺路线步骤 views/production/process/ProcessRouteTab.vue 步骤基本信息区同样改为设备下拉,保存传 equipmentId
生产任务步骤 views/production/production-work-order/StepDetailPanel.vue 同上
任务步骤编辑器 useTaskStepEditor.ts 保存 payload 改为 equipmentId;选中时本地同步 equipmentName 展示

6.2 下拉数据

  • 使用已有 fetchAllEquipments()(/web/admin/equipments/all)
  • Option label:{equipmentCode} / {equipmentName}
  • 过滤:status === '1' 正常设备可选;status === '0' 可显示但标记「异常」
  • 历史数据 equipmentId 为空但 equipmentName 有值:select 显示 placeholder「历史文本:xxx」,引导用户重新选择

6.3 UI 规范

  • 遵循 Fresh Mint 规范;label-position="top"
  • 与「工序分类」下拉交互一致(filterable + clearable)
  • 字段非必填(与现况一致)

7. 业务规则摘要

场景 行为
新建工艺并选设备 写 equipment_id,冗余 equipment_name
工艺改设备 仅更新 biz_process;已有路线/任务步骤不变
路线步骤改设备 仅更新该步骤;允许与来源工艺不同
任务步骤改设备 仅更新该步骤;执行中可改(与现有步骤编辑一致)
设备改名 已存快照名称不变;新保存/新复制使用新名称
设备停用 下拉不可选或弱提示;已关联记录仍显示快照
设备删除 被工艺或路线步骤引用时拒绝删除

8. 测试要点

  1. 工艺 CRUD:选设备、清空设备、列表/详情展示
  2. 拖入路线:步骤继承工艺设备;步骤级改设备后与原工艺不同
  3. 生产任务:选路线克隆、手动加工艺步骤,设备正确复制;步骤级覆盖
  4. 设备删除:被工艺引用时拦截;未被引用可删
  5. 历史数据:仅有 equipment_name 无 ID 时页面不报错,可重新关联
  6. 字段一致性:运行 python scripts/check_field_consistency.py

9. 不在本次范围

  • 设备与 SOP、环境检测等业务联动
  • 生产任务按设备排产/冲突检测
  • 小程序端设备展示
  • 自动同步工艺设备变更到已有路线/任务

10. 实现顺序建议

  1. SQL + Model + 迁移脚本
  2. 后端 helper + process CRUD + API
  3. process_route / production_task 复制与更新逻辑
  4. 设备删除引用检查
  5. 前端三处下拉改造
  6. 历史数据迁移 + 联调