wanshenmean
3 天以前 c4c82824f408176298d48aea46056010a1674401
docs: 添加 OutboundTaskFlowService MoveToNextStatus TODO 设计方案

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
已添加1个文件
148 ■■■■■ 文件已修改
Code/docs/superpowers/specs/2026-04-29-outbound-task-flow-todo-design.md 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/docs/superpowers/specs/2026-04-29-outbound-task-flow-todo-design.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,148 @@
# OutboundTaskFlowService.MoveToNextStatus TODO è®¾è®¡æ–¹æ¡ˆ
## èƒŒæ™¯
`OutboundTaskFlowService.MoveToNextStatus` æ–¹æ³•中存在一个 TODO:
```csharp
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 æ–°å¢žæ–¹æ³•
```csharp
/// <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 ä¿®æ”¹
```csharp
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` | æ–°å¢ž `CheckSourceLineAndCreateRobotTask` å’Œ `ReadLineBarcode` æ–¹æ³• |
| `WIDESEAWCS_TaskInfoService/Flows/OutboundTaskFlowService.cs` | æ›¿æ¢ TODO ä»£ç æ®µä¸ºå§”托调用 |
## éªŒè¯è¦ç‚¹
1. å½“输送线有料时,机械手任务直接本地创建,不调用 WMS æŽ¥å£
2. å½“输送线无料时,降级调用 WMS èŽ·å–ç©ºæ‰˜ç›˜ä»»åŠ¡
3. å¼‚常场景不阻塞主流程,降级到 WMS èŽ·å–