# OutboundTaskFlowService.MoveToNextStatus TODO 实现计划
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 补全 `OutboundTaskFlowService.MoveToNextStatus` 方法中的 TODO,实现在出库任务到达 `Line_OutFinish` 状态时检查对向线体托盘号,有托盘号则本地创建机械手任务,无托盘号则从 WMS 获取任务。
**Architecture:** 在 `RobotTaskService` 中新增 `CheckSourceLineAndCreateRobotTask` 方法,复用已有的 `BuildRobotTaskStock` 获取源线体编号,通过设备通信读取线体托盘号,根据结果决定调用 `CreateLocalRobotTask` 或 `GetWMSOutboundTrayTask`。
**Tech Stack:** C# / .NET 6, ASP.NET Core, SqlSugar ORM
---
## 涉及文件
| 文件 | 改动 |
|------|------|
| `WIDESEAWCS_TaskInfoService/RobotTaskService.cs` | 新增 `CheckSourceLineAndCreateRobotTask` 方法 |
| `WIDESEAWCS_TaskInfoService/Flows/OutboundTaskFlowService.cs` | 替换 TODO 代码段为委托调用 |
---
## Task 1: 在 RobotTaskService 新增 CheckSourceLineAndCreateRobotTask 方法
**Files:**
- Modify: `WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/RobotTaskService.cs:241`(在 `CreateLocalRobotTask` 方法之后)
- [ ] **Step 1: 在 `CreateLocalRobotTask` 方法后添加新方法**
在 `RobotTaskService.cs` 第 240 行(`CreateLocalRobotTask` 方法结束后的位置)添加以下方法:
```csharp
///
/// 检查源线体是否有托盘号,并根据结果创建机械手任务。
///
/// 出库任务实体
///
/// 有托盘号时返回 CreateLocalRobotTask 结果;
/// 无托盘号时返回 GetWMSOutboundTrayTask 结果。
///
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);
}
///
/// 读取指定线体的托盘号。
///
/// 源线体编号
/// 托盘号,如有异常返回 null
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.Barcode, sourceLineNo);
}
catch (Exception ex)
{
_logger.Error(ex, $"读取线体[{sourceLineNo}]托盘号异常");
return null;
}
}
```
- [ ] **Step 2: 验证编译**
Run: `dotnet build WIDESEAWCS_Server/WIDESEAWCS_Server.sln --no-restore`
Expected: BUILD SUCCEEDED(无编译错误)
- [ ] **Step 3: 提交**
```bash
git add WIDESEAWCS_TaskInfoService/RobotTaskService.cs
git commit -m "feat(机械手任务): 新增CheckSourceLineAndCreateRobotTask方法支持检查线体托盘号决策
- 新增CheckSourceLineAndCreateRobotTask方法,根据源线体托盘号决定创建机械手任务方式
- 新增ReadLineBarcode私有方法,读取指定线体的托盘号
- 有托盘号时调用CreateLocalRobotTask,无托盘号时调用GetWMSOutboundTrayTask
- 异常时降级为从WMS获取任务"
```
---
## Task 2: 修改 OutboundTaskFlowService.MoveToNextStatus 调用新方法
**Files:**
- Modify: `WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/Flows/OutboundTaskFlowService.cs:107-114`
- [ ] **Step 1: 替换 TODO 代码段**
将 `OutboundTaskFlowService.cs` 第 107-114 行:
```csharp
if (task.TaskStatus == (int)TaskOutStatusEnum.Line_OutFinish && task.TaskType == (int)TaskOutboundTypeEnum.Outbound)
{
return WebResponseContent.Instance.OK();
// Todo:获取对向线体是否有托盘号,如果有托盘号直接生成机械手任务
return GetWMSOutboundTrayTask(task);
}
```
替换为:
```csharp
if (task.TaskStatus == (int)TaskOutStatusEnum.Line_OutFinish && task.TaskType == (int)TaskOutboundTypeEnum.Outbound)
{
// 获取对向线体是否有托盘号,如果有托盘号直接生成机械手任务
return _robotTaskService.CheckSourceLineAndCreateRobotTask(task);
}
```
- [ ] **Step 2: 验证编译**
Run: `dotnet build WIDESEAWCS_Server/WIDESEAWCS_Server.sln --no-restore`
Expected: BUILD SUCCEEDED(无编译错误)
- [ ] **Step 3: 提交**
```bash
git add WIDESEAWCS_TaskInfoService/Flows/OutboundTaskFlowService.cs
git commit -m "feat(出库任务): MoveToNextStatus调用CheckSourceLineAndCreateRobotTask决策机械手任务创建方式
- 替换TODO代码段为_robotTaskService.CheckSourceLineAndCreateRobotTask调用
- 有托盘号时本地创建机械手任务,无托盘号时从WMS获取"
```
---
## 验证要点
1. 当输送线有料时(对向线体 Barcode 有值),机械手任务直接本地创建,不调用 WMS 接口
2. 当输送线无料时(对向线体 Barcode 为空),降级调用 WMS 获取空托盘任务
3. 异常场景不阻塞主流程,降级到 WMS 获取
---
## 注意事项
- `ReadLineBarcode` 方法复用了 `BuildRobotTaskStock` 中读取 Barcode 的设备查询逻辑(见 `RobotTaskService.cs:365-374`)
- 异常处理返回 null,触发降级逻辑调用 `GetWMSOutboundTrayTask`
- 设计文档位置:`docs/superpowers/specs/2026-04-29-outbound-task-flow-todo-design.md`