From 96adc295cb04fd135d63d3a907f2732274f90965 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期二, 21 四月 2026 01:11:21 +0800
Subject: [PATCH] feat: 添加MES异步上传辅助服务并重构相关代码

---
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Common/CommonStackerCrane.cs |   90 +++++++++++++++++++++++++++++---------------
 1 files changed, 59 insertions(+), 31 deletions(-)

diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Common/CommonStackerCrane.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Common/CommonStackerCrane.cs
index 66e63ff..06829af 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Common/CommonStackerCrane.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Common/CommonStackerCrane.cs
@@ -1,4 +1,5 @@
 锘�#region << 鐗� 鏈� 娉� 閲� >>
+
 /*----------------------------------------------------------------
  * 鍛藉悕绌洪棿锛歐IDESEAWCS_QuartzJob
  * 鍒涘缓鑰咃細鑳$搴�
@@ -11,25 +12,22 @@
  * 淇敼鏃堕棿锛�
  * 鐗堟湰锛歏1.0.1
  * 淇敼璇存槑锛�
- * 
+ *
  *----------------------------------------------------------------*/
+
 #endregion << 鐗� 鏈� 娉� 閲� >>
 
 using HslCommunication;
-using Microsoft.AspNetCore.Http;
-using System;
-using System.Collections.Generic;
 using System.ComponentModel;
-using System.Linq;
 using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
+using System.Threading;
 using WIDESEAWCS_Communicator;
-using WIDESEAWCS_Core.Enums;
 using WIDESEAWCS_QuartzJob.DeviceBase;
 using WIDESEAWCS_QuartzJob.DTO;
 using WIDESEAWCS_QuartzJob.StackerCrane;
+using WIDESEAWCS_QuartzJob.StackerCrane.Common;
 using WIDESEAWCS_QuartzJob.StackerCrane.Enum;
+using WIDESEAWCS_Core.LogHelper;
 
 namespace WIDESEAWCS_QuartzJob
 {
@@ -37,42 +35,53 @@
     /// 涓�鑸爢鍨涙満瀹炵幇绫伙紝瀹炵幇鍫嗗灈鏈烘帴鍙e眰
     /// </summary>
     [Description("鍫嗗灈鏈�")]
-    public class CommonStackerCrane : IStackerCrane
+    public class CommonStackerCrane : StackerCraneBase, IStackerCrane
     {
         #region Private Member
+
         /// <summary>
         /// 鍫嗗灈鏈洪�氳瀵硅薄
         /// </summary>
         private BaseCommunicator _communicator;
+
         /// <summary>
         /// 鍫嗗灈鏈哄崗璁俊鎭�
         /// </summary>
         private readonly List<DeviceProDTO> _deviceProDTOs;
+
         /// <summary>
         /// 鍫嗗灈鏈哄崗璁槑缁嗕俊鎭�
         /// </summary>
         private readonly List<DeviceProtocolDetailDTO> _deviceProtocolDetailDTOs;
+
         /// <summary>
         /// 璁惧缂栧彿
         /// </summary>
         public readonly string _deviceCode;
+
         /// <summary>
         /// 璁惧鍚嶇О
         /// </summary>
         public readonly string _deviceName;
+
         /// <summary>
         /// 涓婁竴娆′换鍔″彿
         /// </summary>
         private int _lastTaskNum;
 
-        private bool _isChecked = false;
+        /// <summary>
+        /// 鏍囪鏄惁姝e湪妫�鏌ヤ换鍔″畬鎴愮姸鎬侊紙volatile 淇濊瘉澶氱嚎绋嬪彲瑙佹�э級
+        /// </summary>
+        private volatile bool _isChecked = false;
 
         private bool _heartStatr = true;
 
         private bool _isConnected = true;
+
         #endregion Private Member
 
         #region Public Member
+
         /// <summary>
         /// 鍫嗗灈鏈洪�氳瀵硅薄
         /// </summary>
@@ -154,6 +163,11 @@
         public bool IsConnected => Communicator.IsConnected && _isConnected;
 
         /// <summary>
+        /// 鍫嗗灈鏈哄畬鎴愪簨浠舵槸鍚﹀凡璁㈤槄
+        /// </summary>
+        public bool IsEventSubscribed => StackerCraneTaskCompletedEventHandler != null;
+
+        /// <summary>
         /// 鍫嗗灈鏈轰换鍔″畬鎴愪簨浠�
         /// </summary>
         public event EventHandler<StackerCraneTaskCompletedEventArgs> StackerCraneTaskCompletedEventHandler;
@@ -163,10 +177,6 @@
         /// </summary>
         public object StackerCraneTaskCommand { get; set; }
 
-        /// <summary>
-        /// 鍫嗗灈鏈哄畬鎴愪簨浠舵槸鍚﹀凡璁㈤槄
-        /// </summary>
-        public bool IsEventSubscribed => StackerCraneTaskCompletedEventHandler != null;
 
         /// <summary>
         /// 涓婁竴娆′换鍔$殑绫诲瀷
@@ -176,6 +186,7 @@
         #endregion
 
         #region Constructor Function
+
         /// <summary>
         /// 鏋勯�犲嚱鏁�
         /// </summary>
@@ -193,9 +204,11 @@
             _deviceName = deviceName;
             CheckConnect();
         }
+
         #endregion
 
         #region Private Method
+
         /// <summary>
         /// 鏍规嵁鍗忚璇诲彇鍫嗗灈鏈虹姸鎬�
         /// </summary>
@@ -217,7 +230,7 @@
                 {
                     return DeviceStatus.Idle;
                 }
-                else if (StackerCraneWorkStatusValue == StackerCraneWorkStatus.Putting || StackerCraneWorkStatusValue == StackerCraneWorkStatus.PickUp || StackerCraneWorkStatusValue == StackerCraneWorkStatus.PickUpCompleted || StackerCraneWorkStatusValue == StackerCraneWorkStatus.PutCompleted)
+                else if (StackerCraneWorkStatusValue == StackerCraneWorkStatus.Putting || StackerCraneWorkStatusValue == StackerCraneWorkStatus.PickUp || StackerCraneWorkStatusValue == StackerCraneWorkStatus.PutMove || StackerCraneWorkStatusValue == StackerCraneWorkStatus.PutCompleted)
                 {
                     return DeviceStatus.Working;
                 }
@@ -228,7 +241,11 @@
         private int GetCurrentTaskNum()
         {
             DeviceProDTO? devicePro = _deviceProDTOs.FirstOrDefault(x => x.DeviceProParamName == nameof(CurrentTaskNum));
-            return devicePro == null ? throw new Exception($"璇诲彇褰撳墠浠诲姟鍙烽敊璇�,鏈幏鍙栧埌鍗忚淇℃伅,璇锋鏌ラ厤缃弬鏁板悕绉版槸鍚﹂厤缃�,涓旈厤缃负涓簕nameof(CurrentTaskNum)}") : (int)Communicator.ReadAsObj(devicePro.DeviceProAddress, devicePro.DeviceDataType);
+            if (devicePro == null)
+                throw new Exception($"璇诲彇褰撳墠浠诲姟鍙烽敊璇�,鏈幏鍙栧埌鍗忚淇℃伅,璇锋鏌ラ厤缃弬鏁板悕绉版槸鍚﹂厤缃�,涓旈厤缃负{nameof(CurrentTaskNum)}");
+
+            object value = Communicator.ReadAsObj(devicePro.DeviceProAddress, devicePro.DeviceDataType);
+            return Convert.ToInt32(value);  // 缁熶竴杞崲涓� int
         }
 
         /// <summary>
@@ -303,11 +320,10 @@
                     {
                         return deviceProtocolDetail.ProtocolDetailType;
                     }
-                    return StackerCraneStatus.Unkonw.ToString();
+                    return StackerCraneStatus.Unknown.ToString();
                 }
             }
-            //todo 閫氳鏈繛鎺ユ椂鎶涘嚭寮傚父
-            return StackerCraneStatus.Unkonw.ToString();
+            return StackerCraneStatus.Unknown.ToString();
         }
 
         private void CheckConnect()
@@ -333,9 +349,11 @@
                 }
             });
         }
+
         #endregion
 
         #region Public Method
+
         /// <summary>
         /// 鍙戦�佷换鍔″懡浠�
         /// </summary>
@@ -346,7 +364,7 @@
             if (Communicator is SiemensS7)
             {
                 if (!IsConnected) throw new Exception($"閫氳杩炴帴閿欒锛岃妫�鏌ョ綉缁�");
-                DeviceProDTO? devicePro = _deviceProDTOs.Where(x => x.DeviceProParamType == nameof(DeviceCommand)).OrderBy(x => x.DeviceProOffset).FirstOrDefault();
+                DeviceProDTO? devicePro = _deviceProDTOs.Where(x => x.DeviceProParamType == nameof(DeviceCommand) && x.DeviceProParamName == "InputTaskNum")/*.OrderBy(x=>x.DeviceProOffset)*/.FirstOrDefault();
                 if (devicePro == null)
                 {
                     return false;
@@ -378,34 +396,43 @@
                 _isChecked = true;
                 try
                 {
-                    DeviceProDTO? devicePro = _deviceProDTOs.FirstOrDefault(x => x.DeviceProParamName == nameof(StackerCraneWorkStatus));
+                    DeviceProDTO? devicePro = _deviceProDTOs.FirstOrDefault(x => x.DeviceProParamName == nameof(StackerCraneCompleted));
                     if (devicePro != null)
                     {
-                        DeviceProtocolDetailDTO? deviceProtocolDetail = _deviceProtocolDetailDTOs.FirstOrDefault(x => x.DeviceProParamName == devicePro.DeviceProParamName && x.ProtocolDetailType == StackerCraneWorkStatus.WorkCompleted.ToString());
+                        DeviceProtocolDetailDTO? deviceProtocolDetail = _deviceProtocolDetailDTOs.FirstOrDefault(x => x.DeviceProParamName == devicePro.DeviceProParamName && x.ProtocolDetailType == StackerCraneCompleted.Completed.ToString());
                         if (deviceProtocolDetail != null)
                         {
                             OperateResult<TimeSpan> operateResult = new OperateResult<TimeSpan>();
                             TypeCode typeCode = SiemensDBDataType.GetTypeCode(devicePro.DeviceDataType);
+
+                            // 瓒呮椂浠� 10*6000ms (60s) 闄嶄綆鍒� 10*1000ms (10s)锛岄槻姝㈡柇杩炴椂闀挎椂闂撮樆濉�
+                            int timeout = 10 * 1000;
                             switch (typeCode)
                             {
                                 case TypeCode.Boolean:
-                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToBoolean(deviceProtocolDetail.ProtocalDetailValue));
+                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, timeout, Convert.ToBoolean(deviceProtocolDetail.ProtocalDetailValue));
                                     break;
+
                                 case TypeCode.Byte:
-                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToByte(deviceProtocolDetail.ProtocalDetailValue));
+                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, timeout, Convert.ToByte(deviceProtocolDetail.ProtocalDetailValue));
                                     break;
+
                                 case TypeCode.Int16:
-                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToInt16(deviceProtocolDetail.ProtocalDetailValue));
+                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, timeout, Convert.ToInt16(deviceProtocolDetail.ProtocalDetailValue));
                                     break;
+
                                 case TypeCode.Int32:
-                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToInt32(deviceProtocolDetail.ProtocalDetailValue));
+                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, timeout, Convert.ToInt32(deviceProtocolDetail.ProtocalDetailValue));
                                     break;
+
                                 case TypeCode.UInt16:
-                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToUInt16(deviceProtocolDetail.ProtocalDetailValue));
+                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, timeout, Convert.ToUInt16(deviceProtocolDetail.ProtocalDetailValue));
                                     break;
+
                                 case TypeCode.UInt32:
-                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToUInt32(deviceProtocolDetail.ProtocalDetailValue));
+                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, timeout, Convert.ToUInt32(deviceProtocolDetail.ProtocalDetailValue));
                                     break;
+
                                 default:
                                     break;
                             }
@@ -421,7 +448,8 @@
                 }
                 catch (Exception ex)
                 {
-
+                    // 璁板綍寮傚父锛岄伩鍏嶉敊璇闈欓粯鍚炴帀
+                    QuartzLogger.Error($"CheckStackerCraneTaskCompleted: 璁惧 {_deviceCode} 妫�鏌ュ紓甯�", "CommonStackerCrane", ex);
                 }
                 finally
                 {
@@ -450,7 +478,6 @@
         /// </summary>
         public void Heartbeat()
         {
-
         }
 
         /// <summary>
@@ -483,6 +510,7 @@
             // 鍛婅瘔鍨冨溇鍥炴敹鍣ㄤ笉鍐嶈皟鐢ㄦ瀵硅薄鐨勭粓缁撳櫒
             GC.SuppressFinalize(this);
         }
+
         #endregion
     }
-}
+}
\ No newline at end of file

--
Gitblit v1.9.3