JET-GZX 2 viikkoa sitten
vanhempi
commit
1433d04443

+ 14 - 0
Framework/Common/CommonData/LeakCheckMode.cs

@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Virgo_DCommon
+{
+    public enum LeakCheckMode
+    {
+        ChamberOnly,
+        ChamberAndGasLine,
+        ChamberAndGasLineAndFAC,
+    }
+}

+ 84 - 0
Framework/Common/CommonData/LeakCheckResultItem.cs

@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.Text;
+
+namespace Virgo_DCommon
+{
+    [DataContract]
+    [Serializable]
+    public enum LeakCheckStatus
+    {
+        [EnumMember]
+        Failed,
+
+        [EnumMember]
+        Aborted,
+
+        [EnumMember]
+        Succeed,
+    }
+
+    [DataContract]
+    [Serializable]
+    public class LeakCheckResultItem
+    {
+        [DataMember]
+        public string Id
+        {
+            get;
+            set;
+        }
+
+        [DataMember]
+        public DateTime Date
+        {
+            get;
+            set;
+        }
+
+        [DataMember]
+        public int StartPressure
+        {
+            get;
+            set;
+        }
+
+        [DataMember]
+        public int StopPressure
+        {
+            get;
+            set;
+        }
+
+        [DataMember]
+        public int LeakCheckTime
+        {
+            get;
+            set;
+        }
+
+        [DataMember]
+        public string LeakCheckStatus
+        {
+            get;
+            set;
+        }
+
+        [DataMember]
+        public string LeakCheckMode
+        {
+            get;
+            set;
+        }
+
+        [DataMember]
+        public double LeakRate
+        {
+            get;
+            set;
+        }
+    }
+
+}

+ 148 - 0
Framework/Common/CommonData/LeakCheckResultManager.cs

@@ -0,0 +1,148 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Xml;
+using Aitex.Common.Util;
+using Aitex.Core.RT.Log;
+using Aitex.Core.Util;
+using Virgo_DCommon;
+
+namespace Virgo_DCommon
+{
+    public class LeakCheckResultManager : Singleton<LeakCheckResultManager>
+    {
+        private string _template = "<?xml version=\"1.0\" encoding=\"utf-16\"?> <LeakCheckResult xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"></LeakCheckResult>";
+
+        private Dictionary<string, XmlDocument> _dicXmlFile = new Dictionary<string, XmlDocument>();
+
+        string _filePath = PathManager.GetAppDir() + "\\LeakCheckResult\\";
+
+        string _fileName = "\\LeakCheckResult.xml";
+
+        public void Initialize(string Module)
+        {
+            try
+            {
+                XmlDocument _dom = new XmlDocument();
+
+                if (!Directory.Exists(_filePath + Module))
+                {
+                    Directory.CreateDirectory(_filePath + Module);
+                }
+                if (!File.Exists(_filePath + Module + _fileName))
+                {
+                    _dom.LoadXml(_template);
+                    _dom.Save(_filePath + Module + _fileName);
+                }
+                else
+                {
+                    _dom.Load(_filePath + Module + _fileName);
+                }
+                _dicXmlFile.Add(Module, _dom);
+            }
+            catch (Exception ex)
+            {
+                LOG.Write(ex);
+                throw;
+            }
+        }
+
+        /*
+         * 
+         * 
+         *                             Date = Convert.ToDateTime(element.GetAttribute("Date")),
+                            LeakCheckStatus = element.GetAttribute("LeakCheckStatus"),
+                            LeakRate = Convert.ToDouble(element.GetAttribute("LeakCheckStatus")),
+                            StartPressure = Convert.ToInt32(element.GetAttribute("StartPressure")),
+                            StopPressure = Convert.ToInt32(element.GetAttribute("StopPressure")),
+                            LeakCheckMode = element.GetAttribute("LeakCheckMode"),
+                            LeakCheckTime = Convert.ToInt32(element.GetAttribute("LeakCheckTime")),
+         * 
+         */
+        public void AddLeakCheck(string Module, DateTime date, int leakCheckTime, int beginPressure, int endPressure, double leakRate, string status, string mode)
+        {
+            try
+            {
+                XmlElement node = _dicXmlFile[Module].CreateNode(XmlNodeType.Element, "LeakCheck", _dicXmlFile[Module].NamespaceURI) as XmlElement;
+                node.SetAttribute("Id", Guid.NewGuid().ToString());
+                node.SetAttribute("Date", date.ToString("yyyy-MM-dd HH:mm:ss.fff"));
+                node.SetAttribute("LeakCheckStatus", status);
+                node.SetAttribute("LeakRate", leakRate.ToString("F5"));
+                node.SetAttribute("StartPressure", beginPressure.ToString());
+                node.SetAttribute("StopPressure", endPressure.ToString());
+                node.SetAttribute("LeakCheckMode", mode);
+                node.SetAttribute("LeakCheckTime", leakCheckTime.ToString());
+
+                XmlElement root = _dicXmlFile[Module].SelectSingleNode("/LeakCheckResult") as XmlElement;
+                root.AppendChild(node);
+
+                _dicXmlFile[Module].Save(_filePath + Module + _fileName);
+            }
+            catch (Exception ex)
+            {
+                LOG.Write(ex);
+
+            }
+
+        }
+
+        /*
+         * 
+         <LeakCheck Date="" StartPressure="" StopPressure 
+         */
+        public List<LeakCheckResultItem> GetHistoryLeakCheck(string Module)
+        {
+            List<LeakCheckResultItem> result = new List<LeakCheckResultItem>();
+
+            try
+            {
+                XmlNodeList lst = _dicXmlFile[Module].SelectNodes("/LeakCheckResult/LeakCheck");
+                if (lst != null)
+                {
+                    foreach (XmlElement element in lst)
+                    {
+                        result.Add(new LeakCheckResultItem()
+                        {
+                            Id = element.GetAttribute("Id"),
+                            Date = Convert.ToDateTime(element.GetAttribute("Date")),
+                            LeakCheckStatus = element.GetAttribute("LeakCheckStatus"),
+                            LeakRate = Convert.ToDouble(element.GetAttribute("LeakRate")),
+                            StartPressure = Convert.ToInt32(element.GetAttribute("StartPressure")),
+                            StopPressure = Convert.ToInt32(element.GetAttribute("StopPressure")),
+                            LeakCheckMode = element.GetAttribute("LeakCheckMode"),
+                            LeakCheckTime = Convert.ToInt32(element.GetAttribute("LeakCheckTime")),
+                        });
+                    }
+                }
+
+
+            }
+            catch (Exception ex)
+            {
+                LOG.Write(ex);
+
+            }
+
+            return result;
+        }
+
+        public void Delete(string Module, string id)
+        {
+            try
+            {
+                XmlElement node = _dicXmlFile[Module].SelectSingleNode(string.Format("/LeakCheckResult/LeakCheck[@Id='{0}']", id)) as XmlElement;
+
+                node.ParentNode.RemoveChild(node);
+
+                _dicXmlFile[Module].Save(_filePath + Module + _fileName);
+            }
+            catch (Exception ex)
+            {
+                LOG.Write(ex);
+
+            }
+        }
+    }
+}

+ 213 - 0
Virgo_DUI/Models/PMs/LeakCheckView.xaml

@@ -0,0 +1,213 @@
+<UserControl x:Class="Virgo_DUI.Client.Models.PMs.LeakCheckView"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
+             xmlns:cal="http://www.caliburn.org"
+             xmlns:ctrl="http://OpenSEMI.Ctrlib.com/presentation"
+             xmlns:local="clr-namespace:Virgo_DUI.Client.Models.PMs"
+             mc:Ignorable="d" d:DesignHeight ="770" d:DesignWidth="1920" IsEnabled="{Binding PageEnabled}">
+    <Grid>
+        <Grid.ColumnDefinitions>
+            <ColumnDefinition Width="*"/>
+            <ColumnDefinition Width="380"/>
+            <ColumnDefinition Width="5"/>
+            <ColumnDefinition Width="1200"/>
+            <ColumnDefinition Width="*"/>
+        </Grid.ColumnDefinitions>
+        <Grid.RowDefinitions>
+            <RowDefinition Height="50"/>
+            <RowDefinition Height="*"/>
+        </Grid.RowDefinitions>
+        <Grid Grid.Column="1" Grid.Row="1">
+            <Grid.ColumnDefinitions>
+                <ColumnDefinition Width="160"/>
+                <ColumnDefinition Width="230"/>
+            </Grid.ColumnDefinitions>
+            <Grid.RowDefinitions>
+                <RowDefinition Height="0"/>
+                <RowDefinition Height="24"/>
+                <RowDefinition Height="24"/>
+                <RowDefinition Height="24"/>
+                <RowDefinition Height="24"/>
+                <RowDefinition Height="24"/>
+                <RowDefinition Height="24"/>
+                <RowDefinition Height="24"/>
+                <RowDefinition Height="24"/>
+                <RowDefinition Height="24"/>
+                <RowDefinition Height="24"/>
+                <RowDefinition Height="24"/>
+                <RowDefinition Height="24"/>
+                <RowDefinition Height="24"/>
+            </Grid.RowDefinitions>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="1" Background="{DynamicResource Table_BG_Title}" Grid.Row="1" Grid.ColumnSpan="2" Padding="5,1">
+                <TextBlock Text="Leak Check Settings" TextWrapping="Wrap" Foreground="{DynamicResource FG_Black}" FontSize="12" FontFamily="Arial" VerticalAlignment="Center" HorizontalAlignment="Center"/>
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="1" Background="{DynamicResource Table_BG_Title}" Grid.Row="2" Padding="5,1">
+                <TextBlock Text="PumpingTime (s)" TextWrapping="Wrap" Foreground="{DynamicResource FG_Black}" FontSize="12" FontFamily="Arial" VerticalAlignment="Center"/>
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="0,1,1,1" Background="{DynamicResource Table_BG_Content}" Grid.Row="2" Grid.Column="1" Padding="5,1">
+                <ctrl:TextBoxEx Text="{Binding Path=LeakCheckPumpDownTimeSetPoint}" TextSaved="{Binding LeakCheckPumpDownTimeSetPointSaved, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"   EditBoxMode="UnSignDecimal" VerticalAlignment="Center"/>
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="1" Background="{DynamicResource Table_BG_Title}" Grid.Row="3" Padding="5,1">
+                <TextBlock Text="LeakCheckTime (s)" TextWrapping="Wrap" Foreground="{DynamicResource FG_Black}" FontSize="12" FontFamily="Arial" VerticalAlignment="Center"/>
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="0,1,1,1" Background="{DynamicResource Table_BG_Content}" Grid.Row="3" Grid.Column="1" Padding="5,1">
+                <ctrl:TextBoxEx Text="{Binding Path=LeakCheckTimeSetPoint}" TextSaved="{Binding LeakCheckTimeSetPointSaved, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" EditBoxMode="UnSignInteger"  VerticalAlignment="Center"/>
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="1" Background="{DynamicResource Table_BG_Title}" Grid.Row="4" Padding="5,1">
+                <TextBlock TextWrapping="Wrap" Foreground="{DynamicResource FG_Black}" FontSize="12" FontFamily="Arial" VerticalAlignment="Center"><Run Text="Leak"/><Run Language="zh-cn" Text="Rate"/><Run Text="Limit (mTorr/min)"/></TextBlock>
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="0,1,1,1" Background="{DynamicResource Table_BG_Content}" Grid.Row="4" Grid.Column="1" Padding="5,1">
+                <ctrl:TextBoxEx Text="{Binding Path=LeakRateUpperLimitSetPoint}" TextSaved="{Binding LeakRateUpperLimitSetPointSaved, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"   EditBoxMode="UnSignDecimal" VerticalAlignment="Center"/>
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="1" Background="{DynamicResource Table_BG_Title}" Grid.Row="5" Padding="5,1">
+                <TextBlock Text="LeakCheckMode" TextWrapping="Wrap" Foreground="{DynamicResource FG_Black}" FontSize="12" FontFamily="Arial" VerticalAlignment="Center"/>
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="0,1,1,1" Background="{DynamicResource Table_BG_Content}" Grid.Row="5" Grid.Column="1" Padding="5,1">
+                <ComboBox Text="{Binding Path=LeakCheckModeSetPoint}"   IsEnabled="{Binding Path=IsLeakCheckEnabled}"  Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" FontSize="13"  >
+                    <ComboBoxItem>ChamberOnly</ComboBoxItem>
+                    <ComboBoxItem>ChamberAndGasLine</ComboBoxItem>
+                    <ComboBoxItem>ChamberAndGasLineAndFAC</ComboBoxItem>
+                </ComboBox>
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="1" Background="{DynamicResource Table_BG_Title}" Grid.Row="6" Padding="5,1">
+                <TextBlock Text="MfcGas1" TextWrapping="Wrap" Foreground="{DynamicResource FG_Black}" FontSize="12" FontFamily="Arial" VerticalAlignment="Center"/>
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="1" Background="{DynamicResource Table_BG_Title}" Grid.Row="6" Grid.Column="1" Padding="5,1">
+                <CheckBox Name="MfcGas1" Grid.Row="4"  Grid.Column="1" Grid.ColumnSpan="2"  HorizontalAlignment="Center" VerticalAlignment="Center" IsEnabled="{Binding IsEnableGas1Line}"  IsChecked="{Binding EnableGasLine1}"   />
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="1" Background="{DynamicResource Table_BG_Title}" Grid.Row="7" Padding="5,1">
+                <TextBlock Text="MfcGas2" TextWrapping="Wrap" Foreground="{DynamicResource FG_Black}" FontSize="12" FontFamily="Arial" VerticalAlignment="Center"/>
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="1" Background="{DynamicResource Table_BG_Title}" Grid.Row="7" Grid.Column="1" Padding="5,1">
+                <CheckBox Name="MfcGas2"  Grid.Row="4"  Grid.Column="1" Grid.ColumnSpan="2"  HorizontalAlignment="Center" VerticalAlignment="Center" IsEnabled="{Binding IsEnableGas2Line}"  IsChecked="{Binding EnableGasLine2}"   />
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="1" Background="{DynamicResource Table_BG_Title}" Grid.Row="8" Padding="5,1">
+                <TextBlock Text="MfcGas3" TextWrapping="Wrap" Foreground="{DynamicResource FG_Black}" FontSize="12" FontFamily="Arial" VerticalAlignment="Center"/>
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="1" Background="{DynamicResource Table_BG_Title}" Grid.Row="8" Grid.Column="1" Padding="5,1">
+                <CheckBox  Grid.Row="4"  Grid.Column="1" Grid.ColumnSpan="2"  HorizontalAlignment="Center" VerticalAlignment="Center" IsEnabled="{Binding IsEnableGas3Line}"  IsChecked="{Binding EnableGasLine3}"   />
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="1" Background="{DynamicResource Table_BG_Title}" Grid.Row="9" Padding="5,1">
+                <TextBlock Text="MfcGas4" TextWrapping="Wrap" Foreground="{DynamicResource FG_Black}" FontSize="12" FontFamily="Arial" VerticalAlignment="Center"/>
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="1" Background="{DynamicResource Table_BG_Title}" Grid.Row="9" Grid.Column="1" Padding="5,1">
+                <CheckBox  Grid.Row="4"  Grid.Column="1" Grid.ColumnSpan="2"  HorizontalAlignment="Center" VerticalAlignment="Center" IsEnabled="{Binding IsEnableGas4Line}"  IsChecked="{Binding EnableGasLine4}"   />
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="1" Background="{DynamicResource Table_BG_Title}" Grid.Row="10" Padding="5,1">
+                <TextBlock Text="CheckAll" TextWrapping="Wrap" Foreground="{DynamicResource FG_Black}" FontSize="12" FontFamily="Arial" VerticalAlignment="Center"/>
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="1" Background="{DynamicResource Table_BG_Title}" Grid.Row="10" Grid.Column="1" Padding="5,1">
+                <CheckBox  Grid.Row="4"  Grid.Column="1" Grid.ColumnSpan="2"  HorizontalAlignment="Center" VerticalAlignment="Center" IsEnabled="{Binding IsEnableMasterGasline}" IsChecked="{Binding MasterGasLineControl}"   />
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="1" Background="{DynamicResource Table_BG_Title}" Grid.Row="11" Padding="5,1">
+                <TextBlock Text="Status" TextWrapping="Wrap" Foreground="{DynamicResource FG_Black}" FontSize="12" FontFamily="Arial" VerticalAlignment="Center"/>
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="1" Background="{DynamicResource Table_BG_Title}" Grid.Row="11" Grid.Column="1" Padding="5,1">
+                <TextBlock Text="{Binding Path=Status}" TextWrapping="Wrap" Foreground="{DynamicResource FG_Black}" FontSize="12" FontFamily="Arial" VerticalAlignment="Center"/>
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="1" Background="{DynamicResource Table_BG_Title}" Grid.Row="12" Padding="5,1">
+                <TextBlock Text="LeakCheckElapseTime" TextWrapping="Wrap" Foreground="{DynamicResource FG_Black}" FontSize="12" FontFamily="Arial" VerticalAlignment="Center"/>
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="1" Background="{DynamicResource Table_BG_Title}" Grid.Row="12" Grid.Column="1" Padding="5,1">
+                <TextBlock Text="{Binding Path=LeakCheckElapseTime}" TextWrapping="Wrap" Foreground="{DynamicResource FG_Black}" FontSize="12" FontFamily="Arial" VerticalAlignment="Center"/>
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="1" Background="{DynamicResource Table_BG_Title}" Grid.Row="13" Padding="5,1">
+                <TextBlock Text="CurrentPressure" TextWrapping="Wrap" Foreground="{DynamicResource FG_Black}" FontSize="12" FontFamily="Arial" VerticalAlignment="Center"/>
+            </Border>
+            <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="1" Background="{DynamicResource Table_BG_Title}" Grid.Row="13" Grid.Column="1" Padding="5,1">
+                <TextBlock Text="{Binding Path=Pressure}" TextWrapping="Wrap" Foreground="{DynamicResource FG_Black}" FontSize="12" FontFamily="Arial" VerticalAlignment="Center"/>
+            </Border>
+        </Grid>
+        <Grid Grid.Column="3" Grid.Row="0" Grid.RowSpan="2">
+            <Grid.RowDefinitions>
+                <RowDefinition Height="50" />
+                <RowDefinition Height="*" />
+            </Grid.RowDefinitions>
+            <StackPanel Grid.Row="0" Margin="0,5,0,10" Orientation="Horizontal" HorizontalAlignment="Center">
+                <Button Width="80" Height="25" Margin="10,0" Content="Start" IsEnabled="{Binding IsLeakCheckEnabled}" >
+                    <i:Interaction.Triggers>
+                        <i:EventTrigger EventName="Click">
+                            <cal:ActionMessage MethodName="LeakCheck"/>
+                        </i:EventTrigger>
+                    </i:Interaction.Triggers>
+                </Button>
+                <Button Width="80" Height="25" Margin="10,0" Content="Stop" IsEnabled="{Binding IsAbortButtonEnabled}">
+                    <i:Interaction.Triggers>
+                        <i:EventTrigger EventName="Click">
+                            <cal:ActionMessage MethodName="AbortLeakCheck"/>
+                        </i:EventTrigger>
+                    </i:Interaction.Triggers>
+                </Button>
+                <Button Width="80" Height="25" Margin="10,0" Content="Delete" IsEnabled="{Binding IsLeakCheckEnabled}">
+                    <i:Interaction.Triggers>
+                        <i:EventTrigger EventName="Click">
+                            <cal:ActionMessage MethodName="DeleteLeakCheck"/>
+                        </i:EventTrigger>
+                    </i:Interaction.Triggers>
+                </Button>
+            </StackPanel>
+
+            <DataGrid Grid.Row="1" Padding="12,0" AutoGenerateColumns="False" BorderThickness="0.1"  FontSize="12" MinRowHeight="20" VerticalAlignment="Stretch"
+                        CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False" CanUserResizeColumns="True" CanUserResizeRows="False" CanUserSortColumns="False" 
+                        SelectionMode="Single" SelectionUnit="FullRow" Background="#05000000" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled"
+                        ItemsSource="{Binding LeakCheckResultList}" SelectedItem="{Binding CurrentLeakCheckResultItem}" FontFamily="Arial,SimSun" Margin="0,0,8,45" SelectionChanged="DataGrid_SelectionChanged">
+                <DataGrid.Columns>
+                    <DataGridTextColumn Width="160" Binding="{Binding Date, StringFormat={}{0:yyyy-MM-dd HH:mm:ss}}"  CanUserSort="False" CanUserReorder="False" IsReadOnly="True" >
+                        <DataGridTextColumn.HeaderTemplate >
+                            <DataTemplate>
+                                <TextBlock Text="{DynamicResource GlobalLableLeakCheckDate}" />
+                            </DataTemplate>
+                        </DataGridTextColumn.HeaderTemplate>
+                    </DataGridTextColumn>
+                    <DataGridTextColumn Width="160" Binding="{Binding StartPressure}" CanUserSort="False" CanUserReorder="False" IsReadOnly="True" >
+                        <DataGridTextColumn.HeaderTemplate >
+                            <DataTemplate>
+                                <TextBlock Text="{DynamicResource GlobalLableStartPressure}" />
+                            </DataTemplate>
+                        </DataGridTextColumn.HeaderTemplate>
+                    </DataGridTextColumn>
+                    <DataGridTextColumn Width="160" Binding="{Binding StopPressure}"   CanUserSort="False" CanUserReorder="False" IsReadOnly="True" >
+                        <DataGridTextColumn.HeaderTemplate >
+                            <DataTemplate>
+                                <TextBlock Text="{DynamicResource GlobalLableStopPressure}" />
+                            </DataTemplate>
+                        </DataGridTextColumn.HeaderTemplate>
+                    </DataGridTextColumn>
+                    <DataGridTextColumn Width="200" Binding="{Binding LeakCheckTime}"   CanUserSort="False" CanUserReorder="False" IsReadOnly="True" >
+                        <DataGridTextColumn.HeaderTemplate >
+                            <DataTemplate>
+                                <TextBlock Text="{DynamicResource GlobalLableLeakCheckTime}" />
+                            </DataTemplate>
+                        </DataGridTextColumn.HeaderTemplate>
+                    </DataGridTextColumn>
+                    <DataGridTextColumn Width="160" Binding="{Binding LeakRate, StringFormat={}{0:F5}}"   CanUserSort="False" CanUserReorder="False" IsReadOnly="True" >
+                        <DataGridTextColumn.HeaderTemplate >
+                            <DataTemplate>
+                                <TextBlock Text="{DynamicResource GlobalLableLeakRate}" />
+                            </DataTemplate>
+                        </DataGridTextColumn.HeaderTemplate>
+                    </DataGridTextColumn>
+                    <DataGridTextColumn Width="200" Binding="{Binding LeakCheckMode}"   CanUserSort="False" CanUserReorder="False" IsReadOnly="True" >
+                        <DataGridTextColumn.HeaderTemplate >
+                            <DataTemplate>
+                                <TextBlock Text="{DynamicResource GlobalLableCheckMode}" />
+                            </DataTemplate>
+                        </DataGridTextColumn.HeaderTemplate>
+                    </DataGridTextColumn>
+                    <DataGridTextColumn Width="*" Binding="{Binding LeakCheckStatus}"  CanUserSort="False" CanUserReorder="False" IsReadOnly="True" >
+                        <DataGridTextColumn.HeaderTemplate >
+                            <DataTemplate>
+                                <TextBlock Text="{DynamicResource GlobalLableLeakCheckStatus}" />
+                            </DataTemplate>
+                        </DataGridTextColumn.HeaderTemplate>
+                    </DataGridTextColumn>
+
+                </DataGrid.Columns>
+
+            </DataGrid>
+        </Grid>
+    </Grid>
+</UserControl>

+ 37 - 0
Virgo_DUI/Models/PMs/LeakCheckView.xaml.cs

@@ -0,0 +1,37 @@
+using MECF.Framework.Common.Equipment;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace Virgo_DUI.Client.Models.PMs
+{
+    /// <summary>
+    /// LeakCheckView.xaml 的交互逻辑
+    /// </summary>
+    public partial class LeakCheckView : UserControl
+    {
+        private LeakCheckViewModel _viewModel;
+
+        public LeakCheckView()
+        {
+            InitializeComponent();
+            this.DataContext = _viewModel = new LeakCheckViewModel();
+        }
+
+        private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+
+        }
+    }
+}

+ 515 - 0
Virgo_DUI/Models/PMs/LeakCheckViewModel.cs

@@ -0,0 +1,515 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Windows;
+using Aitex.Core.RT.Log;
+using Aitex.Core.UI.ControlDataContext;
+using Aitex.Core.Utilities;
+using Aitex.Sorter.Common;
+using Virgo_DUI.Client.Models.Sys;
+using MECF.Framework.Common.DataCenter;
+using OpenSEMI.ClientBase;
+using OpenSEMI.ClientBase.IO;
+
+
+using ExcelLibrary.SpreadSheet;
+using MECF.Framework.Common.OperationCenter;
+using Aitex.Core.Util;
+using Virgo_DCommon;
+using Aitex.Core.Common.DeviceData;
+using Aitex.Core.RT.SCCore;
+
+namespace Virgo_DUI.Client.Models.PMs
+{
+    public class LeakCheckViewModel : ModuleUiViewModelBase, ISupportMultipleSystem
+    {
+        #region 
+        private int MenuPermission;
+        private bool _isEnableGasLine;
+        public bool IsEnableGasLine
+        {
+            get
+            {
+                return (LeakCheckModeSetPoint == "ChamberAndGasLine" || LeakCheckModeSetPoint == "ChamberAndGasLineAndFAC") && IsLeakCheckEnabled;
+            }
+            set
+            {
+                _isEnableGasLine = value;
+                NotifyOfPropertyChange("IsEnableGasLine");
+            }
+        }
+
+        #region GasLine
+        public bool IsEnableGas1Line
+        {
+            get
+            {
+                bool originalCondition = (LeakCheckModeSetPoint == "ChamberAndGasLine" || 
+                                        LeakCheckModeSetPoint == "ChamberAndGasLineAndFAC") && 
+                                        IsLeakCheckEnabled;
+
+                string configValue = QueryDataClient.Instance.Service.GetConfig($"{SystemName}.MfcGas1.Enable").ToString(); // GasIndex 表示当前气体管路序号(1/2/3/4)
+                //string configValue = QueryDataClient.Instance.Service.GetConfig(configKey)?.ToString();
+                bool isGasEnabled = bool.TryParse(configValue, out bool result) ? result : false;
+
+                return originalCondition && isGasEnabled;
+            }
+            set
+            {
+                _isEnableGasLine = value;
+                NotifyOfPropertyChange("IsEnableGasLine");
+            }
+        }
+        public bool IsEnableGas2Line
+        {
+            get
+            {
+                bool originalCondition = (LeakCheckModeSetPoint == "ChamberAndGasLine" ||
+                                        LeakCheckModeSetPoint == "ChamberAndGasLineAndFAC") &&
+                                        IsLeakCheckEnabled;
+
+                string configValue = QueryDataClient.Instance.Service.GetConfig($"{SystemName}.MfcGas2.Enable").ToString(); // GasIndex 表示当前气体管路序号(1/2/3/4)
+                //string configValue = QueryDataClient.Instance.Service.GetConfig(configKey)?.ToString();
+                bool isGasEnabled = bool.TryParse(configValue, out bool result) ? result : false;
+
+                return originalCondition && isGasEnabled;
+            }
+            set
+            {
+                _isEnableGasLine = value;
+                NotifyOfPropertyChange("IsEnableGasLine");
+            }
+        }
+        public bool IsEnableGas3Line
+        {
+            get
+            {
+                bool originalCondition = (LeakCheckModeSetPoint == "ChamberAndGasLine" ||
+                                        LeakCheckModeSetPoint == "ChamberAndGasLineAndFAC") &&
+                                        IsLeakCheckEnabled;
+
+                string configValue = QueryDataClient.Instance.Service.GetConfig($"{SystemName}.MfcGas3.Enable").ToString(); // GasIndex 表示当前气体管路序号(1/2/3/4)
+                //string configValue = QueryDataClient.Instance.Service.GetConfig(configKey)?.ToString();
+                bool isGasEnabled = bool.TryParse(configValue, out bool result) ? result : false;
+
+                return originalCondition && isGasEnabled;
+            }
+            set
+            {
+                _isEnableGasLine = value;
+                NotifyOfPropertyChange("IsEnableGasLine");
+            }
+        }
+        public bool IsEnableGas4Line
+        {
+            get
+            {
+                bool originalCondition = (LeakCheckModeSetPoint == "ChamberAndGasLine" ||
+                                        LeakCheckModeSetPoint == "ChamberAndGasLineAndFAC") &&
+                                        IsLeakCheckEnabled;
+
+                string configValue = QueryDataClient.Instance.Service.GetConfig($"{SystemName}.MfcGas4.Enable").ToString(); // GasIndex 表示当前气体管路序号(1/2/3/4)
+                //string configValue = QueryDataClient.Instance.Service.GetConfig(configKey)?.ToString();
+                bool isGasEnabled = bool.TryParse(configValue, out bool result) ? result : false;
+
+                return originalCondition && isGasEnabled;
+            }
+            set
+            {
+                _isEnableGasLine = value;
+                NotifyOfPropertyChange("IsEnableGasLine");
+            }
+        }
+        public bool IsEnableMasterGasline
+        {
+            get
+            {
+                return (LeakCheckModeSetPoint == "ChamberAndGasLine" || LeakCheckModeSetPoint == "ChamberAndGasLineAndFAC") && IsLeakCheckEnabled;
+            }
+            set
+            {
+                _isEnableGasLine = value;
+                NotifyOfPropertyChange("IsEnableMasterGasline");
+            }
+        }
+
+        #endregion 
+        public bool IsLeakCheckEnabled
+        {
+            get
+            {
+                return IsManualMode && !IsLeakCheck;
+            }
+        }
+
+        [IgnorePropertyChange]
+        public string LeakCheckModeSetPoint
+        {
+            get;
+            set;
+        }
+
+        [IgnorePropertyChange]
+        public string LeakCheckPumpDownTimeSetPoint
+        {
+            get;
+            set;
+        }
+
+        [IgnorePropertyChange]
+        public string LeakCheckTimeSetPoint
+        {
+            get;
+            set;
+        }
+
+        [IgnorePropertyChange]
+        public string LeakRateUpperLimitSetPoint
+        {
+            get;
+            set;
+        }
+
+        [IgnorePropertyChange]
+        public string LeakCheckFlowScale
+        {
+            get;
+            set;
+        }
+
+        [Subscription("IoMfc.MfcGas1.IsEnable")]
+        public bool MfcGas1Enable
+        {
+            get;
+            set;
+        }
+
+        [Subscription("IoMfc.MfcGas2.IsEnable")]
+        public bool MfcGas2Enable
+        {
+            get;
+            set;
+        }
+
+        [Subscription("IoMfc.MfcGas3.IsEnable")]
+        public bool MfcGas3Enable
+        {
+            get;
+            set;
+        }
+
+        [Subscription("IoMfc.MfcGas4.IsEnable")]
+        public bool MfcGas4Enable
+        {
+            get;
+            set;
+        }
+
+        //[Subscription("IoMfc.MfcGas5.IsEnable")]
+        //public bool MfcGas5Enable
+        //{
+        //    get;
+        //    set;
+        //}
+
+        private bool _enableGasLine1;
+        public bool EnableGasLine1
+        {
+            get
+            {
+                return _enableGasLine1;
+            }
+            set
+            {
+                _enableGasLine1 = value;
+                NotifyOfPropertyChange("EnableGasLine1");
+            }
+        }
+
+        private bool _enableGasLine2;
+        public bool EnableGasLine2
+        {
+            get
+            {
+                return _enableGasLine2;
+            }
+            set
+            {
+                _enableGasLine2 = value;
+                NotifyOfPropertyChange("EnableGasLine2");
+            }
+        }
+
+        private bool _enableGasLine3;
+        public bool EnableGasLine3
+        {
+            get
+            {
+                return _enableGasLine3;
+            }
+            set
+            {
+                _enableGasLine3 = value;
+                NotifyOfPropertyChange("EnableGasLine3");
+            }
+        }
+
+        private bool _enableGasLine4;
+        public bool EnableGasLine4
+        {
+            get
+            {
+                return _enableGasLine4;
+            }
+            set
+            {
+                _enableGasLine4 = value;
+                NotifyOfPropertyChange("EnableGasLine4");
+            }
+        }
+
+        private bool _enableGasLine5;
+        public bool EnableGasLine5
+        {
+            get
+            {
+                return _enableGasLine5;
+            }
+            set
+            {
+                _enableGasLine5 = value;
+                NotifyOfPropertyChange("EnableGasLine5");
+            }
+        }
+
+        private bool _masterGasLineControl;
+        public bool MasterGasLineControl
+        {
+            get => _masterGasLineControl;
+            set
+            {
+                if (_masterGasLineControl == value) return;
+                _masterGasLineControl = value;
+
+                // 动态获取各气体管道的配置状态
+                bool gas1Enabled = GetGasConfigState("MfcGas1");
+                bool gas2Enabled = GetGasConfigState("MfcGas2");
+                bool gas3Enabled = GetGasConfigState("MfcGas3");
+                bool gas4Enabled = GetGasConfigState("MfcGas4");
+
+                // 仅操作配置启用的管道
+                if (gas1Enabled) EnableGasLine1 = value;
+                if (gas2Enabled) EnableGasLine2 = value;
+                if (gas3Enabled) EnableGasLine3 = value;
+                if (gas4Enabled) EnableGasLine4 = value;
+
+                NotifyOfPropertyChange(nameof(MasterGasLineControl));
+            }
+        }
+
+        private bool GetGasConfigState(string gasName)
+        {
+            string configKey = $"{SystemName}.{gasName}.Enable";
+            string configValue = QueryDataClient.Instance.Service.GetConfig(configKey)?.ToString();
+            return bool.TryParse(configValue, out bool result) && result; // 配置无效时默认禁用
+        }
+
+        [Subscription(Virgo_DDevice.ProcessGauge)]
+        public AITPressureMeterData ProcessGauge { get; set; }
+
+        [Subscription(Virgo_DDevice.PressureGauge)]
+        public AITPressureMeterData PressureGauge { get; set; }
+
+        [Subscription(Virgo_DDevice.ForelineGauge)]
+        public AITPressureMeterData ForelineGauge { get; set; }
+
+        [Subscription("LeakCheckElapseTime")]
+        public string LeakCheckElapseTime
+        {
+            get;
+            set;
+        }
+
+        public List<LeakCheckResultItem> LeakCheckResultList
+        {
+            get;
+            set;
+        }
+
+        [Subscription("IsAutoMode")]
+        public bool IsAutoMode
+        {
+            get;
+            set;
+        }
+
+        [Subscription(StateData.PMState)]
+        public int PMStatus
+        {
+            get;
+            set;
+        }
+
+        public string Status
+        {
+            get
+            {
+                return ((PMState)PMStatus).ToString();
+            }
+        }
+
+        public string Pressure
+        {
+            get
+            {
+                return ProcessGauge == null ? "0" : ProcessGauge.FeedBack.ToString("F0") + ProcessGauge.Unit;
+            }
+        }
+
+        public bool IsLeakCheck
+        {
+            get
+            {
+                return (PMState)PMStatus == PMState.LeakCheck;
+            }
+        }
+
+        public bool IsManualMode
+        {
+            get
+            {
+                return !IsAutoMode;
+            }
+        }
+
+        public bool IsEnableLeakCheck
+        {
+            get
+            {
+                return !IsAutoMode && (PMState)PMStatus == PMState.Idle;
+            }
+        }
+
+        public LeakCheckResultItem CurrentLeakCheckResultItem
+        {
+            get;
+            set;
+        }
+
+        F_TRIG _trigLeakCheckFinished = new F_TRIG();
+        #endregion 
+
+        public LeakCheckViewModel()
+        {
+            LeakCheckModeSetPoint = LeakCheckMode.ChamberOnly.ToString();
+
+            EnableGasLine1 = true;
+            EnableGasLine2 = true;
+            EnableGasLine3 = true;
+            EnableGasLine4 = true;
+            
+            NotifyOfPropertyChange("EnableGasLine1");
+            NotifyOfPropertyChange("EnableGasLine2");
+            NotifyOfPropertyChange("EnableGasLine3");
+            NotifyOfPropertyChange("EnableGasLine4");
+        }
+
+        protected override void OnInitialize()
+        {
+            base.OnInitialize();
+
+
+        }
+
+        protected override void OnActivate()
+        {
+            base.OnActivate();
+            LeakCheckPumpDownTimeSetPoint = QueryDataClient.Instance.Service.GetConfig($"{SystemName}.Pump.LeakCheckPumpingTime").ToString();
+            LeakCheckTimeSetPoint = QueryDataClient.Instance.Service.GetConfig($"{SystemName}.Pump.LeakCheckWaitTime").ToString();
+            LeakRateUpperLimitSetPoint = ((float)(double)QueryDataClient.Instance.Service.GetConfig($"{SystemName}.Pump.LeakRate")).ToString();
+        }
+
+        public void UpdateLeakCheckResult(string Module)
+        {
+            LeakCheckResultList = QueryDataClient.Instance.Service.GetHistoryLeakCheck(Module);
+            InvokePropertyChanged("LeakCheckResultList");
+        }
+
+        protected override void InvokeBeforeUpdateProperty(Dictionary<string, object> data)
+        {
+            MenuPermission = ClientApp.Instance.GetPermission($"LeakCheck{SystemName}");
+            if (!MfcGas1Enable) EnableGasLine1 = false;
+            if (!MfcGas2Enable) EnableGasLine2 = false;
+            if (!MfcGas3Enable) EnableGasLine3 = false;
+            if (!MfcGas4Enable) EnableGasLine4 = false;
+            //if (!MfcGas5Enable) EnableGasLine5 = false;
+
+            _trigLeakCheckFinished.CLK = IsLeakCheck;
+            if (_trigLeakCheckFinished.Q)
+            {
+                Application.Current.Dispatcher.Invoke(new Action(() =>
+                {
+                    UpdateLeakCheckResult(SystemName);
+
+                }));
+            }
+        }
+
+        protected override void InvokeAfterUpdateProperty(Dictionary<string, object> data)
+        {
+            if (CurrentLeakCheckResultItem == null)
+            {
+                UpdateLeakCheckResult(SystemName);
+                ;
+            }
+        }
+
+        public void LeakCheck()
+        {
+            if (MenuPermission != 3) return;
+            if (!IsLeakCheck)
+            {
+                InvokeClient.Instance.Service.DoOperation("System.SetConfig", $"{SystemName}.Pump.LeakCheckPumpingTime", LeakCheckPumpDownTimeSetPoint.ToString());
+                InvokeClient.Instance.Service.DoOperation("System.SetConfig", $"{SystemName}.Pump.LeakCheckWaitTime", LeakCheckTimeSetPoint.ToString());
+                InvokeClient.Instance.Service.DoOperation("System.SetConfig", $"{SystemName}.Pump.LeakRate", LeakRateUpperLimitSetPoint.ToString());
+                InvokeClient.Instance.Service.DoOperation($"{SystemName}.LeakCheck", new[]
+                                                      {
+                                                          LeakCheckPumpDownTimeSetPoint,
+                                                          LeakCheckTimeSetPoint,
+                                                          LeakCheckModeSetPoint,
+                                                          LeakRateUpperLimitSetPoint,
+                                                          EnableGasLine1.ToString(),
+                                                          EnableGasLine2.ToString(),
+                                                          EnableGasLine3.ToString(),
+                                                          EnableGasLine4.ToString(),
+                                                          EnableGasLine5.ToString(),
+                                                      });
+            }
+        }
+
+        public void AbortLeakCheck()
+        {
+            if (MenuPermission != 3) return;
+            if (MessageBox.Show("Confirm to stop leak detection?", "JetPlasma", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+                InvokeClient.Instance.Service.DoOperation($"{SystemName}.Abort");
+        }
+
+        public void DeleteLeakCheck()
+        {
+            if (MenuPermission != 3) return;
+            if (CurrentLeakCheckResultItem == null)
+            {
+                MessageBox.Show("Please select the leak detection record to delete first.", "JetPlasma", MessageBoxButton.OK);
+
+                return;
+            }
+
+            if (MessageBox.Show("Confirm to delete the current leak detection record?", "JetPlasma", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+                InvokeClient.Instance.Service.DoOperation($"{SystemName}.DeleteLeakCheck", CurrentLeakCheckResultItem.Id);
+
+            CurrentLeakCheckResultItem = null;
+        }
+    }
+}