From 7dd20a8dd323147400575538ef90d87bd9dbdd6d Mon Sep 17 00:00:00 2001
From: zhouz <>
Date: Wed, 22 Jul 2026 13:38:20 +0800
Subject: [PATCH] =?UTF-8?q?Revert=20"docs:=20=E5=87=BA=E5=BA=93=E5=8D=95?=
=?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=A1=B5=E9=9D=A2=E5=AE=9E=E7=8E=B0=E8=AE=A1?=
=?UTF-8?q?=E5=88=92"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This reverts commit c6edf4b8d90bf4a26506f564f67ed65aeebf944c.
---
.../plans/2026-07-22-outbound-create-plan.md | 1325 -----------------
1 file changed, 1325 deletions(-)
delete mode 100644 docs/superpowers/plans/2026-07-22-outbound-create-plan.md
diff --git a/docs/superpowers/plans/2026-07-22-outbound-create-plan.md b/docs/superpowers/plans/2026-07-22-outbound-create-plan.md
deleted file mode 100644
index 850fc5dc..00000000
--- a/docs/superpowers/plans/2026-07-22-outbound-create-plan.md
+++ /dev/null
@@ -1,1325 +0,0 @@
-# 出库单新增页面 实现计划
-
-> **面向 AI 代理的工作者:** 必需子技能:使用 superpowers:subagent-driven-development(推荐)或 superpowers:executing-plans 逐任务实现此计划。步骤使用复选框(`- [ ]`)语法来跟踪进度。
-
-**目标:** 将出入库单主表的新增弹窗重构为出库单新增页面,包含主表表单 + 出库明细 table,支持从库存选择带入和手动新增汇总两种方式。
-
-**架构:** 前端大弹窗页面(form.vue 重构),主表用 `useVbenForm` 水平布局,明细用 vxe-table 内嵌,新增库存选择弹窗和手动汇总弹窗两个子组件。后端新增 `createWithDetails` 接口,事务写入主表 + 明细,库存查询 SQL 写在 Mapper XML 中。通过 Feign 调用 base 模块的 CodeGenApi 生成单据号。
-
-**技术栈:** Java 17, Spring Boot 3, MyBatis-Plus, OpenFeign, Vue 3, Ant Design Vue Next, Vxe Table
-
----
-
-### 文件结构
-
-```
-# 后端 — 新增/修改
-nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/
-├── framework/rpc/config/RpcConfiguration.java [新增] Feign 客户端配置
-├── controller/admin/iostorinv/vo/
-│ ├── IostorInvWithDetailsSaveReqVO.java [新增] 带明细的创建请求 VO
-│ └── AvailableInventoryVO.java [新增] 可用库存查询结果 VO
-├── dal/mysql/iostorinvdtl/IostorinvDtlMapper.java [修改] 新增 selectAvailableInventory 方法
-├── resources/mapper/iostorinvdtl/IostorinvDtlMapper.xml [修改] 新增库存查询 SQL
-├── service/iostorinv/IostorInvService.java [修改] 新增 createWithDetails 方法
-├── service/iostorinv/IostorInvServiceImpl.java [修改] 实现 createWithDetails
-├── service/iostorinvdtl/IostorinvDtlService.java [修改] 新增 batchInsert 方法
-├── service/iostorinvdtl/IostorinvDtlServiceImpl.java [修改] 实现 batchInsert
-└── controller/admin/iostorinv/IostorInvController.java [修改] 新增 createWithDetails 端点
-
-# 前端 — 新增/修改
-nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/
-├── api/wms/iostorinv/index.ts [修改] 新增类型和 API
-├── views/wms/iostorinv/modules/
-│ ├── form.vue [重构] 大弹窗 + 主表 + 明细
-│ ├── inventory-select.vue [新增] 库存选择弹窗
-│ └── manual-detail.vue [新增] 手动新增汇总弹窗
-└── packages/constants/src/dict-enum.ts [修改] 新增 out_bill_type 字典类型
-```
-
----
-
-### 任务 1:后端 — Feign 客户端配置
-
-**文件:**
-- 创建:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/framework/rpc/config/RpcConfiguration.java`
-
-- [ ] **步骤 1:创建 RpcConfiguration,注册 CodeGenApi Feign 客户端**
-
-```java
-package cn.code.nl.module.wms.framework.rpc.config;
-
-import cn.code.nl.module.base.api.codegen.CodeGenApi;
-import org.springframework.cloud.openfeign.EnableFeignClients;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * WMS 模块 RPC 配置
- *
- * @author zhouz
- */
-@Configuration(value = "wmsRpcConfiguration", proxyBeanMethods = false)
-@EnableFeignClients(clients = {CodeGenApi.class})
-public class RpcConfiguration {
-}
-```
-
-> **注意:** 需要确认 `nl-module-wms-server` 的 pom.xml 已依赖 `nl-module-base-api`,否则 Feign 接口编译不到。如缺失,添加依赖:
-> ```xml
->
-> cn.code.nl
-> nl-module-base-api
-> ${project.version}
->
-> ```
-
-- [ ] **步骤 2:Commit**
-
-```bash
-git add nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/framework/rpc/config/RpcConfiguration.java
-git commit -m "feat: 添加 WMS 模块 Feign 客户端配置,注册 CodeGenApi"
-```
-
----
-
-### 任务 2:后端 — 新增请求 VO 和库存查询 VO
-
-**文件:**
-- 创建:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/iostorinv/vo/IostorInvWithDetailsSaveReqVO.java`
-- 创建:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/iostorinv/vo/AvailableInventoryVO.java`
-
-- [ ] **步骤 1:创建带明细的创建请求 VO**
-
-```java
-package cn.code.nl.module.wms.controller.admin.iostorinv.vo;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.Valid;
-import jakarta.validation.constraints.NotEmpty;
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
-import java.util.List;
-
-/**
- * 管理后台 - 出库单新增(含明细)Request VO
- *
- * @author zhouz
- */
-@Schema(description = "管理后台 - 出库单新增(含明细)Request VO")
-@Data
-public class IostorInvWithDetailsSaveReqVO {
-
- @Schema(description = "单据类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "生产领料出库")
- @NotEmpty(message = "单据类型不能为空")
- private String billType;
-
- @Schema(description = "仓库标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "12635")
- @NotEmpty(message = "仓库标识不能为空")
- private String storId;
-
- @Schema(description = "仓库编码")
- private String storCode;
-
- @Schema(description = "仓库名称", example = "原料仓库")
- private String storName;
-
- @Schema(description = "业务日期", requiredMode = Schema.RequiredMode.REQUIRED)
- @NotNull(message = "业务日期不能为空")
- private LocalDateTime bizDate;
-
- @Schema(description = "备注")
- private String remark;
-
- @Schema(description = "出库明细列表", requiredMode = Schema.RequiredMode.REQUIRED)
- @NotEmpty(message = "请至少添加一条出库明细")
- @Valid
- private List details;
-
- /**
- * 出库明细 VO
- */
- @Data
- public static class DetailVO {
-
- @Schema(description = "物料编码", requiredMode = Schema.RequiredMode.REQUIRED)
- @NotEmpty(message = "物料编码不能为空")
- private String materialCode;
-
- @Schema(description = "物料标识")
- private String materialId;
-
- @Schema(description = "批次/子卷号")
- private String pcsn;
-
- @Schema(description = "出库重量", requiredMode = Schema.RequiredMode.REQUIRED)
- @NotNull(message = "出库重量不能为空")
- private BigDecimal planQty;
-
- @Schema(description = "计量单位标识")
- private String qtyUnitId;
-
- @Schema(description = "计量单位名称")
- private String qtyUnitName;
-
- @Schema(description = "备注")
- private String remark;
-
- @Schema(description = "来源单据号")
- private String sourceBillCode;
-
- @Schema(description = "来源单据类型")
- private String sourceBillType;
-
- @Schema(description = "来源单据明细标识")
- private String sourceBilldtlId;
- }
-}
-```
-
-- [ ] **步骤 2:创建可用库存查询结果 VO**
-
-```java
-package cn.code.nl.module.wms.controller.admin.iostorinv.vo;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import java.math.BigDecimal;
-
-/**
- * 管理后台 - 可用库存查询结果 VO
- *
- * @author zhouz
- */
-@Schema(description = "管理后台 - 可用库存查询结果 VO")
-@Data
-public class AvailableInventoryVO {
-
- @Schema(description = "载具编码(箱号)")
- private String vehicleCode;
-
- @Schema(description = "批次/子卷号")
- private String pcsn;
-
- @Schema(description = "物料编码")
- private String materialCode;
-
- @Schema(description = "物料标识")
- private String materialId;
-
- @Schema(description = "组盘数量")
- private BigDecimal qty;
-
- @Schema(description = "冻结数量")
- private BigDecimal frozenQty;
-
- @Schema(description = "可用数量")
- private BigDecimal availableQty;
-
- @Schema(description = "计量单位标识")
- private String qtyUnitId;
-
- @Schema(description = "计量单位名称")
- private String qtyUnitName;
-
- @Schema(description = "来源单据号")
- private String extCode;
-
- @Schema(description = "来源单据类型")
- private String extType;
-
- @Schema(description = "来源单据明细号")
- private String extDtlCode;
-
- @Schema(description = "仓库标识")
- private String storId;
-
- @Schema(description = "仓库编码")
- private String storCode;
-
- @Schema(description = "仓库名称")
- private String storName;
-}
-```
-
-- [ ] **步骤 3:Commit**
-
-```bash
-git add nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/iostorinv/vo/IostorInvWithDetailsSaveReqVO.java nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/iostorinv/vo/AvailableInventoryVO.java
-git commit -m "feat: 新增出库单带明细创建请求 VO 和可用库存查询 VO"
-```
-
----
-
-### 任务 3:后端 — Mapper XML 新增库存查询 SQL
-
-**文件:**
-- 修改:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/mysql/iostorinvdtl/IostorinvDtlMapper.java`
-- 修改:`nl-module-wms/nl-module-wms-server/src/main/resources/mapper/iostorinvdtl/IostorinvDtlMapper.xml`
-
-- [ ] **步骤 1:在 IostorinvDtlMapper 接口中新增方法**
-
-在文件末尾(`}` 之前)添加:
-
-```java
- /**
- * 查询可用库存(wms_group_plate 关联 wms_structattr)
- *
- * @param storId 仓库标识(必传)
- * @param materialCode 物料编码(可选)
- * @param pcsn 批次(可选)
- * @param vehicleCode 载具编码(可选)
- * @return 可用库存列表
- */
- List selectAvailableInventory(
- @Param("storId") String storId,
- @Param("materialCode") String materialCode,
- @Param("pcsn") String pcsn,
- @Param("vehicleCode") String vehicleCode);
-```
-
-同时新增 import:
-
-```java
-import cn.code.nl.module.wms.controller.admin.iostorinv.vo.AvailableInventoryVO;
-import org.apache.ibatis.annotations.Param;
-```
-
-- [ ] **步骤 2:在 IostorinvDtlMapper.xml 中新增 SQL**
-
-替换空的 XML 文件内容为:
-
-```xml
-
-
-
-
-
-
-
-
-
-```
-
-- [ ] **步骤 3:Commit**
-
-```bash
-git add nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/mysql/iostorinvdtl/IostorinvDtlMapper.java nl-module-wms/nl-module-wms-server/src/main/resources/mapper/iostorinvdtl/IostorinvDtlMapper.xml
-git commit -m "feat: 新增可用库存查询 SQL(group_plate 关联 structattr)"
-```
-
----
-
-### 任务 4:后端 — Service 层新增 createWithDetails 和 batchInsert
-
-**文件:**
-- 修改:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/iostorinv/IostorInvService.java`
-- 修改:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/iostorinv/IostorInvServiceImpl.java`
-- 修改:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/iostorinvdtl/IostorinvDtlService.java`
-- 修改:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/iostorinvdtl/IostorinvDtlServiceImpl.java`
-
-- [ ] **步骤 1:在 IostorInvService 接口中新增方法声明**
-
-在文件末尾的 `}` 之前添加:
-
-```java
- /**
- * 创建出库单(含明细)
- *
- * @param reqVO 创建请求(含明细列表)
- * @return 出入单标识
- */
- String createIostorInvWithDetails(@Valid IostorInvWithDetailsSaveReqVO reqVO);
-```
-
-新增 import:
-
-```java
-import cn.code.nl.module.wms.controller.admin.iostorinv.vo.IostorInvWithDetailsSaveReqVO;
-```
-
-- [ ] **步骤 2:在 IostorInvServiceImpl 中实现 createIostorInvWithDetails**
-
-添加 `@Resource` 注入:
-
-```java
- @Resource
- private cn.code.nl.module.base.api.codegen.CodeGenApi codeGenApi;
-
- @Resource
- private cn.code.nl.module.wms.dal.mysql.iostorinvdtl.IostorinvDtlMapper iostorinvDtlMapper;
-```
-
-新增方法实现(在文件末尾 `}` 之前):
-
-```java
- @Override
- @Transactional(rollbackFor = Exception.class)
- public String createIostorInvWithDetails(IostorInvWithDetailsSaveReqDTO reqVO) {
- // 1. 调用 base 模块生成单据号
- CodeGenerateReqDTO codeReq = new CodeGenerateReqDTO();
- codeReq.setRuleCode("IO_CODE");
- CommonResult codeResult = codeGenApi.generate(codeReq);
- if (codeResult == null || codeResult.getData() == null) {
- throw exception(IOSTOR_INV_BILL_CODE_GENERATE_FAIL);
- }
- String billCode = codeResult.getData();
-
- // 2. 构建主表数据
- IostorInvDO master = new IostorInvDO();
- master.setBillCode(billCode);
- master.setIoType("OUT");
- master.setBillType(reqVO.getBillType());
- master.setBizDate(reqVO.getBizDate());
- master.setStorId(reqVO.getStorId());
- master.setStorCode(reqVO.getStorCode());
- master.setStorName(reqVO.getStorName());
- master.setBillStatus("生成");
- master.setRemark(reqVO.getRemark());
- master.setDetailCount(reqVO.getDetails().size());
-
- // 3. 计算总重量
- BigDecimal totalWeight = reqVO.getDetails().stream()
- .map(IostorInvWithDetailsSaveReqVO.DetailVO::getPlanQty)
- .reduce(BigDecimal.ZERO, BigDecimal::add);
- master.setTotalWeight(totalWeight);
-
- // 4. 插入主表
- iostorInvMapper.insert(master);
-
- // 5. 批量插入明细
- String iostorinvId = master.getIostorinvId();
- int seqNo = 1;
- for (IostorInvWithDetailsSaveReqVO.DetailVO detail : reqVO.getDetails()) {
- IostorinvDtlDO dtl = new IostorinvDtlDO();
- dtl.setIostorinvId(iostorinvId);
- dtl.setSeqNo(seqNo++);
- dtl.setMaterialCode(detail.getMaterialCode());
- dtl.setMaterialId(detail.getMaterialId());
- dtl.setPcsn(detail.getPcsn());
- dtl.setPlanQty(detail.getPlanQty());
- dtl.setUnassignQty(detail.getPlanQty()); // 初始未分配 = 计划数量
- dtl.setAssignQty(BigDecimal.ZERO);
- dtl.setQtyUnitId(detail.getQtyUnitId());
- dtl.setQtyUnitName(detail.getQtyUnitName());
- dtl.setRemark(detail.getRemark());
- dtl.setSourceBillCode(detail.getSourceBillCode());
- dtl.setSourceBillType(detail.getSourceBillType());
- dtl.setSourceBilldtlId(detail.getSourceBilldtlId());
- iostorinvDtlMapper.insert(dtl);
- }
-
- return iostorinvId;
- }
-```
-
-新增 import:
-
-```java
-import cn.code.nl.module.base.api.codegen.CodeGenApi;
-import cn.code.nl.module.base.api.codegen.dto.CodeGenerateReqDTO;
-import cn.code.nl.module.framework.common.pojo.CommonResult;
-import cn.code.nl.module.wms.controller.admin.iostorinv.vo.IostorInvWithDetailsSaveReqVO;
-import cn.code.nl.module.wms.dal.dataobject.iostorinvdtl.IostorinvDtlDO;
-import cn.code.nl.module.wms.dal.mysql.iostorinvdtl.IostorinvDtlMapper;
-import java.math.BigDecimal;
-```
-
-- [ ] **步骤 3:在 ErrorCodeConstants 中新增错误码**
-
-修改 `nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/enums/ErrorCodeConstants.java`,在文件末尾添加:
-
-```java
- // ========== 出入库单 1-030-001-000 ==========
- ErrorCode IOSTOR_INV_BILL_CODE_GENERATE_FAIL = new ErrorCode(1_030_001_000, "单据号生成失败,请稍后重试");
-```
-
-> **注意:** 确认错误码 `1_030_001_000` 不与已有错误码冲突。如冲突则顺延。
-
-- [ ] **步骤 4:IostorinvDtlService 和 Impl 暂不改动**
-
-明细的批量插入直接在 `IostorInvServiceImpl` 中通过 `iostorinvDtlMapper.insert()` 完成,无需改动 DtlService 接口。跳过此改动。
-
-- [ ] **步骤 5:Commit**
-
-```bash
-git add nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/iostorinv/IostorInvService.java nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/iostorinv/IostorInvServiceImpl.java nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/enums/ErrorCodeConstants.java
-git commit -m "feat: 实现出库单带明细创建 Service(含 CodeGen 单据号生成)"
-```
-
----
-
-### 任务 5:后端 — Controller 新增 createWithDetails 端点
-
-**文件:**
-- 修改:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/iostorinv/IostorInvController.java`
-
-- [ ] **步骤 1:新增 createWithDetails 方法和可用库存查询方法**
-
-在类末尾的 `}` 之前添加:
-
-```java
- @PostMapping("/create-with-details")
- @Operation(summary = "创建出库单(含明细)")
- @PreAuthorize("@ss.hasPermission('wms:iostor-inv:create')")
- public CommonResult createIostorInvWithDetails(
- @Valid @RequestBody IostorInvWithDetailsSaveReqVO reqVO) {
- return success(iostorInvService.createIostorInvWithDetails(reqVO));
- }
-```
-
-新增 import:
-
-```java
-import cn.code.nl.module.wms.controller.admin.iostorinv.vo.IostorInvWithDetailsSaveReqVO;
-```
-
-- [ ] **步骤 2:Commit**
-
-```bash
-git add nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/iostorinv/IostorInvController.java
-git commit -m "feat: 新增出库单带明细创建 API 端点 POST /create-with-details"
-```
-
----
-
-### 任务 6:前端 — API 层扩展
-
-**文件:**
-- 修改:`nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/api/wms/iostorinv/index.ts`
-
-- [ ] **步骤 1:新增请求类型和 API 方法**
-
-在文件末尾的 `export function exportIostorInv` 之前添加类型定义,并在最后添加 API 方法:
-
-```typescript
-// --- 出库单带明细创建 ---
-
-/** 出库明细项 */
-export interface OutboundDetail {
- materialCode: string;
- materialId?: string;
- pcsn?: string;
- planQty: number;
- qtyUnitId?: string;
- qtyUnitName?: string;
- remark?: string;
- sourceBillCode?: string;
- sourceBillType?: string;
- sourceBilldtlId?: string;
-}
-
-/** 出库单创建请求(含明细) */
-export interface OutboundCreateReq {
- billType: string;
- storId: string;
- storCode?: string;
- storName?: string;
- bizDate: string;
- remark?: string;
- details: OutboundDetail[];
-}
-
-/** 可用库存项 */
-export interface AvailableInventory {
- vehicleCode: string;
- pcsn: string;
- materialCode: string;
- materialId: string;
- qty: number;
- frozenQty: number;
- availableQty: number;
- qtyUnitId: string;
- qtyUnitName: string;
- extCode: string;
- extType: string;
- extDtlCode: string;
- storId: string;
- storCode: string;
- storName: string;
-}
-
-/** 可用库存查询参数 */
-export interface AvailableInventoryQuery {
- storId: string;
- materialCode?: string;
- pcsn?: string;
- vehicleCode?: string;
-}
-```
-
-在文件末尾(`export function exportIostorInv` 之后)添加:
-
-```typescript
-/** 创建出库单(含明细) */
-export function createIostorInvWithDetails(data: OutboundCreateReq) {
- return requestClient.post('/wms/iostor-inv/create-with-details', data);
-}
-
-/** 查询可用库存 */
-export function getAvailableInventory(params: AvailableInventoryQuery) {
- return requestClient.get(
- '/wms/iostorinvdtl/available-inventory',
- { params },
- );
-}
-```
-
-- [ ] **步骤 2:Commit**
-
-```bash
-git add nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/api/wms/iostorinv/index.ts
-git commit -m "feat: 前端 API 层新增出库单带明细创建和可用库存查询"
-```
-
----
-
-### 任务 7:后端 — 可用库存查询 Controller(补充)
-
-> 前面任务 3 只在 Mapper 加了 SQL,但前端需要一个 HTTP 接口调用。需要在 Controller 或现有 Controller 中暴露。
-
-**文件:**
-- 修改:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/iostorinvdtl/IostorinvDtlController.java`
-
-- [ ] **步骤 1:在 IostorinvDtlController 中新增可用库存查询端点**
-
-在类末尾 `}` 之前添加:
-
-```java
- @GetMapping("/available-inventory")
- @Operation(summary = "查询可用库存(组盘关联仓位)")
- @PreAuthorize("@ss.hasPermission('wms:iostor-inv:query')")
- public CommonResult> getAvailableInventory(
- @RequestParam("storId") String storId,
- @RequestParam(value = "materialCode", required = false) String materialCode,
- @RequestParam(value = "pcsn", required = false) String pcsn,
- @RequestParam(value = "vehicleCode", required = false) String vehicleCode) {
- List list = iostorinvDtlMapper.selectAvailableInventory(
- storId, materialCode, pcsn, vehicleCode);
- return success(list);
- }
-```
-
-注入 Mapper:
-
-```java
- @Resource
- private IostorinvDtlMapper iostorinvDtlMapper;
-```
-
-新增 import:
-
-```java
-import cn.code.nl.module.wms.controller.admin.iostorinv.vo.AvailableInventoryVO;
-import cn.code.nl.module.wms.dal.mysql.iostorinvdtl.IostorinvDtlMapper;
-import jakarta.annotation.Resource;
-```
-
-- [ ] **步骤 2:Commit**
-
-```bash
-git add nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/iostorinvdtl/IostorinvDtlController.java
-git commit -m "feat: 新增可用库存查询端点 GET /available-inventory"
-```
-
----
-
-### 任务 8:前端 — 重构 form.vue(主表表单 + 明细 Table)
-
-**文件:**
-- 修改:`nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/wms/iostorinv/modules/form.vue`
-
-- [ ] **步骤 1:重写 form.vue — 脚本部分**
-
-```vue
-
-```
-
-- [ ] **步骤 2:重写 form.vue — 模板部分**
-
-```vue
-
-
-
-
基本信息
-
-
-
-
-
出库明细
-
-
- 从库存选择
-
-
- 手动新增汇总
-
-
-
-
-
-
-
- 删除
-
-
-
-
-
-
-
-
-
-
-```
-
-> **注意:** 模板中使用了 `VxeTable` 组件,需要确认该组件在项目中的实际名称和用法。参考 `index.vue` 中 `useVbenVxeGrid` 的使用方式。如 `VxeTable` 不可用,改用 `vxe-grid` 直接绑定。
-
-- [ ] **步骤 3:Commit**
-
-```bash
-git add nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/wms/iostorinv/modules/form.vue
-git commit -m "feat: 重构出库单新增表单为带明细的单页弹窗"
-```
-
----
-
-### 任务 9:前端 — 新增库存选择弹窗组件
-
-**文件:**
-- 创建:`nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/wms/iostorinv/modules/inventory-select.vue`
-
-- [ ] **步骤 1:创建 inventory-select.vue**
-
-```vue
-
-
-
-
-
-
-
-```
-
-> **注意:** `getMaterialBaseList` 接口参数需要确认。如接口仅支持 `MaterialBaseListReqDTO` 条件查询而非批量按编码查询,可能需要使用循环调用 `getMaterialBaseByCode` 或调整查询方式。此处为简化说明假设支持批量查询。
-
-- [ ] **步骤 2:Commit**
-
-```bash
-git add nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/wms/iostorinv/modules/inventory-select.vue
-git commit -m "feat: 新增库存选择弹窗组件(支持同箱号联动勾选)"
-```
-
----
-
-### 任务 10:前端 — 新增手动新增汇总弹窗组件
-
-**文件:**
-- 创建:`nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/wms/iostorinv/modules/manual-detail.vue`
-
-- [ ] **步骤 1:创建 manual-detail.vue**
-
-```vue
-
-
-
-
-
-
-
-
出库重量:
-
-
{{ formData.qtyUnitName }}
-
-
-
-
-
-
-```
-
-> **注意:** MaterialSelectModal 在此处的集成方式需要参考原组件的 `useVbenModal` 用法。当前简化示例——实际集成时应在 script 中用 `useVbenModal({ connectedComponent: MaterialSelectModal })` 打开物料选择弹窗。
-
-- [ ] **步骤 2:Commit**
-
-```bash
-git add nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/wms/iostorinv/modules/manual-detail.vue
-git commit -m "feat: 新增手动新增汇总弹窗组件"
-```
-
----
-
-### 任务 11:前端 — 字典常量补充 & 最终联调验证
-
-**文件:**
-- 修改:`nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/packages/constants/src/dict-enum.ts`(可选,取决于实际使用方式)
-- 不强制修改,因为已在 form.vue 中通过 `getSimpleDictDataList()` 动态过滤 `out_bill_type`
-
-- [ ] **步骤 1:验证 checklist**
-
-1. 确认 `nl-module-wms-server` 的 pom.xml 包含 `nl-module-base-api` 依赖
-2. 确认 `IostorinvDtlController` 文件存在,且注入 `IostorinvDtlMapper` 无编译错误
-3. 启动后端服务,调用 `POST /wms/iostor-inv/create-with-details` 接口验证
-4. 调用 `GET /wms/iostorinvdtl/available-inventory?storId=xxx` 验证库存查询
-5. 前端页面打开"出库新增"弹窗,验证:
- - 仓库下拉加载正确
- - 业务类型下拉加载正确(out_bill_type 字典)
- - 单据号显示占位提示
- - "从库存选择"弹窗:只显示对应仓库的库存,同箱号联动勾选
- - "手动新增汇总"弹窗:选物料、填重量
- - 明细增删后,明细数和总重量自动更新
- - 提交保存成功
-
----
-
-## 自检
-
-**1. 规格覆盖度:**
-- [x] 主表字段映射 → 任务 8(form.vue schema)+ 任务 4(ServiceImpl 字段赋值)
-- [x] 明细字段映射 → 任务 8(detailList 结构)+ 任务 4(dtl.setXxx)
-- [x] 方式 A 从库存选择 → 任务 9(inventory-select.vue)+ 任务 3(Mapper SQL)+ 任务 7(Controller)
-- [x] 方式 B 手动新增 → 任务 10(manual-detail.vue)
-- [x] 单据号 CodeGenApi → 任务 1(RpcConfig)+ 任务 4(ServiceImpl 调用)
-- [x] 一对多联动 → 任务 9(gridEvents.checkboxChange)
-- [x] planQty/unassignQty/assignQty → 任务 4(ServiceImpl)
-- [x] 箱号不存 → 任务 8(vehicleCode 仅 detailList 前端字段)
-- [x] 库存查询 Mapper XML → 任务 3
-- [x] 错误处理 → 任务 4(异常抛出)+ 任务 8(前端校验)
-- [x] 不考虑的内容(入库/编辑/分配/回传)→ 已明确范围,无遗漏
-
-**2. 占位符扫描:** 无待定/TODO/占位符
-
-**3. 类型一致性:**
-- `OutboundCreateReq` / `OutboundDetail` → 前端 API 层(任务 6)和 form.vue(任务 8)一致
-- `IostorInvWithDetailsSaveReqVO` → 后端 Controller(任务 5)和 Service(任务 4)一致
-- `AvailableInventoryVO` → Mapper(任务 3)、Controller(任务 7)、前端 API(任务 6)一致
-- `AvailableInventory` → 前端 API(任务 6)和 inventory-select(任务 9)一致