1. 新增物料详情页路由、菜单与接口,支持查看物料报价与信息 2. 重构物料列表页面,新增品牌筛选、表格样式优化与详情跳转 3. 扩展物料实体与数据库字段,新增材质、用途、性能参数等字段 4. 新增供应商/甲方报价查询、批量对比、同名称物料匹配接口 5. 新增物料详情组件,包含基础信息、供应商报价、甲方报价标签页 6. 修复比价路由跳转路径错误,调整数据库密码配置 7. 新增物料相关SQL脚本与初始化数据
869 lines
41 KiB
Markdown
869 lines
41 KiB
Markdown
# 智采系统-物料信息模块开发文档
|
||
|
||
> 文档版本: v1.1
|
||
> 创建日期: 2025-05-27
|
||
> 关联文档: [福安德智慧报价平台-完整开发方案.md](./福安德智慧报价平台-完整开发方案.md)
|
||
|
||
---
|
||
|
||
## 一、需求概述
|
||
|
||
### 1.1 功能定位
|
||
智采系统-物料信息模块是整个报价平台的基础数据层,负责管理所有物料的基础信息、性能参数、历史报价记录。
|
||
|
||
### 1.2 核心功能
|
||
- **物料信息管理**: 挂载于物料类型下,支持汇总和CRUD操作
|
||
- **物料详情展示**: 基础信息展示,支持动态更新
|
||
- **历史报价查询**:
|
||
- 供应商历史报价清单(单价、供应商)
|
||
- 我方给甲方的历史报价
|
||
|
||
### 1.3 字段需求
|
||
根据业务需求,物料信息需要以下字段:
|
||
|
||
| 需求字段 | 对应数据库字段 | 说明 |
|
||
|---------|--------------|------|
|
||
| 物料ID | material_id | 主键,自增 |
|
||
| **厂家/品牌** | **brand** | **改为"厂家/品牌"** |
|
||
| 规格型号 | spec | 规格型号(**保持不变**) |
|
||
| 性能参数 | performance_params | JSON格式存储(**新增**) |
|
||
| 材质 | material | 材质(铜/铝合金/PVC等)(**新增**) |
|
||
| 用途 | purpose | 用途描述(**新增**) |
|
||
| 备注 | remark | 备注(**保持不变**) |
|
||
|
||
---
|
||
|
||
## 二、数据库设计
|
||
|
||
### 2.1 现有表结构(保持不变)
|
||
|
||
```sql
|
||
CREATE TABLE `biz_material` (
|
||
`material_id` bigint NOT NULL AUTO_INCREMENT,
|
||
`tenant_id` bigint NOT NULL DEFAULT '1',
|
||
`category_id` bigint DEFAULT '0',
|
||
`material_code` varchar(50) NOT NULL COMMENT '物料编码',
|
||
`material_name` varchar(200) NOT NULL COMMENT '物料名称',
|
||
`spec` varchar(500) DEFAULT '' COMMENT '规格型号',
|
||
`unit` varchar(50) DEFAULT '' COMMENT '单位',
|
||
`brand` varchar(100) DEFAULT '' COMMENT '品牌',
|
||
`description` text COMMENT '描述',
|
||
`status` char(1) DEFAULT '0',
|
||
`create_by` varchar(64) DEFAULT '',
|
||
`create_time` datetime DEFAULT NULL,
|
||
`update_by` varchar(64) DEFAULT '',
|
||
`update_time` datetime DEFAULT NULL,
|
||
`remark` varchar(500) DEFAULT NULL,
|
||
PRIMARY KEY (`material_id`)
|
||
) ENGINE=InnoDB COMMENT='物料';
|
||
```
|
||
|
||
### 2.2 扩展字段
|
||
|
||
执行SQL文件: [sql/20250527/01_material_alter.sql](../sql/20250527/01_material_alter.sql)
|
||
|
||
```sql
|
||
-- 新增字段
|
||
ALTER TABLE biz_material
|
||
ADD COLUMN IF NOT EXISTS performance_params TEXT COMMENT '性能参数(JSON)',
|
||
ADD COLUMN IF NOT EXISTS material VARCHAR(100) DEFAULT '' COMMENT '材质',
|
||
ADD COLUMN IF NOT EXISTS purpose VARCHAR(500) DEFAULT '' COMMENT '用途',
|
||
ADD COLUMN IF NOT EXISTS image_url VARCHAR(500) DEFAULT '' COMMENT '物料图片URL';
|
||
|
||
-- 修改brand字段为"厂家/品牌"
|
||
ALTER TABLE biz_material MODIFY COLUMN brand VARCHAR(100) COMMENT '厂家/品牌';
|
||
```
|
||
|
||
### 2.3 横向对比关系表
|
||
|
||
用于存储物料之间的对比关系(不同品牌、规格的同比信息):
|
||
|
||
```sql
|
||
CREATE TABLE biz_material_comparison (
|
||
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
|
||
tenant_id BIGINT NOT NULL DEFAULT 1 COMMENT '租户ID',
|
||
material_id BIGINT NOT NULL COMMENT '当前物料ID',
|
||
counterpart_id BIGINT NOT NULL COMMENT '对标物料ID',
|
||
comparison_type VARCHAR(50) DEFAULT 'same_spec' COMMENT '对比类型(same_spec:同规格, similar:相似规格)',
|
||
brand_level VARCHAR(50) COMMENT '品牌等级(国产一线/国产二线/进口一线/进口二线)',
|
||
sort_order INT DEFAULT 0 COMMENT '排序',
|
||
status CHAR(1) DEFAULT '0' COMMENT '状态(0正常 1停用)',
|
||
create_by VARCHAR(64) DEFAULT '' COMMENT '创建者',
|
||
create_time DATETIME COMMENT '创建时间',
|
||
update_by VARCHAR(64) DEFAULT '' COMMENT '更新者',
|
||
update_time DATETIME COMMENT '更新时间',
|
||
remark VARCHAR(500) COMMENT '备注',
|
||
UNIQUE KEY uk_material_counterpart (material_id, counterpart_id),
|
||
KEY idx_material (material_id),
|
||
KEY idx_counterpart (counterpart_id)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='物料横向对比关系';
|
||
```
|
||
|
||
**表设计说明**:
|
||
- 不采用"对比组"模式,而是直接建立物料之间的对比关系,更灵活
|
||
- 支持同规格对比和相似规格对比
|
||
- 可维护品牌等级,用于综合评分
|
||
- 通过唯一索引防止重复添加对标物料
|
||
|
||
### 2.3 字段对照说明
|
||
|
||
| 原字段 | 原含义 | 新含义 | 说明 |
|
||
|--------|--------|--------|------|
|
||
| spec | 规格型号 | **规格型号** | **保持不变** |
|
||
| **brand** | **品牌** | **厂家/品牌** | **修改注释** |
|
||
| remark | 备注 | **备注** | **保持不变** |
|
||
| performance_params | - | 性能参数 | 新增 |
|
||
| material | - | 材质 | 新增 |
|
||
| purpose | - | 用途 | 新增 |
|
||
| image_url | - | 物料图片URL | 新增 |
|
||
|
||
### 2.4 性能参数JSON规范
|
||
|
||
```json
|
||
// 变频器示例
|
||
{
|
||
"功率": "37kW",
|
||
"电压": "380V",
|
||
"电流": "72A",
|
||
"过载能力": "150%/60s",
|
||
"通讯接口": "RS485/PROFINET",
|
||
"防护等级": "IP20"
|
||
}
|
||
|
||
// 电缆示例
|
||
{
|
||
"芯数×截面": "3×70+1×35",
|
||
"额定电压": "0.6/1kV",
|
||
"外径": "42mm",
|
||
"载流量": "210A",
|
||
"护套材质": "PVC铠装"
|
||
}
|
||
|
||
// PLC示例
|
||
{
|
||
"CPU型号": "1515-2 PN",
|
||
"内存": "500KB",
|
||
"数字量输入": "1024",
|
||
"数字量输出": "1024",
|
||
"通讯接口": "PROFINET"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 三、页面设计
|
||
|
||
### 3.1 物料信息列表页
|
||
|
||
#### 3.1.1 页面布局
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 智采系统-物料信息 [返回首页] │
|
||
├─────────────────────────────────────────────────────────────┤
|
||
│ 挂载于物料类型下面的物料信息在此进行汇总和CRUD │
|
||
├─────────────────────────────────────────────────────────────┤
|
||
│ 搜索栏: [物料名称] [物料编码] [厂家/品牌] [分类] [搜索] [重置]│
|
||
├─────────────────────────────────────────────────────────────┤
|
||
│ [新增] [删除] [导入] [导出] │
|
||
├─────────────────────────────────────────────────────────────┤
|
||
│ □ | 物料ID | 厂家/品牌 | 规格型号 | 性能参数 | 材质 | 用途 | 操作 │
|
||
│ ───────────────────────────────────────────────────────── │
|
||
│ □ | M001 | 汇川 | MD500T37G | 37kW... | 铜 | 通用 | [详情][修改][删除] │
|
||
│ □ | M002 | 西门子 | G120 | 37kW... | 铝 | 风机 | [详情][修改][删除] │
|
||
├─────────────────────────────────────────────────────────────┤
|
||
│ 分页: 1 2 3 ... 10 │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
#### 3.1.2 表格字段
|
||
|
||
| 字段 | 宽度 | 对应字段 | 说明 |
|
||
|------|------|---------|------|
|
||
| 复选框 | 55px | - | 批量操作 |
|
||
| 物料ID | 100px | material_id | - |
|
||
| **厂家/品牌** | 120px | **brand** | **改为"厂家/品牌"** |
|
||
| **规格型号** | 150px | **spec** | **保持不变** |
|
||
| 性能参数 | 200px | performance_params | 截取显示 |
|
||
| 材质 | 80px | material | 新增 |
|
||
| 用途 | 150px | purpose | 新增 |
|
||
| 操作 | 180px | - | 详情/修改/删除 |
|
||
|
||
#### 3.1.3 操作按钮
|
||
|
||
- **详情**: 跳转到物料详情页
|
||
- **修改**: 打开编辑对话框
|
||
- **删除**: 删除物料(逻辑删除)
|
||
|
||
### 3.2 新增/编辑对话框
|
||
|
||
```
|
||
┌─────────────────────────────────────────┐
|
||
│ 新增物料 / 修改物料 │
|
||
├─────────────────────────────────────────┤
|
||
│ 物料编码* [________________] │
|
||
│ 物料名称* [________________] │
|
||
│ 所属分类 [下拉选择________] │
|
||
├─────────────────────────────────────────┤
|
||
│ 厂家/品牌* [________________] │ ← brand字段(改为"厂家/品牌")
|
||
│ 规格型号* [________________] │ ← spec字段(保持不变)
|
||
│ 备注 [________________] │ ← remark字段(保持不变)
|
||
│ 材质 [________________] │ ← material字段(新增)
|
||
│ 用途 [________________] │ ← purpose字段(新增)
|
||
├─────────────────────────────────────────┤
|
||
│ 性能参数 (动态表单) │
|
||
│ ┌─────────┬─────────┬───────┐ [添加] │
|
||
│ │ 参数名 │ 参数值 │ 单位 │ │
|
||
│ │ [功率] │ [37] │ [kW] │ [删除] │
|
||
│ │ [电压] │ [380] │ [V] │ [删除] │
|
||
│ └─────────┴─────────┴───────┘ │
|
||
├─────────────────────────────────────────┤
|
||
│ 描述 [多行文本框____________] │ ← description字段
|
||
├─────────────────────────────────────────┤
|
||
│ [取消] [确定] │
|
||
└─────────────────────────────────────────┘
|
||
```
|
||
|
||
### 3.3 物料详情页
|
||
|
||
#### 3.3.1 整体布局(重新设计)
|
||
|
||
页面分为上下两部分:
|
||
- **上半部分**: 可编辑的基础信息(物料编码、厂家/品牌、规格型号等 + 性能参数 + 描述)
|
||
- **下半部分**: Tab切换(供应商报价历史、甲方报价历史)
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||
│ 明纬/西门子 电源模块 24VDC/10A,输入85-264VAC,效率≥90% [返回列表] │
|
||
├─────────────────────────────────────────────────────────────────────────────┤
|
||
│ 基础信息 [编辑] [保存] [取消] │
|
||
├─────────────────────────────────────────────────────────────────────────────┤
|
||
│ ┌────────────┬────────────┬────────────┬────────────┬────────────┬────────┐│
|
||
│ │ 物料编码 │ M-EL-006 │ 厂家/品牌 │ 明纬/西门子│ 规格型号 │ 24VDC/10A...│
|
||
│ ├────────────┼────────────┼────────────┼────────────┼────────────┼────────┤│
|
||
│ │ 材质 │ - │ 用途 │ - │ 备注 │ - │
|
||
│ │ 单位 │ 台 │ 所属分类 │ 电源模块 │ │ │
|
||
│ └────────────┴────────────┴────────────┴────────────┴────────────┴────────┘│
|
||
├─────────────────────────────────────────────────────────────────────────────┤
|
||
│ 性能参数 [添加] │
|
||
│ ┌────────────────┬──────────────────────────────┬────────────────┬────────┐│
|
||
│ │ 参数名 │ 参数值 │ 单位 │ 操作 ││
|
||
│ ├────────────────┼──────────────────────────────┼────────────────┼────────┤│
|
||
│ │ 输出电压 │ 24VDC │ V │ [删除] ││
|
||
│ │ 输出电流 │ 10 │ A │ [删除] ││
|
||
│ │ ... │ ... │ ... │ ... ││
|
||
│ └────────────────┴──────────────────────────────┴────────────────┴────────┘│
|
||
├─────────────────────────────────────────────────────────────────────────────┤
|
||
│ 描述 │
|
||
│ ┌────────────────────────────────────────────────────────────────────────┐│
|
||
│ │ 明纬/西门子 电源模块 24VDC/10A,输入85-264VAC,效率≥90% ││
|
||
│ └────────────────────────────────────────────────────────────────────────┘│
|
||
├─────────────────────────────────────────────────────────────────────────────┤
|
||
│ [供应商报价历史] [甲方报价历史] │
|
||
├─────────────────────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ Tab 内容区域(报价历史表格) │
|
||
│ │
|
||
└─────────────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**布局说明**:
|
||
- **顶部标题栏**: 显示物料名称和规格型号,右侧返回按钮
|
||
- **基础信息区域**: 紧凑的网格布局,一行4个字段,可直接编辑
|
||
- **性能参数区域**: 表格形式展示,支持增删改
|
||
- **描述区域**: 文本区域展示,支持编辑
|
||
- **Tab区域**: 仅保留供应商报价历史和甲方报价历史两个Tab
|
||
|
||
**组件实现**: [detail.vue](../ruoyi-ui/src/views/bid/material/detail.vue)
|
||
|
||
**核心功能**:
|
||
1. **基础信息网格布局**: 紧凑的flex布局,一行显示多个字段
|
||
2. **实时编辑**: 点击"编辑"按钮,所有字段变为可编辑状态
|
||
3. **实时保存**: 点击"保存"调用API,更新本地数据,无需刷新页面
|
||
4. **性能参数表格**: 支持添加/删除参数
|
||
5. **描述区域**: 多行文本编辑
|
||
|
||
**数据结构**:
|
||
```javascript
|
||
// 表单数据
|
||
form: {
|
||
materialCode: 'M-EL-006',
|
||
materialName: '电源模块',
|
||
brand: '明纬/西门子',
|
||
spec: '24VDC/10A...',
|
||
unit: '台',
|
||
material: '',
|
||
purpose: '',
|
||
remark: '',
|
||
description: '明纬/西门子 电源模块...'
|
||
}
|
||
|
||
// 性能参数数据
|
||
perfParams: [
|
||
{ name: '输出电压', value: '24VDC', unit: 'V' },
|
||
{ name: '输出电流', value: '10', unit: 'A' }
|
||
]
|
||
```
|
||
|
||
**保存逻辑**:
|
||
```javascript
|
||
async handleSave() {
|
||
const saveData = {
|
||
materialId: this.materialId,
|
||
...this.form,
|
||
performanceParams: JSON.stringify(this.perfParams)
|
||
};
|
||
|
||
await updateMaterial(saveData);
|
||
this.$message.success("保存成功");
|
||
this.isEditing = false;
|
||
|
||
// 更新本地数据(无需刷新页面)
|
||
this.material = { ...this.material, ...saveData };
|
||
}
|
||
```
|
||
// ...
|
||
]
|
||
|
||
// 性能参数数据
|
||
perfParams: [
|
||
{ name: '输出电压', value: '24VDC', unit: 'V' },
|
||
{ name: '输出电流', value: '10', unit: 'A' },
|
||
// ...
|
||
]
|
||
|
||
// 描述数据
|
||
description: '明纬/西门子 电源模块 24VDC/10A...'
|
||
```
|
||
|
||
**保存逻辑**:
|
||
```javascript
|
||
async handleSave() {
|
||
const saveData = {
|
||
materialId: this.material.materialId,
|
||
materialCode: this.basicInfoData[0].value,
|
||
materialName: this.basicInfoData[1].value,
|
||
// ... 其他字段
|
||
performanceParams: JSON.stringify(this.perfParams),
|
||
description: this.description
|
||
};
|
||
|
||
await updateMaterial(saveData);
|
||
this.$message.success("保存成功");
|
||
this.isEditing = false;
|
||
|
||
// 更新本地数据(无需刷新页面)
|
||
this.$emit('update:material', { ...this.material, ...saveData });
|
||
}
|
||
```
|
||
|
||
#### 3.3.3 Tab 2: 供应商报价历史
|
||
|
||
供应商信息完整展示,调整列宽使内容在一行显示:
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────────────────────────┐
|
||
│ 供应商报价历史 [导出Excel] │
|
||
├─────────────────────────────────────────────────────────────────────────────────────────┤
|
||
│ 报价日期 │ 供应商信息 │ 单价(元) │ 数量 │ 交期 │ 状态 │
|
||
│ ───────────────────────────────────────────────────────────────────────────────────── │
|
||
│ 2026-05-20 │ 华顺达电子科技有限公司 │ ¥6,200.00 │ 5 │ 7天 │ [已中标] │
|
||
│ │ 联系人: 张经理 13800138000│ │ │ │ │
|
||
│ ───────────────────────────────────────────────────────────────────────────────────── │
|
||
│ 2026-05-18 │ 博远精密机械有限公司 │ ¥6,500.00 │ 5 │ 10天 │ [未中标] │
|
||
│ │ 联系人: 李工 13900139000 │ │ │ │ │
|
||
│ ───────────────────────────────────────────────────────────────────────────────────── │
|
||
│ 2026-05-15 │ 瑞达工控设备有限公司 │ ¥6,800.00 │ 5 │ 5天 │ [未中标] │
|
||
│ │ 联系人: 王总 13700137000 │ │ │ │ │
|
||
└─────────────────────────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**表格列宽配置**:
|
||
| 列名 | 宽度 | 说明 |
|
||
|------|------|------|
|
||
| 报价日期 | 100px | 日期格式:YYYY-MM-DD |
|
||
| 供应商信息 | 280px | 供应商名称+联系人+电话,完整一行展示 |
|
||
| 单价 | 120px | 右对齐,保留2位小数 |
|
||
| 数量 | 80px | 居中对齐 |
|
||
| 交期 | 80px | 居中对齐,带单位"天" |
|
||
| 状态 | 100px | 标签形式展示 |
|
||
|
||
**Vue组件实现**:
|
||
```vue
|
||
<template>
|
||
<div class="supplier-quote-tab">
|
||
<el-row :gutter="10" class="mb8">
|
||
<el-col :span="1.5">
|
||
<el-button type="warning" icon="el-icon-download" size="mini" @click="handleExport">导出Excel</el-button>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<el-table :data="quoteList" border v-loading="loading">
|
||
<el-table-column label="报价日期" prop="submitTime" width="100" align="center" />
|
||
|
||
<!-- 供应商信息合并展示 -->
|
||
<el-table-column label="供应商信息" min-width="280">
|
||
<template slot-scope="scope">
|
||
<div class="supplier-info">
|
||
<div class="supplier-name">{{ scope.row.supplierName }}</div>
|
||
<div class="supplier-contact">
|
||
<span>联系人: {{ scope.row.contact || '-' }}</span>
|
||
<span v-if="scope.row.phone">{{ scope.row.phone }}</span>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column label="单价(元)" prop="unitPrice" width="120" align="right">
|
||
<template slot-scope="scope">
|
||
<span style="color: #f56c6c; font-weight: bold;">¥{{ formatPrice(scope.row.unitPrice) }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column label="数量" prop="quantity" width="80" align="center" />
|
||
|
||
<el-table-column label="交期" width="80" align="center">
|
||
<template slot-scope="scope">
|
||
<span>{{ scope.row.deliveryDays }}天</span>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column label="状态" width="100" align="center">
|
||
<template slot-scope="scope">
|
||
<el-tag v-if="scope.row.isWinning === '1'" type="success" size="small">已中标</el-tag>
|
||
<el-tag v-else type="info" size="small">未中标</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.supplier-info {
|
||
line-height: 1.5;
|
||
}
|
||
.supplier-name {
|
||
font-weight: 600;
|
||
color: #303133;
|
||
margin-bottom: 4px;
|
||
}
|
||
.supplier-contact {
|
||
font-size: 12px;
|
||
color: #909399;
|
||
}
|
||
.supplier-contact span {
|
||
margin-right: 8px;
|
||
}
|
||
</style>
|
||
```
|
||
|
||
**数据来源**: `biz_quotation_item` → `biz_quotation` → `biz_supplier`
|
||
|
||
#### 3.3.4 Tab 3: 甲方报价历史
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 我方给甲方的历史报价 [导出Excel] │
|
||
├─────────────────────────────────────────────────────────────┤
|
||
│ 报价日期 甲方名称 单价(元) 折扣率 成交价 状态 │
|
||
│ ───────────────────────────────────────────────────────── │
|
||
│ 2026-05-25 福安德科技 ¥8,000 95% ¥7,600 已接受│
|
||
│ 2026-05-22 福安德科技 ¥8,200 90% ¥7,380 已拒绝│
|
||
│ 2026-04-15 某某自动化 ¥8,500 100% ¥8,500 已接受│
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**数据来源**: `biz_client_quote_item` → `biz_client_quote`
|
||
|
||
#### 3.3.5 同品类物料横向对比(基于供应商报价)
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────────┐
|
||
│ 同品类物料横向对比 3个物料 │
|
||
│ [选择对比物料(仅显示有报价的物料)... ] │
|
||
├─────────────────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ ┌─────────────────────────────┐ ┌─────────────────────────────┐ │
|
||
│ │ PLC控制器 │ │ 变频器 │ │
|
||
│ │ CPU模块... / 西门子S7-1200 │ │ 三相380V... / ABB/西门子 │ │
|
||
│ │ 3家报价 │ │ 2家报价 │ │
|
||
│ ├─────────────────────────────┤ ├─────────────────────────────┤ │
|
||
│ │ 规格型号 │ CPU模块... │ │ 规格型号 │ 三相380V... │ │
|
||
│ │ 厂家/品牌│ 西门子S7-1200 │ │ 厂家/品牌│ ABB/西门子 │ │
|
||
│ │ 材质 │ — │ │ 材质 │ — │ │
|
||
│ │ 单位 │ 套 │ │ 单位 │ 台 │ │
|
||
│ ├─────────────────────────────┤ ├─────────────────────────────┤ │
|
||
│ │ ───── 供应商报价明细 ───── │ │ ───── 供应商报价明细 ───── │ │
|
||
│ ├─────────────────────────────┤ ├─────────────────────────────┤ │
|
||
│ │ 供应商 单价 交期 │ │ 供应商 单价 交期 │ │
|
||
│ │ 广州联盟... ¥3,020 30天 │ │ 华顺达... ¥6,200 7天 │ │
|
||
│ │ 深圳华顺... ¥3,180 25天 │ │ 博远... ¥6,500 10天 │ │
|
||
│ │ 上海瑞达... ¥3,450 20天 │ │ │ │
|
||
│ ├─────────────────────────────┤ ├─────────────────────────────┤ │
|
||
│ │ 最低¥3020 │ 最高¥3450 │ │ 最低¥6200 │ 最高¥6500 │ │
|
||
│ │ 均价¥3216 │ 价差¥430(+14.2%)│ │ 均价¥6350 │ 价差¥300(+4.8%) │ │
|
||
│ └─────────────────────────────┘ └─────────────────────────────┘ │
|
||
│ │
|
||
└─────────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**功能说明**:
|
||
- **自动加载**: 进入页面自动加载同品类有报价的物料,默认选中前3个
|
||
- **实时更新**: 选择框变更时即时加载对应报价明细
|
||
- **视觉区分**: 基础信息区域(浅蓝背景)与供应商报价区域(白色背景)通过分隔线明确区分
|
||
- **报价排序**: 按单价从低到高排序,最低价绿色高亮并标记"最低"标签
|
||
- **统计汇总**: 每个物料卡片底部展示最低价、最高价、均价、价差百分比
|
||
- **错误处理**: 加载失败显示错误提示和重试按钮
|
||
- **响应式**: 适配桌面端、平板和手机屏幕
|
||
|
||
**交互流程**:
|
||
1. 用户进入物料详情页 → 系统自动加载同品类物料列表
|
||
2. 默认选中前3个物料 → 自动加载这些物料的供应商报价明细
|
||
3. 用户可在选择框中增删物料 → 报价明细实时更新
|
||
4. 加载过程中显示loading状态 → 失败显示错误提示和重试按钮
|
||
|
||
**数据来源**:
|
||
- 物料信息: `biz_material`
|
||
- 供应商报价: `biz_quotation_item` + `biz_quotation` + `biz_supplier`
|
||
- 关联关系: `biz_rfq_item` (物料与报价明细的关联)
|
||
|
||
---
|
||
|
||
## 四、后端API设计
|
||
|
||
### 4.1 物料管理API
|
||
|
||
| 接口 | 方法 | 说明 | 权限 |
|
||
|------|------|------|------|
|
||
| `/bid/material/list` | GET | 物料列表 | bid:material:list |
|
||
| `/bid/material/{id}` | GET | 物料详情 | bid:material:query |
|
||
| `/bid/material` | POST | 新增物料 | bid:material:add |
|
||
| `/bid/material` | PUT | 修改物料 | bid:material:edit |
|
||
| `/bid/material/{id}` | DELETE | 删除物料 | bid:material:remove |
|
||
|
||
### 4.2 物料详情API
|
||
|
||
| 接口 | 方法 | 说明 | 权限 |
|
||
|------|------|------|------|
|
||
| `/bid/material/{id}/detail` | GET | 物料完整详情(含性能参数) | bid:material:detail |
|
||
| `/bid/material/{id}/supplier-quotes` | GET | 供应商历史报价清单 | bid:material:supplierQuotes |
|
||
| `/bid/material/{id}/client-quotes` | GET | 甲方历史报价清单 | bid:material:clientQuotes |
|
||
| `/bid/material/{id}/comparison` | GET | 横向对比信息 | bid:material:comparison |
|
||
|
||
### 4.3 同名称物料横向对比API(基于物料名称精确匹配)
|
||
|
||
| 接口 | 方法 | 说明 | 权限 | 备注 |
|
||
|------|------|------|------|------|
|
||
| `/bid/material/same-name/{materialName}` | GET | 按名称精确匹配查询物料 | bid:material:list | 返回名称相同但规格/品牌不同的物料(含无报价) |
|
||
| `/bid/material/quote-comparison` | POST | 获取物料报价对比明细 | bid:material:list | 根据物料ID列表返回各供应商报价 |
|
||
|
||
**GET /bid/material/same-name/{materialName}?excludeId=1** 响应示例:
|
||
```json
|
||
[
|
||
{
|
||
"materialId": 2,
|
||
"materialName": "PLC控制器",
|
||
"spec": "CPU模块,数字量I/O 40点,以太网接口",
|
||
"brand": "西门子S7-1200",
|
||
"material": "",
|
||
"purpose": "",
|
||
"unit": "套",
|
||
"categoryName": "控制器"
|
||
},
|
||
{
|
||
"materialId": 3,
|
||
"materialName": "PLC控制器",
|
||
"spec": "CPU模块,数字量I/O 64点,以太网接口",
|
||
"brand": "三菱FX5U",
|
||
"material": "",
|
||
"purpose": "",
|
||
"unit": "套",
|
||
"categoryName": "控制器"
|
||
}
|
||
]
|
||
```
|
||
|
||
**POST /bid/material/quote-comparison** 请求/响应示例:
|
||
```json
|
||
// 请求
|
||
[1, 2, 3]
|
||
|
||
// 响应
|
||
[
|
||
{
|
||
"material_id": 1,
|
||
"unit_price": 6200.00,
|
||
"total_price": 31000.00,
|
||
"delivery_days": 7,
|
||
"quotation_id": 101,
|
||
"quote_no": "Q20250520001",
|
||
"submit_time": "2026-05-20T10:30:00",
|
||
"quote_status": "2",
|
||
"supplier_id": 5,
|
||
"supplier_name": "华顺达电子科技有限公司",
|
||
"supplier_contact": "张经理",
|
||
"supplier_phone": "13800138000"
|
||
}
|
||
]
|
||
```
|
||
|
||
### 4.4 横向对比管理API(可维护对标关系)
|
||
|
||
| 接口 | 方法 | 说明 | 权限 |
|
||
|------|------|------|------|
|
||
| `/bid/material/comparison` | GET | 查询对比组列表 | bid:comparison:list |
|
||
| `/bid/material/comparison` | POST | 添加对标物料 | bid:comparison:add |
|
||
| `/bid/material/comparison/{id}` | PUT | 修改对标信息 | bid:comparison:edit |
|
||
| `/bid/material/comparison/{id}` | DELETE | 删除对标物料 | bid:comparison:remove |
|
||
| `/bid/material/comparison/recommend` | GET | 获取智能推荐 | bid:comparison:recommend |
|
||
|
||
---
|
||
|
||
## 五、前端组件设计
|
||
|
||
### 5.1 目录结构
|
||
|
||
```
|
||
src/views/bid/material/
|
||
├── index.vue # 物料列表页
|
||
├── detail.vue # 物料详情页(主框架)
|
||
└── components/
|
||
├── DetailHeader.vue # 顶部信息卡片
|
||
├── BasicInfoTab.vue # Tab1: 基础信息
|
||
├── SupplierQuoteTab.vue # Tab2: 供应商报价
|
||
├── ClientQuoteTab.vue # Tab3: 甲方报价
|
||
└── ComparisonTab.vue # Tab4: 横向对比
|
||
```
|
||
|
||
### 5.2 关键组件说明
|
||
|
||
#### 5.2.1 性能参数动态表单
|
||
|
||
```vue
|
||
<template>
|
||
<div class="performance-params-form">
|
||
<el-button type="primary" size="small" @click="addRow">+ 添加参数</el-button>
|
||
<el-table :data="params" border size="small" style="margin-top: 10px">
|
||
<el-table-column label="参数名" width="150">
|
||
<template slot-scope="scope">
|
||
<el-input v-model="scope.row.name" placeholder="如: 功率" />
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="参数值" width="150">
|
||
<template slot-scope="scope">
|
||
<el-input v-model="scope.row.value" placeholder="如: 37" />
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="单位" width="100">
|
||
<template slot-scope="scope">
|
||
<el-input v-model="scope.row.unit" placeholder="如: kW" />
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="80" align="center">
|
||
<template slot-scope="scope">
|
||
<el-button type="text" style="color: #f56c6c" @click="removeRow(scope.$index)">删除</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</div>
|
||
</template>
|
||
```
|
||
|
||
#### 5.2.2 横向对比组件 (ComparisonTab.vue)
|
||
|
||
```vue
|
||
<template>
|
||
<div class="comparison-tab">
|
||
<!-- 操作栏 -->
|
||
<el-row :gutter="10" class="mb8">
|
||
<el-col :span="1.5">
|
||
<el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd">添加对标</el-button>
|
||
</el-col>
|
||
<el-col :span="1.5">
|
||
<el-button type="danger" icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete">删除</el-button>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 对比表格 -->
|
||
<el-table :data="comparisonData" border v-loading="loading">
|
||
<el-table-column type="selection" width="55" align="center" fixed="left" />
|
||
<el-table-column label="对比项" prop="attrName" width="120" fixed="left" />
|
||
|
||
<!-- 当前物料列 -->
|
||
<el-table-column :label="currentMaterial.brand + ' ' + currentMaterial.spec" align="center">
|
||
<template slot-scope="scope">
|
||
<span :class="getHighlightClass(scope.row, 'current')">{{ scope.row.currentValue }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<!-- 对标物料列(动态生成) -->
|
||
<el-table-column
|
||
v-for="item in counterpartList"
|
||
:key="item.counterpartId"
|
||
:label="item.brand + ' ' + item.spec"
|
||
align="center">
|
||
<template slot-scope="scope">
|
||
<span :class="getHighlightClass(scope.row, item.counterpartId)">{{ scope.row[item.counterpartId] }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<!-- 智能推荐 -->
|
||
<el-card class="recommend-card" v-if="recommendation">
|
||
<div slot="header">
|
||
<span>💡 智能推荐</span>
|
||
</div>
|
||
<div>
|
||
<p><strong>推荐选型:</strong> {{ recommendation.brand }} {{ recommendation.spec }}</p>
|
||
<p><strong>推荐理由:</strong> {{ recommendation.reason }}</p>
|
||
<p><strong>价格优势:</strong> {{ recommendation.priceAdvantage }}</p>
|
||
</div>
|
||
</el-card>
|
||
|
||
<!-- 添加对标对话框 -->
|
||
<el-dialog title="添加对标物料" :visible.sync="open" width="600px">
|
||
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
|
||
<el-form-item label="对标物料" prop="counterpartId">
|
||
<el-select v-model="form.counterpartId" filterable placeholder="请选择对标物料" style="width: 100%">
|
||
<el-option
|
||
v-for="m in materialOptions"
|
||
:key="m.materialId"
|
||
:label="m.brand + ' ' + m.spec + ' - ' + m.materialName"
|
||
:value="m.materialId" />
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="对比类型" prop="comparisonType">
|
||
<el-radio-group v-model="form.comparisonType">
|
||
<el-radio label="same_spec">同规格</el-radio>
|
||
<el-radio label="similar">相似规格</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
<el-form-item label="品牌等级" prop="brandLevel">
|
||
<el-select v-model="form.brandLevel" placeholder="请选择品牌等级" style="width: 100%">
|
||
<el-option label="国产一线" value="国产一线" />
|
||
<el-option label="国产二线" value="国产二线" />
|
||
<el-option label="进口一线" value="进口一线" />
|
||
<el-option label="进口二线" value="进口二线" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-form>
|
||
<div slot="footer">
|
||
<el-button @click="open = false">取消</el-button>
|
||
<el-button type="primary" @click="submitForm">确定</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
props: ['materialId'],
|
||
data() {
|
||
return {
|
||
loading: false,
|
||
comparisonData: [],
|
||
counterpartList: [],
|
||
currentMaterial: {},
|
||
recommendation: null,
|
||
open: false,
|
||
multiple: true,
|
||
materialOptions: [],
|
||
form: {},
|
||
rules: {
|
||
counterpartId: [{ required: true, message: '请选择对标物料', trigger: 'change' }],
|
||
comparisonType: [{ required: true, message: '请选择对比类型', trigger: 'change' }],
|
||
brandLevel: [{ required: true, message: '请选择品牌等级', trigger: 'change' }]
|
||
}
|
||
}
|
||
},
|
||
created() {
|
||
this.getComparisonData()
|
||
},
|
||
methods: {
|
||
getComparisonData() {
|
||
// 获取横向对比数据
|
||
this.loading = true
|
||
// API调用: GET /bid/material/{id}/comparison
|
||
// 数据处理...
|
||
},
|
||
getHighlightClass(row, type) {
|
||
// 根据数值比较返回高亮样式
|
||
// 优于当前物料: green, 劣于当前物料: red
|
||
},
|
||
handleAdd() {
|
||
this.open = true
|
||
this.getMaterialOptions()
|
||
},
|
||
getMaterialOptions() {
|
||
// 获取可选物料列表(排除当前物料和已添加的对标物料)
|
||
},
|
||
submitForm() {
|
||
// 提交添加对标
|
||
// API调用: POST /bid/material/comparison
|
||
},
|
||
handleDelete() {
|
||
// 删除对标
|
||
// API调用: DELETE /bid/material/comparison/{id}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.recommend-card {
|
||
margin-top: 20px;
|
||
background: #f0f9ff;
|
||
border-left: 4px solid #1890ff;
|
||
}
|
||
.highlight-green {
|
||
color: #52c41a;
|
||
font-weight: bold;
|
||
}
|
||
.highlight-red {
|
||
color: #ff4d4f;
|
||
}
|
||
</style>
|
||
```
|
||
|
||
---
|
||
|
||
## 六、实现优先级
|
||
|
||
| 优先级 | 任务 | 涉及文件 | 预计工时 |
|
||
|--------|------|---------|---------|
|
||
| P0 | 数据库字段扩展 | `sql/20250527/01_material_alter.sql` | 0.5h |
|
||
| P0 | 物料列表页字段更新 | `material/index.vue` | 2h |
|
||
| P0 | 新增/编辑表单更新 | `material/index.vue` 对话框 | 3h |
|
||
| P1 | 性能参数动态表单组件 | `components/PerformanceParamsForm.vue` | 3h |
|
||
| P1 | 物料详情页框架 | `material/detail.vue` | 4h |
|
||
| P1 | Tab 1: 基础信息 | `components/BasicInfoTab.vue` | 2h |
|
||
| P1 | Tab 2: 供应商历史报价 | `components/SupplierQuoteTab.vue` | 3h |
|
||
| P2 | Tab 3: 甲方历史报价 | `components/ClientQuoteTab.vue` | 3h |
|
||
| P2 | Tab 4: 横向对比 | `components/ComparisonTab.vue` | 4h |
|
||
| P2 | 横向对比管理功能 | 添加/编辑/删除对标物料 | 3h |
|
||
| P3 | 智能推荐算法 | 综合评分计算 | 2h |
|
||
| P3 | 后端API实现 | `BizMaterialController.java` | 4h |
|
||
|
||
**总计**: 约 33.5 工时
|
||
|
||
---
|
||
|
||
## 七、注意事项
|
||
|
||
1. **数据迁移**: 执行SQL脚本前请备份数据库
|
||
2. **字段变更**:
|
||
- `spec` 字段保持为"规格型号",**不变更**
|
||
- `brand` 字段改为"厂家/品牌",**变更注释**
|
||
- `remark` 字段保持为"备注",**不变更**
|
||
3. **JSON存储**: 性能参数使用JSON格式,便于灵活扩展
|
||
4. **权限控制**: 详情页需要单独配置菜单权限
|
||
5. **图片上传**: 物料图片使用单独的上传接口,存储URL
|
||
|
||
---
|
||
|
||
## 八、相关文件
|
||
|
||
- SQL脚本: `sql/20250527/01_material_alter.sql`
|
||
- 开发文档: `doc/智采系统-物料信息模块开发文档.md`
|
||
- 完整方案: `doc/福安德智慧报价平台-完整开发方案.md`
|