Merge branch 'master' of http://10.10.28.13:8080/r/PDM/PdmSwPlugin2
New file |
| | |
| | | { |
| | | "Version": 1, |
| | | "WorkspaceRootPath": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\", |
| | | "Documents": [ |
| | | { |
| | | "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|c:\\main\\workspace\\visualstudio\\pdmswplugin2\\pdmalert\\loginuser.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", |
| | | "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:loginuser.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" |
| | | }, |
| | | { |
| | | "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\loginwindow.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", |
| | | "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:loginwindow.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" |
| | | }, |
| | | { |
| | | "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\mainwindow.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", |
| | | "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:mainwindow.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" |
| | | }, |
| | | { |
| | | "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\app.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", |
| | | "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:app.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" |
| | | }, |
| | | { |
| | | "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|c:\\main\\workspace\\visualstudio\\pdmswplugin2\\pdmalert\\loginwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", |
| | | "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:loginwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" |
| | | }, |
| | | { |
| | | "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\util.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", |
| | | "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:util.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" |
| | | }, |
| | | { |
| | | "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\mainwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", |
| | | "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:mainwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" |
| | | }, |
| | | { |
| | | "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\entity\\msgdata.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", |
| | | "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:entity\\msgdata.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" |
| | | }, |
| | | { |
| | | "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\dockapp.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", |
| | | "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:dockapp.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" |
| | | }, |
| | | { |
| | | "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\encryptor.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", |
| | | "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:encryptor.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" |
| | | } |
| | | ], |
| | | "DocumentGroupContainers": [ |
| | | { |
| | | "Orientation": 0, |
| | | "VerticalTabListWidth": 256, |
| | | "DocumentGroups": [ |
| | | { |
| | | "DockedWidth": 200, |
| | | "SelectedChildIndex": 7, |
| | | "Children": [ |
| | | { |
| | | "$type": "Document", |
| | | "DocumentIndex": 4, |
| | | "Title": "LoginWindow.xaml", |
| | | "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\LoginWindow.xaml", |
| | | "RelativeDocumentMoniker": "LoginWindow.xaml", |
| | | "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\LoginWindow.xaml", |
| | | "RelativeToolTip": "LoginWindow.xaml", |
| | | "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", |
| | | "WhenOpened": "2024-08-20T10:32:06.895Z", |
| | | "EditorCaption": "" |
| | | }, |
| | | { |
| | | "$type": "Document", |
| | | "DocumentIndex": 5, |
| | | "Title": "Util.cs", |
| | | "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\Util.cs", |
| | | "RelativeDocumentMoniker": "Util.cs", |
| | | "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\Util.cs", |
| | | "RelativeToolTip": "Util.cs", |
| | | "ViewState": "AQIAAKgBAAAAAAAAAAAowLMBAAARAAAA", |
| | | "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", |
| | | "WhenOpened": "2024-08-20T10:17:23.879Z" |
| | | }, |
| | | { |
| | | "$type": "Document", |
| | | "DocumentIndex": 7, |
| | | "Title": "MsgData.cs", |
| | | "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\Entity\\MsgData.cs", |
| | | "RelativeDocumentMoniker": "Entity\\MsgData.cs", |
| | | "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\Entity\\MsgData.cs", |
| | | "RelativeToolTip": "Entity\\MsgData.cs", |
| | | "ViewState": "AQIAAAAAAAAAAAAAAAAAAAgAAAAAAAAA", |
| | | "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", |
| | | "WhenOpened": "2024-08-20T09:14:07.015Z" |
| | | }, |
| | | { |
| | | "$type": "Document", |
| | | "DocumentIndex": 6, |
| | | "Title": "MainWindow.xaml", |
| | | "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\MainWindow.xaml", |
| | | "RelativeDocumentMoniker": "MainWindow.xaml", |
| | | "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\MainWindow.xaml", |
| | | "RelativeToolTip": "MainWindow.xaml", |
| | | "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", |
| | | "WhenOpened": "2024-08-20T09:08:54.87Z", |
| | | "EditorCaption": "" |
| | | }, |
| | | { |
| | | "$type": "Document", |
| | | "DocumentIndex": 2, |
| | | "Title": "MainWindow.xaml.cs", |
| | | "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\MainWindow.xaml.cs", |
| | | "RelativeDocumentMoniker": "MainWindow.xaml.cs", |
| | | "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\MainWindow.xaml.cs", |
| | | "RelativeToolTip": "MainWindow.xaml.cs", |
| | | "ViewState": "AQIAAGIAAAAAAAAAAAAnwJEAAAAsAAAA", |
| | | "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", |
| | | "WhenOpened": "2024-08-20T09:03:17.694Z", |
| | | "EditorCaption": "" |
| | | }, |
| | | { |
| | | "$type": "Document", |
| | | "DocumentIndex": 8, |
| | | "Title": "DockApp.cs", |
| | | "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\DockApp.cs", |
| | | "RelativeDocumentMoniker": "DockApp.cs", |
| | | "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\DockApp.cs", |
| | | "RelativeToolTip": "DockApp.cs", |
| | | "ViewState": "AQIAABkAAAAAAAAAAAAkwA4AAAArAAAA", |
| | | "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", |
| | | "WhenOpened": "2024-08-20T06:58:33.822Z" |
| | | }, |
| | | { |
| | | "$type": "Document", |
| | | "DocumentIndex": 9, |
| | | "Title": "Encryptor.cs", |
| | | "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\Encryptor.cs", |
| | | "RelativeDocumentMoniker": "Encryptor.cs", |
| | | "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\Encryptor.cs", |
| | | "RelativeToolTip": "Encryptor.cs", |
| | | "ViewState": "AQIAACIAAAAAAAAAAAAawBIAAAAuAAAA", |
| | | "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", |
| | | "WhenOpened": "2024-08-20T06:23:54.361Z" |
| | | }, |
| | | { |
| | | "$type": "Document", |
| | | "DocumentIndex": 0, |
| | | "Title": "LoginUser.cs", |
| | | "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\LoginUser.cs", |
| | | "RelativeDocumentMoniker": "LoginUser.cs", |
| | | "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\LoginUser.cs", |
| | | "RelativeToolTip": "LoginUser.cs", |
| | | "ViewState": "AQIAAEYAAAAAAAAAAAAywFgAAAANAAAA", |
| | | "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", |
| | | "WhenOpened": "2024-08-20T03:50:43.52Z", |
| | | "EditorCaption": "" |
| | | }, |
| | | { |
| | | "$type": "Document", |
| | | "DocumentIndex": 1, |
| | | "Title": "LoginWindow.xaml.cs", |
| | | "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\LoginWindow.xaml.cs", |
| | | "RelativeDocumentMoniker": "LoginWindow.xaml.cs", |
| | | "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\LoginWindow.xaml.cs", |
| | | "RelativeToolTip": "LoginWindow.xaml.cs", |
| | | "ViewState": "AQIAAAYAAAAAAAAAAAAAABAAAAAfAAAA", |
| | | "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", |
| | | "WhenOpened": "2024-08-20T03:46:25.163Z", |
| | | "EditorCaption": "" |
| | | }, |
| | | { |
| | | "$type": "Document", |
| | | "DocumentIndex": 3, |
| | | "Title": "App.xaml.cs", |
| | | "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\App.xaml.cs", |
| | | "RelativeDocumentMoniker": "App.xaml.cs", |
| | | "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\App.xaml.cs", |
| | | "RelativeToolTip": "App.xaml.cs", |
| | | "ViewState": "AQIAAAgAAAAAAAAAAAAIwBgAAAAjAAAA", |
| | | "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", |
| | | "WhenOpened": "2024-08-20T03:42:24.667Z", |
| | | "EditorCaption": "" |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | } |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Configuration; |
| | | using System.Data; |
| | | using System.Linq; |
| | | using System.Threading.Tasks; |
| | | using System.Windows; |
| | | using System.Windows; |
| | | |
| | | namespace PdmAlert |
| | | { |
| | |
| | | public partial class App : Application |
| | | { |
| | | DockApp dockApp; |
| | | LoginWindow loginWindow; |
| | | protected override void OnStartup(StartupEventArgs e) |
| | | { |
| | | base.OnStartup(e); |
| | | this.ShutdownMode = ShutdownMode.OnExplicitShutdown; |
| | | dockApp.Run(); |
| | | if (LoginUser.TryAutoLogin()) |
| | | { |
| | | |
| | | dockApp = new DockApp(); |
| | | dockApp.Run(); |
| | | } |
| | | else |
| | | { |
| | | loginWindow = new LoginWindow(); |
| | | loginWindow.Show(); |
| | | } |
| | | } |
| | | |
| | | private void Application_Startup(object sender, StartupEventArgs e) |
| | | { |
| | | dockApp = new DockApp(); |
| | | |
| | | } |
| | | } |
| | | } |
| | |
| | | if (showWindow != null) |
| | | { |
| | | showWindow.Show(); |
| | | showWindow.Activate(); |
| | | } |
| | | else |
| | | { |
New file |
| | |
| | | using System; |
| | | using System.IO; |
| | | using System.Security.Cryptography; |
| | | using System.Text; |
| | | |
| | | namespace PdmAlert |
| | | { |
| | | public class Encryptor |
| | | { |
| | | private readonly byte[] key; |
| | | private readonly byte[] iv; |
| | | |
| | | public Encryptor(string keyString, string ivString) |
| | | { |
| | | key = Encoding.UTF8.GetBytes(keyString); |
| | | iv = Encoding.UTF8.GetBytes(ivString); |
| | | } |
| | | |
| | | public string Encrypt(string plainText) |
| | | { |
| | | using (var aes = Aes.Create()) |
| | | { |
| | | aes.Key = key; |
| | | aes.IV = iv; |
| | | ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV); |
| | | |
| | | using (MemoryStream msEncrypt = new MemoryStream()) |
| | | { |
| | | using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) |
| | | { |
| | | using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) |
| | | { |
| | | swEncrypt.Write(plainText); |
| | | } |
| | | return Convert.ToBase64String(msEncrypt.ToArray()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | public string Decrypt(string cipherText) |
| | | { |
| | | using (var aes = Aes.Create()) |
| | | { |
| | | aes.Key = key; |
| | | aes.IV = iv; |
| | | ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV); |
| | | byte[] arr = Convert.FromBase64String(cipherText); |
| | | using (MemoryStream msDecrypt = new MemoryStream(arr)) |
| | | { |
| | | using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) |
| | | { |
| | | using (StreamReader srDecrypt = new StreamReader(csDecrypt)) |
| | | { |
| | | return srDecrypt.ReadToEnd(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | namespace PdmAlert.Entity |
| | | { |
| | | public class MsgData |
| | | { |
| | | public string title { get; set; } |
| | | public string content { get; set; } |
| | | } |
| | | } |
New file |
| | |
| | | using PdmAlert.Util; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.IO; |
| | | using System.Net.Http; |
| | | using System.Reflection; |
| | | |
| | | namespace PdmAlert |
| | | { |
| | | public class LoginUser |
| | | { |
| | | public static LoginUser CurrentUser { get; private set; } |
| | | |
| | | private static readonly Encryptor encryptor = new Encryptor("12345678123456781234567812345678", |
| | | "1234567812345678"); |
| | | |
| | | public string id { get; set; } |
| | | public string realName { get; set; } |
| | | public string username { get; set; } |
| | | public string password { get; set; } |
| | | public string appId { get; set; } |
| | | public string pluginVersion { get; set; } |
| | | public bool rememberMe { get; set; } |
| | | |
| | | public static bool TryAutoLogin() |
| | | { |
| | | string fileContent = null; |
| | | if (LoadStrFromBin(ref fileContent)) |
| | | { |
| | | try |
| | | { |
| | | string jsonStr = encryptor.Decrypt(fileContent); |
| | | Dictionary<string, string> user = JsonUtil.Deserialize<Dictionary<string, string>>(jsonStr); |
| | | return Login(user["username"], user["password"], true); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | RemoveCacheBin(); |
| | | return false; |
| | | } |
| | | |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | public static bool Login(string username, string password, bool rememberMe) |
| | | { |
| | | |
| | | using (HttpClient client = new HttpClient |
| | | { |
| | | BaseAddress = new Uri("http://localhost:8888/pdm-web/"), |
| | | }) |
| | | { |
| | | try |
| | | { |
| | | Result<LoginUser> res = client.PostSyncAction<LoginUser>(new LoginUser |
| | | { |
| | | username = username, |
| | | password = password, |
| | | appId = "sockettool", |
| | | pluginVersion = "0.0.0.1" |
| | | |
| | | }, "openApi/wpf/login"); |
| | | CurrentUser = res.HandleResult(); |
| | | CurrentUser.password = password; |
| | | CurrentUser.rememberMe = rememberMe; |
| | | if (rememberMe) |
| | | { |
| | | string userInfo = JsonUtil.Stringfiy(CurrentUser); |
| | | SaveStrToBin(encryptor.Encrypt(userInfo)); |
| | | } |
| | | return true; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | RemoveCacheBin(); |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | |
| | | public static void SaveStrToBin(string content) |
| | | { |
| | | string filePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().FullName), "bin"); |
| | | byte[] bytes = Convert.FromBase64String(content); |
| | | using (Stream stream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite)) |
| | | using (BinaryWriter writer = new BinaryWriter(stream)) |
| | | { |
| | | writer.Write(bytes); |
| | | } |
| | | } |
| | | |
| | | public static bool LoadStrFromBin(ref string content) |
| | | { |
| | | string filePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().FullName), "bin"); |
| | | if (!File.Exists(filePath)) |
| | | { |
| | | return false; |
| | | } |
| | | using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) |
| | | using (BinaryReader reader = new BinaryReader(stream)) |
| | | { |
| | | byte[] bytes = new byte[stream.Length]; |
| | | reader.Read(bytes, 0, bytes.Length); |
| | | content = Convert.ToBase64String(bytes); |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | public static void RemoveCacheBin() |
| | | { |
| | | string filePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().FullName), "bin"); |
| | | File.Delete(filePath); |
| | | } |
| | | } |
| | | } |
| | |
| | | xmlns:local="clr-namespace:PdmAlert" |
| | | mc:Ignorable="d" |
| | | Title="LoginWindow" Height="450" Width="800"> |
| | | <Grid> |
| | | |
| | | </Grid> |
| | | <AdornerDecorator> |
| | | <Border x:Name="mainBorder"> |
| | | <Grid Height="200" VerticalAlignment="Top" Margin="20"> |
| | | <Grid.RowDefinitions> |
| | | <RowDefinition Height="30"/> |
| | | <RowDefinition Height="30"/> |
| | | <RowDefinition Height="30"/> |
| | | <RowDefinition Height="50"/> |
| | | </Grid.RowDefinitions> |
| | | |
| | | <Grid.ColumnDefinitions> |
| | | <ColumnDefinition Width="50"/> |
| | | <ColumnDefinition/> |
| | | </Grid.ColumnDefinitions> |
| | | <Label Content="用户名" VerticalContentAlignment="Center" Grid.Row="0" Grid.Column="0"/> |
| | | <TextBox x:Name="usernameTextBlock" VerticalAlignment="Stretch" VerticalContentAlignment="Center" Grid.Row="0" Grid.Column="1"/> |
| | | <Label Content="密码" VerticalContentAlignment="Center" Grid.Row="1" Grid.Column="0"/> |
| | | <PasswordBox x:Name="passwordTextBlock" VerticalAlignment="Stretch" VerticalContentAlignment="Center" Grid.Row="1" Grid.Column="1"/> |
| | | <CheckBox Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" x:Name="rememberMeInput">自动登录</CheckBox> |
| | | <Button Margin="0,10,0,0" Click="Button_Click" Padding="5" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2">登录</Button> |
| | | </Grid> |
| | | </Border> |
| | | </AdornerDecorator> |
| | | </Window> |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using System.Windows; |
| | | using System.Windows.Controls; |
| | | using System.Windows.Data; |
| | | using System.Windows.Documents; |
| | | using System.Windows.Input; |
| | | using System.Windows.Media; |
| | | using System.Windows.Media.Imaging; |
| | | using System.Windows.Shapes; |
| | | using System.Windows; |
| | | |
| | | namespace PdmAlert |
| | | { |
| | |
| | | { |
| | | InitializeComponent(); |
| | | } |
| | | |
| | | public void Button_Click(object sender, RoutedEventArgs e) |
| | | { |
| | | if (LoginUser.Login(usernameTextBlock.Text, passwordTextBlock.Password, rememberMeInput.IsChecked == true)) |
| | | { |
| | | |
| | | |
| | | } |
| | | |
| | | } |
| | | } |
| | | } |
| | |
| | | xmlns:local="clr-namespace:PdmAlert" |
| | | mc:Ignorable="d" |
| | | WindowStyle="None" |
| | | Topmost="True" |
| | | ResizeMode="NoResize" |
| | | WindowStartupLocation="Manual" |
| | | Loaded="Window_Loaded" |
| | | Deactivated="Window_Deactivated" |
| | | ShowInTaskbar="False" |
| | | Title="MainWindow" Height="600" Width="400"> |
| | | <Window.Resources> |
| | | <Brush x:Key="MainBorder">#0d4d84</Brush> |
| | | <Brush x:Key="MainMenu">#1d6eb2</Brush> |
| | | <Brush x:Key="ChildBorder">#3692e1</Brush> |
| | | <Brush x:Key="MainStatusBar">#1d6eb2</Brush> |
| | | <ResourceDictionary> |
| | | <FontFamily x:Key="iconfont"> |
| | | /PdmAlert;component/Icon/#iconfont |
| | | </FontFamily> |
| | | <Brush x:Key="MainBorder">#0d4d84</Brush> |
| | | <Brush x:Key="MainMenu">#1d6eb2</Brush> |
| | | <Brush x:Key="ChildBorder">#3692e1</Brush> |
| | | <Brush x:Key="MainStatusBar">#1d6eb2</Brush> |
| | | |
| | | <Brush x:Key="SecondaryImportant">Orange</Brush> |
| | | <Brush x:Key="Important">#e17933</Brush> |
| | | <Brush x:Key="ImportantFont">#FFF</Brush> |
| | | <Brush x:Key="SecondaryImportant">Orange</Brush> |
| | | <Brush x:Key="Important">#e17933</Brush> |
| | | <Brush x:Key="ImportantFont">#FFF</Brush> |
| | | |
| | | |
| | | <Brush x:Key="ButtonColor">#103156</Brush> |
| | | <Brush x:Key="ButtonSelected">#02579E</Brush> |
| | | <Brush x:Key="ButtonFont">White</Brush> |
| | | <Brush x:Key="ButtonFontSelected">White</Brush> |
| | | |
| | | <Style x:Key="WindowButton" TargetType="Button"> |
| | | <Setter Property="Background" Value="Transparent"/> |
| | | <Setter Property="FontWeight" Value="SemiBold"/> |
| | | <Setter Property="Foreground" Value="White"/> |
| | | <Setter Property="Width" Value="50"/> |
| | | <Setter Property="FontSize" Value="20"/> |
| | | <Setter Property="BorderThickness" Value="0"/> |
| | | <Setter Property="BorderBrush" Value="Transparent"/> |
| | | <Brush x:Key="ButtonColor">#103156</Brush> |
| | | <Brush x:Key="ButtonSelected">#02579E</Brush> |
| | | <Brush x:Key="ButtonFont">White</Brush> |
| | | <Brush x:Key="ButtonFontSelected">White</Brush> |
| | | |
| | | <Style x:Key="WindowButton" TargetType="Button"> |
| | | <Setter Property="FontFamily" Value="{StaticResource iconfont}"/> |
| | | <Setter Property="Background" Value="Transparent"/> |
| | | <Setter Property="FontWeight" Value="SemiBold"/> |
| | | <Setter Property="Foreground" Value="Black"/> |
| | | <Setter Property="Width" Value="50"/> |
| | | <Setter Property="FontSize" Value="20"/> |
| | | <Setter Property="BorderThickness" Value="1"/> |
| | | <Setter Property="BorderBrush" Value="Transparent"/> |
| | | |
| | | |
| | | <Setter Property="Template"> |
| | | <Setter.Value> |
| | | <ControlTemplate TargetType="Button"> |
| | | <Border x:Name="border" Width="{TemplateBinding Width}" Background="{TemplateBinding Background}" |
| | | <Setter Property="Template"> |
| | | <Setter.Value> |
| | | <ControlTemplate TargetType="Button"> |
| | | <Border x:Name="border" Width="{TemplateBinding Width}" Background="{TemplateBinding Background}" |
| | | BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0"> |
| | | <Label x:Name="label" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" |
| | | <Label x:Name="label" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" |
| | | HorizontalContentAlignment="Center" VerticalContentAlignment="Center" |
| | | Foreground="{TemplateBinding Foreground}" |
| | | Content="{TemplateBinding Content}"/> |
| | | </Border> |
| | | </Border> |
| | | |
| | | <ControlTemplate.Triggers> |
| | | <Trigger Property="IsMouseOver" Value="True"> |
| | | <Setter TargetName="border" Property="Background" Value="Gray"/> |
| | | </Trigger> |
| | | </ControlTemplate.Triggers> |
| | | </ControlTemplate> |
| | | </Setter.Value> |
| | | </Setter> |
| | | </Style> |
| | | <ControlTemplate.Triggers> |
| | | <Trigger Property="IsMouseOver" Value="True"> |
| | | <Setter TargetName="border" Property="Background" Value="Gray"/> |
| | | </Trigger> |
| | | </ControlTemplate.Triggers> |
| | | </ControlTemplate> |
| | | </Setter.Value> |
| | | </Setter> |
| | | </Style> |
| | | |
| | | <Style x:Key="WindowCloseButton" BasedOn="{StaticResource WindowButton}" TargetType="Button"> |
| | | <Setter Property="Template"> |
| | | <Setter.Value> |
| | | <ControlTemplate TargetType="Button"> |
| | | <Border x:Name="border" Width="{TemplateBinding Width}" Background="{TemplateBinding Background}" |
| | | <Style x:Key="WindowCloseButton" BasedOn="{StaticResource WindowButton}" TargetType="Button"> |
| | | <Setter Property="Template"> |
| | | <Setter.Value> |
| | | <ControlTemplate TargetType="Button"> |
| | | <Border x:Name="border" Width="{TemplateBinding Width}" Background="{TemplateBinding Background}" |
| | | BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0"> |
| | | <Label x:Name="label" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" |
| | | <Label x:Name="label" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" |
| | | HorizontalContentAlignment="Center" VerticalContentAlignment="Center" |
| | | Foreground="{TemplateBinding Foreground}" |
| | | Content="{TemplateBinding Content}"/> |
| | | </Border> |
| | | </Border> |
| | | |
| | | <ControlTemplate.Triggers> |
| | | <Trigger Property="IsMouseOver" Value="True"> |
| | | <Setter TargetName="border" Property="Background" Value="Red"/> |
| | | </Trigger> |
| | | </ControlTemplate.Triggers> |
| | | </ControlTemplate> |
| | | </Setter.Value> |
| | | </Setter> |
| | | </Style> |
| | | <ControlTemplate.Triggers> |
| | | <Trigger Property="IsMouseOver" Value="True"> |
| | | <Setter TargetName="border" Property="Background" Value="Red"/> |
| | | </Trigger> |
| | | </ControlTemplate.Triggers> |
| | | </ControlTemplate> |
| | | </Setter.Value> |
| | | </Setter> |
| | | </Style> |
| | | |
| | | <Style x:Key="ChildWindowButton" BasedOn="{StaticResource WindowButton}" TargetType="Button"> |
| | | <Setter Property="FontSize" Value="15"/> |
| | | <Setter Property="Width" Value="30"/> |
| | | <Setter Property="Background" Value="{StaticResource ChildBorder}"/> |
| | | </Style> |
| | | <Style x:Key="ChildWindowButton" BasedOn="{StaticResource WindowButton}" TargetType="Button"> |
| | | <Setter Property="FontSize" Value="15"/> |
| | | <Setter Property="Width" Value="30"/> |
| | | <Setter Property="Background" Value="{StaticResource ChildBorder}"/> |
| | | </Style> |
| | | |
| | | <Style x:Key="ChildWindowCloseButton" BasedOn="{StaticResource ChildWindowButton}" TargetType="Button"> |
| | | |
| | | </Style> |
| | | <Style x:Key="ChildWindowCloseButton" BasedOn="{StaticResource ChildWindowButton}" TargetType="Button"> |
| | | |
| | | <Style x:Key="LinkButton" TargetType="Button"> |
| | | <Setter Property="FontFamily" Value="{StaticResource iconfont}"/> |
| | | <Setter Property="Foreground" Value="{StaticResource ChildBorder}"/> |
| | | </Style> |
| | | |
| | | <Setter Property="Template"> |
| | | <Setter.Value> |
| | | <ControlTemplate TargetType="Button"> |
| | | <TextBlock Style="{x:Null}" x:Name="label" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" |
| | | <Style x:Key="LinkButton" TargetType="Button"> |
| | | <Setter Property="FontFamily" Value="{StaticResource iconfont}"/> |
| | | <Setter Property="Foreground" Value="{StaticResource ChildBorder}"/> |
| | | |
| | | <Setter Property="Template"> |
| | | <Setter.Value> |
| | | <ControlTemplate TargetType="Button"> |
| | | <TextBlock Style="{x:Null}" x:Name="label" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" |
| | | Foreground="{TemplateBinding Foreground}" |
| | | Text="{TemplateBinding Content}"/> |
| | | </ControlTemplate> |
| | | </Setter.Value> |
| | | </Setter> |
| | | </Style> |
| | | </ControlTemplate> |
| | | </Setter.Value> |
| | | </Setter> |
| | | </Style> |
| | | </ResourceDictionary> |
| | | </Window.Resources> |
| | | |
| | | |
| | | |
| | | |
| | | <StackPanel> |
| | | <StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right"> |
| | | <Button Style="{StaticResource WindowButton}" Click="Button_Click">刷新</Button> |
| | | <Button Style="{StaticResource WindowButton}" Click="Button_Click">切换用户</Button> |
| | | <Button Style="{StaticResource WindowCloseButton}" Click="Hide_Click">最小化</Button> |
| | | </StackPanel> |
| | | <Grid> |
| | | <Button Click="Button_Click">测试</Button> |
| | | </Grid> |
| | | <Border BorderThickness="0" Background="LightGray"> |
| | | <StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right"> |
| | | <Button Style="{StaticResource WindowButton}" Click="Refresh_Click" BorderBrush="Black" ToolTip="刷新"></Button> |
| | | <Button Style="{StaticResource WindowButton}" Click="SwitchUser_Click" ToolTip="切换用户"></Button> |
| | | <Button Style="{StaticResource WindowCloseButton}" Click="Hide_Click" ToolTip="最小化"></Button> |
| | | </StackPanel> |
| | | </Border> |
| | | |
| | | |
| | | <Label Content="{Binding messageTitle}"/> |
| | | |
| | | <ListView ItemsSource="{Binding messages}"> |
| | | <ListView.ItemTemplate> |
| | | <DataTemplate> |
| | | <Label Content="999"/> |
| | | </DataTemplate> |
| | | </ListView.ItemTemplate> |
| | | </ListView> |
| | | |
| | | </StackPanel> |
| | | |
| | | |
| | | </Window> |
| | |
| | | using DevComponents.DotNetBar; |
| | | using System.Windows; |
| | | using System.Drawing; |
| | | using System.Net.WebSockets; |
| | | using System; |
| | | using System.Threading.Tasks; |
| | | using System.Text; |
| | | using System.Diagnostics; |
| | | using System.Timers; |
| | | using System.Collections.ObjectModel; |
| | | using System.ComponentModel; |
| | | using System.Runtime.CompilerServices; |
| | | using PdmAlert.Entity; |
| | | |
| | | namespace PdmAlert |
| | | { |
| | | /// <summary> |
| | | /// MainWindow.xaml 的交互逻辑 |
| | | /// </summary> |
| | | public partial class MainWindow : Window |
| | | public partial class MainWindow : Window, INotifyPropertyChanged |
| | | { |
| | | #region INotifyPropertyChanged |
| | | public virtual event PropertyChangedEventHandler PropertyChanged; |
| | | |
| | | protected virtual void RaisePropertyChanged(string name) |
| | | { |
| | | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); |
| | | } |
| | | |
| | | protected void RaiseAndSetIfChanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null) |
| | | { |
| | | old = @new; |
| | | if (propertyName != null) |
| | | { |
| | | RaisePropertyChanged(propertyName); |
| | | } |
| | | } |
| | | #endregion |
| | | |
| | | private ClientWebSocket socket; |
| | | private Task readTask; |
| | | private Task writeTask; |
| | | private System.Timers.Timer heartbeatTimer; |
| | | |
| | | private string _messageTitle = "共有 0 条未读消息"; |
| | | |
| | | public string messageTitle |
| | | { |
| | | get => _messageTitle; |
| | | set => RaiseAndSetIfChanged(ref _messageTitle, value); |
| | | } |
| | | |
| | | private ObservableCollection<MsgData> _messages; |
| | | |
| | | public ObservableCollection<MsgData> messages |
| | | { |
| | | get => _messages; |
| | | set => RaiseAndSetIfChanged(ref _messages, value); |
| | | } |
| | | |
| | | public MainWindow() |
| | | { |
| | | InitializeComponent(); |
| | | } |
| | | |
| | | private long _RunningAlertId = 0; |
| | | private void Button_Click(object sender, RoutedEventArgs e) |
| | | private void Refresh_Click(object sender, RoutedEventArgs e) |
| | | { |
| | | eDesktopAlertColor color = eDesktopAlertColor.Default; |
| | | eAlertPosition position = eAlertPosition.BottomRight; |
| | | DesktopAlert.Show("123", "\uf005", eSymbolSet.Awesome, Color.Empty, color, position, 10, ++_RunningAlertId, AlertClicked); |
| | | |
| | | |
| | | } |
| | | |
| | | private void SwitchUser_Click(object sender, RoutedEventArgs e) |
| | | { |
| | | |
| | | |
| | | } |
| | | |
| | | private void AlertClicked(long alertId) |
| | | { |
| | | |
| | |
| | | |
| | | this.Left = screeWidth - this.Width; |
| | | this.Top = sHeight - this.Height; |
| | | ConnectWebSocket(); |
| | | } |
| | | |
| | | private async Task ConnectWebSocket() |
| | | { |
| | | try |
| | | { |
| | | ClientWebSocket ws = new ClientWebSocket(); |
| | | await ws.ConnectAsync(new Uri($"ws://localhost:8888/pdm-web/daws/{LoginUser.CurrentUser?.id}"), default); |
| | | socket = ws; |
| | | ReadMsg(); |
| | | StartHeartbeat(); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | await ConnectWebSocket(); |
| | | } |
| | | } |
| | | |
| | | private void ReadMsg() |
| | | { |
| | | readTask = Task.Run(() => |
| | | { |
| | | while (socket.State == WebSocketState.Open) |
| | | { |
| | | byte[] buffer = new byte[1024]; |
| | | var task = socket.ReceiveAsync(new ArraySegment<byte>(buffer), default); |
| | | task.Wait(); |
| | | var res = task.Result; |
| | | var msg = Encoding.UTF8.GetString(buffer, 0, res.Count); |
| | | HandleMsg(msg); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | private void HandleMsg(string msg) |
| | | { |
| | | if (string.IsNullOrEmpty(msg) || msg == "heartcheck") |
| | | { |
| | | return; |
| | | } |
| | | Debug.WriteLine(msg); |
| | | Dispatcher.Invoke(() => |
| | | { |
| | | eDesktopAlertColor color = eDesktopAlertColor.Default; |
| | | eAlertPosition position = eAlertPosition.BottomRight; |
| | | DesktopAlert.Show(msg, "\uf005", eSymbolSet.Awesome, Color.Empty, color, position, 5, |
| | | DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), AlertClicked); |
| | | }); |
| | | } |
| | | |
| | | private void StartHeartbeat() |
| | | { |
| | | heartbeatTimer = new System.Timers.Timer(30 * 1000); |
| | | heartbeatTimer.Elapsed += HeartbeatTimer_Elapsed; |
| | | heartbeatTimer.AutoReset = true; |
| | | heartbeatTimer.Start(); |
| | | } |
| | | |
| | | private void HeartbeatTimer_Elapsed(object sender, ElapsedEventArgs e) |
| | | { |
| | | if (socket == null || socket.State != WebSocketState.Open) |
| | | { |
| | | DoDispose(); |
| | | ConnectWebSocket().Wait(); |
| | | } |
| | | else |
| | | { |
| | | byte[] buffer = Encoding.UTF8.GetBytes("test"); |
| | | socket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, default); |
| | | } |
| | | } |
| | | |
| | | public void DoDispose() |
| | | { |
| | | if (heartbeatTimer != null) |
| | | { |
| | | heartbeatTimer.Stop(); |
| | | heartbeatTimer.Dispose(); |
| | | heartbeatTimer = null; |
| | | } |
| | | if (readTask != null) |
| | | { |
| | | readTask.Dispose(); |
| | | readTask = null; |
| | | } |
| | | if (socket != null) |
| | | { |
| | | try |
| | | { |
| | | socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "DoDispose", default).Wait(); |
| | | socket.Dispose(); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | |
| | | } |
| | | finally |
| | | { |
| | | socket = null; |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void Hide_Click(object sender, RoutedEventArgs e) |
| | |
| | | this.Hide(); |
| | | } |
| | | |
| | | private void Window_Deactivated(object sender, EventArgs e) |
| | | { |
| | | this.Hide(); |
| | | } |
| | | } |
| | | } |
| | |
| | | <ErrorReport>prompt</ErrorReport> |
| | | <Prefer32Bit>true</Prefer32Bit> |
| | | </PropertyGroup> |
| | | <PropertyGroup> |
| | | <ApplicationManifest>app.manifest</ApplicationManifest> |
| | | </PropertyGroup> |
| | | <ItemGroup> |
| | | <Reference Include="DevComponents.DotNetBar2"> |
| | | <HintPath>..\lib\DevComponents.DotNetBar2.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="Newtonsoft.Json"> |
| | | <HintPath>lib\Newtonsoft.Json.dll</HintPath> |
| | | </Reference> |
| | | <Reference Include="System" /> |
| | | <Reference Include="System.Data" /> |
| | | <Reference Include="System.Drawing" /> |
| | | <Reference Include="System.Web" /> |
| | | <Reference Include="System.Windows.Forms" /> |
| | | <Reference Include="System.Xml" /> |
| | | <Reference Include="Microsoft.CSharp" /> |
| | |
| | | <Generator>MSBuild:Compile</Generator> |
| | | <SubType>Designer</SubType> |
| | | </ApplicationDefinition> |
| | | <Compile Include="Util.cs" /> |
| | | <Page Include="LoginWindow.xaml"> |
| | | <SubType>Designer</SubType> |
| | | <Generator>MSBuild:Compile</Generator> |
| | |
| | | <SubType>Code</SubType> |
| | | </Compile> |
| | | <Compile Include="DockApp.cs" /> |
| | | <Compile Include="Encryptor.cs" /> |
| | | <Compile Include="Entity\MsgData.cs" /> |
| | | <Compile Include="LoginUser.cs" /> |
| | | <Compile Include="LoginWindow.xaml.cs"> |
| | | <DependentUpon>LoginWindow.xaml</DependentUpon> |
| | | </Compile> |
| | |
| | | <Generator>ResXFileCodeGenerator</Generator> |
| | | <LastGenOutput>Resources.Designer.cs</LastGenOutput> |
| | | </EmbeddedResource> |
| | | <None Include="app.manifest" /> |
| | | <Resource Include="Icon\iconfont.ttf" /> |
| | | <None Include="Properties\Settings.settings"> |
| | | <Generator>SettingsSingleFileGenerator</Generator> |
| | | <LastGenOutput>Settings.Designer.cs</LastGenOutput> |
| | |
| | | <ItemGroup> |
| | | <None Include="App.config" /> |
| | | </ItemGroup> |
| | | <ItemGroup /> |
| | | <ItemGroup> |
| | | <Content Include="Icon\Icon.ico"> |
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory> |
New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.IO; |
| | | using System.Linq; |
| | | using System.Net.Http; |
| | | using System.Reflection; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using System.Web; |
| | | using Newtonsoft.Json; |
| | | |
| | | namespace PdmAlert.Util |
| | | { |
| | | [Serializable] |
| | | public class Result<T> |
| | | { |
| | | [JsonProperty("success")] |
| | | public bool success |
| | | { |
| | | get; set; |
| | | } |
| | | |
| | | [JsonProperty("message")] |
| | | public string message |
| | | { |
| | | get; set; |
| | | } |
| | | |
| | | [JsonProperty("code")] |
| | | public int code |
| | | { |
| | | get; set; |
| | | } |
| | | |
| | | [JsonProperty("result")] |
| | | public T result |
| | | { |
| | | get; set; |
| | | } |
| | | } |
| | | |
| | | public static class ResultHandler |
| | | { |
| | | public static T HandleResult<T>(this Result<T> result) |
| | | { |
| | | if (result.success) |
| | | { |
| | | return result.result; |
| | | } |
| | | throw new CustomWebException(result.message); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 自定义从Web返回的异常 |
| | | /// </summary> |
| | | public class CustomWebException : Exception |
| | | { |
| | | public CustomWebException() |
| | | { |
| | | |
| | | } |
| | | |
| | | public CustomWebException(string message) : base(message) |
| | | { |
| | | |
| | | } |
| | | |
| | | public CustomWebException(string message, Exception inner) : base(message, inner) |
| | | { |
| | | |
| | | } |
| | | } |
| | | |
| | | public class JsonUtil |
| | | { |
| | | static readonly JsonSerializerSettings JsSetting = new JsonSerializerSettings() |
| | | { |
| | | NullValueHandling = NullValueHandling.Ignore |
| | | }; |
| | | |
| | | public static T Deserialize<T>(string jsonStr) |
| | | { |
| | | return JsonConvert.DeserializeObject<T>(jsonStr); |
| | | } |
| | | |
| | | public static string Serialize(object obj) |
| | | { |
| | | return JsonConvert.SerializeObject(obj); |
| | | } |
| | | |
| | | public static string Stringfiy(object obj) |
| | | { |
| | | return JsonConvert.SerializeObject(obj, Formatting.Indented, JsSetting); |
| | | } |
| | | |
| | | } |
| | | |
| | | public static class HttpUtil |
| | | { |
| | | |
| | | /// <summary> |
| | | /// Http GET 同步获取对象 |
| | | /// </summary> |
| | | /// <typeparam name="T">对象类型</typeparam> |
| | | /// <param name="client">客户端</param> |
| | | /// <param name="url">url</param> |
| | | /// <param name="models">参数</param> |
| | | /// <returns>Http返回结果</returns> |
| | | public static Result<T> GetSyncAction<T>(this HttpClient client, string url, params object[] models) |
| | | { |
| | | return JsonUtil.Deserialize<Result<T>>(GetSyncAction(client, url, models)); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// Http GET 同步获取字符 |
| | | /// </summary> |
| | | /// <param name="client">客户端</param> |
| | | /// <param name="url">url</param> |
| | | /// <param name="models">参数</param> |
| | | /// <returns>Http返回结果</returns> |
| | | public static string GetSyncAction(this HttpClient client, string url, params object[] models) |
| | | { |
| | | try |
| | | { |
| | | foreach (object model in models) |
| | | { |
| | | url = url.ModelToUriParam(model); |
| | | } |
| | | |
| | | Task<string> task = client.GetStringAsync(url); |
| | | task.Wait(); |
| | | return task.Result; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | throw new CustomWebException("请求异常", e); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// Http GET 异步获取对象 |
| | | /// </summary> |
| | | /// <typeparam name="T">对象类型</typeparam> |
| | | /// <param name="client">客户端</param> |
| | | /// <param name="url">url</param> |
| | | /// <param name="models">参数</param> |
| | | /// <returns>异步Http返回结果</returns> |
| | | public static async Task<Result<T>> GetAsyncAction<T>(this HttpClient client, string url, params object[] models) |
| | | { |
| | | try |
| | | { |
| | | foreach (object model in models) |
| | | { |
| | | url = url.ModelToUriParam(model); |
| | | } |
| | | return JsonUtil.Deserialize<Result<T>>(await client.GetStringAsync(url)); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | throw new CustomWebException("请求异常", e); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// Http POST 同步获取对象 |
| | | /// </summary> |
| | | /// <typeparam name="T">对象类型</typeparam> |
| | | /// <param name="client">客户端</param> |
| | | /// <param name="url">url</param> |
| | | /// <param name="data">参数json字符</param> |
| | | /// <returns>Http返回结果</returns> |
| | | public static Result<T> PostSyncAction<T>(this HttpClient client, string url, string data) |
| | | { |
| | | StringContent content = new StringContent(data, Encoding.UTF8, "application/json"); |
| | | Task<HttpResponseMessage> task = client.PostAsync(url, content); |
| | | task.Wait(); |
| | | HttpResponseMessage response = task.Result; |
| | | response.EnsureSuccessStatusCode(); |
| | | Task<string> task2 = response.Content.ReadAsStringAsync(); |
| | | task2.Wait(); |
| | | string responseBody = task2.Result; |
| | | return JsonUtil.Deserialize<Result<T>>(responseBody); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// Http POST 同步获取对象 |
| | | /// </summary> |
| | | /// <typeparam name="T">对象类型</typeparam> |
| | | /// <param name="client">客户端</param> |
| | | /// <param name="url">url</param> |
| | | /// <param name="content">Http负载</param> |
| | | /// <returns>Http返回结果</returns> |
| | | public static Result<T> PostSyncAction<T>(this HttpClient client, string url, HttpContent content) |
| | | { |
| | | Task<HttpResponseMessage> task = client.PostAsync(url, content); |
| | | task.Wait(); |
| | | HttpResponseMessage response = task.Result; |
| | | response.EnsureSuccessStatusCode(); |
| | | Task<string> task2 = response.Content.ReadAsStringAsync(); |
| | | task2.Wait(); |
| | | return JsonUtil.Deserialize<Result<T>>(task2.Result); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// Http POST 同步获取对象 |
| | | /// </summary> |
| | | /// <typeparam name="T">对象类型</typeparam> |
| | | /// <param name="client">客户端</param> |
| | | /// <param name="data">参数对象</param> |
| | | /// <param name="url">url</param> |
| | | /// <returns>Http返回结果</returns> |
| | | public static Result<T> PostSyncAction<T>(this HttpClient client, object data, string url) |
| | | { |
| | | string dataStr = JsonUtil.Serialize(data); |
| | | StringContent content = new StringContent(dataStr, Encoding.UTF8, "application/json"); |
| | | Task<HttpResponseMessage> task = client.PostAsync(url, content); |
| | | task.Wait(); |
| | | HttpResponseMessage response = task.Result; |
| | | response.EnsureSuccessStatusCode(); |
| | | Task<string> task2 = response.Content.ReadAsStringAsync(); |
| | | task2.Wait(); |
| | | string responseBody = task2.Result; |
| | | return JsonUtil.Deserialize<Result<T>>(responseBody); |
| | | } |
| | | |
| | | public static string PostSyncAction(this HttpClient client, string url, string data) |
| | | { |
| | | StringContent content = new StringContent(data, Encoding.UTF8, "application/json"); |
| | | Task<HttpResponseMessage> task = client.PostAsync(url, content); |
| | | task.Wait(); |
| | | HttpResponseMessage response = task.Result; |
| | | response.EnsureSuccessStatusCode(); |
| | | Task<string> task2 = response.Content.ReadAsStringAsync(); |
| | | task2.Wait(); |
| | | return task2.Result; |
| | | } |
| | | |
| | | public static async Task<T> PostAsyncAction<T>(this HttpClient client, string url, string data) |
| | | { |
| | | StringContent content = new StringContent(data, Encoding.UTF8, "application/json"); |
| | | HttpResponseMessage response = await client.PostAsync(url, content); |
| | | _ = response.EnsureSuccessStatusCode(); |
| | | return JsonUtil.Deserialize<T>(await response.Content.ReadAsStringAsync()); |
| | | } |
| | | |
| | | public static async Task<Result<T>> PostAsyncAction<T>(this HttpClient client, string url, object data) |
| | | { |
| | | string dataStr = JsonUtil.Serialize(data); |
| | | StringContent content = new StringContent(dataStr, Encoding.UTF8, "application/json"); |
| | | HttpResponseMessage response = await client.PostAsync(url, content); |
| | | _ = response.EnsureSuccessStatusCode(); |
| | | return JsonUtil.Deserialize<Result<T>>(await response.Content.ReadAsStringAsync()); |
| | | } |
| | | |
| | | public static async Task<Result<T>> PostAsyncAction<T>(this HttpClient client, string url, HttpContent content) |
| | | { |
| | | HttpResponseMessage response = await client.PostAsync(url, content); |
| | | _ = response.EnsureSuccessStatusCode(); |
| | | return JsonUtil.Deserialize<Result<T>>(await response.Content.ReadAsStringAsync()); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 下载文件保存到绝对路径 |
| | | /// </summary> |
| | | /// <param name="client"></param> |
| | | /// <param name="url"></param> |
| | | /// <param name="absolutePath"></param> |
| | | /// <param name="models"></param> |
| | | public static async Task GetDownload(this HttpClient client, string url, string absolutePath, params object[] models) |
| | | { |
| | | foreach (object model in models) |
| | | { |
| | | url = url.ModelToUriParam(model); |
| | | } |
| | | HttpResponseMessage response = await client.GetAsync(url); |
| | | int code = Convert.ToInt32(response.StatusCode); |
| | | if (code == 200) |
| | | { |
| | | using (Stream stream = await response.Content.ReadAsStreamAsync()) |
| | | { |
| | | string suffix = Path.GetExtension(response.RequestMessage.RequestUri.ToString()); |
| | | using (FileStream fs = new FileStream(absolutePath, FileMode.OpenOrCreate)) |
| | | { |
| | | byte[] buffer = new byte[1024]; |
| | | int readLength = 0; |
| | | int length; |
| | | while ((length = await stream.ReadAsync(buffer, 0, buffer.Length)) != 0) |
| | | { |
| | | readLength += length; |
| | | fs.Write(buffer, 0, length); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | string error = "图纸下载失败"; |
| | | if (response.Headers.TryGetValues("FileName", out IEnumerable<string> values)) |
| | | { |
| | | error = values.First(); |
| | | } |
| | | throw new CustomWebException(error); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 下载文件保存到绝对路径 |
| | | /// </summary> |
| | | /// <param name="client"></param> |
| | | /// <param name="url"></param> |
| | | /// <param name="absolutePath"></param> |
| | | /// <param name="models"></param> |
| | | public static void GetDownloadSync(this HttpClient client, string url, string absolutePath, params object[] models) |
| | | { |
| | | foreach (object model in models) |
| | | { |
| | | url = url.ModelToUriParam(model); |
| | | } |
| | | Task<HttpResponseMessage> task = client.GetAsync(url); |
| | | task.Wait(); |
| | | HttpResponseMessage response = task.Result; |
| | | int code = Convert.ToInt32(response.StatusCode); |
| | | if (code == 200) |
| | | { |
| | | Task<Stream> task2 = response.Content.ReadAsStreamAsync(); |
| | | task2.Wait(); |
| | | using (Stream stream = task2.Result) |
| | | { |
| | | string suffix = Path.GetExtension(response.RequestMessage.RequestUri.ToString()); |
| | | using (FileStream fs = new FileStream(absolutePath, FileMode.OpenOrCreate)) |
| | | { |
| | | byte[] buffer = new byte[1024]; |
| | | int readLength = 0; |
| | | int length; |
| | | while ((length = stream.Read(buffer, 0, buffer.Length)) != 0) |
| | | { |
| | | readLength += length; |
| | | fs.Write(buffer, 0, length); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | string error = "图纸下载失败"; |
| | | if (response.Headers.TryGetValues("FileName", out IEnumerable<string> values)) |
| | | { |
| | | error = HttpUtility.UrlDecode(values.First()); |
| | | } |
| | | throw new CustomWebException(error); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 下载文件到指定文件夹 |
| | | /// </summary> |
| | | /// <param name="client"></param> |
| | | /// <param name="url"></param> |
| | | /// <param name="dir"></param> |
| | | /// <param name="fileName"></param> |
| | | /// <param name="models"></param> |
| | | public static async Task GetDownload(this HttpClient client, string url, string dir, string fileName, params object[] models) |
| | | { |
| | | foreach (object model in models) |
| | | { |
| | | url = url.ModelToUriParam(model); |
| | | } |
| | | HttpResponseMessage response = await client.GetAsync(url); |
| | | using (Stream stream = await response.Content.ReadAsStreamAsync()) |
| | | { |
| | | string suffix = Path.GetExtension(response.RequestMessage.RequestUri.ToString()); |
| | | using (FileStream fs = new FileStream($"{dir}/{fileName}", FileMode.CreateNew)) |
| | | { |
| | | byte[] buffer = new byte[1024]; |
| | | int readLength = 0; |
| | | int length; |
| | | while ((length = await stream.ReadAsync(buffer, 0, buffer.Length)) != 0) |
| | | { |
| | | readLength += length; |
| | | fs.Write(buffer, 0, length); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | public static async void GetDownloadWithName(this HttpClient client, string url, string dir, params object[] models) |
| | | { |
| | | foreach (object model in models) |
| | | { |
| | | url = url.ModelToUriParam(model); |
| | | } |
| | | |
| | | HttpResponseMessage response = await client.GetAsync(url); |
| | | string fileName = HttpUtility.UrlDecode(response.Headers.GetValues("FileName").FirstOrDefault()); |
| | | using (Stream stream = await response.Content.ReadAsStreamAsync()) |
| | | { |
| | | string suffix = Path.GetExtension(response.RequestMessage.RequestUri.ToString()); |
| | | using (FileStream fs = new FileStream($"{dir}/{fileName}", FileMode.CreateNew)) |
| | | { |
| | | byte[] buffer = new byte[1024]; |
| | | int readLength = 0; |
| | | int length; |
| | | while ((length = await stream.ReadAsync(buffer, 0, buffer.Length)) != 0) |
| | | { |
| | | readLength += length; |
| | | fs.Write(buffer, 0, length); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | public static string ModelToUriParam(this string url, object obj) |
| | | { |
| | | PropertyInfo[] properties = obj.GetType().GetProperties(); |
| | | StringBuilder sb = new StringBuilder() |
| | | .Append(url).Append("?"); |
| | | if (obj is Dictionary<string, string>) |
| | | { |
| | | Dictionary<string, string> dict = (Dictionary<string, string>)obj; |
| | | foreach (var item in dict) |
| | | { |
| | | if (item.Value == null || string.IsNullOrWhiteSpace(item.Value)) |
| | | { |
| | | continue; |
| | | } |
| | | sb = sb.Append(item.Key) |
| | | .Append("=") |
| | | .Append(HttpUtility.UrlEncode(item.Value)) |
| | | .Append("&"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | foreach (PropertyInfo p in properties) |
| | | { |
| | | object v = p.GetValue(obj, null); |
| | | if (v == null || string.IsNullOrWhiteSpace(v.ToString())) |
| | | { |
| | | continue; |
| | | } |
| | | sb = sb.Append(p.Name) |
| | | .Append("=") |
| | | .Append(HttpUtility.UrlEncode(v.ToString())) |
| | | .Append("&"); |
| | | } |
| | | } |
| | | sb = sb.Remove(sb.Length - 1, 1); |
| | | return sb.ToString(); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"> |
| | | <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/> |
| | | <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> |
| | | <security> |
| | | <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> |
| | | <!-- UAC 清单选项 |
| | | 如果想要更改 Windows 用户帐户控制级别,请使用 |
| | | 以下节点之一替换 requestedExecutionLevel 节点。 |
| | | |
| | | <requestedExecutionLevel level="asInvoker" uiAccess="false" /> |
| | | <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> |
| | | <requestedExecutionLevel level="highestAvailable" uiAccess="false" /> |
| | | |
| | | 指定 requestedExecutionLevel 元素将禁用文件和注册表虚拟化。 |
| | | 如果你的应用程序需要此虚拟化来实现向后兼容性,则移除此 |
| | | 元素。 |
| | | --> |
| | | <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> |
| | | </requestedPrivileges> |
| | | </security> |
| | | </trustInfo> |
| | | |
| | | <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> |
| | | <application> |
| | | <!-- 设计此应用程序与其一起工作且已针对此应用程序进行测试的 |
| | | Windows 版本的列表。取消评论适当的元素, |
| | | Windows 将自动选择最兼容的环境。 --> |
| | | |
| | | <!-- Windows Vista --> |
| | | <!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />--> |
| | | |
| | | <!-- Windows 7 --> |
| | | <!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />--> |
| | | |
| | | <!-- Windows 8 --> |
| | | <!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />--> |
| | | |
| | | <!-- Windows 8.1 --> |
| | | <!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />--> |
| | | |
| | | <!-- Windows 10 --> |
| | | <!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />--> |
| | | |
| | | </application> |
| | | </compatibility> |
| | | |
| | | <!-- 指示该应用程序可感知 DPI 且 Windows 在 DPI 较高时将不会对其进行 |
| | | 自动缩放。Windows Presentation Foundation (WPF)应用程序自动感知 DPI,无需 |
| | | 选择加入。选择加入此设置的 Windows 窗体应用程序(面向 .NET Framework 4.6)还应 |
| | | 在其 app.config 中将 "EnableWindowsFormsHighDpiAutoResizing" 设置设置为 "true"。 |
| | | |
| | | 将应用程序设为感知长路径。请参阅 https://docs.microsoft.com/windows/win32/fileio/maximum-file-path-limitation --> |
| | | <!-- |
| | | <application xmlns="urn:schemas-microsoft-com:asm.v3"> |
| | | <windowsSettings> |
| | | <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware> |
| | | <longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware> |
| | | </windowsSettings> |
| | | </application> |
| | | --> |
| | | |
| | | <!-- 启用 Windows 公共控件和对话框的主题(Windows XP 和更高版本) --> |
| | | <!-- |
| | | <dependency> |
| | | <dependentAssembly> |
| | | <assemblyIdentity |
| | | type="win32" |
| | | name="Microsoft.Windows.Common-Controls" |
| | | version="6.0.0.0" |
| | | processorArchitecture="*" |
| | | publicKeyToken="6595b64144ccf1df" |
| | | language="*" |
| | | /> |
| | | </dependentAssembly> |
| | | </dependency> |
| | | --> |
| | | |
| | | </assembly> |