From 9ee7d3bd9c58a204b1efe38e6be61155bbb15c16 Mon Sep 17 00:00:00 2001
From: chr <chr@chr.com>
Date: 星期三, 21 八月 2024 19:16:22 +0800
Subject: [PATCH] Merge branch 'master' of http://10.10.28.13:8080/r/PDM/PdmSwPlugin2
---
PdmAlert/Entity/MsgData.cs | 8
PdmAlert/app.manifest | 79 +++
PdmAlert/MainWindow.xaml.cs | 171 +++++++
PdmAlert/LoginWindow.xaml | 26 +
PdmAlert/Util.cs | 452 +++++++++++++++++++
PdmAlert/Encryptor.cs | 63 ++
PdmAlert/App.xaml.cs | 23
PdmAlert/PdmAlert.csproj | 14
PdmAlert/MainWindow.xaml | 182 ++++---
PdmAlert/lib/Newtonsoft.Json.dll | 0
PdmAlert/Icon/iconfont.ttf | 0
PdmAlert/LoginUser.cs | 117 +++++
PdmAlert/.vs/PdmAlert/v17/DocumentLayout.json | 184 ++++++++
PdmAlert/LoginWindow.xaml.cs | 24
PdmAlert/DockApp.cs | 1
15 files changed, 1,231 insertions(+), 113 deletions(-)
diff --git a/PdmAlert/.vs/PdmAlert/v17/DocumentLayout.json b/PdmAlert/.vs/PdmAlert/v17/DocumentLayout.json
new file mode 100644
index 0000000..fb64986
--- /dev/null
+++ b/PdmAlert/.vs/PdmAlert/v17/DocumentLayout.json
@@ -0,0 +1,184 @@
+{
+ "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": ""
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/PdmAlert/App.xaml.cs b/PdmAlert/App.xaml.cs
index 67e9db4..9740dfb 100644
--- a/PdmAlert/App.xaml.cs
+++ b/PdmAlert/App.xaml.cs
@@ -1,10 +1,4 @@
-锘縰sing System;
-using System.Collections.Generic;
-using System.Configuration;
-using System.Data;
-using System.Linq;
-using System.Threading.Tasks;
-using System.Windows;
+锘縰sing System.Windows;
namespace PdmAlert
{
@@ -14,16 +8,27 @@
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();
+
}
}
}
diff --git a/PdmAlert/DockApp.cs b/PdmAlert/DockApp.cs
index b68feff..4e78dbc 100644
--- a/PdmAlert/DockApp.cs
+++ b/PdmAlert/DockApp.cs
@@ -38,6 +38,7 @@
if (showWindow != null)
{
showWindow.Show();
+ showWindow.Activate();
}
else
{
diff --git a/PdmAlert/Encryptor.cs b/PdmAlert/Encryptor.cs
new file mode 100644
index 0000000..88768ab
--- /dev/null
+++ b/PdmAlert/Encryptor.cs
@@ -0,0 +1,63 @@
+锘縰sing 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();
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/PdmAlert/Entity/MsgData.cs b/PdmAlert/Entity/MsgData.cs
new file mode 100644
index 0000000..c428e94
--- /dev/null
+++ b/PdmAlert/Entity/MsgData.cs
@@ -0,0 +1,8 @@
+锘縩amespace PdmAlert.Entity
+{
+ public class MsgData
+ {
+ public string title { get; set; }
+ public string content { get; set; }
+ }
+}
diff --git a/PdmAlert/Icon/iconfont.ttf b/PdmAlert/Icon/iconfont.ttf
new file mode 100644
index 0000000..66fd530
--- /dev/null
+++ b/PdmAlert/Icon/iconfont.ttf
Binary files differ
diff --git a/PdmAlert/LoginUser.cs b/PdmAlert/LoginUser.cs
new file mode 100644
index 0000000..f397804
--- /dev/null
+++ b/PdmAlert/LoginUser.cs
@@ -0,0 +1,117 @@
+锘縰sing 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);
+ }
+ }
+}
diff --git a/PdmAlert/LoginWindow.xaml b/PdmAlert/LoginWindow.xaml
index 73fe38e..d6f4081 100644
--- a/PdmAlert/LoginWindow.xaml
+++ b/PdmAlert/LoginWindow.xaml
@@ -6,7 +6,27 @@
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>
diff --git a/PdmAlert/LoginWindow.xaml.cs b/PdmAlert/LoginWindow.xaml.cs
index 99cd421..6db9861 100644
--- a/PdmAlert/LoginWindow.xaml.cs
+++ b/PdmAlert/LoginWindow.xaml.cs
@@ -1,16 +1,4 @@
-锘縰sing 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;
+锘縰sing System.Windows;
namespace PdmAlert
{
@@ -23,5 +11,15 @@
{
InitializeComponent();
}
+
+ public void Button_Click(object sender, RoutedEventArgs e)
+ {
+ if (LoginUser.Login(usernameTextBlock.Text, passwordTextBlock.Password, rememberMeInput.IsChecked == true))
+ {
+
+
+ }
+
+ }
}
}
diff --git a/PdmAlert/MainWindow.xaml b/PdmAlert/MainWindow.xaml
index 1f51b53..3defeb9 100644
--- a/PdmAlert/MainWindow.xaml
+++ b/PdmAlert/MainWindow.xaml
@@ -6,115 +6,135 @@
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>
diff --git a/PdmAlert/MainWindow.xaml.cs b/PdmAlert/MainWindow.xaml.cs
index 1f2fcde..8d0f0e9 100644
--- a/PdmAlert/MainWindow.xaml.cs
+++ b/PdmAlert/MainWindow.xaml.cs
@@ -2,27 +2,80 @@
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)
{
@@ -35,6 +88,108 @@
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)
@@ -42,5 +197,9 @@
this.Hide();
}
+ private void Window_Deactivated(object sender, EventArgs e)
+ {
+ this.Hide();
+ }
}
}
diff --git a/PdmAlert/PdmAlert.csproj b/PdmAlert/PdmAlert.csproj
index 74f7194..9a18d0d 100644
--- a/PdmAlert/PdmAlert.csproj
+++ b/PdmAlert/PdmAlert.csproj
@@ -54,13 +54,20 @@
<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" />
@@ -80,6 +87,7 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
+ <Compile Include="Util.cs" />
<Page Include="LoginWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -93,6 +101,9 @@
<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>
@@ -119,6 +130,8 @@
<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>
@@ -127,7 +140,6 @@
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
- <ItemGroup />
<ItemGroup>
<Content Include="Icon\Icon.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
diff --git a/PdmAlert/Util.cs b/PdmAlert/Util.cs
new file mode 100644
index 0000000..b5ed241
--- /dev/null
+++ b/PdmAlert/Util.cs
@@ -0,0 +1,452 @@
+锘縰sing 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();
+ }
+ }
+}
diff --git a/PdmAlert/app.manifest b/PdmAlert/app.manifest
new file mode 100644
index 0000000..4fddf7e
--- /dev/null
+++ b/PdmAlert/app.manifest
@@ -0,0 +1,79 @@
+锘�<?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 杈冮珮鏃跺皢涓嶄細瀵瑰叾杩涜
+ 鑷姩缂╂斁銆俉indows 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>
diff --git a/PdmAlert/lib/Newtonsoft.Json.dll b/PdmAlert/lib/Newtonsoft.Json.dll
new file mode 100644
index 0000000..341d08f
--- /dev/null
+++ b/PdmAlert/lib/Newtonsoft.Json.dll
Binary files differ
--
Gitblit v1.9.1