From 05999b9c77f009ac9a7e98366bc3d23fbb8e83e7 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期日, 26 四月 2026 17:46:10 +0800
Subject: [PATCH] feat: 更新数据库连接配置和机器人任务处理逻辑
---
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs | 1563 +++++++++++++++++++++++++++--------------------------
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotPrefixCommandHandler.cs | 4
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json | 2
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/ConveyorLineDispatchHandler.cs | 25
Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs | 24
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotSimpleCommandHandler.cs | 40
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotWorkflowOrchestrator.cs | 10
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Messaging.cs | 16
8 files changed, 881 insertions(+), 803 deletions(-)
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json
index 991f38a..6cc3b23 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json
@@ -34,7 +34,7 @@
//5.PostgreSQL
"DBType": "SqlServer",
//杩炴帴瀛楃涓�
- "ConnectionString": "Data Source=192.168.60.30;Initial Catalog=WIDESEAWCS_ShanMei;User ID=sa;Password=P@ssw0rd;Integrated Security=False;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
+ "ConnectionString": "Data Source=.;Initial Catalog=WIDESEAWCS_ShanMei;User ID=sa;Password=P@ssw0rd;Integrated Security=False;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
//"ConnectionString": "Data Source=.;Initial Catalog=WIDESEAWCS_ShanMei;User ID=sa;Password=123456;Integrated Security=False;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
//璺ㄥ煙
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/ConveyorLineDispatchHandler.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/ConveyorLineDispatchHandler.cs
index e875238..38f60f8 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/ConveyorLineDispatchHandler.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/ConveyorLineDispatchHandler.cs
@@ -271,18 +271,19 @@
Thread.Sleep(100); // 纭繚 PLC 鑳芥纭鍙栦换鍔″彿鍚庡啀鍐欏叆鏉$爜
var isPalletSet = conveyorLine.SetValue(ConveyorLineDBNameNew.Barcode, task.PalletCode, childDeviceCode);
- bool isTargetSet = true;
- if (targetAddress == "2217" && !isEmptyTask)
- {
- QuartzLogHelper.LogDebug(_logger, $"瀛愯澶�: {childDeviceCode}锛屽嚭搴撶洰鏍囧湴鍧�: {targetAddress}", conveyorLine.DeviceCode);
- Thread.Sleep(100); // 纭繚 PLC 鑳芥纭鍙栦换鍔″彿鍚庡啀鍐欏叆鏉$爜
- isTargetSet = conveyorLine.SetValue(ConveyorLineDBNameNew.Target, targetAddress, childDeviceCode);
- }
- if (!isTargetSet || !isTaskNoSet || !isPalletSet)
- {
- QuartzLogHelper.LogError(_logger, $"RequestOutbound锛氫笅鍙戝嚭搴撲换鍔″け璐ワ紝浠诲姟鍙�: {task.TaskNum}锛屽瓙璁惧: {childDeviceCode}", conveyorLine.DeviceCode);
- return Task.CompletedTask;
- }
+ Thread.Sleep(100); // 纭繚 PLC 鑳芥纭鍙栦换鍔″彿鍚庡啀鍐欏叆鏉$爜
+ bool isTargetSet = conveyorLine.SetValue(ConveyorLineDBNameNew.Target, targetAddress, childDeviceCode);
+ //if (targetAddress == "2217" && !isEmptyTask)
+ //{
+ // QuartzLogHelper.LogDebug(_logger, $"瀛愯澶�: {childDeviceCode}锛屽嚭搴撶洰鏍囧湴鍧�: {targetAddress}", conveyorLine.DeviceCode);
+ // Thread.Sleep(100); // 纭繚 PLC 鑳芥纭鍙栦换鍔″彿鍚庡啀鍐欏叆鏉$爜
+ // isTargetSet = conveyorLine.SetValue(ConveyorLineDBNameNew.Target, targetAddress, childDeviceCode);
+ //}
+ //if (!isTargetSet || !isTaskNoSet || !isPalletSet)
+ //{
+ // QuartzLogHelper.LogError(_logger, $"RequestOutbound锛氫笅鍙戝嚭搴撲换鍔″け璐ワ紝浠诲姟鍙�: {task.TaskNum}锛屽瓙璁惧: {childDeviceCode}", conveyorLine.DeviceCode);
+ // return Task.CompletedTask;
+ //}
bool isWmsResult = false;
// 鏇存柊浠诲姟鐘舵�佹垨浣嶇疆
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs
index 838bd20..97fa4ac 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs
@@ -1,760 +1,805 @@
-using Newtonsoft.Json;
-using Serilog;
-using WIDESEA_Core;
-using WIDESEAWCS_Common;
-using WIDESEAWCS_Common.HttpEnum;
-using WIDESEAWCS_Common.TaskEnum;
-using WIDESEAWCS_Core;
-using WIDESEAWCS_Core.Helper;
-using WIDESEAWCS_Core.LogHelper;
-using WIDESEAWCS_DTO.Stock;
-using WIDESEAWCS_DTO.TaskInfo;
-using WIDESEAWCS_ITaskInfoService;
-using WIDESEAWCS_Model.Models;
-using WIDESEAWCS_QuartzJob;
-using WIDESEAWCS_Tasks.Workflow.Abstractions;
-
-namespace WIDESEAWCS_Tasks
-{
- /// <summary>
- /// 鏈哄櫒浜轰换鍔″鐞嗗櫒 - 璐熻矗浠诲姟鑾峰彇銆佷笅鍙戙�佸叆搴撲换鍔″洖浼犲強搴撳瓨 DTO 鏋勫缓
- /// </summary>
- /// <remarks>
- /// 鏍稿績鑱岃矗锛�
- /// 1. 浠庢暟鎹簱杞寰呭鐞嗙殑鏈哄櫒浜轰换鍔�
- /// 2. 鍚戞満鍣ㄤ汉瀹㈡埛绔笅鍙戝彇璐ф寚浠わ紙Pickbattery锛�
- /// 3. 澶勭悊鍏ュ簱浠诲姟鐨勫洖浼狅紙鎷嗙洏/缁勭洏/鎹㈢洏鍦烘櫙锛�
- /// 4. 鏋勫缓搴撳瓨鍥炰紶 DTO 骞惰皟鐢� WMS 鎺ュ彛
- ///
- /// 閫氳繃缃戝叧璁块棶 Socket锛岄伩鍏嶄笟鍔″眰鐩存帴渚濊禆 TcpSocketServer銆�
- /// </remarks>
- public class RobotTaskProcessor
- {
- /// <summary>
- /// Socket 瀹㈡埛绔綉鍏虫帴鍙�
- /// </summary>
- /// <remarks>
- /// 閫氳繃缃戝叧璁块棶 Socket锛岄伩鍏嶄笟鍔″眰鐩存帴渚濊禆 TcpSocketServer銆�
- /// 鎻愪緵缁熶竴鐨勫鎴风閫氫俊鎺ュ彛銆�
- /// </remarks>
- private readonly ISocketClientGateway _socketClientGateway;
-
- /// <summary>
- /// 鏈烘鎵嬬姸鎬佺鐞嗗櫒
- /// </summary>
- private readonly RobotStateManager _stateManager;
-
- /// <summary>
- /// 鏈哄櫒浜轰换鍔℃湇鍔�
- /// </summary>
- /// <remarks>
- /// 鐢ㄤ簬鏌ヨ銆佹洿鏂般�佸垹闄ゆ満鍣ㄤ汉浠诲姟璁板綍銆�
- /// </remarks>
- private readonly IRobotTaskService _robotTaskService;
-
- /// <summary>
- /// 閫氱敤浠诲姟鏈嶅姟
- /// </summary>
- /// <remarks>
- /// 鐢ㄤ簬涓� WMS 绯荤粺浜や簰锛屾帴鏀朵换鍔°�佸鐞嗕换鍔$姸鎬佺瓑銆�
- /// </remarks>
- private readonly ITaskService _taskService;
-
- /// <summary>
- /// HTTP 瀹㈡埛绔府鍔╃被
- /// </summary>
- /// <remarks>
- /// 鐢ㄤ簬璋冪敤 WMS 绯荤粺鐨� HTTP 鎺ュ彛銆�
- /// </remarks>
- private readonly HttpClientHelper _httpClientHelper;
-
- /// <summary>
- /// 鍋囩數鑺钩闈㈢偣浣嶆湇鍔�
- /// </summary>
- /// <remarks>
- /// 鐢ㄤ簬绠$悊鍋囩數鑺钩闈㈢偣浣嶇殑鍒嗛厤鍜岀姸鎬併��
- /// </remarks>
- private readonly IFakeBatteryPositionService _fakeBatteryPositionService;
-
- /// <summary>
- /// 鏃ュ織璁板綍鍣�
- /// </summary>
+using Masuit.Tools;
+using Newtonsoft.Json;
+using Serilog;
+using WIDESEA_Core;
+using WIDESEAWCS_Common;
+using WIDESEAWCS_Common.HttpEnum;
+using WIDESEAWCS_Common.TaskEnum;
+using WIDESEAWCS_Core;
+using WIDESEAWCS_Core.Helper;
+using WIDESEAWCS_Core.LogHelper;
+using WIDESEAWCS_DTO.Stock;
+using WIDESEAWCS_DTO.TaskInfo;
+using WIDESEAWCS_ITaskInfoService;
+using WIDESEAWCS_Model.Models;
+using WIDESEAWCS_QuartzJob;
+using WIDESEAWCS_Tasks.Workflow.Abstractions;
+
+namespace WIDESEAWCS_Tasks
+{
+ /// <summary>
+ /// 鏈哄櫒浜轰换鍔″鐞嗗櫒 - 璐熻矗浠诲姟鑾峰彇銆佷笅鍙戙�佸叆搴撲换鍔″洖浼犲強搴撳瓨 DTO 鏋勫缓
+ /// </summary>
+ /// <remarks>
+ /// 鏍稿績鑱岃矗锛�
+ /// 1. 浠庢暟鎹簱杞寰呭鐞嗙殑鏈哄櫒浜轰换鍔�
+ /// 2. 鍚戞満鍣ㄤ汉瀹㈡埛绔笅鍙戝彇璐ф寚浠わ紙Pickbattery锛�
+ /// 3. 澶勭悊鍏ュ簱浠诲姟鐨勫洖浼狅紙鎷嗙洏/缁勭洏/鎹㈢洏鍦烘櫙锛�
+ /// 4. 鏋勫缓搴撳瓨鍥炰紶 DTO 骞惰皟鐢� WMS 鎺ュ彛
+ ///
+ /// 閫氳繃缃戝叧璁块棶 Socket锛岄伩鍏嶄笟鍔″眰鐩存帴渚濊禆 TcpSocketServer銆�
+ /// </remarks>
+ public class RobotTaskProcessor
+ {
+ /// <summary>
+ /// Socket 瀹㈡埛绔綉鍏虫帴鍙�
+ /// </summary>
+ /// <remarks>
+ /// 閫氳繃缃戝叧璁块棶 Socket锛岄伩鍏嶄笟鍔″眰鐩存帴渚濊禆 TcpSocketServer銆�
+ /// 鎻愪緵缁熶竴鐨勫鎴风閫氫俊鎺ュ彛銆�
+ /// </remarks>
+ private readonly ISocketClientGateway _socketClientGateway;
+
+ /// <summary>
+ /// 鏈烘鎵嬬姸鎬佺鐞嗗櫒
+ /// </summary>
+ private readonly RobotStateManager _stateManager;
+
+ /// <summary>
+ /// 鏈哄櫒浜轰换鍔℃湇鍔�
+ /// </summary>
+ /// <remarks>
+ /// 鐢ㄤ簬鏌ヨ銆佹洿鏂般�佸垹闄ゆ満鍣ㄤ汉浠诲姟璁板綍銆�
+ /// </remarks>
+ private readonly IRobotTaskService _robotTaskService;
+
+ /// <summary>
+ /// 閫氱敤浠诲姟鏈嶅姟
+ /// </summary>
+ /// <remarks>
+ /// 鐢ㄤ簬涓� WMS 绯荤粺浜や簰锛屾帴鏀朵换鍔°�佸鐞嗕换鍔$姸鎬佺瓑銆�
+ /// </remarks>
+ private readonly ITaskService _taskService;
+
+ /// <summary>
+ /// HTTP 瀹㈡埛绔府鍔╃被
+ /// </summary>
+ /// <remarks>
+ /// 鐢ㄤ簬璋冪敤 WMS 绯荤粺鐨� HTTP 鎺ュ彛銆�
+ /// </remarks>
+ private readonly HttpClientHelper _httpClientHelper;
+
+ /// <summary>
+ /// 鍋囩數鑺钩闈㈢偣浣嶆湇鍔�
+ /// </summary>
+ /// <remarks>
+ /// 鐢ㄤ簬绠$悊鍋囩數鑺钩闈㈢偣浣嶇殑鍒嗛厤鍜岀姸鎬併��
+ /// </remarks>
+ private readonly IFakeBatteryPositionService _fakeBatteryPositionService;
+
+ /// <summary>
+ /// 鏃ュ織璁板綍鍣�
+ /// </summary>
private readonly ILogger _logger;
-
- /// <summary>
- /// 鏋勯�犲嚱鏁�
- /// </summary>
- /// <param name="socketClientGateway">Socket 缃戝叧</param>
- /// <param name="stateManager">鐘舵�佺鐞嗗櫒</param>
- /// <param name="robotTaskService">鏈哄櫒浜轰换鍔℃湇鍔�</param>
- /// <param name="taskService">閫氱敤浠诲姟鏈嶅姟</param>
- /// <param name="httpClientHelper">HTTP 瀹㈡埛绔府鍔╃被</param>
- /// <param name="logger">鏃ュ織璁板綍鍣�</param>
- public RobotTaskProcessor(
- ISocketClientGateway socketClientGateway,
- RobotStateManager stateManager,
- IRobotTaskService robotTaskService,
- ITaskService taskService,
- HttpClientHelper httpClientHelper,
- ILogger logger,
- IFakeBatteryPositionService fakeBatteryPositionService)
- {
- _socketClientGateway = socketClientGateway;
- _stateManager = stateManager;
- _robotTaskService = robotTaskService;
- _taskService = taskService;
- _httpClientHelper = httpClientHelper;
- _logger = logger;
- _fakeBatteryPositionService = fakeBatteryPositionService;
- }
-
- /// <summary>
- /// 鎸夎澶囩紪鐮佽幏鍙栧綋鍓嶆満鍣ㄤ汉鐨勫緟澶勭悊浠诲姟
- /// </summary>
- /// <remarks>
- /// 浠庢暟鎹簱涓煡璇㈡寚瀹氳澶囩紪鐮佺殑寰呭鐞嗘満鍣ㄤ汉浠诲姟銆�
- /// 鍙繑鍥炵姸鎬佷负"寰呭鐞�"鐨勪换鍔°��
- /// </remarks>
- /// <param name="robotCrane">鏈哄櫒浜鸿澶囦俊鎭紝鍖呭惈璁惧缂栫爜</param>
- /// <returns>寰呭鐞嗙殑浠诲姟瀵硅薄锛屽鏋滄病鏈夊垯杩斿洖 null</returns>
- public Dt_RobotTask? GetTask(RobotCraneDevice robotCrane)
- {
- return _robotTaskService.QueryRobotCraneTask(robotCrane.DeviceCode);
- }
-
- /// <summary>
- /// 鎸夎澶囩紪鐮佽幏鍙栧綋鍓嶆満鍣ㄤ汉鐨勬墽琛屼腑浠诲姟
- /// </summary>
- /// <remarks>
- /// 浠庢暟鎹簱涓煡璇㈡寚瀹氳澶囩紪鐮佺殑鎵ц涓満鍣ㄤ汉浠诲姟銆�
- /// 褰揜obotArmObject涓�1锛堟湁鐗╂枡锛変笖娌℃湁寰呭鐞嗕换鍔℃椂璋冪敤銆�
- /// </remarks>
- /// <param name="robotCrane">鏈哄櫒浜鸿澶囦俊鎭紝鍖呭惈璁惧缂栫爜</param>
- /// <returns>鎵ц涓殑浠诲姟瀵硅薄锛屽鏋滄病鏈夊垯杩斿洖 null</returns>
- public Dt_RobotTask? GetExecutingTask(RobotCraneDevice robotCrane)
- {
- return _robotTaskService.QueryRobotCraneExecutingTask(robotCrane.DeviceCode);
- }
-
- /// <summary>
- /// 鍒犻櫎鏈哄櫒浜轰换鍔�
- /// </summary>
- /// <remarks>
- /// 褰撲换鍔″畬鎴愶紙鏃犺鏄垚鍔熻繕鏄け璐ワ級鏃惰皟鐢紝鍒犻櫎鏁版嵁搴撲腑鐨勪换鍔¤褰曘��
- /// </remarks>
- /// <param name="ID">瑕佸垹闄ょ殑浠诲姟 ID</param>
- /// <returns>鍒犻櫎鏄惁鎴愬姛</returns>
- public bool? DeleteTask(int ID)
- {
- return _robotTaskService.DeleteRobotTask(ID);
- }
-
- /// <summary>
- /// 涓嬪彂鍙栬揣鎸囦护锛圥ickbattery锛夊埌鏈哄櫒浜哄鎴风
- /// </summary>
- /// <remarks>
- /// 鍙戦�佹牸寮忥細Pickbattery,{婧愬湴鍧�}
- /// 渚嬪锛歅ickbattery,A01 琛ㄧず浠� A01 浣嶇疆鍙栬揣
- ///
- /// 涓嬪彂鎴愬姛鍚庯細
- /// 1. 鏇存柊浠诲姟鐘舵�佷负"鏈哄櫒浜烘墽琛屼腑"
- /// 2. 灏嗕换鍔″叧鑱斿埌鐘舵�佸璞�
- /// 3. 瀹夊叏鏇存柊鐘舵�佸埌 Redis
- /// 4. 鏇存柊浠诲姟璁板綍鍒版暟鎹簱
- /// </remarks>
- /// <param name="task">瑕佷笅鍙戠殑浠诲姟瀵硅薄</param>
- /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
- /// <param name="isScanNG">鏄惁鎵爜NG</param>
- public async Task SendSocketRobotPickAsync(Dt_RobotTask task, RobotSocketState state, bool isScanNG = false)
- {
- // 鏋勫缓鍙栬揣鎸囦护锛屾牸寮忥細Pickbattery,{婧愬湴鍧�}
- string taskString = $"Pickbattery,{task.RobotSourceAddress}";
-
- // 鏇存柊浠诲姟鐘舵�佷负"鏈哄櫒浜烘墽琛屼腑"
- task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
-
- // 灏嗕换鍔″叧鑱斿埌鐘舵�佸璞�
- state.CurrentTask = task;
-
- if (isScanNG)
- {
- state.IsScanNG = true;
- }
-
- // 淇濇寔鍘熻涔夛細浠呭湪鐘舵�佸畨鍏ㄥ啓鍏ユ垚鍔熷悗鍐嶆洿鏂颁换鍔$姸鎬�
- // 杩欐牱鍙互纭繚鐘舵�佸拰浠诲姟璁板綍鐨勪竴鑷存��
- if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
- {
- QuartzLogHelper.LogInfo(_logger, $"鐘舵�佹洿鏂版垚鍔燂紝璁惧: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
- // 閫氳繃 Socket 缃戝叧鍙戦�佹寚浠ゅ埌鏈哄櫒浜哄鎴风
- bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
- if (result)
- {
- // 鍙戦�佹垚鍔燂紝璁板綍 Info 鏃ュ織
- QuartzLogHelper.LogInfo(_logger, $"涓嬪彂鍙栬揣鎸囦护鎴愬姛锛屾寚浠�: {taskString}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
- //await _robotTaskService.UpdateRobotTaskAsync(task);
- }
- else
- {
- // 鍙戦�佸け璐ワ紝璁板綍 Error 鏃ュ織
- QuartzLogHelper.LogError(_logger, $"涓嬪彂鍙栬揣鎸囦护澶辫触锛屾寚浠�: {taskString}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
- }
- }
- }
-
- /// <summary>
- /// 涓嬪彂鍋囩數鑺彇璐ф寚浠ゅ埌鏈哄櫒浜哄鎴风
- /// </summary>
- /// <remarks>
- /// 鍙戦�佹牸寮忥細Pickbattery,5,{startPosition}-{endPosition}
- /// 渚嬪锛歅ickbattery,5,1-3 琛ㄧず浠庡亣鐢佃姱浣嶇疆5鎶撳彇锛屽钩闈㈢偣浣�1鍒�3
- ///
- /// 涓嬪彂鎴愬姛鍚庯細
- /// 1. 鏍囪鐐逛綅涓哄凡浣跨敤
- /// 2. 鏇存柊浠诲姟鐘舵�佷负"鏈哄櫒浜烘墽琛屼腑"
- /// 3. 瀹夊叏鏇存柊鐘舵�佸埌 Redis
- /// </remarks>
- /// <param name="task">瑕佷笅鍙戠殑浠诲姟瀵硅薄</param>
- /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
- /// <param name="positions">瑕佹姄鍙栫殑骞抽潰鐐逛綅鍒楄〃</param>
- public async Task SendSocketRobotFakeBatteryPickAsync(Dt_RobotTask task, RobotSocketState state, List<int> positions)
- {
- if (positions == null || positions.Count == 0)
- {
- QuartzLogHelper.LogWarn(_logger, $"SendSocketRobotFakeBatteryPickAsync锛氬钩闈㈢偣浣嶅垪琛ㄤ负绌猴紝浠诲姟鍙�: {task.RobotTaskNum}", state.RobotCrane?.DeviceName ?? "Unknown");
- return;
- }
-
- // 璁$畻鐐逛綅鑼冨洿锛屾牸寮忥細1-3
- int startPos = positions.Min();
- int endPos = positions.Max();
- string taskString = $"Pickbattery,5,{startPos}-{endPos}";
-
- // 鏍囪鐐逛綅涓哄凡浣跨敤
- _fakeBatteryPositionService.MarkAsUsed(positions);
-
- // 鏇存柊浠诲姟鐘舵�佷负"鏈哄櫒浜烘墽琛屼腑"
- task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
-
- // 灏嗕换鍔″叧鑱斿埌鐘舵�佸璞�
- state.CurrentTask = task;
-
- if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
- {
- // 閫氳繃 Socket 缃戝叧鍙戦�佹寚浠ゅ埌鏈哄櫒浜哄鎴风
- bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
-
- if (result)
- {
- QuartzLogHelper.LogInfo(_logger, $"涓嬪彂鍋囩數鑺彇璐ф寚浠ゆ垚鍔燂紝鎸囦护: {taskString}锛岀偣浣�: {string.Join(",", positions)}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
- //await _robotTaskService.UpdateRobotTaskAsync(task);
- }
- else
- {
- QuartzLogHelper.LogError(_logger, $"涓嬪彂鍋囩數鑺彇璐ф寚浠ゅけ璐ワ紝鎸囦护: {taskString}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
- }
- }
- }
-
- /// <summary>
- /// 鑾峰彇涓婲涓彲鐢ㄧ殑鍋囩數鑺钩闈㈢偣浣�
- /// </summary>
- /// <param name="count">闇�瑕佽幏鍙栫殑鐐逛綅鏁伴噺</param>
- /// <returns>鍙敤鐐逛綅鍒楄〃</returns>
- public List<int> GetNextAvailableFakeBatteryPositions(int count)
- {
- return _fakeBatteryPositionService.GetNextAvailable(count);
- }
-
- /// <summary>
- /// 璁$畻鎵规缂栧彿鑼冨洿
- /// </summary>
- /// <remarks>
- /// 杩斿洖鏍煎紡锛�(start, end)
- /// - remaining >= 4: (currentIndex, currentIndex + 3)
- /// - remaining > 1: (currentIndex, currentIndex + remaining - 1)
- /// - remaining == 1: (currentIndex, 0) -- 鍗曚釜鐗╁搧鐢� 0 琛ㄧず end
- /// </remarks>
- /// <param name="currentIndex">褰撳墠鎵规璧峰缂栧彿</param>
- /// <param name="remaining">鍓╀綑鏁伴噺</param>
- /// <returns>(start, end) 鍏冪粍</returns>
- public (int Start, int End) BuildBatchRange(int currentIndex, int remaining)
- {
- if (remaining >= 4)
- return (currentIndex, currentIndex + 3);
- else if (remaining > 1)
- return (currentIndex, currentIndex + remaining - 1);
- else // remaining == 1
- return (currentIndex, 0);
- }
-
- /// <summary>
- /// 涓嬪彂鍙栬揣鎸囦护锛堝甫鎵规鏍煎紡鍜屾�绘暟锛�
- /// </summary>
- /// <remarks>
- /// 鍙戦�侀『搴忥細
- /// 1. PickTotalNum,{N} -- 鐪熷疄鐢佃姱鎬绘暟
- /// 2. Pickbattery,{浣嶇疆},{start}-{end} -- 鎵规鍙栬揣鎸囦护
- ///
- /// 涓嬪彂鎴愬姛鍚庢洿鏂颁换鍔$姸鎬佷负"鏈哄櫒浜烘墽琛屼腑"銆�
- /// </remarks>
- /// <param name="task">瑕佷笅鍙戠殑浠诲姟瀵硅薄</param>
- /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
- /// <param name="position">鍙栬揣浣嶇疆</param>
- /// <param name="batchStart">鎵规璧峰缂栧彿</param>
- /// <param name="batchEnd">鎵规缁撴潫缂栧彿</param>
- public async Task SendPickWithBatchAsync(Dt_RobotTask task, RobotSocketState state, string position, int batchStart, int batchEnd)
- {
-
- task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
- state.CurrentTask = task;
-
- if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
- {
- // 鍏堝彂閫佹�绘暟鎸囦护
- string totalNumCmd = $"PickTotalNum,{task.RobotTaskTotalNum}";
- await _socketClientGateway.SendToClientAsync(state.IPAddress, totalNumCmd);
-
- // 鍐嶅彂閫佹壒娆″彇璐ф寚浠�
- string range = batchEnd == 0 ? $"{batchStart}-0" : $"{batchStart}-{batchEnd}";
- string taskString = $"Pickbattery,{position},{range}";
-
- bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
-
- if (result)
- {
- QuartzLogHelper.LogInfo(_logger, $"涓嬪彂鎵规鍙栬揣鎸囦护鎴愬姛锛屾寚浠�: {taskString}锛屾壒娆�: {range}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
- //await _robotTaskService.UpdateRobotTaskAsync(task);
- }
- else
- {
- QuartzLogHelper.LogError(_logger, $"涓嬪彂鎵规鍙栬揣鎸囦护澶辫触锛屾寚浠�: {taskString}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
- }
- }
- }
-
- /// <summary>
- /// 涓嬪彂鍋囩數鑺彇璐ф寚浠わ紙甯︽壒娆℃牸寮忓拰鎬绘暟锛�
- /// </summary>
- /// <remarks>
- /// 鍙戦�侀『搴忥細
- /// 1. PickTotalNum,{N} -- 鐪熷疄鐢佃姱鎬绘暟
- /// 2. Pickbattery,5,{start}-{end} -- 鎵规鍙栬揣鎸囦护锛堝浐瀹氫粠5鍙蜂綅鍙栵級
- ///
- /// 涓嬪彂鎴愬姛鍚庢洿鏂颁换鍔$姸鎬佷负"鏈哄櫒浜烘墽琛屼腑"銆�
- /// </remarks>
- /// <param name="task">瑕佷笅鍙戠殑浠诲姟瀵硅薄</param>
- /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
- /// <param name="batchStart">鎵规璧峰缂栧彿</param>
- /// <param name="batchEnd">鎵规缁撴潫缂栧彿</param>
- public async Task SendFakeBatteryPickWithBatchAsync(Dt_RobotTask task, RobotSocketState state, int batchStart, int batchEnd)
- {
- task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
- state.CurrentTask = task;
-
- if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
- {
- // 鍏堝彂閫佹�绘暟鎸囦护
- string totalNumCmd = $"PickTotalNum,{task.RobotTaskTotalNum}";
- await _socketClientGateway.SendToClientAsync(state.IPAddress, totalNumCmd);
-
- // 鍐嶅彂閫佹壒娆″彇璐ф寚浠わ紙鍋囩數鑺浐瀹氫粠5鍙蜂綅鍙栵級
- string range = batchEnd == 0 ? $"{batchStart}-0" : $"{batchStart}-{batchEnd}";
- string taskString = $"Pickbattery,5,{range}";
-
- bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
-
- if (result)
- {
- QuartzLogHelper.LogInfo(_logger, $"涓嬪彂鍋囩數鑺壒娆″彇璐ф寚浠ゆ垚鍔燂紝鎸囦护: {taskString}锛屾壒娆�: {range}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
-
- //await _robotTaskService.UpdateRobotTaskAsync(task);
- }
- else
- {
- QuartzLogHelper.LogError(_logger, $"涓嬪彂鍋囩數鑺壒娆″彇璐ф寚浠ゅけ璐ワ紝鎸囦护: {taskString}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
- }
- }
- }
-
- /// <summary>
- /// 涓嬪彂鏀捐揣鎸囦护锛堝甫鎵规鏍煎紡鍜屾�绘暟锛�
- /// </summary>
- /// <remarks>
- /// 鍙戦�侀『搴忥細
- /// 1. PutTotalNum,{N} -- 鐪熷疄鐢佃姱鎬绘暟
- /// 2. Putbattery,{浣嶇疆},{start}-{end} -- 鎵规鏀捐揣鎸囦护
- ///
- /// 涓嬪彂鎴愬姛鍚庢洿鏂颁换鍔$姸鎬佷负"鏈哄櫒浜烘墽琛屼腑"銆�
- /// </remarks>
- /// <param name="task">瑕佷笅鍙戠殑浠诲姟瀵硅薄</param>
- /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
- /// <param name="position">鏀捐揣浣嶇疆</param>
- /// <param name="batchStart">鎵规璧峰缂栧彿</param>
- /// <param name="batchEnd">鎵规缁撴潫缂栧彿</param>
- public async Task SendPutWithBatchAsync(Dt_RobotTask task, RobotSocketState state, string position, int batchStart, int batchEnd)
- {
- task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
- state.CurrentTask = task;
-
- if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
- {
- // 鍏堝彂閫佹�绘暟鎸囦护
- string totalNumCmd = $"PutTotalNum,{task.RobotTaskTotalNum}";
- await _socketClientGateway.SendToClientAsync(state.IPAddress, totalNumCmd);
-
- // 鍐嶅彂閫佹壒娆℃斁璐ф寚浠�
- string range = batchEnd == 0 ? $"{batchStart}-0" : $"{batchStart}-{batchEnd}";
- string taskString = $"Putbattery,{position},{range}";
-
- bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
-
- if (result)
- {
- QuartzLogHelper.LogInfo(_logger, $"涓嬪彂鏀捐揣鎸囦护鎴愬姛锛屾寚浠�: {taskString}锛屾壒娆�: {range}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
-
- //await _robotTaskService.UpdateRobotTaskAsync(task);
- }
- else
- {
- QuartzLogHelper.LogError(_logger, $"涓嬪彂鏀捐揣鎸囦护澶辫触锛屾寚浠�: {taskString}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
- }
- }
- }
-
- /// <summary>
- /// 澶勭悊鍏ュ簱浠诲姟鍥炰紶锛堟媶鐩�/缁勭洏/鎹㈢洏鍦烘櫙锛�
- /// </summary>
- /// <remarks>
- /// 褰撳彇璐у畬鎴愶紙AllPickFinished锛夋垨鏀捐揣瀹屾垚锛圓llPutFinished锛夋椂璋冪敤姝ゆ柟娉曘��
- /// 鏍规嵁浠诲姟绫诲瀷鍜屽湴鍧�鏉ユ簮鍐冲畾濡備綍鍥炰紶缁� WMS銆�
- ///
- /// 澶勭悊閫昏緫锛�
- /// 1. 鏍规嵁 useSourceAddress 鍐冲畾浣跨敤婧愬湴鍧�杩樻槸鐩爣鍦板潃
- /// 2. 鏍规嵁浠诲姟绫诲瀷锛堢粍鐩�/鎹㈢洏/鎷嗙洏锛夊喅瀹氫换鍔$被鍨嬶紙鍏ュ簱/绌烘墭鐩樺叆搴擄級
- /// 3. 鏋勫缓 CreateTaskDto 骞惰皟鐢� WMS 鎺ュ彛鍒涘缓浠诲姟
- /// 4. 鎺ユ敹 WMS 杩斿洖鐨勪换鍔′俊鎭�
- /// 5. 鏇存柊杈撻�佺嚎鐨勭洰鏍囧湴鍧�銆佷换鍔″彿绛�
- /// </remarks>
- /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
- /// <param name="useSourceAddress">鏄惁浣跨敤婧愬湴鍧�锛坱rue 琛ㄧず鎷嗙洏/鎹㈢洏鍦烘櫙锛宖alse 琛ㄧず缁勭洏/鎹㈢洏鍦烘櫙锛�</param>
- /// <returns>澶勭悊鏄惁鎴愬姛</returns>
- public async Task<bool> HandleInboundTaskAsync(RobotSocketState state, bool useSourceAddress, string isRoadway = null)
- {
- // 鑾峰彇褰撳墠鍏宠仈鐨勪换鍔�
- var currentTask = state.CurrentTask;
- if (currentTask == null)
- {
- QuartzLogHelper.LogDebug(_logger, $"HandleInboundTaskAsync锛氬綋鍓嶄换鍔′负绌�", state.RobotCrane?.DeviceName ?? "Unknown");
- return false;
- }
-
- // 鑾峰彇宸烽亾浠g爜
- string roadway = string.Empty;
-
- // 鏍规嵁宸烽亾鍚嶇О鍒ゆ柇浠撳簱 ID
- int warehouseId = 0;
-
- // 婧愬湴鍧�鍜岀洰鏍囧湴鍧�锛堝垵濮嬪寲锛�
- string SourceAddress = currentTask.RobotTargetAddressLineCode;
- string TargetAddress = currentTask.RobotSourceAddressLineCode;
-
- // 浠诲姟绫诲瀷锛�0 琛ㄧず鏈畾涔夛紝绋嶅悗鏍规嵁浠诲姟绫诲瀷璁剧疆锛�
- int taskType = 0;
-
- // 鎵樼洏浠g爜锛堝垵濮嬪寲涓虹┖锛�
- string PalletCode = string.Empty;
-
- // 鑾峰彇浠诲姟绫诲瀷鐨勬灇涓惧��
- var robotTaskType = (RobotTaskTypeEnum)currentTask.RobotTaskType;
-
- // 鏍规嵁 useSourceAddress 鍐冲畾澶勭悊閫昏緫
- if (useSourceAddress)
- {
- // 浣跨敤婧愬湴鍧�鐨勫満鏅細鎷嗙洏銆佹崲鐩橈紙鏀剧┖鎵樼洏锛�
- switch (robotTaskType)
- {
- case RobotTaskTypeEnum.GroupPallet:
- warehouseId = 1;
- roadway = "GWSC1";
- break;
-
- case RobotTaskTypeEnum.ChangePallet:
- // 鎹㈢洏/鎷嗙洏鍦烘櫙锛氭墭鐩橀渶瑕佸叆搴�
- taskType = TaskTypeEnum.InEmpty.GetHashCode(); // 绌烘墭鐩樺叆搴�
- PalletCode = currentTask.RobotSourceAddressPalletCode; // 浣跨敤婧愬湴鍧�鐨勬墭鐩樼爜
- if (isRoadway == "HWSC1")
- {
- warehouseId = 2;
- roadway = "HWSC1";
- }
- else if (isRoadway == "GWSC1")
- {
- warehouseId = 1;
- roadway = "GWSC1";
- }
-
- break;
- case RobotTaskTypeEnum.SplitPallet:
- // 鎹㈢洏/鎷嗙洏鍦烘櫙锛氭墭鐩橀渶瑕佸叆搴�
- taskType = TaskTypeEnum.InEmpty.GetHashCode(); // 绌烘墭鐩樺叆搴�
- PalletCode = currentTask.RobotSourceAddressPalletCode; // 浣跨敤婧愬湴鍧�鐨勬墭鐩樼爜
-
- warehouseId = 3;
- roadway = "CWSC1";
- break;
- }
- }
- else
- {
- // 浣跨敤鐩爣鍦板潃鐨勫満鏅細缁勭洏銆佹崲鐩橈紙鎴愬搧鍏ュ簱锛�
- switch (robotTaskType)
- {
- case RobotTaskTypeEnum.ChangePallet:
- // 鎹㈢洏/缁勭洏鍦烘櫙锛氳揣鐗╅渶瑕佸叆搴�
- taskType = TaskTypeEnum.Inbound.GetHashCode(); // 鎴愬搧鍏ュ簱
- PalletCode = currentTask.RobotTargetAddressPalletCode; // 浣跨敤鐩爣鍦板潃鐨勬墭鐩樼爜
-
- if (isRoadway == "HWSC1")
- {
- warehouseId = 2;
- roadway = "HWSC1";
- }
- else if (isRoadway == "GWSC1")
- {
- warehouseId = 1;
- roadway = "GWSC1";
- }
-
- break;
- case RobotTaskTypeEnum.GroupPallet:
- // 鎹㈢洏/缁勭洏鍦烘櫙锛氳揣鐗╅渶瑕佸叆搴�
- taskType = TaskTypeEnum.Inbound.GetHashCode(); // 鎴愬搧鍏ュ簱
- PalletCode = currentTask.RobotTargetAddressPalletCode; // 浣跨敤鐩爣鍦板潃鐨勬墭鐩樼爜
-
- warehouseId = 1;
- roadway = "GWSC1";
- break;
-
- case RobotTaskTypeEnum.SplitPallet:
-
- break;
- }
- }
-
- // 鏋勫缓鍒涘缓浠诲姟鐨� DTO
- CreateTaskDto taskDto = new CreateTaskDto
- {
- PalletCode = PalletCode, // 鎵樼洏鏉$爜
- SourceAddress = SourceAddress ?? string.Empty, // 婧愬湴鍧�
- TargetAddress = roadway ?? string.Empty, // 鐩爣鍦板潃
- Roadway = roadway ?? string.Empty, // 宸烽亾
- WarehouseId = warehouseId, // 浠撳簱 ID
- PalletType = 1, // 鎵樼洏绫诲瀷锛堥粯璁や负1锛�
- TaskType = taskType // 浠诲姟绫诲瀷锛堝叆搴�/绌烘墭鐩樺叆搴擄級
- };
-
- // 璁板綍鏃ュ織锛氬紑濮嬭皟鐢� WMS 鍒涘缓鍏ュ簱浠诲姟
- QuartzLogHelper.LogInfo(_logger, $"HandleInboundTaskAsync锛氳皟鐢╓MS鍒涘缓鍏ュ簱浠诲姟锛屾墭鐩樼爜: {PalletCode}锛屼换鍔$被鍨�: {taskType}", state.RobotCrane?.DeviceName ?? "Unknown");
-
- // 璋冪敤 WMS 鎺ュ彛鍒涘缓鍏ュ簱浠诲姟
- string configKey = nameof(ConfigKey.CreateTaskInboundAsync);
- string requestParam = taskDto.ToJson();
- DateTime startTime = DateTime.Now;
-
- var result = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
-
- if (!result.IsSuccess || !result.Data.Status)
- {
- QuartzLogHelper.LogError(_logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆恵configKey}銆�,璇锋眰鍙傛暟:銆恵requestParam}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�", state.RobotCrane?.DeviceName ?? "Unknown");
- return false;
- }
-
- QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:{(DateTime.Now - startTime).TotalMilliseconds}ms", state.RobotCrane?.DeviceName ?? "Unknown");
-
- // 濡傛灉璋冪敤澶辫触鎴栬繑鍥為敊璇姸鎬�
- if (!result.Data.Status && result.IsSuccess)
- {
- QuartzLogHelper.LogError(_logger, $"HandleInboundTaskAsync锛歐MS杩斿洖閿欒鐘舵�侊紝Status: {result.Data.Status}", state.RobotCrane?.DeviceName ?? "Unknown");
- return false;
- }
-
- // 瑙f瀽 WMS 杩斿洖鐨勪换鍔′俊鎭�
- WMSTaskDTO taskDTO = JsonConvert.DeserializeObject<WMSTaskDTO>(result.Data.Data.ToJson() ?? string.Empty) ?? new WMSTaskDTO();
-
- // 璋冪敤浠诲姟鏈嶅姟鎺ユ敹 WMS 浠诲姟
- var content = _taskService.ReceiveWMSTask(new List<WMSTaskDTO> { taskDTO });
- if (!content.Status)
- {
- QuartzLogHelper.LogError(_logger, $"HandleInboundTaskAsync锛氭帴鏀禬MS浠诲姟澶辫触", state.RobotCrane?.DeviceName ?? "Unknown");
- return false;
- }
-
- return true;
- }
-
- /// <summary>
- /// 鏋勫缓搴撳瓨鍥炰紶 DTO
- /// </summary>
- /// <remarks>
- /// 鐢ㄤ簬鎷嗙洏鍜岀粍鐩樻搷浣滄椂锛屽悜 WMS 鍥炰紶搴撳瓨淇℃伅銆�
- /// DTO 鍖呭惈婧愯揣浣嶃�佺洰鏍囪揣浣嶃�佹墭鐩樼爜浠ュ強姣忎釜浣嶇疆鐨勭數姹犳潯鐮併��
- /// </remarks>
- /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
- /// <param name="positions">鐢垫睜浣嶇疆鏁扮粍</param>
- /// <returns>鏋勫缓濂界殑搴撳瓨 DTO</returns>
- public static StockDTO BuildStockDTO(RobotSocketState state, int[] positions)
- {
- return new StockDTO
- {
- // 婧愯緭閫佺嚎缂栧彿
- SourceLineNo = state.CurrentTask.RobotSourceAddressLineCode,
-
- // 婧愭墭鐩樺彿
- SourcePalletNo = state.CurrentTask.RobotSourceAddressPalletCode,
-
- // 鐩爣鎵樼洏鍙�
- TargetPalletNo = state.CurrentTask.RobotTargetAddressPalletCode,
-
- // 鐩爣杈撻�佺嚎缂栧彿
- TargetLineNo = state.CurrentTask.RobotTargetAddressLineCode,
-
- // 宸烽亾缂栧彿(鏈哄櫒浜哄悕绉�)
- Roadway = state.CurrentTask.RobotRoadway,
-
- // 鐢垫睜浣嶇疆璇︽儏鍒楄〃
- // 杩囨护鎺変綅缃负 0 鎴栬礋鏁扮殑鏃犳晥鏁版嵁
- // 鎸変綅缃紪鍙锋帓搴�
- // 涓烘瘡涓綅缃敓鎴愬搴旂殑搴撳瓨璇︽儏
- Details = positions
- .Where(x => x > 0) // 杩囨护鏃犳晥浣嶇疆
- .OrderBy(x => x) // 鎸変綅缃帓搴�
- .Select((x, idx) => new StockDetailDTO
- {
- // 鏁伴噺锛氬鏋滃凡鏈変换鍔℃�绘暟锛屼娇鐢ㄤ换鍔℃�绘暟+褰撳墠浣嶇疆鏁帮紱鍚﹀垯鍙娇鐢ㄥ綋鍓嶄綅缃暟
- Quantity = 1,
-
- // 閫氶亾/浣嶇疆缂栧彿
- Channel = x,
-
- // 鐢垫睜鏉$爜锛氬鏋滅姸鎬佷腑鏈夋潯鐮佸垪琛紝鍙栧搴斾綅缃殑鏉$爜锛涘惁鍒欎负绌�
- //CellBarcode = state.CellBarcode?.Count > 0 ? state.CellBarcode[x - 1] : ""
- CellBarcode = state.CellBarcode[idx].ToString()
- })
- .ToList()
- };
- }
-
- /// <summary>
- /// 璋冪敤鎷嗙洏 API
- /// </summary>
- /// <remarks>
- /// 褰撳彇璐у畬鎴愪笖闇�瑕佹媶鐩樻椂璋冪敤銆�
- /// 灏嗙數姹犱粠鎵樼洏涓婂彇涓嬶紝閫愪釜鏀剧疆鍒扮洰鏍囦綅缃��
- /// </remarks>
- /// <param name="stockDTO">搴撳瓨 DTO锛屽寘鍚鎷嗙洏鐨勭數鑺俊鎭�</param>
- /// <returns>HTTP 鍝嶅簲缁撴灉</returns>
- public HttpResponseResult<WebResponseContent> PostSplitPalletAsync(StockDTO stockDTO)
- {
- string configKey = nameof(ConfigKey.SplitPalletAsync);
- string requestParam = stockDTO.ToJson();
- DateTime startTime = DateTime.Now;
-
- var result = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
-
- if (!result.IsSuccess || !result.Data.Status)
- QuartzLogHelper.LogError(_logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆恵configKey}銆�,璇锋眰鍙傛暟:銆恵requestParam}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�", "RobotTaskProcessor");
- else
- QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:{(DateTime.Now - startTime).TotalMilliseconds}ms", "RobotTaskProcessor");
-
- return result;
- }
-
- /// <summary>
- /// 璋冪敤缁勭洏/鎹㈢洏 API
- /// </summary>
- /// <remarks>
- /// 褰撴斁璐у畬鎴愪笖闇�瑕佺粍鐩樻垨鎹㈢洏鏃惰皟鐢ㄣ��
- /// 灏嗗涓數姹犵粍鍚堝埌鍚屼竴涓墭鐩樹笂銆�
- ///
- /// configKey 鍙傛暟鍐冲畾璋冪敤鍝釜 API锛�
- /// - GroupPalletAsync: 缁勭洏鎺ュ彛
- /// - ChangePalletAsync: 鎹㈢洏鎺ュ彛
- /// </remarks>
- /// <param name="configKey">閰嶇疆閿悕锛屽喅瀹氳皟鐢ㄥ摢涓� API</param>
- /// <param name="stockDTO">搴撳瓨 DTO锛屽寘鍚缁勭洏鐨勭數鑺俊鎭�</param>
- /// <returns>HTTP 鍝嶅簲缁撴灉</returns>
- public HttpResponseResult<WebResponseContent> PostGroupPalletAsync(string configKey, StockDTO stockDTO)
- {
- string requestParam = stockDTO.ToJson();
- DateTime startTime = DateTime.Now;
-
- var result = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
-
- if (!result.IsSuccess || !result.Data.Status)
- QuartzLogHelper.LogError(_logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆恵configKey}銆�,璇锋眰鍙傛暟:銆恵requestParam}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�", "RobotTaskProcessor");
- else
- QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:{(DateTime.Now - startTime).TotalMilliseconds}ms", "RobotTaskProcessor");
-
- return result;
- }
-
- /// <summary>
- /// 璋冪敤鎵归噺鎷嗙洏纭 API
- /// </summary>
- /// <remarks>
- /// 褰撴媶鐩樹换鍔″叏閮ㄥ彇瀹屾椂璋冪敤锛屼竴娆℃�т笂浼犳暣涓墭鐩樼殑瑙g粦鏁版嵁鍒� MES銆�
- /// </remarks>
- /// <param name="palletCode">婧愭墭鐩樺彿</param>
- /// <param name="deviceName">璁惧鍚嶇О锛岀敤浜庝紶閫掑埌 WMS</param>
- /// <returns>HTTP 鍝嶅簲缁撴灉</returns>
- public HttpResponseResult<WebResponseContent> PostSplitPalletConfirmAsync(string palletCode, string deviceName)
- {
- string configKey = nameof(ConfigKey.SplitPalletConfirm);
- var request = new { PalletCode = palletCode, DeviceName = deviceName };
- string requestParam = request.ToJson();
- DateTime startTime = DateTime.Now;
-
- var result = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
-
- if (!result.IsSuccess || !result.Data.Status)
- QuartzLogHelper.LogError(_logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆恵configKey}銆�,璇锋眰鍙傛暟:銆恵requestParam}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�", "RobotTaskProcessor");
- else
- QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:{(DateTime.Now - startTime).TotalMilliseconds}ms", "RobotTaskProcessor");
-
- return result;
- }
-
- /// <summary>
- /// 璋冪敤鎵归噺缁勭洏纭 API
- /// </summary>
- /// <remarks>
- /// 褰撶粍鐩樹换鍔″叏閮ㄦ斁瀹屾椂璋冪敤锛屼竴娆℃�т笂浼犳暣涓墭鐩樼殑缁戝畾鏁版嵁鍒� MES銆�
- /// </remarks>
- /// <param name="palletCode">鐩爣鎵樼洏鍙�</param>
- /// <param name="deviceName">璁惧鍚嶇О锛岀敤浜庝紶閫掑埌 WMS</param>
- /// <returns>HTTP 鍝嶅簲缁撴灉</returns>
- public HttpResponseResult<WebResponseContent> PostGroupPalletConfirmAsync(string palletCode, string deviceName)
- {
- string configKey = nameof(ConfigKey.GroupPalletConfirm);
- var request = new { PalletCode = palletCode, DeviceName = deviceName };
- string requestParam = request.ToJson();
- DateTime startTime = DateTime.Now;
-
- var result = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
-
- if (!result.IsSuccess || !result.Data.Status)
- QuartzLogHelper.LogError(_logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆恵configKey}銆�,璇锋眰鍙傛暟:銆恵requestParam}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�", "RobotTaskProcessor");
- else
- QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:{(DateTime.Now - startTime).TotalMilliseconds}ms", "RobotTaskProcessor");
-
- return result;
- }
-
- public bool UpdateRobotTask(Dt_RobotTask task)
- {
- WebResponseContent content = _robotTaskService.UpdateData(task);
- return content.Status;
- }
- }
-}
+
+ /// <summary>
+ /// 鏋勯�犲嚱鏁�
+ /// </summary>
+ /// <param name="socketClientGateway">Socket 缃戝叧</param>
+ /// <param name="stateManager">鐘舵�佺鐞嗗櫒</param>
+ /// <param name="robotTaskService">鏈哄櫒浜轰换鍔℃湇鍔�</param>
+ /// <param name="taskService">閫氱敤浠诲姟鏈嶅姟</param>
+ /// <param name="httpClientHelper">HTTP 瀹㈡埛绔府鍔╃被</param>
+ /// <param name="logger">鏃ュ織璁板綍鍣�</param>
+ public RobotTaskProcessor(
+ ISocketClientGateway socketClientGateway,
+ RobotStateManager stateManager,
+ IRobotTaskService robotTaskService,
+ ITaskService taskService,
+ HttpClientHelper httpClientHelper,
+ ILogger logger,
+ IFakeBatteryPositionService fakeBatteryPositionService)
+ {
+ _socketClientGateway = socketClientGateway;
+ _stateManager = stateManager;
+ _robotTaskService = robotTaskService;
+ _taskService = taskService;
+ _httpClientHelper = httpClientHelper;
+ _logger = logger;
+ _fakeBatteryPositionService = fakeBatteryPositionService;
+ }
+
+ /// <summary>
+ /// 鎸夎澶囩紪鐮佽幏鍙栧綋鍓嶆満鍣ㄤ汉鐨勫緟澶勭悊浠诲姟
+ /// </summary>
+ /// <remarks>
+ /// 浠庢暟鎹簱涓煡璇㈡寚瀹氳澶囩紪鐮佺殑寰呭鐞嗘満鍣ㄤ汉浠诲姟銆�
+ /// 鍙繑鍥炵姸鎬佷负"寰呭鐞�"鐨勪换鍔°��
+ /// </remarks>
+ /// <param name="robotCrane">鏈哄櫒浜鸿澶囦俊鎭紝鍖呭惈璁惧缂栫爜</param>
+ /// <returns>寰呭鐞嗙殑浠诲姟瀵硅薄锛屽鏋滄病鏈夊垯杩斿洖 null</returns>
+ public Dt_RobotTask? GetTask(RobotCraneDevice robotCrane)
+ {
+ return _robotTaskService.QueryRobotCraneTask(robotCrane.DeviceCode);
+ }
+
+ /// <summary>
+ /// 鎸夎澶囩紪鐮佽幏鍙栧綋鍓嶆満鍣ㄤ汉鐨勬墽琛屼腑浠诲姟
+ /// </summary>
+ /// <remarks>
+ /// 浠庢暟鎹簱涓煡璇㈡寚瀹氳澶囩紪鐮佺殑鎵ц涓満鍣ㄤ汉浠诲姟銆�
+ /// 褰揜obotArmObject涓�1锛堟湁鐗╂枡锛変笖娌℃湁寰呭鐞嗕换鍔℃椂璋冪敤銆�
+ /// </remarks>
+ /// <param name="robotCrane">鏈哄櫒浜鸿澶囦俊鎭紝鍖呭惈璁惧缂栫爜</param>
+ /// <returns>鎵ц涓殑浠诲姟瀵硅薄锛屽鏋滄病鏈夊垯杩斿洖 null</returns>
+ public Dt_RobotTask? GetExecutingTask(RobotCraneDevice robotCrane)
+ {
+ return _robotTaskService.QueryRobotCraneExecutingTask(robotCrane.DeviceCode);
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="robotCrane"></param>
+ /// <returns></returns>
+ public Dt_RobotTask? GetRobotTask(RobotCraneDevice robotCrane)
+ {
+ return _robotTaskService.Repository.QueryFirst(x => x.RobotRoadway == robotCrane.DeviceCode);
+ }
+
+ /// <summary>
+ /// 鍒犻櫎鏈哄櫒浜轰换鍔�
+ /// </summary>
+ /// <remarks>
+ /// 褰撲换鍔″畬鎴愶紙鏃犺鏄垚鍔熻繕鏄け璐ワ級鏃惰皟鐢紝鍒犻櫎鏁版嵁搴撲腑鐨勪换鍔¤褰曘��
+ /// </remarks>
+ /// <param name="ID">瑕佸垹闄ょ殑浠诲姟 ID</param>
+ /// <returns>鍒犻櫎鏄惁鎴愬姛</returns>
+ public bool? DeleteTask(int ID)
+ {
+ return _robotTaskService.DeleteRobotTask(ID);
+ }
+
+ /// <summary>
+ /// 涓嬪彂鍙栬揣鎸囦护锛圥ickbattery锛夊埌鏈哄櫒浜哄鎴风
+ /// </summary>
+ /// <remarks>
+ /// 鍙戦�佹牸寮忥細Pickbattery,{婧愬湴鍧�}
+ /// 渚嬪锛歅ickbattery,A01 琛ㄧず浠� A01 浣嶇疆鍙栬揣
+ ///
+ /// 涓嬪彂鎴愬姛鍚庯細
+ /// 1. 鏇存柊浠诲姟鐘舵�佷负"鏈哄櫒浜烘墽琛屼腑"
+ /// 2. 灏嗕换鍔″叧鑱斿埌鐘舵�佸璞�
+ /// 3. 瀹夊叏鏇存柊鐘舵�佸埌 Redis
+ /// 4. 鏇存柊浠诲姟璁板綍鍒版暟鎹簱
+ /// </remarks>
+ /// <param name="task">瑕佷笅鍙戠殑浠诲姟瀵硅薄</param>
+ /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
+ /// <param name="isScanNG">鏄惁鎵爜NG</param>
+ public async Task SendSocketRobotPickAsync(Dt_RobotTask task, RobotSocketState state, bool isScanNG = false)
+ {
+ // 鏋勫缓鍙栬揣鎸囦护锛屾牸寮忥細Pickbattery,{婧愬湴鍧�}
+ string taskString = $"Pickbattery,{task.RobotSourceAddress}";
+
+ // 鏇存柊浠诲姟鐘舵�佷负"鏈哄櫒浜烘墽琛屼腑"
+ task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
+
+ // 灏嗕换鍔″叧鑱斿埌鐘舵�佸璞�
+ state.CurrentTask = task;
+
+ if (isScanNG)
+ {
+ state.IsScanNG = true;
+ }
+
+ // 淇濇寔鍘熻涔夛細浠呭湪鐘舵�佸畨鍏ㄥ啓鍏ユ垚鍔熷悗鍐嶆洿鏂颁换鍔$姸鎬�
+ // 杩欐牱鍙互纭繚鐘舵�佸拰浠诲姟璁板綍鐨勪竴鑷存��
+ if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
+ {
+ QuartzLogHelper.LogInfo(_logger, $"鐘舵�佹洿鏂版垚鍔燂紝璁惧: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+ // 閫氳繃 Socket 缃戝叧鍙戦�佹寚浠ゅ埌鏈哄櫒浜哄鎴风
+ bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
+ if (result)
+ {
+ // 鍙戦�佹垚鍔燂紝璁板綍 Info 鏃ュ織
+ QuartzLogHelper.LogInfo(_logger, $"涓嬪彂鍙栬揣鎸囦护鎴愬姛锛屾寚浠�: {taskString}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+ //await _robotTaskService.UpdateRobotTaskAsync(task);
+ }
+ else
+ {
+ // 鍙戦�佸け璐ワ紝璁板綍 Error 鏃ュ織
+ QuartzLogHelper.LogError(_logger, $"涓嬪彂鍙栬揣鎸囦护澶辫触锛屾寚浠�: {taskString}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+ }
+ }
+ }
+
+
+ public async Task SendSocketRobotNumAsync(Dt_RobotTask task, RobotSocketState state, bool isPick = true)
+ {
+ string taskString = string.Empty;
+
+ if (isPick)
+ // 鏋勫缓鎸囦护锛屾牸寮忥細PickTotalNum,{鏁伴噺}||PutTotalNum,{鏁伴噺}
+ taskString = $"PickTotalNum,{task.RobotTaskTotalNum + state.RobotTaskTotalNum}";
+ else
+ // 鏋勫缓鎸囦护锛屾牸寮忥細PutTotalNum,{鏁伴噺}||PutTotalNum,{鏁伴噺}
+ taskString = $"PutTotalNum,{task.RobotTaskTotalNum + state.RobotTaskTotalNum}";
+
+ // 閫氳繃 Socket 缃戝叧鍙戦�佹寚浠ゅ埌鏈哄櫒浜哄鎴风
+ bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
+ if (result)
+ {
+ // 鍙戦�佹垚鍔燂紝璁板綍 Info 鏃ュ織
+ QuartzLogHelper.LogInfo(_logger, $"涓嬪彂鎬绘暟鎸囦护鎴愬姛锛屾寚浠�: {taskString}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+ //await _robotTaskService.UpdateRobotTaskAsync(task);
+ }
+ else
+ {
+ // 鍙戦�佸け璐ワ紝璁板綍 Error 鏃ュ織
+ QuartzLogHelper.LogError(_logger, $"涓嬪彂鎬绘暟鎸囦护澶辫触锛屾寚浠�: {taskString}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+ }
+ }
+
+ /// <summary>
+ /// 涓嬪彂鍋囩數鑺彇璐ф寚浠ゅ埌鏈哄櫒浜哄鎴风
+ /// </summary>
+ /// <remarks>
+ /// 鍙戦�佹牸寮忥細Pickbattery,5,{startPosition}-{endPosition}
+ /// 渚嬪锛歅ickbattery,5,1-3 琛ㄧず浠庡亣鐢佃姱浣嶇疆5鎶撳彇锛屽钩闈㈢偣浣�1鍒�3
+ ///
+ /// 涓嬪彂鎴愬姛鍚庯細
+ /// 1. 鏍囪鐐逛綅涓哄凡浣跨敤
+ /// 2. 鏇存柊浠诲姟鐘舵�佷负"鏈哄櫒浜烘墽琛屼腑"
+ /// 3. 瀹夊叏鏇存柊鐘舵�佸埌 Redis
+ /// </remarks>
+ /// <param name="task">瑕佷笅鍙戠殑浠诲姟瀵硅薄</param>
+ /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
+ /// <param name="positions">瑕佹姄鍙栫殑骞抽潰鐐逛綅鍒楄〃</param>
+ public async Task SendSocketRobotFakeBatteryPickAsync(Dt_RobotTask task, RobotSocketState state, List<int> positions)
+ {
+ if (positions == null || positions.Count == 0)
+ {
+ QuartzLogHelper.LogWarn(_logger, $"SendSocketRobotFakeBatteryPickAsync锛氬钩闈㈢偣浣嶅垪琛ㄤ负绌猴紝浠诲姟鍙�: {task.RobotTaskNum}", state.RobotCrane?.DeviceName ?? "Unknown");
+ return;
+ }
+
+ // 璁$畻鐐逛綅鑼冨洿锛屾牸寮忥細1-3
+ int startPos = positions.Min();
+ int endPos = positions.Max();
+ string taskString = $"Pickbattery,5,{startPos}-{endPos}";
+
+ // 鏍囪鐐逛綅涓哄凡浣跨敤
+ _fakeBatteryPositionService.MarkAsUsed(positions);
+
+ // 鏇存柊浠诲姟鐘舵�佷负"鏈哄櫒浜烘墽琛屼腑"
+ task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
+
+ // 灏嗕换鍔″叧鑱斿埌鐘舵�佸璞�
+ state.CurrentTask = task;
+
+ if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
+ {
+ // 閫氳繃 Socket 缃戝叧鍙戦�佹寚浠ゅ埌鏈哄櫒浜哄鎴风
+ bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
+
+ if (result)
+ {
+ QuartzLogHelper.LogInfo(_logger, $"涓嬪彂鍋囩數鑺彇璐ф寚浠ゆ垚鍔燂紝鎸囦护: {taskString}锛岀偣浣�: {string.Join(",", positions)}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+ //await _robotTaskService.UpdateRobotTaskAsync(task);
+ }
+ else
+ {
+ QuartzLogHelper.LogError(_logger, $"涓嬪彂鍋囩數鑺彇璐ф寚浠ゅけ璐ワ紝鎸囦护: {taskString}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+ }
+ }
+ }
+
+ /// <summary>
+ /// 鑾峰彇涓婲涓彲鐢ㄧ殑鍋囩數鑺钩闈㈢偣浣�
+ /// </summary>
+ /// <param name="count">闇�瑕佽幏鍙栫殑鐐逛綅鏁伴噺</param>
+ /// <returns>鍙敤鐐逛綅鍒楄〃</returns>
+ public List<int> GetNextAvailableFakeBatteryPositions(int count)
+ {
+ return _fakeBatteryPositionService.GetNextAvailable(count);
+ }
+
+ /// <summary>
+ /// 璁$畻鎵规缂栧彿鑼冨洿
+ /// </summary>
+ /// <remarks>
+ /// 杩斿洖鏍煎紡锛�(start, end)
+ /// - remaining >= 4: (currentIndex, currentIndex + 3)
+ /// - remaining > 1: (currentIndex, currentIndex + remaining - 1)
+ /// - remaining == 1: (currentIndex, 0) -- 鍗曚釜鐗╁搧鐢� 0 琛ㄧず end
+ /// </remarks>
+ /// <param name="currentIndex">褰撳墠鎵规璧峰缂栧彿</param>
+ /// <param name="remaining">鍓╀綑鏁伴噺</param>
+ /// <returns>(start, end) 鍏冪粍</returns>
+ public (int Start, int End) BuildBatchRange(int currentIndex, int remaining)
+ {
+ if (remaining >= 4)
+ return (currentIndex, currentIndex + 3);
+ else if (remaining > 1)
+ return (currentIndex, currentIndex + remaining - 1);
+ else // remaining == 1
+ return (currentIndex, 0);
+ }
+
+ /// <summary>
+ /// 涓嬪彂鍙栬揣鎸囦护锛堝甫鎵规鏍煎紡鍜屾�绘暟锛�
+ /// </summary>
+ /// <remarks>
+ /// 鍙戦�侀『搴忥細
+ /// 1. PickTotalNum,{N} -- 鐪熷疄鐢佃姱鎬绘暟
+ /// 2. Pickbattery,{浣嶇疆},{start}-{end} -- 鎵规鍙栬揣鎸囦护
+ ///
+ /// 涓嬪彂鎴愬姛鍚庢洿鏂颁换鍔$姸鎬佷负"鏈哄櫒浜烘墽琛屼腑"銆�
+ /// </remarks>
+ /// <param name="task">瑕佷笅鍙戠殑浠诲姟瀵硅薄</param>
+ /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
+ /// <param name="position">鍙栬揣浣嶇疆</param>
+ /// <param name="batchStart">鎵规璧峰缂栧彿</param>
+ /// <param name="batchEnd">鎵规缁撴潫缂栧彿</param>
+ public async Task SendPickWithBatchAsync(Dt_RobotTask task, RobotSocketState state, string position, int batchStart, int batchEnd)
+ {
+
+ task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
+ state.CurrentTask = task;
+
+ if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
+ {
+ // 鍏堝彂閫佹�绘暟鎸囦护
+ string totalNumCmd = $"PickTotalNum,{task.RobotTaskTotalNum}";
+ await _socketClientGateway.SendToClientAsync(state.IPAddress, totalNumCmd);
+
+ // 鍐嶅彂閫佹壒娆″彇璐ф寚浠�
+ string range = batchEnd == 0 ? $"{batchStart}-0" : $"{batchStart}-{batchEnd}";
+ string taskString = $"Pickbattery,{position},{range}";
+
+ bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
+
+ if (result)
+ {
+ QuartzLogHelper.LogInfo(_logger, $"涓嬪彂鎵规鍙栬揣鎸囦护鎴愬姛锛屾寚浠�: {taskString}锛屾壒娆�: {range}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+ //await _robotTaskService.UpdateRobotTaskAsync(task);
+ }
+ else
+ {
+ QuartzLogHelper.LogError(_logger, $"涓嬪彂鎵规鍙栬揣鎸囦护澶辫触锛屾寚浠�: {taskString}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+ }
+ }
+ }
+
+ /// <summary>
+ /// 涓嬪彂鍋囩數鑺彇璐ф寚浠わ紙甯︽壒娆℃牸寮忓拰鎬绘暟锛�
+ /// </summary>
+ /// <remarks>
+ /// 鍙戦�侀『搴忥細
+ /// 1. PickTotalNum,{N} -- 鐪熷疄鐢佃姱鎬绘暟
+ /// 2. Pickbattery,5,{start}-{end} -- 鎵规鍙栬揣鎸囦护锛堝浐瀹氫粠5鍙蜂綅鍙栵級
+ ///
+ /// 涓嬪彂鎴愬姛鍚庢洿鏂颁换鍔$姸鎬佷负"鏈哄櫒浜烘墽琛屼腑"銆�
+ /// </remarks>
+ /// <param name="task">瑕佷笅鍙戠殑浠诲姟瀵硅薄</param>
+ /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
+ /// <param name="batchStart">鎵规璧峰缂栧彿</param>
+ /// <param name="batchEnd">鎵规缁撴潫缂栧彿</param>
+ public async Task SendFakeBatteryPickWithBatchAsync(Dt_RobotTask task, RobotSocketState state, int batchStart, int batchEnd)
+ {
+ task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
+ state.CurrentTask = task;
+
+ if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
+ {
+ // 鍏堝彂閫佹�绘暟鎸囦护
+ string totalNumCmd = $"PickTotalNum,{task.RobotTaskTotalNum}";
+ await _socketClientGateway.SendToClientAsync(state.IPAddress, totalNumCmd);
+
+ // 鍐嶅彂閫佹壒娆″彇璐ф寚浠わ紙鍋囩數鑺浐瀹氫粠5鍙蜂綅鍙栵級
+ string range = batchEnd == 0 ? $"{batchStart}-0" : $"{batchStart}-{batchEnd}";
+ string taskString = $"Pickbattery,5,{range}";
+
+ bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
+
+ if (result)
+ {
+ QuartzLogHelper.LogInfo(_logger, $"涓嬪彂鍋囩數鑺壒娆″彇璐ф寚浠ゆ垚鍔燂紝鎸囦护: {taskString}锛屾壒娆�: {range}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+
+ //await _robotTaskService.UpdateRobotTaskAsync(task);
+ }
+ else
+ {
+ QuartzLogHelper.LogError(_logger, $"涓嬪彂鍋囩數鑺壒娆″彇璐ф寚浠ゅけ璐ワ紝鎸囦护: {taskString}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+ }
+ }
+ }
+
+ /// <summary>
+ /// 涓嬪彂鏀捐揣鎸囦护锛堝甫鎵规鏍煎紡鍜屾�绘暟锛�
+ /// </summary>
+ /// <remarks>
+ /// 鍙戦�侀『搴忥細
+ /// 1. PutTotalNum,{N} -- 鐪熷疄鐢佃姱鎬绘暟
+ /// 2. Putbattery,{浣嶇疆},{start}-{end} -- 鎵规鏀捐揣鎸囦护
+ ///
+ /// 涓嬪彂鎴愬姛鍚庢洿鏂颁换鍔$姸鎬佷负"鏈哄櫒浜烘墽琛屼腑"銆�
+ /// </remarks>
+ /// <param name="task">瑕佷笅鍙戠殑浠诲姟瀵硅薄</param>
+ /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
+ /// <param name="position">鏀捐揣浣嶇疆</param>
+ /// <param name="batchStart">鎵规璧峰缂栧彿</param>
+ /// <param name="batchEnd">鎵规缁撴潫缂栧彿</param>
+ public async Task SendPutWithBatchAsync(Dt_RobotTask task, RobotSocketState state, string position, int batchStart, int batchEnd)
+ {
+ task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
+ state.CurrentTask = task;
+
+ if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
+ {
+ // 鍏堝彂閫佹�绘暟鎸囦护
+ string totalNumCmd = $"PutTotalNum,{task.RobotTaskTotalNum}";
+ await _socketClientGateway.SendToClientAsync(state.IPAddress, totalNumCmd);
+
+ // 鍐嶅彂閫佹壒娆℃斁璐ф寚浠�
+ string range = batchEnd == 0 ? $"{batchStart}-0" : $"{batchStart}-{batchEnd}";
+ string taskString = $"Putbattery,{position},{range}";
+
+ bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
+
+ if (result)
+ {
+ QuartzLogHelper.LogInfo(_logger, $"涓嬪彂鏀捐揣鎸囦护鎴愬姛锛屾寚浠�: {taskString}锛屾壒娆�: {range}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+
+ //await _robotTaskService.UpdateRobotTaskAsync(task);
+ }
+ else
+ {
+ QuartzLogHelper.LogError(_logger, $"涓嬪彂鏀捐揣鎸囦护澶辫触锛屾寚浠�: {taskString}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+ }
+ }
+ }
+
+ /// <summary>
+ /// 澶勭悊鍏ュ簱浠诲姟鍥炰紶锛堟媶鐩�/缁勭洏/鎹㈢洏鍦烘櫙锛�
+ /// </summary>
+ /// <remarks>
+ /// 褰撳彇璐у畬鎴愶紙AllPickFinished锛夋垨鏀捐揣瀹屾垚锛圓llPutFinished锛夋椂璋冪敤姝ゆ柟娉曘��
+ /// 鏍规嵁浠诲姟绫诲瀷鍜屽湴鍧�鏉ユ簮鍐冲畾濡備綍鍥炰紶缁� WMS銆�
+ ///
+ /// 澶勭悊閫昏緫锛�
+ /// 1. 鏍规嵁 useSourceAddress 鍐冲畾浣跨敤婧愬湴鍧�杩樻槸鐩爣鍦板潃
+ /// 2. 鏍规嵁浠诲姟绫诲瀷锛堢粍鐩�/鎹㈢洏/鎷嗙洏锛夊喅瀹氫换鍔$被鍨嬶紙鍏ュ簱/绌烘墭鐩樺叆搴擄級
+ /// 3. 鏋勫缓 CreateTaskDto 骞惰皟鐢� WMS 鎺ュ彛鍒涘缓浠诲姟
+ /// 4. 鎺ユ敹 WMS 杩斿洖鐨勪换鍔′俊鎭�
+ /// 5. 鏇存柊杈撻�佺嚎鐨勭洰鏍囧湴鍧�銆佷换鍔″彿绛�
+ /// </remarks>
+ /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
+ /// <param name="useSourceAddress">鏄惁浣跨敤婧愬湴鍧�锛坱rue 琛ㄧず鎷嗙洏/鎹㈢洏鍦烘櫙锛宖alse 琛ㄧず缁勭洏/鎹㈢洏鍦烘櫙锛�</param>
+ /// <returns>澶勭悊鏄惁鎴愬姛</returns>
+ public async Task<bool> HandleInboundTaskAsync(RobotSocketState state, bool useSourceAddress, string isRoadway = null)
+ {
+ // 鑾峰彇褰撳墠鍏宠仈鐨勪换鍔�
+ var currentTask = state.CurrentTask;
+ if (currentTask == null)
+ {
+ QuartzLogHelper.LogDebug(_logger, $"HandleInboundTaskAsync锛氬綋鍓嶄换鍔′负绌�", state.RobotCrane?.DeviceName ?? "Unknown");
+ return false;
+ }
+
+ // 鑾峰彇宸烽亾浠g爜
+ string roadway = string.Empty;
+
+ // 鏍规嵁宸烽亾鍚嶇О鍒ゆ柇浠撳簱 ID
+ int warehouseId = 0;
+
+ // 婧愬湴鍧�鍜岀洰鏍囧湴鍧�锛堝垵濮嬪寲锛�
+ string SourceAddress = currentTask.RobotTargetAddressLineCode;
+ string TargetAddress = currentTask.RobotSourceAddressLineCode;
+
+ // 浠诲姟绫诲瀷锛�0 琛ㄧず鏈畾涔夛紝绋嶅悗鏍规嵁浠诲姟绫诲瀷璁剧疆锛�
+ int taskType = 0;
+
+ // 鎵樼洏浠g爜锛堝垵濮嬪寲涓虹┖锛�
+ string PalletCode = string.Empty;
+
+ // 鑾峰彇浠诲姟绫诲瀷鐨勬灇涓惧��
+ var robotTaskType = (RobotTaskTypeEnum)currentTask.RobotTaskType;
+
+ // 鏍规嵁 useSourceAddress 鍐冲畾澶勭悊閫昏緫
+ if (useSourceAddress)
+ {
+ // 浣跨敤婧愬湴鍧�鐨勫満鏅細鎷嗙洏銆佹崲鐩橈紙鏀剧┖鎵樼洏锛�
+ switch (robotTaskType)
+ {
+ case RobotTaskTypeEnum.GroupPallet:
+ warehouseId = 1;
+ roadway = "GWSC1";
+ SourceAddress = currentTask.RobotSourceAddressLineCode;
+ TargetAddress = currentTask.RobotTargetAddressLineCode;
+ break;
+
+ case RobotTaskTypeEnum.ChangePallet:
+ // 鎹㈢洏/鎷嗙洏鍦烘櫙锛氭墭鐩橀渶瑕佸叆搴�
+ taskType = TaskTypeEnum.InEmpty.GetHashCode(); // 绌烘墭鐩樺叆搴�
+ PalletCode = currentTask.RobotSourceAddressPalletCode; // 浣跨敤婧愬湴鍧�鐨勬墭鐩樼爜
+ if (isRoadway == "HCSC1")
+ {
+ warehouseId = 2;
+ roadway = "HCSC1";
+ }
+ else if (isRoadway == "GWSC1")
+ {
+ warehouseId = 1;
+ roadway = "GWSC1";
+ }
+
+ SourceAddress = currentTask.RobotSourceAddressLineCode;
+ TargetAddress = currentTask.RobotTargetAddressLineCode;
+ break;
+ case RobotTaskTypeEnum.SplitPallet:
+ // 鎹㈢洏/鎷嗙洏鍦烘櫙锛氭墭鐩橀渶瑕佸叆搴�
+ taskType = TaskTypeEnum.InEmpty.GetHashCode(); // 绌烘墭鐩樺叆搴�
+ PalletCode = currentTask.RobotSourceAddressPalletCode; // 浣跨敤婧愬湴鍧�鐨勬墭鐩樼爜
+
+ warehouseId = 3;
+ roadway = "CWSC1";
+
+ SourceAddress = currentTask.RobotSourceAddressLineCode;
+ TargetAddress = currentTask.RobotTargetAddressLineCode;
+ break;
+ }
+ }
+ else
+ {
+ // 浣跨敤鐩爣鍦板潃鐨勫満鏅細缁勭洏銆佹崲鐩橈紙鎴愬搧鍏ュ簱锛�
+ switch (robotTaskType)
+ {
+ case RobotTaskTypeEnum.ChangePallet:
+ // 鎹㈢洏/缁勭洏鍦烘櫙锛氳揣鐗╅渶瑕佸叆搴�
+ taskType = TaskTypeEnum.Inbound.GetHashCode(); // 鎴愬搧鍏ュ簱
+ PalletCode = currentTask.RobotTargetAddressPalletCode; // 浣跨敤鐩爣鍦板潃鐨勬墭鐩樼爜
+
+ if (isRoadway == "HCSC1")
+ {
+ warehouseId = 2;
+ roadway = "HCSC1";
+ }
+ else if (isRoadway == "GWSC1")
+ {
+ warehouseId = 1;
+ roadway = "GWSC1";
+ }
+
+ break;
+ case RobotTaskTypeEnum.GroupPallet:
+ // 鎹㈢洏/缁勭洏鍦烘櫙锛氳揣鐗╅渶瑕佸叆搴�
+ taskType = TaskTypeEnum.Inbound.GetHashCode(); // 鎴愬搧鍏ュ簱
+ PalletCode = currentTask.RobotTargetAddressPalletCode; // 浣跨敤鐩爣鍦板潃鐨勬墭鐩樼爜
+
+ warehouseId = 1;
+ roadway = "GWSC1";
+ break;
+
+ case RobotTaskTypeEnum.SplitPallet:
+
+ break;
+ }
+ }
+
+ // 鏋勫缓鍒涘缓浠诲姟鐨� DTO
+ CreateTaskDto taskDto = new CreateTaskDto
+ {
+ PalletCode = PalletCode, // 鎵樼洏鏉$爜
+ SourceAddress = SourceAddress ?? string.Empty, // 婧愬湴鍧�
+ TargetAddress = roadway ?? string.Empty, // 鐩爣鍦板潃
+ Roadway = roadway ?? string.Empty, // 宸烽亾
+ WarehouseId = warehouseId, // 浠撳簱 ID
+ PalletType = 1, // 鎵樼洏绫诲瀷锛堥粯璁や负1锛�
+ TaskType = taskType // 浠诲姟绫诲瀷锛堝叆搴�/绌烘墭鐩樺叆搴擄級
+ };
+
+ // 璁板綍鏃ュ織锛氬紑濮嬭皟鐢� WMS 鍒涘缓鍏ュ簱浠诲姟
+ QuartzLogHelper.LogInfo(_logger, $"HandleInboundTaskAsync锛氳皟鐢╓MS鍒涘缓鍏ュ簱浠诲姟锛屾墭鐩樼爜: {PalletCode}锛屼换鍔$被鍨�: {taskType}", state.RobotCrane?.DeviceName ?? "Unknown");
+
+ // 璋冪敤 WMS 鎺ュ彛鍒涘缓鍏ュ簱浠诲姟
+ string configKey = nameof(ConfigKey.CreateTaskInboundAsync);
+ string requestParam = taskDto.ToJson();
+ DateTime startTime = DateTime.Now;
+
+ var result = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
+
+ if (!result.IsSuccess || !result.Data.Status)
+ {
+ QuartzLogHelper.LogError(_logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆恵configKey}銆�,璇锋眰鍙傛暟:銆恵requestParam}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�", state.RobotCrane?.DeviceName ?? "Unknown");
+ return false;
+ }
+
+ QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:{(DateTime.Now - startTime).TotalMilliseconds}ms", state.RobotCrane?.DeviceName ?? "Unknown");
+
+ // 濡傛灉璋冪敤澶辫触鎴栬繑鍥為敊璇姸鎬�
+ if (!result.Data.Status && result.IsSuccess)
+ {
+ QuartzLogHelper.LogError(_logger, $"HandleInboundTaskAsync锛歐MS杩斿洖閿欒鐘舵�侊紝Status: {result.Data.Status}", state.RobotCrane?.DeviceName ?? "Unknown");
+ return false;
+ }
+
+ // 瑙f瀽 WMS 杩斿洖鐨勪换鍔′俊鎭�
+ WMSTaskDTO taskDTO = JsonConvert.DeserializeObject<WMSTaskDTO>(result.Data.Data.ToJson() ?? string.Empty) ?? new WMSTaskDTO();
+
+ // 璋冪敤浠诲姟鏈嶅姟鎺ユ敹 WMS 浠诲姟
+ var content = _taskService.ReceiveWMSTask(new List<WMSTaskDTO> { taskDTO });
+ if (!content.Status)
+ {
+ QuartzLogHelper.LogError(_logger, $"HandleInboundTaskAsync锛氭帴鏀禬MS浠诲姟澶辫触", state.RobotCrane?.DeviceName ?? "Unknown");
+ return false;
+ }
+
+ return true;
+ }
+
+ /// <summary>
+ /// 鏋勫缓搴撳瓨鍥炰紶 DTO
+ /// </summary>
+ /// <remarks>
+ /// 鐢ㄤ簬鎷嗙洏鍜岀粍鐩樻搷浣滄椂锛屽悜 WMS 鍥炰紶搴撳瓨淇℃伅銆�
+ /// DTO 鍖呭惈婧愯揣浣嶃�佺洰鏍囪揣浣嶃�佹墭鐩樼爜浠ュ強姣忎釜浣嶇疆鐨勭數姹犳潯鐮併��
+ /// </remarks>
+ /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
+ /// <param name="positions">鐢垫睜浣嶇疆鏁扮粍</param>
+ /// <returns>鏋勫缓濂界殑搴撳瓨 DTO</returns>
+ public static StockDTO BuildStockDTO(RobotSocketState state, int[] positions)
+ {
+ return new StockDTO
+ {
+ // 婧愯緭閫佺嚎缂栧彿
+ SourceLineNo = state.CurrentTask.RobotSourceAddressLineCode,
+
+ // 婧愭墭鐩樺彿
+ SourcePalletNo = state.CurrentTask.RobotSourceAddressPalletCode,
+
+ // 鐩爣鎵樼洏鍙�
+ TargetPalletNo = state.CurrentTask.RobotTargetAddressPalletCode,
+
+ // 鐩爣杈撻�佺嚎缂栧彿
+ TargetLineNo = state.CurrentTask.RobotTargetAddressLineCode,
+
+ // 宸烽亾缂栧彿(鏈哄櫒浜哄悕绉�)
+ Roadway = state.CurrentTask.RobotRoadway,
+
+ // 鐢垫睜浣嶇疆璇︽儏鍒楄〃
+ // 杩囨护鎺変綅缃负 0 鎴栬礋鏁扮殑鏃犳晥鏁版嵁
+ // 鎸変綅缃紪鍙锋帓搴�
+ // 涓烘瘡涓綅缃敓鎴愬搴旂殑搴撳瓨璇︽儏
+ Details = positions
+ .Where(x => x > 0) // 杩囨护鏃犳晥浣嶇疆
+ .OrderBy(x => x) // 鎸変綅缃帓搴�
+ .Select((x, idx) => new StockDetailDTO
+ {
+ // 鏁伴噺锛氬鏋滃凡鏈変换鍔℃�绘暟锛屼娇鐢ㄤ换鍔℃�绘暟+褰撳墠浣嶇疆鏁帮紱鍚﹀垯鍙娇鐢ㄥ綋鍓嶄綅缃暟
+ Quantity = 1,
+
+ // 閫氶亾/浣嶇疆缂栧彿
+ Channel = x,
+
+ // 鐢垫睜鏉$爜锛氬鏋滅姸鎬佷腑鏈夋潯鐮佸垪琛紝鍙栧搴斾綅缃殑鏉$爜锛涘惁鍒欎负绌�
+ //CellBarcode = state.CellBarcode?.Count > 0 ? state.CellBarcode[x - 1] : ""
+ CellBarcode = !state.CellBarcode.IsNullOrEmpty() ? state.CellBarcode[idx].ToString() ?? string.Empty : string.Empty
+ })
+ .ToList()
+ };
+ }
+
+ /// <summary>
+ /// 璋冪敤鎷嗙洏 API
+ /// </summary>
+ /// <remarks>
+ /// 褰撳彇璐у畬鎴愪笖闇�瑕佹媶鐩樻椂璋冪敤銆�
+ /// 灏嗙數姹犱粠鎵樼洏涓婂彇涓嬶紝閫愪釜鏀剧疆鍒扮洰鏍囦綅缃��
+ /// </remarks>
+ /// <param name="stockDTO">搴撳瓨 DTO锛屽寘鍚鎷嗙洏鐨勭數鑺俊鎭�</param>
+ /// <returns>HTTP 鍝嶅簲缁撴灉</returns>
+ public HttpResponseResult<WebResponseContent> PostSplitPalletAsync(StockDTO stockDTO)
+ {
+ string configKey = nameof(ConfigKey.SplitPalletAsync);
+ string requestParam = stockDTO.ToJson();
+ DateTime startTime = DateTime.Now;
+
+ var result = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
+
+ if (!result.IsSuccess || !result.Data.Status)
+ QuartzLogHelper.LogError(_logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆恵configKey}銆�,璇锋眰鍙傛暟:銆恵requestParam}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�", "RobotTaskProcessor");
+ else
+ QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:{(DateTime.Now - startTime).TotalMilliseconds}ms", "RobotTaskProcessor");
+
+ return result;
+ }
+
+ /// <summary>
+ /// 璋冪敤缁勭洏/鎹㈢洏 API
+ /// </summary>
+ /// <remarks>
+ /// 褰撴斁璐у畬鎴愪笖闇�瑕佺粍鐩樻垨鎹㈢洏鏃惰皟鐢ㄣ��
+ /// 灏嗗涓數姹犵粍鍚堝埌鍚屼竴涓墭鐩樹笂銆�
+ ///
+ /// configKey 鍙傛暟鍐冲畾璋冪敤鍝釜 API锛�
+ /// - GroupPalletAsync: 缁勭洏鎺ュ彛
+ /// - ChangePalletAsync: 鎹㈢洏鎺ュ彛
+ /// </remarks>
+ /// <param name="configKey">閰嶇疆閿悕锛屽喅瀹氳皟鐢ㄥ摢涓� API</param>
+ /// <param name="stockDTO">搴撳瓨 DTO锛屽寘鍚缁勭洏鐨勭數鑺俊鎭�</param>
+ /// <returns>HTTP 鍝嶅簲缁撴灉</returns>
+ public HttpResponseResult<WebResponseContent> PostGroupPalletAsync(string configKey, StockDTO stockDTO)
+ {
+ string requestParam = stockDTO.ToJson();
+ DateTime startTime = DateTime.Now;
+
+ var result = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
+
+ if (!result.IsSuccess || !result.Data.Status)
+ QuartzLogHelper.LogError(_logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆恵configKey}銆�,璇锋眰鍙傛暟:銆恵requestParam}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�", "RobotTaskProcessor");
+ else
+ QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:{(DateTime.Now - startTime).TotalMilliseconds}ms", "RobotTaskProcessor");
+
+ return result;
+ }
+
+ /// <summary>
+ /// 璋冪敤鎵归噺鎷嗙洏纭 API
+ /// </summary>
+ /// <remarks>
+ /// 褰撴媶鐩樹换鍔″叏閮ㄥ彇瀹屾椂璋冪敤锛屼竴娆℃�т笂浼犳暣涓墭鐩樼殑瑙g粦鏁版嵁鍒� MES銆�
+ /// </remarks>
+ /// <param name="palletCode">婧愭墭鐩樺彿</param>
+ /// <param name="deviceName">璁惧鍚嶇О锛岀敤浜庝紶閫掑埌 WMS</param>
+ /// <returns>HTTP 鍝嶅簲缁撴灉</returns>
+ public HttpResponseResult<WebResponseContent> PostSplitPalletConfirmAsync(string palletCode, string deviceName)
+ {
+ string configKey = nameof(ConfigKey.SplitPalletConfirm);
+ var request = new { PalletCode = palletCode, DeviceName = deviceName };
+ string requestParam = request.ToJson();
+ DateTime startTime = DateTime.Now;
+
+ var result = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
+
+ if (!result.IsSuccess || !result.Data.Status)
+ QuartzLogHelper.LogError(_logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆恵configKey}銆�,璇锋眰鍙傛暟:銆恵requestParam}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�", "RobotTaskProcessor");
+ else
+ QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:{(DateTime.Now - startTime).TotalMilliseconds}ms", "RobotTaskProcessor");
+
+ return result;
+ }
+
+ /// <summary>
+ /// 璋冪敤鎵归噺缁勭洏纭 API
+ /// </summary>
+ /// <remarks>
+ /// 褰撶粍鐩樹换鍔″叏閮ㄦ斁瀹屾椂璋冪敤锛屼竴娆℃�т笂浼犳暣涓墭鐩樼殑缁戝畾鏁版嵁鍒� MES銆�
+ /// </remarks>
+ /// <param name="palletCode">鐩爣鎵樼洏鍙�</param>
+ /// <param name="deviceName">璁惧鍚嶇О锛岀敤浜庝紶閫掑埌 WMS</param>
+ /// <returns>HTTP 鍝嶅簲缁撴灉</returns>
+ public HttpResponseResult<WebResponseContent> PostGroupPalletConfirmAsync(string palletCode, string deviceName)
+ {
+ string configKey = nameof(ConfigKey.GroupPalletConfirm);
+ var request = new { PalletCode = palletCode, DeviceName = deviceName };
+ string requestParam = request.ToJson();
+ DateTime startTime = DateTime.Now;
+
+ var result = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
+
+ if (!result.IsSuccess || !result.Data.Status)
+ QuartzLogHelper.LogError(_logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆恵configKey}銆�,璇锋眰鍙傛暟:銆恵requestParam}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�", "RobotTaskProcessor");
+ else
+ QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:{(DateTime.Now - startTime).TotalMilliseconds}ms", "RobotTaskProcessor");
+
+ return result;
+ }
+
+ public bool UpdateRobotTask(Dt_RobotTask task)
+ {
+ WebResponseContent content = _robotTaskService.UpdateData(task);
+ return content.Status;
+ }
+ }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotPrefixCommandHandler.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotPrefixCommandHandler.cs
index cf749d9..503b5ec 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotPrefixCommandHandler.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotPrefixCommandHandler.cs
@@ -153,7 +153,7 @@
.ToArray();
// 浠庢暟鎹簱閲嶆柊鏌ヨ褰撳墠浠诲姟锛堢‘淇濊幏鍙栨渶鏂扮姸鎬侊級
- var task = await _robotTaskService.Repository.QueryFirstAsync(x => x.RobotTaskState == TaskRobotStatusEnum.RobotExecuting.GetHashCode() && x.RobotRoadway == state.RobotCrane.DeviceName);
+ var task = await _robotTaskService.Repository.QueryFirstAsync(x => /*x.RobotTaskState == TaskRobotStatusEnum.RobotExecuting.GetHashCode() &&*/ x.RobotRoadway == state.RobotCrane.DeviceName);
if (task != null)
{
@@ -319,7 +319,7 @@
task.RobotTaskTotalNum -= positions.Length;
var stockDTO = RobotTaskProcessor.BuildStockDTO(state, positions);
- var result = _taskProcessor.PostGroupPalletAsync(nameof(ConfigKey.GroupPalletAsync), stockDTO);
+ var result = _taskProcessor.PostGroupPalletAsync(nameof(ConfigKey.ChangePalletAsync), stockDTO);
putSuccess = result.Data.Status && result.IsSuccess;
}
}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotSimpleCommandHandler.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotSimpleCommandHandler.cs
index 5c709bf..d60d160 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotSimpleCommandHandler.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotSimpleCommandHandler.cs
@@ -159,6 +159,8 @@
var isResult = UpdateStatus(state, true);
if (!isResult)
return false;
+
+ await _socketClientGateway.SendToClientAsync(state.IPAddress, "pickbatteryover");
return true;
// 鏀捐揣鎺ユ敹
@@ -166,6 +168,8 @@
isResult = UpdateStatus(state, false);
if (!isResult)
return false;
+
+ await _socketClientGateway.SendToClientAsync(state.IPAddress, "putbatteryover");
return true;
// ==================== 鍏ㄩ儴瀹屾垚鍛戒护 ====================
@@ -213,8 +217,8 @@
return false;
}
- await _socketClientGateway.SendToClientAsync(state.IPAddress, $"Swap,diskFinished");
- QuartzLogHelper.LogInfo(_logger, $"鍙戦�佹秷鎭細銆怱wap,diskFinished銆�", state.RobotCrane.DeviceName);
+ await _socketClientGateway.SendToClientAsync(state.IPAddress, $"Group,diskFinished");
+ QuartzLogHelper.LogInfo(_logger, $"鍙戦�佹秷鎭細銆怗roup,diskFinished銆�", state.RobotCrane.DeviceName);
state.CurrentTask = null;
state.RobotTaskTotalNum = 0;
@@ -242,14 +246,14 @@
return false;
}
- if (_taskProcessor.DeleteTask(currentTask.RobotTaskId) != true)
- {
- QuartzLogHelper.LogError(_logger, $"allpickfinished锛氬垹闄や换鍔¤褰曞け璐ワ紝浠诲姟鍙�: {currentTask.RobotTaskNum}", state.RobotCrane?.DeviceName ?? "Unknown");
- return false;
- }
+ //if (_taskProcessor.DeleteTask(currentTask.RobotTaskId) != true)
+ //{
+ // QuartzLogHelper.LogError(_logger, $"allpickfinished锛氬垹闄や换鍔¤褰曞け璐ワ紝浠诲姟鍙�: {currentTask.RobotTaskNum}", state.RobotCrane?.DeviceName ?? "Unknown");
+ // return false;
+ //}
- await _socketClientGateway.SendToClientAsync(state.IPAddress, $"Swap,diskFinished");
- QuartzLogHelper.LogInfo(_logger, $"鍙戦�佹秷鎭細銆怱wap,diskFinished銆�", state.RobotCrane.DeviceName);
+ await _socketClientGateway.SendToClientAsync(state.IPAddress, $"Group,diskFinished");
+ QuartzLogHelper.LogInfo(_logger, $"鍙戦�佹秷鎭細銆怗roup,diskFinished銆�", state.RobotCrane.DeviceName);
state.ChangePalletPhase = 0;
state.CurrentBatchIndex = 1;
@@ -281,8 +285,8 @@
return false;
}
- await _socketClientGateway.SendToClientAsync(state.IPAddress, $"Swap,diskFinished");
- QuartzLogHelper.LogInfo(_logger, $"鍙戦�佹秷鎭細銆怱wap,diskFinished銆�", state.RobotCrane.DeviceName);
+ await _socketClientGateway.SendToClientAsync(state.IPAddress, $"Group,diskFinished");
+ QuartzLogHelper.LogInfo(_logger, $"鍙戦�佹秷鎭細銆怗roup,diskFinished銆�", state.RobotCrane.DeviceName);
return true;
}
return false;
@@ -334,8 +338,8 @@
state.RobotTaskTotalNum = 0;
state.CellBarcode = new List<string>();
- await _socketClientGateway.SendToClientAsync(state.IPAddress, $"Swap,diskFinished");
- QuartzLogHelper.LogInfo(_logger, $"鍙戦�佹秷鎭細銆怱wap,diskFinished銆�", state.RobotCrane.DeviceName);
+ await _socketClientGateway.SendToClientAsync(state.IPAddress, $"Group,diskFinished");
+ QuartzLogHelper.LogInfo(_logger, $"鍙戦�佹秷鎭細銆怗roup,diskFinished銆�", state.RobotCrane.DeviceName);
state.ChangePalletPhase = 0;
state.CurrentBatchIndex = 1;
@@ -370,8 +374,8 @@
state.RobotTaskTotalNum = 0;
state.CellBarcode = new List<string>();
- await _socketClientGateway.SendToClientAsync(state.IPAddress, $"Swap,diskFinished");
- QuartzLogHelper.LogInfo(_logger, $"鍙戦�佹秷鎭細銆怱wap,diskFinished銆�", state.RobotCrane.DeviceName);
+ await _socketClientGateway.SendToClientAsync(state.IPAddress, $"Group,diskFinished");
+ QuartzLogHelper.LogInfo(_logger, $"鍙戦�佹秷鎭細銆怗roup,diskFinished銆�", state.RobotCrane.DeviceName);
state.ChangePalletPhase = 0;
state.CurrentBatchIndex = 1;
@@ -461,14 +465,14 @@
public bool UpdateStatus(RobotSocketState state, bool isPick)
{
- var task = _taskProcessor.GetTask(state?.RobotCrane);
+ var task = _taskProcessor.GetRobotTask(state?.RobotCrane);
if (task == null)
{
QuartzLogHelper.LogError(_logger, $"鍙栬揣鎺ユ敹澶辫触: 鏈壘鍒般�恵state?.RobotCrane}銆戠殑浠诲姟", state.RobotCrane?.DeviceName ?? "Unknown");
+ return false;
}
task.RobotTaskState = (int)TaskRobotStatusEnum.RobotExecuting;
- _taskProcessor.UpdateRobotTask(task);
- return true;
+ return _taskProcessor.UpdateRobotTask(task);
}
}
}
\ No newline at end of file
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 2567908..3d5241e 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotWorkflowOrchestrator.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotWorkflowOrchestrator.cs
@@ -169,6 +169,9 @@
bool isFlowA = task.RobotSourceAddressLineCode is "11001" or "11010";
+ await _taskProcessor.SendSocketRobotNumAsync(task, state, false);
+ Thread.Sleep(500);
+
// ==================== Phase 2: 鏀炬甯哥數鑺埌鐩爣鎵樼洏锛堜袱娴佸悜鐩稿悓锛�====================
// PickFinished 鍒拌揪锛歅hase 1 鐨� Pick 鍛戒护瀹屾垚锛岀幇鍦ㄤ笅鍙� Put 鍛戒护鏀炬甯哥數鑺�
if (state?.ChangePalletPhase == 2)
@@ -239,8 +242,6 @@
return;
}
- // 闈炴壒娆℃ā寮忔垨鍏朵粬闃舵涓嶄笅鍙戞寚浠�
- return;
}
// 闈炴崲鐩樹换鍔★細浣跨敤鍘熸湁鏍煎紡
@@ -389,8 +390,11 @@
// 鍒ゆ柇娴佸悜锛坣ull-safe锛�
bool isFlowA = task.RobotSourceAddressLineCode is "11001" or "11010";
+ await _taskProcessor.SendSocketRobotNumAsync(task, stateForUpdate);
+ Thread.Sleep(500);
+
// 鐩爣鏁伴噺涓�48锛氱洿鎺ヨ蛋鍘熸湁閫昏緫锛屼笉杩涘叆鎵规妯″紡
- if (targetNormalCount == targetTotal)
+ if (targetNormalCount + currentCompletedCount == targetTotal)
{
await _taskProcessor.SendSocketRobotPickAsync(task, stateForUpdate);
return;
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Messaging.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Messaging.cs
index 6c5b0ef..15fd6f2 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Messaging.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Messaging.cs
@@ -60,14 +60,14 @@
}
// 鎸夊鎴风鍘婚噸锛氭鏌ユ槸鍚︿笌璇ュ鎴风涓婃娑堟伅鐩稿悓
- lock (_syncRoot)
- {
- if (_clientLastMessage.TryGetValue(clientId, out var prev) && message == prev)
- {
- continue;
- }
- _clientLastMessage[clientId] = message;
- }
+ //lock (_syncRoot)
+ //{
+ // if (_clientLastMessage.TryGetValue(clientId, out var prev) && message == prev)
+ // {
+ // continue;
+ // }
+ // _clientLastMessage[clientId] = message;
+ //}
// 鏇存柊瀹㈡埛绔姸鎬�
UpdateClientStatus(clientId, message);
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs
index 2a154b9..7c21540 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs
@@ -209,6 +209,30 @@
return await ExecuteWithinTransactionAsync(async () =>
{
+ // 骞傜瓑鍐欏叆锛氭鏌ヤ复鏃惰〃鏄惁宸叉湁璇ユ墭鐩樿褰曪紝鏃犲垯鍐欏叆
+ var existingTemp = SqlSugarClient.Queryable<Dt_SplitTemp>()
+ .Where(t => t.PalletCode == stock.SourcePalletNo)
+ .First();
+ if (existingTemp == null)
+ {
+ // 鏌ヨ璇ユ墭鐩樺綋鍓嶆墍鏈夌數鑺紝瀛樺叆涓存椂琛�
+ var sourceStockForTemp = StockInfoService.Repository.QueryFirst(s => s.PalletCode == stock.SourcePalletNo);
+ if (sourceStockForTemp != null)
+ {
+ var allDetails = StockInfoDetailService.Repository.QueryData(d => d.StockId == sourceStockForTemp.Id);
+ if (allDetails != null && allDetails.Any())
+ {
+ var sfcListJson = JsonConvert.SerializeObject(allDetails.Select(d => d.SerialNumber).ToList());
+ await SqlSugarClient.Insertable(new Dt_SplitTemp
+ {
+ PalletCode = stock.SourcePalletNo,
+ SfcList = sfcListJson,
+ CreateTime = DateTime.Now
+ }).ExecuteCommandAsync();
+ }
+ }
+ }
+
var sourceStock = await StockInfoService.Repository.QueryDataNavFirstAsync(s => s.PalletCode == stock.SourcePalletNo);
if (sourceStock == null) return content.Error("婧愭墭鐩樹笉瀛樺湪");
--
Gitblit v1.9.3