# 库位管理:货架批量出库设计 > 日期: 2026-07-28 > 状态: 已确认 > 范围: web-admin 库位管理 + 货架列表字段小幅 enrichment(无新批量出库 API) > 参考 Demo: `docs/demos/storage-facility-batch-outbound-demo.html`(方案 B) ## 1. 背景与目标 当前库位管理中,储物格点击仅打开「储物格明细」弹窗,出库须在弹窗「在库物品」操作列逐条完成,大批量出库效率低。 **目标**:在货架界面直接勾选占用储物格,工具栏一键批量出库,减少进出弹窗次数。 **非目标**: - 不新增后端批量出库事务 API(可后续升级) - 不提供「全选占用」 - 不改小程序端 - 不改变明细弹窗内单条「出库」行为 ## 2. 已确认决策 | 项 | 决策 | |----|------| | 交互形态 | 方案 B:占用格左上角常驻勾选框 | | 点格 vs 点框 | 勾选框切换选中;格子其它区域仍打开储物格明细 | | 二次确认 | 需要:确认框列出已选格子编码 + 物品名称 | | 全选 | 不要,仅逐格勾选 | | 出库实现 | 方案 1:前端串行调用现有 `fetchRemoveOccupancy` | | 占用 ID | 货架列表 enrichment 增加 `storedOccupancyId` | ## 3. 界面与交互 ### 3.1 格子 - 占用格(`slotStatus === '占用'` 且存在在库占用)左上角常驻勾选框;空格不显示勾选框、不可选。 - 勾选框 `@click.stop`:切换选中;点格子其它区域:`handleOpenOccupancyDialog`(现有行为)。 - 选中态:勾选框主色填充 + 格子浅绿描边(Fresh Mint:`--primary` / `#ecfdf5` / `#a7f3d0`)。 - 删除按钮(×)行为不变,继续 `@click.stop`。 ### 3.2 工具栏(叶子节点且已有格子时) 顺序(符合列表工具栏「已选在前」约定): 1. 「已选 N 项」文案 2. 「出库已选」主按钮(`type="primary"`,N=0 时禁用;执行中 loading) 3. 现有「批量生成格子 / 清空格子」等按钮 不提供「全选占用」「清空选择」独立按钮(取消勾选即可;切换节点会清空选择)。 ### 3.3 确认与结果 - 点击「出库已选」→ `ElMessageBox.confirm`(与现有单条出库确认一致),正文列出每项:`格子编码` + `物品名称`(无名称则物品编码);条目过多时正文可截断并注明「等共 N 项」。 - 确认后串行出库;成功提示「出库成功,共 N 项」。 - 刷新当前叶子节点格子列表与左侧占用统计;清空选择。 ### 3.4 选择生命周期 - 切换左侧树节点、执行「清空格子」后:清空选择。 - 筛选关键词变化:保留仍在当前可见且仍占用的选中项;不可见或已空的自动剔除。 - 单格在明细弹窗内出库成功后:若该格在选中集合中,从集合移除并刷新。 ## 4. 数据流与错误处理 ### 4.1 占用 ID 现有 `enrich_slots_with_stored_cell_products` 仅附带展示字段,不含占用记录 id。 单条出库接口 `PUT /web/admin/storage-slot-occupancies/{occupancy_id}/remove` 需要 occupancy id。 **改动**:enrichment 时写入 `storedOccupancyId = occ.id`(当前 `occupancy_status == stored` 的那条;一格一物)。 前端选中结构示例: ```ts { slotId, occupancyId, slotCode, itemName } ``` 仅当 `storedOccupancyId` 存在时允许勾选。 ### 4.2 执行流程 1. 用户勾选 → `selectedMap`(key=`slotId`) 2. 确认框展示列表 3. 按选中顺序串行 `await fetchRemoveOccupancy(occupancyId)` 4. 全部成功:刷新货架 + 统计;清空选择;成功提示 5. 过程中主按钮 loading,防止重复提交 ### 4.3 错误处理 - 第 k 条失败:停止后续请求;已成功的 k-1 条保留出库结果;提示「已出库 M 项,第 M+1 项失败:…」(或接口返回文案);刷新货架;清理选中中已不存在/已空的项。 - 用户取消确认:无请求。 - 不做事务级「全成或全败」(若业务后续强制要求,另开批量 API 变更)。 ## 5. 改动清单 | 文件 | 改动 | |------|------| | `backend/app/crud/storage_occupancy.py` | `enrich_slots_with_stored_cell_products` 增加 `storedOccupancyId` | | `web-admin/src/views/operations/storage-facility/index.vue` | 勾选 UI、工具栏、确认与串行出库、选中态样式、生命周期清理 | | `docs/demos/storage-facility-batch-outbound-demo.html` | 参考用 Demo(非上线依赖) | ## 6. 验收标准 1. 占用格有勾选框,空格无;点框选中,点格身仍开明细。 2. N>0 时可点「出库已选」;确认框列出编码 + 名称。 3. 确认后逐条出库,货架与左侧统计刷新,选择清空。 4. 中途失败:已成功保留,提示已出库数与失败原因,货架刷新。 5. 切换树节点后选择清空;明细弹窗单条出库行为不变。 6. 货架接口响应中占用格含 `storedOccupancyId`。 ## 7. 测试要点 - 手动入库「其他」物品与细胞产品占用格均可勾选并出库。 - 仅空格的叶子节点:无勾选框,「出库已选」禁用。 - 筛选命中部分占用格时,仅能勾选可见占用格。 - 出库后格子变为空,勾选框消失。