From 2f7c7a0621ee2e84c47ccd054889a71e8ce4fdd0 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期六, 18 四月 2026 22:08:14 +0800
Subject: [PATCH] feat(机械手任务): 实现换盘任务多阶段处理逻辑

---
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotWorkflowOrchestrator.cs |  301 ++++++++++++++++++++------------------------------
 1 files changed, 121 insertions(+), 180 deletions(-)

diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotWorkflowOrchestrator.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotWorkflowOrchestrator.cs
index 05f2357..fbb989d 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotWorkflowOrchestrator.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotWorkflowOrchestrator.cs
@@ -166,7 +166,7 @@
 
             var state = _stateManager.GetState(ipAddress);
 
-            // 鎹㈢洏浠诲姟浣跨敤鎵规鏍煎紡
+            // 鎹㈢洏浠诲姟鎵规妯″紡
             if (task.RobotTaskType == RobotTaskTypeEnum.ChangePallet.GetHashCode())
             {
                 int targetNormalCount = task.RobotTaskTotalNum;
@@ -174,78 +174,94 @@
 
                 bool isFlowA = task.RobotSourceAddressLineCode is "11001" or "11010";
 
-                // 娴佸悜A Phase 2锛氭斁鍋囩數鑺埌鐩爣鎵樼洏
-                if (isFlowA && state?.ChangePalletPhase == 2)
+                // ==================== Phase 2: 鏀炬甯哥數鑺埌鐩爣鎵樼洏锛堜袱娴佸悜鐩稿悓锛�====================
+                // PickFinished 鍒拌揪锛歅hase 1 鐨� Pick 鍛戒护瀹屾垚锛岀幇鍦ㄤ笅鍙� Put 鍛戒护鏀炬甯哥數鑺�
+                if (state?.ChangePalletPhase == 2)
                 {
-                    int remaining = 48 - currentCompletedCount;
-                    if (remaining <= 0) return;
+                    int remainingNormal = targetNormalCount - currentCompletedCount;
+                    if (remainingNormal <= 0)
+                    {
+                        // 姝e父鐢佃姱鍏ㄩ儴鏀惧畬锛岀瓑寰� HandlePutFinishedAsync 鍒囨崲鍒� Phase 3
+                        return;
+                    }
 
-                    int batchStart = targetNormalCount + 1 + (state.CurrentBatchIndex - 1);
-                    int putCount = Math.Min(4, remaining);
+                    int batchStart = (currentCompletedCount / 4) * 4 + 1;
+                    int putCount = Math.Min(4, remainingNormal);
                     var (start, end) = _taskProcessor.BuildBatchRange(batchStart, putCount);
 
                     await _taskProcessor.SendPutWithBatchAsync(task, state, task.RobotTargetAddress, start, end);
+
+                    // Phase 淇濇寔涓� 2锛岀瓑 HandlePutFinishedAsync 澶勭悊瀹屾斁璐ц鏁板悗鍐嶅垏鍥� Phase 1
+                    _stateManager.TryUpdateStateSafely(ipAddress, state);
                     return;
                 }
 
-                // 娴佸悜B Phase 4锛氭斁鍋囩數鑺埌5鍙蜂綅
-                if (!isFlowA && state?.ChangePalletPhase == 4)
+                // ==================== Phase 4: 鏀惧亣鐢佃姱锛堜袱娴佸悜鍒嗗弶锛�====================
+                // PickFinished 鍒拌揪锛歅hase 3 鐨� Pick 鍛戒护瀹屾垚锛岀幇鍦ㄤ笅鍙� Put 鍛戒护鏀惧亣鐢佃姱
+                if (state?.ChangePalletPhase == 4)
                 {
                     int fakeCount = 48 - targetNormalCount;
                     int completedFake = Math.Max(0, currentCompletedCount - targetNormalCount);
                     int remainingFake = fakeCount - completedFake;
 
-                    if (remainingFake <= 0) return;
-
-                    var positions = _taskProcessor.GetNextAvailableFakeBatteryPositions(Math.Min(4, remainingFake));
-                    if (positions.Count == 0)
+                    if (remainingFake <= 0)
                     {
-                        _logger.LogError("HandlePickFinishedStateAsync锛氭棤鍙敤鍋囩數鑺偣浣嶏紝浠诲姟鍙�: {TaskNum}", task.RobotTaskNum);
+                        // 鍋囩數鑺叏閮ㄦ斁瀹岋紝绛夊緟 allputfinished 瑙﹀彂 Phase 5 鍏ュ簱
                         return;
                     }
 
-                    int start = positions.Min();
-                    int end = positions.Max();
-
-                    await _taskProcessor.SendPutWithBatchAsync(task, state, "5", start, end);
-                    return;
-                }
-
-                // 娴佸悜B Phase 2锛氭斁姝e父鐢佃姱鍒扮洰鏍囨墭鐩�
-                if (!isFlowA && state?.ChangePalletPhase == 2)
-                {
-                    int remainingNormal = targetNormalCount - currentCompletedCount;
-                    if (remainingNormal <= 0) return;
-
-                    int batchStart = ((currentCompletedCount - 1) / 4) * 4 + 1;
-                    int putCount = Math.Min(4, remainingNormal);
-                    var (start, end) = _taskProcessor.BuildBatchRange(batchStart, putCount);
-
-                    await _taskProcessor.SendPutWithBatchAsync(task, state, task.RobotTargetAddress, start, end);
-                    return;
-                }
-
-                // 榛樿锛氫娇鐢ㄥ師鏈夋牸寮�
-                taskString = $"Putbattery,{task.RobotTargetAddress}";
-            }
-            else
-            {
-                // 闈炴崲鐩樹换鍔★細浣跨敤鍘熸湁鏍煎紡
-                if (state != null && state.IsGroupPallet && task.RobotTaskType == RobotTaskTypeEnum.GroupPallet.GetHashCode())
-                {
-                    // 缁勭洏浠诲姟锛氭斁璐ч渶鍒ゆ柇鏄惁NG锛屽鏋淣G鍒欐斁鍒癗G鍙�
-                    if (state.IsScanNG)
+                    if (isFlowA)
                     {
-                        taskString = $"Putbattery,4";
+                        // 娴佸悜A锛氭斁鍋囩數鑺埌鐩爣鎵樼洏
+                        int batchStart = targetNormalCount + 1 + (state.CurrentBatchIndex - 1);
+                        int putCount = Math.Min(4, remainingFake);
+                        var (start, end) = _taskProcessor.BuildBatchRange(batchStart, putCount);
+
+                        await _taskProcessor.SendPutWithBatchAsync(task, state, task.RobotTargetAddress, start, end);
+
+                        state.CurrentBatchIndex += putCount;
+                        // Phase 淇濇寔涓� 4锛岀瓑 HandlePutFinishedAsync 澶勭悊瀹屽悗鍐嶅垏鍥� Phase 3
+                        _stateManager.TryUpdateStateSafely(ipAddress, state);
                     }
                     else
                     {
-                        taskString = $"Putbattery,{task.RobotTargetAddress}";
+                        // 娴佸悜B锛氭斁鍋囩數鑺埌5鍙蜂綅
+                        var positions = _taskProcessor.GetNextAvailableFakeBatteryPositions(Math.Min(4, remainingFake));
+                        if (positions.Count == 0)
+                        {
+                            _logger.LogError("HandlePickFinishedStateAsync锛氭棤鍙敤鍋囩數鑺偣浣嶏紝浠诲姟鍙�: {TaskNum}", task.RobotTaskNum);
+                            return;
+                        }
+
+                        int start = positions.Min();
+                        int end = positions.Max();
+
+                        await _taskProcessor.SendPutWithBatchAsync(task, state, "5", start, end);
+
+                        // Phase 淇濇寔涓� 4锛岀瓑 HandlePutFinishedAsync 澶勭悊瀹屽悗鍐嶅垏鍥� Phase 3
+                        _stateManager.TryUpdateStateSafely(ipAddress, state);
                     }
+                    return;
+                }
+
+                // 闈炴壒娆℃ā寮忔垨鍏朵粬闃舵涓嶄笅鍙戞寚浠�
+                return;
+            }
+
+            // 闈炴崲鐩樹换鍔★細浣跨敤鍘熸湁鏍煎紡
+            if (state != null && state.IsGroupPallet && task.RobotTaskType == RobotTaskTypeEnum.GroupPallet.GetHashCode())
+            {
+                if (state.IsScanNG)
+                {
+                    taskString = $"Putbattery,4";
                 }
                 else
+                {
                     taskString = $"Putbattery,{task.RobotTargetAddress}";
+                }
             }
+            else
+                taskString = $"Putbattery,{task.RobotTargetAddress}";
 
             bool result = await _clientManager.SendToClientAsync(ipAddress, taskString);
 
@@ -376,7 +392,9 @@
             else if (task.RobotTaskType == RobotTaskTypeEnum.ChangePallet.GetHashCode())
             {
                 const int targetTotal = 48;
+                // 鎹㈢洏浠诲姟杩涘叆鎵规妯″紡锛屽垎闃舵澶勭悊姝e父鐢佃姱鍜屽亣鐢佃姱 锛堟満鍣ㄤ汉浠诲姟鎬绘暟锛�
                 int targetNormalCount = task.RobotTaskTotalNum;
+                // 褰撳墠宸插畬鎴愭暟閲忥紙鍙栬揣瀹屾垚鐨勬暟閲忥級锛屽垵濮嬩负鐘舵�佷腑鐨� RobotTaskTotalNum锛屽悗缁牴鎹彇璐у畬鎴愮殑鏁伴噺鍔ㄦ�佹洿鏂�
                 int currentCompletedCount = stateForUpdate.RobotTaskTotalNum;
 
                 // 鍒ゆ柇娴佸悜锛坣ull-safe锛�
@@ -396,159 +414,82 @@
                     stateForUpdate.CurrentBatchIndex = 1;
                     _logger.LogInformation("HandlePutFinishedStateAsync锛氭崲鐩樹换鍔¤繘鍏ユ壒娆℃ā寮忥紝浠诲姟鍙�: {TaskNum}锛屾祦鍚�: {Flow}",
                         task.RobotTaskNum, isFlowA ? "A" : "B");
+                    _stateManager.TryUpdateStateSafely(ipAddress, stateForUpdate);
                 }
 
-                // ==================== 娴佸悜A锛氳ˉ鍋囩數鑺埌鐩爣鎵樼洏 ====================
-                if (isFlowA)
+                // ==================== Phase 1: 鍙栨甯哥數鑺紙涓ゆ祦鍚戠浉鍚岋級====================
+                if (stateForUpdate.ChangePalletPhase == 1)
                 {
-                    // Phase 1: 鍙栧亣鐢佃姱锛堜粠5鍙蜂綅锛屼娇鐢� PositionIndex锛�
-                    if (stateForUpdate.ChangePalletPhase == 1)
+                    int remainingNormal = targetNormalCount - currentCompletedCount;
+                    if (remainingNormal <= 0)
                     {
-                        int remaining = targetTotal - currentCompletedCount;
-                        if (remaining <= 0)
-                        {
-                            stateForUpdate.ChangePalletPhase = 0;
-                            stateForUpdate.CurrentBatchIndex = 1;
-                            stateForUpdate.IsInFakeBatteryMode = false;
-                            _logger.LogInformation("HandlePutFinishedStateAsync锛氭祦鍚慉瀹屾垚锛屼换鍔″彿: {TaskNum}", task.RobotTaskNum);
-                            return;
-                        }
-
-                        int pickCount = Math.Min(4, remaining);
-                        var positions = _taskProcessor.GetNextAvailableFakeBatteryPositions(pickCount);
-                        if (positions.Count == 0)
-                        {
-                            _logger.LogError("HandlePutFinishedStateAsync锛氭棤鍙敤鍋囩數鑺偣浣嶏紝浠诲姟鍙�: {TaskNum}", task.RobotTaskNum);
-                            return;
-                        }
-
-                        await _taskProcessor.SendSocketRobotFakeBatteryPickAsync(task, stateForUpdate, positions);
-                        stateForUpdate.ChangePalletPhase = 2;
+                        // 姝e父鐢佃姱鍙栧畬锛屽垏鎹㈠埌 Phase 3 鍙栧亣鐢佃姱
+                        stateForUpdate.ChangePalletPhase = 3;
+                        stateForUpdate.CurrentBatchIndex = 1; // 鍋囩數鑺壒娆′粠澶村紑濮�
+                        _logger.LogInformation("HandlePutFinishedStateAsync锛氭甯哥數鑺彇瀹岋紝鍒囨崲鍒癙hase 3鍙栧亣鐢佃姱锛屼换鍔″彿: {TaskNum}", task.RobotTaskNum);
+                        _stateManager.TryUpdateStateSafely(ipAddress, stateForUpdate);
+                        return;
                     }
-                    // Phase 2: 鏀惧亣鐢佃姱鍒扮洰鏍囨墭鐩橈紙浠� targetNormalCount+1 寮�濮嬮�掑锛�
-                    else if (stateForUpdate.ChangePalletPhase == 2)
-                    {
-                        int remaining = targetTotal - currentCompletedCount;
-                        if (remaining <= 0)
-                        {
-                            stateForUpdate.ChangePalletPhase = 0;
-                            stateForUpdate.CurrentBatchIndex = 1;
-                            stateForUpdate.IsInFakeBatteryMode = false;
-                            _logger.LogInformation("HandlePutFinishedStateAsync锛氭祦鍚慉瀹屾垚锛屼换鍔″彿: {TaskNum}", task.RobotTaskNum);
-                            return;
-                        }
 
-                        // 璁$畻鏀捐揣鎵规缂栧彿锛氫粠 targetNormalCount + 1 寮�濮�
-                        int batchStart = targetNormalCount + 1 + (stateForUpdate.CurrentBatchIndex - 1);
-                        int putCount = Math.Min(4, remaining);
-                        var (start, end) = _taskProcessor.BuildBatchRange(batchStart, putCount);
+                    int pickCount = Math.Min(4, remainingNormal);
+                    var (start, end) = _taskProcessor.BuildBatchRange(stateForUpdate.CurrentBatchIndex, pickCount);
 
-                        await _taskProcessor.SendPutWithBatchAsync(task, stateForUpdate, task.RobotTargetAddress, start, end);
+                    await _taskProcessor.SendPickWithBatchAsync(task, stateForUpdate, task.RobotSourceAddress, start, end);
 
-                        stateForUpdate.CurrentBatchIndex += putCount;
-                        stateForUpdate.ChangePalletPhase = 1;
-                    }
+                    stateForUpdate.CurrentBatchIndex += pickCount;
+                    // 鍙戝畬 Pick 鍚庡垏鎹㈠埌 Phase=2锛岀瓑 PickFinished 瑙﹀彂 HandlePickFinishedStateAsync 涓嬪彂鏀捐揣鎸囦护
+                    stateForUpdate.ChangePalletPhase = 2;
+                    _stateManager.TryUpdateStateSafely(ipAddress, stateForUpdate);
+                    return;
                 }
-                // ==================== 娴佸悜B锛氬彇姝e父鐢佃姱 + 鍥炴敹鍋囩數鑺� ====================
-                else
+
+                // ==================== Phase 3: 澶勭悊鍋囩數鑺紙娴佸悜A/B 鍒嗗弶锛夛紝鑷繁寰幆 ====================
+                if (stateForUpdate.ChangePalletPhase == 3)
                 {
-                    // Phase 1: 鍙栨甯哥數鑺紙浠庢簮鍦板潃锛屼粠1寮�濮嬮�掑锛�
-                    if (stateForUpdate.ChangePalletPhase == 1)
+                    int fakeCount = targetTotal - targetNormalCount;
+                    int completedFake = Math.Max(0, currentCompletedCount - targetNormalCount);
+                    int remainingFake = fakeCount - completedFake;
+
+                    if (remainingFake <= 0)
                     {
-                        int remainingNormal = targetNormalCount - currentCompletedCount;
-                        if (remainingNormal <= 0)
-                        {
-                            // 姝e父鐢佃姱鍙栧畬锛屽垏鎹㈠埌 Phase 3
-                            stateForUpdate.ChangePalletPhase = 3;
-                            stateForUpdate.CurrentBatchIndex = targetNormalCount + 1;
-                            _logger.LogInformation("HandlePutFinishedStateAsync锛氭甯哥數鑺叏閮ㄥ彇瀹岋紝杩涘叆Phase 3鍥炴敹鍋囩數鑺紝浠诲姟鍙�: {TaskNum}", task.RobotTaskNum);
-                            return;
-                        }
-
-                        int pickCount = Math.Min(4, remainingNormal);
-                        var (start, end) = _taskProcessor.BuildBatchRange(stateForUpdate.CurrentBatchIndex, pickCount);
-
-                        await _taskProcessor.SendPickWithBatchAsync(task, stateForUpdate, task.RobotSourceAddress, start, end);
-
-                        stateForUpdate.CurrentBatchIndex += pickCount;
-                        stateForUpdate.ChangePalletPhase = 2;
+                        // 鍋囩數鑺叏閮ㄥ鐞嗗畬锛屽垏鎹㈠埌 Phase 5 绛夊緟鍏ュ簱
+                        stateForUpdate.ChangePalletPhase = 5;
+                        _logger.LogInformation("HandlePutFinishedStateAsync锛氬亣鐢佃姱澶勭悊瀹屾瘯锛屽垏鎹㈠埌Phase 5绛夊緟鍏ュ簱锛屼换鍔″彿: {TaskNum}", task.RobotTaskNum);
+                        _stateManager.TryUpdateStateSafely(ipAddress, stateForUpdate);
+                        return;
                     }
-                    // Phase 2: 鏀炬甯哥數鑺埌鐩爣鎵樼洏锛堟斁璐х紪鍙蜂笌鍙栬揣缂栧彿涓�鑷达級
-                    else if (stateForUpdate.ChangePalletPhase == 2)
+
+                    if (isFlowA)
                     {
-                        int remainingNormal = targetNormalCount - currentCompletedCount;
-                        if (remainingNormal <= 0)
-                        {
-                            // 姝e父鐢佃姱鏀惧畬锛屽垏鎹㈠埌 Phase 3
-                            stateForUpdate.ChangePalletPhase = 3;
-                            stateForUpdate.CurrentBatchIndex = targetNormalCount + 1;
-                            _logger.LogInformation("HandlePutFinishedStateAsync锛氭甯哥數鑺叏閮ㄦ斁瀹岋紝杩涘叆Phase 3鍥炴敹鍋囩數鑺紝浠诲姟鍙�: {TaskNum}", task.RobotTaskNum);
-                            return;
-                        }
-
-                        // 璁$畻鏈壒鏀捐揣缂栧彿锛氬熀浜� currentCompletedCount 鎺ㄥ鎵规璧峰
-                        int batchStart = ((currentCompletedCount - 1) / 4) * 4 + 1;
-                        int putCount = Math.Min(4, remainingNormal);
-                        var (start, end) = _taskProcessor.BuildBatchRange(batchStart, putCount);
-
-                        await _taskProcessor.SendPutWithBatchAsync(task, stateForUpdate, task.RobotTargetAddress, start, end);
-
-                        stateForUpdate.ChangePalletPhase = 1;
-                    }
-                    // Phase 3: 鍙栧亣鐢佃姱锛堜粠婧愬湴鍧�锛屼粠 targetNormalCount+1 寮�濮嬮�掑锛�
-                    else if (stateForUpdate.ChangePalletPhase == 3)
-                    {
-                        int fakeCount = targetTotal - targetNormalCount;
-                        int completedFake = Math.Max(0, currentCompletedCount - targetNormalCount);
-                        int remainingFake = fakeCount - completedFake;
-
-                        if (remainingFake <= 0)
-                        {
-                            stateForUpdate.ChangePalletPhase = 0;
-                            stateForUpdate.CurrentBatchIndex = 1;
-                            stateForUpdate.IsInFakeBatteryMode = false;
-                            _logger.LogInformation("HandlePutFinishedStateAsync锛氭祦鍚態瀹屾垚锛屼换鍔″彿: {TaskNum}", task.RobotTaskNum);
-                            return;
-                        }
-
-                        int pickCount = Math.Min(4, remainingFake);
-                        var (start, end) = _taskProcessor.BuildBatchRange(stateForUpdate.CurrentBatchIndex, pickCount);
-
-                        await _taskProcessor.SendPickWithBatchAsync(task, stateForUpdate, task.RobotSourceAddress, start, end);
-
-                        stateForUpdate.CurrentBatchIndex += pickCount;
-                        stateForUpdate.ChangePalletPhase = 4;
-                    }
-                    // Phase 4: 鏀惧亣鐢佃姱鍒�5鍙蜂綅锛堜娇鐢� PositionIndex锛�
-                    else if (stateForUpdate.ChangePalletPhase == 4)
-                    {
-                        int fakeCount = targetTotal - targetNormalCount;
-                        int completedFake = Math.Max(0, currentCompletedCount - targetNormalCount);
-                        int remainingFake = fakeCount - completedFake;
-
-                        if (remainingFake <= 0)
-                        {
-                            stateForUpdate.ChangePalletPhase = 0;
-                            stateForUpdate.CurrentBatchIndex = 1;
-                            stateForUpdate.IsInFakeBatteryMode = false;
-                            _logger.LogInformation("HandlePutFinishedStateAsync锛氭祦鍚態瀹屾垚锛屼换鍔″彿: {TaskNum}", task.RobotTaskNum);
-                            return;
-                        }
-
+                        // 娴佸悜A锛氫粠5鍙蜂綅鍙栧亣鐢佃姱
                         var positions = _taskProcessor.GetNextAvailableFakeBatteryPositions(Math.Min(4, remainingFake));
                         if (positions.Count == 0)
                         {
                             _logger.LogError("HandlePutFinishedStateAsync锛氭棤鍙敤鍋囩數鑺偣浣嶏紝浠诲姟鍙�: {TaskNum}", task.RobotTaskNum);
                             return;
                         }
-
-                        int start = positions.Min();
-                        int end = positions.Max();
-
-                        await _taskProcessor.SendPutWithBatchAsync(task, stateForUpdate, "5", start, end);
-
-                        stateForUpdate.ChangePalletPhase = 3;
+                        await _taskProcessor.SendSocketRobotFakeBatteryPickAsync(task, stateForUpdate, positions);
                     }
+                    else
+                    {
+                        // 娴佸悜B锛氫粠婧愬湴鍧�鍙栧亣鐢佃姱
+                        int pickCount = Math.Min(4, remainingFake);
+                        var (start, end) = _taskProcessor.BuildBatchRange(stateForUpdate.CurrentBatchIndex, pickCount);
+                        await _taskProcessor.SendPickWithBatchAsync(task, stateForUpdate, task.RobotSourceAddress, start, end);
+                        stateForUpdate.CurrentBatchIndex += pickCount;
+                    }
+
+                    // 鍙戝畬 Pick 鍚庡垏鎹㈠埌 Phase=4锛岀瓑 PickFinished 瑙﹀彂 HandlePickFinishedStateAsync 涓嬪彂鏀捐揣鎸囦护
+                    stateForUpdate.ChangePalletPhase = 4;
+                    _stateManager.TryUpdateStateSafely(ipAddress, stateForUpdate);
+                    return;
+                }
+
+                // ==================== Phase 5: 瀹屾垚鍏ュ簱锛坅llputfinished / allpickfinished 瑙﹀彂锛�====================
+                if (stateForUpdate.ChangePalletPhase == 5)
+                {
+                    // Phase 5 鐢� allpickfinished/allputfinished 瑙﹀彂鍏ュ簱锛屾湰鏂规硶涓嶅啀涓嬪彂鎸囦护
+                    return;
                 }
             }
             else

--
Gitblit v1.9.3