Просмотр исходного кода

从TiN前移已解决bug:1.recipe手动Abort导致建表少Scheduler.CoolingRemainTime列
2.主界面执行sub recipe非table1时快速查看recipe没有跳转到正确的table
3.跨天但是间隔不满24小时数据查询时间段不对
4.触摸屏误触问题
5.UIWafer信息更新定时器内改成先获取wafer改动模块,根据改动module更新UI的wafer信息,降低通讯占用
6.禅道bug:.bug461 带table的recipe增加表同名检测,table1最少保留1步
修复bug460和444:recipe步次使用其他步override对象造成的引用bug

huangping месяцев назад: 5
Родитель
Сommit
5e0c17997b

+ 1 - 0
FrameworkLocal/Common/DataCenter/IQueryDataService.cs

@@ -145,6 +145,7 @@ namespace MECF.Framework.Common.DataCenter
     [ServiceKnownType(typeof(List<RecipeFileNode>))]
     [ServiceKnownType(typeof(Dictionary<string, List<string>>))]
     [ServiceKnownType(typeof(Dictionary<string, Dictionary<string, string>>))]
+    [ServiceKnownType(typeof(Dictionary<string, bool>))]
 
     public interface IQueryDataService
     {

+ 47 - 13
FrameworkLocal/Common/SubstrateTrackings/WaferManager.cs

@@ -5,6 +5,7 @@ using Aitex.Core.Common;
 using Aitex.Core.RT.DataCenter;
 using Aitex.Core.RT.Event;
 using Aitex.Core.RT.Log;
+using Aitex.Core.RT.OperationCenter;
 using Aitex.Core.Util;
 using FabConnect.SecsGemInterface.Common;
 using MECF.Framework.Common.DataCenter;
@@ -67,6 +68,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
 
         private PeriodicJob _thread;
         private bool _needSerialize;
+        public Dictionary<string, bool> NeedUpdateModule = new Dictionary<string, bool>();
 
         public WaferManager()
         {
@@ -140,9 +142,19 @@ namespace MECF.Framework.Common.SubstrateTrackings
             //EV.Subscribe(new EventItem("Event", Event_STS_Unoccupied, "Substrate location state is Unoccupied."));
             //EV.Subscribe(new EventItem("Event", Event_STS_Occupied, "Substrate location state is occupied."));
 
-
-
-
+            DATA.Subscribe("System.ChangeWafers", () => NeedUpdateModule);
+            OP.Subscribe("System.UpdateWafersNotify", (string cmd, object[] args) =>
+            {
+                if (args.Length > 0 && args[0] is Dictionary<string, bool> updateModules)
+                {
+                    foreach (var module in updateModules.Keys)
+                    {
+                        if (NeedUpdateModule.ContainsKey(module)) NeedUpdateModule[module] = false;
+                    }
+                    return true;
+                }
+                return false;
+            });
             Deserialize();
             _thread = new PeriodicJob(1000, Serialize, $"SerializeMonitorHandler", true);
         }
@@ -172,6 +184,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
             }
 
             DATA.Subscribe(module.ToString(), "ModuleWaferList", () => _locationWafers[module].Values.ToArray());
+            NeedUpdateModule[module.ToString()] = true;
         }
 
         public void WaferMoved(ModuleName moduleFrom, int slotFrom, ModuleName moduleTo, int slotTo, bool needHistory = true)
@@ -247,7 +260,8 @@ namespace MECF.Framework.Common.SubstrateTrackings
 
             if (needHistory)
                 EV.PostInfoLog("System", $"Wafer:{wafer.WaferID} moved from {moduleFrom} slot:{slotFrom + 1} to {moduleTo} slot:{slotTo + 1}.");
-
+            NeedUpdateModule[moduleFrom.ToString()] = true;
+            NeedUpdateModule[moduleTo.ToString()] = true;
             //Serialize();
             _needSerialize = true;
         }
@@ -328,7 +342,8 @@ namespace MECF.Framework.Common.SubstrateTrackings
 
             UpdateWaferProcessStatus(moduleFrom, slotFrom, EnumWaferProcessStatus.Failed);
             UpdateWaferProcessStatus(moduleTo, slotTo, EnumWaferProcessStatus.Failed);
-
+            NeedUpdateModule[moduleFrom.ToString()] = true;
+            NeedUpdateModule[moduleTo.ToString()] = true;
             //Serialize();
             _needSerialize = true;
         }
@@ -610,7 +625,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
 
 
             WaferDataRecorder.CreateWafer(_locationWafers[module][slot].InnerId.ToString(), carrierInnerId, module.ToString(), slot, _locationWafers[module][slot].WaferID, _locationWafers[module][slot].ProcessState.ToString());
-
+            NeedUpdateModule[module.ToString()] = true;
             //Serialize();
             _needSerialize = true;
             EV.PostInfoLog("System", $"Create wafer successfully on {module} slot:{slot + 1}.");
@@ -694,6 +709,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
 
             //Serialize();
             _needSerialize = true;
+            NeedUpdateModule[module.ToString()] = true;
             EV.PostInfoLog("System", $"Create wafer successfully on {module} slot:{slot + 1}.");
             return _locationWafers[module][slot];
         }
@@ -763,7 +779,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
 
             //Serialize();
             _needSerialize = true;
-
+            NeedUpdateModule[module.ToString()] = true;
             return _locationWafers[module][slot];
         }
 
@@ -797,7 +813,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
                     _dict.Remove(_locationWafers[module][slot].WaferID);
                 }
             }
-
+            NeedUpdateModule[module.ToString()] = true;
             //Serialize();
             _needSerialize = true;
         }
@@ -834,6 +850,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
 
             //Serialize();
             _needSerialize = true;
+            NeedUpdateModule[module.ToString()] = true;
         }
 
         public void ManualDeleteWafer(ModuleName module, int slotFrom, int count = 1)
@@ -870,6 +887,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
 
             //Serialize();
             _needSerialize = true;
+            NeedUpdateModule[module.ToString()] = true;
         }
 
 
@@ -889,6 +907,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
 
             //Serialize();
             _needSerialize = true;
+            NeedUpdateModule[module.ToString()] = true;
         }
 
         public void UpdateWaferDestination(ModuleName module, int slot, string destCarrierID, int destslot)
@@ -909,6 +928,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
 
             //Serialize();
             _needSerialize = true;
+            NeedUpdateModule[module.ToString()] = true;
         }
 
         public void UpdateWaferDestination(ModuleName module, int slot, ModuleName destmodule, int destslot)
@@ -929,6 +949,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
 
             //Serialize();
             _needSerialize = true;
+            NeedUpdateModule[module.ToString()] = true;
         }
 
 
@@ -951,6 +972,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
 
             //Serialize();
             _needSerialize = true;
+            NeedUpdateModule[module.ToString()] = true;
         }
 
         public void UpdateWaferT7Code(ModuleName module, int slot, string T7Code)
@@ -968,6 +990,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
             }
             //Serialize();
             _needSerialize = true;
+            NeedUpdateModule[module.ToString()] = true;
         }
 
         public void UpdataWaferPPID(ModuleName module, int slot, string PPID)
@@ -985,6 +1008,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
             }
             //Serialize();
             _needSerialize = true;
+            NeedUpdateModule[module.ToString()] = true;
         }
 
         public void UpdateWaferT7CodeWithScoreAndFileName(ModuleName module, int slot, string t7Code, string t7CodeScore, string fileName, string filePath)
@@ -1005,6 +1029,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
             }
             //Serialize();
             _needSerialize = true;
+            NeedUpdateModule[module.ToString()] = true;
         }
 
         public void UpdateWaferTransFlag(ModuleName module, int slot, string flag)
@@ -1021,6 +1046,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
             }
             //Serialize();
             _needSerialize = true;
+            NeedUpdateModule[module.ToString()] = true;
         }
 
         public void UpdateWaferNotch(ModuleName module, int slot, int angle)
@@ -1036,6 +1062,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
             }
             //Serialize();
             _needSerialize = true;
+            NeedUpdateModule[module.ToString()] = true;
         }
         public List<WaferInfo> GetAllWafers()
         {
@@ -1072,6 +1099,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
 
             }
             _needSerialize = true;
+            NeedUpdateModule[module.ToString()] = true;
         }
 
         public void UpdateWaferInfo(ModuleName module, int slot, float thick)
@@ -1086,6 +1114,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
                 _locationWafers[module][slot].Thick = thick;
             }
             _needSerialize = true;
+            NeedUpdateModule[module.ToString()] = true;
         }
         public void UpdateWaferProcessStatus(ModuleName module, int slot, EnumWaferProcessStatus status)
         {
@@ -1103,6 +1132,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
             }
             //Serialize();
             _needSerialize = true;
+            NeedUpdateModule[module.ToString()] = true;
         }
 
         public void UpdateWaferProcessStatus(ModuleName module, int slot, EnumWaferProcessStatus processStatus, WaferStatus waferStatus)
@@ -1121,6 +1151,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
                 WaferDataRecorder.SetWaferStatus(_locationWafers[module][slot].InnerId.ToString(), processStatus.ToString());
             }
             _needSerialize = true;
+            NeedUpdateModule[module.ToString()] = true;
         }
 #pragma warning disable CS0618  
         public void UpdateWaferProcessStatus(ModuleName module, int slot, ProcessStatus status)
@@ -1187,6 +1218,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
             UpdateWaferHistory(module, slot, SubstAccessType.UpdateWaferID);
             //Serialize();
             _needSerialize = true;
+            NeedUpdateModule[module.ToString()] = true;
         }
 
         public void UpdateWaferJodID(ModuleName module, int slot, string pjID, string cjID)
@@ -1204,6 +1236,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
             }
             //Serialize();
             _needSerialize = true;
+            NeedUpdateModule[module.ToString()] = true;
         }
 
         public void SlotMapVerifyOK(ModuleName module)
@@ -1260,8 +1293,6 @@ namespace MECF.Framework.Common.SubstrateTrackings
             }
             //Serialize();
             _needSerialize = true;
-            //Serialize();
-            _needSerialize = true;
         }
 
 
@@ -1329,7 +1360,6 @@ namespace MECF.Framework.Common.SubstrateTrackings
             }
             //Serialize();
             _needSerialize = true;
-
         }
 
         public void UpdateWaferE90State(ModuleName module, int slot, EnumE90Status E90state)
@@ -1378,7 +1408,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
             }
             //Serialize();
             _needSerialize = true;
-
+            NeedUpdateModule[module.ToString()] = true;
         }
 
         public void UpdateWaferHistory(ModuleName module, int slot, SubstAccessType accesstype)
@@ -1404,6 +1434,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
             }
             //Serialize();
             _needSerialize = true;
+            NeedUpdateModule[module.ToString()] = true;
         }
 
 
@@ -1423,6 +1454,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
             }
             //Serialize();
             _needSerialize = true;
+            NeedUpdateModule[module.ToString()] = true;
         }
         public void UpdateWaferHostLM1(ModuleName module, int slot, string lasermark1)
         {
@@ -1438,6 +1470,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
             }
             //Serialize();
             _needSerialize = true;
+            NeedUpdateModule[module.ToString()] = true;
         }
         public void UpdateWaferHostLM2(ModuleName module, int slot, string lasermark2)
         {
@@ -1453,6 +1486,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
             }
             //Serialize();
             _needSerialize = true;
+            NeedUpdateModule[module.ToString()] = true;
         }
         public void UpdateWaferProcessStatus(string waferID, EnumWaferProcessStatus status)
         {
@@ -1543,7 +1577,7 @@ namespace MECF.Framework.Common.SubstrateTrackings
             }
 
             _needSerialize = true;
-
+            NeedUpdateModule[module.ToString()] = true;
             Serialize();
             return true;
         }

+ 0 - 22
FrameworkLocal/UIClient/CenterViews/DataLogs/DataHistory/DataViewModel.cs

@@ -309,28 +309,6 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.DataHistory
             }
         }
 
-        public void ToLeftClick(int index)
-        {
-            var view = GetView() as DataView;
-            index += 1;//从0开始
-            if ((index & 0x01) == 1)
-                view.chart.sciChart.ChartModifier.XAxis.Scroll(50, SciChart.Charting.ClipMode.ClipAtMin);
-            if ((index & 0x02) == 2)
-            {
-                view.chart.sciChart.ChartModifier.YAxis.Scroll(50, SciChart.Charting.ClipMode.ClipAtMin);
-            }
-        }
-
-        public void ToRightClick(int index)
-        {
-            var view = GetView() as DataView;
-            index += 1;
-            if ((index & 0x01) == 1)
-                view.chart.sciChart.ChartModifier.XAxis.Scroll(-50, SciChart.Charting.ClipMode.ClipAtMax);
-            if ((index & 0x02) == 2)
-                view.chart.sciChart.ChartModifier.YAxis.Scroll(-50, SciChart.Charting.ClipMode.ClipAtMax);
-        }
-
         public void ZoomInClick(int index)
         {
             var view = GetView() as DataView;

+ 9 - 56
FrameworkLocal/UIClient/CenterViews/DataLogs/ProcessHistory/ProcessDetailViewModel.cs

@@ -34,7 +34,6 @@ using System.Windows.Controls;
 using SciChart.Charting.Model.ChartData;
 using MECF.Framework.UI.Client.Converter;
 using MECF.Framework.UI.Client.CenterViews.Operations.RealTime;
-using DocumentFormat.OpenXml.Office2016.Drawing.ChartDrawing;
 
 namespace MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory
 {
@@ -107,10 +106,11 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory
             get { return _ParameterNodes; }
             set { _ParameterNodes = value; NotifyOfPropertyChange("ParameterNodes"); }
         }
+        public List<ParameterNode> DoubleParameterNodes { get; set; } = new List<ParameterNode>();
+
 
         public ObservableCollection<IRenderableSeries> SelectedData { get; set; }
         public ObservableCollection<IRenderableSeries> SynSelectedData { get; set; }
-        public List<ParameterNode> DoubleParameterNodes { get; set; } = new List<ParameterNode>();
 
         public List<ProcessHistoryLot> RecipeDatas { get; set; }
 
@@ -294,6 +294,12 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory
             DisplayName = "Process Detail";
             RecipeDatas = recipes;
             ParameterNodes = _realtimeProvider.GetParameters(out var dict);
+            DoubleParameterNodes = _realtimeProvider.GetParameters(out dict).ToList();
+            for (int j = 0; j < ParameterNodes.Count; j++)
+            {
+                ParameterNodes[j].IsVisibilityParentNode = Visibility.Hidden;
+                DoubleParameterNodes[j].IsVisibilityParentNode = Visibility.Hidden;
+            }
             _processDetailDisplayDic = dict;
             if (recipes == null || recipes.Count == 0)
             {
@@ -302,12 +308,7 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory
             SelectedData = new ObservableCollection<IRenderableSeries>();
             SynSelectedData = new ObservableCollection<IRenderableSeries>();
             VisibleRangeValue = new DoubleRange(0, 10);
-            DoubleParameterNodes = _realtimeProvider.GetParameters(out dict).ToList();
-            for (int j = 0; j < ParameterNodes.Count; j++)
-            {
-                ParameterNodes[j].IsVisibilityParentNode = Visibility.Hidden;
-                DoubleParameterNodes[j].IsVisibilityParentNode = Visibility.Hidden;
-            }
+
             // Annotations = new AnnotationCollection();
             _thread = new PeriodicJob(200, MonitorData, "ProcessDetail", true);
             try
@@ -459,7 +460,6 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory
                 if (_isAdding)
                     return true;
                 bool allUpdated = true;
-         
                 lock (_lockSelection)
                 {
                     foreach (var item in _lstTokenTimeData)
@@ -883,7 +883,6 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory
 
                     SelectedData.Remove(cp);
                 }
-                if (SynSelectedData.Contains(cp)) { SynSelectedData.Remove(cp); }
             }
         }
 
@@ -1263,50 +1262,6 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory
                     break;
             }
         }
-        public void BackPan()//前移
-        {
-            if ((_directionByte & 0x01) == 1)//x
-            {
-                // LOG.Info($"A BackPan.X:scale{XScale},{VisibleRangeTime.Min}:{VisibleRangeTime.Max}");
-                if (VisibleRangeTime is DoubleRange range)
-                {
-                    VisibleRangeTime = new DoubleRange(range.Min - XScale, range.Max - XScale);
-                    // LOG.Info($"BackPan.X:scale{XScale},{VisibleRangeTime.Min}:{VisibleRangeTime.Max}");
-                }
-            }
-            if ((_directionByte & 0x02) == 2)
-            {
-                // LOG.Info($"A BackPan.Y:scale{YScale},{VisibleRangeValue.Min}:{VisibleRangeValue.Max}");
-                if (VisibleRangeValue is DoubleRange range)
-                {
-                    VisibleRangeValue = new DoubleRange(range.Min - YScale, range.Max - YScale);
-                    //LOG.Info($"BackPan.Y:scale{YScale},{VisibleRangeValue.Min}:{VisibleRangeValue.Max}");
-                }
-            }
-        }
-
-        public void ForwardPan()//后移
-        {
-            if ((_directionByte & 0x01) == 1)//x
-            {
-                // LOG.Info($"A ForwardPan.X:scale{XScale},{VisibleRangeTime.Min}:{VisibleRangeTime.Max}");
-                if (VisibleRangeTime is DoubleRange range)
-                {
-                    VisibleRangeTime = new DoubleRange(range.Min + XScale, range.Max + XScale);
-                    // LOG.Info($"ForwardPan.X:scale{XScale},{VisibleRangeTime.Min}:{VisibleRangeTime.Max}");
-                }
-            }
-            if ((_directionByte & 0x02) == 2)
-            {
-                //LOG.Info($"A ForwardPan.Y:scale{YScale},{VisibleRangeValue.Min}:{VisibleRangeValue.Max}");
-                if (VisibleRangeValue is DoubleRange range)
-                {
-                    VisibleRangeValue = new DoubleRange(range.Min + YScale, range.Max + YScale);
-                    //LOG.Info($"ForwardPan.Y:scale{YScale},{VisibleRangeValue.Min}:{VisibleRangeValue.Max}");
-                }
-            }
-        }
-
         public void ZoomInClick()//放大
         {
             double scale = 0;
@@ -1401,7 +1356,6 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory
                 });
 
                 allCheckNode.ForEach(x => { ParameterCheck(x, SelectedData); });
-
             }
         }
 
@@ -1472,7 +1426,6 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory
             }
         }
     }
-
     public class ProcessDataLot : NotifiableItem
     {
         private string _guid;

+ 17 - 15
FrameworkLocal/UIClient/CenterViews/Editors/Recipe/RecipeDataBase.cs

@@ -281,7 +281,7 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
         }
 
 
-        public string TableName => Tables.Count > 0 ? Tables.FirstOrDefault(x => x.Index == TableIndex).Name : "";
+        public string TableName => Tables?.FirstOrDefault(x => x.Index == TableIndex)?.Name ?? "";
 
         private DateTime deviseTime;
         public DateTime ReviseTime
@@ -320,19 +320,21 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
         public void ShallowCopyStep(ref Step destinationStep, Step originalStep)
         {
             int stepNo = destinationStep.StepNo;
-            Type type = originalStep.GetType();
-            PropertyInfo[] properties = type.GetProperties();
-            // 遍历属性并赋值
-            foreach (PropertyInfo property in properties)
-            {
-                // 判断属性是否可写
-                if (property.CanWrite)
-                {
-                    // 设置属性的值
-                    property.SetValue(destinationStep, property.GetValue(originalStep));
-                }
-            }
+            //Type type = originalStep.GetType();
+            //PropertyInfo[] properties = type.GetProperties();
+            //// 遍历属性并赋值
+            //foreach (PropertyInfo property in properties)
+            //{
+            //    // 判断属性是否可写
+            //    if (property.CanWrite)
+            //    {
+            //        // 设置属性的值
+            //        property.SetValue(destinationStep, property.GetValue(originalStep));
+            //    }
+            //}
+            originalStep.Adapt(destinationStep);
             destinationStep.StepNo = stepNo;
+            SetDelegateEvent(destinationStep);
         }
         public void CloneStep(ref Step destinationStep, Step originalStep)
         {
@@ -829,8 +831,8 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
                 {
                     Steps.Clear();
                     StepNos.Clear();
-                    TableIndex = 1;
-                    Tables[0].TableData.Steps.ToList().ForEach(
+                    TableIndex = tableNo;
+                    Tables[tableNo - 1].TableData.Steps.ToList().ForEach(
                         x =>
                         {
                             var tempStep = x;// (Step)CloneUtil.CloneObject(x);

+ 55 - 47
FrameworkLocal/UIClient/ClientBase/ModuleDataMonitor.cs

@@ -8,8 +8,9 @@ using System.Windows.Threading;
 using Aitex.Core.RT.Log;
 using Aitex.Core.Util;
 using MECF.Framework.Common.DataCenter;
+using MECF.Framework.Common.OperationCenter;
 using RTDefine = Aitex.Core.Common;
- 
+
 namespace MECF.Framework.UI.Client.ClientBase
 {
     public class ModuleDataMonitor
@@ -38,61 +39,68 @@ namespace MECF.Framework.UI.Client.ClientBase
         {
             try
             {
-                Dictionary<string, object> data  = QueryDataClient.Instance.Service.PollData(_lstWaferDataName);
-
-                if (data != null && Application.Current != null)
+                var changeModule = QueryDataClient.Instance.Service.GetData("System.ChangeWafers");
+                if (changeModule is Dictionary<string, bool> module && module?.Count > 0)
                 {
-                    Application.Current.Dispatcher.Invoke(new Action(() =>
+                    var changedModule = module.Where(r => r.Value);
+                    if (!changedModule.Any()) return true;
+                    InvokeClient.Instance.Service.DoOperation("System.UpdateWafersNotify", changeModule);
+                    Dictionary<string, object> data = QueryDataClient.Instance.Service.PollData(changedModule.Select(r => $"{r.Key}.ModuleWaferList"));
+
+                    if (data != null && Application.Current != null)
                     {
-                        foreach (var waferData in data)
+                        Application.Current.Dispatcher.Invoke(new Action(() =>
                         {
-                            if (!_mapWaferDataModule.ContainsKey(waferData.Key))
-                                continue;
+                            foreach (var waferData in data)
+                            {
+                                if (!_mapWaferDataModule.ContainsKey(waferData.Key))
+                                    continue;
 
-                            RTDefine.WaferInfo[] wafers = waferData.Value as RTDefine.WaferInfo[];
-                            if (wafers == null)
-                                continue;
+                                RTDefine.WaferInfo[] wafers = waferData.Value as RTDefine.WaferInfo[];
+                                if (wafers == null)
+                                    continue;
 
-                            ModuleInfo info = _mapWaferDataModule[waferData.Key];
-                            if (info.WaferManager.Wafers.Count == 0)
-                            {
-                                for (int i = 0; i < wafers.Length; i++)
+                                ModuleInfo info = _mapWaferDataModule[waferData.Key];
+                                if (info.WaferManager.Wafers.Count == 0)
                                 {
-                                    info.WaferManager.Wafers.Add(WaferInfoConverter(wafers[i], info.WaferModuleID, i));
-                                }
+                                    for (int i = 0; i < wafers.Length; i++)
+                                    {
+                                        info.WaferManager.Wafers.Add(WaferInfoConverter(wafers[i], info.WaferModuleID, i));
+                                    }
 
-                                if (info.IsWaferReverseDisplay)
-                                {
-                                     info.WaferManager.Wafers = new ObservableCollection<WaferInfo>(info.WaferManager.Wafers.Reverse());
+                                    if (info.IsWaferReverseDisplay)
+                                    {
+                                        info.WaferManager.Wafers = new ObservableCollection<WaferInfo>(info.WaferManager.Wafers.Reverse());
+                                    }
+                                    continue;
                                 }
-                                continue;
-                            }
 
-                            if (wafers.Length == info.WaferManager.Wafers.Count)
-                            {
-                                int index;
-                                for (int i = 0; i < wafers.Length; i++)
+                                if (wafers.Length == info.WaferManager.Wafers.Count)
                                 {
-                                    if (info.IsWaferReverseDisplay)
-                                        index = wafers.Length - i - 1;
-                                    else
-                                        index = i;
-
-                                    var convertedWafer = WaferInfoConverter(wafers[index], info.WaferModuleID, index);
-                                    info.WaferManager.Wafers[i].WaferStatus = convertedWafer.WaferStatus;
-                                    info.WaferManager.Wafers[i].WaferID = convertedWafer.WaferID;
-                                    info.WaferManager.Wafers[i].SourceName = convertedWafer.SourceName;
-                                    info.WaferManager.Wafers[i].WaferType = convertedWafer.WaferType;
-                                    info.WaferManager.Wafers[i].UseCount = convertedWafer.UseCount;
-                                    info.WaferManager.Wafers[i].UseTime = convertedWafer.UseTime;
-                                    info.WaferManager.Wafers[i].UseThick = convertedWafer.UseThick;
-                                    info.WaferManager.Wafers[i].Thick = convertedWafer.Thick;
-                                    info.WaferManager.Wafers[i].LotId = convertedWafer.LotId;
-                                    info.WaferManager.Wafers[i].ProcessJobID = convertedWafer.ProcessJobID;
+                                    int index;
+                                    for (int i = 0; i < wafers.Length; i++)
+                                    {
+                                        if (info.IsWaferReverseDisplay)
+                                            index = wafers.Length - i - 1;
+                                        else
+                                            index = i;
+
+                                        var convertedWafer = WaferInfoConverter(wafers[index], info.WaferModuleID, index);
+                                        info.WaferManager.Wafers[i].WaferStatus = convertedWafer.WaferStatus;
+                                        info.WaferManager.Wafers[i].WaferID = convertedWafer.WaferID;
+                                        info.WaferManager.Wafers[i].SourceName = convertedWafer.SourceName;
+                                        info.WaferManager.Wafers[i].WaferType = convertedWafer.WaferType;
+                                        info.WaferManager.Wafers[i].UseCount = convertedWafer.UseCount;
+                                        info.WaferManager.Wafers[i].UseTime = convertedWafer.UseTime;
+                                        info.WaferManager.Wafers[i].UseThick = convertedWafer.UseThick;
+                                        info.WaferManager.Wafers[i].Thick = convertedWafer.Thick;
+                                        info.WaferManager.Wafers[i].LotId = convertedWafer.LotId;
+                                        info.WaferManager.Wafers[i].ProcessJobID = convertedWafer.ProcessJobID;
+                                    }
                                 }
                             }
-                        }
-                    }));
+                        }));
+                    }
                 }
             }
             catch (Exception ex)
@@ -144,7 +152,7 @@ namespace MECF.Framework.UI.Client.ClientBase
                 switch (awafer.ProcessState)
                 {
                     case RTDefine.EnumWaferProcessStatus.InProcess: return 3;
-                    case RTDefine.EnumWaferProcessStatus.Completed: return awafer.HasError ? 5 :(awafer.HasWarning?7:4);
+                    case RTDefine.EnumWaferProcessStatus.Completed: return awafer.HasError ? 5 : (awafer.HasWarning ? 7 : 4);
                     case RTDefine.EnumWaferProcessStatus.Failed: return 5;
                     case RTDefine.EnumWaferProcessStatus.Wait: return 3;
                     case RTDefine.EnumWaferProcessStatus.Idle: return awafer.ProcessJob == null ? 1 : 2;
@@ -159,7 +167,7 @@ namespace MECF.Framework.UI.Client.ClientBase
 
             return 5;
         }
- 
+
     }
- 
+
 }

+ 2 - 1
Furnace/FurnaceRT/Equipments/Jobs/AutoTransfer.cs

@@ -152,7 +152,7 @@ namespace FurnaceRT.Equipments.Jobs
 
                 var coolTime = pj != null ? pj.CoolTimeSec : 0;
                 if (_coolTimer.IsRunning)
-                    return (coolTime - _coolTimer.ElapsedMilliseconds / 1000) > 0 ? coolTime - _coolTimer.ElapsedMilliseconds / 1000 : 0;
+                    return (coolTime - _coolTimer.ElapsedMilliseconds / 1000) > 0 ? Convert.ToInt32(coolTime - _coolTimer.ElapsedMilliseconds / 1000) : 0;
                 return coolTime;
             });
             DATA.Subscribe($"Scheduler.StockerUseSlots", () =>
@@ -801,6 +801,7 @@ namespace FurnaceRT.Equipments.Jobs
                     JobDataRecorder.EndPJ(pj.InnerId.ToString(), aborted, unprocessed);
                 }
             }
+            if (_coolTimer.IsRunning) _coolTimer.Stop();
             Singleton<FAJobController>.Instance.FAProcessJobs[jobName].RequestAbort();
             foreach (var pj in pjAbortList)
             {

+ 1 - 0
Furnace/FurnaceRT/Equipments/PMs/PMModule.cs

@@ -315,6 +315,7 @@ namespace FurnaceRT.Equipments.PMs
             DATA.Subscribe($"{Name}.SelectedRecipeName", () => _recipeRunningInfo.RecipeName);
 
             DATA.Subscribe($"{Name}.ProcessSubRecipe", () => _recipeRunningInfo.SubRecipeName);
+            DATA.Subscribe($"{Name}.ProcessSubRecipeTable", () => _recipeRunningInfo.SubRecipeTable);
             DATA.Subscribe($"{Name}.ProcessAbortRecipe", () => _recipeRunningInfo.AbortRecipeName);
 
             DATA.Subscribe($"{Name}.AbortRecipeName", () => _recipeRunningInfo.RecipeName);

+ 3 - 0
Furnace/FurnaceRT/Equipments/PMs/RecipeExecutions/Process.cs

@@ -339,12 +339,14 @@ namespace FurnaceRT.Equipments.PMs.RecipeExecutions
                 {
                     PMModule.RecipeRunningInfo.SubRecipeCurrentLoopCount = 1;
                     PMModule.RecipeRunningInfo.SubRecipeLoopCount = PMModule.RecipeRunningInfo.RecipeStepList[_currentStepNumber].SubRecipeLoopCount;
+                    PMModule.RecipeRunningInfo.SubRecipeTable = PMModule.RecipeRunningInfo.RecipeStepList[_currentStepNumber].SubRecipeTableInfo;
                 }
                 PMModule.RecipeRunningInfo.RecipeStepList[_currentStepNumber].IsCallSubStep = false;
                 IsSubReciep = true;
             }
             else
             {
+                PMModule.RecipeRunningInfo.SubRecipeTable = string.Empty;
                 curSteps = PMModule.RecipeRunningInfo.RecipeStepList;
                 PMModule.RecipeRunningInfo.SubRecipeLoopCount = 0;
             }
@@ -862,6 +864,7 @@ namespace FurnaceRT.Equipments.PMs.RecipeExecutions
                     PMModule.RecipeRunningInfo.ExecRecipeType = PMModule.RecipeRunningInfo.RecipeStepList[_currentStepNumber].SubRecipeSteps[_currentSubRecipeStepNumber].RecipeType;
                     PMModule.RecipeRunningInfo.SubRecipeCurrentLoopCount = PMModule.RecipeRunningInfo.SubRecipeLoopCount - PMModule.RecipeRunningInfo.RecipeStepList[_currentStepNumber].SubRecipeLoopCount + 1;
                     PMModule.RecipeRunningInfo.SubRecipeName = PMModule.RecipeRunningInfo.Head.SubRecipe;
+                    PMModule.RecipeRunningInfo.SubRecipeTable = PMModule.RecipeRunningInfo.RecipeStepList[_currentStepNumber].SubRecipeTableInfo;
 
                     step = _currentSubRecipeStepNumber;
                     if (_state == RecipeRunningState.Paused)

+ 2 - 0
Furnace/FurnaceRT/Equipments/PMs/RecipeExecutions/RecipeRunningInfo.cs

@@ -43,6 +43,8 @@ namespace FurnaceRT.Equipments.PMs.RecipeExecutions
         public int SubRecipeLoopCount { get; set; }
         public int SubRecipeCurrentLoopCount { get; set; }
         public string SubRecipeName { get; set; }
+        public string SubRecipeTable { get; set; }
+
         public string AbortRecipeName { get; set; }
 
         public bool IsLooping { get; set; }

+ 3 - 0
Furnace/FurnaceUI/App.config

@@ -78,4 +78,7 @@
       </providers>
     </roleManager>
   </system.web>
+	<runtime>
+		<AppContextSwitchOverrides value="Switch.System.Windows.Input.Stylus.DisableStylusAndTouchSupport=true" />
+	</runtime>
 </configuration>

+ 10 - 3
Furnace/FurnaceUI/Views/Operations/StatusViewModel.cs

@@ -611,7 +611,7 @@ namespace FurnaceUI.Views.Operations
                 return $"{PM1ExecRecipeType} : {PM1LoopCountCurrent} / {PM1LoopCountSet}";
             }
         }
-       
+
         [Subscription("PM1.SubRecipeCurrentLoopCount")]
         public int PM1SubRecipeCurrentLoopCount { get; set; }
         [Subscription("PM1.ProcessSubRecipe")]
@@ -622,6 +622,8 @@ namespace FurnaceUI.Views.Operations
         public int PM1SubRecipeLoopCount { get; set; }
         [Subscription("PM1.IsExecuteSubRecipe")]
         public bool PM1IsExecuteSubRecipe { get; set; }
+        [Subscription("PM1.ProcessSubRecipeTable")]
+        public string PM1SubTable { get; set; }
         public string SubInfo
         {
             get
@@ -1582,8 +1584,13 @@ namespace FurnaceUI.Views.Operations
                         {
                             viewProcessRecipeRecipeType = PM1ExecRecipeType.ToLower();
                         }
-
-                        var viewProcessRecipe = new RecipeProcessEditViewModel($"Furnace\\{viewProcessRecipeRecipeType}", recipeName);
+                        int tableIndex = 1;
+                        var table = PM1SubTable.Split(':');
+                        if (table.Length < 0 || !int.TryParse(table[0], out tableIndex))
+                        {
+                            tableIndex = 1;
+                        }
+                        var viewProcessRecipe = new RecipeProcessEditViewModel($"Furnace\\{viewProcessRecipeRecipeType}", recipeName, tableIndex: tableIndex);
                         viewProcessRecipe.RecipeType = viewProcessRecipeRecipeType;
                         viewProcessRecipe.IndexNoDefault = PM1RecipeStepNumber;
                         viewProcessRecipe.SelectedStepName = PM1RecipeStepName;

+ 0 - 1
Furnace/FurnaceUI/Views/Recipes/RecipeProcessEditView.xaml

@@ -1331,7 +1331,6 @@
                                                     <i:Interaction.Triggers>
                                                         <i:EventTrigger EventName="PreviewMouseLeftButtonDown">
                                                             <cal:ActionMessage MethodName="SelectStep">
-                                                                <cal:Parameter Value="$source"></cal:Parameter>
                                                                 <cal:Parameter Value="{Binding}"></cal:Parameter>
                                                             </cal:ActionMessage>
                                                         </i:EventTrigger>

+ 9 - 23
Furnace/FurnaceUI/Views/Recipes/RecipeProcessEditViewModel.cs

@@ -10,6 +10,7 @@ using FurnaceUI.Common;
 using FurnaceUI.Models;
 using FurnaceUI.Views.Editors;
 using FurnaceUI.Views.Parameter;
+using Mapster;
 using MECF.Framework.Common.Communications;
 using MECF.Framework.Common.DataCenter;
 using MECF.Framework.Common.OperationCenter;
@@ -1226,10 +1227,10 @@ namespace FurnaceUI.Views.Recipes
         public string RecipeType { get; set; }
 
         private RecipeProcessEditView view1;
+        private int _tableIndex;
 
-        public RecipeProcessEditViewModel(string strPrefixPath, string strRecipeName, string permission = "")
+        public RecipeProcessEditViewModel(string strPrefixPath, string strRecipeName, string permission = "", int tableIndex = 1)
         {
-
             PumpDict.Clear();
             PumpDict.Add("DPR", "ValveAV91");
             PumpDict.Add("AGV", "AGVPump");
@@ -1247,6 +1248,7 @@ namespace FurnaceUI.Views.Recipes
             CurrentRecipe.PrefixPath = strPrefixPath;
             CurrentRecipe.Name = strRecipeName;
             CurrentRecipe.RecipePermission = permission;
+            _tableIndex = tableIndex;
         }
         protected override void OnViewLoaded(object view)
         {
@@ -1299,7 +1301,7 @@ namespace FurnaceUI.Views.Recipes
                 return;
             }
             //     CurrentRecipe.RecipeChamberType = "OriginChamber";
-            CurrentRecipe.InitData(CurrentRecipe.PrefixPath, CurrentRecipe.Name, recipeContent, "PM1");
+            CurrentRecipe.InitData(CurrentRecipe.PrefixPath, CurrentRecipe.Name, recipeContent, "PM1", _tableIndex);
             if (CurrentRecipe.Steps.Count > 0)
             {
                 if (!string.IsNullOrEmpty(SelectedStepName))
@@ -1350,16 +1352,6 @@ namespace FurnaceUI.Views.Recipes
         private Dictionary<string, string> PumpDict = new Dictionary<string, string>();
         private Dictionary<string, string> OtherPumpDict = new Dictionary<string, string>();
 
-        public void SelectStep(object sender, object step)
-        {
-            var textBox = sender as UIElement;
-            if (textBox != null)
-            {
-                Keyboard.Focus(textBox);
-            }
-            SelectStep(step);
-        }
-
         public void SelectStep(object step)
         {
             if (step == null || !(step is Step))
@@ -2224,7 +2216,7 @@ namespace FurnaceUI.Views.Recipes
                 case "PressureWait":
                     RecipePressureWaitViewModel recipePressureWaitViewModel = new RecipePressureWaitViewModel();
                     tempStep = CurrentRecipe.Steps.Where(x => x.StepNo == SelectedRecipeStep.StepNo).FirstOrDefault();
-                    var destinationStep = (Step)CloneUtil.CloneObject(tempStep);
+                    var destinationStep = tempStep.Adapt<Step>();
                     destinationStep.StepNo = tempStep.StepNo;
                     destinationStep.PressWaitUnit.SetValue((string)QueryDataClient.Instance.Service.GetConfig($"PM1.APC.PressureUnit"));
                     recipePressureWaitViewModel.SelectedStep = destinationStep;
@@ -3025,7 +3017,7 @@ namespace FurnaceUI.Views.Recipes
             CurrentRecipe.Tables.FirstOrDefault(x => x.Index == CurrentRecipe.TableIndex).TableData.Steps.Clear();
             CurrentRecipe.Steps.ToList().ForEach(x =>
             {
-                var tempStep = (Step)CloneUtil.CloneAllObject(x);
+                var tempStep = x.Adapt<Step>();
                 CurrentRecipe.Tables.FirstOrDefault(y => y.Index == CurrentRecipe.TableIndex).TableData.Steps.Add(tempStep);
             });
             CurrentRecipe.StepCloneChangedIndex();
@@ -3039,7 +3031,7 @@ namespace FurnaceUI.Views.Recipes
                 }
                 CurrentRecipe.Tables.FirstOrDefault(x => x.Index == (getIndex + 1)).TableData.Steps.ToList().ForEach(x =>
                 {
-                    Step tempStep = (Step)CloneUtil.CloneAllObject(x);
+                    Step tempStep = x.Adapt<Step>();
                     CurrentRecipe.SetDelegateEvent(tempStep);
                     CurrentRecipe.Steps.Add(tempStep);
                 });
@@ -3072,8 +3064,7 @@ namespace FurnaceUI.Views.Recipes
             currentPage = currentPage - 1;
             NewSteps = new ObservableCollection<Step>(CurrentRecipe.Steps.Take(pageSize * currentPage).Skip(pageSize * (currentPage - 1)));
             IndexNoDefault = 9;
-            SelectStep(NewSteps[IndexNoDefault]);
-            RefreshUpdate();
+            SelectStep(NewSteps[IndexNoDefault]);    
         }
         public void PageTop()
         {
@@ -3089,9 +3080,6 @@ namespace FurnaceUI.Views.Recipes
             }
             IndexNoDefault = IndexNoDefault - 1;
             SelectStep(NewSteps[IndexNoDefault]);
-            RefreshUpdate();
-
-
         }
         public void PageDown()
         {
@@ -3106,7 +3094,6 @@ namespace FurnaceUI.Views.Recipes
 
             }
             SelectStep(NewSteps[IndexNoDefault]);
-            RefreshUpdate();
         }
         public void PageLineDown()
         {
@@ -3119,7 +3106,6 @@ namespace FurnaceUI.Views.Recipes
             NewSteps = new ObservableCollection<Step>(CurrentRecipe.Steps.Take(pageSize * currentPage).Skip(pageSize * (currentPage - 1)));
             IndexNoDefault = 0;
             SelectStep(NewSteps[IndexNoDefault]);
-            RefreshUpdate();
 
 
         }

+ 38 - 7
Furnace/FurnaceUI/Views/Recipes/RecipeTableSelectDialogViewModel.cs

@@ -63,20 +63,32 @@ namespace FurnaceUI.Views.Recipes
         }
         public void Clear()
         {
+            if (SelectedIndex < 0)
+            {
+                DialogBox.ShowWarning("No table is selected");
+                return;
+            }
             if (!DialogBox.Confirm("Clear this table?"))
                 return;
             // SelectedTable.Name = "";
             SelectedTable.EndStatus = "";
-            if (SelectedTable.TableData.Steps.Count > 1)
+            if (SelectedTable.TableData.Steps.Count > 0)
             {
-                while (SelectedTable.TableData.Steps.Count > 1)
+                if (SelectedIndex == 0)
                 {
-                    SelectedTable.TableData.Steps.RemoveAt(1);
+                    if (SelectedTable.TableData.Steps.Count < 2)
+                    {
+                        DialogBox.ShowInfo("Table1 have one step at least");
+                        return;
+                    }
+                    var step = SelectedTable.TableData.Steps.First();
+                    if (step != null)
+                    {
+                        SelectedTable.TableData.Steps.Clear();
+                        SelectedTable.TableData.Steps.Add(step);
+                    }
                 }
-            }
-            else
-            {
-                SelectedTable.TableData = new RecipeDataBase();
+                else SelectedTable.TableData.Steps.Clear();
             }
         }
 
@@ -99,6 +111,25 @@ namespace FurnaceUI.Views.Recipes
             }
             else
             {
+                //table名不能重复
+                for (int i = 0; i < Recipe.Tables.Count; i++)
+                {
+                    if (Recipe.Tables[i].TableData?.Steps?.Count > 0)
+                    {
+                        var tablename = Recipe.Tables[i].Name.Trim();
+                        for (int j = i + 1; j < Recipe.Tables.Count; j++)
+                        {
+                            if (Recipe.Tables[j].TableData?.Steps?.Count > 0)
+                            {
+                                if (tablename == Recipe.Tables[j].Name.Trim())
+                                {
+                                    DialogBox.ShowError($"Table{i + 1} and Table{j + 1} couldn't have same table name [{tablename}]");
+                                    return;
+                                }
+                            }
+                        }
+                    }
+                }
                 Recipe.TableIndex = SelectedTable.Index;
                 Recipe.Steps.Clear();
                 SelectedTable.TableData.Steps.ToList().ForEach(x =>