From eedc2e5ea456cfc89db1421acdb0c41c08b61ad8 Mon Sep 17 00:00:00 2001 From: dathlin Date: Tue, 11 Jul 2017 17:32:58 +0800 Subject: [PATCH] =?UTF-8?q?wpf=E7=89=88=E7=99=BB=E5=BD=95=E7=AA=97?= =?UTF-8?q?=E4=BD=93=E5=AE=8C=E6=88=90=EF=BC=8C=E6=9C=8D=E5=8A=A1=E5=99=A8?= =?UTF-8?q?=E7=AB=AF=E7=BB=B4=E6=8A=A4BUG=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 软件系统客户端Wpf/LoginWindow.xaml | 26 ++- 软件系统客户端Wpf/LoginWindow.xaml.cs | 263 +++++++++++++++++++++- 软件系统客户端Wpf/screenshots/client1.png | Bin 0 -> 14603 bytes 软件系统服务端模版/FormServerWindow.cs | 6 +- 4 files changed, 277 insertions(+), 18 deletions(-) create mode 100644 软件系统客户端Wpf/screenshots/client1.png diff --git a/软件系统客户端Wpf/LoginWindow.xaml b/软件系统客户端Wpf/LoginWindow.xaml index 3ad0e61..2251d46 100644 --- a/软件系统客户端Wpf/LoginWindow.xaml +++ b/软件系统客户端Wpf/LoginWindow.xaml @@ -32,7 +32,7 @@ [您的软件系统] - + @@ -43,30 +43,32 @@ - - + - - + - + + + 是否记住密码? + - - - 是否记住密码? - + - 正在连接服务器... + 正在连接服务器... diff --git a/软件系统客户端Wpf/LoginWindow.xaml.cs b/软件系统客户端Wpf/LoginWindow.xaml.cs index f1cef46..0f29fe1 100644 --- a/软件系统客户端Wpf/LoginWindow.xaml.cs +++ b/软件系统客户端Wpf/LoginWindow.xaml.cs @@ -11,6 +11,12 @@ using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; +using System.Windows.Media.Animation; +using System.Threading; +using HslCommunication; +using CommonLibrary; +using HslCommunication.BasicFramework; +using Newtonsoft.Json.Linq; namespace 软件系统客户端Wpf { @@ -26,7 +32,257 @@ namespace 软件系统客户端Wpf private void Button_Click(object sender, RoutedEventArgs e) { - this.DialogResult = true; + //启动线程登录 + //验证输入 + if (string.IsNullOrEmpty(NameTextBox.Text)) + { + SetInformationString("请输入用户名"); + NameTextBox.Focus(); + return; + } + + if (string.IsNullOrEmpty(PasswordBox.Password)) + { + SetInformationString("请输入密码"); + PasswordBox.Focus(); + return; + } + + SetInformationString("正在验证维护状态..."); + UISettings(false); + + UserName = NameTextBox.Text; + UserPassword = PasswordBox.Password; + IsChecked = (bool)Remember.IsChecked; + + ThreadAccountLogin = new Thread(ThreadCheckAccount); + ThreadAccountLogin.IsBackground = true; + ThreadAccountLogin.Start(); + } + + #region 账户验证的逻辑块 + + + + private string UserName = string.Empty; + private string UserPassword = string.Empty; + private bool IsChecked = false; + + /// + /// 用于验证的后台线程 + /// + private Thread ThreadAccountLogin = null; + /// + /// 用户账户验证的后台端 + /// + private void ThreadCheckAccount() + { + //定义委托 + Action message_show = delegate (string message) + { + SetInformationString(message); + }; + Action start_update = delegate + { + //需要该exe支持,否则将无法是实现自动版本控制 + string update_file_name = AppDomain.CurrentDomain.BaseDirectory + @"\软件自动更新.exe"; + try + { + System.Diagnostics.Process.Start(update_file_name); + Environment.Exit(0);//退出系统 + } + catch + { + MessageBox.Show("更新程序启动失败,请检查文件是否丢失,联系管理员获取。"); + } + }; + Action thread_finish = delegate + { + UISettings(true); + }; + + //延时 + Thread.Sleep(200); + + //请求指令头数据,该数据需要更具实际情况更改 + OperateResultString result = UserClient.Net_simplify_client.ReadFromServer(CommonHeadCode.SimplifyHeadCode.维护检查); + if (result.IsSuccess) + { + byte[] temp = Encoding.Unicode.GetBytes(result.Content); + //例如返回结果为1说明允许登录,0则说明服务器处于维护中,并将信息显示 + if (result.Content != "1") + { + Dispatcher.Invoke(message_show, result.Content.Substring(1)); + Dispatcher.Invoke(thread_finish); + return; + } + } + else + { + //访问失败 + Dispatcher.Invoke(message_show, result.Message); + Dispatcher.Invoke(thread_finish); + return; + } + + + + //检查账户 + Dispatcher.Invoke(message_show, "正在检查账户..."); + + //延时 + Thread.Sleep(200); + + //=================================================================================== + // 根据实际情况校验,选择数据库校验或是将用户名密码发至服务器校验 + // 以下展示了服务器校验的方法,如您需要数据库校验,请删除下面并改成SQL访问验证的方式 + + //包装数据 + JObject json = new JObject + { + { UserAccount.UserNameText, new JValue(UserName) }, + { UserAccount.PasswordText, new JValue(UserPassword) } + }; + result = UserClient.Net_simplify_client.ReadFromServer(CommonLibrary.CommonHeadCode.SimplifyHeadCode.账户检查, json.ToString()); + if (result.IsSuccess) + { + //服务器应该返回账户的信息 + UserAccount account = JObject.Parse(result.Content).ToObject(); + if (!account.LoginEnable) + { + //不允许登录 + Dispatcher.Invoke(message_show, account.ForbidMessage); + Dispatcher.Invoke(thread_finish); + return; + } + UserClient.UserAccount = account; + } + else + { + //访问失败 + Dispatcher.Invoke(message_show, result.Message); + Dispatcher.Invoke(thread_finish); + return; + } + + //登录成功,进行保存用户名称和密码 + UserClient.JsonSettings.LoginName = UserName; + UserClient.JsonSettings.Password = IsChecked ? UserPassword : ""; + UserClient.JsonSettings.LoginTime = DateTime.Now; + UserClient.JsonSettings.SaveToFile(); + + + //版本验证 + Dispatcher.Invoke(message_show, "正在验证版本..."); + + //延时 + Thread.Sleep(200); + + result = UserClient.Net_simplify_client.ReadFromServer(CommonLibrary.CommonHeadCode.SimplifyHeadCode.更新检查); + if (result.IsSuccess) + { + //服务器应该返回服务器的版本号 + SystemVersion sv = new SystemVersion(result.Content); + //系统账户跳过低版本检测 + if (UserClient.UserAccount.UserName != "admin") + { + if (UserClient.CurrentVersion != sv) + { + //保存新版本信息 + UserClient.JsonSettings.IsNewVersionRunning = true; + UserClient.JsonSettings.SaveToFile(); + //和当前系统版本号不一致,启动更新 + Dispatcher.Invoke(start_update); + return; + } + } + else + { + if (UserClient.CurrentVersion < sv) + { + //保存新版本信息 + UserClient.JsonSettings.IsNewVersionRunning = true; + UserClient.JsonSettings.SaveToFile(); + //和当前系统版本号不一致,启动更新 + Dispatcher.Invoke(start_update); + return; + } + } + } + else + { + //访问失败 + Dispatcher.Invoke(message_show, result.Message); + Dispatcher.Invoke(thread_finish); + return; + } + + + //================================================================================ + //验证结束后,根据需要是否下载服务器的数据,或是等到进入主窗口下载也可以 + //如果有参数决定主窗口的显示方式,那么必要在下面向服务器请求数据 + //以下展示了初始化参数的功能 + Dispatcher.Invoke(message_show, "正在下载参数..."); + + //延时 + Thread.Sleep(200); + + + result = UserClient.Net_simplify_client.ReadFromServer(CommonLibrary.CommonHeadCode.SimplifyHeadCode.参数下载); + if (result.IsSuccess) + { + //服务器返回初始化的数据,此处进行数据的提取,有可能包含了多个数据 + json = Newtonsoft.Json.Linq.JObject.Parse(result.Content); + //例如公告数据 + UserClient.Announcement = SoftBasic.GetValueFromJsonObject(json, nameof(UserClient.Announcement), ""); + + } + else + { + //访问失败 + Dispatcher.Invoke(message_show, result.Message); + Dispatcher.Invoke(thread_finish); + return; + } + + //启动主窗口 + Dispatcher.Invoke(new Action(() => + { + DialogResult = true; + return; + })); + } + + + #endregion + + private void UISettings(bool enable) + { + NameTextBox.IsEnabled = enable; + PasswordBox.IsEnabled = enable; + Remember.IsEnabled = enable; + LoginButton.IsEnabled = enable; + } + + private void SetInformationString(string str) + { + if (WindowToolTip.Opacity == 1) + { + DoubleAnimation hidden = new DoubleAnimation(1, 0, TimeSpan.FromMilliseconds(100)); + hidden.Completed += delegate + { + DoubleAnimation show = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(100)); + WindowToolTip.Text = str; + WindowToolTip.BeginAnimation(OpacityProperty, show); + }; + WindowToolTip.BeginAnimation(OpacityProperty, hidden); + } + else + { + DoubleAnimation show = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(100)); + WindowToolTip.Text = str; + WindowToolTip.BeginAnimation(OpacityProperty, show); + } } private void ToggleButton_Checked(object sender, RoutedEventArgs e) @@ -41,6 +297,7 @@ namespace 软件系统客户端Wpf private void Window_Loaded(object sender, RoutedEventArgs e) { + WindowToolTip.Opacity = 0; TextBlockSoftName.Text = CommonLibrary.Resource.StringResouce.SoftName; TextBlockSoftVersion.Text = UserClient.CurrentVersion.ToString(); TextBlockSoftCopyright.Text = $"本软件著作权归{CommonLibrary.Resource.StringResouce.SoftCopyRight}所有"; @@ -63,12 +320,12 @@ namespace 软件系统客户端Wpf private void NameTextBox_KeyDown(object sender, KeyEventArgs e) { - PasswordBox.Focus(); + if(e.Key==Key.Enter) PasswordBox.Focus(); } private void PasswordBox_KeyDown(object sender, KeyEventArgs e) { - Button_Click(null, new RoutedEventArgs()); + if (e.Key == Key.Enter) Button_Click(null, new RoutedEventArgs()); } } } diff --git a/软件系统客户端Wpf/screenshots/client1.png b/软件系统客户端Wpf/screenshots/client1.png new file mode 100644 index 0000000000000000000000000000000000000000..76bcae3adea9dbc9bf5cb1916db7aa6fed4f2841 GIT binary patch literal 14603 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 ew!