920 lines
33 KiB
Markdown
920 lines
33 KiB
Markdown
# 三楼仓库可视化界面设计方案
|
||
|
||
## 一、背景
|
||
|
||
由仓库管理提出,三楼仓库目前缺少直观的库位可视化展示能力,仓库人员无法快速了解各库位使用状态、物料分布和整体仓储情况。现有立库查询界面已具备 2D 网格矩阵可视化能力(巷道筛选、状态颜色标识、库位点击查看物料详情、统计面板),可参考该方案为三楼仓库开发类似的可视化界面。
|
||
|
||
当前仓库人员判断库位使用情况主要依赖库位管理页面(`LocationManagement`)逐条查询和物料库位页面(`MaterialLocation`)按物料查阅,缺少全局视角的库位状态总览。在盘点、出入库规划、空间利用率评估等场景下,仓库人员需要一屏总览仓库所有库位状态和物料分布,便于快速定位目标库位和发现异常。
|
||
|
||
本次需求优先级为 P1,纳入第一阶段实施。
|
||
|
||
<br/>
|
||
|
||
## 二、现状核对
|
||
|
||
### 2.1 已有立库可视化组件
|
||
|
||
主组件文件:
|
||
|
||
- `src/views/WarehouseManagement/WarehouseVisualization/index.vue`
|
||
- 组件名:`WarehouseVisualizationSystem`
|
||
|
||
已实现功能:
|
||
|
||
- 按 4 个巷道加载立库数据,接口名为 `GetPositionView`
|
||
- 库位矩阵用原生 HTML `<table>` 绘制
|
||
- 4 种库位状态:0=空库位、1=有托盘无物料、2=有物料有托盘、9=锁库
|
||
- 统计信息卡片:总库位数、有物料有托盘数、有托盘无物料数、空闲库位数、使用率、数据行数
|
||
- 支持按行-层筛选、分页显示
|
||
- 点击状态为 2 的库位调用 `StockDetail(rowLayer, column)` 查询 `StockDetailView` 获取物料明细
|
||
- 点击非 2 状态库位弹出库位详情弹窗
|
||
- 支持文字/图标两种显示模式切换
|
||
- 使用独立的立库数据库服务入口(`ExecDatabase1`,走 `config.js` 中的 `url1`)
|
||
|
||
辅助组件文件:
|
||
|
||
- `src/views/WarehouseVisualization/index.vue`
|
||
- 组件名:`WarehouseVisualization`
|
||
- 纯展示组件,通过 `props` 接收 `warehouseData`
|
||
|
||
### 2.2 已有仓储数据页面
|
||
|
||
| 页面 | 路径 | 功能 |
|
||
| --- | --- | --- |
|
||
| 库位管理 | `WarehouseManagement/LocationManagement/index.vue` | 库位增删改查,接口 `仓储管理_库位_查询` |
|
||
| 物料库位 | `WarehouseManagement/MaterialLocation/index.vue` | 按物料查库位,接口 `仓储管理_物料库位_查询数据` |
|
||
| 库存查询 | `WarehouseManagement/InventoryQuery/index.vue` | 库存汇总查询,接口 `仓储管理_库存查询_查询` |
|
||
| 库存盘点 | `WarehouseManagement/InventoryCheck/index.vue` | 盘点数据查询 |
|
||
| 仓储汇总 | `WarehouseManagement/WarehouseSummary/index.vue` | 看板式统计汇总 |
|
||
|
||
### 2.3 接口调用模式
|
||
|
||
仓储管理模块所有页面的 API 调用均内联在 `.vue` 组件中,通过 `this.CreateData()` + `this.ExecDatabase()` 构造请求参数并调用后端,无独立 API 文件。接口命名遵循 `模块_子模块_操作` 格式。
|
||
|
||
立库可视化走独立的 `ExecDatabase1`(连接立库数据库 `url1`),三楼仓库数据走主业务数据库(`ExecDatabase`),两者数据源不同。
|
||
|
||
### 2.4 数据差异
|
||
|
||
| 对比项 | 立库 | 三楼仓库 |
|
||
| --- | --- | --- |
|
||
| 数据服务 | 独立志库数据库(`url1:10006`) | 主业务数据库(`url:8030`) |
|
||
| 库位编码 | 行-列-层 三段式(如 `03-12-01`) | 待确认(需求文档待确认事项第 10 条) |
|
||
| 调用方法 | `ExecDatabase1` | `ExecDatabase` |
|
||
| 库位状态 | 0=空、1=有盘无物、2=有物有盘、9=锁 | 待确认(需求文档待确认事项第 11 条) |
|
||
| 物理布局 | 巷道-行-列-层 四维结构 | 待确认(需求文档待确认事项第 10 条) |
|
||
|
||
## 三、设计原则
|
||
|
||
1. 参考立库可视化组件的页面结构和交互模式(统计卡片 + 图例 + 库位网格矩阵 + 详情弹窗),复用成熟的交互设计,降低用户学习成本。
|
||
2. 三楼仓库数据走主业务数据库(`ExecDatabase`),不走立库独立服务(`ExecDatabase1`),与库位管理、物料库位、库存盘点等仓储页面使用同一数据源。
|
||
3. 接口命名遵循项目现有规范(如 `仓储管理_三楼仓库库位_查询数据`)。
|
||
4. 使用 Vue 2 Options API + Element UI,保持与现有代码风格一致。
|
||
5. 不引入新的第三方库,不使用 Vue 3 或 Composition API。
|
||
6. 样式与立库可视化保持一致的设计语言(颜色方案、卡片风格、单元格交互),但库位布局和状态分类根据三楼仓库实际业务定义。
|
||
7. 库位数据查询和物料详情查询走标准后端接口名,前端不直接拼 SQL,与立库组件中 `StockDetail` 直接构造 SQL 的做法不同,降低前后端耦合。
|
||
|
||
<br/>
|
||
|
||
## 四、前端页面结构设计
|
||
|
||
### 4.1 页面总览
|
||
|
||
新增三楼仓库可视化页面,路径:`src/views/WarehouseManagement/ThirdFloorWarehouse/index.vue`
|
||
|
||
页面整体采用标准的 `div.app-container > el-card` 布局,主体包含以下区域:
|
||
|
||
1. 顶部筛选与操作区
|
||
2. 统计信息卡片区
|
||
3. 状态图例区
|
||
4. 三楼仓库库位网格矩阵区
|
||
5. 分页区
|
||
6. 库位详情弹窗
|
||
7. 物料信息弹窗
|
||
|
||
### 4.2 顶部筛选与操作区
|
||
|
||
参考立库可视化的筛选区布局,但筛选维度调整为三楼仓库的实际布局维度。
|
||
|
||
#### 4.2.1 区域筛选
|
||
|
||
控件类型:`el-select`
|
||
|
||
用途:三楼仓库按物理区域划分(如 A 区、B 区、C 区等,具体区域名称需现场确认)。
|
||
|
||
数据来源:页面初始化时从库位数据中自动提取去重,或后端返回区域字典。
|
||
|
||
选项生成规则:
|
||
|
||
- 从库位查询结果中提取 `区域` 字段
|
||
- 自动去重
|
||
- 按区域编码或名称排序
|
||
|
||
#### 4.2.2 库位类型筛选
|
||
|
||
控件类型:`el-select`
|
||
|
||
可选项(具体需现场确认):
|
||
|
||
- 全部
|
||
- 有库存
|
||
- 空闲
|
||
- 预占/待处理
|
||
- 异常/禁用
|
||
|
||
用途:按库位状态快速筛选关注类别的库位。
|
||
|
||
#### 4.2.3 库位编号搜索
|
||
|
||
控件类型:`el-input`
|
||
|
||
用途:直接输入库位编号定位到对应库位。
|
||
|
||
交互:
|
||
|
||
- 输入库位编号后,点击搜索,矩阵中匹配的库位高亮显示
|
||
- 支持模糊匹配
|
||
|
||
#### 4.2.4 操作按钮
|
||
|
||
| 按钮 | 类型 | 作用 |
|
||
| --- | --- | --- |
|
||
| 搜索 | `el-button type="primary"` | 按筛选条件重新查询库位数据 |
|
||
| 重置 | `el-button type="default"` | 清空所有筛选条件,恢复全局视图 |
|
||
| 刷新数据 | `el-button type="success"` | 重新调用后端接口获取最新数据 |
|
||
| 自动刷新开关 | `el-switch` | 控制定时自动刷新(默认关闭) |
|
||
|
||
#### 4.2.5 显示模式切换
|
||
|
||
控件类型:`el-switch`
|
||
|
||
两种模式:
|
||
|
||
- 显示文字:每个库位格显示状态简称(如 `存`、`空`、`预`、`异`)
|
||
- 显示图标:每个库位格显示对应 Element UI 图标
|
||
|
||
### 4.3 统计信息卡片区
|
||
|
||
参考立库可视化的 `el-row + el-col` 卡片布局,展示以下 6 项指标:
|
||
|
||
| 序号 | 统计项 | 计算方式 | 颜色 |
|
||
| --- | --- | --- | --- |
|
||
| 1 | 总库位数 | 当前加载的库位总数 | `#303133` |
|
||
| 2 | 有库存 | 状态为"有库存"的库位数 | `#4caf50`(绿色) |
|
||
| 3 | 预占/待处理 | 状态为"预占"的库位数 | `#ff9800`(橙色) |
|
||
| 4 | 空闲库位 | 状态为"空闲"的库位数 | `#e0e0e0`(灰色) |
|
||
| 5 | 异常/禁用 | 状态为"异常"的库位数 | `#f56c6c`(红色) |
|
||
| 6 | 使用率 | `(有库存 + 预占) / 总库位数 * 100%` | `#2196f3`(蓝色) |
|
||
|
||
布局:`el-row :gutter="10"`,每项占 `el-col :span="4"`。
|
||
|
||
统计计算方式:
|
||
|
||
- 前端根据库位列表数据实时计算
|
||
- 支持筛选后重新统计(筛选后统计数字反映当前筛选结果)
|
||
|
||
### 4.4 状态图例区
|
||
|
||
参考立库可视化图例,居中展示库位状态颜色含义:
|
||
|
||
| 颜色 | 含义 | 文字简称 | 图标 |
|
||
| --- | --- | --- | --- |
|
||
| 绿色 `#4caf50` | 有库存 | 存 | `el-icon-box` |
|
||
| 橙色 `#ff9800` | 预占或待处理 | 预 | `el-icon-time` |
|
||
| 灰色 `#e0e0e0` | 空闲库位 | 空 | `el-icon-minus` |
|
||
| 红色 `#f56c6c` | 异常或禁用 | 异 | `el-icon-warning` |
|
||
| 蓝色边框 `#2196f3` | 当前选中库位 | — | — |
|
||
|
||
说明:
|
||
|
||
- 具体状态分类需与仓库现场确认(待确认事项第 11 条)
|
||
- 如果三楼仓库不需要"预占"和"异常"状态,可简化为三种状态(有库存、空闲、选中)
|
||
- 如果三楼仓库与立库状态分类一致,可直接复用立库的 4 状态方案(0=空、1=盘无物、2=物有盘、9=锁),但建议重新命名以贴合三楼仓库业务
|
||
|
||
### 4.5 库位网格矩阵区
|
||
|
||
参考立库可视化组件使用原生 `<table>` 绘制矩阵的方案。
|
||
|
||
#### 4.5.1 矩阵布局
|
||
|
||
三楼仓库的物理布局需现场确认(待确认事项第 10 条),本设计按以下原则适配:
|
||
|
||
- 如果三楼仓库按"排-列"二维布局:每行对应一排,每列对应一个列号
|
||
- 如果三楼仓库按"区域-排-列"三维布局:区域通过顶部筛选切换,每个区域内按"排-列"二维展示
|
||
- 如果三楼仓库按不规则布局:可按库位编号分组展示,或按物理位置映射到网格
|
||
|
||
矩阵结构:
|
||
|
||
```html
|
||
<table class="warehouse-table">
|
||
<thead>
|
||
<tr>
|
||
<th class="row-header">排/行号</th>
|
||
<th v-for="col in columnCount" :key="col" class="column-header">{{ col }}</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr v-for="(row, rowIndex) in displayedLocationData" :key="rowIndex">
|
||
<td class="row-label-cell">{{ row['行标识'] }}</td>
|
||
<td v-for="col in columnKeys" :key="col"
|
||
:class="['status-' + row[col].状态, { 'selected-cell': isSelected(row['行标识'], col) }]"
|
||
class="location-cell"
|
||
@click="selectLocation(row['行标识'], col, row[col])"
|
||
@mouseenter="onCellHover(row['行标识'], col, row[col])"
|
||
@mouseleave="onCellLeave">
|
||
<div class="cell-content">
|
||
<span v-if="showCellText === 'text'" class="cell-text">{{ getStatusText(row[col].状态) }}</span>
|
||
<span v-else class="cell-icon"><i :class="getStatusIcon(row[col].状态)"></i></span>
|
||
<div v-if="isHoveredCell(row['行标识'], col)" class="cell-tooltip">
|
||
{{ getStatusDescription(row[col].状态) }}
|
||
</div>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
```
|
||
|
||
#### 4.5.2 单元格数据结构
|
||
|
||
每个库位单元格的数据结构建议如下:
|
||
|
||
```javascript
|
||
{
|
||
'行标识': 'A-01', // 行/排标识
|
||
1: { // 列号对应的库位信息
|
||
库位编号: 'A-01-01',
|
||
库位名称: 'A-01-01',
|
||
状态: 0, // 0=空闲, 1=预占, 2=有库存, 3=异常
|
||
区域: 'A区'
|
||
},
|
||
2: {
|
||
库位编号: 'A-01-02',
|
||
库位名称: 'A-01-02',
|
||
状态: 2,
|
||
区域: 'A区'
|
||
}
|
||
// ...
|
||
}
|
||
```
|
||
|
||
说明:
|
||
|
||
- 矩阵数据结构参考立库 `warehouseData` 的组织方式(行标识 + 列号映射),但每个单元格从简单状态值扩展为包含 `库位编号`、`库位名称`、`状态`、`区域` 的对象
|
||
- 与立库组件中单元格仅存储状态数字值(`0/1/2/9`)相比,三楼仓库单元格存储更丰富的信息,便于点击时直接获取库位编号查询物料明细
|
||
|
||
#### 4.5.3 单元格交互效果
|
||
|
||
参考立库可视化组件的交互设计:
|
||
|
||
- 鼠标悬停:单元格放大(`transform: scale(1.1)`)并显示状态说明浮层
|
||
- 点击选中:蓝色边框高亮选中库位
|
||
- 选中后高亮当前行和列
|
||
|
||
### 4.6 分页区
|
||
|
||
参考立库分页方案,当库位行数较多时支持分页显示:
|
||
|
||
- 分页针对"行数据",不是单元格
|
||
- 每页可选条数:`5`、`8`、`10`、`15`
|
||
- 布局:`total, sizes, prev, pager, next, jumper`
|
||
|
||
### 4.7 库位详情弹窗
|
||
|
||
点击非"有库存"状态的库位时弹出,参考立库的库位详情弹窗但信息更丰富。
|
||
|
||
弹窗标题:`库位详情 - {库位编号}`
|
||
|
||
弹窗内容(使用 `el-descriptions` 组件):
|
||
|
||
| 字段 | 数据来源 | 说明 |
|
||
| --- | --- | --- |
|
||
| 库位编号 | 行数据 | 当前点击的库位编号 |
|
||
| 库位名称 | 行数据 | 库位显示名称 |
|
||
| 区域 | 行数据 | 所属区域 |
|
||
| 当前状态 | 行数据 | 状态中文说明 |
|
||
| 状态描述 | 前端映射 | 状态对应的业务说明 |
|
||
| 最后更新时间 | 后端接口 | 该库位最近一次库存变动时间(需后端支持) |
|
||
|
||
弹窗底部操作按钮:
|
||
|
||
| 按钮 | 作用 |
|
||
| --- | --- |
|
||
| 关闭 | 关闭弹窗 |
|
||
|
||
### 4.8 物料信息弹窗
|
||
|
||
点击"有库存"状态的库位时弹出,参考立库的物料信息弹窗。
|
||
|
||
弹窗标题:`库位物料信息 - {库位编号}`
|
||
|
||
弹窗内容(使用 `el-table` 组件):
|
||
|
||
| 列名 | 字段 | 宽度 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| 物料编号 | `物料编号` | 150 | 显示溢出省略 |
|
||
| 物料名称 | `物料名称` | 120 | 显示溢出省略 |
|
||
| 图号 | `图号` | 150 | 显示溢出省略 |
|
||
| 规格型号 | `规格型号` | 150 | 显示溢出省略 |
|
||
| 库存数量 | `库存数量` | 100 | 右对齐,大于 0 绿色、等于 0 红色,保留 3 位小数,下方显示单位 |
|
||
| 批次 | `批次` | 120 | 显示溢出省略 |
|
||
|
||
弹窗底部操作按钮:
|
||
|
||
| 按钮 | 作用 |
|
||
| --- | --- |
|
||
| 关闭 | 关闭弹窗 |
|
||
|
||
数据来源:调用后端接口 `仓储管理_三楼仓库库位物料_查询数据`,传入库位编号。
|
||
|
||
### 4.9 自动刷新
|
||
|
||
仓储汇总看板(`WarehouseSummary`)已有 1 分钟定时刷新的先例。三楼仓库可视化支持可选的自动刷新:
|
||
|
||
- 默认关闭,通过顶部 `el-switch` 开启
|
||
- 刷新频率可选:30 秒、1 分钟、5 分钟
|
||
- 刷新时调用与初始加载相同的后端接口重新查询
|
||
- 刷新期间显示 `v-loading` 加载动画
|
||
- 刷新期间不阻断用户操作
|
||
|
||
<br/>
|
||
|
||
## 五、后端接口设计
|
||
|
||
### 5.1 库位数据查询接口
|
||
|
||
接口名:`仓储管理_三楼仓库库位_查询数据`
|
||
|
||
请求类型:`type = '1'`(查询)
|
||
|
||
请求参数:
|
||
|
||
| 参数名 | 参数类型 | 是否必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `区域_check` | int | 否 | 是否传入区域筛选,0=不筛选,1=筛选 |
|
||
| `区域` | string | 否 | 区域名称,如 `A区` |
|
||
| `库位编号_check` | int | 否 | 是否传入库位编号筛选 |
|
||
| `库位编号` | string | 否 | 库位编号,支持模糊匹配 |
|
||
| `库位状态_check` | int | 否 | 是否传入状态筛选 |
|
||
| `库位状态` | int | 否 | 库位状态值 |
|
||
|
||
返回数据结构:
|
||
|
||
```javascript
|
||
[
|
||
{
|
||
'行标识': 'A-01', // 矩阵行标识
|
||
1: { // 列号
|
||
库位编号: 'A-01-01',
|
||
库位名称: 'A-01-01',
|
||
状态: 0, // 0=空闲, 1=预占, 2=有库存, 3=异常
|
||
区域: 'A区'
|
||
},
|
||
2: {
|
||
库位编号: 'A-01-02',
|
||
库位名称: 'A-01-02',
|
||
状态: 2,
|
||
区域: 'A区'
|
||
}
|
||
// ...
|
||
},
|
||
// ...
|
||
]
|
||
```
|
||
|
||
说明:
|
||
|
||
- 返回数据结构与立库 `GetPositionView` 类似,但单元格从简单数字扩展为含库位信息的对象
|
||
- 如果后端返回扁平的库位列表更便于实现,前端也可以在接收到扁平数据后自行转换为矩阵结构(见 5.3 节数据转换说明)
|
||
- 后端也可以按立库的方式返回矩阵格式,前端直接渲染
|
||
|
||
备选方案(后端返回扁平列表):
|
||
|
||
```javascript
|
||
[
|
||
{ 库位编号: 'A-01-01', 库位名称: 'A-01-01', 状态: 0, 区域: 'A区', 排: 'A-01', 列: 1 },
|
||
{ 库位编号: 'A-01-02', 库位名称: 'A-01-02', 状态: 2, 区域: 'A区', 排: 'A-01', 列: 2 },
|
||
// ...
|
||
]
|
||
```
|
||
|
||
前端接收到扁平数据后自动生成矩阵(见 5.3 节)。
|
||
|
||
### 5.2 库位物料详情查询接口
|
||
|
||
接口名:`仓储管理_三楼仓库库位物料_查询数据`
|
||
|
||
请求类型:`type = '1'`(查询)
|
||
|
||
请求参数:
|
||
|
||
| 参数名 | 参数类型 | 是否必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `库位编号_check` | int | 是 | 固定传 1 |
|
||
| `库位编号` | string | 是 | 当前点击的库位编号 |
|
||
| `UserID` | string | 是 | 从 Cookie 获取 |
|
||
| `ModularID` | string | 是 | 当前路由路径 |
|
||
|
||
返回数据结构:
|
||
|
||
```javascript
|
||
[
|
||
{
|
||
物料编号: '02.009.001.0001',
|
||
物料名称: '齿轮',
|
||
图号: 'LRS3056-001',
|
||
规格型号: 'LRS3056-001-A',
|
||
库存数量: 12.000,
|
||
单位: '台',
|
||
批次: 'BATCH20260601001'
|
||
}
|
||
]
|
||
```
|
||
|
||
说明:
|
||
|
||
- 返回字段与立库 `StockDetailView` 对齐(物料编号 mno、物料名称 mname、图号 spec、型号 thao、库存数量 qty、单位 munit、批次 batch),但使用中文字段名以保持与项目命名规范一致
|
||
- 如果后端已在仓储管理相关视图中维护了三楼仓库的物料库存与库位关系,优先复用现有视图或过程
|
||
|
||
### 5.3 数据转换(前端侧)
|
||
|
||
如果后端返回扁平的库位列表,前端需要将扁平数据转换为矩阵结构。转换逻辑如下:
|
||
|
||
```javascript
|
||
// 将扁平库位列表转换为矩阵结构
|
||
transformToMatrix(locationList) {
|
||
// 按"排/行标识"分组
|
||
var rowMap = {}
|
||
locationList.forEach(function(item) {
|
||
var rowKey = item.排 || item.行标识
|
||
if (!rowMap[rowKey]) {
|
||
rowMap[rowKey] = { '行标识': rowKey }
|
||
}
|
||
var colKey = item.列
|
||
rowMap[rowKey][colKey] = {
|
||
库位编号: item.库位编号,
|
||
库位名称: item.库位名称,
|
||
状态: item.状态,
|
||
区域: item.区域
|
||
}
|
||
})
|
||
// 转为数组并按行标识排序
|
||
var matrixData = Object.values(rowMap)
|
||
matrixData.sort(function(a, b) {
|
||
return a['行标识'].localeCompare(b['行标识'])
|
||
})
|
||
return matrixData
|
||
}
|
||
```
|
||
|
||
### 5.4 后端接口复用评估
|
||
|
||
| 已有接口 | 可否复用 | 说明 |
|
||
| --- | --- | --- |
|
||
| `仓储管理_库位_查询` | 部分复用 | 现有库位管理页查询全部库位,但缺少"状态"字段和矩阵布局信息,需补充或新增三楼仓库专用接口 |
|
||
| `仓储管理_物料库位_查询数据` | 作为物料详情备选 | 按物料查库位,可反向使用按库位查物料,但参数和返回字段可能需要调整 |
|
||
| `仓储管理_库存查询_查询` | 不直接复用 | 库存查询按物料聚合,与按库位聚合的需求方向不同 |
|
||
| `仓储管理_库存盘点_查询` | 参考数据来源 | 库存盘点数据包含物料与库位的对应关系和库存数量,可作为三楼仓库库位状态和物料明细的数据来源 |
|
||
| `GetPositionView`(立库) | 不复用 | 立库走独立数据库,数据结构不同 |
|
||
|
||
<br/>
|
||
|
||
## 六、data 数据结构设计
|
||
|
||
```javascript
|
||
data() {
|
||
return {
|
||
// ========== 筛选条件 ==========
|
||
areaFilter: '', // 区域筛选值
|
||
statusFilter: '', // 状态筛选值
|
||
locationCodeSearch: '', // 库位编号搜索
|
||
areaOptions: [], // 区域下拉选项,从数据动态生成
|
||
statusOptions: [ // 状态下拉选项
|
||
{ label: '全部', value: '' },
|
||
{ label: '有库存', value: 2 },
|
||
{ label: '预占/待处理', value: 1 },
|
||
{ label: '空闲', value: 0 },
|
||
{ label: '异常/禁用', value: 3 }
|
||
],
|
||
|
||
// ========== 自动刷新 ==========
|
||
autoRefresh: false, // 自动刷新开关
|
||
refreshInterval: 60, // 刷新间隔(秒)
|
||
refreshTimer: null, // 定时器引用
|
||
refreshOptions: [ // 刷新间隔选项
|
||
{ label: '30秒', value: 30 },
|
||
{ label: '1分钟', value: 60 },
|
||
{ label: '5分钟', value: 300 }
|
||
],
|
||
|
||
// ========== 分页 ==========
|
||
pageCurrent: 1,
|
||
pageSize: 8,
|
||
|
||
// ========== 矩阵数据 ==========
|
||
locationRawData: [], // 后端返回的原始数据(扁平列表)
|
||
locationMatrixData: [], // 转换后的矩阵数据
|
||
filteredData: [], // 筛选后的矩阵数据
|
||
displayedData: [], // 当前页显示的矩阵数据
|
||
|
||
// ========== 选中与交互状态 ==========
|
||
selectedCell: null, // { 行标识, 列号, 库位信息 }
|
||
highlightedRow: null, // 当前高亮行
|
||
hoveredCell: null, // 当前悬停单元格
|
||
|
||
// ========== 统计信息 ==========
|
||
statistics: {
|
||
total: 0,
|
||
withStock: 0,
|
||
preOccupied: 0,
|
||
empty: 0,
|
||
abnormal: 0,
|
||
usageRate: 0
|
||
},
|
||
|
||
// ========== 弹窗 ==========
|
||
detailDialogVisible: false, // 库位详情弹窗
|
||
detailInfo: {}, // 当前弹窗展示的库位信息
|
||
materialDialogVisible: false, // 物料信息弹窗
|
||
materialLoading: false,
|
||
materialList: [], // 当前库位的物料列表
|
||
materialLocationCode: '', // 当前查询的库位编号
|
||
|
||
// ========== 显示设置 ==========
|
||
showCellText: 'text', // 'text' 或 'icon'
|
||
loading: false,
|
||
lastUpdateTime: ''
|
||
}
|
||
}
|
||
```
|
||
|
||
<br/>
|
||
|
||
## 七、methods 核心方法设计
|
||
|
||
### 7.1 数据加载与转换
|
||
|
||
```javascript
|
||
// 加载三楼仓库库位数据
|
||
loadLocationData() {
|
||
this.loading = true
|
||
var param = []
|
||
param[0] = ['区域_check', this.areaFilter ? 1 : 0]
|
||
param[1] = ['区域', this.areaFilter]
|
||
param[2] = ['库位编号_check', this.locationCodeSearch ? 1 : 0]
|
||
param[3] = ['库位编号', this.locationCodeSearch]
|
||
param[4] = ['库位状态_check', this.statusFilter !== '' ? 1 : 0]
|
||
param[5] = ['库位状态', this.statusFilter]
|
||
var Data = this.CreateData('1', '仓储管理_三楼仓库库位_查询数据', param)
|
||
this.getTable(Data).then(response => {
|
||
this.locationRawData = response.data || []
|
||
this.locationMatrixData = this.transformToMatrix(this.locationRawData)
|
||
this.filteredData = this.locationMatrixData
|
||
this.updateStatistics()
|
||
this.updateDisplayedData()
|
||
this.updateAreaOptions()
|
||
this.updateLastUpdateTime()
|
||
this.loading = false
|
||
}).catch(() => {
|
||
this.loading = false
|
||
})
|
||
}
|
||
|
||
// 将扁平库位列表转换为矩阵结构
|
||
transformToMatrix(list) {
|
||
// 按"排/行标识"分组(同 5.3 节)
|
||
}
|
||
```
|
||
|
||
### 7.2 统计计算
|
||
|
||
```javascript
|
||
updateStatistics() {
|
||
var withStock = 0
|
||
var preOccupied = 0
|
||
var empty = 0
|
||
var abnormal = 0
|
||
this.filteredData.forEach(function(row) {
|
||
Object.keys(row).forEach(function(key) {
|
||
if (key !== '行标识') {
|
||
var status = row[key].状态
|
||
if (status === 2) withStock++
|
||
else if (status === 1) preOccupied++
|
||
else if (status === 0) empty++
|
||
else if (status === 3) abnormal++
|
||
}
|
||
})
|
||
})
|
||
var total = withStock + preOccupied + empty + abnormal
|
||
var usageRate = total > 0 ? (((withStock + preOccupied) / total) * 100).toFixed(1) : 0
|
||
this.statistics = { total, withStock, preOccupied, empty, abnormal, usageRate }
|
||
}
|
||
```
|
||
|
||
### 7.3 单元格点击交互
|
||
|
||
```javascript
|
||
selectLocation(rowKey, colKey, locationInfo) {
|
||
this.selectedCell = { 行标识: rowKey, 列号: colKey, 信息: locationInfo }
|
||
this.highlightedRow = rowKey
|
||
if (locationInfo.状态 === 2) {
|
||
// 有库存,查询物料明细
|
||
this.loadMaterialDetail(locationInfo.库位编号)
|
||
} else {
|
||
// 非有库存状态,显示库位详情
|
||
this.showLocationDetail(locationInfo)
|
||
}
|
||
}
|
||
|
||
// 查询库位物料明细
|
||
loadMaterialDetail(locationCode) {
|
||
this.materialLoading = true
|
||
this.materialLocationCode = locationCode
|
||
var param = []
|
||
param[0] = ['库位编号_check', 1]
|
||
param[1] = ['库位编号', locationCode]
|
||
var Data = this.CreateData('1', '仓储管理_三楼仓库库位物料_查询数据', param)
|
||
this.getTable(Data).then(response => {
|
||
this.materialList = response.data || []
|
||
this.materialDialogVisible = true
|
||
this.materialLoading = false
|
||
}).catch(() => {
|
||
this.materialLoading = false
|
||
})
|
||
}
|
||
|
||
// 显示库位详情
|
||
showLocationDetail(locationInfo) {
|
||
this.detailInfo = {
|
||
库位编号: locationInfo.库位编号,
|
||
库位名称: locationInfo.库位名称,
|
||
区域: locationInfo.区域,
|
||
状态: this.getStatusLabel(locationInfo.状态),
|
||
状态描述: this.getStatusDescription(locationInfo.状态)
|
||
}
|
||
this.detailDialogVisible = true
|
||
}
|
||
```
|
||
|
||
### 7.4 状态映射方法
|
||
|
||
```javascript
|
||
// 获取状态显示文字
|
||
getStatusLabel(status) {
|
||
var map = { 0: '空', 1: '预', 2: '存', 3: '异' }
|
||
return map[status] || '未知'
|
||
}
|
||
|
||
// 获取状态完整描述
|
||
getStatusDescription(status) {
|
||
var map = {
|
||
0: '空闲库位,可存放物料',
|
||
1: '预占或待处理,库位已被预留',
|
||
2: '有库存,库位上存放有物料',
|
||
3: '异常或禁用,库位不可使用'
|
||
}
|
||
return map[status] || '未知状态'
|
||
}
|
||
|
||
// 获取状态图标类名
|
||
getStatusIcon(status) {
|
||
var map = {
|
||
0: 'el-icon-minus',
|
||
1: 'el-icon-time',
|
||
2: 'el-icon-box',
|
||
3: 'el-icon-warning'
|
||
}
|
||
return map[status] || 'el-icon-question'
|
||
}
|
||
```
|
||
|
||
### 7.5 自动刷新
|
||
|
||
```javascript
|
||
// 切换自动刷新
|
||
handleAutoRefreshChange(val) {
|
||
if (val) {
|
||
this.startAutoRefresh()
|
||
} else {
|
||
this.stopAutoRefresh()
|
||
}
|
||
}
|
||
|
||
startAutoRefresh() {
|
||
this.stopAutoRefresh()
|
||
var self = this
|
||
this.refreshTimer = setInterval(function() {
|
||
self.loadLocationData()
|
||
}, this.refreshInterval * 1000)
|
||
}
|
||
|
||
stopAutoRefresh() {
|
||
if (this.refreshTimer) {
|
||
clearInterval(this.refreshTimer)
|
||
this.refreshTimer = null
|
||
}
|
||
}
|
||
```
|
||
|
||
<br/>
|
||
|
||
## 八、页面样式设计
|
||
|
||
参考立库可视化组件的样式方案,保持一致的设计语言。
|
||
|
||
### 8.1 核心样式类
|
||
|
||
| 类名 | 用途 | 参考来源 |
|
||
| --- | --- | --- |
|
||
| `.warehouse-table` | 矩阵表格 | 立库 `.warehouse-table` 复用 |
|
||
| `.location-cell` | 库位单元格 | 立库 `.warehouse-cell` 调整命名 |
|
||
| `.status-0` | 空闲库位灰色 | 立库 `.status-0` 复用 |
|
||
| `.status-1` | 预占橙色 | 立库 `.status-1`(橙色),新增 |
|
||
| `.status-2` | 有库存绿色 | 立库 `.status-2` 复用 |
|
||
| `.status-3` | 异常红色 | 新增,区别于立库锁库蓝色 |
|
||
| `.selected-cell` | 选中蓝色边框 | 立库 `.selected-cell` 复用 |
|
||
| `.highlighted-row` | 行高亮 | 立库 `.highlighted-row` 复用 |
|
||
| `.cell-tooltip` | 悬浮提示 | 立库 `.cell-tooltip` 复用 |
|
||
| `.legend-color` | 图例色块 | 立库 `.legend-color` 复用 |
|
||
|
||
### 8.2 大屏适配
|
||
|
||
参考立库可视化组件的响应式断点:
|
||
|
||
```scss
|
||
// 全屏大屏:默认 1920px
|
||
.warehouse-table {
|
||
min-width: 1200px;
|
||
.location-cell { min-width: 40px; height: 40px; }
|
||
}
|
||
|
||
// 中等屏幕:1400px 以下
|
||
@media (max-width: 1400px) {
|
||
.warehouse-table {
|
||
min-width: 900px;
|
||
.location-cell { min-width: 35px; height: 35px; }
|
||
}
|
||
}
|
||
|
||
// 小屏幕:992px 以下
|
||
@media (max-width: 992px) {
|
||
.warehouse-table {
|
||
min-width: 700px;
|
||
.location-cell { min-width: 30px; height: 30px; }
|
||
}
|
||
}
|
||
```
|
||
|
||
### 8.3 与立库样式的差异
|
||
|
||
| 差异项 | 立库 | 三楼仓库 |
|
||
| --- | --- | --- |
|
||
| 异常状态颜色 | 锁库=天蓝色 `skyblue` | 异常=红色 `#f56c6c` |
|
||
| 状态数量 | 4 种 | 3-4 种(取决于现场确认) |
|
||
| 单元格内容 | 纯状态值 | 含库位信息的对象 |
|
||
|
||
<br/>
|
||
|
||
## 九、功能实现流程
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A["开始:三楼仓库可视化"] --> B["页面 created 调用 loadLocationData"]
|
||
B --> C["构造请求参数:区域、库位编号、状态"]
|
||
C --> D["调用 仓储管理_三楼仓库库位_查询数据"]
|
||
D --> E{"后端返回数据格式"}
|
||
E -- "矩阵格式" --> F["直接渲染矩阵"]
|
||
E -- "扁平列表" --> G["前端调用 transformToMatrix 转换为矩阵"]
|
||
F --> H["更新统计卡片、图例、矩阵"]
|
||
G --> H
|
||
H --> I["用户操作"]
|
||
I --> J{"操作类型"}
|
||
J -- "切换区域" --> K["更新 areaFilter 并重新 loadLocationData"]
|
||
J -- "切换状态筛选" --> L["前端筛选 filteredData 并重新统计"]
|
||
J -- "输入库位编号搜索" --> M["高亮匹配库位"]
|
||
J -- "切换显示模式" --> N["切换文字/图标"]
|
||
J -- "点击库位" --> O{"库位状态"}
|
||
O -- "有库存" --> P["调用 仓储管理_三楼仓库库位物料_查询数据"]
|
||
P --> Q["弹出物料信息表格弹窗"]
|
||
O -- "非有库存" --> R["弹出库位详情描述弹窗"]
|
||
J -- "开启自动刷新" --> S["启动定时器,按间隔重新 loadLocationData"]
|
||
S --> I
|
||
K --> H
|
||
L --> H
|
||
```
|
||
|
||
<br/>
|
||
|
||
## 十、待确认事项
|
||
|
||
| 序号 | 事项 | 影响 | 建议 |
|
||
| --- | --- | --- | --- |
|
||
| 1 | 三楼仓库的物理布局和库位编码规则 | 决定矩阵行列定义和编码规则 | 需仓库现场确认区域划分、排/列号规则 |
|
||
| 2 | 库位状态分类是否与立库一致 | 决定状态数量、颜色和业务含义 | 建议与仓库确认是否需要"预占"和"异常"状态 |
|
||
| 3 | 自动刷新频率 | 刷新频率影响服务器压力 | 建议默认 1 分钟,大屏场景可配置 |
|
||
| 4 | 后端是否可返回矩阵格式数据 | 影响前端转换复杂度 | 建议后端返回扁平列表,前端转换为矩阵,职责更清晰 |
|
||
| 5 | 库位数据是否与立库共用表还是独立表 | 影响后端接口是否复用 | 需后端确认三楼仓库库位数据所在表 |
|
||
| 6 | 是否需要导出功能 | 需求文档未提及,但立库已预留 | 建议本期暂不实现,预留后续扩展 |
|
||
| 7 | 三楼仓库库位数量规模 | 影响是否需要分页和性能优化 | 需现场确认库位总数,若少于 100 个可一屏展示不分页 |
|
||
|
||
<br/>
|
||
|
||
## 十一、影响范围
|
||
|
||
### 11.1 新增文件
|
||
|
||
| 文件 | 说明 |
|
||
| --- | --- |
|
||
| `src/views/WarehouseManagement/ThirdFloorWarehouse/index.vue` | 三楼仓库可视化页面组件 |
|
||
|
||
### 11.2 新增后端接口
|
||
|
||
| 接口名 | 说明 |
|
||
| --- | --- |
|
||
| `仓储管理_三楼仓库库位_查询数据` | 查询三楼仓库库位列表及状态 |
|
||
| `仓储管理_三楼仓库库位物料_查询数据` | 按库位编号查询物料明细 |
|
||
|
||
### 11.3 不受影响
|
||
|
||
- 立库可视化组件 `WarehouseVisualization` 不受影响
|
||
- 库位管理 `LocationManagement` 不受影响
|
||
- 物料库位 `MaterialLocation` 不受影响
|
||
- 其他仓储业务页面不受影响
|
||
|
||
<br/>
|
||
|
||
## 十二、验收清单
|
||
|
||
| 序号 | 验收项 | 验收方式 |
|
||
| --- | --- | --- |
|
||
| 1 | 三楼仓库可视化页面可正常加载并展示所有库位 | 打开页面,确认矩阵展示正常 |
|
||
| 2 | 不同状态的库位用不同颜色区分,图例说明清晰 | 检查图例与矩阵颜色对应 |
|
||
| 3 | 统计面板数据与实际库位状态一致 | 手工统计库位数量与面板数据对比 |
|
||
| 4 | 点击有库存的库位可查看物料详情 | 点击绿色库位,弹窗显示物料编号、名称、图号、库存数量等 |
|
||
| 5 | 点击空闲库位可查看库位基本信息 | 点击灰色库位,弹窗显示库位编号、状态说明等 |
|
||
| 6 | 区域筛选和状态筛选功能正常 | 切换筛选条件,矩阵刷新并统计更新 |
|
||
| 7 | 库位编号搜索可定位到对应库位 | 输入库位编号,点击搜索,目标库位高亮 |
|
||
| 8 | 刷新数据后页面状态更新正确 | 点击刷新按钮,矩阵重新加载 |
|
||
| 9 | 自动刷新开启后定时更新 | 开启自动刷新,等待自动刷新触发,确认数据更新 |
|
||
| 10 | 文字/图标两种显示模式切换正常 | 切换显示模式,确认单元格内容变化 |
|
||
| 11 | 大屏展示布局合理,文字清晰可读 | 在 1920px 宽度下检查布局和字体 |
|
||
| 12 | 不影响现有立库可视化功能 | 切换到立库可视化页面,确认功能正常 |
|
||
| 13 | 分页功能正常(如库位行数较多) | 切换分页,确认分页数据正确 |
|
||
|
||
<br/>
|
||
|
||
## 十三、风险与回退
|
||
|
||
### 13.1 风险
|
||
|
||
| 风险 | 影响 | 缓解措施 |
|
||
| --- | --- | --- |
|
||
| 三楼仓库库位数据与立库数据结构差异较大 | 可能需要单独设计接口和前端组件 | 复用立库可视化交互设计模式,仅数据层调整 |
|
||
| 库位编码规则未确认 | 矩阵行列定义无法确定 | 先与仓库确认编码规则再开发,避免返工 |
|
||
| 库位状态分类未确认 | 状态值和颜色方案无法确定 | 先与仓库确认状态需求再定义映射 |
|
||
| 库位数量规模未知 | 影响性能和分页设计 | 预留分页方案,小规模时可一屏展示 |
|
||
| 后端接口未就绪 | 前端无法联调 | 前端先用模拟数据开发,接口就绪后对接 |
|
||
|
||
### 13.2 回退方式
|
||
|
||
- 该功能为新增页面,不修改现有任何组件
|
||
- 如有问题,直接移除 `ThirdFloorWarehouse` 目录和对应菜单配置即可回退
|
||
- 不影响其他任何仓储页面功能
|
||
|
||
<br/>
|
||
|
||
## 十四、发布步骤
|
||
|
||
1. 后端部署库位查询和物料详情查询接口
|
||
2. 后端配置三楼仓库可视化的菜单数据(路由、菜单名称、图标等)
|
||
3. 发布前端代码(`ThirdFloorWarehouse/index.vue`)
|
||
4. 清浏览器缓存后进入系统
|
||
5. 在仓储管理菜单下打开三楼仓库可视化页面
|
||
6. 验证库位矩阵展示与仓库实际布局一致
|
||
7. 验证统计卡片数据准确
|
||
8. 验证点击库位可查看物料详情或库位详情
|
||
9. 验证筛选、搜索、刷新、自动刷新等功能正常
|
||
10. 由仓库人员在现场环境实际使用并确认数据正确性
|
||
|
||
<br/>
|
||
|
||
## 十五、实施拆分
|
||
|
||
### 开发步骤
|
||
|
||
| 步骤 | 内容 | 前置依赖 |
|
||
| --- | --- | --- |
|
||
| 1 | 与仓库确认物理布局、库位编码规则、状态分类 | 无 |
|
||
| 2 | 后端新增库位查询和物料详情查询接口 | 步骤 1 |
|
||
| 3 | 前端创建 `ThirdFloorWarehouse/index.vue` 页面框架 | 步骤 1 |
|
||
| 4 | 实现矩阵数据加载和转换逻辑 | 步骤 2、3 |
|
||
| 5 | 实现统计卡片、图例、矩阵渲染 | 步骤 4 |
|
||
| 6 | 实现单元格点击交互和弹窗 | 步骤 5 |
|
||
| 7 | 实现筛选、搜索、分页功能 | 步骤 5 |
|
||
| 8 | 实现自动刷新功能 | 步骤 4 |
|
||
| 9 | 大屏适配和样式调优 | 步骤 7 |
|
||
| 10 | 联调测试 | 步骤 9 |
|
||
|
||
<br/>
|
||
|
||
修改人:Ld 修改时间:2026-06-30
|