Chr
2024-08-23 12acdf14fcddae8d16e00b7b981559da67ce60ea
完善消息通知程序;
5个文件已删除
11个文件已添加
13个文件已修改
1344 ■■■■ 已修改文件
PdmAlert/.vs/PdmAlert/v17/DocumentLayout.json 248 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/App.xaml.cs 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/DockApp.cs 35 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/Encryptor.cs 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/Entity/MsgData.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/Icon.ico 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/LoginUser.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/LoginWindow.xaml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/LoginWindow.xaml.cs 44 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/MainWindow.xaml 119 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/MainWindow.xaml.cs 328 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/PdmAlert.csproj 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/PdmAlert.iss 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/Properties/AssemblyInfo.cs 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/ReleaseSettings/ToolSetting.xml 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/ReleaseSettings/UpdaterSetting.xml 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/Settings/ToolSetting.xml 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/Settings/UpdaterSetting.xml 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/ToolSetting.cs 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/Util.cs 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/lib/Fleck.dll 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/lib/log4net.dll 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/lib/websocket-sharp.dll 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/log4net.config 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PdmSw/.vs/PdmSw/FileContentIndex/1e97e5f0-ad3c-4fa0-845d-d0d4b508b3aa.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
PdmSw/.vs/PdmSw/FileContentIndex/4671096b-140b-4229-a025-97df57021262.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
PdmSw/.vs/PdmSw/FileContentIndex/6b982709-fe14-4b34-a175-b50bca946af4.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
PdmSw/.vs/PdmSw/FileContentIndex/92f976c2-0875-4c1f-bb43-2d01b4d875dc.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
PdmSw/.vs/PdmSw/FileContentIndex/a5ce55b6-65c6-4de9-8b17-865577fcdb4d.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
PdmAlert/.vs/PdmAlert/v17/DocumentLayout.json
@@ -3,44 +3,49 @@
  "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:{00000000-0000-0000-0000-000000000000}|\u003CSolution\u003E|PdmAlert||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|"
    },
    {
      "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:{EDC73C56-D0C5-4AC9-B296-3253915EF933}|..\\..\\CommonUpdater\\VersionControl\\VersionControl.csproj|c:\\main\\workspace\\visualstudio\\commonupdater\\versioncontrol\\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.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
      "AbsoluteMoniker": "D:0:0:{11C62041-5E6E-4230-A5E8-4246C033BA67}|..\\..\\CommonUpdater\\AutoUpdater\\AutoUpdater.csproj|c:\\main\\workspace\\visualstudio\\commonupdater\\autoupdater\\settings\\updatersetting.xml||{FA3CD31E-987B-443A-9B81-186104E8DAC1}"
    },
    {
      "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|c:\\main\\workspace\\visualstudio\\pdmswplugin2\\pdmalert\\settings\\updatersetting.xml||{FA3CD31E-987B-443A-9B81-186104E8DAC1}",
      "RelativeMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|solutionrelative:settings\\updatersetting.xml||{FA3CD31E-987B-443A-9B81-186104E8DAC1}"
    },
    {
      "AbsoluteMoniker": "D:0:0:{11C62041-5E6E-4230-A5E8-4246C033BA67}|..\\..\\CommonUpdater\\AutoUpdater\\AutoUpdater.csproj|c:\\main\\workspace\\visualstudio\\commonupdater\\autoupdater\\mainwindow.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
    },
    {
      "AbsoluteMoniker": "D:0:0:{11C62041-5E6E-4230-A5E8-4246C033BA67}|..\\..\\CommonUpdater\\AutoUpdater\\AutoUpdater.csproj|c:\\main\\workspace\\visualstudio\\commonupdater\\autoupdater\\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.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}",
      "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:{EDC73C56-D0C5-4AC9-B296-3253915EF933}|..\\..\\CommonUpdater\\VersionControl\\VersionControl.csproj|c:\\main\\workspace\\visualstudio\\commonupdater\\versioncontrol\\versionutil.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||{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\\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}"
      "AbsoluteMoniker": "D:0:0:{FC7FBDE7-D0D2-4E79-A586-501ABC73FE46}|PdmAlert.csproj|c:\\main\\workspace\\visualstudio\\pdmswplugin2\\pdmalert\\||{B270807C-D8C6-49EB-8EBE-8E8D566637A1}|1e78f8db-6c07-4d61-a18f-7514010abd56"
    }
  ],
  "DocumentGroupContainers": [
@@ -50,130 +55,159 @@
      "DocumentGroups": [
        {
          "DockedWidth": 200,
          "SelectedChildIndex": 7,
          "SelectedChildIndex": 0,
          "Children": [
            {
              "$type": "Document",
              "DocumentIndex": 0,
              "Title": "PdmAlert",
              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\PdmAlert.csproj",
              "RelativeDocumentMoniker": "PdmAlert.csproj",
              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\PdmAlert.csproj",
              "RelativeToolTip": "PdmAlert.csproj",
              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001001|",
              "WhenOpened": "2024-08-22T13:00:12.272Z",
              "EditorCaption": ""
            },
            {
              "$type": "Document",
              "DocumentIndex": 1,
              "Title": "Util.cs",
              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\CommonUpdater\\VersionControl\\Util.cs",
              "RelativeDocumentMoniker": "..\\..\\CommonUpdater\\VersionControl\\Util.cs",
              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\CommonUpdater\\VersionControl\\Util.cs",
              "RelativeToolTip": "..\\..\\CommonUpdater\\VersionControl\\Util.cs",
              "ViewState": "AQIAAIMBAAAAAAAAAAAgwKcBAAANAAAA",
              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
              "WhenOpened": "2024-08-22T12:56:26.502Z",
              "EditorCaption": ""
            },
            {
              "$type": "Document",
              "DocumentIndex": 2,
              "Title": "UpdaterSetting.xml",
              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\CommonUpdater\\AutoUpdater\\Settings\\UpdaterSetting.xml",
              "RelativeDocumentMoniker": "..\\..\\CommonUpdater\\AutoUpdater\\Settings\\UpdaterSetting.xml",
              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\CommonUpdater\\AutoUpdater\\Settings\\UpdaterSetting.xml",
              "RelativeToolTip": "..\\..\\CommonUpdater\\AutoUpdater\\Settings\\UpdaterSetting.xml",
              "ViewState": "AQIAAAAAAAAAAAAAAAAAAA8AAAARAAAA",
              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003576|",
              "WhenOpened": "2024-08-22T12:57:06.965Z",
              "EditorCaption": ""
            },
            {
              "$type": "Document",
              "DocumentIndex": 3,
              "Title": "UpdaterSetting.xml",
              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\Settings\\UpdaterSetting.xml",
              "RelativeDocumentMoniker": "Settings\\UpdaterSetting.xml",
              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\PdmSwPlugin2\\PdmAlert\\Settings\\UpdaterSetting.xml",
              "RelativeToolTip": "Settings\\UpdaterSetting.xml",
              "ViewState": "AQIAAAAAAAAAAAAAAAAAAAcAAAARAAAA",
              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003576|",
              "WhenOpened": "2024-08-22T11:46:07.203Z",
              "EditorCaption": ""
            },
            {
              "$type": "Document",
              "DocumentIndex": 4,
              "Title": "MainWindow.xaml.cs",
              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\CommonUpdater\\AutoUpdater\\MainWindow.xaml.cs",
              "RelativeDocumentMoniker": "..\\..\\CommonUpdater\\AutoUpdater\\MainWindow.xaml.cs",
              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\CommonUpdater\\AutoUpdater\\MainWindow.xaml.cs",
              "RelativeToolTip": "..\\..\\CommonUpdater\\AutoUpdater\\MainWindow.xaml.cs",
              "ViewState": "AQIAAKsAAAAAAAAAAAD4v7sAAAA8AAAA",
              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
              "WhenOpened": "2024-08-22T11:42:13.882Z",
              "EditorCaption": ""
            },
            {
              "$type": "Document",
              "DocumentIndex": 11,
              "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",
              "WhenOpened": "2024-08-22T11:41:42.779Z",
              "EditorCaption": ""
            },
            {
              "$type": "Document",
              "DocumentIndex": 9,
              "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": "AQIAAAAAAAAAAAAAAAAAAAkAAAASAAAA",
              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
              "WhenOpened": "2024-08-22T11:38:26.763Z",
              "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",
              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\CommonUpdater\\AutoUpdater\\Util.cs",
              "RelativeDocumentMoniker": "..\\..\\CommonUpdater\\AutoUpdater\\Util.cs",
              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\CommonUpdater\\AutoUpdater\\Util.cs",
              "RelativeToolTip": "..\\..\\CommonUpdater\\AutoUpdater\\Util.cs",
              "ViewState": "AQIAAGoAAAAAAAAAAAAkwKAAAAAFAAAA",
              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
              "WhenOpened": "2024-08-20T10:17:23.879Z"
              "WhenOpened": "2024-08-22T11:14:30.598Z",
              "EditorCaption": ""
            },
            {
              "$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",
              "DocumentIndex": 8,
              "Title": "VersionUtil.cs",
              "DocumentMoniker": "C:\\Main\\Workspace\\VisualStudio\\CommonUpdater\\VersionControl\\VersionUtil.cs",
              "RelativeDocumentMoniker": "..\\..\\CommonUpdater\\VersionControl\\VersionUtil.cs",
              "ToolTip": "C:\\Main\\Workspace\\VisualStudio\\CommonUpdater\\VersionControl\\VersionUtil.cs",
              "RelativeToolTip": "..\\..\\CommonUpdater\\VersionControl\\VersionUtil.cs",
              "ViewState": "AQIAAGwAAAAAAAAAAAAAAAgAAAAjAAAA",
              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
              "WhenOpened": "2024-08-20T09:14:07.015Z"
              "WhenOpened": "2024-08-22T10:35:18.104Z",
              "EditorCaption": ""
            },
            {
              "$type": "Document",
              "DocumentIndex": 6,
              "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": "AQIAAMMAAAAAAAAAAAAnwNcAAAAJAAAA",
              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
              "WhenOpened": "2024-08-22T10:31:21.777Z",
              "EditorCaption": ""
            },
            {
              "$type": "Document",
              "DocumentIndex": 10,
              "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",
              "WhenOpened": "2024-08-22T10:31:19.726Z",
              "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,
              "DocumentIndex": 7,
              "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",
              "ViewState": "AQIAAGwAAAAAAAAAAAAywHIAAAANAAAA",
              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
              "WhenOpened": "2024-08-20T03:42:24.667Z",
              "WhenOpened": "2024-08-22T10:29:45.832Z",
              "EditorCaption": ""
            }
          ]
PdmAlert/App.xaml.cs
@@ -1,4 +1,11 @@
using System.Windows;
using CommonUpdater.VersionControl;
using log4net;
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows;
namespace PdmAlert
{
@@ -7,22 +14,104 @@
    /// </summary>
    public partial class App : Application
    {
        public static readonly string AppId = "PdmMsgAlert";
        public static readonly string Version = "0.0.0.1";
        DockApp dockApp;
        LoginWindow loginWindow;
        private static System.Threading.Mutex mutex;
        private static ILog Logger = LogManager.GetLogger("MsgAlert");
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            this.ShutdownMode = ShutdownMode.OnExplicitShutdown;
            if (LoginUser.TryAutoLogin())
            mutex = new System.Threading.Mutex(true, "MsgAlert_OnlyRunOne");
            if (mutex.WaitOne(0, false))
            {
                base.OnStartup(e);
                this.ShutdownMode = ShutdownMode.OnLastWindowClose;
                // 写入版本,就算异常了也不报错
                try
                {
                    VersionUtil.SetPluginVersion(AppId, Version);
                }
                catch (Exception ex)
                {
                    Logger.Error("Write App Version Failed.", ex);
                }
                dockApp = new DockApp();
                dockApp.Run();
                Task.Run(() => CheckUpdate());
                if (LoginUser.TryAutoLogin())
                {
                    InitDockApp();
                }
                else
                {
                    loginWindow = new LoginWindow();
                    loginWindow.Show();
                }
            }
            else
            {
                loginWindow = new LoginWindow();
                loginWindow.Show();
                MessageBox.Show("请勿多次运行程序!", "提示");
                this.Shutdown();
            }
        }
        public void CheckUpdate()
        {
            try
            {
                VersionUtil.UpdateAutoUpdater(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
            }
            catch (Exception ex)
            {
                Logger.Error("Updater AutoUpdater.exe Failed!", ex);
                Dispatcher.Invoke(() =>
                {
                    MessageBox.Show("更新程序异常", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                });
                // 更新程序没有更新,就不检查更新了吧
                return;
            }
            try
            {
                var update = VersionUtil.CheckSingleAppUpdate(AppId, Version);
                if (update != null)
                {
                    Dispatcher.Invoke(() =>
                    {
                        var res = MessageBox.Show("检查到软件更新,是否现在更新?", "提示", MessageBoxButton.YesNo, MessageBoxImage.Question);
                        if (res == MessageBoxResult.Yes)
                        {
                            string updaterPath = "AutoUpdater\\AutoUpdater.exe";
                            string exePath = new DirectoryInfo(Assembly.GetExecutingAssembly().Location).Parent.FullName;
                            string exeFileName = $"{exePath}\\{updaterPath}";
                            int mainProcessId = Process.GetCurrentProcess().Id;
                            Process updaterProcess = new Process
                            {
                                StartInfo = new ProcessStartInfo
                                {
                                    FileName = exeFileName,
                                    Arguments = $"{mainProcessId}"
                                }
                            };
                            updaterProcess.Start();
                        }
                    });
                }
            }
            catch (Exception ex)
            {
                Logger.Error($"Check Updater Failed.", ex);
                Dispatcher.Invoke(() =>
                {
                    MessageBox.Show("检查更新失败!", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                });
            }
        }
@@ -30,5 +119,19 @@
        {
        }
        public void InitDockApp()
        {
            dockApp = new DockApp();
            dockApp.Run();
        }
        public void SwithUser()
        {
            LoginUser.RemoveCacheBin();
            LoginWindow loginWindow = new LoginWindow();
            loginWindow.Show();
            if (dockApp != null) dockApp.Stop();
        }
    }
}
PdmAlert/DockApp.cs
@@ -6,22 +6,22 @@
{
    public class DockApp
    {
        private Window showWindow;
        private MainWindow showWindow;
        private NotifyIcon icon;
        public DockApp()
        {
            icon = new NotifyIcon();
            icon.BalloonTipText = "启动中...";
            icon.Text = "PDM消息通知程序";
            icon.Text = "消息通知程序";
            icon.Icon = new System.Drawing.Icon("./Icon/Icon.ico");
            icon.Visible = true;
            MenuItem mainItem = new MenuItem("显示主界面");
            mainItem.Click += ExitItem_Click;
            mainItem.Click += Icon_DoubleClick;
            MenuItem switchUserItem = new MenuItem("切换用户");
            switchUserItem.Click += ExitItem_Click;
            switchUserItem.Click += SwitchUser_Click;
            MenuItem exitItem = new MenuItem("关闭");
            exitItem.Click += ExitItem_Click;
@@ -43,13 +43,9 @@
            else
            {
                showWindow = new MainWindow();
                showWindow.Closed += MainWindow_Closed;
                showWindow.Show();
            }
        }
        private void Icon_DoubleClick(object sender, EventArgs e)
        {
            RefreshWindow();
        }
        public void Run()
@@ -57,9 +53,23 @@
            RefreshWindow();
        }
        private void MainWindow_Closed(object sender, EventArgs e)
        public void Stop()
        {
            if (showWindow != null) showWindow.DoDispose();
            showWindow.Close();
            showWindow = null;
            icon.Visible = false;
            icon.Dispose();
        }
        private void Icon_DoubleClick(object sender, EventArgs e)
        {
            RefreshWindow();
        }
        private void SwitchUser_Click(object sender, EventArgs e)
        {
            ((App)System.Windows.Application.Current).SwithUser();
        }
        private void ExitItem_Click(object sender, EventArgs e)
@@ -72,5 +82,10 @@
            icon.Dispose();
            System.Windows.Application.Current.Shutdown(0);
        }
        private void MainWindow_Closed(object sender, EventArgs e)
        {
            showWindow = null;
        }
    }
}
PdmAlert/Encryptor.cs
@@ -5,6 +5,9 @@
namespace PdmAlert
{
    /// <summary>
    /// 字符加解密
    /// </summary>
    public class Encryptor
    {
        private readonly byte[] key;
PdmAlert/Entity/MsgData.cs
@@ -2,7 +2,11 @@
{
    public class MsgData
    {
        public string title { get; set; }
        public string content { get; set; }
        public string id { get; set; }
        public string anntId { get; set; }
        public string titile { get; set; }
        public string msgContent { get; set; }
        public string sender { get; set; }
        public string sendTime { get; set; } = "sdadadads";
    }
}
PdmAlert/Icon.ico
PdmAlert/LoginUser.cs
@@ -11,8 +11,8 @@
    {
        public static LoginUser CurrentUser { get; private set; }
        private static readonly Encryptor encryptor = new Encryptor("12345678123456781234567812345678",
            "1234567812345678");
        private static readonly Encryptor encryptor = new Encryptor("aB3dE5fG7hI9jjK1lMnOpQrS2tUvWxYz",
            "8Wq9RsT4vYx6ZuB1");
        public string id { get; set; }
        public string realName { get; set; }
@@ -38,17 +38,16 @@
                    RemoveCacheBin();
                    return false;
                }
            }
            return false;
        }
        public static bool Login(string username, string password, bool rememberMe)
        {
            ToolSetting setting = ToolSetting.Instance;
            using (HttpClient client = new HttpClient
            {
                BaseAddress = new Uri("http://localhost:8888/pdm-web/"),
                BaseAddress = new Uri($"http://{setting.Ip}:{setting.Port}/{setting.BaseUrl}/"),
            })
            {
                try
@@ -59,7 +58,6 @@
                        password = password,
                        appId = "sockettool",
                        pluginVersion = "0.0.0.1"
                    }, "openApi/wpf/login");
                    CurrentUser = res.HandleResult();
                    CurrentUser.password = password;
@@ -74,12 +72,16 @@
                catch (Exception ex)
                {
                    RemoveCacheBin();
                    throw ex;
                }
            }
            return false;
        }
        /// <summary>
        /// 把明文密码加密后以二进制存入bin文件中
        /// TODO 使用机器码加密
        /// </summary>
        /// <param name="content"></param>
        public static void SaveStrToBin(string content)
        {
            string filePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().FullName), "bin");
PdmAlert/LoginWindow.xaml
@@ -4,15 +4,16 @@
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:PdmAlert"
        WindowStartupLocation="CenterScreen"
        mc:Ignorable="d"
        Title="LoginWindow" Height="450" Width="800">
        Title="{Binding windowTitle}" Height="250" Width="400">
    <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="Auto"/>
                    <RowDefinition Height="50"/>
                </Grid.RowDefinitions>
@@ -24,7 +25,7 @@
                <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>
                <CheckBox Margin="0,10,0,5" VerticalContentAlignment="Center" 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>
PdmAlert/LoginWindow.xaml.cs
@@ -1,4 +1,7 @@
using System.Windows;
using PdmAlert.Util;
using System;
using System.Threading.Tasks;
using System.Windows;
namespace PdmAlert
{
@@ -9,16 +12,47 @@
    {
        public LoginWindow()
        {
            _windowTitle = $"V{App.Version}";
            DataContext = this;
            InitializeComponent();
        }
        private string _windowTitle;
        public string windowTitle
        {
            get => _windowTitle;
        }
        public void Button_Click(object sender, RoutedEventArgs e)
        {
            if (LoginUser.Login(usernameTextBlock.Text, passwordTextBlock.Password, rememberMeInput.IsChecked == true))
            MaskAdorner.ShowMask(mainBorder);
            string username = usernameTextBlock.Text;
            string password = passwordTextBlock.Password;
            bool rememberMe = rememberMeInput.IsChecked == true;
            Task.Run(() =>
            {
            }
                try
                {
                    if (LoginUser.Login(username, password, rememberMe))
                    {
                        Dispatcher.Invoke(() =>
                        {
                            ((App)Application.Current).InitDockApp();
                            this.Close();
                        });
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "登录异常", MessageBoxButton.OK, MessageBoxImage.Error);
                }
                finally
                {
                    MaskAdorner.HideMask(mainBorder);
                }
            });
        }
    }
PdmAlert/MainWindow.xaml
@@ -39,7 +39,7 @@
                <Setter Property="FontWeight" Value="SemiBold"/>
                <Setter Property="Foreground" Value="Black"/>
                <Setter Property="Width" Value="50"/>
                <Setter Property="FontSize" Value="20"/>
                <Setter Property="FontSize" Value="30"/>
                <Setter Property="BorderThickness" Value="1"/>
                <Setter Property="BorderBrush" Value="Transparent"/>
@@ -97,44 +97,103 @@
            </Style>
            <Style x:Key="LinkButton" TargetType="Button">
                <Setter Property="FontFamily" Value="{StaticResource iconfont}"/>
                <Setter Property="Foreground" Value="{StaticResource ChildBorder}"/>
            <Style x:Key="LinkButton" TargetType="{x:Type Button}" >
                <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 TargetType="{x:Type ButtonBase}">
                            <ContentPresenter x:Name="buttonContent" TextBlock.FontSize="{TemplateBinding FontSize}"
                        TextBlock.FontFamily="{StaticResource iconfont}"
                        TextBlock.Foreground="{StaticResource ChildBorder}"
                        Margin="0,0,5,0"
                        VerticalAlignment="Center"
                        HorizontalAlignment="Center"
                        Content="{TemplateBinding Content}"/>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsMouseOver" Value="True">
                                    <Setter TargetName="buttonContent" Property="TextBlock.Foreground" Value="Purple"/>
                                    <Setter TargetName="buttonContent" Property="Cursor" Value="Hand"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ResourceDictionary>
    </Window.Resources>
    <Border BorderBrush="Black" BorderThickness="1">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Border Grid.Row="0" Background="LightGray">
                <DockPanel LastChildFill="True">
                    <Button DockPanel.Dock="Right" Style="{StaticResource WindowCloseButton}" Click="Hide_Click" ToolTip="最小化">&#xe67a;</Button>
                    <Button DockPanel.Dock="Right" Style="{StaticResource WindowButton}" Click="SwitchUser_Click" ToolTip="切换用户">&#xe6ed;</Button>
                    <Button DockPanel.Dock="Right" Style="{StaticResource WindowButton}" Click="Refresh_Click" BorderBrush="Black" ToolTip="刷新">&#xe600;</Button>
                    <Label Content="{Binding userInfo}" FontSize="20" VerticalContentAlignment="Center"/>
                </DockPanel>
            </Border>
            <AdornerDecorator Grid.Row="1">
                <Grid x:Name="mainContent" >
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <DockPanel Grid.Row="0" LastChildFill="True" HorizontalAlignment="Stretch" >
                        <Button DockPanel.Dock="Right" Margin="0,0,20,0" FontSize="16" Style="{StaticResource LinkButton}" Click="ReadAll_Click">全部已读</Button>
                        <Label DockPanel.Dock="Left" FontSize="16" Content="{Binding messageTitle}"/>
                    </DockPanel>
    <StackPanel>
        <Border BorderThickness="0" Background="LightGray">
            <StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
                <Button Style="{StaticResource WindowButton}" Click="Refresh_Click" BorderBrush="Black" ToolTip="刷新">&#xe600;</Button>
                <Button Style="{StaticResource WindowButton}" Click="SwitchUser_Click" ToolTip="切换用户">&#xe6ed;</Button>
                <Button Style="{StaticResource WindowCloseButton}" Click="Hide_Click" ToolTip="最小化">&#xe67a;</Button>
            </StackPanel>
        </Border>
                    <ListView BorderThickness="0,1,0,1" Grid.Row="1" ItemsSource="{Binding messages}">
                        <ListView.ItemContainerStyle>
                            <Style TargetType="{x:Type ListViewItem}">
                                <Setter Property="Focusable" Value="False"/>
                                <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                            </Style>
                        </ListView.ItemContainerStyle>
        <Label Content="{Binding messageTitle}"/>
        <ListView ItemsSource="{Binding messages}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Label Content="999"/>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackPanel>
                        <ListView.ItemTemplate>
                            <DataTemplate>
                                <DockPanel LastChildFill="True">
                                    <Button DockPanel.Dock="Right" FontSize="16" Margin="0,0,15,0"
                                        DataContext="{Binding}"
                                        Click="SingleRead_Click"
                                        Style="{StaticResource LinkButton}">已读</Button>
                                    <StackPanel DockPanel.Dock="Right">
                                        <StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
                                            <Label FontSize="18" FontWeight="Bold" Content="{Binding titile}"/>
                                            <Label FontSize="18" FontWeight="Bold" Content="{Binding sendTime}"/>
                                        </StackPanel>
                                        <Label FontSize="16" Content="{Binding msgContent}"/>
                                    </StackPanel>
                                </DockPanel>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>
                    <StatusBar Grid.Row="2" VerticalAlignment="Center">
                        <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                            <Ellipse Width="12" Height="12"  VerticalAlignment="Center">
                                <Ellipse.Style>
                                    <Style TargetType="Ellipse">
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding socketStatus}" Value="Error">
                                                <Setter Property="Shape.Fill" Value="Red"/>
                                            </DataTrigger>
                                            <DataTrigger Binding="{Binding socketStatus}" Value="Success">
                                                <Setter Property="Shape.Fill" Value="Green"/>
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </Ellipse.Style>
                            </Ellipse>
                            <Label FontSize="12" Content="{Binding statusMessage}"/>
                        </StackPanel>
                    </StatusBar>
                </Grid>
            </AdornerDecorator>
        </Grid>
    </Border>
</Window>
PdmAlert/MainWindow.xaml.cs
@@ -2,16 +2,19 @@
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;
using System.Threading;
using System.Net.Http;
using PdmAlert.Util;
using log4net;
using WebSocketSharp;
using System.Windows.Controls;
namespace PdmAlert
{
@@ -38,10 +41,17 @@
        }
        #endregion
        private ClientWebSocket socket;
        private static ILog Logger = LogManager.GetLogger("MsgAlert");
        // private ClientWebSocket socket;
        private WebSocket socket;
        private Task readTask;
        private Task writeTask;
        private System.Timers.Timer heartbeatTimer;
        private CancellationTokenSource cancelTokenSource;
        private CancellationToken cancelToken;
        private ToolSetting setting;
        private HttpClient client;
        private volatile bool IsRefreshing = false;
        private string _messageTitle = "共有 0 条未读消息";
@@ -50,6 +60,31 @@
            get => _messageTitle;
            set => RaiseAndSetIfChanged(ref _messageTitle, value);
        }
        private string _statusMessage = "启动中...";
        public string statusMessage
        {
            get => _statusMessage;
            set => RaiseAndSetIfChanged(ref _statusMessage, value);
        }
        private string _userInfo = "";
        public string userInfo
        {
            get => _userInfo;
            set => RaiseAndSetIfChanged(ref _userInfo, value);
        }
        private string _socketStatus = "";
        public string socketStatus
        {
            get => _socketStatus;
            set => RaiseAndSetIfChanged(ref _socketStatus, value);
        }
        private ObservableCollection<MsgData> _messages;
@@ -61,19 +96,104 @@
        public MainWindow()
        {
            cancelTokenSource = new CancellationTokenSource();
            cancelToken = cancelTokenSource.Token;
            setting = ToolSetting.Instance;
            client = new HttpClient
            {
                BaseAddress = new Uri($"http://{setting.Ip}:{setting.Port}/{setting.BaseUrl}/"),
                Timeout = TimeSpan.FromSeconds(setting.TimeOut),
            };
            client.DefaultRequestHeaders.Add("Client-Access-Token", LoginUser.CurrentUser.username);
            userInfo = $"用户:{LoginUser.CurrentUser.realName}";
            DataContext = this;
            InitializeComponent();
        }
        private void ShowStatus(string status, string message)
        {
            Dispatcher.Invoke(() =>
            {
                socketStatus = status;
                statusMessage = message;
            });
        }
        private void Refresh_Click(object sender, RoutedEventArgs e)
        {
            MaskAdorner.ShowMask(mainContent);
            Task.Run(() =>
            {
                try
                {
                    RefreshData();
                }
                catch (Exception ex)
                {
                    Logger.Error("Request Unread Message Failed.", ex);
                }
                finally
                {
                    MaskAdorner.HideMask(mainContent);
                }
            });
        }
        public void RefreshData()
        {
            try
            {
                IsRefreshing = true;
                Result<Page<MsgData>> res = client.GetSyncAction<Page<MsgData>>("pdm/annountCement/listSysMsgByUser", new Page<object>
                {
                    pageNo = 1,
                    pageSize = 100
                });
                Page<MsgData> pageList = res.HandleResult();
                Dispatcher.Invoke(() =>
                {
                    messageTitle = $"共有 {pageList.total} 条未读消息";
                    this.messages = new ObservableCollection<MsgData>(pageList.records);
                });
            }
            finally
            {
                IsRefreshing = false;
            }
        }
        private void FirstRefreshMsg()
        {
            try
            {
                Result<Page<MsgData>> res = client.GetSyncAction<Page<MsgData>>("pdm/annountCement/listSysMsgByUser", new Page<object>
                {
                    pageNo = 1,
                    pageSize = 100
                });
                Page<MsgData> pageList = res.HandleResult();
                messageTitle = $"共有 {pageList.total} 条未读消息";
                this.messages = new ObservableCollection<MsgData>(pageList.records);
                if (pageList.total > 0)
                {
                    Dispatcher.Invoke(() =>
                    {
                        eDesktopAlertColor color = eDesktopAlertColor.Default;
                        eAlertPosition position = eAlertPosition.BottomRight;
                        DesktopAlert.Show($"您有{pageList.total}条未读消息,请检查", "\uf005", eSymbolSet.Awesome, Color.Empty, color, position, 5,
                            DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), AlertClicked);
                    });
                }
            }
            catch (Exception ex)
            {
                Logger.Error("First Request Unread Message Failed.", ex);
            }
        }
        private void SwitchUser_Click(object sender, RoutedEventArgs e)
        {
            ((App)Application.Current).SwithUser();
        }
        private void AlertClicked(long alertId)
@@ -85,33 +205,97 @@
        {
            var screeWidth = SystemParameters.WorkArea.Width;
            var sHeight = SystemParameters.WorkArea.Height;
            this.Left = screeWidth - this.Width;
            this.Top = sHeight - this.Height;
            FirstRefreshMsg();
            ConnectWebSocket();
        }
        private async Task ConnectWebSocket()
        private void ConnectWebSocket()
        {
            try
            {
                ClientWebSocket ws = new ClientWebSocket();
                await ws.ConnectAsync(new Uri($"ws://localhost:8888/pdm-web/daws/{LoginUser.CurrentUser?.id}"), default);
                socket = new WebSocket($"ws://{setting.Ip}:{setting.Port}/{setting.BaseUrl}/daws/{LoginUser.CurrentUser?.id}");
                socket.OnOpen += Socket_OnOpen;
                socket.OnClose += Socket_OnClose;
                socket.OnMessage += Socket_OnMessage;
                socket.OnError += Socket_OnError;
                socket.Connect();
                StartHeartBeat();
                /*await ws.ConnectAsync(new Uri($"ws://{setting.Ip}:{setting.Port}/{setting.BaseUrl}/daws/{LoginUser.CurrentUser?.id}"), default);
                socket = ws;
                ReadMsg();
                StartHeartbeat();
                StartHeartbeat();*/
            }
            catch (Exception ex)
            {
                await ConnectWebSocket();
                Logger.Error("Connect Websocket Failed.", ex);
                ShowStatus("Error", "与服务连接连接失败,尝试重连...");
            }
        }
        private void ReadMsg()
        private void Socket_OnError(object sender, ErrorEventArgs e)
        {
            Logger.Error("Websocket On Error.", e.Exception);
            //ResetSocket();
            //ConnectWebSocket();
        }
        private void Socket_OnMessage(object sender, MessageEventArgs e)
        {
            HandleMsg(e.Data);
        }
        private void Socket_OnClose(object sender, CloseEventArgs e)
        {
            Logger.Info("Websocket On Close.");
            StopHeartBeat();
        }
        private void Socket_OnOpen(object sender, EventArgs e)
        {
            Logger.Info("Websocket On Open.");
            ShowStatus("Success", "与服务器连接状态正常");
            // StartHeartBeat();
        }
        public void StartHeartBeat()
        {
            if (heartbeatTimer == null)
            {
                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.IsAlive)
            {
                Logger.Error($"Websocket HeartBeat Error. Socket is NULL:{socket == null}; IsAlive:{socket.IsAlive}");
                ShowStatus("Error", "与服务器通讯中断,正在尝试重连...");
                ResetSocket();
                ConnectWebSocket();
            }
            else
            {
                socket.Send("HeartBeat");
            }
        }
        public void StopHeartBeat()
        {
        }
        /*private void ReadMsg()
        {
            readTask = Task.Run(() =>
            {
                while (socket.State == WebSocketState.Open)
                while (socket.State == WebSocketState.Open && !cancelToken.IsCancellationRequested)
                {
                    byte[] buffer = new byte[1024];
                    var task = socket.ReceiveAsync(new ArraySegment<byte>(buffer), default);
@@ -119,9 +303,10 @@
                    var res = task.Result;
                    var msg = Encoding.UTF8.GetString(buffer, 0, res.Count);
                    HandleMsg(msg);
                    Thread.Sleep(100);
                }
            });
        }
            }, cancelToken);
        }*/
        private void HandleMsg(string msg)
        {
@@ -129,35 +314,39 @@
            {
                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);
                Refresh_Click(null, null);
            });
        }
        private void StartHeartbeat()
        public void ResetSocket()
        {
            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)
            if (readTask != null)
            {
                DoDispose();
                ConnectWebSocket().Wait();
                cancelTokenSource.Cancel();
                readTask = null;
            }
            else
            if (socket != null)
            {
                byte[] buffer = Encoding.UTF8.GetBytes("test");
                socket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, default);
                using (var _socketServer = socket)
                {
                    try
                    {
                        _socketServer.Close();
                        socket = null;
                        /*socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "DoDispose", default).Wait();
                        socket.Dispose();*/
                    }
                    catch (Exception ex)
                    {
                        Logger.Error("Websocket Close Error.", ex);
                    }
                }
            }
        }
@@ -169,25 +358,13 @@
                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)
                {
            ResetSocket();
                }
                finally
            if (client != null)
            {
                using (var _client = client)
                {
                    socket = null;
                    client = null;
                }
            }
        }
@@ -201,5 +378,56 @@
        {
            this.Hide();
        }
        private void ReadAll_Click(object sender, RoutedEventArgs e)
        {
            MaskAdorner.ShowMask(mainContent);
            Task.Run(() =>
            {
                try
                {
                    Result<object> res = client.PutSyncAction<object>("pdm/sysAnnouncementSend/readAll");
                    _ = res.HandleResult();
                    RefreshData();
                }
                catch (Exception ex)
                {
                    Logger.Error("Read All Fail.", ex);
                }
                finally
                {
                    MaskAdorner.HideMask(mainContent);
                }
            });
        }
        private void SingleRead_Click(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;
            MsgData msg = button.DataContext as MsgData;
            if (msg == null) return;
            MaskAdorner.ShowMask(mainContent);
            Task.Run(() =>
            {
                try
                {
                    Result<object> res = client.PutSyncAction<object>("pdm/sysAnnouncementSend/editByAnntIdAndUserId", new MsgData
                    {
                        anntId = msg.id
                    });
                    _ = res.HandleResult();
                    RefreshData();
                }
                catch (Exception ex)
                {
                    Logger.Error("Read All Fail.", ex);
                }
                finally
                {
                    MaskAdorner.HideMask(mainContent);
                }
            });
        }
    }
}
PdmAlert/PdmAlert.csproj
@@ -57,9 +57,15 @@
  <PropertyGroup>
    <ApplicationManifest>app.manifest</ApplicationManifest>
  </PropertyGroup>
  <PropertyGroup>
    <ApplicationIcon>Icon.ico</ApplicationIcon>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="DevComponents.DotNetBar2">
      <HintPath>..\lib\DevComponents.DotNetBar2.dll</HintPath>
    </Reference>
    <Reference Include="log4net">
      <HintPath>lib\log4net.dll</HintPath>
    </Reference>
    <Reference Include="Newtonsoft.Json">
      <HintPath>lib\Newtonsoft.Json.dll</HintPath>
@@ -78,6 +84,9 @@
    <Reference Include="System.Xaml">
      <RequiredTargetFramework>4.0</RequiredTargetFramework>
    </Reference>
    <Reference Include="websocket-sharp">
      <HintPath>lib\websocket-sharp.dll</HintPath>
    </Reference>
    <Reference Include="WindowsBase" />
    <Reference Include="PresentationCore" />
    <Reference Include="PresentationFramework" />
@@ -87,6 +96,7 @@
      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
    </ApplicationDefinition>
    <Compile Include="ToolSetting.cs" />
    <Compile Include="Util.cs" />
    <Page Include="LoginWindow.xaml">
      <SubType>Designer</SubType>
@@ -132,6 +142,9 @@
    </EmbeddedResource>
    <None Include="app.manifest" />
    <Resource Include="Icon\iconfont.ttf" />
    <None Include="log4net.config">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Include="Properties\Settings.settings">
      <Generator>SettingsSingleFileGenerator</Generator>
      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
@@ -141,9 +154,43 @@
    <None Include="App.config" />
  </ItemGroup>
  <ItemGroup>
    <Resource Include="Icon.ico" />
    <Content Include="Icon\Icon.ico">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="ReleaseSettings\ToolSetting.xml">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="ReleaseSettings\UpdaterSetting.xml">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Settings\UpdaterSetting.xml">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Settings\ToolSetting.xml">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\..\CommonUpdater\VersionControl\VersionControl.csproj">
      <Project>{edc73c56-d0c5-4ac9-b296-3253915ef933}</Project>
      <Name>VersionControl</Name>
    </ProjectReference>
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <PropertyGroup>
    <PostBuildEvent>xcopy "C:\Main\Workspace\VisualStudio\CommonUpdater\AutoUpdater\bin\x64\$(ConfigurationName)\" "$(TargetDir)AutoUpdater\" /S /Y
IF "$(ConfigurationName)"=="Release" GOTO PRE
GOTO END
:PRE
rd /Q/S "$(TargetDir)Settings" &amp;&amp; ren "$(TargetDir)ReleaseSettings" "Settings"
GOTO END
:END
xcopy "$(TargetDir)Settings\UpdaterSetting.xml" "$(TargetDir)AutoUpdater\Settings\UpdaterSetting.xml" /Y
</PostBuildEvent>
  </PropertyGroup>
</Project>
PdmAlert/PdmAlert.iss
New file
@@ -0,0 +1,62 @@
; AppId
#define AppId = "PdmMsgAlert"
; AppName
#define AppName = "PdmMsgAlert"
; 打包的应用文件夹路径
#define AppDir = "C:\Main\Workspace\VisualStudio\PdmSwPlugin2\PdmAlert\bin\x64\Release\"
; 自动更新程序路径
#define AutoUpdaterDir = "C:\Main\Workspace\VisualStudio\PdmSwPlugin2\PdmAlert\bin\x64\Release\AutoUpdater\"
; 版本
#define Version = "0.0.0.1"
; 生成的Installer存放路径
#define OutPutDir = "C:\Main\Workspace\Output"
[Setup]
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{{#AppId}}
AppName={#AppName}
AppVersion={#Version}
;AppVerName=Test 1.0
; 安装路径 C:\Program Files (x86)\LHJ\PdmSwPlugin
DefaultDirName={autopf}\HengXin\PdmMsgAlert
DisableDirPage=yes
DefaultGroupName=PdmMsgAlert
DisableProgramGroupPage=yes
; Uncomment the following line to run in non administrative install mode (install for current user only.)
;PrivilegesRequired=lowest
OutputDir={#OutputDir}
OutputBaseFilename=PdmMsgAlertInstaller_V{#Version}
Compression=lzma
SolidCompression=yes
WizardStyle=modern
PrivilegesRequired=admin
UsedUserAreasWarning=no
[Languages]
Name: "chinesesimplified"; MessagesFile: "compiler:Languages\ChineseSimplified.isl"
[Files]
Source: "{#AppDir}*"; DestDir: "{app}"; Excludes: "temp\*,Log\*"; Flags:recursesubdirs ignoreversion
;Source: "{#AutoUpdaterDir}*"; DestDir: "{app}\AutoUpdater"; Excludes: "download\*"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
[Dirs]
Name: {app}; Permissions: users-full
[Icons]
Name: "{group}\{cm:UninstallProgram,Test}"; Filename: "{uninstallexe}"
Name: "{userdesktop}\{#AppName}";Filename: "{app}\PdmAlert.exe"; WorkingDir: "{app}"
[code]
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  if CurUninstallStep = usDone then
  begin
    DelTree(ExpandConstant('{app}'), True, True, True);
  end;
end;
PdmAlert/Properties/AssemblyInfo.cs
@@ -1,4 +1,5 @@
using System.Reflection;
using log4net.Config;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -53,3 +54,4 @@
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
PdmAlert/ReleaseSettings/ToolSetting.xml
Binary files differ
PdmAlert/ReleaseSettings/UpdaterSetting.xml
Binary files differ
PdmAlert/Settings/ToolSetting.xml
Binary files differ
PdmAlert/Settings/UpdaterSetting.xml
Binary files differ
PdmAlert/ToolSetting.cs
New file
@@ -0,0 +1,88 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Xml;
using System.IO;
namespace PdmAlert
{
    public class ToolSetting
    {
        public static ToolSetting Instance { get; private set; }
        private Dictionary<string, string> DataMap;
        public int TimeOut { get; private set; } = 600;
        public string Mode { get; private set; } = "prod";
        public string Ip { get; private set; } = "";
        public int Port { get; private set; } = 0;
        public string BaseUrl { get; private set; } = "";
        private void Init()
        {
        }
        static ToolSetting()
        {
            Instance = LoadFromXml(null);
        }
        private static ToolSetting LoadFromXml(string xmlPath)
        {
            if (xmlPath == null)
            {
                string dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                xmlPath = Path.Combine(dir, "Settings", "ToolSetting.xml");
            }
            ToolSetting setting = new ToolSetting();
            if (File.Exists(xmlPath))
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(xmlPath);
                XmlNode xmlRoot = xmlDoc.DocumentElement;
                BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
                var props = typeof(ToolSetting).GetProperties(flags).ToArray();
                foreach (var prop in props)
                {
                    string name = prop.Name;
                    string value = xmlRoot.SelectSingleNode(name)?.InnerText;
                    if (value == null)
                    {
                        continue;
                    }
                    Type type = prop.PropertyType;
                    if (type == typeof(int))
                    {
                        int.TryParse(value, out int temp);
                        prop.SetValue(setting, temp);
                    }
                    else if (type == typeof(bool))
                    {
                        bool.TryParse(value, out bool temp);
                        prop.SetValue(setting, temp);
                    }
                    else if (type == typeof(string))
                    {
                        prop.SetValue(setting, value);
                    }
                }
            }
            setting.Init();
            return setting;
        }
        /// <summary>
        /// 强制刷新配置
        /// </summary>
        /// <param name="xmlPath"></param>
        /// <returns></returns>
        public static ToolSetting RefreshFromXml(string xmlPath)
        {
            Instance = LoadFromXml(xmlPath);
            return Instance;
        }
    }
}
PdmAlert/Util.cs
@@ -7,10 +7,158 @@
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows;
using Newtonsoft.Json;
namespace PdmAlert.Util
{
    public class MaskAdorner : Adorner
    {
        private UIElement child;
        private TextBox textBox;
        public static readonly Dictionary<Visual, MaskAdorner> cache = new Dictionary<Visual, MaskAdorner>();
        public MaskAdorner(UIElement adornedElement, string message = null) : base(adornedElement)
        {
            textBox = new TextBox
            {
                TextAlignment = TextAlignment.Center,
                Background = new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)),
                Text = message,
                BorderThickness = new Thickness(0),
                BorderBrush = new SolidColorBrush(Color.FromArgb(0, 0, 0, 0))
            };
            StackPanel stackPanel = new StackPanel()
            {
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                Background = new SolidColorBrush(Color.FromArgb(0, 255, 255, 255)),
            };
            stackPanel.Children.Add(new ProgressBar
            {
                Width = 100,
                Height = 20,
                IsIndeterminate = true
            });
            stackPanel.Children.Add(textBox);
            Child = new Border
            {
                Background = new SolidColorBrush(Color.FromArgb(100, 0, 0, 0)),
                HorizontalAlignment = HorizontalAlignment.Stretch,
                VerticalAlignment = VerticalAlignment.Stretch,
                Child = stackPanel
            };
        }
        //Adorner 直接继承自 FrameworkElement,
        //没有Content和Child属性,
        //自己添加一个,方便向其中添加我们的控件
        public UIElement Child
        {
            get => child;
            set
            {
                if (value == null)
                {
                    RemoveVisualChild(child);
                }
                else
                {
                    AddVisualChild(value);
                }
                child = value;
            }
        }
        //重写VisualChildrenCount 表示此控件只有一个子控件
        protected override int VisualChildrenCount => 1;
        //控件计算大小的时候,我们在装饰层上添加的控件也计算一下大小
        protected override Size ArrangeOverride(Size finalSize)
        {
            child?.Arrange(new Rect(finalSize));
            return finalSize;
        }
        //重写GetVisualChild,返回我们添加的控件
        protected override Visual GetVisualChild(int index)
        {
            if (index == 0 && child != null) return child;
            return base.GetVisualChild(index);
        }
        public void ShowMessage(string message)
        {
            this.textBox.Text = message;
        }
        public static void ShowMask(Visual visual, string message = null)
        {
            var sb = cache;
            if (cache.ContainsKey(visual))
            {
                return;
            }
            visual.Dispatcher.Invoke(() =>
            {
                AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(visual);
                if (adornerLayer == null) return;
                Adorner[] ads = adornerLayer.GetAdorners(adornerLayer);
                if (ads != null)
                {
                    foreach (Adorner ad in ads)
                    {
                        if (ad is MaskAdorner adorner)
                        {
                            return;
                        }
                    }
                }
                //创建我们定义的Adorner
                MaskAdorner _adorner = new MaskAdorner(adornerLayer, message);
                //添加到adornerLayer装饰层上
                adornerLayer.Add(_adorner);
                cache.Add(visual, _adorner);
            });
        }
        public static void ShowMessage(Visual visual, string message)
        {
            if (!cache.ContainsKey(visual))
            {
                return;
            }
            visual.Dispatcher.Invoke(() =>
            {
                AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(visual);
                MaskAdorner mask = cache[visual];
                if (mask == null)
                {
                    return;
                }
                mask.ShowMessage(message);
            });
        }
        public static void HideMask(Visual visual)
        {
            if (!cache.ContainsKey(visual))
            {
                return;
            }
            visual.Dispatcher.Invoke(() =>
            {
                if (cache.ContainsKey(visual))
                {
                    AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(visual);
                    adornerLayer.Remove(cache[visual]);
                    cache.Remove(visual);
                }
            });
        }
    }
    [Serializable]
    public class Result<T>
    {
@@ -37,6 +185,16 @@
        {
            get; set;
        }
    }
    public class Page<T>
    {
        public int pageNo { get; set; }
        public int pageSize { get; set; }
        public int total { get; set; }
        public int current { get; set; }
        public int size { get; set; }
        public List<T> records { get; set; }
    }
    public static class ResultHandler
@@ -236,6 +394,27 @@
            return task2.Result;
        }
        public static Result<T> PutSyncAction<T>(this HttpClient client, string url, object data = null)
        {
            StringContent content;
            if (data != null)
            {
                string dataStr = JsonUtil.Serialize(data);
                content = new StringContent(dataStr, Encoding.UTF8, "application/json");
            }
            else
            {
                content = new StringContent("");
            }
            Task<HttpResponseMessage> task = client.PutAsync(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);
        }
        public static async Task<T> PostAsyncAction<T>(this HttpClient client, string url, string data)
        {
            StringContent content = new StringContent(data, Encoding.UTF8, "application/json");
PdmAlert/lib/Fleck.dll
Binary files differ
PdmAlert/lib/log4net.dll
Binary files differ
PdmAlert/lib/websocket-sharp.dll
Binary files differ
PdmAlert/log4net.config
New file
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<log4net>
    <!-- 控制台日志配置 -->
    <appender name="Console" type="log4net.Appender.ConsoleAppender">
        <!-- 日志输出格式 -->
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%5level [%thread] (%file:%line) - %message%newline" />
        </layout>
    </appender>
    <!-- 文件存储日志配置 -->
    <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
        <!-- 保存文件的名称 -->
        <file value="./Log/" />
        <appendToFile value="true" />
        <rollingStyle value="Date" />
        <datePattern value="'log_'yyyyMMdd'.log'"/>
        <staticLogFileName value="false"/>
        <!-- 文件的编码方式 -->
        <param name="Encoding" value="UTF-8"/>
        <!-- 保存文件数量 -->
        <maxSizeRollBackups value="7" />
        <!-- 日志输出格式 -->
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date{ISO8601} [%logger]  %level  %class - %message%newline" />
        </layout>
    </appender>
    <root>
        <level value="INFO" />
        <appender-ref ref="Console" />
        <appender-ref ref="RollingFile" />
    </root>
</log4net>
PdmSw/.vs/PdmSw/FileContentIndex/1e97e5f0-ad3c-4fa0-845d-d0d4b508b3aa.vsidx
Binary files differ
PdmSw/.vs/PdmSw/FileContentIndex/4671096b-140b-4229-a025-97df57021262.vsidx
Binary files differ
PdmSw/.vs/PdmSw/FileContentIndex/6b982709-fe14-4b34-a175-b50bca946af4.vsidx
Binary files differ
PdmSw/.vs/PdmSw/FileContentIndex/92f976c2-0875-4c1f-bb43-2d01b4d875dc.vsidx
Binary files differ
PdmSw/.vs/PdmSw/FileContentIndex/a5ce55b6-65c6-4de9-8b17-865577fcdb4d.vsidx
Binary files differ