yaoxiaohan пре 7 месеци
родитељ
комит
8e89915bf6

+ 119 - 0
TeamAAS-VM/Core/FileHelper.cs

@@ -1,6 +1,7 @@
 using ControlzEx.Standard;
 using Newtonsoft.Json;
 using Newtonsoft.Json.Linq;
+using NPOI.OpenXmlFormats.Wordprocessing;
 using NPOI.Util;
 using System;
 using System.Collections.Generic;
@@ -13,6 +14,7 @@ using System.Threading.Tasks;
 using TeamAAS_VP;
 using TeamAAS_VP.Models;
 using TeamAAS_VP.Resources.Languages;
+using TeamAAS_VP.Views.Home;
 
 namespace TeamAAS_VP.Core
 {
@@ -863,5 +865,122 @@ namespace TeamAAS_VP.Core
             }
         }
         #endregion
+
+        #region 写CTQ的csv
+        public static void WriteDataToCSV(DataFormCtq cd)
+        {
+            string s1, s2, s3, s4,
+                t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18,
+                r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18;
+            //
+            string path = "E:\\Data\\产品数据\\";
+            if (!Directory.Exists(path))
+            {
+                Directory.CreateDirectory(path);
+            }
+            //
+            t1 = "PPID";
+            t2 = "PROCESS_NAME";
+            t3 = "PROCESS_START_TIME";
+            t4 = "CTQ_NAME";
+            t5 = "CTQ_VALUE";
+            t6 = "CTQ_LSL";
+            t7 = "CTQ_USL";
+            t8 = "PROCESS_END_TIME";
+            t9 = "SUPPLIER_NAME";
+            t10 = "COMMODITY_TYPE";
+            t11 = "REVISION";
+            t12 = "WO#";
+            t13 = "MFG_LOT#";
+            t14 = "MFG_ASSY_LINE";
+            t15 = "PROCESS_OUTCOME";
+            t16 = "PROCESS_MACHINE_ID";
+            t17 = "CTQ_UNIT_OF_MEASURE";
+            t18 = "ERROR_MESSAGE";
+            //
+            r1 = cd.PPID;
+            r2 = cd.PROCESS_NAME;
+            r3 = cd.PROCESS_START_TIME;
+            r4 = cd.CTQ_NAME;
+            r5 = cd.CTQ_VALUE.ToString();
+            r6 = cd.CTQ_LSL.ToString();
+            r7 = cd.CTQ_USL.ToString();
+            r8 = cd.PROCESS_END_TIME;
+            r9 = cd.SUPPLIER_NAME;
+            r10 = cd.COMMODITY_TYPE;
+            r11 = cd.REVISION;
+            r12 = cd.WO;
+            r13 = cd.MFG_LOT;
+            r14 = cd.MFG_ASSY_LINE;
+            r15 = cd.PROCESS_OUTCOME;
+            r16 = cd.PROCESS_MACHINE_ID;
+            r17 = cd.CTQ_UNIT_OF_MEASURE;
+            r18 = cd.ERROR_MESSAGE;
+
+            //=========================
+            s1 = path;
+            s2 = DateTime.Now.ToString("yyyyMMdd"); //表格命名以天记录
+            s3 = t1 + "," + t2 + "," + t3 + "," + t4 + "," + t5 + "," + t6 + "," + t7 + "," + t8 + "," + t9 + "," + t10
+                + "," + t11 + "," + t12 + "," + t13 + "," + t14 + "," + t15 + "," + t16 + "," + t17 + "," + t18;
+            s4 = r1 + "," + r2 + "," + r3 + "," + r4 + "," + r5 + "," + r6 + "," + r7 + "," + r8 + "," + r9 + "," + r10
+                + "," + r11 + "," + r12 + "," + r13 + "," + r14 + "," + r15 + "," + r16 + "," + r17 + "," + r18;
+            //
+            Save(s1, s2, s3, s4);
+        }
+
+
+
+        //写csv
+        public static bool Save(string fullPath, string fileName, string RowName, string Data)
+        {
+            bool result = true;
+            try
+            {
+                if (!Directory.Exists(fullPath))
+                {
+                    Directory.CreateDirectory(fullPath);
+                }
+
+                if (fileName == null)
+                {
+                    fileName = DateTime.Now.ToString("yyyyMMdd");
+                }
+
+                string text = "";
+                string path = fullPath + "\\" + text;
+                string text2 = ".csv";
+                string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
+                if (!File.Exists(fullPath + "\\" + fileNameWithoutExtension + fileName + text2))
+                {
+                    using (File.Create(fullPath + "\\" + fileNameWithoutExtension + fileName + text2))
+                    {
+                    }
+
+                    FileStream fileStream2 = new FileStream(fullPath + "\\" + fileNameWithoutExtension + fileName + text2, FileMode.Append);
+                    StreamWriter streamWriter = new StreamWriter(fileStream2, Encoding.UTF8);
+                    streamWriter.WriteLine(RowName);
+                    streamWriter.WriteLine(Data);
+                    streamWriter.Flush();
+                    streamWriter.Close();
+                    fileStream2.Close();
+                }
+                else
+                {
+                    FileStream fileStream2 = new FileStream(fullPath + "\\" + fileNameWithoutExtension + fileName + text2, FileMode.Append);
+                    StreamWriter streamWriter = new StreamWriter(fileStream2, Encoding.UTF8);
+                    streamWriter.WriteLine(Data);
+                    streamWriter.Flush();
+                    streamWriter.Close();
+                    fileStream2.Close();
+                }
+            }
+            catch
+            {
+                result = false;
+            }
+
+            return result;
+        }
+        #endregion
     }
 }

+ 124 - 29
TeamAAS-VM/Core/Management.cs

@@ -31,6 +31,7 @@ using System.Linq;
 using System.Net.Sockets;
 using System.Reflection.Metadata;
 using System.Security.Cryptography;
+using System.Security.Policy;
 using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
@@ -116,6 +117,8 @@ namespace TeamAAS_VP.Core
         /// </summary>
         private int _pressureMaxDurationSeconds = 30; //超时自动停止秒数
         List<LockResult> lockResultsAll = new List<LockResult>();//一个产品的总结果
+        string productSn = "";//产品sn
+        DateTime StartScrewTime = DateTime.Now;//开始锁附的时间
         #endregion
 
         #region 属性
@@ -184,16 +187,6 @@ namespace TeamAAS_VP.Core
 
         public Dictionary<string, object> BackupObject { get; set; } = new Dictionary<string, object>();
 
-        private string _COM;
-        /// <summary>
-        /// 扭力测量仪COM
-        /// </summary>
-        public string COM
-        {
-            get { return _COM; }
-            set { SetProperty(ref _COM, value); }
-        }
-
         private string _SignalValue = "0";
         /// <summary>
         /// 扭力测量仪获取的最大值
@@ -204,16 +197,6 @@ namespace TeamAAS_VP.Core
             set { SetProperty(ref _SignalValue, value); }
         }
 
-        private double _Value;
-        /// <summary>
-        /// 电批扭力值
-        /// </summary>
-        public double Value
-        {
-            get { return _Value; }
-            set { SetProperty(ref _Value, value); }
-        }
-
         private NumberStatistics _NumStatistics;
         /// <summary>
         /// 数量(批头、吸嘴、供料器)
@@ -242,7 +225,15 @@ namespace TeamAAS_VP.Core
             set { _TorqueStatus = value; }
         }
 
-
+        private ObservableCollection<DataFormCtq> _dfc = new ObservableCollection<DataFormCtq>();
+        /// <summary>
+        /// CTQ数据集合
+        /// </summary>
+        public ObservableCollection<DataFormCtq> DFC
+        {
+            get { return _dfc; }
+            set { SetProperty(ref _dfc, value); }
+        }
         #endregion
 
         #region 命令
@@ -1713,6 +1704,7 @@ namespace TeamAAS_VP.Core
                         if (state == 1)
                         {
                             SendTaskMessage(Lang.收到开始锁付信号, MessageLevel.Debug);
+                            StartScrewTime = DateTime.Now;
                             //位置编号
                             Int16 positionIndex = plc.ReadNode<Int16>(addressConfig.In_ProductNum.Address);
                             SendTaskMessage(string.Format(Lang.编号0, positionIndex), MessageLevel.Info);
@@ -1767,6 +1759,7 @@ namespace TeamAAS_VP.Core
                             var headRecord = await _systemDatabaseService.GetLatestHeadChangeRecordAsync();
                             //最后一次的披头编号
                             string headNumber = headRecord != null ? headRecord.HeadBatchNumber : "N/A";
+                            var cdata = _configService.GetCTQDataInfo();//获取ctq数据参数
 
                             await Task.Delay(60);
                             //获取电批结果
@@ -1836,6 +1829,75 @@ namespace TeamAAS_VP.Core
                             await plc.WriteNodeAsync(addressConfig.In_WorkDone.Address, (Int16)0);
                             // 停止采集压力并保存
                             await StopAndSavePressureCollectionAsync(currentProduct.Name, _productService.CurrentProductCode, positionIndex);
+
+                            DFC.Clear();
+                            DFC.Add(new DataFormCtq
+                            {
+                                PPID = productSn,
+                                PROCESS_NAME = cdata.PROCESS_NAME,
+                                PROCESS_START_TIME = StartScrewTime.ToString(),
+                                CTQ_NAME = "Torque",
+                                CTQ_VALUE = lockResult.LockTorque,
+                                CTQ_LSL = lockResult.TargetTorqueLowerLimit,
+                                CTQ_USL = lockResult.TargetTorqueUpperLimit,
+                                PROCESS_END_TIME = DateTime.Now.ToString(),
+                                SUPPLIER_NAME = cdata.SUPPLIER_NAME,
+                                COMMODITY_TYPE = cdata.COMMODITY_TYPE,
+                                REVISION = cdata.REVISION,
+                                WO = cdata.WO,
+                                MFG_LOT = cdata.MFG_LOT,
+                                MFG_ASSY_LINE = cdata.MFG_ASSY_LINE,
+                                PROCESS_OUTCOME = lockResult.LockPassed ? "PASS" : "FAIL",
+                                PROCESS_MACHINE_ID = cdata.PROCESS_MACHINE_ID,
+                                CTQ_UNIT_OF_MEASURE = "kgf.cm",
+                                ERROR_MESSAGE = lockResult.LockPassed ? "" : "Torque_Spec OOS"
+                            });
+                            DFC.Add(new DataFormCtq
+                            {
+                                PPID = productSn,
+                                PROCESS_NAME = cdata.PROCESS_NAME,
+                                PROCESS_START_TIME = StartScrewTime.ToString(),
+                                CTQ_NAME = "Turn",
+                                CTQ_VALUE = lockResult.LockTurns,
+                                CTQ_LSL = lockResult.TargetTurnsLowerLimit,
+                                CTQ_USL = lockResult.TargetTurnsUpperLimit,
+                                PROCESS_END_TIME = DateTime.Now.ToString(),
+                                SUPPLIER_NAME = cdata.SUPPLIER_NAME,
+                                COMMODITY_TYPE = cdata.COMMODITY_TYPE,
+                                REVISION = cdata.REVISION,
+                                WO = cdata.WO,
+                                MFG_LOT = cdata.MFG_LOT,
+                                MFG_ASSY_LINE = cdata.MFG_ASSY_LINE,
+                                PROCESS_OUTCOME = lockResult.LockPassed ? "PASS" : "FAIL",
+                                PROCESS_MACHINE_ID = cdata.PROCESS_MACHINE_ID,
+                                CTQ_UNIT_OF_MEASURE = "圈",
+                                ERROR_MESSAGE = lockResult.LockPassed ? "" : "Turn_Spec OOS"
+                            });
+                            DFC.Add(new DataFormCtq
+                            {
+                                PPID = productSn,
+                                PROCESS_NAME = cdata.PROCESS_NAME,
+                                PROCESS_START_TIME = StartScrewTime.ToString(),
+                                CTQ_NAME = "Pressure",
+                                CTQ_VALUE = lockResult.Pressure,
+                                CTQ_LSL = cdata.CTQ_LSL_Pressure,
+                                CTQ_USL = cdata.CTQ_USL_Pressure,
+                                PROCESS_END_TIME = DateTime.Now.ToString(),
+                                SUPPLIER_NAME = cdata.SUPPLIER_NAME,
+                                COMMODITY_TYPE = cdata.COMMODITY_TYPE,
+                                REVISION = cdata.REVISION,
+                                WO = cdata.WO,
+                                MFG_LOT = cdata.MFG_LOT,
+                                MFG_ASSY_LINE = cdata.MFG_ASSY_LINE,
+                                PROCESS_OUTCOME = lockResult.LockPassed ? "PASS" : "FAIL",
+                                PROCESS_MACHINE_ID = cdata.PROCESS_MACHINE_ID,
+                                CTQ_UNIT_OF_MEASURE = "N",
+                                ERROR_MESSAGE = lockResult.LockPassed ? "" : "Pressure_Spec OOS"
+                            });
+                            foreach (var item in DFC)
+                            {
+                                FileHelper.WriteDataToCSV(item);
+                            }
                         }
                         else
                         {
@@ -2060,7 +2122,9 @@ namespace TeamAAS_VP.Core
                                 else
                                 {
                                     code = plc.ReadNode<string>(string.Format(addressConfig.In_Code.Address, i));
+                                    //code = "JSTEST045";
                                 }
+                                productSn = code;
 
                                 //询问mes
                                 if (state == 1)
@@ -2068,8 +2132,9 @@ namespace TeamAAS_VP.Core
                                     //这里缺少从MES获取产品配方的内容,需要补充
 
                                     _LastMesCheckTime[i] = DateTime.UtcNow;
-
-                                    (bool isSuccess, string response) = await _mesService.StationGetAsync(code, 2);
+                                    LogHelper.WriteLogMes($"【mes开始QUERY】");
+                                    SendTaskMessage($"mes开始QUERY", MessageLevel.Info);
+                                    (bool isSuccess, string response) = await _mesService.StationGetAsync(code,"", 2);//询问mes
                                     if (i == 0)
                                     {
                                         SendTaskMessage($"收到当前过站检查请求(当站是否生产)...", MessageLevel.Debug);
@@ -2082,16 +2147,22 @@ namespace TeamAAS_VP.Core
                                     {
                                         //产品发生改变并且供料器发生了变化时,需要通知PLC进行取料更改
                                         await plc.WriteNodeAsync(addressConfig.Out_ScrewFeederIsChanged.Address, (Int16)1); //不发生改变
-
                                         await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)1);
+
+                                        LogHelper.WriteLogMes($"询问mes成功");
+                                        SendTaskMessage($"询问mes成功", MessageLevel.Debug);
                                     }
                                     else
                                     {
                                         //产品发生改变并且供料器发生了变化时,需要通知PLC进行取料更改
                                         await plc.WriteNodeAsync(addressConfig.Out_ScrewFeederIsChanged.Address, (Int16)1); //不发生改变
+                                        await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)2);
 
-                                        await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)0);
+                                        LogHelper.WriteLogMes($"询问mes失败");
+                                        SendTaskMessage($"询问mes失败:{response}", MessageLevel.Error);
                                     }
+                                    LogHelper.WriteLogMes($"【mes结束QUERY】");
+                                    SendTaskMessage($"mes结束QUERY", MessageLevel.Info);
                                 }
                                 // 上传本站数据
                                 else if (state == 2)
@@ -2121,12 +2192,36 @@ namespace TeamAAS_VP.Core
                                             Remark = $"TotalSeconds:{DateTime.UtcNow.Subtract(_LastMesCheckTime[i]).TotalSeconds.ToString("F2")}",
                                         });
 
-                                    (bool isSuccess, string response) = await _mesService.SubmitGetAsync(code, resultIndex == 1 ? true : false, _LastMesCheckTime[i], DateTime.UtcNow);
-                                    //假设上传成功,这里缺少上传失败的处理
-
+                                    LogHelper.WriteLogMes($"【mes开始ADD】");
+                                    SendTaskMessage($"mes开始ADD", MessageLevel.Info);
+                                    //上传mes
+                                    string torque = ""; string pressure = ""; string turn = "";
+                                    //string torque = "1-1.11,2-2.22,3-1.11,4-2.22,5-1.11,6-2.22,7-1.11,8-2.22,9-1.11,10-2.22,1-1.11,2-2.22,3-1.11,4-2.22,5-1.11,6-2.22,7-1.11,8-2.22,9-1.11,10-2.22" +
+                                    //    "1-1.11,2-2.22,3-1.11,4-2.22,5-1.11,6-2.22,7-1.11,8-2.22,9-1.11,10-2.22,1-1.11,2-2.22,3-1.11,4-2.22,5-1.11,6-2.22,7-1.11,8-2.22,9-1.11,10-2.22" +
+                                    //    "1-1.11,2-2.22,3-1.11,4-2.22,5-1.11,6-2.22,7-1.11,8-2.22,9-1.11,10-2.22,1-1.11,2-2.22,3-1.11,4-2.22,5-1.11,6-2.22,7-1.11,8-2.22,9-1.11,10-2.22,61-3.33";
+                                    //string pressure = "1-1.11,2-2.22,3-1.11,4-2.22,5-1.11,6-2.22,7-1.11,8-2.22,9-1.11,10-2.22,1-1.11,2-2.22,3-1.11,4-2.22,5-1.11,6-2.22,7-1.11,8-2.22,9-1.11,10-2.22" +
+                                    //    "1-1.11,2-2.22,3-1.11,4-2.22,5-1.11,6-2.22,7-1.11,8-2.22,9-1.11,10-2.22,1-1.11,2-2.22,3-1.11,4-2.22,5-1.11,6-2.22,7-1.11,8-2.22,9-1.11,10-2.22" +
+                                    //    "1-1.11,2-2.22,3-1.11,4-2.22,5-1.11,6-2.22,7-1.11,8-2.22,9-1.11,10-2.22,1-1.11,2-2.22,3-1.11,4-2.22,5-1.11,6-2.22,7-1.11,8-2.22,9-1.11,10-2.22,61-3.33";
+                                    //string turn = "1-1.11,2-2.22,3-1.11,4-2.22,5-1.11,6-2.22,7-1.11,8-2.22,9-1.11,10-2.22,1-1.11,2-2.22,3-1.11,4-2.22,5-1.11,6-2.22,7-1.11,8-2.22,9-1.11,10-2.22" +
+                                    //    "1-1.11,2-2.22,3-1.11,4-2.22,5-1.11,6-2.22,7-1.11,8-2.22,9-1.11,10-2.22,1-1.11,2-2.22,3-1.11,4-2.22,5-1.11,6-2.22,7-1.11,8-2.22,9-1.11,10-2.22" +
+                                    //    "1-1.11,2-2.22,3-1.11,4-2.22,5-1.11,6-2.22,7-1.11,8-2.22,9-1.11,10-2.22,1-1.11,2-2.22,3-1.11,4-2.22,5-1.11,6-2.22,7-1.11,8-2.22,9-1.11,10-2.22,61-3.33";
+                                    (bool isSuccess, string response) = await _mesService.SubmitGetAsync(code,"",torque,pressure,turn, resultIndex == 1 ? true : false, _LastMesCheckTime[i], DateTime.UtcNow);
+                                    if (isSuccess)
+                                    {
+                                        LogHelper.WriteLogMes($"上传mes成功");
+                                        SendTaskMessage($"上传mes成功", MessageLevel.Debug);
+                                    }
+                                    else
+                                    {
+                                        LogHelper.WriteLogMes($"上传mes失败");
+                                        SendTaskMessage($"上传mes失败", MessageLevel.Error);
+                                    }
                                     await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)3);
 
                                     WriteProductLog(lockResultsAll, code, CTtime);
+
+                                    LogHelper.WriteLogMes($"【mes结束ADD】");
+                                    SendTaskMessage($"mes结束ADD", MessageLevel.Info);
                                 }
                                 else
                                 {
@@ -2149,7 +2244,7 @@ namespace TeamAAS_VP.Core
 
         #region 方法
 
-        private void SendTaskMessage(string msg, MessageLevel level)
+        public void SendTaskMessage(string msg, MessageLevel level)
         {
             App.Current.Dispatcher.Invoke(() =>
             {

+ 3 - 0
TeamAAS-VM/Interfaces/IConfigService.cs

@@ -507,5 +507,8 @@ namespace TeamAAS_VP.Interfaces
         void SaveTorqueReaderConfig(TorqueSerialPortConfig config);
 
         TorqueSerialPortConfig GetTorqueReaderConfig();
+
+        CTQ_Data GetCTQDataInfo();
+        void SaveCTQDataInfo(CTQ_Data cd);
     }
 }

+ 4 - 4
TeamAAS-VM/Interfaces/IMesService.cs

@@ -27,7 +27,7 @@ namespace TeamAAS_VP.Interfaces
         /// - 实现应尊重 <paramref name="cancellationToken"/>,在取消时尽早抛出 <see cref="OperationCanceledException"/> 或返回失败结果。
         /// - 若 <paramref name="sn"/> 无效,应抛出 <see cref="ArgumentNullException"/> 或 <see cref="ArgumentException"/>。
         /// </remarks>
-        Task<(bool IsSuccess, string Response)> StationGetAsync(string sn, CancellationToken cancellationToken = default);
+        Task<(bool IsSuccess, string Response)> StationGetAsync(string sn, string comp, CancellationToken cancellationToken = default);
 
         /// <summary>
         /// 使用配置的过站(Station)URL 发起 GET 请求,携带序列号(sn)作为查询参数进行过站,并使用指定的超时时间(秒)。
@@ -43,7 +43,7 @@ namespace TeamAAS_VP.Interfaces
         /// - 此重载方便在不使用 <see cref="CancellationToken"/> 的场景中指定超时时间。
         /// - 实现应验证 <paramref name="timeoutInSeconds"/> 为合理值(例如 > 0),否则可抛出 <see cref="ArgumentOutOfRangeException"/>。
         /// </remarks>
-        Task<(bool IsSuccess, string Response)> StationGetAsync(string sn, double timeoutInSeconds);
+        Task<(bool IsSuccess, string Response)> StationGetAsync(string sn,string comp, double timeoutInSeconds);
 
         /// <summary>
         /// 使用配置的提交(Submit)URL 发起 GET 请求,提交过站结果及时间信息。
@@ -63,7 +63,7 @@ namespace TeamAAS_VP.Interfaces
         /// - 若 <paramref name="start_time"/> 晚于 <paramref name="stop_time"/>,实现应记录并视情况返回失败或抛出异常。
         /// - 实现应尊重 <paramref name="cancellationToken"/>,并在取消时尽早中止请求。
         /// </remarks>
-        Task<(bool IsSuccess, string Response)> SubmitGetAsync(string sn, bool isSuccess, DateTime start_time, DateTime stop_time, CancellationToken cancellationToken = default);
+        Task<(bool IsSuccess, string Response)> SubmitGetAsync(string sn, string comp, string torque, string pressure, string turn, bool isSuccess, DateTime start_time, DateTime stop_time, CancellationToken cancellationToken = default);
 
         /// <summary>
         /// 使用配置的提交(Submit)URL 发起 GET 请求,提交过站结果及时间信息,并使用指定的超时时间(秒)。
@@ -82,6 +82,6 @@ namespace TeamAAS_VP.Interfaces
         /// - 此重载用于在不传入 <see cref="CancellationToken"/> 的场景中指定超时时间。
         /// - 实现应确保对时间参数与布尔参数进行适当的 URL 编码或格式化。
         /// </remarks>
-        Task<(bool IsSuccess, string Response)> SubmitGetAsync(string sn, bool isSuccess, DateTime start_time, DateTime stop_time, double timeoutInSeconds);
+        Task<(bool IsSuccess, string Response)> SubmitGetAsync(string sn,string comp, string torque, string pressure, string turn, bool isSuccess, DateTime start_time, DateTime stop_time, double timeoutInSeconds);
     }
 }

+ 133 - 0
TeamAAS-VM/Models/CTQ_Data.cs

@@ -0,0 +1,133 @@
+using Prism.Mvvm;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TeamAAS_VP.Models
+{
+    public class CTQ_Data:BindableBase
+    {
+        private string _PPID;
+        /// <summary>
+        /// sn
+        /// </summary>
+        public string PPID { get => _PPID; set => SetProperty(ref _PPID, value); }
+
+        private string _PROCESS_NAME;
+        /// <summary>
+        /// 设备名称
+        /// </summary>
+        public string PROCESS_NAME { get => _PROCESS_NAME; set => SetProperty(ref _PROCESS_NAME, value); }
+
+        private string _PROCESS_START_TIME;
+        /// <summary>
+        /// 开始时间
+        /// </summary>
+        public string PROCESS_START_TIME { get => _PROCESS_START_TIME; set => SetProperty(ref _PROCESS_START_TIME, value); }
+
+        private string _CTQ_NAME;
+        /// <summary>
+        /// 检测项名称
+        /// </summary>
+        public string CTQ_NAME { get => _CTQ_NAME; set => SetProperty(ref _CTQ_NAME, value); }
+
+        private double _CTQ_VALUE;
+        /// <summary>
+        /// 检测值
+        /// </summary>
+        public double CTQ_VALUE { get => _CTQ_VALUE; set => SetProperty(ref _CTQ_VALUE, value); }
+
+        //private double _CTQ_LSL_Torque;
+        ///// <summary>
+        ///// 下限(扭力)
+        ///// </summary>
+        //public double CTQ_LSL_Torque { get => _CTQ_LSL_Torque; set => SetProperty(ref _CTQ_LSL_Torque, value); }
+
+        //private double _CTQ_USL_Torque;
+        ///// <summary>
+        ///// 上限(扭力)
+        ///// </summary>
+        //public double CTQ_USL_Torque { get => _CTQ_USL_Torque; set => SetProperty(ref _CTQ_USL_Torque, value); }
+
+        //private double _CTQ_LSL_Turn;
+        ///// <summary>
+        ///// 下限(圈数)
+        ///// </summary>
+        //public double CTQ_LSL_Turn { get => _CTQ_LSL_Turn; set => SetProperty(ref _CTQ_LSL_Turn, value); }
+
+        //private double _CTQ_USL_Turn;
+        ///// <summary>
+        ///// 上限(圈数)
+        ///// </summary>
+        //public double CTQ_USL_Turn { get => _CTQ_USL_Turn; set => SetProperty(ref _CTQ_USL_Turn, value); }
+
+        private double _CTQ_LSL_Pressure;
+        /// <summary>
+        /// 下限(压力)
+        /// </summary>
+        public double CTQ_LSL_Pressure { get => _CTQ_LSL_Pressure; set => SetProperty(ref _CTQ_LSL_Pressure, value); }
+
+        private double _CTQ_USL_Pressure;
+        /// <summary>
+        /// 上限(压力)
+        /// </summary>
+        public double CTQ_USL_Pressure { get => _CTQ_USL_Pressure; set => SetProperty(ref _CTQ_USL_Pressure, value); }
+
+        private string _PROCESS_END_TIME;
+        /// <summary>
+        /// 结束时间
+        /// </summary>
+        public string PROCESS_END_TIME { get => _PROCESS_END_TIME; set => SetProperty(ref _PROCESS_END_TIME, value); }
+
+        private string _SUPPLIER_NAME;
+        public string SUPPLIER_NAME { get => _SUPPLIER_NAME; set => SetProperty(ref _SUPPLIER_NAME, value); }
+
+        private string _COMMODITY_TYPE;
+        public string COMMODITY_TYPE { get => _COMMODITY_TYPE; set => SetProperty(ref _COMMODITY_TYPE, value); }
+
+        private string _REVISION;
+        public string REVISION { get => _REVISION; set => SetProperty(ref _REVISION, value); }
+
+        private string _WO;
+        /// <summary>
+        /// 工单号
+        /// </summary>
+        public string WO { get => _WO; set => SetProperty(ref _WO, value); }
+
+        private string _MFG_LOT;
+        public string MFG_LOT { get => _MFG_LOT; set => SetProperty(ref _MFG_LOT, value); }
+
+        private string _MFG_ASSY_LINE;
+        /// <summary>
+        /// 线体
+        /// </summary>
+        public string MFG_ASSY_LINE { get => _MFG_ASSY_LINE; set => SetProperty(ref _MFG_ASSY_LINE, value); }
+
+        private string _PROCESS_OUTCOME;
+        /// <summary>
+        /// 结果
+        /// </summary>
+        public string PROCESS_OUTCOME { get => _PROCESS_OUTCOME; set => SetProperty(ref _PROCESS_OUTCOME, value); }
+
+        private string _PROCESS_MACHINE_ID;
+        /// <summary>
+        /// 设备ID
+        /// </summary>
+        public string PROCESS_MACHINE_ID { get => _PROCESS_MACHINE_ID; set => SetProperty(ref _PROCESS_MACHINE_ID, value); }
+
+        private string _CTQ_UNIT_OF_MEASURE;
+        /// <summary>
+        /// 单位
+        /// </summary>
+        public string CTQ_UNIT_OF_MEASURE { get => _CTQ_UNIT_OF_MEASURE; set => SetProperty(ref _CTQ_UNIT_OF_MEASURE, value); }
+
+        private string _ERROR_MESSAGE;
+        /// <summary>
+        /// 报错信息
+        /// </summary>
+        public string ERROR_MESSAGE { get => _ERROR_MESSAGE; set => SetProperty(ref _ERROR_MESSAGE, value); }
+
+    }
+}

+ 110 - 0
TeamAAS-VM/Models/DataFormCtq.cs

@@ -0,0 +1,110 @@
+using Prism.Mvvm;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TeamAAS_VP.Models
+{
+    public class DataFormCtq : BindableBase
+    {
+        private string _PPID;
+        /// <summary>
+        /// sn
+        /// </summary>
+        public string PPID { get => _PPID; set => SetProperty(ref _PPID, value); }
+
+        private string _PROCESS_NAME;
+        /// <summary>
+        /// 设备名称
+        /// </summary>
+        public string PROCESS_NAME { get => _PROCESS_NAME; set => SetProperty(ref _PROCESS_NAME, value); }
+
+        private string _PROCESS_START_TIME;
+        /// <summary>
+        /// 开始时间
+        /// </summary>
+        public string PROCESS_START_TIME { get => _PROCESS_START_TIME; set => SetProperty(ref _PROCESS_START_TIME, value); }
+
+        private string _CTQ_NAME;
+        /// <summary>
+        /// 检测项名称
+        /// </summary>
+        public string CTQ_NAME { get => _CTQ_NAME; set => SetProperty(ref _CTQ_NAME, value); }
+
+        private double _CTQ_VALUE;
+        /// <summary>
+        /// 检测值
+        /// </summary>
+        public double CTQ_VALUE { get => _CTQ_VALUE; set => SetProperty(ref _CTQ_VALUE, value); }
+
+        private double _CTQ_LSL;
+        /// <summary>
+        /// 下限
+        /// </summary>
+        public double CTQ_LSL { get => _CTQ_LSL; set => SetProperty(ref _CTQ_LSL, value); }
+
+        private double _CTQ_USL;
+        /// <summary>
+        /// 上限
+        /// </summary>
+        public double CTQ_USL { get => _CTQ_USL; set => SetProperty(ref _CTQ_USL, value); }
+
+        private string _PROCESS_END_TIME;
+        /// <summary>
+        /// 结束时间
+        /// </summary>
+        public string PROCESS_END_TIME { get => _PROCESS_END_TIME; set => SetProperty(ref _PROCESS_END_TIME, value); }
+
+        private string _SUPPLIER_NAME;
+        public string SUPPLIER_NAME { get => _SUPPLIER_NAME; set => SetProperty(ref _SUPPLIER_NAME, value); }
+
+        private string _COMMODITY_TYPE;
+        public string COMMODITY_TYPE { get => _COMMODITY_TYPE; set => SetProperty(ref _COMMODITY_TYPE, value); }
+
+        private string _REVISION;
+        public string REVISION { get => _REVISION; set => SetProperty(ref _REVISION, value); }
+
+        private string _WO;
+        /// <summary>
+        /// 工单号
+        /// </summary>
+        public string WO { get => _WO; set => SetProperty(ref _WO, value); }
+
+        private string _MFG_LOT;
+        public string MFG_LOT { get => _MFG_LOT; set => SetProperty(ref _MFG_LOT, value); }
+
+        private string _MFG_ASSY_LINE;
+        /// <summary>
+        /// 线体
+        /// </summary>
+        public string MFG_ASSY_LINE { get => _MFG_ASSY_LINE; set => SetProperty(ref _MFG_ASSY_LINE, value); }
+
+        private string _PROCESS_OUTCOME;
+        /// <summary>
+        /// 结果
+        /// </summary>
+        public string PROCESS_OUTCOME { get => _PROCESS_OUTCOME; set => SetProperty(ref _PROCESS_OUTCOME, value); }
+
+        private string _PROCESS_MACHINE_ID;
+        /// <summary>
+        /// 设备ID
+        /// </summary>
+        public string PROCESS_MACHINE_ID { get => _PROCESS_MACHINE_ID; set => SetProperty(ref _PROCESS_MACHINE_ID, value); }
+
+        private string _CTQ_UNIT_OF_MEASURE;
+        /// <summary>
+        /// 单位
+        /// </summary>
+        public string CTQ_UNIT_OF_MEASURE { get => _CTQ_UNIT_OF_MEASURE; set => SetProperty(ref _CTQ_UNIT_OF_MEASURE, value); }
+
+        private string _ERROR_MESSAGE;
+        /// <summary>
+        /// 报错信息
+        /// </summary>
+        public string ERROR_MESSAGE { get => _ERROR_MESSAGE; set => SetProperty(ref _ERROR_MESSAGE, value); }
+
+    }
+
+}

+ 13 - 10
TeamAAS-VM/Models/DeviceInfo.cs

@@ -1,5 +1,6 @@
 using Prism.Mvvm;
 using System;
+using System.Windows;
 
 namespace TeamAAS_VP.Models
 {
@@ -32,26 +33,28 @@ namespace TeamAAS_VP.Models
         /// </summary>
         public bool EnableMES { get => _enableMes; set => SetProperty(ref _enableMes, value); }
 
-        private string _mesStationUrl;
+        private string _mesUrl;
         /// <summary>
-        /// MES ¹ýÕ¾ URL
+        /// URL
         /// </summary>
-        public string MesStationUrl { get => _mesStationUrl; set => SetProperty(ref _mesStationUrl, value); }
+        public string MesUrl { get => _mesUrl; set => SetProperty(ref _mesUrl, value); }
 
-        private string _mesSubmitUrl;
-        /// <summary>
-        /// MES Ìá½» URL
-        /// </summary>
-        public string MesSubmitUrl { get => _mesSubmitUrl; set => SetProperty(ref _mesSubmitUrl, value); }
+
+        private string _f;
+        public string F { get => _f; set => SetProperty(ref _f, value); }
+
+        private string _comp;
+        public string comp { get => _comp; set => SetProperty(ref _comp, value); }
 
         public DeviceInfo()
         {
             Line = string.Empty;
             Station = string.Empty;
             FixtureId = string.Empty;
+            F = string.Empty;
+            comp = string.Empty;
+            MesUrl = string.Empty;
             EnableMES = false;
-            MesStationUrl = string.Empty;
-            MesSubmitUrl = string.Empty;
         }
     }
 }

+ 48 - 0
TeamAAS-VM/Services/ConfigService.cs

@@ -55,6 +55,8 @@ namespace TeamAAS_VP.Services
             public static readonly string CardReaderConfigurationPath = "..//Config//CardReaderConfiguration.cfg";
             // 电批配置路径
             public static readonly string TorqueReaderConfigurationPath = "..//Config//TorqueReaderConfiguration.cfg";
+            // 生产数据配置路径
+            public static readonly string DataConfigurationPath = "..//Config//DataConfiguration.cfg";
         }
 
         private readonly object _sync = new object();
@@ -72,6 +74,7 @@ namespace TeamAAS_VP.Services
 
         // Device info
         private DeviceInfo _deviceInfo;
+        public CTQ_Data CtqData { get; set; }
 
         private PlcAddressConfig PlcAddressConfig { get; set; }
         // 单个电批配置
@@ -227,6 +230,13 @@ namespace TeamAAS_VP.Services
                     FileHelper.WriteJsonFile(_cardReaderConfig, ConfigPaths.CardReaderConfigurationPath);
                 }
 
+                if (File.Exists(ConfigPaths.DataConfigurationPath))
+                    CtqData = FileHelper.ReadJsonFile<CTQ_Data>(ConfigPaths.DataConfigurationPath);
+                else
+                {
+                    CtqData = new CTQ_Data();
+                    FileHelper.WriteJsonFile(CtqData, ConfigPaths.DataConfigurationPath);
+                }
             }
         }
 
@@ -269,6 +279,8 @@ namespace TeamAAS_VP.Services
                 // save card reader config
                 if (_cardReaderConfig != null)
                     FileHelper.WriteJsonFile(_cardReaderConfig, ConfigPaths.CardReaderConfigurationPath);
+                if (CtqData != null)
+                    FileHelper.WriteJsonFile(CtqData, ConfigPaths.DataConfigurationPath);
             }
         }
 
@@ -409,6 +421,42 @@ namespace TeamAAS_VP.Services
         }
         #endregion
 
+        #region CTQData
+        /// <summary>
+        /// 获取CTQ信息配置
+        /// </summary>
+        public CTQ_Data GetCTQDataInfo()
+        {
+            lock (_sync)
+            {
+                if (CtqData == null)
+                {
+                    if (File.Exists(ConfigPaths.DataConfigurationPath))
+                        CtqData = FileHelper.ReadJsonFile<CTQ_Data>(ConfigPaths.DataConfigurationPath);
+                    else
+                    {
+                        CtqData = new CTQ_Data();
+                        FileHelper.WriteJsonFile(CtqData, ConfigPaths.DataConfigurationPath);
+                    }
+                }
+                return CtqData;
+            }
+        }
+
+        /// <summary>
+        /// 保存CTQ信息
+        /// </summary>
+        public void SaveCTQDataInfo(CTQ_Data cd)
+        {
+            if (cd == null) return;
+            lock (_sync)
+            {
+                CtqData = cd;
+                FileHelper.WriteJsonFile(CtqData, ConfigPaths.DataConfigurationPath);
+            }
+        }
+        #endregion
+
         #region Robots
         /// <summary>
         /// 获取所有机器人配置的只读集合。

+ 75 - 16
TeamAAS-VM/Services/MesService.cs

@@ -1,11 +1,18 @@
+using NPOI.SS.Formula.Functions;
+using Prism.Events;
+using Prism.Ioc;
 using System;
 using System.Collections.Generic;
 using System.Net.Http;
 using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
+using TeamAAS_VP.Core;
+using TeamAAS_VP.Enums;
+using TeamAAS_VP.Events;
 using TeamAAS_VP.Interfaces;
 using TeamAAS_VP.Models;
+using TeamAAS_VP.Resources.Languages;
 
 namespace TeamAAS_VP.Services
 {
@@ -23,6 +30,7 @@ namespace TeamAAS_VP.Services
     /// </summary>
     public class MesService : IMesService
     {
+        IEventAggregator _eventAggregator;
         /// <summary>
         /// 用于执行 HTTP 请求的客户端实例。建议在服务生命周期内重用,避免频繁创建导致套接字/端口耗尽。
         /// </summary>
@@ -43,11 +51,12 @@ namespace TeamAAS_VP.Services
         /// </summary>
         /// <param name="configService">用于获取设备配置信息的实现,不能为空。</param>
         /// <exception cref="ArgumentNullException">当 <paramref name="configService"/> 为 null 时抛出。</exception>
-        public MesService(IConfigService configService)
+        public MesService(IConfigService configService, IContainerProvider container, IEventAggregator ea)
         {
             _configService = configService ?? throw new ArgumentNullException(nameof(configService));
             _httpClient = new HttpClient();
             _disposed = false;
+            _eventAggregator = ea;
         }
 
 
@@ -70,7 +79,7 @@ namespace TeamAAS_VP.Services
         /// - 捕获 <see cref="OperationCanceledException"/> 返回 "Canceled",捕获其它异常则返回异常消息。
         /// - 若实例已被释放则抛出 <see cref="ObjectDisposedException"/>。
         /// </remarks>
-        public async Task<(bool IsSuccess, string Response)> StationGetAsync(string sn, CancellationToken cancellationToken = default)
+        public async Task<(bool IsSuccess, string Response)> StationGetAsync(string sn,string comp, CancellationToken cancellationToken = default)
         {
             // 如果已经释放,则抛出异常,防止在已释放资源上继续操作。
             if (_disposed) throw new ObjectDisposedException(nameof(MesService));
@@ -80,19 +89,40 @@ namespace TeamAAS_VP.Services
             {
                 return (true, "MES功能未启用!");
             }
-            if (string.IsNullOrWhiteSpace(device.MesStationUrl))
+            if (string.IsNullOrWhiteSpace(device.MesUrl))
                 return (false, "Missing MES station URL");
+            if (device.F == "PTL")
+            {
+                if (string.IsNullOrEmpty(device.comp))
+                {
+                    return (false, "PTL模式下comp不能为空");
+                }
+            }
 
-            var url = string.Format(device.MesStationUrl, sn);
-
+            string url = "";
+            if (device.F == "PTL")
+            {
+                url = $"{device.MesUrl}?c=QUERY_RECORD&line={device.Line}&station={device.Station}&fixtureid={device.FixtureId}&sn={sn}&comp={comp}&p=unit_process_check,model";
+            }
+            else
+            {
+                url = $"{device.MesUrl}?c=QUERY_RECORD&line={device.Line}&station={device.Station}&fixtureid={device.FixtureId}&sn={sn}&p=unit_process_check,model";
+            }
+            
+            LogHelper.WriteLogMes($"【询问URL】{url}");
+            SendTaskMessage($"【询问URL】{url}", MessageLevel.Info);
             (bool IsSuccess, string Response) result = (false, string.Empty);
-            for (int i = 0; i < 5; i++)
+
+            for (int i = 0; i < 3; i++)
             {
                 try
                 {
-                    using (var rsp = await _httpClient.GetAsync(url, cancellationToken))
+                    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"))
                         {
@@ -122,11 +152,11 @@ namespace TeamAAS_VP.Services
         /// <param name="sn">序列号(SN)。</param>
         /// <param name="timeoutInSeconds">请求超时,单位为秒。</param>
         /// <returns>与 <see cref="StationGetAsync(string, CancellationToken)"/> 相同的返回语义。</returns>
-        public async Task<(bool IsSuccess, string Response)> StationGetAsync(string sn, double timeoutInSeconds)
+        public async Task<(bool IsSuccess, string Response)> StationGetAsync(string sn,string comp, double timeoutInSeconds)
         {
             using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeoutInSeconds)))
             {
-                return await StationGetAsync(sn, cts.Token);
+                return await StationGetAsync(sn, comp, cts.Token);
             }
         }
 
@@ -152,7 +182,7 @@ namespace TeamAAS_VP.Services
         /// - 捕获 <see cref="OperationCanceledException"/> 返回 "Canceled",捕获其它异常则返回异常消息。
         /// - 若实例已被释放则抛出 <see cref="ObjectDisposedException"/>。
         /// </remarks>
-        public async Task<(bool IsSuccess, string Response)> SubmitGetAsync(string sn, bool isSuccess, DateTime start_time, DateTime stop_time, CancellationToken cancellationToken = default)
+        public async Task<(bool IsSuccess, string Response)> SubmitGetAsync(string sn,string comp,string torque,string pressure,string turn, bool isSuccess, DateTime start_time, DateTime stop_time, CancellationToken cancellationToken = default)
         {
             // 如果已经释放,则抛出异常,防止在已释放资源上继续操作。
             if (_disposed) throw new ObjectDisposedException(nameof(MesService));
@@ -162,19 +192,41 @@ namespace TeamAAS_VP.Services
             {
                 return (true, "MES功能未启用!");
             }
-            if (string.IsNullOrWhiteSpace(device.MesStationUrl))
+            if (string.IsNullOrWhiteSpace(device.MesUrl))
                 return (false, "Missing MES submit URL");
+            if (device.F == "PTL")
+            {
+                if (string.IsNullOrEmpty(device.comp))
+                {
+                    return (false, "PTL模式下comp不能为空");
+                }
+            }
 
-            var url = string.Format(device.MesStationUrl, sn, isSuccess ? "PASS" : "FAIL", start_time.ToString("yyyy-MM-dd HH:mm:ss"), stop_time.ToString("yyyy-MM-dd HH:mm:ss"));
-
+            string res = isSuccess ? "PASS" : "FAIL";
+            string url = "";
+            if (device.F=="PTL")
+            {
+                url = $"{device.MesUrl}?c=ADD_RECORD&line={device.Line}&station={device.Station}&fixtureid={device.FixtureId}&sn={sn}&f=PTL&comp={comp}" +
+                    $"&torque={torque}&pressure={pressure}&turn={turn}&result={res}&start_time={start_time.ToString("yyyy-MM-dd HH:mm:ss")}&stop_time={stop_time.ToString("yyyy-MM-dd HH:mm:ss")}";
+            }
+            else
+            {
+                url = $"{device.MesUrl}?c=ADD_RECORD&line={device.Line}&station={device.Station}&fixtureid={device.FixtureId}&sn={sn}&f=PQC" +
+                    $"&torque={torque}&pressure={pressure}&turn={turn}&result={res}&start_time={start_time.ToString("yyyy-MM-dd HH:mm:ss")}&stop_time={stop_time.ToString("yyyy-MM-dd HH:mm:ss")}";
+            }
+            LogHelper.WriteLogMes($"【上传URL】{url}");
+            SendTaskMessage($"【上传URL】{url}", MessageLevel.Info);
             (bool IsSuccess, string Response) result = (false, string.Empty);
-            for (int i = 0; i < 5; i++)
+
+            for (int i = 0; i < 3; i++)
             {
                 try
                 {
                     using (var rsp = await _httpClient.GetAsync(url, cancellationToken))
                     {
                         var text = await rsp.Content.ReadAsStringAsync();
+                        LogHelper.WriteLogMes($"【HTTP接收】{text}");
+                        SendTaskMessage($"【HTTP接收】{text}", MessageLevel.Info);
                         // "SFC_OK" 代表和 MES 连接成功
                         if (text.Contains("SFC_OK"))
                         {
@@ -209,11 +261,11 @@ namespace TeamAAS_VP.Services
         /// <param name="stop_time">结束时间。</param>
         /// <param name="timeoutInSeconds">请求超时,单位为秒。</param>
         /// <returns>与 <see cref="SubmitGetAsync(string, bool, DateTime, DateTime, CancellationToken)"/> 相同的返回语义。</returns>
-        public async Task<(bool IsSuccess, string Response)> SubmitGetAsync(string sn, bool isSuccess, DateTime start_time, DateTime stop_time, double timeoutInSeconds)
+        public async Task<(bool IsSuccess, string Response)> SubmitGetAsync(string sn,string comp, string torque, string pressure, string turn, bool isSuccess, DateTime start_time, DateTime stop_time, double timeoutInSeconds)
         {
             using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeoutInSeconds)))
             {
-                return await SubmitGetAsync(sn, isSuccess, start_time, stop_time, cts.Token);
+                return await SubmitGetAsync(sn, comp,torque,pressure,turn, isSuccess, start_time, stop_time, cts.Token);
             }
         }
 
@@ -229,5 +281,12 @@ namespace TeamAAS_VP.Services
                 _disposed = true;
             }
         }
+        public void SendTaskMessage(string msg, MessageLevel level)
+        {
+            App.Current.Dispatcher.Invoke(() =>
+            {
+                _eventAggregator.GetEvent<TaskMessageNotification>().Publish(new Models.MessageStruct() { Message = msg, level = level });
+            });
+        }
     }
 }

+ 2 - 0
TeamAAS-VM/TeamAAS-VP.csproj

@@ -535,6 +535,8 @@
     <Compile Include="Events\WorkShiftChangedNotification.cs" />
     <Compile Include="Events\WorkShiftUpdateNotification.cs" />
     <Compile Include="Interfaces\IMesService.cs" />
+    <Compile Include="Models\CTQ_Data.cs" />
+    <Compile Include="Models\DataFormCtq.cs" />
     <Compile Include="Models\DeviceInfo.cs" />
     <Compile Include="Models\Feeder\ScrewFeederInfo.cs" />
     <Compile Include="Models\HeadChangeRecord.cs" />

+ 1 - 1
TeamAAS-VM/ViewModels/HomeViewModel.cs

@@ -345,7 +345,7 @@ namespace TeamAAS_VP.ViewModels
         {
             try
             {
-                if (MessageQueue.Count >= 20)
+                if (MessageQueue.Count >= 100)
                 {
                     MessageQueue.RemoveAt(0);// 从队列头部移除最早的消息
                 }

+ 32 - 0
TeamAAS-VM/ViewModels/SettingViewModel.cs

@@ -336,6 +336,13 @@ namespace TeamAAS_VP.ViewModels
             set { SetProperty(ref _DeviceInfo, value); }
         }
 
+        private CTQ_Data _dataInfo;
+        public CTQ_Data DataInfo
+        {
+            get { return _dataInfo; }
+            set { SetProperty(ref _dataInfo, value); }
+        }
+
         private SerialPortConfig _CardReaderConfig;
         public SerialPortConfig CardReaderConfig
         {
@@ -439,6 +446,9 @@ namespace TeamAAS_VP.ViewModels
         private DelegateCommand _SaveDeviceInfoCommand;
         public DelegateCommand SaveDeviceInfoCommand => _SaveDeviceInfoCommand ?? (_SaveDeviceInfoCommand = new DelegateCommand(ExecuteSaveDeviceInfoCommand));
 
+        private DelegateCommand _SaveDataInfoCommand;
+        public DelegateCommand SaveDataInfoCommand => _SaveDataInfoCommand ?? (_SaveDataInfoCommand = new DelegateCommand(ExecuteSaveDataInfoCommand));
+
         private DelegateCommand _BrowseScrewCurvePathCommand;
         public DelegateCommand BrowseScrewCurvePathCommand => _BrowseScrewCurvePathCommand ?? (_BrowseScrewCurvePathCommand = new DelegateCommand(ExecuteBrowseScrewCurvePathCommand));
 
@@ -1378,6 +1388,12 @@ namespace TeamAAS_VP.ViewModels
                 DeviceInfo = _configService.GetDeviceInfo();
             }
 
+            if (DataInfo == null)
+            {
+                // load device info
+                DataInfo = _configService.GetCTQDataInfo();
+            }
+
             if (ScrewFeederList == null)
             {
                 var screwFeeders = _configService.GetAllScrewFeeders();
@@ -1707,6 +1723,22 @@ namespace TeamAAS_VP.ViewModels
                 _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = ex.Message, Duration = 1 });
             }
         }
+
+        private void ExecuteSaveDataInfoCommand()
+        {
+            try
+            {
+                if (DataInfo != null)
+                {
+                    _configService.SaveCTQDataInfo(DataInfo);
+                    _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = Lang.完成, Duration = 1 });
+                }
+            }
+            catch (Exception ex)
+            {
+                _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = ex.Message, Duration = 1 });
+            }
+        }
         #endregion
     }
 }

+ 1 - 1
TeamAAS-VM/Views/HomeView.xaml

@@ -472,7 +472,7 @@
                             <DataTemplate>
                                 <Border BorderThickness="0"
                                         HorizontalAlignment="Left">
-                                    <Label MaxWidth="600"
+                                    <Label MaxWidth="1000"
                                            BorderThickness="0"
                                            Background="Transparent"
                                            Margin="0"

+ 227 - 234
TeamAAS-VM/Views/SettingView.xaml

@@ -228,244 +228,237 @@
                     </StackPanel>
                 </TabItem.Header>
 
-                <Grid Margin="16">
+                <Grid>
                     <Grid.RowDefinitions>
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
+                        <RowDefinition Height="auto"/>
+                        <RowDefinition Height="auto"/>
                     </Grid.RowDefinitions>
-                    <Grid.ColumnDefinitions>
-                        <ColumnDefinition Width="auto" />
-                        <ColumnDefinition Width="*" />
-                    </Grid.ColumnDefinitions>
+                    <Grid Margin="16">
+                        <Grid.RowDefinitions>
+                            <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
+                        </Grid.RowDefinitions>
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition Width="auto" />
+                            <ColumnDefinition Width="*" />
+                        </Grid.ColumnDefinitions>
 
-                    <TextBlock Grid.Row="0"
-                               Grid.Column="0"
-                               Text="线别:"
-                               HorizontalAlignment="Right"
-                               VerticalAlignment="Center" />
-                    <TextBox Grid.Row="0"
-                             Grid.Column="1"
-                             Text="{Binding DeviceInfo.Line, Mode=TwoWay}"
-                             Margin="6" />
-
-                    <TextBlock Grid.Row="1"
-                               Grid.Column="0"
-                               Text="站别:"
-                               HorizontalAlignment="Right"
-                               VerticalAlignment="Center" />
-                    <TextBox Grid.Row="1"
-                             Grid.Column="1"
-                             Text="{Binding DeviceInfo.Station, Mode=TwoWay}"
-                             Margin="6" />
-
-                    <TextBlock Grid.Row="2"
-                               Grid.Column="0"
-                               Text="机台号:"
-                               HorizontalAlignment="Right"
-                               VerticalAlignment="Center" />
-                    <TextBox Grid.Row="2"
-                             Grid.Column="1"
-                             Text="{Binding DeviceInfo.FixtureId, Mode=TwoWay}"
-                             Margin="6" />
-
-                    <TextBlock Grid.Row="3"
-                               Grid.Column="0"
-                               Text="启用 MES:"
-                               HorizontalAlignment="Right"
-                               VerticalAlignment="Center" />
-                    <CheckBox Grid.Row="3"
-                              Grid.Column="1"
-                              IsChecked="{Binding DeviceInfo.EnableMES, Mode=TwoWay}"
-                              Margin="6" />
-
-                    <TextBlock Grid.Row="4"
-                               Grid.Column="0"
-                               Text="MES 过站 URL:"
-                               HorizontalAlignment="Right"
-                               VerticalAlignment="Center" />
-                    <TextBox Grid.Row="4"
-                             Grid.Column="1"
-                             Text="{Binding DeviceInfo.MesStationUrl, Mode=TwoWay}"
-                             Margin="6" />
-
-                    <TextBlock Grid.Row="5"
-                               Grid.Column="0"
-                               Text="MES 提交 URL:"
-                               HorizontalAlignment="Right"
-                               VerticalAlignment="Center" />
-                    <TextBox Grid.Row="5"
-                             Grid.Column="1"
-                             Text="{Binding DeviceInfo.MesSubmitUrl, Mode=TwoWay}"
-                             Margin="6" />
-
-                    <StackPanel Orientation="Horizontal"
-                                HorizontalAlignment="Right"
-                                Grid.Row="6"
-                                Grid.ColumnSpan="2"
-                                Margin="6">
-                        <Button Style="{StaticResource MaterialDesignRaisedButton}"
-                                Command="{Binding SaveDeviceInfoCommand}">保存</Button>
-                    </StackPanel>
 
-                    <TextBlock Grid.Row="7"
-                               Grid.Column="0"
-                               Text="PROCESS_NAME:"
-                               HorizontalAlignment="Right"
-                               VerticalAlignment="Center" />
-                    <TextBox Grid.Row="7"
-                             Grid.Column="1"
-                             Text="{Binding DeviceInfo.MesSubmitUrl, Mode=TwoWay}"
-                             Margin="6" />
-
-                    <TextBlock Grid.Row="8"
-                               Grid.Column="0"
-                               Text="CTQ_LSL(扭力下限):"
-                               HorizontalAlignment="Right"
-                               VerticalAlignment="Center" />
-                    <TextBox Grid.Row="8"
-                             Grid.Column="1"
-                             Text="{Binding DeviceInfo.MesSubmitUrl, Mode=TwoWay}"
-                             Margin="6" />
-
-                    <TextBlock Grid.Row="9"
-                               Grid.Column="0"
-                               Text="CTQ_USL(扭力上限)"
-                               HorizontalAlignment="Right"
-                               VerticalAlignment="Center" />
-                    <TextBox Grid.Row="9"
-                             Grid.Column="1"
-                             Text="{Binding DeviceInfo.MesSubmitUrl, Mode=TwoWay}"
-                             Margin="6" />
-
-                    <TextBlock Grid.Row="10"
-                               Grid.Column="0"
-                               Text="CTQ_LSL(压力下限):"
-                               HorizontalAlignment="Right"
-                               VerticalAlignment="Center" />
-                    <TextBox Grid.Row="10"
-                             Grid.Column="1"
-                             Text="{Binding DeviceInfo.MesSubmitUrl, Mode=TwoWay}"
-                             Margin="6" />
-
-                    <TextBlock Grid.Row="11"
-                               Grid.Column="0"
-                               Text="CTQ_USL(压力上限):"
-                               HorizontalAlignment="Right"
-                               VerticalAlignment="Center" />
-                    <TextBox Grid.Row="11"
-                             Grid.Column="1"
-                             Text="{Binding DeviceInfo.MesSubmitUrl, Mode=TwoWay}"
-                             Margin="6" />
-
-                    <TextBlock Grid.Row="12"
-                               Grid.Column="0"
-                               Text="SUPPLIER_NAME:"
-                               HorizontalAlignment="Right"
-                               VerticalAlignment="Center" />
-                    <TextBox Grid.Row="12"
-                             Grid.Column="1"
-                             Text="{Binding DeviceInfo.MesSubmitUrl, Mode=TwoWay}"
-                             Margin="6" />
-
-                    <TextBlock Grid.Row="13"
-                               Grid.Column="0"
-                               Text="COMMODITY_TYPE:"
-                               HorizontalAlignment="Right"
-                               VerticalAlignment="Center" />
-                    <TextBox Grid.Row="13"
-                             Grid.Column="1"
-                             Text="{Binding DeviceInfo.MesSubmitUrl, Mode=TwoWay}"
-                             Margin="6" />
-
-                    <TextBlock Grid.Row="14"
-                               Grid.Column="0"
-                               Text="REVISION:"
-                               HorizontalAlignment="Right"
-                               VerticalAlignment="Center" />
-                    <TextBox Grid.Row="14"
-                             Grid.Column="1"
-                             Text="{Binding DeviceInfo.MesSubmitUrl, Mode=TwoWay}"
-                             Margin="6" />
-
-                    <TextBlock Grid.Row="15"
-                               Grid.Column="0"
-                               Text="WO#:"
-                               HorizontalAlignment="Right"
-                               VerticalAlignment="Center" />
-                    <TextBox Grid.Row="15"
-                             Grid.Column="1"
-                             Text="{Binding DeviceInfo.MesSubmitUrl, Mode=TwoWay}"
-                             Margin="6" />
-
-                    <TextBlock Grid.Row="16"
-                               Grid.Column="0"
-                               Text="MFG_LOT#:"
-                               HorizontalAlignment="Right"
-                               VerticalAlignment="Center" />
-                    <TextBox Grid.Row="16"
-                             Grid.Column="1"
-                             Text="{Binding DeviceInfo.MesSubmitUrl, Mode=TwoWay}"
-                             Margin="6" />
-
-                    <TextBlock Grid.Row="17"
-                               Grid.Column="0"
-                               Text="MFG_ASSY_LINE:"
-                               HorizontalAlignment="Right"
-                               VerticalAlignment="Center" />
-                    <TextBox Grid.Row="17"
-                             Grid.Column="1"
-                             Text="{Binding DeviceInfo.MesSubmitUrl, Mode=TwoWay}"
-                             Margin="6" />
-
-                    <TextBlock Grid.Row="18"
-                               Grid.Column="0"
-                               Text="PROCESS_MACHINE_ID:"
-                               HorizontalAlignment="Right"
-                               VerticalAlignment="Center" />
-                    <TextBox Grid.Row="18"
-                             Grid.Column="1"
-                             Text="{Binding DeviceInfo.MesSubmitUrl, Mode=TwoWay}"
-                             Margin="6" />
-
-                    <TextBlock Grid.Row="19"
-                               Grid.Column="0"
-                               Text="CTQ_UNIT_OF_MEASURE:"
-                               HorizontalAlignment="Right"
-                               VerticalAlignment="Center" />
-                    <TextBox Grid.Row="19"
-                             Grid.Column="1"
-                             Text="{Binding DeviceInfo.MesSubmitUrl, Mode=TwoWay}"
-                             Margin="6" />
-
-                    <StackPanel Orientation="Horizontal"
-                                HorizontalAlignment="Right"
-                                Grid.Row="20"
-                                Grid.ColumnSpan="2"
-                                Margin="6">
-                        <Button Style="{StaticResource MaterialDesignRaisedButton}"
-                                Command="{Binding SaveDeviceInfoCommand}">保存</Button>
-                    </StackPanel>
+                        <TextBlock Grid.Row="0"
+                                   Grid.Column="0"
+                                   Text="Url:"
+                                   HorizontalAlignment="Right"
+                                   VerticalAlignment="Center" />
+                        <TextBox Grid.Row="0"
+                                 Grid.Column="1"
+                                 Text="{Binding DeviceInfo.MesUrl, Mode=TwoWay}"
+                                 Margin="6" />
+                        
+                        <TextBlock Grid.Row="1"
+                                   Grid.Column="0"
+                                   Text="Line:"
+                                   HorizontalAlignment="Right"
+                                   VerticalAlignment="Center" />
+                        <TextBox Grid.Row="1"
+                                 Grid.Column="1"
+                                 Text="{Binding DeviceInfo.Line, Mode=TwoWay}"
+                                 Margin="6" />
+
+                        <TextBlock Grid.Row="2"
+                                   Grid.Column="0"
+                                   Text="Station:"
+                                   HorizontalAlignment="Right"
+                                   VerticalAlignment="Center" />
+                        <TextBox Grid.Row="2"
+                                 Grid.Column="1"
+                                 Text="{Binding DeviceInfo.Station, Mode=TwoWay}"
+                                 Margin="6" />
+
+                        <TextBlock Grid.Row="3"
+                                   Grid.Column="0"
+                                   Text="FixtureId:"
+                                   HorizontalAlignment="Right"
+                                   VerticalAlignment="Center" />
+                        <TextBox Grid.Row="3"
+                                 Grid.Column="1"
+                                 Text="{Binding DeviceInfo.FixtureId, Mode=TwoWay}"
+                                 Margin="6" />
+
+                        <TextBlock Grid.Row="4"
+                                   Grid.Column="0"
+                                   Text="f:"
+                                   HorizontalAlignment="Right"
+                                   VerticalAlignment="Center" />
+                        <TextBox Grid.Row="4"
+                                 Grid.Column="1"
+                                 Text="{Binding DeviceInfo.F, Mode=TwoWay}"
+                                 Margin="6" />
+
+                        <TextBlock Grid.Row="5"
+                                   Grid.Column="0"
+                                   Text="comp:"
+                                   HorizontalAlignment="Right"
+                                   VerticalAlignment="Center" />
+                        <TextBox Grid.Row="5"
+                                 Grid.Column="1"
+                                 Text="{Binding DeviceInfo.comp, Mode=TwoWay}"
+                                 Margin="6" />
+
+                        <TextBlock Grid.Row="6"
+                                   Grid.Column="0"
+                                   Text="启用 MES:"
+                                   HorizontalAlignment="Right"
+                                   VerticalAlignment="Center" />
+                        <CheckBox Grid.Row="6"
+                                  Grid.Column="1"
+                                  IsChecked="{Binding DeviceInfo.EnableMES, Mode=TwoWay}"
+                                  Margin="6" />
+                        
+                        <StackPanel Orientation="Horizontal"
+                                    HorizontalAlignment="Right"
+                                    Grid.Row="7"
+                                    Grid.ColumnSpan="2"
+                                    Margin="6">
+                            <Button Style="{StaticResource MaterialDesignRaisedButton}"
+                                    Command="{Binding SaveDeviceInfoCommand}">保存</Button>
+                        </StackPanel>
+                    </Grid>
+
+                    <Grid Margin="16"
+                          Grid.Row="1">
+                        <Grid.RowDefinitions>
+                            <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
+                        </Grid.RowDefinitions>
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition Width="auto" />
+                            <ColumnDefinition Width="*" />
+                        </Grid.ColumnDefinitions>
+
+                        <TextBlock Grid.Row="0"
+                                   Grid.Column="0"
+                                   Text="PROCESS_NAME:"
+                                   HorizontalAlignment="Right"
+                                   VerticalAlignment="Center" />
+                        <TextBox Grid.Row="0"
+                                 Grid.Column="1"
+                                 Text="{Binding DataInfo.PROCESS_NAME, Mode=TwoWay}"
+                                 Margin="6" />
+
+                        <TextBlock Grid.Row="1"
+                                   Grid.Column="0"
+                                   Text="CTQ_LSL(压力下限):"
+                                   HorizontalAlignment="Right"
+                                   VerticalAlignment="Center" />
+                        <TextBox Grid.Row="1"
+                                 Grid.Column="1"
+                                 Text="{Binding DataInfo.CTQ_LSL_Pressure, Mode=TwoWay}"
+                                 Margin="6" />
+
+                        <TextBlock Grid.Row="2"
+                                   Grid.Column="0"
+                                   Text="CTQ_USL(压力上限):"
+                                   HorizontalAlignment="Right"
+                                   VerticalAlignment="Center" />
+                        <TextBox Grid.Row="2"
+                                 Grid.Column="1"
+                                 Text="{Binding DataInfo.CTQ_USL_Pressure, Mode=TwoWay}"
+                                 Margin="6" />
+
+                        <TextBlock Grid.Row="3"
+                                   Grid.Column="0"
+                                   Text="SUPPLIER_NAME:"
+                                   HorizontalAlignment="Right"
+                                   VerticalAlignment="Center" />
+                        <TextBox Grid.Row="3"
+                                 Grid.Column="1"
+                                 Text="{Binding DataInfo.SUPPLIER_NAME, Mode=TwoWay}"
+                                 Margin="6" />
+
+                        <TextBlock Grid.Row="4"
+                                   Grid.Column="0"
+                                   Text="COMMODITY_TYPE:"
+                                   HorizontalAlignment="Right"
+                                   VerticalAlignment="Center" />
+                        <TextBox Grid.Row="4"
+                                 Grid.Column="1"
+                                 Text="{Binding DataInfo.COMMODITY_TYPE, Mode=TwoWay}"
+                                 Margin="6" />
+
+                        <TextBlock Grid.Row="5"
+                                   Grid.Column="0"
+                                   Text="REVISION:"
+                                   HorizontalAlignment="Right"
+                                   VerticalAlignment="Center" />
+                        <TextBox Grid.Row="5"
+                                 Grid.Column="1"
+                                 Text="{Binding DataInfo.REVISION, Mode=TwoWay}"
+                                 Margin="6" />
+
+                        <TextBlock Grid.Row="6"
+                                   Grid.Column="0"
+                                   Text="WO#:"
+                                   HorizontalAlignment="Right"
+                                   VerticalAlignment="Center" />
+                        <TextBox Grid.Row="6"
+                                 Grid.Column="1"
+                                 Text="{Binding DataInfo.WO, Mode=TwoWay}"
+                                 Margin="6" />
+
+                        <TextBlock Grid.Row="7"
+                                   Grid.Column="0"
+                                   Text="MFG_LOT#:"
+                                   HorizontalAlignment="Right"
+                                   VerticalAlignment="Center" />
+                        <TextBox Grid.Row="7"
+                                 Grid.Column="1"
+                                 Text="{Binding DataInfo.MFG_LOT, Mode=TwoWay}"
+                                 Margin="6" />
+
+                        <TextBlock Grid.Row="8"
+                                   Grid.Column="0"
+                                   Text="MFG_ASSY_LINE:"
+                                   HorizontalAlignment="Right"
+                                   VerticalAlignment="Center" />
+                        <TextBox Grid.Row="8"
+                                 Grid.Column="1"
+                                 Text="{Binding DataInfo.MFG_ASSY_LINE, Mode=TwoWay}"
+                                 Margin="6" />
+
+                        <TextBlock Grid.Row="9"
+                                   Grid.Column="0"
+                                   Text="PROCESS_MACHINE_ID:"
+                                   HorizontalAlignment="Right"
+                                   VerticalAlignment="Center" />
+                        <TextBox Grid.Row="9"
+                                 Grid.Column="1"
+                                 Text="{Binding DataInfo.PROCESS_MACHINE_ID, Mode=TwoWay}"
+                                 Margin="6" />
+
+                        <StackPanel Orientation="Horizontal"
+                                    HorizontalAlignment="Right"
+                                    Grid.Row="10"
+                                    Grid.ColumnSpan="2"
+                                    Margin="6">
+                            <Button Style="{StaticResource MaterialDesignRaisedButton}"
+                                    Command="{Binding SaveDataInfoCommand}">保存</Button>
+                        </StackPanel>
+                    </Grid>
                 </Grid>
             </TabItem>