docs: add product-lines batch fill design and plan
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
e6c8a9c88d
commit
5942feb06e
2 files changed
+775
No files matched your search
@@ -0,0 +1,176 @@
|
||||
# 入库明细:复制首行属性 + 储物格起止批量填充
|
||||
|
||||
> 日期: 2026-07-28
|
||||
> 状态: 已确认
|
||||
> 范围: web-admin(前端为主,复用现有储物格列表接口)
|
||||
> 关联模块: 生产任务产出(细胞产品)、细胞产品管理
|
||||
|
||||
## 1. 背景
|
||||
|
||||
生产任务「任务执行」→「产出(细胞产品)」新增弹窗中,入库明细按「入库份数」生成多行。业务侧常出现:
|
||||
|
||||
1. 多行规格、预计细胞数量、活率相同,逐行填写费时
|
||||
2. 储物格需按盒内连续位置分配,且可能跨多个盒子
|
||||
|
||||
现有能力:每行独立远程下拉选格;表单内不可重复;已占用格置灰;支持「造血干一键填充」(与本需求无关)。
|
||||
|
||||
## 2. 目标
|
||||
|
||||
在**新增**入库明细区域提供两类快捷操作:
|
||||
|
||||
| 能力 | 说明 |
|
||||
|------|------|
|
||||
| 复制首行属性 | 将第 1 行的规格、预计细胞数量、活率复制到其余行 |
|
||||
| 储物格起止批量填充 | 选择同盒起始格与结束格,填充当前仍为空的储物格行;支持多次执行以跨盒 |
|
||||
|
||||
编辑单条产出时不展示入库明细表,故**不提供**上述按钮。
|
||||
|
||||
## 3. 需求确认
|
||||
|
||||
| 维度 | 决策 |
|
||||
|------|------|
|
||||
| 储物格填充交互 | **起始 + 结束** |
|
||||
| 份数与区间数量 | 区间可用格数 ≥ 空行数 N 时取前 N 格;不足则失败提示 |
|
||||
| 区间内占用格 | **不允许**;区间内任一占用则整段失败 |
|
||||
| 跨盒 | 单次必须同盒;跨盒通过**多次填充**(每次只填空行) |
|
||||
| 已选储物格的行 | **不覆盖**;只填 `storageSlotId` 为空的行 |
|
||||
| 复制字段 | 仅 `specName`、`expectedCellCount`、`viability` |
|
||||
| 不复制 | 产品编码、代次、储物格 |
|
||||
| 落地页面 | ① `TaskOutputProductDialog.vue` ② `cell-product/index.vue` 新增弹窗 |
|
||||
|
||||
## 4. 界面
|
||||
|
||||
### 4.1 入口位置
|
||||
|
||||
「入库明细」标题行右侧(`product-lines-head`),新增两个描边按钮(带图标,符合按钮图标规范):
|
||||
|
||||
1. **复制首行属性**
|
||||
2. **批量填储物格**
|
||||
|
||||
仅 `!isEdit` 且存在入库明细表时显示。
|
||||
|
||||
### 4.2 批量填储物格弹层
|
||||
|
||||
小型 `el-dialog`(或内嵌确认区),字段:
|
||||
|
||||
- 起始储物格:与现有行内一致的远程 `el-select`(可检索编号)
|
||||
- 结束储物格:同上
|
||||
- 提示文案:须同盒;区间内不可有占用格;只填充当前空行;可多次操作以跨盒
|
||||
|
||||
底栏:取消 / 确定(Close / Check 图标)。
|
||||
|
||||
遮罩无背景模糊;`label-position="top"`。
|
||||
|
||||
## 5. 行为细则
|
||||
|
||||
### 5.1 复制首行属性
|
||||
|
||||
1. 若明细行数 < 2:提示「至少两行明细才能复制」
|
||||
2. 取第 1 行 `specName`、`expectedCellCount`、`viability`,写入第 2…n 行
|
||||
3. 成功提示:已复制到其余行
|
||||
|
||||
允许首行三字段为空(仍复制空值,便于统一清空)。
|
||||
|
||||
### 5.2 批量填储物格(单次)
|
||||
|
||||
```
|
||||
N = 明细中 storageSlotId 为空的行数
|
||||
若 N = 0 → 提示「没有可填充的空行」并结束
|
||||
|
||||
用户选择 startId、endId
|
||||
若未选齐 → 校验提示
|
||||
|
||||
通过 facilityNodeId 判断 start、end 是否同盒
|
||||
若不同盒 → 提示「起始与结束须在同一盒子内」
|
||||
|
||||
请求 fetchStorageSlotList({ facilityNodeId }) 获取同盒全部格子
|
||||
按现有盒内排序(order_num / 行列,与 storage-slot-options 一致)排序
|
||||
|
||||
在有序列表中定位 start、end 下标
|
||||
若找不到 → 提示格不存在
|
||||
若 startIndex > endIndex → 交换或按「从起始到结束」失败提示(推荐:自动按较小下标到较大下标取闭区间,避免用户选反)
|
||||
|
||||
range = slots[from..to](闭区间)
|
||||
若 range 中任一格不可用(非空 / occupied)→ 提示「区间内存在已占用储物格,请调整起止范围」
|
||||
|
||||
fromFormUsed = 本表单所有行已选的 storageSlotId(含非空行)
|
||||
availableInRange = range 中 id 不在 fromFormUsed 的格
|
||||
(注:因只填空行,fromFormUsed 主要排除其他行已选;区间本身已要求全部空闲)
|
||||
|
||||
若 availableInRange.length < N → 提示「区间内可用储物格不足(需要 N 个,实际 M 个)」
|
||||
|
||||
将 availableInRange 前 N 个依次赋给空行(按明细行从上到下)
|
||||
将选中格 ensure 进各行下拉 options,保证回显
|
||||
成功提示:已为 N 行填充储物格
|
||||
```
|
||||
|
||||
### 5.3 多次填充(跨盒)
|
||||
|
||||
用户可再次点击「批量填储物格」,对新的同盒起止重复 5.2。
|
||||
每次 `N` 只统计**当前仍为空**的行,直至全部填完或用户停止。
|
||||
|
||||
### 5.4 与现有校验的关系
|
||||
|
||||
提交前仍走:
|
||||
|
||||
- 表单内储物格不可重复(`validateUniqueStorageSlotIds`)
|
||||
- 行间重复选格自动清空的 watch 保持不变
|
||||
|
||||
批量填充赋值后不应触发「误清空」:一次写入互不重复的 id。
|
||||
|
||||
## 6. 技术方案
|
||||
|
||||
### 6.1 方案选择
|
||||
|
||||
**前端计算区间**(复用 `GET /web/admin/storage-facility-slots?facilityNodeId=`),不新增区间专用 API。
|
||||
|
||||
理由:单次限制同盒,盒内格数量通常有限;规则变更成本低。
|
||||
|
||||
### 6.2 代码落点
|
||||
|
||||
| 项 | 路径 |
|
||||
|----|------|
|
||||
| 生产任务产出弹窗 | `web-admin/src/views/production/production-work-order/TaskOutputProductDialog.vue` |
|
||||
| 细胞产品新增 | `web-admin/src/views/production/cell-product/index.vue` |
|
||||
| 可选抽取 | `web-admin/src/utils/storage-slot-range-fill.ts`(排序、切区间、校验、取前 N) |
|
||||
|
||||
两页 UI 与逻辑保持一致;优先抽公共函数避免分叉。
|
||||
|
||||
### 6.3 起止下标方向
|
||||
|
||||
**采用:自动规范化闭区间**(`from = min(iStart,iEnd)`, `to = max(...)`)。
|
||||
用户先选编号较大的格再选较小的格也能工作,减少操作摩擦。
|
||||
|
||||
### 6.4 起始/结束格的 facilityNodeId
|
||||
|
||||
远程下拉选项当前可能只有 `id`/`name`。实现时需保证能得到 `facilityNodeId`:
|
||||
|
||||
- 方案:选中后按 id `ensure`/`fetch` 补全;或扩展 select-options 返回 `facilityNodeId`(若响应已有则直接用,见 CRUD `_slot_to_dict` / select-options 已含该字段时可透出到前端 option 类型)。
|
||||
|
||||
## 7. 非目标
|
||||
|
||||
- 不改编辑态单条产出表单
|
||||
- 不自动修改「入库份数」
|
||||
- 不支持单次跨盒区间
|
||||
- 不跳过区间内占用格(占用即失败)
|
||||
- 不覆盖已填写的储物格
|
||||
- 不改后端占用模型与提交接口契约
|
||||
|
||||
## 8. 验收要点
|
||||
|
||||
1. 复制首行:两行以上时,其余行规格/细胞数/活率与首行一致;编码与储物格不变
|
||||
2. 同盒连续空格、空行数 ≤ 区间长度:空行被按序填满;已有格的行不变
|
||||
3. 跨盒:两次操作可分别填两盒,最终空行可全部填完
|
||||
4. 不同盒起止:失败提示,明细不变
|
||||
5. 区间含占用:失败提示,明细不变
|
||||
6. 可用格 < 空行:失败提示,明细不变
|
||||
7. 无空行时点批量填:提示无空行
|
||||
8. 提交时仍校验一格一物、表单内不重复
|
||||
9. 两处入口(任务产出 + 细胞产品新增)行为一致
|
||||
|
||||
## 9. 测试建议
|
||||
|
||||
- 手动:入库份数 5,先填 2 行手选格,再批量填同盒区间覆盖剩余 3 行
|
||||
- 手动:份数 8,盒 A 填 5、盒 B 填 3
|
||||
- 手动:故意选跨盒起止、区间含占用、区间过短,确认提示与数据未改
|
||||
- 回归:造血干一键填充、产品编码生成、代次、提交占用冲突提示
|
||||
Reference in new issue
Block a user