using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OpenCvSharp; using Prism.Commands; using Prism.Events; using Prism.Ioc; using Prism.Mvvm; using Prism.Regions; using Prism.Services.Dialogs; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Net.Http; using System.Text; using System.Threading.Tasks; using System.Windows; using TeamAAS_VP.Core; using TeamAAS_VP.Core.Lights; using TeamAAS_VP.Data; using TeamAAS_VP.Enums; using TeamAAS_VP.Events; using TeamAAS_VP.Interfaces; using TeamAAS_VP.Models; using TeamAAS_VP.Resources.Languages; using TeamAAS_VP.Views; using TeamAAS_VP.Views.User; namespace TeamAAS_VP.ViewModels.User { public class CardLoginWindowViewModel : BindableBase { #region 字段 IConfigService _configService; private readonly ISystemDatabaseService _systemDatabaseService; private readonly IEventAggregator _eventAggregator; private List Users; #endregion #region 属性 private ObservableCollection _UserNameList = new ObservableCollection(); /// /// 用户列表 /// public ObservableCollection UserNameList { get { return _UserNameList; } set { _UserNameList = value; } } private string _SelectedUserName; /// /// 当前在账号登录页选择的用户名。 /// 窗口加载时会清空;切换用户名时会同步清空密码。 /// public string SelectedUserName { get { return _SelectedUserName; } set { if (SetProperty(ref _SelectedUserName, value)) { Password = string.Empty; } } } private string _Password; /// /// 当前输入的账号登录密码。 /// 登录流程结束后会清空,避免窗口保留密码记录。 /// public string Password { get { return _Password; } set { SetProperty(ref _Password, value); } } /// /// 标识当前登录是否为本地登录模式。 /// public bool IsLocal { get; private set; } /// /// 当前弹窗实例,用于登录成功或取消时设置 DialogResult。 /// public CardLoginWindow View { get; set; } //正在登录中 private bool _IsLogining; /// /// 标识账号登录流程是否正在执行,用于禁用重复点击登录。 /// public bool IsLogining { get { return _IsLogining; } set { SetProperty(ref _IsLogining, value); } } private int _PageIndex; /// /// 当前登录页索引。 /// 0 表示刷卡登录页,1 表示账号登录页。 /// public int PageIndex { get { return _PageIndex; } set { SetProperty(ref _PageIndex, value); } } private Visibility _CardBtnVisibility = Visibility.Visible; /// /// 刷卡登录按钮可见性。 /// 管理员模式下隐藏刷卡入口。 /// public Visibility CardBtnVisibility { get { return _CardBtnVisibility; } set { SetProperty(ref _CardBtnVisibility, value); } } /// /// 刷卡器串口通讯对象。 /// 窗口关闭时需要解绑事件并释放连接。 /// public SerialPortProtocol serialPortProtocol { get; set; } #endregion #region 命令 private DelegateCommand _LoginCommand; /// /// 账号登录命令。 /// public DelegateCommand LoginCommand => _LoginCommand ?? (_LoginCommand = new DelegateCommand(ExecuteLoginCommand, CanExecuteLoginCommand).ObservesProperty(() => SelectedUserName).ObservesProperty(() => Password).ObservesProperty(() => IsLogining)); private DelegateCommand _CloseCommand; /// /// 关闭登录窗口命令。 /// public DelegateCommand CloseCommand => _CloseCommand ?? (_CloseCommand = new DelegateCommand(ExecuteCloseCommand)); private DelegateCommand _TransitionerCommand; /// /// 切换登录页命令。 /// public DelegateCommand TransitionerCommand => _TransitionerCommand ?? (_TransitionerCommand = new DelegateCommand(ExecuteTransitionerCommand)); private DelegateCommand _LoadedCommand; /// /// 窗口加载命令。 /// public DelegateCommand LoadedCommand => _LoadedCommand ?? (_LoadedCommand = new DelegateCommand(ExecuteLoadedCommand)); #endregion #region 事件 #endregion public CardLoginWindowViewModel(IConfigService configService, ISystemDatabaseService systemDatabaseService, IEventAggregator eventAggregator) { _configService = configService; _systemDatabaseService = systemDatabaseService; _eventAggregator = eventAggregator; } #region 方法 /// /// 窗口加载时初始化用户列表和刷卡器通讯。 /// 同时清除记住用户标记,并清空用户名选择和密码输入。 /// async void ExecuteLoadedCommand() { //获取刷卡器配置 var cardConfig = _configService.GetCardReaderConfig(); try { Users = _systemDatabaseService.GetAllUsersAsync().GetAwaiter().GetResult()?.ToList(); } catch { Users = new List(); } if (Users != null) { UserNameList.Clear(); foreach (var user in Users) { UserNameList.Add(user.UserName); } } try { await _systemDatabaseService.ClearRememberUserAsync(); } catch { } SelectedUserName = null; Password = string.Empty; //创建刷卡器通讯 serialPortProtocol = new SerialPortProtocol(cardConfig); serialPortProtocol.DataReceived += CardSerial_DataReceived; bool isConnected = await serialPortProtocol.ConnectAsync(); if (!isConnected) { MessageBox.Show("刷卡器连接失败,请检查连接!"); } } /// /// 处理刷卡器收到的卡号。 /// 在刷卡登录页中将卡号作为临时工程师账号登录,并发布用户切换事件。 /// /// 串口事件发送方。 /// 刷卡器读取到的卡号。 private async void CardSerial_DataReceived(object sender, string code) { if (PageIndex == 0) { if (string.IsNullOrEmpty(code)) { return; } Models.User user = new Models.User(); user.UserName = code.Trim().TrimStart('\0'); user.userPart = UserPart.Engineer; user.UserPassword = code.Trim().TrimStart('\0'); //刷卡密码默认为卡号 user.CreateTime = DateTime.Now; user.Id = -1; await _systemDatabaseService.SetCurrentUserAsync(user); //App.Current.Dispatcher.Invoke(() => //{ // user.UserPassword = string.Empty; // _eventAggregator.GetEvent().Publish(_systemDatabaseService.GetCurrentUser()); // View.DialogResult = true; //}); } } /// /// 窗口关闭时释放刷卡器通讯资源。 /// /// 窗口关闭事件发送方。 /// 关闭事件参数。 public async void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { if (serialPortProtocol!=null) { serialPortProtocol.DataReceived -= CardSerial_DataReceived; } await serialPortProtocol?.DisconnectAsync(); serialPortProtocol?.Dispose(); serialPortProtocol = null; } /// /// 执行账号登录。 /// 操作员账号允许免密码登录;工程师和管理员仍需要密码认证。 /// 登录完成后清除记住用户标记、清空密码,并关闭登录弹窗。 /// async void ExecuteLoginCommand() { if (Users == null || string.IsNullOrEmpty(SelectedUserName)) return; IsLogining = true; try { var selectedUser = Users.FirstOrDefault(u => u.UserName == SelectedUserName); if (selectedUser == null) return; if (_systemDatabaseService.GetCurrentUser() != null) { if (_systemDatabaseService.GetCurrentUser().UserName == SelectedUserName) { Password = string.Empty; _eventAggregator.GetEvent().Publish(_systemDatabaseService.GetCurrentUser()); View.DialogResult = true; return; } } var user = selectedUser.userPart == UserPart.Operator ? selectedUser : await _systemDatabaseService.AuthenticateUserAsync(SelectedUserName, Password); if (user != null) { try { await _systemDatabaseService.ClearRememberUserAsync(); } catch { } // mark current user in system DB and record login await _systemDatabaseService.SetCurrentUserAsync(user.Id); await _systemDatabaseService.RecordUserLoginAsync(new UserLoginRecord { UserId = user.Id, Success = true, Time = DateTime.Now, Message = "Login success" }); Password = string.Empty; _eventAggregator.GetEvent().Publish(_systemDatabaseService.GetCurrentUser()); View.DialogResult = true; } } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { Password = string.Empty; IsLogining = false; } } /// /// 判断账号登录命令是否可执行。 /// 选择用户名且当前未处于登录中时允许执行。 /// /// 可执行返回 true,否则返回 false。 bool CanExecuteLoginCommand() { return !string.IsNullOrEmpty(SelectedUserName) && !IsLogining; } /// /// 关闭登录窗口并返回取消结果。 /// void ExecuteCloseCommand() { View.DialogResult = false; } /// /// 切换刷卡登录页和账号登录页。 /// /// 目标页索引字符串。 void ExecuteTransitionerCommand(string parameter) { PageIndex = int.Parse(parameter); } /// /// 设置登录窗口模式。 /// 管理员模式进入账号登录页并隐藏刷卡按钮,普通模式进入刷卡登录页。 /// /// 是否使用管理员登录模式。 public void SetModel(bool isAdmin) { PageIndex = isAdmin ? 1 : 0; CardBtnVisibility = isAdmin ? Visibility.Collapsed : Visibility.Visible; } #endregion } }