wanshenmean
3 天以前 5ac33ef565ff0730aede7f39a0459d53c214cc18
docs: 添加 OutboundTaskFlowService TODO 实现计划

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
已添加1个文件
170 ■■■■■ 文件已修改
Code/docs/superpowers/plans/2026-04-29-outbound-task-flow-todo-implementation.md 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/docs/superpowers/plans/2026-04-29-outbound-task-flow-todo-implementation.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,170 @@
# 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
/// <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>
/// <param name="sourceLineNo">源线体编号</param>
/// <returns>托盘号,如有异常返回 null</returns>
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 (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`