Sfoglia il codice sorgente

二维码拍照,mes功能同步

844184169 6 mesi fa
parent
commit
bb4f8812ea

+ 14 - 2
TeamAAS-VM/Core/Management.cs

@@ -2216,8 +2216,20 @@ namespace TeamAAS_VP.Core
 
                             if (scanOk && !ScanValue.IsNullOrWhiteSpace())
                             {
-                                SendTaskMessage($"二维码拍照成功,接收到值:{ScanValue}", MessageLevel.Alarm);
-                                await plc.WriteNodeAsync(addressConfig.Out_QrCodePhotoResault.Address, (short)1);
+                                PartSN = ScanValue;
+                                //await plc.WriteNodeAsync(addressConfig.Out_PartCode.Address, PartSN);
+                                SendTaskMessage($"二维码拍照成功,接收到值:{ScanValue}", MessageLevel.Info);
+
+                                var stationConfig = _configService.GetDeviceInfo(0);
+                                if (stationConfig.EnableMES)
+                                {
+                                    (bool isSuccess, string response) = await _mesService.StationGetEx2Async(0, PartSN, "", 2);//询问零件码,是否可以使用
+                                    if (!isSuccess)//如果二维码已使用,则返回false
+                                    {
+                                        await plc.WriteNodeAsync(addressConfig.Out_QrCodePhotoResault.Address, (Int16)3);
+                                        return;
+                                    }
+                                }
                             }
                             else
                             {

+ 9 - 0
TeamAAS-VM/Interfaces/IMesService.cs

@@ -54,6 +54,15 @@ namespace TeamAAS_VP.Interfaces
         /// <returns></returns>
         Task<(bool IsSuccess, string Response)> StationGetExAsync(int deviceNo, string sn, string comp, double timeoutInSeconds);
 
+        /// <summary>
+        /// 过站请求的扩展版本,允许同时指定 <see cref="CancellationToken"/> 和超时时间(秒)。实现应优先考虑取消请求,但在未取消的情况下应用超时。
+        /// </summary>
+        /// <param name="sn"></param>
+        /// <param name="comp"></param>
+        /// <param name="timeoutInSeconds"></param>
+        /// <returns></returns>
+        Task<(bool IsSuccess, string Response)> StationGetEx2Async(int deviceNo, string partSN, string comp, double timeoutInSeconds);
+
         /// <summary>
         /// 使用配置的提交(Submit)URL 发起 GET 请求,提交过站结果及时间信息。
         /// </summary>

+ 93 - 0
TeamAAS-VM/Services/MesService.cs

@@ -234,6 +234,91 @@ namespace TeamAAS_VP.Services
             return result;
         }
 
+        /// <summary>
+        /// 向配置中指定的 MES 站点 URL 发起 GET 请求(用于零件使用查询)。
+        /// </summary>
+        /// <param name="partSN">要查询的序列号(SN)。</param>
+        /// <param name="cancellationToken">可选的取消令牌,用于请求超时或取消。</param>
+        /// <returns>
+        /// 返回元组 (IsSuccess, Response):
+        /// - IsSuccess: 请求是否视为成功(即 MES 返回了预期的 "SFC_OK" 且包含 "unit_process_check=OK")。
+        /// - Response: 原始响应文本或错误信息说明(如 "MES功能未启用!"、"Missing MES station URL"、"Canceled" 等)。
+        /// </returns>
+        /// <remarks>
+        /// 行为说明:
+        /// - 从配置获取设备信息,若 MES 未启用则直接返回 IsSuccess=true 且 Response 为提示文本(不视为错误)。
+        /// - 若未配置 MES URL 则返回 IsSuccess=false 与错误文本。
+        /// - 使用配置的 URL(通过 <see cref="string.Format"/> 填充 sn)发起 GET 请求,最多重试 10 次。
+        /// - 只有当响应包含 "SFC_OK" 且包含 "unit_process_check=OK" 时视为成功并立即返回。
+        /// - 捕获 <see cref="OperationCanceledException"/> 返回 "Canceled",捕获其它异常则返回异常消息。
+        /// - 若实例已被释放则抛出 <see cref="ObjectDisposedException"/>。
+        /// </remarks>
+        public async Task<(bool IsSuccess, string Response)> StationGetEx2Async(int deviceNo, string partSN, string comp, CancellationToken cancellationToken = default)
+        {
+            // 如果已经释放,则抛出异常,防止在已释放资源上继续操作。
+            if (_disposed) throw new ObjectDisposedException(nameof(MesService));
+
+            var device = _configService.GetDeviceInfo(deviceNo);
+            if (device == null)
+                device = _configService.GetDeviceInfo();
+            if (device == null || !device.EnableMES)
+            {
+                return (false, "MES功能未启用!");
+            }
+            if (string.IsNullOrWhiteSpace(device.MesUrl))
+                return (false, "Missing MES station URL");
+
+            string url = "";
+            url = $"{device.MesUrl}?c=QUERY_RECORD&line={device.Line}&station={device.Station}&fixtureid={device.FixtureId}&sn={partSN}&p=sn,message";
+
+            LogHelper.WriteLogMes($"【询问URL】{url}");
+            SendTaskMessage($"【询问URL】{url}", MessageLevel.Info);
+            (bool IsSuccess, string Response) result = (false, string.Empty);
+
+            for (int i = 0; i < 3; i++)
+            {
+                try
+                {
+                    using (var rsp = await _httpClient.GetAsync(url))
+                    {
+                        var text = await rsp.Content.ReadAsStringAsync();
+                        LogHelper.WriteLogMes($"【HTTP接收】{text}");
+                        SendTaskMessage($"【HTTP接收】{text}", MessageLevel.Info);
+
+                        // "SFC_OK" 代表和 MES 连接成功
+                        if (text.Contains("SFC_OK"))
+                        {
+                            string[] item = text.Split('\n');
+                            string snItem = item.FirstOrDefault(f => f.Contains("sn="));
+                            if (snItem != null)
+                            {
+                                if (snItem.Replace("sn=", "").Length == 0)//如果零件没做过
+                                {
+                                    return (true, text);
+                                }
+                                else//如果零件已做过
+                                {
+                                    string ProductMainSN_Temp = snItem.Replace("sn=", "").Trim();
+                                    SendTaskMessage($"零件已绑定sn:{ProductMainSN_Temp}", MessageLevel.Error);
+                                    return (false, text);
+                                }
+                            }
+                        }
+                        result = (false, text);
+                    }
+                }
+                catch (OperationCanceledException)
+                {
+                    result = (false, "Canceled");
+                }
+                catch (Exception ex)
+                {
+                    result = (false, ex.Message);
+                }
+            }
+            return result;
+        }
+
         public async Task<(bool IsSuccess, string Response)> StationGetExAsync(int deviceNo, string sn, string comp, double timeoutInSeconds)
         {
             using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeoutInSeconds)))
@@ -242,6 +327,14 @@ namespace TeamAAS_VP.Services
             }
         }
 
+        public async Task<(bool IsSuccess, string Response)> StationGetEx2Async(int deviceNo, string partSN, string comp, double timeoutInSeconds)
+        {
+            using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeoutInSeconds)))
+            {
+                return await StationGetEx2Async(deviceNo, partSN, comp, cts.Token);
+            }
+        }
+
         /// <summary>
         /// 向配置中指定的 MES 提交 URL 发起 GET 请求(用于提交测试结果/记录)。
         /// </summary>