using Aitex.Core.Account; using Aitex.Core.Common.DeviceData; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.Util; using Aitex.Core.WCF; using Caliburn.Micro; using MECF.Framework.Common.Account.Extends; using MECF.Framework.UI.Client.CenterViews.LogOnOff; using MECF.Framework.UI.Client.ClientBase; using MECF.Framework.UI.Core.Accounts; using OpenSEMI.ClientBase; using OpenSEMI.ClientBase.Command; using OpenSEMI.ClientBase.Utility; using SciChart.Charting.ChartModifiers; using SciChart.Charting.Visuals; using SciChart.Charting.Visuals.Annotations; using SciChart.Charting.Visuals.Axes; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Reflection; using System.Threading; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Input; using System.Windows.Threading; using Sicentury.Core.Collections; using Cali = Caliburn.Micro.Core; using System.Diagnostics; using Caliburn.Micro.Core; namespace SicUI.Client { public class MainViewModel : TimeredMainViewModel { #region Menus public string NowDateTime { get; set; } private bool _IsLogin = false; public bool IsLogin { get => _IsLogin; set { _IsLogin = value; NotifyOfPropertyChange(); } } private List roles; public List Roles { get => roles; set { roles = value; RaisePropertyChangedEventImmediately("Roles"); } } private ICommand menuItemClickCommand; public ICommand MenuItemClickCommand { get { if (menuItemClickCommand == null) menuItemClickCommand = new BaseCommand((AppMenu menuViewItem) => SwitchMenuItem(menuViewItem)); return menuItemClickCommand; } } private ICommand mainmenuItemClickCommand; public ICommand MainMenuItemClickCommand { get { if (mainmenuItemClickCommand == null) mainmenuItemClickCommand = new BaseCommand((AppMenu menuViewItem) => MainSwitchMenuItem(menuViewItem)); return mainmenuItemClickCommand; } } public List MenuItems { get => menuItems; set { menuItems = value; NotifyOfPropertyChange(); } } public List SubMenuItems { get => subMenuItems; set { subMenuItems = value; NotifyOfPropertyChange(); } } public ObservableCollection HistoryMenus { get => historyItems; set { historyItems = value; NotifyOfPropertyChange(); } } public string Context { get => context; set { context = value; NotifyOfPropertyChange(); } } public BaseModel CurrentViewModel { get; private set; } public UserContext User => BaseApp.Instance.UserContext; private AppMenu _currentMenuItem; private List menuItems; private List subMenuItems; private ObservableCollection historyItems; private string context; private MainView _view; private Dictionary _models; #endregion public bool IsPM1Installed { get; set; } public bool IsPM2Installed { get; set; } public bool IsBufferInstalled { get; set; } public bool IsLLInstalled { get; set; } public bool IsPermission { get; set; } public bool IsAutoLogout { get; set; } public int LogoutTime { get; set; } //public ObservableCollection WarnEventLogList { get; set; } private DelayedPresentRollingObservableCollection EventLogList { get; } /// /// 用于在主界面显示Event Log的视图。 /// 通过该视图筛选IsAlarm条目。 /// public ICollectionView EventLogsView { get; } private bool _isShowAlarmEventOnly; /// /// IsAlarm CheckBox绑定到这里,直接从中过滤所需的数据。 /// public bool IsShowAlarmEventOnly { get => _isShowAlarmEventOnly; set { _isShowAlarmEventOnly = value; if (_isShowAlarmEventOnly) { EventLogsView.Filter = item => { if (item is EventItem ei) { return ei.Level == EventLevel.Alarm; } return false; }; } else { EventLogsView.Filter = null; } OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsShowAlarmEventOnly))); } } public Visibility AllEventsVisibility { get; set; } public Visibility WarnEventsVisibility { get; set; } [Subscription("Rt.Status")] public string RtStatus { get; set; } public string RtStatusBackground => ModuleStatusBackground.GetStatusBackground(RtStatus); [Subscription("System.ControlStatus")] public string ControlStatus { get; set; } [Subscription("System.CommunicationStatus")] public string HostStatus { get; set; } public string HostStatusBackground { get { switch (HostStatus) { case "Disabled": return "Yellow"; case "Enabled": case "EnabledNotCommunicating": case "WaitCRA": case "WaitDelay": case "WaitCRFromHost": return "Transparent"; case "EnabledCommunicating": return "LawnGreen"; default: return "Yellow"; } } } [Subscription("PM1.Status")] public string _PM1Status { get; set; } public string PM1Status { get { if (IsPM1Installed) return _PM1Status; else return "NotInstall"; } set => _PM1Status = value; } public string PM1StatusBackground => ModuleStatusBackground.GetStatusBackground(PM1Status); [Subscription("PM2.Status")] public string _PM2Status { get; set; } public string PM2Status { get { if (IsPM2Installed) return _PM2Status; else return "NotInstall"; } set => _PM2Status = value; } public string PM2StatusBackground => ModuleStatusBackground.GetStatusBackground(PM2Status); [Subscription("Aligner.Status")] public string AlignerStatus { get; set; } public string AlignerStatusBackground => ModuleStatusBackground.GetStatusBackground(AlignerStatus); [Subscription("CassAL.Status")] public string CassALStatus { get; set; } public string CassALStatusBackground => ModuleStatusBackground.GetStatusBackground(CassALStatus); [Subscription("CassAR.Status")] public string CassARStatus { get; set; } public string CassARStatusBackground => ModuleStatusBackground.GetStatusBackground(CassARStatus); [Subscription("CassBL.Status")] public string CassBLStatus { get; set; } public string CassBLStatusBackground => ModuleStatusBackground.GetStatusBackground(CassBLStatus); //[Subscription("UnLoad.Status")] public string UnLoadStatus { get => "NotInstall"; set { } } public string UnLoadStatusBackground => ModuleStatusBackground.GetStatusBackground(UnLoadStatus); [Subscription("EFEM.Status")] public string EFEMStatus { get; set; } public string EFEMStatusBackground => ModuleStatusBackground.GetStatusBackground(EFEMStatus); [Subscription("Buffer.Status")] public string BufferStatus { get; set; } public string BufferStatusBackground => ModuleStatusBackground.GetStatusBackground(BufferStatus); [Subscription("LoadLock.Status")] public string LLStatus { get; set; } public string LLStatusBackground => ModuleStatusBackground.GetStatusBackground(LLStatus); [Subscription("TM.Status")] public string TMStatus { get; set; } public string TMStatusBackground => ModuleStatusBackground.GetStatusBackground(TMStatus); [Subscription("WaferRobot.Status")] public string WaferRobotStatus { get; set; } public string WaferRobotStatusBackground => ModuleStatusBackground.GetStatusBackground(WaferRobotStatus); [Subscription("TrayRobot.Status")] public string TrayRobotStatus { get; set; } public string TrayRobotStatusBackground => ModuleStatusBackground.GetStatusBackground(TrayRobotStatus); [Subscription("System.IsOnline")] public bool IsOnlineSystem { get; set; } [Subscription("PM1.IsOnline")] public bool IsOnlinePM1 { get; set; } [Subscription("PM2.IsOnline")] public bool IsOnlinePM2 { get; set; } [Subscription("EFEM.IsOnline")] public bool IsOnlineEFEM { get; set; } [Subscription("Aligner.IsOnline")] public bool IsOnlineAligner { get; set; } [Subscription("CassAL.IsOnline")] public bool IsOnlineCassAL { get; set; } [Subscription("CassBL.IsOnline")] public bool IsOnlineCassBL { get; set; } [Subscription("CassAR.IsOnline")] public bool IsOnlineCassAR { get; set; } [Subscription("UnLoad.IsOnline")] public bool IsOnlineUnLoad { get; set; } [Subscription("LoadLock.IsOnline")] public bool IsOnlineLL { get; set; } [Subscription("TM.IsOnline")] public bool IsOnlineTM { get; set; } [Subscription("Buffer.IsOnline")] public bool IsOnlineBuffer { get; set; } [Subscription("WaferRobot.IsOnline")] public bool IsOnlineWaferRobot { get; set; } [Subscription("TrayRobot.IsOnline")] public bool IsOnlineTrayRobot { get; set; } [Subscription("System.SignalTowerData")] public AITSignalTowerData SignalTowerData { get; set; } public string SoftwareVersion { get; set; } [Subscription("System.IsEngMode")] public bool IsEngMode { get; set; } public string RunTime => DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); [Subscription("System.HasActiveAlarm")] public bool SystemHasAlarm { get; set; } private AppMenu _alarmMenu; private readonly IEventAggregator _eventAggregator; public MainViewModel(IEventAggregator eventAggregator) { BaseApp.Instance.Initialize(); ((ClientApp)BaseApp.Instance).ViewModelSwitcher = this; _models = new Dictionary(); _eventAggregator = eventAggregator; //for login part Roles = RoleAccountProvider.Instance.GetRoles(); EventLogList = new DelayedPresentRollingObservableCollection(1000); EventLogsView = CollectionViewSource.GetDefaultView(EventLogList); //WarnEventLogList = new ObservableCollection(); SoftwareVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); EventClient.Instance.OnEvent += Instance_OnEvent; EventClient.Instance.OnDisconnectedWithRT += Instance_OnDisconnectedWithRT; EventClient.Instance.Start(); IsPM1Installed = (bool)QueryDataClient.Instance.Service.GetConfig("System.SetUp.IsPM1Installed"); IsPM2Installed = (bool)QueryDataClient.Instance.Service.GetConfig("System.SetUp.IsPM2Installed"); IsBufferInstalled = (bool)QueryDataClient.Instance.Service.GetConfig("System.SetUp.IsBufferInstalled"); IsLLInstalled = (bool)QueryDataClient.Instance.Service.GetConfig("System.SetUp.IsLoadLockInstalled"); Reset(); } 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; NotifyOfPropertyChange("AllEventsVisibility"); NotifyOfPropertyChange("WarnEventsVisibility"); } public void ShowAllEvents() { AllEventsVisibility = Visibility.Visible; WarnEventsVisibility = Visibility.Hidden; NotifyOfPropertyChange("AllEventsVisibility"); 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: if (obj.Description == "ShutDown") { AccountClient.Instance.Service.LogoutEx(BaseApp.Instance.UserContext.LoginName, BaseApp.Instance.UserContext.LoginId); ShutdownThread = ShutdownExecute; ShutdownThread.BeginInvoke(ShutdownCallBack, ShutdownThread); } break; case EventType.Sound_Notify: break; case EventType.UIMessage_Notify: //PopUIMessage(obj); break; } } private void LogEvent(EventItem obj) { if (obj.Type != EventType.EventUI_Notify) return; EventLogList.Add(obj); } #region login part public void Enter(KeyEventArgs args, string loginName, PasswordBox password, Role role) { if (args.Key == Key.Enter) 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) { BaseApp.Instance.UserContext.LoginId = result.SessionId; BaseApp.Instance.UserMode = UserMode.Normal; BaseApp.Instance.UserContext.LoginName = loginName; BaseApp.Instance.UserContext.Role = role; BaseApp.Instance.UserContext.RoleID = role.RoleID; BaseApp.Instance.UserContext.RoleName = role.RoleName; BaseApp.Instance.UserContext.LoginTime = DateTime.Now; //ClientApp.Instance.UserContext.Token = token; BaseApp.Instance.UserContext.LastAccessTime = DateTime.Now; BaseApp.Instance.UserContext.IsLogin = true; //Load menu by role //filer menu if necessary... BaseApp.Instance.MenuManager.LoadMenu(RoleAccountProvider.Instance.GetMenusByRole(role.RoleID, BaseApp.Instance.MenuLoader.MenuList)); IsAutoLogout = role.IsAutoLogout; LogoutTime = role.LogoutTime; IsPermission = RoleAccountProvider.Instance.GetMenuPermission(role.RoleID, "Header") == 3; InitMenu(); //bind menu to main view IsLogin = true; //control the display logic of main view 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 public void SetModuleOnline(string module) { if (MessageBoxResult.Yes == MessageBox.Show($"Set {module} Online ?", "", MessageBoxButton.YesNo, MessageBoxImage.Warning)) { InvokeClient.Instance.Service.DoOperation($"{module}.SetOnline"); } } public void SetModuleOffline(string module) { if (MessageBoxResult.Yes == MessageBox.Show($"Set {module} Offline ?", "", MessageBoxButton.YesNo, MessageBoxImage.Warning)) { InvokeClient.Instance.Service.DoOperation($"{module}.SetOffline"); } } public void Logout() { 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: Logoff(); 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)); TryClose(); break; case UserMode.Shutdown: //配置立即生效。 string roleID2 = BaseApp.Instance.UserContext.RoleID; bool canShutDown = RoleAccountProvider.Instance.GetMenuPermission(roleID2, "Operation.Behaviour.ShutDown") == 3; if (canShutDown) InvokeClient.Instance.Service.DoOperation("System.ShutDown"); else { DialogBox.ShowError("No Permission for ShutDown"); } break; } _eventAggregator.PublishOnUIThread(logoffViewmodel.DialogResult); } 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( $"{BaseApp.Instance.UserContext.LoginName} logoff as {BaseApp.Instance.UserContext.RoleName}"); } catch (Exception exp) { LOG.Write(exp); } } IsLogin = false; //no independent login page Roles = RoleAccountProvider.Instance.GetRoles(); // 如果 ProcessMonitor 打开,则关闭 //if (_eventAggregator?.HandlerExistsFor(typeof(ShowCloseMonitorWinEvent)) == true) // _eventAggregator?.PublishOnUIThread(new ShowCloseMonitorWinEvent(false)); } public void Reset() { InvokeClient.Instance.Service.DoOperation("System.Reset"); } public void BuzzerOff() { InvokeClient.Instance.Service.DoOperation($"System.AckAllAlarms"); } #region override functions public override void CanClose(Action callback) { if (BaseApp.Instance.UserMode == UserMode.Normal) { callback(false); Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, (ThreadStart)delegate { OnLogoutCommand(); }); } else callback(true); } protected override void OnInitialize() { //display system version or other info... DisplayName = "Sic - GE Manual"; base.OnInitialize(); StartTimer(); DrawSciChart(); if (Debugger.IsAttached) { Login("admin", new PasswordBox() { Password = "admin" }, new Role("0", "Manager", false, 1000, "")); } } protected override void OnActivate() { base.OnActivate(); ShowAllEvents(); EnableTimer(true); } 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); _view = view as MainView; _view.tbLoginName.Focus(); _view.SplashScreen?.Complete(); } protected override void OnDeactivate(bool close) { base.OnDeactivate(close); EnableTimer(false); } #endregion #region #region Sync ShutDown Thread public delegate void ShutDownSysncThread(); ShutDownSysncThread ShutdownThread = null; ShutdownViewModel ShutdownWindow = null; private void ShutdownExecute() { 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)); TryClose(); } private void ShutdownCallBack(IAsyncResult result) { if (ShutdownWindow != null) { ShutdownWindow.TryClose(); } ShutdownThread.EndInvoke(result); } #endregion #region Menu Control and page switch private void InitMenu() { MenuItems = BaseApp.Instance.MenuManager.MenuItems; SubMenuItems = new List(); HistoryMenus = new ObservableCollection(); if (MenuItems.Count > 0) { AppMenu _default = null; foreach (AppMenu menuitem in MenuItems) { if (menuitem.MenuItems.Count > 0) { if (menuitem.AlarmModule == "System") { _alarmMenu = menuitem; break; } if (_default == null) _default = menuitem.MenuItems[0]; } } SwitchMenuItem(_default); } } 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) { 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; } ActivateItem(((BaseModel)menuViewItem.Model)); CurrentViewModel = ((BaseModel)menuViewItem.Model); //if (((BaseModel)menuViewItem.Model).Page != PageID.MAX_PAGE) // BaseApp.Instance.SetCurrentPage(((BaseModel)menuViewItem.Model).Page); HandleSubAndHistoryMenu(menuViewItem); if (_currentMenuItem != null) { _currentMenuItem.Selected = false; _currentMenuItem.Parent.Selected = false; } menuViewItem.Selected = true; menuViewItem.Parent.Selected = true; menuViewItem.Parent.LastSelectedSubMenu = menuViewItem; _currentMenuItem = menuViewItem; } } private void HandleSubAndHistoryMenu(AppMenu menuitem) { SubMenuItems = menuitem.Parent.MenuItems; if (!HistoryMenus.Contains(menuitem)) { if (HistoryMenus.Count >= 8) HistoryMenus.RemoveAt(7); HistoryMenus.Insert(0, menuitem); } else { HistoryMenus.Remove(menuitem); HistoryMenus.Insert(0, menuitem); } } public bool SwitchPage(string firstLevelMenuID, string secondLevelMenuID) { foreach (AppMenu menuitem in BaseApp.Instance.MenuManager.MenuItems) { if (menuitem.MenuID == firstLevelMenuID) { foreach (AppMenu menu in menuitem.MenuItems) { if (menu.MenuID == secondLevelMenuID) { SwitchMenuItem(menu); return true; } } } } return false; } #endregion #region Refresh Date Time on page protected override void InvokeAfterUpdateProperty(Dictionary data) { if (_alarmMenu != null) _alarmMenu.IsAlarm = SystemHasAlarm; } protected override bool OnTimer() { try { base.Poll(); List roles = RoleAccountProvider.Instance.GetRoles(); if (!string.IsNullOrEmpty(BaseApp.Instance.UserContext.RoleName)) { Role role = roles.Find(x => x.RoleName == BaseApp.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; } private void StartTimer() { DispatcherTimer myDispatcherTimer = new 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) { NowDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); NotifyOfPropertyChange("NowDateTime"); } #endregion #endregion } }