Sic03-8inch/SicUI/MainViewModel.cs

1180 lines
42 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.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
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 System.Diagnostics;
using Caliburn.Micro.Core;
using MECF.Framework.Common.Account.Permissions;
using MECF.Framework.Common.MECF.Framework.Common.SCCore;
using MECF.Framework.UI.Client.ClientBase.Dialog;
using MECF.Framework.UI.Client.Core;
using MECF.Framework.UI.Client.Ctrlib.Controls;
namespace SicUI
{
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 string _context;
private bool _isReadOnlyMode;
private readonly IEventAggregator _eventAggregator;
private readonly IProgress<Credential> _prgShowLoginRequestConfirmDialog;
private CancellationTokenSource _ctsLoginRequestConfirmDialog;
#endregion
#region Constructors
public MainViewModel(IEventAggregator eventAggregator)
{
BaseApp.Instance.Initialize();
((ClientApp)BaseApp.Instance).ViewModelSwitcher = this;
_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 => _IsLogin;
set { _IsLogin = value; NotifyOfPropertyChange(); }
}
private List<Role> roles;
public List<Role> Roles
{
get => roles;
set { roles = value; RaisePropertyChangedEventImmediately("Roles"); }
}
private ICommand menuItemClickCommand;
public ICommand MenuItemClickCommand
{
get
{
if (menuItemClickCommand == null)
menuItemClickCommand = new BaseCommand<AppMenu>((AppMenu menuViewItem) => SwitchMenuItem(menuViewItem));
return menuItemClickCommand;
}
}
private ICommand mainmenuItemClickCommand;
public ICommand MainMenuItemClickCommand
{
get
{
if (mainmenuItemClickCommand == null)
mainmenuItemClickCommand = new BaseCommand<AppMenu>((AppMenu menuViewItem) => MainSwitchMenuItem(menuViewItem));
return mainmenuItemClickCommand;
}
}
public List<AppMenu> MenuItems
{
get => _menuItems;
set { _menuItems = value; NotifyOfPropertyChange(); }
}
public List<AppMenu> SubMenuItems
{
get => _subMenuItems;
set { _subMenuItems = value; NotifyOfPropertyChange(); }
}
public ObservableCollection<AppMenu> 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;
#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 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; }
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; 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("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; }
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.Token);
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);
}
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 override 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...
DisplayName = "Sic Auto-GE";
base.OnInitialize();
StartTimer();
}
protected override void OnActivate()
{
base.OnActivate();
ShowAllEvents();
EnableTimer(true);
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));
}
}
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($"{BaseApp.Instance.UserContext.LoginName} shutdown as {BaseApp.Instance.UserContext.Role.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<AppMenu>();
HistoryMenus = new ObservableCollection<AppMenu>();
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 (!string.IsNullOrEmpty(menuViewItem.ViewModel))
{
if (menuViewItem.Model == null)
{
menuViewItem.Model =
(BaseModel)AssemblyUtil.CreateInstance(AssemblyUtil.GetType(menuViewItem.ViewModel));
((BaseModel)menuViewItem.Model).Permission = menuViewItem.Permission;
if (menuViewItem.Model is ISupportMultipleSystem smsViewModel)
smsViewModel.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);
}
}
#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 == BaseApp.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("NowDateTime");
}
#endregion
#endregion
}
}