Files
huachuang/docs/superpowers/plans/2026-08-17-lms-core-binding-scheduling.md

9.9 KiB
Raw Blame History

LMS 管芯托盘绑定与日计划定时调度实现计划

面向 AI 代理的工作者: 必需子技能:使用 superpowers:executing-plans 逐任务实现此计划。步骤使用复选框(- [ ]跟踪进度。本仓库规则未获得新增测试授权因此不创建或运行测试以编译、Lint、SQL 幂等执行和数据库事务场景核验代替。

目标: 建立逐根管芯台账和 PDA 托盘绑定接口,并实现按最新日计划策略逐根创建桁架抓取、托盘 AGV 搬运和管芯出库任务的两个 XXL-JOB。

架构: lms_core_tube 是每根管芯的唯一状态真值,lms_base_papervehicle 只保存托盘格位关联。LMS 使用现有日计划 Claim、管芯/点位条件更新和 Task RPC 生成单根现场任务MQ 回调幂等更新位置与日计划进度。Task 模块补充业务标识查询和并发防重能力。

技术栈: Java 17、Spring Boot、MyBatis XML、MySQL、OpenFeign、RocketMQ、XXL-JOB、UniApp PDA 接口契约。


任务 1创建管芯表、字典和编码规则

文件:

  • 创建:sql/mysql/lms_core_tube.sql

  • 修改:sql/mysql/lms_daily_plan.sql

  • 创建 lms_core_tube,字段按规格定义;重量为 decimal(12,3);租户内管芯编号唯一;有效托盘格位通过 tenant_id, vehicle_code, row_num, col_num, active_slot 唯一约束。

  • 幂等增加 lms_base_papervehicle.core_tube_id/core_tube_code 及查询索引。

  • lms_daily_plan_strategy 增加 cursor_executed_qty int NOT NULL DEFAULT 0,用于逐根权重计数。

  • 初始化 lms_core_tube_stagelms_core_tube_status 字典和 CORE_TUBE_CODE 编码规则,格式为 GX + yyyyMMdd + 6位序列

  • huachuang_lms_dev 连续执行两遍脚本,确认表、字段、字典和编码规则不重复。

任务 2实现管芯主表和 PDA 5×5 批量绑定

文件:

  • 创建:nl-module-lms/nl-module-lms-server/src/main/java/cn/code/nl/module/lms/dal/dataobject/coretube/CoreTubeDO.java

  • 创建:.../dal/mysql/coretube/CoreTubeMapper.java

  • 创建:.../resources/mapper/coretube/CoreTubeMapper.xml

  • 创建:.../controller/pda/coretube/CoreTubePdaController.java

  • 创建:.../controller/pda/coretube/vo/CoreTubePalletRespVO.java

  • 创建:.../controller/pda/coretube/vo/CoreTubeBindReqVO.java

  • 创建:.../controller/pda/coretube/vo/CoreTubeBindItemReqVO.java

  • 创建:.../controller/pda/coretube/vo/CoreTubeBindRespVO.java

  • 创建:.../service/coretube/CoreTubeBindingService.java

  • 创建:.../service/coretube/CoreTubeBindingServiceImpl.java

  • 修改:.../stockingivt/PaperVehicleDO.java

  • 修改:.../stockingivt/StockingIvtMapper.java/xml

  • 修改:nl-module-lms/nl-module-lms-api/src/main/java/cn/code/nl/module/lms/enums/ErrorCodeConstants.java

  • 定义绑定请求:requestNovehicleCodematerialId 和格位列表;每格包含 15 的行列和大于零的重量。响应返回每格生成的管芯 ID、编号和重量。

  • 实现 GET /api/pda/coreTube/pallet,关联管芯主表返回托盘点位和完整 5×5 格位。

  • 实现 POST /api/pda/coreTube/bind:锁定托盘点位,批量校验格位,逐根调用 CodeGenApi.generate(CORE_TUBE_CODE),同事务插入管芯和格位关系。

  • 使用请求号和格位唯一约束防止重复绑定;并发冲突整个批次回滚并抛中文业务异常。

  • 运行 LMS Maven compile预期 BUILD SUCCESS

任务 3补齐 Task RPC 的业务防重

文件:

  • 修改:nl-module-task/nl-module-task-api/src/main/java/cn/code/nl/module/task/api/TransportTaskApi.java

  • 修改:.../dto/TaskInfoDTO.java

  • 修改:nl-module-task/nl-module-task-server/src/main/java/cn/code/nl/module/task/api/TransportTaskApiImpl.java

  • 修改:.../service/transporttask/TransportTaskService.java

  • 修改:.../service/transporttask/TransportTaskServiceImpl.java

  • 修改:.../dal/mysql/transporttask/TransportTaskMapper.java

  • 增加 getUnfinishedTaskByBiz(ownerService, bizType, bizId) RPC返回未终态任务。

  • RPC 创建入口以 ownerService:bizType:bizId 获取 Redisson 锁,锁内重查;存在时抛“相同业务任务正在执行”,不存在才插入。

  • LMS 调用超时后先按业务标识查询,已存在则绑定既有任务 ID明确不存在才释放预占。

  • 编译 Task 和 LMS 依赖,预期 BUILD SUCCESS

任务 4将日计划调度改为逐根策略游标

文件:

  • 修改:.../dailyplan/DailyPlanScheduleService.java

  • 修改:.../dailyplan/DailyPlanScheduleServiceImpl.java

  • 修改:.../dailyplan/DailyPlanScheduleCandidate.java

  • 修改:.../dailyplan/DailyPlanStrategyDO.java

  • 修改:.../dailyplan/DailyPlanStrategyMapper.java

  • 修改:.../resources/mapper/dailyplan/DailyPlanStrategyMapper.xml

  • 修改:.../dailyplan/DailyPlanMapper.java

  • 修改:.../resources/mapper/dailyplan/DailyPlanMapper.xml

  • 增加不立即创建 Claim 的备货/套管候选预览,权重模式从当前游标开始排列,供 Job 跨规格扫描。

  • 增加领取指定计划的方法,claimedQty 固定为 1锁内重新校验状态、剩余量和未完成单根业务任务。

  • 增加“现场任务创建成功”确认:权重计数加 1达到最新权重才推进游标只创建 AGV、缺货或跳过时不消耗权重。

  • 模式、顺序或权重变化时下一轮重读策略;模式切换清零本轮计数。

  • 已创建任务持有 Claim回收 Claim 前必须核对任务,不得因过期重复创建现场任务。

任务 5实现备货与套管任务选择、预占和创建

文件:

  • 创建:.../service/coretube/CoreTubeTaskDispatchService.java

  • 创建:.../service/coretube/CoreTubeTaskDispatchServiceImpl.java

  • 创建:.../service/coretube/CoreTubeTaskContext.java

  • 创建:.../enums/CoreTubeStageEnum.java

  • 创建:.../enums/CoreTubeStatusEnum.java

  • 创建:.../enums/CoreTubeLocationTypeEnum.java

  • 创建:.../enums/CoreTubeTaskBizTypeEnum.java

  • 创建:.../enums/CoreTubeHandleCodeConstants.java

  • 修改:.../dal/mysql/coretube/CoreTubeMapper.java/xml

  • 修改:.../stockingivt/StockingIvtMapper.java/xml

  • 备货先按策略顺序和物料去重扫描对接位;命中目标规格后锁定一根、创建单根 Claim、预占管芯并创建桁架抓取任务本轮结束。

  • 所有规格均不能直接抓取时:对接位有其他托盘则创建一条移出任务;为空则按“足够且最接近缺口,否则数量最多”选择缓存托盘创建一条移入任务。

  • 同规格、同托盘、同对接位和同管芯均使用稳定业务幂等键及条件更新,任何时刻只允许一条未完成任务。

  • 套管每轮领取一个计划,从管芯库按点位顺序预占一根目标规格管芯并创建出库任务。

  • 套管无管芯时查询该规格的 AGV/抓取任务,分别记录“正在备货”或“备货区库存不足”,释放无任务 Claim。

任务 6实现任务完成、取消和恢复回调

文件:

  • 创建:.../task/CoreTubeStockingTask.java

  • 创建:.../task/CoreTubeSleevingTask.java

  • 修改:.../service/coretube/CoreTubeTaskDispatchService.java/Impl.java

  • 修改:.../dal/mysql/coretube/CoreTubeMapper.java/xml

  • 修改:.../stockingivt/StockingIvtMapper.java/xml

  • AGV 完成时更新来源/目标点位和托盘位置,不更新日计划备货进度;取消时只释放预占。

  • 桁架抓取完成时解绑托盘格位,将管芯更新为“管芯库/可用”并将备货进度增加 1取消时恢复“备货区/可用”。

  • 管芯出库完成时更新为“套管中/作业中”并将套管进度增加 1取消时恢复“管芯库/可用”。

  • 回调按任务 ID 和管芯阶段幂等;备货、套管使用不同处理器,互不修改对方状态。

  • 增加内部恢复方法:任务不存在/失败释放资源,执行中续期,成功但未回写时补做幂等回调。

任务 7增加两个 XXL-JOB

文件:

  • 创建:nl-module-lms/nl-module-lms-server/src/main/java/cn/code/nl/module/lms/job/DailyPlanCoreTubeJob.java

  • 修改LMS 配置示例文件

  • @XxlJob("dailyPlanStockingJob") 调用一次备货分配;无任务、正在备货和库存不足均记录中文业务日志并正常结束。

  • @XxlJob("dailyPlanSleevingJob") 调用一次套管分配,每次最多创建一条单根出库任务。

  • lms.core-tube.* 配置 AGV 系统类型、ACS 类型、抓取目标点、套管目标点和任务参数,不硬编码现场设备点位。

任务 8完整验证

文件:

  • 必要时同步:docs/superpowers/specs/2026-08-17-lms-core-binding-scheduling-design.md

  • 执行 mvn -pl nl-module-lms/nl-module-lms-server,nl-module-task/nl-module-task-server -am -DskipTests compile,确认 BUILD SUCCESS

  • SQL 连续执行两遍,核对表、约束、字典、编码规则和升级列。

  • 在回滚事务中核对PDA 重复绑定、A/B/C 对接位为 B 时只选 B、所有规格不匹配时只选一条 AGV、权重 2/3 得到 A/A/B/B/B、套管提示分支、AGV 不累计进度、抓取只累计 1。

  • 执行 git diff --checkgit status --short;保留用户原有未跟踪 nl-module-wms/img.png

任务 9PDA UniApp 页面接入(外部仓库前置)

前置条件: README 引用的 nl-ui-admin-uniapp 源码加入工作区。当前仓库只有截图,没有可修改的 UniApp 文件,因此不能伪造文件路径或在 Vben 管理端创建替代页面。

  • 在 UniApp 仓库定位此前确认的 5×5 管芯绑定页面、扫码组件和请求封装。
  • 扫描托盘后调用 GET /api/pda/coreTube/pallet;提交调用 POST /api/pda/coreTube/bind;显示每格管芯编号和重量。
  • 运行该仓库 package.json 已定义的 Lint/类型检查命令。