9.8 KiB
9.8 KiB
工艺设备关联设备管理 设计文档
日期: 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 历史数据迁移
- 对三表现有
equipment_name非空记录,按tenant_no+ 精确/trim 后匹配biz_equipment.equipment_name回填equipment_id - 无法匹配的记录:
equipment_id留 NULL,equipment_name保留原值;列表/表单展示时提示「未关联设备(历史数据)」 - 匹配脚本放
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 扩展字段:
equipmentIdequipmentName(快照名称,已有)- 列表/详情可选 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. 测试要点
- 工艺 CRUD:选设备、清空设备、列表/详情展示
- 拖入路线:步骤继承工艺设备;步骤级改设备后与原工艺不同
- 生产任务:选路线克隆、手动加工艺步骤,设备正确复制;步骤级覆盖
- 设备删除:被工艺引用时拦截;未被引用可删
- 历史数据:仅有
equipment_name无 ID 时页面不报错,可重新关联 - 字段一致性:运行
python scripts/check_field_consistency.py
9. 不在本次范围
- 设备与 SOP、环境检测等业务联动
- 生产任务按设备排产/冲突检测
- 小程序端设备展示
- 自动同步工艺设备变更到已有路线/任务
10. 实现顺序建议
- SQL + Model + 迁移脚本
- 后端 helper + process CRUD + API
- process_route / production_task 复制与更新逻辑
- 设备删除引用检查
- 前端三处下拉改造
- 历史数据迁移 + 联调