Files
huachuang/docs/lms日计划备货套管代码导读.md
2026-08-17 18:00:49 +08:00

11 KiB
Raw Blame History

LMS 日计划、备货、套管代码导读

本文对应当前 LMS 日计划和管芯调度实现,用于快速定位业务入口、调度决策、现场任务以及完成回调。

一、先建立整体认识

系统分为两条调用链:

  1. 人工操作链:页面调用日计划接口,只修改订单、备货、套管状态,不直接创建现场任务。
  2. 定时调度链XXL-JOB 查询状态为“进行中且未完成”的日计划,按顺序或权重策略创建现场任务;任务完成回调后才累计数量。

备货和套管共用日计划,但分别维护状态、进度、策略和 Claim因此两种作业可以并行互不占用对方的领取记录。

二、日计划人工操作时序

sequenceDiagram
    autonumber
    actor Worker as 工人
    participant Page as 日计划管理/作业页面
    participant Controller as DailyPlanController
    participant Service as DailyPlanServiceImpl
    participant Mapper as DailyPlanMapper
    participant DB as MySQL

    Worker->>Page: 创建或查看日计划
    Page->>Controller: create / managementPage / workPage
    Controller->>Service: 创建或查询
    Service->>Mapper: 读写日计划
    Mapper->>DB: lms_daily_plan
    DB-->>Page: 日计划及当前状态

    Worker->>Page: 开始订单并确认计划量
    Page->>Controller: startOrder(planQty, appendQty, version)
    Controller->>Service: startOrder
    Service->>Mapper: 校验未开始和版本,更新订单状态
    Service->>Mapper: 写数量及订单操作日志

    Worker->>Page: 开始备货或开始套管
    Page->>Controller: startStocking / startSleeving
    Controller->>Service: 变更对应作业状态
    Service->>Mapper: 状态改为进行中并记录日志
    Note over Service,DB: 此处只改变状态,不创建 Task 任务

    opt 追加数量
        Worker->>Page: 追加数量
        Page->>Controller: appendQuantity
        Controller->>Service: appendQuantity
        Service->>Mapper: 增加 append_qty
        Service->>Mapper: 已完成作业重新改为进行中
    end

    opt 取消或恢复
        Worker->>Page: 取消/恢复订单、备货或套管
        Page->>Controller: cancelXxx / restoreXxx
        Controller->>Service: 校验状态和乐观锁版本
        Service->>Mapper: 更新状态并记录原因
    end

关键规则:

  • 开始订单、开始备货、开始套管都不会直接下发任务。
  • 订单取消会阻止新任务领取;取消之前已合法创建的任务仍可完成并回写实际数量。
  • 追加数量作用于整个日计划,所以已完成的备货、套管都会重新进入进行中,不需要在作业页分别追加。
  • 所有页面操作都携带 version,防止页面操作相互覆盖。

三、备货定时调度时序

sequenceDiagram
    autonumber
    participant XXL as XXL-JOB<br/>dailyPlanStockingJob
    participant Dispatch as CoreTubeTaskDispatchServiceImpl
    participant Schedule as DailyPlanScheduleServiceImpl
    participant CoreDB as CoreTubeMapper
    participant PointDB as StockingIvtMapper
    participant Task as Task模块

    XXL->>Dispatch: dispatchStockingOnce()
    Dispatch->>Schedule: previewStockingCandidates()
    Schedule-->>Dispatch: 按顺序/权重排列的候选

    loop 每种物料规格只检查一次
        Dispatch->>CoreDB: 查询对接位可用目标管芯
        alt 对接位存在目标管芯
            Dispatch->>Schedule: claimStockingCandidate(日计划ID)
            Schedule-->>Dispatch: 单根Claim
            Dispatch->>CoreDB: 原子预占一根管芯
            Dispatch->>Task: 创建CORE_TUBE_STOCKING_PICK
            Task-->>Dispatch: taskId
            Dispatch->>CoreDB: 管芯绑定taskId
            Dispatch->>Schedule: confirmTaskCreated(claimToken)
            Note over Schedule: 只有单根任务创建成功才推进权重
            Dispatch-->>XXL: 本轮结束,只创建一条任务
        else 当前规格不能直接抓取
            Note over Dispatch: 跳到下一规格,不提前消耗权重
        end
    end

    alt 所有规格都不能直接抓取且对接位有托盘
        Dispatch->>PointDB: 查询空缓存位
        Dispatch->>Task: 创建CORE_TUBE_PALLET_OUT
        Note over Dispatch: 本轮只移出一托盘,不创建抓取任务
    else 对接位为空
        Dispatch->>PointDB: 为候选规格选择缓存位托盘
        Note over PointDB: 优先选择可满足剩余量的最小托盘<br/>否则选择库存最多托盘
        Dispatch->>Task: 创建CORE_TUBE_PALLET_IN
        Note over Dispatch: 同规格未完成托盘任务使用业务键防重
    else 无可用托盘
        Dispatch-->>XXL: 记录备货区无可用管芯并结束
    end

备货数量何时增加:

  • 托盘移入或移出完成:只更新托盘点位和整托盘管芯位置,stocked_qty 不增加。
  • 桁架成功抓取一根管芯并送入管芯库:stocked_qty + 1
  • 每轮调度每个租户最多创建一条现场任务。

四、套管定时调度时序

sequenceDiagram
    autonumber
    participant XXL as XXL-JOB<br/>dailyPlanSleevingJob
    participant Dispatch as CoreTubeTaskDispatchServiceImpl
    participant Schedule as DailyPlanScheduleServiceImpl
    participant CoreDB as CoreTubeMapper
    participant Task as Task模块

    XXL->>Dispatch: dispatchSleevingOnce()
    Dispatch->>Schedule: previewSleevingCandidates()
    Schedule-->>Dispatch: 按套管策略排列的候选

    loop 每种物料规格只检查一次
        Dispatch->>CoreDB: 查询管芯库一根可用目标管芯
        alt 管芯存在
            Dispatch->>Schedule: claimSleevingCandidate(日计划ID)
            Schedule-->>Dispatch: 单根Claim
            Dispatch->>CoreDB: 原子预占管芯
            Dispatch->>Task: 创建CORE_TUBE_SLEEVING_OUT
            Task-->>Dispatch: taskId
            Dispatch->>CoreDB: 管芯绑定taskId
            Dispatch->>Schedule: confirmTaskCreated(claimToken)
            Dispatch-->>XXL: 本轮结束,只创建一根
        else 管芯库没有目标管芯
            Dispatch->>Task: 查询该物料的未完成备货任务
            alt 存在托盘移入或备货抓取任务
                Dispatch-->>XXL: 记录“正在备货”,继续下一规格
            else 不存在备货任务
                Dispatch-->>XXL: 记录“备货区库存不足”,继续下一规格
            end
        end
    end

套管数量只在单根管芯出库任务完成后增加。套管策略和备货策略分别存储,因此可以一边使用顺序模式、一边使用权重模式。

五、任务完成与取消回调时序

sequenceDiagram
    autonumber
    participant ACS as AGV/桁架/套管设备
    participant Task as Task模块
    participant Handler as CoreTubeStockingTask<br/>CoreTubeSleevingTask
    participant Dispatch as CoreTubeTaskDispatchServiceImpl
    participant CoreDB as lms_core_tube
    participant Plan as DailyPlanScheduleServiceImpl

    ACS->>Task: 上报任务完成或取消
    Task->>Handler: 按handleCode调用处理器

    alt 托盘移入/移出完成
        Handler->>Dispatch: handleFinished(taskId, false)
        Dispatch->>CoreDB: 原子迁移源/目标点位
        Dispatch->>CoreDB: 更新整托盘管芯当前位置
        Note over Plan: 不更新日计划完成数量
    else 单根备货抓取完成
        Handler->>Dispatch: handleFinished(taskId, false)
        Dispatch->>CoreDB: 管芯进入管芯库并清除托盘格位
        Dispatch->>Plan: increaseStockedQuantity(..., 1)
        Plan->>Plan: 确认Claim并写进度日志
    else 单根套管出库完成
        Handler->>Dispatch: handleFinished(taskId, true)
        Dispatch->>CoreDB: 管芯进入套管设备阶段
        Dispatch->>Plan: increaseSleevedQuantity(..., 1)
        Plan->>Plan: 确认Claim并写进度日志
    else 单根任务取消
        Handler->>Dispatch: handleCancelled(taskId, ...)
        Dispatch->>CoreDB: 管芯恢复原阶段和可用状态
        Dispatch->>Plan: releaseClaim(claimToken)
    end

    Note over Dispatch,Plan: 更新语句绑定taskId或claimToken<br/>重复完成、重复取消不会重复累计

六、推荐代码阅读顺序

第一步:看页面能做什么

  • DailyPlanController:所有日计划管理和作业接口入口。
  • DailyPlanService:人工操作能力清单。
  • DailyPlanServiceImpl:订单、备货、套管的状态转换和追加数量逻辑。

先重点阅读这些方法:

  1. startOrder
  2. appendQuantity
  3. startStocking / startSleeving
  4. cancelOrder / restoreOrder / finishOrder
  5. updateSort / updateWeight / updateStrategy

第二步:看定时器入口

  • DailyPlanCoreTubeJob.dailyPlanStockingJob
  • DailyPlanCoreTubeJob.dailyPlanSleevingJob

这两个方法本身很薄,只负责按租户触发调度。核心判断都在 CoreTubeTaskDispatchServiceImpl

第三步:看备货和套管如何选任务

  • CoreTubeTaskDispatchServiceImpl.dispatchStockingOnce:对接位优先、托盘移出/移入及规格跳过。
  • CoreTubeTaskDispatchServiceImpl.dispatchSleevingOnce:管芯库单根出库和缺货日志。
  • CoreTubeTaskDispatchServiceImpl.createSingleTubeTaskClaim、管芯预占、Task 创建及权重确认的事务边界。
  • CoreTubeTaskDispatchServiceImpl.createPalletTask:一次只创建一条托盘任务的决策。

第四步:看顺序、权重和并发控制

  • DailyPlanScheduleServiceImpl.previewCandidates:只排列候选,不分配库存、不推进权重。
  • DailyPlanScheduleServiceImpl.claimCandidate:为一根现场任务创建排他 Claim。
  • DailyPlanScheduleServiceImpl.confirmTaskCreated:任务真正创建成功后才推进权重。
  • DailyPlanScheduleServiceImpl.increaseQuantity:任务完成后的幂等进度确认。
  • DailyPlanStrategyInitializer:为新租户并发安全地初始化默认顺序策略。

第五步:看任务完成后发生什么

  • CoreTubeStockingTask:托盘和备货抓取任务回调入口。
  • CoreTubeSleevingTask:套管出库任务回调入口。
  • CoreTubeTaskDispatchServiceImpl.handleFinished:完成后的库存位置和日计划数量更新。
  • CoreTubeTaskDispatchServiceImpl.handleCancelled:取消后的管芯与 Claim 恢复。

第六步:最后看 SQL 原子条件

  • DailyPlanMapper.xml:候选条件、状态转换、已备货/已套管数量原子累加。
  • DailyPlanClaimMapper.xmlClaim 活动、确认、释放和过期条件。
  • CoreTubeMapper.xml:管芯预占、绑定任务、完成和取消。
  • StockingIvtMapper.xml:对接位、缓存位、托盘选择和托盘点位迁移。

七、最重要的四个业务边界

  1. 页面“开始备货/开始套管”只改变状态,真正任务由 XXL-JOB 创建。
  2. 候选预览不等于库存分配;只有创建单根任务成功后才消耗权重。
  3. 托盘 AGV 任务不增加日计划进度,单根管芯任务完成才增加一根。
  4. 备货和套管有独立状态、策略、Claim 和进度,同一日计划上可以并行执行。