SicMultiplate/SicUI/MainViewModel.cs

1144 lines
40 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Aitex.Core.Account;
using Aitex.Core.Common.DeviceData;
using Aitex.Core.WCF;
using Caliburn.Micro;
using MECF.Framework.Common.Account.Extends;
using MECF.Framework.Common.DataCenter;
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.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
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.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;
using MECF.Framework.UI.Client.Ctrlib.Controls;
using System.Net;
using MECF.Framework.UI.Client.Core;
using MECF.Framework.UI.Client.ClientBase.Dialog;
using MECF.Framework.Common.Account.Permissions;
using MECF.Framework.Common.MECF.Framework.Common.SCCore;
namespace SicUI.Client
{
public class MainViewModel : TimeredMainViewModel
{
#region Variables
private MainView _view;
private AppMenu _alarmMenu;
private AppMenu _currentMenuItem;
private List<AppMenu> _menuItems;
private List<AppMenu> _subMenuItems;
private ObservableCollection<AppMenu> _historyItems;
private Dictionary<Type, BaseModel> _models;
private string _context;
private bool _isReadOnlyMode;
private readonly IEventAggregator _eventAggregator;
private readonly IProgress<Credential> _prgShowLoginRequestConfirmDialog;
private CancellationTokenSource _ctsLoginRequestConfirmDialog;
#endregion
#region Constructors
public MainViewModel(Cali.IEventAggregator eventAggregator)
{
((SicUI.Client.ClientApp)BaseApp.Instance).ViewModelSwitcher = this;
this._models = new Dictionary<Type, BaseModel>();
_eventAggregator = eventAggregator;
//for login part
Roles = RoleAccountProvider.Instance.GetRoles();
EventLogList = new DelayedPresentRollingObservableCollection<EventItem>(1000);
EventLogsView = CollectionViewSource.GetDefaultView(EventLogList);
//WarnEventLogList = new ObservableCollection<EventItem>();
SoftwareVersion = System.Reflection.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");
_prgShowLoginRequestConfirmDialog = new Progress<Credential>(ShowLoginRequestConfirmDialog);
Reset();
}
#endregion
#region Menus
public string NowDateTime { get; set; }
private bool _isLogin = false;
public bool IsLogin
{
get { return _isLogin; }
set { _isLogin = value; NotifyOfPropertyChange("IsLogin"); }
}
private List<Role> _roles;
public List<Role> 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>((AppMenu menuViewItem) => this.SwitchMenuItem(menuViewItem));
return this._menuItemClickCommand;
}
}
private ICommand _mainmenuItemClickCommand;
public ICommand MainMenuItemClickCommand
{
get
{
if (this._mainmenuItemClickCommand == null)
this._mainmenuItemClickCommand = new BaseCommand<AppMenu>((AppMenu menuViewItem) => this.MainSwitchMenuItem(menuViewItem));
return this._mainmenuItemClickCommand;
}
}
public List<AppMenu> MenuItems
{
get { return this._menuItems; }
set { this._menuItems = value; this.NotifyOfPropertyChange("MenuItems"); }
}
public List<AppMenu> SubMenuItems
{
get { return this._subMenuItems; }
set { this._subMenuItems = value; this.NotifyOfPropertyChange("SubMenuItems"); }
}
public ObservableCollection<AppMenu> 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 UserContext User { get { return BaseApp.Instance.UserContext; } }
#endregion
#region Properties
public BaseModel CurrentViewModel { get; private set; }
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 bool IsReadOnlyMode
{
get => _isReadOnlyMode;
set
{
_isReadOnlyMode = value;
NotifyOfPropertyChange();
if (_isReadOnlyMode)
{
BaseApp.Instance.UserMode = UserMode.ReadOnly;
// 通知RecipeEditor视图或PMProcess视图锁定Recipe
_eventAggregator.PublishOnUIThread(CommonAggregateEvents.EnterReadOnlyMode);
}
}
}
//public ObservableCollection<EventItem> WarnEventLogList { get; set; }
private DelayedPresentRollingObservableCollection<EventItem> EventLogList { get; }
/// <summary>
/// 用于在主界面显示Event Log的视图。
/// 通过该视图筛选IsAlarm条目。
/// </summary>
public ICollectionView EventLogsView { get; }
private bool _isShowAlarmEventOnly;
/// <summary>
/// IsAlarm CheckBox绑定到这里直接从<see cref="EventLogsView"/>中过滤所需的数据。
/// </summary>
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("PM1.IsBypassInterlock")]
public bool IsPM1InterlockBypassed { get; set; }
[Subscription("PM1.IsBypassEnableTable")]
public bool IsPM1EnableTableBypassed { get; set; }
public bool IsPM1Warning => IsPM1InterlockBypassed || IsPM1EnableTableBypassed;
public string PM1WarningMessage
{
get
{
if (IsPM1InterlockBypassed && IsPM1EnableTableBypassed)
return "PM1 Interlock and Enable Table are bypassed";
if (IsPM1InterlockBypassed)
return "PM1 Interlock is bypassed";
return "PM1 Enable Table is bypassed";
}
}
[Subscription("PM2.IsBypassInterlock")]
public bool IsPM2InterlockBypassed { get; set; }
[Subscription("PM2.IsBypassEnableTable")]
public bool IsPM2EnableTableBypassed { get; set; }
public bool IsPM2Warning => IsPM2InterlockBypassed || IsPM2EnableTableBypassed;
public string PM2WarningMessage
{
get
{
if (IsPM2InterlockBypassed && IsPM2EnableTableBypassed)
return "PM2 Interlock and Enable Table are bypassed";
if (IsPM2InterlockBypassed)
return "PM2 Interlock is bypassed";
return "PM2 Enable Table is bypassed";
}
}
[Subscription("TM.IsBypassInterlock")]
public bool IsTMInterlockBypassed { get; set; }
[Subscription("TM.IsBypassEnableTable")]
public bool IsTMEanbleTableBypassed { get; set; }
public bool IsTMWarning => IsTMInterlockBypassed || IsTMEanbleTableBypassed;
public string TMWarningMessage
{
get
{
if (IsTMInterlockBypassed && IsTMEanbleTableBypassed)
return "TM Interlock and Enable Table are bypassed";
if (IsTMInterlockBypassed)
return "TM Interlock is bypassed";
return "TM Enable Table is bypassed";
}
}
[Subscription("Rt.Status")]
public string RtStatus { get; set; }
[Subscription("PM1.Status")]
public string _PM1Status { get; set; }
public string PM1Status
{
get
{
if (IsPM1Installed)
return _PM1Status;
else
return "NotInstall";
}
set { _PM1Status = value; }
}
[Subscription("PM2.Status")]
public string _PM2Status { get; set; }
public string PM2Status
{
get
{
if (IsPM2Installed)
return _PM2Status;
else
return "NotInstall";
}
set { _PM2Status = value; }
}
[Subscription("Aligner.Status")]
public string AlignerStatus { get; set; }
[Subscription("CassAL.Status")]
public string CassALStatus { get; set; }
[Subscription("CassAR.Status")]
public string CassARStatus { get; set; }
[Subscription("CassBL.Status")]
public string CassBLStatus { get; set; }
[Subscription("UnLoad.Status")]
public string UnLoadStatus { get; set; }
[Subscription("EFEM.Status")]
public string EFEMStatus { get; set; }
[Subscription("Buffer.Status")]
public string BufferStatus { get; set; }
[Subscription("LoadLock.Status")]
public string LLStatus { get; set; }
[Subscription("TM.Status")]
public string TMStatus { get; set; }
[Subscription("WaferRobot.Status")]
public string WaferRobotStatus { get; set; }
[Subscription("TrayRobot.Status")]
public string TrayRobotStatus { get; set; }
[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("PM1.SignalTower.DeviceData")]
public AITSignalTowerData SignalTowerData { get; set; }
public string SoftwareVersion
{
get;
set;
}
public string RunTime => DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
[Subscription("System.HasActiveAlarm")]
public bool SystemHasAlarm { get; set; }
#endregion
#region Methods
private void Instance_OnDisconnectedWithRT()
{
MessageBox.Show("Disconnected with RT, UI will exit", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
Environment.Exit(0);
}
private void Instance_OnEvent(EventItem evt)
{
switch (evt.Type)
{
case EventType.EventUI_Notify:
LogEvent(evt);
break;
/*case EventType.Dialog_Nofity:
Execute.OnUIThread(() => DialogBox.ShowInfo(evt.ToString()));
break;*/
case EventType.KickOut_Notify:
if (evt.Description == "ShutDown")
{
AccountClient.Instance.Service.LogoutEx(BaseApp.Instance.UserContext.Token);
ShutdownThread = ShutdownExecute;
ShutdownThread.BeginInvoke(ShutdownCallBack, ShutdownThread);
}
break;
case EventType.Sound_Notify:
break;
case EventType.UIMessage_Notify:
//PopUIMessage(obj);
break;
}
}
#region Log
public void ShowAlarmEvents()
{
AllEventsVisibility = Visibility.Hidden;
WarnEventsVisibility = Visibility.Visible;
NotifyOfPropertyChange(nameof(AllEventsVisibility));
NotifyOfPropertyChange(nameof(WarnEventsVisibility));
}
public void ShowAllEvents()
{
AllEventsVisibility = Visibility.Visible;
WarnEventsVisibility = Visibility.Hidden;
NotifyOfPropertyChange(nameof(AllEventsVisibility));
NotifyOfPropertyChange(nameof(WarnEventsVisibility));
}
private void LogEvent(EventItem obj)
{
if (obj.Type != EventType.EventUI_Notify)
return;
EventLogList.Add(obj);
}
#endregion
public void SetModuleOnline(object sender, RoutedEventArgs args)
{
if (sender is ModuleStatusIndicator indicator)
{
if (indicator.HasWarning)
{
DialogBox.ShowError($"Unable to set {indicator.Caption} online since {indicator.WarningTip}");
return;
}
if (MessageBoxResult.Yes == MessageBox.Show($"Set {indicator.Caption} Online?", "", MessageBoxButton.YesNo, MessageBoxImage.Warning))
InvokeClient.Instance.Service.DoOperation($"{indicator.ModuleName}.SetOnline");
}
}
public void SetModuleOffline(object sender, RoutedEventArgs args)
{
if (sender is ModuleStatusIndicator indicator)
{
if (MessageBoxResult.Yes == MessageBox.Show($"Set {indicator.Caption} Offline?", "", MessageBoxButton.YesNo, MessageBoxImage.Warning))
{
InvokeClient.Instance.Service.DoOperation($"{indicator.ModuleName}.SetOffline");
}
}
}
public void Reset()
{
InvokeClient.Instance.Service.DoOperation("System.Reset");
}
public void BuzzerOff()
{
InvokeClient.Instance.Service.DoOperation($"System.AckAllAlarms");
}
#region Login/Logout Operations
private Task<LoginResult> _loginTask;
private LoginRequestWaitDialog _loginWaitDialog = null;
/// <summary>
/// 密码输入框中按下Enter键。
/// </summary>
/// <param name="args"></param>
/// <param name="loginName"></param>
/// <param name="password"></param>
/// <param name="role"></param>
public void PasswordBoxEnterKeyPressed(KeyEventArgs args, string loginName, PasswordBox password, Role role)
{
if (args.Key == Key.Enter)
RequestLogin(loginName, password, role);
}
/// <summary>
/// 显示远程登录请求确认对话框。
/// </summary>
/// <param name="credRequesting">正在请求登录的凭据</param>
private void ShowLoginRequestConfirmDialog(Credential credRequesting)
{
var dlgConfirm = new LoginRequestConfirmationDialog(credRequesting, _ctsLoginRequestConfirmDialog)
{
Owner = Application.Current.MainWindow
};
var retDlg = dlgConfirm.ShowDialog();
if (retDlg == true)
{
AccountClient.Instance.Service.ConfirmLoginRequest(credRequesting.AccountInfo.LoginName);
var role = BaseApp.Instance.UserContext.Role;
Logoff();
// 降级为仅查看模式
IsReadOnlyMode = true;
BaseApp.Instance.UserContext.Role = role;
BaseApp.Instance.UserContext.Credential = Credential.ReadOnlyOne;
}
else
{
AccountClient.Instance.Service.RejectLoginRequest(credRequesting.AccountInfo.LoginName);
}
}
/// <summary>
/// 显示登录确认等待对话框。
/// </summary>
/// <param name="cts"></param>
/// <returns></returns>
private Task ShowRequestLoginWaiter(CancellationTokenSource cts)
{
var ct = cts.Token;
return Task.Run(() =>
{
/*bool? waitResult = null;*/
// 如果超过一定时间没有从RT返回确认信息则显示登录中的提示
Thread.Sleep(500);
if (ct.IsCancellationRequested)
return;
Execute.OnUIThread(() =>
{
_loginWaitDialog = new LoginRequestWaitDialog()
{
Owner = Application.Current.MainWindow
};
_loginWaitDialog.ShowDialog();
});
/*while (true)
{
Thread.Sleep(500);
// 等待对话框关闭不关心返回的DialogResult
// 关闭原因:
// 1. 点击Cancel按钮
// 2. 超时
// 3. 远端接受或拒绝请求
if (waitResult.HasValue)
break;
if (ct.IsCancellationRequested)
break;
}
// 强制关闭等待对话框
Execute.OnUIThread(() =>
{
loginWaitDialog?.Close();
});*/
}, ct);
}
public async void RequestLogin(string loginName, PasswordBox password, Role role)
{
if (_loginTask is { Status: TaskStatus.Running })
return;
#region Validate Parameters
if (string.IsNullOrEmpty(loginName))
{
DialogBox.ShowError("User Name can not be empty.");
return;
}
if (string.IsNullOrEmpty(password.Password))
{
DialogBox.ShowError("Password can not be empty.");
return;
}
if (role == null || string.IsNullOrEmpty(role.RoleId))
{
DialogBox.ShowError("Role can not be empty.");
return;
}
#endregion
// 向RT请求登录
try
{
var ctsWaitingTask = new CancellationTokenSource();
var taskWaiting = ShowRequestLoginWaiter(ctsWaitingTask);
_loginTask = AccountClient.Instance.Service.LoginEx(loginName, password.Password, role?.RoleId ?? "",
BaseApp.Instance.ClientInfo);
// 等待确认超时,或已被接受/拒绝登录
await Task.WhenAny(_loginTask, taskWaiting);
if (_loginTask.Status == TaskStatus.RanToCompletion)
{
// 被接受或拒绝登录
ctsWaitingTask.Cancel();
_loginWaitDialog?.Close();
switch (_loginTask.Result.Result)
{
case LoginRequestResults.Error:
DialogBox.ShowError("Error occurred when login, see log for details.");
break;
case LoginRequestResults.WrongPwd:
DialogBox.ShowError("Invalid password.");
break;
case LoginRequestResults.NoMatchRole:
DialogBox.ShowError("The user does not belong to the role.");
break;
case LoginRequestResults.NoMatchUser:
DialogBox.ShowError("The user is not found.");
break;
case LoginRequestResults.Rejected:
DialogBox.ShowError("Login Request is rejected.");
break;
case LoginRequestResults.RequstingLogin:
DialogBox.ShowError(
"The same user is requesting to login from other place, please try again later.");
break;
case LoginRequestResults.Timeout:
DialogBox.ShowError("Timeout to wait login request confirmation.");
break;
case LoginRequestResults.Confirmed:
var cred = _loginTask.Result.Credential;
BaseApp.Instance.UserMode = UserMode.Normal;
BaseApp.Instance.UserContext.Credential = cred;
BaseApp.Instance.UserContext.Role = role;
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.GetAccessibleMenusByRole(role.RoleId));
IsAutoLogout = role.IsAutoLogout;
LogoutTime = role.LogoutTime;
IsPermission = RoleAccountProvider.Instance.GetMenuPermission(role.RoleId, "Header") == MenuPermissionEnum.MP_READ_WRITE;
InitMenu(); //bind menu to main view
IsLogin = true; //control the display logic of main view
IsReadOnlyMode = false;
LOG.Info($"{loginName} login as {role.RoleName}");
break;
default:
DialogBox.ShowError("Unknown login result, see log for details.");
break;
}
}
else if (taskWaiting.Status == TaskStatus.RanToCompletion)
{
// 等待确认超时
// 注意该请求在RT的存活时间比UI超时时间长因此需要显式取消请求否则下次登录请求需要等CredentialManager超时后才能重新发起
AccountClient.Instance.Service.CancelLoginRequest(loginName);
}
else
{
// 两个任务均失败显式调用下列方法强制RT清理凭据。
AccountClient.Instance.Service.CancelLoginRequest(loginName);
}
}
catch (InvalidOperationException ex)
{
LOG.Error(ex.Message);
}
catch (Exception ex)
{
LOG.Error(ex.Message);
}
}
public void ShowLogoutDialog()
{
if (!IsReadOnlyMode)
{
var 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.Token);
BaseApp.Instance.UserMode = UserMode.Exit;
LOG.Info($"{BaseApp.Instance.UserContext.LoginName} exit as {BaseApp.Instance.UserContext.Role.RoleName}");
TryClose();
break;
case UserMode.Shutdown:
//配置立即生效。
var roleId = BaseApp.Instance.UserContext.Role.RoleId;
var canShutDown =
RoleAccountProvider.Instance.GetMenuPermission(roleId, "Operation.Behaviour.ShutDown") ==
MenuPermissionEnum.MP_READ_WRITE;
if (canShutDown)
InvokeClient.Instance.Service.DoOperation("System.ShutDown");
else
{
DialogBox.ShowError("No Permission for ShutDown");
}
break;
}
_eventAggregator.PublishOnUIThread(logoffViewmodel.DialogResult);
}
else
{
Logoff();
IsReadOnlyMode = false;
}
}
public void Logoff()
{
BaseApp.Instance.UserMode = UserMode.Logoff;
if (BaseApp.Instance.UserContext.IsLogin)
{
try
{
AccountClient.Instance.Service.LogoutEx(BaseApp.Instance.UserContext.Token);
LOG.Info(
$"{BaseApp.Instance.UserContext.LoginName} logoff as {BaseApp.Instance.UserContext.Role.RoleName}");
BaseApp.Instance.UserContext.Clear();
ClearItems();
}
catch (Exception exp)
{
LOG.Write(exp);
}
}
IsLogin = false; //no independent login page
Roles = RoleAccountProvider.Instance.GetRoles();
}
#endregion
#region Overrided Functions
public override void CanClose(Action<bool> callback)
{
if (BaseApp.Instance.UserMode == UserMode.Normal)
{
callback(false);
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, (ThreadStart)ShowLogoutDialog);
}
else
callback(true);
}
protected override void OnInitialize()
{
//display system version or other info...
this.DisplayName = "Sic Auto-GE";
base.OnInitialize();
this.StartTimer();
List<ConfigChangedInfo> s = (List<ConfigChangedInfo>)QueryDataClient.Instance.Service.GetConfig("SystemConfig.DataChangedList");
if (s != null && s.Count > 0)
{
string tips = "";
foreach (var t in s)
{
var value = QueryDataClient.Instance.Service.GetConfig(t.Name);
if (value != null)
{
tips += t.Name + (t.Enable ? " " : " HAS ") + "CHANGED:\r\n(Previous)\t" + t.OldValue + " => " + value.ToString() + "\t(Latest)\r\n";
}
}
if (tips != "")
{
DialogBox.ShowInfo("There are some changes in SystemConfig,\r\n" +
"please make sure those changes are OK:\r\n" +
"****************************************************\r\n" + tips);
InvokeClient.Instance.Service.DoOperation("SystemConfig.Confirm");
}
}
if (Debugger.IsAttached)
{
RequestLogin("admin", new PasswordBox() { Password = "admin" }, new Role("0", "Manager", false, 1000, null));
}
}
protected override void OnActivate()
{
base.OnActivate();
this.ShowAllEvents();
EnableTimer(true);
}
protected override void OnViewLoaded(object view)
{
base.OnViewLoaded(view);
this._view = view as MainView;
this._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($"{BaseApp.Instance.UserContext.LoginName} shutdown as {BaseApp.Instance.UserContext.Role.RoleName}");
this.TryClose();
}
private void ShutdownCallBack(IAsyncResult result)
{
if (ShutdownWindow != null)
{
ShutdownWindow.TryClose();
}
ShutdownThread.EndInvoke(result);
}
#endregion
#region Menu Control and page switch
private void InitMenu()
{
this.MenuItems = BaseApp.Instance.MenuManager.MenuItems;
this.SubMenuItems = new List<AppMenu>();
this.HistoryMenus = new ObservableCollection<AppMenu>();
if (this.MenuItems.Count > 0)
{
AppMenu _default = null;
foreach (AppMenu menuitem in this.MenuItems)
{
if (menuitem.MenuItems.Count > 0)
{
if (menuitem.AlarmModule == "System")
{
_alarmMenu = menuitem;
break;
}
if (_default == null)
_default = menuitem.MenuItems[0];
}
}
this.SwitchMenuItem(_default);
}
}
public void MainSwitchMenuItem(AppMenu menuViewItem)
{
if (menuViewItem.MenuItems.Count <= 0)
return;
SwitchMenuItem(menuViewItem.LastSelectedSubMenu ?? menuViewItem.MenuItems[0]);
}
public void SwitchMenuItem(AppMenu menuViewItem)
{
if (string.IsNullOrEmpty(menuViewItem.ViewModel))
return;
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 smsViewModel)
smsViewModel.SystemName = menuViewItem.System;
}
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;
}
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)
{
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<string, object> data)
{
if (_alarmMenu != null)
_alarmMenu.IsAlarm = SystemHasAlarm;
}
protected override bool OnTimer()
{
try
{
base.Poll();
List<Role> roles = RoleAccountProvider.Instance.GetRoles();
if (!Credential.IsEmpty(BaseApp.Instance.UserContext.Credential))
{
Role role = roles.Find(x => x.RoleName == ClientApp.Instance.UserContext.Role.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();
else
{
// keep credential alive
var retKeepAlive = AccountClient.Instance.Service.KeepAlive(BaseApp.Instance.UserContext.Token);
switch (retKeepAlive.State)
{
case CredentialKeepAliveStates.Alive or CredentialKeepAliveStates.NotFound:
{
if (_ctsLoginRequestConfirmDialog is { IsCancellationRequested: false })
_ctsLoginRequestConfirmDialog.Cancel();
if (retKeepAlive.State == CredentialKeepAliveStates.NotFound)
{
Logoff();
Execute.OnUIThread(() => { DialogBox.ShowError("You are kicked by RT."); });
}
break;
}
case CredentialKeepAliveStates.RequestingLogin:
{
// 当前用户在其它地方请求登录
if (_ctsLoginRequestConfirmDialog == null ||
_ctsLoginRequestConfirmDialog.IsCancellationRequested)
{
_ctsLoginRequestConfirmDialog = new CancellationTokenSource();
_prgShowLoginRequestConfirmDialog.Report(retKeepAlive.RequestingCredential);
}
/* Execute.OnUIThread(() =>
{
var dlgConfirm = new LoginRequestConfirmationDialog(retKeepAlive.RequestingCredential);
var retDlg = dlgConfirm.ShowDialog();
if (retDlg == true)
{
AccountClient.Instance.Service.ConfirmLoginRequest(retKeepAlive.RequestingCredential.AccountInfo.LoginName);
Logoff();
// 降级为仅查看模式
IsReadOnlyMode = true;
BaseApp.Instance.UserContext.Role = role;
BaseApp.Instance.UserContext.Credential = Credential.ReadOnlyOne;
}
else
{
AccountClient.Instance.Service.RejectLoginRequest(retKeepAlive.RequestingCredential.AccountInfo.LoginName);
}
});*/
// 等待RT处理凭据否则有可能反复触发请求登录确认窗口.
Thread.Sleep(1000);
break;
}
}
}
}
}
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(nameof(NowDateTime));
}
#endregion
#endregion
#endregion
}
}