From b698a2085fd090e90abedb1e91266ec496574b29 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期四, 16 四月 2026 23:31:35 +0800
Subject: [PATCH] 1
---
Code/docs/superpowers/specs/2026-04-16-change-pallet-batch-command-design.md | 180 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 180 insertions(+), 0 deletions(-)
diff --git a/Code/docs/superpowers/specs/2026-04-16-change-pallet-batch-command-design.md b/Code/docs/superpowers/specs/2026-04-16-change-pallet-batch-command-design.md
new file mode 100644
index 0000000..a3f0f7d
--- /dev/null
+++ b/Code/docs/superpowers/specs/2026-04-16-change-pallet-batch-command-design.md
@@ -0,0 +1,180 @@
+# 鎹㈢洏浠诲姟鎵规鎸囦护涓庡弻娴佸悜璁捐
+
+## 姒傝堪
+
+瀵规崲鐩樹换鍔★紙ChangePallet锛夌殑鍙栬揣/鏀捐揣鎸囦护鏍煎紡杩涜鍗囩骇锛屾敮鎸佹壒娆$紪鍙峰拰鎬绘暟鎸囦护锛屽苟鏍规嵁 `RobotSourceAddressLineCode` 鍖哄垎涓ょ娴佸悜銆�
+
+## 鑳屾櫙
+
+褰撳墠鎹㈢洏浠诲姟瀹炵幇锛堜笂涓�杞凯浠o級浠呭鐞嗕簡 `HandlePutFinishedStateAsync` 涓殑鍋囩數鑺ˉ鍏呴�昏緫锛屾寚浠ゆ牸寮忎负绠�鍗曠殑 `Pickbattery,{鍦板潃}` 鍜� `Pickbattery,5,{start}-{end}`銆傜幇闇�瑕侊細
+
+1. 鎵�鏈夋崲鐩樺彇璐�/鏀捐揣鎸囦护缁熶竴涓烘壒娆℃牸寮� `{Command},{浣嶇疆},{start}-{end}`
+2. 姣忔壒鍓嶅彂閫佹�绘暟鎸囦护 `PickTotalNum,{N}` / `PutTotalNum,{N}`
+3. 鏍规嵁婧愬湴鍧�绾夸綋缂栫爜鍖哄垎涓ょ瀹屽叏涓嶅悓鐨勬搷浣滄祦鍚�
+
+## 鎸囦护鏍煎紡
+
+### 鎵规鎸囦护
+
+| 鎸囦护绫诲瀷 | 鏍煎紡 | 绀轰緥 |
+|----------|------|------|
+| 鍙栬揣鎬绘暟 | `PickTotalNum,{N}` | `PickTotalNum,11` |
+| 鏀捐揣鎬绘暟 | `PutTotalNum,{N}` | `PutTotalNum,11` |
+| 鍙栬揣鎵规 | `Pickbattery,{浣嶇疆},{start}-{end}` | `Pickbattery,3,1-4` |
+| 鏀捐揣鎵规 | `Putbattery,{浣嶇疆},{start}-{end}` | `Putbattery,6,5-8` |
+| 鍙栬揣鍗曚釜 | `Pickbattery,{浣嶇疆},{n}-0` | `Pickbattery,3,11-0` |
+| 鏀捐揣鍗曚釜 | `Putbattery,{浣嶇疆},{n}-0` | `Putbattery,6,11-0` |
+
+- `PickTotalNum/PutTotalNum` 浠呮崲鐩樹换鍔″彂閫侊紝姣忔壒鍙�/鏀句箣鍓嶉兘鍙�
+- `N` = 鐪熷疄鐢佃姱鏁伴噺锛堝嵆 `task.RobotTaskTotalNum`锛夛紝鏈哄櫒浜哄浐浠剁敤姝ゅ�煎垽鏂墭鐩樹笂姝e父鐢佃姱鎬绘暟锛屼袱绉嶆祦鍚戝潎鍙戦�佺浉鍚岀殑 N 鍊�
+- 姣忔壒鏈�澶�4涓紝涓嶆弧4涓寜瀹為檯鏁板彂锛屽墿1涓椂 end=0
+
+### 鎵规缂栧彿璁$畻
+
+`BuildBatchRange(currentIndex, remaining)` 鈫� `(start, end)`:
+- `remaining >= 4` 鈫� `(currentIndex, currentIndex + 3)`
+- `remaining > 1` 鈫� `(currentIndex, currentIndex + remaining - 1)`
+- `remaining == 1` 鈫� `(currentIndex, 0)`
+
+绀轰緥锛坱argetNormalCount=11锛夛細绗�1鎵� 1-4锛岀2鎵� 5-8锛岀3鎵� 9-11
+绀轰緥锛坱argetNormalCount=9锛夛細绗�1鎵� 1-4锛岀2鎵� 5-8锛岀3鎵� 9-0锛堝崟涓紝end=0锛�
+
+## 涓ょ娴佸悜
+
+### 娴佸悜A锛氳ˉ鍋囩數鑺埌鐩爣鎵樼洏
+
+**鏉′欢锛�** `RobotSourceAddressLineCode == "11001" || "11010"`
+
+**鍦烘櫙锛�** 鐩爣鎵樼洏鏈� N 涓甯哥數鑺紙N < 48锛夛紝闇�浠�5鍙蜂綅鍋囩數鑺墭鐩樺彇鍋囩數鑺ˉ婊�48涓��
+
+**闃舵娴佽浆锛�**
+
+```
+[鍙栧亣鐢佃姱] Pickbattery,5,{positionIndex} 鈫� 浠�5鍙蜂綅鍙栵紝缂栧彿鐢ㄥ钩闈㈢偣浣嶈〃PositionIndex
+ 鈫�
+[鏀惧亣鐢佃姱] Putbattery,{鐩爣鍦板潃},{N+1}-{N+4} 鈫� 鏀惧埌鐩爣鎵樼洏锛岀紪鍙蜂粠姝e父鏁�+1閫掑
+ 鈫�
+閲嶅鐩村埌琛ユ弧48涓�
+```
+
+鍋囩數鑺暟閲� = `48 - task.RobotTaskTotalNum`
+
+### 娴佸悜B锛氬彇姝e父鐢佃姱 + 鍥炴敹鍋囩數鑺�
+
+**鏉′欢锛�** `RobotSourceAddressLineCode != "11001" && != "11010"`
+
+**鍦烘櫙锛�** 婧愭墭鐩樺師鏈弧48涓紙姝e父鐢佃姱 + 鍋囩數鑺贩鍚堬級锛屽厛鍙栬蛋姝e父鐢佃姱鏀惧埌鐩爣鎵樼洏锛屽啀鎶婃簮鎵樼洏涓婂墿浣欑殑鍋囩數鑺彇鍑烘斁鍥�5鍙蜂綅銆�
+
+**闃舵娴佽浆锛�**
+
+```
+Phase 1 - 鍙栨甯哥數鑺�:
+[鍙栨甯竇 Pickbattery,{婧愬湴鍧�},{1}-{4} 鈫� 缂栧彿浠�1閫掑
+ 鈫�
+[鏀炬甯竇 Putbattery,{鐩爣鍦板潃},{1}-{4} 鈫� 缂栧彿浠�1閫掑
+ 鈫�
+閲嶅鐩村埌 N 涓甯哥數鑺叏閮ㄥ彇瀹�
+
+Phase 2 - 鍥炴敹鍋囩數鑺�:
+[鍙栧亣鐢佃姱] Pickbattery,{婧愬湴鍧�},{N+1}-{N+4} 鈫� 缂栧彿浠庢甯告暟+1缁х画閫掑
+ 鈫�
+[鏀惧亣鐢佃姱] Putbattery,5,{positionIndex} 鈫� 鏀惧洖5鍙蜂綅锛岀紪鍙风敤骞抽潰鐐逛綅琛≒ositionIndex
+ 鈫�
+閲嶅鐩村埌鍋囩數鑺叏閮ㄥ洖鏀讹紙48-N 涓級
+```
+
+## 鐘舵�佺鐞�
+
+### RobotSocketState 鏂板瀛楁
+
+```csharp
+/// <summary>
+/// 褰撳墠鎵规璧峰缂栧彿锛堢敤浜庨�掑璁$畻鍙栬揣/鏀捐揣缂栧彿锛�
+/// </summary>
+public int CurrentBatchIndex { get; set; } = 1;
+
+/// <summary>
+/// 鎹㈢洏浠诲姟褰撳墠闃舵
+/// </summary>
+/// <remarks>
+/// 0: 鏈紑濮�
+/// 1: 鍙栨甯哥數鑺� / 鍙栧亣鐢佃姱锛堟祦鍚慉锛�
+/// 2: 鏀炬甯哥數鑺� / 鏀惧亣鐢佃姱锛堟祦鍚慉锛�
+/// 3: 鍙栧亣鐢佃姱锛堟祦鍚態 Phase2锛�
+/// 4: 鏀惧亣鐢佃姱鍒�5鍙蜂綅锛堟祦鍚態 Phase2锛�
+/// </remarks>
+public int ChangePalletPhase { get; set; }
+```
+
+### CurrentBatchIndex 鐢熷懡鍛ㄦ湡
+
+**娴佸悜A锛�**
+- Phase 0鈫�1锛歚CurrentBatchIndex = 1`锛堝垵濮嬪寲锛岀敤浜� PositionIndex 鏌ヨ璧风偣锛�
+- Phase 1鈫�2锛氫笉閲嶇疆锛堟斁璐х紪鍙蜂粠 `targetNormalCount + 1` 寮�濮嬶紝鐢� Orchestrator 璁$畻锛�
+- Phase 2鈫�1锛歚CurrentBatchIndex += 鏈壒鏁伴噺`锛堥�掑锛屼笅涓�鎵圭户缁級
+- 瀹屾垚鈫�0锛歚CurrentBatchIndex = 1`锛堥噸缃級
+
+**娴佸悜B锛�**
+- Phase 0鈫�1锛歚CurrentBatchIndex = 1`锛堝彇姝e父鐢佃姱浠�1寮�濮嬶級
+- Phase 1鈫�2锛氫笉閲嶇疆锛堟斁璐х紪鍙蜂笌鍙栬揣缂栧彿涓�鑷达級
+- Phase 2鈫�1锛歚CurrentBatchIndex += 鏈壒鏁伴噺`锛堥�掑锛�
+- Phase 2鈫�3锛堟甯哥數鑺彇瀹岋紝鍗� `state.RobotTaskTotalNum >= targetNormalCount` 鏃� putfinished 瀹屾垚鍚庤Е鍙戯級锛歚CurrentBatchIndex = targetNormalCount + 1`锛堝亣鐢佃姱浠庢甯告暟+1寮�濮嬶級
+- Phase 3鈫�4锛氫笉閲嶇疆锛堟斁鍋囩數鑺敤 PositionIndex锛岀敱 Orchestrator 璁$畻锛�
+- Phase 4鈫�3锛歚CurrentBatchIndex += 鏈壒鏁伴噺`锛堥�掑锛�
+- 瀹屾垚鈫�0锛歚CurrentBatchIndex = 1`锛堥噸缃級
+
+### 闃舵娴佽浆鐘舵�佹満
+
+**娴佸悜A锛�**
+```
+Phase 0 鈫� Phase 1锛堝彇鍋囩數鑺痜rom 5鍙蜂綅锛夆啋 Phase 2锛堟斁鍋囩數鑺痶o 鐩爣锛夆啋 Phase 1 鈫� ... 鈫� Phase 0锛堝畬鎴愶級
+```
+
+**娴佸悜B锛�**
+```
+Phase 0 鈫� Phase 1锛堝彇姝e父from 婧愶級鈫� Phase 2锛堟斁姝e父to 鐩爣锛夆啋 Phase 1 鈫� ...
+ 鈫� Phase 3锛堝彇鍋囩數鑺痜rom 婧愶級鈫� Phase 4锛堟斁鍋囩數鑺痶o 5鍙蜂綅锛夆啋 Phase 3 鈫� ... 鈫� Phase 0锛堝畬鎴愶級
+```
+
+## 浠g爜鏀瑰姩鑼冨洿
+
+| 鏂囦欢 | 鏀瑰姩 |
+|------|------|
+| `RobotSocketState.cs` | +`CurrentBatchIndex`, +`ChangePalletPhase` |
+| `RobotTaskProcessor.cs` | +`BuildBatchRange()`, +`SendPickWithBatchAsync()`, +`SendPutWithBatchAsync()`, 淇敼鐜版湁鍋囩數鑺柟娉� |
+| `RobotWorkflowOrchestrator.cs` | 閲嶅啓 ChangePallet 鍒嗘敮锛圚andlePutFinishedStateAsync + HandlePickFinishedStateAsync锛� |
+| `RobotPrefixCommandHandler.cs` | HandlePutFinishedAsync 涓尯鍒嗘崲鐩橀樁娈碉細鍋囩數鑺斁璐т笉璋冪敤 ChangePalletAsync API锛屼笉閫掑 `RobotTaskTotalNum`锛汬andlePickFinishedAsync 涓亣鐢佃姱鍙栬揣涓嶈皟鐢ㄦ媶鐩� API |
+| `RobotSimpleCommandHandler.cs` | allpickfinished/allputfinished 涓鍔� `ChangePalletPhase` 瀹堝崼锛氫粎褰� Phase==0锛堟墍鏈夐樁娈靛畬鎴愶級鏃舵墠瑙﹀彂鍏ュ簱鍜屽垹闄や换鍔★紝涓棿闃舵涓嶅鐞� |
+| `IFakeBatteryPositionService.cs` | +`MarkAsAvailable(List<int> positions)` 鏂规硶 |
+| `FakeBatteryPositionService.cs` | +`MarkAsAvailable` 瀹炵幇 |
+| `IFakeBatteryPositionRepository.cs` | +`MarkAsAvailable(List<int> positions)` 鏂规硶 |
+| `FakeBatteryPositionRepository.cs` | +`MarkAsAvailable` 瀹炵幇锛堝皢鎸囧畾鐐逛綅 IsUsed 璁句负 false锛� |
+
+## 鍛戒护澶勭悊鍣ㄤ氦浜�
+
+### RobotPrefixCommandHandler 鍙樻洿
+
+**pickfinished 澶勭悊锛�**
+- 褰� `ChangePalletPhase == 3`锛堟祦鍚態鍙栧亣鐢佃姱锛夋椂锛屼笉璋冪敤鎷嗙洏 API锛屼粎鏇存柊鐘舵��
+- 鍏朵粬闃舵淇濇寔鐜版湁閫昏緫
+
+**putfinished 澶勭悊锛�**
+- 鍒ゆ柇娴佸悜锛氶�氳繃 `state.CurrentTask.RobotSourceAddressLineCode` 鍒ゆ柇鏄祦鍚慉杩樻槸娴佸悜B
+- 褰� `ChangePalletPhase == 2` 涓旀祦鍚態锛堟斁姝e父鐢佃姱锛夋椂锛屾甯歌皟鐢� ChangePalletAsync API锛宍state.RobotTaskTotalNum += positions.Length`
+- 褰� `ChangePalletPhase == 4`锛堟祦鍚態鏀惧亣鐢佃姱鍒�5鍙蜂綅锛夋椂锛屼笉璋冪敤 API锛屼笉閫掑 `RobotTaskTotalNum`锛岃皟鐢� `MarkAsAvailable(positions)` 閲婃斁鐐逛綅
+- 褰� `ChangePalletPhase == 2` 涓旀祦鍚慉锛堟斁鍋囩數鑺埌鐩爣锛夋椂锛屼笉璋冪敤 API锛屼笉閫掑 `RobotTaskTotalNum`
+
+### RobotSimpleCommandHandler 鍙樻洿
+
+**allpickfinished / allputfinished锛�**
+- 澧炲姞瀹堝崼鏉′欢锛氫粎褰� `state.ChangePalletPhase == 0`锛堟墍鏈夐樁娈靛畬鎴愶級鏃讹紝鎵嶆墽琛屽叆搴撳洖浼犲拰浠诲姟鍒犻櫎
+- 涓棿闃舵鏀跺埌 allpickfinished/allputfinished 鏃讹紝浠呮洿鏂� `state.CurrentAction`锛屼笉瑙﹀彂鍏ュ簱閫昏緫
+- 浠诲姟瀹屾垚鏃堕澶栭噸缃細`state.ChangePalletPhase = 0`, `state.CurrentBatchIndex = 1`, `state.IsInFakeBatteryMode = false`
+
+## 杈圭晫鏉′欢
+
+- `task.RobotTaskTotalNum == 48`锛氱洿鎺ヨ蛋鍘熸湁閫昏緫锛屼笉杩涘叆鎵规妯″紡
+- `task.RobotTaskTotalNum == 0`锛氭祦鍚慉 琛ユ弧48涓亣鐢佃姱锛涙祦鍚態 璺宠繃 Phase 1/2锛岀洿鎺ヨ繘鍏� Phase 3/4 鍥炴敹48涓亣鐢佃姱
+- 鍋囩數鑺钩闈㈢偣浣嶄笉瓒筹細璁板綍閿欒鏃ュ織锛屼腑姝㈠綋鍓嶆壒娆�
+- 鍋囩數鑺偣浣嶇鐗囧寲锛歚GetNextAvailable` 瑕佹眰鍚岃杩炵画锛屽鏋滆姹�4涓壘涓嶅埌锛屼緷娆″皾璇�3銆�2銆�1涓�
+- 鎵规缂栧彿婧㈠嚭锛堣秴杩�48锛夛細涓嶅簲鍙戠敓锛屼絾闇�闃插尽鎬ф鏌�
--
Gitblit v1.9.3