Files
my-mom-system/prd/mom系统产品BOM-页面开发说明文档.md
panchengyong c28ada5050 commit content
2026-03-06 02:02:59 +08:00

1783 lines
69 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 产品BOMEBOM- 页面设计开发说明文档
> 版本: 1.1.0
> 创建日期: 2026-02-06
> 更新日期: 2026-02-06
> 来源系统: 升阳云ERP 演示系统
> 来源页面: `https://demo.rsun.vip/rd/develop/ebom?workType=0&fmConfig=010401,020401`
> 所属模块: 研发管理 > 产品BOM
> 前端路由: `/rd/develop/ebom`
---
## 目录
1. [页面概述](#1-页面概述)
2. [页面结构](#2-页面结构)
3. [列表页设计](#3-列表页设计)
4. [新增/编辑页设计](#4-新增编辑页设计)
5. [数据字段定义](#5-数据字段定义)
6. [按钮操作说明](#6-按钮操作说明)
7. [页面交互规则](#7-页面交互规则)
8. [接口调用说明](#8-接口调用说明)
9. [状态流转](#9-状态流转)
10. [业务规则](#10-业务规则)
11. [前端组件设计](#11-前端组件设计)
12. [数据模型](#12-数据模型)
---
## 1. 页面概述
### 1.1 功能说明
产品BOMEngineering Bill of MaterialsEBOM页面用于管理产品的研发物料清单。EBOM是产品研发阶段的核心数据定义了产品由哪些子件物料组成及其用量比例关系是后续生产计划、物料需求计算、采购管理的基础数据来源。
### 1.2 业务场景
- **新建BOM**: 研发人员选择母件产品,录入子件物料清单,定义用量关系
- **BOM版本管理**: 支持同一产品创建多个BOM版本用于产品迭代升级
- **翻单功能**: 基于已有BOM复制创建新版本版本号自动递增
- **审核流程**: BOM创建后需经审核生效审核后不可编辑支持反审核
- **多阶展开**: 支持多层BOM的层次展开查看
- **BOM校验**: 自动检测是否存在死循环嵌套
- **BOM导出**: 支持导出完整物料清单到电子表格
### 1.3 URL路由参数
| 参数名 | 类型 | 说明 |
|--------|------|------|
| workType | integer | 工作类型0=研发BOM |
| fmConfig | string | 表单配置编码010401,020401 |
### 1.4 页面截图参考
| 截图文件 | 说明 |
|----------|------|
| `docs/ui-make/rsun-产品bom列表-明细视图.png` | 列表页 - 明细视图(默认视图) |
| `docs/ui-make/rsun-产品bom列表-单据视图.png` | 列表页 - 单据视图 |
| `docs/ui-make/rsun-产品bom新增-1.png` | 新增页 - 空白表单 |
| `docs/ui-make/rsun-产品bom新增-2.png` | 新增页 - 已填写数据 |
| `docs/ui-make/rsun-产品bom新增-物料编码选择弹窗.png` | 选择物料弹窗 |
---
## 2. 页面结构
### 2.1 整体布局
```
┌─────────────────────────────────────────────────────────────────┐
│ 顶部导航栏 (64px) │
├────────┬────────────────────────────────────────────────────────┤
│ 左侧 │ 面包屑: 首页 / 研发管理 / 产品BOM │
│ 菜单 │ ┌────────────────────────────────────────────────┐ │
│ (200px │ │ Tab标签: ● 产品BOM │ │
│ /64px)│ ├────────────────────────────────────────────────┤ │
│ │ │ 查询区域 (搜索条件) │ │
│ 研发管 │ ├────────────────────────────────────────────────┤ │
│ 理 │ │ 工具栏 (操作按钮) │ │
│ ├产品 │ ├────────────────────────────────────────────────┤ │
│ 设计 │ │ 数据表格 │ │
│ ├产品 │ │ │ │
│ BOM★ │ │ │ │
│ ├孪生 │ ├────────────────────────────────────────────────┤ │
│ 物料 │ │ 分页组件 │ │
│ ├订单 │ └────────────────────────────────────────────────┘ │
│ 参数 │ │
│ ├生产 │ │
│ 放量 │ │
├────────┴────────────────────────────────────────────────────────┤
```
### 2.2 页面模式
| 模式 | 说明 | 入口 |
|------|------|------|
| 列表页 - 明细视图 | **默认视图**以BOM物料维度展示列表侧重物料信息展示 | 菜单点击「产品BOM」 |
| 列表页 - 单据视图 | 以BOM单据维度展示列表侧重单据流程管理 | 明细视图点击「单据」按钮切换 |
| 新增页 | 新建EBOM清单填写表头+物料明细 | 列表页点击「新增」按钮 |
| 编辑页 | 修改已有EBOM清单仅开立状态 | 单据视图点击「编辑」按钮 |
| 查看页 | 只读查看EBOM清单详情 | 单据视图点击「查看」按钮 |
### 2.3 列表页双视图概述
列表页提供 **明细视图****单据视图** 两种展示模式,通过工具栏左侧第一个按钮相互切换:
```
┌──────────────────────────────────────────────────────────────┐
│ 明细视图(默认) 单据视图 │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ [单据] 按钮 │ ──切换到单据视图──► │ [明细] 按钮 │ │
│ │ │ ◄──切换到明细视图── │ │ │
│ └─────────────┘ └─────────────┘ │
│ │
│ ● 侧重物料信息展示 ● 侧重单据流程管理 │
│ ● 无复选框,不支持批量操作 ● 有复选框,支持批量操作 │
│ ● 操作列: 多阶/翻单/导出 ● 操作列: 查看/编辑/删除 │
│ ● 搜索含物料分类 ● 搜索含单据状态/业务状态 │
└──────────────────────────────────────────────────────────────┘
```
**两种视图对比总览:**
| 对比项 | 明细视图(默认) | 单据视图 |
|--------|-----------------|---------|
| 切换按钮 | 工具栏显示「单据」按钮 | 工具栏显示「明细」按钮 |
| 复选框列 | 无 | 有 |
| 序号列 | 有 | 无 |
| 搜索条件 | 单据编码、物料编码、物料名称、**物料分类**、日期范围 | 单据编码、物料编码、物料名称、**单据状态**、**业务状态**、日期范围 |
| 工具栏按钮 | 单据、查询所有、新增、清空、导入、导出 | 明细、查询所有、新增、删、审核、反审核 |
| 数据列 | 物料编码、物料名称、母件基数、版本号等 | 单据日期、单据状态、业务类型、业务部门等 |
| 操作列 | 多阶、翻单、导出 | 查看、编辑、删除(按状态显隐) |
| 批量操作 | 不支持 | 支持(删除、审核、反审核) |
| 适用场景 | 研发人员查看BOM物料组成 | 管理员进行单据审核管理 |
---
## 3. 列表页设计
### 3.1 明细视图(默认视图)
明细视图是进入产品BOM页面时的默认视图侧重于展示BOM的物料组成信息。
> 截图参考: `docs/ui-make/rsun-产品bom列表-明细视图.png`
#### 3.1.1 搜索条件区域
| 序号 | 字段名 | 标签 | 组件类型 | 宽度 | 说明 |
|------|--------|------|----------|------|------|
| 1 | bomCode | 单据编码 | el-input | 140px | 模糊搜索 |
| 2 | itemCode | 物料编码 | el-input | 140px | 模糊搜索 |
| 3 | itemName | 物料名称 | el-input | 140px | 模糊搜索 |
| 4 | itemTypeId | 物料分类 | el-select | 120px | 下拉选择物料分类,可清空 |
| 5 | startDate | 开始日期 | el-date-picker | 140px | 日期范围起 |
| 6 | endDate | 结束日期 | el-date-picker | 140px | 日期范围止 |
> **注意**: 明细视图的搜索条件没有「单据状态」和「业务状态」,而是有「物料分类」下拉选择。
#### 3.1.2 工具栏按钮
| 序号 | 按钮名称 | 图标 | 类型 | 权限标识 | 说明 |
|------|----------|------|------|----------|------|
| 1 | 单据 | - | primary | rd:ebom:list | 切换到单据视图 |
| 2 | 查询所有 | el-icon-tickets | default | rd:ebom:list | 重置搜索条件并查询所有 |
| 3 | 新增 | el-icon-plus | success | rd:ebom:add | 打开新增EBOM页面 |
| 4 | 清空 | el-icon-circle-close | warning | rd:ebom:remove | 清空列表数据(需确认) |
| 5 | 导入 | el-icon-upload2 | default | rd:ebom:import | 导入BOM数据 |
| 6 | 导出 | el-icon-download | default | rd:ebom:export | 导出BOM列表到Excel |
#### 3.1.3 数据表格列定义
| 序号 | 列标题 | 字段名 | 宽度 | 对齐 | 说明 |
|------|--------|--------|------|------|------|
| 1 | 序号 | - | 60px | center | 自动编号(无复选框) |
| 2 | 单据编码 | bomCode | 140px | left | 蓝色链接,可点击打开详情 |
| 3 | 物料编码 | itemCode | 140px | left | 母件物料编码 |
| 4 | 物料名称 | itemName | 200px | left | 母件物料名称 |
| 5 | 母件基数 | baseQty | 80px | center | 母件基本数量 |
| 6 | 版本号 | version | 80px | center | BOM版本号如 1.00、7.00 |
| 7 | 版本说明 | versionDesc | 120px | left | 版本变更说明 |
| 8 | 图纸号 | drawingNo | 100px | left | 产品图纸编号 |
| 9 | 单据状态 | status | 80px | center | 状态标签(开立/审核/退回) |
| 10 | 单据日期 | bomDate | 100px | center | 单据创建日期 |
| 11 | 操作 | - | 140px | center | 操作按钮组 |
#### 3.1.4 明细视图操作列按钮
明细视图操作列对所有状态的BOM统一显示以下按钮
| 按钮 | 颜色 | 权限 | 说明 |
|------|------|------|------|
| 多阶 | primary (蓝色文字) | rd:ebom:expand | 展开多层BOM结构树 |
| 翻单 | success (绿色文字) | rd:ebom:copy | 复制当前BOM生成新版本 |
| 导出 | warning (橙色文字) | rd:ebom:export | 导出当前BOM明细到Excel |
> **注意**: 明细视图的操作列不区分状态所有BOM均显示「多阶」「翻单」「导出」三个按钮。
---
### 3.2 单据视图
单据视图侧重于BOM的单据流程管理支持批量操作审核、反审核、删除
> 截图参考: `docs/ui-make/rsun-产品bom列表-单据视图.png`
#### 3.2.1 搜索条件区域
| 序号 | 字段名 | 标签 | 组件类型 | 宽度 | 说明 |
|------|--------|------|----------|------|------|
| 1 | bomCode | 单据编码 | el-input | 140px | 模糊搜索 |
| 2 | itemCode | 物料编码 | el-input | 140px | 模糊搜索 |
| 3 | itemName | 物料名称 | el-input | 140px | 模糊搜索 |
| 4 | status | 单据状态 | el-select | 120px | 下拉选择,可清空 |
| 5 | businessStatus | 业务状态 | el-select | 120px | 下拉选择,可清空 |
| 6 | startDate | 开始日期 | el-date-picker | 140px | 日期范围起 |
| 7 | endDate | 结束日期 | el-date-picker | 140px | 日期范围止 |
> **注意**: 单据视图的搜索条件没有「物料分类」,而是有「单据状态」和「业务状态」两个下拉选择。
**单据状态选项:**
| 值 | 标签 | 标签颜色 |
|----|------|----------|
| DRAFT | 开立 | info (灰色) |
| APPROVED | 审核 | success (绿色) |
| REJECTED | 退回 | warning (橙色) |
**业务状态选项:**
| 值 | 标签 |
|----|------|
| NORMAL | 正常 |
| PAUSE | 暂停 |
| CANCEL | 取消 |
#### 3.2.2 工具栏按钮
| 序号 | 按钮名称 | 图标 | 类型 | 权限标识 | 说明 |
|------|----------|------|------|----------|------|
| 1 | 明细 | - | primary | rd:ebom:list | 切换到明细视图 |
| 2 | 查询所有 | el-icon-tickets | default | rd:ebom:list | 重置搜索条件并查询所有 |
| 3 | 新增 | el-icon-plus | success | rd:ebom:add | 打开新增EBOM页面 |
| 4 | 删 | el-icon-delete | danger | rd:ebom:remove | 批量删除选中记录(需勾选) |
| 5 | 审核 | el-icon-check | primary | rd:ebom:approve | 批量审核选中记录(需勾选) |
| 6 | 反审核 | - | default | rd:ebom:unapprove | 批量反审核选中记录(需勾选) |
#### 3.2.3 数据表格列定义
| 序号 | 列标题 | 字段名 | 宽度 | 对齐 | 排序 | 说明 |
|------|--------|--------|------|------|------|------|
| 0 | (复选框) | - | 55px | center | - | 多选列,用于批量操作 |
| 1 | 单据编码 | bomCode | 140px | left | 否 | 可点击打开详情 |
| 2 | 单据日期 | bomDate | 120px | center | 是 ▼ | 默认降序排列 |
| 3 | 单据状态 | status | 80px | center | 否 | 状态标签(颜色区分) |
| 4 | 业务类型 | businessType | 100px | center | 否 | 如机械BOM |
| 5 | 业务部门 | deptName | 100px | center | 否 | |
| 6 | 业务人员 | operatorName | 100px | center | 否 | |
| 7 | 业务状态 | businessStatus | 80px | center | 否 | |
| 8 | 审核日期 | approveDate | 120px | center | 否 | 仅审核后显示 |
| 9 | 操作 | - | 160px | center | - | 操作按钮组(按状态显隐) |
#### 3.2.4 单据视图操作列按钮
单据视图操作列按钮根据单据状态动态显隐:
**status = APPROVED已审核:**
| 按钮 | 颜色 | 权限 | 说明 |
|------|------|------|------|
| 查看 | success (绿色文字) | rd:ebom:query | 打开查看页(只读) |
| 翻单 | primary (蓝色文字) | rd:ebom:copy | 复制BOM生成新版本 |
**status = DRAFT开立:**
| 按钮 | 颜色 | 权限 | 说明 |
|------|------|------|------|
| 查看 | success (绿色文字) | rd:ebom:query | 打开查看页 |
| 编辑 | primary (蓝色文字) | rd:ebom:edit | 打开编辑页 |
| 删除 | danger (红色文字) | rd:ebom:remove | 二次确认后删除 |
**status = REJECTED退回:**
| 按钮 | 颜色 | 权限 | 说明 |
|------|------|------|------|
| 查看 | success (绿色文字) | rd:ebom:query | 打开查看页 |
| 编辑 | primary (蓝色文字) | rd:ebom:edit | 打开编辑页(重新修改) |
| 删除 | danger (红色文字) | rd:ebom:remove | 二次确认后删除 |
---
### 3.3 分页组件(两种视图通用)
| 属性 | 值 | 说明 |
|------|------|------|
| 默认每页条数 | 100 | 可选: 10, 20, 50, 100 |
| 布局 | total, sizes, prev, pager, next, jumper | 完整分页 |
| 总条数显示 | 共 {total} 条 | 左侧显示 |
---
## 4. 新增/编辑页设计
### 4.1 页面布局
新增/编辑页面为独立的全屏页面(非弹窗),包含表头表单区和物料明细表格区两个部分。
```
┌──────────────────────────────────────────────────────────────┐
│ EBOM清单 [保存][取消][审核][反审核][收起] │
├──────────────────────────────────────────────────────────────┤
│ 表头表单区 (4列布局可折叠) │
│ ┌──────────┬──────────┬──────────┬──────────┐ │
│ │ 单据编码 │ 业务类型 │ 物料编码 │ 图纸号 │ │
│ │ 单据日期 │ 操作员 │ 物料名称 │ 版本号 │ │
│ │ 单据状态 │ 审核员 │ 计量单位 │ 版本说明 │ │
│ │ 业务状态 │ 审核日期 │ 母件基数 │ 备注信息 │ │
│ └──────────┴──────────┴──────────┴──────────┘ │
├──────────────────────────────────────────────────────────────┤
│ 物料信息 [+ 新增物料] │
│ ┌────┬────────┬──────┬──────┬────┬──────┬──────┬──┬────┬──┬──┬──┐ │
│ │序号│物料编码 │物料名│型号规│主计│计划线│领料方│分│用量│图│备│操│ │
│ │ │ │称 │格 │量 │路 │式 │子│方式│纸│注│作│ │
│ ├────┼────────┼──────┼──────┼────┼──────┼──────┼──┼────┼──┼──┼──┤ │
│ │ 1 │(选择) │ │ │ │ │按单领│ │按比│ │ │删│ │
│ │ 2 │(选择) │ │ │ │ │按单领│ │按比│ │ │删│ │
│ └────┴────────┴──────┴──────┴────┴──────┴──────┴──┴────┴──┴──┴──┘ │
└──────────────────────────────────────────────────────────────┘
```
### 4.2 表头表单字段
表头采用4列栅格布局el-col :span="6"每行4个字段。
| 序号 | 字段名 | 标签 | 组件类型 | 必填 | 默认值 | 说明 |
|------|--------|------|----------|------|--------|------|
| 1 | bomCode | 单据编码 | el-input | 是 | 自动生成 | 只读,格式: EBOM000XXX |
| 2 | businessType | 业务类型 | el-select | 是 | 机械BOM | 下拉选择 |
| 3 | itemCode | 物料编码 | el-input + 选择按钮 | 是 | - | 点击「选择」弹窗选择物料 |
| 4 | drawingNo | 图纸号 | el-input | 否 | - | 产品图纸编号 |
| 5 | bomDate | 单据日期 | el-date-picker | 是 | 当天日期 | 日期选择器 |
| 6 | operatorName | 操作员 | el-input | 是 | 当前登录用户 | 只读 |
| 7 | itemName | 物料名称 | el-input | 是 | - | 只读,选择物料后自动带入 |
| 8 | version | 版本号 | el-input-number | 是 | 1.0 | 支持 -/+ 按钮调整步长0.1 |
| 9 | status | 单据状态 | el-tag | - | 开立 | 只读标签显示 |
| 10 | approverName | 审核员 | el-input | 否 | - | 只读,审核时自动填充 |
| 11 | unitName | 计量单位 | el-input | 否 | - | 只读,选择物料后自动带入 |
| 12 | versionDesc | 版本说明 | el-input | 否 | - | 文本输入最多200字 |
| 13 | businessStatus | 业务状态 | el-select | 是 | 正常 | 下拉选择 |
| 14 | approveDate | 审核日期 | el-date-picker | 否 | - | 只读,审核时自动填充 |
| 15 | baseQty | 母件基数 | el-input-number | 是 | 1.0 | 母件基本数量 |
| 16 | remark | 备注信息 | el-input(textarea) | 否 | - | 多行文本最多500字 |
**业务类型选项:**
| 值 | 标签 |
|----|------|
| MECHANICAL | 机械BOM |
| ELECTRONIC | 电子BOM |
| ASSEMBLY | 装配BOM |
| GENERAL | 通用BOM |
### 4.3 物料明细表格(子表)
子表为可编辑表格,位于表头下方,标题为「物料信息」。
| 序号 | 列标题 | 字段名 | 宽度 | 组件类型 | 必填 | 说明 |
|------|--------|--------|------|----------|------|------|
| 1 | 序号 | lineNo | 60px | 自动编号 | - | 行序号,自动递增 |
| 2 | 物料编码 | bomItemCode | 150px | el-input + 选择按钮 | 是 | 点击「选择」弹窗选择子件物料 |
| 3 | 物料名称 | bomItemName | 180px | el-input | - | 只读,选择物料后自动带入 |
| 4 | 型号规格 | specification | 150px | el-input | 否 | 只读,选择物料后自动带入 |
| 5 | 主计量 | unitName | 80px | el-input | - | 只读,选择物料后自动带入 |
| 6 | 计划线路 | routeName | 100px | el-select | 否 | 下拉选择工艺路线 |
| 7 | 领料方式 | pickType | 120px | el-select | 是 | 按单领用/按库领用 |
| 8 | 分子 | numerator | 80px | el-input-number | 是 | 分子数量(用量比例的分子) |
| 9 | 用量方式 | usageType | 120px | el-select | 是 | 按比例/按固定 |
| 10 | 图纸号 | lineDrawingNo | 100px | el-input | 否 | 子件图纸号 |
| 11 | 备注 | lineRemark | 100px | el-input | 否 | 行备注 |
| 12 | 操作 | - | 80px | el-button | - | 删除按钮 |
**领料方式选项:**
| 值 | 标签 |
|----|------|
| ORDER_PICK | 按单领用 |
| STOCK_PICK | 按库领用 |
**用量方式选项:**
| 值 | 标签 |
|----|------|
| RATIO | 按比例 |
| FIXED | 按固定 |
### 4.4 选择物料弹窗
点击物料编码的「选择」按钮,打开物料选择弹窗。
> 截图参考: `docs/ui-make/rsun-产品bom新增-物料编码选择弹窗.png`
| 属性 | 值 |
|------|------|
| 弹窗标题 | 选择物料 |
| 弹窗宽度 | 1000px |
| 弹窗高度 | 自适应最大70vh |
| 关闭方式 | 右上角 X 按钮 |
| 选择模式 | 单选(点击行操作列「选择」按钮) |
**弹窗布局:**
```
┌──────────────────────────────────────────────────────────────┐
│ 选择物料 [X] │
├──────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ 物料编码 [______] 物料名称 [______] │
│ │Q 请输入分类名│ [搜索] [重置] [查询所有] │
│ │ │ ┌──────┬──────┬────┬────┬────┬────┬──┐ │
│ │ ▸ 01-成品 │ │物料编│物料名│型号│主计│图纸│供应│操│ │
│ │ ▸ 04-原材料 │ │码 │称 │规格│量 │号 │方式│作│ │
│ │ ▸ 05-五金件 │ ├──────┼──────┼────┼────┼────┼────┼──┤ │
│ │ ▸ 06-包装物 │ │010200│简易机│ │台 │ │生产│选│ │
│ │ 07-加工成品│ │010200│简易机│190 │台 │ │生产│选│ │
│ │ ▸ 08-代销类 │ │010300│组装电│ │台 │ │装配│选│ │
│ │ ▸ 09-直销类 │ │010300│组装电│ │台 │ │装配│选│ │
│ │ ▸ 10-电脑组 │ │010300│TESA4│1250│台 │ │委外│选│ │
│ │ 装件 │ │... │... │... │... │... │... │..│ │
│ └─────────────┘ └──────┴──────┴────┴────┴────┴────┴──┘ │
│ 共18条 | 100条/页 | < 1 > │
└──────────────────────────────────────────────────────────────┘
```
**左侧物料分类树:**
| 分类编码 | 分类名称 | 说明 |
|----------|----------|------|
| 01 | 成品 | 可折叠展开子分类 |
| 04 | 原材料 | 可折叠展开子分类 |
| 05 | 五金件 | 可折叠展开子分类 |
| 06 | 包装物 | 可折叠展开子分类 |
| 07 | 加工成品 | 叶子节点 |
| 08 | 代销类 | 可折叠展开子分类 |
| 09 | 直销类 | 可折叠展开子分类 |
| 10 | 电脑组装件 | 可折叠展开子分类 |
- 分类树顶部有搜索框placeholder: "请输入分类名称"
- 点击分类节点,右侧列表按该分类过滤
- 分类树通过 `/md/itemtype/treeselect` 接口获取
**搜索区域:**
| 组件 | 说明 |
|------|------|
| 物料编码输入框 | 模糊搜索 |
| 物料名称输入框 | 模糊搜索 |
| 搜索按钮 | primary类型执行搜索 |
| 重置按钮 | default类型清空搜索条件 |
| 查询所有按钮 | 位于右侧,重置分类选择+搜索条件,查询全部 |
**物料列表表格列:**
| 序号 | 列标题 | 字段名 | 宽度 | 说明 |
|------|--------|--------|------|------|
| 1 | 物料编码 | itemCode | 140px | |
| 2 | 物料名称 | itemName | 200px | |
| 3 | 型号规格 | specification | 150px | |
| 4 | 主计量 | unitName | 80px | 计量单位 |
| 5 | 图纸号 | drawingNo | 100px | |
| 6 | 供应方式 | supplyType | 80px | 生产/装配/委外/加工/采购 |
| 7 | 操作 | - | 60px | 「选择」蓝色链接按钮 |
**选择交互:**
- 点击某行的「选择」按钮,选中该物料
- **表头选择**: 选中后弹窗关闭,自动填充表头的物料编码、物料名称、计量单位
- **明细行选择**: 选中后弹窗关闭,自动填充该行的物料编码、物料名称、型号规格、主计量
> **注意**: 表头选择物料时仅限「生产」「装配」「加工」「委外」供应方式的物料可以作为母件建BOM供应方式为采购的物料不能建BOM。明细行选择子件物料不限供应方式。
---
## 5. 数据字段定义
### 5.1 BOM表头字段erp_md_bom / md_bom
| 字段名 | 数据库字段 | 类型 | 长度 | 必填 | 默认值 | 说明 |
|--------|-----------|------|------|------|--------|------|
| BOM ID | bom_id | bigint | - | 是 | AUTO | 主键,自增 |
| 租户ID | tenant_id | varchar | 20 | 是 | - | 多租户隔离 |
| BOM编码 | bom_code | varchar | 32 | 是 | 自动生成 | 格式: EBOM + 6位流水号 |
| BOM名称 | bom_name | varchar | 100 | 否 | - | BOM名称 |
| 产品物料ID | item_id | bigint | - | 是 | - | 外键 → md_item.item_id |
| 产品物料编码 | item_code | varchar | 32 | 是 | - | 冗余字段 |
| 产品物料名称 | item_name | varchar | 100 | 是 | - | 冗余字段 |
| 产品规格 | item_spec | varchar | 200 | 否 | - | 冗余字段 |
| 计量单位 | unit_name | varchar | 20 | 否 | - | 产品计量单位 |
| 母件基数 | base_qty | decimal | 18,4 | 是 | 1.0 | 母件基本数量 |
| 版本号 | version | varchar | 20 | 否 | 1.0 | BOM版本号 |
| 版本说明 | version_desc | varchar | 200 | 否 | - | 版本变更说明 |
| 单据日期 | bom_date | date | - | 是 | 当天 | 单据创建日期 |
| 业务类型 | business_type | varchar | 20 | 否 | MECHANICAL | 机械BOM/电子BOM等 |
| 图纸号 | drawing_no | varchar | 50 | 否 | - | 产品图纸编号 |
| 单据状态 | status | varchar | 20 | 是 | DRAFT | 开立/审核/退回 |
| 业务状态 | business_status | varchar | 20 | 否 | NORMAL | 正常/暂停/取消 |
| 启用标志 | enable_flag | char | 1 | 是 | Y | Y/N |
| 操作员ID | operator_id | bigint | - | 否 | - | 当前用户ID |
| 操作员 | operator_name | varchar | 50 | 否 | - | 当前用户名 |
| 部门ID | dept_id | bigint | - | 否 | - | 部门ID |
| 部门名称 | dept_name | varchar | 50 | 否 | - | 部门名称 |
| 审核员ID | approver_id | bigint | - | 否 | - | |
| 审核员 | approver_name | varchar | 50 | 否 | - | |
| 审核日期 | approve_date | datetime | - | 否 | - | |
| 备注 | remark | varchar | 500 | 否 | - | |
| 删除标志 | del_flag | char | 1 | 是 | 0 | 0存在/1删除 |
| 创建者 | create_by | varchar | 64 | 否 | - | |
| 创建时间 | create_time | datetime | - | 否 | - | |
| 更新者 | update_by | varchar | 64 | 否 | - | |
| 更新时间 | update_time | datetime | - | 否 | - | |
### 5.2 BOM明细字段erp_md_bom_line / md_product_bom
| 字段名 | 数据库字段 | 类型 | 长度 | 必填 | 默认值 | 说明 |
|--------|-----------|------|------|------|--------|------|
| 明细ID | line_id / bom_line_id | bigint | - | 是 | AUTO | 主键,自增 |
| BOM表头ID | bom_id | bigint | - | 是 | - | 外键 → md_bom.bom_id |
| BOM编码 | bom_code | varchar | 32 | 否 | - | 冗余字段 |
| 行号 | line_no | int | - | 是 | 自动 | 行序号 |
| 子件物料ID | bom_item_id / item_id | bigint | - | 是 | - | 外键 → md_item.item_id |
| 子件物料编码 | bom_item_code / item_code | varchar | 32 | 是 | - | 冗余字段 |
| 子件物料名称 | bom_item_name / item_name | varchar | 100 | 是 | - | 冗余字段 |
| 型号规格 | specification | varchar | 200 | 否 | - | 子件规格型号 |
| 计量单位 | unit_name | varchar | 20 | 否 | - | 子件计量单位 |
| 分子数量 | numerator / base_qty | decimal | 18,6 | 是 | 1.0 | 用量比例分子 |
| 分母数量 | denominator | decimal | 18,6 | 否 | 1.0 | 用量比例分母 |
| 损耗率 | loss_rate | decimal | 5,2 | 否 | 0 | 损耗百分比 |
| 供应方式 | supply_type | varchar | 20 | 否 | PURCHASE | 采购/自制/委外 |
| 领料方式 | pick_type | varchar | 20 | 否 | ORDER_PICK | 按单领用/按库领用 |
| 用量方式 | usage_type | varchar | 20 | 否 | RATIO | 按比例/按固定 |
| 计划线路 | route_id | bigint | - | 否 | - | 关联工艺路线 |
| 计划线路名称 | route_name | varchar | 50 | 否 | - | 冗余字段 |
| 图纸号 | drawing_no | varchar | 50 | 否 | - | 子件图纸号 |
| 备注 | remark | varchar | 200 | 否 | - | |
| 删除标志 | del_flag | char | 1 | 是 | 0 | |
| 租户ID | tenant_id | varchar | 20 | 是 | - | |
---
## 6. 按钮操作说明
### 6.1 明细视图工具栏按钮
#### 6.1.1 「单据」按钮(视图切换)
| 项目 | 说明 |
|------|------|
| 触发条件 | 始终可用 |
| 操作 | 切换到单据视图,重新加载列表数据 |
| 权限 | rd:ebom:list |
| 效果 | 搜索区域、工具栏、表格列、操作列全部切换为单据视图样式 |
#### 6.1.2 查询所有按钮
| 项目 | 说明 |
|------|------|
| 触发条件 | 始终可用 |
| 操作 | 清空所有搜索条件包括物料分类选择重新加载列表pageNum=1 |
| 权限 | rd:ebom:list |
#### 6.1.3 新增按钮
| 项目 | 说明 |
|------|------|
| 触发条件 | 始终可用 |
| 操作 | 路由跳转到新增EBOM页面 |
| 权限 | rd:ebom:add |
| 路由 | `/rd/develop/ebom/add` |
#### 6.1.4 清空按钮
| 项目 | 说明 |
|------|------|
| 触发条件 | 始终可用 |
| 操作 | 弹出确认框确认后清空符合搜索条件的BOM数据谨慎操作 |
| 权限 | rd:ebom:remove |
#### 6.1.5 导入按钮
| 项目 | 说明 |
|------|------|
| 触发条件 | 始终可用 |
| 操作 | 打开文件上传弹窗选择Excel文件导入BOM数据 |
| 权限 | rd:ebom:import |
| 文件格式 | .xlsx / .xls |
#### 6.1.6 导出按钮(工具栏)
| 项目 | 说明 |
|------|------|
| 触发条件 | 始终可用 |
| 操作 | 按当前搜索条件导出BOM列表到Excel |
| 权限 | rd:ebom:export |
### 6.2 明细视图操作列按钮
#### 6.2.1 多阶按钮
| 项目 | 说明 |
|------|------|
| 触发条件 | 始终可用,所有状态均显示 |
| 操作 | 打开多阶BOM展开弹窗树形展示多层BOM结构 |
| 权限 | rd:ebom:expand |
#### 6.2.2 翻单按钮
| 项目 | 说明 |
|------|------|
| 触发条件 | 始终可用,所有状态均显示 |
| 操作 | 弹出确认框确认后复制当前BOM生成新版本版本号自动+1 |
| 权限 | rd:ebom:copy |
| 结果 | 创建新BOM状态为开立(DRAFT),版本号递增 |
#### 6.2.3 导出按钮(行操作)
| 项目 | 说明 |
|------|------|
| 触发条件 | 始终可用,所有状态均显示 |
| 操作 | 导出当前BOM的完整物料清单到Excel |
| 权限 | rd:ebom:export |
### 6.3 单据视图工具栏按钮
#### 6.3.1 「明细」按钮(视图切换)
| 项目 | 说明 |
|------|------|
| 触发条件 | 始终可用 |
| 操作 | 切换到明细视图,重新加载列表数据 |
| 权限 | rd:ebom:list |
| 效果 | 搜索区域、工具栏、表格列、操作列全部切换为明细视图样式 |
#### 6.3.2 删除按钮(批量)
| 项目 | 说明 |
|------|------|
| 触发条件 | 勾选一条或多条记录 |
| 前置校验 | 仅开立(DRAFT)/退回(REJECTED)状态允许删除;已审核状态记录跳过并提示 |
| 操作 | 弹出确认框:"确认删除选中的{n}条BOM记录",确认后调用删除接口 |
| 权限 | rd:ebom:remove |
#### 6.3.3 审核按钮(批量)
| 项目 | 说明 |
|------|------|
| 触发条件 | 勾选一条或多条记录 |
| 前置校验 | 仅开立(DRAFT)状态允许审核需要至少有1条物料明细 |
| 操作 | 弹出确认框,确认后批量审核 |
| 权限 | rd:ebom:approve |
| 结果 | status → APPROVED自动记录审核员和审核日期 |
#### 6.3.4 反审核按钮(批量)
| 项目 | 说明 |
|------|------|
| 触发条件 | 勾选一条或多条记录 |
| 前置校验 | 仅审核(APPROVED)状态允许反审核需要检查该BOM未被下游引用 |
| 操作 | 弹出确认框,确认后批量反审核 |
| 权限 | rd:ebom:unapprove |
| 结果 | status → DRAFT清空审核员和审核日期 |
### 6.4 单据视图操作列按钮
#### 6.4.1 查看按钮
| 项目 | 说明 |
|------|------|
| 显示条件 | 所有状态均显示 |
| 操作 | 路由跳转到EBOM查看页面只读模式 |
| 权限 | rd:ebom:query |
#### 6.4.2 编辑按钮
| 项目 | 说明 |
|------|------|
| 显示条件 | 仅 status = DRAFT开立或 status = REJECTED退回 |
| 操作 | 路由跳转到EBOM编辑页面 |
| 权限 | rd:ebom:edit |
#### 6.4.3 删除按钮(行操作)
| 项目 | 说明 |
|------|------|
| 显示条件 | 仅 status = DRAFT开立或 status = REJECTED退回 |
| 操作 | 弹出确认框确认后删除当前BOM |
| 权限 | rd:ebom:remove |
#### 6.4.4 翻单按钮(行操作)
| 项目 | 说明 |
|------|------|
| 显示条件 | 仅 status = APPROVED审核时显示替代编辑/删除按钮 |
| 操作 | 复制当前BOM生成新版本 |
| 权限 | rd:ebom:copy |
### 6.2 新增/编辑页按钮
#### 6.2.1 保存按钮
| 项目 | 说明 |
|------|------|
| 位置 | 页面右上角 |
| 颜色 | primary (蓝色) |
| 触发条件 | 表单校验通过 |
| 操作 | 保存BOM表头和明细数据 |
| 成功提示 | "保存成功" |
| 失败提示 | 显示后端返回的错误信息 |
#### 6.2.2 取消按钮
| 项目 | 说明 |
|------|------|
| 位置 | 保存按钮右侧 |
| 颜色 | default (灰色) |
| 操作 | 如有未保存修改,弹出确认框"有未保存的数据,确认离开?";返回列表页 |
#### 6.2.3 审核按钮
| 项目 | 说明 |
|------|------|
| 位置 | 取消按钮右侧 |
| 颜色 | success (绿色) |
| 显示条件 | 仅在编辑模式且 status = DRAFT 时显示 |
| 前置条件 | 需先保存至少有1条物料明细 |
| 操作 | 调用审核接口,成功后页面变为只读 |
#### 6.2.4 反审核按钮
| 项目 | 说明 |
|------|------|
| 位置 | 审核按钮右侧 |
| 颜色 | warning (橙色) |
| 显示条件 | 仅在查看模式且 status = APPROVED 时显示 |
| 前置条件 | 该BOM未被下游业务引用 |
| 操作 | 调用反审核接口,成功后页面变为可编辑 |
#### 6.2.5 收起/展开按钮
| 项目 | 说明 |
|------|------|
| 位置 | 页面右上角最右侧 |
| 操作 | 折叠/展开表头表单区域,仅显示物料明细 |
#### 6.2.6 新增物料按钮(子表)
| 项目 | 说明 |
|------|------|
| 位置 | 物料信息区域右上角 |
| 颜色 | primary (蓝色) |
| 操作 | 在明细表格末尾新增一行空白记录 |
| 显示条件 | 仅编辑状态显示 |
#### 6.2.7 删除行按钮(子表操作列)
| 项目 | 说明 |
|------|------|
| 位置 | 每行操作列 |
| 颜色 | danger (红色文字) |
| 操作 | 删除当前行,需二次确认 |
| 显示条件 | 仅编辑状态显示 |
---
## 7. 页面交互规则
### 7.1 列表页通用交互
| 序号 | 交互场景 | 交互规则 |
|------|----------|----------|
| 1 | 页面首次加载 | 默认以明细视图加载第1页数据按单据日期降序排列 |
| 2 | 搜索操作 | 点击搜索按钮重置pageNum=1保持当前pageSize不变 |
| 3 | 单据编码点击 | 点击单据编码列蓝色链接文字,路由跳转到查看页面 |
| 4 | 状态标签 | 用el-tag组件渲染开立=info(灰), 审核=success(绿), 退回=warning(橙) |
| 5 | 空数据状态 | 列表无数据时显示空状态图标和"暂无数据"文字 |
| 6 | 视图切换 | 切换视图时保留搜索条件中的公共字段(单据编码、物料编码、物料名称、日期范围),清空视图特有字段 |
### 7.2 明细视图特有交互
| 序号 | 交互场景 | 交互规则 |
|------|----------|----------|
| 1 | 物料分类筛选 | 选择物料分类下拉后,列表自动按该分类过滤 |
| 2 | 无批量操作 | 明细视图无复选框,不支持批量选择和批量操作 |
| 3 | 多阶操作 | 点击某行「多阶」→ 弹出多阶BOM展开弹窗树形展示层次结构 |
| 4 | 翻单操作 | 点击某行「翻单」→ 确认弹窗 → 后端复制BOM → 成功后刷新列表提示新BOM编码和版本号 |
| 5 | 行级导出 | 点击某行「导出」→ 直接下载该BOM的物料明细Excel文件 |
| 6 | 导入操作 | 点击工具栏「导入」→ 打开文件选择弹窗 → 选择Excel → 上传解析 → 成功后刷新列表 |
### 7.3 单据视图特有交互
| 序号 | 交互场景 | 交互规则 |
|------|----------|----------|
| 1 | 批量选择 | 复选框勾选多条记录后,批量操作按钮(删/审核/反审核)启用;未勾选时置灰 |
| 2 | 操作列动态显隐 | 根据status动态渲染操作按钮审核状态显示查看+翻单;开立/退回状态显示查看+编辑+删除 |
| 3 | 单条删除 | 点击行操作列「删除」→ 确认弹窗 → 调用删除接口 → 刷新列表 |
| 4 | 批量删除 | 勾选记录 → 点击工具栏「删」→ 校验状态 → 确认弹窗 → 调用删除接口 |
| 5 | 批量审核 | 勾选记录 → 点击工具栏「审核」→ 校验状态和明细 → 确认弹窗 → 调用审核接口 |
| 6 | 批量反审核 | 勾选记录 → 点击工具栏「反审核」→ 校验状态和下游引用 → 确认弹窗 → 调用反审核接口 |
### 7.2 新增/编辑页交互
| 序号 | 交互场景 | 交互规则 |
|------|----------|----------|
| 1 | 页面加载(新增) | 自动填充:单据编码(调接口获取)、单据日期(当天)、操作员(当前用户)、版本号(1.0)、母件基数(1.0)、单据状态(开立)、业务状态(正常) |
| 2 | 页面加载(编辑) | 调用详情接口加载BOM表头和明细数据 |
| 3 | 选择母件物料 | 点击物料编码旁「选择」按钮 → 打开物料选择弹窗 → 选中后自动填充:物料编码、物料名称、计量单位 |
| 4 | 版本号调整 | 通过 -/+ 按钮调整步长0.1最小值1.0 |
| 5 | 新增物料行 | 点击「+ 新增物料」→ 子表末尾新增空行 → 行内点击物料编码「选择」→ 弹窗选择子件物料 |
| 6 | 选择子件物料 | 弹窗选择后自动填充:物料编码、物料名称、型号规格、主计量、供应方式 |
| 7 | 删除物料行 | 点击行操作列「删除」→ 确认弹窗 → 确认后删除该行,重新编号 |
| 8 | 保存操作 | 前端表单校验 → 校验通过调用保存接口 → 成功提示 → 页面变为编辑模式 |
| 9 | 审核操作 | 需先保存 → 确认弹窗 → 调用审核接口 → 成功后页面变只读 |
| 10 | 反审核操作 | 确认弹窗 → 调用反审核接口 → 成功后页面变可编辑 |
| 11 | 表头折叠 | 点击「收起」→ 表头表单区域收起,仅显示物料明细;点击「展开」→ 恢复 |
| 12 | 离开页面 | 有未保存修改时,触发 `beforeRouteLeave` 提示确认 |
### 7.3 表单校验规则
#### 表头校验
| 字段 | 规则 | 提示信息 |
|------|------|----------|
| bomCode | 必填 | 单据编码不能为空 |
| bomDate | 必填 | 单据日期不能为空 |
| businessType | 必填 | 业务类型不能为空 |
| itemCode | 必填 | 请选择产品物料 |
| version | 必填min=1.0 | 版本号不能为空 |
| baseQty | 必填min=0.0001 | 母件基数必须大于0 |
#### 明细校验
| 字段 | 规则 | 提示信息 |
|------|------|----------|
| bomItemCode | 必填 | 请选择子件物料 |
| numerator | 必填min=0.000001 | 分子数量必须大于0 |
| pickType | 必填 | 请选择领料方式 |
| usageType | 必填 | 请选择用量方式 |
#### 业务校验
| 规则 | 说明 |
|------|------|
| 子件不能等于母件 | 不允许添加与母件相同的物料作为子件 |
| 子件不能重复 | 同一BOM中不允许出现重复的子件物料 |
| 至少一行明细 | 保存时至少要有一条物料明细 |
| 循环检测 | 保存/审核时后端校验不能存在BOM循环引用 |
---
## 8. 接口调用说明
### 8.1 接口总览
| 序号 | 功能 | 方法 | 路径 | 说明 |
|------|------|------|------|------|
| 1 | 查询BOM列表 | GET | /rd/ebom/list | 分页查询EBOM列表 |
| 2 | 获取BOM详情 | GET | /rd/ebom/{bomId} | 获取单条BOM表头+明细 |
| 3 | 新增BOM | POST | /rd/ebom | 创建新BOM |
| 4 | 修改BOM | PUT | /rd/ebom | 更新BOM表头+明细 |
| 5 | 删除BOM | DELETE | /rd/ebom/{bomIds} | 批量删除BOM |
| 6 | 审核BOM | PUT | /rd/ebom/approve/{bomId} | 审核单据 |
| 7 | 反审核BOM | PUT | /rd/ebom/unapprove/{bomId} | 反审核单据 |
| 8 | 获取BOM编码 | GET | /rd/ebom/genCode | 生成新的BOM编码 |
| 9 | BOM校验 | POST | /rd/ebom/check/{bomId} | 循环引用校验 |
| 10 | BOM多阶展开 | GET | /rd/ebom/expand/{bomId} | 多层BOM展开 |
| 11 | BOM翻单 | POST | /rd/ebom/copy/{bomId} | 复制BOM生成新版本 |
| 12 | BOM导出 | GET | /rd/ebom/export | 导出BOM清单 |
| 13 | 选择物料 | GET | /md/item/list | 物料选择弹窗数据 |
| 14 | 物料分类树 | GET | /md/itemtype/treeselect | 物料分类树形数据 |
### 8.2 接口详细说明
#### 8.2.1 查询BOM列表
```
GET /rd/ebom/list
```
**请求参数:**
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| pageNum | integer | 否 | 页码默认1 |
| pageSize | integer | 否 | 每页数默认100 |
| bomCode | string | 否 | 单据编码(模糊) |
| itemCode | string | 否 | 物料编码(模糊) |
| itemName | string | 否 | 物料名称(模糊) |
| status | string | 否 | 单据状态 |
| businessStatus | string | 否 | 业务状态 |
| beginDate | string | 否 | 开始日期 (yyyy-MM-dd) |
| endDate | string | 否 | 结束日期 (yyyy-MM-dd) |
| workType | integer | 否 | 工作类型0=研发BOM |
**响应示例:**
```json
{
"total": 126,
"rows": [
{
"bomId": 777,
"bomCode": "EBOM000777",
"bomDate": "2026-01-29",
"status": "APPROVED",
"businessType": "机械BOM",
"itemId": 100,
"itemCode": "CP001",
"itemName": "减速器总成",
"unitName": "台",
"version": "1.0",
"baseQty": 1.0,
"deptName": "",
"operatorName": "admin",
"businessStatus": "正常",
"approveDate": "2026-01-29",
"approverName": "admin"
}
],
"code": 200,
"msg": "查询成功"
}
```
#### 8.2.2 获取BOM详情
```
GET /rd/ebom/{bomId}
```
**路径参数:**
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| bomId | integer | 是 | BOM ID |
**响应示例:**
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"bomId": 777,
"bomCode": "EBOM000777",
"bomDate": "2026-01-29",
"status": "APPROVED",
"businessType": "MECHANICAL",
"itemId": 100,
"itemCode": "CP001",
"itemName": "减速器总成",
"specification": "RV-110",
"unitName": "台",
"version": "1.0",
"versionDesc": "",
"baseQty": 1.0,
"drawingNo": "DWG-CP001",
"operatorId": 1,
"operatorName": "admin",
"businessStatus": "NORMAL",
"approveDate": "2026-01-29",
"approverName": "admin",
"remark": "",
"lines": [
{
"lineId": 1001,
"bomId": 777,
"lineNo": 1,
"bomItemId": 201,
"bomItemCode": "LJ001",
"bomItemName": "主轴",
"specification": "φ25×200",
"unitName": "根",
"numerator": 1.0,
"denominator": 1.0,
"supplyType": "SELF_MADE",
"pickType": "ORDER_PICK",
"usageType": "RATIO",
"lossRate": 0,
"routeName": "",
"drawingNo": "",
"remark": ""
},
{
"lineId": 1002,
"bomId": 777,
"lineNo": 2,
"bomItemId": 202,
"bomItemCode": "WL001",
"bomItemName": "轴承6205",
"specification": "25×52×15",
"unitName": "个",
"numerator": 2.0,
"denominator": 1.0,
"supplyType": "PURCHASE",
"pickType": "ORDER_PICK",
"usageType": "RATIO",
"lossRate": 2.00,
"routeName": "",
"drawingNo": "",
"remark": ""
}
]
}
}
```
#### 8.2.3 新增BOM
```
POST /rd/ebom
```
**请求体:**
```json
{
"bomCode": "EBOM000778",
"bomDate": "2026-02-06",
"businessType": "MECHANICAL",
"itemId": 100,
"itemCode": "CP001",
"itemName": "减速器总成",
"unitName": "台",
"version": "1.0",
"versionDesc": "初始版本",
"baseQty": 1.0,
"drawingNo": "DWG-CP001",
"businessStatus": "NORMAL",
"remark": "",
"lines": [
{
"lineNo": 1,
"bomItemId": 201,
"bomItemCode": "LJ001",
"bomItemName": "主轴",
"specification": "φ25×200",
"unitName": "根",
"numerator": 1.0,
"supplyType": "SELF_MADE",
"pickType": "ORDER_PICK",
"usageType": "RATIO"
}
]
}
```
**响应:**
```json
{
"code": 200,
"msg": "新增成功",
"data": {
"bomId": 778
}
}
```
#### 8.2.4 修改BOM
```
PUT /rd/ebom
```
**请求体:** 同新增,但包含 `bomId` 和各明细行的 `lineId`
**注意:** 修改时采用全量提交策略后端根据lineId判断新增/修改/删除:
- 无lineId的行 → 新增
- 有lineId的行 → 修改
- 请求中不存在的lineId → 删除
#### 8.2.5 删除BOM
```
DELETE /rd/ebom/{bomIds}
```
**路径参数:**
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| bomIds | string | 是 | BOM ID多个用逗号分隔 |
**业务规则:**
- 仅允许删除开立(DRAFT)状态的BOM
- 删除时同时删除明细行记录
- 逻辑删除del_flag = 1
#### 8.2.6 审核BOM
```
PUT /rd/ebom/approve/{bomId}
```
**业务规则:**
- 仅开立(DRAFT)状态允许审核
- 至少有一条物料明细
- 审核后自动填充审核员和审核日期
- status → APPROVED
#### 8.2.7 反审核BOM
```
PUT /rd/ebom/unapprove/{bomId}
```
**业务规则:**
- 仅审核(APPROVED)状态允许反审核
- 需校验该BOM未被生产计划等下游业务引用
- 反审核后清空审核员和审核日期
- status → DRAFT
#### 8.2.8 BOM翻单复制新版本
```
POST /rd/ebom/copy/{bomId}
```
**业务规则:**
- 基于原BOM复制生成新单据
- 新BOM编码自动生成
- 版本号自动+1如1.0 → 2.0
- 新BOM状态为开立(DRAFT)
- 物料明细完全复制
**响应:**
```json
{
"code": 200,
"msg": "翻单成功",
"data": {
"bomId": 779,
"bomCode": "EBOM000779",
"version": "2.0"
}
}
```
#### 8.2.9 BOM多阶展开
```
GET /rd/ebom/expand/{bomId}
```
**响应:** 返回树形结构展示多层BOM层次关系。
```json
{
"code": 200,
"data": {
"bomId": 777,
"itemCode": "CP001",
"itemName": "减速器总成",
"children": [
{
"itemCode": "LJ001",
"itemName": "主轴",
"quantity": 1.0,
"level": 1,
"children": []
},
{
"itemCode": "ZJ001",
"itemName": "齿轮组件",
"quantity": 1.0,
"level": 1,
"children": [
{
"itemCode": "WL002",
"itemName": "大齿轮",
"quantity": 1.0,
"level": 2,
"children": []
}
]
}
]
}
}
```
#### 8.2.10 BOM校验
```
POST /rd/ebom/check/{bomId}
```
**功能:** 校验BOM是否存在循环引用死循环嵌套
**响应:**
```json
{
"code": 200,
"msg": "校验通过BOM结构正常"
}
```
或错误情况:
```json
{
"code": 500,
"msg": "检测到BOM循环引用: CP001 → ZJ001 → CP001"
}
```
#### 8.2.11 BOM导出
```
GET /rd/ebom/export
```
**请求参数:** 同查询列表参数。
**响应:** 返回Excel文件流 (application/vnd.openxmlformats-officedocument.spreadsheetml.sheet)
#### 8.2.12 物料选择接口
```
GET /md/item/list
```
**请求参数:**
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| pageNum | integer | 否 | 页码 |
| pageSize | integer | 否 | 每页数 |
| itemCode | string | 否 | 物料编码(模糊) |
| itemName | string | 否 | 物料名称(模糊) |
| itemTypeId | integer | 否 | 物料分类ID |
| supplyType | string | 否 | 供应方式筛选 |
#### 8.2.13 物料分类树
```
GET /md/itemtype/treeselect
```
**响应:** 返回物料分类的树形结构,用于物料选择弹窗的左侧分类树。
---
## 9. 状态流转
### 9.1 单据状态流转图
```
┌──────────────┐
│ │
┌─────────► 开立(DRAFT) ◄──────────┐
│ │ │ │
│ └──────┬───────┘ │
│ │ │
│ [审核操作] [反审核操作]
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ │ │
[反审核未通过] │ 审核(APPROVED)├───────────┘
│ │ │
│ └──────┬───────┘
│ │
│ [不可直接到退回]
│ │
│ ▼
│ ┌──────────────┐
└──────────┤ │
│ 退回(REJECTED)│
│ │
└──────────────┘
```
### 9.2 状态说明
| 状态 | 编码 | 可执行操作 | 说明 |
|------|------|-----------|------|
| 开立 | DRAFT | 编辑、保存、删除、审核 | 初始状态,可自由编辑 |
| 审核 | APPROVED | 查看、反审核、翻单、多阶展开、校验、导出 | 生效状态,不可编辑 |
| 退回 | REJECTED | 编辑、保存、审核 | 退回后可重新编辑提交 |
---
## 10. 业务规则
### 10.1 编码规则
| 规则 | 说明 |
|------|------|
| 前缀 | EBOM |
| 流水号 | 6位数字不足补零 |
| 格式 | EBOM000001, EBOM000002, ... |
| 生成方式 | 后端自动生成,不可手动修改 |
### 10.2 版本管理规则
| 规则 | 说明 |
|------|------|
| 默认版本 | 新建BOM默认版本号为 1.0 |
| 翻单版本 | 翻单时自动在原版本基础上 +11.0 → 2.0 |
| 版本范围 | 最小1.0步长0.1 |
| 同产品多版本 | 允许同一产品存在多个版本的BOM |
| 默认BOM | 最新审核版本为该产品的默认BOM |
### 10.3 BOM建立规则
| 规则 | 说明 |
|------|------|
| 母件条件 | 只有供应方式为「生产」「加工」「委外」的物料才能作为母件建BOM |
| 子件条件 | 所有物料均可作为子件 |
| 循环校验 | A的BOM中不能直接或间接包含A本身 |
| 重复校验 | 同一BOM中不允许出现相同的子件 |
| 最小行数 | BOM至少包含1条明细行 |
| 删除关联 | 删除BOM时同步删除所有明细行 |
### 10.4 下游引用规则
| 引用场景 | 影响 |
|----------|------|
| 被生产计划引用 | 不允许反审核、不允许删除 |
| 被生产订单引用 | 不允许反审核、不允许删除 |
| 未被任何引用 | 可以反审核、可以删除仅DRAFT状态 |
---
## 11. 前端组件设计
### 11.1 文件结构
```
src/
├── api/
│ └── rd/
│ └── ebom.js # EBOM相关API接口定义
├── views/
│ └── rd/
│ └── ebom/
│ ├── index.vue # EBOM列表页含明细视图+单据视图切换)
│ ├── add.vue # EBOM新增页
│ ├── edit.vue # EBOM编辑页
│ └── components/
│ ├── DetailViewTable.vue # 明细视图表格组件
│ ├── DocumentViewTable.vue # 单据视图表格组件
│ ├── BomHeaderForm.vue # 表头表单组件
│ ├── BomLineTable.vue # 物料明细表格组件(可编辑子表)
│ ├── ItemSelectDialog.vue # 物料选择弹窗组件(含分类树)
│ ├── BomTreeDialog.vue # BOM多阶展开弹窗组件
│ └── ImportDialog.vue # BOM导入弹窗组件
```
### 11.2 API接口文件
```javascript
// src/api/rd/ebom.js
import request from '@/utils/request'
// 查询EBOM列表
export function listEbom(query) {
return request({
url: '/rd/ebom/list',
method: 'get',
params: query
})
}
// 获取EBOM详情
export function getEbom(bomId) {
return request({
url: '/rd/ebom/' + bomId,
method: 'get'
})
}
// 新增EBOM
export function addEbom(data) {
return request({
url: '/rd/ebom',
method: 'post',
data: data
})
}
// 修改EBOM
export function updateEbom(data) {
return request({
url: '/rd/ebom',
method: 'put',
data: data
})
}
// 删除EBOM
export function delEbom(bomIds) {
return request({
url: '/rd/ebom/' + bomIds,
method: 'delete'
})
}
// 审核EBOM
export function approveEbom(bomId) {
return request({
url: '/rd/ebom/approve/' + bomId,
method: 'put'
})
}
// 反审核EBOM
export function unapproveEbom(bomId) {
return request({
url: '/rd/ebom/unapprove/' + bomId,
method: 'put'
})
}
// 获取BOM编码
export function genBomCode() {
return request({
url: '/rd/ebom/genCode',
method: 'get'
})
}
// BOM校验
export function checkEbom(bomId) {
return request({
url: '/rd/ebom/check/' + bomId,
method: 'post'
})
}
// BOM多阶展开
export function expandEbom(bomId) {
return request({
url: '/rd/ebom/expand/' + bomId,
method: 'get'
})
}
// BOM翻单
export function copyEbom(bomId) {
return request({
url: '/rd/ebom/copy/' + bomId,
method: 'post'
})
}
// 导出EBOM
export function exportEbom(query) {
return request({
url: '/rd/ebom/export',
method: 'get',
params: query,
responseType: 'blob'
})
}
```
### 11.3 路由配置
```javascript
// src/router/modules/rd.js
{
path: '/rd',
component: Layout,
redirect: '/rd/develop/ebom',
name: 'Rd',
meta: { title: '研发管理', icon: 'el-icon-document' },
children: [
{
path: 'develop/ebom',
name: 'Ebom',
component: () => import('@/views/rd/ebom/index'),
meta: { title: '产品BOM', icon: 'el-icon-tickets' }
},
{
path: 'develop/ebom/add',
name: 'EbomAdd',
component: () => import('@/views/rd/ebom/add'),
meta: { title: '新增EBOM', activeMenu: '/rd/develop/ebom' },
hidden: true
},
{
path: 'develop/ebom/edit/:bomId',
name: 'EbomEdit',
component: () => import('@/views/rd/ebom/edit'),
meta: { title: '编辑EBOM', activeMenu: '/rd/develop/ebom' },
hidden: true
}
]
}
```
### 11.4 关键组件规范
#### 列表页核心结构(含双视图切换)
```vue
<!-- src/views/rd/ebom/index.vue -->
<template>
<div class="app-container">
<!-- 搜索区域 - 根据视图模式动态渲染 -->
<el-form :model="queryParams" ref="queryForm" :inline="true">
<el-form-item label="单据编码" prop="bomCode">
<el-input v-model="queryParams.bomCode" placeholder="请输入" clearable />
</el-form-item>
<el-form-item label="物料编码" prop="itemCode">
<el-input v-model="queryParams.itemCode" placeholder="请输入" clearable />
</el-form-item>
<el-form-item label="物料名称" prop="itemName">
<el-input v-model="queryParams.itemName" placeholder="请输入" clearable />
</el-form-item>
<!-- 明细视图特有: 物料分类 -->
<el-form-item v-if="viewMode === 'detail'" label="物料分类" prop="itemTypeId">
<el-select v-model="queryParams.itemTypeId" placeholder="请选择" clearable />
</el-form-item>
<!-- 单据视图特有: 单据状态业务状态 -->
<el-form-item v-if="viewMode === 'document'" label="单据状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择" clearable />
</el-form-item>
<el-form-item v-if="viewMode === 'document'" label="业务状态" prop="businessStatus">
<el-select v-model="queryParams.businessStatus" placeholder="请选择" clearable />
</el-form-item>
<!-- 公共: 日期范围 + 搜索 -->
<el-form-item label="开始日期" prop="startDate">
<el-date-picker v-model="queryParams.startDate" type="date" placeholder="选择日期" />
</el-form-item>
<el-form-item label="结束日期" prop="endDate">
<el-date-picker v-model="queryParams.endDate" type="date" placeholder="选择日期" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
</el-form-item>
</el-form>
<!-- 工具栏 - 根据视图模式动态渲染 -->
<el-row :gutter="10" class="mb8">
<!-- 明细视图工具栏 -->
<template v-if="viewMode === 'detail'">
<el-col :span="1.5">
<el-button type="primary" @click="switchView('document')">单据</el-button>
</el-col>
<el-col :span="1.5"><el-button @click="handleQueryAll">查询所有</el-button></el-col>
<el-col :span="1.5"><el-button type="success" icon="el-icon-plus" @click="handleAdd">新增</el-button></el-col>
<el-col :span="1.5"><el-button type="warning" @click="handleClear">清空</el-button></el-col>
<el-col :span="1.5"><el-button icon="el-icon-upload2" @click="handleImport">导入</el-button></el-col>
<el-col :span="1.5"><el-button icon="el-icon-download" @click="handleExport">导出</el-button></el-col>
</template>
<!-- 单据视图工具栏 -->
<template v-else>
<el-col :span="1.5">
<el-button type="primary" @click="switchView('detail')">明细</el-button>
</el-col>
<el-col :span="1.5"><el-button @click="handleQueryAll">查询所有</el-button></el-col>
<el-col :span="1.5"><el-button type="success" icon="el-icon-plus" @click="handleAdd">新增</el-button></el-col>
<el-col :span="1.5"><el-button type="danger" :disabled="multiple" @click="handleDelete"></el-button></el-col>
<el-col :span="1.5"><el-button type="primary" :disabled="multiple" @click="handleApprove">审核</el-button></el-col>
<el-col :span="1.5"><el-button :disabled="multiple" @click="handleUnapprove">反审核</el-button></el-col>
</template>
</el-row>
<!-- 明细视图表格 -->
<el-table v-if="viewMode === 'detail'" v-loading="loading" :data="bomList">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column label="单据编码" prop="bomCode" width="140">
<template slot-scope="scope">
<el-link type="primary" @click="handleView(scope.row)">{{ scope.row.bomCode }}</el-link>
</template>
</el-table-column>
<el-table-column label="物料编码" prop="itemCode" width="140" />
<el-table-column label="物料名称" prop="itemName" min-width="200" />
<el-table-column label="母件基数" prop="baseQty" width="80" align="center" />
<el-table-column label="版本号" prop="version" width="80" align="center" />
<el-table-column label="版本说明" prop="versionDesc" width="120" />
<el-table-column label="图纸号" prop="drawingNo" width="100" />
<el-table-column label="单据状态" prop="status" width="80" align="center">
<template slot-scope="scope">
<el-tag :type="statusTagType(scope.row.status)" size="small">{{ statusLabel(scope.row.status) }}</el-tag>
</template>
</el-table-column>
<el-table-column label="单据日期" prop="bomDate" width="100" align="center" />
<el-table-column label="操作" width="140" align="center">
<template slot-scope="scope">
<el-button size="mini" type="text" @click="handleExpand(scope.row)">多阶</el-button>
<el-button size="mini" type="text" style="color:#67C23A" @click="handleCopy(scope.row)">翻单</el-button>
<el-button size="mini" type="text" style="color:#E6A23C" @click="handleExportRow(scope.row)">导出</el-button>
</template>
</el-table-column>
</el-table>
<!-- 单据视图表格 -->
<el-table v-else v-loading="loading" :data="bomList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="单据编码" prop="bomCode" width="140">
<template slot-scope="scope">
<el-link type="primary" @click="handleView(scope.row)">{{ scope.row.bomCode }}</el-link>
</template>
</el-table-column>
<el-table-column label="单据日期" prop="bomDate" width="120" align="center" sortable />
<el-table-column label="单据状态" prop="status" width="80" align="center">
<template slot-scope="scope">
<el-tag :type="statusTagType(scope.row.status)" size="small">{{ statusLabel(scope.row.status) }}</el-tag>
</template>
</el-table-column>
<el-table-column label="业务类型" prop="businessType" width="100" align="center" />
<el-table-column label="业务部门" prop="deptName" width="100" align="center" />
<el-table-column label="业务人员" prop="operatorName" width="100" align="center" />
<el-table-column label="业务状态" prop="businessStatus" width="80" align="center" />
<el-table-column label="审核日期" prop="approveDate" width="120" align="center" />
<el-table-column label="操作" width="160" align="center">
<template slot-scope="scope">
<el-button size="mini" type="text" style="color:#67C23A" @click="handleView(scope.row)">查看</el-button>
<template v-if="scope.row.status === 'APPROVED'">
<el-button size="mini" type="text" @click="handleCopy(scope.row)">翻单</el-button>
</template>
<template v-else>
<el-button size="mini" type="text" @click="handleEdit(scope.row)">编辑</el-button>
<el-button size="mini" type="text" style="color:#F56C6C" @click="handleDelete(scope.row)">删除</el-button>
</template>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
</div>
</template>
<script>
export default {
data() {
return {
viewMode: 'detail', // 'detail' | 'document'
// ...其他数据
}
},
methods: {
switchView(mode) {
this.viewMode = mode
this.resetQuery()
this.getList()
},
// ...其他方法
}
}
</script>
```
---
## 12. 数据模型
### 12.1 表关系图
```
┌──────────────────────────┐
│ erp_md_item_type │
│ (物料分类) │
└──────────┬───────────────┘
│ 1:N
┌──────────────────────────┐ ┌──────────────────────────┐
│ erp_md_bom │ │ erp_md_item │
│ (BOM表头/EBOM) │◄─┤ (物料档案) │
│ │ │ │
│ bom_id (PK) │ │ item_id (PK) │
│ bom_code (UK) │ │ item_code │
│ item_id (FK) ────────────┼──┤ item_name │
│ item_code │ │ default_bom_id (FK) ─────┼──► bom_id
│ item_name │ │ supply_type │
│ version │ └──────────────────────────┘
│ status │
│ base_qty │
└──────────┬───────────────┘
│ 1:N
┌──────────────────────────┐
│ erp_md_bom_line │
│ (BOM明细/子件清单) │
│ │
│ line_id (PK) │
│ bom_id (FK) ─────────────┼──► erp_md_bom.bom_id
│ item_id (FK) ────────────┼──► erp_md_item.item_id (子件物料)
│ line_no │
│ base_qty (用量) │
│ supply_type │
│ loss_rate │
└──────────────────────────┘
```
### 12.2 MOM系统表映射
| ERP表名 | MOM表名 | 说明 |
|---------|---------|------|
| erp_md_bom | md_bom | BOM表头 |
| erp_md_bom_line | md_product_bom | BOM明细 |
| erp_md_item | md_item | 物料档案 |
| erp_md_item_type | md_item_type | 物料分类 |
### 12.3 数据同步方向
```
ERP (erp_md_bom) ──同步──► MOM (md_bom)
ERP (erp_md_bom_line) ──同步──► MOM (md_product_bom)
```
- 同步方向: ERP → MOM单向同步
- 同步频率: 实时/准实时
- 同步触发: BOM审核后触发数据同步
---
## 附录A: 状态标签颜色映射
```javascript
// 状态标签类型映射
const statusTagMap = {
'DRAFT': 'info', // 灰色 - 开立
'APPROVED': 'success', // 绿色 - 审核
'REJECTED': 'warning' // 橙色 - 退回
}
// 状态标签文字映射
const statusLabelMap = {
'DRAFT': '开立',
'APPROVED': '审核',
'REJECTED': '退回'
}
// 业务状态映射
const businessStatusMap = {
'NORMAL': '正常',
'PAUSE': '暂停',
'CANCEL': '取消'
}
```
---
## 附录B: 权限标识汇总
| 权限标识 | 说明 | 对应操作 | 所属视图 |
|----------|------|----------|----------|
| rd:ebom:list | 列表查询 | 查看BOM列表、视图切换 | 通用 |
| rd:ebom:query | 详情查询 | 查看BOM详情 | 单据视图 |
| rd:ebom:add | 新增 | 新增BOM | 通用 |
| rd:ebom:edit | 编辑 | 修改BOM | 单据视图 |
| rd:ebom:remove | 删除 | 删除BOM、清空 | 单据视图/明细视图 |
| rd:ebom:approve | 审核 | 审核BOM | 单据视图 |
| rd:ebom:unapprove | 反审核 | 反审核BOM | 单据视图 |
| rd:ebom:export | 导出 | 导出BOM列表/单条BOM | 明细视图 |
| rd:ebom:import | 导入 | 导入BOM数据 | 明细视图 |
| rd:ebom:expand | 多阶展开 | 多层BOM结构展开 | 明细视图 |
| rd:ebom:copy | 翻单 | 复制BOM生成新版本 | 明细视图/单据视图 |
---
## 附录C: 参考截图说明
| 截图文件 | 说明 |
|----------|------|
| `docs/ui-make/rsun-产品bom列表-明细视图.png` | 列表页明细视图:序号列、物料编码/名称/版本号等字段、操作列(多阶/翻单/导出) |
| `docs/ui-make/rsun-产品bom列表-单据视图.png` | 列表页单据视图:复选框列、单据日期/状态/业务类型等字段、操作列(查看/编辑/删除) |
| `docs/ui-make/rsun-产品bom新增-1.png` | 新增页空白表单状态,展示表头字段布局和物料明细空行 |
| `docs/ui-make/rsun-产品bom新增-2.png` | 新增页已填写数据,展示物料编码选择后的自动填充效果 |
| `docs/ui-make/rsun-产品bom新增-物料编码选择弹窗.png` | 选择物料弹窗:左侧分类树、搜索区、物料列表(含供应方式列) |
---
## 修订历史
| 版本 | 日期 | 修订内容 | 修订人 |
|------|------|----------|--------|
| 1.0.0 | 2026-02-06 | 初始版本,完整页面设计开发说明 | System |
| 1.1.0 | 2026-02-06 | 补充列表页双视图(明细视图/单据视图)设计说明,更新物料选择弹窗详细设计 | System |