using Aitex.Core.Account; using Aitex.Core.Common.DeviceData; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.UI.Dialog; using Aitex.Core.Util; using Aitex.Core.WCF; using Caliburn.Micro; using MECF.Framework.Common.Account.Extends; using MECF.Framework.Common.DataCenter; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.OperationCenter; using MECF.Framework.UI.Core.Accounts; using OpenSEMI.ClientBase; using OpenSEMI.ClientBase.Command; using OpenSEMI.ClientBase.Utility; using OpenSEMI.Core.Msg; using SciChart.Charting.ChartModifiers; using SciChart.Charting.Visuals; using SciChart.Charting.Visuals.Annotations; using SciChart.Charting.Visuals.Axes; using SciChart.Core.Extensions; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Data; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Threading; using VirgoCommon; using VirgoUI.Client.Models.History.Statistics; using VirgoUI.Client.Models.Operate.WaferAssociation; using VirgoUI.Client.Models.PMs; using Cali = Caliburn.Micro.Core; namespace VirgoUI.Client { public class TimeredMainViewModel : Cali.Conductor.Collection.OneActive { private PeriodicJob _timer; public R_TRIG _trigGauge = new R_TRIG(); public R_TRIG _trigAlarm = new R_TRIG(); public R_TRIG _trigPMAStatsWarning = new R_TRIG(); public R_TRIG _trigPMBStatsWarning = new R_TRIG(); public R_TRIG _trigPMAStatsAlarm = new R_TRIG(); public R_TRIG _trigPMBStatsAlarm = new R_TRIG(); private ConcurrentBag _subscribedKeys = new ConcurrentBag(); public ObservableCollection StatData { get; set; } private Func _isSubscriptionAttribute; private Func _hasSubscriptionAttribute; public string SoftwareVersion { get; set; } public string SystemTime { get { return DateTime.Now.ToString("HH:mm:ss"); } } public string GetUnitStatusBackground(string status) { if (status == null) return "Black"; status = status.Trim().ToLower(); switch (status) { case "error": return "red"; case "idle": return "Transparent"; case "init": case "unknown": return "Yellow"; default: return "LawnGreen"; } } public TimeredMainViewModel() { _timer = new PeriodicJob(1000, this.OnTimer, "UIUpdaterThread - " + GetType().Name); StatData = new ObservableCollection(); _isSubscriptionAttribute = attribute => attribute is SubscriptionAttribute; _hasSubscriptionAttribute = mi => mi.GetCustomAttributes(false).Any(_isSubscriptionAttribute); SoftwareVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(); NotifyOfPropertyChange("SoftwareVersion"); SubscribeKeys(this); } // protected virtual bool OnTimer() { try { Poll(); } catch (Exception ex) { LOG.Error(ex.Message); } return true; } public virtual void EnableTimer(bool enable) { if (enable) _timer.Start(); else _timer.Pause(); } protected virtual void Poll() { //此处在reset之后会报警 //_trigGauge.CLK = PMARfAlarm || PMAMfcAlarm1 || PMAMfcAlarm2 || PMAMfcAlarm3 || PMAMfcAlarm4 || PMAMfcAlarm5 // || PMBRfAlarm || PMBMfcAlarm1 || PMBMfcAlarm2 || PMBMfcAlarm3 || PMBMfcAlarm4 || PMBMfcAlarm5 // || PMAMfcGas1PressureAlarm && PMAMfcGas2PressureAlarm && PMAMfcGas3PressureAlarm && PMAMfcGas4PressureAlarm && PMAMfcGas5PressureAlarm // || PMBMfcGas1PressureAlarm && PMBMfcGas2PressureAlarm && PMBMfcGas3PressureAlarm && PMBMfcGas4PressureAlarm && PMBMfcGas5PressureAlarm; //if (_trigGauge.Q) //{ // InvokeClient.Instance.Service.DoOperation($"{ModuleName.EFEM}.{EfemOperation.SwitchOnBuzzerAndRed}"); //} //_trigAlarm.CLK = PMAIsAlarm || PMBIsAlarm; //if (_trigAlarm.Q) //{ // InvokeClient.Instance.Service.DoOperation($"{ModuleName.EFEM}.{EfemOperation.SwitchOnBuzzerAndRed}"); //} if (_subscribedKeys.Count > 0) { Dictionary result = QueryDataClient.Instance.Service.PollData(_subscribedKeys); if (result == null) { LOG.Error("获取RT数据失败"); return; } if (result.Count != _subscribedKeys.Count) { string unknowKeys = string.Empty; foreach (string key in _subscribedKeys) { if (!result.ContainsKey(key)) { unknowKeys += key + "\r\n"; } } //System.Diagnostics.Debug.Assert(false, unknowKeys); } InvokeBeforeUpdateProperty(result); UpdateValue(result); Application.Current.Dispatcher.Invoke(new System.Action(() => { InvokePropertyChanged(); InvokeAfterUpdateProperty(result); })); } string sql = $"SELECT * FROM \"stats_data\" order by \"name\" ASC;"; DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql); if (dbData == null || dbData.Rows.Count == 0) return; string[] clearedNameList = Array.ConvertAll(StatData.ToArray(), x => x.Name); List removableList = new List(); if (clearedNameList.Length > 0) removableList = clearedNameList.ToList(); for (int i = 0; i < dbData.Rows.Count; i++) { if (!dbData.Rows[i]["is_visible"].Equals(DBNull.Value) && !Convert.ToBoolean(dbData.Rows[i]["is_visible"].ToString())) continue; string name = dbData.Rows[i]["name"].ToString(); removableList.RemoveIfContains(name); StatsDataListItem item = StatData.FirstOrDefault(x => x.Name == name); if (item == null) { item = new StatsDataListItem(); item.Name = dbData.Rows[i]["name"].ToString(); item.AlarmEnable = false; item.WarningEnable = false; item.IsVisible = true; item.AlarmTextSaved = true; item.WarningTextSaved = true; item.AlarmValueSetPoint = dbData.Rows[i]["alarm_value"].ToString(); item.WarningValueSetPoint = dbData.Rows[i]["warning_value"].ToString(); StatData.Add(item); } item.Description = dbData.Rows[i]["description"].ToString(); item.Value = dbData.Rows[i]["value"].ToString(); item.Total = dbData.Rows[i]["total"].ToString(); if (!dbData.Rows[i]["enable_warning"].Equals(DBNull.Value)) item.WarningEnable = Convert.ToBoolean(dbData.Rows[i]["enable_warning"].ToString()); item.WarningValue = dbData.Rows[i]["warning_value"].ToString(); if (!dbData.Rows[i]["enable_alarm"].Equals(DBNull.Value)) item.AlarmEnable = Convert.ToBoolean(dbData.Rows[i]["enable_alarm"].ToString()); item.AlarmValue = dbData.Rows[i]["alarm_value"].ToString(); } foreach (var name in removableList) { StatsDataListItem item = StatData.FirstOrDefault(x => x.Name == name); if (item != null) StatData.Remove(item); } foreach (var item in StatData) { if (item.Name == "PMA.ProcessedWaferCount") { _trigPMAStatsAlarm.CLK = item.AlarmEnable && Convert.ToInt32(item.AlarmValue) < Convert.ToInt32(item.Value); if (_trigPMAStatsAlarm.Q) { InvokeClient.Instance.Service.DoOperation("System.Stats.Alarm", item.Name); } _trigPMAStatsWarning.CLK = item.WarningEnable && Convert.ToInt32(item.WarningValue) < Convert.ToInt32(item.Value); if (_trigPMAStatsWarning.Q) { InvokeClient.Instance.Service.DoOperation("System.Stats.Warning", item.Name); } } if (item.Name == "PMB.ProcessedWaferCount") { _trigPMBStatsAlarm.CLK = item.AlarmEnable && Convert.ToInt32(item.AlarmValue) < Convert.ToInt32(item.Value); if (_trigPMBStatsAlarm.Q) { InvokeClient.Instance.Service.DoOperation("System.Stats.Alarm", item.Name); } _trigPMBStatsWarning.CLK = item.WarningEnable && Convert.ToInt32(item.WarningValue) < Convert.ToInt32(item.Value); if (_trigPMBStatsWarning.Q) { InvokeClient.Instance.Service.DoOperation("System.Stats.Warning", item.Name); } } } } private void InvokePropertyChanged() { Refresh(); } protected virtual void InvokeBeforeUpdateProperty(Dictionary data) { } protected virtual void InvokeAfterUpdateProperty(Dictionary data) { } void UpdateValue(Dictionary data) { if (data == null) return; UpdateSubscribe(data, this); var properties = GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.GetCustomAttribute() != null); foreach (var property in properties) { var moduleAttr = property.GetCustomAttribute(); UpdateSubscribe(data, property.GetValue(this), moduleAttr.Module); } } protected void Subscribe(string key) { if (!string.IsNullOrEmpty(key)) { _subscribedKeys.Add(key); } } public void SubscribeKeys(TimeredMainViewModel target) { Parallel.ForEach(target.GetType().GetProperties().Where(_hasSubscriptionAttribute), property => { SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute; string key = subscription.ModuleKey; if (!_subscribedKeys.Contains(key)) _subscribedKeys.Add(key); }); Parallel.ForEach(target.GetType().GetFields().Where(_hasSubscriptionAttribute), method => { SubscriptionAttribute subscription = method.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute; string key = subscription.ModuleKey; if (!_subscribedKeys.Contains(key)) _subscribedKeys.Add(key); }); } public void UpdateSubscribe(Dictionary data, object target, string module = null) { Parallel.ForEach(target.GetType().GetProperties().Where(_hasSubscriptionAttribute), property => { PropertyInfo pi = (PropertyInfo)property; SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute; string key = subscription.ModuleKey; key = module == null ? key : string.Format("{0}.{1}", module, key); if (_subscribedKeys.Contains(key) && data.ContainsKey(key)) { try { var convertedValue = Convert.ChangeType(data[key], pi.PropertyType); var originValue = Convert.ChangeType(pi.GetValue(target, null), pi.PropertyType); if (originValue != convertedValue) { if (pi.Name == "PumpLimitSetPoint") pi.SetValue(target, convertedValue, null); else pi.SetValue(target, convertedValue, null); } } catch (Exception ex) { LOG.Error("由RT返回的数据更新失败" + key, ex); } } }); Parallel.ForEach(target.GetType().GetFields().Where(_hasSubscriptionAttribute), property => { FieldInfo pi = (FieldInfo)property; SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute; string key = subscription.ModuleKey; if (_subscribedKeys.Contains(key) && data.ContainsKey(key)) { try { var convertedValue = Convert.ChangeType(data[key], pi.FieldType); pi.SetValue(target, convertedValue); } catch (Exception ex) { LOG.Error("由RT返回的数据更新失败" + key, ex); } } }); } } public class MainViewModel : TimeredMainViewModel { public bool IsAutoLogout { get; set; } public int LogoutTime { get; set; } public ObservableCollection WarnEventLogList { get; set; } public ObservableCollection EventLogList { get; set; } public Visibility AllEventsVisibility { get; set; } public Visibility WarnEventsVisibility { get; set; } public bool IsAlarmListOpen { get; set; } [Subscription("Rt.Status")] public string RtStatus { get; set; } public string RtStatusBackground { get { return GetUnitStatusBackground(RtStatus); } } [Subscription("EFEM.FsmState")] public string EfemStatus { get; set; } public string EfemStatusBackground { get { return GetUnitStatusBackground(EfemStatus); } } public string HostStatusBackground { get { return $"{HostCommunicationStatus}"; } } [Subscription("System.ControlStatus")] public string HostControlStatus { get; set; } public string HostControlStatusBackground { get { switch (HostControlStatus) { case "Unknown": return "Yellow"; case "EquipmentOffline": case "AttemptOnline": case "HostOffline": return "Transparent"; case "OnlineLocal": case "OnlineRemote": return "LawnGreen"; default: return "Yellow"; } } } [Subscription("System.CommunicationStatus")] public string HostCommunicationStatus { get; set; } /// Disabled = 0, /// Enabled = 1, /// EnabledNotCommunicating = 2, /// EnabledCommunicating = 3, /// WaitCRA = 4, /// WaitDelay = 5, /// WaitCRFromHost = 6, public string HostCommunicationStatusBackground { get { switch (HostCommunicationStatus) { case "Disabled": return "Yellow"; case "Enabled": case "EnabledNotCommunicating": case "WaitCRA": case "WaitDelay": case "WaitCRFromHost": return "Transparent"; case "EnabledCommunicating": return "LawnGreen"; default: return "Yellow"; } } } public bool IsEnableFAEnable { get { return HostCommunicationStatus == "Disabled"; } } public bool IsDisableFAEnable { get { return HostCommunicationStatus != "Disabled"; } } [Subscription("PMA.FsmState")] public string PMAStatus { get; set; } public string PMAStatusBackground { get { return GetUnitStatusBackground(PMAStatus); } } [Subscription("PMB.FsmState")] public string PMBStatus { get; set; } public string PMBStatusBackground { get { return GetUnitStatusBackground(PMBStatus); } } [Subscription("LP1.CassettePresent")] public int LP1Present { get; set; } [Subscription("LP2.CassettePresent")] public int LP2Present { get; set; } [Subscription("PMA.IsOnline")] public bool PMAIsOnline { get; set; } public string PMA_TopFrame_TextColor { get { return PMAIsOnline ? "LimeGreen" : "White"; } } [Subscription("PMB.IsOnline")] public bool PMBIsOnline { get; set; } public string PMB_TopFrame_TextColor { get { return PMBIsOnline ? "LimeGreen" : "White"; } } [Subscription("System.SignalTower.DeviceData")] public AITSignalTowerData SignalTowerData { get; set; } private string _lastLoginName; public string LastLoginName { get { return _lastLoginName; } set { _lastLoginName = value; this.NotifyOfPropertyChange("LastLoginName"); } } private string _loginName; public string LoginName { get { return _loginName; } set { _loginName = value; this.NotifyOfPropertyChange("LoginName"); } } private string _roleName; public string RoleName { get { return _roleName; } set { _roleName = value; this.NotifyOfPropertyChange("RoleName"); } } [StructLayout(LayoutKind.Sequential)] internal struct LASTINPUTINFO { [MarshalAs(UnmanagedType.U4)] public int cbSize; [MarshalAs(UnmanagedType.U4)] public int dwTime; } [DllImport("user32.dll")] internal static extern bool GetLastInputInfo(ref LASTINPUTINFO plii); /// /// 获取鼠标键盘不活动的时间 /// /// 结果 public static int GetLastInputTime() { LASTINPUTINFO lastInputInfo = new LASTINPUTINFO(); lastInputInfo.cbSize = Marshal.SizeOf(lastInputInfo); lastInputInfo.dwTime = 0; int idleTime = 0; if (GetLastInputInfo(ref lastInputInfo)) { idleTime = Environment.TickCount - lastInputInfo.dwTime; } return ((idleTime > 0) ? (idleTime / 1000) : 0); } private bool _enablePopJobCompleteDialog = true; public MainViewModel() { BaseApp.Instance.Initialize(); ((VirgoUI.Client.ClientApp)BaseApp.Instance).ViewModelSwitcher = this; this._models = new Dictionary(); //for login part Roles = RoleAccountProvider.Instance.GetRoles(); EventLogList = new ObservableCollection(); EventClient.Instance.OnEvent += Instance_OnEvent; EventClient.Instance.OnDisconnectedWithRT += Instance_OnDisconnectedWithRT; EventClient.Instance.Start(); WarnEventLogList = new ObservableCollection(); SoftwareVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(); _enablePopJobCompleteDialog = (bool)QueryDataClient.Instance.Service.GetConfig("System.DisplayPopDialogWhenJobComplete"); } private void Instance_OnDisconnectedWithRT() { MessageBox.Show("Disconnected with RT, UI will exit", "Error", MessageBoxButton.OK, MessageBoxImage.Error); Environment.Exit(0); } public void ShowAlarmEvents() { AllEventsVisibility = Visibility.Hidden; WarnEventsVisibility = Visibility.Visible; this.NotifyOfPropertyChange("AllEventsVisibility"); this.NotifyOfPropertyChange("WarnEventsVisibility"); } public void ShowAllEvents() { AllEventsVisibility = Visibility.Visible; WarnEventsVisibility = Visibility.Hidden; this.NotifyOfPropertyChange("AllEventsVisibility"); this.NotifyOfPropertyChange("WarnEventsVisibility"); } private void Instance_OnEvent(EventItem obj) { switch (obj.Type) { case EventType.EventUI_Notify: LogEvent(obj); break; case EventType.Dialog_Nofity: PopDialog(obj); break; case EventType.KickOut_Notify: break; case EventType.Sound_Notify: break; case EventType.UIMessage_Notify: //PopUIMessage(obj); break; } } void PopDialog(EventItem item) { Application.Current.Dispatcher.Invoke(new System.Action(() => { switch (item.Level) { case EventLevel.Alarm: MessageBoxEx.ShowError(item.Description, item.Explaination); break; case EventLevel.Warning: MessageBoxEx.ShowWarning(item.Description, item.Explaination); break; case EventLevel.Information: MessageBoxEx.ShowInfo(item.Description, item.Explaination); break; case EventLevel.InformationNoDelay: ShowLotComplete(item.Explaination); //MessageBoxEx.ShowInfoNoDelay(item.Description, item.Explaination); break; } })); } LotCompleteDialogViewModel _lotCompleteDialog = new LotCompleteDialogViewModel(); void ShowLotComplete(string result) { _enablePopJobCompleteDialog = (bool)QueryDataClient.Instance.Service.GetConfig("System.DisplayPopDialogWhenJobComplete"); if (!_enablePopJobCompleteDialog) return; string[] info = result.Split(';'); if (info.Length > 5) { var module = info[0]; _lotCompleteDialog.DisplayName = "Information"; //LP;WaferSize;Lot;Number;Start;End; if (module == "LP1") { _lotCompleteDialog.LP1LotComplete.Module = "LP1"; _lotCompleteDialog.LP1LotComplete.LotID = info[2]; _lotCompleteDialog.LP1LotComplete.WaferNumber = info[3]; _lotCompleteDialog.LP1LotComplete.StartTime = info[4]; _lotCompleteDialog.LP1LotComplete.EndTime = info[5]; switch (info[1]) { case "WS3": _lotCompleteDialog.LP1LotComplete.WaferSize = $"WS{QueryDataClient.Instance.Service.GetConfig($"System.SmallWafer")}"; break; case "WS4": _lotCompleteDialog.LP1LotComplete.WaferSize = $"WS{QueryDataClient.Instance.Service.GetConfig($"System.MidWafer")}"; break; case "WS6": _lotCompleteDialog.LP1LotComplete.WaferSize = $"WS{QueryDataClient.Instance.Service.GetConfig($"System.BigWafer")}"; break; } _lotCompleteDialog.LP1LotComplete.InvokePropertyChanged(); } if (module == "LP2") { _lotCompleteDialog.LP2LotComplete.Module = "LP2"; _lotCompleteDialog.LP2LotComplete.LotID = info[2]; _lotCompleteDialog.LP2LotComplete.WaferNumber = info[3]; _lotCompleteDialog.LP2LotComplete.StartTime = info[4]; _lotCompleteDialog.LP2LotComplete.EndTime = info[5]; switch (info[1]) { case "WS3": _lotCompleteDialog.LP2LotComplete.WaferSize = $"WS{QueryDataClient.Instance.Service.GetConfig($"System.SmallWafer")}"; break; case "WS4": _lotCompleteDialog.LP2LotComplete.WaferSize = $"WS{QueryDataClient.Instance.Service.GetConfig($"System.MidWafer")}"; break; case "WS6": _lotCompleteDialog.LP2LotComplete.WaferSize = $"WS{QueryDataClient.Instance.Service.GetConfig($"System.BigWafer")}"; break; } _lotCompleteDialog.LP2LotComplete.InvokePropertyChanged(); } _lotCompleteDialog.SetVisible(module, true); } if (!_lotCompleteDialog.IsDisplayed) { _lotCompleteDialog.IsDisplayed = true; Task.Run(() => { Application.Current.Dispatcher.Invoke(() => { WindowManager wm = new WindowManager(); bool? bret = wm.ShowDialog(_lotCompleteDialog); if ((bool)bret) { } _lotCompleteDialog.IsDisplayed = false; }); }); } } void LogEvent(EventItem obj) { if (obj.Type != EventType.EventUI_Notify) return; Application.Current.Dispatcher.Invoke(() => { while (EventLogList.Count > 100) { EventLogList.RemoveAt(0); } EventLogList.Add(obj); if (obj.Level == EventLevel.Alarm) this.WarnEventLogList.Add(obj); }); if (this.WarnEventLogList.Count() > 1) this.IsAlarmListOpen = true; } void ResetAlarmList() { this.WarnEventLogList.Clear(); } #region login part public void Enter(KeyEventArgs args, string loginName, PasswordBox password, Role role) { if (args.Key == Key.Enter) this.Login(loginName, password, role); } public void Login(string loginName, PasswordBox password, Role role) { try { LoginResult result = AccountClient.Instance.Service.LoginEx(loginName, password.Password, role.RoleID); if (result.ActSucc) { ClientApp.Instance.UserContext.LoginId = result.SessionId; ClientApp.Instance.UserMode = UserMode.Normal; ClientApp.Instance.UserContext.LoginName = loginName; ClientApp.Instance.UserContext.Role = role; ClientApp.Instance.UserContext.RoleID = role.RoleID; ClientApp.Instance.UserContext.RoleName = role.RoleName; ClientApp.Instance.UserContext.LoginTime = DateTime.Now; //ClientApp.Instance.UserContext.Token = token; ClientApp.Instance.UserContext.LastAccessTime = DateTime.Now; ClientApp.Instance.UserContext.IsLogin = true; //Load menu by role //filer menu if necessary... ClientApp.Instance.MenuManager.LoadMenu(RoleAccountProvider.Instance.GetMenusByRole(role.RoleID, ClientApp.Instance.MenuLoader.MenuList)); IsAutoLogout = role.IsAutoLogout; LogoutTime = role.LogoutTime; InitMenu(); //bind menu to main view IsLogin = true; //control the display logic of main view //main view is common page, need register keys with true flag ClientApp.Instance.StatesManager.Register(new List() { "System.RtStatus" }, true); LoginName = loginName; RoleName = role.RoleName; LOG.Info(string.Format("{0} login as {1}", loginName, role.RoleName)); } else { Enum.TryParse(result.Description, out AuthorizeResult errCode); switch (errCode) { case AuthorizeResult.None: DialogBox.ShowError("Not connected with RT."); break; case AuthorizeResult.WrongPwd: DialogBox.ShowError("Invalid password."); break; case AuthorizeResult.HasLogin: DialogBox.ShowError("{0} has already logged in.", loginName); break; case AuthorizeResult.NoMatchRole: DialogBox.ShowError("{0} does not match {1} role.", loginName, role.RoleName); break; case AuthorizeResult.NoMatchUser: DialogBox.ShowError("{0} does not exists.", loginName); break; case AuthorizeResult.NoSession: DialogBox.ShowError("The current session is invalid."); break; } } password.Clear(); } catch (Exception ex) { LOG.Error(ex.Message, ex); } } #endregion login part public void Logout() { this.OnLogoutCommand(); } public void OnLogoutCommand() { WindowManager windowmanager = new WindowManager(); var logoffViewmodel = new LogoffViewModel(); windowmanager.ShowDialog(logoffViewmodel); BaseApp.Instance.UserMode = logoffViewmodel.DialogResult; switch (logoffViewmodel.DialogResult) { case UserMode.Logoff: BaseApp.Instance.UserMode = UserMode.Logoff; if (BaseApp.Instance.UserContext.IsLogin) { try { AccountClient.Instance.Service.LogoutEx(BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.LoginId); BaseApp.Instance.UserContext.IsLogin = false; LOG.Info(string.Format("{0} logoff as {1}", BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.RoleName)); } catch (Exception exp) { LOG.Write(exp); } } IsLogin = false; //no independent login page break; case UserMode.Exit: AccountClient.Instance.Service.LogoutEx(BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.LoginId); BaseApp.Instance.UserMode = UserMode.Exit; LOG.Info(string.Format("{0} exit as {1}", BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.RoleName)); MsgPool.TerminateAll(); this.TryClose(); break; case UserMode.Shutdown: AccountClient.Instance.Service.LogoutEx(BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.LoginId); ShutdownWindow = new ShutdownViewModel(); ShutdownThread = ShutdownExecute; windowmanager.ShowWindow(ShutdownWindow); ShutdownThread.BeginInvoke(ShutdownCallBack, ShutdownThread); break; } } public void Reset() { _trigGauge.RST = true; _trigAlarm.RST = true; _trigPMAStatsAlarm.RST = true; _trigPMBStatsAlarm.RST = true; _trigPMAStatsWarning.RST = true; _trigPMBStatsWarning.RST = true; InvokeClient.Instance.Service.DoOperation("System.Reset"); this.ResetAlarmList(); } public void BuzzerOff() { InvokeClient.Instance.Service.DoOperation($"{ModuleName.EFEM}.{EfemOperation.TurnOffBuzzer}"); } public void FAEnable() { InvokeClient.Instance.Service.DoOperation($"System.FACommand", "FAEnable"); } public void FADisable() { InvokeClient.Instance.Service.DoOperation($"System.FACommand", "FADisable"); } #region override functions public void Logoff() { BaseApp.Instance.UserMode = UserMode.Logoff; if (BaseApp.Instance.UserContext.IsLogin) { try { AccountClient.Instance.Service.LogoutEx(BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.LoginId); BaseApp.Instance.UserContext.IsLogin = false; LOG.Info(string.Format("{0} logoff as {1}", BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.RoleName)); } catch (Exception exp) { LOG.Write(exp); } } IsLogin = false; //no independent login page Roles = RoleAccountProvider.Instance.GetRoles(); } protected override bool OnTimer() { try { base.Poll(); List roles = RoleAccountProvider.Instance.GetRoles(); if (!string.IsNullOrEmpty(ClientApp.Instance.UserContext.RoleName)) { Role role = roles.Find(x => x.RoleName == ClientApp.Instance.UserContext.RoleName); LogoutTime = role.LogoutTime; IsAutoLogout = role.IsAutoLogout; int intervaltime = GetLastInputTime(); //if (System.DateTime.Now >= ClientApp.Instance.UserContext.LoginTime.AddMinutes(LogoutTime) && IsLogin && IsAutoLogout) if (intervaltime >= LogoutTime * 60 && IsLogin && IsAutoLogout) Logoff(); } } catch (Exception ex) { LOG.Error(ex.Message); } return true; } public override void CanClose(Action callback) { if (BaseApp.Instance.UserMode == UserMode.Normal) { callback(false); Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, (ThreadStart)delegate { this.OnLogoutCommand(); }); } else callback(true); } protected override void OnInitialize() { //display system version or other info... this.DisplayName = "JetPlasma"; base.OnInitialize(); this.StartTimer(); DrawSciChart(); //TODO, Login //Login("admin", new PasswordBox() { Password = "admin" }, new Role("0", "Manager", false, 1000, "")); } protected override void OnActivate() { base.OnActivate(); this.ShowAllEvents(); EnableTimer(true); } protected override void InvokeAfterUpdateProperty(Dictionary data) { base.InvokeAfterUpdateProperty(data); if (LP1Present == 0 && _lotCompleteDialog.IsDisplayed && _lotCompleteDialog.LP1Visibility==Visibility.Visible) { _lotCompleteDialog.LP1LotComplete.Clear(); _lotCompleteDialog.SetVisible("LP1", false); } if (LP2Present == 0 && _lotCompleteDialog.IsDisplayed && _lotCompleteDialog.LP2Visibility == Visibility.Visible) { _lotCompleteDialog.LP2LotComplete.Clear(); _lotCompleteDialog.SetVisible("LP2", false); } if (_lotCompleteDialog.LP1Visibility==Visibility.Hidden && _lotCompleteDialog.LP2Visibility == Visibility.Hidden && _lotCompleteDialog.IsDisplayed) { _lotCompleteDialog.TryClose(true); _lotCompleteDialog.IsDisplayed = false; } } void DrawSciChart() { // Create the chart surface var sciChartSurface = new SciChartSurface(); // Create the X and Y Axis var xAxis = new NumericAxis() { AxisTitle = "Number of Samples (per series)" }; var yAxis = new NumericAxis() { AxisTitle = "Value" }; sciChartSurface.XAxis = xAxis; sciChartSurface.YAxis = yAxis; // Specify Interactivity Modifiers sciChartSurface.ChartModifier = new ModifierGroup(new RubberBandXyZoomModifier(), new ZoomExtentsModifier()); // Add annotation hints to the user var textAnnotation = new TextAnnotation() { Text = "Hello World!", X1 = 5.0, Y1 = 5.0 }; sciChartSurface.Annotations.Add(textAnnotation); } protected override void OnViewLoaded(object view) { base.OnViewLoaded(view); this._view = view as MainView; this._view.tbLoginName.Focus(); } protected override void OnDeactivate(bool close) { base.OnDeactivate(close); EnableTimer(false); } #endregion override functions #region #region Sync ShutDown Thread public delegate void ShutDownSysncThread(); private ShutDownSysncThread ShutdownThread = null; private ShutdownViewModel ShutdownWindow = null; private void ShutdownExecute() { MsgPool.TerminateAll(); BaseApp.Instance.UserMode = UserMode.Shutdown; BaseApp.Instance.UserContext.IsLogin = false; LOG.Info(string.Format("{0} shutdown as {1}", BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.RoleName)); this.TryClose(); } private void ShutdownCallBack(IAsyncResult result) { if (ShutdownWindow != null) { ShutdownWindow.TryClose(); } ShutdownThread.EndInvoke(result); } #endregion Sync ShutDown Thread #region Menu Control and page switch private void InitMenu() { this.MenuItems = BaseApp.Instance.MenuManager.MenuItems; this.HistoryMenus = new ObservableCollection(); if (this.MenuItems.Count > 0) { foreach (AppMenu menuitem in this.MenuItems) { if (menuitem.MenuItems.Count > 0) { this.SwitchMenuItem(menuitem.MenuItems[0]); break; } } } } public void MainSwitchMenuItem(AppMenu menuViewItem) { if (menuViewItem.MenuItems.Count > 0) { if (menuViewItem.LastSelectedSubMenu != null) SwitchMenuItem(menuViewItem.LastSelectedSubMenu); else SwitchMenuItem(menuViewItem.MenuItems[0]); } } public void SwitchMenuItem(AppMenu menuViewItem, object queryFilter = null) { if (menuViewItem.ViewModel != null && menuViewItem.ViewModel != string.Empty) { if (menuViewItem.Model == null) { menuViewItem.Model = (BaseModel)AssemblyUtil.CreateInstance(AssemblyUtil.GetType(menuViewItem.ViewModel)); ((BaseModel)menuViewItem.Model).Permission = menuViewItem.Permission; ((BaseModel)menuViewItem.Model).Token = BaseApp.Instance.UserContext.Token; if (menuViewItem.Model is ISupportMultipleSystem) (menuViewItem.Model as ISupportMultipleSystem).SystemName = menuViewItem.System; if (menuViewItem.Model is RFCalibrationViewModel) { var viewModel = (menuViewItem.Model as RFCalibrationViewModel); if (viewModel.CustomParameter == null) viewModel.CustomParameter = new CustomCalibration(viewModel.SystemName); } } this.ActivateItem(((BaseModel)menuViewItem.Model)); CurrentViewModel = ((BaseModel)menuViewItem.Model); if (((BaseModel)menuViewItem.Model).Page != PageID.MAX_PAGE) BaseApp.Instance.SetCurrentPage(((BaseModel)menuViewItem.Model).Page); this.HandleSubAndHistoryMenu(menuViewItem); if (this._currentMenuItem != null) { this._currentMenuItem.Selected = false; this._currentMenuItem.Parent.Selected = false; } menuViewItem.Selected = true; menuViewItem.Parent.Selected = true; menuViewItem.Parent.LastSelectedSubMenu = menuViewItem; this._currentMenuItem = menuViewItem; if (queryFilter != null) { Task.Delay(1000).ContinueWith((x) => { var viewModel = (menuViewItem.Model as Models.History.ProcessHistory.ProcessHistoryViewModel); viewModel.Query(queryFilter); }); } } } private void HandleSubAndHistoryMenu(AppMenu menuitem) { this.SubMenuItems = menuitem.Parent.MenuItems; if (!this.HistoryMenus.Contains(menuitem)) { if (this.HistoryMenus.Count >= 8) this.HistoryMenus.RemoveAt(7); this.HistoryMenus.Insert(0, menuitem); } else { this.HistoryMenus.Remove(menuitem); this.HistoryMenus.Insert(0, menuitem); } } public bool SwitchPage(string firstLevelMenuID, string secondLevelMenuID, object queryFilter = null) { foreach (AppMenu menuitem in BaseApp.Instance.MenuManager.MenuItems) { if (menuitem.MenuID == firstLevelMenuID) { foreach (AppMenu menu in menuitem.MenuItems) { if (menu.MenuID == secondLevelMenuID) { SwitchMenuItem(menu, queryFilter); return true; } } } } return false; } #endregion Menu Control and page switch #region Refresh Date Time on page private void StartTimer() { System.Windows.Threading.DispatcherTimer myDispatcherTimer = new System.Windows.Threading.DispatcherTimer(); myDispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 1000); myDispatcherTimer.Tick += new EventHandler(Each_Tick); myDispatcherTimer.Start(); } public void Each_Tick(object o, EventArgs sender) { this.NowDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); this.NotifyOfPropertyChange("NowDateTime"); } #endregion Refresh Date Time on page #endregion public string NowDateTime { get; set; } private bool _IsLogin = false; public bool IsLogin { get { return _IsLogin; } set { _IsLogin = value; NotifyOfPropertyChange("IsLogin"); } } private List roles; public List Roles { get { return this.roles; } set { this.roles = value; this.RaisePropertyChangedEventImmediately("Roles"); } } private ICommand menuItemClickCommand; public ICommand MenuItemClickCommand { get { if (this.menuItemClickCommand == null) this.menuItemClickCommand = new BaseCommand((AppMenu menuViewItem) => this.SwitchMenuItem(menuViewItem)); return this.menuItemClickCommand; } } private ICommand mainmenuItemClickCommand; public ICommand MainMenuItemClickCommand { get { if (this.mainmenuItemClickCommand == null) this.mainmenuItemClickCommand = new BaseCommand((AppMenu menuViewItem) => this.MainSwitchMenuItem(menuViewItem)); return this.mainmenuItemClickCommand; } } public List MenuItems { get { return this.menuItems; } set { this.menuItems = value; this.NotifyOfPropertyChange("MenuItems"); } } public List SubMenuItems { get { return this.subMenuItems; } set { this.subMenuItems = value; this.NotifyOfPropertyChange("SubMenuItems"); } } public ObservableCollection HistoryMenus { get { return this.historyItems; } set { this.historyItems = value; this.NotifyOfPropertyChange("HistoryMenus"); } } public string Context { get { return this.context; } set { this.context = value; this.NotifyOfPropertyChange("Context"); } } public BaseModel CurrentViewModel { get; private set; } public UserContext User { get { return BaseApp.Instance.UserContext; } } private AppMenu _currentMenuItem; private List menuItems; private List subMenuItems; private ObservableCollection historyItems; private string context; private MainView _view; private Dictionary _models; } }