From 7a7ec7c75eb744dc9ad217daad5c2f1503a31cf6 Mon Sep 17 00:00:00 2001 From: zhouz <> Date: Thu, 6 Aug 2026 09:21:08 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=96=B0=E5=A2=9E=E6=9C=A8=E7=AE=B1?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E6=9F=A5=E8=AF=A2=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E5=BA=93=E5=AD=98=E4=BF=A1=E6=81=AF=E6=9F=A5=E8=AF=A2=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .image/立库仓位分块图.png | Bin 0 -> 155174 bytes .../plans/2026-08-05-box-info-query.md | 57 ++++ .../plans/2026-08-05-empty-box-transport.md | 281 ++++++++++++++++++ .../plans/2026-08-05-struct-inventory-type.md | 63 ++++ .../specs/2026-08-05-box-info-query-design.md | 35 +++ .../module/wms/api/emptybox/EmptyBoxApi.java | 33 ++ .../dto/EmptyBoxInboundCreateReq.java | 17 ++ .../dto/EmptyBoxInboundCreateResp.java | 18 ++ .../dto/EmptyBoxOutboundCreateReq.java | 14 + .../dto/EmptyBoxOutboundCreateResp.java | 18 ++ .../wms/api/emptybox/EmptyBoxApiImpl.java | 36 +++ .../admin/boxinfo/BoxInfoController.java | 45 +++ .../admin/boxinfo/vo/BoxInfoPageReqVO.java | 28 ++ .../admin/boxinfo/vo/BoxInfoRespVO.java | 57 ++++ .../admin/emptybox/EmptyBoxController.java | 46 +++ .../structAttr/vo/StrucAttrPageReqVO.java | 5 +- .../admin/structAttr/vo/StrucAttrRespVO.java | 6 +- .../wms/dal/dataobject/boxinfo/BoxInfoDO.java | 37 +++ .../wms/dal/dataobject/boxtype/BoxTypeDO.java | 22 ++ .../structAttr/EmptyBoxRowCandidate.java | 16 + .../dataobject/structAttr/StrucAttrDO.java | 6 +- .../wms/dal/mysql/boxinfo/BoxInfoMapper.java | 52 ++++ .../wms/dal/mysql/boxtype/BoxTypeMapper.java | 17 ++ .../dal/mysql/structAttr/StrucAttrMapper.java | 34 ++- .../enums/emptybox/EmptyBoxStatusEnum.java | 21 ++ .../structattr/StructInventoryTypeEnum.java | 20 ++ .../wms/service/boxinfo/BoxInfoService.java | 19 ++ .../service/boxinfo/BoxInfoServiceImpl.java | 32 ++ .../wms/service/emptybox/EmptyBoxService.java | 24 ++ .../service/emptybox/EmptyBoxServiceImpl.java | 264 ++++++++++++++++ .../service/moveinv/MoveInvServiceImpl.java | 6 +- .../code/nl/module/wms/task/EmptyBoxTask.java | 29 ++ .../mapper/boxinfo/BoxInfoMapper.xml | 83 ++++++ .../mapper/boxtype/BoxTypeMapper.xml | 14 + .../mapper/structAttr/StrucAttrMapper.xml | 116 ++++++++ .../src/api/wms/boxinfo/index.ts | 41 +++ .../src/api/wms/structAttr/index.ts | 1 + .../src/views/wms/boxinfo/data.ts | 92 ++++++ .../src/views/wms/boxinfo/index.vue | 46 +++ .../src/views/wms/structAttr/data.ts | 24 ++ sql/mysql/wms_box_info_menu.sql | 59 ++++ sql/mysql/wms_box_info_test_data.sql | 65 ++++ sql/mysql/wms_empty_box.sql | 39 +++ sql/mysql/wms_structattr_inventory_type.sql | 4 + sql/mysql/wms_structattr_layout_full.sql | 80 +++++ 45 files changed, 2017 insertions(+), 5 deletions(-) create mode 100644 .image/立库仓位分块图.png create mode 100644 docs/superpowers/plans/2026-08-05-box-info-query.md create mode 100644 docs/superpowers/plans/2026-08-05-empty-box-transport.md create mode 100644 docs/superpowers/plans/2026-08-05-struct-inventory-type.md create mode 100644 docs/superpowers/specs/2026-08-05-box-info-query-design.md create mode 100644 nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/EmptyBoxApi.java create mode 100644 nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/dto/EmptyBoxInboundCreateReq.java create mode 100644 nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/dto/EmptyBoxInboundCreateResp.java create mode 100644 nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/dto/EmptyBoxOutboundCreateReq.java create mode 100644 nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/dto/EmptyBoxOutboundCreateResp.java create mode 100644 nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/api/emptybox/EmptyBoxApiImpl.java create mode 100644 nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/boxinfo/BoxInfoController.java create mode 100644 nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/boxinfo/vo/BoxInfoPageReqVO.java create mode 100644 nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/boxinfo/vo/BoxInfoRespVO.java create mode 100644 nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/emptybox/EmptyBoxController.java create mode 100644 nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/dataobject/boxinfo/BoxInfoDO.java create mode 100644 nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/dataobject/boxtype/BoxTypeDO.java create mode 100644 nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/dataobject/structAttr/EmptyBoxRowCandidate.java create mode 100644 nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/mysql/boxinfo/BoxInfoMapper.java create mode 100644 nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/mysql/boxtype/BoxTypeMapper.java create mode 100644 nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/enums/emptybox/EmptyBoxStatusEnum.java create mode 100644 nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/enums/structattr/StructInventoryTypeEnum.java create mode 100644 nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/boxinfo/BoxInfoService.java create mode 100644 nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/boxinfo/BoxInfoServiceImpl.java create mode 100644 nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/emptybox/EmptyBoxService.java create mode 100644 nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/emptybox/EmptyBoxServiceImpl.java create mode 100644 nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/task/EmptyBoxTask.java create mode 100644 nl-module-wms/nl-module-wms-server/src/main/resources/mapper/boxinfo/BoxInfoMapper.xml create mode 100644 nl-module-wms/nl-module-wms-server/src/main/resources/mapper/boxtype/BoxTypeMapper.xml create mode 100644 nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/api/wms/boxinfo/index.ts create mode 100644 nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/wms/boxinfo/data.ts create mode 100644 nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/wms/boxinfo/index.vue create mode 100644 sql/mysql/wms_box_info_menu.sql create mode 100644 sql/mysql/wms_box_info_test_data.sql create mode 100644 sql/mysql/wms_empty_box.sql create mode 100644 sql/mysql/wms_structattr_inventory_type.sql create mode 100644 sql/mysql/wms_structattr_layout_full.sql diff --git a/.image/立库仓位分块图.png b/.image/立库仓位分块图.png new file mode 100644 index 0000000000000000000000000000000000000000..a9189fce67025857301d40a980a9825903417bc0 GIT binary patch literal 155174 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%0Ap#%f(4KIxKxN-0@;uH}{E+T*39jjrQ; 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

19-<7@)Gk=S{(}c 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

4`Pon(Ms$M)+Kx{*&Ct-mMO90;K|eI3lnuN#qPQ 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 S)U%g*WT0nqv+DXUzx@XlSK_(= literal 0 HcmV?d00001 diff --git a/docs/superpowers/plans/2026-08-05-box-info-query.md b/docs/superpowers/plans/2026-08-05-box-info-query.md new file mode 100644 index 00000000..8f90532a --- /dev/null +++ b/docs/superpowers/plans/2026-08-05-box-info-query.md @@ -0,0 +1,57 @@ +# 木箱信息只读查询实现计划 + +> **面向 AI 代理的工作者:** 在当前会话内按步骤实现并逐项验证。 + +**目标:** 在WMS模块的“基础模块”下提供 `wmw_boxinfo` 的只读分页菜单和查询页面。 + +**架构:** 后端使用 Controller → Service → MyBatis XML Mapper 的只读链路;前端使用独立API和VXE分页表格;菜单由幂等SQL配置。所有层均不暴露写能力。 + +**技术栈:** Java 17、Spring Boot、MyBatis-Plus分页、MyBatis XML、Vue 3、TypeScript、Vben Admin、VXE Table、MySQL。 + +--- + +### 任务1:后端只读分页 + +**文件:** +- 创建:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/boxinfo/vo/BoxInfoPageReqVO.java` +- 创建:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/boxinfo/vo/BoxInfoRespVO.java` +- 创建:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/mysql/boxinfo/BoxInfoMapper.java` +- 创建:`nl-module-wms/nl-module-wms-server/src/main/resources/mapper/boxinfo/BoxInfoMapper.xml` +- 创建:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/boxinfo/BoxInfoService.java` +- 创建:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/boxinfo/BoxInfoServiceImpl.java` +- 创建:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/boxinfo/BoxInfoController.java` + +- [ ] 定义与 `wmw_boxinfo` 字段一一对应的只读响应对象。 +- [ ] 定义继承 `PageParam` 的查询参数,支持木箱号、物料和状态筛选。 +- [ ] 在Mapper XML中实现动态条件、`box_id DESC`排序和分页查询。 +- [ ] Service接收请求对象并返回 `PageResult`。 +- [ ] Controller仅暴露 `GET /wms/box-info/page`,权限为 `wms:box-info:query`。 +- [ ] 运行模块编译并确认成功。 + +### 任务2:前端只读列表 + +**文件:** +- 创建:`nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/api/wms/boxinfo/index.ts` +- 创建:`nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/wms/boxinfo/data.ts` +- 创建:`nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/wms/boxinfo/index.vue` + +- [ ] 定义木箱信息类型和分页API。 +- [ ] 定义五个查询条件和全部基础信息列表列。 +- [ ] 创建仅含查询、刷新和分页的页面,不配置复选框及操作按钮。 +- [ ] 运行前端类型检查并确认新增文件无错误。 + +### 任务3:菜单权限 + +**文件:** +- 创建:`sql/mysql/wms_box_info_menu.sql` + +- [ ] 查询基础管理菜单ID和项目菜单字段结构。 +- [ ] 编写“木箱信息”页面菜单及 `wms:box-info:query` 按钮权限的幂等SQL。 +- [ ] 执行SQL并查询确认菜单记录唯一。 + +### 任务4:联调验证 + +- [ ] 确认后端编译成功且Mapper XML无语法错误。 +- [ ] 确认前端API路径与Controller一致。 +- [ ] 确认菜单组件路径与页面文件一致。 +- [ ] 确认代码中不存在木箱信息写接口或写按钮。 diff --git a/docs/superpowers/plans/2026-08-05-empty-box-transport.md b/docs/superpowers/plans/2026-08-05-empty-box-transport.md new file mode 100644 index 00000000..d2ce22ac --- /dev/null +++ b/docs/superpowers/plans/2026-08-05-empty-box-transport.md @@ -0,0 +1,281 @@ +# 空木箱出入库实现计划 + +> **面向 AI 代理的工作者:** 必需子技能:使用 superpowers:subagent-driven-development(推荐)或 superpowers:executing-plans 逐任务实现此计划。步骤使用复选框(`- [ ]`)语法来跟踪进度。 + +**目标:** 实现基于木箱规格、仓位优先级和任务回调的空木箱入库与先进先出出库能力,并向其他模块开放创建接口。 + +**架构:** WMS API 模块定义跨模块契约,WMS Server 的 `EmptyBoxService` 统一负责选位、条件抢锁、木箱状态和任务生命周期;`EmptyBoxTask` 只将完成、取消事件转发给 Service。候选排与候选木箱由 Mapper XML 限量筛选,优先级和并发重试由 Java 控制。 + +**技术栈:** Java 17、Spring Boot、OpenFeign、MyBatis/MyBatis-Plus、MySQL、现有 TransportTaskApi 与 CodeGenApi。 + +--- + +## 文件结构 + +- 创建 `sql/mysql/wms_empty_box.sql`:木箱规格表、木箱实例状态字段、锁字典和 `BOX_CODE` 编码规则变更。 +- 创建 `nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/EmptyBoxApi.java`:跨模块创建接口。 +- 创建 `nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/dto/*.java`:入库、出库请求与响应对象。 +- 创建 `nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/dataobject/boxtype/BoxTypeDO.java`:木箱规格数据对象。 +- 创建 `nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/dataobject/boxinfo/BoxInfoDO.java`:木箱实例数据对象。 +- 创建 `nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/mysql/boxtype/BoxTypeMapper.java` 与对应 XML:按规格编码查询。 +- 扩展 `nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/mysql/boxinfo/BoxInfoMapper.java` 与对应 XML:插入、状态更新、先进先出候选查询。 +- 扩展 `StrucAttrMapper.java` 与 `StrucAttrMapper.xml`:同规格候选排、空排、条件锁定、任务绑定、完成和取消。 +- 创建 `nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/emptybox/EmptyBoxService.java` 和 `EmptyBoxServiceImpl.java`:领域业务。 +- 创建 `nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/api/emptybox/EmptyBoxApiImpl.java`:跨模块接口实现。 +- 创建 `nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/emptybox/EmptyBoxController.java`:管理端接口。 +- 创建 `nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/task/EmptyBoxTask.java`:任务事件转发。 +- 修改木箱查询 VO/XML:展示状态、入库时间和出库时间。 + +### 任务 1:数据库与枚举基础 + +**文件:** +- 创建:`sql/mysql/wms_empty_box.sql` +- 创建:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/enums/emptybox/EmptyBoxStatusEnum.java` + +- [ ] **步骤 1:编写幂等数据库脚本** + +脚本创建 `wms_boxtype`,向 `wmw_boxinfo` 增加 `status varchar(1)` 和 `out_time varchar(25)`,向 `wms_lock_type` 增加值 `8/9`,并幂等创建 `BOX_CODE` 编码规则。`material_code` 建唯一索引;`wmw_boxinfo` 增加 `(material_code, status, insert_time)` 普通索引以支持 FIFO。 + +- [ ] **步骤 2:增加木箱状态枚举** + +```java +public enum EmptyBoxStatusEnum { + PENDING_INBOUND("0"), IN_STOCK("1"), OUTBOUND("2"); + private final String code; +} +``` + +- [ ] **步骤 3:校验脚本和 Java 格式** + +运行:`git diff --check -- sql/mysql/wms_empty_box.sql nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/enums/emptybox/EmptyBoxStatusEnum.java` + +预期:无输出,退出码 0。 + +### 任务 2:跨模块 API 契约 + +**文件:** +- 创建:`nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/EmptyBoxApi.java` +- 创建:`nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/dto/EmptyBoxInboundCreateReq.java` +- 创建:`nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/dto/EmptyBoxInboundCreateResp.java` +- 创建:`nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/dto/EmptyBoxOutboundCreateReq.java` +- 创建:`nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/dto/EmptyBoxOutboundCreateResp.java` + +- [ ] **步骤 1:定义带注解校验的请求对象** + +入库请求包含必填 `deviceCode`、`materialCode`;出库请求包含必填 `materialCode`。 + +- [ ] **步骤 2:定义响应对象** + +入库响应包含 `taskId`、`boxNo`、`targetStructCode`;出库响应包含 `taskId`、`boxNo`、`destinationPoint`。 + +- [ ] **步骤 3:定义 Feign API** + +```java +@PostMapping(PREFIX + "/createInbound") +CommonResult createInbound( + @Valid @RequestBody EmptyBoxInboundCreateReq req); + +@PostMapping(PREFIX + "/createOutbound") +CommonResult createOutbound( + @Valid @RequestBody EmptyBoxOutboundCreateReq req); +``` + +- [ ] **步骤 4:编译 API 模块** + +运行:`./mvnw -pl nl-module-wms/nl-module-wms-api -am -DskipTests compile` + +预期:`BUILD SUCCESS`。 + +### 任务 3:规格与木箱持久化 + +**文件:** +- 创建:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/dataobject/boxtype/BoxTypeDO.java` +- 创建:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/dataobject/boxinfo/BoxInfoDO.java` +- 创建:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/mysql/boxtype/BoxTypeMapper.java` +- 创建:`nl-module-wms/nl-module-wms-server/src/main/resources/mapper/boxtype/BoxTypeMapper.xml` +- 修改:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/mysql/boxinfo/BoxInfoMapper.java` +- 修改:`nl-module-wms/nl-module-wms-server/src/main/resources/mapper/boxinfo/BoxInfoMapper.xml` + +- [ ] **步骤 1:映射规格表和木箱实例表** + +`BoxTypeDO` 精确对应 `wms_boxtype`;`BoxInfoDO` 对应 `wmw_boxinfo`,包含新增状态和出库时间。 + +- [ ] **步骤 2:在 XML 中实现规格查询** + +```sql +SELECT id, material_code, material_name, lash_num, + box_length, box_width, box_height +FROM wms_boxtype +WHERE material_code = #{materialCode} +``` + +- [ ] **步骤 3:在 BoxInfo XML 实现实例写入和状态迁移** + +增加 `insertPendingInbound`、`completeInbound`、`deletePendingInbound`、`completeOutbound`;完成更新均同时校验原状态,避免重复回调静默成功。 + +- [ ] **步骤 4:实现 FIFO 候选查询** + +关联 `wms_structattr.storagevehicle_code = wmw_boxinfo.box_no`,筛选在库、仓位可用且未锁定的数据,按 `insert_time ASC, box_id ASC` 排序并限制候选数量。 + +- [ ] **步骤 5:检查 XML 可解析性** + +运行:`xmllint --noout nl-module-wms/nl-module-wms-server/src/main/resources/mapper/boxtype/BoxTypeMapper.xml nl-module-wms/nl-module-wms-server/src/main/resources/mapper/boxinfo/BoxInfoMapper.xml` + +预期:无输出,退出码 0。 + +### 任务 4:仓位候选与条件锁 + +**文件:** +- 创建:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/dataobject/structAttr/EmptyBoxRowCandidate.java` +- 修改:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/mysql/structAttr/StrucAttrMapper.java` +- 修改:`nl-module-wms/nl-module-wms-server/src/main/resources/mapper/structAttr/StrucAttrMapper.xml` + +- [ ] **步骤 1:增加同规格候选排查询** + +按仓库、库区、块、排、层分组。候选排必须至少存在一个同规格在库空木箱,不存在其他规格木箱或组盘载具,并至少存在一个未锁定空仓位;结果限制 32 排。 + +- [ ] **步骤 2:增加整排为空候选查询** + +复用现有排维度,要求整排载具为空且至少一个可用未锁定仓位;结果限制 32 排。 + +- [ ] **步骤 3:增加入库条件锁和任务绑定** + +以 `struct_id`、未锁定、载具为空为条件将锁类型改为 `8` 并写预占码;创建任务后仅在预占码匹配时替换为任务 ID。 + +- [ ] **步骤 4:增加出库条件锁** + +以 `struct_id`、未锁定、指定木箱编码仍绑定、木箱仍为在库为条件改为锁类型 `9` 并写预占码。 + +- [ ] **步骤 5:增加完成和取消 SQL** + +入库完成绑定木箱并解锁;出库完成清空载具并解锁;取消只恢复锁和任务码。所有更新按 `task_code` 与锁类型精确匹配。 + +- [ ] **步骤 6:检查 Mapper XML** + +运行:`xmllint --noout nl-module-wms/nl-module-wms-server/src/main/resources/mapper/structAttr/StrucAttrMapper.xml` + +预期:无输出,退出码 0。 + +### 任务 5:空木箱领域服务 + +**文件:** +- 创建:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/emptybox/EmptyBoxService.java` +- 创建:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/emptybox/EmptyBoxServiceImpl.java` + +- [ ] **步骤 1:实现入库选位和预占** + +先遍历同规格候选排,再遍历空排;每排查询一个空位并条件锁定。全部失败时抛出“未找到符合条件的空木箱入库仓位”。 + +- [ ] **步骤 2:生成木箱编码并创建待入库记录** + +调用 `CodeGenApi.generate(new CodeGenerateReqDTO().setRuleCode("BOX_CODE"))`,检查远程调用结果;复制 `wms_boxtype` 规格属性到 `wmw_boxinfo`,状态设为待入库。 + +- [ ] **步骤 3:创建并下发入库任务** + +任务起点为设备号,终点为仓位,`handleCode` 为 `EMPTYBOXTASK`,`bizType` 为 `EMPTY_BOX_IN`。绑定任务 ID 后调用任务下发回滚接口。 + +- [ ] **步骤 4:实现 FIFO 出库预占** + +遍历 FIFO 候选并条件抢锁;全部失败时抛出“没有可出库的该规格空木箱”。 + +- [ ] **步骤 5:实现临时出库点负载选择** + +定义 `ZXQ_01`、`ZXQ_02` 常量,分别计算未完成任务数并加点位库存数。增加中文扩展注释,说明后续由 LMS 一次性返回出库点及占用库存;当前库存数查询方法返回 WMS 可获取的点位占用数量。相同负载固定选择 `ZXQ_01`。 + +- [ ] **步骤 6:创建并下发出库任务** + +任务起点为仓位,终点为选定出库点,`bizType` 为 `EMPTY_BOX_OUT`;响应返回任务 ID、木箱号和目的点。 + +- [ ] **步骤 7:实现完成与取消事务** + +完成时先根据任务锁确定方向:入库绑定仓位并把木箱改为在库,出库清空仓位并把木箱改为已出库;取消入库时删除待入库记录,取消出库时保留在库记录。每项更新必须恰好影响一行。 + +### 任务 6:接口与任务回调接入 + +**文件:** +- 创建:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/api/emptybox/EmptyBoxApiImpl.java` +- 创建:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/emptybox/EmptyBoxController.java` +- 创建:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/task/EmptyBoxTask.java` + +- [ ] **步骤 1:实现内部 API** + +使用 `@Resource` 注入 `EmptyBoxService`,将创建结果包装为 `CommonResult.success`。 + +- [ ] **步骤 2:实现管理端接口** + +提供 `/wms/empty-box/createInbound` 和 `/wms/empty-box/createOutbound`,返回 `CommonResult`,请求使用 `@Valid`。 + +- [ ] **步骤 3:实现任务处理器** + +```java +@Component("EMPTYBOXTASK") +public class EmptyBoxTask extends AbstractTask { + @Resource + private EmptyBoxService emptyBoxService; + + @Override + public void doHandleFinish(TaskExecuteDTO dto) { + emptyBoxService.completeTask(dto.getTaskId()); + } + + @Override + public void doHandleCancel(TaskExecuteDTO dto) { + emptyBoxService.cancelTask(dto.getTaskId()); + } +} +``` + +- [ ] **步骤 4:确认任务工厂自动发现处理器** + +检查 `WmsTaskStatusChangeConsumer` 仍通过现有 `TaskFactory` 按 `handleCode` 分发,无需加入业务分支。 + +### 任务 7:木箱查询展示状态 + +**文件:** +- 修改:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/boxinfo/vo/BoxInfoRespVO.java` +- 修改:`nl-module-wms/nl-module-wms-server/src/main/resources/mapper/boxinfo/BoxInfoMapper.xml` +- 修改:`nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/api/wms/boxinfo/model.ts` +- 修改:`nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/wms/boxinfo/data.ts` + +- [ ] **步骤 1:后端返回状态和出库时间** + +分页 SQL 增加 `status`、`out_time`,响应对象增加对应字段。 + +- [ ] **步骤 2:前端增加只读列** + +列表展示状态、入库时间、出库时间;状态使用明确文本“待入库/在库/已出库”。 + +- [ ] **步骤 3:运行前端静态检查** + +运行项目现有 ESLint 命令,仅检查本次修改的木箱信息文件。 + +预期:退出码 0。 + +### 任务 8:整体验证 + +**文件:** +- 检查本计划涉及的全部文件。 + +- [ ] **步骤 1:检查注解 SQL 和格式问题** + +运行:`rg -n "@(Select|Update|Insert|Delete)" nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/{service/emptybox,dal/mysql/boxtype,dal/mysql/boxinfo,dal/mysql/structAttr}` + +预期:没有本功能新增的注解 SQL。 + +- [ ] **步骤 2:编译 WMS 模块** + +运行:`./mvnw -pl nl-module-wms/nl-module-wms-server -am -DskipTests clean compile` + +预期:`BUILD SUCCESS`。 + +- [ ] **步骤 3:检查 XML 与差异** + +运行:`xmllint --noout nl-module-wms/nl-module-wms-server/src/main/resources/mapper/{boxtype/BoxTypeMapper.xml,boxinfo/BoxInfoMapper.xml,structAttr/StrucAttrMapper.xml}` + +运行:`git diff --check` + +预期:两条命令均退出码 0。 + +- [ ] **步骤 4:人工核对关键路径** + +确认同规格同排优先、空排回退、FIFO、条件抢锁、任务 ID 绑定、完成和取消状态迁移,以及出库响应目的点全部在代码中形成闭环。 diff --git a/docs/superpowers/plans/2026-08-05-struct-inventory-type.md b/docs/superpowers/plans/2026-08-05-struct-inventory-type.md new file mode 100644 index 00000000..02280878 --- /dev/null +++ b/docs/superpowers/plans/2026-08-05-struct-inventory-type.md @@ -0,0 +1,63 @@ +# 仓位库存类型实现计划 + +> **面向 AI 代理的工作者:** 必需子技能:使用 superpowers:subagent-driven-development(推荐)或 superpowers:executing-plans 逐任务实现此计划。步骤使用复选框(`- [ ]`)语法来跟踪进度。 + +**目标:** 新增仓位库存类型字段,并在成品、空载具、空木箱和移库完成时保持字段与实际库存一致。 + +**架构:** 库存类型使用 WMS 枚举表达,仓位完成 SQL 与载具号在同一语句中更新;移库服务读取来源类型并传给目标完成 SQL。现有选位逻辑不依赖该字段,历史数据不回填。 + +**技术栈:** Java 17、Spring Boot、MyBatis XML、MySQL、Vue/TypeScript。 + +--- + +### 任务 1:数据库字段和枚举 + +**文件:** +- 创建:`sql/mysql/wms_structattr_inventory_type.sql` +- 创建:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/enums/structattr/StructInventoryTypeEnum.java` +- 修改:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/dataobject/structAttr/StrucAttrDO.java` + +- [ ] 增加 `inventory_type varchar(1) NOT NULL DEFAULT '0'`,不包含回填 SQL。 +- [ ] 增加 `EMPTY/FINISHED_PRODUCT/EMPTY_VEHICLE/EMPTY_BOX` 枚举,编码为 `0/1/2/3`。 +- [ ] 给仓位 DO 增加 `inventoryType`。 +- [ ] 运行 `git diff --check`,预期退出码 0。 + +### 任务 2:完成 SQL 维护库存类型 + +**文件:** +- 修改:`nl-module-wms/nl-module-wms-server/src/main/resources/mapper/structAttr/StrucAttrMapper.xml` +- 修改:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/mysql/structAttr/StrucAttrMapper.java` + +- [ ] 成品入库/出库完成分别写入 `1/0`。 +- [ ] 空载具入库/出库完成分别写入 `2/0`。 +- [ ] 空木箱入库/出库完成分别写入 `3/0`。 +- [ ] 移库来源完成写入 `0`;目标完成方法增加 `inventoryType` 参数并写入来源类型。 +- [ ] 运行 `xmllint --noout StrucAttrMapper.xml`,预期退出码 0。 + +### 任务 3:移库动态转移类型 + +**文件:** +- 修改:`nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/moveinv/MoveInvServiceImpl.java` + +- [ ] 完成每条移库明细前按来源仓位编码查询仓位。 +- [ ] 来源不存在或类型为 `0` 时抛出来源仓位状态异常。 +- [ ] 将来源 `inventoryType` 传给目标仓位完成更新,然后清空来源。 +- [ ] 取消逻辑不修改库存类型。 + +### 任务 4:仓位管理展示 + +**文件:** +- 修改:仓位保存、响应、分页查询 VO。 +- 修改:`nl-ui/.../src/api/wms/structAttr/index.ts` +- 修改:`nl-ui/.../src/views/wms/structAttr/data.ts` + +- [ ] 后端 VO 增加库存类型字段。 +- [ ] 前端模型、查询条件和列表列增加库存类型,显示“空/成品/空载具/空木箱”。 +- [ ] 运行目标文件 ESLint,预期退出码 0。 + +### 任务 5:验证 + +- [ ] 应用本地数据库字段脚本,不执行历史回填。 +- [ ] 运行 WMS Server 及依赖模块编译,预期 `BUILD SUCCESS`。 +- [ ] 运行 Mapper XML、前端 ESLint 和 `git diff --check`,预期全部退出码 0。 +- [ ] 核对所有完成入口与移库动态转移路径。 diff --git a/docs/superpowers/specs/2026-08-05-box-info-query-design.md b/docs/superpowers/specs/2026-08-05-box-info-query-design.md new file mode 100644 index 00000000..d7f7da59 --- /dev/null +++ b/docs/superpowers/specs/2026-08-05-box-info-query-design.md @@ -0,0 +1,35 @@ +# 木箱信息只读查询设计 + +## 目标 + +在WMS模块的“基础模块”下新增“木箱信息”菜单,读取 `wmw_boxinfo` 表并提供分页查询。该功能只用于查看木箱基础信息,不提供新增、修改、删除、批量操作或导出能力。 + +## 后端设计 + +- 接口地址:`GET /wms/box-info/page`。 +- 权限标识:`wms:box-info:query`。 +- 查询条件:木箱号、物料编码、物料名称、是否包装、载具类型。 +- 默认按 `box_id` 倒序。 +- `wmw_boxinfo` 没有通用审计和逻辑删除字段,Mapper直接返回只读响应对象,不继承通用数据对象,也不暴露通用写方法。 +- 查询SQL写入 `BoxInfoMapper.xml`,Controller、Service 和 Mapper 均不提供写方法。 + +## 前端设计 + +- 页面路径:`views/wms/boxinfo/index.vue`。 +- 页面仅包含查询表单、刷新按钮、分页表格。 +- 不显示复选框、操作列及新增、修改、删除、导出按钮。 +- 表格展示木箱号、物料、数量、尺寸、重量、插入时间、捆扎数量、载具类型和包装状态。 + +## 菜单设计 + +- 菜单名称:木箱信息。 +- 上级菜单:WMS模块 / 基础模块。 +- 组件:`wms/boxinfo/index`。 +- 菜单权限:`wms:box-info:query`。 +- SQL采用 `NOT EXISTS` 幂等写法,同时创建页面菜单和查询按钮权限。 + +## 验证 + +- 编译 `nl-module-base`,确认Java和MyBatis XML可加载。 +- 对前端相关文件执行类型检查或项目既有检查命令。 +- 执行菜单SQL后核对菜单、权限和接口分页响应。 diff --git a/nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/EmptyBoxApi.java b/nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/EmptyBoxApi.java new file mode 100644 index 00000000..9317567d --- /dev/null +++ b/nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/EmptyBoxApi.java @@ -0,0 +1,33 @@ +package cn.code.nl.module.wms.api.emptybox; + +import cn.code.nl.framework.common.pojo.CommonResult; +import cn.code.nl.module.wms.api.emptybox.dto.EmptyBoxInboundCreateReq; +import cn.code.nl.module.wms.api.emptybox.dto.EmptyBoxInboundCreateResp; +import cn.code.nl.module.wms.api.emptybox.dto.EmptyBoxOutboundCreateReq; +import cn.code.nl.module.wms.api.emptybox.dto.EmptyBoxOutboundCreateResp; +import cn.code.nl.module.wms.enums.ApiConstants; +import jakarta.validation.Valid; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +/** + * 空木箱出入库内部接口。 + */ +@FeignClient(name = ApiConstants.NAME) +public interface EmptyBoxApi { + + String PREFIX = ApiConstants.PREFIX + "/empty-box"; + + /** + * 创建空木箱入库任务。 + */ + @PostMapping(PREFIX + "/createInbound") + CommonResult createInbound(@Valid @RequestBody EmptyBoxInboundCreateReq req); + + /** + * 创建空木箱出库任务。 + */ + @PostMapping(PREFIX + "/createOutbound") + CommonResult createOutbound(@Valid @RequestBody EmptyBoxOutboundCreateReq req); +} diff --git a/nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/dto/EmptyBoxInboundCreateReq.java b/nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/dto/EmptyBoxInboundCreateReq.java new file mode 100644 index 00000000..6e443e5d --- /dev/null +++ b/nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/dto/EmptyBoxInboundCreateReq.java @@ -0,0 +1,17 @@ +package cn.code.nl.module.wms.api.emptybox.dto; + +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +/** + * 空木箱入库创建请求。 + */ +@Data +public class EmptyBoxInboundCreateReq { + + @NotBlank(message = "设备号不能为空") + private String deviceCode; + + @NotBlank(message = "木箱规格编码不能为空") + private String materialCode; +} diff --git a/nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/dto/EmptyBoxInboundCreateResp.java b/nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/dto/EmptyBoxInboundCreateResp.java new file mode 100644 index 00000000..78e97c16 --- /dev/null +++ b/nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/dto/EmptyBoxInboundCreateResp.java @@ -0,0 +1,18 @@ +package cn.code.nl.module.wms.api.emptybox.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 空木箱入库创建结果。 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class EmptyBoxInboundCreateResp { + + private Long taskId; + private String boxNo; + private String targetStructCode; +} diff --git a/nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/dto/EmptyBoxOutboundCreateReq.java b/nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/dto/EmptyBoxOutboundCreateReq.java new file mode 100644 index 00000000..316f15b1 --- /dev/null +++ b/nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/dto/EmptyBoxOutboundCreateReq.java @@ -0,0 +1,14 @@ +package cn.code.nl.module.wms.api.emptybox.dto; + +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +/** + * 空木箱出库创建请求。 + */ +@Data +public class EmptyBoxOutboundCreateReq { + + @NotBlank(message = "木箱规格编码不能为空") + private String materialCode; +} diff --git a/nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/dto/EmptyBoxOutboundCreateResp.java b/nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/dto/EmptyBoxOutboundCreateResp.java new file mode 100644 index 00000000..2a46b999 --- /dev/null +++ b/nl-module-wms/nl-module-wms-api/src/main/java/cn/code/nl/module/wms/api/emptybox/dto/EmptyBoxOutboundCreateResp.java @@ -0,0 +1,18 @@ +package cn.code.nl.module.wms.api.emptybox.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 空木箱出库创建结果。 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class EmptyBoxOutboundCreateResp { + + private Long taskId; + private String boxNo; + private String destinationPoint; +} diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/api/emptybox/EmptyBoxApiImpl.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/api/emptybox/EmptyBoxApiImpl.java new file mode 100644 index 00000000..b43c6852 --- /dev/null +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/api/emptybox/EmptyBoxApiImpl.java @@ -0,0 +1,36 @@ +package cn.code.nl.module.wms.api.emptybox; + +import cn.code.nl.framework.common.pojo.CommonResult; +import cn.code.nl.module.wms.api.emptybox.dto.EmptyBoxInboundCreateReq; +import cn.code.nl.module.wms.api.emptybox.dto.EmptyBoxInboundCreateResp; +import cn.code.nl.module.wms.api.emptybox.dto.EmptyBoxOutboundCreateReq; +import cn.code.nl.module.wms.api.emptybox.dto.EmptyBoxOutboundCreateResp; +import cn.code.nl.module.wms.service.emptybox.EmptyBoxService; +import jakarta.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RestController; + +import static cn.code.nl.framework.common.pojo.CommonResult.success; + +/** + * 空木箱出入库内部接口实现。 + */ +@RestController +@Validated +public class EmptyBoxApiImpl implements EmptyBoxApi { + + @Resource + private EmptyBoxService emptyBoxService; + + /** 创建空木箱入库任务。 */ + @Override + public CommonResult createInbound(EmptyBoxInboundCreateReq req) { + return success(emptyBoxService.createInbound(req)); + } + + /** 创建空木箱出库任务。 */ + @Override + public CommonResult createOutbound(EmptyBoxOutboundCreateReq req) { + return success(emptyBoxService.createOutbound(req)); + } +} diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/boxinfo/BoxInfoController.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/boxinfo/BoxInfoController.java new file mode 100644 index 00000000..c0e376b4 --- /dev/null +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/boxinfo/BoxInfoController.java @@ -0,0 +1,45 @@ +package cn.code.nl.module.wms.controller.admin.boxinfo; + +import cn.code.nl.framework.common.pojo.CommonResult; +import cn.code.nl.framework.common.pojo.PageResult; +import cn.code.nl.module.wms.controller.admin.boxinfo.vo.BoxInfoPageReqVO; +import cn.code.nl.module.wms.controller.admin.boxinfo.vo.BoxInfoRespVO; +import cn.code.nl.module.wms.service.boxinfo.BoxInfoService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import static cn.code.nl.framework.common.pojo.CommonResult.success; + +/** + * 木箱基础信息只读查询控制器。 + */ +@Tag(name = "管理后台 - 木箱信息") +@RestController +@RequestMapping("/wms/box-info") +@Validated +public class BoxInfoController { + + /** 木箱基础信息服务。 */ + @Resource + private BoxInfoService boxInfoService; + + /** + * 分页查询木箱基础信息。 + * + * @param pageReqVO 查询参数 + * @return 木箱基础信息分页结果 + */ + @GetMapping("/page") + @Operation(summary = "获得木箱基础信息分页") + @PreAuthorize("@ss.hasPermission('wms:box-info:query')") + public CommonResult> getBoxInfoPage(@Valid BoxInfoPageReqVO pageReqVO) { + return success(boxInfoService.getBoxInfoPage(pageReqVO)); + } +} diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/boxinfo/vo/BoxInfoPageReqVO.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/boxinfo/vo/BoxInfoPageReqVO.java new file mode 100644 index 00000000..412f95a5 --- /dev/null +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/boxinfo/vo/BoxInfoPageReqVO.java @@ -0,0 +1,28 @@ +package cn.code.nl.module.wms.controller.admin.boxinfo.vo; + +import cn.code.nl.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 木箱信息分页查询参数。 + */ +@Data +@Schema(description = "管理后台 - 木箱信息分页查询参数") +public class BoxInfoPageReqVO extends PageParam { + + @Schema(description = "木箱号") + private String boxNo; + + @Schema(description = "物料编码") + private String materialCode; + + @Schema(description = "物料名称") + private String materialName; + + @Schema(description = "是否包装") + private String isPacking; + + @Schema(description = "载具类型") + private String vehicleType; +} diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/boxinfo/vo/BoxInfoRespVO.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/boxinfo/vo/BoxInfoRespVO.java new file mode 100644 index 00000000..b0f2b49e --- /dev/null +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/boxinfo/vo/BoxInfoRespVO.java @@ -0,0 +1,57 @@ +package cn.code.nl.module.wms.controller.admin.boxinfo.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 木箱基础信息响应对象。 + */ +@Data +@Schema(description = "管理后台 - 木箱基础信息") +public class BoxInfoRespVO { + + @Schema(description = "木箱主键", requiredMode = Schema.RequiredMode.REQUIRED) + private Long boxId; + + @Schema(description = "木箱号", requiredMode = Schema.RequiredMode.REQUIRED) + private String boxNo; + + @Schema(description = "物料编码", requiredMode = Schema.RequiredMode.REQUIRED) + private String materialCode; + + @Schema(description = "物料名称", requiredMode = Schema.RequiredMode.REQUIRED) + private String materialName; + + @Schema(description = "数量") + private String num; + + @Schema(description = "木箱长度", requiredMode = Schema.RequiredMode.REQUIRED) + private String boxLength; + + @Schema(description = "木箱宽度", requiredMode = Schema.RequiredMode.REQUIRED) + private String boxWidth; + + @Schema(description = "木箱高度", requiredMode = Schema.RequiredMode.REQUIRED) + private String boxHigh; + + @Schema(description = "插入时间", requiredMode = Schema.RequiredMode.REQUIRED) + private String insertTime; + + @Schema(description = "捆扎数量", requiredMode = Schema.RequiredMode.REQUIRED) + private String lashNum; + + @Schema(description = "载具类型") + private String vehicleType; + + @Schema(description = "是否包装") + private String isPacking; + + @Schema(description = "木箱重量") + private String boxWeight; + + @Schema(description = "木箱状态") + private String status; + + @Schema(description = "出库时间") + private String outTime; +} diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/emptybox/EmptyBoxController.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/emptybox/EmptyBoxController.java new file mode 100644 index 00000000..ade89e54 --- /dev/null +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/emptybox/EmptyBoxController.java @@ -0,0 +1,46 @@ +package cn.code.nl.module.wms.controller.admin.emptybox; + +import cn.code.nl.framework.common.pojo.CommonResult; +import cn.code.nl.module.wms.api.emptybox.dto.EmptyBoxInboundCreateReq; +import cn.code.nl.module.wms.api.emptybox.dto.EmptyBoxInboundCreateResp; +import cn.code.nl.module.wms.api.emptybox.dto.EmptyBoxOutboundCreateReq; +import cn.code.nl.module.wms.api.emptybox.dto.EmptyBoxOutboundCreateResp; +import cn.code.nl.module.wms.service.emptybox.EmptyBoxService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import static cn.code.nl.framework.common.pojo.CommonResult.success; + +/** + * 空木箱出入库管理接口。 + */ +@Tag(name = "管理后台 - 空木箱出入库") +@RestController +@RequestMapping("/wms/empty-box") +public class EmptyBoxController { + + @Resource + private EmptyBoxService emptyBoxService; + + /** 创建空木箱入库任务。 */ + @PostMapping("/createInbound") + @Operation(summary = "创建空木箱入库任务") + public CommonResult createInbound( + @Valid @RequestBody EmptyBoxInboundCreateReq req) { + return success(emptyBoxService.createInbound(req)); + } + + /** 创建空木箱出库任务。 */ + @PostMapping("/createOutbound") + @Operation(summary = "创建空木箱出库任务") + public CommonResult createOutbound( + @Valid @RequestBody EmptyBoxOutboundCreateReq req) { + return success(emptyBoxService.createOutbound(req)); + } +} diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/structAttr/vo/StrucAttrPageReqVO.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/structAttr/vo/StrucAttrPageReqVO.java index 0206e9c1..d0875e5d 100644 --- a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/structAttr/vo/StrucAttrPageReqVO.java +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/structAttr/vo/StrucAttrPageReqVO.java @@ -104,6 +104,9 @@ public class StrucAttrPageReqVO extends PageParam { @Schema(description = "载具数量") private Integer storagevehicleQty; + @Schema(description = "库存类型:0空、1成品、2空载具、3空木箱") + private String inventoryType; + @Schema(description = "锁定类型", example = "2") private String lockType; @@ -125,4 +128,4 @@ public class StrucAttrPageReqVO extends PageParam { @Schema(description = "备注", example = "你猜") private String remark; -} \ No newline at end of file +} diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/structAttr/vo/StrucAttrRespVO.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/structAttr/vo/StrucAttrRespVO.java index c2247d39..261cfcd0 100644 --- a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/structAttr/vo/StrucAttrRespVO.java +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/controller/admin/structAttr/vo/StrucAttrRespVO.java @@ -104,6 +104,10 @@ public class StrucAttrRespVO { @ExcelProperty("载具数量") private Integer storagevehicleQty; + @Schema(description = "库存类型:0空、1成品、2空载具、3空木箱") + @ExcelProperty("库存类型") + private String inventoryType; + @Schema(description = "锁定类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") @ExcelProperty("锁定类型") private String lockType; @@ -132,4 +136,4 @@ public class StrucAttrRespVO { @ExcelProperty("备注") private String remark; -} \ No newline at end of file +} diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/dataobject/boxinfo/BoxInfoDO.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/dataobject/boxinfo/BoxInfoDO.java new file mode 100644 index 00000000..acd33117 --- /dev/null +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/dataobject/boxinfo/BoxInfoDO.java @@ -0,0 +1,37 @@ +package cn.code.nl.module.wms.dal.dataobject.boxinfo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 木箱实例数据对象。 + */ +@Data +@TableName("wmw_boxinfo") +public class BoxInfoDO { + + @TableId + private Long boxId; + private String boxNo; + private String materialCode; + private String materialName; + private String num; + private String boxLength; + private String boxWidth; + private String boxHigh; + private String insertTime; + private String lashNum; + private String vehicleType; + private String isPacking; + private String boxWeight; + private String status; + private String outTime; + + @TableField(exist = false) + private String structId; + + @TableField(exist = false) + private String structCode; +} diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/dataobject/boxtype/BoxTypeDO.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/dataobject/boxtype/BoxTypeDO.java new file mode 100644 index 00000000..bdcf134d --- /dev/null +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/dataobject/boxtype/BoxTypeDO.java @@ -0,0 +1,22 @@ +package cn.code.nl.module.wms.dal.dataobject.boxtype; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 木箱规格数据对象。 + */ +@Data +@TableName("wms_boxtype") +public class BoxTypeDO { + + @TableId + private Long id; + private String materialCode; + private String materialName; + private String lashNum; + private String boxLength; + private String boxWidth; + private String boxHeight; +} diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/dataobject/structAttr/EmptyBoxRowCandidate.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/dataobject/structAttr/EmptyBoxRowCandidate.java new file mode 100644 index 00000000..633d2d9c --- /dev/null +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/dataobject/structAttr/EmptyBoxRowCandidate.java @@ -0,0 +1,16 @@ +package cn.code.nl.module.wms.dal.dataobject.structAttr; + +import lombok.Data; + +/** + * 空木箱入库候选排。 + */ +@Data +public class EmptyBoxRowCandidate { + + private String storId; + private String sectId; + private Integer blockNum; + private Integer rowNum; + private Integer layerNum; +} diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/dataobject/structAttr/StrucAttrDO.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/dataobject/structAttr/StrucAttrDO.java index 6d21b914..9f984bcf 100644 --- a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/dataobject/structAttr/StrucAttrDO.java +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/dataobject/structAttr/StrucAttrDO.java @@ -143,6 +143,10 @@ public class StrucAttrDO extends BaseDO { * 载具数量 */ private Integer storagevehicleQty; + /** + * 库存类型:0空、1成品、2空载具、3空木箱 + */ + private String inventoryType; /** * 锁定类型 */ @@ -173,4 +177,4 @@ public class StrucAttrDO extends BaseDO { private String remark; -} \ No newline at end of file +} diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/mysql/boxinfo/BoxInfoMapper.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/mysql/boxinfo/BoxInfoMapper.java new file mode 100644 index 00000000..e368ae70 --- /dev/null +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/mysql/boxinfo/BoxInfoMapper.java @@ -0,0 +1,52 @@ +package cn.code.nl.module.wms.dal.mysql.boxinfo; + +import cn.code.nl.framework.common.pojo.PageResult; +import cn.code.nl.framework.mybatis.core.util.MyBatisUtils; +import cn.code.nl.module.wms.controller.admin.boxinfo.vo.BoxInfoPageReqVO; +import cn.code.nl.module.wms.controller.admin.boxinfo.vo.BoxInfoRespVO; +import cn.code.nl.module.wms.dal.dataobject.boxinfo.BoxInfoDO; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + * 木箱基础信息只读 Mapper。 + */ +@Mapper +public interface BoxInfoMapper { + + /** + * 分页查询木箱基础信息。 + * + * @param reqVO 查询参数 + * @return 木箱基础信息分页结果 + */ + default PageResult selectBoxInfoPage(BoxInfoPageReqVO reqVO) { + Page page = selectBoxInfoPage(MyBatisUtils.buildPage(reqVO), reqVO); + return new PageResult<>(page.getRecords(), page.getTotal()); + } + + /** + * 执行木箱基础信息分页查询SQL。 + * + * @param page 分页对象 + * @param reqVO 查询参数 + * @return 木箱基础信息分页数据 + */ + Page selectBoxInfoPage(Page page, @Param("reqVO") BoxInfoPageReqVO reqVO); + + /** 插入待入库木箱。 */ + int insertPendingInbound(BoxInfoDO boxInfo); + + /** 查询先进先出的可出库木箱候选。 */ + java.util.List selectOutboundCandidates(@Param("materialCode") String materialCode); + + /** 入库任务完成。 */ + int completeInbound(@Param("boxNo") String boxNo, @Param("insertTime") String insertTime); + + /** 物理删除取消入库的待入库木箱。 */ + int deletePendingInbound(@Param("boxNo") String boxNo); + + /** 出库任务完成。 */ + int completeOutbound(@Param("boxNo") String boxNo, @Param("outTime") String outTime); +} diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/mysql/boxtype/BoxTypeMapper.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/mysql/boxtype/BoxTypeMapper.java new file mode 100644 index 00000000..60a017d9 --- /dev/null +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/mysql/boxtype/BoxTypeMapper.java @@ -0,0 +1,17 @@ +package cn.code.nl.module.wms.dal.mysql.boxtype; + +import cn.code.nl.module.wms.dal.dataobject.boxtype.BoxTypeDO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + * 木箱规格 Mapper。 + */ +@Mapper +public interface BoxTypeMapper { + + /** + * 根据规格编码查询木箱规格。 + */ + BoxTypeDO selectByMaterialCode(@Param("materialCode") String materialCode); +} diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/mysql/structAttr/StrucAttrMapper.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/mysql/structAttr/StrucAttrMapper.java index 4f926815..63dd50fc 100644 --- a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/mysql/structAttr/StrucAttrMapper.java +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/dal/mysql/structAttr/StrucAttrMapper.java @@ -7,6 +7,7 @@ import cn.code.nl.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.code.nl.framework.mybatis.core.mapper.BaseMapperX; import cn.code.nl.module.wms.dal.dataobject.structAttr.StrucAttrDO; import cn.code.nl.module.wms.dal.dataobject.structAttr.EmptyVehicleRowCandidate; +import cn.code.nl.module.wms.dal.dataobject.structAttr.EmptyBoxRowCandidate; import cn.code.nl.module.wms.controller.admin.moveinv.vo.MoveInvInventoryRespVO; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -20,6 +21,35 @@ import cn.code.nl.module.wms.controller.admin.structAttr.vo.*; @Mapper public interface StrucAttrMapper extends BaseMapperX { + List selectEmptyBoxPreferredRows(@Param("materialCode") String materialCode); + + List selectEmptyBoxEmptyRows(); + + StrucAttrDO selectFreeStructInEmptyBoxRow(EmptyBoxRowCandidate row); + + int lockEmptyBoxInbound(@Param("structId") String structId, + @Param("reservationCode") String reservationCode, + @Param("boxNo") String boxNo); + + int lockEmptyBoxOutbound(@Param("structId") String structId, + @Param("reservationCode") String reservationCode, + @Param("boxNo") String boxNo); + + int bindEmptyBoxTask(@Param("structId") String structId, + @Param("reservationCode") String reservationCode, + @Param("taskId") String taskId, + @Param("lockType") String lockType); + + StrucAttrDO selectEmptyBoxTaskStruct(@Param("taskId") String taskId); + + int completeEmptyBoxInbound(@Param("taskId") String taskId, @Param("boxNo") String boxNo); + + int completeEmptyBoxOutbound(@Param("taskId") String taskId, @Param("boxNo") String boxNo); + + int cancelEmptyBoxTask(@Param("taskId") String taskId); + + Long countEmptyBoxAtPoint(@Param("pointCode") String pointCode); + List selectEmptyVehiclePreferredRows(); List selectCompletelyEmptyRows(); @@ -71,7 +101,8 @@ public interface StrucAttrMapper extends BaseMapperX { int completeMoveIn(@Param("structCode") String structCode, @Param("invId") String invId, - @Param("vehicleCode") String vehicleCode); + @Param("vehicleCode") String vehicleCode, + @Param("inventoryType") String inventoryType); int lockForOutbound(@Param("structId") String structId, @Param("invType") String invType, @@ -132,6 +163,7 @@ public interface StrucAttrMapper extends BaseMapperX { .eqIfPresent(StrucAttrDO::getStoragevehicleCode, reqVO.getStoragevehicleCode()) .eqIfPresent(StrucAttrDO::getStoragevehicleType, reqVO.getStoragevehicleType()) .eqIfPresent(StrucAttrDO::getStoragevehicleQty, reqVO.getStoragevehicleQty()) + .eqIfPresent(StrucAttrDO::getInventoryType, reqVO.getInventoryType()) .eqIfPresent(StrucAttrDO::getLockType, reqVO.getLockType()) .eqIfPresent(StrucAttrDO::getTaskCode, reqVO.getTaskCode()) .eqIfPresent(StrucAttrDO::getInvType, reqVO.getInvType()) diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/enums/emptybox/EmptyBoxStatusEnum.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/enums/emptybox/EmptyBoxStatusEnum.java new file mode 100644 index 00000000..49dfb2f8 --- /dev/null +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/enums/emptybox/EmptyBoxStatusEnum.java @@ -0,0 +1,21 @@ +package cn.code.nl.module.wms.enums.emptybox; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 空木箱状态。 + */ +@Getter +@AllArgsConstructor +public enum EmptyBoxStatusEnum { + + PENDING_INBOUND("0"), + IN_STOCK("1"), + OUTBOUND("2"); + + /** + * 状态编码。 + */ + private final String code; +} diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/enums/structattr/StructInventoryTypeEnum.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/enums/structattr/StructInventoryTypeEnum.java new file mode 100644 index 00000000..146aed85 --- /dev/null +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/enums/structattr/StructInventoryTypeEnum.java @@ -0,0 +1,20 @@ +package cn.code.nl.module.wms.enums.structattr; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 仓位库存类型。 + */ +@Getter +@AllArgsConstructor +public enum StructInventoryTypeEnum { + + EMPTY("0"), + FINISHED_PRODUCT("1"), + EMPTY_VEHICLE("2"), + EMPTY_BOX("3"); + + /** 类型编码。 */ + private final String code; +} diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/boxinfo/BoxInfoService.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/boxinfo/BoxInfoService.java new file mode 100644 index 00000000..0aed23a2 --- /dev/null +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/boxinfo/BoxInfoService.java @@ -0,0 +1,19 @@ +package cn.code.nl.module.wms.service.boxinfo; + +import cn.code.nl.framework.common.pojo.PageResult; +import cn.code.nl.module.wms.controller.admin.boxinfo.vo.BoxInfoPageReqVO; +import cn.code.nl.module.wms.controller.admin.boxinfo.vo.BoxInfoRespVO; + +/** + * 木箱基础信息只读服务。 + */ +public interface BoxInfoService { + + /** + * 分页查询木箱基础信息。 + * + * @param pageReqVO 查询参数 + * @return 木箱基础信息分页结果 + */ + PageResult getBoxInfoPage(BoxInfoPageReqVO pageReqVO); +} diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/boxinfo/BoxInfoServiceImpl.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/boxinfo/BoxInfoServiceImpl.java new file mode 100644 index 00000000..7614c396 --- /dev/null +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/boxinfo/BoxInfoServiceImpl.java @@ -0,0 +1,32 @@ +package cn.code.nl.module.wms.service.boxinfo; + +import cn.code.nl.framework.common.pojo.PageResult; +import cn.code.nl.module.wms.controller.admin.boxinfo.vo.BoxInfoPageReqVO; +import cn.code.nl.module.wms.controller.admin.boxinfo.vo.BoxInfoRespVO; +import cn.code.nl.module.wms.dal.mysql.boxinfo.BoxInfoMapper; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +/** + * 木箱基础信息只读服务实现。 + */ +@Service +@Validated +public class BoxInfoServiceImpl implements BoxInfoService { + + /** 木箱基础信息 Mapper。 */ + @Resource + private BoxInfoMapper boxInfoMapper; + + /** + * 分页查询木箱基础信息。 + * + * @param pageReqVO 查询参数 + * @return 木箱基础信息分页结果 + */ + @Override + public PageResult getBoxInfoPage(BoxInfoPageReqVO pageReqVO) { + return boxInfoMapper.selectBoxInfoPage(pageReqVO); + } +} diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/emptybox/EmptyBoxService.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/emptybox/EmptyBoxService.java new file mode 100644 index 00000000..e31ccc5d --- /dev/null +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/emptybox/EmptyBoxService.java @@ -0,0 +1,24 @@ +package cn.code.nl.module.wms.service.emptybox; + +import cn.code.nl.module.wms.api.emptybox.dto.EmptyBoxInboundCreateReq; +import cn.code.nl.module.wms.api.emptybox.dto.EmptyBoxInboundCreateResp; +import cn.code.nl.module.wms.api.emptybox.dto.EmptyBoxOutboundCreateReq; +import cn.code.nl.module.wms.api.emptybox.dto.EmptyBoxOutboundCreateResp; + +/** + * 空木箱出入库服务。 + */ +public interface EmptyBoxService { + + /** 创建空木箱入库任务。 */ + EmptyBoxInboundCreateResp createInbound(EmptyBoxInboundCreateReq req); + + /** 创建空木箱出库任务。 */ + EmptyBoxOutboundCreateResp createOutbound(EmptyBoxOutboundCreateReq req); + + /** 完成空木箱任务。 */ + void completeTask(Long taskId); + + /** 取消空木箱任务。 */ + void cancelTask(Long taskId); +} diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/emptybox/EmptyBoxServiceImpl.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/emptybox/EmptyBoxServiceImpl.java new file mode 100644 index 00000000..c8d3b5ff --- /dev/null +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/emptybox/EmptyBoxServiceImpl.java @@ -0,0 +1,264 @@ +package cn.code.nl.module.wms.service.emptybox; + +import cn.code.nl.framework.common.exception.ServiceException; +import cn.code.nl.module.base.api.codegen.CodeGenApi; +import cn.code.nl.module.base.api.codegen.dto.CodeGenerateReqDTO; +import cn.code.nl.module.task.api.TransportTaskApi; +import cn.code.nl.module.task.dto.TransportTaskCreateReqDTO; +import cn.code.nl.module.wms.api.emptybox.dto.EmptyBoxInboundCreateReq; +import cn.code.nl.module.wms.api.emptybox.dto.EmptyBoxInboundCreateResp; +import cn.code.nl.module.wms.api.emptybox.dto.EmptyBoxOutboundCreateReq; +import cn.code.nl.module.wms.api.emptybox.dto.EmptyBoxOutboundCreateResp; +import cn.code.nl.module.wms.dal.dataobject.boxinfo.BoxInfoDO; +import cn.code.nl.module.wms.dal.dataobject.boxtype.BoxTypeDO; +import cn.code.nl.module.wms.dal.dataobject.structAttr.EmptyBoxRowCandidate; +import cn.code.nl.module.wms.dal.dataobject.structAttr.StrucAttrDO; +import cn.code.nl.module.wms.dal.mysql.boxinfo.BoxInfoMapper; +import cn.code.nl.module.wms.dal.mysql.boxtype.BoxTypeMapper; +import cn.code.nl.module.wms.dal.mysql.structAttr.StrucAttrMapper; +import cn.code.nl.module.wms.enums.emptybox.EmptyBoxStatusEnum; +import cn.hutool.core.util.IdUtil; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + +/** + * 空木箱出入库服务实现。 + */ +@Service +public class EmptyBoxServiceImpl implements EmptyBoxService { + + private static final String OWNER_SERVICE = "WMS"; + private static final String HANDLE_CODE = "EMPTYBOXTASK"; + private static final String INBOUND_LOCK = "8"; + private static final String OUTBOUND_LOCK = "9"; + private static final String OUTBOUND_POINT_1 = "ZXQ_01"; + private static final String OUTBOUND_POINT_2 = "ZXQ_02"; + private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + @Resource + private BoxTypeMapper boxTypeMapper; + @Resource + private BoxInfoMapper boxInfoMapper; + @Resource + private StrucAttrMapper strucAttrMapper; + @Resource + private CodeGenApi codeGenApi; + @Resource + private TransportTaskApi transportTaskApi; + + /** + * 创建空木箱入库任务。 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public EmptyBoxInboundCreateResp createInbound(EmptyBoxInboundCreateReq req) { + BoxTypeDO boxType = boxTypeMapper.selectByMaterialCode(req.getMaterialCode()); + if (boxType == null) { + throw new ServiceException(500, "木箱规格不存在"); + } + String boxNo = generateBoxNo(); + String reservationCode = "EMPTY_BOX_" + IdUtil.getSnowflakeNextIdStr(); + StrucAttrDO struct = reserveInboundStruct(req.getMaterialCode(), reservationCode, boxNo); + if (struct == null) { + throw new ServiceException(500, "未找到符合条件的空木箱入库仓位"); + } + insertPendingBox(boxType, boxNo); + Long taskId = createTransportTask("空木箱入库任务", "EMPTY_BOX_IN", struct, req.getDeviceCode(), + struct.getStructCode(), boxNo, req.getMaterialCode()); + bindTask(struct, reservationCode, taskId, INBOUND_LOCK); + transportTaskApi.issueTransportTaskRollBack(taskId).getCheckedData(); + return new EmptyBoxInboundCreateResp(taskId, boxNo, struct.getStructCode()); + } + + /** + * 创建空木箱出库任务。 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public EmptyBoxOutboundCreateResp createOutbound(EmptyBoxOutboundCreateReq req) { + if (boxTypeMapper.selectByMaterialCode(req.getMaterialCode()) == null) { + throw new ServiceException(500, "木箱规格不存在"); + } + String reservationCode = "EMPTY_BOX_" + IdUtil.getSnowflakeNextIdStr(); + BoxInfoDO box = reserveOutboundBox(req.getMaterialCode(), reservationCode); + if (box == null) { + throw new ServiceException(500, "没有可出库的该规格空木箱"); + } + String destinationPoint = selectOutboundPoint(); + StrucAttrDO struct = new StrucAttrDO(); + struct.setStructId(box.getStructId()); + struct.setStructCode(box.getStructCode()); + Long taskId = createTransportTask("空木箱出库任务", "EMPTY_BOX_OUT", struct, + box.getStructCode(), destinationPoint, box.getBoxNo(), req.getMaterialCode()); + bindTask(struct, reservationCode, taskId, OUTBOUND_LOCK); + transportTaskApi.issueTransportTaskRollBack(taskId).getCheckedData(); + return new EmptyBoxOutboundCreateResp(taskId, box.getBoxNo(), destinationPoint); + } + + /** + * 完成空木箱任务。 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void completeTask(Long taskId) { + String taskCode = String.valueOf(taskId); + StrucAttrDO struct = strucAttrMapper.selectEmptyBoxTaskStruct(taskCode); + if (struct == null) { + throw new ServiceException(500, "未找到空木箱任务锁定的仓位"); + } + String boxNo = struct.getInvCode(); + String time = LocalDateTime.now().format(TIME_FORMATTER); + if (INBOUND_LOCK.equals(struct.getLockType())) { + if (strucAttrMapper.completeEmptyBoxInbound(taskCode, boxNo) != 1 + || boxInfoMapper.completeInbound(boxNo, time) != 1) { + throw new ServiceException(500, "空木箱入库完成状态异常"); + } + return; + } + if (strucAttrMapper.completeEmptyBoxOutbound(taskCode, boxNo) != 1 + || boxInfoMapper.completeOutbound(boxNo, time) != 1) { + throw new ServiceException(500, "空木箱出库完成状态异常"); + } + } + + /** + * 取消空木箱任务。 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void cancelTask(Long taskId) { + String taskCode = String.valueOf(taskId); + StrucAttrDO struct = strucAttrMapper.selectEmptyBoxTaskStruct(taskCode); + if (struct == null) { + throw new ServiceException(500, "未找到空木箱任务锁定的仓位"); + } + if (strucAttrMapper.cancelEmptyBoxTask(taskCode) != 1) { + throw new ServiceException(500, "空木箱任务取消状态异常"); + } + if (INBOUND_LOCK.equals(struct.getLockType()) + && boxInfoMapper.deletePendingInbound(struct.getInvCode()) != 1) { + throw new ServiceException(500, "待入库木箱删除失败"); + } + } + + /** + * 生成木箱编码。 + */ + private String generateBoxNo() { + CodeGenerateReqDTO req = new CodeGenerateReqDTO(); + req.setRuleCode("BOX_CODE"); + return codeGenApi.generate(req).getCheckedData(); + } + + /** + * 按同规格排、全空排的顺序预占入库仓位。 + */ + private StrucAttrDO reserveInboundStruct(String materialCode, String reservationCode, String boxNo) { + StrucAttrDO struct = reserveFromRows(strucAttrMapper.selectEmptyBoxPreferredRows(materialCode), + reservationCode, boxNo); + return struct != null ? struct + : reserveFromRows(strucAttrMapper.selectEmptyBoxEmptyRows(), reservationCode, boxNo); + } + + /** + * 从候选排逐排尝试抢占空仓位。 + */ + private StrucAttrDO reserveFromRows(List rows, String reservationCode, String boxNo) { + for (EmptyBoxRowCandidate row : rows) { + StrucAttrDO struct = strucAttrMapper.selectFreeStructInEmptyBoxRow(row); + if (struct != null && strucAttrMapper.lockEmptyBoxInbound( + struct.getStructId(), reservationCode, boxNo) == 1) { + return struct; + } + } + return null; + } + + /** + * 创建待入库木箱实例。 + */ + private void insertPendingBox(BoxTypeDO boxType, String boxNo) { + BoxInfoDO box = new BoxInfoDO(); + box.setBoxId(IdUtil.getSnowflakeNextId()); + box.setBoxNo(boxNo); + box.setMaterialCode(boxType.getMaterialCode()); + box.setMaterialName(boxType.getMaterialName()); + box.setNum("1"); + box.setBoxLength(boxType.getBoxLength()); + box.setBoxWidth(boxType.getBoxWidth()); + box.setBoxHigh(boxType.getBoxHeight()); + box.setInsertTime(LocalDateTime.now().format(TIME_FORMATTER)); + box.setLashNum(boxType.getLashNum()); + box.setIsPacking("0"); + box.setStatus(EmptyBoxStatusEnum.PENDING_INBOUND.getCode()); + if (boxInfoMapper.insertPendingInbound(box) != 1) { + throw new ServiceException(500, "待入库木箱创建失败"); + } + } + + /** + * 按先进先出顺序抢占可出库木箱。 + */ + private BoxInfoDO reserveOutboundBox(String materialCode, String reservationCode) { + for (BoxInfoDO box : boxInfoMapper.selectOutboundCandidates(materialCode)) { + if (strucAttrMapper.lockEmptyBoxOutbound( + box.getStructId(), reservationCode, box.getBoxNo()) == 1) { + return box; + } + } + return null; + } + + /** + * 按任务和点位库存综合负载选择出库点。 + */ + private String selectOutboundPoint() { + // TODO 后续改为调用 LMS 接口,统一获取候选出库点和点位库存占用情况。 + long point1Load = transportTaskApi.countUnfinishedByDestination( + OUTBOUND_POINT_1, OWNER_SERVICE).getCheckedData() + + strucAttrMapper.countEmptyBoxAtPoint(OUTBOUND_POINT_1); + long point2Load = transportTaskApi.countUnfinishedByDestination( + OUTBOUND_POINT_2, OWNER_SERVICE).getCheckedData() + + strucAttrMapper.countEmptyBoxAtPoint(OUTBOUND_POINT_2); + return point1Load <= point2Load ? OUTBOUND_POINT_1 : OUTBOUND_POINT_2; + } + + /** + * 创建搬运任务。 + */ + private Long createTransportTask(String taskName, String bizType, StrucAttrDO struct, + String startPoint, String endPoint, String boxNo, String materialCode) { + TransportTaskCreateReqDTO task = new TransportTaskCreateReqDTO(); + task.setTaskName(taskName); + task.setOwnerService(OWNER_SERVICE); + task.setBizType(bizType); + task.setBizId(struct.getStructId()); + task.setHandleCode(HANDLE_CODE); + task.setTaskType("EMPTY_BOX_IN".equals(bizType) ? "010501" : "010503"); + task.setAcsTaskType("7"); + task.setAgvSystemType("1"); + task.setPointCode1(startPoint); + task.setPointCode2(endPoint); + task.setVehicleCode(boxNo); + task.setMaterialCode(materialCode); + task.setIsAutoIssue("0"); + task.setProductArea("LK"); + task.setIsCreateFinish(true); + return transportTaskApi.createTransportTask(task).getCheckedData(); + } + + /** + * 将仓位预占码替换为任务 ID。 + */ + private void bindTask(StrucAttrDO struct, String reservationCode, Long taskId, String lockType) { + if (strucAttrMapper.bindEmptyBoxTask(struct.getStructId(), reservationCode, + String.valueOf(taskId), lockType) != 1) { + throw new ServiceException(500, "空木箱仓位预占状态异常,请重试"); + } + } +} diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/moveinv/MoveInvServiceImpl.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/moveinv/MoveInvServiceImpl.java index 42ae65b9..b00b2eba 100644 --- a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/moveinv/MoveInvServiceImpl.java +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/moveinv/MoveInvServiceImpl.java @@ -259,9 +259,13 @@ public class MoveInvServiceImpl implements MoveInvService { Set moveInvIds = new HashSet<>(); for (MoveInvDtlDO detail : details) { String moveInvId = String.valueOf(detail.getMoveinvId()); + StrucAttrDO sourceStruct = strucAttrMapper.selectByStructCode(detail.getTurnoutStructCode()); + if (sourceStruct == null || "0".equals(sourceStruct.getInventoryType())) { + throw exception(MOVE_INV_SOURCE_INVALID); + } // 先占用目标仓位,再清理来源仓位;任一步失败都会回滚整个事务。 if (strucAttrMapper.completeMoveIn(detail.getTurninStructCode(), moveInvId, - detail.getStoragevehicleCode()) != 1) { + detail.getStoragevehicleCode(), sourceStruct.getInventoryType()) != 1) { throw exception(MOVE_INV_TARGET_INVALID); } if (strucAttrMapper.completeMoveOut(detail.getTurnoutStructCode(), moveInvId, diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/task/EmptyBoxTask.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/task/EmptyBoxTask.java new file mode 100644 index 00000000..b2175ad5 --- /dev/null +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/task/EmptyBoxTask.java @@ -0,0 +1,29 @@ +package cn.code.nl.module.wms.task; + +import cn.code.nl.framework.execute.core.AbstractTask; +import cn.code.nl.framework.execute.core.dto.TaskExecuteDTO; +import cn.code.nl.module.wms.service.emptybox.EmptyBoxService; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + +/** + * 空木箱任务状态处理器。 + */ +@Component("EMPTYBOXTASK") +public class EmptyBoxTask extends AbstractTask { + + @Resource + private EmptyBoxService emptyBoxService; + + /** 转发任务完成事件。 */ + @Override + public void doHandleFinish(TaskExecuteDTO dto) { + emptyBoxService.completeTask(dto.getTaskId()); + } + + /** 转发任务取消事件。 */ + @Override + public void doHandleCancel(TaskExecuteDTO dto) { + emptyBoxService.cancelTask(dto.getTaskId()); + } +} diff --git a/nl-module-wms/nl-module-wms-server/src/main/resources/mapper/boxinfo/BoxInfoMapper.xml b/nl-module-wms/nl-module-wms-server/src/main/resources/mapper/boxinfo/BoxInfoMapper.xml new file mode 100644 index 00000000..401e2c2f --- /dev/null +++ b/nl-module-wms/nl-module-wms-server/src/main/resources/mapper/boxinfo/BoxInfoMapper.xml @@ -0,0 +1,83 @@ + + + + + + + + INSERT INTO wmw_boxinfo + (box_id, box_no, material_code, material_name, num, box_length, box_width, box_high, + insert_time, lash_num, vehicle_type, is_packing, status) + VALUES + (#{boxId}, #{boxNo}, #{materialCode}, #{materialName}, #{num}, #{boxLength}, #{boxWidth}, #{boxHigh}, + #{insertTime}, #{lashNum}, #{vehicleType}, #{isPacking}, #{status}) + + + + + + UPDATE wmw_boxinfo + SET status = '1', insert_time = #{insertTime} + WHERE box_no = #{boxNo} AND status = '0' + + + + DELETE FROM wmw_boxinfo WHERE box_no = #{boxNo} AND status = '0' + + + + UPDATE wmw_boxinfo + SET status = '2', out_time = #{outTime} + WHERE box_no = #{boxNo} AND status = '1' + + + diff --git a/nl-module-wms/nl-module-wms-server/src/main/resources/mapper/boxtype/BoxTypeMapper.xml b/nl-module-wms/nl-module-wms-server/src/main/resources/mapper/boxtype/BoxTypeMapper.xml new file mode 100644 index 00000000..b9e6571d --- /dev/null +++ b/nl-module-wms/nl-module-wms-server/src/main/resources/mapper/boxtype/BoxTypeMapper.xml @@ -0,0 +1,14 @@ + + + + + + + diff --git a/nl-module-wms/nl-module-wms-server/src/main/resources/mapper/structAttr/StrucAttrMapper.xml b/nl-module-wms/nl-module-wms-server/src/main/resources/mapper/structAttr/StrucAttrMapper.xml index 4cea95d4..2c0566f8 100644 --- a/nl-module-wms/nl-module-wms-server/src/main/resources/mapper/structAttr/StrucAttrMapper.xml +++ b/nl-module-wms/nl-module-wms-server/src/main/resources/mapper/structAttr/StrucAttrMapper.xml @@ -3,6 +3,116 @@ "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> + + + + + + + + UPDATE wms_structattr + SET lock_type = '8', task_code = #{reservationCode}, + inv_type = 'EMPTY_BOX_IN', inv_code = #{boxNo} + WHERE struct_id = #{structId} AND deleted = '0' AND is_used = 1 + AND lock_type = '1' + AND (storagevehicle_code IS NULL OR storagevehicle_code = '') + + + + UPDATE wms_structattr + SET lock_type = '9', task_code = #{reservationCode}, + inv_type = 'EMPTY_BOX_OUT', inv_code = #{boxNo} + WHERE struct_id = #{structId} AND deleted = '0' AND is_used = 1 + AND lock_type = '1' AND storagevehicle_code = #{boxNo} + AND EXISTS (SELECT 1 FROM wmw_boxinfo b + WHERE b.box_no = #{boxNo} AND b.status = '1') + + + + UPDATE wms_structattr SET task_code = #{taskId} + WHERE struct_id = #{structId} AND deleted = '0' + AND lock_type = #{lockType} AND task_code = #{reservationCode} + + + + + + UPDATE wms_structattr + SET storagevehicle_code = #{boxNo}, storagevehicle_qty = 1, + inventory_type = '3', + lock_type = '1', task_code = NULL, inv_type = NULL, inv_code = NULL + WHERE deleted = '0' AND task_code = #{taskId} AND lock_type = '8' + AND inv_code = #{boxNo} + AND (storagevehicle_code IS NULL OR storagevehicle_code = '') + + + + UPDATE wms_structattr + SET storagevehicle_code = NULL, storagevehicle_qty = 0, + inventory_type = '0', + lock_type = '1', task_code = NULL, inv_type = NULL, inv_code = NULL + WHERE deleted = '0' AND task_code = #{taskId} AND lock_type = '9' + AND inv_code = #{boxNo} AND storagevehicle_code = #{boxNo} + + + + UPDATE wms_structattr + SET lock_type = '1', task_code = NULL, inv_type = NULL, inv_code = NULL + WHERE deleted = '0' AND task_code = #{taskId} AND lock_type IN ('8', '9') + + + +