编辑 | blame | 历史 | 原始文档

OutboundTaskFlowService.MoveToNextStatus TODO 设计方案

背景

OutboundTaskFlowService.MoveToNextStatus 方法中存在一个 TODO:

if (task.TaskStatus == (int)TaskOutStatusEnum.Line_OutFinish && task.TaskType == (int)TaskOutboundTypeEnum.Outbound)
{
    return WebResponseContent.Instance.OK();

    // Todo:获取对向线体是否有托盘号,如果有托盘号直接生成机械手任务

    return GetWMSOutboundTrayTask(task);
}

该 TODO 需要在出库任务到达 Line_OutFinish 状态时,检查对向线体是否有托盘号,以决定后续机械手任务的创建方式。

业务逻辑

出库任务流程中,当物料通过输送线到达目标位置后:

  • 对向线体有托盘号 → 托盘上有货,直接在本地创建机械手任务执行换盘/组盘/拆盘
  • 对向线体无托盘号 → 需要从 WMS 获取空托盘出库任务

方案选择

采用方案 B:在 RobotTaskService 中封装检查逻辑,复用已有的 BuildRobotTaskStock 基础设施。

原因

  • RobotTaskService.BuildRobotTaskStock 已实现通过 AddressSourceLineNoMap 解析源线体编号,并通过设备通信读取 Barcode 的完整逻辑
  • 新增方法职责单一:检查 → 决策,仅做判断不执行副作用
  • OutboundTaskFlowService 保持简洁,只需调用即可

实现设计

1. RobotTaskService 新增方法

/// <summary>
/// 检查源线体是否有托盘号,并根据结果创建机械手任务。
/// </summary>
/// <param name="task">出库任务实体</param>
/// <returns>
/// 有托盘号时返回 CreateLocalRobotTask 结果;
/// 无托盘号时返回 GetWMSOutboundTrayTask 结果。
/// </returns>
public WebResponseContent CheckSourceLineAndCreateRobotTask(Dt_Task task)
{
    // 1. 获取源线体编号(复用已有逻辑)
    string configKey = ResolveRobotTaskConfigKey(task.TargetAddress);
    StockDTO stock = BuildRobotTaskStock(task, configKey);
    string sourceLineNo = stock.SourceLineNo;

    if (string.IsNullOrWhiteSpace(sourceLineNo))
    {
        return GetWMSOutboundTrayTask(task);
    }

    // 2. 通过设备通信读取线体托盘号
    string? palletCode = ReadLineBarcode(sourceLineNo);

    if (!string.IsNullOrWhiteSpace(palletCode))
    {
        // 有托盘号,本地创建机械手任务
        return CreateLocalRobotTask(task);
    }

    // 无托盘号,从 WMS 获取任务
    return GetWMSOutboundTrayTask(task);
}

/// <summary>
/// 读取指定线体的托盘号。
/// </summary>
private string? ReadLineBarcode(string sourceLineNo)
{
    try
    {
        IDevice? device = Storage.Devices.FirstOrDefault(x =>
            x.DeviceProDTOs.Any(d => d.DeviceChildCode == sourceLineNo));

        if (device == null)
            return null;

        CommonConveyorLine conveyorLine = (CommonConveyorLine)device;
        return conveyorLine.GetValue<ConveyorLineDBNameNew, string>(
            ConveyorLineDBNameNew.Barcode, sourceLineNo);
    }
    catch
    {
        return null;
    }
}

2. OutboundTaskFlowService 修改

if (task.TaskStatus == (int)TaskOutStatusEnum.Line_OutFinish && task.TaskType == (int)TaskOutboundTypeEnum.Outbound)
{
    // 获取对向线体是否有托盘号,如果有托盘号直接生成机械手任务
    return _robotTaskService.CheckSourceLineAndCreateRobotTask(task);
}

数据流

MoveToNextStatus (OutboundTaskFlowService)
    │
    ▼
CheckSourceLineAndCreateRobotTask (RobotTaskService)
    │
    ├───► BuildRobotTaskStock ──► ResolveRobotTaskConfigKey
    │                              └──► AddressSourceLineNoMap 获取 sourceLineNo
    │
    ▼
ReadLineBarcode(sourceLineNo)
    │
    ├───► Storage.Devices 查找设备
    └───► CommonConveyorLine.GetValue(Barcode)
                │
                ▼
        ┌───────┴───────┐
        │  托盘号有值    │     托盘号为空
        ▼               ▼
CreateLocalRobotTask   GetWMSOutboundTrayTask

错误处理

  • 设备查找失败或读取异常 → 降级为调用 GetWMSOutboundTrayTask(从 WMS 获取任务)
  • 不阻塞主流程,异常仅记录日志

涉及文件

文件 改动
WIDESEAWCS_TaskInfoService/RobotTaskService.cs 新增 CheckSourceLineAndCreateRobotTaskReadLineBarcode 方法
WIDESEAWCS_TaskInfoService/Flows/OutboundTaskFlowService.cs 替换 TODO 代码段为委托调用

验证要点

  1. 当输送线有料时,机械手任务直接本地创建,不调用 WMS 接口
  2. 当输送线无料时,降级调用 WMS 获取空托盘任务
  3. 异常场景不阻塞主流程,降级到 WMS 获取