hulei 2 週之前
父節點
當前提交
deef875356
共有 100 個文件被更改,包括 21282 次插入0 次删除
  1. 17
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/ExternalSystem/CS/MouseEventFlag.ts
  2. 20
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/ExternalSystem/CS/NativeRECT.cs
  3. 143
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/ExternalSystem/CS/Win32API.cs
  4. 156
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/ExternalSystem/CS/Win32App.cs
  5. 38
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/ExternalSystem/CS/Win32AppHost.cs
  6. 213
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/ExternalSystem/ScriptHelper.ts
  7. 13
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/ExternalSystem/TS/NativeRECT.ts
  8. 1
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/Function/ErrorCodeMap.ts
  9. 676
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/Function/ExcelFunction/ExcelFuntion.ts
  10. 331
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/Function/ExcelFunction/SelectFrm.xaml
  11. 106
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/Function/ExcelFunction/SelectFrm.xaml.cs
  12. 395
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/Function/SystemFunction.ts
  13. 1066
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/Function/TradePageExtension.ts
  14. 1117
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/Function/UserFunction.ts
  15. 36
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/NPOI/Abstract/NPOIExcel.cs
  16. 25
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/NPOI/Abstract/NPOIFactory.cs
  17. 14
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/NPOI/Abstract/NPOIWord.cs
  18. 33
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/NPOI/Factory/NPOIFactory_03.cs
  19. 33
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/NPOI/Factory/NPOIFactory_07.cs
  20. 21
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/NPOI/NPOIHelper.cs
  21. 194
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/NPOI/Product/Excel/excel_03.cs
  22. 192
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/NPOI/Product/Excel/excel_07.cs
  23. 14
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/NPOI/Product/Word/word_03.cs
  24. 14
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/NPOI/Product/Word/word_07.cs
  25. 324
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/RuleInfoPSet.cs
  26. 249
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/RuleInfoPSet.ts
  27. 601
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/AICapacity.cs
  28. 414
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/AICapacity.ts
  29. 1009
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/AnalyzeFile.cs
  30. 178
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/AnalyzeFile.ts
  31. 529
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ChineseCodeConverter.cs
  32. 373
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ChineseCodeConverter.ts
  33. 25
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/CodeView.cs
  34. 39
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/CodeView.ts
  35. 49
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ComboBoxDataGridExtension.cs
  36. 63
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ComboBoxDataGridExtension.ts
  37. 52
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Commands.cs
  38. 31
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Commands.ts
  39. 122
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Currency2DicManager.cs
  40. 118
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Currency2DicManager.ts
  41. 2150
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/DataBoxExtension.cs
  42. 275
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/DataBoxExtension.ts
  43. 839
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ExcelToTxt.cs
  44. 460
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ExcelToTxt.ts
  45. 469
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/FtpHandle_TS.cs
  46. 198
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/FtpHandle_TS.ts
  47. 43
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/IPageExtension.cs
  48. 50
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/IPageExtension.ts
  49. 55
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/IdInfo.cs
  50. 60
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/IdInfo.ts
  51. 306
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ImageCutHelper.cs
  52. 198
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ImageCutHelper.ts
  53. 147
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/LoggerFTP.cs
  54. 140
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/LoggerFTP.ts
  55. 14
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/INotification.cs
  56. 65
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/MessageData.cs
  57. 31
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/IExecuteWithObject.cs
  58. 20
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/IExecuteWithObject.ts
  59. 17
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/IExecuteWithObjectAndResult.cs
  60. 9
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/IExecuteWithObjectAndResult.ts
  61. 214
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/IMessenger.cs
  62. 197
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/IMessenger.ts
  63. 69
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/Message/MessageBase.cs
  64. 45
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/Message/MessageBase.ts
  65. 29
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/Message/NotificationMessage.cs
  66. 45
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/Message/NotificationMessage.ts
  67. 67
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/Message/TaskMessage.cs
  68. 81
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/Message/TaskMessage.ts
  69. 538
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/Messenger.cs
  70. 275
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/Messenger.ts
  71. 192
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/WeakAction.cs
  72. 173
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/WeakActionGeneric.cs
  73. 226
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/WeakFunc.cs
  74. 175
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/WeakFuncGeneric.cs
  75. 31
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/NotificationAttribute.cs
  76. 246
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/NotificationManager.cs
  77. 38
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/NotificationMessageBox.xaml
  78. 149
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/NotificationMessageBox.xaml.cs
  79. 92
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/TaskMessageBox.xaml
  80. 173
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/TaskMessageBox.xaml.cs
  81. 119
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/WeakAction.ts
  82. 103
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/OutOfDataObject.cs
  83. 79
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/OutOfDataObject.ts
  84. 134
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/PageController.cs
  85. 93
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/PageController.ts
  86. 145
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/PerCombBoxData.cs
  87. 131
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/PerCombBoxData.ts
  88. 199
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Pinyin.cs
  89. 105
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Pinyin.ts
  90. 68
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ProvinceCityCountyManager.cs
  91. 95
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ProvinceCityCountyManager.ts
  92. 410
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/PyCode.cs
  93. 391
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/PyCode.ts
  94. 411
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/PyHash.cs
  95. 133
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/RegexRuleExtension.cs
  96. 124
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/RegexRuleExtension.ts
  97. 59
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ReportWindow.xaml
  98. 95
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ReportWindow.xaml.cs
  99. 743
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/SSO/LoginAuthentication.cs
  100. 0
    0
      ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/SSO/LoginAuthentication.ts

+ 17
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/ExternalSystem/CS/MouseEventFlag.ts 查看文件

@@ -0,0 +1,17 @@
1
+// 定义鼠标事件标志的枚举
2
+enum MouseEventFlag {
3
+    Move = 0x0001,
4
+    LeftDown = 0x0002,
5
+    LeftUp = 0x0004,
6
+    RightDown = 0x0008,
7
+    RightUp = 0x0010,
8
+    MiddleDown = 0x0020,
9
+    MiddleUp = 0x0040,
10
+    XDown = 0x0080,
11
+    XUp = 0x0100,
12
+    Wheel = 0x0800,
13
+    VirtualDesk = 0x4000,
14
+    Absolute = 0x8000
15
+}
16
+
17
+export { MouseEventFlag };

+ 20
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/ExternalSystem/CS/NativeRECT.cs 查看文件

@@ -0,0 +1,20 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Runtime.InteropServices;
6
+
7
+namespace TellerSystem.Library.Ext.ExternalSystem
8
+{
9
+    /// <summary>
10
+    /// 鼠标事件api辅助结构
11
+    /// </summary>
12
+    [StructLayout(LayoutKind.Sequential)]
13
+    public struct NativeRECT
14
+    {
15
+        public int left;
16
+        public int top;
17
+        public int right;
18
+        public int bottom;
19
+    }
20
+}

+ 143
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/ExternalSystem/CS/Win32API.cs 查看文件

@@ -0,0 +1,143 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Runtime.InteropServices;
6
+
7
+namespace TellerSystem.Library.Ext.ExternalSystem
8
+{
9
+    /// <summary>
10
+    /// 调用windows相关api方法与常量
11
+    /// </summary>
12
+    public class Win32API
13
+    {
14
+        #region 相关常量
15
+        public const int WS_VSCROLL = 0x00200000;
16
+        public const int SWP_NOOWNERZORDER = 0x200;
17
+        public const int SWP_NOREDRAW = 0x8;
18
+        public const int SWP_NOZORDER = 0x4;
19
+        public const int SWP_SHOWWINDOW = 0x0040;
20
+        public const int WS_EX_MDICHILD = 0x40;
21
+        public const int SWP_FRAMECHANGED = 0x20;
22
+        public const int SWP_NOACTIVATE = 0x10;
23
+        public const int SWP_ASYNCWINDOWPOS = 0x4000;
24
+        public const int SWP_NOMOVE = 0x2;
25
+        public const int SWP_NOSIZE = 0x1;
26
+        public const int GWL_STYLE = (-16);
27
+        public const int WS_VISIBLE = 0x10000000;
28
+        public const int WM_CLOSE = 0x10;
29
+        public const int WS_CHILD = 0x40000000;
30
+        public const int WM_CHAR = 0X102;
31
+        public const int WM_KEYDOWN = 0X100;
32
+        public const int WM_KEYUP = 0X101;
33
+        public const int WM_SYSKEYUP = 0X105;
34
+        public const int WM_SYSKEYDOWN = 0X104;
35
+        /// <summary>
36
+        /// //显示最小化
37
+        /// </summary>
38
+        public const int SW_SHOWMINIMIZED = 2;
39
+        /// <summary>
40
+        /// 窗口命令
41
+        /// </summary>
42
+        public const int WM_SYSCOMMAND = 0x0112;
43
+        /// <summary>
44
+        /// 最大化窗口
45
+        /// </summary>
46
+        public const int SC_MAXIMIZE = 0xF030;
47
+        /// <summary>
48
+        /// 键盘插入键
49
+        /// </summary>
50
+        public const int INSERT = 0x2D;
51
+        public const int WM_SETFOCUS = 0x0007;
52
+        public const int WM_ACTIVATE = 0x0006;
53
+        #endregion
54
+
55
+        #region 外部方法
56
+        /// <summary>
57
+        /// 给窗口发消息
58
+        /// </summary>
59
+        /// <param name="hWnd"></param>
60
+        /// <param name="Msg"></param>
61
+        /// <param name="wParam"></param>
62
+        /// <param name="lParam"></param>
63
+        /// <returns></returns>
64
+        [DllImport("user32.dll")]
65
+        public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
66
+
67
+        /// <summary>
68
+        /// 给窗口发送
69
+        /// </summary>
70
+        /// <param name="hWnd">接收窗口句柄</param>
71
+        /// <param name="Msg">发送的消息</param>
72
+        /// <param name="wParam"></param>
73
+        /// <param name="lParam"></param>
74
+        /// <returns></returns>
75
+        [DllImport("User32.dll", EntryPoint = "SendMessage")]
76
+        public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);
77
+
78
+        /// <summary>
79
+        /// 设置窗口样式
80
+        /// </summary>
81
+        /// <param name="hwnd">窗口句柄</param>
82
+        /// <param name="nIndex">属性索引</param>
83
+        /// <param name="dwNewLong">属性值</param>
84
+        /// <returns></returns>
85
+        [DllImport("user32.dll", SetLastError = true)]
86
+        public static extern long SetWindowLong(IntPtr hwnd, int nIndex, int dwNewLong);
87
+
88
+        /// <summary>
89
+        /// 设置窗口的父窗口
90
+        /// </summary>
91
+        /// <param name="hWndChild">预设置窗口句柄</param>
92
+        /// <param name="hWndNewParent">父窗口句柄</param>
93
+        /// <returns></returns>
94
+        [DllImport("user32.dll", SetLastError = true)]
95
+        public static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
96
+
97
+        /// <summary>
98
+        /// 设置输入焦点
99
+        /// </summary>
100
+        /// <param name="winHandl">获取焦点的窗口或者控件句柄</param>
101
+        /// <returns></returns>
102
+        [DllImport("user32.dll", SetLastError = true)]
103
+        public static extern IntPtr SetFocus(IntPtr winHandl);
104
+
105
+        /// <summary>
106
+        /// 激活窗口
107
+        /// </summary>
108
+        /// <param name="hWnd">需要激活的窗口句柄</param>
109
+        /// <returns></returns>
110
+        [DllImport("user32.dll", SetLastError = true)]
111
+        public static extern IntPtr SetActiveWindow(IntPtr hWnd);
112
+
113
+        /// <summary>
114
+        /// 获取hwnd代表的窗口的屏幕显示区域
115
+        /// </summary>
116
+        /// <param name="hwnd">窗口句柄引用</param>
117
+        /// <param name="rect">屏幕显示的窗口矩形区域</param>
118
+        /// <returns></returns>
119
+        [DllImport("user32.dll")]
120
+        public static extern bool GetWindowRect(HandleRef hwnd, out NativeRECT rect);
121
+
122
+        /// <summary>
123
+        /// 设置鼠标在屏幕上的位置
124
+        /// </summary>
125
+        /// <param name="X">以左上角为0点的横向坐标</param>
126
+        /// <param name="Y">以左上角为0点的纵向坐标</param>
127
+        /// <returns></returns>
128
+        [DllImport("user32.dll")]
129
+        public static extern bool SetCursorPos(int X, int Y);
130
+
131
+        /// <summary>
132
+        /// 执行鼠标事件
133
+        /// </summary>
134
+        /// <param name="flags">鼠标的按键标识</param>
135
+        /// <param name="dx">触发事件时鼠标的横向偏移量</param>
136
+        /// <param name="dy">>触发事件时鼠标的纵向偏移量</param>
137
+        /// <param name="data"></param>
138
+        /// <param name="extraInfo"></param>
139
+        [DllImport("user32.dll")]
140
+        public static extern void mouse_event(MouseEventFlag flags, int dx, int dy, uint data, UIntPtr extraInfo);
141
+        #endregion
142
+    }
143
+}

+ 156
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/ExternalSystem/CS/Win32App.cs 查看文件

@@ -0,0 +1,156 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Diagnostics;
6
+using TellerSystem.ServiceProxy.Ext.TradeBusinessEntitys;
7
+
8
+namespace TellerSystem.Library.Ext.ExternalSystem
9
+{
10
+    /// <summary>
11
+    /// 外接系统应用程序管理类
12
+    /// 目前该类只针对netterm的打开
13
+    /// 如有其它系统,需要根据系统特点做相应调整
14
+    /// </summary>
15
+    public class Win32App
16
+    {
17
+        private Process process;
18
+        private IntPtr appMainFormHandle;
19
+
20
+        /// <summary>
21
+        /// 外接应用程序主窗口句柄
22
+        /// </summary>
23
+        public IntPtr AppMainFormHandle
24
+        {
25
+            get { return appMainFormHandle; }
26
+            private set { appMainFormHandle = value; }
27
+        }
28
+
29
+        /// <summary>
30
+        /// 外接系统基本信息对象
31
+        /// </summary>
32
+        public TT_Extsys_ExtuserFromByGroup ExtSystemInfo
33
+        {
34
+            get;
35
+            set;
36
+        }
37
+
38
+        public Win32App(TT_Extsys_ExtuserFromByGroup extSysInfo)
39
+        {
40
+            this.ExtSystemInfo = extSysInfo;
41
+        }
42
+
43
+        /// <summary>
44
+        /// 打开外接应用程序
45
+        /// </summary>
46
+        /// <returns>外接应用程序主窗口</returns>
47
+        public IntPtr StartApp()
48
+        {
49
+            ProcessStartInfo psi = new ProcessStartInfo(this.ExtSystemInfo.ExtAddress);
50
+            psi.RedirectStandardOutput = true;
51
+            psi.WindowStyle = ProcessWindowStyle.Maximized;
52
+            psi.UseShellExecute = false;
53
+            process = System.Diagnostics.Process.Start(psi);
54
+            // Wait for process to be created and enter idle condition
55
+            process.WaitForInputIdle();
56
+            // 最小化
57
+            Win32API.SendMessage(process.MainWindowHandle,Win32API.WM_SYSCOMMAND, (IntPtr)Win32API.SC_MAXIMIZE, "");
58
+           // this.process.Add(this.entity, process);
59
+
60
+            // 获取主窗口句柄
61
+            return this.appMainFormHandle = process.MainWindowHandle;
62
+        }
63
+
64
+        /// <summary>
65
+        /// 将外接应用程序宿主到指定的窗口中
66
+        /// </summary>
67
+        /// <param name="parentHandle">父窗口句柄</param>
68
+        public void HostInTo(IntPtr parentHandle)
69
+        {
70
+            // 去掉窗口边框
71
+            Win32API.SetWindowLong(this.appMainFormHandle, Win32API.GWL_STYLE, Win32API.WS_CHILD | Win32API.WS_VISIBLE | Win32API.WS_VSCROLL);
72
+            Win32API.SetParent(this.appMainFormHandle, parentHandle);
73
+        }
74
+
75
+        public void DestroyWindow()
76
+        {
77
+            process.Kill();
78
+            //Win32API.DestroyWindow(this.appMainFormHandle);
79
+        }
80
+
81
+        /// <summary>
82
+        /// 设置焦点
83
+        /// </summary>
84
+        public void SetFocus()
85
+        {
86
+            //Win32API.SendMessage(this.appMainFormHandle, Win32API.WM_ACTIVATE, 0, 0);
87
+            //Win32API.SendMessage(this.appMainFormHandle, Win32API.WM_SETFOCUS, 0, 0);
88
+
89
+            Win32API.SetActiveWindow(this.appMainFormHandle);
90
+            Win32API.SetFocus(this.appMainFormHandle);
91
+            Win32API.SetCursorPos(300, 300);
92
+        }
93
+
94
+        /// <summary>
95
+        /// 发送一条消息
96
+        /// </summary>
97
+        /// <param name="msg">消息内容</param>
98
+        public void SendLine(string msg)
99
+        {
100
+            if (this.appMainFormHandle.ToInt32() != 0)
101
+            {
102
+                this.SendLine(msg,this.appMainFormHandle);
103
+            }
104
+        }
105
+
106
+        /// <summary>
107
+        /// 往指定窗口发送一条消息
108
+        /// </summary>
109
+        /// <param name="msg">消息内容</param>
110
+        /// <param name="handle">接收消息窗口</param>
111
+        private void SendLine(string msg,IntPtr handle)
112
+        {
113
+            byte[] ch = (ASCIIEncoding.ASCII.GetBytes(msg));
114
+            for (int i = 0; i < ch.Length; i++)
115
+            {
116
+                Win32API.SendMessage(this.appMainFormHandle, Win32API.WM_CHAR, ch[i], 0);
117
+            }
118
+        }
119
+
120
+        public void LoadOPSystem()
121
+        {
122
+            this.SendLine("winqt");
123
+            this.SendEnter();
124
+            this.SendLine("winqt");
125
+        }
126
+
127
+        public void OpenSoftWare()
128
+        {
129
+            this.SendLine("cibas");
130
+            this.SendEnter();
131
+        }
132
+
133
+        public void LoginSoftWare()
134
+        {
135
+            this.SendLine(this.ExtSystemInfo.ExtUserId);
136
+            this.SendEnter();
137
+            this.SendLine(this.ExtSystemInfo.ExtPsw);
138
+        }
139
+
140
+        public void OpenTrade()
141
+        {
142
+            Win32API.SendMessage(this.appMainFormHandle, Win32API.WM_KEYDOWN, Win32API.INSERT, 0); //输入ENTER(0x0d)
143
+            Win32API.SendMessage(this.appMainFormHandle, Win32API.WM_KEYUP, Win32API.INSERT, 0);
144
+            this.SendLine("3000");
145
+        }
146
+
147
+        /// <summary>
148
+        /// 给当前窗口发送回车键
149
+        /// </summary>
150
+        public void SendEnter()
151
+        {
152
+            Win32API.SendMessage(this.appMainFormHandle, Win32API.WM_KEYDOWN, 0X0D, 0); //输入ENTER(0x0d)
153
+            Win32API.SendMessage(this.appMainFormHandle, Win32API.WM_KEYUP, 0X0D, 0);
154
+        }
155
+    }
156
+}

+ 38
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/ExternalSystem/CS/Win32AppHost.cs 查看文件

@@ -0,0 +1,38 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Windows.Interop;
6
+using System.Runtime.InteropServices;
7
+
8
+namespace TellerSystem.Library.Ext.ExternalSystem
9
+{
10
+    /// <summary>
11
+    /// win32应用程序宿主窗口,
12
+    /// </summary>
13
+    public class Win32AppHost : HwndHost
14
+    {
15
+        /// <summary>
16
+        /// 寄宿的win32应用程序
17
+        /// </summary>
18
+        private Win32App win32App { get; set; }
19
+
20
+        protected override System.Runtime.InteropServices.HandleRef BuildWindowCore(System.Runtime.InteropServices.HandleRef hwndParent)
21
+        {
22
+            win32App.HostInTo(hwndParent.Handle);
23
+            return new HandleRef(this, win32App.AppMainFormHandle);
24
+        }
25
+
26
+        protected override void DestroyWindowCore(System.Runtime.InteropServices.HandleRef hwnd)
27
+        {
28
+            this.win32App.DestroyWindow();
29
+        }
30
+
31
+        protected override void OnLostKeyboardFocus(System.Windows.Input.KeyboardFocusChangedEventArgs e)
32
+        {
33
+            win32App.SetFocus();
34
+            e.Handled = true;
35
+            base.OnLostKeyboardFocus(e);
36
+        }
37
+    }
38
+}

+ 213
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/ExternalSystem/ScriptHelper.ts 查看文件

@@ -0,0 +1,213 @@
1
+// 假设这些类型在其他文件中定义,这里先简单声明
2
+interface Win32App {
3
+    ExtSystemInfo: {
4
+        ExtName: string;
5
+        ExtPsw: string;
6
+    };
7
+}
8
+
9
+interface HtmlDocument {
10
+    GetElementById(id: string): HtmlElement | null;
11
+    All: {
12
+        [name: string]: HtmlElement | null;
13
+    };
14
+    Body: {
15
+        All: HtmlElement[];
16
+    };
17
+    InvokeScript(name: string, parameters?: object[]): void;
18
+}
19
+
20
+interface HtmlElement {
21
+    SetAttribute(name: string, value: string): void;
22
+    InvokeMember(name: string, parameter?: string): void;
23
+    TagName: string;
24
+    Name: string;
25
+    GetAttribute(name: string): string;
26
+    Children: {
27
+        Count: number;
28
+    };
29
+}
30
+
31
+interface XDocument {
32
+    Element(name: string): XElement | null;
33
+}
34
+
35
+interface XElement {
36
+    Attributes(): XAttribute[];
37
+    Element(name: string): XElement | null;
38
+    Elements(name?: string): XElement[];
39
+    Name: {
40
+        LocalName: string;
41
+    };
42
+}
43
+
44
+interface XAttribute {
45
+    Name: {
46
+        LocalName: string;
47
+    };
48
+    Value: string;
49
+}
50
+
51
+class ScriptHelper {
52
+    /**
53
+     * 分析脚本,取出外接系统相关参数
54
+     * @param script 脚本内容
55
+     * @param app Win32应用对象
56
+     */
57
+    public static Analysis(script: string, app: Win32App): void {
58
+        const xDoc = new DOMParser().parseFromString(script, 'text/xml');
59
+        // to do 取出外接系统相关参数
60
+        // 比如机器名称,密码,服务器地址等相关信息
61
+    }
62
+
63
+    /**
64
+     * 执行脚本
65
+     * @param htmlDoc HTML文档对象
66
+     * @param script 脚本内容
67
+     * @param app Win32应用对象
68
+     */
69
+    public static ExcutScript(htmlDoc: HtmlDocument, script: string, app: Win32App): void {
70
+        const xDoc = XDocument.Parse(script.toLowerCase());
71
+        const root = xDoc.Element('externalsystemautologin');
72
+
73
+        // 赋值
74
+        if (root) {
75
+            const loginParameter = root.Element('loginparameter');
76
+            if (loginParameter) {
77
+                for (const item of loginParameter.Elements()) {
78
+                    const element = this.GetElement(item, htmlDoc);
79
+                    if (element === null) {
80
+                        // 没有取到HtmlElement
81
+                        continue;
82
+                    }
83
+
84
+                    const property = item.Element('property');
85
+                    if (property) {
86
+                        for (const prop of property.Attributes()) {
87
+                            element.SetAttribute(prop.Name.LocalName, prop.Value === '@name' ? app.ExtSystemInfo.ExtName : app.ExtSystemInfo.ExtPsw);
88
+                        }
89
+                    }
90
+                }
91
+            }
92
+        }
93
+
94
+        // 登录
95
+        if (root) {
96
+            const loginMethod = root.Element('loginmethod');
97
+            if (loginMethod) {
98
+                for (const item of loginMethod.Elements()) {
99
+                    const method = item.Element('method');
100
+                    if (!method) continue;
101
+
102
+                    // 如果是Item
103
+                    if (item.Name.LocalName.toLowerCase() === 'item') {
104
+                        const element = this.GetElement(item, htmlDoc);
105
+                        if (element === null) {
106
+                            // 没有取到HtmlElement
107
+                            continue;
108
+                        }
109
+
110
+                        const attName = method.Attribute('name');
111
+                        const attParameter = method.Attribute('parameter');
112
+                        if (!attName) return;
113
+
114
+                        if (!attParameter) {
115
+                            element.InvokeMember(attName.Value);
116
+                        } else {
117
+                            element.InvokeMember(attName.Value, attParameter.Value);
118
+                        }
119
+                    } 
120
+                    // 如果是脚本
121
+                    else if (item.Name.LocalName.toLowerCase() === 'script') {
122
+                        const attName = method.Attribute('name');
123
+                        const attParameter = method.Attribute('parameter');
124
+                        if (!attName) return;
125
+
126
+                        if (!attParameter) {
127
+                            htmlDoc.InvokeScript(attName.Value);
128
+                        } else {
129
+                            htmlDoc.InvokeScript(attName.Value, [attParameter.Value]);
130
+                        }
131
+                    }
132
+                }
133
+            }
134
+        }
135
+    }
136
+
137
+    /**
138
+     * 根据XElement获取HtmlElement
139
+     * @param item XElement对象
140
+     * @param htmlDoc HTML文档对象
141
+     * @returns HtmlElement对象或null
142
+     */
143
+    private static GetElement(item: XElement, htmlDoc: HtmlDocument): HtmlElement | null {
144
+        const attID = item.Attribute('id');
145
+
146
+        // 如果att中有ID,使用ID选择器选择
147
+        if (attID) {
148
+            return htmlDoc.GetElementById(attID.Value);
149
+        }
150
+
151
+        const attName = item.Attribute('name');
152
+
153
+        // 如果有Name
154
+        if (attName) {
155
+            const items = htmlDoc.All[attName.Value];
156
+
157
+            // 如果唯一
158
+            if (items && items.Children.Count === 1) {
159
+                return items;
160
+            }
161
+        }
162
+
163
+        let flg = true;
164
+        const attTag = item.Attribute('tagname');
165
+
166
+        // 其他
167
+        for (let i = 0; i < htmlDoc.Body.All.length; i++) {
168
+            const element = htmlDoc.Body.All[i];
169
+
170
+            // 如果有TagName
171
+            if (attTag) {
172
+                if (element.TagName.toLowerCase()!== attTag.Value.toLowerCase()) {
173
+                    continue;
174
+                }
175
+            }
176
+
177
+            // 如果有Name
178
+            if (attName) {
179
+                if (element.Name.toLowerCase()!== attName.Value.toLowerCase()) {
180
+                    continue;
181
+                }
182
+            }
183
+
184
+            flg = true;
185
+
186
+            // 其他选择器取并集
187
+            for (const att of item.Attributes().filter(att => att.Value && att.Name.LocalName.toLowerCase()!== 'tagname' && att.Name.LocalName.toLowerCase()!== 'name')) {
188
+                if (element.GetAttribute(att.Name.LocalName).toLowerCase()!== att.Value.toLowerCase()) {
189
+                    flg = false;
190
+                    break;
191
+                }
192
+            }
193
+
194
+            if (flg) {
195
+                return element;
196
+            }
197
+        }
198
+
199
+        return null;
200
+    }
201
+}
202
+
203
+// 由于没有实际的XDocument.Parse方法,这里简单模拟
204
+namespace XDocument {
205
+    export function Parse(script: string): XDocument {
206
+        // 这里只是简单返回一个模拟对象,实际需要根据XML解析逻辑实现
207
+        return {
208
+            Element: () => null
209
+        };
210
+    }
211
+}
212
+
213
+export { ScriptHelper };

+ 13
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/ExternalSystem/TS/NativeRECT.ts 查看文件

@@ -0,0 +1,13 @@
1
+// 定义 NativeRECT 接口,用于表示矩形区域
2
+interface NativeRECT {
3
+    // 矩形左边界的位置
4
+    left: number;
5
+    // 矩形上边界的位置
6
+    top: number;
7
+    // 矩形右边界的位置
8
+    right: number;
9
+    // 矩形下边界的位置
10
+    bottom: number;
11
+}
12
+
13
+export { NativeRECT };

+ 1
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/Function/ErrorCodeMap.ts 查看文件

@@ -0,0 +1 @@
1
+// TODO原项目中被排除了

+ 676
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/Function/ExcelFunction/ExcelFuntion.ts 查看文件

@@ -0,0 +1,676 @@
1
+// namespace ExcelFuntion {
2
+//     // 模拟GetWindowThreadProcessId函数
3
+//     function GetWindowThreadProcessId(hWnd: number, lpdwProcessId: { value: number }): number {
4
+//         // 这里只是模拟,实际需要根据具体情况实现
5
+//         lpdwProcessId.value = 0;
6
+//         return 0;
7
+//     }
8
+
9
+//     // 杀死Excel进程
10
+//     function KillSpecialExcel(mObjExcel: Application): void {
11
+//         try {
12
+//             if (!mObjExcel) return;
13
+//             const lpdwProcessId = { value: 0 };
14
+//             GetWindowThreadProcessId(mObjExcel.Hwnd, lpdwProcessId);
15
+//             Process.getProcessById(lpdwProcessId.value).kill();
16
+//         } catch (ex) {
17
+//             // Console.WriteLine("Delete Excel Process Error:" + ex.Message);
18
+//         }
19
+//     }
20
+
21
+//     // 简单导出Excel文件
22
+//     function ExportSimpleExcel(dt: DataTable, outputFile: string, groupColumn: string, sheetPrefixName: string): void {
23
+//         if (!dt || dt.rows.length === 0) return;
24
+//         const xlApp = new Application();
25
+//         xlApp.Visible = false;
26
+//         xlApp.DisplayAlerts = false;
27
+//         const workbooks = xlApp.Workbooks;
28
+//         const workbook = workbooks.Add(XlWBATemplate.xlWBATWorksheet);
29
+//         if (groupColumn && dt.columns.includes(groupColumn)) {
30
+//             const result = dt.rows.reduce((acc, dr) => {
31
+//                 const key = dr[groupColumn].toString();
32
+//                 if (!acc[key]) {
33
+//                     acc[key] = [];
34
+//                 }
35
+//                 acc[key].push(dr);
36
+//                 return acc;
37
+//             }, {} as { [key: string]: any[] });
38
+//             for (const key in result) {
39
+//                 const rows = result[key];
40
+//                 const rowCount = rows.length;
41
+//                 const colCount = dt.columns.length;
42
+//                 const worksheet = workbook.Worksheets.Add();
43
+//                 worksheet.Name = key;
44
+//                 for (let i = 0; i < dt.columns.length; i++) {
45
+//                     worksheet.Cells[1][i + 1] = dt.columns[i].ColumnName;
46
+//                 }
47
+//                 for (let j = 0; j < rowCount; j++) {
48
+//                     for (let k = 0; k < colCount; k++) {
49
+//                         worksheet.Cells[j + 2][k + 1] = rows[j][k].toString();
50
+//                     }
51
+//                 }
52
+//             }
53
+//         } else {
54
+//             const worksheet = workbook.Worksheets.Add();
55
+//             worksheet.Name = sheetPrefixName;
56
+//             for (let i = 0; i < dt.columns.length; i++) {
57
+//                 worksheet.Cells[1][i + 1] = dt.columns[i].ColumnName;
58
+//             }
59
+//             for (let r = 0; r < dt.rows.length; r++) {
60
+//                 for (let i = 0; i < dt.columns.length; i++) {
61
+//                     // 前加单引号设置单元格格式为文本
62
+//                     worksheet.Cells[r + 2][i + 1] = "'" + dt.rows[r][i].toString();
63
+//                 }
64
+//             }
65
+//         }
66
+//         try {
67
+//             workbook.Saved = true;
68
+//             workbook.SaveAs(outputFile, null, null, null, null, null, XlSaveAsAccessMode.xlExclusive, null, null, null, null);
69
+//         } catch (e) {
70
+//             throw e;
71
+//         } finally {
72
+//             try {
73
+//                 workbook.Close(true, null, null);
74
+//                 xlApp.Workbooks.Close();
75
+//                 xlApp.Application.Quit();
76
+//                 xlApp.Quit();
77
+//                 KillSpecialExcel(xlApp);
78
+//             } catch { }
79
+//             // 模拟GC.Collect()
80
+//             // 在TypeScript中,垃圾回收由JavaScript引擎自动处理
81
+//         }
82
+//     }
83
+
84
+//     // DataBox数据导出Excel文档
85
+//     function ExportSimpleExcelDataBox(databox: DataBox, groupColumn: string = null, sheetPrefixName: string = "sheet"): void {
86
+//         const saveDialog = new SaveFileDialog();
87
+//         saveDialog.FileName = "DataBoxToExcel";
88
+//         saveDialog.showDialog();
89
+//         const outputFile = saveDialog.FileName;
90
+//         if (outputFile.indexOf(":") < 0) return; // 被点了取消
91
+//         ExportSimpleExcel(databox.DataSource, outputFile, groupColumn, sheetPrefixName);
92
+//     }
93
+
94
+//     // 根据DataTable导出Excel
95
+//     function ExportExcelByDataTable(table: DataTable, outputFile: string, groupColumn: string = null, sheetPrefixName: string = "sheet"): void {
96
+//         if (table) {
97
+//             const a = () => {
98
+//                 ExportSimpleExcel(table, outputFile, groupColumn, sheetPrefixName);
99
+//             };
100
+//             a();
101
+//             // 这里C#的异步调用在TypeScript中可以使用异步函数和Promise替代
102
+//             // 原代码中异步调用处理比较简单,这里直接同步执行
103
+//         }
104
+//     }
105
+
106
+//     // 导出到excel(NPOI版)
107
+//     function ExportToExcel(dataAll: DataTable, outputFile: string): void {
108
+//         const filePath = outputFile;
109
+//         const last = filePath.lastIndexOf(".");
110
+//         const ExcelType = filePath.substring(last + 1);
111
+//         const fs = new FileStream(filePath, "create", "write");
112
+//         const fc = NPOIHelper.CreateFactory(ExcelType);
113
+//         const source = fc.CreateExcel().DataTableToExcel(dataAll);
114
+//         if (source && source.length > 0) {
115
+//             fs.write(source, 0, source.length);
116
+//             fs.flush();
117
+//             return;
118
+//         }
119
+//     }
120
+
121
+//     // 以弹出框的形式将DataTable倒入Excel(NPOI版)
122
+//     function ExportToExcelDataTable(dt: DataTable): boolean {
123
+//         let IsFild = true;
124
+//         if (!dt) {
125
+//             return false;
126
+//         }
127
+//         const saveDialog = new SaveFileDialog();
128
+//         saveDialog.DefaultExt = "xlsx";
129
+//         saveDialog.Filter = "Excel文件(*.xlsx,*.xls)|*.xlsx;*.xls";
130
+//         saveDialog.FileName = "Excel";
131
+//         saveDialog.onFileOk = (s, a) => {
132
+//             const fs = new FileStream(saveDialog.FileName, "create", "write");
133
+//             const arry = saveDialog.FileName.split('.');
134
+//             const source = NPOIHelper.CreateFactory(arry[arry.length - 1]).CreateExcel().DataTableToExcel(dt);
135
+//             if (source && source.length > 0) {
136
+//                 fs.write(source, 0, source.length);
137
+//                 fs.flush();
138
+//                 IsFild = true;
139
+//                 return;
140
+//             }
141
+//         };
142
+//         saveDialog.showDialog();
143
+//         return IsFild;
144
+//     }
145
+
146
+//     // 以路径的形式将DataSet倒入Excel(NPOI版)
147
+//     function DataSetToExcle(ds: DataSet, filePath: string): boolean {
148
+//         if (!ds || ds.tables.length <= 0) {
149
+//             return false;
150
+//         }
151
+//         const arryOther = filePath.split('\\');
152
+//         if (!arryOther[arryOther.length - 1]) {
153
+//             filePath = filePath + "Excel";
154
+//         }
155
+//         let ExcelType = "xlsx";
156
+//         const arry = filePath.split('.');
157
+//         if (arry[arry.length - 1] === "xlsx" || arry[arry.length - 1] === "xls") {
158
+//             ExcelType = arry[arry.length - 1];
159
+//         } else {
160
+//             filePath = filePath + ".xlsx";
161
+//         }
162
+//         if (!filePath) {
163
+//             return false;
164
+//         }
165
+//         if (File.exists(filePath)) {
166
+//             if (MessageBox.show("文件保存位置已存在该文件,是否覆盖?", "警告", "YesNo") === "No") {
167
+//                 return false;
168
+//             }
169
+//         }
170
+//         const fs = new FileStream(filePath, "create", "write");
171
+//         const source = NPOIHelper.CreateFactory(ExcelType).CreateExcel().DataSetToExcel(ds);
172
+//         if (source && source.length > 0) {
173
+//             fs.write(source, 0, source.length);
174
+//             fs.flush();
175
+//             return true;
176
+//         }
177
+//         return false;
178
+//     }
179
+
180
+//     // 以弹出框的形式将DataSet倒入Excel(NPOI版)
181
+//     function DataSetToExcleDataSet(ds: DataSet): boolean {
182
+//         let IsFild = true;
183
+//         if (!ds || ds.tables.length <= 0) {
184
+//             return false;
185
+//         }
186
+//         const saveDialog = new SaveFileDialog();
187
+//         saveDialog.DefaultExt = "xlsx";
188
+//         saveDialog.Filter = "Excel文件(*.xlsx,*.xls)|*.xlsx;*.xls";
189
+//         saveDialog.FileName = "Excel";
190
+//         saveDialog.onFileOk = (s, a) => {
191
+//             const fs = new FileStream(saveDialog.FileName, "create", "write");
192
+//             const arry = saveDialog.FileName.split('.');
193
+//             const source = NPOIHelper.CreateFactory(arry[arry.length - 1]).CreateExcel().DataSetToExcel(ds);
194
+//             if (source && source.length > 0) {
195
+//                 fs.write(source, 0, source.length);
196
+//                 fs.flush();
197
+//                 IsFild = true;
198
+//                 return;
199
+//             }
200
+//         };
201
+//         saveDialog.showDialog();
202
+//         return IsFild;
203
+//     }
204
+
205
+//     // 读取模板文件导出Excel文件
206
+//     function ExportTemplateExcel(databox: DataBox, top: number, left: number, groupColumn: string = null, sheetPrefixName: string = "Sheet"): void {
207
+//         const open = new OpenFileDialog();
208
+//         open.Filter = "xls files (*.xls)|*.xls|xlsx files (*.xlsx)|*.xlsx";
209
+//         open.showDialog();
210
+//         const openFileName = open.FileName;
211
+//         if (openFileName.indexOf(":") < 0) return;
212
+//         const saveDialog = new SaveFileDialog();
213
+//         saveDialog.FileName = "DataBoxToExcel";
214
+//         saveDialog.showDialog();
215
+//         const saveFileName = saveDialog.FileName;
216
+//         if (saveFileName.indexOf(":") < 0) return;
217
+//         DataTableToExcel(databox.DataSource, top, left, openFileName, saveFileName, groupColumn, sheetPrefixName);
218
+//     }
219
+
220
+//     // 从DataTable导出到Excel
221
+//     function DataTableToExcel(dt: DataTable, top: number, left: number, templetFile: string, outputFile: string, groupColumn: string, sheetPrefixName: string): void {
222
+//         if (!dt || dt.rows.length === 0) return;
223
+//         const app = new Application();
224
+//         app.Visible = false;
225
+//         app.DisplayAlerts = false;
226
+//         const workBook = app.Workbooks.Open(templetFile, null, null, null, null, null, null, null, null, null, null, null, null);
227
+//         const workSheet = workBook.Sheets[1] as Worksheet;
228
+//         if (groupColumn && dt.columns.includes(groupColumn)) {
229
+//             const result = dt.rows.reduce((acc, dr) => {
230
+//                 const key = dr[groupColumn].toString();
231
+//                 if (!acc[key]) {
232
+//                     acc[key] = [];
233
+//                 }
234
+//                 acc[key].push(dr);
235
+//                 return acc;
236
+//             }, {} as { [key: string]: any[] });
237
+//             const enumerable = Object.keys(result).map(key => ({ key, rows: result[key] }));
238
+//             for (let i = 0; i < enumerable.length - 1; i++) {
239
+//                 for (let j = 1; j < workBook.Sheets.length + 1; j++) {
240
+//                     workBook.Sheets[j].Name = j.toString();
241
+//                 }
242
+//                 workSheet.Copy(null, workBook.Sheets[workBook.Sheets.length]);
243
+//             }
244
+//             for (let i = 0; i < enumerable.length; i++) {
245
+//                 const rowCount = enumerable[i].rows.length;
246
+//                 const rows = enumerable[i].rows;
247
+//                 const colCount = dt.columns.length;
248
+//                 const newworksheet = workBook.Sheets[i + 1] as Worksheet;
249
+//                 newworksheet.Name = enumerable[i].key;
250
+//                 for (let j = 0; j < rowCount; j++) {
251
+//                     for (let k = 0; k < colCount; k++) {
252
+//                         newworksheet.Cells[top + j][left + k] = rows[j][k].toString();
253
+//                     }
254
+//                 }
255
+//             }
256
+//         } else {
257
+//             const sheet = workBook.Worksheets[1] as Worksheet;
258
+//             sheet.Name = sheetPrefixName;
259
+//             for (let j = 0; j < dt.rows.length; j++) {
260
+//                 for (let k = 0; k < dt.columns.length; k++) {
261
+//                     sheet.Cells[top + j][left + k] = dt.rows[j][k].toString();
262
+//                 }
263
+//             }
264
+//         }
265
+//         try {
266
+//             workBook.SaveAs(outputFile, null, null, null, null, null, XlSaveAsAccessMode.xlExclusive, null, null, null, null);
267
+//         } catch (e) {
268
+//             throw e;
269
+//         } finally {
270
+//             try {
271
+//                 workBook.Close(null, null, null);
272
+//                 app.Workbooks.Close();
273
+//                 app.Application.Quit();
274
+//                 app.Quit();
275
+//                 KillSpecialExcel(app);
276
+//             } catch { }
277
+//             // 模拟GC.Collect()
278
+//             // 在TypeScript中,垃圾回收由JavaScript引擎自动处理
279
+//         }
280
+//     }
281
+
282
+//     // 自定义单元格样式导出Excel文件
283
+//     function DataTableToExcelDataBox(databox: DataBox, selectForm: any): void {
284
+//         if (databox.DataSource) {
285
+//             let fileSaved = false;
286
+//             const saveDialog = new SaveFileDialog();
287
+//             saveDialog.DefaultExt = "xls";
288
+//             saveDialog.Filter = "Excel文件|*.xls";
289
+//             saveDialog.FileName = "Excel";
290
+//             saveDialog.showDialog();
291
+//             const saveFileName = saveDialog.FileName;
292
+//             if (saveFileName.indexOf(":") < 0) return; // 被点了取消
293
+//             const xlApp = new Application();
294
+//             if (!xlApp) {
295
+//                 MessageBox.show("无法启动Excel,可能您未安装Excel");
296
+//                 return;
297
+//             }
298
+//             const workbook = xlApp.Workbooks.Add(true);
299
+//             const worksheet = workbook.Worksheets[1] as Worksheet;
300
+//             let range: Range;
301
+//             let rangeCon: Range;
302
+//             let colIndex = 0;
303
+//             let RowIndex = 0;
304
+//             const colCount = databox.DataSource.columns.length;
305
+//             const RowCount = databox.DataSource.rows.length;
306
+//             worksheet.Name = selectForm.SheetName.Text === "" ? "sheet" : selectForm.SheetName.Text;
307
+//             const objData = new Array(RowCount + 1).fill(0).map(() => new Array(colCount).fill(0));
308
+//             for (RowIndex = 0; RowIndex < RowCount; RowIndex++) {
309
+//                 for (colIndex = 0; colIndex < colCount; colIndex++) {
310
+//                     objData[RowIndex][colIndex] = databox.DataSource.rows[RowIndex][colIndex];
311
+//                 }
312
+//             }
313
+//             range = worksheet.Range(worksheet.Cells[1][1], worksheet.Cells[1][colCount]);
314
+//             range.MergeCells = true;
315
+//             range.RowHeight = 38;
316
+//             range.Font.Bold = selectForm.TitBold.GetSelectedValue();
317
+//             range.Font.Size = selectForm.TitFontSize.GetSelectedKey();
318
+//             range.Font.Name = selectForm.TitFontStyle.GetSelectedValue();
319
+//             range.Font.ColorIndex = selectForm.TitFontColor.GetSelectedValue();
320
+//             xlApp.ActiveCell.FormulaR1C1 = selectForm.TitelName.Text;
321
+//             xlApp.Cells.HorizontalAlignment = "xlCenter";
322
+//             range = worksheet.Range(worksheet.Cells[2][1], worksheet.Cells[2][colCount]);
323
+//             range.MergeCells = true;
324
+//             range.Value2 = "日期范围:" + selectForm.StartDate.Text + " 到 " + selectForm.EndDate.Text + ",查询条件:" + selectForm.SelectTerm.Text;
325
+//             range.Cells.HorizontalAlignment = "xlLeft";
326
+//             for (let i = 0; i < databox.DataSource.columns.length; i++) {
327
+//                 range = worksheet.Range(worksheet.Cells[3][i + 1], worksheet.Cells[3][i + 1]);
328
+//                 range.Font.Bold = selectForm.TopBold.GetSelectedValue();
329
+//                 range.Font.Size = selectForm.TopFontSize.GetSelectedKey();
330
+//                 range.Font.Name = selectForm.TopFontStyle.GetSelectedValue();
331
+//                 range.Font.ColorIndex = selectForm.TopFontColor.GetSelectedValue();
332
+//                 range.AroundBorders();
333
+//                 range.Value2 = databox.DataSource.columns[i].Caption;
334
+//             }
335
+//             for (let i = 4; i < RowCount + 3; i++) {
336
+//                 for (let j = 0; j < databox.DataSource.columns.length; j++) {
337
+//                     range = worksheet.Range(worksheet.Cells[i][j + 1], worksheet.Cells[i][j + 1]);
338
+//                     if (j === 0 && i === 4) {
339
+//                         range.Value2 = "合计(人数:" + (RowCount - 2) + ")";
340
+//                         range.Font.Bold = true;
341
+//                         range.Font.ColorIndex = 3;
342
+//                     }
343
+//                     range.Cells.HorizontalAlignment = "xlLeft";
344
+//                     range.AroundBorders();
345
+//                 }
346
+//             }
347
+//             range = worksheet.Range(worksheet.Cells[5][1], worksheet.Cells[RowCount + 2][colCount]);
348
+//             range.Value2 = objData;
349
+//             let startRow = selectForm.StartRow.Text.GetStringToNum() < 5 ? 5 : selectForm.StartRow.Text.GetStringToNum();
350
+//             let startCol = selectForm.StartCol.Text.GetStringToNum() === 0 ? 1 : selectForm.StartCol.Text.GetStringToNum();
351
+//             let endRow = selectForm.EndRow.Text.GetStringToNum() === 0 ? RowCount + 3 : selectForm.EndRow.Text.GetStringToNum();
352
+//             let endCol = selectForm.EndCol.Text.GetStringToNum() === 0 ? databox.DataSource.columns.length : selectForm.EndCol.Text.GetStringToNum();
353
+//             rangeCon = worksheet.Range(worksheet.Cells[startRow][startCol], worksheet.Cells[endRow][endCol]);
354
+//             rangeCon.Font.Bold = selectForm.ConBold.GetSelectedValue();
355
+//             rangeCon.Font.Size = selectForm.ConFontSize.GetSelectedKey();
356
+//             rangeCon.Font.Name = selectForm.ConFontStyle.GetSelectedValue();
357
+//             rangeCon.Font.ColorIndex = selectForm.ConFontColor.GetSelectedValue();
358
+//             worksheet.Columns.EntireColumn.AutoFit();
359
+//             if (saveFileName) {
360
+//                 try {
361
+//                     workbook.Saved = true;
362
+//                     workbook.SaveCopyAs(saveFileName);
363
+//                     fileSaved = true;
364
+//                 } catch (ex) {
365
+//                     fileSaved = false;
366
+//                     MessageBox.show("导出文件时出错,文件可能正被打开!\n" + ex.Message);
367
+//                 }
368
+//             } else {
369
+//                 fileSaved = false;
370
+//             }
371
+//             xlApp.Quit();
372
+//             // 模拟GC.Collect()
373
+//             // 在TypeScript中,垃圾回收由JavaScript引擎自动处理
374
+//             const dateEnd = new Date();
375
+//             MessageBox.show("导出成功");
376
+//             if (fileSaved && File.exists(saveFileName)) {
377
+//                 Process.start(saveFileName);
378
+//             }
379
+//         } else {
380
+//             MessageBox.show("没有数据需要导出");
381
+//             return;
382
+//         }
383
+//     }
384
+
385
+//     // Databox分组导出Excel
386
+//     function DataboxToExcelGroupBy(databox: DataBox): void {
387
+//         if (databox.DataSource) {
388
+//             const SelectForm = new SelectFrm();
389
+//             SelectForm.showDialog();
390
+//             if (SelectForm.Flag.Text !== "1") {
391
+//                 return;
392
+//             }
393
+//             if (SelectForm.DataSave.GetSelectedValue() === "0") {
394
+//                 databox.DataTableToExcel(SelectForm);
395
+//                 return;
396
+//             }
397
+//             let fileSaved = false;
398
+//             const saveDialog = new SaveFileDialog();
399
+//             saveDialog.DefaultExt = "xls";
400
+//             saveDialog.Filter = "Excel文件|*.xls";
401
+//             saveDialog.FileName = "Excel";
402
+//             saveDialog.showDialog();
403
+//             const saveFileName = saveDialog.FileName;
404
+//             if (saveFileName.indexOf(":") < 0) return; // 被点了取消
405
+//             const xlApp = new Application();
406
+//             const workbook = xlApp.Workbooks.Add(true);
407
+//             let worksheet: Worksheet;
408
+//             let range: Range;
409
+//             let rangeCoun: Range;
410
+//             let rownum = 0;
411
+//             const byGroup = SelectForm.SheetName.Text === "" ? 0 : SelectForm.SheetName.Text.GetStringToNum();
412
+//             const result = databox.DataSource.rows.reduce((acc, dr) => {
413
+//                 const key = dr[byGroup].toString();
414
+//                 if (!acc[key]) {
415
+//                     acc[key] = [];
416
+//                 }
417
+//                 acc[key].push(dr);
418
+//                 return acc;
419
+//             }, {} as { [key: string]: any[] });
420
+//             for (const key in result) {
421
+//                 const ig = { key, rows: result[key] };
422
+//                 rownum = 3;
423
+//                 worksheet = xlApp.Worksheets.Add();
424
+//                 worksheet.Name = ig.key;
425
+//                 range = worksheet.Range(worksheet.Cells[1][1], worksheet.Cells[1][databox.DataSource.columns.length]);
426
+//                 range.MergeCells = true;
427
+//                 range.RowHeight = 38;
428
+//                 range.Font.Bold = SelectForm.TitBold.GetSelectedValue();
429
+//                 range.Font.Size = SelectForm.TitFontSize.GetSelectedKey();
430
+//                 range.Font.Name = SelectForm.TitFontStyle.GetSelectedValue();
431
+//                 range.Font.ColorIndex = SelectForm.TitFontColor.GetSelectedValue();
432
+//                 xlApp.ActiveCell.FormulaR1C1 = SelectForm.TitelName.Text;
433
+//                 xlApp.Cells.HorizontalAlignment = "xlCenter";
434
+//                 range = worksheet.Range(worksheet.Cells[2][1], worksheet.Cells[2][databox.DataSource.columns.length]);
435
+//                 range.MergeCells = true;
436
+//                 range.Value2 = "日期范围:" + SelectForm.StartDate.Text + " 到 " + SelectForm.EndDate.Text + ",查询条件:" + SelectForm.SelectTerm.Text;
437
+//                 range.Cells.HorizontalAlignment = "xlLeft";
438
+//                 for (let i = 0; i < databox.DataSource.columns.length; i++) {
439
+//                     range = worksheet.Range(worksheet.Cells[3][i + 1], worksheet.Cells[3][i + 1]);
440
+//                     range.Font.Bold = SelectForm.TopBold.GetSelectedValue();
441
+//                     range.Font.Size = SelectForm.TopFontSize.GetSelectedKey();
442
+//                     range.Font.Name = SelectForm.TopFontStyle.GetSelectedValue();
443
+//                     range.Font.ColorIndex = SelectForm.TopFontColor.GetSelectedValue();
444
+//                     range.AroundBorders();
445
+//                     range.Value2 = databox.DataSource.columns[i].Caption;
446
+//                 }
447
+//                 let startRow = SelectForm.StartRow.Text.GetStringToNum() < 5 ? 5 : SelectForm.StartRow.Text.GetStringToNum();
448
+//                 let startCol = SelectForm.StartCol.Text.GetStringToNum() === 0 ? 1 : SelectForm.StartCol.Text.GetStringToNum();
449
+//                 let endRow = 0;
450
+//                 let endCol = 0;
451
+//                 for (const drr of ig.rows) {
452
+//                     rownum++;
453
+//                     for (let j = 0; j < drr.ItemArray.length; j++) {
454
+//                         range = worksheet.Range(worksheet.Cells[rownum + 1][j + 1], worksheet.Cells[rownum + 1][j + 1]);
455
+//                         range.Value2 = drr.ItemArray[j].toString();
456
+//                         range.Cells.HorizontalAlignment = "xlLeft";
457
+//                         range.AroundBorders();
458
+//                     }
459
+//                     endRow = SelectForm.EndRow.Text.GetStringToNum() === 0 ? rownum + 1 : SelectForm.EndRow.Text.GetStringToNum();
460
+//                     endCol = SelectForm.EndCol.Text.GetStringToNum() === 0 ? drr.ItemArray.length : SelectForm.EndCol.Text.GetStringToNum();
461
+//                 }
462
+//                 rangeCoun = worksheet.Range(worksheet.Cells[startRow][startCol], worksheet.Cells[endRow][endCol]);
463
+//                 rangeCoun.Font.Bold = SelectForm.ConBold.GetSelectedValue();
464
+//                 rangeCoun.Font.Size = SelectForm.ConFontSize.GetSelectedKey();
465
+//                 rangeCoun.Font.Name = SelectForm.ConFontStyle.GetSelectedValue();
466
+//                 rangeCoun.Font.ColorIndex = SelectForm.ConFontColor.GetSelectedValue();
467
+//                 for (let i = 0; i < databox.DataSource.columns.length; i++) {
468
+//                     range = worksheet.Range(worksheet.Cells[4][i + 1], worksheet.Cells[4][i + 1]);
469
+//                     if (i === 0) {
470
+//                         range.Value2 = "合计(人数:" + (rownum - 3) + ")";
471
+//                         range.Font.Bold = true;
472
+//                         range.Font.ColorIndex = 3;
473
+//                     }
474
+//                     range.Cells.HorizontalAlignment = "xlLeft";
475
+//                     range.AroundBorders();
476
+//                 }
477
+//                 worksheet.Columns.EntireColumn.AutoFit();
478
+//             }
479
+//             if (saveFileName) {
480
+//                 try {
481
+//                     workbook.Saved = true;
482
+//                     workbook.SaveCopyAs(saveFileName);
483
+//                     fileSaved = true;
484
+//                     xlApp.Workbooks.Close();
485
+//                     xlApp.Application.Quit();
486
+//                     // 释放资源
487
+//                     // 在TypeScript中,对象的释放由JavaScript引擎自动处理
488
+//                 } catch (ex) {
489
+//                     fileSaved = false;
490
+//                     MessageBox.show("导出文件时出错,文件可能正被打开!\n" + ex.Message);
491
+//                     return;
492
+//                 }
493
+//             } else {
494
+//                 fileSaved = false;
495
+//             }
496
+//             // 模拟GC.Collect()
497
+//             // 在TypeScript中,垃圾回收由JavaScript引擎自动处理
498
+//             MessageBox.show("导出成功");
499
+//             if (fileSaved && File.exists(saveFileName)) {
500
+//                 Process.start(saveFileName);
501
+//             }
502
+//         } else {
503
+//             MessageBox.show("没有数据需要导出");
504
+//             return;
505
+//         }
506
+//     }
507
+
508
+//     // 为Excel范围添加外边框
509
+//     function AroundBorders(range: Range): void {
510
+//         range.Borders[XlBordersIndex.xlEdgeTop].LineStyle = XlLineStyle.xlContinuous;
511
+//         range.Borders[XlBordersIndex.xlEdgeLeft].LineStyle = XlLineStyle.xlContinuous;
512
+//         range.Borders[XlBordersIndex.xlEdgeRight].LineStyle = XlLineStyle.xlContinuous;
513
+//         range.Borders[XlBordersIndex.xlEdgeBottom].LineStyle = XlLineStyle.xlContinuous;
514
+//     }
515
+
516
+//     // 导入Excel文件
517
+//     function ImportSimpleExcel(databox: DataBox, columnNames: string[], startRow: number = 0): void {
518
+//         const ofd = new OpenFileDialog();
519
+//         ofd.Title = "Excel文件";
520
+//         ofd.FileName = "";
521
+//         ofd.InitialDirectory = Environment.getFolderPath(Environment.SpecialFolder.MyDocuments);
522
+//         ofd.Filter = "Excel文件(*.xls)|*.xls|Excel文件(*.xlsx)|*.xlsx|所有文件(*.*)|*.*";
523
+//         ofd.ValidateNames = true;
524
+//         ofd.CheckFileExists = true;
525
+//         ofd.CheckPathExists = true;
526
+//         ofd.Multiselect = true;
527
+//         const result = ofd.showDialog();
528
+//         if (!result) return;
529
+//         const datastr = ImportSimpleExcel(ofd.FileNames, columnNames.length, startRow);
530
+//         databox.DataBinding(datastr, columnNames);
531
+//     }
532
+
533
+//     // 导入Excel文件辅助方法
534
+//     function ImportSimpleExcel(filePaths: string[], columnsCount: number, startRow: number): string {
535
+//         let stringData = "";
536
+//         for (const filePath of filePaths) {
537
+//             const ds = EcxelToDataSet(filePath);
538
+//             for (let i = 0; i < ds.tables.length; i++) {
539
+//                 if (startRow >= ds.tables[i].rows.length) continue;
540
+//                 const sb = [];
541
+//                 sb.push("|");
542
+//                 if (columnsCount <= ds.tables[i].columns.length) {
543
+//                     for (let t = startRow; t < ds.tables[i].rows.length; t++) {
544
+//                         for (let j = 0; j < columnsCount; j++) {
545
+//                             sb.push(ds.tables[i].rows[t][j]);
546
+//                             sb.push("|");
547
+//                         }
548
+//                         sb.push("\n|");
549
+//                     }
550
+//                 } else {
551
+//                     for (let t = startRow; t < ds.tables[i].rows.length; t++) {
552
+//                         for (let j = 0; j < ds.tables[i].columns.length; j++) {
553
+//                             sb.push(ds.tables[i].rows[t][j]);
554
+//                             sb.push("|");
555
+//                         }
556
+//                         for (let j = 0; j < columnsCount - ds.tables[i].columns.length; j++) {
557
+//                             sb.push("|");
558
+//                         }
559
+//                         sb.push("\n|");
560
+//                     }
561
+//                 }
562
+//                 stringData = sb.join("");
563
+//             }
564
+//         }
565
+//         return stringData;
566
+//     }
567
+
568
+//     // Excel文件转DataSet
569
+//     function EcxelToDataSet(filePath: string): DataSet {
570
+//         const extension = Path.extname(filePath);
571
+//         let strConn = "";
572
+//         if (extension === ".xls") {
573
+//             strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source = " + filePath + ";Extended Properties ='Excel 8.0;HDR=NO;IMEX=1'";
574
+//         } else if (extension === ".xlsx") {
575
+//             strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source = " + filePath + ";Extended Properties ='Excel 12.0;HDR=NO;IMEX=1'";
576
+//         } else {
577
+//             MessageBox.show("不支持所选的数据格式!");
578
+//         }
579
+//         const conn = new OleDbConnection(strConn);
580
+//         conn.open();
581
+//         const dt = conn.getOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
582
+//         const ds = new DataSet();
583
+//         for (const row of dt.rows) {
584
+//             const strExcel = "select  * from   [" + row["TABLE_NAME"].toString() + "]";
585
+//             const myCommand = new OleDbDataAdapter(strExcel, strConn);
586
+//             myCommand.fill(ds);
587
+//         }
588
+//         return ds;
589
+//     }
590
+
591
+//     // 以路径的形式将Excel转为DataTable(NPOI版本)
592
+//     function ExcelToDataTable(filePath: string, sheetIndex: number = 0): DataTable {
593
+//         if (!File.exists(filePath)) {
594
+//             MessageBox.show("文件不存在!");
595
+//             return null;
596
+//         }
597
+//         const arry = filePath.split('.');
598
+//         if (arry[arry.length - 1]!== "xls" && arry[arry.length - 1]!== "xlsx") {
599
+//             MessageBox.show("文件类型需要为xls或xlsx!");
600
+//             return null;
601
+//         }
602
+//         const dt = new DataTable();
603
+//         return NPOIHelper.CreateFactory(arry[arry.length - 1]).CreateExcel().ExcelToTable(filePath, sheetIndex);
604
+//     }
605
+
606
+//     // 以选择文件的形式将Excel转为DataTable(NPOI版本)
607
+//     function ExcelToDataTableSelect(sheetIndex: number = 0): DataTable {
608
+//         const dt = new DataTable();
609
+//         const opd = new OpenFileDialog();
610
+//         opd.Title = "Excel文件";
611
+//         opd.FileName = "";
612
+//         opd.InitialDirectory = Environment.getFolderPath(Environment.SpecialFolder.MyDocuments);
613
+//         opd.Filter = "Excel文件(*.xlsx,*.xls)|*.xlsx;*.xls";
614
+//         opd.ValidateNames = true;
615
+//         opd.CheckFileExists = true;
616
+//         opd.CheckPathExists = true;
617
+//         opd.onFileOk = (s, a) => {
618
+//             const arry = opd.FileName.split('.');
619
+//             dt = NPOIHelper.CreateFactory(arry[arry.length - 1]).CreateExcel().ExcelToTable(opd.FileName, sheetIndex);
620
+//             dt.TableName = opd.FileName;
621
+//             return;
622
+//         };
623
+//         opd.showDialog();
624
+//         return dt;
625
+//     }
626
+
627
+//     // 导出txt文本
628
+//     function ExportTxt(databox: DataBox): void {
629
+//         const dialogOpenFile = new SaveFileDialog();
630
+//         dialogOpenFile.DefaultExt = "txt";
631
+//         dialogOpenFile.AddExtension = true;
632
+//         dialogOpenFile.Filter = "文本文档(*.txt)|.txt|所有文件 (*.*)|*.*";
633
+//         dialogOpenFile.OverwritePrompt = true;
634
+//         dialogOpenFile.FileName = "txt1";
635
+//         dialogOpenFile.CheckPathExists = true;
636
+//         dialogOpenFile.Title = "数据保存为*.txt";
637
+//         if (!dialogOpenFile.showDialog()) return;
638
+//         const fileName = dialogOpenFile.FileName;
639
+//         ExportTxt(databox.DataSource, fileName);
640
+//     }
641
+
642
+//     // 导出txt文本辅助方法
643
+//     function ExportTxt(dt: DataTable, fileName: string): void {
644
+//         try {
645
+//             const sb = [];
646
+//             for (const row of dt.rows) {
647
+//                 for (const item of row.ItemArray) {
648
+//                     sb.push(item);
649
+//                     sb.push(" ");
650
+//                 }
651
+//                 sb.push("\n");
652
+//             }
653
+//             const stream = File.openWrite(fileName);
654
+//             const writer = new StreamWriter(stream);
655
+//             writer.write(sb.join(""));
656
+//             writer.close();
657
+//         } catch (ex) {
658
+//             MessageBox.show(ex.Message, "Simple Edeitor", "OK", "Exclamation");
659
+//         }
660
+//     }
661
+
662
+//     // 字符串转化为数字
663
+//     function GetStringToNum(str: string): number {
664
+//         let intResult = 0;
665
+//         const r = /^[0-9]*$/;
666
+//         if (str.trim().length!== 0) {
667
+//             if (!r.test(str)) {
668
+//                 return -1;
669
+//             }
670
+//             return parseInt(str);
671
+//         }
672
+//         return intResult;
673
+//     }
674
+// }
675
+
676
+// export default ExcelFuntion;

+ 331
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/Function/ExcelFunction/SelectFrm.xaml 查看文件

@@ -0,0 +1,331 @@
1
+<Window x:Class="TellerSystem.Library.Ext.Function.ExcelFunction.SelectFrm"
2
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+        Title="Excel导出设置" Height="581" Width="600">
5
+    <StackPanel>
6
+        <GroupBox Name="SaveSetGroup" Header="Excel保存设置" Width="540">
7
+            <Grid Width="520">
8
+                <Grid.RowDefinitions>
9
+                    <RowDefinition  Height="15"/>
10
+                    <RowDefinition Height="23"/>
11
+                    <RowDefinition Height="6"/>
12
+                    <RowDefinition Height="23"/>
13
+                    <RowDefinition Height="6"/>
14
+                    <RowDefinition Height="23"/>
15
+
16
+                </Grid.RowDefinitions>
17
+                <Grid.ColumnDefinitions>
18
+                    <ColumnDefinition Width="15" />
19
+                    <ColumnDefinition Width="6" />
20
+                    <ColumnDefinition Width="60"/>
21
+                    <ColumnDefinition Width="6" />
22
+                    <ColumnDefinition Width="120"/>
23
+                    <ColumnDefinition Width="6" />
24
+                    <ColumnDefinition Width="46"/>
25
+                    <ColumnDefinition Width="6" />
26
+                    <ColumnDefinition Width="74"/>
27
+                    <ColumnDefinition Width="6" />
28
+                    <ColumnDefinition Width="120"/>
29
+                    <ColumnDefinition Width="55*" />
30
+                </Grid.ColumnDefinitions>
31
+                <TextBlock 
32
+                    Grid.Row="1"
33
+                    Grid.Column="2"
34
+                    Text="数据分组保存"
35
+                    TextAlignment="Right"
36
+                    />
37
+                <ComboBox Name="DataSave" 
38
+                          Grid.Row="1"
39
+                          Grid.Column="4"
40
+                          Width="119"
41
+                          LostFocus="DataSave_LostFocus"
42
+                          />
43
+                <TextBlock
44
+                            Name="TBlockSelect"
45
+                            Grid.Row="1"
46
+                           Grid.Column="8"
47
+                           TextAlignment="Right"
48
+                           Text="工作表名" />
49
+                <TextBox Name="SheetName" Grid.Column="10" Grid.Row="1" 
50
+                         
51
+                         />
52
+
53
+                <TextBlock Grid.Row="3"
54
+                           Grid.Column="8"
55
+                           TextAlignment="Right"
56
+                           Text="起始日期" />
57
+                <TextBlock Grid.Row="5"
58
+                           Grid.Column="2"
59
+                           TextAlignment="Right"
60
+                           Text="查询条件"  />
61
+                <TextBox Name="SelectTerm" 
62
+                          Grid.Row="5"
63
+                          Grid.Column="4"
64
+                          Width="378" Grid.ColumnSpan="7" />
65
+
66
+                <TextBox Name="StartDate" 
67
+                          Grid.Row="3"
68
+                          Grid.Column="10"
69
+                          Width="119"  />
70
+                <TextBlock Grid.Row="3"
71
+                           Grid.Column="2"
72
+                           TextAlignment="Right"
73
+                           Text="终止日期"/>
74
+                <TextBox Name="EndDate" 
75
+                          Grid.Row="3"
76
+                          Grid.Column="4"
77
+                          Width="120" />
78
+            </Grid>
79
+        </GroupBox>
80
+        <GroupBox Name="TitleGroupBox" Header="标题字体设置" Width="540">
81
+            <Grid Width="520">
82
+                <Grid.RowDefinitions>
83
+                    <RowDefinition  Height="15"/>
84
+                    <RowDefinition Height="23"/>
85
+                    <RowDefinition Height="6"/>
86
+                    <RowDefinition Height="23"/>
87
+                    <RowDefinition Height="6"/>
88
+                    <RowDefinition Height="23"/>
89
+
90
+                </Grid.RowDefinitions>
91
+                <Grid.ColumnDefinitions>
92
+                    <ColumnDefinition Width="15" />
93
+                    <ColumnDefinition Width="6" />
94
+                    <ColumnDefinition Width="60"/>
95
+                    <ColumnDefinition Width="6" />
96
+                    <ColumnDefinition Width="120"/>
97
+                    <ColumnDefinition Width="6" />
98
+                    <ColumnDefinition Width="60"/>
99
+                    <ColumnDefinition Width="6" />
100
+                    <ColumnDefinition Width="60"/>
101
+                    <ColumnDefinition Width="6" />
102
+                    <ColumnDefinition Width="119"/>
103
+                    <ColumnDefinition Width="Auto" />
104
+                </Grid.ColumnDefinitions>
105
+                <TextBlock 
106
+                    Grid.Row="1"
107
+                    Grid.Column="2"
108
+                    Text="标题名"
109
+                    TextAlignment="Right"
110
+                    />
111
+                <TextBox Name="TitelName"
112
+                         Grid.Row="1"
113
+                         Grid.Column="4"
114
+                         Width="377" Grid.ColumnSpan="7" />
115
+                <TextBlock Grid.Row="3"
116
+                           Grid.Column="2"
117
+                           TextAlignment="Right"
118
+                           Text="字体大小"/>
119
+                <ComboBox Name="TitFontSize" 
120
+                          Grid.Row="3"
121
+                          Grid.Column="4"
122
+                          Width="119"
123
+                          />
124
+                <TextBlock Grid.Row="3"
125
+                           Grid.Column="8"
126
+                           TextAlignment="Right"
127
+                           Text="字体格式" />
128
+                <TextBlock Grid.Row="5"
129
+                           Grid.Column="8"
130
+                           TextAlignment="Right"
131
+                           Text="是否加粗" />
132
+                <ComboBox Name="TitBold" 
133
+                          Grid.Row="5"
134
+                          Grid.Column="10"
135
+                          Width="119"
136
+                          />
137
+
138
+                <ComboBox Name="TitFontStyle" 
139
+                          Grid.Row="3"
140
+                          Grid.Column="10"
141
+                          Width="119"  />
142
+                <TextBlock Grid.Row="5"
143
+                           Grid.Column="2"
144
+                           TextAlignment="Right"
145
+                           Text="字体颜色"/>
146
+                <ComboBox Name="TitFontColor" 
147
+                          Grid.Row="5"
148
+                          Grid.Column="4"
149
+                          Width="119" />
150
+            </Grid>
151
+        </GroupBox>
152
+        <GroupBox Name="TableTopGroup" Header="表头字体样式设置" Width="540">
153
+            <Grid Width="520">
154
+                <Grid.RowDefinitions>
155
+                    <RowDefinition  Height="15"/>
156
+                    <RowDefinition Height="23"/>
157
+                    <RowDefinition Height="6"/>
158
+                    <RowDefinition Height="23"/>
159
+
160
+                </Grid.RowDefinitions>
161
+                <Grid.ColumnDefinitions>
162
+                    <ColumnDefinition Width="15" />
163
+                    <ColumnDefinition Width="6" />
164
+                    <ColumnDefinition Width="60"/>
165
+                    <ColumnDefinition Width="6" />
166
+                    <ColumnDefinition Width="120"/>
167
+                    <ColumnDefinition Width="6" />
168
+                    <ColumnDefinition Width="60"/>
169
+                    <ColumnDefinition Width="6" />
170
+                    <ColumnDefinition Width="60"/>
171
+                    <ColumnDefinition Width="6" />
172
+                    <ColumnDefinition Width="120"/>
173
+                    <ColumnDefinition Width="55*" />
174
+                </Grid.ColumnDefinitions>
175
+
176
+                <TextBlock Grid.Row="1"
177
+                           Grid.Column="2"
178
+                           TextAlignment="Right"
179
+                           Text="字体大小"/>
180
+                <ComboBox Name="TopFontSize" 
181
+                          Grid.Row="1"
182
+                          Grid.Column="4"
183
+                          Width="120"
184
+                          />
185
+                <TextBlock Grid.Row="1"
186
+                           Grid.Column="8"
187
+                           TextAlignment="Right"
188
+                           Text="字体格式" />
189
+                <TextBlock Grid.Row="3"
190
+                           Grid.Column="8"
191
+                           TextAlignment="Right"
192
+                           Text="是否加粗" />
193
+                <ComboBox Name="TopBold" 
194
+                          Grid.Row="3"
195
+                          Grid.Column="10"
196
+                          Width="119"
197
+                          />
198
+
199
+                <ComboBox Name="TopFontStyle" 
200
+                          Grid.Row="1"
201
+                          Grid.Column="10"
202
+                          Width="119"  />
203
+                <TextBlock Grid.Row="3"
204
+                           Grid.Column="2"
205
+                           TextAlignment="Right"
206
+                           Text="字体颜色"/>
207
+                <ComboBox Name="TopFontColor" 
208
+                          Grid.Row="3"
209
+                          Grid.Column="4"
210
+                          Width="119"
211
+                          />
212
+            </Grid>
213
+
214
+        </GroupBox>
215
+        <GroupBox Name="TableConGroup" Header="表内容字体样式设置" Width="540">
216
+            <Grid Width="520">
217
+                <Grid.RowDefinitions>
218
+                    <RowDefinition  Height="15"/>
219
+                    <RowDefinition Height="23"/>
220
+                    <RowDefinition Height="6"/>
221
+                    <RowDefinition Height="23"/>
222
+                    <RowDefinition Height="6"/>
223
+                    <RowDefinition Height="23"/>
224
+
225
+                </Grid.RowDefinitions>
226
+                <Grid.ColumnDefinitions>
227
+                    <ColumnDefinition Width="15" />
228
+                    <ColumnDefinition Width="6" />
229
+                    <ColumnDefinition Width="60"/>
230
+                    <ColumnDefinition Width="6" />
231
+                    <ColumnDefinition Width="120"/>
232
+                    <ColumnDefinition Width="6" />
233
+                    <ColumnDefinition Width="60"/>
234
+                    <ColumnDefinition Width="6" />
235
+                    <ColumnDefinition Width="60"/>
236
+                    <ColumnDefinition Width="6" />
237
+                    <ColumnDefinition Width="120"/>
238
+                    <ColumnDefinition Width="55*" />
239
+                </Grid.ColumnDefinitions>
240
+                <TextBlock 
241
+                    Grid.Row="1"
242
+                    Grid.Column="2"
243
+                    Text="开始行列值"
244
+                    TextAlignment="Right"
245
+                    />
246
+                <TextBlock 
247
+                    Grid.Row="1"
248
+                    Grid.Column="4"
249
+                    Text="行"
250
+                    TextAlignment="Right" Margin="2,0,102,0" />
251
+                <TextBox Name="StartRow" 
252
+                         Width="30"
253
+                         Height="23"
254
+                         Grid.Row="1"
255
+                         Grid.Column="4" Margin="24,0,0,0" />
256
+                <TextBlock 
257
+                    Grid.Row="1"
258
+                    Grid.Column="4"
259
+                    Text="列"
260
+                    TextAlignment="Right" Margin="67,0,37,0" />
261
+                <TextBox Name="StartCol" 
262
+                         Width="30"
263
+                         Grid.Row="1"
264
+                         Grid.Column="4" Margin="89,0,0,0" />
265
+                <TextBlock 
266
+                    Grid.Row="1"
267
+                    Grid.Column="8"
268
+                    TextAlignment="Right"
269
+                    Text="结束行列值"/>
270
+                <TextBlock 
271
+                    Grid.Row="1"
272
+                    Grid.Column="10"
273
+                    Text="行"
274
+                    TextAlignment="Right" Margin="2,0,102,0" />
275
+                <TextBox Name="EndRow" 
276
+                         Width="30"
277
+                         Grid.Row="1"
278
+                         Grid.Column="10" Margin="24,0,0,0" />
279
+                <TextBlock 
280
+                    Grid.Row="1"
281
+                    Grid.Column="10"
282
+                    Text="列"
283
+                    TextAlignment="Right" Margin="67,0,37,0" />
284
+                <TextBox Name="EndCol" 
285
+                         Width="30"
286
+                         Grid.Row="1"
287
+                         Grid.Column="10" Margin="89,0,0,0" />
288
+
289
+                <TextBlock Grid.Row="3"
290
+                           Grid.Column="2"
291
+                           TextAlignment="Right"
292
+                           Text="字体大小"/>
293
+                <ComboBox Name="ConFontSize" 
294
+                          Grid.Row="3"
295
+                          Grid.Column="4"
296
+                          Width="119"
297
+                          />
298
+                <TextBlock Grid.Row="3"
299
+                           Grid.Column="8"
300
+                           TextAlignment="Right"
301
+                           Text="字体格式" />
302
+
303
+                <ComboBox Name="ConFontStyle" 
304
+                          Grid.Row="3"
305
+                          Grid.Column="10"
306
+                          Width="119"  />
307
+                <TextBlock Grid.Row="5"
308
+                           Grid.Column="2"
309
+                           TextAlignment="Right"
310
+                           Text="字体颜色"/>
311
+                <ComboBox Name="ConFontColor" 
312
+                          Grid.Row="5"
313
+                          Grid.Column="4"
314
+                          Width="119"
315
+                          />
316
+                <TextBlock Grid.Row="5"
317
+                           Grid.Column="8"
318
+                           TextAlignment="Right"
319
+                           Text="是否加粗" />
320
+                <ComboBox Name="ConBold" 
321
+                          Grid.Row="5"
322
+                          Grid.Column="10"
323
+                          Width="120"
324
+                          />
325
+                <TextBox Name="Flag" Visibility="Hidden"/>
326
+
327
+            </Grid>
328
+        </GroupBox>
329
+        <Button Name="Bnt_Ok" Height="23" Content="确定" Click="Bnt_OkClick"/>
330
+    </StackPanel>
331
+</Window>

+ 106
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/Function/ExcelFunction/SelectFrm.xaml.cs 查看文件

@@ -0,0 +1,106 @@
1
+using System;
2
+using System.Collections;
3
+using System.Collections.Generic;
4
+using System.Diagnostics;
5
+using System.IO;
6
+using System.Linq;
7
+using System.Runtime.InteropServices;
8
+using System.Text;
9
+using System.Text.RegularExpressions;
10
+using System.Windows;
11
+using System.Windows.Controls;
12
+using System.Windows.Controls.Primitives;
13
+using System.Windows.Data;
14
+using System.Windows.Documents;
15
+using System.Windows.Input;
16
+using System.Windows.Media;
17
+using System.Windows.Media.Imaging;
18
+using System.Windows.Navigation;
19
+using System.Windows.Shapes;
20
+using System.Xml;
21
+using Platform.Common.LogSystem;
22
+using Platform.Common.RunningParameters;
23
+
24
+/******************************平台Dll*****************************/
25
+
26
+using Platform.Controls.ControlsHelper;
27
+using Platform.Library;
28
+using Platform.Presentation.FocusManagers;
29
+using Platform.Presentation.Interfaces;
30
+using Platform.Presentation.PageFunctions;
31
+using Platform.Print;
32
+using TellerSystem.Communication;
33
+using TellerSystem.Library.Ext.Function;
34
+using TellerSystem.Library.Ext.TradeExtension;
35
+using TellerSystem.Library.Ext.Variables;
36
+using TellerSystem.PrintTemplate;
37
+
38
+namespace TellerSystem.Library.Ext.Function.ExcelFunction
39
+{
40
+    /// <summary>
41
+    /// SelectFrm.xaml 的交互逻辑
42
+    /// </summary>
43
+    public partial class SelectFrm : Window
44
+    {
45
+        public SelectFrm()
46
+        {
47
+            InitializeComponent();
48
+            TitFontSize.SetItems(UserVariable.GetFontSize());
49
+            TitFontSize.SelectedIndex = 8;
50
+            TitFontStyle.SetItems(UserVariable.GetFontStyle());
51
+            TitFontColor.SetItems(UserVariable.GetFontColor());
52
+            TitBold.SetItems(UserVariable.GetFontBold());
53
+            TopFontSize.SetItems(UserVariable.GetFontSize());
54
+            TopFontSize.SelectedIndex = 4;
55
+            TopFontStyle.SetItems(UserVariable.GetFontStyle());
56
+            TopFontColor.SetItems(UserVariable.GetFontColor());
57
+            TopBold.SetItems(UserVariable.GetFontBold());
58
+            TopBold.SelectedIndex = 1;
59
+            ConFontSize.SetItems(UserVariable.GetFontSize());
60
+            ConFontSize.SelectedIndex = 4;
61
+            ConFontStyle.SetItems(UserVariable.GetFontStyle());
62
+            ConFontColor.SetItems(UserVariable.GetFontColor());
63
+            ConBold.SetItems(UserVariable.GetFontBold());
64
+            DataSave.SetItems(new Dictionary<string, string> { { "保存为单个sheet页", "0" }, { "依照分组保存为多个sheet页", "1" } });
65
+        }
66
+
67
+        private void Bnt_OkClick(object sender, RoutedEventArgs e)
68
+        {
69
+            if (StartRow.Text.GetStringToNum() == -1 || StartCol.Text.GetStringToNum() == -1 || EndRow.Text.GetStringToNum() == -1 || EndCol.Text.GetStringToNum() == -1)
70
+            {
71
+                MessageBox.Show("行列值输入只能输入数字");
72
+                StartRow.Text = "";
73
+                StartCol.Text = "";
74
+                EndRow.Text = "";
75
+                EndCol.Text = "";
76
+                Flag.Text = "-1";
77
+            }
78
+            else
79
+            {
80
+                Flag.Text = "1";
81
+                this.Close();
82
+            }
83
+        }
84
+
85
+        
86
+
87
+        private void DataSave_LostFocus(object sender, RoutedEventArgs e)
88
+        {
89
+            if (DataSave.GetSelectedValue() == "1")
90
+            {
91
+                TBlockSelect.Text = "分组列值";
92
+                if (SheetName.Text.GetStringToNum() == -1)
93
+                {
94
+                    MessageBox.Show("分组列值输入只能输入数字");
95
+                    SheetName.Text = "";
96
+                }
97
+            }
98
+            else
99
+            {
100
+                TBlockSelect.Text = "工作表名";
101
+            }
102
+
103
+        }
104
+
105
+    }
106
+}

+ 395
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/Function/SystemFunction.ts 查看文件

@@ -0,0 +1,395 @@
1
+// 由于没有确切的类型定义,我们先定义一些可能需要的类型
2
+import Message from "../../Communication/Message";
3
+import LoginUserInfo from "@/views/front/platfrom/common/RunningParameters/LoginUserInfo";
4
+import { IPage } from "@/views/front/platfrom/presentation/Interfaces/Ipage";
5
+import { TransitType } from "@/views/front/develop/Communication/MessageHelper/TransitType";
6
+// interface IPage {
7
+//     // 这里需要根据实际情况补充IPage接口的属性和方法
8
+//     OwnerContainer: any;
9
+//     CallServer(msg: Message): boolean;
10
+//     DoTransit(msg: Message, transitName?: string): boolean;
11
+//     GetTradeInfoData(): TradeInfoData;
12
+//     // 其他可能的方法
13
+// }
14
+
15
+// interface Message {
16
+//     BitMapType: any;
17
+//     Fd2: string;
18
+//     Fd3: string;
19
+//     Fd5: string;
20
+//     Fd6: string;
21
+//     Fd7: string;
22
+//     Fd10: string;
23
+//     Fd16: string;
24
+//     Fd17: string;
25
+//     Fd18: string;
26
+//     Fd30: string;
27
+//     Fd66: string;
28
+//     Fd74: string;
29
+//     Fd79: string;
30
+//     TransitNode: TransitType;
31
+//     TransitName: string;
32
+//     CustomizeTransitEntry: any;
33
+//     DoTransit(): boolean;
34
+//     Init(): void;
35
+//     InitGateway2CBS(txCode: string, serviceCode: string, svcSubCode: string, predicate2retCode: ((code: string) => boolean) | null): void;
36
+//     InitHfmsApp(url: string, predicate2retCode: ((code: string) => boolean) | null): void;
37
+//     FileData: string;
38
+//     // 其他可能的属性和方法
39
+// }
40
+
41
+// interface LoginUserInfo {
42
+//     KinbrNo: string;
43
+//     TradeDate: string;
44
+//     TellerNo: string;
45
+//     TtyName: string;
46
+//     // 其他可能的属性
47
+// }
48
+
49
+interface LoginAuthentication {
50
+    PaymentNo: string;
51
+}
52
+
53
+interface TradeInfoData {
54
+    LatestMessage: Message;
55
+    // 其他可能的属性
56
+}
57
+
58
+// enum TransitType {
59
+//     Unknown,
60
+//     CallServer,
61
+//     CallAgn,
62
+//     CallAgn_JWK,
63
+//     CallAgnCard,
64
+//     CallAgnIBPS,
65
+//     CallAgnIDC,
66
+//     CallAgnRun,
67
+//     CallAgnTips,
68
+//     CallAgnCnaps2,
69
+//     CallAgn_FGJWQ,
70
+//     CallGateway2CBS,
71
+//     CallHfmsApp,
72
+//     CallAgnCIS,
73
+//     CallAgn_EasyPay,
74
+//     CallAgn_Ebill,
75
+//     CallAgn_SDYCT,
76
+//     CallAgn_CZYYSW,
77
+//     CallAgn_GasFee,
78
+//     CallAgnCLFJG,
79
+//     CallAgn_NJT,
80
+//     CallNoFileSys,
81
+//     CallAgnNew_WL,
82
+//     CallAgn_FGJWQ_HH,
83
+//     CallAgn_DF,
84
+//     CallAgn_CW,
85
+//     CallAgn_ZJJG,
86
+//     CallAgn_CKXT,
87
+//     CallAgn_GGJ
88
+// }
89
+
90
+// 假设的全局变量
91
+// const LoginUserInfo: LoginUserInfo = {
92
+//     KinbrNo: "",
93
+//     TradeDate: "",
94
+//     TellerNo: "",
95
+//     TtyName: ""
96
+// };
97
+
98
+const LoginAuthentication = {
99
+    PaymentNo: ""
100
+};
101
+
102
+export default class SystemFunction {
103
+    static SubSwipeCardData(dataString: string): string {
104
+        // todo
105
+        return dataString;
106
+    }
107
+
108
+    static InitFd(target: IPage, message: Message): void {
109
+        message.Init(Message.BitMap);
110
+    }
111
+
112
+    static CommSend(target: IPage, message: Message): void {
113
+        message.Fd2 = LoginUserInfo.KinbrNo;
114
+        message.Fd3 = LoginUserInfo.KinbrNo;
115
+        message.Fd5 = LoginUserInfo.TradeDate;
116
+        message.Fd6 = new Date().toLocaleTimeString().replace(/:/g, '').substring(0, 6);
117
+        message.Fd7 = LoginUserInfo.TellerNo;
118
+        message.Fd10 = LoginUserInfo.TtyName;
119
+
120
+        switch (message.BitMapType) {
121
+            case Message.BitMap.Server:
122
+                //TODO:交易号
123
+                // UserFunction.CommSend96(target, message);
124
+                break;
125
+            case Message.BitMap.Agn:
126
+                break;
127
+            case Message.BitMap.Cnaps2:
128
+                message.Fd17 = LoginAuthentication.PaymentNo;
129
+                break;
130
+            default:
131
+                break;
132
+        }
133
+    }
134
+
135
+    static CommSend_Agn(target: IPage, message: Message): void {
136
+        message.Fd2 = LoginUserInfo.KinbrNo;
137
+        message.Fd3 = LoginUserInfo.KinbrNo;
138
+        message.Fd5 = LoginUserInfo.TradeDate;
139
+        message.Fd6 = new Date().toLocaleTimeString().replace(/:/g, '').substring(0, 6);
140
+        message.Fd7 = LoginUserInfo.TellerNo;
141
+        message.Fd10 = LoginUserInfo.TtyName;
142
+        message.Fd92 = LoginUserInfo.TellerNo;
143
+    }
144
+
145
+    static Registration(target: IPage, tellerNo: string): string {
146
+        let result = "";
147
+        if (tellerNo.trim() === "") return result;
148
+        const msg = new Message();
149
+        SystemFunction.CommSend(target, msg);
150
+        msg.Fd16 = "1827";
151
+        msg.Fd30 = tellerNo.trim();
152
+        // target.CallServer(msg);//hulei这里没有Callsever
153
+        if (msg.Fd66.trim() !== "0" && msg.Fd66.trim() !== "2") {
154
+            result = "";
155
+        }
156
+        return result = msg.Fd66;
157
+    }
158
+
159
+    static CheckTransit(message: Message): void {
160
+        switch (message.TransitNode) {
161
+            case TransitType.CallAgn:
162
+                if (message.Fd18 === "") {
163
+                    message.Fd18 = "ECI";
164
+                }
165
+                message.TransitNode = TransitType.CallAgn;
166
+                break;
167
+            case TransitType.CallAgn_JWK:
168
+                if (message.Fd18 === "") {
169
+                    message.Fd18 = "JWK";
170
+                }
171
+                message.TransitNode = TransitType.CallAgn_JWK;
172
+                break;
173
+            case TransitType.CallAgnCard:
174
+                message.Fd18 = "CBP";
175
+                message.TransitNode = TransitType.CallAgn;
176
+                break;
177
+            case TransitType.CallAgnIBPS:
178
+                message.Fd18 = "SNB";
179
+                message.TransitNode = TransitType.CallAgn;
180
+                break;
181
+            case TransitType.CallAgnIDC:
182
+                message.Fd18 = "C101";
183
+                message.Fd17 = LoginAuthentication.PaymentNo;
184
+                if (LoginUserInfo.KinbrNo.substring(0, 3) === "118") {
185
+                    message.Fd17 = "320465100015";
186
+                }
187
+                message.TransitNode = TransitType.CallAgnIDC;
188
+                break;
189
+            case TransitType.CallAgnRun:
190
+                message.Fd18 = "RUNB";
191
+                message.TransitNode = TransitType.CallAgn;
192
+                break;
193
+            case TransitType.CallAgnTips:
194
+                message.Fd18 = "TIBP";
195
+                message.TransitNode = TransitType.CallAgn;
196
+                break;
197
+            case TransitType.CallAgnCnaps2:
198
+                message.Fd18 = "CBS";
199
+                message.Fd17 = LoginAuthentication.PaymentNo;
200
+                message.TransitNode = TransitType.CallAgnCnaps2;
201
+                break;
202
+            case TransitType.CallAgn_FGJWQ:
203
+                message.Fd6 = new Date().toLocaleTimeString().replace(/:/g, '').substring(0, 6);
204
+                message.TransitNode = TransitType.CallAgn_FGJWQ;
205
+                break;
206
+            case TransitType.CallGateway2CBS:
207
+                if (message.CustomizeTransitEntry === null) {
208
+                    let txCode = message["__TxCode__"] as string;
209
+                    let serviceCode: string | null = null;
210
+                    let svcSubCode: string | null = null;
211
+                    const tmp = txCode.split('.');
212
+                    switch (tmp.length) {
213
+                        case 1:
214
+                            break;
215
+                        case 2:
216
+                            serviceCode = tmp[0];
217
+                            svcSubCode = "01";
218
+                            txCode = tmp[1];
219
+                            break;
220
+                        case 3:
221
+                            serviceCode = tmp[0];
222
+                            svcSubCode = tmp[1];
223
+                            txCode = tmp[2];
224
+                            break;
225
+                        default:
226
+                            throw new Error("未设置有效的交易码[__TxCode__]!" + txCode);
227
+                    }
228
+                    const retCodeRegex = message["__RetCodeRegex__"] as string;
229
+                    const predicate2retCode = retCodeRegex === "" ? null : (code: string) => new RegExp(retCodeRegex).test(code);
230
+                    message.InitGateway2CBS(txCode, serviceCode!, svcSubCode!, predicate2retCode);
231
+                }
232
+                break;
233
+            case TransitType.CallHfmsApp:
234
+                if (message.CustomizeTransitEntry === null) {
235
+                    const url = message["__TxCode__"] as string;
236
+                    const retCodeRegex = message["__RetCodeRegex__"] as string;
237
+                    const predicate2retCode = retCodeRegex === "" ? null : (code: string) => new RegExp(retCodeRegex).test(code);
238
+                    message.InitHfmsApp(url, predicate2retCode);
239
+                }
240
+                break;
241
+        }
242
+        // 兼容处理
243
+        try {
244
+            // 假设这里有获取_transitList的逻辑
245
+            const _transitList: string[] = [];
246
+            if (message.TransitName.startsWith("CallAgn") && !_transitList.includes(message.TransitName)) {
247
+                console.log(`CheckTransit:调整[${message.TransitName}]=>[CallAgn],fd16=[${message.Fd16}],fd18=[${message.Fd18}]`);
248
+                message.TransitNode = TransitType.CallAgn;
249
+            }
250
+        } catch (ex) {
251
+            console.error("CheckTransit:获取服务端配置信息报错!", ex);
252
+        }
253
+        try {
254
+            // 假设这里有获取服务端时间的逻辑
255
+            const serverTime = new Date().toLocaleTimeString().replace(/:/g, '').substring(0, 6);
256
+            message.Fd6 = serverTime;
257
+            // 假设LoginUserInfoExt有TradeTime属性
258
+            // LoginUserInfoExt.TradeTime = message.Fd6;
259
+        } catch (ex) {
260
+            console.error("CheckTransit:同步服务端时间信息报错!", ex);
261
+        }
262
+    }
263
+
264
+    static DoTransit(target: IPage, message: Message, transitName?: string): boolean {
265
+        //hulei 通讯逻辑需要改写不能按原有的处理
266
+        if (message === null) return false;
267
+        if (transitName !== undefined) message.TransitName = transitName;
268
+        SystemFunction.CheckTransit(message);
269
+        let returnValue = false;
270
+        const action = () => {
271
+            returnValue = message.DoTransit();
272
+        };
273
+        if (target.OwnerContainer !== null) {
274
+            // 假设这里有获取主页面的逻辑
275
+            const page = MainPageManager.GetMainPage() as IPage;//hulei创建页面
276
+            // if (page === null || !page.isAncestorOf(target)) {
277
+            //     page = target;
278
+            // }
279
+            // 假设这里有ModalInvoke的逻辑
280
+            // page.OwnerContainer.ModalInvoke(action, "网络通讯中,请稍后...");
281
+            //hulei
282
+        } else {
283
+            action();
284
+        }
285
+        // target.GetTradeInfoData().LatestMessage = message;
286
+        return returnValue;
287
+    }
288
+
289
+    static CallServer(target: IPage, message: Message): boolean {
290
+        return this.DoTransit(target, message, "TransitType.CallServer");//hulei 改为字符
291
+    }
292
+
293
+    static CallAgn(target: IPage, message: Message): boolean {
294
+        return this.DoTransit(target, message, "TransitType.CallAgn");
295
+    }
296
+
297
+    // 其他方法...
298
+
299
+    static Atoi(number: string): number {
300
+        if (number.trim() === "") {
301
+            number = "0";
302
+        }
303
+        return parseInt(number, 10);
304
+    }
305
+
306
+    static Itoa(number: number, format: string): string {
307
+        const rgx = /^%{1}(-)?(([0-9]*)[dD]{1})|(([0-9]*)(.)?([0-9]*)[fF]{1})$/;
308
+        if (!rgx.test(format)) {
309
+            throw new Error("不支持该格式转换!");
310
+        }
311
+
312
+        let outdata = "";
313
+        let width = -1;
314
+        let sindex = 0;
315
+        let eindex = 0;
316
+        let signindex = format.includes("-") ? format.indexOf("-") : -1;
317
+        let dotindex = -1;
318
+        let formatparse = format;
319
+        let hasZero = false;
320
+
321
+        if (signindex === -1) {
322
+            if (format.substring(1, 2) === "0") {
323
+                formatparse = format.substring(0, 1) + format.substring(2);
324
+                hasZero = true;
325
+            }
326
+        } else {
327
+            if (format.substring(2, 3) === "0") {
328
+                formatparse = format.substring(0, 2) + format.substring(3);
329
+                hasZero = true;
330
+            }
331
+        }
332
+
333
+        if (formatparse === "" || formatparse.includes("d") || formatparse.includes("D")) {
334
+            eindex = formatparse.includes("d") ? formatparse.indexOf("d") : formatparse.indexOf("D");
335
+            outdata = number.toFixed(0);
336
+        }
337
+
338
+        if (formatparse.includes("f") || formatparse.includes("F")) {
339
+            dotindex = formatparse.indexOf(".");
340
+            eindex = formatparse.includes("f") ? formatparse.indexOf("f") : formatparse.indexOf("F");
341
+
342
+            if (dotindex === -1) {
343
+                outdata = number.toFixed(0);
344
+            } else {
345
+                if (eindex - dotindex === 1) {
346
+                    outdata = number.toFixed(0);
347
+                } else {
348
+                    const precision = parseInt(formatparse.substring(dotindex + 1, eindex), 10);
349
+                    outdata = number.toFixed(precision);
350
+                }
351
+            }
352
+        }
353
+
354
+        if (dotindex === -1) {
355
+            if (signindex === -1) {
356
+                width = eindex - sindex === 1 ? -1 : parseInt(formatparse.substring(sindex + 1, eindex), 10);
357
+            } else {
358
+                width = eindex - signindex === 1 ? -1 : parseInt(formatparse.substring(signindex + 1, eindex), 10);
359
+            }
360
+        } else {
361
+            if (signindex === -1) {
362
+                width = dotindex - sindex === 1 ? -1 : parseInt(formatparse.substring(sindex + 1, dotindex), 10);
363
+            } else {
364
+                width = dotindex - signindex === 1 ? -1 : parseInt(formatparse.substring(signindex + 1, dotindex), 10);
365
+            }
366
+        }
367
+
368
+        if (width === -1) {
369
+            return outdata;
370
+        } else {
371
+            if (outdata.length >= width) {
372
+                return outdata;
373
+            } else {
374
+                if (signindex === -1) {
375
+                    if (hasZero) {
376
+                        return outdata.padStart(width, '0');
377
+                    } else {
378
+                        return outdata.padStart(width);
379
+                    }
380
+                } else {
381
+                    if (hasZero) {
382
+                        return outdata.padEnd(width, '0');
383
+                    } else {
384
+                        return outdata.padEnd(width);
385
+                    }
386
+                }
387
+            }
388
+        }
389
+    }
390
+
391
+    // 其他字符串数字处理方法...
392
+}
393
+
394
+export { SystemFunction };
395
+//hulei 这个文件还缺少很多方法 原文件由3328行后面缺的在补。

+ 1066
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/Function/TradePageExtension.ts
文件差異過大導致無法顯示
查看文件


+ 1117
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/Function/UserFunction.ts
文件差異過大導致無法顯示
查看文件


+ 36
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/NPOI/Abstract/NPOIExcel.cs 查看文件

@@ -0,0 +1,36 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Data;
6
+
7
+namespace TellerSystem.Library.Ext.NPOI
8
+{
9
+    /// <summary>
10
+    /// 抽象产品 excel
11
+    /// </summary>
12
+    public abstract class NPOIExcel
13
+    {
14
+        /// <summary>
15
+        /// 
16
+        /// </summary>
17
+        /// <param name="filePath"></param>
18
+        /// <param name="sheetIndex"></param>
19
+        /// <returns></returns>
20
+        abstract public DataTable ExcelToTable(string filePath, int sheetIndex = 0);
21
+
22
+        /// <summary>
23
+        /// 
24
+        /// </summary>
25
+        /// <param name="dt"></param>
26
+        /// <returns></returns>
27
+        abstract public byte[] DataTableToExcel(DataTable dt);
28
+
29
+        /// <summary>
30
+        /// 
31
+        /// </summary>
32
+        /// <param name="ds"></param>
33
+        /// <returns></returns>
34
+        abstract public byte[] DataSetToExcel(DataSet ds);
35
+    }
36
+}

+ 25
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/NPOI/Abstract/NPOIFactory.cs 查看文件

@@ -0,0 +1,25 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+
6
+namespace TellerSystem.Library.Ext.NPOI
7
+{
8
+    /// <summary>
9
+    /// 抽象工厂
10
+    /// </summary>
11
+    public abstract class NPOIFactory
12
+    {
13
+        /// <summary>
14
+        /// 
15
+        /// </summary>
16
+        /// <returns></returns>
17
+        abstract public NPOIExcel CreateExcel();
18
+
19
+        /// <summary>
20
+        /// 
21
+        /// </summary>
22
+        /// <returns></returns>
23
+        abstract public NPOIWord CreateWord();
24
+    }
25
+}

+ 14
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/NPOI/Abstract/NPOIWord.cs 查看文件

@@ -0,0 +1,14 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+
6
+namespace TellerSystem.Library.Ext.NPOI
7
+{
8
+    /// <summary>
9
+    /// 抽象产品 word
10
+    /// </summary>
11
+    public abstract class NPOIWord
12
+    {
13
+    }
14
+}

+ 33
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/NPOI/Factory/NPOIFactory_03.cs 查看文件

@@ -0,0 +1,33 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using TellerSystem.Library.Ext.NPOI;
6
+using TellerSystem.Library.Ext.NPOI.Product;
7
+
8
+namespace TellerSystem.Library.Ext.NPOI.Factory
9
+{
10
+    /// <summary>
11
+    /// 
12
+    /// </summary>
13
+    public class NPOIFactory_03 : NPOIFactory
14
+    {
15
+        /// <summary>
16
+        /// 
17
+        /// </summary>
18
+        /// <returns></returns>
19
+        public override NPOIExcel CreateExcel()
20
+        {
21
+            return new excel_03();
22
+        }
23
+
24
+        /// <summary>
25
+        /// 
26
+        /// </summary>
27
+        /// <returns></returns>
28
+        public override NPOIWord CreateWord()
29
+        {
30
+            return new word_03();
31
+        }
32
+    }
33
+}

+ 33
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/NPOI/Factory/NPOIFactory_07.cs 查看文件

@@ -0,0 +1,33 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using TellerSystem.Library.Ext.NPOI;
6
+using TellerSystem.Library.Ext.NPOI.Product;
7
+
8
+namespace TellerSystem.Library.Ext.NPOI.Factory
9
+{
10
+    /// <summary>
11
+    /// 
12
+    /// </summary>
13
+    public class NPOIFactory_07 : NPOIFactory
14
+    {
15
+        /// <summary>
16
+        /// 
17
+        /// </summary>
18
+        /// <returns></returns>
19
+        public override NPOIExcel CreateExcel()
20
+        {
21
+            return new excel_07();
22
+        }
23
+
24
+        /// <summary>
25
+        /// 
26
+        /// </summary>
27
+        /// <returns></returns>
28
+        public override NPOIWord CreateWord()
29
+        {
30
+            return new word_07();
31
+        }
32
+    }
33
+}

+ 21
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/NPOI/NPOIHelper.cs 查看文件

@@ -0,0 +1,21 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.IO;
6
+using TellerSystem.Library.Ext.NPOI.Factory;
7
+
8
+namespace TellerSystem.Library.Ext.NPOI
9
+{
10
+    public class NPOIHelper
11
+    {
12
+        public static NPOIFactory CreateFactory(string extension)
13
+        {
14
+            if (extension.ToLower() == "xls" || extension.ToLower() == "doc")
15
+                return new NPOIFactory_03();
16
+            else if (extension.ToLower() == "xlsx" || extension.ToLower() == "docx")
17
+                return new NPOIFactory_07();
18
+            else return null;
19
+        }
20
+    }
21
+}

+ 194
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/NPOI/Product/Excel/excel_03.cs 查看文件

@@ -0,0 +1,194 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using TellerSystem.Library.Ext.NPOI;
6
+using System.Data;
7
+using System.IO;
8
+using NPOI.HSSF.UserModel;
9
+using NPOI.SS.UserModel;
10
+
11
+namespace TellerSystem.Library.Ext.NPOI.Product
12
+{
13
+    /// <summary>
14
+    /// 
15
+    /// </summary>
16
+    public class excel_03 : NPOIExcel
17
+    {
18
+        /// <summary>
19
+        /// 将excel中的指定sheet页转换为datatable
20
+        /// </summary>
21
+        /// <param name="filePath"></param>
22
+        /// <param name="sheetIndex"></param>
23
+        /// <returns></returns>
24
+        public override DataTable ExcelToTable(string filePath, int sheetIndex = 0)
25
+        {
26
+            DataTable dt = new DataTable();
27
+            using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
28
+            {
29
+                HSSFWorkbook hssfworkbook = new HSSFWorkbook(fs);
30
+                ISheet sheet = hssfworkbook.GetSheetAt(sheetIndex);
31
+                //表头  
32
+                IRow header = sheet.GetRow(sheet.FirstRowNum);
33
+                foreach (var cell in header.Cells)
34
+                {
35
+                    if (string.IsNullOrWhiteSpace(cell.StringCellValue))
36
+                        break;
37
+                    dt.Columns.Add(new DataColumn(cell.StringCellValue));
38
+                }
39
+                //数据
40
+                for (int rowIndex = sheet.FirstRowNum + 1; rowIndex <= sheet.LastRowNum; rowIndex++)
41
+                {
42
+                    DataRow dr = dt.NewRow();
43
+                    IRow row = sheet.GetRow(rowIndex);
44
+                    if (row != null)
45
+                    {
46
+                        bool flag = false;
47
+                        for (int cellIndex = 0; cellIndex < dt.Columns.Count; cellIndex++)
48
+                        {
49
+                            if (row.GetCell(cellIndex) == null)
50
+                                continue;
51
+                            if (!string.IsNullOrEmpty(row.GetCell(cellIndex).ToString()))
52
+                                flag = true;
53
+                            dr[cellIndex] = getCellStringValueAllCase(row.GetCell(cellIndex));
54
+                        }
55
+                        if (flag)
56
+                            dt.Rows.Add(dr);
57
+                    }
58
+                }
59
+            }
60
+            return dt;
61
+        }
62
+        /// <summary>
63
+        /// 将DataTable转换成Excel中的sheet页,其中sheet页的名称为DataTable的名称
64
+        /// </summary>
65
+        /// <param name="dt"></param>
66
+        /// <returns></returns>
67
+        public override byte[] DataTableToExcel(DataTable dt)
68
+        {
69
+            HSSFWorkbook book = new HSSFWorkbook();
70
+            ISheet sheet = book.CreateSheet(string.IsNullOrEmpty(dt.TableName) ? "DataTable" : dt.TableName);
71
+            //第一行为列头
72
+            IRow row = sheet.CreateRow(0);
73
+            for (int i = 0; i < dt.Columns.Count; i++)
74
+            {
75
+                string caption = dt.Columns[i].Caption;
76
+                string colName = dt.Columns[i].ColumnName;
77
+                row.CreateCell(i).SetCellValue(string.IsNullOrWhiteSpace(caption) ? colName : caption);
78
+            }
79
+            for (int i = 0; i < dt.Rows.Count; i++)
80
+            {
81
+                IRow row2 = sheet.CreateRow(i + 1);
82
+                for (int j = 0; j < dt.Columns.Count; j++)
83
+                {
84
+                    row2.CreateCell(j).SetCellValue(Convert.ToString(dt.Rows[i][j]));
85
+                }
86
+            }
87
+            using (MemoryStream ms = new MemoryStream())
88
+            {
89
+                book.Write(ms);
90
+                return ms.ToArray();
91
+            }
92
+        }
93
+        /// <summary>
94
+        /// 将DataSet转换成Excel中的sheet页,其中sheet页的名称为对应的DataTable的名称
95
+        /// </summary>
96
+        /// <param name="ds"></param>
97
+        /// <returns></returns>
98
+        public override byte[] DataSetToExcel(DataSet ds)
99
+        {
100
+            HSSFWorkbook book = new HSSFWorkbook();
101
+            if (ds == null || ds.Tables.Count <= 0)
102
+            {
103
+                return null;
104
+            }
105
+            foreach (DataTable dt in ds.Tables)
106
+            {
107
+                ISheet sheet = book.CreateSheet(string.IsNullOrEmpty(dt.TableName) ? "DataTable" : dt.TableName);
108
+                //第一行为列头
109
+                IRow row = sheet.CreateRow(0);
110
+                for (int i = 0; i < dt.Columns.Count; i++)
111
+                {
112
+                    row.CreateCell(i).SetCellValue(dt.Columns[i].ColumnName);
113
+                }
114
+                for (int i = 0; i < dt.Rows.Count; i++)
115
+                {
116
+                    IRow row2 = sheet.CreateRow(i + 1);
117
+                    for (int j = 0; j < dt.Columns.Count; j++)
118
+                    {
119
+                        row2.CreateCell(j).SetCellValue(Convert.ToString(dt.Rows[i][j]));
120
+                    }
121
+                }
122
+            }
123
+            using (MemoryStream ms = new MemoryStream())
124
+            {
125
+                book.Write(ms);
126
+                return ms.ToArray();
127
+            }
128
+        }
129
+        /// <summary>
130
+        /// 将单元格的值转化为字符串
131
+        /// </summary>
132
+        /// <param name="tCell"></param>
133
+        /// <returns></returns>
134
+        private string getCellStringValueAllCase(ICell tCell)
135
+        {
136
+            string tempValue = "";
137
+            switch (tCell.CellType)
138
+            {
139
+                case CellType.Blank:
140
+                    break;
141
+                case CellType.Boolean:
142
+                    tempValue = tCell.BooleanCellValue.ToString();
143
+                    break;
144
+                case CellType.Error:
145
+                    break;
146
+                case CellType.Formula:
147
+                    IFormulaEvaluator fe = WorkbookFactory.CreateFormulaEvaluator(tCell.Sheet.Workbook);
148
+                    var cellValue = fe.Evaluate(tCell);
149
+                    switch (cellValue.CellType)
150
+                    {
151
+                        case CellType.Blank:
152
+                            break;
153
+                        case CellType.Boolean:
154
+                            tempValue = cellValue.BooleanValue.ToString();
155
+                            break;
156
+                        case CellType.Error:
157
+                            break;
158
+                        case CellType.Formula:
159
+                            break;
160
+                        case CellType.Numeric:
161
+                            tempValue = cellValue.NumberValue.ToString();
162
+                            break;
163
+                        case CellType.String:
164
+                            tempValue = cellValue.StringValue.ToString();
165
+                            break;
166
+                        case CellType.Unknown:
167
+                            break;
168
+                        default:
169
+                            break;
170
+                    }
171
+                    break;
172
+                case CellType.Numeric:
173
+
174
+                    if (DateUtil.IsCellDateFormatted(tCell))
175
+                    {
176
+                        tempValue = tCell.DateCellValue.ToString("yyyy-MM-dd");
177
+                    }
178
+                    else
179
+                    {
180
+                        tempValue = tCell.NumericCellValue.ToString();
181
+                    }
182
+                    break;
183
+                case CellType.String:
184
+                    tempValue = tCell.StringCellValue.Trim();
185
+                    break;
186
+                case CellType.Unknown:
187
+                    break;
188
+                default:
189
+                    break;
190
+            }
191
+            return tempValue;
192
+        }
193
+    }
194
+}

+ 192
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/NPOI/Product/Excel/excel_07.cs 查看文件

@@ -0,0 +1,192 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Data;
6
+using System.IO;
7
+using NPOI.XSSF.UserModel;
8
+using NPOI.SS.UserModel;
9
+
10
+namespace TellerSystem.Library.Ext.NPOI.Product
11
+{
12
+    /// <summary>
13
+    /// 
14
+    /// </summary>
15
+    public class excel_07 : NPOIExcel
16
+    {
17
+        /// <summary>
18
+        /// 将excel中的指定sheet页转换为datatable
19
+        /// </summary>
20
+        /// <param name="filePath"></param>
21
+        /// <param name="sheetIndex"></param>
22
+        /// <returns></returns>
23
+        public override System.Data.DataTable ExcelToTable(string filePath, int sheetIndex = 0)
24
+        {
25
+            DataTable dt = new DataTable();
26
+            using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
27
+            {
28
+                XSSFWorkbook hssfworkbook = new XSSFWorkbook(fs);
29
+                ISheet sheet = hssfworkbook.GetSheetAt(sheetIndex);
30
+                //表头  
31
+                IRow header = sheet.GetRow(sheet.FirstRowNum);
32
+                foreach (var cell in header.Cells)
33
+                {
34
+                    if (string.IsNullOrWhiteSpace(cell.StringCellValue))
35
+                        break;
36
+                    dt.Columns.Add(new DataColumn(cell.StringCellValue));
37
+                }
38
+                //数据
39
+                for (int rowIndex = sheet.FirstRowNum + 1; rowIndex <= sheet.LastRowNum; rowIndex++)
40
+                {
41
+                    DataRow dr = dt.NewRow();
42
+                    IRow row = sheet.GetRow(rowIndex);
43
+                    if (row != null)
44
+                    {
45
+                        bool flag = false;
46
+                        for (int cellIndex = 0; cellIndex < dt.Columns.Count; cellIndex++)
47
+                        {
48
+                            if (row.GetCell(cellIndex) == null)
49
+                                continue;
50
+                            if(!string.IsNullOrEmpty(row.GetCell(cellIndex).ToString()))
51
+                                flag = true;
52
+                            dr[cellIndex] = getCellStringValueAllCase(row.GetCell(cellIndex));
53
+                        }
54
+                        if(flag)
55
+                            dt.Rows.Add(dr);
56
+                    }
57
+                }
58
+            }
59
+            return dt;
60
+        }
61
+        /// <summary>
62
+        /// 将DataTable转换成Excel中的sheet页,其中sheet页的名称为DataTable的名称
63
+        /// </summary>
64
+        /// <param name="dt"></param>
65
+        /// <returns></returns>
66
+        public override byte[] DataTableToExcel(System.Data.DataTable dt)
67
+        {
68
+            XSSFWorkbook book = new XSSFWorkbook();
69
+            ISheet sheet = book.CreateSheet(string.IsNullOrEmpty(dt.TableName) ? "DataTable" : dt.TableName);
70
+            //第一行为列头
71
+            IRow row = sheet.CreateRow(0);
72
+            for (int i = 0; i < dt.Columns.Count; i++)
73
+            {
74
+                row.CreateCell(i).SetCellValue(dt.Columns[i].ColumnName);
75
+            }
76
+            for (int i = 0; i < dt.Rows.Count; i++)
77
+            {
78
+                IRow row2 = sheet.CreateRow(i + 1);
79
+                for (int j = 0; j < dt.Columns.Count; j++)
80
+                {
81
+                    row2.CreateCell(j).SetCellValue(Convert.ToString(dt.Rows[i][j]));
82
+                }
83
+            }
84
+            using (MemoryStream ms = new MemoryStream())
85
+            {
86
+                book.Write(ms);
87
+                return ms.ToArray();
88
+            }
89
+        }
90
+        /// <summary>
91
+        /// 将DataSet转换成Excel中的sheet页,其中sheet页的名称为对应的DataTable的名称
92
+        /// </summary>
93
+        /// <param name="ds"></param>
94
+        /// <returns></returns>
95
+        public override byte[] DataSetToExcel(System.Data.DataSet ds)
96
+        {
97
+            XSSFWorkbook book = new XSSFWorkbook();
98
+            if (ds == null || ds.Tables.Count <= 0)
99
+            {
100
+                return null;
101
+            }
102
+            foreach (DataTable dt in ds.Tables)
103
+            {
104
+                ISheet sheet = book.CreateSheet(string.IsNullOrEmpty(dt.TableName) ? "DataTable" : dt.TableName);
105
+                //第一行为列头
106
+                IRow row = sheet.CreateRow(0);
107
+                for (int i = 0; i < dt.Columns.Count; i++)
108
+                {
109
+                    row.CreateCell(i).SetCellValue(dt.Columns[i].ColumnName);
110
+                }
111
+                for (int i = 0; i < dt.Rows.Count; i++)
112
+                {
113
+                    IRow row2 = sheet.CreateRow(i + 1);
114
+                    for (int j = 0; j < dt.Columns.Count; j++)
115
+                    {
116
+                        row2.CreateCell(j).SetCellValue(Convert.ToString(dt.Rows[i][j]));
117
+                    }
118
+                }
119
+            }
120
+            using (MemoryStream ms = new MemoryStream())
121
+            {
122
+                book.Write(ms);
123
+                return ms.ToArray();
124
+            }
125
+        }
126
+
127
+        /// <summary>
128
+        /// 将单元格的值转化为字符串
129
+        /// </summary>
130
+        /// <param name="tCell"></param>
131
+        /// <returns></returns>
132
+        private string getCellStringValueAllCase(ICell tCell)
133
+        {
134
+            string tempValue = "";
135
+            switch (tCell.CellType)
136
+            {
137
+                case CellType.Blank:
138
+                    break;
139
+                case CellType.Boolean:
140
+                    tempValue = tCell.BooleanCellValue.ToString();
141
+                    break;
142
+                case CellType.Error:
143
+                    break;
144
+                case CellType.Formula:
145
+                    IFormulaEvaluator fe = WorkbookFactory.CreateFormulaEvaluator(tCell.Sheet.Workbook);
146
+                    var cellValue = fe.Evaluate(tCell);
147
+                    switch (cellValue.CellType)
148
+                    {
149
+                        case CellType.Blank:
150
+                            break;
151
+                        case CellType.Boolean:
152
+                            tempValue = cellValue.BooleanValue.ToString();
153
+                            break;
154
+                        case CellType.Error:
155
+                            break;
156
+                        case CellType.Formula:
157
+                            break;
158
+                        case CellType.Numeric:
159
+                            tempValue = cellValue.NumberValue.ToString();
160
+                            break;
161
+                        case CellType.String:
162
+                            tempValue = cellValue.StringValue.ToString();
163
+                            break;
164
+                        case CellType.Unknown:
165
+                            break;
166
+                        default:
167
+                            break;
168
+                    }
169
+                    break;
170
+                case CellType.Numeric:
171
+
172
+                    if (DateUtil.IsCellDateFormatted(tCell))
173
+                    {
174
+                        tempValue = tCell.DateCellValue.ToString("yyyy-MM-dd");
175
+                    }
176
+                    else
177
+                    {
178
+                        tempValue = tCell.NumericCellValue.ToString();
179
+                    }
180
+                    break;
181
+                case CellType.String:
182
+                    tempValue = tCell.StringCellValue.Trim();
183
+                    break;
184
+                case CellType.Unknown:
185
+                    break;
186
+                default:
187
+                    break;
188
+            }
189
+            return tempValue;
190
+        }
191
+    }
192
+}

+ 14
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/NPOI/Product/Word/word_03.cs 查看文件

@@ -0,0 +1,14 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+
6
+namespace TellerSystem.Library.Ext.NPOI.Product
7
+{
8
+    /// <summary>
9
+    /// 
10
+    /// </summary>
11
+    public class word_03 : NPOIWord
12
+    {
13
+    }
14
+}

+ 14
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/NPOI/Product/Word/word_07.cs 查看文件

@@ -0,0 +1,14 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+
6
+namespace TellerSystem.Library.Ext.NPOI.Product
7
+{
8
+    /// <summary>
9
+    /// 
10
+    /// </summary>
11
+    public class word_07 : NPOIWord
12
+    {
13
+    }
14
+}

+ 324
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/RuleInfoPSet.cs 查看文件

@@ -0,0 +1,324 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Collections.ObjectModel;
4
+using System.ComponentModel;
5
+using System.Linq;
6
+using System.Text;
7
+using System.Windows.Controls;
8
+using TellerSystem.ServiceProxy.Ext.Annotations;
9
+using TellerSystem.ServiceProxy.Ext.TradeBusinessEntitys;
10
+
11
+namespace TellerSystem.Library.Ext
12
+{
13
+    public class RuleInfoPSet : INotifyPropertyChanged
14
+    {
15
+        public RuleInfoPSet(string ruleId, string rulePId, string ruleNo, string ruleName, string ruleRemark, string ruleTypeCode, string ruleType, string extId, string ruleComment)
16
+        {
17
+            _ruleId = ruleId;
18
+            _rulePId = rulePId;
19
+            _ruleNo = ruleNo;
20
+            _ruleName = ruleName;
21
+            _ruleRemark = ruleRemark;
22
+            _ruleTypeCode = ruleTypeCode;
23
+            _ruleType = ruleType;
24
+            _extId = extId;
25
+            _ruleComment = ruleComment;
26
+        }
27
+        public RuleInfoPSet(string ruleId, string rulePId, string ruleNo, string ruleName, string ruleRemark, string ruleTypeCode, string ruleType, string extId, string ruleComment, List<TT_RuleInfo> list)
28
+        {
29
+            _ruleId = ruleId;
30
+            _rulePId = rulePId;
31
+            _ruleNo = ruleNo;
32
+            _ruleName = ruleName;
33
+            _ruleRemark = ruleRemark;
34
+            _ruleTypeCode = ruleTypeCode;
35
+            _ruleType = ruleType;
36
+            _extId = extId;
37
+            _ruleComment = ruleComment;
38
+
39
+            list.ForEach(drElement =>
40
+            {
41
+
42
+                if (drElement.RulePId == ruleId && drElement.RuleId != ruleId)
43
+                {
44
+                    this.Children.Add(new RuleInfoPSet(drElement.RuleId, drElement.RulePId, drElement.RuleNo, drElement.RuleName, drElement.RuleRemark, drElement.RuleTypeCode, drElement.RuleType, drElement.ExtId, drElement.RuleComment, list));
45
+                }
46
+
47
+            });
48
+
49
+        }
50
+        public RuleInfoPSet(string ruleId, string rulePId, string ruleNo, string ruleName, string ruleRemark, string ruleTypeCode, string ruleType, string extId, string ruleComment, List<TT_RuleInfo> list, List<TT_RuleInfo> powerlist)
51
+        {
52
+            _ruleId = ruleId;
53
+            _rulePId = rulePId;
54
+            _ruleNo = ruleNo;
55
+            _ruleName = ruleName;
56
+            _ruleRemark = ruleRemark;
57
+            _ruleTypeCode = ruleTypeCode;
58
+            _ruleType = ruleType;
59
+            _extId = extId;
60
+            _ruleComment = ruleComment;
61
+
62
+            list.ForEach(drElement =>
63
+            {
64
+
65
+                if (drElement.RulePId == ruleId && drElement.RuleId != ruleId)
66
+                {
67
+                    this.Children.Add(new RuleInfoPSet(drElement.RuleId, drElement.RulePId, drElement.RuleNo, drElement.RuleName, drElement.RuleRemark, drElement.RuleTypeCode, drElement.RuleType, drElement.ExtId, drElement.RuleComment, list, powerlist) { IsEnabled = false, IsChecked = powerlist.Any(x => x.RuleId == drElement.RuleId), Parent = this });
68
+                }
69
+
70
+            });
71
+
72
+        }
73
+        public RuleInfoPSet(string ruleId, string rulePId, string ruleNo, string ruleName, string ruleRemark, string ruleTypeCode, string ruleType, string extId, string ruleComment, List<TT_RuleInfo> list, List<TT_RuleInfo> powerlist, List<TT_RuleInfo> grouppowerdeleteentitys, List<TT_RuleInfo> grouppowerentitys)
74
+        {
75
+            _ruleId = ruleId;
76
+            _rulePId = rulePId;
77
+            _ruleNo = ruleNo;
78
+            _ruleName = ruleName;
79
+            _ruleRemark = ruleRemark;
80
+            _ruleTypeCode = ruleTypeCode;
81
+            _ruleType = ruleType;
82
+            _extId = extId;
83
+            _ruleComment = ruleComment;
84
+
85
+            list.ForEach(drElement =>
86
+            {
87
+
88
+                if (drElement.RulePId == ruleId && drElement.RuleId != ruleId)
89
+                {
90
+                    
91
+                    var ruleInfoPSet = new RuleInfoPSet(drElement.RuleId, drElement.RulePId, drElement.RuleNo, drElement.RuleName,
92
+                                                drElement.RuleRemark, drElement.RuleTypeCode, drElement.RuleType,
93
+                                                drElement.ExtId, drElement.RuleComment, list, powerlist, grouppowerdeleteentitys, grouppowerentitys)
94
+                    {
95
+                        IsEnabled = false,
96
+                        Parent = this
97
+                    };
98
+                    if (powerlist.Any(x => x.RuleId == drElement.RuleId)
99
+                           || (!(grouppowerdeleteentitys.Any(x => x.RuleId == drElement.RuleId))
100
+                              && grouppowerentitys.Any(x => x.RuleId == drElement.RuleId)))
101
+                    {
102
+                        ruleInfoPSet.IsChecked = true;
103
+                    }
104
+
105
+                    this.Children.Add(ruleInfoPSet);
106
+                }
107
+
108
+            });
109
+
110
+        }
111
+        private string _ruleId;
112
+        private string _rulePId;
113
+        private string _ruleNo;
114
+        private string _ruleName;
115
+        private string _ruleRemark;
116
+        private string _ruleTypeCode;
117
+        private string _ruleType;
118
+        private string _extId;
119
+        private string _ruleComment;
120
+        private bool? _ischecked = false;
121
+        private bool _isenable = false;
122
+        /// <summary>
123
+        /// 功能ID
124
+        /// </summary>
125
+        public string RuleId
126
+        {
127
+            get { return _ruleId; }
128
+            set
129
+            {
130
+                _ruleId = value;
131
+                OnPropertyChanged("RuleId");
132
+            }
133
+        }
134
+        /// <summary>
135
+        /// 上级功能ID
136
+        /// </summary>
137
+        public string RulePId
138
+        {
139
+            get { return _rulePId; }
140
+            set
141
+            {
142
+                _rulePId = value;
143
+                OnPropertyChanged("RulePId");
144
+            }
145
+        }
146
+        /// <summary>
147
+        /// 交易(功能)编号
148
+        /// </summary>
149
+        public string RuleNo
150
+        {
151
+            get { return _ruleNo; }
152
+            set
153
+            {
154
+                _ruleNo = value;
155
+                OnPropertyChanged("RuleNo");
156
+            }
157
+        }
158
+        /// <summary>
159
+        /// 功能名称
160
+        /// </summary>
161
+        public string RuleName
162
+        {
163
+            get { return _ruleName; }
164
+            set
165
+            {
166
+                _ruleName = value;
167
+                OnPropertyChanged("RuleName");
168
+            }
169
+        }
170
+        /// <summary>
171
+        /// 功能描述
172
+        /// </summary>
173
+        public string RuleRemark
174
+        {
175
+            get { return _ruleRemark; }
176
+            set
177
+            {
178
+                _ruleRemark = value;
179
+                OnPropertyChanged("RuleRemark");
180
+            }
181
+        }
182
+        /// <summary>
183
+        /// 功能类型号
184
+        /// </summary>
185
+        public string RuleTypeCode
186
+        {
187
+            get { return _ruleTypeCode; }
188
+            set
189
+            {
190
+                _ruleTypeCode = value;
191
+                OnPropertyChanged("RuleTypeCode");
192
+            }
193
+        }
194
+        /// <summary>
195
+        /// 功能类型
196
+        /// </summary>
197
+        public string RuleType
198
+        {
199
+            get { return _ruleType; }
200
+            set
201
+            {
202
+                _ruleType = value;
203
+                OnPropertyChanged("RuleType");
204
+            }
205
+        }
206
+        /// <summary>
207
+        /// 外接系统ID
208
+        /// </summary>
209
+        public string ExtId
210
+        {
211
+            get { return _extId; }
212
+            set
213
+            {
214
+                _extId = value;
215
+                OnPropertyChanged("ExtId");
216
+            }
217
+        }
218
+        /// <summary>
219
+        /// 备注
220
+        /// </summary>
221
+        public string RuleComment
222
+        {
223
+            get { return _ruleComment; }
224
+            set
225
+            {
226
+                _ruleComment = value;
227
+                OnPropertyChanged("RuleComment");
228
+            }
229
+        }
230
+
231
+        /// <summary>
232
+        /// 是否选中
233
+        /// </summary>
234
+        public bool? IsChecked
235
+        {
236
+            get { return _ischecked; }
237
+            set
238
+            {
239
+                _ischecked = value;
240
+                OnPropertyChanged("IsChecked");
241
+            }
242
+        }
243
+
244
+        /// <summary>
245
+        /// 是否可选
246
+        /// </summary>
247
+        public bool IsEnabled
248
+        {
249
+            get { return _isenable; }
250
+            set
251
+            {
252
+                _isenable = value;
253
+                OnPropertyChanged("IsEnabled");
254
+            }
255
+        }
256
+
257
+        private RuleInfoPSet _parent;
258
+        public RuleInfoPSet Parent
259
+        {
260
+            get { return _parent; }
261
+            set
262
+            {
263
+                _parent = value;
264
+                OnPropertyChanged("Parent");
265
+            }
266
+        }
267
+
268
+        private readonly ObservableCollection<RuleInfoPSet> _children = new ObservableCollection<RuleInfoPSet>();
269
+        public ObservableCollection<RuleInfoPSet> Children
270
+        {
271
+            get { return _children; }
272
+        }
273
+
274
+        public event PropertyChangedEventHandler PropertyChanged;
275
+
276
+        [NotifyPropertyChangedInvocator]
277
+        protected virtual void OnPropertyChanged(string propertyName)
278
+        {
279
+            PropertyChangedEventHandler handler = PropertyChanged;
280
+            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
281
+        }
282
+    }
283
+    //public class TreeViewListList : INotifyPropertyChanged
284
+    //{
285
+    //    public event PropertyChangedEventHandler PropertyChanged;
286
+
287
+    //    [NotifyPropertyChangedInvocator]
288
+    //    protected virtual void OnPropertyChanged(string propertyName)
289
+    //    {
290
+    //        PropertyChangedEventHandler handler = PropertyChanged;
291
+    //        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
292
+    //    }
293
+    //}
294
+    //public class TreeViewListList<T> : INotifyPropertyChanged
295
+    //{
296
+    //    private T _itemInfo;
297
+
298
+    //    public T ItemInfo
299
+    //    {
300
+    //        get { return _itemInfo; }
301
+    //        set
302
+    //        {
303
+    //            _itemInfo = value;
304
+    //            OnPropertyChanged("ItemInfo");
305
+    //        }
306
+    //    }
307
+
308
+    //    private ObservableCollection<T> _children;
309
+
310
+    //    public ObservableCollection<T> Children
311
+    //    {
312
+    //        get { return _children; }
313
+    //    }
314
+
315
+    //    public event PropertyChangedEventHandler PropertyChanged;
316
+
317
+    //    [NotifyPropertyChangedInvocator]
318
+    //    protected virtual void OnPropertyChanged(string propertyName)
319
+    //    {
320
+    //        PropertyChangedEventHandler handler = PropertyChanged;
321
+    //        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
322
+    //    }
323
+    //}
324
+}

+ 249
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/RuleInfoPSet.ts 查看文件

@@ -0,0 +1,249 @@
1
+// 引入必要的类型
2
+import { ObservableCollection } from 'some-observable-collection-library'; // 假设存在这个库用于模拟ObservableCollection
3
+
4
+// 假设TT_RuleInfo的定义
5
+interface TT_RuleInfo {
6
+    RuleId: string;
7
+    RulePId: string;
8
+    RuleNo: string;
9
+    RuleName: string;
10
+    RuleRemark: string;
11
+    RuleTypeCode: string;
12
+    RuleType: string;
13
+    ExtId: string;
14
+    RuleComment: string;
15
+}
16
+
17
+// 定义RuleInfoPSet类
18
+class RuleInfoPSet {
19
+    private _ruleId: string;
20
+    private _rulePId: string;
21
+    private _ruleNo: string;
22
+    private _ruleName: string;
23
+    private _ruleRemark: string;
24
+    private _ruleTypeCode: string;
25
+    private _ruleType: string;
26
+    private _extId: string;
27
+    private _ruleComment: string;
28
+    private _ischecked: boolean | null = false;
29
+    private _isenable: boolean = false;
30
+    private _parent: RuleInfoPSet | null = null;
31
+    private readonly _children: ObservableCollection<RuleInfoPSet> = new ObservableCollection<RuleInfoPSet>();
32
+
33
+    // 事件处理相关
34
+    private propertyChangedHandlers: ((propertyName: string) => void)[] = [];
35
+
36
+    constructor(
37
+        ruleId: string,
38
+        rulePId: string,
39
+        ruleNo: string,
40
+        ruleName: string,
41
+        ruleRemark: string,
42
+        ruleTypeCode: string,
43
+        ruleType: string,
44
+        extId: string,
45
+        ruleComment: string,
46
+        list?: TT_RuleInfo[],
47
+        powerlist?: TT_RuleInfo[],
48
+        grouppowerdeleteentitys?: TT_RuleInfo[],
49
+        grouppowerentitys?: TT_RuleInfo[]
50
+    ) {
51
+        this._ruleId = ruleId;
52
+        this._rulePId = rulePId;
53
+        this._ruleNo = ruleNo;
54
+        this._ruleName = ruleName;
55
+        this._ruleRemark = ruleRemark;
56
+        this._ruleTypeCode = ruleTypeCode;
57
+        this._ruleType = ruleType;
58
+        this._extId = extId;
59
+        this._ruleComment = ruleComment;
60
+
61
+        if (list) {
62
+            list.forEach((drElement) => {
63
+                if (drElement.RulePId === ruleId && drElement.RuleId!== ruleId) {
64
+                    let newRuleInfo: RuleInfoPSet;
65
+                    if (powerlist && grouppowerdeleteentitys && grouppowerentitys) {
66
+                        newRuleInfo = new RuleInfoPSet(
67
+                            drElement.RuleId,
68
+                            drElement.RulePId,
69
+                            drElement.RuleNo,
70
+                            drElement.RuleName,
71
+                            drElement.RuleRemark,
72
+                            drElement.RuleTypeCode,
73
+                            drElement.RuleType,
74
+                            drElement.ExtId,
75
+                            drElement.RuleComment,
76
+                            list,
77
+                            powerlist,
78
+                            grouppowerdeleteentitys,
79
+                            grouppowerentitys
80
+                        );
81
+                        newRuleInfo.IsEnabled = false;
82
+                        newRuleInfo.Parent = this;
83
+                        if (powerlist.some((x) => x.RuleId === drElement.RuleId) ||
84
+                            (!grouppowerdeleteentitys.some((x) => x.RuleId === drElement.RuleId) &&
85
+                                grouppowerentitys.some((x) => x.RuleId === drElement.RuleId))) {
86
+                            newRuleInfo.IsChecked = true;
87
+                        }
88
+                    } else if (powerlist) {
89
+                        newRuleInfo = new RuleInfoPSet(
90
+                            drElement.RuleId,
91
+                            drElement.RulePId,
92
+                            drElement.RuleNo,
93
+                            drElement.RuleName,
94
+                            drElement.RuleRemark,
95
+                            drElement.RuleTypeCode,
96
+                            drElement.RuleType,
97
+                            drElement.ExtId,
98
+                            drElement.RuleComment,
99
+                            list,
100
+                            powerlist
101
+                        );
102
+                        newRuleInfo.IsEnabled = false;
103
+                        newRuleInfo.IsChecked = powerlist.some((x) => x.RuleId === drElement.RuleId);
104
+                        newRuleInfo.Parent = this;
105
+                    } else {
106
+                        newRuleInfo = new RuleInfoPSet(
107
+                            drElement.RuleId,
108
+                            drElement.RulePId,
109
+                            drElement.RuleNo,
110
+                            drElement.RuleName,
111
+                            drElement.RuleRemark,
112
+                            drElement.RuleTypeCode,
113
+                            drElement.RuleType,
114
+                            drElement.ExtId,
115
+                            drElement.RuleComment,
116
+                            list
117
+                        );
118
+                    }
119
+                    this._children.add(newRuleInfo);
120
+                }
121
+            });
122
+        }
123
+    }
124
+
125
+    // 以下是属性的getter和setter
126
+    get RuleId(): string {
127
+        return this._ruleId;
128
+    }
129
+
130
+    set RuleId(value: string) {
131
+        this._ruleId = value;
132
+        this.onPropertyChanged('RuleId');
133
+    }
134
+
135
+    get RulePId(): string {
136
+        return this._rulePId;
137
+    }
138
+
139
+    set RulePId(value: string) {
140
+        this._rulePId = value;
141
+        this.onPropertyChanged('RulePId');
142
+    }
143
+
144
+    get RuleNo(): string {
145
+        return this._ruleNo;
146
+    }
147
+
148
+    set RuleNo(value: string) {
149
+        this._ruleNo = value;
150
+        this.onPropertyChanged('RuleNo');
151
+    }
152
+
153
+    get RuleName(): string {
154
+        return this._ruleName;
155
+    }
156
+
157
+    set RuleName(value: string) {
158
+        this._ruleName = value;
159
+        this.onPropertyChanged('RuleName');
160
+    }
161
+
162
+    get RuleRemark(): string {
163
+        return this._ruleRemark;
164
+    }
165
+
166
+    set RuleRemark(value: string) {
167
+        this._ruleRemark = value;
168
+        this.onPropertyChanged('RuleRemark');
169
+    }
170
+
171
+    get RuleTypeCode(): string {
172
+        return this._ruleTypeCode;
173
+    }
174
+
175
+    set RuleTypeCode(value: string) {
176
+        this._ruleTypeCode = value;
177
+        this.onPropertyChanged('RuleTypeCode');
178
+    }
179
+
180
+    get RuleType(): string {
181
+        return this._ruleType;
182
+    }
183
+
184
+    set RuleType(value: string) {
185
+        this._ruleType = value;
186
+        this.onPropertyChanged('RuleType');
187
+    }
188
+
189
+    get ExtId(): string {
190
+        return this._extId;
191
+    }
192
+
193
+    set ExtId(value: string) {
194
+        this._extId = value;
195
+        this.onPropertyChanged('ExtId');
196
+    }
197
+
198
+    get RuleComment(): string {
199
+        return this._ruleComment;
200
+    }
201
+
202
+    set RuleComment(value: string) {
203
+        this._ruleComment = value;
204
+        this.onPropertyChanged('RuleComment');
205
+    }
206
+
207
+    get IsChecked(): boolean | null {
208
+        return this._ischecked;
209
+    }
210
+
211
+    set IsChecked(value: boolean | null) {
212
+        this._ischecked = value;
213
+        this.onPropertyChanged('IsChecked');
214
+    }
215
+
216
+    get IsEnabled(): boolean {
217
+        return this._isenable;
218
+    }
219
+
220
+    set IsEnabled(value: boolean) {
221
+        this._isenable = value;
222
+        this.onPropertyChanged('IsEnabled');
223
+    }
224
+
225
+    get Parent(): RuleInfoPSet | null {
226
+        return this._parent;
227
+    }
228
+
229
+    set Parent(value: RuleInfoPSet | null) {
230
+        this._parent = value;
231
+        this.onPropertyChanged('Parent');
232
+    }
233
+
234
+    get Children(): ObservableCollection<RuleInfoPSet> {
235
+        return this._children;
236
+    }
237
+
238
+    // 事件触发方法
239
+    onPropertyChanged(propertyName: string): void {
240
+        this.propertyChangedHandlers.forEach((handler) => handler(propertyName));
241
+    }
242
+
243
+    // 模拟事件订阅方法
244
+    addPropertyChangedHandler(handler: (propertyName: string) => void): void {
245
+        this.propertyChangedHandlers.push(handler);
246
+    }
247
+}
248
+
249
+export { RuleInfoPSet };

+ 601
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/AICapacity.cs 查看文件

@@ -0,0 +1,601 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.IO;
6
+using System.Diagnostics;
7
+using Platform.Common.RunningParameters;
8
+using System.Windows.Media.Imaging;
9
+using System.Net;
10
+using Newtonsoft.Json;
11
+using System.Net.Cache;
12
+using Newtonsoft.Json.Linq;
13
+using TellerSystem.ServiceProxy.Ext.ServiceHelper;
14
+using TellerSystem.Library.Ext.Function;
15
+using Platform.Common.LogSystem;
16
+
17
+namespace TellerSystem.Library.Ext.TradeExtension
18
+{
19
+    public class AICapacity
20
+    {
21
+        private static AICapacity instence = null;
22
+        /// <summary>
23
+        /// token信息
24
+        /// </summary>
25
+        private string token;
26
+        /// <summary>
27
+        /// ip端口
28
+        /// </summary>
29
+        private string ipCom;
30
+        /// <summary>
31
+        /// 机构号前3位
32
+        /// </summary>
33
+        private string jgh;
34
+        /// <summary>
35
+        /// 生态平台用户名
36
+        /// </summary>
37
+        private string userCode;
38
+        /// <summary>
39
+        /// 生态平台密钥
40
+        /// </summary>
41
+        private string password;
42
+        /// <summary>
43
+        /// 生态平台对接柜面的系统名
44
+        /// </summary>
45
+        private string sysName;
46
+        /// <summary>
47
+        /// 人脸比对阈值
48
+        /// </summary>
49
+        private string rlbd_yz;
50
+        /// <summary>
51
+        /// 人脸比对开关
52
+        /// </summary>
53
+        private bool rlbz_isOpen;
54
+        /// <summary>
55
+        /// 上次获取时间
56
+        /// </summary>
57
+        private DateTime lastTime = DateTime.Now.AddMinutes(-10);
58
+        /// <summary>
59
+        /// 版本标志
60
+        /// </summary>
61
+        string flag = TradeManagerHandle.TT_SYSCONFIG_GetConfigValueByConfigID("2ea3a7e6cfa04f89a335bf1e363295de");
62
+        /// <summary>
63
+        /// 柜面参数配置表
64
+        /// </summary>
65
+        private List<ServiceProxy.Ext.TradeBusinessEntitys.TT_SysConfig> sysConfigList;
66
+        /// <summary>
67
+        /// 柜面参数是否可用
68
+        /// </summary>
69
+        private bool isEnble;
70
+        /// <summary>
71
+        /// 错误信息
72
+        /// </summary>
73
+        private string ErrMes;
74
+        private AICapacity()
75
+        {
76
+            sysConfigList = TradeManagerHandle.GetSysconfigList(null);
77
+            jgh = LoginUserInfo.KinbrNo.Substring(0, 3);
78
+            userCode = GetSysConfig("AI_用户名");
79
+            password = GetSysConfig("AI_密钥");
80
+            sysName = GetSysConfig("AI_系统名");
81
+            rlbz_isOpen = GetSysConfig("AI_人脸比对_开关").ToLower() == "true";
82
+            rlbd_yz = GetSysConfig("AI_人脸比对_阈值");
83
+            var list = GetSysConfig("AI_地址").Split('|');
84
+            ipCom = list.Length == 1 ? list[0] : list.FirstOrDefault(x =>
85
+            {
86
+                //检测网络连通性,使用获取token接口来测试
87
+                var request = System.Net.WebRequest.Create("http://" + x + "/core/auth/getVirtualToken");
88
+                try
89
+                {
90
+                    request.Timeout = 10000;//10s内无反应,视为无效
91
+                    request.GetResponse();
92
+                    return true;
93
+                }
94
+                catch (Exception ex)
95
+                {
96
+                    //返回非200的正常响应,也认为配置可用
97
+                    return (ex is WebException && (ex as WebException).Status == WebExceptionStatus.ProtocolError);
98
+                }
99
+                finally
100
+                {
101
+                    request.Abort();
102
+                }
103
+            });
104
+            isEnble = RLSB_isEnble();
105
+        }
106
+        /// <summary>
107
+        /// 人脸比对开关
108
+        /// </summary>
109
+        public bool IsOpen
110
+        {
111
+            get { return rlbz_isOpen; }
112
+        }
113
+
114
+        /// <summary>
115
+        /// 柜面人脸比对参数是否可用
116
+        /// </summary>
117
+        public bool IsEnble
118
+        {
119
+            get { return isEnble; }
120
+        }
121
+
122
+        /// <summary>
123
+        /// 获取柜面配置的参数值,优先取带机构号前三位的参数值
124
+        /// </summary>
125
+        /// <param name="key"></param>
126
+        /// <returns></returns>
127
+        private string GetSysConfig(string key)
128
+        {
129
+            string value = "";
130
+            //青隆做升级处理,加上机构号前三位
131
+            string key_ql = key + "_" + jgh;
132
+            if (sysConfigList.Exists(x => x.Configname == key_ql))
133
+            {
134
+                value = sysConfigList.Find(x => x.Configname == key_ql).Configvalue;
135
+            }
136
+            else if (sysConfigList.Exists(x => x.Configname == key))
137
+            {
138
+                value = sysConfigList.Find(x => x.Configname == key).Configvalue;
139
+            }
140
+            return value;
141
+        }
142
+        /// <summary>
143
+        /// 获取人脸比对结果
144
+        /// </summary>
145
+        /// <param name="img">身份核查照片信息</param>
146
+        /// <returns></returns>
147
+        public bool? GetResultFromRLBD(string img, out string result)
148
+        {
149
+            return GetResultFromRLBD(img, out result, null);
150
+        }
151
+
152
+        public bool? GetResultFromRLBD(string img, out string result, ExtData ext)
153
+        {
154
+            result = "人脸比对失败(未开启服务)!";
155
+            if (!rlbz_isOpen)
156
+                return null;
157
+            result = "柜面人脸比对参数配置错误!";
158
+            if (isEnble)
159
+            {
160
+                result = "人脸比对失败(联网核查的照片信息为空)!";
161
+                if (!string.IsNullOrEmpty(img))
162
+                {
163
+                    string img_GPY = AICapacity.GetInstence().getCusPhoto();
164
+                    result = "人脸比对失败(拍摄的照片信息为空)!";
165
+                    if (!string.IsNullOrEmpty(img_GPY))
166
+                    {
167
+                        var score = faceMach(img, img_GPY, ext);
168
+                        var f = score.ToDecimal() >= rlbd_yz.ToDecimal();
169
+                        if (string.IsNullOrEmpty(ErrMes))
170
+                            result = (f ? "通过" : "未通过") + "(" + score + ")!";
171
+                        else
172
+                            result = (f ? "通过" : "未通过") + "(" + score + ErrMes + ")!";
173
+                        //result = "人脸比对结果:" + (f ? "通过" : "未通过") + "(" + score + ")!";
174
+                        return f;
175
+                    }
176
+                }
177
+            }
178
+            return false;
179
+        }
180
+        /// <summary>
181
+        /// 判断人脸识别参数是否可用
182
+        /// </summary>
183
+        /// <returns></returns>
184
+        private bool RLSB_isEnble()
185
+        {
186
+            if (string.IsNullOrEmpty(userCode) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(sysName) || string.IsNullOrEmpty(rlbd_yz) || string.IsNullOrEmpty(ipCom))
187
+            {
188
+                return false;
189
+            }
190
+            return true;
191
+        }
192
+
193
+        /// <summary>
194
+        /// 获取客户拍照信息
195
+        /// </summary>
196
+        /// <returns></returns>
197
+        private string getCusPhoto()
198
+        {
199
+            var entity = Devices.DeviceHelper.Capture(Devices.Interface.CameraKind.Minor2Outside);
200
+            if (entity.HasError) return string.Empty;
201
+            byte[] ystp = null;
202
+            using (var ms = new MemoryStream(entity.Data))
203
+            {
204
+                BitmapImage bitmapImage = new BitmapImage();
205
+                bitmapImage.BeginInit();
206
+                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
207
+                bitmapImage.StreamSource = ms;
208
+                bitmapImage.EndInit();
209
+                bitmapImage.Freeze();
210
+                //压缩图片
211
+                ystp = SystemFunction.GetPhotoBytesForSize_QL(bitmapImage, 100, 150);
212
+            }
213
+            return ystp == null ? string.Empty : Convert.ToBase64String(ystp);
214
+        }
215
+
216
+        /// <summary>
217
+        /// AI调用通讯
218
+        /// </summary>
219
+        /// <param name="path">路径</param>
220
+        /// <param name="req">请求参数</param>
221
+        /// <param name="accessToken">token</param>
222
+        /// <returns></returns>
223
+        private string AIRequest(string path, string req, string accessToken, string method = "POST")
224
+        {
225
+            StringBuilder loginfo = new StringBuilder();
226
+            loginfo.AppendLine("通讯接口:" + path);
227
+            loginfo.AppendLine("操作柜员:" + LoginUserInfo.TellerNo);
228
+            loginfo.AppendLine("发生时间:" + DateTime.Now.ToString("HHmmss"));
229
+            loginfo.AppendLine("日志信息:通讯报文:" + req);
230
+            PlatformLogger.CommunicationInfo(loginfo.ToString());
231
+            //先根据用户请求的uri构造请求地址
232
+            string serviceUrl = "http://" + ipCom + path;
233
+            //创建Web访问对象
234
+            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(serviceUrl);
235
+            webRequest.ServicePoint.Expect100Continue = false;
236
+            //把用户传过来的数据转成“UTF-8”的字节流
237
+            byte[] buf = System.Text.Encoding.GetEncoding("UTF-8").GetBytes(req);
238
+            webRequest.Method = method;
239
+            webRequest.ContentLength = buf.Length;
240
+            webRequest.ContentType = "application/json";
241
+            webRequest.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
242
+            webRequest.Accept = "*/*";
243
+            if (!string.IsNullOrEmpty(accessToken))
244
+                webRequest.Headers.Add("Authorization", accessToken);
245
+            if (method == "POST")
246
+            {
247
+                //发送请求
248
+                Stream stream = webRequest.GetRequestStream();
249
+                stream.Write(buf, 0, buf.Length);
250
+                stream.Close();
251
+            }
252
+            //获取接口返回值
253
+            //通过Web访问对象获取响应内容
254
+            HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
255
+            //通过响应内容流创建StreamReader对象,因为StreamReader更高级更快
256
+            StreamReader reader = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8);
257
+            //string returnXml = HttpUtility.UrlDecode(reader.ReadToEnd());//如果有编码问题就用这个方法
258
+            string returnXml = reader.ReadToEnd();//利用StreamReader就可以从响应内容从头读到尾
259
+            reader.Close();
260
+            webResponse.Close();
261
+            loginfo = new StringBuilder();
262
+            loginfo.AppendLine("通讯接口:" + path);
263
+            loginfo.AppendLine("操作柜员:" + LoginUserInfo.TellerNo);
264
+            loginfo.AppendLine("发生时间:" + DateTime.Now.ToString("HHmmss"));
265
+            loginfo.AppendLine("日志信息:通讯响应:" + returnXml);
266
+            PlatformLogger.CommunicationInfo(loginfo.ToString());
267
+            return returnXml;
268
+        }
269
+
270
+        #region Simple Call
271
+        public abstract class Req
272
+        {
273
+            [JsonProperty("extData")]
274
+            public ExtData ExtData { get; set; }
275
+        }
276
+
277
+        public class ExtData
278
+        {
279
+            public ExtData(string serialNo, Dictionary<string, string> extInfo = null)
280
+            {
281
+                Branch = LoginUserInfo.KinbrNo;
282
+                Operator = LoginUserInfo.TellerNo;
283
+                SerialNo = serialNo;
284
+                ExtInfo = extInfo ?? new Dictionary<string, string> { };
285
+            }
286
+
287
+            [JsonProperty("branch")]
288
+            public string Branch { get; private set; }
289
+
290
+            [JsonProperty("operator")]
291
+            public string Operator { get; private set; }
292
+
293
+            [JsonProperty("serialNo")]
294
+            public string SerialNo { get; private set; }
295
+
296
+            [JsonProperty("extInfo")]
297
+            public Dictionary<string, string> ExtInfo { get; private set; }
298
+        }
299
+
300
+        public class Resp
301
+        {
302
+            private JObject root;
303
+
304
+            public Resp(string data)
305
+            {
306
+                HasError = true;
307
+                ErrorMsg = data;
308
+                try
309
+                {
310
+                    root = JsonConvert.DeserializeObject(data) as JObject;
311
+                    HasError = Value("errcode", -1) != 0;
312
+                    ErrorMsg = Value("errmsg", "未提取到有效信息");
313
+                }
314
+                catch { }
315
+            }
316
+
317
+            public bool HasError { get; internal set; }
318
+
319
+            public string ErrorMsg { get; internal set; }
320
+
321
+            /// <summary>
322
+            /// 提取要素
323
+            /// </summary>
324
+            /// <typeparam name="T"></typeparam>
325
+            /// <param name="path"></param>
326
+            /// <param name="def"></param>
327
+            /// <returns></returns>
328
+            public T Value<T>(string path, T def)
329
+            {
330
+                if (root == null) return def;
331
+                var ele = root.SelectToken(path);
332
+                if (ele == null) return def;
333
+                return ele.ToObject<T>();
334
+            }
335
+        }
336
+
337
+        /// <summary>
338
+        /// post请求
339
+        /// </summary>
340
+        /// <typeparam name="T"></typeparam>
341
+        /// <param name="path"></param>
342
+        /// <param name="req"></param>
343
+        /// <returns></returns>
344
+        public Resp AIRequest<T>(string path, T req)
345
+            where T : Req, new()
346
+        {
347
+            return AIRequest2Resp(path, JsonConvert.SerializeObject(req));
348
+        }
349
+
350
+        /// <summary>
351
+        /// get请求
352
+        /// </summary>
353
+        /// <param name="path"></param>
354
+        /// <param name="parms"></param>
355
+        /// <returns></returns>
356
+        public Resp AIRequest(string path, Dictionary<string, string> parms)
357
+        {
358
+            var p = "?" + string.Join("&", parms.Select(x => string.Format("{0}={1}", x.Key, x.Value)));
359
+            return AIRequest2Resp(path + p, string.Empty, "GET");
360
+        }
361
+
362
+        public Resp AIRequest2Resp(string path, string req, string method = "POST")
363
+        {
364
+            var accessToken = getTokenInfo();
365
+            if (string.IsNullOrEmpty(accessToken))
366
+                return new Resp("token获取失败!");
367
+            try
368
+            {
369
+                var data = AIRequest(path, req, accessToken, method);
370
+                return new Resp(data);
371
+            }
372
+            catch (Exception ex)
373
+            {
374
+                return new Resp("AI平台调用异常!" + ex.Message);
375
+            }
376
+        }
377
+
378
+        public class UniversalReq<T> : Req
379
+        {
380
+            [JsonProperty("buscode")]
381
+            public string BizCode { get; set; }
382
+
383
+            [JsonProperty("group")]
384
+            public string Group { get; set; }
385
+
386
+            [JsonProperty("data")]
387
+            public T Data { get; set; }
388
+        }
389
+
390
+        public Resp AIRequest2Universal<T>(string bizCode, T data, ExtData ext = null)
391
+        {
392
+            var req = new UniversalReq<T>
393
+            {
394
+                BizCode = bizCode,
395
+                Group = "real",
396
+                Data = data,
397
+                ExtData = ext,
398
+            };
399
+            return AIRequest("/tech/ai/celerity/universal", req);
400
+        }
401
+        #endregion
402
+
403
+        #region 文件服务
404
+        /// <summary>
405
+        /// 上传文件
406
+        /// </summary>
407
+        /// <param name="path">上传服务器地址</param>
408
+        /// <param name="filePath">文件路径</param>
409
+        /// <param name="fileName">文件名称</param>
410
+        /// <param name="accessToken"></param>
411
+        /// <returns></returns>
412
+        public Resp UploadFile(byte[] fileByte, string fileName, int days = 1)
413
+        {
414
+            var resp = new Resp("");
415
+            try
416
+            {
417
+                //先根据用户请求的uri构造请求地址
418
+                string serviceUrl = "http://" + ipCom + "/upload/";
419
+
420
+                StringBuilder loginfo = new StringBuilder();
421
+                loginfo.AppendLine("通讯接口:" + serviceUrl);
422
+                loginfo.AppendLine("操作柜员:" + LoginUserInfo.TellerNo);
423
+                loginfo.AppendLine("发生时间:" + DateTime.Now.ToString("HHmmss"));
424
+                loginfo.AppendLine("日志信息:通讯报文:上传文件名:" + fileName);
425
+                PlatformLogger.CommunicationInfo(loginfo.ToString());
426
+
427
+                //创建Web访问对象
428
+                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serviceUrl);
429
+                CookieContainer cookieContainer = new CookieContainer();
430
+                request.CookieContainer = cookieContainer;
431
+                request.AllowAutoRedirect = true;
432
+                request.MaximumResponseHeadersLength = 1024;
433
+                request.Method = "POST";
434
+                string boundary = DateTime.Now.Ticks.ToString("X"); // 随机分隔线
435
+                request.ContentType = "multipart/form-data;charset=utf-8;boundary=----WebKitFormBoundary" + boundary;
436
+                byte[] itemBoundaryBytes = Encoding.UTF8.GetBytes("\r\n------WebKitFormBoundary" + boundary + "\r\n");
437
+                byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n------WebKitFormBoundary" + boundary + "--\r\n");
438
+                //请求头部信息 
439
+                StringBuilder sbHeader = new StringBuilder(string.Format("Content-Disposition:form-data;name=\"file\";filename=\"{0}\"\r\nContent-Type:application/octet-stream\r\n\r\n", fileName, 2));
440
+                //请求头部信息 
441
+                StringBuilder sbbody = new StringBuilder(string.Format("Content-Disposition:form-data;name=\"saveDay\";\r\n\r\n"));
442
+                byte[] postHeaderBytes = Encoding.UTF8.GetBytes(sbHeader.ToString());
443
+                byte[] postbodyBytes = Encoding.UTF8.GetBytes(sbbody.ToString());
444
+                byte[] bodyBytes = Encoding.UTF8.GetBytes(days.ToString());
445
+                Stream postStream = request.GetRequestStream();
446
+                postStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length);
447
+                postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
448
+                postStream.Write(fileByte, 0, fileByte.Length);
449
+                postStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length);
450
+                postStream.Write(postbodyBytes, 0, postbodyBytes.Length);
451
+                postStream.Write(bodyBytes, 0, bodyBytes.Length);
452
+                postStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
453
+                postStream.Close();
454
+                HttpWebResponse res;
455
+
456
+                res = (HttpWebResponse)request.GetResponse();
457
+                StreamReader sr = new StreamReader(res.GetResponseStream(), Encoding.UTF8);
458
+                var content = sr.ReadToEnd();
459
+
460
+                loginfo = new StringBuilder();
461
+                loginfo.AppendLine("通讯接口:" + serviceUrl);
462
+                loginfo.AppendLine("操作柜员:" + LoginUserInfo.TellerNo);
463
+                loginfo.AppendLine("发生时间:" + DateTime.Now.ToString("HHmmss"));
464
+                loginfo.AppendLine("上传文件名:" + fileName);
465
+                loginfo.AppendLine("日志信息:通讯响应:" + content);
466
+                PlatformLogger.CommunicationInfo(loginfo.ToString());
467
+                return new Resp(content);
468
+            }
469
+            catch (Exception ex)
470
+            {
471
+                return new Resp(ex.ToString());
472
+            }
473
+        }
474
+        #endregion
475
+
476
+        /// <summary>
477
+        /// 获取人脸比对token信息
478
+        /// </summary>
479
+        /// <returns></returns>
480
+        private string getTokenInfo()
481
+        {
482
+            //token信息15分钟失效,暂控制在10分钟之内。
483
+            if (lastTime.AddMinutes(10) < DateTime.Now)
484
+            {
485
+                var path = "/core/auth/getVirtualToken";
486
+                TokenInfoReq data = new TokenInfoReq();
487
+                if (!RLSB_isEnble())
488
+                {
489
+                    return "";
490
+                }
491
+
492
+                //比较参数配置表里面的机构号
493
+                data.userCode = userCode;
494
+                data.password = password;
495
+                data.sysName = sysName;
496
+                string req = JsonConvert.SerializeObject(data);
497
+                var res = AIRequest(path, req, "");
498
+                JObject jo = (JObject)JsonConvert.DeserializeObject(res);
499
+                if (jo.GetValue("errcode").ToString() == "0")
500
+                {
501
+                    lastTime = DateTime.Now;
502
+                    token = jo.GetValue("data")["accessToken"].ToString();
503
+                }
504
+                else { return ""; }
505
+            }
506
+            return token;
507
+        }
508
+
509
+        /// <summary>
510
+        /// 人脸比对
511
+        /// </summary>
512
+        /// <param name="img_SFHC">身份核查照片</param>
513
+        /// <param name="img_GPY">高拍仪照片</param>
514
+        /// <returns></returns>
515
+        private string faceMach(string img_SFHC, string img_GPY, ExtData ext = null)
516
+        {
517
+            //传入数据
518
+            var data = new FaceMachReq()
519
+            {
520
+                Async = false,
521
+                LiveCode = "",
522
+                ExtData = ext ?? new ExtData(string.Empty),
523
+            };
524
+            var image = new TuPian()
525
+            {
526
+                Origin = "self",
527
+                Data = img_SFHC,
528
+            };
529
+            var faceData = new FaceData()
530
+            {
531
+                Type = "image",
532
+                VideoType = "SILENT",
533
+                Origin = "self",
534
+                Data = img_GPY,
535
+            };
536
+            data.image = new TuPian();
537
+            data.faceData = new FaceData();
538
+            data.image = image;
539
+            data.faceData = faceData;
540
+            var path = "/tech/ai/face/match";
541
+            string grade = "";
542
+            var resp = AIRequest(path, data);
543
+            ErrMes = resp.ErrorMsg;//默认
544
+            if (!resp.HasError)
545
+            {
546
+                grade = resp.Value("data.result.score", string.Empty);
547
+                ErrMes = "";
548
+            }
549
+            else if (resp.Value("errcode", -1) == 1715)
550
+            {
551
+                ErrMes = "人脸识别剩余次数不足,请充值";
552
+            }
553
+            return grade;
554
+        }
555
+
556
+        public static AICapacity GetInstence()
557
+        {
558
+            if (instence == null)
559
+            {
560
+                instence = new AICapacity();
561
+            }
562
+            return instence;
563
+        }
564
+    }
565
+    public class FaceMachReq : AICapacity.Req
566
+    {
567
+        [JsonProperty("async")]
568
+        public Boolean Async { get; set; }
569
+        [JsonProperty("liveCode")]
570
+        public string LiveCode { get; set; }
571
+        [JsonProperty("image")]
572
+        public TuPian image { get; set; }
573
+        [JsonProperty("faceData")]
574
+        public FaceData faceData { get; set; }
575
+    }
576
+    public class TuPian
577
+    {
578
+        [JsonProperty("origin")]
579
+        public string Origin { get; set; }
580
+        [JsonProperty("data")]
581
+        public string Data { get; set; }
582
+
583
+    }
584
+    public class FaceData
585
+    {
586
+        [JsonProperty("type")]
587
+        public string Type { get; set; }
588
+        [JsonProperty("videoType")]
589
+        public string VideoType { get; set; }
590
+        [JsonProperty("origin")]
591
+        public string Origin { get; set; }
592
+        [JsonProperty("data")]
593
+        public string Data { get; set; }
594
+    }
595
+    public class TokenInfoReq
596
+    {
597
+        public string sysName { get; set; }
598
+        public string userCode { get; set; }
599
+        public string password { get; set; }
600
+    }
601
+}

+ 414
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/AICapacity.ts 查看文件

@@ -0,0 +1,414 @@
1
+// 模拟依赖的类和命名空间
2
+class TradeManagerHandle {
3
+    static GetSysconfigList(_: any) {
4
+        return [];
5
+    }
6
+    static TT_SYSCONFIG_GetConfigValueByConfigID(id: string) {
7
+        return "";
8
+    }
9
+}
10
+
11
+class LoginUserInfo {
12
+    static get KinbrNo() {
13
+        return "";
14
+    }
15
+    static get TellerNo() {
16
+        return "";
17
+    }
18
+    static get TradeDate() {
19
+        return "";
20
+    }
21
+}
22
+
23
+class PlatformLogger {
24
+    static CommunicationInfo(info: string) {
25
+        console.log(info);
26
+    }
27
+}
28
+
29
+class Devices {
30
+    static DeviceHelper = {
31
+        Capture(cameraKind: any) {
32
+            return {
33
+                HasError: false,
34
+                Data: new Uint8Array()
35
+            };
36
+        }
37
+    };
38
+    static Interface = {
39
+        CameraKind: {
40
+            Minor2Outside: "Minor2Outside"
41
+        }
42
+    };
43
+}
44
+
45
+class SystemFunction {
46
+    static GetPhotoBytesForSize_QL(bitmapImage: any, width: number, height: number) {
47
+        return new Uint8Array();
48
+    }
49
+}
50
+
51
+// 定义 ExtData 类
52
+class ExtData {
53
+    Branch: string;
54
+    Operator: string;
55
+    SerialNo: string;
56
+    ExtInfo: { [key: string]: string };
57
+
58
+    constructor(serialNo: string, extInfo?: { [key: string]: string }) {
59
+        this.Branch = LoginUserInfo.KinbrNo;
60
+        this.Operator = LoginUserInfo.TellerNo;
61
+        this.SerialNo = serialNo;
62
+        this.ExtInfo = extInfo || {};
63
+    }
64
+}
65
+
66
+// 定义 Resp 类
67
+class Resp {
68
+    HasError: boolean;
69
+    ErrorMsg: string;
70
+    private root: any;
71
+
72
+    constructor(data: string) {
73
+        this.HasError = true;
74
+        this.ErrorMsg = data;
75
+        try {
76
+            this.root = JSON.parse(data);
77
+            this.HasError = this.Value("errcode", -1) !== 0;
78
+            this.ErrorMsg = this.Value("errmsg", "未提取到有效信息");
79
+        } catch (error) {
80
+            // 忽略解析错误
81
+        }
82
+    }
83
+
84
+    Value<T>(path: string, def: T): T {
85
+        if (!this.root) return def;
86
+        const parts = path.split('.');
87
+        let current = this.root;
88
+        for (const part of parts) {
89
+            if (!current[part]) return def;
90
+            current = current[part];
91
+        }
92
+        return current as T;
93
+    }
94
+}
95
+
96
+// 定义 FaceMachReq 类
97
+class FaceMachReq {
98
+    @JsonProperty("async")
99
+    Async: boolean;
100
+    @JsonProperty("liveCode")
101
+    LiveCode: string;
102
+    @JsonProperty("image")
103
+    image: TuPian;
104
+    @JsonProperty("faceData")
105
+    faceData: FaceData;
106
+    @JsonProperty("extData")
107
+    ExtData: ExtData;
108
+
109
+    constructor() {
110
+        this.Async = false;
111
+        this.LiveCode = "";
112
+        this.image = new TuPian();
113
+        this.faceData = new FaceData();
114
+        this.ExtData = new ExtData("");
115
+    }
116
+}
117
+
118
+// 定义 TuPian 类
119
+class TuPian {
120
+    @JsonProperty("origin")
121
+    Origin: string;
122
+    @JsonProperty("data")
123
+    Data: string;
124
+
125
+    constructor() {
126
+        this.Origin = "self";
127
+        this.Data = "";
128
+    }
129
+}
130
+
131
+// 定义 FaceData 类
132
+class FaceData {
133
+    @JsonProperty("type")
134
+    Type: string;
135
+    @JsonProperty("videoType")
136
+    VideoType: string;
137
+    @JsonProperty("origin")
138
+    Origin: string;
139
+    @JsonProperty("data")
140
+    Data: string;
141
+
142
+    constructor() {
143
+        this.Type = "image";
144
+        this.VideoType = "SILENT";
145
+        this.Origin = "self";
146
+        this.Data = "";
147
+    }
148
+}
149
+
150
+// 定义 TokenInfoReq 类
151
+class TokenInfoReq {
152
+    sysName: string;
153
+    userCode: string;
154
+    password: string;
155
+}
156
+
157
+// 定义 AICapacity 类
158
+class AICapacity {
159
+    private static instence: AICapacity | null = null;
160
+    private token: string = "";
161
+    private ipCom: string = "";
162
+    private jgh: string = "";
163
+    private userCode: string = "";
164
+    private password: string = "";
165
+    private sysName: string = "";
166
+    private rlbd_yz: string = "";
167
+    private rlbz_isOpen: boolean = false;
168
+    private lastTime: Date = new Date(Date.now() - 10 * 60 * 1000);
169
+    private flag: string = TradeManagerHandle.TT_SYSCONFIG_GetConfigValueByConfigID("2ea3a7e6cfa04f89a335bf1e363295de");
170
+    private sysConfigList: any[] = [];
171
+    private isEnble: boolean = false;
172
+    private ErrMes: string = "";
173
+
174
+    private constructor() {
175
+        this.sysConfigList = TradeManagerHandle.GetSysconfigList(null);
176
+        this.jgh = LoginUserInfo.KinbrNo.substring(0, 3);
177
+        this.userCode = this.GetSysConfig("AI_用户名");
178
+        this.password = this.GetSysConfig("AI_密钥");
179
+        this.sysName = this.GetSysConfig("AI_系统名");
180
+        this.rlbz_isOpen = this.GetSysConfig("AI_人脸比对_开关").toLowerCase() === "true";
181
+        this.rlbd_yz = this.GetSysConfig("AI_人脸比对_阈值");
182
+        const list = this.GetSysConfig("AI_地址").split('|');
183
+        this.ipCom = list.length === 1 ? list[0] : list.find(async (x) => {
184
+            try {
185
+                const response = await fetch(`http://${x}/core/auth/getVirtualToken`, {
186
+                    method: 'GET',
187
+                    timeout: 10000
188
+                });
189
+                return true;
190
+            } catch (error) {
191
+                return error instanceof TypeError && error.message.includes('NetworkError');
192
+            }
193
+        }) || "";
194
+        this.isEnble = this.RLSB_isEnble();
195
+    }
196
+
197
+    static GetInstence(): AICapacity {
198
+        if (!this.instence) {
199
+            this.instence = new AICapacity();
200
+        }
201
+        return this.instence;
202
+    }
203
+
204
+    get IsOpen(): boolean {
205
+        return this.rlbz_isOpen;
206
+    }
207
+
208
+    get IsEnble(): boolean {
209
+        return this.isEnble;
210
+    }
211
+
212
+    private GetSysConfig(key: string): string {
213
+        let value = "";
214
+        const key_ql = key + "_" + this.jgh;
215
+        const itemWithQl = this.sysConfigList.find(x => x.Configname === key_ql);
216
+        if (itemWithQl) {
217
+            value = itemWithQl.Configvalue;
218
+        } else {
219
+            const item = this.sysConfigList.find(x => x.Configname === key);
220
+            if (item) {
221
+                value = item.Configvalue;
222
+            }
223
+        }
224
+        return value;
225
+    }
226
+
227
+    GetResultFromRLBD(img: string, ext?: ExtData): { result: string; success?: boolean } {
228
+        let result = "人脸比对失败(未开启服务)!";
229
+        if (!this.rlbz_isOpen) {
230
+            return { result };
231
+        }
232
+        result = "柜面人脸比对参数配置错误!";
233
+        if (this.isEnble) {
234
+            result = "人脸比对失败(联网核查的照片信息为空)!";
235
+            if (img) {
236
+                const img_GPY = this.getCusPhoto();
237
+                result = "人脸比对失败(拍摄的照片信息为空)!";
238
+                if (img_GPY) {
239
+                    const score = this.faceMach(img, img_GPY, ext);
240
+                    const f = parseFloat(score) >= parseFloat(this.rlbd_yz);
241
+                    if (!this.ErrMes) {
242
+                        result = (f ? "通过" : "未通过") + `(${score})!`;
243
+                    } else {
244
+                        result = (f ? "通过" : "未通过") + `(${score}${this.ErrMes})!`;
245
+                    }
246
+                    return { result, success: f };
247
+                }
248
+            }
249
+        }
250
+        return { result, success: false };
251
+    }
252
+
253
+    private RLSB_isEnble(): boolean {
254
+        return !!this.userCode && !!this.password && !!this.sysName && !!this.rlbd_yz && !!this.ipCom;
255
+    }
256
+
257
+    private getCusPhoto(): string {
258
+        const entity = Devices.DeviceHelper.Capture(Devices.Interface.CameraKind.Minor2Outside);
259
+        if (entity.HasError) return "";
260
+        let ystp: Uint8Array | null = null;
261
+        const blob = new Blob([entity.Data], { type: 'image/jpeg' });
262
+        const bitmapImage = URL.createObjectURL(blob);
263
+        ystp = SystemFunction.GetPhotoBytesForSize_QL(bitmapImage, 100, 150);
264
+        return ystp ? btoa(String.fromCharCode.apply(null, Array.from(ystp))) : "";
265
+    }
266
+
267
+    private async AIRequest(path: string, req: string, accessToken: string, method: string = "POST"): Promise<string> {
268
+        const loginfo = [];
269
+        loginfo.push(`通讯接口:${path}`);
270
+        loginfo.push(`操作柜员:${LoginUserInfo.TellerNo}`);
271
+        loginfo.push(`发生时间:${new Date().toLocaleTimeString().replace(/:/g, '')}`);
272
+        loginfo.push(`日志信息:通讯报文:${req}`);
273
+        PlatformLogger.CommunicationInfo(loginfo.join('\n'));
274
+
275
+        const serviceUrl = `http://${this.ipCom}${path}`;
276
+        const headers: { [key: string]: string } = {
277
+            'Content-Type': 'application/json',
278
+            'Accept': '*/*'
279
+        };
280
+        if (accessToken) {
281
+            headers['Authorization'] = accessToken;
282
+        }
283
+
284
+        const response = await fetch(serviceUrl, {
285
+            method,
286
+            headers,
287
+            body: method === "POST" ? req : undefined
288
+        });
289
+
290
+        const returnXml = await response.text();
291
+
292
+        const loginfoAfter = [];
293
+        loginfoAfter.push(`通讯接口:${path}`);
294
+        loginfoAfter.push(`操作柜员:${LoginUserInfo.TellerNo}`);
295
+        loginfoAfter.push(`发生时间:${new Date().toLocaleTimeString().replace(/:/g, '')}`);
296
+        loginfoAfter.push(`日志信息:通讯响应:${returnXml}`);
297
+        PlatformLogger.CommunicationInfo(loginfoAfter.join('\n'));
298
+
299
+        return returnXml;
300
+    }
301
+
302
+    private async getTokenInfo(): Promise<string> {
303
+        if (new Date(this.lastTime.getTime() + 10 * 60 * 1000) < new Date()) {
304
+            const path = "/core/auth/getVirtualToken";
305
+            const data = new TokenInfoReq();
306
+            if (!this.RLSB_isEnble()) {
307
+                return "";
308
+            }
309
+            data.userCode = this.userCode;
310
+            data.password = this.password;
311
+            data.sysName = this.sysName;
312
+            const req = JSON.stringify(data);
313
+            const res = await this.AIRequest(path, req, "");
314
+            try {
315
+                const jo = JSON.parse(res);
316
+                if (jo.errcode.toString() === "0") {
317
+                    this.lastTime = new Date();
318
+                    this.token = jo.data.accessToken;
319
+                } else {
320
+                    return "";
321
+                }
322
+            } catch (error) {
323
+                return "";
324
+            }
325
+        }
326
+        return this.token;
327
+    }
328
+
329
+    private async faceMach(img_SFHC: string, img_GPY: string, ext?: ExtData): Promise<string> {
330
+        const data = new FaceMachReq();
331
+        data.Async = false;
332
+        data.LiveCode = "";
333
+        data.ExtData = ext || new ExtData("");
334
+        const image = new TuPian();
335
+        image.Origin = "self";
336
+        image.Data = img_SFHC;
337
+        const faceData = new FaceData();
338
+        faceData.Type = "image";
339
+        faceData.VideoType = "SILENT";
340
+        faceData.Origin = "self";
341
+        faceData.Data = img_GPY;
342
+        data.image = image;
343
+        data.faceData = faceData;
344
+        const path = "/tech/ai/face/match";
345
+        let grade = "";
346
+        const resp = await this.AIRequest2Resp(path, JSON.stringify(data));
347
+        this.ErrMes = resp.ErrorMsg;
348
+        if (!resp.HasError) {
349
+            grade = resp.Value("data.result.score", "");
350
+            this.ErrMes = "";
351
+        } else if (resp.Value("errcode", -1) === 1715) {
352
+            this.ErrMes = "人脸识别剩余次数不足,请充值";
353
+        }
354
+        return grade;
355
+    }
356
+
357
+    async AIRequest2Resp(path: string, req: string, method: string = "POST"): Promise<Resp> {
358
+        const accessToken = await this.getTokenInfo();
359
+        if (!accessToken) {
360
+            return new Resp("token获取失败!");
361
+        }
362
+        try {
363
+            const data = await this.AIRequest(path, req, accessToken, method);
364
+            return new Resp(data);
365
+        } catch (error) {
366
+            return new Resp(`AI平台调用异常!${error.message}`);
367
+        }
368
+    }
369
+
370
+    async UploadFile(fileByte: Uint8Array, fileName: string, days: number = 1): Promise<Resp> {
371
+        try {
372
+            const serviceUrl = `http://${this.ipCom}/upload/`;
373
+            const loginfo = [];
374
+            loginfo.push(`通讯接口:${serviceUrl}`);
375
+            loginfo.push(`操作柜员:${LoginUserInfo.TellerNo}`);
376
+            loginfo.push(`发生时间:${new Date().toLocaleTimeString().replace(/:/g, '')}`);
377
+            loginfo.push(`日志信息:通讯报文:上传文件名:${fileName}`);
378
+            PlatformLogger.CommunicationInfo(loginfo.join('\n'));
379
+
380
+            const formData = new FormData();
381
+            const blob = new Blob([fileByte], { type: 'application/octet-stream' });
382
+            formData.append('file', blob, fileName);
383
+            formData.append('saveDay', days.toString());
384
+
385
+            const response = await fetch(serviceUrl, {
386
+                method: 'POST',
387
+                body: formData
388
+            });
389
+
390
+            const content = await response.text();
391
+
392
+            const loginfoAfter = [];
393
+            loginfoAfter.push(`通讯接口:${serviceUrl}`);
394
+            loginfoAfter.push(`操作柜员:${LoginUserInfo.TellerNo}`);
395
+            loginfoAfter.push(`发生时间:${new Date().toLocaleTimeString().replace(/:/g, '')}`);
396
+            loginfoAfter.push(`上传文件名:${fileName}`);
397
+            loginfoAfter.push(`日志信息:通讯响应:${content}`);
398
+            PlatformLogger.CommunicationInfo(loginfoAfter.join('\n'));
399
+
400
+            return new Resp(content);
401
+        } catch (error) {
402
+            return new Resp(error.toString());
403
+        }
404
+    }
405
+}
406
+
407
+// 模拟 JsonProperty 装饰器
408
+function JsonProperty(name: string) {
409
+    return function (target: any, propertyKey: string) {
410
+        // 这里可以实现更多逻辑,当前仅作标记
411
+    };
412
+}
413
+
414
+export { AICapacity };

+ 1009
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/AnalyzeFile.cs
文件差異過大導致無法顯示
查看文件


+ 178
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/AnalyzeFile.ts 查看文件

@@ -0,0 +1,178 @@
1
+// 模拟 DataTable 和 DataSet
2
+class DataTable {
3
+    columns: string[] = [];
4
+    rows: any[][] = [];
5
+    tableName: string = "";
6
+
7
+    addColumn(columnName: string) {
8
+        this.columns.push(columnName);
9
+    }
10
+
11
+    addRow(rowData: any[]) {
12
+        this.rows.push(rowData);
13
+    }
14
+
15
+    deleteRow(index: number) {
16
+        this.rows.splice(index, 1);
17
+    }
18
+
19
+    acceptChanges() {
20
+        // 模拟接受更改
21
+    }
22
+}
23
+
24
+class DataSet {
25
+    tables: DataTable[] = [];
26
+}
27
+
28
+// 模拟文件选择对话框
29
+function openFileDialog(filter: string): string | null {
30
+    // 这里需要实现文件选择逻辑,返回文件路径
31
+    return null;
32
+}
33
+
34
+// 模拟文件读取
35
+async function readFile(path: string, encoding: string): Promise<string> {
36
+    // 这里需要实现文件读取逻辑,返回文件内容
37
+    return "";
38
+}
39
+
40
+// 模拟 Excel 连接和查询
41
+async function queryExcel(connString: string, sql: string): Promise<DataSet> {
42
+    // 这里需要实现 Excel 连接和查询逻辑,返回 DataSet
43
+    return new DataSet();
44
+}
45
+
46
+class AnalyzeFile {
47
+    private path: string = "";
48
+    private listSheet: string[] = [];
49
+    private static excelVerson: string = "";
50
+    private txt_EnCode: string = "";
51
+    private txt_LineSplit: string[] = [];
52
+    private txt_ColSplit: string = "";
53
+    private m_OpenFlag: boolean = false;
54
+
55
+    public async AnalyzeTxtData(txt_RowSplit: string[], txt_ColumnSlit: string, txt_EnCode: string, isColumnHeader: boolean = true): Promise<DataTable | null> {
56
+        if (!txt_RowSplit || txt_RowSplit.length === 0 || !txt_ColumnSlit || !txt_EnCode) {
57
+            return null;
58
+        }
59
+
60
+        this.path = openFileDialog("txt Files|*.txt") || "";
61
+        if (!this.path) {
62
+            return null;
63
+        }
64
+
65
+        const content = await readFile(this.path, txt_EnCode);
66
+        const lines = content.split(txt_RowSplit.join(''));
67
+        const dataTable = new DataTable();
68
+
69
+        if (isColumnHeader && lines.length > 0) {
70
+            const headers = lines[0].split(txt_ColumnSlit);
71
+            headers.forEach(header => dataTable.addColumn(header.trim()));
72
+            lines.shift();
73
+        } else if (lines.length > 0) {
74
+            const firstLineColumns = lines[0].split(txt_ColumnSlit);
75
+            for (let i = 0; i < firstLineColumns.length; i++) {
76
+                dataTable.addColumn(`col${i}`);
77
+            }
78
+        }
79
+
80
+        lines.forEach(line => {
81
+            const columns = line.split(txt_ColumnSlit);
82
+            dataTable.addRow(columns);
83
+        });
84
+
85
+        return dataTable;
86
+    }
87
+
88
+    public async AnalyzeTxtDataMulti(multiSelect: boolean, txt_RowSplit: string[], txt_ColumnSlit: string, txt_EnCode: string, isColumnHeader: boolean = true): Promise<DataTable[] | null> {
89
+        if (!txt_RowSplit || txt_RowSplit.length === 0 || !txt_EnCode) {
90
+            return null;
91
+        }
92
+
93
+        // 模拟多选文件选择,这里简化处理
94
+        const paths: string[] = [];
95
+        if (multiSelect) {
96
+            // 实现多选逻辑
97
+        } else {
98
+            const path = openFileDialog("txt Files|*.txt");
99
+            if (path) {
100
+                paths.push(path);
101
+            }
102
+        }
103
+
104
+        const tableList: DataTable[] = [];
105
+        for (const path of paths) {
106
+            this.path = path;
107
+            const table = await this.AnalyzeTxtData(txt_RowSplit, txt_ColumnSlit, txt_EnCode, isColumnHeader);
108
+            if (table) {
109
+                table.tableName = path.split('\\').pop() || "";
110
+                tableList.push(table);
111
+            }
112
+        }
113
+
114
+        return tableList;
115
+    }
116
+
117
+    public async AnalyseExcelData(RowCount: number = 0, columnCount: number = 0): Promise<DataTable | null> {
118
+        this.path = openFileDialog("Excel Files|*.xlsx;*.xls;") || "";
119
+        if (!this.path) {
120
+            return null;
121
+        }
122
+
123
+        // 模拟检查 Excel 版本
124
+        AnalyzeFile.excelVerson = "12.0";
125
+        this.listSheet = ["Sheet1"];
126
+
127
+        const connString = this.ExcelConnString(AnalyzeFile.excelVerson, this.path);
128
+        const sql = `SELECT * FROM [${this.listSheet[0]}$]`;
129
+        const dataSet = await queryExcel(connString, sql);
130
+        const dataTable = dataSet.tables[0];
131
+        dataTable.tableName = this.path.split('\\').pop() || "";
132
+
133
+        if (RowCount > 0 && columnCount > 0) {
134
+            const newTable = new DataTable();
135
+            newTable.tableName = dataTable.tableName;
136
+            for (let i = 0; i < columnCount; i++) {
137
+                newTable.addColumn(dataTable.columns[i]);
138
+            }
139
+            for (let i = 0; i < RowCount; i++) {
140
+                const newRow: any[] = [];
141
+                for (let j = 0; j < columnCount; j++) {
142
+                    newRow.push(dataTable.rows[i][j]);
143
+                }
144
+                newTable.addRow(newRow);
145
+            }
146
+            return newTable;
147
+        }
148
+
149
+        // 删除空行
150
+        for (let i = dataTable.rows.length - 1; i >= 0; i--) {
151
+            const row = dataTable.rows[i];
152
+            let isEmpty = true;
153
+            for (let j = 0; j < row.length; j++) {
154
+                if (row[j] && row[j].toString().trim() !== "") {
155
+                    isEmpty = false;
156
+                    row[j] = row[j].toString().replace(/ /g, "").replace(/ /g, "");
157
+                }
158
+            }
159
+            if (isEmpty) {
160
+                dataTable.deleteRow(i);
161
+            }
162
+        }
163
+        dataTable.acceptChanges();
164
+
165
+        return dataTable;
166
+    }
167
+
168
+    private ExcelConnString(excelVerson: string, filePath: string): string {
169
+        if (excelVerson === "8.0") {
170
+            return `Provider=Microsoft.Jet.OLEDB.4.0;Data Source=${filePath};Extended Properties='Excel 8.0;HDR=Yes'`;
171
+        } else if (excelVerson === "12.0") {
172
+            return `Provider=Microsoft.Ace.OleDb.12.0;Data Source=${filePath};Extended Properties='Excel 12.0;HDR=Yes'`;
173
+        }
174
+        return "";
175
+    }
176
+}
177
+
178
+export { AnalyzeFile };

+ 529
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ChineseCodeConverter.cs 查看文件

@@ -0,0 +1,529 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+//
6
+using System.Text.RegularExpressions;
7
+
8
+namespace TellerSystem.Library.Ext.TradeExtension
9
+{
10
+    public class ChineseCodeConverter
11
+    {
12
+        #region 属性数据定义
13
+        /// <summary>
14
+        /// 汉字的机内码数组
15
+        /// </summary>
16
+        private static int[] pyValue = new int[]
17
+        {
18
+            -20319,-20317,-20304,-20295,-20292,-20283,-20265,-20257,-20242,-20230,-20051,-20036,
19
+            -20032,-20026,-20002,-19990,-19986,-19982,-19976,-19805,-19784,-19775,-19774,-19763,
20
+            -19756,-19751,-19746,-19741,-19739,-19728,-19725,-19715,-19540,-19531,-19525,-19515,
21
+            -19500,-19484,-19479,-19467,-19289,-19288,-19281,-19275,-19270,-19263,-19261,-19249,
22
+            -19243,-19242,-19238,-19235,-19227,-19224,-19218,-19212,-19038,-19023,-19018,-19006,
23
+            -19003,-18996,-18977,-18961,-18952,-18783,-18774,-18773,-18763,-18756,-18741,-18735,
24
+            -18731,-18722,-18710,-18697,-18696,-18526,-18518,-18501,-18490,-18478,-18463,-18448,
25
+            -18447,-18446,-18239,-18237,-18231,-18220,-18211,-18201,-18184,-18183, -18181,-18012,
26
+            -17997,-17988,-17970,-17964,-17961,-17950,-17947,-17931,-17928,-17922,-17759,-17752,
27
+            -17733,-17730,-17721,-17703,-17701,-17697,-17692,-17683,-17676,-17496,-17487,-17482,
28
+            -17468,-17454,-17433,-17427,-17417,-17202,-17185,-16983,-16970,-16942,-16915,-16733,
29
+            -16708,-16706,-16689,-16664,-16657,-16647,-16474,-16470,-16465,-16459,-16452,-16448,
30
+            -16433,-16429,-16427,-16423,-16419,-16412,-16407,-16403,-16401,-16393,-16220,-16216,
31
+            -16212,-16205,-16202,-16187,-16180,-16171,-16169,-16158,-16155,-15959,-15958,-15944,
32
+            -15933,-15920,-15915,-15903,-15889,-15878,-15707,-15701,-15681,-15667,-15661,-15659,
33
+            -15652,-15640,-15631,-15625,-15454,-15448,-15436,-15435,-15419,-15416,-15408,-15394,
34
+            -15385,-15377,-15375,-15369,-15363,-15362,-15183,-15180,-15165,-15158,-15153,-15150,
35
+            -15149,-15144,-15143,-15141,-15140,-15139,-15128,-15121,-15119,-15117,-15110,-15109,
36
+            -14941,-14937,-14933,-14930,-14929,-14928,-14926,-14922,-14921,-14914,-14908,-14902,
37
+            -14894,-14889,-14882,-14873,-14871,-14857,-14678,-14674,-14670,-14668,-14663,-14654,
38
+            -14645,-14630,-14594,-14429,-14407,-14399,-14384,-14379,-14368,-14355,-14353,-14345,
39
+            -14170,-14159,-14151,-14149,-14145,-14140,-14137,-14135,-14125,-14123,-14122,-14112,
40
+            -14109,-14099,-14097,-14094,-14092,-14090,-14087,-14083,-13917,-13914,-13910,-13907,
41
+            -13906,-13905,-13896,-13894,-13878,-13870,-13859,-13847,-13831,-13658,-13611,-13601,
42
+            -13406,-13404,-13400,-13398,-13395,-13391,-13387,-13383,-13367,-13359,-13356,-13343,
43
+            -13340,-13329,-13326,-13318,-13147,-13138,-13120,-13107,-13096,-13095,-13091,-13076,
44
+            -13068,-13063,-13060,-12888,-12875,-12871,-12860,-12858,-12852,-12849,-12838,-12831,
45
+            -12829,-12812,-12802,-12607,-12597,-12594,-12585,-12556,-12359,-12346,-12320,-12300,
46
+            -12120,-12099,-12089,-12074,-12067,-12058,-12039,-11867,-11861,-11847,-11831,-11798,
47
+            -11781,-11604,-11589,-11536,-11358,-11340,-11339,-11324,-11303,-11097,-11077,-11067,
48
+            -11055,-11052,-11045,-11041,-11038,-11024,-11020,-11019,-11018,-11014,-10838,-10832,
49
+            -10815,-10800,-10790,-10780,-10764,-10587,-10544,-10533,-10519,-10331,-10329,-10328,
50
+            -10322,-10315,-10309,-10307,-10296,-10281,-10274,-10270,-10262,-10260,-10256,-10254
51
+        };
52
+        /// <summary>
53
+        /// 机内码对应的拼音数组
54
+        /// </summary>
55
+        private static string[] pyName = new string[]
56
+        {
57
+            "A","Ai","An","Ang","Ao","Ba","Bai","Ban","Bang","Bao","Bei","Ben",
58
+            "Beng","Bi","Bian","Biao","Bie","Bin","Bing","Bo","Bu","Ba","Cai","Can",
59
+            "Cang","Cao","Ce","Ceng","Cha","Chai","Chan","Chang","Chao","Che","Chen","Cheng",
60
+            "Chi","Chong","Chou","Chu","Chuai","Chuan","Chuang","Chui","Chun","Chuo","Ci","Cong",
61
+            "Cou","Cu","Cuan","Cui","Cun","Cuo","Da","Dai","Dan","Dang","Dao","De",
62
+            "Deng","Di","Dian","Diao","Die","Ding","Diu","Dong","Dou","Du","Duan","Dui",
63
+            "Dun","Duo","E","En","Er","Fa","Fan","Fang","Fei","Fen","Feng","Fo",
64
+            "Fou","Fu","Ga","Gai","Gan","Gang","Gao","Ge","Gei","Gen","Geng","Gong",
65
+            "Gou","Gu","Gua","Guai","Guan","Guang","Gui","Gun","Guo","Ha","Hai","Han",
66
+            "Hang","Hao","He","Hei","Hen","Heng","Hong","Hou","Hu","Hua","Huai","Huan",
67
+            "Huang","Hui","Hun","Huo","Ji","Jia","Jian","Jiang","Jiao","Jie","Jin","Jing",
68
+            "Jiong","Jiu","Ju","Juan","Jue","Jun","Ka","Kai","Kan","Kang","Kao","Ke",
69
+            "Ken","Keng","Kong","Kou","Ku","Kua","Kuai","Kuan","Kuang","Kui","Kun","Kuo",
70
+            "La","Lai","Lan","Lang","Lao","Le","Lei","Leng","Li","Lia","Lian","Liang",
71
+            "Liao","Lie","Lin","Ling","Liu","Long","Lou","Lu","Lv","Luan","Lue","Lun",
72
+            "Luo","Ma","Mai","Man","Mang","Mao","Me","Mei","Men","Meng","Mi","Mian",
73
+            "Miao","Mie","Min","Ming","Miu","Mo","Mou","Mu","Na","Nai","Nan","Nang",
74
+            "Nao","Ne","Nei","Nen","Neng","Ni","Nian","Niang","Niao","Nie","Nin","Ning",
75
+            "Niu","Nong","Nu","Nv","Nuan","Nue","Nuo","O","Ou","Pa","Pai","Pan",
76
+            "Pang","Pao","Pei","Pen","Peng","Pi","Pian","Piao","Pie","Pin","Ping","Po",
77
+            "Pu","Qi","Qia","Qian","Qiang","Qiao","Qie","Qin","Qing","Qiong","Qiu","Qu",
78
+            "Quan","Que","Qun","Ran","Rang","Rao","Re","Ren","Reng","Ri","Rong","Rou",
79
+            "Ru","Ruan","Rui","Run","Ruo","Sa","Sai","San","Sang","Sao","Se","Sen",
80
+            "Seng","Sha","Shai","Shan","Shang","Shao","She","Shen","Sheng","Shi","Shou","Shu",
81
+            "Shua","Shuai","Shuan","Shuang","Shui","Shun","Shuo","Si","Song","Sou","Su","Suan",
82
+            "Sui","Sun","Suo","Ta","Tai","Tan","Tang","Tao","Te","Teng","Ti","Tian",
83
+            "Tiao","Tie","Ting","Tong","Tou","Tu","Tuan","Tui","Tun","Tuo","Wa","Wai",
84
+            "Wan","Wang","Wei","Wen","Weng","Wo","Wu","Xi","Xia","Xian","Xiang","Xiao",
85
+            "Xie","Xin","Xing","Xiong","Xiu","Xu","Xuan","Xue","Xun","Ya","Yan","Yang",
86
+            "Yao","Ye","Yi","Yin","Ying","Yo","Yong","You","Yu","Yuan","Yue","Yun",
87
+            "Za", "Zai","Zan","Zang","Zao","Ze","Zei","Zen","Zeng","Zha","Zhai","Zhan",
88
+            "Zhang","Zhao","Zhe","Zhen","Zheng","Zhi","Zhong","Zhou","Zhu","Zhua","Zhuai","Zhuan",
89
+            "Zhuang","Zhui","Zhun","Zhuo","Zi","Zong","Zou","Zu","Zuan","Zui","Zun","Zuo"
90
+        };
91
+        #endregion
92
+
93
+        #region 把汉字转换成拼音(全拼)无间隔符号
94
+        /// <summary>
95
+        /// 把汉字转换成拼音(全拼)
96
+        /// </summary>
97
+        /// <param name="hzString">汉字字符串</param>
98
+        /// <returns>转换后的拼音(全拼)字符串</returns>
99
+        public static string Convert(string hzString)
100
+        {
101
+            // 匹配中文字符
102
+            Regex regex = new Regex("^[\u4e00-\u9fa5]+$");
103
+            byte[] array = new byte[2];
104
+            string pyString = "";
105
+            int chrAsc = 0;
106
+            int i1 = 0;
107
+            int i2 = 0;
108
+            char[] noWChar = hzString.ToCharArray();
109
+            for (int j = 0; j < noWChar.Length; j++)
110
+            {
111
+                // 中文字符
112
+                if (regex.IsMatch(noWChar[j].ToString()))
113
+                {
114
+                    array = System.Text.Encoding.Default.GetBytes(noWChar[j].ToString());
115
+                    i1 = (short)(array[0]);
116
+                    i2 = (short)(array[1]);
117
+                    chrAsc = i1 * 256 + i2 - 65536;
118
+                    if (chrAsc > 0 && chrAsc < 160)
119
+                    {
120
+                        pyString += noWChar[j];
121
+                    }
122
+                    else
123
+                    {
124
+                        // 修正部分文字
125
+                        if (chrAsc == -9254)  // 修正“圳”字
126
+                            pyString += "Zhen";
127
+                        else if (chrAsc == -6741)
128
+                            pyString += "Han";
129
+                        else
130
+                        {
131
+                            for (int i = (pyValue.Length - 1); i >= 0; i--)
132
+                            {
133
+                                if (pyValue[i] <= chrAsc)
134
+                                {
135
+                                    pyString += pyName[i];
136
+                                    break;
137
+                                }
138
+                            }
139
+                        }
140
+                    }
141
+                }
142
+                // 非中文字符
143
+                else
144
+                {
145
+                    pyString += noWChar[j].ToString();
146
+                }
147
+            }
148
+            return pyString;
149
+        }
150
+        #endregion
151
+
152
+
153
+        #region 把汉字转换成拼音(全拼) 用空格间隔
154
+        /// <summary>
155
+        /// 把汉字转换成拼音(全拼)
156
+        /// </summary>
157
+        /// <param name="hzString">汉字字符串</param>
158
+        /// <returns>转换后的拼音(全拼)字符串</returns>
159
+        public static string ConvertWithBlank(string hzString)
160
+        {
161
+            int count = 1;
162
+            // 匹配中文字符
163
+            Regex regex = new Regex("^[\u4e00-\u9fa5]+$");
164
+            byte[] array = new byte[2];
165
+            string pyString = "";
166
+            int chrAsc = 0;
167
+            int i1 = 0;
168
+            int i2 = 0;
169
+            char[] noWChar = hzString.ToCharArray();
170
+            for (int j = 0; j < noWChar.Length; j++)
171
+            {
172
+                // 中文字符
173
+                if (regex.IsMatch(noWChar[j].ToString()))
174
+                {
175
+                    array = System.Text.Encoding.Default.GetBytes(noWChar[j].ToString());
176
+                    i1 = (short)(array[0]);
177
+                    i2 = (short)(array[1]);
178
+                    chrAsc = i1 * 256 + i2 - 65536;
179
+                    if (chrAsc > 0 && chrAsc < 160)
180
+                    {
181
+                        pyString = pyString + " " + noWChar[j];
182
+                    }
183
+                    else
184
+                    {
185
+                        // 修正部分文字
186
+                        if (chrAsc == -9254)  // 修正“圳”字
187
+                            pyString = pyString + " " + "Zhen";
188
+                        else
189
+                        {
190
+                            for (int i = (pyValue.Length - 1); i >= 0; i--)
191
+                            {
192
+                                if (pyValue[i] <= chrAsc)
193
+                                {
194
+                                    if (hzString.Length == 3)
195
+                                    {
196
+                                        if (count == 1)
197
+                                        {
198
+                                            pyString = pyString + " " + pyName[i] + " ";
199
+                                            count++;
200
+                                        }
201
+                                        else
202
+                                        {
203
+                                            pyString = pyString + pyName[i];
204
+                                        }
205
+
206
+                                    }
207
+                                    else if (hzString.Length == 4)
208
+                                    {
209
+                                        if (count < 2)
210
+                                        {
211
+                                            pyString = pyString + pyName[i];
212
+                                            count++;
213
+                                        }
214
+                                        else if (count == 2)
215
+                                        {
216
+                                            pyString = pyString + pyName[i] + " ";
217
+                                            count++;
218
+                                        }
219
+                                        else
220
+                                        {
221
+                                            pyString = pyString + pyName[i];
222
+                                        }
223
+                                    }
224
+                                    else
225
+                                    {
226
+                                        pyString = pyString + " " + pyName[i];
227
+                                    }
228
+                                    break;
229
+                                }
230
+                            }
231
+                        }
232
+                    }
233
+                }
234
+                // 非中文字符
235
+                else
236
+                {
237
+                    pyString = pyString + " " + noWChar[j].ToString();
238
+                }
239
+            }
240
+            return pyString.Trim();
241
+        }
242
+        #endregion
243
+
244
+
245
+        #region 把汉字转换成拼音(全拼) 用特定的字符间隔
246
+        /// <summary>
247
+        /// 把汉字转换成拼音(全拼)
248
+        /// </summary>
249
+        /// <param name="hzString">汉字字符串</param>
250
+        /// <returns>转换后的拼音(全拼)字符串</returns>
251
+        public static string ConvertWithSplitChar(string hzString, string splitChar)
252
+        {
253
+            int count = 1;
254
+            // 匹配中文字符
255
+            Regex regex = new Regex("^[\u4e00-\u9fa5]+$");
256
+            byte[] array = new byte[2];
257
+            string pyString = "";
258
+            int chrAsc = 0;
259
+            int i1 = 0;
260
+            int i2 = 0;
261
+            char[] noWChar = hzString.ToCharArray();
262
+            for (int j = 0; j < noWChar.Length; j++)
263
+            {
264
+                // 中文字符
265
+                if (regex.IsMatch(noWChar[j].ToString()))
266
+                {
267
+                    array = System.Text.Encoding.Default.GetBytes(noWChar[j].ToString());
268
+                    i1 = (short)(array[0]);
269
+                    i2 = (short)(array[1]);
270
+                    chrAsc = i1 * 256 + i2 - 65536;
271
+                    if (chrAsc > 0 && chrAsc < 160)
272
+                    {
273
+                        pyString = pyString + splitChar + noWChar[j];
274
+                    }
275
+                    else
276
+                    {
277
+                        // 修正部分文字
278
+                        if (chrAsc == -9254)  // 修正“圳”字
279
+                            pyString = pyString + splitChar + "Zhen";
280
+                        else
281
+                        {
282
+                            for (int i = (pyValue.Length - 1); i >= 0; i--)
283
+                            {
284
+                                if (pyValue[i] <= chrAsc)
285
+                                {
286
+                                    if (pyValue[i] <= chrAsc)
287
+                                    {
288
+                                        if (hzString.Length == 3)
289
+                                        {
290
+                                            if (count == 1)
291
+                                            {
292
+                                                pyString = pyString + splitChar + pyName[i] + splitChar;
293
+                                                count++;
294
+                                            }
295
+                                            else
296
+                                            {
297
+                                                pyString = pyString + pyName[i];
298
+                                            }
299
+
300
+                                        }
301
+                                        else if (hzString.Length == 4)
302
+                                        {
303
+                                            if (count < 2)
304
+                                            {
305
+                                                pyString = pyString + pyName[i];
306
+                                                count++;
307
+                                            }
308
+                                            else if (count == 2)
309
+                                            {
310
+                                                pyString = pyString + pyName[i] + splitChar;
311
+                                                count++;
312
+                                            }
313
+                                            else
314
+                                            {
315
+                                                pyString = pyString + pyName[i];
316
+                                            }
317
+                                        }
318
+                                        else
319
+                                        {
320
+                                            pyString = pyString + splitChar + pyName[i];
321
+                                        }
322
+                                        break;
323
+                                        //pyString = pyString + splitChar + pyName[i];
324
+                                        //break;
325
+                                    }
326
+                                }
327
+                            }
328
+                        }
329
+                    }
330
+                }
331
+                // 非中文字符
332
+                else
333
+                {
334
+                    pyString = pyString + splitChar + noWChar[j].ToString();
335
+                }
336
+            }
337
+            char[] trimAChar = splitChar.ToCharArray();
338
+            return pyString.TrimStart(trimAChar);
339
+        }
340
+        #endregion
341
+
342
+
343
+        #region 汉字转拼音缩写 (字符串) (小写)
344
+        /// <summary>
345
+        /// 汉字转拼音缩写
346
+        /// </summary>
347
+        /// <param name="str">要转换的汉字字符串</param>
348
+        /// <returns>拼音缩写</returns>
349
+        public static string GetSpellStringLower(string str)
350
+        {
351
+            string tempStr = "";
352
+            foreach (char c in str)
353
+            {
354
+                if ((int)c >= 33 && (int)c <= 126)
355
+                {
356
+                    //字母和符号原样保留
357
+                    tempStr += c.ToString();
358
+                }
359
+                else
360
+                {
361
+                    //累加拼音声母
362
+                    tempStr += GetSpellCharLower(c.ToString());
363
+                }
364
+            }
365
+            return tempStr;
366
+        }
367
+        #endregion
368
+
369
+        #region 汉字转拼音缩写 (字符串) (小写) (空格间隔)
370
+        /// <summary>
371
+        /// 汉字转拼音缩写 (字符串) (小写) (空格间隔)
372
+        /// </summary>
373
+        /// <param name="str">要转换的汉字字符串</param>
374
+        /// <returns>拼音缩写</returns>
375
+        public static string GetSpellStringLowerSplitWithBlank(string str)
376
+        {
377
+            string tempStr = "";
378
+            foreach (char c in str)
379
+            {
380
+                if ((int)c >= 33 && (int)c <= 126)
381
+                {
382
+                    //字母和符号原样保留
383
+                    tempStr = tempStr + " " + c.ToString();
384
+                }
385
+                else
386
+                {
387
+                    //累加拼音声母
388
+                    tempStr = tempStr + " " + GetSpellCharLower(c.ToString());
389
+                }
390
+            }
391
+            return tempStr.Trim();
392
+        }
393
+        #endregion
394
+
395
+
396
+        #region 汉字转拼音缩写 (字符串)(大写)
397
+        /// <summary>
398
+        /// 汉字转拼音缩写 (大写)
399
+        /// </summary>
400
+        /// <param name="str">要转换的汉字字符串</param>
401
+        /// <returns>拼音缩写</returns>
402
+        public static string GetSpellStringSupper(string str)
403
+        {
404
+            string tempStr = "";
405
+            foreach (char c in str)
406
+            {
407
+                if ((int)c >= 33 && (int)c <= 126)
408
+                {
409
+                    //字母和符号原样保留
410
+                    tempStr += c.ToString();
411
+                }
412
+                else
413
+                {
414
+                    //累加拼音声母
415
+                    tempStr += GetSpellCharSupper(c.ToString());
416
+                }
417
+            }
418
+            return tempStr;
419
+        }
420
+        #endregion
421
+
422
+
423
+        #region 汉字转拼音缩写 (字符串)(大写)(空格间隔)
424
+        /// <summary>
425
+        /// 汉字转拼音缩写  (字符串)(大写)(空格间隔)
426
+        /// </summary>
427
+        /// <param name="str">要转换的汉字字符串</param>
428
+        /// <returns>拼音缩写</returns>
429
+        public static string GetSpellStringSupperSplitWithBlank(string str)
430
+        {
431
+            string tempStr = "";
432
+            foreach (char c in str)
433
+            {
434
+                if ((int)c >= 33 && (int)c <= 126)
435
+                {
436
+                    //字母和符号原样保留
437
+                    tempStr = tempStr + " " + c.ToString();
438
+                }
439
+                else
440
+                {
441
+                    //累加拼音声母
442
+                    tempStr = tempStr + " " + GetSpellCharSupper(c.ToString());
443
+                }
444
+            }
445
+            return tempStr.Trim();
446
+        }
447
+        #endregion
448
+
449
+
450
+        #region 取单个字符的拼音声母(字符)(大写)
451
+        /// <summary>
452
+        /// 取单个字符的拼音声母
453
+        /// </summary>
454
+        /// <param name="c">要转换的单个汉字</param>
455
+        /// <returns>拼音声母</returns>
456
+        public static string GetSpellCharSupper(string c)
457
+        {
458
+            byte[] array = new byte[2];
459
+            array = System.Text.Encoding.Default.GetBytes(c);
460
+            int i = (short)(array[0] - '0') * 256 + ((short)(array[1] - '0'));
461
+            if (i < 0xB0A1) return c;
462
+            if (i < 0xB0C5) return "A";
463
+            if (i < 0xB2C1) return "B";
464
+            if (i < 0xB4EE) return "C";
465
+            if (i < 0xB6EA) return "D";
466
+            if (i < 0xB7A2) return "E";
467
+            if (i < 0xB8C1) return "F";
468
+            if (i < 0xB9FE) return "G";
469
+            if (i < 0xBBF7) return "H";
470
+            if (i < 0xBFA6) return "J";
471
+            if (i < 0xC0AC) return "K";
472
+            if (i < 0xC2E8) return "L";
473
+            if (i < 0xC4C3) return "M";
474
+            if (i < 0xC5B6) return "N";
475
+            if (i < 0xC5BE) return "O";
476
+            if (i < 0xC6DA) return "P";
477
+            if (i < 0xC8BB) return "Q";
478
+            if (i < 0xC8F6) return "R";
479
+            if (i < 0xCBFA) return "S";
480
+            if (i < 0xCDDA) return "T";
481
+            if (i < 0xCEF4) return "W";
482
+            if (i < 0xD1B9) return "X";
483
+            if (i < 0xD4D1) return "Y";
484
+            if (i < 0xD7FA) return "Z";
485
+            return c;
486
+        }
487
+        #endregion
488
+
489
+
490
+        #region 取单个字符的拼音声母(字符)(小写)
491
+        /// <summary>
492
+        /// 取单个字符的拼音声母
493
+        /// </summary>
494
+        /// <param name="c">要转换的单个汉字</param>
495
+        /// <returns>拼音声母</returns>
496
+        public static string GetSpellCharLower(string c)
497
+        {
498
+            byte[] array = new byte[2];
499
+            array = System.Text.Encoding.Default.GetBytes(c);
500
+            int i = (short)(array[0] - '0') * 256 + ((short)(array[1] - '0'));
501
+            if (i < 0xB0A1) return c;
502
+            if (i < 0xB0C5) return "a";
503
+            if (i < 0xB2C1) return "b";
504
+            if (i < 0xB4EE) return "c";
505
+            if (i < 0xB6EA) return "d";
506
+            if (i < 0xB7A2) return "e";
507
+            if (i < 0xB8C1) return "f";
508
+            if (i < 0xB9FE) return "g";
509
+            if (i < 0xBBF7) return "h";
510
+            if (i < 0xBFA6) return "j";
511
+            if (i < 0xC0AC) return "k";
512
+            if (i < 0xC2E8) return "l";
513
+            if (i < 0xC4C3) return "m";
514
+            if (i < 0xC5B6) return "n";
515
+            if (i < 0xC5BE) return "o";
516
+            if (i < 0xC6DA) return "p";
517
+            if (i < 0xC8BB) return "q";
518
+            if (i < 0xC8F6) return "r";
519
+            if (i < 0xCBFA) return "s";
520
+            if (i < 0xCDDA) return "t";
521
+            if (i < 0xCEF4) return "w";
522
+            if (i < 0xD1B9) return "x";
523
+            if (i < 0xD4D1) return "y";
524
+            if (i < 0xD7FA) return "z";
525
+            return c;
526
+        }
527
+        #endregion
528
+    }
529
+}

+ 373
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ChineseCodeConverter.ts 查看文件

@@ -0,0 +1,373 @@
1
+// 汉字的机内码数组
2
+const pyValue: number[] = [
3
+    -20319,-20317,-20304,-20295,-20292,-20283,-20265,-20257,-20242,-20230,-20051,-20036,
4
+    -20032,-20026,-20002,-19990,-19986,-19982,-19976,-19805,-19784,-19775,-19774,-19763,
5
+    -19756,-19751,-19746,-19741,-19739,-19728,-19725,-19715,-19540,-19531,-19525,-19515,
6
+    -19500,-19484,-19479,-19467,-19289,-19288,-19281,-19275,-19270,-19263,-19261,-19249,
7
+    -19243,-19242,-19238,-19235,-19227,-19224,-19218,-19212,-19038,-19023,-19018,-19006,
8
+    -19003,-18996,-18977,-18961,-18952,-18783,-18774,-18773,-18763,-18756,-18741,-18735,
9
+    -18731,-18722,-18710,-18697,-18696,-18526,-18518,-18501,-18490,-18478,-18463,-18448,
10
+    -18447,-18446,-18239,-18237,-18231,-18220,-18211,-18201,-18184,-18183, -18181,-18012,
11
+    -17997,-17988,-17970,-17964,-17961,-17950,-17947,-17931,-17928,-17922,-17759,-17752,
12
+    -17733,-17730,-17721,-17703,-17701,-17697,-17692,-17683,-17676,-17496,-17487,-17482,
13
+    -17468,-17454,-17433,-17427,-17417,-17202,-17185,-16983,-16970,-16942,-16915,-16733,
14
+    -16708,-16706,-16689,-16664,-16657,-16647,-16474,-16470,-16465,-16459,-16452,-16448,
15
+    -16433,-16429,-16427,-16423,-16419,-16412,-16407,-16403,-16401,-16393,-16220,-16216,
16
+    -16212,-16205,-16202,-16187,-16180,-16171,-16169,-16158,-16155,-15959,-15958,-15944,
17
+    -15933,-15920,-15915,-15903,-15889,-15878,-15707,-15701,-15681,-15667,-15661,-15659,
18
+    -15652,-15640,-15631,-15625,-15454,-15448,-15436,-15435,-15419,-15416,-15408,-15394,
19
+    -15385,-15377,-15375,-15369,-15363,-15362,-15183,-15180,-15165,-15158,-15153,-15150,
20
+    -15149,-15144,-15143,-15141,-15140,-15139,-15128,-15121,-15119,-15117,-15110,-15109,
21
+    -14941,-14937,-14933,-14930,-14929,-14928,-14926,-14922,-14921,-14914,-14908,-14902,
22
+    -14894,-14889,-14882,-14873,-14871,-14857,-14678,-14674,-14670,-14668,-14663,-14654,
23
+    -14645,-14630,-14594,-14429,-14407,-14399,-14384,-14379,-14368,-14355,-14353,-14345,
24
+    -14170,-14159,-14151,-14149,-14145,-14140,-14137,-14135,-14125,-14123,-14122,-14112,
25
+    -14109,-14099,-14097,-14094,-14092,-14090,-14087,-14083,-13917,-13914,-13910,-13907,
26
+    -13906,-13905,-13896,-13894,-13878,-13870,-13859,-13847,-13831,-13658,-13611,-13601,
27
+    -13406,-13404,-13400,-13398,-13395,-13391,-13387,-13383,-13367,-13359,-13356,-13343,
28
+    -13340,-13329,-13326,-13318,-13147,-13138,-13120,-13107,-13096,-13095,-13091,-13076,
29
+    -13068,-13063,-13060,-12888,-12875,-12871,-12860,-12858,-12852,-12849,-12838,-12831,
30
+    -12829,-12812,-12802,-12607,-12597,-12594,-12585,-12556,-12359,-12346,-12320,-12300,
31
+    -12120,-12099,-12089,-12074,-12067,-12058,-12039,-11867,-11861,-11847,-11831,-11798,
32
+    -11781,-11604,-11589,-11536,-11358,-11340,-11339,-11324,-11303,-11097,-11077,-11067,
33
+    -11055,-11052,-11045,-11041,-11038,-11024,-11020,-11019,-11018,-11014,-10838,-10832,
34
+    -10815,-10800,-10790,-10780,-10764,-10587,-10544,-10533,-10519,-10331,-10329,-10328,
35
+    -10322,-10315,-10309,-10307,-10296,-10281,-10274,-10270,-10262,-10260,-10256,-10254
36
+];
37
+
38
+// 机内码对应的拼音数组
39
+const pyName: string[] = [
40
+    "A","Ai","An","Ang","Ao","Ba","Bai","Ban","Bang","Bao","Bei","Ben",
41
+    "Beng","Bi","Bian","Biao","Bie","Bin","Bing","Bo","Bu","Ba","Cai","Can",
42
+    "Cang","Cao","Ce","Ceng","Cha","Chai","Chan","Chang","Chao","Che","Chen","Cheng",
43
+    "Chi","Chong","Chou","Chu","Chuai","Chuan","Chuang","Chui","Chun","Chuo","Ci","Cong",
44
+    "Cou","Cu","Cuan","Cui","Cun","Cuo","Da","Dai","Dan","Dang","Dao","De",
45
+    "Deng","Di","Dian","Diao","Die","Ding","Diu","Dong","Dou","Du","Duan","Dui",
46
+    "Dun","Duo","E","En","Er","Fa","Fan","Fang","Fei","Fen","Feng","Fo",
47
+    "Fou","Fu","Ga","Gai","Gan","Gang","Gao","Ge","Gei","Gen","Geng","Gong",
48
+    "Gou","Gu","Gua","Guai","Guan","Guang","Gui","Gun","Guo","Ha","Hai","Han",
49
+    "Hang","Hao","He","Hei","Hen","Heng","Hong","Hou","Hu","Hua","Huai","Huan",
50
+    "Huang","Hui","Hun","Huo","Ji","Jia","Jian","Jiang","Jiao","Jie","Jin","Jing",
51
+    "Jiong","Jiu","Ju","Juan","Jue","Jun","Ka","Kai","Kan","Kang","Kao","Ke",
52
+    "Ken","Keng","Kong","Kou","Ku","Kua","Kuai","Kuan","Kuang","Kui","Kun","Kuo",
53
+    "La","Lai","Lan","Lang","Lao","Le","Lei","Leng","Li","Lia","Lian","Liang",
54
+    "Liao","Lie","Lin","Ling","Liu","Long","Lou","Lu","Lv","Luan","Lue","Lun",
55
+    "Luo","Ma","Mai","Man","Mang","Mao","Me","Mei","Men","Meng","Mi","Mian",
56
+    "Miao","Mie","Min","Ming","Miu","Mo","Mou","Mu","Na","Nai","Nan","Nang",
57
+    "Nao","Ne","Nei","Nen","Neng","Ni","Nian","Niang","Niao","Nie","Nin","Ning",
58
+    "Niu","Nong","Nu","Nv","Nuan","Nue","Nuo","O","Ou","Pa","Pai","Pan",
59
+    "Pang","Pao","Pei","Pen","Peng","Pi","Pian","Piao","Pie","Pin","Ping","Po",
60
+    "Pu","Qi","Qia","Qian","Qiang","Qiao","Qie","Qin","Qing","Qiong","Qiu","Qu",
61
+    "Quan","Que","Qun","Ran","Rang","Rao","Re","Ren","Reng","Ri","Rong","Rou",
62
+    "Ru","Ruan","Rui","Run","Ruo","Sa","Sai","San","Sang","Sao","Se","Sen",
63
+    "Seng","Sha","Shai","Shan","Shang","Shao","She","Shen","Sheng","Shi","Shou","Shu",
64
+    "Shua","Shuai","Shuan","Shuang","Shui","Shun","Shuo","Si","Song","Sou","Su","Suan",
65
+    "Sui","Sun","Suo","Ta","Tai","Tan","Tang","Tao","Te","Teng","Ti","Tian",
66
+    "Tiao","Tie","Ting","Tong","Tou","Tu","Tuan","Tui","Tun","Tuo","Wa","Wai",
67
+    "Wan","Wang","Wei","Wen","Weng","Wo","Wu","Xi","Xia","Xian","Xiang","Xiao",
68
+    "Xie","Xin","Xing","Xiong","Xiu","Xu","Xuan","Xue","Xun","Ya","Yan","Yang",
69
+    "Yao","Ye","Yi","Yin","Ying","Yo","Yong","You","Yu","Yuan","Yue","Yun",
70
+    "Za", "Zai","Zan","Zang","Zao","Ze","Zei","Zen","Zeng","Zha","Zhai","Zhan",
71
+    "Zhang","Zhao","Zhe","Zhen","Zheng","Zhi","Zhong","Zhou","Zhu","Zhua","Zhuai","Zhuan",
72
+    "Zhuang","Zhui","Zhun","Zhuo","Zi","Zong","Zou","Zu","Zuan","Zui","Zun","Zuo"
73
+];
74
+
75
+class ChineseCodeConverter {
76
+    /**
77
+     * 把汉字转换成拼音(全拼)
78
+     * @param hzString 汉字字符串
79
+     * @returns 转换后的拼音(全拼)字符串
80
+     */
81
+    static Convert(hzString: string): string {
82
+        const regex = /^[\u4e00-\u9fa5]+$/;
83
+        let pyString = "";
84
+        for (let j = 0; j < hzString.length; j++) {
85
+            const char = hzString[j];
86
+            if (regex.test(char)) {
87
+                const array = new TextEncoder().encode(char);
88
+                const i1 = array[0];
89
+                const i2 = array[1];
90
+                const chrAsc = i1 * 256 + i2 - 65536;
91
+                if (chrAsc > 0 && chrAsc < 160) {
92
+                    pyString += char;
93
+                } else {
94
+                    if (chrAsc === -9254) {
95
+                        pyString += "Zhen";
96
+                    } else if (chrAsc === -6741) {
97
+                        pyString += "Han";
98
+                    } else {
99
+                        for (let i = pyValue.length - 1; i >= 0; i--) {
100
+                            if (pyValue[i] <= chrAsc) {
101
+                                pyString += pyName[i];
102
+                                break;
103
+                            }
104
+                        }
105
+                    }
106
+                }
107
+            } else {
108
+                pyString += char;
109
+            }
110
+        }
111
+        return pyString;
112
+    }
113
+
114
+    /**
115
+     * 把汉字转换成拼音(全拼) 用空格间隔
116
+     * @param hzString 汉字字符串
117
+     * @returns 转换后的拼音(全拼)字符串
118
+     */
119
+    static ConvertWithBlank(hzString: string): string {
120
+        let count = 1;
121
+        const regex = /^[\u4e00-\u9fa5]+$/;
122
+        let pyString = "";
123
+        for (let j = 0; j < hzString.length; j++) {
124
+            const char = hzString[j];
125
+            if (regex.test(char)) {
126
+                const array = new TextEncoder().encode(char);
127
+                const i1 = array[0];
128
+                const i2 = array[1];
129
+                const chrAsc = i1 * 256 + i2 - 65536;
130
+                if (chrAsc > 0 && chrAsc < 160) {
131
+                    pyString += " " + char;
132
+                } else {
133
+                    if (chrAsc === -9254) {
134
+                        pyString += " " + "Zhen";
135
+                    } else {
136
+                        for (let i = pyValue.length - 1; i >= 0; i--) {
137
+                            if (pyValue[i] <= chrAsc) {
138
+                                if (hzString.length === 3) {
139
+                                    if (count === 1) {
140
+                                        pyString += " " + pyName[i] + " ";
141
+                                        count++;
142
+                                    } else {
143
+                                        pyString += pyName[i];
144
+                                    }
145
+                                } else if (hzString.length === 4) {
146
+                                    if (count < 2) {
147
+                                        pyString += pyName[i];
148
+                                        count++;
149
+                                    } else if (count === 2) {
150
+                                        pyString += pyName[i] + " ";
151
+                                        count++;
152
+                                    } else {
153
+                                        pyString += pyName[i];
154
+                                    }
155
+                                } else {
156
+                                    pyString += " " + pyName[i];
157
+                                }
158
+                                break;
159
+                            }
160
+                        }
161
+                    }
162
+                }
163
+            } else {
164
+                pyString += " " + char;
165
+            }
166
+        }
167
+        return pyString.trim();
168
+    }
169
+
170
+    /**
171
+     * 把汉字转换成拼音(全拼) 用特定的字符间隔
172
+     * @param hzString 汉字字符串
173
+     * @param splitChar 间隔字符
174
+     * @returns 转换后的拼音(全拼)字符串
175
+     */
176
+    static ConvertWithSplitChar(hzString: string, splitChar: string): string {
177
+        let count = 1;
178
+        const regex = /^[\u4e00-\u9fa5]+$/;
179
+        let pyString = "";
180
+        for (let j = 0; j < hzString.length; j++) {
181
+            const char = hzString[j];
182
+            if (regex.test(char)) {
183
+                const array = new TextEncoder().encode(char);
184
+                const i1 = array[0];
185
+                const i2 = array[1];
186
+                const chrAsc = i1 * 256 + i2 - 65536;
187
+                if (chrAsc > 0 && chrAsc < 160) {
188
+                    pyString += splitChar + char;
189
+                } else {
190
+                    if (chrAsc === -9254) {
191
+                        pyString += splitChar + "Zhen";
192
+                    } else {
193
+                        for (let i = pyValue.length - 1; i >= 0; i--) {
194
+                            if (pyValue[i] <= chrAsc) {
195
+                                if (hzString.length === 3) {
196
+                                    if (count === 1) {
197
+                                        pyString += splitChar + pyName[i] + splitChar;
198
+                                        count++;
199
+                                    } else {
200
+                                        pyString += pyName[i];
201
+                                    }
202
+                                } else if (hzString.length === 4) {
203
+                                    if (count < 2) {
204
+                                        pyString += pyName[i];
205
+                                        count++;
206
+                                    } else if (count === 2) {
207
+                                        pyString += pyName[i] + splitChar;
208
+                                        count++;
209
+                                    } else {
210
+                                        pyString += pyName[i];
211
+                                    }
212
+                                } else {
213
+                                    pyString += splitChar + pyName[i];
214
+                                }
215
+                                break;
216
+                            }
217
+                        }
218
+                    }
219
+                }
220
+            } else {
221
+                pyString += splitChar + char;
222
+            }
223
+        }
224
+        if (pyString.startsWith(splitChar)) {
225
+            pyString = pyString.slice(splitChar.length);
226
+        }
227
+        return pyString;
228
+    }
229
+
230
+    /**
231
+     * 汉字转拼音缩写 (字符串) (小写)
232
+     * @param str 要转换的汉字字符串
233
+     * @returns 拼音缩写
234
+     */
235
+    static GetSpellStringLower(str: string): string {
236
+        let tempStr = "";
237
+        for (const c of str) {
238
+            const charCode = c.charCodeAt(0);
239
+            if (charCode >= 33 && charCode <= 126) {
240
+                tempStr += c;
241
+            } else {
242
+                tempStr += this.GetSpellCharLower(c);
243
+            }
244
+        }
245
+        return tempStr;
246
+    }
247
+
248
+    /**
249
+     * 汉字转拼音缩写 (字符串) (小写) (空格间隔)
250
+     * @param str 要转换的汉字字符串
251
+     * @returns 拼音缩写
252
+     */
253
+    static GetSpellStringLowerSplitWithBlank(str: string): string {
254
+        let tempStr = "";
255
+        for (const c of str) {
256
+            const charCode = c.charCodeAt(0);
257
+            if (charCode >= 33 && charCode <= 126) {
258
+                tempStr += " " + c;
259
+            } else {
260
+                tempStr += " " + this.GetSpellCharLower(c);
261
+            }
262
+        }
263
+        return tempStr.trim();
264
+    }
265
+
266
+    /**
267
+     * 汉字转拼音缩写 (字符串)(大写)
268
+     * @param str 要转换的汉字字符串
269
+     * @returns 拼音缩写
270
+     */
271
+    static GetSpellStringSupper(str: string): string {
272
+        let tempStr = "";
273
+        for (const c of str) {
274
+            const charCode = c.charCodeAt(0);
275
+            if (charCode >= 33 && charCode <= 126) {
276
+                tempStr += c;
277
+            } else {
278
+                tempStr += this.GetSpellCharSupper(c);
279
+            }
280
+        }
281
+        return tempStr;
282
+    }
283
+
284
+    /**
285
+     * 汉字转拼音缩写 (字符串)(大写)(空格间隔)
286
+     * @param str 要转换的汉字字符串
287
+     * @returns 拼音缩写
288
+     */
289
+    static GetSpellStringSupperSplitWithBlank(str: string): string {
290
+        let tempStr = "";
291
+        for (const c of str) {
292
+            const charCode = c.charCodeAt(0);
293
+            if (charCode >= 33 && charCode <= 126) {
294
+                tempStr += " " + c;
295
+            } else {
296
+                tempStr += " " + this.GetSpellCharSupper(c);
297
+            }
298
+        }
299
+        return tempStr.trim();
300
+    }
301
+
302
+    /**
303
+     * 取单个字符的拼音声母(字符)(大写)
304
+     * @param c 要转换的单个汉字
305
+     * @returns 拼音声母
306
+     */
307
+    static GetSpellCharSupper(c: string): string {
308
+        const array = new TextEncoder().encode(c);
309
+        const i = (array[0] - '0'.charCodeAt(0)) * 256 + (array[1] - '0'.charCodeAt(0));
310
+        if (i < 0xB0A1) return c;
311
+        if (i < 0xB0C5) return "A";
312
+        if (i < 0xB2C1) return "B";
313
+        if (i < 0xB4EE) return "C";
314
+        if (i < 0xB6EA) return "D";
315
+        if (i < 0xB7A2) return "E";
316
+        if (i < 0xB8C1) return "F";
317
+        if (i < 0xB9FE) return "G";
318
+        if (i < 0xBBF7) return "H";
319
+        if (i < 0xBFA6) return "J";
320
+        if (i < 0xC0AC) return "K";
321
+        if (i < 0xC2E8) return "L";
322
+        if (i < 0xC4C3) return "M";
323
+        if (i < 0xC5B6) return "N";
324
+        if (i < 0xC5BE) return "O";
325
+        if (i < 0xC6DA) return "P";
326
+        if (i < 0xC8BB) return "Q";
327
+        if (i < 0xC8F6) return "R";
328
+        if (i < 0xCBFA) return "S";
329
+        if (i < 0xCDDA) return "T";
330
+        if (i < 0xCEF4) return "W";
331
+        if (i < 0xD1B9) return "X";
332
+        if (i < 0xD4D1) return "Y";
333
+        if (i < 0xD7FA) return "Z";
334
+        return c;
335
+    }
336
+
337
+    /**
338
+     * 取单个字符的拼音声母(字符)(小写)
339
+     * @param c 要转换的单个汉字
340
+     * @returns 拼音声母
341
+     */
342
+    static GetSpellCharLower(c: string): string {
343
+        const array = new TextEncoder().encode(c);
344
+        const i = (array[0] - '0'.charCodeAt(0)) * 256 + (array[1] - '0'.charCodeAt(0));
345
+        if (i < 0xB0A1) return c;
346
+        if (i < 0xB0C5) return "a";
347
+        if (i < 0xB2C1) return "b";
348
+        if (i < 0xB4EE) return "c";
349
+        if (i < 0xB6EA) return "d";
350
+        if (i < 0xB7A2) return "e";
351
+        if (i < 0xB8C1) return "f";
352
+        if (i < 0xB9FE) return "g";
353
+        if (i < 0xBBF7) return "h";
354
+        if (i < 0xBFA6) return "j";
355
+        if (i < 0xC0AC) return "k";
356
+        if (i < 0xC2E8) return "l";
357
+        if (i < 0xC4C3) return "m";
358
+        if (i < 0xC5B6) return "n";
359
+        if (i < 0xC5BE) return "o";
360
+        if (i < 0xC6DA) return "p";
361
+        if (i < 0xC8BB) return "q";
362
+        if (i < 0xC8F6) return "r";
363
+        if (i < 0xCBFA) return "s";
364
+        if (i < 0xCDDA) return "t";
365
+        if (i < 0xCEF4) return "w";
366
+        if (i < 0xD1B9) return "x";
367
+        if (i < 0xD4D1) return "y";
368
+        if (i < 0xD7FA) return "z";
369
+        return c;
370
+    }
371
+}
372
+
373
+export default ChineseCodeConverter;

+ 25
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/CodeView.cs 查看文件

@@ -0,0 +1,25 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+
6
+namespace TellerSystem.Library.Ext.TradeExtension
7
+{
8
+    public class CodeView
9
+    {
10
+        public string Value { get; set; }
11
+
12
+        public string Key { get; set; }
13
+    }
14
+    public class Province : CodeView
15
+    {
16
+        public List<City> Child { get; set; }
17
+    }
18
+    public class City : CodeView
19
+    {
20
+        public List<County> Child { get; set; }
21
+    }
22
+    public class County : CodeView
23
+    {
24
+    }
25
+}

+ 39
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/CodeView.ts 查看文件

@@ -0,0 +1,39 @@
1
+// 定义 CodeView 类
2
+class CodeView {
3
+    public Value: string;
4
+    public Key: string;
5
+
6
+    constructor() {
7
+        this.Value = "";
8
+        this.Key = "";
9
+    }
10
+}
11
+
12
+// 定义 Province 类
13
+class Province extends CodeView {
14
+    public Child: City[];
15
+
16
+    constructor() {
17
+        super();
18
+        this.Child = [];
19
+    }
20
+}
21
+
22
+// 定义 City 类
23
+class City extends CodeView {
24
+    public Child: County[];
25
+
26
+    constructor() {
27
+        super();
28
+        this.Child = [];
29
+    }
30
+}
31
+
32
+// 定义 County 类
33
+class County extends CodeView {
34
+    constructor() {
35
+        super();
36
+    }
37
+}
38
+
39
+export { CodeView, Province, City, County };

+ 49
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ComboBoxDataGridExtension.cs 查看文件

@@ -0,0 +1,49 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Windows.Documents;
6
+using System.Windows;
7
+using System.Windows.Media;
8
+using System.Windows.Controls;
9
+using System.Globalization;
10
+using Platform.Presentation.FocusManagers;
11
+using System.Windows.Input;
12
+using System.Data;
13
+using Platform.Controls.TableContainer;
14
+using System.Collections;
15
+
16
+namespace TellerSystem.Library.Ext.TradeExtension
17
+{
18
+    public static class ComboBoxDataGridExtension
19
+    {
20
+        #region Extension
21
+        /// <summary>
22
+        /// 获取当前选择行
23
+        /// </summary>
24
+        /// <param name="cbxDataGrid">ComboBoxDataGrid</param>
25
+        /// <returns>当前行(CurrentRow)</returns>
26
+        public static DataRow GetSelectRow(this ComboBoxDataGrid cbxDataGrid)
27
+        {
28
+            DataRowView drv = cbxDataGrid.SelectedItem as DataRowView;
29
+            if (drv == null) return null;
30
+
31
+            return drv.Row;
32
+        }
33
+
34
+        /// <summary>
35
+        /// 获取当前选择行的值
36
+        /// </summary>
37
+        /// <param name="cbxDataGrid">ComboBoxDataGrid</param>
38
+        /// <returns>DataRow.ItemArray</returns>
39
+        public static string[] GetSelectRowValue(this ComboBoxDataGrid cbxDataGrid)
40
+        {
41
+            DataRow row = GetSelectRow(cbxDataGrid);
42
+            if (row == null) return null;
43
+
44
+            return row.ItemArray.Select(obj => obj.ToString()).ToArray();
45
+        }
46
+        #endregion
47
+
48
+    }
49
+}

+ 63
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ComboBoxDataGridExtension.ts 查看文件

@@ -0,0 +1,63 @@
1
+// 模拟 ComboBoxDataGrid 类型
2
+class ComboBoxDataGrid {
3
+    selectedItem: DataRowView | null;
4
+
5
+    constructor() {
6
+        this.selectedItem = null;
7
+    }
8
+}
9
+
10
+// 模拟 DataRowView 类型
11
+class DataRowView {
12
+    row: DataRow;
13
+
14
+    constructor(row: DataRow) {
15
+        this.row = row;
16
+    }
17
+}
18
+
19
+// 模拟 DataRow 类型
20
+class DataRow {
21
+    itemArray: any[];
22
+
23
+    constructor(itemArray: any[]) {
24
+        this.itemArray = itemArray;
25
+    }
26
+}
27
+
28
+// 定义扩展方法所在的命名空间
29
+namespace TellerSystem {
30
+    export namespace Library {
31
+        export namespace Ext {
32
+            export namespace TradeExtension {
33
+                export class ComboBoxDataGridExtension {
34
+                    /**
35
+                     * 获取当前选择行
36
+                     * @param cbxDataGrid ComboBoxDataGrid
37
+                     * @returns 当前行(CurrentRow)
38
+                     */
39
+                    static GetSelectRow(cbxDataGrid: ComboBoxDataGrid): DataRow | null {
40
+                        const drv = cbxDataGrid.selectedItem;
41
+                        if (drv === null) return null;
42
+
43
+                        return drv.row;
44
+                    }
45
+
46
+                    /**
47
+                     * 获取当前选择行的值
48
+                     * @param cbxDataGrid ComboBoxDataGrid
49
+                     * @returns DataRow.ItemArray
50
+                     */
51
+                    static GetSelectRowValue(cbxDataGrid: ComboBoxDataGrid): string[] | null {
52
+                        const row = this.GetSelectRow(cbxDataGrid);
53
+                        if (row === null) return null;
54
+
55
+                        return row.itemArray.map(obj => obj.toString());
56
+                    }
57
+                }
58
+            }
59
+        }
60
+    }
61
+}
62
+
63
+export default TellerSystem.Library.Ext.TradeExtension.ComboBoxDataGridExtension;

+ 52
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Commands.cs 查看文件

@@ -0,0 +1,52 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Windows.Input;
6
+
7
+namespace TellerSystem.Library.Ext.TradeExtension
8
+{
9
+    /// <summary>
10
+    /// 影像控件
11
+    /// </summary>
12
+    /// <author>jiying</author>
13
+    /// <date>2012/8/28 11:24:17</date>
14
+    public static class Commands
15
+    {
16
+        #region Constructor & destructor
17
+        static Commands()
18
+        {
19
+            // Capture Image
20
+            CaptureImage = new RoutedUICommand("Capture image", "CaptureImage", typeof(Commands));
21
+
22
+            // Remove Image
23
+            RemoveImage = new RoutedUICommand("Remove image", "RemoveImage", typeof(Commands));
24
+
25
+            // Clear All Images
26
+            ClearAllImages = new RoutedUICommand("Clear all images", "ClearAllImages", typeof(Commands));
27
+
28
+            //click Image
29
+            ClickImage = new RoutedUICommand("Click Image", "ClickImage", typeof(Commands));
30
+        }
31
+        #endregion
32
+
33
+        /// <summary>
34
+        /// Captures an image
35
+        /// </summary>
36
+        public static RoutedUICommand CaptureImage { get; private set; }
37
+
38
+        /// <summary>
39
+        /// Removes an image
40
+        /// </summary>
41
+        public static RoutedUICommand RemoveImage { get; private set; }
42
+
43
+        /// <summary>
44
+        /// Clears all images
45
+        /// </summary>
46
+        public static RoutedUICommand ClearAllImages { get; private set; }
47
+        /// <summary>
48
+        /// Click Image _brcapture will get source
49
+        /// </summary>
50
+        public static RoutedUICommand ClickImage { get; private set; }
51
+    }
52
+}

+ 31
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Commands.ts 查看文件

@@ -0,0 +1,31 @@
1
+// 模拟 RoutedUICommand 类
2
+class RoutedUICommand {
3
+    constructor(
4
+        public text: string,
5
+        public name: string,
6
+        public ownerType: any
7
+    ) {}
8
+}
9
+
10
+// 定义 Commands 类
11
+export class Commands {
12
+    static CaptureImage: RoutedUICommand;
13
+    static RemoveImage: RoutedUICommand;
14
+    static ClearAllImages: RoutedUICommand;
15
+    static ClickImage: RoutedUICommand;
16
+
17
+    // 静态初始化块模拟静态构造函数
18
+    static {
19
+        // Capture Image
20
+        Commands.CaptureImage = new RoutedUICommand("Capture image", "CaptureImage", Commands);
21
+
22
+        // Remove Image
23
+        Commands.RemoveImage = new RoutedUICommand("Remove image", "RemoveImage", Commands);
24
+
25
+        // Clear All Images
26
+        Commands.ClearAllImages = new RoutedUICommand("Clear all images", "ClearAllImages", Commands);
27
+
28
+        // click Image
29
+        Commands.ClickImage = new RoutedUICommand("Click Image", "ClickImage", Commands);
30
+    }
31
+}

+ 122
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Currency2DicManager.cs 查看文件

@@ -0,0 +1,122 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using TellerSystem.Communication;
6
+using Platform.Presentation.Interfaces;
7
+using TellerSystem.Library.Ext.Function;
8
+using System.Data;
9
+using TellerSystem.ServiceProxy.Ext.ServiceHelper;
10
+using Platform.Common.RunningParameters;
11
+
12
+namespace TellerSystem.Library.Ext.TradeExtension
13
+{
14
+    class Currency2DicManager
15
+    {
16
+        public Currency2DicManager()
17
+        {
18
+            _dicCurrency = new Dictionary<string, string>();
19
+            _dicTicketDistinct = new Dictionary<string, string>();
20
+            _dicKinbr = new Dictionary<string, string>();
21
+        }
22
+        /// <summary>
23
+        /// 单例
24
+        /// </summary>
25
+        private static Currency2DicManager _instance;
26
+        /// <summary>
27
+        /// 单例
28
+        /// </summary>
29
+        public static Currency2DicManager Instance
30
+        {
31
+            get 
32
+            {
33
+                if (_instance == null)
34
+                    _instance = new Currency2DicManager();
35
+                return _instance; 
36
+            }
37
+        }
38
+        /// <summary>
39
+        /// 币种
40
+        /// </summary>
41
+        private static Dictionary<string, string> _dicCurrency;
42
+        /// <summary>
43
+        /// 券别
44
+        /// </summary>
45
+        private static Dictionary<string, string> _dicTicketDistinct;
46
+        /// <summary>
47
+        /// 机构信息
48
+        /// </summary>
49
+        private static Dictionary<string, string> _dicKinbr;
50
+
51
+        /// <summary>
52
+        /// 获取币种字典
53
+        /// </summary>
54
+        /// <returns></returns>
55
+        public Dictionary<string, string> GetDicCurrency()
56
+        {
57
+            if (_dicCurrency.Count==0)
58
+            {
59
+                Message message = new Message();
60
+                SystemFunction.InitFd(null, message);
61
+                SystemFunction.CommSend(null, message);
62
+                message.Fd16 = "2016";
63
+                var dic = new Dictionary<string, string> ();
64
+                message.FileData = UserFunction.ConvertDictionaryToXML(dic);
65
+                message.TransitNode = TellerSystem.Communication.MessageHelper.TransitType.CallNoFileSys;
66
+                if (message.DoTransit() && message.Fd12 == "0000")
67
+                {
68
+                    DataTable dt = UserFunction.ConvertXMLToDataTable(message.FileData);
69
+                    foreach (DataRow row in dt.Rows)
70
+                    {
71
+                        _dicCurrency.Add(row["CurrencyNo"].ToString(), row["CurrencyName"].ToString());
72
+                    }
73
+                }
74
+            }
75
+            return _dicCurrency;
76
+ 
77
+        }
78
+        /// <summary>
79
+        /// 获取券别字典
80
+        /// </summary>
81
+        /// <returns></returns>
82
+        public Dictionary<string, string> GetDicTicketDistinct()
83
+        {
84
+            if (_dicTicketDistinct.Count == 0)
85
+            {
86
+                Message message = new Message();
87
+                SystemFunction.InitFd(null, message);
88
+                SystemFunction.CommSend(null, message);
89
+                message.Fd16 = "2015";
90
+                var dic = new Dictionary<string, string>();
91
+                message.FileData = UserFunction.ConvertDictionaryToXML(dic);
92
+                message.TransitNode = TellerSystem.Communication.MessageHelper.TransitType.CallNoFileSys;
93
+                if (message.DoTransit() && message.Fd12 == "0000")
94
+                {
95
+                    DataTable dt = UserFunction.ConvertXMLToDataTable(message.FileData);
96
+                    foreach (DataRow row in dt.Rows)
97
+                    {
98
+                        _dicTicketDistinct.Add(row["CouponsNo"].ToString(), row["CouponsName"].ToString());
99
+                    }
100
+                }
101
+            }
102
+            return _dicTicketDistinct;
103
+        }
104
+
105
+        /// <summary>
106
+        /// 获取机构信息的字典
107
+        /// </summary>
108
+        /// <returns></returns>
109
+        public Dictionary<string, string> GetDicKinbr()
110
+        {
111
+            if (_dicKinbr.Count == 0)
112
+            {
113
+                var entitys = TradeManagerHandle.GetAllKinbrInfo(LoginUserInfo.KinbrNo);
114
+                foreach (var entity in entitys)
115
+                {
116
+                    _dicKinbr.Add(entity.KinbrName, entity.KinbrNo);
117
+                }
118
+            }
119
+            return _dicKinbr;
120
+        }
121
+    }
122
+}

+ 118
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Currency2DicManager.ts 查看文件

@@ -0,0 +1,118 @@
1
+// 模拟依赖的类和方法
2
+class Message {
3
+    Fd16: string = '';
4
+    FileData: string = '';
5
+    TransitNode: any;
6
+    Fd12: string = '';
7
+
8
+    DoTransit(): boolean {
9
+        // 模拟消息传输成功
10
+        return true;
11
+    }
12
+}
13
+
14
+namespace SystemFunction {
15
+    export function InitFd(_: any, message: Message) {}
16
+    export function CommSend(_: any, message: Message) {}
17
+}
18
+
19
+namespace UserFunction {
20
+    export function ConvertDictionaryToXML(_: { [key: string]: string }): string {
21
+        return '';
22
+    }
23
+    export function ConvertXMLToDataTable(xml: string): { rows: { [key: string]: string }[] } {
24
+        return { rows: [] };
25
+    }
26
+}
27
+
28
+namespace TellerSystem {
29
+    export namespace Communication {
30
+        export namespace MessageHelper {
31
+            export const TransitType = {
32
+                CallNoFileSys: 'CallNoFileSys'
33
+            };
34
+        }
35
+    }
36
+}
37
+
38
+namespace TradeManagerHandle {
39
+    export function GetAllKinbrInfo(kinbrNo: string) {
40
+        return [];
41
+    }
42
+}
43
+
44
+class LoginUserInfo {
45
+    static get KinbrNo() {
46
+        return '';
47
+    }
48
+}
49
+
50
+class Currency2DicManager {
51
+    private static _instance: Currency2DicManager;
52
+    private _dicCurrency: { [key: string]: string } = {};
53
+    private _dicTicketDistinct: { [key: string]: string } = {};
54
+    private _dicKinbr: { [key: string]: string } = {};
55
+
56
+    private constructor() {
57
+        this._dicCurrency = {};
58
+        this._dicTicketDistinct = {};
59
+        this._dicKinbr = {};
60
+    }
61
+
62
+    static get Instance(): Currency2DicManager {
63
+        if (!this._instance) {
64
+            this._instance = new Currency2DicManager();
65
+        }
66
+        return this._instance;
67
+    }
68
+
69
+    public GetDicCurrency(): { [key: string]: string } {
70
+        if (Object.keys(this._dicCurrency).length === 0) {
71
+            const message = new Message();
72
+            SystemFunction.InitFd(null, message);
73
+            SystemFunction.CommSend(null, message);
74
+            message.Fd16 = '2016';
75
+            const dic: { [key: string]: string } = {};
76
+            message.FileData = UserFunction.ConvertDictionaryToXML(dic);
77
+            message.TransitNode = TellerSystem.Communication.MessageHelper.TransitType.CallNoFileSys;
78
+            if (message.DoTransit() && message.Fd12 === '0000') {
79
+                const dt = UserFunction.ConvertXMLToDataTable(message.FileData);
80
+                dt.rows.forEach((row) => {
81
+                    this._dicCurrency[row['CurrencyNo']] = row['CurrencyName'];
82
+                });
83
+            }
84
+        }
85
+        return this._dicCurrency;
86
+    }
87
+
88
+    public GetDicTicketDistinct(): { [key: string]: string } {
89
+        if (Object.keys(this._dicTicketDistinct).length === 0) {
90
+            const message = new Message();
91
+            SystemFunction.InitFd(null, message);
92
+            SystemFunction.CommSend(null, message);
93
+            message.Fd16 = '2015';
94
+            const dic: { [key: string]: string } = {};
95
+            message.FileData = UserFunction.ConvertDictionaryToXML(dic);
96
+            message.TransitNode = TellerSystem.Communication.MessageHelper.TransitType.CallNoFileSys;
97
+            if (message.DoTransit() && message.Fd12 === '0000') {
98
+                const dt = UserFunction.ConvertXMLToDataTable(message.FileData);
99
+                dt.rows.forEach((row) => {
100
+                    this._dicTicketDistinct[row['CouponsNo']] = row['CouponsName'];
101
+                });
102
+            }
103
+        }
104
+        return this._dicTicketDistinct;
105
+    }
106
+
107
+    public GetDicKinbr(): { [key: string]: string } {
108
+        if (Object.keys(this._dicKinbr).length === 0) {
109
+            const entitys = TradeManagerHandle.GetAllKinbrInfo(LoginUserInfo.KinbrNo);
110
+            entitys.forEach((entity) => {
111
+                this._dicKinbr[entity.KinbrName] = entity.KinbrNo;
112
+            });
113
+        }
114
+        return this._dicKinbr;
115
+    }
116
+}
117
+
118
+export default Currency2DicManager;

+ 2150
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/DataBoxExtension.cs
文件差異過大導致無法顯示
查看文件


+ 275
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/DataBoxExtension.ts 查看文件

@@ -0,0 +1,275 @@
1
+// 模拟 DataBox 类
2
+class DataBox {
3
+    DataBoxHost: DataGrid;
4
+    DataSource: DataTable;
5
+    IsShowPrintButton: boolean;
6
+    IsShowExportButton: boolean;
7
+    IsMultiSelected: boolean;
8
+    IsShowPageBar: boolean;
9
+    PrintButtonClick: (sender: any, e: any) => void;
10
+    ExportButtonClick: (sender: any, e: any) => void;
11
+    CustomerPrintPreview: (topMsg?: string, bottomMsg?: string) => void;
12
+    GetDataTableForPrint: () => DataTable;
13
+    FindVisualTreeAncestor: (predicate: (d: any) => boolean) => any;
14
+    GetIsBinding: () => boolean;
15
+    DataBindBeginEvent: () => void;
16
+    DataBindEndEvent: () => void;
17
+    HotkeyControlEvent: (e: any) => boolean;
18
+    IsShowRadioColumn: boolean;
19
+    SetValue: (property: any, value: any) => void;
20
+    GetValue: (property: any) => any;
21
+    DataBinding: (data: any) => void;
22
+
23
+    constructor() {
24
+        this.DataBoxHost = new DataGrid();
25
+        this.DataSource = new DataTable();
26
+        this.IsShowPrintButton = false;
27
+        this.IsShowExportButton = false;
28
+        this.IsMultiSelected = false;
29
+        this.IsShowPageBar = false;
30
+    }
31
+}
32
+
33
+// 模拟 DataGrid 类
34
+class DataGrid {
35
+    ItemsSource: any;
36
+    Columns: DataGridColumn[];
37
+    Rows: () => any[];
38
+    SelectedItem: any;
39
+    AutoGenerateColumns: boolean;
40
+    AutoColumnWidth: () => void;
41
+    GetTable: () => DataTable;
42
+    PrintDialog: () => void;
43
+    SetDisplayMode: (mode: any) => void;
44
+    ZoomMode: any;
45
+    LocalReport: {
46
+        LoadReportDefinition: (stream: any) => void;
47
+        DataSources: {
48
+            Add: (dataSource: any) => void;
49
+        };
50
+        SetParameters: (parameters: any[]) => void;
51
+        RefreshReport: () => void;
52
+    };
53
+    RenderingComplete: (sender: any, e: any) => void;
54
+
55
+    constructor() {
56
+        this.ItemsSource = null;
57
+        this.Columns = [];
58
+    }
59
+}
60
+
61
+// 模拟 DataTable 类
62
+class DataTable {
63
+    Rows: any[];
64
+    Columns: DataColumn[];
65
+    Clone: () => DataTable;
66
+    ImportRow: (row: any) => void;
67
+    AcceptChanges: () => void;
68
+    Copy: () => DataTable;
69
+
70
+    constructor() {
71
+        this.Rows = [];
72
+        this.Columns = [];
73
+    }
74
+}
75
+
76
+// 模拟 DataColumn 类
77
+class DataColumn {
78
+    ColumnName: string;
79
+    DataType: any;
80
+
81
+    constructor(name: string, type?: any) {
82
+        this.ColumnName = name;
83
+        this.DataType = type || String;
84
+    }
85
+}
86
+
87
+// 模拟 DataGridColumn 类
88
+class DataGridColumn {
89
+    Header: string;
90
+    SortMemberPath: string;
91
+    Visibility: any;
92
+    ActualWidth: number;
93
+    Width: any;
94
+
95
+    constructor() {
96
+        this.Header = "";
97
+        this.SortMemberPath = "";
98
+        this.Visibility = "Visible";
99
+        this.ActualWidth = 0;
100
+    }
101
+}
102
+
103
+// 模拟其他辅助类和方法
104
+class DataGridTextColumn extends DataGridColumn {}
105
+class DataGridComboBoxColumn extends DataGridColumn {}
106
+class DataGridTemplateColumn extends DataGridColumn {}
107
+class MessageBox {
108
+    static Show(message: string) {
109
+        console.log(message);
110
+    }
111
+}
112
+class File {
113
+    static Delete(path: string) {}
114
+}
115
+class Stream {
116
+    static Load(path: string) {
117
+        return null;
118
+    }
119
+}
120
+class ReportWindow {
121
+    Report: DataGrid;
122
+    ShowDialog: () => void;
123
+    Source: any;
124
+}
125
+
126
+// 枚举类型
127
+enum DisplayLevelEnum {
128
+    All,
129
+    Right,
130
+    Intelligence
131
+}
132
+
133
+// 扩展类
134
+class DataBoxExtension {
135
+    // 常量
136
+    static readonly COL_SPLITTER = '|';
137
+    static readonly ROW_SPLITTER = '\n';
138
+    static readonly MONEY_SYMBOL = '$';
139
+    static readonly DATE_SYMBOL = '#';
140
+    static readonly HEAD_SYMBOL = '~';
141
+    static readonly LEFT_SYMBOL = '@';
142
+
143
+    // 打印相关附加属性
144
+    static readonly PrintColumnsProperty = { name: 'PrintColumns', defaultValue: null };
145
+    static readonly PageMarginProperty = { name: 'PageMargin', defaultValue: { left: 0, top: 0, right: 0, bottom: 0.5 } };
146
+    static readonly IsVerticalProperty = { name: 'IsVertical', defaultValue: false };
147
+    static readonly IsCustomizePrintProperty = { name: 'IsCustomizePrint', defaultValue: false };
148
+
149
+    // 初始化方法
150
+    static InitDataBox(dataBox: DataBox) {
151
+        dataBox.DataBoxHost.ItemsSource = null;
152
+        dataBox.DataBoxHost.Columns = [];
153
+
154
+        this.RemoveAllEventHandler(dataBox.DataBoxHost, "_dataBindBeginEvent", "DataBindBeginEvent");
155
+        this.RemoveAllEventHandler(dataBox.DataBoxHost, "_dataBindEndEvent", "DataBindEndEvent");
156
+        this.RemoveAllEventHandler(dataBox, "_hotkeyControlEvent", "HotkeyControlEvent");
157
+    }
158
+
159
+    // 移除事件处理程序
160
+    static RemoveAllEventHandler(obj: any, eventName: string, propEvent: string) {
161
+        // 由于 TypeScript 没有直接的反射机制,这里简化处理
162
+    }
163
+
164
+    // 获取 DataTable 数据
165
+    static GetDataForDataTable(dataBox: DataBox): DataTable {
166
+        return dataBox.DataSource;
167
+    }
168
+
169
+    // 获取字符串数据
170
+    static GetDataForString(dataBox: DataBox, col_splitter?: string): string {
171
+        if (!col_splitter) {
172
+            col_splitter = this.COL_SPLITTER.toString();
173
+        }
174
+        const dataTable = this.GetDataForDataTable(dataBox);
175
+        if (!dataTable) {
176
+            return null;
177
+        }
178
+        let fileData = "";
179
+        for (let i = 0; i < dataTable.Rows.length; i++) {
180
+            for (let j = 0; j < dataTable.Columns.length; j++) {
181
+                fileData += dataTable.Rows[i][j].toString() + col_splitter;
182
+            }
183
+            fileData += this.ROW_SPLITTER.toString();
184
+        }
185
+        return fileData;
186
+    }
187
+
188
+    // 解析 XML 字符串
189
+    static AnalyzeXMLtoStr(xmlSource: string, nodeName: string): string {
190
+        let result = "";
191
+        if (!xmlSource) {
192
+            return result;
193
+        }
194
+        // 由于 TypeScript 没有直接的 XML 解析类,这里简化处理
195
+        return result;
196
+    }
197
+
198
+    // 绑定 DataTable 数据源
199
+    static BindDataTable(dataBox: DataBox, dtSource: DataTable) {
200
+        if (dataBox.IsShowPrintButton) {
201
+            dataBox.PrintButtonClick = this.databox_PrintButtonClick.bind(this);
202
+        }
203
+        if (dataBox.IsShowExportButton) {
204
+            dataBox.ExportButtonClick = this.databox_ExportButtonClick.bind(this);
205
+        }
206
+        dataBox.DataBoxHost.AutoGenerateColumns = false;
207
+        this.BuildDataGridColumn(dataBox, dtSource);
208
+        dataBox.DataBinding(dtSource);
209
+    }
210
+
211
+    // 打印按钮点击事件
212
+    static databox_PrintButtonClick(sender: any, e: any) {
213
+        const db = (sender as any).FindVisualTreeAncestor((d: any) => d instanceof DataBox) as DataBox;
214
+        if (db) {
215
+            db.CustomerPrintPreview();
216
+        } else {
217
+            MessageBox.Show("未找到 DataBox 对象,无法产生打印对象!");
218
+        }
219
+    }
220
+
221
+    // 导出按钮点击事件
222
+    static databox_ExportButtonClick(sender: any, e: any) {
223
+        const db = (sender as any).FindVisualTreeAncestor((d: any) => d instanceof DataBox) as DataBox;
224
+        if (db) {
225
+            const table = db.GetDataTableForPrint();
226
+            if (table && table.Rows.length > 0) {
227
+                // 模拟导出逻辑
228
+            }
229
+        }
230
+    }
231
+
232
+    // 自动设置列宽
233
+    static AutoColumnWidth(databox: DataGrid) {
234
+        let DataActualWidth = databox.Rows().length;
235
+        const columnCount = databox.Columns.length;
236
+        if (columnCount === 0) {
237
+            return;
238
+        }
239
+        for (let i = 0; i < columnCount; i++) {
240
+            DataActualWidth += databox.Columns[i].ActualWidth;
241
+        }
242
+        if (databox.ActualWidth > DataActualWidth) {
243
+            databox.Columns[columnCount - 1].Width = databox.Columns[columnCount - 1].Width + databox.ActualWidth - DataActualWidth;
244
+        }
245
+    }
246
+
247
+    // 数据绑定方法(部分重载)
248
+    static DataBinding(dataBox: DataBox, fileData: string, level: DisplayLevelEnum, ...columnNames: string[]) {
249
+        // 实现数据绑定逻辑
250
+    }
251
+
252
+    // 设置列标题
253
+    static SetColumnsHeader(dataBox: DataBox, columnIndex: number, header: string) {
254
+        const DataBindEndHandler = () => {
255
+            const index = this.GetColumnIndex(dataBox, columnIndex);
256
+            if (dataBox.DataBoxHost.Columns.length <= index) {
257
+                return;
258
+            }
259
+            dataBox.DataBoxHost.Columns[index].Header = header;
260
+        };
261
+        if (dataBox.GetIsBinding()) {
262
+            DataBindEndHandler();
263
+        }
264
+        dataBox.DataBoxHost.DataBindEndEvent = DataBindEndHandler;
265
+    }
266
+
267
+    // 其他方法...
268
+
269
+    // 打印预览
270
+    static PrintPreview(dataBox: DataBox, title: string, topMsg?: string, bottomMsg?: string) {
271
+        // 实现打印预览逻辑
272
+    }
273
+}
274
+
275
+export { DataBoxExtension, DisplayLevelEnum };

+ 839
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ExcelToTxt.cs 查看文件

@@ -0,0 +1,839 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using Microsoft.Office.Interop.Excel;
6
+using Microsoft.Office.Interop;
7
+using System.Diagnostics;
8
+using System.Data;
9
+using System.IO;
10
+
11
+namespace TellerSystem.Library.Ext.TradeExtension
12
+{
13
+    public class ExcelToTxt
14
+    {
15
+        #region Feilds
16
+        private Stopwatch wath = new Stopwatch();
17
+
18
+        /// <summary>
19
+        /// 转换后的文件文本内容
20
+        /// </summary>
21
+        private string changedFileContant = string.Empty;
22
+
23
+        private bool isHasTotalMoneyAndTotalCout = false;
24
+
25
+        private List<string> tableColumNames = new List<string>();
26
+
27
+        private string sourceFileFullName = string.Empty;
28
+
29
+        private System.Data.DataTable tableTypeData;
30
+        #endregion
31
+
32
+        #region Properties
33
+
34
+        /// <summary>
35
+        /// 总金额
36
+        /// </summary>
37
+        public double TotalMoney
38
+        {
39
+            get;
40
+            set;
41
+        }
42
+
43
+        /// <summary>
44
+        /// 总笔数
45
+        /// </summary>
46
+        public int TotalCount
47
+        {
48
+            get;
49
+            set;
50
+        }
51
+
52
+        /// <summary>
53
+        /// 文件转换后表格的所有列名称
54
+        /// </summary>
55
+        public List<string> TableColumNames
56
+        {
57
+            get
58
+            {
59
+                if (this.tableColumNames.Count == 0)
60
+                {
61
+                    foreach (DataColumn dc in this.TableTypeData.Columns)
62
+                    {
63
+                        this.tableColumNames.Add(dc.ColumnName);
64
+                    }
65
+                }
66
+                return this.tableColumNames;
67
+            }
68
+            set
69
+            {
70
+                if (value.Count > 0)
71
+                {
72
+                    foreach (string colName in value)
73
+                    {
74
+                        if (!this.TableTypeData.Columns.Contains(colName))
75
+                        {
76
+                            this.TableTypeData.Columns.Add(new DataColumn(colName));
77
+                        }
78
+                    }
79
+                }
80
+            }
81
+        }
82
+
83
+        /// <summary>
84
+        /// 目标文件头
85
+        /// </summary>
86
+        public string TargetFileHead { get; set; }
87
+
88
+        /// <summary>
89
+        /// 目标文件尾
90
+        /// </summary>
91
+        public string TargetFileEnd { get; set; }
92
+
93
+        /// <summary>
94
+        /// 数据的表格表现形式
95
+        /// </summary>
96
+        public System.Data.DataTable TableTypeData
97
+        {
98
+            get
99
+            {
100
+                return this.tableTypeData;
101
+            }
102
+            private set
103
+            {
104
+                this.tableTypeData = value;
105
+                if (value.Columns.Count == 0 && this.TableColumNames.Count > 0)
106
+                {
107
+                    foreach (string colName in this.TableColumNames)
108
+                    {
109
+                        this.TableTypeData.Columns.Add(new DataColumn(colName));
110
+                    }
111
+                }
112
+            }
113
+        }
114
+
115
+        /// <summary>
116
+        /// 源文件类型
117
+        /// </summary>
118
+        public FileType SourceFileType
119
+        {
120
+            get;
121
+            private set;
122
+        }
123
+
124
+        /// <summary>
125
+        /// 源文件名称
126
+        /// </summary>
127
+        public string SourceFileName
128
+        {
129
+            get { return this.SourceFileFullName.Split("\\".ToCharArray()).Last(); }
130
+        }
131
+
132
+        /// <summary>
133
+        /// 转换后的文件名称
134
+        /// </summary>
135
+        public string TargetFileName
136
+        {
137
+            get { return this.TargetFileFullName.Split("\\".ToCharArray()).Last(); }
138
+        }
139
+
140
+        /// <summary>
141
+        /// 源文件(转换前的excel或者txt的完整名称)
142
+        /// </summary>
143
+        public string SourceFileFullName
144
+        {
145
+            get { return this.sourceFileFullName; }
146
+            set
147
+            {
148
+                this.sourceFileFullName = value;
149
+                if (value.ToLower().EndsWith(".txt"))
150
+                {
151
+                    this.SourceFileType = FileType.TXT;
152
+                }
153
+                else
154
+                {
155
+                    this.SourceFileType = FileType.EXCEL;
156
+                }
157
+            }
158
+        }
159
+
160
+        /// <summary>
161
+        /// 目标文件(转换后的txt的完整名称)
162
+        /// </summary>
163
+        public string TargetFileFullName
164
+        {
165
+            get;
166
+            set;
167
+        }
168
+
169
+        /// <summary>
170
+        /// 转换后的文件文本内容
171
+        /// </summary>
172
+        public string ChangedFileContant
173
+        {
174
+            get
175
+            {
176
+                if (this.isHasTotalMoneyAndTotalCout)
177
+                {
178
+                    return this.TargetFileHead + this.changedFileContant + this.TargetFileEnd;
179
+                }
180
+                else
181
+                {
182
+                    return string.Format(this.TargetFileHead + "\n" + this.changedFileContant + this.TargetFileEnd, this.TotalCount.ToString(), this.TotalMoney.ToString());
183
+                }
184
+            }
185
+        }
186
+        #endregion
187
+
188
+        public ExcelToTxt(string sourceFile, string targetFile) : this()
189
+        {
190
+            this.SourceFileFullName = sourceFile;
191
+            this.TargetFileFullName = targetFile;
192
+        }
193
+
194
+        public ExcelToTxt()
195
+        {
196
+            this.TableTypeData = new System.Data.DataTable();
197
+            this.TargetFileHead = "TOTAL NO ";
198
+            this.TargetFileEnd = "\nEND";
199
+        }
200
+
201
+        public bool ChangeExcelToTxt()
202
+        {
203
+            if (string.IsNullOrEmpty(this.SourceFileFullName))
204
+            {
205
+                throw new ArgumentException("找不到指定路径:" + this.SourceFileFullName + "的一部分。", "SourceFile");
206
+            }
207
+            return this.ChangeExcelToTxt(this.SourceFileFullName);
208
+        }
209
+
210
+        /// <summary>
211
+        /// 将txt转换成指定的格式
212
+        /// </summary>
213
+        /// <param name="fileFullName">需转换的文件路径</param>
214
+        /// <param name="changedFileContant">转换后的文本内容</param>
215
+        /// <returns>转换是否成功</returns>
216
+        public bool ChangeExcelToTxt(string fileFullName)
217
+        {
218
+            return ChangeExcelToTxt(fileFullName, 0, 0, false, 1);
219
+        }
220
+
221
+        /// <summary>
222
+        /// 将excel文件转换成指定的txt格式
223
+        /// </summary>
224
+        /// <param name="filePath">需转换的文件路径</param>
225
+        /// <param name="changedFileContant">转换后的文本内容</param>
226
+        /// <param name="headLineCount">sheet中表头的行数</param>
227
+        /// <param name="needName">是否需要表中的名称</param>
228
+        /// <param name="beginLine">表开始的行数,即就是表中名称的行标(从1开始)</param>
229
+        /// <returns>转换是否成功</returns>
230
+        public bool ChangeExcelToTxt(string filePath, int headLineCount, int endLineCount, bool hasColumnTitle, int beginLine)
231
+        {
232
+            bool result = false;
233
+            this.SourceFileFullName = filePath;
234
+            if (string.IsNullOrEmpty(this.SourceFileFullName))
235
+            {
236
+                throw new ArgumentException("找不到指定路径:" + this.SourceFileFullName + "的一部分。", "SourceFile");
237
+            }
238
+            try
239
+            {
240
+                if (this.SourceFileFullName.EndsWith(".xls") || this.SourceFileFullName.EndsWith(".xlsx"))
241
+                {
242
+                    this.changedFileContant = this.ExcelToText(filePath, headLineCount, endLineCount, hasColumnTitle, beginLine);
243
+                }
244
+            }
245
+            catch (Exception)
246
+            {
247
+                changedFileContant = string.Empty;
248
+            }
249
+            return result;
250
+        }
251
+
252
+        /// <summary>
253
+        /// 只处理了第一个sheet页,如果有更多sheet页需要做调整  
254
+        /// </summary>
255
+        /// <param name="filePath">文件路径</param>
256
+        /// <param name="headLineCount">sheet中表头的行数</param> 
257
+        /// <param name="needName">是否需要表中的名称</param>
258
+        /// <param name="beginLine">表开始的行数,即就是表中名称的行标</param>
259
+        private string ExcelToText(string filePath, int headLineCount, int endLineCount, bool hasColumnTitle, int beginLine)
260
+        {
261
+            isHasTotalMoneyAndTotalCout = true;
262
+            string head = string.Empty;
263
+            string data = string.Empty;
264
+            this.TableTypeData.Clear();
265
+            Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
266
+            Sheets sheets;
267
+            Workbook workbook = null;
268
+            object oMissiong = System.Reflection.Missing.Value;
269
+            System.Data.DataTable dt = new System.Data.DataTable();
270
+
271
+            //当前行索引
272
+            int currentRowIndex = 0;
273
+            //当前列索引
274
+            int currentColIndex = 0;
275
+            wath.Start();
276
+
277
+            try
278
+            {
279
+                if (app == null)
280
+                {
281
+                    return head + data;
282
+                }
283
+                workbook = app.Workbooks.Open(filePath, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong);
284
+                sheets = workbook.Worksheets;
285
+                Worksheet worksheet = (Worksheet)sheets.get_Item(1);//读取第一张表   
286
+                //总行数
287
+                int rowCount = worksheet.UsedRange.Rows.Count;
288
+                if (worksheet == null)
289
+                    return head + data;
290
+
291
+                #region 处理表头
292
+                for (int i = beginLine; i < beginLine + headLineCount; i++)
293
+                {
294
+                    currentRowIndex = i;
295
+                    foreach (Range rc in worksheet.UsedRange.Rows[i].Columns)
296
+                    {
297
+                        currentColIndex++;
298
+                        var cells = ((dynamic)rc).Cells;
299
+                        if (cells != null && !string.IsNullOrEmpty(cells.Text.Trim()))
300
+                        {
301
+                            if (cells.Text.Contains(":"))
302
+                            {
303
+                                continue;
304
+                            }
305
+                            head += cells.Text.Trim() + " ";
306
+                        }
307
+                    }
308
+                }
309
+                #endregion
310
+
311
+                #region 处理表中数据内容
312
+                for (int i = beginLine + headLineCount; i <= rowCount - endLineCount; i++)
313
+                {
314
+                    string tempData = string.Empty;
315
+                    currentColIndex = 0;
316
+                    currentRowIndex = i;
317
+                    if (hasColumnTitle)
318
+                    {
319
+                        foreach (Range rc in worksheet.UsedRange.Rows[i].Columns)
320
+                        {
321
+                            currentColIndex++;
322
+                            var cells = ((dynamic)rc).Cells;
323
+                            if (cells != null && !string.IsNullOrEmpty(cells.Text.Trim()))
324
+                            {
325
+                                this.TableTypeData.Columns.Add(cells.Text.Trim());
326
+                            }
327
+                        }
328
+                        hasColumnTitle = false;
329
+                        continue;
330
+                    }
331
+                    //处理表里面的数据内容
332
+                    #region Data
333
+                    System.Data.DataRow dr = this.TableTypeData.NewRow();
334
+                    bool isAddRow = false;
335
+                    #region
336
+                    foreach (Range rc in worksheet.UsedRange.Rows[i].Columns)
337
+                    {
338
+                        currentColIndex++;
339
+                        string temp = string.Empty;
340
+                        var cells = ((dynamic)rc).Cells;
341
+                        if (cells != null && !string.IsNullOrEmpty(cells.Text.Trim()))
342
+                        {
343
+                            string t = temp = cells.Text;
344
+                            DateTime dateTime;
345
+                            if ((t.Contains(":") || t.Contains("-") || t.Contains("/")) && DateTime.TryParse(t, out dateTime))
346
+                            {
347
+                                if (dateTime.Hour != 0)
348
+                                {
349
+                                    t = dateTime.ToString("hhmmss");
350
+                                    temp = dateTime.ToString("hh:mm:ss");
351
+                                }
352
+                                else
353
+                                {
354
+                                    t = dateTime.ToString("yyyyMMdd");
355
+                                    temp = dateTime.ToString("yyyy-MM-dd");
356
+                                }
357
+                            }
358
+                            tempData += t.Trim() + " ";
359
+                            dr[currentColIndex - 1] = temp;
360
+                            isAddRow = true;
361
+                        }
362
+                    }
363
+                    if (isAddRow)
364
+                    {
365
+                        this.TableTypeData.Rows.Add(dr);
366
+                    }
367
+                    #endregion
368
+                    if (!string.IsNullOrEmpty(tempData.Trim()))
369
+                    {
370
+                        data += "\n"+tempData.TrimEnd(' ');
371
+                    }
372
+                    #endregion
373
+                }
374
+                #endregion
375
+
376
+                #region 处理表尾
377
+                for (int i = rowCount - endLineCount + 1; i <= rowCount; i++)
378
+                {
379
+                    currentColIndex = 0;
380
+                    currentRowIndex = i;
381
+                    string temp = string.Empty;
382
+                    foreach (Range rc in worksheet.UsedRange.Rows[i].Columns)
383
+                    {
384
+                        currentColIndex++;
385
+                        var cells = ((dynamic)rc).Cells;
386
+                        if (cells != null && !string.IsNullOrEmpty(cells.Text.Trim()))
387
+                        {
388
+                            if (cells.Text.Contains(":"))
389
+                            {
390
+                                continue;
391
+                            }
392
+                            temp += cells.Text.Trim() + " ";
393
+                        }
394
+                    }
395
+                    head = temp + head;
396
+                }
397
+                #endregion
398
+
399
+                wath.Stop();
400
+                TimeSpan ts = wath.Elapsed;
401
+                return head + data;
402
+            }
403
+            catch (Exception e)
404
+            {
405
+                throw new Exception(string.Format("‘{0}’行,‘{1}’列初数据转换错误。", currentRowIndex,currentColIndex));
406
+            }
407
+            finally
408
+            {
409
+                workbook.Close(false, oMissiong, oMissiong);
410
+                System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook);
411
+                workbook = null;
412
+                app.Workbooks.Close();
413
+                app.Quit();
414
+                System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
415
+                app = null;
416
+                GC.Collect();
417
+                GC.WaitForPendingFinalizers();
418
+            }
419
+        }
420
+
421
+        public bool Save()
422
+        {
423
+            if (string.IsNullOrEmpty(this.TargetFileFullName))
424
+            {
425
+                throw new ArgumentException("找不到指定路径:" + this.TargetFileFullName + "的一部分。", "TargetFile");
426
+            }
427
+            return this.Save(this.TargetFileFullName, this.ChangedFileContant);
428
+        }
429
+
430
+        public bool Save(string targetFile)
431
+        {
432
+            if (string.IsNullOrEmpty(targetFile))
433
+            {
434
+                throw new ArgumentException("找不到指定路径:" + targetFile + "的一部分。", "TargetFile");
435
+            }
436
+            return this.Save(targetFile, this.ChangedFileContant);
437
+        }
438
+
439
+        /// <summary>
440
+        /// 保存成*.txt文件件
441
+        /// </summary>
442
+        /// <param name="targetFile">保存文件名称</param>
443
+        public bool Save(string targetFile, string fileContant)
444
+        {
445
+            this.TargetFileFullName = targetFile;
446
+            using (FileStream fs = File.OpenWrite(targetFile))
447
+            {
448
+                byte[] bt = Encoding.Default.GetBytes(fileContant);
449
+                fs.Write(bt, 0, bt.Count());
450
+                fs.Flush();
451
+                fs.Close();
452
+            }
453
+            return true;
454
+        }
455
+
456
+        /// <summary>
457
+        /// 
458
+        /// </summary>
459
+        /// <param name="sourceFile">原文件名</param>
460
+        /// <param name="countColumnName">需要计算的列名(如果没有需要计算的列,传“”或者String.Empty)</param>
461
+        public void TxtToDataTableColumnName(string sourceFile, string countColumnName)
462
+        {
463
+            string temp = string.Empty;
464
+            temp = File.ReadAllText(sourceFile, Encoding.Default);
465
+            temp = temp.Replace("\r\n", "\n");
466
+            this.TargetFileHead = (this.isHasTotalMoneyAndTotalCout = temp.StartsWith("TOTAL")) ? "" : this.TargetFileHead + "{0} {1}";
467
+            this.changedFileContant = temp.Replace('^', ' ');
468
+            this.ToDataTable(" ", countColumnName);
469
+        }
470
+        /// <summary>
471
+        /// 
472
+        /// </summary>
473
+        /// <param name="sourceFile">原文件名</param>
474
+        /// <param name="countColumnName">需要计算的列名(如果没有需要计算的列,传“”或者String.Empty)</param>
475
+        /// <param name="splitChar">txt文件的分隔符</param>
476
+        public void TxtToDataTableColumnName(string sourceFile, string countColumnName,string splitChar)
477
+        {
478
+            string temp = string.Empty;
479
+            temp = File.ReadAllText(sourceFile, Encoding.Default);
480
+            temp = temp.Replace("\r\n", "\n");
481
+            this.TargetFileHead = (this.isHasTotalMoneyAndTotalCout = temp.StartsWith("TOTAL")) ? "" : this.TargetFileHead + "{0} {1}";
482
+            this.changedFileContant = temp.Replace('^', ' ');
483
+            this.ToDataTable(splitChar, countColumnName);
484
+        }
485
+        /// <summary>
486
+        /// 
487
+        /// </summary>
488
+        /// <param name="sourceFile">原文件名</param>
489
+        /// <param name="countColumnName">需要计算的列名(如果没有需要计算的列,传“”或者String.Empty)</param>
490
+        /// /// <param name="t">是否忽略文件第一行</param>
491
+        public void TxtToDataTableColumnName(string sourceFile, string countColumnName,bool t)
492
+        {
493
+            string temp = string.Empty;
494
+            temp = File.ReadAllText(sourceFile, Encoding.Default);
495
+            temp = temp.Replace("\r\n", "\n");
496
+            this.TargetFileHead = (this.isHasTotalMoneyAndTotalCout = temp.StartsWith("TOTAL")) ? "" : this.TargetFileHead + "{0} {1}";
497
+            this.changedFileContant = temp.Replace('^', ' ');
498
+            this.ToDataTable(" ", countColumnName,t);
499
+        }
500
+
501
+        /// <summary>
502
+        /// 专门对应txt格式s文件
503
+        /// </summary>
504
+        /// <param name="sourceFile">源文件名称</param>
505
+        /// <param name="count">总笔数</param>
506
+        /// <param name="totalMoney">总金额</param>
507
+        /// <param name="beginLine">开始行</param>
508
+        /// <param name="splitChar">分割字符</param>
509
+        public void TxtToDataTable(string sourceFile)
510
+        {
511
+            this.TotalCount = 0;
512
+            List<string> needLines = new List<string>();
513
+            string[] lines = File.ReadAllLines(sourceFile, Encoding.Default);
514
+            for (int i = 0; i < lines.Length; i++)
515
+            {
516
+                if (lines[i].StartsWith("U"))
517
+                {
518
+                    this.TotalCount++;
519
+                    needLines.Add(lines[i]);
520
+                    this.changedFileContant += lines[i] + "\n";
521
+                }
522
+            }
523
+            this.TargetFileHead += "{0} {1} ";
524
+            this.changedFileContant = this.changedFileContant.Trim("\n".ToCharArray()).Replace('^', ' ');
525
+            this.ToDataTable(" ", string.Empty);
526
+        }
527
+
528
+        /// <summary>
529
+        /// 对于批量返回的txt文件
530
+        /// </summary>
531
+        /// <param name="sourceFile">源文件名称</param>
532
+        /// <param name="count">总笔数</param>
533
+        /// <param name="totalMoney">总金额</param>
534
+        /// <param name="splitChar">分割字符</param>
535
+        public void TxtToDataTable(string sourceFile, string splitChar)
536
+        {
537
+            this.changedFileContant = File.ReadAllText(sourceFile, Encoding.Default);
538
+            this.ToDataTable(splitChar, string.Empty);
539
+        }
540
+
541
+        private void ToDataTable(string splitChar, string countColumn)
542
+        {
543
+            string[] strs = this.ChangedFileContant.Split('\n');
544
+            int i = 0;
545
+            //是否计算总笔数
546
+            bool needAddTotalCount = false;
547
+            //是否计算总金额
548
+            bool needCountTotalMoney = false;
549
+            if (strs != null)
550
+            {
551
+                this.TableTypeData.Clear();
552
+                foreach (string item in strs)
553
+                {   
554
+                    if (item.StartsWith("END"))
555
+                    {
556
+                        break;
557
+                    }
558
+                    if (string.IsNullOrEmpty(item.Trim()))
559
+                    {
560
+                        continue;  
561
+                    }
562
+                    if (item=='\n'.ToString())
563
+                    {
564
+                        continue;
565
+                    }
566
+                    string[] strT = item.Split(splitChar.ToCharArray(),StringSplitOptions.None);
567
+                    if (strT == null || strT.Length < 1)
568
+                    {
569
+                        throw new FileFormatException("不可处理的文件格式。");
570
+                    }
571
+                    if (i == 0)
572
+                    {
573
+                        this.TargetFileHead = strT[0] + " " + strT[1] + " {0} {1} ";
574
+                        this.TotalCount = Convert.ToInt32(strT[2]);
575
+                        needAddTotalCount = this.TotalCount > 0 ? false : true;
576
+                        this.TotalMoney = Convert.ToDouble(strT[3]);
577
+                        needCountTotalMoney = this.TotalMoney > 0 ? false : true;
578
+                        if (strT.Length > 4)
579
+                        {
580
+                            for (int j = 4; j < strT.Length; j++)
581
+                            {
582
+                                this.TargetFileHead += strT[j];
583
+                            }
584
+                        }
585
+                    }
586
+                    else
587
+                    {
588
+                        DataRow dr = this.TableTypeData.NewRow();
589
+                        for (int j = 0; j < strT.Length; j++)
590
+                        {
591
+                            dr[j] = strT[j];
592
+                        }
593
+                        if (!string.IsNullOrEmpty(countColumn) && needCountTotalMoney)
594
+                        {
595
+                            if (!Convert.IsDBNull(dr[countColumn])&&dr[countColumn]!=null)
596
+                            {
597
+                                this.TotalMoney += Convert.ToDouble(dr[countColumn]);
598
+                            }
599
+                            
600
+                        }   
601
+
602
+                        this.TotalCount = needAddTotalCount? this.TotalCount+1:this.TotalCount;
603
+                        this.TableTypeData.Rows.Add(dr);
604
+                    }
605
+                    i++;
606
+                }
607
+            }
608
+            else
609
+            {
610
+                throw new FileFormatException("不可处理的文件格式。");
611
+            }
612
+
613
+        }
614
+
615
+        private void ToDataTable(string splitChar, string countColumn,bool t)
616
+        {
617
+            string[] strs = this.ChangedFileContant.Split('\n');
618
+            int i = 0;
619
+            //是否计算总笔数
620
+            bool needAddTotalCount = false;
621
+            //是否计算总金额
622
+            bool needCountTotalMoney = false;
623
+            if (strs != null)
624
+            {
625
+                this.TableTypeData.Clear();
626
+                foreach (string item in strs)
627
+                {
628
+                    if (item.StartsWith("END"))
629
+                    {
630
+                        break;
631
+                    }
632
+                    if (string.IsNullOrEmpty(item.Trim()))
633
+                    {
634
+                        continue;
635
+                    }
636
+                    if (!t&&item.StartsWith("TOTAL"))
637
+                    {
638
+                        continue;
639
+                    }
640
+                    string[] strT = item.Split(splitChar.ToCharArray(), StringSplitOptions.None);
641
+                    if (strT == null || strT.Length < 1)
642
+                    {
643
+                        throw new FileFormatException("不可处理的文件格式。");
644
+                    }
645
+                    if (t)
646
+                    {
647
+                        if (t)
648
+                        {
649
+                            this.TargetFileHead = strT[0] + " " + strT[1] + " {0} {1} ";
650
+                            this.TotalCount = Convert.ToInt32(strT[2]);
651
+                            needAddTotalCount = this.TotalCount > 0 ? false : true;
652
+                            this.TotalMoney = Convert.ToDouble(strT[3]);
653
+                            needCountTotalMoney = this.TotalMoney > 0 ? false : true;
654
+                        }
655
+                        if (strT.Length > 4)
656
+                        {
657
+                            for (int j = 4; j < strT.Length; j++)
658
+                            {
659
+                                this.TargetFileHead += strT[j];
660
+                            }
661
+                        }
662
+                    }
663
+                    else
664
+                    {
665
+                        DataRow dr = this.TableTypeData.NewRow();
666
+                        for (int j = 0; j < strT.Length; j++)
667
+                        {
668
+                            dr[j] = strT[j];
669
+                        }
670
+                        if (!string.IsNullOrEmpty(countColumn) && needCountTotalMoney)
671
+                        {
672
+                            this.TotalMoney += Convert.ToDouble(dr[countColumn]);
673
+                        }
674
+
675
+                        this.TotalCount = needAddTotalCount ? this.TotalCount + 1 : this.TotalCount;
676
+                        this.TableTypeData.Rows.Add(dr);
677
+                    }
678
+                    i++;
679
+                }
680
+            }
681
+            else
682
+            {
683
+                throw new FileFormatException("不可处理的文件格式。");
684
+            }
685
+
686
+        }
687
+        /// <summary>
688
+        /// DataTable转换成txt
689
+        /// </summary>
690
+        /// <param name="dt">带转换的数据表</param>
691
+        /// <param name="countColumnName">表中要计算的数据列名</param>
692
+        /// <param name="state">是否计算总金额</param>
693
+        public void DataTableToTxt(System.Data.DataTable dt, string countColumnName, bool state)
694
+        {
695
+
696
+            this.TotalCount = 0;
697
+            this.TotalMoney = 0;
698
+            this.tableTypeData = dt;
699
+            string data = string.Empty;
700
+            foreach (DataRow dr in dt.Rows)
701
+            {
702
+                this.TotalCount++;
703
+                string drdata = string.Empty;
704
+                foreach (var item in dr.ItemArray)
705
+                {
706
+                    drdata += item.ToString() + " ";
707
+                }
708
+                data += drdata + "\n";
709
+                if (state)
710
+                {
711
+                    if (!string.IsNullOrEmpty(countColumnName))
712
+                    {
713
+                        this.TotalMoney += Convert.ToDouble(dr[countColumnName]);
714
+                    }
715
+                }
716
+
717
+            }
718
+            this.TargetFileHead += "TOTAL NO " + TotalCount + " " + TotalMoney + "\n";
719
+            this.changedFileContant = data.Trim("\n".ToCharArray());
720
+
721
+        }
722
+    
723
+
724
+        /// <summary>
725
+        /// DataTable转换成txt
726
+        /// </summary>
727
+        /// <param name="dt">带转换的数据表</param>
728
+        /// <param name="countColumnName">表中要计算的数据列名</param>
729
+        public void DataTableToTxt(System.Data.DataTable dt, string countColumnName)
730
+        {
731
+            this.TargetFileHead += "{0} {1} ";
732
+            this.TotalCount = 0;
733
+            this.TotalMoney = 0;
734
+            this.tableTypeData = dt;
735
+            string data = string.Empty;
736
+            foreach (DataRow dr in dt.Rows)
737
+            {
738
+                this.TotalCount++;
739
+                string drdata = string.Empty;
740
+                foreach (var item in dr.ItemArray)
741
+                {
742
+                    drdata += item.ToString() + " ";
743
+                }
744
+                data += drdata + "\n";
745
+                if (!string.IsNullOrEmpty(countColumnName))
746
+                {
747
+                    this.TotalMoney += Convert.ToDouble(dr[countColumnName]);
748
+                }
749
+            }
750
+            this.changedFileContant = data.Trim("\n".ToCharArray());
751
+        }
752
+
753
+        /// <summary>
754
+        /// DataTable转换成txt(不计算总金额)
755
+        /// </summary>
756
+        /// <param name="dt">带转换的数据表</param>
757
+       
758
+        public void DataTableToTxt(System.Data.DataTable dt)
759
+        {
760
+            this.TargetFileHead += "{0} {1} ";
761
+            this.TotalCount = 0;
762
+            this.TotalMoney = 0;
763
+            this.tableTypeData = dt;
764
+            string data = string.Empty;
765
+            foreach (DataRow dr in dt.Rows)
766
+            {
767
+                this.TotalCount++;
768
+                string drdata = string.Empty;
769
+                foreach (var item in dr.ItemArray)
770
+                {
771
+                    drdata += item.ToString() + " ";
772
+                }
773
+                data += drdata + "\n";
774
+     
775
+            }
776
+            this.changedFileContant = data.Trim("\n".ToCharArray());
777
+        }
778
+
779
+        public enum FileType
780
+        {
781
+            /// <summary>
782
+            /// 文本文件
783
+            /// </summary>
784
+            TXT,
785
+            /// <summary>
786
+            /// excel表格文件
787
+            /// </summary>
788
+            EXCEL
789
+        }
790
+        /// <summary>
791
+        /// 统计文件中的总金额,总笔数
792
+        /// </summary>
793
+        /// <param name="s">要统计的字符串</param>
794
+        /// <param name="totalmoney">金额所在列号</param>
795
+        public void TotalCountAndTotalMoney(string s, int totalmoney)
796
+        {
797
+
798
+            int j = 0;
799
+            string[] str1 = s.Split('\n');
800
+            string s2 = string.Empty;
801
+            foreach (string item in str1)
802
+            {
803
+                string[] str2 = item.Split(' ');
804
+                if (item == "" || item == "END")
805
+                {
806
+                    continue;
807
+                }
808
+                if (str2[0] == "TOTAL")
809
+                {
810
+                    continue;
811
+                }
812
+                this.TotalMoney = this.TotalMoney + Convert.ToDouble(str2[totalmoney]);
813
+                j++;
814
+            }
815
+            this.TotalCount = j;
816
+            str1[0] = " "+this.TotalCount.ToString() + " " + this.TotalMoney.ToString();
817
+          //  this.TargetFileHead = str1[0] + '\n';
818
+            for (int n = 0; n < str1.Length; n++)
819
+            {
820
+
821
+                if (str1[n] == "")
822
+                {
823
+                    continue;
824
+                }
825
+
826
+                if (str1[n + 1] != "END")
827
+                    s2 = s2 + str1[n] + '\n';
828
+                else
829
+                {
830
+                    s2 = s2 + str1[n];
831
+                    break;
832
+                }
833
+            }
834
+            this.changedFileContant = s2;
835
+        }
836
+
837
+
838
+    }
839
+}

+ 460
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ExcelToTxt.ts 查看文件

@@ -0,0 +1,460 @@
1
+// 模拟依赖的类型和模块
2
+type DataTable = {
3
+    columns: string[];
4
+    rows: any[][];
5
+    clear(): void;
6
+    newRow(): any;
7
+    addRow(row: any): void;
8
+};
9
+
10
+type Worksheet = {
11
+    UsedRange: {
12
+        Rows: {
13
+            item(index: number): any;
14
+        };
15
+        Columns: any;
16
+    };
17
+};
18
+
19
+type Workbook = {
20
+    Close(saveChanges?: boolean, fileName?: any, routeWorkbook?: any): void;
21
+};
22
+
23
+type ExcelApplication = {
24
+    Workbooks: {
25
+        Open(filePath: string, ...args: any[]): Workbook;
26
+        Close(): void;
27
+    };
28
+    Quit(): void;
29
+};
30
+
31
+// 定义 FileType 枚举
32
+enum FileType {
33
+    TXT,
34
+    EXCEL
35
+}
36
+
37
+class ExcelToTxt {
38
+    private wath: { start(): void; stop(): void; elapsed: { totalMilliseconds: number } } = {
39
+        start() {},
40
+        stop() {},
41
+        elapsed: { totalMilliseconds: 0 }
42
+    };
43
+    private changedFileContant: string = "";
44
+    private isHasTotalMoneyAndTotalCout: boolean = false;
45
+    private tableColumNames: string[] = [];
46
+    private sourceFileFullName: string = "";
47
+    private tableTypeData: DataTable = {
48
+        columns: [],
49
+        rows: [],
50
+        clear() {
51
+            this.columns = [];
52
+            this.rows = [];
53
+        },
54
+        newRow() {
55
+            return {};
56
+        },
57
+        addRow(row: any) {
58
+            this.rows.push(row);
59
+        }
60
+    };
61
+
62
+    public TotalMoney: number = 0;
63
+    public TotalCount: number = 0;
64
+    public TargetFileHead: string = "TOTAL NO ";
65
+    public TargetFileEnd: string = "\nEND";
66
+    public SourceFileType: FileType = FileType.EXCEL;
67
+    public TargetFileFullName: string = "";
68
+
69
+    constructor(sourceFile?: string, targetFile?: string) {
70
+        if (sourceFile && targetFile) {
71
+            this.SourceFileFullName = sourceFile;
72
+            this.TargetFileFullName = targetFile;
73
+        }
74
+        this.tableTypeData.clear();
75
+    }
76
+
77
+    get TableColumNames(): string[] {
78
+        if (this.tableColumNames.length === 0) {
79
+            this.tableColumNames = this.tableTypeData.columns;
80
+        }
81
+        return this.tableColumNames;
82
+    }
83
+
84
+    set TableColumNames(value: string[]) {
85
+        if (value.length > 0) {
86
+            value.forEach((colName) => {
87
+                if (!this.tableTypeData.columns.includes(colName)) {
88
+                    this.tableTypeData.columns.push(colName);
89
+                }
90
+            });
91
+        }
92
+    }
93
+
94
+    get SourceFileName(): string {
95
+        return this.sourceFileFullName.split("\\").pop() || "";
96
+    }
97
+
98
+    get TargetFileName(): string {
99
+        return this.TargetFileFullName.split("\\").pop() || "";
100
+    }
101
+
102
+    set SourceFileFullName(value: string) {
103
+        this.sourceFileFullName = value;
104
+        if (value.toLowerCase().endsWith(".txt")) {
105
+            this.SourceFileType = FileType.TXT;
106
+        } else {
107
+            this.SourceFileType = FileType.EXCEL;
108
+        }
109
+    }
110
+
111
+    get ChangedFileContant(): string {
112
+        if (this.isHasTotalMoneyAndTotalCout) {
113
+            return this.TargetFileHead + this.changedFileContant + this.TargetFileEnd;
114
+        } else {
115
+            return `${this.TargetFileHead}\n${this.changedFileContant}${this.TargetFileEnd}`.replace(
116
+                "{0}",
117
+                this.TotalCount.toString()
118
+            ).replace("{1}", this.TotalMoney.toString());
119
+        }
120
+    }
121
+
122
+    public ChangeExcelToTxt(): boolean {
123
+        if (!this.sourceFileFullName) {
124
+            throw new Error(`找不到指定路径:${this.sourceFileFullName}的一部分。`);
125
+        }
126
+        return this.ChangeExcelToTxt(this.sourceFileFullName);
127
+    }
128
+
129
+    public ChangeExcelToTxt(fileFullName: string): boolean {
130
+        return this.ChangeExcelToTxt(fileFullName, 0, 0, false, 1);
131
+    }
132
+
133
+    public ChangeExcelToTxt(
134
+        filePath: string,
135
+        headLineCount: number,
136
+        endLineCount: number,
137
+        hasColumnTitle: boolean,
138
+        beginLine: number
139
+    ): boolean {
140
+        let result = false;
141
+        this.SourceFileFullName = filePath;
142
+        if (!this.sourceFileFullName) {
143
+            throw new Error(`找不到指定路径:${this.sourceFileFullName}的一部分。`);
144
+        }
145
+        try {
146
+            if (filePath.endsWith(".xls") || filePath.endsWith(".xlsx")) {
147
+                this.changedFileContant = this.ExcelToText(filePath, headLineCount, endLineCount, hasColumnTitle, beginLine);
148
+            }
149
+        } catch (error) {
150
+            this.changedFileContant = "";
151
+        }
152
+        return result;
153
+    }
154
+
155
+    private ExcelToText(
156
+        filePath: string,
157
+        headLineCount: number,
158
+        endLineCount: number,
159
+        hasColumnTitle: boolean,
160
+        beginLine: number
161
+    ): string {
162
+        this.isHasTotalMoneyAndTotalCout = true;
163
+        let head = "";
164
+        let data = "";
165
+        this.tableTypeData.clear();
166
+        const app: ExcelApplication = {
167
+            Workbooks: {
168
+                Open() {
169
+                    return {
170
+                        Close() {}
171
+                    };
172
+                },
173
+                Close() {}
174
+            },
175
+            Quit() {}
176
+        };
177
+        let workbook: Workbook | null = null;
178
+        try {
179
+            this.wath.start();
180
+            workbook = app.Workbooks.Open(filePath);
181
+            const sheets = workbook;
182
+            const worksheet: Worksheet = {
183
+                UsedRange: {
184
+                    Rows: {
185
+                        item(index: number) {
186
+                            return {
187
+                                Columns: {
188
+                                    forEach(callback: (rc: any) => void) {
189
+                                        // 模拟列遍历
190
+                                    }
191
+                                }
192
+                            };
193
+                        }
194
+                    },
195
+                    Columns: {}
196
+                }
197
+            };
198
+            const rowCount = 100; // 模拟总行数
199
+
200
+            // 处理表头
201
+            for (let i = beginLine; i < beginLine + headLineCount; i++) {
202
+                let currentColIndex = 0;
203
+                worksheet.UsedRange.Rows.item(i).Columns.forEach((rc: any) => {
204
+                    currentColIndex++;
205
+                    const cells = rc.Cells;
206
+                    if (cells && cells.Text.trim()) {
207
+                        if (!cells.Text.includes(":")) {
208
+                            head += cells.Text.trim() + " ";
209
+                        }
210
+                    }
211
+                });
212
+            }
213
+
214
+            // 处理表中数据内容
215
+            for (let i = beginLine + headLineCount; i <= rowCount - endLineCount; i++) {
216
+                let tempData = "";
217
+                let currentColIndex = 0;
218
+                if (hasColumnTitle) {
219
+                    worksheet.UsedRange.Rows.item(i).Columns.forEach((rc: any) => {
220
+                        currentColIndex++;
221
+                        const cells = rc.Cells;
222
+                        if (cells && cells.Text.trim()) {
223
+                            this.tableTypeData.columns.push(cells.Text.trim());
224
+                        }
225
+                    });
226
+                    hasColumnTitle = false;
227
+                    continue;
228
+                }
229
+                const dr = this.tableTypeData.newRow();
230
+                let isAddRow = false;
231
+                worksheet.UsedRange.Rows.item(i).Columns.forEach((rc: any) => {
232
+                    currentColIndex++;
233
+                    let temp = "";
234
+                    const cells = rc.Cells;
235
+                    if (cells && cells.Text.trim()) {
236
+                        let t = cells.Text;
237
+                        let dateTime = new Date(t);
238
+                        if (t.includes(":") || t.includes("-") || t.includes("/")) {
239
+                            if (!isNaN(dateTime.getTime())) {
240
+                                if (dateTime.getHours() !== 0) {
241
+                                    t = dateTime.toLocaleTimeString("en-US", { hour12: false, hour: "2-digit", minute: "2-digit", second: "2-digit" }).replace(/:/g, "");
242
+                                    temp = dateTime.toLocaleTimeString("en-US", { hour12: false, hour: "2-digit", minute: "2-digit", second: "2-digit" });
243
+                                } else {
244
+                                    t = dateTime.toISOString().split("T")[0].replace(/-/g, "");
245
+                                    temp = dateTime.toISOString().split("T")[0];
246
+                                }
247
+                            }
248
+                        }
249
+                        tempData += t.trim() + " ";
250
+                        dr[currentColIndex - 1] = temp;
251
+                        isAddRow = true;
252
+                    }
253
+                });
254
+                if (isAddRow) {
255
+                    this.tableTypeData.addRow(dr);
256
+                }
257
+                if (tempData.trim()) {
258
+                    data += `\n${tempData.trimEnd()}`;
259
+                }
260
+            }
261
+
262
+            // 处理表尾
263
+            for (let i = rowCount - endLineCount + 1; i <= rowCount; i++) {
264
+                let currentColIndex = 0;
265
+                let temp = "";
266
+                worksheet.UsedRange.Rows.item(i).Columns.forEach((rc: any) => {
267
+                    currentColIndex++;
268
+                    const cells = rc.Cells;
269
+                    if (cells && cells.Text.trim()) {
270
+                        if (!cells.Text.includes(":")) {
271
+                            temp += cells.Text.trim() + " ";
272
+                        }
273
+                    }
274
+                });
275
+                head = temp + head;
276
+            }
277
+
278
+            this.wath.stop();
279
+            return head + data;
280
+        } catch (error) {
281
+            throw new Error(`数据转换错误。`);
282
+        } finally {
283
+            if (workbook) {
284
+                workbook.Close(false);
285
+            }
286
+            app.Workbooks.Close();
287
+            app.Quit();
288
+        }
289
+    }
290
+
291
+    public Save(): boolean {
292
+        if (!this.TargetFileFullName) {
293
+            throw new Error(`找不到指定路径:${this.TargetFileFullName}的一部分。`);
294
+        }
295
+        return this.Save(this.TargetFileFullName, this.ChangedFileContant);
296
+    }
297
+
298
+    public Save(targetFile: string): boolean {
299
+        if (!targetFile) {
300
+            throw new Error(`找不到指定路径:${targetFile}的一部分。`);
301
+        }
302
+        return this.Save(targetFile, this.ChangedFileContant);
303
+    }
304
+
305
+    public Save(targetFile: string, fileContant: string): boolean {
306
+        this.TargetFileFullName = targetFile;
307
+        // 模拟文件写入
308
+        console.log(`将内容写入文件: ${targetFile}`);
309
+        return true;
310
+    }
311
+
312
+    public TxtToDataTableColumnName(sourceFile: string, countColumnName: string, splitChar?: string, t?: boolean): void {
313
+        let temp = "";
314
+        // 模拟文件读取
315
+        temp = temp.replace("\r\n", "\n");
316
+        this.TargetFileHead = temp.startsWith("TOTAL") ? "" : this.TargetFileHead + "{0} {1}";
317
+        this.changedFileContant = temp.replace("^", " ");
318
+        if (splitChar && t !== undefined) {
319
+            this.ToDataTable(splitChar, countColumnName, t);
320
+        } else if (splitChar) {
321
+            this.ToDataTable(splitChar, countColumnName);
322
+        } else {
323
+            this.ToDataTable(" ", countColumnName);
324
+        }
325
+    }
326
+
327
+    public TxtToDataTable(sourceFile: string, splitChar?: string): void {
328
+        this.TotalCount = 0;
329
+        let needLines: string[] = [];
330
+        // 模拟文件读取
331
+        const lines: string[] = [];
332
+        lines.forEach((line) => {
333
+            if (line.startsWith("U")) {
334
+                this.TotalCount++;
335
+                needLines.push(line);
336
+                this.changedFileContant += line + "\n";
337
+            }
338
+        });
339
+        this.TargetFileHead += "{0} {1} ";
340
+        this.changedFileContant = this.changedFileContant.trim().replace("^", " ");
341
+        if (splitChar) {
342
+            this.ToDataTable(splitChar, "");
343
+        } else {
344
+            this.ToDataTable(" ", "");
345
+        }
346
+    }
347
+
348
+    private ToDataTable(splitChar: string, countColumn: string, t?: boolean): void {
349
+        const strs = this.ChangedFileContant.split("\n");
350
+        let i = 0;
351
+        let needAddTotalCount = false;
352
+        let needCountTotalMoney = false;
353
+        if (strs) {
354
+            this.tableTypeData.clear();
355
+            strs.forEach((item) => {
356
+                if (item.startsWith("END")) {
357
+                    return;
358
+                }
359
+                if (!item.trim()) {
360
+                    return;
361
+                }
362
+                const strT = item.split(splitChar);
363
+                if (!strT || strT.length < 1) {
364
+                    throw new Error("不可处理的文件格式。");
365
+                }
366
+                if (i === 0) {
367
+                    if (t) {
368
+                        this.TargetFileHead = `${strT[0]} ${strT[1]} {0} {1} `;
369
+                        this.TotalCount = parseInt(strT[2], 10);
370
+                        needAddTotalCount = this.TotalCount > 0 ? false : true;
371
+                        this.TotalMoney = parseFloat(strT[3]);
372
+                        needCountTotalMoney = this.TotalMoney > 0 ? false : true;
373
+                    }
374
+                    if (strT.length > 4) {
375
+                        for (let j = 4; j < strT.length; j++) {
376
+                            this.TargetFileHead += strT[j];
377
+                        }
378
+                    }
379
+                } else {
380
+                    const dr = this.tableTypeData.newRow();
381
+                    strT.forEach((value, index) => {
382
+                        dr[index] = value;
383
+                    });
384
+                    if (countColumn && needCountTotalMoney) {
385
+                        const colIndex = this.tableTypeData.columns.indexOf(countColumn);
386
+                        if (colIndex !== -1 && dr[colIndex] !== undefined) {
387
+                            this.TotalMoney += parseFloat(dr[colIndex]);
388
+                        }
389
+                    }
390
+                    this.TotalCount = needAddTotalCount ? this.TotalCount + 1 : this.TotalCount;
391
+                    this.tableTypeData.addRow(dr);
392
+                }
393
+                i++;
394
+            });
395
+        } else {
396
+            throw new Error("不可处理的文件格式。");
397
+        }
398
+    }
399
+
400
+    public DataTableToTxt(dt: DataTable, countColumnName?: string, state?: boolean): void {
401
+        this.TotalCount = 0;
402
+        this.TotalMoney = 0;
403
+        this.tableTypeData = dt;
404
+        let data = "";
405
+        dt.rows.forEach((dr) => {
406
+            this.TotalCount++;
407
+            let drdata = "";
408
+            dr.forEach((item) => {
409
+                drdata += item.toString() + " ";
410
+            });
411
+            data += drdata + "\n";
412
+            if (state && countColumnName) {
413
+                const colIndex = dt.columns.indexOf(countColumnName);
414
+                if (colIndex !== -1 && dr[colIndex] !== undefined) {
415
+                    this.TotalMoney += parseFloat(dr[colIndex]);
416
+                }
417
+            }
418
+        });
419
+        if (state) {
420
+            this.TargetFileHead += `TOTAL NO ${this.TotalCount} ${this.TotalMoney}\n`;
421
+        } else {
422
+            this.TargetFileHead += "{0} {1} ";
423
+        }
424
+        this.changedFileContant = data.trim();
425
+    }
426
+
427
+    public TotalCountAndTotalMoney(s: string, totalmoney: number): void {
428
+        let j = 0;
429
+        const str1 = s.split("\n");
430
+        let s2 = "";
431
+        str1.forEach((item) => {
432
+            const str2 = item.split(" ");
433
+            if (!item || item === "END") {
434
+                return;
435
+            }
436
+            if (str2[0] === "TOTAL") {
437
+                return;
438
+            }
439
+            if (str2[totalmoney] !== undefined) {
440
+                this.TotalMoney += parseFloat(str2[totalmoney]);
441
+            }
442
+            j++;
443
+        });
444
+        this.TotalCount = j;
445
+        str1[0] = ` ${this.TotalCount} ${this.TotalMoney}`;
446
+        str1.forEach((item, index) => {
447
+            if (!item) {
448
+                return;
449
+            }
450
+            if (str1[index + 1] !== "END") {
451
+                s2 += item + "\n";
452
+            } else {
453
+                s2 += item;
454
+            }
455
+        });
456
+        this.changedFileContant = s2;
457
+    }
458
+}
459
+
460
+export { ExcelToTxt, FileType };

+ 469
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/FtpHandle_TS.cs 查看文件

@@ -0,0 +1,469 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using TellerSystem.ServiceProxy.Ext.WebAPI.Auth.Entity;
6
+using System.Threading;
7
+using System.IO;
8
+using Platform.Common.LogSystem;
9
+using Platform.Common.RunningParameters;
10
+using System.Net;
11
+using System.Windows;
12
+using System.Text.RegularExpressions;
13
+using System.Diagnostics;
14
+using TellerSystem.ServiceProxy.Ext.ServiceHelper;
15
+using System.Windows.Media;
16
+using TellerSystem;
17
+using System.Windows.Media.Imaging;
18
+using TellerSystem.Library.Ext.Function;
19
+using System.Drawing.Imaging;
20
+using System.Drawing;
21
+using System.Drawing.Drawing2D;
22
+
23
+
24
+namespace TellerSystem.Library.Ext.TradeExtension
25
+{
26
+    /// <summary>
27
+    /// FTP接口类
28
+    /// </summary>
29
+    public class FtpHandle_TS
30
+    {
31
+        public static string YXLC = TradeManagerHandle.TT_SYSCONFIG_GetConfigValueByConfigID("YXLC");
32
+        /// <summary>
33
+        /// 压缩图片
34
+        /// </summary>
35
+        public static byte[] ystp;
36
+        /// <summary>
37
+        /// 上传文件
38
+        /// </summary>
39
+        /// <param name="fileinfo">需要上传的文件</param>
40
+        /// <param name="targetDir">目标路径</param>
41
+        /// <param name="hostname">ftp地址</param>
42
+        /// <param name="username">ftp用户名</param>
43
+        /// <param name="password">ftp密码</param>
44
+        public static void UploadFile(FileInfo fileinfo, string targetDir, string hostname, string username, string password)
45
+        {
46
+            //1. check target
47
+            string target;
48
+            if (targetDir.Trim() == "")
49
+            {
50
+                return;
51
+            }
52
+            //target = Guid.NewGuid().ToString();  //使用临时文件名
53
+            target = fileinfo.Name;//文件名
54
+
55
+            //string URI = "FTP://" + hostname + "/image/image/" + targetDir + "/" + target;
56
+            string URI = "FTP://" + hostname + "/" + targetDir + "/" + target;
57
+            System.Net.FtpWebRequest ftp = GetRequest(URI, username, password);
58
+
59
+            ftp.Method = WebRequestMethods.Ftp.GetFileSize;
60
+            ftp.ContentLength = fileinfo.Length;
61
+            //设置FTP命令 设置所要执行的FTP命令,
62
+            //ftp.Method = System.Net.WebRequestMethods.Ftp.ListDirectoryDetails;//假设此处为显示指定路径下的文件列表
63
+            ftp.Method = System.Net.WebRequestMethods.Ftp.UploadFile;
64
+            //指定文件传输的数据类型
65
+            ftp.UseBinary = true;
66
+            ftp.UsePassive = true;
67
+            
68
+            //告诉ftp文件大小
69
+            ftp.ContentLength = fileinfo.Length;
70
+            //缓冲大小设置为2KB
71
+            const int BufferSize = 2048;
72
+            byte[] content = new byte[BufferSize - 1 + 1];
73
+            int dataRead;
74
+
75
+            //打开一个文件流 (System.IO.FileStream) 去读上传的文件
76
+            using (FileStream fs = fileinfo.OpenRead())
77
+            {
78
+                try
79
+                {
80
+                    //把上传的文件写入流
81
+                    using (Stream rs = ftp.GetRequestStream())
82
+                    {
83
+                        do
84
+                        {
85
+                            //每次读文件流的2KB
86
+                            dataRead = fs.Read(content, 0, BufferSize);
87
+                            rs.Write(content, 0, dataRead);
88
+                        } while (!(dataRead < BufferSize));
89
+                        rs.Close();
90
+                    }
91
+
92
+                }
93
+                catch (Exception ex) { TradeHandle.WriteImportantLog("写文件异常", "写文件异常", "pic", "pp"); }
94
+                finally
95
+                {
96
+                    fs.Close();
97
+                }
98
+
99
+            }
100
+
101
+            //ftp = null;
102
+            ////设置FTP命令
103
+            //ftp = GetRequest(URI, username, password);
104
+            //ftp.Method = System.Net.WebRequestMethods.Ftp.Rename; //改名
105
+            //ftp.RenameTo = fileinfo.Name;
106
+            //try
107
+            //{
108
+            //    ftp.GetResponse();
109
+            //}
110
+            //catch (Exception ex)
111
+            //{
112
+            //    TradeHandle.WriteImportantLog("文件重命名异常", "文件重命名异常", "pic", "pp");
113
+            //    ftp = GetRequest(URI, username, password);
114
+            //    ftp.Method = System.Net.WebRequestMethods.Ftp.DeleteFile; //删除
115
+            //    try
116
+            //    {
117
+            //        ftp.GetResponse();
118
+            //    }
119
+            //    catch (Exception ex1)
120
+            //    {
121
+            //        TradeHandle.WriteImportantLog("留存服务器删除文件异常", "留存服务器删除文件异常", "pic", "pp");
122
+            //        throw ex1;
123
+            //    }
124
+            //    throw ex;
125
+            //}
126
+            //finally
127
+            //{
128
+            //    //fileinfo.Delete();
129
+            //}
130
+
131
+            // 可以记录一个日志  "上传" + fileinfo.FullName + "上传到" + "FTP://" + hostname + "/" + targetDir + "/" + fileinfo.Name + "成功." );
132
+            ftp = null;
133
+
134
+            #region
135
+            /*****
136
+             *FtpWebResponse
137
+             * ****/
138
+            //FtpWebResponse ftpWebResponse = (FtpWebResponse)ftp.GetResponse();
139
+            #endregion
140
+        }
141
+
142
+        private static FtpWebRequest GetRequest(string URI, string username, string password)
143
+        {
144
+            //根据服务器信息FtpWebRequest创建类的对象
145
+            FtpWebRequest result = (FtpWebRequest)FtpWebRequest.Create(URI);
146
+            //提供身份验证信息
147
+            result.Credentials = new System.Net.NetworkCredential(username, password);
148
+            //设置请求完成之后是否保持到FTP服务器的控制连接,默认值为true
149
+            result.KeepAlive = false;
150
+            return result;
151
+        }
152
+
153
+        /// 在ftp服务器上创建目录
154
+        /// </summary>
155
+        /// <param name="dirName">创建的目录名称</param>
156
+        /// <param name="ftpHostIP">ftp地址</param>
157
+        /// <param name="username">用户名</param>
158
+        /// <param name="password">密码</param>
159
+        public static void MakeDir(string dirName, string ftpHostIP, string username, string password)
160
+        {
161
+            if (!ftpIsExistsFile(LoginUserInfo.TradeDate, YXLC.Split('|')[0].Trim(), YXLC.Split('|')[1].Trim(), YXLC.Split('|')[2].Trim()))
162
+            {
163
+                string uri = null;
164
+                try
165
+                {
166
+                    //uri = "ftp://" + ftpHostIP + "/image/image/" + dirName;
167
+                    uri = "ftp://" + ftpHostIP + "/" + dirName;
168
+                    System.Net.FtpWebRequest ftp = GetRequest(uri, username, password);
169
+                    ftp.Method = WebRequestMethods.Ftp.MakeDirectory;
170
+
171
+                    FtpWebResponse response = (FtpWebResponse)ftp.GetResponse();
172
+                    response.Close();
173
+                }
174
+                catch (Exception ex)
175
+                {
176
+                    TradeHandle.WriteImportantLog("创建目录失败", uri, "pic", "pp");
177
+                    //MessageBox.Show(ex.Message);
178
+                }
179
+            }
180
+            
181
+        }
182
+
183
+        /// <summary>
184
+        /// 判断ftp服务器上该目录是否存在
185
+        /// </summary>
186
+        /// <param name="dirName"></param>
187
+        /// <param name="ftpHostIP"></param>
188
+        /// <param name="username"></param>
189
+        /// <param name="password"></param>
190
+        /// <returns></returns>
191
+        public static bool ftpIsExistsFile(string dirName, string ftpHostIP, string username, string password)
192
+        {
193
+            bool flag = false;
194
+            try
195
+            {
196
+                //string uri = "ftp://" + ftpHostIP + "/image/image/";// +dirName;
197
+                string uri = "ftp://" + ftpHostIP;// +dirName;
198
+                System.Net.FtpWebRequest ftp = GetRequest(uri, username, password);
199
+                ftp.Method = WebRequestMethods.Ftp.ListDirectory;
200
+
201
+                FtpWebResponse response = (FtpWebResponse)ftp.GetResponse();
202
+                StreamReader reader = new StreamReader(response.GetResponseStream());
203
+                string line = null;
204
+                while((line = reader.ReadLine()) != null)
205
+                {
206
+                    if (line != null && line.Contains(LoginUserInfo.TradeDate))
207
+                    {
208
+                        flag = true;
209
+                    }
210
+                }
211
+                //string line = reader.ReadLine();
212
+                //if (line != null && line.Contains(LoginUserInfo.TradeDate))
213
+                //{
214
+                //    flag = true;
215
+                //}
216
+                //else
217
+                //{
218
+                //    flag = false;
219
+                //}
220
+                response.Close();
221
+            }
222
+            catch (Exception)
223
+            {
224
+                TradeHandle.WriteImportantLog("判断ftp服务器上该目录是否存在方法异常", "判断ftp服务器上该目录是否存在方法异常", "pic", "pp");
225
+                flag = false;
226
+            }
227
+            return flag;
228
+        }
229
+
230
+        /// <summary>
231
+        /// 执行拍照动作并保存图片至指定路径下
232
+        /// </summary>
233
+        /// <param name="IdNo"></param>
234
+        /// <returns></returns>
235
+        public static void photograph(string IdNo)
236
+        {
237
+            string FLAG = TradeManagerHandle.TT_SYSCONFIG_GetConfigValueByConfigID("2ea3a7e6cfa04f89a335bf1e363295de");
238
+            string devicesTagStr = null;
239
+            //执行拍摄动作
240
+            Process[] processes = Process.GetProcessesByName("CameraPlayer");
241
+            if (processes.Length > 0)
242
+            {
243
+                foreach (Process process in processes)
244
+                {
245
+                    if (!process.HasExited)
246
+                        process.Kill();
247
+                }
248
+            }
249
+            if (devicesTagStr == null)
250
+            {
251
+                string kh = String.Format("KH|{0}|{1};", ConfigManager.GetInstance().GetConfigValue("KHVid", ConfigType.User), ConfigManager.GetInstance().GetConfigValue("KHPid", ConfigType.User));
252
+                devicesTagStr = kh;
253
+            }
254
+            string saveImgDir = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"picture", LoginUserInfo.TradeDate);
255
+            //创建头像存储路径
256
+            DirectoryInfo dir = null;
257
+            if (!File.Exists(saveImgDir))
258
+            {
259
+                dir = Directory.CreateDirectory(saveImgDir);
260
+            }
261
+            //DateTime.Now.ToString("yyyyMMddHHmmss")
262
+            string fileName = LoginUserInfo.TradeDate + "_" + LoginUserInfo.TellerNo + "_" + IdNo + ".png";
263
+            string fileName1 = DateTime.Now.ToString("yyyyMMddHHmmss") + "_" + LoginUserInfo.TellerNo + "_" + IdNo + ".png";
264
+            string outImgPath = System.IO.Path.Combine(@"picture", LoginUserInfo.TradeDate, fileName);
265
+            string outImgPath1 = System.IO.Path.Combine(@"picture", LoginUserInfo.TradeDate, fileName1);
266
+            Process printProcess = new Process();
267
+            printProcess.StartInfo.FileName = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Devices\CameraPlayer\CameraPlayer.exe");
268
+            printProcess.StartInfo.Arguments = FLAG + " " + "KH" + " " + devicesTagStr + " " + outImgPath;
269
+            printProcess.Start();
270
+            printProcess.WaitForExit();
271
+            string saveImgPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, outImgPath);
272
+            string saveImgPath1 = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, outImgPath1);
273
+            Bitmap ystph;
274
+            if (File.Exists(saveImgPath))
275
+            {
276
+                BitmapImage bitmapImage = new BitmapImage();
277
+                bitmapImage.BeginInit();
278
+                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
279
+                bitmapImage.UriSource = new Uri(saveImgPath);//szPath为图片的全路径
280
+                bitmapImage.EndInit();
281
+                bitmapImage.Freeze();
282
+                CompressImage(saveImgPath, saveImgPath1,720,1280,90);
283
+            }
284
+
285
+
286
+            string getDirecName = LoginUserInfo.TradeDate;
287
+            FtpHandle_TS.MakeDir(getDirecName, YXLC.Split('|')[0].Trim(), YXLC.Split('|')[1].Trim(), YXLC.Split('|')[2].Trim());
288
+            //FtpHandle_TS.MakeDir(getDirecName, "16.5.21.61", "c6front", "c6front321");
289
+
290
+            DirectoryInfo dire = dir as DirectoryInfo;
291
+            if (dire == null) return;
292
+            FileSystemInfo[] files = dire.GetFileSystemInfos();
293
+            for (int i = 0; i < files.Length; i++)
294
+            {
295
+                FileInfo fi = files[i] as FileInfo;
296
+                if (fi != null && fi.Name == fileName1)
297
+                {
298
+                    DirectoryInfo DirecObj = fi.Directory;
299
+                    string DireObjName = DirecObj.Name;
300
+                    FtpHandle_TS.UploadFile(fi, DireObjName, YXLC.Split('|')[0].Trim(), YXLC.Split('|')[1].Trim(), YXLC.Split('|')[2].Trim());
301
+                    //FtpHandle_TS.UploadFile(fi, DireObjName, "16.5.21.61", "c6front", "c6front321");
302
+                }
303
+            }
304
+            //判断文件夹是否还存在--清理当前拍摄照片的原文件
305
+            if (Directory.Exists(saveImgDir))
306
+            {
307
+                //去除文件夹和子文件的只读属性
308
+                System.IO.DirectoryInfo fileInfo = new DirectoryInfo(saveImgDir);
309
+                fileInfo.Attributes = FileAttributes.Normal & FileAttributes.Directory;
310
+                System.IO.File.SetAttributes(saveImgDir, System.IO.FileAttributes.Normal);
311
+                foreach (string f in Directory.GetFileSystemEntries(saveImgDir))
312
+                {
313
+                    if (File.Exists(f) && f == saveImgPath)
314
+                    {
315
+                        //如果有子文件删除文件
316
+                        File.Delete(f);
317
+                    }
318
+                }
319
+                ////删除空文件夹
320
+                //Directory.Delete(saveImgDir);
321
+            }
322
+
323
+            string filePath = "picture";
324
+            FileSystemInfo filesInfo = new DirectoryInfo(filePath);
325
+            ClearFiles(filesInfo);
326
+        }
327
+
328
+        /// <summary>
329
+        /// 清除本地图片文件
330
+        /// </summary>
331
+        public static void ClearFiles(FileSystemInfo file)
332
+        {
333
+            DirectoryInfo dire = file as DirectoryInfo;
334
+            if (dire == null) return;
335
+            FileSystemInfo[] files = dire.GetFileSystemInfos();
336
+            string date = string.Empty;
337
+            if (LoginUserInfo.TradeDate.Length == 8)
338
+                date = LoginUserInfo.TradeDate.Substring(0, 4) + "-" + LoginUserInfo.TradeDate.Substring(4, 2) + "-" + LoginUserInfo.TradeDate.Substring(6, 2);
339
+            DateTime dt = DateTime.Now;
340
+            if (!DateTime.TryParse(date, out dt))
341
+                return;
342
+            string[] dateList = new string[3];
343
+            dateList[0] = LoginUserInfo.TradeDate;
344
+            dateList[1] = string.Format("{0:yyyyMMdd}", dt.AddDays(-1));
345
+            dateList[2] = string.Format("{0:yyyyMMdd}", dt.AddDays(-2));
346
+            for (int i = 0; i < files.Length; i++)
347
+            {
348
+                bool flag = true;
349
+                string finame = files[i].Name;
350
+                string fipath = files[i].FullName;
351
+                for (int y = 0; y < dateList.Length; y++)
352
+                {
353
+                    if (files[i].Name == dateList[y])
354
+                    {
355
+                        flag = false;
356
+                        continue;
357
+                    }
358
+
359
+                }
360
+                if (flag)
361
+                {
362
+                    DirectoryInfo dirInfo = new DirectoryInfo(fipath);
363
+                    //删除目录及其子目录
364
+                    dirInfo.Delete(true);
365
+                }
366
+
367
+
368
+            }
369
+        }
370
+        public static Bitmap BytesToBitmap(byte[] Bytes)
371
+        {
372
+            MemoryStream stream = null;
373
+            try
374
+            {
375
+                stream = new MemoryStream(Bytes);
376
+                return new Bitmap((Image)new Bitmap(stream));
377
+            }
378
+            catch (ArgumentNullException ex)
379
+            {
380
+                throw ex;
381
+            }
382
+            catch (ArgumentException ex)
383
+            {
384
+                throw ex;
385
+            }
386
+            finally
387
+            {
388
+                stream.Close();
389
+            }
390
+        }
391
+
392
+        public static bool CompressImage(string sFile, string dFile, int dHeight, int dWidth, int flag)
393
+        {
394
+
395
+
396
+            System.Drawing.Image iSource = System.Drawing.Image.FromFile(sFile);
397
+            ImageFormat tFormat = iSource.RawFormat;
398
+            int sW = 0, sH = 0;
399
+            //按比例缩放  
400
+            System.Windows.Size tem_size = new System.Windows.Size(iSource.Width, iSource.Height);
401
+
402
+
403
+            if (tem_size.Width > dHeight || tem_size.Width > dWidth)
404
+            {
405
+                if ((tem_size.Width * dHeight) > (tem_size.Height * dWidth))
406
+                {
407
+                    sW = dWidth;
408
+                    sH = (dWidth * Convert.ToInt32(tem_size.Height)) / Convert.ToInt32(tem_size.Width);
409
+                }
410
+                else
411
+                {
412
+                    sH = dHeight;
413
+                    sW = (Convert.ToInt32(tem_size.Width) * dHeight) / Convert.ToInt32(tem_size.Height);
414
+                }
415
+            }
416
+            else
417
+            {
418
+                sW = Convert.ToInt32(tem_size.Width);
419
+                sH = Convert.ToInt32(tem_size.Height);
420
+            }
421
+            Bitmap ob = new Bitmap(dWidth, dHeight);
422
+            Graphics g = Graphics.FromImage(ob);
423
+            g.CompositingQuality = CompositingQuality.HighQuality;
424
+            g.SmoothingMode = SmoothingMode.HighQuality;
425
+            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
426
+            g.DrawImage(iSource, new Rectangle((dWidth - sW) / 2, (dHeight - sH) / 2, sW, sH), 0, 0, iSource.Width, iSource.Height, GraphicsUnit.Pixel);
427
+            g.Dispose();
428
+            //以下代码为保存图片时,设置压缩质量  
429
+            EncoderParameters ep = new EncoderParameters();
430
+            long[] qy = new long[1];
431
+            qy[0] = flag;//设置压缩的比例1-100  
432
+            EncoderParameter eParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy);
433
+            ep.Param[0] = eParam;
434
+            try
435
+            {
436
+                ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
437
+                ImageCodecInfo jpegICIinfo = null;
438
+                for (int x = 0; x < arrayICI.Length; x++)
439
+                {
440
+                    if (arrayICI[x].FormatDescription.Equals("JPEG"))
441
+                    {
442
+                        jpegICIinfo = arrayICI[x];
443
+                        break;
444
+                    }
445
+                }
446
+                if (jpegICIinfo != null)
447
+                {
448
+                    ob.Save(dFile, jpegICIinfo, ep);//dFile是压缩后的新路径  
449
+                }
450
+                else
451
+                {
452
+                    ob.Save(dFile, tFormat);
453
+                }
454
+                return true;
455
+            }
456
+            catch
457
+            {
458
+                return false;
459
+            }
460
+            finally
461
+            {
462
+                iSource.Dispose();
463
+                ob.Dispose();
464
+            }
465
+
466
+
467
+        }
468
+    }
469
+}

+ 198
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/FtpHandle_TS.ts 查看文件

@@ -0,0 +1,198 @@
1
+// 模拟依赖的类和方法
2
+class TradeManagerHandle {
3
+    static TT_SYSCONFIG_GetConfigValueByConfigID(id: string): string {
4
+        return "";
5
+    }
6
+}
7
+
8
+class LoginUserInfo {
9
+    static get TradeDate(): string {
10
+        return "";
11
+    }
12
+    static get TellerNo(): string {
13
+        return "";
14
+    }
15
+}
16
+
17
+class ConfigManager {
18
+    static GetInstance() {
19
+        return {
20
+            GetConfigValue: (key: string, type: any) => ""
21
+        };
22
+    }
23
+}
24
+
25
+class TradeHandle {
26
+    static WriteImportantLog(title: string, content: string, type: string, subType: string) {
27
+        console.log(`[${title}] ${content}`);
28
+    }
29
+}
30
+
31
+// 模拟文件系统操作
32
+const fs = require('fs');
33
+const path = require('path');
34
+const child_process = require('child_process');
35
+
36
+// 模拟 FTP 操作
37
+const ftp = require('basic-ftp');
38
+
39
+class FtpHandle_TS {
40
+    static YXLC = TradeManagerHandle.TT_SYSCONFIG_GetConfigValueByConfigID("YXLC");
41
+    static ystp: Buffer;
42
+
43
+    static async UploadFile(filePath: string, targetDir: string, hostname: string, username: string, password: string) {
44
+        if (!targetDir.trim()) {
45
+            return;
46
+        }
47
+
48
+        const client = new ftp.Client();
49
+        try {
50
+            await client.access({
51
+                host: hostname,
52
+                user: username,
53
+                password: password,
54
+                secure: false
55
+            });
56
+
57
+            const fileName = path.basename(filePath);
58
+            await client.ensureDir(targetDir);
59
+            await client.uploadFrom(filePath, `${targetDir}/${fileName}`);
60
+        } catch (error) {
61
+            TradeHandle.WriteImportantLog("写文件异常", "写文件异常", "pic", "pp");
62
+        } finally {
63
+            client.close();
64
+        }
65
+    }
66
+
67
+    static async MakeDir(dirName: string, ftpHostIP: string, username: string, password: string) {
68
+        if (!await this.ftpIsExistsFile(dirName, ftpHostIP, username, password)) {
69
+            const client = new ftp.Client();
70
+            try {
71
+                await client.access({
72
+                    host: ftpHostIP,
73
+                    user: username,
74
+                    password: password,
75
+                    secure: false
76
+                });
77
+                await client.ensureDir(dirName);
78
+            } catch (error) {
79
+                TradeHandle.WriteImportantLog("创建目录失败", `ftp://${ftpHostIP}/${dirName}`, "pic", "pp");
80
+            } finally {
81
+                client.close();
82
+            }
83
+        }
84
+    }
85
+
86
+    static async ftpIsExistsFile(dirName: string, ftpHostIP: string, username: string, password: string) {
87
+        const client = new ftp.Client();
88
+        try {
89
+            await client.access({
90
+                host: ftpHostIP,
91
+                user: username,
92
+                password: password,
93
+                secure: false
94
+            });
95
+            const list = await client.list();
96
+            return list.some(item => item.name === dirName);
97
+        } catch (error) {
98
+            TradeHandle.WriteImportantLog("判断ftp服务器上该目录是否存在方法异常", "判断ftp服务器上该目录是否存在方法异常", "pic", "pp");
99
+            return false;
100
+        } finally {
101
+            client.close();
102
+        }
103
+    }
104
+
105
+    static async photograph(IdNo: string) {
106
+        const FLAG = TradeManagerHandle.TT_SYSCONFIG_GetConfigValueByConfigID("2ea3a7e6cfa04f89a335bf1e363295de");
107
+        let devicesTagStr = null;
108
+
109
+        const processes = child_process.execSync('tasklist').toString().split('\n').filter(line => line.includes('CameraPlayer'));
110
+        processes.forEach(() => {
111
+            child_process.execSync('taskkill /F /IM CameraPlayer.exe');
112
+        });
113
+
114
+        if (!devicesTagStr) {
115
+            const kh = `KH|${ConfigManager.GetInstance().GetConfigValue("KHVid", "User")}|${ConfigManager.GetInstance().GetConfigValue("KHPid", "User")};`;
116
+            devicesTagStr = kh;
117
+        }
118
+
119
+        const saveImgDir = path.join(process.cwd(), 'picture', LoginUserInfo.TradeDate);
120
+        if (!fs.existsSync(saveImgDir)) {
121
+            fs.mkdirSync(saveImgDir, { recursive: true });
122
+        }
123
+
124
+        const fileName = `${LoginUserInfo.TradeDate}_${LoginUserInfo.TellerNo}_${IdNo}.png`;
125
+        const fileName1 = `${new Date().toISOString().replace(/[:.-]/g, '')}_${LoginUserInfo.TellerNo}_${IdNo}.png`;
126
+        const outImgPath = path.join('picture', LoginUserInfo.TradeDate, fileName);
127
+        const outImgPath1 = path.join('picture', LoginUserInfo.TradeDate, fileName1);
128
+
129
+        const printProcess = child_process.spawn(path.join(process.cwd(), 'Devices', 'CameraPlayer', 'CameraPlayer.exe'), [FLAG, "KH", devicesTagStr, outImgPath]);
130
+        await new Promise((resolve) => printProcess.on('close', resolve));
131
+
132
+        if (fs.existsSync(outImgPath)) {
133
+            // 模拟图片压缩
134
+            fs.copyFileSync(outImgPath, outImgPath1);
135
+        }
136
+
137
+        await this.MakeDir(LoginUserInfo.TradeDate, this.YXLC.split('|')[0].trim(), this.YXLC.split('|')[1].trim(), this.YXLC.split('|')[2].trim());
138
+
139
+        const files = fs.readdirSync(saveImgDir);
140
+        files.forEach(file => {
141
+            if (file === fileName1) {
142
+                const filePath = path.join(saveImgDir, file);
143
+                this.UploadFile(filePath, LoginUserInfo.TradeDate, this.YXLC.split('|')[0].trim(), this.YXLC.split('|')[1].trim(), this.YXLC.split('|')[2].trim());
144
+            }
145
+        });
146
+
147
+        // 清理原文件
148
+        if (fs.existsSync(outImgPath)) {
149
+            fs.unlinkSync(outImgPath);
150
+        }
151
+
152
+        this.ClearFiles(new fs.Stats());
153
+    }
154
+
155
+    static ClearFiles(file: fs.Stats) {
156
+        const filePath = 'picture';
157
+        if (!fs.lstatSync(filePath).isDirectory()) {
158
+            return;
159
+        }
160
+
161
+        const date = LoginUserInfo.TradeDate;
162
+        let dt: Date;
163
+        if (date.length === 8) {
164
+            const year = date.substring(0, 4);
165
+            const month = date.substring(4, 6);
166
+            const day = date.substring(6, 8);
167
+            dt = new Date(`${year}-${month}-${day}`);
168
+        } else {
169
+            return;
170
+        }
171
+
172
+        const dateList = [
173
+            LoginUserInfo.TradeDate,
174
+            new Date(dt.getTime() - 24 * 60 * 60 * 1000).toISOString().split('T')[0].replace(/-/g, ''),
175
+            new Date(dt.getTime() - 2 * 24 * 60 * 60 * 1000).toISOString().split('T')[0].replace(/-/g, '')
176
+        ];
177
+
178
+        const dirs = fs.readdirSync(filePath);
179
+        dirs.forEach(dir => {
180
+            if (!dateList.includes(dir)) {
181
+                fs.rmSync(path.join(filePath, dir), { recursive: true, force: true });
182
+            }
183
+        });
184
+    }
185
+
186
+    static BytesToBitmap(bytes: Buffer) {
187
+        // 由于 TypeScript 没有 Bitmap 类型,这里简单返回字节数组
188
+        return bytes;
189
+    }
190
+
191
+    static CompressImage(sFile: string, dFile: string, dHeight: number, dWidth: number, flag: number) {
192
+        // 模拟图片压缩
193
+        fs.copyFileSync(sFile, dFile);
194
+        return true;
195
+    }
196
+}
197
+
198
+export { FtpHandle_TS };

+ 43
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/IPageExtension.cs 查看文件

@@ -0,0 +1,43 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Windows;
6
+using System.Windows.Controls;
7
+using System.Windows.Data;
8
+using System.Windows.Documents;
9
+using System.Windows.Input;
10
+using System.Windows.Media;
11
+using System.Windows.Media.Imaging;
12
+using System.Windows.Navigation;
13
+using System.Windows.Shapes;
14
+using Platform.Presentation.Interfaces;
15
+using Platform.Common.BasicFunctions;
16
+using System.Xml.Linq;
17
+
18
+namespace TellerSystem.Library.Ext.TradeExtension
19
+{
20
+    internal class IPageExtension : DependencyObject
21
+    {      
22
+        #region CurrentTabItem
23
+
24
+
25
+        public static TabItem GetCurrentTabItem(DependencyObject obj)
26
+        {
27
+            return (TabItem)obj.GetValue(CurrentTabItemProperty);
28
+        }
29
+
30
+        public static void SetCurrentTabItem(DependencyObject obj, TabItem value)
31
+        {
32
+            obj.SetValue(CurrentTabItemProperty, value);
33
+        }
34
+
35
+        // Using a DependencyProperty as the backing store for CurrentTabItem.  This enables animation, styling, binding, etc...
36
+        public static readonly DependencyProperty CurrentTabItemProperty =
37
+            DependencyProperty.RegisterAttached("CurrentTabItem", typeof(TabItem), typeof(IPageExtension), new UIPropertyMetadata(null));
38
+
39
+
40
+        #endregion
41
+
42
+    }
43
+}

+ 50
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/IPageExtension.ts 查看文件

@@ -0,0 +1,50 @@
1
+// 模拟 DependencyObject 类
2
+class DependencyObject {
3
+    private properties: { [key: string]: any } = {};
4
+
5
+    getValue(property: string): any {
6
+        return this.properties[property];
7
+    }
8
+
9
+    setValue(property: string, value: any): void {
10
+        this.properties[property] = value;
11
+    }
12
+}
13
+
14
+// 模拟 TabItem 类
15
+class TabItem {}
16
+
17
+// 模拟 UIPropertyMetadata 类
18
+class UIPropertyMetadata {
19
+    constructor(public defaultValue: any) {}
20
+}
21
+
22
+// 模拟 DependencyProperty 类
23
+class DependencyProperty {
24
+    constructor(
25
+        public name: string,
26
+        public type: any,
27
+        public ownerType: any,
28
+        public metadata: UIPropertyMetadata
29
+    ) {}
30
+
31
+    static registerAttached(name: string, type: any, ownerType: any, metadata: UIPropertyMetadata): DependencyProperty {
32
+        return new DependencyProperty(name, type, ownerType, metadata);
33
+    }
34
+}
35
+
36
+// 定义 IPageExtension 类
37
+class IPageExtension {
38
+    static readonly CurrentTabItemProperty: DependencyProperty =
39
+        DependencyProperty.registerAttached("CurrentTabItem", TabItem, IPageExtension, new UIPropertyMetadata(null));
40
+
41
+    static GetCurrentTabItem(obj: DependencyObject): TabItem {
42
+        return obj.getValue(IPageExtension.CurrentTabItemProperty.name) as TabItem;
43
+    }
44
+
45
+    static SetCurrentTabItem(obj: DependencyObject, value: TabItem): void {
46
+        obj.setValue(IPageExtension.CurrentTabItemProperty.name, value);
47
+    }
48
+}
49
+
50
+export { IPageExtension };

+ 55
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/IdInfo.cs 查看文件

@@ -0,0 +1,55 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+
6
+namespace TellerSystem.Library.Ext.TradeExtension
7
+{
8
+    ///<summary>
9
+    /// 身份证信息
10
+    ///</summary>
11
+    public class IdInfo
12
+    {
13
+        ///<summary>
14
+        /// 姓名
15
+        ///</summary>
16
+        public string Name { get; set; }
17
+        ///<summary>
18
+        /// 身份证号
19
+        ///</summary>
20
+        public string IdNo { get; set; }
21
+        ///<summary>
22
+        /// 性别
23
+        ///</summary>
24
+        public string Sex { get; set; }
25
+        ///<summary>
26
+        /// 民族
27
+        ///</summary>
28
+        public string Nation { get; set; }
29
+        ///<summary>
30
+        /// 生日
31
+        ///</summary>
32
+        public string Birth { get; set; }
33
+        ///<summary>
34
+        /// 地址
35
+        ///</summary>
36
+        public string Address { get; set; }
37
+        ///<summary>
38
+        /// 签发机构
39
+        ///</summary>
40
+        public string Issue { get; set; }
41
+        ///<summary>
42
+        /// 身份证有效起始日期
43
+        ///</summary>
44
+        public string UserLifeBegin { get; set; }
45
+        ///<summary>
46
+        /// 身份证有效结束日期
47
+        ///</summary>
48
+        public string UserLifeEnd { get; set; }
49
+        ///<summary>
50
+        /// 图片base64串
51
+        ///</summary>
52
+        public string ImageBase64 { get; set; }
53
+
54
+    }
55
+}

+ 60
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/IdInfo.ts 查看文件

@@ -0,0 +1,60 @@
1
+/**
2
+ * 身份证信息
3
+ */
4
+class IdInfo {
5
+    /**
6
+     * 姓名
7
+     */
8
+    Name: string;
9
+    /**
10
+     * 身份证号
11
+     */
12
+    IdNo: string;
13
+    /**
14
+     * 性别
15
+     */
16
+    Sex: string;
17
+    /**
18
+     * 民族
19
+     */
20
+    Nation: string;
21
+    /**
22
+     * 生日
23
+     */
24
+    Birth: string;
25
+    /**
26
+     * 地址
27
+     */
28
+    Address: string;
29
+    /**
30
+     * 签发机构
31
+     */
32
+    Issue: string;
33
+    /**
34
+     * 身份证有效起始日期
35
+     */
36
+    UserLifeBegin: string;
37
+    /**
38
+     * 身份证有效结束日期
39
+     */
40
+    UserLifeEnd: string;
41
+    /**
42
+     * 图片base64串
43
+     */
44
+    ImageBase64: string;
45
+
46
+    constructor() {
47
+        this.Name = "";
48
+        this.IdNo = "";
49
+        this.Sex = "";
50
+        this.Nation = "";
51
+        this.Birth = "";
52
+        this.Address = "";
53
+        this.Issue = "";
54
+        this.UserLifeBegin = "";
55
+        this.UserLifeEnd = "";
56
+        this.ImageBase64 = "";
57
+    }
58
+}
59
+
60
+export default IdInfo;

+ 306
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ImageCutHelper.cs 查看文件

@@ -0,0 +1,306 @@
1
+using System.Collections.Generic;
2
+using System.Text;
3
+using System.Runtime.InteropServices;
4
+using System.IO;
5
+
6
+namespace TellerSystem.Library.Ext.TradeExtension
7
+{
8
+    public class ImageCutHelper
9
+    {
10
+        /*
11
+            输入:
12
+            char *filename 含有绝对路径的文件名
13
+            int iCutMode 裁剪方式
14
+			            1 整幅图像整体裁剪
15
+			            2 先分为左右两部分,然后再次裁剪
16
+                        BOOL bDegbugFlag 是否调试 TRUE 调试输出 FALSE 不调试
17
+                        char *SavePath 裁剪后的保存路径
18
+            输出:
19
+                0 切割成功
20
+	            1 裁剪方式错误(没有找到对应文件)
21
+	            9 图像质量太差,无法裁剪
22
+        */
23
+        [DllImport("FLowBankImageMfcDll.dll")]
24
+        private static extern int HKPD_CUT(string filename, int iMode, bool bDebugFlag, string SavePath);
25
+
26
+        /// <summary>
27
+        /// 切割汇款凭证,图形集合依次为 -0.大写金额- 1.小写金额- 2.业务类型时间-   3.转出方-  4.转入方-
28
+        /// </summary>
29
+        /// <param name="data"></param>
30
+        /// <param name="cutData"></param>
31
+        /// <returns></returns>
32
+        public static bool CutHKPD(byte[] data, out List<byte[]> cutData)
33
+        {
34
+            cutData = new List<byte[]>();
35
+
36
+            //将源数据保存为图片
37
+            var file = new FileInfo(Path.Combine("temp", "HKPD.bmp"));
38
+            if (!file.Directory.Exists) file.Directory.Create();
39
+            var dir = new DirectoryInfo(Path.Combine("temp", "HKPD"));
40
+            try
41
+            {
42
+                File.WriteAllBytes(file.FullName, data);
43
+                if (!file.Exists) return false;
44
+                if (!dir.Exists) dir.Create();
45
+
46
+                var ret = HKPD_CUT(file.FullName, 1, false, dir.FullName);
47
+                if (ret != 0) return false;
48
+
49
+                //检查裁剪数据
50
+                var f = new FileInfo(Path.Combine(dir.FullName, "大写金额.bmp"));
51
+                if (!f.Exists) return false;
52
+                cutData.Add(File.ReadAllBytes(f.FullName));
53
+
54
+                f = new FileInfo(Path.Combine(dir.FullName, "小写金额.bmp"));
55
+                if (!f.Exists) return false;
56
+                cutData.Add(File.ReadAllBytes(f.FullName));
57
+
58
+                f = new FileInfo(Path.Combine(dir.FullName, "业务类型时间.bmp"));
59
+                if (!f.Exists) return false;
60
+                cutData.Add(File.ReadAllBytes(f.FullName));
61
+
62
+                f = new FileInfo(Path.Combine(dir.FullName, "转出方.bmp"));
63
+                if (!f.Exists) return false;
64
+                cutData.Add(File.ReadAllBytes(f.FullName));
65
+
66
+                f = new FileInfo(Path.Combine(dir.FullName, "转入方.bmp"));
67
+                if (!f.Exists) return false;
68
+                cutData.Add(File.ReadAllBytes(f.FullName));
69
+            }
70
+            catch
71
+            {
72
+                return false;
73
+            }
74
+            finally
75
+            {
76
+                File.Delete(file.FullName);
77
+                Directory.Delete(dir.FullName, true);
78
+            }
79
+            return true;
80
+        }
81
+
82
+
83
+        /*
84
+            功能:组织机构代码的裁剪
85
+            输入:
86
+               char *filename 含有绝对路径的文件名
87
+               BOOL bDegbugFlag 是否调试 TRUE 调试输出 FALSE 不调试
88
+               char *SavePath 裁剪后的保存路径
89
+               char *ORGNO 组织机构代码
90
+               char *ORGNAME 组织名称
91
+           输出:
92
+               0 成功
93
+               1 裁剪方式错误
94
+               7 目录不存在或者格式错误
95
+               8 不存在图像文件或图像格式错误 必须为bmp格式
96
+               9 图像质量太差,无法裁剪
97
+        */
98
+        [DllImport("FLowBankImageMfcDll.dll")]
99
+        private static extern int ORGNOTE_CUT(string filename, bool bDebugFlag, string SavePath, StringBuilder ORGNO, StringBuilder ORGNAME);
100
+
101
+        /// <summary>
102
+        /// 切割组织机构代码,图形集合依次为 -0.{[识别的组织机构代码证号],[组织机构代码证号图像数据]}- 1.{[识别的组织机构代码证名],[组织机构代码证名图像数据]} 
103
+        /// </summary>
104
+        /// <param name="data"></param>
105
+        /// <param name="cutData"></param>
106
+        /// <returns></returns>
107
+        public static bool CutORGNOTE(byte[] data, out Dictionary<string, byte[]> cutData)
108
+        {
109
+            cutData = new Dictionary<string, byte[]>();
110
+
111
+            //将源数据保存为图片
112
+            var file = new FileInfo(Path.Combine("temp", "ORGNOTE.bmp"));
113
+            if (!file.Directory.Exists) file.Directory.Create();
114
+            var dir = new DirectoryInfo(Path.Combine("temp", "ORGNOTE"));
115
+            try
116
+            {
117
+                File.WriteAllBytes(file.FullName, data);
118
+                if (!file.Exists) return false;
119
+                if (!dir.Exists) dir.Create();
120
+
121
+                var ORGNO = new StringBuilder();
122
+                var ORGNAME = new StringBuilder();
123
+                var ret = ORGNOTE_CUT(file.FullName, false, dir.FullName, ORGNO, ORGNAME);
124
+                if (ret != 0) return false;
125
+
126
+                //检查裁剪数据
127
+                var f = new FileInfo(Path.Combine(dir.FullName, "机构代码.bmp"));
128
+                if (!f.Exists) return false;
129
+                var ORGNO_Value = ORGNO.ToString();
130
+                var index = ORGNO_Value.IndexOf(':');
131
+                if (index >= 0)
132
+                {
133
+                    ORGNO_Value = ORGNO_Value.Substring(index + 1);
134
+                }
135
+                cutData.Add(ORGNO_Value.Replace(" ", ""), File.ReadAllBytes(f.FullName));
136
+
137
+                f = new FileInfo(Path.Combine(dir.FullName, "机构名称.bmp"));
138
+                if (!f.Exists) return false;
139
+                var ORGNAME_Value = ORGNAME.ToString();
140
+                index = ORGNAME_Value.IndexOf(':');
141
+                if (index >= 0)
142
+                {
143
+                    ORGNAME_Value = ORGNAME_Value.Substring(index + 1);
144
+                }
145
+                cutData.Add(ORGNAME_Value.Replace(" ", ""), File.ReadAllBytes(f.FullName));
146
+            }
147
+            catch
148
+            {
149
+                return false;
150
+            }
151
+            finally
152
+            {
153
+                File.Delete(file.FullName);
154
+                Directory.Delete(dir.FullName, true);
155
+            }
156
+            return true;
157
+        }
158
+
159
+        /*
160
+           功能:身份证的裁剪
161
+           输入:
162
+           char *filename 含有绝对路径的文件名
163
+           BOOL bDegbugFlag 是否调试 TRUE 调试输出 FALSE 不调试
164
+           char *SavePath 裁剪后的保存路径
165
+           char *IDNAME 身份证名称
166
+           char *IDNO 身份证号码
167
+           输出:
168
+               0		成功
169
+               1		//initialization failed
170
+               2		//unsupported image format
171
+               3		// file operating error ( reading or writing)
172
+               4		// writing file error
173
+               5		// no enough memory
174
+               6		//no recognized result
175
+               7		//软件加密锁未连接,或加密锁驱动未安装
176
+               8		//Getcharinfo()该字符没有字符信息,比如:空格,制表符,回车换行符
177
+               9		//Getcharinfo()传入索引超过总字符数
178
+               10		//Getcharinfo(),本页没有文字识别结果
179
+               11		// errors not listed above
180
+               12		// dll load error
181
+               13		// 参数错误
182
+               14		// 版面分析无结果
183
+               15		裁剪失败,没有定位到具体位置
184
+               16		打开图像文件错误
185
+               17		保存路径为空
186
+           */
187
+        //int  IDCARD_CUT(char *filename,BOOL bDebugFlag,char *SavePath,char *IdName,char *IdNo)
188
+        [DllImport("FLowBankImageMfcDll.dll")]
189
+        private static extern int IDCARD_CUT(string filename, bool bDebugFlag, string SavePath, StringBuilder IDNAME, StringBuilder IDNO, bool bCutEdge);
190
+
191
+        /// <summary>
192
+        /// 切割组织机构代码,图形集合依次为 -0.{[识别的组织机构代码证号],[组织机构代码证号图像数据]}- 1.{[识别的组织机构代码证名],[组织机构代码证名图像数据]} 
193
+        /// </summary>
194
+        /// <param name="data"></param>
195
+        /// <param name="cutData"></param>
196
+        /// <returns></returns>
197
+        public static bool CutIDCARD(byte[] data, out Dictionary<string, byte[]> cutData)
198
+        {
199
+            cutData = new Dictionary<string, byte[]>();
200
+
201
+            //将源数据保存为图片
202
+            var file = new FileInfo(Path.Combine("temp", "IDCARD.bmp"));
203
+            if (!file.Directory.Exists) file.Directory.Create();
204
+            var dir = new DirectoryInfo(Path.Combine("temp", "IDCARD"));
205
+            try
206
+            {
207
+                File.WriteAllBytes(file.FullName, data);
208
+                if (!file.Exists) return false;
209
+                if (!dir.Exists) dir.Create();
210
+
211
+                var IDNAME = new StringBuilder();
212
+                var IDNO = new StringBuilder();
213
+                var ret = IDCARD_CUT(file.FullName, false, dir.FullName, IDNAME, IDNO, false);
214
+                if (ret != 0) return false;
215
+
216
+                //检查裁剪数据
217
+                var f = new FileInfo(Path.Combine(dir.FullName, "身份证名称.bmp"));
218
+                if (!f.Exists) return false;
219
+                //var IDNAME_Value = IDNAME.ToString();
220
+                //if (IDNAME_Value.Length > 4)
221
+                //    IDNAME_Value = IDNAME_Value.Substring(4);
222
+                cutData.Add(IDNAME.ToString().Replace(" ", ""), File.ReadAllBytes(f.FullName));
223
+
224
+                f = new FileInfo(Path.Combine(dir.FullName, "身份证号码.bmp"));
225
+                if (!f.Exists) return false;
226
+                //var IDNO_Value = IDNO.ToString();
227
+                //for (int i = 0; i < IDNO_Value.Length; i++)
228
+                //{
229
+                //    var c = IDNO_Value[i];
230
+                //    if (c >= '0' && c <= '9')
231
+                //    {
232
+                //        IDNO_Value = IDNO_Value.Substring(i);
233
+                //        break;
234
+                //    }
235
+                //}
236
+                cutData.Add(IDNO.ToString().Replace(" ", ""), File.ReadAllBytes(f.FullName));
237
+            }
238
+            catch
239
+            {
240
+                return false;
241
+            }
242
+            finally
243
+            {
244
+                File.Delete(file.FullName);
245
+                Directory.Delete(dir.FullName, true);
246
+            }
247
+            return true;
248
+        }
249
+
250
+        /*
251
+            功能:身份证的裁剪-删掉图像的边缘
252
+            输入:
253
+            char *filename 含有绝对路径的文件名
254
+            BOOL bDegbugFlag 是否调试 TRUE 调试输出 FALSE 不调试
255
+            char *SavePath 裁剪后的保存路径
256
+            char *SaveName 保存裁剪后的名称
257
+            BOOL bCutEdge 是否删除原图像 TRUE 删除 FALSE 不删除
258
+            int  iSaveMode 保存模式
259
+            			0	与原图相同
260
+            			1	灰度图像
261
+            			2	二值图像
262
+            输出:
263
+            	0		成功
264
+            
265
+        **/
266
+        [DllImport("FLowBankImageMfcDll.dll")]
267
+        private static extern int IDCARD_CUT_EDGE(string filename, bool bDegbugFlag, string SavePath, string SaveName, bool bDelete, int iSaveMode);
268
+
269
+        /// <summary>
270
+        /// 处理身份证图片,返回去黑边之后的数据
271
+        /// </summary>
272
+        /// <param name="data"></param>
273
+        /// <returns></returns>
274
+        public static byte[] CutIDCARDBorder(byte[] data)
275
+        {
276
+            byte[] retData = null;
277
+            //将源数据保存为图片
278
+            var file = new FileInfo(Path.Combine("temp", "IDCARD.bmp"));
279
+            if (!file.Directory.Exists) file.Directory.Create();
280
+            var dir = new DirectoryInfo(Path.Combine("temp", "IDCARD"));
281
+            try
282
+            {
283
+                File.WriteAllBytes(file.FullName, data);
284
+                if (file.Exists)
285
+                {
286
+                    if (!dir.Exists) dir.Create();
287
+                    var f = new FileInfo(Path.Combine(dir.FullName, "去边身份证.bmp"));
288
+                    var ret = IDCARD_CUT_EDGE(file.FullName, false, dir.FullName, f.Name, false, 1);
289
+                    if (ret == 0 && f.Exists)
290
+                    {
291
+                        retData = File.ReadAllBytes(f.FullName);
292
+                    }
293
+                }
294
+            }
295
+            catch
296
+            {
297
+            }
298
+            finally
299
+            {
300
+                File.Delete(file.FullName);
301
+                Directory.Delete(dir.FullName, true);
302
+            }
303
+            return retData;
304
+        }
305
+    }
306
+}

+ 198
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ImageCutHelper.ts 查看文件

@@ -0,0 +1,198 @@
1
+// 模拟后端服务调用
2
+async function callBackendService(endpoint: string, data: any): Promise<any> {
3
+    // 这里需要替换为实际的后端服务调用逻辑
4
+    return new Promise((resolve) => {
5
+        setTimeout(() => {
6
+            resolve({ success: true, data: null });
7
+        }, 1000);
8
+    });
9
+}
10
+
11
+// 模拟文件操作
12
+class FileSystem {
13
+    static async writeFile(path: string, data: Uint8Array): Promise<void> {
14
+        // 这里需要替换为实际的文件写入逻辑
15
+    }
16
+
17
+    static async readFile(path: string): Promise<Uint8Array> {
18
+        // 这里需要替换为实际的文件读取逻辑
19
+        return new Uint8Array();
20
+    }
21
+
22
+    static async deleteFile(path: string): Promise<void> {
23
+        // 这里需要替换为实际的文件删除逻辑
24
+    }
25
+
26
+    static async createDirectory(path: string): Promise<void> {
27
+        // 这里需要替换为实际的目录创建逻辑
28
+    }
29
+
30
+    static async deleteDirectory(path: string, recursive: boolean): Promise<void> {
31
+        // 这里需要替换为实际的目录删除逻辑
32
+    }
33
+
34
+    static async fileExists(path: string): Promise<boolean> {
35
+        // 这里需要替换为实际的文件存在检查逻辑
36
+        return false;
37
+    }
38
+}
39
+
40
+class ImageCutHelper {
41
+    static async CutHKPD(data: Uint8Array): Promise<{ success: boolean; cutData: Uint8Array[] }> {
42
+        const cutData: Uint8Array[] = [];
43
+        const tempFilePath = "temp/HKPD.bmp";
44
+        const outputDir = "temp/HKPD";
45
+
46
+        try {
47
+            await FileSystem.createDirectory("temp");
48
+            await FileSystem.writeFile(tempFilePath, data);
49
+
50
+            const result = await callBackendService("HKPD_CUT", {
51
+                filename: tempFilePath,
52
+                iMode: 1,
53
+                bDebugFlag: false,
54
+                SavePath: outputDir,
55
+            });
56
+
57
+            if (!result.success) {
58
+                return { success: false, cutData: [] };
59
+            }
60
+
61
+            const filenames = ["大写金额.bmp", "小写金额.bmp", "业务类型时间.bmp", "转出方.bmp", "转入方.bmp"];
62
+            for (const filename of filenames) {
63
+                const filePath = `${outputDir}/${filename}`;
64
+                if (await FileSystem.fileExists(filePath)) {
65
+                    cutData.push(await FileSystem.readFile(filePath));
66
+                } else {
67
+                    return { success: false, cutData: [] };
68
+                }
69
+            }
70
+
71
+            return { success: true, cutData };
72
+        } catch (error) {
73
+            return { success: false, cutData: [] };
74
+        } finally {
75
+            await FileSystem.deleteFile(tempFilePath);
76
+            await FileSystem.deleteDirectory(outputDir, true);
77
+        }
78
+    }
79
+
80
+    static async CutORGNOTE(data: Uint8Array): Promise<{ success: boolean; cutData: { [key: string]: Uint8Array } }> {
81
+        const cutData: { [key: string]: Uint8Array } = {};
82
+        const tempFilePath = "temp/ORGNOTE.bmp";
83
+        const outputDir = "temp/ORGNOTE";
84
+
85
+        try {
86
+            await FileSystem.createDirectory("temp");
87
+            await FileSystem.writeFile(tempFilePath, data);
88
+
89
+            const result = await callBackendService("ORGNOTE_CUT", {
90
+                filename: tempFilePath,
91
+                bDebugFlag: false,
92
+                SavePath: outputDir,
93
+            });
94
+
95
+            if (!result.success) {
96
+                return { success: false, cutData: {} };
97
+            }
98
+
99
+            const ORGNO = result.ORGNO;
100
+            const ORGNAME = result.ORGNAME;
101
+
102
+            const filenames = ["机构代码.bmp", "机构名称.bmp"];
103
+            const keys = [ORGNO.replace(" ", ""), ORGNAME.replace(" ", "")];
104
+
105
+            for (let i = 0; i < filenames.length; i++) {
106
+                const filePath = `${outputDir}/${filenames[i]}`;
107
+                if (await FileSystem.fileExists(filePath)) {
108
+                    cutData[keys[i]] = await FileSystem.readFile(filePath);
109
+                } else {
110
+                    return { success: false, cutData: {} };
111
+                }
112
+            }
113
+
114
+            return { success: true, cutData };
115
+        } catch (error) {
116
+            return { success: false, cutData: {} };
117
+        } finally {
118
+            await FileSystem.deleteFile(tempFilePath);
119
+            await FileSystem.deleteDirectory(outputDir, true);
120
+        }
121
+    }
122
+
123
+    static async CutIDCARD(data: Uint8Array): Promise<{ success: boolean; cutData: { [key: string]: Uint8Array } }> {
124
+        const cutData: { [key: string]: Uint8Array } = {};
125
+        const tempFilePath = "temp/IDCARD.bmp";
126
+        const outputDir = "temp/IDCARD";
127
+
128
+        try {
129
+            await FileSystem.createDirectory("temp");
130
+            await FileSystem.writeFile(tempFilePath, data);
131
+
132
+            const result = await callBackendService("IDCARD_CUT", {
133
+                filename: tempFilePath,
134
+                bDebugFlag: false,
135
+                SavePath: outputDir,
136
+            });
137
+
138
+            if (!result.success) {
139
+                return { success: false, cutData: {} };
140
+            }
141
+
142
+            const IDNAME = result.IDNAME.replace(" ", "");
143
+            const IDNO = result.IDNO.replace(" ", "");
144
+
145
+            const filenames = ["身份证名称.bmp", "身份证号码.bmp"];
146
+            const keys = [IDNAME, IDNO];
147
+
148
+            for (let i = 0; i < filenames.length; i++) {
149
+                const filePath = `${outputDir}/${filenames[i]}`;
150
+                if (await FileSystem.fileExists(filePath)) {
151
+                    cutData[keys[i]] = await FileSystem.readFile(filePath);
152
+                } else {
153
+                    return { success: false, cutData: {} };
154
+                }
155
+            }
156
+
157
+            return { success: true, cutData };
158
+        } catch (error) {
159
+            return { success: false, cutData: {} };
160
+        } finally {
161
+            await FileSystem.deleteFile(tempFilePath);
162
+            await FileSystem.deleteDirectory(outputDir, true);
163
+        }
164
+    }
165
+
166
+    static async CutIDCARDBorder(data: Uint8Array): Promise<Uint8Array | null> {
167
+        const tempFilePath = "temp/IDCARD.bmp";
168
+        const outputDir = "temp/IDCARD";
169
+        const outputFilePath = `${outputDir}/去边身份证.bmp`;
170
+
171
+        try {
172
+            await FileSystem.createDirectory("temp");
173
+            await FileSystem.writeFile(tempFilePath, data);
174
+
175
+            const result = await callBackendService("IDCARD_CUT_EDGE", {
176
+                filename: tempFilePath,
177
+                bDegbugFlag: false,
178
+                SavePath: outputDir,
179
+                SaveName: "去边身份证.bmp",
180
+                bDelete: false,
181
+                iSaveMode: 1,
182
+            });
183
+
184
+            if (result.success && await FileSystem.fileExists(outputFilePath)) {
185
+                return await FileSystem.readFile(outputFilePath);
186
+            } else {
187
+                return null;
188
+            }
189
+        } catch (error) {
190
+            return null;
191
+        } finally {
192
+            await FileSystem.deleteFile(tempFilePath);
193
+            await FileSystem.deleteDirectory(outputDir, true);
194
+        }
195
+    }
196
+}
197
+
198
+export default ImageCutHelper;

+ 147
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/LoggerFTP.cs 查看文件

@@ -0,0 +1,147 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+//
6
+using System.IO;
7
+using System.Net;
8
+using System.Text.RegularExpressions;
9
+using TellerSystem.ServiceProxy.Ext.ServiceHelper;
10
+using Platform.Common.RunningParameters;
11
+
12
+namespace TellerSystem.Library.Ext.TradeExtension
13
+{
14
+    /// <summary>
15
+    /// FTP日志上传备份 
16
+    /// </summary>
17
+    /// <author>翟国栋</author>
18
+    /// <date>2013/9/25 9:23:56</date>
19
+    public static class LoggerFTP
20
+    {
21
+        static string FileName = "Logs";
22
+        private static byte[] fileData = null;
23
+        private static string filePath = "";
24
+        private static List<string> localLogPath = new List<string>();
25
+
26
+        /// <summary>
27
+        /// 判断当前日志文件是否存在没有备份的
28
+        /// </summary>
29
+        /// <param name="file">文件路径</param>
30
+        /// <param name="currentDate">营业日期</param>
31
+        /// <returns>True-存在,False-不存在</returns>
32
+        public static bool IsExistLogFile(FileSystemInfo file, string currentDate)
33
+        {
34
+            if (!file.Exists)
35
+                return false;
36
+            DirectoryInfo dire = file as DirectoryInfo;
37
+            if (dire == null)
38
+                return false;
39
+            FileSystemInfo[] files = dire.GetFileSystemInfos();
40
+            var fileCount = files.TakeWhile(x => Convert.ToDecimal(x.Name) < Convert.ToDecimal(currentDate)).ToList();
41
+            if (fileCount.Count() > 0)
42
+                return true;
43
+            return false;
44
+        }
45
+        /// <summary>
46
+        /// 递归遍历本地日志路径
47
+        /// </summary>
48
+        /// <param name="path">本地日志路径</param>
49
+        /// <returns>日志路径列表</returns>
50
+        private static List<string> getFiles(string path)
51
+        {
52
+            string[] strFileNames = Directory.GetFiles(path);
53
+            string[] strDirectories = Directory.GetDirectories(path);
54
+            foreach (string filename in strFileNames)
55
+            {
56
+                localLogPath.Add(filename);
57
+            }
58
+            foreach (string dir in strDirectories)
59
+            {
60
+                getFiles(dir);
61
+            }
62
+            return localLogPath;
63
+        }
64
+        /// <summary>
65
+        /// 遍历子目录,备份当前日期前的日志文件        
66
+        /// </summary>
67
+        /// <param name="file"></param>
68
+        public static void GetFileSystemInfos(FileSystemInfo file)
69
+        {
70
+            localLogPath.Clear();
71
+            if (!file.Exists) return;
72
+            var list = getFiles(file.FullName);
73
+
74
+            foreach (var item in list)
75
+            {
76
+
77
+                if (!item.Contains(LoginUserInfo.TradeDate))
78
+                {
79
+                    var upLastName = item.Substring(item.IndexOf(FileName), item.Length - item.IndexOf(FileName)).ToString();
80
+                    //上传日志文件
81
+                    string upPath = string.Empty;
82
+                    string[] upPathArray = upLastName.Split('\\');
83
+                    for (int i = 0; i < upPathArray.Length; i++)
84
+                    {
85
+                        if (i < upPathArray.Length - 1)
86
+                        {
87
+                            upPath += upPathArray[i] + "/";
88
+                        }
89
+                    }
90
+                    fileData = File.ReadAllBytes(item);
91
+                    var result = 0.00;
92
+                    try
93
+                    {
94
+                        result = TradeHandle.FtpUpLoad(upLastName.Split('\\').LastOrDefault(), upPath, fileData);
95
+                    }
96
+                    catch (Exception e)
97
+                    {
98
+
99
+                    }
100
+                }
101
+            }
102
+        }
103
+
104
+        /// <summary>
105
+        /// 清除本地日志文件
106
+        /// </summary>
107
+        public static void ClearFiles(FileSystemInfo file)
108
+        {
109
+            DirectoryInfo dire = file as DirectoryInfo;
110
+            if (dire == null) return;
111
+            FileSystemInfo[] files = dire.GetFileSystemInfos();
112
+            string date = string.Empty;
113
+            if (LoginUserInfo.TradeDate.Length == 8)
114
+                date = LoginUserInfo.TradeDate.Substring(0, 4) + "-" + LoginUserInfo.TradeDate.Substring(4, 2) + "-" + LoginUserInfo.TradeDate.Substring(6, 2);
115
+            DateTime dt = DateTime.Now;
116
+            if (!DateTime.TryParse(date, out dt))
117
+                return;
118
+            string[] dateList = new string[3];
119
+            dateList[0] = LoginUserInfo.TradeDate;
120
+            dateList[1] = string.Format("{0:yyyyMMdd}", dt.AddDays(-1));
121
+            dateList[2] = string.Format("{0:yyyyMMdd}", dt.AddDays(-2));
122
+            for (int i = 0; i < files.Length; i++)
123
+            {
124
+                bool flag = true;
125
+                string finame = files[i].Name;
126
+                string fipath = files[i].FullName;
127
+                for (int y = 0; y < dateList.Length; y++)
128
+                {
129
+                    if (files[i].Name == dateList[y])
130
+                    {
131
+                        flag = false;
132
+                        continue;
133
+                    }                        
134
+                   
135
+                }
136
+                if (flag)
137
+                {
138
+                    DirectoryInfo dirInfo = new DirectoryInfo(fipath);
139
+                    //删除目录及其子目录
140
+                    dirInfo.Delete(true);
141
+                }
142
+                
143
+                  
144
+            }
145
+        }
146
+    }
147
+}

+ 140
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/LoggerFTP.ts 查看文件

@@ -0,0 +1,140 @@
1
+// 模拟依赖的类和方法
2
+class FileSystemInfo {
3
+    exists: boolean;
4
+    fullName: string;
5
+
6
+    constructor(exists: boolean, fullName: string) {
7
+        this.exists = exists;
8
+        this.fullName = fullName;
9
+    }
10
+}
11
+
12
+class DirectoryInfo extends FileSystemInfo {
13
+    constructor(exists: boolean, fullName: string) {
14
+        super(exists, fullName);
15
+    }
16
+
17
+    getFileSystemInfos(): FileSystemInfo[] {
18
+        // 模拟实现,实际需要根据文件系统操作实现
19
+        return [];
20
+    }
21
+
22
+    delete(recursive: boolean): void {
23
+        // 模拟删除操作
24
+    }
25
+}
26
+
27
+class TradeHandle {
28
+    static FtpUpLoad(fileName: string, path: string, fileData: number[]): number {
29
+        // 模拟 FTP 上传操作
30
+        return 0;
31
+    }
32
+}
33
+
34
+class LoginUserInfo {
35
+    static get TradeDate(): string {
36
+        return "";
37
+    }
38
+}
39
+
40
+class LoggerFTP {
41
+    static FileName: string = "Logs";
42
+    private static fileData: number[] | null = null;
43
+    private static filePath: string = "";
44
+    private static localLogPath: string[] = [];
45
+
46
+    static IsExistLogFile(file: FileSystemInfo, currentDate: string): boolean {
47
+        if (!file.exists) {
48
+            return false;
49
+        }
50
+        const dire = file as DirectoryInfo;
51
+        if (!dire) {
52
+            return false;
53
+        }
54
+        const files = dire.getFileSystemInfos();
55
+        const fileCount = files.filter(x => parseFloat(x.fullName.split('/').pop() || '') < parseFloat(currentDate));
56
+        return fileCount.length > 0;
57
+    }
58
+
59
+    private static getFiles(path: string): string[] {
60
+        const strFileNames: string[] = []; // 模拟获取文件列表
61
+        const strDirectories: string[] = []; // 模拟获取子目录列表
62
+
63
+        strFileNames.forEach(filename => {
64
+            this.localLogPath.push(filename);
65
+        });
66
+
67
+        strDirectories.forEach(dir => {
68
+            this.getFiles(dir);
69
+        });
70
+
71
+        return this.localLogPath;
72
+    }
73
+
74
+    static GetFileSystemInfos(file: FileSystemInfo): void {
75
+        this.localLogPath = [];
76
+        if (!file.exists) {
77
+            return;
78
+        }
79
+        const list = this.getFiles(file.fullName);
80
+
81
+        list.forEach(item => {
82
+            if (!item.includes(LoginUserInfo.TradeDate)) {
83
+                const upLastName = item.substring(item.indexOf(this.FileName));
84
+                let upPath = "";
85
+                const upPathArray = upLastName.split('\\');
86
+                for (let i = 0; i < upPathArray.length; i++) {
87
+                    if (i < upPathArray.length - 1) {
88
+                        upPath += upPathArray[i] + "/";
89
+                    }
90
+                }
91
+                // 模拟读取文件字节数据
92
+                this.fileData = []; 
93
+                let result = 0;
94
+                try {
95
+                    result = TradeHandle.FtpUpLoad(upPathArray[upPathArray.length - 1], upPath, this.fileData);
96
+                } catch (e) {
97
+                    // 忽略异常
98
+                }
99
+            }
100
+        });
101
+    }
102
+
103
+    static ClearFiles(file: FileSystemInfo): void {
104
+        const dire = file as DirectoryInfo;
105
+        if (!dire) {
106
+            return;
107
+        }
108
+        const files = dire.getFileSystemInfos();
109
+        let date = "";
110
+        if (LoginUserInfo.TradeDate.length === 8) {
111
+            date = `${LoginUserInfo.TradeDate.substring(0, 4)}-${LoginUserInfo.TradeDate.substring(4, 2)}-${LoginUserInfo.TradeDate.substring(6, 2)}`;
112
+        }
113
+        let dt = new Date();
114
+        if (isNaN(Date.parse(date))) {
115
+            return;
116
+        }
117
+        dt = new Date(date);
118
+        const dateList: string[] = [
119
+            LoginUserInfo.TradeDate,
120
+            new Date(dt.getTime() - 24 * 60 * 60 * 1000).toISOString().slice(0, 10).replace(/-/g, ''),
121
+            new Date(dt.getTime() - 2 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10).replace(/-/g, '')
122
+        ];
123
+
124
+        files.forEach(fileInfo => {
125
+            let flag = true;
126
+            const finame = fileInfo.fullName.split('/').pop() || '';
127
+            dateList.forEach(dateItem => {
128
+                if (finame === dateItem) {
129
+                    flag = false;
130
+                }
131
+            });
132
+            if (flag) {
133
+                const dirInfo = new DirectoryInfo(true, fileInfo.fullName);
134
+                dirInfo.delete(true);
135
+            }
136
+        });
137
+    }
138
+}
139
+
140
+export { LoggerFTP };

+ 14
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/INotification.cs 查看文件

@@ -0,0 +1,14 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+
6
+namespace TellerSystem.Library.Ext.TradeExtension
7
+{
8
+    interface INotification
9
+    {
10
+         void Register();
11
+
12
+         void Unregister();
13
+    }
14
+}

+ 65
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/MessageData.cs 查看文件

@@ -0,0 +1,65 @@
1
+using System.Xml;
2
+
3
+namespace TellerSystem.Library.Ext.TradeExtension
4
+{
5
+    /// <summary>
6
+    /// 报文数据
7
+    /// </summary>
8
+    public class MessageData
9
+    {
10
+        public MessageData()
11
+        {
12
+                
13
+        }
14
+
15
+        public MessageData(XmlNode xnRoot)
16
+        {
17
+            XmlNode node = xnRoot.SelectSingleNode("Message");
18
+            Type = node.Attributes["type"].Value;
19
+            XmlNode nodeItem = node.SelectSingleNode("info");
20
+            Key = nodeItem.Attributes["Key"].Value;
21
+            Sender = nodeItem.Attributes["Sender"].Value;
22
+            Time = nodeItem.Attributes["Time"].Value;
23
+            Title = nodeItem.Attributes["Title"].Value;
24
+            Trade = nodeItem.Attributes["Trade"].Value;
25
+            Other = nodeItem.Attributes["Other"].Value;
26
+        }
27
+
28
+        /// <summary>
29
+        ///     0-表示公告消息;
30
+        ///     1-表示任务推送;
31
+        ///     2-表示任务消息
32
+        /// </summary>
33
+        public string Type { get; set; }
34
+
35
+        /// <summary>
36
+        ///     发起人
37
+        /// </summary>
38
+        public string Sender { get; set; }
39
+
40
+        /// <summary>
41
+        ///     发起时间
42
+        /// </summary>
43
+        public string Time { get; set; }
44
+
45
+        /// <summary>
46
+        ///     标题
47
+        /// </summary>
48
+        public string Title { get; set; }
49
+
50
+        /// <summary>
51
+        ///     交易名称
52
+        /// </summary>
53
+        public string Trade { get; set; }
54
+
55
+        /// <summary>
56
+        ///     关键key
57
+        /// </summary>
58
+        public string Key { get; set; }
59
+
60
+        /// <summary>
61
+        ///     其他
62
+        /// </summary>
63
+        public string Other { get; set; }
64
+    }
65
+}

+ 31
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/IExecuteWithObject.cs 查看文件

@@ -0,0 +1,31 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+
6
+namespace TellerSystem.Library.Ext.TradeExtension
7
+{
8
+   public  interface IExecuteWithObject
9
+    {
10
+        /// <summary>
11
+        ///Action触发对象
12
+        /// </summary>
13
+        object Target
14
+        {
15
+            get;
16
+        }
17
+
18
+        /// <summary>
19
+        ///执行Action
20
+        /// </summary>
21
+        /// <param name="parameter">
22
+        /// Action参数
23
+        /// </param>
24
+        void ExecuteWithObject(object parameter);
25
+
26
+        /// <summary>
27
+        ///删除所有引用,通知清理方法
28
+        /// </summary>
29
+        void MarkForDeletion();
30
+    }
31
+}

+ 20
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/IExecuteWithObject.ts 查看文件

@@ -0,0 +1,20 @@
1
+// 定义接口
2
+interface IExecuteWithObject {
3
+    /**
4
+     * Action触发对象
5
+     */
6
+    getTarget(): object;
7
+
8
+    /**
9
+     * 执行Action
10
+     * @param parameter Action参数
11
+     */
12
+    executeWithObject(parameter: object): void;
13
+
14
+    /**
15
+     * 删除所有引用,通知清理方法
16
+     */
17
+    markForDeletion(): void;
18
+}
19
+
20
+export { IExecuteWithObject };

+ 17
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/IExecuteWithObjectAndResult.cs 查看文件

@@ -0,0 +1,17 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+
6
+namespace TellerSystem.Library.Ext.TradeExtension
7
+{
8
+    public interface IExecuteWithObjectAndResult
9
+    {
10
+        /// <summary>
11
+        /// 执行Action并返回结果
12
+        /// </summary>
13
+        /// <param name="parameter">Action参数</param>
14
+        /// <returns>Action 返回值</returns>
15
+        object ExecuteWithObject(object parameter);
16
+    }
17
+}

+ 9
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/IExecuteWithObjectAndResult.ts 查看文件

@@ -0,0 +1,9 @@
1
+// 定义接口,保持与 C# 命名一致
2
+export interface IExecuteWithObjectAndResult {
3
+    /**
4
+     * 执行Action并返回结果
5
+     * @param parameter Action参数
6
+     * @returns Action 返回值
7
+     */
8
+    ExecuteWithObject(parameter: any): any;
9
+}

+ 214
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/IMessenger.cs 查看文件

@@ -0,0 +1,214 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Diagnostics.CodeAnalysis;
4
+using System.Linq;
5
+using System.Text;
6
+
7
+namespace TellerSystem.Library.Ext.TradeExtension
8
+{
9
+    public interface IMessenger
10
+    {
11
+        /// <summary>
12
+        /// Registers a recipient for a type of message TMessage. The action
13
+        /// parameter will be executed when a corresponding message is sent.
14
+        /// <para>Registering a recipient does not create a hard reference to it,
15
+        /// so if this recipient is deleted, no memory leak is caused.</para>
16
+        /// </summary>
17
+        /// <typeparam name="TMessage">The type of message that the recipient registers
18
+        /// for.</typeparam>
19
+        /// <param name="recipient">The recipient that will receive the messages.</param>
20
+        /// <param name="action">The action that will be executed when a message
21
+        /// of type TMessage is sent.</param>
22
+        void Register<TMessage>(object recipient, Action<TMessage> action);
23
+
24
+        /// <summary>
25
+        /// Registers a recipient for a type of message TMessage.
26
+        /// The action parameter will be executed when a corresponding 
27
+        /// message is sent. See the receiveDerivedMessagesToo parameter
28
+        /// for details on how messages deriving from TMessage (or, if TMessage is an interface,
29
+        /// messages implementing TMessage) can be received too.
30
+        /// <para>Registering a recipient does not create a hard reference to it,
31
+        /// so if this recipient is deleted, no memory leak is caused.</para>
32
+        /// </summary>
33
+        /// <typeparam name="TMessage">The type of message that the recipient registers
34
+        /// for.</typeparam>
35
+        /// <param name="recipient">The recipient that will receive the messages.</param>
36
+        /// <param name="token">A token for a messaging channel. If a recipient registers
37
+        /// using a token, and a sender sends a message using the same token, then this
38
+        /// message will be delivered to the recipient. Other recipients who did not
39
+        /// use a token when registering (or who used a different token) will not
40
+        /// get the message. Similarly, messages sent without any token, or with a different
41
+        /// token, will not be delivered to that recipient.</param>
42
+        /// <param name="action">The action that will be executed when a message
43
+        /// of type TMessage is sent.</param>
44
+        void Register<TMessage>(object recipient, object token, Action<TMessage> action);
45
+
46
+        /// <summary>
47
+        /// Registers a recipient for a type of message TMessage.
48
+        /// The action parameter will be executed when a corresponding 
49
+        /// message is sent. See the receiveDerivedMessagesToo parameter
50
+        /// for details on how messages deriving from TMessage (or, if TMessage is an interface,
51
+        /// messages implementing TMessage) can be received too.
52
+        /// <para>Registering a recipient does not create a hard reference to it,
53
+        /// so if this recipient is deleted, no memory leak is caused.</para>
54
+        /// </summary>
55
+        /// <typeparam name="TMessage">The type of message that the recipient registers
56
+        /// for.</typeparam>
57
+        /// <param name="recipient">The recipient that will receive the messages.</param>
58
+        /// <param name="token">A token for a messaging channel. If a recipient registers
59
+        /// using a token, and a sender sends a message using the same token, then this
60
+        /// message will be delivered to the recipient. Other recipients who did not
61
+        /// use a token when registering (or who used a different token) will not
62
+        /// get the message. Similarly, messages sent without any token, or with a different
63
+        /// token, will not be delivered to that recipient.</param>
64
+        /// <param name="receiveDerivedMessagesToo">If true, message types deriving from
65
+        /// TMessage will also be transmitted to the recipient. For example, if a SendOrderMessage
66
+        /// and an ExecuteOrderMessage derive from OrderMessage, registering for OrderMessage
67
+        /// and setting receiveDerivedMessagesToo to true will send SendOrderMessage
68
+        /// and ExecuteOrderMessage to the recipient that registered.
69
+        /// <para>Also, if TMessage is an interface, message types implementing TMessage will also be
70
+        /// transmitted to the recipient. For example, if a SendOrderMessage
71
+        /// and an ExecuteOrderMessage implement IOrderMessage, registering for IOrderMessage
72
+        /// and setting receiveDerivedMessagesToo to true will send SendOrderMessage
73
+        /// and ExecuteOrderMessage to the recipient that registered.</para>
74
+        /// </param>
75
+        /// <param name="action">The action that will be executed when a message
76
+        /// of type TMessage is sent.</param>
77
+        void Register<TMessage>(object recipient, object token, bool receiveDerivedMessagesToo, Action<TMessage> action);
78
+
79
+        /// <summary>
80
+        /// Registers a recipient for a type of message TMessage.
81
+        /// The action parameter will be executed when a corresponding 
82
+        /// message is sent. See the receiveDerivedMessagesToo parameter
83
+        /// for details on how messages deriving from TMessage (or, if TMessage is an interface,
84
+        /// messages implementing TMessage) can be received too.
85
+        /// <para>Registering a recipient does not create a hard reference to it,
86
+        /// so if this recipient is deleted, no memory leak is caused.</para>
87
+        /// </summary>
88
+        /// <typeparam name="TMessage">The type of message that the recipient registers
89
+        /// for.</typeparam>
90
+        /// <param name="recipient">The recipient that will receive the messages.</param>
91
+        /// <param name="receiveDerivedMessagesToo">If true, message types deriving from
92
+        /// TMessage will also be transmitted to the recipient. For example, if a SendOrderMessage
93
+        /// and an ExecuteOrderMessage derive from OrderMessage, registering for OrderMessage
94
+        /// and setting receiveDerivedMessagesToo to true will send SendOrderMessage
95
+        /// and ExecuteOrderMessage to the recipient that registered.
96
+        /// <para>Also, if TMessage is an interface, message types implementing TMessage will also be
97
+        /// transmitted to the recipient. For example, if a SendOrderMessage
98
+        /// and an ExecuteOrderMessage implement IOrderMessage, registering for IOrderMessage
99
+        /// and setting receiveDerivedMessagesToo to true will send SendOrderMessage
100
+        /// and ExecuteOrderMessage to the recipient that registered.</para>
101
+        /// </param>
102
+        /// <param name="action">The action that will be executed when a message
103
+        /// of type TMessage is sent.</param>
104
+        void Register<TMessage>(object recipient, bool receiveDerivedMessagesToo, Action<TMessage> action);
105
+
106
+        /// <summary>
107
+        /// Sends a message to registered recipients. The message will
108
+        /// reach all recipients that registered for this message type
109
+        /// using one of the Register methods.
110
+        /// </summary>
111
+        /// <typeparam name="TMessage">The type of message that will be sent.</typeparam>
112
+        /// <param name="message">The message to send to registered recipients.</param>
113
+        void Send<TMessage>(TMessage message);
114
+
115
+        /// <summary>
116
+        /// Sends a message to registered recipients. The message will
117
+        /// reach only recipients that registered for this message type
118
+        /// using one of the Register methods, and that are
119
+        /// of the targetType.
120
+        /// </summary>
121
+        /// <typeparam name="TMessage">The type of message that will be sent.</typeparam>
122
+        /// <typeparam name="TTarget">The type of recipients that will receive
123
+        /// the message. The message won't be sent to recipients of another type.</typeparam>
124
+        /// <param name="message">The message to send to registered recipients.</param>
125
+        [SuppressMessage(
126
+            "Microsoft.Design",
127
+            "CA1004:GenericMethodsShouldProvideTypeParameter",
128
+            Justification = "This syntax is more convenient than other alternatives.")]
129
+        void Send<TMessage, TTarget>(TMessage message);
130
+
131
+        /// <summary>
132
+        /// Sends a message to registered recipients. The message will
133
+        /// reach only recipients that registered for this message type
134
+        /// using one of the Register methods, and that are
135
+        /// of the targetType.
136
+        /// </summary>
137
+        /// <typeparam name="TMessage">The type of message that will be sent.</typeparam>
138
+        /// <param name="message">The message to send to registered recipients.</param>
139
+        /// <param name="token">A token for a messaging channel. If a recipient registers
140
+        /// using a token, and a sender sends a message using the same token, then this
141
+        /// message will be delivered to the recipient. Other recipients who did not
142
+        /// use a token when registering (or who used a different token) will not
143
+        /// get the message. Similarly, messages sent without any token, or with a different
144
+        /// token, will not be delivered to that recipient.</param>
145
+        void Send<TMessage>(TMessage message, object token);
146
+
147
+        /// <summary>
148
+        /// Unregisters a messager recipient completely. After this method
149
+        /// is executed, the recipient will not receive any messages anymore.
150
+        /// </summary>
151
+        /// <param name="recipient">The recipient that must be unregistered.</param>
152
+        void Unregister(object recipient);
153
+
154
+        /// <summary>
155
+        /// Unregisters a message recipient for a given type of messages only. 
156
+        /// After this method is executed, the recipient will not receive messages
157
+        /// of type TMessage anymore, but will still receive other message types (if it
158
+        /// registered for them previously).
159
+        /// </summary>
160
+        /// <typeparam name="TMessage">The type of messages that the recipient wants
161
+        /// to unregister from.</typeparam>
162
+        /// <param name="recipient">The recipient that must be unregistered.</param>
163
+        [SuppressMessage(
164
+            "Microsoft.Design",
165
+            "CA1004:GenericMethodsShouldProvideTypeParameter",
166
+            Justification = "This syntax is more convenient than other alternatives.")]
167
+        void Unregister<TMessage>(object recipient);
168
+
169
+        /// <summary>
170
+        /// Unregisters a message recipient for a given type of messages only and for a given token. 
171
+        /// After this method is executed, the recipient will not receive messages
172
+        /// of type TMessage anymore with the given token, but will still receive other message types
173
+        /// or messages with other tokens (if it registered for them previously).
174
+        /// </summary>
175
+        /// <param name="recipient">The recipient that must be unregistered.</param>
176
+        /// <param name="token">The token for which the recipient must be unregistered.</param>
177
+        /// <typeparam name="TMessage">The type of messages that the recipient wants
178
+        /// to unregister from.</typeparam>
179
+        [SuppressMessage(
180
+            "Microsoft.Design",
181
+            "CA1004:GenericMethodsShouldProvideTypeParameter",
182
+            Justification = "This syntax is more convenient than other alternatives.")]
183
+        void Unregister<TMessage>(object recipient, object token);
184
+
185
+        /// <summary>
186
+        /// Unregisters a message recipient for a given type of messages and for
187
+        /// a given action. Other message types will still be transmitted to the
188
+        /// recipient (if it registered for them previously). Other actions that have
189
+        /// been registered for the message type TMessage and for the given recipient (if
190
+        /// available) will also remain available.
191
+        /// </summary>
192
+        /// <typeparam name="TMessage">The type of messages that the recipient wants
193
+        /// to unregister from.</typeparam>
194
+        /// <param name="recipient">The recipient that must be unregistered.</param>
195
+        /// <param name="action">The action that must be unregistered for
196
+        /// the recipient and for the message type TMessage.</param>
197
+        void Unregister<TMessage>(object recipient, Action<TMessage> action);
198
+
199
+        /// <summary>
200
+        /// Unregisters a message recipient for a given type of messages, for
201
+        /// a given action and a given token. Other message types will still be transmitted to the
202
+        /// recipient (if it registered for them previously). Other actions that have
203
+        /// been registered for the message type TMessage, for the given recipient and other tokens (if
204
+        /// available) will also remain available.
205
+        /// </summary>
206
+        /// <typeparam name="TMessage">The type of messages that the recipient wants
207
+        /// to unregister from.</typeparam>
208
+        /// <param name="recipient">The recipient that must be unregistered.</param>
209
+        /// <param name="token">The token for which the recipient must be unregistered.</param>
210
+        /// <param name="action">The action that must be unregistered for
211
+        /// the recipient and for the message type TMessage.</param>
212
+        void Unregister<TMessage>(object recipient, object token, Action<TMessage> action);
213
+    }
214
+}

+ 197
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/IMessenger.ts 查看文件

@@ -0,0 +1,197 @@
1
+// 定义 Action 类型,模拟 C# 中的 Action 委托
2
+type Action<T> = (arg: T) => void;
3
+
4
+export interface IMessenger {
5
+    /**
6
+     * Registers a recipient for a type of message TMessage. The action
7
+     * parameter will be executed when a corresponding message is sent.
8
+     * Registering a recipient does not create a hard reference to it,
9
+     * so if this recipient is deleted, no memory leak is caused.
10
+     * 
11
+     * @template TMessage - The type of message that the recipient registers for.
12
+     * @param recipient - The recipient that will receive the messages.
13
+     * @param action - The action that will be executed when a message of type TMessage is sent.
14
+     */
15
+    Register<TMessage>(recipient: any, action: Action<TMessage>): void;
16
+
17
+    /**
18
+     * Registers a recipient for a type of message TMessage.
19
+     * The action parameter will be executed when a corresponding 
20
+     * message is sent. See the receiveDerivedMessagesToo parameter
21
+     * for details on how messages deriving from TMessage (or, if TMessage is an interface,
22
+     * messages implementing TMessage) can be received too.
23
+     * Registering a recipient does not create a hard reference to it,
24
+     * so if this recipient is deleted, no memory leak is caused.
25
+     * 
26
+     * @template TMessage - The type of message that the recipient registers for.
27
+     * @param recipient - The recipient that will receive the messages.
28
+     * @param token - A token for a messaging channel. If a recipient registers
29
+     * using a token, and a sender sends a message using the same token, then this
30
+     * message will be delivered to the recipient. Other recipients who did not
31
+     * use a token when registering (or who used a different token) will not
32
+     * get the message. Similarly, messages sent without any token, or with a different
33
+     * token, will not be delivered to that recipient.
34
+     * @param action - The action that will be executed when a message of type TMessage is sent.
35
+     */
36
+    Register<TMessage>(recipient: any, token: any, action: Action<TMessage>): void;
37
+
38
+    /**
39
+     * Registers a recipient for a type of message TMessage.
40
+     * The action parameter will be executed when a corresponding 
41
+     * message is sent. See the receiveDerivedMessagesToo parameter
42
+     * for details on how messages deriving from TMessage (or, if TMessage is an interface,
43
+     * messages implementing TMessage) can be received too.
44
+     * Registering a recipient does not create a hard reference to it,
45
+     * so if this recipient is deleted, no memory leak is caused.
46
+     * 
47
+     * @template TMessage - The type of message that the recipient registers for.
48
+     * @param recipient - The recipient that will receive the messages.
49
+     * @param token - A token for a messaging channel. If a recipient registers
50
+     * using a token, and a sender sends a message using the same token, then this
51
+     * message will be delivered to the recipient. Other recipients who did not
52
+     * use a token when registering (or who used a different token) will not
53
+     * get the message. Similarly, messages sent without any token, or with a different
54
+     * token, will not be delivered to that recipient.
55
+     * @param receiveDerivedMessagesToo - If true, message types deriving from
56
+     * TMessage will also be transmitted to the recipient. For example, if a SendOrderMessage
57
+     * and an ExecuteOrderMessage derive from OrderMessage, registering for OrderMessage
58
+     * and setting receiveDerivedMessagesToo to true will send SendOrderMessage
59
+     * and ExecuteOrderMessage to the recipient that registered.
60
+     * Also, if TMessage is an interface, message types implementing TMessage will also be
61
+     * transmitted to the recipient. For example, if a SendOrderMessage
62
+     * and an ExecuteOrderMessage implement IOrderMessage, registering for IOrderMessage
63
+     * and setting receiveDerivedMessagesToo to true will send SendOrderMessage
64
+     * and ExecuteOrderMessage to the recipient that registered.
65
+     * @param action - The action that will be executed when a message of type TMessage is sent.
66
+     */
67
+    Register<TMessage>(recipient: any, token: any, receiveDerivedMessagesToo: boolean, action: Action<TMessage>): void;
68
+
69
+    /**
70
+     * Registers a recipient for a type of message TMessage.
71
+     * The action parameter will be executed when a corresponding 
72
+     * message is sent. See the receiveDerivedMessagesToo parameter
73
+     * for details on how messages deriving from TMessage (or, if TMessage is an interface,
74
+     * messages implementing TMessage) can be received too.
75
+     * Registering a recipient does not create a hard reference to it,
76
+     * so if this recipient is deleted, no memory leak is caused.
77
+     * 
78
+     * @template TMessage - The type of message that the recipient registers for.
79
+     * @param recipient - The recipient that will receive the messages.
80
+     * @param receiveDerivedMessagesToo - If true, message types deriving from
81
+     * TMessage will also be transmitted to the recipient. For example, if a SendOrderMessage
82
+     * and an ExecuteOrderMessage derive from OrderMessage, registering for OrderMessage
83
+     * and setting receiveDerivedMessagesToo to true will send SendOrderMessage
84
+     * and ExecuteOrderMessage to the recipient that registered.
85
+     * Also, if TMessage is an interface, message types implementing TMessage will also be
86
+     * transmitted to the recipient. For example, if a SendOrderMessage
87
+     * and an ExecuteOrderMessage implement IOrderMessage, registering for IOrderMessage
88
+     * and setting receiveDerivedMessagesToo to true will send SendOrderMessage
89
+     * and ExecuteOrderMessage to the recipient that registered.
90
+     * @param action - The action that will be executed when a message of type TMessage is sent.
91
+     */
92
+    Register<TMessage>(recipient: any, receiveDerivedMessagesToo: boolean, action: Action<TMessage>): void;
93
+
94
+    /**
95
+     * Sends a message to registered recipients. The message will
96
+     * reach all recipients that registered for this message type
97
+     * using one of the Register methods.
98
+     * 
99
+     * @template TMessage - The type of message that will be sent.
100
+     * @param message - The message to send to registered recipients.
101
+     */
102
+    Send<TMessage>(message: TMessage): void;
103
+
104
+    /**
105
+     * Sends a message to registered recipients. The message will
106
+     * reach only recipients that registered for this message type
107
+     * using one of the Register methods, and that are
108
+     * of the targetType.
109
+     * 
110
+     * @template TMessage - The type of message that will be sent.
111
+     * @template TTarget - The type of recipients that will receive
112
+     * the message. The message won't be sent to recipients of another type.
113
+     * @param message - The message to send to registered recipients.
114
+     */
115
+    Send<TMessage, TTarget>(message: TMessage): void;
116
+
117
+    /**
118
+     * Sends a message to registered recipients. The message will
119
+     * reach only recipients that registered for this message type
120
+     * using one of the Register methods, and that are
121
+     * of the targetType.
122
+     * 
123
+     * @template TMessage - The type of message that will be sent.
124
+     * @param message - The message to send to registered recipients.
125
+     * @param token - A token for a messaging channel. If a recipient registers
126
+     * using a token, and a sender sends a message using the same token, then this
127
+     * message will be delivered to the recipient. Other recipients who did not
128
+     * use a token when registering (or who used a different token) will not
129
+     * get the message. Similarly, messages sent without any token, or with a different
130
+     * token, will not be delivered to that recipient.
131
+     */
132
+    Send<TMessage>(message: TMessage, token: any): void;
133
+
134
+    /**
135
+     * Unregisters a messager recipient completely. After this method
136
+     * is executed, the recipient will not receive any messages anymore.
137
+     * 
138
+     * @param recipient - The recipient that must be unregistered.
139
+     */
140
+    Unregister(recipient: any): void;
141
+
142
+    /**
143
+     * Unregisters a message recipient for a given type of messages only. 
144
+     * After this method is executed, the recipient will not receive messages
145
+     * of type TMessage anymore, but will still receive other message types (if it
146
+     * registered for them previously).
147
+     * 
148
+     * @template TMessage - The type of messages that the recipient wants
149
+     * to unregister from.
150
+     * @param recipient - The recipient that must be unregistered.
151
+     */
152
+    Unregister<TMessage>(recipient: any): void;
153
+
154
+    /**
155
+     * Unregisters a message recipient for a given type of messages only and for a given token. 
156
+     * After this method is executed, the recipient will not receive messages
157
+     * of type TMessage anymore with the given token, but will still receive other message types
158
+     * or messages with other tokens (if it registered for them previously).
159
+     * 
160
+     * @template TMessage - The type of messages that the recipient wants
161
+     * to unregister from.
162
+     * @param recipient - The recipient that must be unregistered.
163
+     * @param token - The token for which the recipient must be unregistered.
164
+     */
165
+    Unregister<TMessage>(recipient: any, token: any): void;
166
+
167
+    /**
168
+     * Unregisters a message recipient for a given type of messages and for
169
+     * a given action. Other message types will still be transmitted to the
170
+     * recipient (if it registered for them previously). Other actions that have
171
+     * been registered for the message type TMessage and for the given recipient (if
172
+     * available) will also remain available.
173
+     * 
174
+     * @template TMessage - The type of messages that the recipient wants
175
+     * to unregister from.
176
+     * @param recipient - The recipient that must be unregistered.
177
+     * @param action - The action that must be unregistered for
178
+     * the recipient and for the message type TMessage.
179
+     */
180
+    Unregister<TMessage>(recipient: any, action: Action<TMessage>): void;
181
+
182
+    /**
183
+     * Unregisters a message recipient for a given type of messages, for
184
+     * a given action and a given token. Other message types will still be transmitted to the
185
+     * recipient (if it registered for them previously). Other actions that have
186
+     * been registered for the message type TMessage, for the given recipient and other tokens (if
187
+     * available) will also remain available.
188
+     * 
189
+     * @template TMessage - The type of messages that the recipient wants
190
+     * to unregister from.
191
+     * @param recipient - The recipient that must be unregistered.
192
+     * @param token - The token for which the recipient must be unregistered.
193
+     * @param action - The action that must be unregistered for
194
+     * the recipient and for the message type TMessage.
195
+     */
196
+    Unregister<TMessage>(recipient: any, token: any, action: Action<TMessage>): void;
197
+}

+ 69
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/Message/MessageBase.cs 查看文件

@@ -0,0 +1,69 @@
1
+using System;
2
+using System.Globalization;
3
+
4
+namespace TellerSystem.Library.Ext.TradeExtension
5
+{
6
+    /// <summary>
7
+    ///     Base class for all messages broadcasted by the Messenger.
8
+    ///     You can create your own message types by extending this class.
9
+    /// </summary>
10
+    ////[ClassInfo(typeof(Messenger))]
11
+    internal class MessageBase
12
+    {
13
+        /// <summary>
14
+        ///     Initializes a new instance of the MessageBase class.
15
+        /// </summary>
16
+        public MessageBase()
17
+        {
18
+        }
19
+
20
+        /// <summary>
21
+        ///     Initializes a new instance of the MessageBase class.
22
+        /// </summary>
23
+        /// <param name="sender">The message's original sender.</param>
24
+        public MessageBase(object sender)
25
+        {
26
+            Sender = sender;
27
+        }
28
+
29
+        /// <summary>
30
+        ///     Initializes a new instance of the MessageBase class.
31
+        /// </summary>
32
+        /// <param name="sender">The message's original sender.</param>
33
+        /// <param name="target">
34
+        ///     The message's intended target. This parameter can be used
35
+        ///     to give an indication as to whom the message was intended for. Of course
36
+        ///     this is only an indication, amd may be null.
37
+        /// </param>
38
+        public MessageBase(object sender, object target)
39
+            : this(sender)
40
+        {
41
+            Target = target;
42
+        }
43
+
44
+        /// <summary>
45
+        ///     Gets or sets the message's sender.
46
+        /// </summary>
47
+        public object Sender { get; protected set; }
48
+
49
+        /// <summary>
50
+        ///     Gets or sets the message's intended target. This property can be used
51
+        ///     to give an indication as to whom the message was intended for. Of course
52
+        ///     this is only an indication, amd may be null.
53
+        /// </summary>
54
+        public object Target { get; protected set; }
55
+
56
+        #region Method
57
+
58
+        protected string FormatDateTime(string dateTime)
59
+        {
60
+            string ret = "";
61
+            ret =
62
+                DateTime.ParseExact(dateTime, "yyyyMMddHHmmss", new CultureInfo("zh-CN", true),
63
+                                    DateTimeStyles.AllowInnerWhite).ToString("yyyy-MM-dd HH:mm:ss");
64
+            return ret;
65
+        }
66
+
67
+        #endregion
68
+    }
69
+}

+ 45
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/Message/MessageBase.ts 查看文件

@@ -0,0 +1,45 @@
1
+// 引入必要的模块
2
+import { CultureInfo, DateTime, DateTimeStyles } from 'typescript-dotnet-commonjs';
3
+
4
+// 定义 MessageBase 类
5
+export class MessageBase {
6
+    // 消息发送者
7
+    public sender: any;
8
+    // 消息预期接收者
9
+    public target: any;
10
+
11
+    // 无参构造函数
12
+    constructor();
13
+    // 带 sender 参数的构造函数
14
+    constructor(sender: any);
15
+    // 带 sender 和 target 参数的构造函数
16
+    constructor(sender?: any, target?: any) {
17
+        if (sender) {
18
+            this.sender = sender;
19
+        }
20
+        if (target) {
21
+            this.target = target;
22
+        }
23
+    }
24
+
25
+    /**
26
+     * 格式化日期时间字符串
27
+     * @param dateTime 待格式化的日期时间字符串,格式为 'yyyyMMddHHmmss'
28
+     * @returns 格式化后的日期时间字符串,格式为 'yyyy-MM-dd HH:mm:ss'
29
+     */
30
+    protected formatDateTime(dateTime: string): string {
31
+        let ret = '';
32
+        try {
33
+            const parsedDateTime = DateTime.parseExact(
34
+                dateTime,
35
+                'yyyyMMddHHmmss',
36
+                new CultureInfo('zh-CN', true),
37
+                DateTimeStyles.AllowInnerWhite
38
+            );
39
+            ret = parsedDateTime.toString('yyyy-MM-dd HH:mm:ss');
40
+        } catch (error) {
41
+            console.error('日期时间格式化失败:', error);
42
+        }
43
+        return ret;
44
+    }
45
+}

+ 29
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/Message/NotificationMessage.cs 查看文件

@@ -0,0 +1,29 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Windows;
6
+
7
+namespace TellerSystem.Library.Ext.TradeExtension
8
+{
9
+    [NotificationAttribute("0", "公告消息")]
10
+     class NotificationMessage:MessageBase
11
+    {
12
+        public NotificationMessage(MessageData data)
13
+        {
14
+            Sender = data.Sender;
15
+            Time = data.Time;
16
+            Key = data.Key;
17
+            Title = data.Title;
18
+        }
19
+
20
+        public string Sender { get; set; }
21
+
22
+        public string Time { get; set; }
23
+
24
+        public string Key { get; set; }
25
+
26
+        public string Title { get; set; }   
27
+        
28
+    }
29
+}

+ 45
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/Message/NotificationMessage.ts 查看文件

@@ -0,0 +1,45 @@
1
+// 假设 NotificationAttribute 是一个装饰器,这里简单模拟其定义
2
+function NotificationAttribute(code: string, description: string) {
3
+    return function (target: Function) {
4
+        // 可以在这里添加更多逻辑,目前仅做标记
5
+        target.prototype.notificationCode = code;
6
+        target.prototype.notificationDescription = description;
7
+    };
8
+}
9
+
10
+// 假设 MessageBase 和 MessageData 类型定义如下
11
+class MessageBase {
12
+    // 可以根据实际情况添加 MessageBase 的属性和方法
13
+}
14
+
15
+class MessageData {
16
+    Sender: string;
17
+    Time: string;
18
+    Key: string;
19
+    Title: string;
20
+
21
+    constructor(sender: string, time: string, key: string, title: string) {
22
+        this.Sender = sender;
23
+        this.Time = time;
24
+        this.Key = key;
25
+        this.Title = title;
26
+    }
27
+}
28
+
29
+@NotificationAttribute("0", "公告消息")
30
+class NotificationMessage extends MessageBase {
31
+    Sender: string;
32
+    Time: string;
33
+    Key: string;
34
+    Title: string;
35
+
36
+    constructor(data: MessageData) {
37
+        super();
38
+        this.Sender = data.Sender;
39
+        this.Time = data.Time;
40
+        this.Key = data.Key;
41
+        this.Title = data.Title;
42
+    }
43
+}
44
+
45
+export { NotificationMessage };

+ 67
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/Message/TaskMessage.cs 查看文件

@@ -0,0 +1,67 @@
1
+using System;
2
+using TellerSystem.Library.Ext.TradeInterfaces;
3
+
4
+namespace TellerSystem.Library.Ext.TradeExtension
5
+{
6
+    [Notification("1", "任务消息")]
7
+    internal class TaskMessage : MessageBase
8
+    {
9
+        #region Field
10
+
11
+        private readonly dynamic _mainPage;
12
+
13
+        #endregion
14
+
15
+        public TaskMessage(MessageData data)
16
+        {
17
+            string[] des = data.Title.Split(new[] {"||"}, StringSplitOptions.None);
18
+            string tradeNo = des[0];
19
+            string state = des[1];
20
+            string taskdes;
21
+            switch (state)
22
+            {
23
+                case "Super":
24
+                    taskdes = "等待复核";
25
+                    break;
26
+                case "Auth":
27
+                    taskdes = "等待授权";
28
+                    break;
29
+                case "Submit":
30
+                    taskdes = "等待确认";
31
+                    break;
32
+                default:
33
+                    taskdes = "其他";
34
+                    break;
35
+            }
36
+
37
+
38
+            if (_mainPage == null)
39
+            {
40
+                _mainPage = MainPageManager.GetMainPage();
41
+            }
42
+
43
+            StartTeller = data.Sender;
44
+            StartTime = FormatDateTime(data.Time);
45
+            TradeDes = tradeNo + "  " + _mainPage.GetTradeName(tradeNo);
46
+            TaskDes = taskdes;
47
+            Key = data.Key;
48
+            Other = data.Other;
49
+            Trade = data.Trade;
50
+        }
51
+
52
+
53
+        public string StartTeller { get; set; }
54
+
55
+        public string StartTime { get; set; }
56
+
57
+        public string TradeDes { get; set; }
58
+
59
+        public string TaskDes { get; set; }
60
+
61
+        public string Key { get; set; }
62
+
63
+        public string Other { get; set; }
64
+
65
+        public string Trade { get; set; }
66
+    }
67
+}

+ 81
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/Message/TaskMessage.ts 查看文件

@@ -0,0 +1,81 @@
1
+// 假设 Notification 装饰器可以用一个函数模拟
2
+function Notification(id: string, name: string) {
3
+    return function (target: Function) {
4
+        // 这里可以添加装饰器的逻辑,暂时只是占位
5
+    };
6
+}
7
+
8
+// 假设 MessageBase 类在某个地方定义,这里先做一个空类
9
+class MessageBase { }
10
+
11
+// 假设 MessageData 接口定义如下
12
+interface MessageData {
13
+    Title: string;
14
+    Sender: string;
15
+    Time: string;
16
+    Key: string;
17
+    Other: string;
18
+    Trade: string;
19
+}
20
+
21
+// 假设 MainPageManager 类定义如下
22
+class MainPageManager {
23
+    static getMainPage() {
24
+        // 这里返回一个动态对象,在 TypeScript 里用 any 类型
25
+        return {} as any;
26
+    }
27
+}
28
+
29
+// 模拟 FormatDateTime 函数
30
+function FormatDateTime(time: string): string {
31
+    return time;
32
+}
33
+
34
+@Notification("1", "任务消息")
35
+class TaskMessage extends MessageBase {
36
+    private _mainPage: any;
37
+
38
+    StartTeller: string;
39
+    StartTime: string;
40
+    TradeDes: string;
41
+    TaskDes: string;
42
+    Key: string;
43
+    Other: string;
44
+    Trade: string;
45
+
46
+    constructor(data: MessageData) {
47
+        super();
48
+        const des = data.Title.split("||");
49
+        const tradeNo = des[0];
50
+        const state = des[1];
51
+        let taskdes: string;
52
+        switch (state) {
53
+            case "Super":
54
+                taskdes = "等待复核";
55
+                break;
56
+            case "Auth":
57
+                taskdes = "等待授权";
58
+                break;
59
+            case "Submit":
60
+                taskdes = "等待确认";
61
+                break;
62
+            default:
63
+                taskdes = "其他";
64
+                break;
65
+        }
66
+
67
+        if (!this._mainPage) {
68
+            this._mainPage = MainPageManager.getMainPage();
69
+        }
70
+
71
+        this.StartTeller = data.Sender;
72
+        this.StartTime = FormatDateTime(data.Time);
73
+        this.TradeDes = `${tradeNo}  ${this._mainPage.GetTradeName(tradeNo)}`;
74
+        this.TaskDes = taskdes;
75
+        this.Key = data.Key;
76
+        this.Other = data.Other;
77
+        this.Trade = data.Trade;
78
+    }
79
+}
80
+
81
+export { TaskMessage };

+ 538
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/Messenger.cs 查看文件

@@ -0,0 +1,538 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Diagnostics.CodeAnalysis;
4
+using System.Linq;
5
+using System.Windows.Threading;
6
+
7
+namespace TellerSystem.Library.Ext.TradeExtension
8
+{
9
+    public class Messenger : IMessenger
10
+    {
11
+        private static readonly object CreationLock = new object();
12
+        private static IMessenger _defaultInstance;
13
+        private readonly object _registerLock = new object();
14
+        private Dictionary<Type, List<WeakActionAndToken>> _recipientsOfSubclassesAction;
15
+        private Dictionary<Type, List<WeakActionAndToken>> _recipientsStrictAction;
16
+
17
+        /// <summary>
18
+        ///     获取默认单例
19
+        /// </summary>
20
+        public static IMessenger Default
21
+        {
22
+            get
23
+            {
24
+                if (_defaultInstance == null)
25
+                {
26
+                    lock (CreationLock)
27
+                    {
28
+                        if (_defaultInstance == null)
29
+                        {
30
+                            _defaultInstance = new Messenger();
31
+                        }
32
+                    }
33
+                }
34
+
35
+                return _defaultInstance;
36
+            }
37
+        }
38
+
39
+        #region IMessenger Members
40
+
41
+        private bool _isCleanupRegistered;
42
+
43
+        /// <summary>
44
+        ///     消息监听注册
45
+        /// </summary>
46
+        /// <typeparam name="TMessage">监听类型</typeparam>
47
+        /// <param name="recipient">接收对象</param>
48
+        /// <param name="action">执行Action</param>
49
+        public virtual void Register<TMessage>(object recipient, Action<TMessage> action)
50
+        {
51
+            Register(recipient, null, false, action);
52
+        }
53
+
54
+        /// <summary>
55
+        ///     消息监听注册
56
+        /// </summary>
57
+        /// <typeparam name="TMessage">监听类型</typeparam>
58
+        /// <param name="recipient">接收对象</param>
59
+        /// <param name="receiveDerivedMessagesToo">是否允许接收派生类</param>
60
+        /// <param name="action">执行Action</param>
61
+        public virtual void Register<TMessage>(object recipient, bool receiveDerivedMessagesToo, Action<TMessage> action)
62
+        {
63
+            Register(recipient, null, receiveDerivedMessagesToo, action);
64
+        }
65
+
66
+        /// <summary>
67
+        ///     消息监听注册
68
+        /// </summary>
69
+        /// <typeparam name="TMessage">监听类型</typeparam>
70
+        /// <param name="recipient">接收对象</param>
71
+        /// <param name="token">令牌环</param>
72
+        /// <param name="action">执行Action</param>
73
+        public virtual void Register<TMessage>(object recipient, object token, Action<TMessage> action)
74
+        {
75
+            Register(recipient, token, false, action);
76
+        }
77
+
78
+        /// <summary>
79
+        ///     消息监听注册
80
+        /// </summary>
81
+        /// <typeparam name="TMessage">监听类型</typeparam>
82
+        /// <param name="recipient">接收对象</param>
83
+        /// <param name="token">令牌环</param>
84
+        /// <param name="receiveDerivedMessagesToo">是否允许接收派生类</param>
85
+        /// <param name="action">Action</param>
86
+        public virtual void Register<TMessage>(
87
+            object recipient,
88
+            object token,
89
+            bool receiveDerivedMessagesToo,
90
+            Action<TMessage> action)
91
+        {
92
+            lock (_registerLock)
93
+            {
94
+                Type messageType = typeof (TMessage);
95
+
96
+                Dictionary<Type, List<WeakActionAndToken>> recipients;
97
+
98
+                if (receiveDerivedMessagesToo)
99
+                {
100
+                    if (_recipientsOfSubclassesAction == null)
101
+                    {
102
+                        _recipientsOfSubclassesAction = new Dictionary<Type, List<WeakActionAndToken>>();
103
+                    }
104
+
105
+                    recipients = _recipientsOfSubclassesAction;
106
+                }
107
+                else
108
+                {
109
+                    if (_recipientsStrictAction == null)
110
+                    {
111
+                        _recipientsStrictAction = new Dictionary<Type, List<WeakActionAndToken>>();
112
+                    }
113
+
114
+                    recipients = _recipientsStrictAction;
115
+                }
116
+
117
+                lock (recipients)
118
+                {
119
+                    List<WeakActionAndToken> list;
120
+
121
+                    if (!recipients.ContainsKey(messageType))
122
+                    {
123
+                        list = new List<WeakActionAndToken>();
124
+                        recipients.Add(messageType, list);
125
+                    }
126
+                    else
127
+                    {
128
+                        list = recipients[messageType];
129
+                    }
130
+
131
+                    var weakAction = new WeakAction<TMessage>(recipient, action);
132
+
133
+                    var item = new WeakActionAndToken
134
+                        {
135
+                            Action = weakAction,
136
+                            Token = token
137
+                        };
138
+
139
+                    list.Add(item);
140
+                }
141
+            }
142
+
143
+            RequestCleanup();
144
+        }
145
+
146
+        /// <summary>
147
+        ///     发送消息
148
+        /// </summary>
149
+        /// <typeparam name="TMessage">消息类型</typeparam>
150
+        /// <param name="message">消息实体</param>
151
+        public virtual void Send<TMessage>(TMessage message)
152
+        {
153
+            SendToTargetOrType(message, null, null);
154
+        }
155
+
156
+        /// <summary>
157
+        ///     发送消息
158
+        /// </summary>
159
+        /// <typeparam name="TMessage">消息类型</typeparam>
160
+        /// <typeparam name="TTarget">消息接收对象类型</typeparam>
161
+        /// <param name="message">消息实体</param>
162
+        [SuppressMessage(
163
+            "Microsoft.Design",
164
+            "CA1004:GenericMethodsShouldProvideTypeParameter",
165
+            Justification = "This syntax is more convenient than other alternatives.")]
166
+        public virtual void Send<TMessage, TTarget>(TMessage message)
167
+        {
168
+            SendToTargetOrType(message, typeof (TTarget), null);
169
+        }
170
+
171
+        /// <summary>
172
+        ///     发送消息
173
+        /// </summary>
174
+        /// <typeparam name="TMessage">消息类型</typeparam>
175
+        /// <param name="message">消息实体</param>
176
+        /// <param name="token">令牌环</param>
177
+        public virtual void Send<TMessage>(TMessage message, object token)
178
+        {
179
+            SendToTargetOrType(message, null, token);
180
+        }
181
+
182
+        /// <summary>
183
+        ///     注销监听
184
+        /// </summary>
185
+        /// <param name="recipient">需要注销的监听者</param>
186
+        public virtual void Unregister(object recipient)
187
+        {
188
+            UnregisterFromLists(recipient, _recipientsOfSubclassesAction);
189
+            UnregisterFromLists(recipient, _recipientsStrictAction);
190
+        }
191
+
192
+        /// <summary>
193
+        ///     注销监听
194
+        /// </summary>
195
+        /// <typeparam name="TMessage">消息类型</typeparam>
196
+        /// <param name="recipient">需要注销的监听者</param>
197
+        [SuppressMessage(
198
+            "Microsoft.Design",
199
+            "CA1004:GenericMethodsShouldProvideTypeParameter",
200
+            Justification = "This syntax is more convenient than other alternatives.")]
201
+        public virtual void Unregister<TMessage>(object recipient)
202
+        {
203
+            Unregister<TMessage>(recipient, null, null);
204
+        }
205
+
206
+        /// <summary>
207
+        ///     注销监听
208
+        /// </summary>
209
+        /// <typeparam name="TMessage">消息类型</typeparam>
210
+        /// <param name="recipient">需要注销的监听者</param>
211
+        /// <param name="token">令牌环</param>
212
+        [SuppressMessage(
213
+            "Microsoft.Design",
214
+            "CA1004:GenericMethodsShouldProvideTypeParameter",
215
+            Justification = "This syntax is more convenient than other alternatives.")]
216
+        public virtual void Unregister<TMessage>(object recipient, object token)
217
+        {
218
+            Unregister<TMessage>(recipient, token, null);
219
+        }
220
+
221
+        /// <summary>
222
+        ///     Unregisters a message recipient for a given type of messages and for
223
+        ///     a given action. Other message types will still be transmitted to the
224
+        ///     recipient (if it registered for them previously). Other actions that have
225
+        ///     been registered for the message type TMessage and for the given recipient (if
226
+        ///     available) will also remain available.
227
+        /// </summary>
228
+        /// <typeparam name="TMessage">
229
+        ///     The type of messages that the recipient wants
230
+        ///     to unregister from.
231
+        /// </typeparam>
232
+        /// <param name="recipient">The recipient that must be unregistered.</param>
233
+        /// <param name="action">
234
+        ///     The action that must be unregistered for
235
+        ///     the recipient and for the message type TMessage.
236
+        /// </param>
237
+        public virtual void Unregister<TMessage>(object recipient, Action<TMessage> action)
238
+        {
239
+            Unregister(recipient, null, action);
240
+        }
241
+
242
+        /// <summary>
243
+        ///     Unregisters a message recipient for a given type of messages, for
244
+        ///     a given action and a given token. Other message types will still be transmitted to the
245
+        ///     recipient (if it registered for them previously). Other actions that have
246
+        ///     been registered for the message type TMessage, for the given recipient and other tokens (if
247
+        ///     available) will also remain available.
248
+        /// </summary>
249
+        /// <typeparam name="TMessage">
250
+        ///     The type of messages that the recipient wants
251
+        ///     to unregister from.
252
+        /// </typeparam>
253
+        /// <param name="recipient">The recipient that must be unregistered.</param>
254
+        /// <param name="token">The token for which the recipient must be unregistered.</param>
255
+        /// <param name="action">
256
+        ///     The action that must be unregistered for
257
+        ///     the recipient and for the message type TMessage.
258
+        /// </param>
259
+        public virtual void Unregister<TMessage>(object recipient, object token, Action<TMessage> action)
260
+        {
261
+            UnregisterFromLists(recipient, token, action, _recipientsStrictAction);
262
+            UnregisterFromLists(recipient, token, action, _recipientsOfSubclassesAction);
263
+            RequestCleanup();
264
+        }
265
+
266
+        #endregion
267
+
268
+        /// <summary>
269
+        ///     Provides a way to override the Messenger.Default instance with
270
+        ///     a custom instance, for example for unit testing purposes.
271
+        /// </summary>
272
+        /// <param name="newMessenger">The instance that will be used as Messenger.Default.</param>
273
+        public static void OverrideDefault(IMessenger newMessenger)
274
+        {
275
+            _defaultInstance = newMessenger;
276
+        }
277
+
278
+        /// <summary>
279
+        ///     Sets the Messenger's default (static) instance to null.
280
+        /// </summary>
281
+        public static void Reset()
282
+        {
283
+            _defaultInstance = null;
284
+        }
285
+
286
+        /// <summary>
287
+        ///     Provides a non-static access to the static <see cref="Reset" /> method.
288
+        ///     Sets the Messenger's default (static) instance to null.
289
+        /// </summary>
290
+        [SuppressMessage(
291
+            "Microsoft.Performance",
292
+            "CA1822:MarkMembersAsStatic",
293
+            Justification = "Non static access is needed.")]
294
+        public void ResetAll()
295
+        {
296
+            Reset();
297
+        }
298
+
299
+        private static void CleanupList(IDictionary<Type, List<WeakActionAndToken>> lists)
300
+        {
301
+            if (lists == null)
302
+            {
303
+                return;
304
+            }
305
+
306
+            lock (lists)
307
+            {
308
+                var listsToRemove = new List<Type>();
309
+                foreach (var list in lists)
310
+                {
311
+                    List<WeakActionAndToken> recipientsToRemove = list.Value
312
+                                                                      .Where(
313
+                                                                          item =>
314
+                                                                          item.Action == null || !item.Action.IsAlive)
315
+                                                                      .ToList();
316
+
317
+                    foreach (WeakActionAndToken recipient in recipientsToRemove)
318
+                    {
319
+                        list.Value.Remove(recipient);
320
+                    }
321
+
322
+                    if (list.Value.Count == 0)
323
+                    {
324
+                        listsToRemove.Add(list.Key);
325
+                    }
326
+                }
327
+
328
+                foreach (Type key in listsToRemove)
329
+                {
330
+                    lists.Remove(key);
331
+                }
332
+            }
333
+        }
334
+
335
+        private static void SendToList<TMessage>(
336
+            TMessage message,
337
+            IEnumerable<WeakActionAndToken> weakActionsAndTokens,
338
+            Type messageTargetType,
339
+            object token)
340
+        {
341
+            if (weakActionsAndTokens != null)
342
+            {
343
+                // Clone to protect from people registering in a "receive message" method
344
+                // Correction Messaging BL0004.007
345
+                List<WeakActionAndToken> list = weakActionsAndTokens.ToList();
346
+                List<WeakActionAndToken> listClone = list.Take(list.Count()).ToList();
347
+
348
+                foreach (WeakActionAndToken item in listClone)
349
+                {
350
+                    var executeAction = item.Action as IExecuteWithObject;
351
+
352
+                    if (executeAction != null
353
+                        && item.Action.IsAlive
354
+                        && item.Action.Target != null
355
+                        && (messageTargetType == null
356
+                            || item.Action.Target.GetType() == messageTargetType
357
+                            || messageTargetType.IsAssignableFrom(item.Action.Target.GetType()))
358
+                        && ((item.Token == null && token == null)
359
+                            || item.Token != null && item.Token.Equals(token)))
360
+                    {
361
+                        executeAction.ExecuteWithObject(message);
362
+                    }
363
+                }
364
+            }
365
+        }
366
+
367
+        private static void UnregisterFromLists(object recipient, Dictionary<Type, List<WeakActionAndToken>> lists)
368
+        {
369
+            if (recipient == null
370
+                || lists == null
371
+                || lists.Count == 0)
372
+            {
373
+                return;
374
+            }
375
+
376
+            lock (lists)
377
+            {
378
+                foreach (Type messageType in lists.Keys)
379
+                {
380
+                    foreach (WeakActionAndToken item in lists[messageType])
381
+                    {
382
+                        var weakAction = (IExecuteWithObject) item.Action;
383
+
384
+                        if (weakAction != null
385
+                            && recipient == weakAction.Target)
386
+                        {
387
+                            weakAction.MarkForDeletion();
388
+                        }
389
+                    }
390
+                }
391
+            }
392
+        }
393
+
394
+        private static void UnregisterFromLists<TMessage>(
395
+            object recipient,
396
+            object token,
397
+            Action<TMessage> action,
398
+            Dictionary<Type, List<WeakActionAndToken>> lists)
399
+        {
400
+            Type messageType = typeof (TMessage);
401
+
402
+            if (recipient == null
403
+                || lists == null
404
+                || lists.Count == 0
405
+                || !lists.ContainsKey(messageType))
406
+            {
407
+                return;
408
+            }
409
+
410
+            lock (lists)
411
+            {
412
+                foreach (WeakActionAndToken item in lists[messageType])
413
+                {
414
+                    var weakActionCasted = item.Action as WeakAction<TMessage>;
415
+
416
+                    if (weakActionCasted != null
417
+                        && recipient == weakActionCasted.Target
418
+                        && (action == null
419
+                            || action.Method.Name == weakActionCasted.MethodName)
420
+                        && (token == null
421
+                            || token.Equals(item.Token)))
422
+                    {
423
+                        item.Action.MarkForDeletion();
424
+                    }
425
+                }
426
+            }
427
+        }
428
+
429
+        /// <summary>
430
+        ///     Notifies the Messenger that the lists of recipients should
431
+        ///     be scanned and cleaned up.
432
+        ///     Since recipients are stored as <see cref="WeakReference" />,
433
+        ///     recipients can be garbage collected even though the Messenger keeps
434
+        ///     them in a list. During the cleanup operation, all "dead"
435
+        ///     recipients are removed from the lists. Since this operation
436
+        ///     can take a moment, it is only executed when the application is
437
+        ///     idle. For this reason, a user of the Messenger class should use
438
+        ///     <see cref="RequestCleanup" /> instead of forcing one with the
439
+        ///     <see cref="Cleanup" /> method.
440
+        /// </summary>
441
+        public void RequestCleanup()
442
+        {
443
+            if (!_isCleanupRegistered)
444
+            {
445
+                Action cleanupAction = Cleanup;
446
+
447
+                Dispatcher.CurrentDispatcher.BeginInvoke(
448
+                    cleanupAction,
449
+                    DispatcherPriority.ApplicationIdle,
450
+                    null);
451
+                _isCleanupRegistered = true;
452
+            }
453
+        }
454
+
455
+        /// <summary>
456
+        ///     Scans the recipients' lists for "dead" instances and removes them.
457
+        ///     Since recipients are stored as <see cref="WeakReference" />,
458
+        ///     recipients can be garbage collected even though the Messenger keeps
459
+        ///     them in a list. During the cleanup operation, all "dead"
460
+        ///     recipients are removed from the lists. Since this operation
461
+        ///     can take a moment, it is only executed when the application is
462
+        ///     idle. For this reason, a user of the Messenger class should use
463
+        ///     <see cref="RequestCleanup" /> instead of forcing one with the
464
+        ///     <see cref="Cleanup" /> method.
465
+        /// </summary>
466
+        public void Cleanup()
467
+        {
468
+            CleanupList(_recipientsOfSubclassesAction);
469
+            CleanupList(_recipientsStrictAction);
470
+            _isCleanupRegistered = false;
471
+        }
472
+
473
+        private void SendToTargetOrType<TMessage>(TMessage message, Type messageTargetType, object token)
474
+        {
475
+            Type messageType = typeof (TMessage);
476
+
477
+            if (_recipientsOfSubclassesAction != null)
478
+            {
479
+                // Clone to protect from people registering in a "receive message" method
480
+                // Correction Messaging BL0008.002
481
+                List<Type> listClone =
482
+                    _recipientsOfSubclassesAction.Keys.Take(_recipientsOfSubclassesAction.Count()).ToList();
483
+
484
+                foreach (Type type in listClone)
485
+                {
486
+                    List<WeakActionAndToken> list = null;
487
+
488
+                    if (messageType == type
489
+                        || messageType.IsSubclassOf(type)
490
+                        || type.IsAssignableFrom(messageType))
491
+                    {
492
+                        lock (_recipientsOfSubclassesAction)
493
+                        {
494
+                            list =
495
+                                _recipientsOfSubclassesAction[type].Take(_recipientsOfSubclassesAction[type].Count())
496
+                                                                   .ToList();
497
+                        }
498
+                    }
499
+
500
+                    SendToList(message, list, messageTargetType, token);
501
+                }
502
+            }
503
+
504
+            if (_recipientsStrictAction != null)
505
+            {
506
+                List<WeakActionAndToken> list = null;
507
+
508
+                lock (_recipientsStrictAction)
509
+                {
510
+                    if (_recipientsStrictAction.ContainsKey(messageType))
511
+                    {
512
+                        list = _recipientsStrictAction[messageType]
513
+                            .Take(_recipientsStrictAction[messageType].Count())
514
+                            .ToList();
515
+                    }
516
+                }
517
+
518
+                if (list != null)
519
+                {
520
+                    SendToList(message, list, messageTargetType, token);
521
+                }
522
+            }
523
+
524
+            RequestCleanup();
525
+        }
526
+
527
+        #region Nested type: WeakActionAndToken
528
+
529
+        private struct WeakActionAndToken
530
+        {
531
+            public WeakAction Action;
532
+
533
+            public object Token;
534
+        }
535
+
536
+        #endregion
537
+    }
538
+}

+ 275
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/Messenger.ts 查看文件

@@ -0,0 +1,275 @@
1
+// 定义 WeakAction 接口,模拟 C# 中的 WeakAction 功能
2
+interface WeakAction {
3
+    IsAlive: boolean;
4
+    Target: any;
5
+    MethodName?: string;
6
+    MarkForDeletion(): void;
7
+    ExecuteWithObject(message: any): void;
8
+}
9
+
10
+// 定义 WeakActionAndToken 结构
11
+interface WeakActionAndToken {
12
+    Action: WeakAction;
13
+    Token: any;
14
+}
15
+
16
+// 定义 IMessenger 接口
17
+interface IMessenger {
18
+    Register<TMessage>(recipient: any, action: (message: TMessage) => void): void;
19
+    Register<TMessage>(recipient: any, receiveDerivedMessagesToo: boolean, action: (message: TMessage) => void): void;
20
+    Register<TMessage>(recipient: any, token: any, action: (message: TMessage) => void): void;
21
+    Register<TMessage>(recipient: any, token: any, receiveDerivedMessagesToo: boolean, action: (message: TMessage) => void): void;
22
+    Send<TMessage>(message: TMessage): void;
23
+    Send<TMessage, TTarget>(message: TMessage): void;
24
+    Send<TMessage>(message: TMessage, token: any): void;
25
+    Unregister(recipient: any): void;
26
+    Unregister<TMessage>(recipient: any): void;
27
+    Unregister<TMessage>(recipient: any, token: any): void;
28
+    Unregister<TMessage>(recipient: any, action: (message: TMessage) => void): void;
29
+    Unregister<TMessage>(recipient: any, token: any, action: (message: TMessage) => void): void;
30
+    OverrideDefault(newMessenger: IMessenger): void;
31
+    Reset(): void;
32
+    ResetAll(): void;
33
+    RequestCleanup(): void;
34
+    Cleanup(): void;
35
+}
36
+
37
+// 实现 Messenger 类
38
+class Messenger implements IMessenger {
39
+    private static CreationLock: object = {};
40
+    private static _defaultInstance: IMessenger | null = null;
41
+    private _registerLock: object = {};
42
+    private _recipientsOfSubclassesAction: Map<Function, WeakActionAndToken[]> | null = null;
43
+    private _recipientsStrictAction: Map<Function, WeakActionAndToken[]> | null = null;
44
+    private _isCleanupRegistered: boolean = false;
45
+
46
+    public static get Default(): IMessenger {
47
+        if (Messenger._defaultInstance === null) {
48
+            // 使用闭包模拟锁机制
49
+            (() => {
50
+                if (Messenger._defaultInstance === null) {
51
+                    Messenger._defaultInstance = new Messenger();
52
+                }
53
+            })();
54
+        }
55
+        return Messenger._defaultInstance;
56
+    }
57
+
58
+    public Register<TMessage>(recipient: any, param1: any, param2?: any, param3?: any): void {
59
+        let token: any = null;
60
+        let receiveDerivedMessagesToo: boolean = false;
61
+        let action: (message: TMessage) => void;
62
+
63
+        if (typeof param1 === 'boolean') {
64
+            receiveDerivedMessagesToo = param1;
65
+            action = param2 as (message: TMessage) => void;
66
+        } else if (typeof param1 === 'function') {
67
+            action = param1;
68
+        } else {
69
+            token = param1;
70
+            if (typeof param2 === 'boolean') {
71
+                receiveDerivedMessagesToo = param2;
72
+                action = param3 as (message: TMessage) => void;
73
+            } else {
74
+                action = param2 as (message: TMessage) => void;
75
+            }
76
+        }
77
+
78
+        const messageType = this.getMessageType<TMessage>();
79
+        let recipients: Map<Function, WeakActionAndToken[]>;
80
+
81
+        if (receiveDerivedMessagesToo) {
82
+            if (this._recipientsOfSubclassesAction === null) {
83
+                this._recipientsOfSubclassesAction = new Map<Function, WeakActionAndToken[]>();
84
+            }
85
+            recipients = this._recipientsOfSubclassesAction;
86
+        } else {
87
+            if (this._recipientsStrictAction === null) {
88
+                this._recipientsStrictAction = new Map<Function, WeakActionAndToken[]>();
89
+            }
90
+            recipients = this._recipientsStrictAction;
91
+        }
92
+
93
+        // 模拟锁机制
94
+        (() => {
95
+            let list: WeakActionAndToken[];
96
+            if (!recipients.has(messageType)) {
97
+                list = [];
98
+                recipients.set(messageType, list);
99
+            } else {
100
+                list = recipients.get(messageType)!;
101
+            }
102
+
103
+            // 这里简单模拟 WeakAction,实际使用中可能需要更完善的实现
104
+            const weakAction: WeakAction = {
105
+                IsAlive: true,
106
+                Target: recipient,
107
+                MethodName: action.name,
108
+                MarkForDeletion() {
109
+                    this.IsAlive = false;
110
+                },
111
+                ExecuteWithObject(message: any) {
112
+                    action(message);
113
+                }
114
+            };
115
+
116
+            const item: WeakActionAndToken = {
117
+                Action: weakAction,
118
+                Token: token
119
+            };
120
+
121
+            list.push(item);
122
+        })();
123
+
124
+        this.RequestCleanup();
125
+    }
126
+
127
+    public Send<TMessage>(message: TMessage, param1?: any, param2?: any): void {
128
+        const messageType = this.getMessageType<TMessage>();
129
+        const messageTargetType = param1 as Function | null;
130
+        const token = param2;
131
+
132
+        if (this._recipientsOfSubclassesAction) {
133
+            const listClone = Array.from(this._recipientsOfSubclassesAction.keys());
134
+            listClone.forEach((type) => {
135
+                let list: WeakActionAndToken[] | null = null;
136
+                if (messageType === type || messageType.prototype instanceof type || type.prototype.isPrototypeOf(messageType.prototype)) {
137
+                    list = this._recipientsOfSubclassesAction!.get(type)?.slice() || null;
138
+                }
139
+                this.SendToList(message, list, messageTargetType, token);
140
+            });
141
+        }
142
+
143
+        if (this._recipientsStrictAction) {
144
+            let list: WeakActionAndToken[] | null = null;
145
+            if (this._recipientsStrictAction.has(messageType)) {
146
+                list = this._recipientsStrictAction.get(messageType)?.slice() || null;
147
+            }
148
+            if (list) {
149
+                this.SendToList(message, list, messageTargetType, token);
150
+            }
151
+        }
152
+
153
+        this.RequestCleanup();
154
+    }
155
+
156
+    public Unregister(recipient: any, param1?: any, param2?: any, param3?: any): void {
157
+        if (typeof param1 === 'undefined') {
158
+            this.UnregisterFromLists(recipient, this._recipientsOfSubclassesAction);
159
+            this.UnregisterFromLists(recipient, this._recipientsStrictAction);
160
+        } else {
161
+            const messageType = this.getMessageType<any>();
162
+            this.UnregisterFromLists(recipient, param1, param2, this._recipientsStrictAction);
163
+            this.UnregisterFromLists(recipient, param1, param2, this._recipientsOfSubclassesAction);
164
+            this.RequestCleanup();
165
+        }
166
+    }
167
+
168
+    public static OverrideDefault(newMessenger: IMessenger): void {
169
+        Messenger._defaultInstance = newMessenger;
170
+    }
171
+
172
+    public static Reset(): void {
173
+        Messenger._defaultInstance = null;
174
+    }
175
+
176
+    public ResetAll(): void {
177
+        Messenger.Reset();
178
+    }
179
+
180
+    private CleanupList(lists: Map<Function, WeakActionAndToken[]> | null): void {
181
+        if (!lists) {
182
+            return;
183
+        }
184
+        // 模拟锁机制
185
+        (() => {
186
+            const listsToRemove: Function[] = [];
187
+            lists.forEach((list, type) => {
188
+                const recipientsToRemove = list.filter(item => !item.Action.IsAlive);
189
+                recipientsToRemove.forEach(recipient => {
190
+                    const index = list.indexOf(recipient);
191
+                    if (index !== -1) {
192
+                        list.splice(index, 1);
193
+                    }
194
+                });
195
+                if (list.length === 0) {
196
+                    listsToRemove.push(type);
197
+                }
198
+            });
199
+            listsToRemove.forEach(key => {
200
+                lists.delete(key);
201
+            });
202
+        })();
203
+    }
204
+
205
+    private SendToList<TMessage>(message: TMessage, weakActionsAndTokens: WeakActionAndToken[] | null, messageTargetType: Function | null, token: any): void {
206
+        if (weakActionsAndTokens) {
207
+            const listClone = weakActionsAndTokens.slice();
208
+            listClone.forEach((item) => {
209
+                if (item.Action.IsAlive && item.Action.Target &&
210
+                    (messageTargetType === null || item.Action.Target.constructor === messageTargetType || messageTargetType.prototype.isPrototypeOf(item.Action.Target.constructor.prototype)) &&
211
+                    ((item.Token === null && token === null) || (item.Token !== null && item.Token === token))) {
212
+                    item.Action.ExecuteWithObject(message);
213
+                }
214
+            });
215
+        }
216
+    }
217
+
218
+    private UnregisterFromLists(recipient: any, lists: Map<Function, WeakActionAndToken[]> | null): void {
219
+        if (!recipient || !lists || lists.size === 0) {
220
+            return;
221
+        }
222
+        // 模拟锁机制
223
+        (() => {
224
+            lists.forEach((list) => {
225
+                list.forEach((item) => {
226
+                    if (item.Action.Target === recipient) {
227
+                        item.Action.MarkForDeletion();
228
+                    }
229
+                });
230
+            });
231
+        })();
232
+    }
233
+
234
+    private UnregisterFromLists<TMessage>(recipient: any, token: any, action: ((message: TMessage) => void) | null, lists: Map<Function, WeakActionAndToken[]> | null): void {
235
+        const messageType = this.getMessageType<TMessage>();
236
+        if (!recipient || !lists || lists.size === 0 || !lists.has(messageType)) {
237
+            return;
238
+        }
239
+        // 模拟锁机制
240
+        (() => {
241
+            const list = lists.get(messageType)!;
242
+            list.forEach((item) => {
243
+                const weakActionCasted = item.Action;
244
+                if (weakActionCasted.Target === recipient &&
245
+                    (action === null || action.name === weakActionCasted.MethodName) &&
246
+                    (token === null || token === item.Token)) {
247
+                    weakActionCasted.MarkForDeletion();
248
+                }
249
+            });
250
+        })();
251
+    }
252
+
253
+    public RequestCleanup(): void {
254
+        if (!this._isCleanupRegistered) {
255
+            // 模拟 Dispatcher 延迟执行
256
+            setTimeout(() => {
257
+                this.Cleanup();
258
+            }, 0);
259
+            this._isCleanupRegistered = true;
260
+        }
261
+    }
262
+
263
+    public Cleanup(): void {
264
+        this.CleanupList(this._recipientsOfSubclassesAction);
265
+        this.CleanupList(this._recipientsStrictAction);
266
+        this._isCleanupRegistered = false;
267
+    }
268
+
269
+    private getMessageType<TMessage>(): Function {
270
+        // 简单模拟获取类型,实际可能需要更复杂的处理
271
+        return ({} as TMessage).constructor;
272
+    }
273
+}
274
+
275
+export { Messenger, IMessenger };

+ 192
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/WeakAction.cs 查看文件

@@ -0,0 +1,192 @@
1
+using System;
2
+using System.Diagnostics.CodeAnalysis;
3
+using System.Reflection;
4
+
5
+namespace TellerSystem.Library.Ext.TradeExtension
6
+{
7
+    public class WeakAction
8
+    {
9
+        private Action _staticAction;
10
+
11
+        /// <summary>
12
+        ///     构造函数
13
+        /// </summary>
14
+        protected WeakAction()
15
+        {
16
+        }
17
+
18
+        /// <summary>
19
+        ///     构造函数
20
+        /// </summary>
21
+        /// <param name="action">需要关联的Action</param>
22
+        public WeakAction(Action action)
23
+            : this(action == null ? null : action.Target, action)
24
+        {
25
+        }
26
+
27
+        /// <summary>
28
+        ///     Initializes a new instance of the <see cref="WeakAction" /> class.
29
+        /// </summary>
30
+        /// <param name="target">The action's owner.</param>
31
+        /// <param name="action">The action that will be associated to this instance.</param>
32
+        [SuppressMessage(
33
+            "Microsoft.Design",
34
+            "CA1062:Validate arguments of public methods",
35
+            MessageId = "1",
36
+            Justification = "Method should fail with an exception if action is null.")]
37
+        public WeakAction(object target, Action action)
38
+        {
39
+            if (action.Method.IsStatic)
40
+            {
41
+                _staticAction = action;
42
+
43
+                if (target != null)
44
+                {
45
+                    // Keep a reference to the target to control the
46
+                    // WeakAction's lifetime.
47
+                    Reference = new WeakReference(target);
48
+                }
49
+
50
+                return;
51
+            }
52
+
53
+            Method = action.Method;
54
+            ActionReference = new WeakReference(action.Target);
55
+            Reference = new WeakReference(target);
56
+        }
57
+
58
+        /// <summary>
59
+        ///     引用的取方法信息
60
+        /// </summary>
61
+        protected MethodInfo Method { get; set; }
62
+
63
+        /// <summary>
64
+        ///     引用的方法名称
65
+        /// </summary>
66
+        public virtual string MethodName
67
+        {
68
+            get
69
+            {
70
+                if (_staticAction != null)
71
+                {
72
+                    return _staticAction.Method.Name;
73
+                }
74
+
75
+                return Method.Name;
76
+            }
77
+        }
78
+
79
+        /// <summary>
80
+        ///     行为目标实体的弱引用
81
+        /// </summary>
82
+        protected WeakReference ActionReference { get; set; }
83
+
84
+        /// <summary>
85
+        ///     行为对象实体的弱引用
86
+        /// </summary>
87
+        protected WeakReference Reference { get; set; }
88
+
89
+        /// <summary>
90
+        ///     静态方法标志
91
+        /// </summary>
92
+        public bool IsStatic
93
+        {
94
+            get { return _staticAction != null; }
95
+        }
96
+
97
+        /// <summary>
98
+        ///     实体 活动标志
99
+        /// </summary>
100
+        public virtual bool IsAlive
101
+        {
102
+            get
103
+            {
104
+                if (_staticAction == null
105
+                    && Reference == null)
106
+                {
107
+                    return false;
108
+                }
109
+
110
+                if (_staticAction != null)
111
+                {
112
+                    if (Reference != null)
113
+                    {
114
+                        return Reference.IsAlive;
115
+                    }
116
+
117
+                    return true;
118
+                }
119
+
120
+                return Reference.IsAlive;
121
+            }
122
+        }
123
+
124
+        /// <summary>
125
+        ///     Action的拥有者
126
+        /// </summary>
127
+        public object Target
128
+        {
129
+            get
130
+            {
131
+                if (Reference == null)
132
+                {
133
+                    return null;
134
+                }
135
+
136
+                return Reference.Target;
137
+            }
138
+        }
139
+
140
+        /// <summary>
141
+        ///     Action触发对象
142
+        /// </summary>
143
+        protected object ActionTarget
144
+        {
145
+            get
146
+            {
147
+                if (ActionReference == null)
148
+                {
149
+                    return null;
150
+                }
151
+
152
+                return ActionReference.Target;
153
+            }
154
+        }
155
+
156
+        /// <summary>
157
+        ///     执行活动中的Action
158
+        /// </summary>
159
+        public void Execute()
160
+        {
161
+            if (_staticAction != null)
162
+            {
163
+                _staticAction();
164
+                return;
165
+            }
166
+
167
+            object actionTarget = ActionTarget;
168
+
169
+            if (IsAlive)
170
+            {
171
+                if (Method != null
172
+                    && ActionReference != null
173
+                    && actionTarget != null)
174
+                {
175
+                    Method.Invoke(actionTarget, null);
176
+                    return;
177
+                }
178
+            }
179
+        }
180
+
181
+        /// <summary>
182
+        ///     清空操作
183
+        /// </summary>
184
+        public void MarkForDeletion()
185
+        {
186
+            Reference = null;
187
+            ActionReference = null;
188
+            Method = null;
189
+            _staticAction = null;
190
+        }
191
+    }
192
+}

+ 173
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/WeakActionGeneric.cs 查看文件

@@ -0,0 +1,173 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Diagnostics.CodeAnalysis;
4
+using System.Linq;
5
+using System.Text;
6
+
7
+namespace TellerSystem.Library.Ext.TradeExtension
8
+{
9
+    /// <summary>
10
+    /// Stores an Action without causing a hard reference
11
+    /// to be created to the Action's owner. The owner can be garbage collected at any time.
12
+    /// </summary>
13
+    /// <typeparam name="T">The type of the Action's parameter.</typeparam>
14
+    ////[ClassInfo(typeof(WeakAction))]
15
+    public class WeakAction<T> : WeakAction, IExecuteWithObject
16
+    {
17
+
18
+        private Action<T> _staticAction;
19
+
20
+        /// <summary>
21
+        /// Gets the name of the method that this WeakAction represents.
22
+        /// </summary>
23
+        public override string MethodName
24
+        {
25
+            get
26
+            {
27
+                if (_staticAction != null)
28
+                {
29
+
30
+                    return _staticAction.Method.Name;
31
+                }
32
+                return Method.Name;
33
+            }
34
+        }
35
+
36
+        /// <summary>
37
+        /// Gets a value indicating whether the Action's owner is still alive, or if it was collected
38
+        /// by the Garbage Collector already.
39
+        /// </summary>
40
+        public override bool IsAlive
41
+        {
42
+            get
43
+            {
44
+                if (_staticAction == null
45
+                    && Reference == null)
46
+                {
47
+                    return false;
48
+                }
49
+
50
+                if (_staticAction != null)
51
+                {
52
+                    if (Reference != null)
53
+                    {
54
+                        return Reference.IsAlive;
55
+                    }
56
+
57
+                    return true;
58
+                }
59
+
60
+                return Reference.IsAlive;
61
+            }
62
+        }
63
+
64
+        /// <summary>
65
+        /// Initializes a new instance of the WeakAction class.
66
+        /// </summary>
67
+        /// <param name="action">The action that will be associated to this instance.</param>
68
+        public WeakAction(Action<T> action)
69
+            : this(action == null ? null : action.Target, action)
70
+        {
71
+        }
72
+
73
+        /// <summary>
74
+        /// Initializes a new instance of the WeakAction class.
75
+        /// </summary>
76
+        /// <param name="target">The action's owner.</param>
77
+        /// <param name="action">The action that will be associated to this instance.</param>
78
+        [SuppressMessage(
79
+            "Microsoft.Design",
80
+            "CA1062:Validate arguments of public methods",
81
+            MessageId = "1",
82
+            Justification = "Method should fail with an exception if action is null.")]
83
+        public WeakAction(object target, Action<T> action)
84
+        {
85
+
86
+            if (action.Method.IsStatic)
87
+
88
+            {
89
+                _staticAction = action;
90
+
91
+                if (target != null)
92
+                {
93
+                    // Keep a reference to the target to control the
94
+                    // WeakAction's lifetime.
95
+                    Reference = new WeakReference(target);
96
+                }
97
+
98
+                return;
99
+            }
100
+
101
+            Method = action.Method;
102
+
103
+            ActionReference = new WeakReference(action.Target);
104
+
105
+            Reference = new WeakReference(target);
106
+        }
107
+
108
+        /// <summary>
109
+        /// Executes the action. This only happens if the action's owner
110
+        /// is still alive. The action's parameter is set to default(T).
111
+        /// </summary>
112
+        public new void Execute()
113
+        {
114
+            Execute(default(T));
115
+        }
116
+
117
+        /// <summary>
118
+        /// Executes the action. This only happens if the action's owner
119
+        /// is still alive.
120
+        /// </summary>
121
+        /// <param name="parameter">A parameter to be passed to the action.</param>
122
+        public void Execute(T parameter)
123
+        {
124
+            if (_staticAction != null)
125
+            {
126
+                _staticAction(parameter);
127
+                return;
128
+            }
129
+
130
+            var actionTarget = ActionTarget;
131
+
132
+            if (IsAlive)
133
+            {
134
+                if (Method != null
135
+                    && ActionReference != null
136
+                    && actionTarget != null)
137
+                {
138
+                    Method.Invoke(
139
+                        actionTarget,
140
+                        new object[]
141
+                        {
142
+                            parameter
143
+                        });
144
+                }
145
+            }
146
+        }
147
+
148
+        /// <summary>
149
+        /// Executes the action with a parameter of type object. This parameter
150
+        /// will be casted to T. This method implements <see cref="IExecuteWithObject.ExecuteWithObject" />
151
+        /// and can be useful if you store multiple WeakAction{T} instances but don't know in advance
152
+        /// what type T represents.
153
+        /// </summary>
154
+        /// <param name="parameter">The parameter that will be passed to the action after
155
+        /// being casted to T.</param>
156
+        public void ExecuteWithObject(object parameter)
157
+        {
158
+            var parameterCasted = (T)parameter;
159
+            Execute(parameterCasted);
160
+        }
161
+
162
+        /// <summary>
163
+        /// Sets all the actions that this WeakAction contains to null,
164
+        /// which is a signal for containing objects that this WeakAction
165
+        /// should be deleted.
166
+        /// </summary>
167
+        public new void MarkForDeletion()
168
+        {
169
+            _staticAction = null;
170
+            base.MarkForDeletion();
171
+        }
172
+    }
173
+}

+ 226
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/WeakFunc.cs 查看文件

@@ -0,0 +1,226 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Diagnostics.CodeAnalysis;
4
+using System.Linq;
5
+using System.Reflection;
6
+using System.Text;
7
+
8
+namespace TellerSystem.Library.Ext.TradeExtension
9
+{
10
+    public class WeakFunc<TResult>
11
+    {
12
+        private Func<TResult> _staticFunc;
13
+
14
+        /// <summary>
15
+        /// Gets or sets the <see cref="MethodInfo" /> corresponding to this WeakFunc's
16
+        /// method passed in the constructor.
17
+        /// </summary>
18
+        protected MethodInfo Method
19
+        {
20
+            get;
21
+            set;
22
+        }
23
+
24
+        /// <summary>
25
+        /// Get a value indicating whether the WeakFunc is static or not.
26
+        /// </summary>
27
+        public bool IsStatic
28
+        {
29
+            get
30
+            {
31
+                return _staticFunc != null;
32
+            }
33
+        }
34
+
35
+        /// <summary>
36
+        /// Gets the name of the method that this WeakFunc represents.
37
+        /// </summary>
38
+        public virtual string MethodName
39
+        {
40
+            get
41
+            {
42
+                if (_staticFunc != null)
43
+                {
44
+                    return _staticFunc.Method.Name;
45
+                }
46
+
47
+                return Method.Name;
48
+            }
49
+        }
50
+
51
+        /// <summary>
52
+        /// Gets or sets a WeakReference to this WeakFunc's action's target.
53
+        /// This is not necessarily the same as
54
+        /// <see cref="Reference" />, for example if the
55
+        /// method is anonymous.
56
+        /// </summary>
57
+        protected WeakReference FuncReference
58
+        {
59
+            get;
60
+            set;
61
+        }
62
+
63
+        /// <summary>
64
+        /// Gets or sets a WeakReference to the target passed when constructing
65
+        /// the WeakFunc. This is not necessarily the same as
66
+        /// <see cref="FuncReference" />, for example if the
67
+        /// method is anonymous.
68
+        /// </summary>
69
+        protected WeakReference Reference
70
+        {
71
+            get;
72
+            set;
73
+        }
74
+
75
+        /// <summary>
76
+        /// Initializes an empty instance of the WeakFunc class.
77
+        /// </summary>
78
+        protected WeakFunc()
79
+        {
80
+        }
81
+
82
+        /// <summary>
83
+        /// Initializes a new instance of the WeakFunc class.
84
+        /// </summary>
85
+        /// <param name="func">The Func that will be associated to this instance.</param>
86
+        public WeakFunc(Func<TResult> func)
87
+            : this(func == null ? null : func.Target, func)
88
+        {
89
+        }
90
+
91
+        /// <summary>
92
+        /// Initializes a new instance of the WeakFunc class.
93
+        /// </summary>
94
+        /// <param name="target">The Func's owner.</param>
95
+        /// <param name="func">The Func that will be associated to this instance.</param>
96
+        [SuppressMessage(
97
+            "Microsoft.Design",
98
+            "CA1062:Validate arguments of public methods",
99
+            MessageId = "1",
100
+            Justification = "Method should fail with an exception if func is null.")]
101
+        public WeakFunc(object target, Func<TResult> func)
102
+        {
103
+            if (func.Method.IsStatic)
104
+            {
105
+                _staticFunc = func;
106
+
107
+                if (target != null)
108
+                {
109
+                    // Keep a reference to the target to control the
110
+                    // WeakAction's lifetime.
111
+                    Reference = new WeakReference(target);
112
+                }
113
+
114
+                return;
115
+            }
116
+            Method = func.Method;
117
+            FuncReference = new WeakReference(func.Target);
118
+
119
+            Reference = new WeakReference(target);
120
+        }
121
+
122
+        /// <summary>
123
+        /// Gets a value indicating whether the Func's owner is still alive, or if it was collected
124
+        /// by the Garbage Collector already.
125
+        /// </summary>
126
+        public virtual bool IsAlive
127
+        {
128
+            get
129
+            {
130
+                if (_staticFunc == null
131
+                    && Reference == null)
132
+                {
133
+                    return false;
134
+                }
135
+
136
+                if (_staticFunc != null)
137
+                {
138
+                    if (Reference != null)
139
+                    {
140
+                        return Reference.IsAlive;
141
+                    }
142
+
143
+                    return true;
144
+                }
145
+
146
+                return Reference.IsAlive;
147
+            }
148
+        }
149
+
150
+        /// <summary>
151
+        /// Gets the Func's owner. This object is stored as a 
152
+        /// <see cref="WeakReference" />.
153
+        /// </summary>
154
+        public object Target
155
+        {
156
+            get
157
+            {
158
+                if (Reference == null)
159
+                {
160
+                    return null;
161
+                }
162
+
163
+                return Reference.Target;
164
+            }
165
+        }
166
+
167
+        /// <summary>
168
+        /// Gets the owner of the Func that was passed as parameter.
169
+        /// This is not necessarily the same as
170
+        /// <see cref="Target" />, for example if the
171
+        /// method is anonymous.
172
+        /// </summary>
173
+        protected object FuncTarget
174
+        {
175
+            get
176
+            {
177
+                if (FuncReference == null)
178
+                {
179
+                    return null;
180
+                }
181
+
182
+                return FuncReference.Target;
183
+            }
184
+        }
185
+
186
+        /// <summary>
187
+        /// Executes the action. This only happens if the Func's owner
188
+        /// is still alive.
189
+        /// </summary>
190
+        /// <returns>The result of the Func stored as reference.</returns>
191
+        public TResult Execute()
192
+        {
193
+            if (_staticFunc != null)
194
+            {
195
+                return _staticFunc();
196
+            }
197
+
198
+            var funcTarget = FuncTarget;
199
+
200
+            if (IsAlive)
201
+            {
202
+                if (Method != null
203
+                    && FuncReference != null
204
+                    && funcTarget != null)
205
+                {
206
+                    return (TResult)Method.Invoke(funcTarget, null);
207
+                }
208
+
209
+            }
210
+
211
+            return default(TResult);
212
+        }
213
+
214
+        /// <summary>
215
+        /// Sets the reference that this instance stores to null.
216
+        /// </summary>
217
+        public void MarkForDeletion()
218
+        {
219
+            Reference = null;
220
+            FuncReference = null;
221
+            Method = null;
222
+            _staticFunc = null;
223
+
224
+        }
225
+    }
226
+}

+ 175
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/Messenger/WeakFuncGeneric.cs 查看文件

@@ -0,0 +1,175 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Diagnostics.CodeAnalysis;
4
+using System.Linq;
5
+using System.Text;
6
+
7
+namespace TellerSystem.Library.Ext.TradeExtension
8
+{
9
+
10
+    /// <summary>
11
+    /// Stores an Func without causing a hard reference
12
+    /// to be created to the Func's owner. The owner can be garbage collected at any time.
13
+    /// </summary>
14
+    /// <typeparam name="T">The type of the Func's parameter.</typeparam>
15
+    /// <typeparam name="TResult">The type of the Func's return value.</typeparam>
16
+    ////[ClassInfo(typeof(WeakAction))]
17
+    public class WeakFunc<T, TResult> : WeakFunc<TResult>, IExecuteWithObjectAndResult
18
+    {
19
+        private Func<T, TResult> _staticFunc;
20
+
21
+        /// <summary>
22
+        /// Gets or sets the name of the method that this WeakFunc represents.
23
+        /// </summary>
24
+        public override string MethodName
25
+        {
26
+            get
27
+            {
28
+                if (_staticFunc != null)
29
+                {
30
+                    return _staticFunc.Method.Name;
31
+                }
32
+
33
+                return Method.Name;
34
+            }
35
+        }
36
+
37
+        /// <summary>
38
+        /// Gets a value indicating whether the Func's owner is still alive, or if it was collected
39
+        /// by the Garbage Collector already.
40
+        /// </summary>
41
+        public override bool IsAlive
42
+        {
43
+            get
44
+            {
45
+                if (_staticFunc == null
46
+                    && Reference == null)
47
+                {
48
+                    return false;
49
+                }
50
+
51
+                if (_staticFunc != null)
52
+                {
53
+                    if (Reference != null)
54
+                    {
55
+                        return Reference.IsAlive;
56
+                    }
57
+
58
+                    return true;
59
+                }
60
+
61
+                return Reference.IsAlive;
62
+            }
63
+        }
64
+
65
+        /// <summary>
66
+        /// Initializes a new instance of the WeakFunc class.
67
+        /// </summary>
68
+        /// <param name="func">The Func that will be associated to this instance.</param>
69
+        public WeakFunc(Func<T, TResult> func)
70
+            : this(func == null ? null : func.Target, func)
71
+        {
72
+        }
73
+
74
+        /// <summary>
75
+        /// Initializes a new instance of the WeakFunc class.
76
+        /// </summary>
77
+        /// <param name="target">The Func's owner.</param>
78
+        /// <param name="func">The Func that will be associated to this instance.</param>
79
+        [SuppressMessage(
80
+            "Microsoft.Design",
81
+            "CA1062:Validate arguments of public methods",
82
+            MessageId = "1",
83
+            Justification = "Method should fail with an exception if func is null.")]
84
+        public WeakFunc(object target, Func<T, TResult> func)
85
+        {
86
+            if (func.Method.IsStatic)
87
+            {
88
+                _staticFunc = func;
89
+
90
+                if (target != null)
91
+                {
92
+                    // Keep a reference to the target to control the
93
+                    // WeakAction's lifetime.
94
+                    Reference = new WeakReference(target);
95
+                }
96
+
97
+                return;
98
+            }
99
+
100
+            Method = func.Method;
101
+            FuncReference = new WeakReference(func.Target);
102
+
103
+            Reference = new WeakReference(target);
104
+        }
105
+
106
+        /// <summary>
107
+        /// Executes the Func. This only happens if the Func's owner
108
+        /// is still alive. The Func's parameter is set to default(T).
109
+        /// </summary>
110
+        /// <returns>The result of the Func stored as reference.</returns>
111
+        public new TResult Execute()
112
+        {
113
+            return Execute(default(T));
114
+        }
115
+
116
+        /// <summary>
117
+        /// Executes the Func. This only happens if the Func's owner
118
+        /// is still alive.
119
+        /// </summary>
120
+        /// <param name="parameter">A parameter to be passed to the action.</param>
121
+        /// <returns>The result of the Func stored as reference.</returns>
122
+        public TResult Execute(T parameter)
123
+        {
124
+            if (_staticFunc != null)
125
+            {
126
+                return _staticFunc(parameter);
127
+            }
128
+
129
+            var funcTarget = FuncTarget;
130
+
131
+            if (IsAlive)
132
+            {
133
+                if (Method != null
134
+                    && FuncReference != null
135
+                    && funcTarget != null)
136
+                {
137
+                    return (TResult)Method.Invoke(
138
+                        funcTarget,
139
+                        new object[]
140
+                        {
141
+                            parameter
142
+                        });
143
+                }
144
+            }
145
+
146
+            return default(TResult);
147
+        }
148
+
149
+        /// <summary>
150
+        /// Executes the Func with a parameter of type object. This parameter
151
+        /// will be casted to T. This method implements <see cref="IExecuteWithObject.ExecuteWithObject" />
152
+        /// and can be useful if you store multiple WeakFunc{T} instances but don't know in advance
153
+        /// what type T represents.
154
+        /// </summary>
155
+        /// <param name="parameter">The parameter that will be passed to the Func after
156
+        /// being casted to T.</param>
157
+        /// <returns>The result of the execution as object, to be casted to T.</returns>
158
+        public object ExecuteWithObject(object parameter)
159
+        {
160
+            var parameterCasted = (T)parameter;
161
+            return Execute(parameterCasted);
162
+        }
163
+
164
+        /// <summary>
165
+        /// Sets all the funcs that this WeakFunc contains to null,
166
+        /// which is a signal for containing objects that this WeakFunc
167
+        /// should be deleted.
168
+        /// </summary>
169
+        public new void MarkForDeletion()
170
+        {
171
+            _staticFunc = null;
172
+            base.MarkForDeletion();
173
+        }
174
+    }
175
+}

+ 31
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/NotificationAttribute.cs 查看文件

@@ -0,0 +1,31 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+
6
+namespace TellerSystem.Library.Ext.TradeExtension
7
+{
8
+    class NotificationAttribute:Attribute
9
+    {
10
+        /// <summary>
11
+        /// 构造函数
12
+        /// </summary>
13
+        /// <param name="Flag">报文标志</param>
14
+        /// <param name="Desc">报文描述</param>
15
+        public NotificationAttribute(string Flag, string Desc)
16
+        {
17
+            this.NotificationFlag = Flag;
18
+            this.NotificationDescription = Desc;
19
+        }
20
+
21
+        /// <summary>
22
+        /// 报文标志
23
+        /// </summary>
24
+        public string NotificationFlag { get; set; }
25
+
26
+        /// <summary>
27
+        /// 报文描述
28
+        /// </summary>
29
+        public string NotificationDescription { get; set; }
30
+    }
31
+}

+ 246
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/NotificationManager.cs 查看文件

@@ -0,0 +1,246 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Reflection;
5
+using System.Windows;
6
+using System.Xml;
7
+using Platform.Common.LogSystem;
8
+using Platform.Common.RunningParameters;
9
+using Platform.Library;
10
+using TellerSystem.Communication.SocketListener;
11
+using TellerSystem.ServiceProxy.Ext.ServiceHelper;
12
+using TellerSystem.Library.Ext.TradeInterfaces;
13
+using Platform.Presentation.Interfaces;
14
+
15
+namespace TellerSystem.Library.Ext.TradeExtension
16
+{
17
+    /// <summary>
18
+    ///     消息推送管理
19
+    /// </summary>
20
+    public static class NotificationManager
21
+    {
22
+        #region Field
23
+
24
+        /// <summary>
25
+        /// Socket监听对象
26
+        /// </summary>
27
+        private static SocketManager _socketEntry;
28
+
29
+        /// <summary>
30
+        /// 消息类型列表
31
+        /// </summary>
32
+        private static IEnumerable<Type> _messageTypeList;
33
+
34
+        #endregion
35
+
36
+        #region Method
37
+
38
+        /// <summary>
39
+        ///     启动监听模块
40
+        /// </summary>
41
+        /// <param name="port"></param>
42
+        public static void Startup(int port)
43
+        {
44
+            // NotificationMessageBox.IsReceiveMessage = true;
45
+            //开始监听
46
+            _socketEntry.StartListenning(port);
47
+        }
48
+
49
+        /// <summary>
50
+        ///     关闭监听模块
51
+        /// </summary>
52
+        public static void Shutdown()
53
+        {
54
+            _socketEntry.Dispose();
55
+            _socketEntry = null;
56
+        }
57
+
58
+        /// <summary>
59
+        ///  初始化消息推送模块
60
+        /// </summary>
61
+        public static void Init(int port)
62
+        {
63
+            // 初始化Socket对象
64
+            _socketEntry = new SocketManager();
65
+
66
+            //监听错误处理
67
+            _socketEntry.ErrorHappened += (sender, e) =>
68
+                {
69
+                    PlatformLogger.SystemErrorInfo(string.Format("开启客户端监听模块失败!Operation[{0}]", e.ErrorOperation),
70
+                                                   e.SocketException);
71
+                    //MsgHelper.ShowErrorMessageBox(null, "消息监听模块启用失败!");
72
+                };
73
+
74
+            //监听开始处理
75
+            _socketEntry.ServerStart +=
76
+                (sender, e) => PlatformLogger.SystemInfo(string.Format("开启客户端监听模块!Port[{0}]...", e.Port));
77
+
78
+            //监听停止处理
79
+            _socketEntry.ServerStop +=
80
+                (sender, e) => PlatformLogger.SystemInfo(string.Format("关闭客户端监听模块!Port[{0}]...", e.Port));
81
+
82
+            //接收数据处理
83
+            _socketEntry.DataReceived += (sender, e) =>
84
+                {
85
+                    if (!e.IsCompleted || e.Data == null) return;
86
+                    var data = new ReceivedData(e.Data) { Handle = false };
87
+                    Application.Current.Dispatcher.Invoke(new Action<ReceivedData>(x =>
88
+                        {
89
+                            //分析报文类型
90
+                            dynamic message = AnalyzeData(x.Data);
91
+
92
+                            if (message != null)
93
+                            {
94
+                                //发送对应类型报文消息                                
95
+                                Messenger.Default.Send(message);
96
+
97
+                            }
98
+                        }), data);
99
+                };
100
+
101
+            try
102
+            {
103
+
104
+                //初始化所有消息窗体(开启对应类型报文监听)
105
+                Assembly.GetExecutingAssembly()
106
+                        .GetTypes()
107
+                        .Where(c => c.GetInterface("INotification") != null)
108
+                        .ToList()
109
+                        .ForEach(item => item.GetMethod("Init").Invoke(null, null));
110
+            }
111
+            catch
112
+            {
113
+
114
+            }
115
+            //开启监听服务
116
+            Startup(port);
117
+        }
118
+        private static MessageBase AnalyzeData(byte[] data)
119
+        {
120
+            MessageBase message = null;
121
+
122
+            if (data != null)
123
+            {
124
+                try
125
+                {
126
+                    var md = new MessageData(GetXmlNode(data));
127
+
128
+                    if (md.Type == "UploadLog")
129
+                    {
130
+                        try
131
+                        {
132
+                            string filePath = "Logs/" + md.Trade + "/" + md.Sender + "/" + md.Other;
133
+                            if (System.IO.File.Exists(filePath))
134
+                            {
135
+                                string fileName = md.Other;                               
136
+                                string upFilePath = "UpLoadLogs" + "/" + md.Trade + "/" + md.Sender + "/";
137
+                                byte[] filedata=System.IO.File.ReadAllBytes(filePath);
138
+                                TradeHandle.FtpUpLoad(fileName, upFilePath, filedata);
139
+                            }
140
+                        }
141
+                        catch { }
142
+                    }
143
+                    if (md.Type == "5")
144
+                    {
145
+                        try
146
+                        {
147
+                            var page = MainPageManager.GetMainPage() as IPage;
148
+                            if (page == null)
149
+                                MessageBox.Show("对不起,您因故被柜员“" + md.Sender + "”强制下线。", "下线提醒");
150
+                            else
151
+                                page.ShowMessageBox("对不起,您因故被柜员“" + md.Sender + "”强制下线。", "下线提醒");
152
+                            Application.Current.Dispatcher.InvokeShutdown();
153
+                        }
154
+                        catch { }
155
+                    }                  
156
+                    if (_messageTypeList == null)
157
+                    {
158
+                        //获取报文类型列表
159
+                        _messageTypeList = Assembly.GetExecutingAssembly()
160
+                                                   .GetTypes()
161
+                                                   .Where(c => c.BaseType == typeof(MessageBase));
162
+                    }
163
+
164
+                    //获取对应报文类型
165
+                    Type type = _messageTypeList.SingleOrDefault(c =>
166
+                        {
167
+                            object[] atts = c.GetCustomAttributes(typeof(NotificationAttribute), false);
168
+
169
+                            if (atts.Count() == 1)
170
+                            {
171
+                                var att = atts[0] as NotificationAttribute;
172
+                                if (att != null && att.NotificationFlag == md.Type)
173
+                                {
174
+                                    return true;
175
+                                }
176
+                            }
177
+                            return false;
178
+                        });
179
+
180
+                    //生成对应报文实例
181
+                    if (type != null)
182
+                    {
183
+                        object item = Assembly.Load("TellerSystem.Library.Ext.TradeExtension")
184
+                                              .CreateInstance(type.FullName, true, BindingFlags.Default, null, new Object[]
185
+                                                  {
186
+                                                      md
187
+                                                  }, null, null);
188
+
189
+                        message = item as MessageBase;
190
+                    }
191
+                }
192
+                catch (Exception e)
193
+                {
194
+                    PlatformLogger.SystemErrorInfo("无效的通知报文!", e);
195
+                }
196
+            }
197
+            return message;
198
+        }
199
+
200
+        /// <summary>
201
+        /// XML数据转换
202
+        /// </summary>
203
+        /// <param name="data"></param>
204
+        /// <returns></returns>
205
+        private static XmlNode GetXmlNode(byte[] data)
206
+        {
207
+            string sData = PlatformSettings.Encoding.GetString(data);
208
+            var xd = new XmlDocument();
209
+            XmlDeclaration dec = xd.CreateXmlDeclaration("1.0", "GB2312", null);
210
+            xd.AppendChild(dec);
211
+            xd.LoadXml(sData);
212
+            XmlNode xnRoot = xd.SelectSingleNode("root");
213
+            return xnRoot;
214
+        }
215
+
216
+        #endregion
217
+
218
+        #region Class
219
+
220
+        /// <summary>
221
+        ///  接收数据
222
+        /// </summary>
223
+        public class ReceivedData
224
+        {
225
+            /// <summary>
226
+            /// </summary>
227
+            /// <param name="data"></param>
228
+            public ReceivedData(byte[] data)
229
+            {
230
+                Data = data;
231
+            }
232
+
233
+            /// <summary>
234
+            ///     数据是否已处理
235
+            /// </summary>
236
+            public bool Handle { get; set; }
237
+
238
+            /// <summary>
239
+            ///     收到的数据对象
240
+            /// </summary>
241
+            public byte[] Data { get; private set; }
242
+        }
243
+
244
+        #endregion
245
+    }
246
+}

+ 38
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/NotificationMessageBox.xaml 查看文件

@@ -0,0 +1,38 @@
1
+<dhcc:TradePage x:Class="TellerSystem.Library.Ext.TradeExtension.NotificationMessageBox"
2
+                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+                xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5
+                xmlns:dhcc="http://www.dhcc.com.cn"
6
+                xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
7
+                d:DesignHeight="200"
8
+                d:DesignWidth="300"
9
+                DataContext="{Binding Source}"
10
+                mc:Ignorable="d">
11
+    <Grid Width="300" Height="200">
12
+        <DockPanel LastChildFill="True">
13
+            <Grid Margin="0,3,0,0" DockPanel.Dock="Top">
14
+                <StackPanel Margin="3,0" Orientation="Horizontal">
15
+                    <TextBlock Margin="5" Text="发送人:" />
16
+                    <TextBlock Margin="5" Text="{Binding Path=Sender}" />
17
+                    <TextBlock Margin="5" Text="时间:" />
18
+                    <TextBlock Margin="5" Text="{Binding Path=Time}" />
19
+                </StackPanel>
20
+            </Grid>
21
+            <Grid VerticalAlignment="Top" DockPanel.Dock="Bottom">
22
+                <Label HorizontalAlignment="Left">
23
+                    <Hyperlink Click="Hlink_OpenMessageBox_Click"
24
+                               Tag="{Binding Path=Key}"
25
+                               TextDecorations="None">
26
+                        <TextBlock Width="280"
27
+                                   Margin="5"
28
+                                   HorizontalAlignment="Left"
29
+                                   Padding="5"
30
+                                   Text="{Binding Path=Title}"
31
+                                   TextDecorations="Underline"
32
+                                   TextWrapping="Wrap" />
33
+                    </Hyperlink>
34
+                </Label>
35
+            </Grid>
36
+        </DockPanel>
37
+    </Grid>
38
+</dhcc:TradePage>

+ 149
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/NotificationMessageBox.xaml.cs 查看文件

@@ -0,0 +1,149 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Globalization;
4
+using System.Windows;
5
+using System.Windows.Documents;
6
+using Platform.Common.RunningParameters;
7
+using Platform.Library;
8
+using Platform.Presentation.Interfaces;
9
+using TellerSystem.Library.Ext.Function;
10
+using TellerSystem.Library.Ext.TradeInterfaces;
11
+using TellerSystem.ServiceProxy.Ext.ServiceHelper;
12
+
13
+namespace TellerSystem.Library.Ext.TradeExtension
14
+{
15
+    /// <summary>
16
+    ///     NotificationMessageBox.xaml 的交互逻辑
17
+    /// </summary>
18
+    public partial class NotificationMessageBox : INotification
19
+    {
20
+        #region Field
21
+        private static NotificationMessageBox _instance;
22
+
23
+        private static dynamic _mainPage;
24
+        #endregion
25
+
26
+        #region Property
27
+        /// <summary>
28
+        /// 单例实体
29
+        /// </summary>
30
+        public static NotificationMessageBox Instance
31
+        {
32
+            get
33
+            {
34
+                if (_instance == null)
35
+                {
36
+                    _instance = new NotificationMessageBox();
37
+                }
38
+                return _instance;
39
+            }
40
+        }
41
+
42
+        #endregion
43
+        
44
+        #region DependencyProperty
45
+        /// <summary>
46
+        /// 数据源
47
+        /// </summary>
48
+        NotificationMessage Source
49
+        {
50
+            get { return (NotificationMessage)GetValue(SourceProperty); }
51
+            set { SetValue(SourceProperty, value); }
52
+        }
53
+
54
+        // Using a DependencyProperty as the backing store for Source.  This enables animation, styling, binding, etc...
55
+        /// <summary>
56
+        /// 消息数据源
57
+        /// </summary>
58
+        public static readonly DependencyProperty SourceProperty =
59
+            DependencyProperty.Register("Source", typeof(NotificationMessage), typeof(NotificationMessageBox));
60
+        #endregion
61
+
62
+        #region Ctor
63
+        /// <summary>
64
+        ///     构造通知窗体对象
65
+        /// </summary>
66
+        private NotificationMessageBox()
67
+        {
68
+            InitializeComponent();
69
+        }
70
+        #endregion
71
+
72
+        #region Method
73
+        /// <summary>
74
+        /// 注册监听
75
+        /// </summary>
76
+        public void Register()
77
+        {
78
+            Messenger.Default.Register(this, new Action<NotificationMessage>(NewMessage));
79
+        }
80
+
81
+        /// <summary>
82
+        /// 注销监听
83
+        /// </summary>
84
+        public void Unregister()
85
+        {
86
+            Messenger.Default.Unregister<NotificationMessage>(this);
87
+        }
88
+
89
+        /// <summary>
90
+        /// 初始化监听
91
+        /// </summary>
92
+        public static void Init()
93
+        {
94
+            Instance.Register();
95
+        }
96
+
97
+        /// <summary>
98
+        /// 新消息提示
99
+        /// </summary>
100
+        /// <param name="message"></param>
101
+        private void NewMessage(NotificationMessage message)
102
+        {
103
+            if (message == null)
104
+                return;
105
+
106
+            if (_mainPage == null)
107
+            {
108
+                _mainPage = MainPageManager.GetMainPage();
109
+
110
+                if (_mainPage == null)
111
+                    throw new Exception("无法找到主界面!");
112
+            }
113
+
114
+            var messageBox = new NotificationMessageBox { Source = message };
115
+
116
+            _mainPage.ShowBottomDialog("消息提示", messageBox);
117
+        }
118
+        #endregion
119
+
120
+        #region Event
121
+        /// <summary>
122
+        /// 打开消息盒子
123
+        /// </summary>
124
+        /// <param name="sender"></param>
125
+        /// <param name="e"></param>
126
+        private void Hlink_OpenMessageBox_Click(object sender, RoutedEventArgs e)
127
+        {
128
+            var hyperlink = sender as Hyperlink;
129
+
130
+            if (hyperlink == null || string.IsNullOrWhiteSpace(hyperlink.Tag.ToString()))
131
+                return;
132
+
133
+            //显示公告消息盒子
134
+            string userid = PlatformManagerHandle.Get_TT_LOGINUSER_UserID(LoginUserInfo.TellerNo.Trim());
135
+            dynamic mainPage = MainPageManager.GetMainPage();
136
+            if (mainPage != null)
137
+            {
138
+                try
139
+                {
140
+                    mainPage.ShowNotifyBox(userid, hyperlink.Tag.ToString());
141
+                }
142
+                catch (Exception)
143
+                {
144
+                }
145
+            }
146
+        }
147
+        #endregion
148
+    }
149
+}

+ 92
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/TaskMessageBox.xaml 查看文件

@@ -0,0 +1,92 @@
1
+<dhcc:TradePage x:Class="TellerSystem.Library.Ext.TradeExtension.TaskMessageBox"
2
+                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+                xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5
+                xmlns:dhcc="http://www.dhcc.com.cn"
6
+                xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
7
+                d:DesignHeight="200"
8
+                d:DesignWidth="300"
9
+                DataContext="{Binding Source}"
10
+                mc:Ignorable="d">
11
+    <Grid Width="300" Height="200">
12
+        <Grid.RowDefinitions>
13
+            <RowDefinition Height="30" />
14
+            <RowDefinition Height="30" />
15
+            <RowDefinition Height="30" />
16
+            <RowDefinition Height="30" />
17
+            <RowDefinition Height="50" />
18
+        </Grid.RowDefinitions>
19
+        <Grid.ColumnDefinitions>
20
+            <ColumnDefinition Width="60" />
21
+            <ColumnDefinition Width="10" />
22
+            <ColumnDefinition />
23
+        </Grid.ColumnDefinitions>
24
+        <TextBlock Grid.Row="0"
25
+                   Grid.Column="0"
26
+                   HorizontalAlignment="Right"
27
+                   VerticalAlignment="Center"
28
+                   Text="发起柜员:" />
29
+        <TextBlock Grid.Row="0"
30
+                   Grid.Column="2"
31
+                   HorizontalAlignment="Left"
32
+                   VerticalAlignment="Center"
33
+                   Text="{Binding StartTeller}" />
34
+        <TextBlock Grid.Row="1"
35
+                   Grid.Column="0"
36
+                   HorizontalAlignment="Right"
37
+                   VerticalAlignment="Center"
38
+                   Text="发起时间:" />
39
+        <TextBlock Grid.Row="1"
40
+                   Grid.Column="2"
41
+                   HorizontalAlignment="Left"
42
+                   VerticalAlignment="Center"
43
+                   Text="{Binding StartTime}" />
44
+        <TextBlock Grid.Row="2"
45
+                   Grid.Column="0"
46
+                   HorizontalAlignment="Right"
47
+                   VerticalAlignment="Center"
48
+                   Text="业务描述:" />
49
+        <TextBlock Grid.Row="2"
50
+                   Grid.Column="2"
51
+                   HorizontalAlignment="Left"
52
+                   VerticalAlignment="Center"
53
+                   Text="{Binding TradeDes}" />
54
+        <TextBlock Grid.Row="3"
55
+                   Grid.Column="0"
56
+                   HorizontalAlignment="Right"
57
+                   VerticalAlignment="Center"
58
+                   Text="任务描述:" />
59
+        <TextBlock Grid.Row="3"
60
+                   Grid.Column="2"
61
+                   HorizontalAlignment="Left"
62
+                   VerticalAlignment="Center"
63
+                   Text="{Binding TaskDes}" />
64
+        <Path Grid.Row="4"
65
+              Grid.Column="0"
66
+              Grid.ColumnSpan="3"
67
+              Height="1"
68
+              Margin="0,3,0,0"
69
+              VerticalAlignment="Top"
70
+              Data="M0,64 L608,64"
71
+              Stretch="Fill">
72
+            <Path.Stroke>
73
+                <LinearGradientBrush MappingMode="RelativeToBoundingBox" SpreadMethod="Repeat" StartPoint="0,0.5" EndPoint="1,0.5">
74
+                    <GradientStop Offset="0" Color="White" />
75
+                    <GradientStop Offset="0.1" Color="Blue" />
76
+                    <GradientStop Offset="0.9" Color="Gray" />
77
+                    <GradientStop Offset="1" Color="White" />
78
+                </LinearGradientBrush>
79
+            </Path.Stroke>
80
+        </Path>
81
+        <Button x:Name="btn_Perform"
82
+                Grid.Row="6"
83
+                Grid.Column="2"
84
+                Width="80"
85
+                Height="23"
86
+                Margin="115,10,0,0"
87
+                HorizontalAlignment="Left"
88
+                VerticalAlignment="Top"
89
+                Click="btn_Perform_PreviewKeyDown"
90
+                Content="执行" />
91
+    </Grid>
92
+</dhcc:TradePage>

+ 173
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/TaskMessageBox.xaml.cs 查看文件

@@ -0,0 +1,173 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Windows;
4
+using TellerSystem.Library.Ext.Function;
5
+using TellerSystem.Library.Ext.TradeInterfaces;
6
+using TellerSystem.ServiceProxy.Ext.ServiceHelper;
7
+
8
+namespace TellerSystem.Library.Ext.TradeExtension
9
+{
10
+    /// <summary>
11
+    ///     NotificationMessageBox.xaml 的交互逻辑
12
+    /// </summary>
13
+    public partial class TaskMessageBox : INotification
14
+    {
15
+        #region Field
16
+
17
+        private static TaskMessageBox _instance;
18
+
19
+        private static dynamic _mainPage;
20
+
21
+        #endregion
22
+
23
+        #region Property
24
+
25
+        /// <summary>
26
+        ///     单例实体
27
+        /// </summary>
28
+        public static TaskMessageBox Instance
29
+        {
30
+            get
31
+            {
32
+                if (_instance == null)
33
+                {
34
+                    _instance = new TaskMessageBox();
35
+                }
36
+                return _instance;
37
+            }
38
+        }
39
+
40
+        #endregion
41
+
42
+        #region DependencyProperty
43
+
44
+        /// <summary>
45
+        /// 消息数据源
46
+        /// </summary>
47
+        public static readonly DependencyProperty SourceProperty =
48
+            DependencyProperty.Register("Source", typeof (TaskMessage), typeof (TaskMessageBox));
49
+
50
+        /// <summary>
51
+        ///     数据源
52
+        /// </summary>
53
+        private TaskMessage Source
54
+        {
55
+            get { return (TaskMessage) GetValue(SourceProperty); }
56
+            set { SetValue(SourceProperty, value); }
57
+        }
58
+
59
+        #endregion
60
+
61
+        #region Ctor
62
+
63
+        /// <summary>
64
+        ///     构造通知窗体对象
65
+        /// </summary>
66
+        public TaskMessageBox()
67
+        {
68
+            InitializeComponent();
69
+        }
70
+
71
+        #endregion
72
+
73
+        #region Event
74
+
75
+        /// <summary>
76
+        ///     执行按钮响应事件
77
+        /// </summary>
78
+        /// <param name="sender"></param>
79
+        /// <param name="e"></param>
80
+        private void btn_Perform_PreviewKeyDown(object sender, RoutedEventArgs e)
81
+        {
82
+            Dictionary<string, string> tradedata = WorkFlowHandle.GetTradedataBySerialNo(Source.Key);
83
+
84
+            if (tradedata == null)
85
+            {
86
+                btn_Perform.IsEnabled = false;
87
+                return;
88
+            }
89
+
90
+            if (tradedata.ContainsKey("WorkItemId"))
91
+            {
92
+                tradedata["WorkItemId"] = Source.Other;
93
+            }
94
+            else
95
+            {
96
+                tradedata.Add("WorkItemId", Source.Other);
97
+            }
98
+            if ("Restore".Equals(Source.Trade)) //交易还原
99
+            {
100
+                // 这里授权结果使用的的是AuthFlag,复核使用的是SuperFlag
101
+                var bus = new TradeBusData();
102
+                foreach (var item in tradedata)
103
+                    bus[item.Key] = item.Value;
104
+                //TODO:20140422
105
+                //this.RestoreTradePage(tradedata["SerialId"], bus);
106
+                btn_Perform.IsEnabled = false;
107
+            }
108
+            else //打开新交易
109
+            {
110
+                var d = new TradeBusData();
111
+                foreach (var item in tradedata)
112
+                {
113
+                    d[item.Key] = item.Value;
114
+                }
115
+                btn_Perform.IsEnabled = false;
116
+                this.OpenTradePage(Source.Trade, TradePageExtension.OpenOptions.NewPage, null, d);
117
+            }
118
+        }
119
+
120
+        #endregion
121
+
122
+        #region Method
123
+
124
+        /// <summary>
125
+        ///     注册监听
126
+        /// </summary>
127
+        public void Register()
128
+        {
129
+            Messenger.Default.Register(this, new Action<TaskMessage>(NewMessage));
130
+        }
131
+
132
+        /// <summary>
133
+        ///     注销监听
134
+        /// </summary>
135
+        public void Unregister()
136
+        {
137
+            Messenger.Default.Unregister<TaskMessage>(this);
138
+        }
139
+
140
+
141
+        /// <summary>
142
+        ///     初始化监听
143
+        /// </summary>
144
+        public static void Init()
145
+        {
146
+            Instance.Register();
147
+        }
148
+
149
+        /// <summary>
150
+        ///     新消息提示
151
+        /// </summary>
152
+        /// <param name="message"></param>
153
+        private void NewMessage(TaskMessage message)
154
+        {
155
+            if (message == null)
156
+                return;
157
+
158
+            if (_mainPage == null)
159
+            {
160
+                _mainPage = MainPageManager.GetMainPage();
161
+
162
+                if (_mainPage == null)
163
+                    throw new Exception("无法找到主界面!");
164
+            }
165
+
166
+            var messageBox = new TaskMessageBox {Source = message};
167
+
168
+            _mainPage.ShowBottomDialog("消息提示", messageBox);
169
+        }
170
+
171
+        #endregion
172
+    }
173
+}

+ 119
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Notification/WeakAction.ts 查看文件

@@ -0,0 +1,119 @@
1
+// 定义一个泛型函数类型 Action
2
+type Action = () => void;
3
+
4
+// 定义 WeakReference 类来模拟 C# 中的弱引用
5
+class WeakReference<T extends object> {
6
+    private ref: WeakRef<T> | null;
7
+
8
+    constructor(target: T | null) {
9
+        this.ref = target ? new WeakRef(target) : null;
10
+    }
11
+
12
+    get IsAlive(): boolean {
13
+        return this.ref !== null && this.ref.deref() !== undefined;
14
+    }
15
+
16
+    get Target(): T | null {
17
+        return this.ref ? this.ref.deref() || null : null;
18
+    }
19
+}
20
+
21
+// 定义 WeakAction 类
22
+export class WeakAction {
23
+    private _staticAction: Action | null = null;
24
+    protected Method: PropertyDescriptor | null = null;
25
+    protected ActionReference: WeakReference<object> | null = null;
26
+    protected Reference: WeakReference<object> | null = null;
27
+
28
+    // 构造函数
29
+    protected constructor() { }
30
+
31
+    // 构造函数
32
+    constructor(action: Action | null);
33
+    constructor(target: object | null, action: Action);
34
+    constructor(arg1?: object | Action | null, arg2?: Action) {
35
+        if (typeof arg1 === 'function') {
36
+            const action = arg1;
37
+            this.constructor(action ? action.Target : null, action);
38
+        } else if (arg1 !== undefined && arg2 !== undefined) {
39
+            const target = arg1;
40
+            const action = arg2;
41
+            const method = Object.getOwnPropertyDescriptor(action, 'prototype')?.value;
42
+            if (method && typeof method === 'function' && method.hasOwnProperty('name')) {
43
+                this._staticAction = action;
44
+                if (target) {
45
+                    this.Reference = new WeakReference(target);
46
+                }
47
+                return;
48
+            }
49
+
50
+            this.Method = Object.getOwnPropertyDescriptor(action, 'prototype');
51
+            this.ActionReference = new WeakReference(action.Target || {});
52
+            this.Reference = new WeakReference(target);
53
+        }
54
+    }
55
+
56
+    // 引用的方法名称
57
+    get MethodName(): string {
58
+        if (this._staticAction) {
59
+            return this._staticAction.name;
60
+        }
61
+        return this.Method?.value?.name || '';
62
+    }
63
+
64
+    // 静态方法标志
65
+    get IsStatic(): boolean {
66
+        return this._staticAction !== null;
67
+    }
68
+
69
+    // 实体 活动标志
70
+    get IsAlive(): boolean {
71
+        if (!this._staticAction && !this.Reference) {
72
+            return false;
73
+        }
74
+
75
+        if (this._staticAction) {
76
+            if (this.Reference) {
77
+                return this.Reference.IsAlive;
78
+            }
79
+            return true;
80
+        }
81
+
82
+        return this.Reference?.IsAlive || false;
83
+    }
84
+
85
+    // Action 的拥有者
86
+    get Target(): object | null {
87
+        return this.Reference?.Target || null;
88
+    }
89
+
90
+    // Action 触发对象
91
+    protected get ActionTarget(): object | null {
92
+        return this.ActionReference?.Target || null;
93
+    }
94
+
95
+    // 执行活动中的 Action
96
+    Execute(): void {
97
+        if (this._staticAction) {
98
+            this._staticAction();
99
+            return;
100
+        }
101
+
102
+        const actionTarget = this.ActionTarget;
103
+
104
+        if (this.IsAlive) {
105
+            if (this.Method && this.ActionReference && actionTarget) {
106
+                const methodFunc = this.Method.value as Function;
107
+                methodFunc.apply(actionTarget);
108
+            }
109
+        }
110
+    }
111
+
112
+    // 清空操作
113
+    MarkForDeletion(): void {
114
+        this.Reference = null;
115
+        this.ActionReference = null;
116
+        this.Method = null;
117
+        this._staticAction = null;
118
+    }
119
+}

+ 103
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/OutOfDataObject.cs 查看文件

@@ -0,0 +1,103 @@
1
+using System.Collections.Generic;
2
+using TellerSystem.Library.Ext;
3
+
4
+namespace TellerSystem.Library.Ext.TradeExtension
5
+{
6
+
7
+    public static class OutOfDataObject
8
+    {
9
+       
10
+     //public  static NormalTradePage page = new NormalTradePage();
11
+
12
+     //public static NormalTradePage Page
13
+     //   {
14
+     //       get { return page; }
15
+     //       set { page = value; }
16
+     //   }
17
+     //public static Dictionary<string, Dictionary<string, string>> dirt = new Dictionary<string, Dictionary<string, string>>();
18
+
19
+     // public static Dictionary<string, Dictionary<string, string>> Dirt
20
+     //   {
21
+     //       get { return dirt; }
22
+     //       set { dirt = value; }
23
+     //   }
24
+     // private static string id;
25
+
26
+     // public static string Id
27
+     // {
28
+     //     get { return OutOfDataObject.id; }
29
+     //     set { OutOfDataObject.id = value; }
30
+     // }
31
+
32
+     
33
+       /// <summary>
34
+       /// 检索数据,得到外部数据
35
+       /// </summary>
36
+       /// <param name="trade_type">交易类型</param>
37
+       /// <param name="keywords">关键字</param>
38
+       /// <returns>外部数据</returns>
39
+      public  static Dictionary<string,string> GetOutofData(string trade_type, string keywords)
40
+        {
41
+            //Dictionary<string, string> outData = new Dictionary<string, string>();
42
+            //TradeServiceService trade = new TradeServiceService();
43
+            //string tradeNo = page.GetType().Name;
44
+            //string branch_no = LoginUserInfo.KinbrNo;
45
+            //if (OutOfDataObject.Dirt != null)
46
+            //{
47
+            //    if (OutOfDataObject.Dirt.ContainsKey(keywords))
48
+            //    {
49
+            //        outData = OutOfDataObject.Dirt[keywords];
50
+            //    }
51
+            //    else
52
+            //    {
53
+
54
+            //        string outstr = trade.GetOutOfData(tradeNo, trade_type, keywords, branch_no); 
55
+            //        if (outstr != null)
56
+            //        {
57
+            //            //反序列化
58
+            //            outData = TradePageExtension.Deserialize <Dictionary<string, string>>(page, outstr);
59
+            //        }
60
+            //        //else
61
+            //        //{
62
+            //        //    MessageBox.Show("没有查到保存的数据");
63
+            //        //}
64
+            //    }
65
+               
66
+            //}
67
+            //else
68
+            //{
69
+            //    ////查询数据库
70
+            //    string outstr = trade.GetOutOfData(tradeNo, trade_type, keywords, branch_no);
71
+            //    if (outstr != null)
72
+            //    {
73
+            //        //反序列化
74
+            //        outData = TradePageExtension.Deserialize<Dictionary<string, string>>(page, outstr);
75
+            //    }
76
+               
77
+            //}
78
+
79
+            //return outData;
80
+          return null;
81
+        }
82
+        /// <summary>
83
+        /// 保存外部数据
84
+        /// </summary>
85
+        /// <param name="keywords"></param>
86
+        /// <param name="dirct"></param>
87
+        /// <returns></returns>
88
+        //public static  bool SetOutofData(string trade_type, string keywords,Dictionary<string,string> dirct)
89
+        //{
90
+        //    string outdataId = Guid.NewGuid().ToString("N");
91
+        //    OutOfDataObject.Id = outdataId;
92
+        //    string branch_no = LoginUserInfo.KinbrNo;
93
+        //    string tradeNo = OutOfDataObject.page.GetType().Name;
94
+        //    string tellerNo = LoginUserInfo.TellerNo.Trim();
95
+        //    string outdata = TradePageExtension.Serialize(page, dirct);
96
+        //    TradeServiceService trade = new TradeServiceService();
97
+        //    bool Isok = trade.SetOutOfData(outdataId, tradeNo, trade_type, keywords, outdata, tellerNo, branch_no);
98
+        //    return Isok;
99
+        //}
100
+
101
+    }
102
+ 
103
+}

+ 79
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/OutOfDataObject.ts 查看文件

@@ -0,0 +1,79 @@
1
+// 模拟依赖的类和方法
2
+class NormalTradePage {}
3
+class TradeServiceService {
4
+    GetOutOfData(tradeNo: string, tradeType: string, keywords: string, branchNo: string): string | null {
5
+        // 模拟实现,实际需根据业务实现
6
+        return null;
7
+    }
8
+    SetOutOfData(outdataId: string, tradeNo: string, tradeType: string, keywords: string, outdata: string, tellerNo: string, branchNo: string): boolean {
9
+        // 模拟实现,实际需根据业务实现
10
+        return false;
11
+    }
12
+}
13
+class TradePageExtension {
14
+    static Deserialize<T>(page: NormalTradePage, str: string): T {
15
+        // 模拟反序列化,实际需根据业务实现
16
+        return JSON.parse(str) as T;
17
+    }
18
+    static Serialize(page: NormalTradePage, data: any): string {
19
+        // 模拟序列化,实际需根据业务实现
20
+        return JSON.stringify(data);
21
+    }
22
+}
23
+class LoginUserInfo {
24
+    static get KinbrNo(): string {
25
+        // 模拟实现,实际需根据业务实现
26
+        return "";
27
+    }
28
+    static get TellerNo(): string {
29
+        // 模拟实现,实际需根据业务实现
30
+        return "";
31
+    }
32
+}
33
+
34
+// 定义 OutOfDataObject 类
35
+export class OutOfDataObject {
36
+    static page: NormalTradePage = new NormalTradePage();
37
+    static dirt: { [key: string]: { [key: string]: string } } = {};
38
+    static id: string = "";
39
+
40
+    static GetOutofData(trade_type: string, keywords: string): { [key: string]: string } | null {
41
+        // 原注释代码的逻辑实现
42
+        // const outData: { [key: string]: string } = {};
43
+        // const trade = new TradeServiceService();
44
+        // const tradeNo = this.page.constructor.name;
45
+        // const branch_no = LoginUserInfo.KinbrNo;
46
+
47
+        // if (this.dirt) {
48
+        //     if (this.dirt[keywords]) {
49
+        //         return this.dirt[keywords];
50
+        //     } else {
51
+        //         const outstr = trade.GetOutOfData(tradeNo, trade_type, keywords, branch_no);
52
+        //         if (outstr) {
53
+        //             return TradePageExtension.Deserialize<{ [key: string]: string }>(this.page, outstr);
54
+        //         }
55
+        //     }
56
+        // } else {
57
+        //     const outstr = trade.GetOutOfData(tradeNo, trade_type, keywords, branch_no);
58
+        //     if (outstr) {
59
+        //         return TradePageExtension.Deserialize<{ [key: string]: string }>(this.page, outstr);
60
+        //     }
61
+        // }
62
+
63
+        // return outData;
64
+
65
+        // 当前实际实现
66
+        return null;
67
+    }
68
+
69
+    static SetOutofData(trade_type: string, keywords: string, dirct: { [key: string]: string }): boolean {
70
+        const outdataId = Math.random().toString(36).substr(2, 9);
71
+        this.id = outdataId;
72
+        const branch_no = LoginUserInfo.KinbrNo;
73
+        const tradeNo = this.page.constructor.name;
74
+        const tellerNo = LoginUserInfo.TellerNo.trim();
75
+        const outdata = TradePageExtension.Serialize(this.page, dirct);
76
+        const trade = new TradeServiceService();
77
+        return trade.SetOutOfData(outdataId, tradeNo, trade_type, keywords, outdata, tellerNo, branch_no);
78
+    }
79
+}

+ 134
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/PageController.cs 查看文件

@@ -0,0 +1,134 @@
1
+using System;
2
+
3
+namespace TellerSystem.Library.Ext.TradeExtension
4
+{
5
+    public class PageController
6
+    {
7
+        /// <summary>
8
+        /// 当前页数
9
+        /// </summary> 
10
+        public int CurPage { get; set; }
11
+        /// <summary>
12
+        /// 总页数
13
+        /// </summary> 
14
+        public int TotalPage { get; set; }
15
+        /// <summary>
16
+        /// 首页
17
+        /// </summary> 
18
+        public event EventHandler EventFristPage;
19
+        /// <summary>
20
+        /// 末页
21
+        /// </summary>
22
+        public event EventHandler EventLastPage;
23
+        /// <summary>
24
+        /// 中间页
25
+        /// </summary>
26
+        public event EventHandler EventPage;
27
+        /// <summary>
28
+        /// 只有一页
29
+        /// </summary>
30
+        public event EventHandler EventOnlyPage;
31
+
32
+
33
+        /// <summary>
34
+        /// 初始化构造方法
35
+        /// </summary>
36
+        public PageController()
37
+        {
38
+            this.CurPage = 1;
39
+            this.TotalPage = 1;
40
+        }
41
+
42
+        /// <summary>
43
+        /// 计算页数
44
+        /// </summary>
45
+        public void CountPage(int totalPage)
46
+        {
47
+            this.TotalPage = totalPage; 
48
+            FireEvent();
49
+        }
50
+
51
+
52
+        /// <summary>
53
+        /// 首页
54
+        /// </summary>
55
+        public void FristPage()
56
+        {
57
+            this.CurPage = 1;
58
+            FireEvent();
59
+        }
60
+
61
+        /// <summary>
62
+        /// 上一页
63
+        /// </summary>
64
+        public void PreviousPage()
65
+        {
66
+            this.CurPage--;
67
+            if (this.CurPage < 1)
68
+            {
69
+                this.CurPage = 1;
70
+            }
71
+            FireEvent();
72
+        }
73
+        /// <summary>
74
+        /// 下一页
75
+        /// </summary>
76
+        public void NextPage()
77
+        {
78
+            this.CurPage++;
79
+            if (this.CurPage > this.TotalPage)
80
+            {
81
+                this.CurPage = this.TotalPage;
82
+            }
83
+            FireEvent();
84
+        }
85
+
86
+        /// <summary>
87
+        /// 末页
88
+        /// </summary>
89
+        public void LastPage()
90
+        {
91
+            this.CurPage = this.TotalPage;
92
+            FireEvent();
93
+        }
94
+
95
+        /// <summary>
96
+        /// 调用事件
97
+        /// </summary>
98
+        public void FireEvent()
99
+        {
100
+            if (this.TotalPage < 2)
101
+            {
102
+                if (EventOnlyPage != null)
103
+                {
104
+                    EventOnlyPage(this, EventArgs.Empty);
105
+                    return;
106
+                }
107
+            }
108
+            if (CurPage == 1)
109
+            {
110
+                if (EventFristPage != null)
111
+                {
112
+                    EventFristPage(this, EventArgs.Empty);
113
+                    return;
114
+                }
115
+            }
116
+            if (CurPage == this.TotalPage)
117
+            {
118
+                if (EventLastPage != null)
119
+                {
120
+                    EventLastPage(this, EventArgs.Empty);
121
+                    return;
122
+                }
123
+            }
124
+            if (CurPage > 1 && CurPage < this.TotalPage)
125
+            {
126
+                if (EventPage != null)
127
+                {
128
+                    EventPage(this, EventArgs.Empty);
129
+                    return;
130
+                }
131
+            }
132
+        }
133
+    }
134
+}

+ 93
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/PageController.ts 查看文件

@@ -0,0 +1,93 @@
1
+// 定义事件处理函数类型
2
+type EventHandler = (sender: PageController, args: EventArgs) => void;
3
+
4
+// 定义 EventArgs 类
5
+class EventArgs {
6
+    static Empty = new EventArgs();
7
+}
8
+
9
+class PageController {
10
+    // 当前页数
11
+    public CurPage: number;
12
+    // 总页数
13
+    public TotalPage: number;
14
+    // 首页事件
15
+    public EventFristPage?: EventHandler;
16
+    // 末页事件
17
+    public EventLastPage?: EventHandler;
18
+    // 中间页事件
19
+    public EventPage?: EventHandler;
20
+    // 只有一页事件
21
+    public EventOnlyPage?: EventHandler;
22
+
23
+    constructor() {
24
+        this.CurPage = 1;
25
+        this.TotalPage = 1;
26
+    }
27
+
28
+    // 计算页数
29
+    public CountPage(totalPage: number): void {
30
+        this.TotalPage = totalPage;
31
+        this.FireEvent();
32
+    }
33
+
34
+    // 首页
35
+    public FristPage(): void {
36
+        this.CurPage = 1;
37
+        this.FireEvent();
38
+    }
39
+
40
+    // 上一页
41
+    public PreviousPage(): void {
42
+        this.CurPage--;
43
+        if (this.CurPage < 1) {
44
+            this.CurPage = 1;
45
+        }
46
+        this.FireEvent();
47
+    }
48
+
49
+    // 下一页
50
+    public NextPage(): void {
51
+        this.CurPage++;
52
+        if (this.CurPage > this.TotalPage) {
53
+            this.CurPage = this.TotalPage;
54
+        }
55
+        this.FireEvent();
56
+    }
57
+
58
+    // 末页
59
+    public LastPage(): void {
60
+        this.CurPage = this.TotalPage;
61
+        this.FireEvent();
62
+    }
63
+
64
+    // 调用事件
65
+    public FireEvent(): void {
66
+        if (this.TotalPage < 2) {
67
+            if (this.EventOnlyPage) {
68
+                this.EventOnlyPage(this, EventArgs.Empty);
69
+                return;
70
+            }
71
+        }
72
+        if (this.CurPage === 1) {
73
+            if (this.EventFristPage) {
74
+                this.EventFristPage(this, EventArgs.Empty);
75
+                return;
76
+            }
77
+        }
78
+        if (this.CurPage === this.TotalPage) {
79
+            if (this.EventLastPage) {
80
+                this.EventLastPage(this, EventArgs.Empty);
81
+                return;
82
+            }
83
+        }
84
+        if (this.CurPage > 1 && this.CurPage < this.TotalPage) {
85
+            if (this.EventPage) {
86
+                this.EventPage(this, EventArgs.Empty);
87
+                return;
88
+            }
89
+        }
90
+    }
91
+}
92
+
93
+export { PageController };

+ 145
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/PerCombBoxData.cs 查看文件

@@ -0,0 +1,145 @@
1
+using System.Collections.Generic;
2
+using System.Windows.Controls;
3
+using Platform.Controls.ControlsHelper;
4
+using Platform.Library;
5
+using Platform.Presentation.Interfaces;
6
+using TellerSystem.Communication;
7
+using TellerSystem.Library.Ext.Function;
8
+using TellerSystem.Library.Ext.Variables;
9
+
10
+namespace TellerSystem.Library.Ext.TradeExtension
11
+{
12
+    /// <summary>
13
+    /// ComboBox实体数据层
14
+    /// </summary>
15
+    public class PerCombBoxData
16
+    {
17
+        private static PerCombBoxData instance;
18
+        private static object _lock = new object();
19
+        private List<PerCombBoxData> comboboxList = new List<PerCombBoxData>();
20
+
21
+        private PerCombBoxData()
22
+        {
23
+            _combBoxKeyValue = new Dictionary<string, string>();
24
+        }
25
+
26
+        /// <summary>
27
+        /// 初始化一个PerCombBoxData,(单例模式)
28
+        /// </summary>
29
+        /// <returns></returns>
30
+        public static PerCombBoxData GetInstance()
31
+        {
32
+            if (instance == null)
33
+            {
34
+                lock (_lock)
35
+                {
36
+                    if (instance == null)
37
+                    {
38
+                        instance = new PerCombBoxData();
39
+                    }
40
+                }
41
+            }
42
+            return instance;
43
+        }
44
+
45
+        private IPage _tradeName;
46
+        private string _combBoxName;
47
+        private string _combBoxMark;
48
+        private Dictionary<string, string> _combBoxKeyValue;
49
+
50
+        /// <summary>
51
+        /// 交易名称
52
+        /// </summary>
53
+        public IPage TradeName
54
+        {
55
+            get { return _tradeName; }
56
+            set { _tradeName = value; }
57
+        }
58
+
59
+        /// <summary>
60
+        /// ComboBox名称
61
+        /// </summary>
62
+        public string CombBoxName
63
+        {
64
+            get { return _combBoxName; }
65
+            set { _combBoxName = value; }
66
+        }
67
+
68
+        /// <summary>
69
+        /// 标识符,同一个交易,同一个Combobox,不同的数据
70
+        /// </summary>
71
+        public string CombBoxNumber
72
+        {
73
+            get { return _combBoxMark; }
74
+            set { _combBoxMark = value; }
75
+        }
76
+
77
+        /// <summary>
78
+        /// ComboBox key and Value
79
+        /// </summary>
80
+        public Dictionary<string, string> CombBoxKeyValue
81
+        {
82
+            get { return _combBoxKeyValue; }
83
+            set { _combBoxKeyValue = value; }
84
+        }
85
+
86
+        /// <summary>
87
+        /// 把Combobox的值添加列表中
88
+        /// </summary>
89
+        /// <param name="target">Ipage对象</param>
90
+        /// <param name="comboBox">ComboBox对象</param>
91
+        /// <param name="msg">Message通讯对象</param>
92
+        /// <param name="formatString">Combobox展现格式</param>
93
+        /// <param name="defalutCombox">默认Combobox标识符</param>
94
+        /// <returns>modify slzh 因涉及业务 返回错误描述,方便界面提示</returns>
95
+        public Result SetComboBoxList(IPage target, ComboBox comboBox, Message msg, string formatString, string defalutCombox = "Null")
96
+        {
97
+            var result = new Result();
98
+            if (comboBox == null || msg == null || string.IsNullOrEmpty(defalutCombox))
99
+            {
100
+                result.Code = "Erro";
101
+                result.Desc = "系统异常:未设置ComboBox或Message对象";
102
+                return result;
103
+            }
104
+            foreach (var comboboxData in comboboxList)
105
+            {
106
+                if (comboboxData.TradeName.GetType().Name == target.GetType().Name && comboboxData.CombBoxName == comboBox.Name && comboboxData.CombBoxNumber == defalutCombox)
107
+                {
108
+                    comboBox.SetItems(comboboxData.CombBoxKeyValue);
109
+                    return result;
110
+                }
111
+            }
112
+            PerCombBoxData _perCombBoxDate = new PerCombBoxData();
113
+            var boolcallServer = SystemFunction.CallServer(target, msg);
114
+            if (!boolcallServer)
115
+            {
116
+                result.Code = "Erro";
117
+                result.Desc = "CallServer与核心通信失败";
118
+                return result;
119
+            }
120
+            if (msg.Fd12 != "0000")
121
+            {
122
+                result.Code = msg.Fd12;
123
+                result.Desc = target.GetError(msg);
124
+                return result;
125
+            }
126
+            string fileData = msg.FileData;
127
+            var boolSetSel = SystemFunction.SetSel(comboBox, fileData, formatString);
128
+            if (!boolSetSel)
129
+            {
130
+                result.Code = "Erro";
131
+                result.Desc = "系统异常:SetSel设置失败";
132
+                return result;
133
+            }
134
+            _perCombBoxDate.TradeName = target;
135
+            _perCombBoxDate.CombBoxName = comboBox.Name;
136
+            _perCombBoxDate.CombBoxNumber = defalutCombox;
137
+            foreach (KeyValuePair<string, string> item in comboBox.Items)
138
+            {
139
+                _perCombBoxDate.CombBoxKeyValue.Add(item.Key, item.Value);
140
+            }
141
+            comboboxList.Add(_perCombBoxDate);
142
+            return result;
143
+        }
144
+    }
145
+}

+ 131
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/PerCombBoxData.ts 查看文件

@@ -0,0 +1,131 @@
1
+// 模拟依赖的类型和函数
2
+interface IPage {}
3
+class ComboBox {
4
+    SetItems(keyValue: { [key: string]: string }) {}
5
+    Items: { [key: string]: string } = {};
6
+    name: string = "";
7
+}
8
+class Message {
9
+    Fd12: string = "";
10
+    FileData: string = "";
11
+}
12
+class Result {
13
+    Code: string = "";
14
+    Desc: string = "";
15
+}
16
+class SystemFunction {
17
+    static CallServer(target: IPage, msg: Message): boolean {
18
+        return true;
19
+    }
20
+    static SetSel(comboBox: ComboBox, fileData: string, formatString: string): boolean {
21
+        return true;
22
+    }
23
+}
24
+
25
+class PerCombBoxData {
26
+    private static instance: PerCombBoxData | null = null;
27
+    private static _lock: object = {};
28
+    private comboboxList: PerCombBoxData[] = [];
29
+
30
+    private _tradeName: IPage | null = null;
31
+    private _combBoxName: string = "";
32
+    private _combBoxMark: string = "";
33
+    private _combBoxKeyValue: { [key: string]: string } = {};
34
+
35
+    private constructor() {
36
+        this._combBoxKeyValue = {};
37
+    }
38
+
39
+    static GetInstance(): PerCombBoxData {
40
+        if (!this.instance) {
41
+            // 模拟锁机制
42
+            if (!this.instance) {
43
+                this.instance = new PerCombBoxData();
44
+            }
45
+        }
46
+        return this.instance;
47
+    }
48
+
49
+    get TradeName(): IPage | null {
50
+        return this._tradeName;
51
+    }
52
+    set TradeName(value: IPage | null) {
53
+        this._tradeName = value;
54
+    }
55
+
56
+    get CombBoxName(): string {
57
+        return this._combBoxName;
58
+    }
59
+    set CombBoxName(value: string) {
60
+        this._combBoxName = value;
61
+    }
62
+
63
+    get CombBoxNumber(): string {
64
+        return this._combBoxMark;
65
+    }
66
+    set CombBoxNumber(value: string) {
67
+        this._combBoxMark = value;
68
+    }
69
+
70
+    get CombBoxKeyValue(): { [key: string]: string } {
71
+        return this._combBoxKeyValue;
72
+    }
73
+    set CombBoxKeyValue(value: { [key: string]: string }) {
74
+        this._combBoxKeyValue = value;
75
+    }
76
+
77
+    SetComboBoxList(target: IPage, comboBox: ComboBox, msg: Message, formatString: string, defalutCombox: string = "Null"): Result {
78
+        const result = new Result();
79
+        if (!comboBox || !msg || defalutCombox === "") {
80
+            result.Code = "Erro";
81
+            result.Desc = "系统异常:未设置ComboBox或Message对象";
82
+            return result;
83
+        }
84
+
85
+        for (const comboboxData of this.comboboxList) {
86
+            if (
87
+                comboboxData.TradeName?.constructor.name === target.constructor.name &&
88
+                comboboxData.CombBoxName === comboBox.name &&
89
+                comboboxData.CombBoxNumber === defalutCombox
90
+            ) {
91
+                comboBox.SetItems(comboboxData.CombBoxKeyValue);
92
+                return result;
93
+            }
94
+        }
95
+
96
+        const perCombBoxDate = new PerCombBoxData();
97
+        const boolcallServer = SystemFunction.CallServer(target, msg);
98
+        if (!boolcallServer) {
99
+            result.Code = "Erro";
100
+            result.Desc = "CallServer与核心通信失败";
101
+            return result;
102
+        }
103
+
104
+        if (msg.Fd12 !== "0000") {
105
+            result.Code = msg.Fd12;
106
+            // 模拟获取错误信息
107
+            result.Desc = "获取错误信息"; 
108
+            return result;
109
+        }
110
+
111
+        const fileData = msg.FileData;
112
+        const boolSetSel = SystemFunction.SetSel(comboBox, fileData, formatString);
113
+        if (!boolSetSel) {
114
+            result.Code = "Erro";
115
+            result.Desc = "系统异常:SetSel设置失败";
116
+            return result;
117
+        }
118
+
119
+        perCombBoxDate.TradeName = target;
120
+        perCombBoxDate.CombBoxName = comboBox.name;
121
+        perCombBoxDate.CombBoxNumber = defalutCombox;
122
+        for (const key in comboBox.Items) {
123
+            perCombBoxDate.CombBoxKeyValue[key] = comboBox.Items[key];
124
+        }
125
+        this.comboboxList.push(perCombBoxDate);
126
+
127
+        return result;
128
+    }
129
+}
130
+
131
+export { PerCombBoxData };

+ 199
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Pinyin.cs 查看文件

@@ -0,0 +1,199 @@
1
+/**
2
+ * NPinyin包含一个公开类Pinyin,该类实现了取汉字文本首字母、文本对应拼音、以及
3
+ * 获取和拼音对应的汉字列表等方法。由于汉字字库大,且多音字较多,因此本组中实现的
4
+ * 拼音转换不一定和词语中的字的正确读音完全吻合。但绝大部分是正确的。
5
+ * 
6
+ * 最后感谢百度网友韦祎提供的常用汉字拼音对照表。见下载地址:
7
+ * http://wenku.baidu.com/view/d725f4335a8102d276a22f46.html
8
+ * 
9
+ * 最后,我想简要地说明一下我的设计思路:
10
+ * 首先,我将汉字按拼音分组后建立一个字符串数组(见PyCode.codes),然后使用程序
11
+ * 将PyCode.codes中每一个汉字通过其编码值使用散列函数:
12
+ * 
13
+ *     f(x) = x % PyCode.codes.Length
14
+ *   { 
15
+ *     g(f(x)) = pos(x)
16
+ *     
17
+ * 其中, pos(x)为字符x所属字符串所在的PyCode.codes的数组下标, 然后散列到同
18
+ * PyCode.codes长度相同长度的一个散列表中PyHash.hashes)。
19
+ * 当检索一个汉字的拼音时,首先从PyHash.hashes中获取和
20
+ * 对应的PyCode.codes中数组下标,然后从对应字符串查找,当到要查找的字符时,字符
21
+ * 串的前6个字符即包含了该字的拼音。
22
+ * 
23
+ * 此种方法的好处一是节约了存储空间,二是兼顾了查询效率。
24
+ *
25
+ * 如有意见,请与我联系反馈。我的邮箱是:qzyzwsy@gmail.com
26
+ * 
27
+ * 汪思言 2011年1月3日凌晨
28
+ * */
29
+
30
+/*
31
+ * v0.2.x的变化
32
+ * =================================================================
33
+ * 1、增加对不同编码格式文本的支持,同时增加编码转换方法Pinyin.ConvertEncoding
34
+ * 2、重构单字符拼音的获取,未找到拼音时返回字符本身.
35
+ * 
36
+ * 汪思言 2012年7月23日晚
37
+ * 
38
+ */
39
+
40
+using System;
41
+using System.Collections.Generic;
42
+using System.Text;
43
+
44
+namespace NPinyin
45
+{
46
+  public static class Pinyin
47
+  {
48
+    /// <summary>
49
+    /// 取中文文本的拼音首字母
50
+    /// </summary>
51
+    /// <param name="text">编码为UTF8的文本</param>
52
+    /// <returns>返回中文对应的拼音首字母</returns>
53
+ 
54
+    public static string GetInitials(string text)
55
+    {
56
+      text = text.Trim();
57
+      StringBuilder chars = new StringBuilder();
58
+      for (var i = 0; i < text.Length; ++i)
59
+      {
60
+        string py = GetPinyin(text[i]);
61
+        if (py != "") chars.Append(py[0]);
62
+      }
63
+
64
+      return chars.ToString().ToUpper();
65
+    }
66
+
67
+
68
+    /// <summary>
69
+    /// 取中文文本的拼音首字母
70
+    /// </summary>
71
+    /// <param name="text">文本</param>
72
+    /// <param name="encoding">源文本的编码</param>
73
+    /// <returns>返回encoding编码类型中文对应的拼音首字母</returns>
74
+    public static string GetInitials(string text, Encoding encoding)
75
+    {
76
+      string temp = ConvertEncoding(text, encoding, Encoding.UTF8);
77
+      return ConvertEncoding(GetInitials(temp), Encoding.UTF8, encoding);
78
+    }
79
+
80
+
81
+
82
+    /// <summary>
83
+    /// 取中文文本的拼音
84
+    /// </summary>
85
+    /// <param name="text">编码为UTF8的文本</param>
86
+    /// <returns>返回中文文本的拼音</returns>
87
+ 
88
+    public static string GetPinyin(string text)
89
+    {
90
+      StringBuilder sbPinyin = new StringBuilder();
91
+      for (var i = 0; i < text.Length; ++i)
92
+      {
93
+        string py = GetPinyin(text[i]);
94
+        if (py != "") sbPinyin.Append(py);
95
+        //sbPinyin.Append(" ");
96
+      }
97
+
98
+      return sbPinyin.ToString().Trim();
99
+    }
100
+
101
+    /// <summary>
102
+    /// 取中文文本的拼音
103
+    /// </summary>
104
+    /// <param name="text">编码为UTF8的文本</param>
105
+    /// <param name="encoding">源文本的编码</param>
106
+    /// <returns>返回encoding编码类型的中文文本的拼音</returns>
107
+    public static string GetPinyin(string text, Encoding encoding)
108
+    {
109
+      string temp = ConvertEncoding(text.Trim(), encoding, Encoding.UTF8);
110
+      return ConvertEncoding(GetPinyin(temp), Encoding.UTF8, encoding);
111
+    }
112
+
113
+    /// <summary>
114
+    /// 取和拼音相同的汉字列表
115
+    /// </summary>
116
+    /// <param name="Pinyin">编码为UTF8的拼音</param>
117
+    /// <returns>取拼音相同的汉字列表,如拼音“ai”将会返回“唉爱……”等</returns>
118
+    public static string GetChineseText(string pinyin)
119
+    {
120
+      string key = pinyin.Trim().ToLower();
121
+
122
+      foreach (string str in PyCode.codes)
123
+      {
124
+        if (str.StartsWith(key + " ") || str.StartsWith(key + ":"))
125
+         return str.Substring(7);
126
+      }
127
+
128
+      return "";
129
+    }
130
+
131
+
132
+    /// <summary>
133
+    /// 取和拼音相同的汉字列表,编码同参数encoding
134
+    /// </summary>
135
+    /// <param name="Pinyin">编码为encoding的拼音</param>
136
+    /// <param name="encoding">编码</param>
137
+    /// <returns>返回编码为encoding的拼音为pinyin的汉字列表,如拼音“ai”将会返回“唉爱……”等</returns>
138
+    public static string GetChineseText(string pinyin, Encoding encoding)
139
+    {
140
+      string text = ConvertEncoding(pinyin, encoding, Encoding.UTF8);
141
+      return ConvertEncoding(GetChineseText(text), Encoding.UTF8, encoding);
142
+    }
143
+
144
+
145
+
146
+    /// <summary>
147
+    /// 返回单个字符的汉字拼音
148
+    /// </summary>
149
+    /// <param name="ch">编码为UTF8的中文字符</param>
150
+    /// <returns>ch对应的拼音</returns>
151
+    public static string GetPinyin(char ch)
152
+    {
153
+      short hash = GetHashIndex(ch);
154
+      for (var i = 0; i < PyHash.hashes[hash].Length; ++i)
155
+      {
156
+        short index = PyHash.hashes[hash][i];
157
+        var pos = PyCode.codes[index].IndexOf(ch, 7);
158
+        if (pos != -1)
159
+          return PyCode.codes[index].Substring(0, 6).Trim();
160
+      }
161
+      return ch.ToString();
162
+    }
163
+
164
+    /// <summary>
165
+    /// 返回单个字符的汉字拼音
166
+    /// </summary>
167
+    /// <param name="ch">编码为encoding的中文字符</param>
168
+    /// <returns>编码为encoding的ch对应的拼音</returns>
169
+    public static string GetPinyin(char ch, Encoding encoding)
170
+    {
171
+      ch = ConvertEncoding(ch.ToString(), encoding, Encoding.UTF8)[0];
172
+      return ConvertEncoding(GetPinyin(ch), Encoding.UTF8, encoding);
173
+    }
174
+
175
+    /// <summary>
176
+    /// 转换编码 
177
+    /// </summary>
178
+    /// <param name="text">文本</param>
179
+    /// <param name="srcEncoding">源编码</param>
180
+    /// <param name="dstEncoding">目标编码</param>
181
+    /// <returns>目标编码文本</returns>
182
+    public static string ConvertEncoding(string text, Encoding srcEncoding,  Encoding dstEncoding)
183
+    {
184
+      byte[] srcBytes = srcEncoding.GetBytes(text);
185
+      byte[] dstBytes = Encoding.Convert(srcEncoding, dstEncoding, srcBytes);
186
+      return dstEncoding.GetString(dstBytes);
187
+    }
188
+
189
+    /// <summary>
190
+    /// 取文本索引值
191
+    /// </summary>
192
+    /// <param name="ch">字符</param>
193
+    /// <returns>文本索引值</returns>
194
+    private static short GetHashIndex(char ch)
195
+    {
196
+      return (short)((uint)ch % PyCode.codes.Length);
197
+    }
198
+  }
199
+}

+ 105
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/Pinyin.ts 查看文件

@@ -0,0 +1,105 @@
1
+// 模拟 PyCode 和 PyHash 类
2
+class PyCode {
3
+    static codes: string[] = []; // 需根据实际情况填充数据
4
+}
5
+
6
+class PyHash {
7
+    static hashes: number[][]= []; // 需根据实际情况填充数据
8
+}
9
+
10
+// 模拟 Encoding 类
11
+class Encoding {
12
+    static UTF8 = new Encoding();
13
+    static Convert(srcEncoding: Encoding, dstEncoding: Encoding, srcBytes: number[]): number[] {
14
+        // 简单模拟,实际需实现编码转换逻辑
15
+        return srcBytes;
16
+    }
17
+    getBytes(text: string): number[] {
18
+        // 简单模拟,实际需实现编码转换逻辑
19
+        return Array.from(text).map(c => c.charCodeAt(0));
20
+    }
21
+    getString(bytes: number[]): string {
22
+        // 简单模拟,实际需实现编码转换逻辑
23
+        return String.fromCharCode(...bytes);
24
+    }
25
+}
26
+
27
+class Pinyin {
28
+    static ConvertEncoding(text: string, srcEncoding: Encoding, dstEncoding: Encoding): string {
29
+        const srcBytes = srcEncoding.getBytes(text);
30
+        const dstBytes = Encoding.Convert(srcEncoding, dstEncoding, srcBytes);
31
+        return dstEncoding.getString(dstBytes);
32
+    }
33
+
34
+    static GetHashIndex(ch: string): number {
35
+        const code = ch.charCodeAt(0);
36
+        return code % PyCode.codes.length;
37
+    }
38
+
39
+    static GetPinyin(ch: string, encoding?: Encoding): string {
40
+        if (encoding) {
41
+            const utf8Ch = this.ConvertEncoding(ch, encoding, Encoding.UTF8);
42
+            const pinyin = this.GetPinyin(utf8Ch);
43
+            return this.ConvertEncoding(pinyin, Encoding.UTF8, encoding);
44
+        }
45
+        const hash = this.GetHashIndex(ch);
46
+        for (let i = 0; i < PyHash.hashes[hash].length; i++) {
47
+            const index = PyHash.hashes[hash][i];
48
+            const pos = PyCode.codes[index].indexOf(ch, 7);
49
+            if (pos !== -1) {
50
+                return PyCode.codes[index].substring(0, 6).trim();
51
+            }
52
+        }
53
+        return ch;
54
+    }
55
+
56
+    static GetInitials(text: string, encoding?: Encoding): string {
57
+        if (encoding) {
58
+            const utf8Text = this.ConvertEncoding(text, encoding, Encoding.UTF8);
59
+            const initials = this.GetInitials(utf8Text);
60
+            return this.ConvertEncoding(initials, Encoding.UTF8, encoding);
61
+        }
62
+        text = text.trim();
63
+        let result = '';
64
+        for (let i = 0; i < text.length; i++) {
65
+            const py = this.GetPinyin(text[i]);
66
+            if (py) {
67
+                result += py[0];
68
+            }
69
+        }
70
+        return result.toUpperCase();
71
+    }
72
+
73
+    static GetPinyinText(text: string, encoding?: Encoding): string {
74
+        if (encoding) {
75
+            const utf8Text = this.ConvertEncoding(text, encoding, Encoding.UTF8);
76
+            const pinyin = this.GetPinyinText(utf8Text);
77
+            return this.ConvertEncoding(pinyin, Encoding.UTF8, encoding);
78
+        }
79
+        let result = '';
80
+        for (let i = 0; i < text.length; i++) {
81
+            const py = this.GetPinyin(text[i]);
82
+            if (py) {
83
+                result += py;
84
+            }
85
+        }
86
+        return result.trim();
87
+    }
88
+
89
+    static GetChineseText(pinyin: string, encoding?: Encoding): string {
90
+        if (encoding) {
91
+            const utf8Pinyin = this.ConvertEncoding(pinyin, encoding, Encoding.UTF8);
92
+            const chineseText = this.GetChineseText(utf8Pinyin);
93
+            return this.ConvertEncoding(chineseText, Encoding.UTF8, encoding);
94
+        }
95
+        pinyin = pinyin.trim().toLowerCase();
96
+        for (const str of PyCode.codes) {
97
+            if (str.startsWith(pinyin + ' ') || str.startsWith(pinyin + ':')) {
98
+                return str.substring(7);
99
+            }
100
+        }
101
+        return '';
102
+    }
103
+}
104
+
105
+export { Pinyin };

+ 68
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ProvinceCityCountyManager.cs 查看文件

@@ -0,0 +1,68 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Xml;
6
+using System.IO;
7
+
8
+namespace TellerSystem.Library.Ext.TradeExtension
9
+{
10
+    /// <summary>
11
+    /// 省市区信息管理类
12
+    /// </summary>
13
+    public class ProvinceCityCountyManager
14
+    {
15
+        /// <summary>
16
+        /// 
17
+        /// </summary>
18
+        public ProvinceCityCountyManager()
19
+        {
20
+            _provinces = new List<Province>();
21
+        }
22
+        private static ProvinceCityCountyManager _instance;
23
+        /// <summary>
24
+        /// 
25
+        /// </summary>
26
+        public static ProvinceCityCountyManager Instance
27
+        {
28
+            get
29
+            {
30
+                if (_instance == null)
31
+                    _instance = new ProvinceCityCountyManager();
32
+                return _instance;
33
+            }
34
+        }
35
+        private List<Province> _provinces;
36
+
37
+        public List<Province> GetProvinces()
38
+        {
39
+            if (_provinces != null && _provinces.Count > 0)
40
+                return _provinces;
41
+            else
42
+            {
43
+                if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(new System.Windows.DependencyObject()))
44
+                    return new List<Province>();
45
+                List<Province> provinces = new List<Province>();
46
+                XmlDocument doc = new XmlDocument();
47
+                doc.Load(@"Config/PCC.xml");
48
+                foreach (XmlNode item in doc.SelectNodes("/Root/Province"))
49
+                {
50
+                    Province p = new Province { Value = item.Attributes["Code"].Value.ToString(), Key = item.Attributes["Text"].Value.ToString(), Child = new List<City>() };
51
+                    foreach (XmlNode item1 in item.SelectNodes("City"))
52
+                    {
53
+                        City c = new City { Value = item1.Attributes["Code"].Value.ToString(), Key = item1.Attributes["Text"].Value.ToString(), Child = new List<County>() };
54
+                        foreach (XmlNode item2 in item1.SelectNodes("County"))
55
+                        {
56
+                            c.Child.Add(new County { Value = item2.Attributes["Code"].Value.ToString(), Key = item2.Attributes["Text"].Value.ToString() });
57
+                        }
58
+                        p.Child.Add(c);
59
+                    }
60
+                    provinces.Add(p);
61
+                }
62
+                if (provinces != null && provinces.Count > 0)
63
+                    _provinces = provinces;
64
+                return provinces;
65
+            }
66
+        }
67
+    }
68
+}

+ 95
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ProvinceCityCountyManager.ts 查看文件

@@ -0,0 +1,95 @@
1
+// 定义 Province、City 和 County 类
2
+class County {
3
+    constructor(public Value: string, public Key: string) {}
4
+}
5
+
6
+class City {
7
+    Child: County[];
8
+    constructor(public Value: string, public Key: string) {
9
+        this.Child = [];
10
+    }
11
+}
12
+
13
+class Province {
14
+    Child: City[];
15
+    constructor(public Value: string, public Key: string) {
16
+        this.Child = [];
17
+    }
18
+}
19
+
20
+// 模拟 DesignerProperties 类
21
+class DesignerProperties {
22
+    static GetIsInDesignMode(_: any): boolean {
23
+        return false;
24
+    }
25
+}
26
+
27
+// 定义 ProvinceCityCountyManager 类
28
+class ProvinceCityCountyManager {
29
+    private static _instance: ProvinceCityCountyManager;
30
+    private _provinces: Province[];
31
+
32
+    private constructor() {
33
+        this._provinces = [];
34
+    }
35
+
36
+    static get Instance(): ProvinceCityCountyManager {
37
+        if (!this._instance) {
38
+            this._instance = new ProvinceCityCountyManager();
39
+        }
40
+        return this._instance;
41
+    }
42
+
43
+    async GetProvinces(): Promise<Province[]> {
44
+        if (this._provinces.length > 0) {
45
+            return this._provinces;
46
+        }
47
+
48
+        if (DesignerProperties.GetIsInDesignMode({})) {
49
+            return [];
50
+        }
51
+
52
+        try {
53
+            const response = await fetch('Config/PCC.xml');
54
+            const xmlText = await response.text();
55
+            const parser = new DOMParser();
56
+            const doc = parser.parseFromString(xmlText, 'text/xml');
57
+
58
+            const provinceNodes = doc.querySelectorAll('/Root/Province');
59
+            const provinces: Province[] = [];
60
+
61
+            provinceNodes.forEach((provinceNode) => {
62
+                const provinceCode = provinceNode.getAttribute('Code') || '';
63
+                const provinceText = provinceNode.getAttribute('Text') || '';
64
+                const province = new Province(provinceCode, provinceText);
65
+
66
+                const cityNodes = provinceNode.querySelectorAll('City');
67
+                cityNodes.forEach((cityNode) => {
68
+                    const cityCode = cityNode.getAttribute('Code') || '';
69
+                    const cityText = cityNode.getAttribute('Text') || '';
70
+                    const city = new City(cityCode, cityText);
71
+
72
+                    const countyNodes = cityNode.querySelectorAll('County');
73
+                    countyNodes.forEach((countyNode) => {
74
+                        const countyCode = countyNode.getAttribute('Code') || '';
75
+                        const countyText = countyNode.getAttribute('Text') || '';
76
+                        const county = new County(countyCode, countyText);
77
+                        city.Child.push(county);
78
+                    });
79
+
80
+                    province.Child.push(city);
81
+                });
82
+
83
+                provinces.push(province);
84
+            });
85
+
86
+            this._provinces = provinces;
87
+            return provinces;
88
+        } catch (error) {
89
+            console.error('加载省市区数据时出错:', error);
90
+            return [];
91
+        }
92
+    }
93
+}
94
+
95
+export default ProvinceCityCountyManager;

+ 410
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/PyCode.cs 查看文件

@@ -0,0 +1,410 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Text;
4
+
5
+namespace NPinyin
6
+{
7
+  internal class PyCode
8
+  {
9
+    internal static string[] codes = new string[]{
10
+"a     :阿啊吖嗄腌锕",
11
+"ai    :爱埃碍矮挨唉哎哀皑癌蔼艾隘捱嗳嗌嫒瑷暧砹锿霭",
12
+"an    :安按暗岸案俺氨胺鞍谙埯揞犴庵桉铵鹌黯",
13
+"ang   :昂肮盎",
14
+"ao    :凹奥敖熬翱袄傲懊澳坳拗嗷岙廒遨媪骜獒聱螯鏊鳌鏖",
15
+"ba    :把八吧巴拔霸罢爸坝芭捌扒叭笆疤跋靶耙茇菝岜灞钯粑鲅魃",
16
+"bai   :百白败摆柏佰拜稗捭掰",
17
+"ban   :办半板班般版拌搬斑扳伴颁扮瓣绊阪坂钣瘢癍舨",
18
+"bang  :帮棒邦榜梆膀绑磅蚌镑傍谤蒡浜",
19
+"bao   :报保包剥薄胞暴宝饱抱爆堡苞褒雹豹鲍葆孢煲鸨褓趵龅",
20
+"bei   :北被倍备背辈贝杯卑悲碑钡狈惫焙孛陂邶埤萆蓓呗悖碚鹎褙鐾鞴",
21
+"ben   :本奔苯笨畚坌贲锛",
22
+"beng  :泵崩绷甭蹦迸嘣甏",
23
+"bi    :比必避闭辟笔壁臂毕彼逼币鼻蔽鄙碧蓖毙毖庇痹敝弊陛匕俾荜荸薜吡哔狴庳愎滗濞弼妣婢嬖璧畀铋秕裨筚箅篦舭襞跸髀",
24
+"bian  :变边便编遍辩扁辨鞭贬卞辫匾弁苄忭汴缏飚煸砭碥窆褊蝙笾鳊",
25
+"biao  :表标彪膘婊骠杓飑飙镖镳瘭裱鳔髟",
26
+"bie   :别鳖憋瘪蹩",
27
+"bin   :宾彬斌濒滨摈傧豳缤玢槟殡膑镔髌鬓",
28
+"bing  :并病兵柄冰丙饼秉炳禀邴摒",
29
+"bo    :波播伯拨博勃驳玻泊菠钵搏铂箔帛舶脖膊渤亳啵饽檗擘礴钹鹁簸跛踣",
30
+"bu    :不部步布补捕卜哺埠簿怖卟逋瓿晡钚钸醭",
31
+"ca    :擦嚓礤",
32
+"cai   :采才材菜财裁彩猜睬踩蔡",
33
+"can   :参残蚕灿餐惭惨孱骖璨粲黪",
34
+"cang  :藏仓苍舱沧",
35
+"cao   :草槽操糙曹嘈漕螬艚",
36
+"ce    :测策侧册厕恻",
37
+"cen   :岑涔",
38
+"ceng  :层蹭",
39
+"cha   :查差插察茶叉茬碴搽岔诧猹馇汊姹杈楂槎檫锸镲衩",
40
+"chai  :柴拆豺侪钗瘥虿",
41
+"chan  :产铲阐搀掺蝉馋谗缠颤冁谄蒇廛忏潺澶羼婵骣觇禅镡蟾躔",
42
+"chang :长常场厂唱肠昌倡偿畅猖尝敞伥鬯苌菖徜怅惝阊娼嫦昶氅鲳",
43
+"chao  :朝超潮巢抄钞嘲吵炒怊晁耖",
44
+"che   :车彻撤扯掣澈坼砗",
45
+"chen  :陈沉称衬尘臣晨郴辰忱趁伧谌谶抻嗔宸琛榇碜龀",
46
+"cheng :成程称城承乘呈撑诚橙惩澄逞骋秤丞埕噌枨柽塍瞠铖铛裎蛏酲",
47
+"chi   :持尺齿吃赤池迟翅斥耻痴匙弛驰侈炽傺坻墀茌叱哧啻嗤彳饬媸敕眵鸱瘛褫蚩螭笞篪豉踟魑",
48
+"chong :虫充冲崇宠茺忡憧铳舂艟",
49
+"chou  :抽仇臭酬畴踌稠愁筹绸瞅丑俦帱惆瘳雠",
50
+"chu   :出处除初础触楚锄储橱厨躇雏滁矗搐亍刍怵憷绌杵楮樗褚蜍蹰黜",
51
+"chuai :揣搋啜膪踹",
52
+"chuan :传船穿串川椽喘舛遄巛氚钏舡",
53
+"chuang:床创窗闯疮幢怆",
54
+"chui  :吹垂锤炊捶陲棰槌",
55
+"chun  :春纯醇椿唇淳蠢莼鹑蝽",
56
+"chuo  :戳绰辍踔龊",
57
+"ci    :此次刺磁雌词茨疵辞慈瓷赐茈呲祠鹚糍",
58
+"cong  :从丛聪葱囱匆苁淙骢琮璁",
59
+"cou   :凑楱辏腠",
60
+"cu    :粗促醋簇蔟徂猝殂酢蹙蹴",
61
+"cuan  :篡蹿窜汆撺爨镩",
62
+"cui   :催脆淬粹摧崔瘁翠萃啐悴璀榱毳隹",
63
+"cun   :存村寸忖皴",
64
+"cuo   :错措撮磋搓挫厝嵯脞锉矬痤鹾蹉",
65
+"da    :大打达答搭瘩耷哒嗒怛妲疸褡笪靼鞑",
66
+"dai   :代带待袋戴呆歹傣殆贷逮怠埭甙呔岱迨骀绐玳黛",
67
+"dan   :单但弹担蛋淡胆氮丹旦耽郸掸惮诞儋萏啖殚赕眈疸瘅聃箪",
68
+"dang  :党当档挡荡谠凼菪宕砀裆",
69
+"dao   :到道导刀倒稻岛捣盗蹈祷悼叨忉氘纛",
70
+"de    :的得德锝",
71
+"deng  :等灯登邓蹬瞪凳噔嶝戥磴镫簦",
72
+"di    :地第低敌底帝抵滴弟递堤迪笛狄涤翟嫡蒂缔氐籴诋谛邸荻嘀娣绨柢棣觌砥碲睇镝羝骶",
73
+"dia   :嗲",
74
+"dian  :电点垫典店颠淀掂滇碘靛佃甸惦奠殿阽坫巅玷钿癜癫簟踮",
75
+"diao  :调掉吊碉叼雕凋刁钓铞铫貂鲷",
76
+"die   :迭跌爹碟蝶谍叠垤堞揲喋牒瓞耋蹀鲽",
77
+"ding  :定顶钉丁订盯叮鼎锭仃啶玎腚碇町疔耵酊",
78
+"diu   :丢铥",
79
+"dong  :动东冬懂洞冻董栋侗恫垌咚岽峒氡胨胴硐鸫",
80
+"dou   :斗豆兜抖陡逗痘蔸窦蚪篼",
81
+"du    :度都毒独读渡杜堵镀顿督犊睹赌肚妒芏嘟渎椟牍蠹笃髑黩",
82
+"duan  :断端段短锻缎椴煅簖",
83
+"dui   :对队堆兑怼憝碓",
84
+"dun   :盾吨顿蹲敦墩囤钝遁沌炖砘礅盹镦趸",
85
+"duo   :多夺朵掇哆垛躲跺舵剁惰堕咄哚沲缍柁铎裰踱",
86
+"e     :而二尔儿恶额恩俄耳饵蛾饿峨鹅讹娥厄扼遏鄂噩谔垩苊莪萼呃愕屙婀轭腭锇锷鹗颚鳄",
87
+"ei    :诶",
88
+"en    :恩蒽摁",
89
+"er    :而二尔儿耳饵洱贰佴迩珥铒鸸鲕",
90
+"fa    :发法阀乏伐罚筏珐垡砝",
91
+"fan   :反翻范犯饭繁泛番凡烦返藩帆樊矾钒贩蕃蘩幡梵燔畈蹯",
92
+"fang  :方放防访房纺仿妨芳肪坊邡枋钫舫鲂",
93
+"fei   :非肥飞费废肺沸菲匪啡诽吠芾狒悱淝妃绯榧腓斐扉镄痱蜚篚翡霏鲱",
94
+"fen   :分粉奋份粪纷芬愤酚吩氛坟焚汾忿偾瀵棼鲼鼢",
95
+"feng  :风封蜂丰缝峰锋疯奉枫烽逢冯讽凤俸酆葑唪沣砜",
96
+"fou   :否缶",
97
+"fu    :复服副府夫负富附福伏符幅腐浮辅付腹妇孵覆扶辐傅佛缚父弗甫肤氟敷拂俘涪袱抚俯釜斧脯腑赴赋阜讣咐匐凫郛芙苻茯莩菔拊呋幞怫滏艴孚驸绂绋桴赙祓砩黻黼罘稃馥蚨蜉蝠蝮麸趺跗鲋鳆",
98
+"ga    :噶嘎尬尕尜旮钆",
99
+"gai   :改该盖概钙溉丐陔垓戤赅",
100
+"gan   :干杆感敢赶甘肝秆柑竿赣坩苷尴擀泔淦澉绀橄旰矸疳酐",
101
+"gang  :刚钢缸纲岗港杠冈肛戆罡筻",
102
+"gao   :高搞告稿膏篙皋羔糕镐睾诰郜藁缟槔槁杲锆",
103
+"ge    :个各革格割歌隔哥铬阁戈葛搁鸽胳疙蛤鬲仡哿圪塥嗝搿膈硌镉袼虼舸骼",
104
+"gen   :根跟亘茛哏艮",
105
+"geng  :更耕颈庚羹埂耿梗哽赓绠鲠",
106
+"gong  :工公共供功攻巩贡汞宫恭龚躬弓拱珙肱蚣觥",
107
+"gou   :够构沟狗钩勾购苟垢佝诟岣遘媾缑枸觏彀笱篝鞲",
108
+"gu    :鼓固古骨故顾股谷估雇孤姑辜菇咕箍沽蛊嘏诂菰崮汩梏轱牯牿臌毂瞽罟钴锢鸪痼蛄酤觚鲴鹘",
109
+"gua   :挂刮瓜剐寡褂卦诖呱栝胍鸹",
110
+"guai  :怪乖拐",
111
+"guan  :关管观官灌贯惯冠馆罐棺倌莞掼涫盥鹳矜鳏",
112
+"guang :光广逛咣犷桄胱",
113
+"gui   :规贵归硅鬼轨龟桂瑰圭闺诡癸柜跪刽匦刿庋宄妫桧炅晷皈簋鲑鳜",
114
+"gun   :滚辊棍衮绲磙鲧",
115
+"guo   :国过果锅郭裹馘埚掴呙帼崞猓椁虢聒蜾蝈",
116
+"ha    :哈铪",
117
+"hai   :还海害孩骸氦亥骇嗨胲醢",
118
+"han   :含焊旱喊汉寒汗函韩酣憨邯涵罕翰撼捍憾悍邗菡撖阚瀚晗焓顸颔蚶鼾",
119
+"hang  :航夯杭沆绗珩颃",
120
+"hao   :好号毫耗豪郝浩壕嚎蒿薅嗥嚆濠灏昊皓颢蚝",
121
+"he    :和合河何核赫荷褐喝贺呵禾盒菏貉阂涸鹤诃劾壑嗬阖纥曷盍颌蚵翮",
122
+"hei   :黑嘿",
123
+"hen   :很狠痕恨",
124
+"heng  :横衡恒哼亨蘅桁",
125
+"hong  :红洪轰烘哄虹鸿宏弘黉訇讧荭蕻薨闳泓",
126
+"hou   :后候厚侯喉猴吼堠後逅瘊篌糇鲎骺",
127
+"hu    :护互湖呼户弧乎胡糊虎忽瑚壶葫蝴狐唬沪冱唿囫岵猢怙惚浒滹琥槲轷觳烀煳戽扈祜瓠鹄鹕鹱笏醐斛",
128
+"hua   :化花话划滑华画哗猾骅桦砉铧",
129
+"huai  :坏怀淮槐徊踝",
130
+"huan  :环换欢缓患幻焕桓唤痪豢涣宦郇奂萑擐圜獾洹浣漶寰逭缳锾鲩鬟",
131
+"huang :黄簧荒皇慌蝗磺凰惶煌晃幌恍谎隍徨湟潢遑璜肓癀蟥篁鳇",
132
+"hui   :会回灰挥辉汇毁慧恢绘惠徽蛔悔卉晦贿秽烩讳诲诙茴荟蕙咴哕喙隳洄浍彗缋珲晖恚虺蟪麾",
133
+"hun   :混浑荤昏婚魂诨馄阍溷",
134
+"huo   :活或火货获伙霍豁惑祸劐藿攉嚯夥钬锪镬耠蠖",
135
+"ji    :级及机极几积给基记己计集即际季激济技击继急剂既纪寄挤鸡迹绩吉脊辑籍疾肌棘畸圾稽箕饥讥姬缉汲嫉蓟冀伎祭悸寂忌妓藉丌亟乩剞佶偈诘墼芨芰荠蒺蕺掎叽咭哜唧岌嵴洎屐骥畿玑楫殛戟戢赍觊犄齑矶羁嵇稷瘠虮笈笄暨跻跽霁鲚鲫髻麂",
136
+"jia   :加家架价甲夹假钾贾稼驾嘉枷佳荚颊嫁伽郏葭岬浃迦珈戛胛恝铗镓痂瘕袷蛱笳袈跏",
137
+"jian  :间件见建坚减检践尖简碱剪艰渐肩键健柬鉴剑歼监兼奸箭茧舰俭笺煎缄硷拣捡荐槛贱饯溅涧僭谏谫菅蒹搛湔蹇謇缣枧楗戋戬牮犍毽腱睑锏鹣裥笕翦趼踺鲣鞯",
138
+"jiang :将降讲江浆蒋奖疆僵姜桨匠酱茳洚绛缰犟礓耩糨豇",
139
+"jiao  :较教交角叫脚胶浇焦搅酵郊铰窖椒礁骄娇嚼矫侥狡饺缴绞剿轿佼僬艽茭挢噍峤徼姣敫皎鹪蛟醮跤鲛",
140
+"jie   :结阶解接节界截介借届街揭洁杰竭皆秸劫桔捷睫姐戒藉芥疥诫讦拮喈嗟婕孑桀碣疖颉蚧羯鲒骱",
141
+"jin   :进金近紧斤今尽仅劲浸禁津筋锦晋巾襟谨靳烬卺荩堇噤馑廑妗缙瑾槿赆觐衿",
142
+"jing  :经精京径井静竟晶净境镜景警茎敬惊睛竞荆兢鲸粳痉靖刭儆阱菁獍憬泾迳弪婧肼胫腈旌",
143
+"jiong :炯窘迥扃",
144
+"jiu   :就九旧究久救酒纠揪玖韭灸厩臼舅咎疚僦啾阄柩桕鸠鹫赳鬏",
145
+"ju    :具据局举句聚距巨居锯剧矩拒鞠拘狙疽驹菊咀沮踞俱惧炬倨讵苣苴莒掬遽屦琚椐榘榉橘犋飓钜锔窭裾趄醵踽龃雎鞫",
146
+"juan  :卷捐鹃娟倦眷绢鄄狷涓桊蠲锩镌隽",
147
+"jue   :决觉绝掘撅攫抉倔爵诀厥劂谲矍蕨噘噱崛獗孓珏桷橛爝镢蹶觖",
148
+"jun   :军均菌君钧峻俊竣浚郡骏捃皲筠麇",
149
+"ka    :卡喀咖咯佧咔胩",
150
+"kai   :开凯揩楷慨剀垲蒈忾恺铠锎锴",
151
+"kan   :看刊坎堪勘砍侃莰戡龛瞰",
152
+"kang  :抗康炕慷糠扛亢伉闶钪",
153
+"kao   :考靠拷烤尻栲犒铐",
154
+"ke    :可克科刻客壳颗棵柯坷苛磕咳渴课嗑岢恪溘骒缂珂轲氪瞌钶锞稞疴窠颏蝌髁",
155
+"ken   :肯啃垦恳裉",
156
+"keng  :坑吭铿",
157
+"kong  :孔空控恐倥崆箜",
158
+"kou   :口扣抠寇芤蔻叩眍筘",
159
+"ku    :苦库枯酷哭窟裤刳堀喾绔骷",
160
+"kua   :跨夸垮挎胯侉",
161
+"kuai  :快块筷侩蒯郐哙狯脍",
162
+"kuan  :宽款髋",
163
+"kuang :况矿狂框匡筐眶旷诓诳邝圹夼哐纩贶",
164
+"kui   :奎溃馈亏盔岿窥葵魁傀愧馗匮夔隗蒉揆喹喟悝愦逵暌睽聩蝰篑跬",
165
+"kun   :困昆坤捆悃阃琨锟醌鲲髡",
166
+"kuo   :扩括阔廓蛞",
167
+"la    :拉啦蜡腊蓝垃喇辣剌邋旯砬瘌",
168
+"lai   :来赖莱崃徕涞濑赉睐铼癞籁",
169
+"lan   :兰烂蓝览栏婪拦篮阑澜谰揽懒缆滥岚漤榄斓罱镧褴",
170
+"lang  :浪朗郎狼琅榔廊莨蒗啷阆锒稂螂",
171
+"lao   :老劳牢涝捞佬姥酪烙唠崂栳铑铹痨耢醪",
172
+"le    :了乐勒肋仂叻泐鳓",
173
+"lei   :类雷累垒泪镭蕾磊儡擂肋羸诔嘞嫘缧檑耒酹",
174
+"leng  :冷棱楞塄愣",
175
+"li    :理里利力立离例历粒厘礼李隶黎璃励犁梨丽厉篱狸漓鲤莉荔吏栗砾傈俐痢沥哩俪俚郦坜苈莅蓠藜呖唳喱猁溧澧逦娌嫠骊缡枥栎轹戾砺詈罹锂鹂疠疬蛎蜊蠡笠篥粝醴跞雳鲡鳢黧",
176
+"lia   :俩",
177
+"lian  :连联练炼脸链莲镰廉怜涟帘敛恋蔹奁潋濂琏楝殓臁裢裣蠊鲢",
178
+"liang :量两粮良亮梁凉辆粱晾谅墚椋踉靓魉",
179
+"liao  :料疗辽僚撩聊燎寥潦撂镣廖蓼尥嘹獠寮缭钌鹩",
180
+"lie   :列裂烈劣猎冽埒捩咧洌趔躐鬣",
181
+"lin   :林磷临邻淋麟琳霖鳞凛赁吝蔺啉嶙廪懔遴檩辚膦瞵粼躏",
182
+"ling  :领另零令灵岭铃龄凌陵拎玲菱伶羚酃苓呤囹泠绫柃棂瓴聆蛉翎鲮",
183
+"liu   :流六留刘硫柳馏瘤溜琉榴浏遛骝绺旒熘锍镏鹨鎏",
184
+"long  :龙垄笼隆聋咙窿拢陇垅茏泷珑栊胧砻癃",
185
+"lou   :漏楼娄搂篓陋偻蒌喽嵝镂瘘耧蝼髅",
186
+"lu    :路率露绿炉律虑滤陆氯鲁铝录旅卢吕芦颅庐掳卤虏麓碌赂鹿潞禄戮驴侣履屡缕垆撸噜闾泸渌漉逯璐栌榈橹轳辂辘氇胪膂镥稆鸬鹭褛簏舻鲈",
187
+"luan  :卵乱峦挛孪滦脔娈栾鸾銮",
188
+"lue   :略掠锊",
189
+"lun   :论轮伦抡仑沦纶囵",
190
+"luo   :落罗螺洛络逻萝锣箩骡裸骆倮蠃荦捋摞猡泺漯珞椤脶镙瘰雒",
191
+"m     :呒",
192
+"ma    :马麻吗妈骂嘛码玛蚂唛犸嬷杩蟆",
193
+"mai   :麦脉卖买埋迈劢荬霾",
194
+"man   :满慢曼漫蔓瞒馒蛮谩墁幔缦熳镘颟螨鳗鞔",
195
+"mang  :忙芒盲茫氓莽邙漭硭蟒",
196
+"mao   :毛矛冒貌贸帽猫茅锚铆卯茂袤茆峁泖瑁昴牦耄旄懋瞀蟊髦",
197
+"me    :么麽",
198
+"mei   :没每美煤霉酶梅妹眉玫枚媒镁昧寐媚莓嵋猸浼湄楣镅鹛袂魅",
199
+"men   :们门闷扪焖懑钔",
200
+"meng  :孟猛蒙盟梦萌锰檬勐甍瞢懵朦礞虻蜢蠓艋艨",
201
+"mi    :米密迷蜜秘眯醚靡糜谜弥觅泌幂芈谧蘼咪嘧猕汨宓弭脒祢敉糸縻麋",
202
+"mian  :面棉免绵眠冕勉娩缅沔渑湎腼眄",
203
+"miao  :苗秒描庙妙瞄藐渺喵邈缈缪杪淼眇鹋",
204
+"mie   :灭蔑咩蠛篾",
205
+"min   :民敏抿皿悯闽苠岷闵泯缗玟珉愍黾鳘",
206
+"ming  :命明名鸣螟铭冥茗溟暝瞑酩",
207
+"miu   :谬",
208
+"mo    :磨末模膜摸墨摩莫抹默摹蘑魔沫漠寞陌谟茉蓦馍嫫殁镆秣瘼耱貊貘",
209
+"mou   :某谋牟侔哞眸蛑蝥鍪",
210
+"mu    :亩目木母墓幕牧姆穆拇牡暮募慕睦仫坶苜沐毪钼",
211
+"n     :嗯",
212
+"na    :那南哪拿纳钠呐娜捺肭镎衲",
213
+"nai   :耐奶乃氖奈鼐艿萘柰",
214
+"nan   :南难男喃囝囡楠腩蝻赧",
215
+"nang  :囊攮囔馕曩",
216
+"nao   :脑闹挠恼淖孬垴呶猱瑙硇铙蛲",
217
+"ne    :呢讷",
218
+"nei   :内馁",
219
+"nen   :嫩恁",
220
+"neng  :能",
221
+"ni    :你泥尼逆拟尿妮霓倪匿腻溺伲坭猊怩昵旎慝睨铌鲵",
222
+"nian  :年念粘蔫拈碾撵捻酿廿埝辇黏鲇鲶",
223
+"niang :娘",
224
+"niao  :尿鸟茑嬲脲袅",
225
+"nie   :镍啮涅捏聂孽镊乜陧蘖嗫颞臬蹑",
226
+"nin   :您",
227
+"ning  :宁凝拧柠狞泞佞苎咛甯聍",
228
+"niu   :牛扭钮纽狃忸妞",
229
+"nong  :农弄浓脓侬哝",
230
+"nou   :耨",
231
+"nu    :女奴努怒弩胬孥驽恧钕衄",
232
+"nuan  :暖",
233
+"nue   :虐",
234
+"nuo   :诺挪懦糯傩搦喏锘",
235
+"o     :欧偶哦鸥殴藕呕沤讴噢怄瓯耦",
236
+"ou    :欧偶鸥殴藕呕沤讴怄瓯耦",
237
+"pa    :怕派爬帕啪趴琶葩杷筢",
238
+"pai   :派排拍牌哌徘湃俳蒎",
239
+"pan   :判盘叛潘攀磐盼畔胖爿泮袢襻蟠蹒",
240
+"pang  :旁乓庞耪胖彷滂逄螃",
241
+"pao   :跑炮刨抛泡咆袍匏狍庖脬疱",
242
+"pei   :配培陪胚呸裴赔佩沛辔帔旆锫醅霈",
243
+"pen   :喷盆湓",
244
+"peng  :碰棚蓬朋捧膨砰抨烹澎彭硼篷鹏堋嘭怦蟛",
245
+"pi    :批皮坯脾疲砒霹披劈琵毗啤匹痞僻屁譬丕仳陴邳郫圮鼙芘擗噼庀淠媲纰枇甓睥罴铍癖疋蚍蜱貔",
246
+"pian  :片偏篇骗谝骈犏胼翩蹁",
247
+"piao  :票漂飘瓢剽嘌嫖缥殍瞟螵",
248
+"pie   :撇瞥丿苤氕",
249
+"pin   :品贫频拼苹聘拚姘嫔榀牝颦",
250
+"ping  :平评瓶凭苹乒坪萍屏俜娉枰鲆",
251
+"po    :破迫坡泼颇婆魄粕叵鄱珀攴钋钷皤笸",
252
+"pou   :剖裒掊",
253
+"pu    :普谱扑埔铺葡朴蒲仆莆菩圃浦曝瀑匍噗溥濮璞氆镤镨蹼",
254
+"qi    :起其气期七器齐奇汽企漆欺旗畦启弃歧栖戚妻凄柒沏棋崎脐祈祁骑岂乞契砌迄泣讫亓俟圻芑芪萁萋葺蕲嘁屺岐汔淇骐绮琪琦杞桤槭耆欹祺憩碛颀蛴蜞綦綮蹊鳍麒",
255
+"qia   :恰掐洽葜髂",
256
+"qian  :前千钱浅签迁铅潜牵钳谴扦钎仟谦乾黔遣堑嵌欠歉倩佥阡芊芡茜荨掮岍悭慊骞搴褰缱椠肷愆钤虔箬箝",
257
+"qiang :强枪抢墙腔呛羌蔷戕嫱樯戗炝锖锵镪襁蜣羟跄",
258
+"qiao  :桥瞧巧敲乔蕉橇锹悄侨鞘撬翘峭俏窍劁诮谯荞愀憔樵硗跷鞒",
259
+"qie   :切且茄怯窃郄惬妾挈锲箧",
260
+"qin   :亲侵勤秦钦琴芹擒禽寝沁芩揿吣嗪噙溱檎锓覃螓衾",
261
+"qing  :情清青轻倾请庆氢晴卿擎氰顷苘圊檠磬蜻罄箐謦鲭黥",
262
+"qiong :穷琼邛茕穹蛩筇跫銎",
263
+"qiu   :求球秋丘邱囚酋泅俅巯犰湫逑遒楸赇虬蚯蝤裘糗鳅鼽",
264
+"qu    :去区取曲渠屈趋驱趣蛆躯娶龋诎劬蕖蘧岖衢阒璩觑氍朐祛磲鸲癯蛐蠼麴瞿黢",
265
+"quan  :全权圈劝泉醛颧痊拳犬券诠荃悛绻辁畎铨蜷筌鬈",
266
+"que   :确却缺炔瘸鹊榷雀阕阙悫",
267
+"qun   :群裙逡",
268
+"ran   :然燃染冉苒蚺髯",
269
+"rang  :让壤嚷瓤攘禳穰",
270
+"rao   :绕扰饶荛娆桡",
271
+"re    :热惹",
272
+"ren   :人认任仁刃忍壬韧妊纫仞荏葚饪轫稔衽",
273
+"reng  :仍扔",
274
+"ri    :日",
275
+"rong  :容溶荣熔融绒戎茸蓉冗嵘狨榕肜蝾",
276
+"rou   :肉揉柔糅蹂鞣",
277
+"ru    :如入儒乳茹蠕孺辱汝褥蓐薷嚅洳溽濡缛铷襦颥",
278
+"ruan  :软阮朊",
279
+"rui   :瑞锐蕊芮蕤枘睿蚋",
280
+"run   :润闰",
281
+"ruo   :弱若偌",
282
+"sa    :撒萨洒卅仨挲脎飒",
283
+"sai   :塞赛腮鳃噻",
284
+"san   :三散叁伞馓毵糁",
285
+"sang  :桑丧嗓搡磉颡",
286
+"sao   :扫搔骚嫂埽缫缲臊瘙鳋",
287
+"se    :色瑟涩啬铯穑",
288
+"sen   :森",
289
+"seng  :僧",
290
+"sha   :沙杀砂啥纱莎刹傻煞杉唼歃铩痧裟霎鲨",
291
+"shai  :筛晒",
292
+"shan  :山闪善珊扇陕苫杉删煽衫擅赡膳汕缮剡讪鄯埏芟潸姗嬗骟膻钐疝蟮舢跚鳝",
293
+"shang :上商伤尚墒赏晌裳垧绱殇熵觞",
294
+"shao  :少烧稍绍哨梢捎芍勺韶邵劭苕潲蛸筲艄",
295
+"she   :社设射摄舌涉舍蛇奢赊赦慑厍佘猞滠歙畲麝",
296
+"shen  :深身神伸甚渗沈肾审申慎砷呻娠绅婶诜谂莘哂渖椹胂矧蜃",
297
+"sheng :生胜声省升盛绳剩圣牲甥嵊晟眚笙",
298
+"shi   :是时十使事实式识世试石什示市史师始施士势湿适食失视室氏蚀诗释拾饰驶狮尸虱矢屎柿拭誓逝嗜噬仕侍恃谥埘莳蓍弑轼贳炻铈螫舐筮酾豕鲥鲺",
299
+"shou  :手受收首守授寿兽售瘦狩绶艏",
300
+"shu   :数书树属术输述熟束鼠疏殊舒蔬薯叔署枢梳抒淑赎孰暑曙蜀黍戍竖墅庶漱恕丨倏塾菽摅沭澍姝纾毹腧殳秫",
301
+"shua  :刷耍唰",
302
+"shuai :衰帅摔甩蟀",
303
+"shuan :栓拴闩涮",
304
+"shuang:双霜爽孀",
305
+"shui  :水谁睡税",
306
+"shun  :顺吮瞬舜",
307
+"shuo  :说硕朔烁蒴搠妁槊铄",
308
+"si    :四思死斯丝似司饲私撕嘶肆寺嗣伺巳厮兕厶咝汜泗澌姒驷缌祀锶鸶耜蛳笥",
309
+"song  :松送宋颂耸怂讼诵凇菘崧嵩忪悚淞竦",
310
+"sou   :搜艘擞嗽叟薮嗖嗾馊溲飕瞍锼螋",
311
+"su    :素速苏塑缩俗诉宿肃酥粟僳溯夙谡蔌嗉愫涑簌觫稣",
312
+"suan  :算酸蒜狻",
313
+"sui   :随穗碎虽岁隋绥髓遂隧祟谇荽濉邃燧眭睢",
314
+"sun   :损孙笋荪狲飧榫隼",
315
+"suo   :所缩锁索蓑梭唆琐唢嗦嗍娑桫睃羧",
316
+"ta    :他它她塔踏塌獭挞蹋闼溻遢榻沓铊趿鳎",
317
+"tai   :台太态胎抬泰苔酞汰邰薹肽炱钛跆鲐",
318
+"tan   :谈碳探炭坦贪滩坍摊瘫坛檀痰潭谭毯袒叹郯澹昙忐钽锬",
319
+"tang  :堂糖唐塘汤搪棠膛倘躺淌趟烫傥帑溏瑭樘铴镗耥螗螳羰醣",
320
+"tao   :套讨逃陶萄桃掏涛滔绦淘鼗啕洮韬焘饕",
321
+"te    :特忒忑铽",
322
+"teng  :腾疼藤誊滕",
323
+"ti    :提题体替梯惕剔踢锑蹄啼嚏涕剃屉倜悌逖缇鹈裼醍",
324
+"tian  :天田添填甜恬舔腆掭忝阗殄畋",
325
+"tiao  :条跳挑迢眺佻祧窕蜩笤粜龆鲦髫",
326
+"tie   :铁贴帖萜餮",
327
+"ting  :听停庭挺廷厅烃汀亭艇莛葶婷梃铤蜓霆",
328
+"tong  :同通统铜痛筒童桶桐酮瞳彤捅佟仝茼嗵恸潼砼",
329
+"tou   :头投透偷钭骰",
330
+"tu    :图土突途徒凸涂吐兔屠秃堍荼菟钍酴",
331
+"tuan  :团湍抟彖疃",
332
+"tui   :推退腿颓蜕褪煺",
333
+"tun   :吞屯臀氽饨暾豚",
334
+"tuo   :脱拖托妥椭鸵陀驮驼拓唾乇佗坨庹沱柝橐砣箨酡跎鼍",
335
+"wa    :瓦挖哇蛙洼娃袜佤娲腽",
336
+"wai   :外歪",
337
+"wan   :完万晚弯碗顽湾挽玩豌丸烷皖惋宛婉腕剜芄菀纨绾琬脘畹蜿",
338
+"wang  :往王望网忘妄亡旺汪枉罔尢惘辋魍",
339
+"wei   :为位委围维唯卫微伟未威危尾谓喂味胃魏伪违韦畏纬巍桅惟潍苇萎蔚渭尉慰偎诿隈葳薇囗帏帷崴嵬猥猬闱沩洧涠逶娓玮韪軎炜煨痿艉鲔",
340
+"wen   :问温文稳纹闻蚊瘟吻紊刎阌汶璺雯",
341
+"weng  :嗡翁瓮蓊蕹",
342
+"wo    :我握窝蜗涡沃挝卧斡倭莴喔幄渥肟硪龌",
343
+"wu    :无五物武务误伍舞污悟雾午屋乌吴诬钨巫呜芜梧吾毋捂侮坞戊晤勿兀仵阢邬圬芴唔庑怃忤浯寤迕妩婺骛杌牾焐鹉鹜痦蜈鋈鼯",
344
+"xi    :系席西习细吸析喜洗铣稀戏隙希息袭锡烯牺悉惜溪昔熙硒矽晰嘻膝夕熄汐犀檄媳僖兮隰郗菥葸蓰奚唏徙饩阋浠淅屣嬉玺樨曦觋欷熹禊禧皙穸蜥螅蟋舄舾羲粞翕醯鼷",
345
+"xia   :下夏吓狭霞瞎虾匣辖暇峡侠厦呷狎遐瑕柙硖罅黠",
346
+"xian  :线现先县限显鲜献险陷宪纤掀弦腺锨仙咸贤衔舷闲涎嫌馅羡冼苋莶藓岘猃暹娴氙燹祆鹇痫蚬筅籼酰跣跹霰",
347
+"xiang :想向相象响项箱乡香像详橡享湘厢镶襄翔祥巷芗葙饷庠骧缃蟓鲞飨",
348
+"xiao  :小消削效笑校销硝萧肖孝霄哮嚣宵淆晓啸哓崤潇逍骁绡枭枵筱箫魈",
349
+"xie   :些写斜谢协械卸屑鞋歇邪胁蟹泄泻楔蝎挟携谐懈偕亵勰燮薤撷獬廨渫瀣邂绁缬榭榍躞",
350
+"xin   :新心信锌芯辛欣薪忻衅囟馨昕歆鑫",
351
+"xing  :行性形型星兴醒姓幸腥猩惺刑邢杏陉荇荥擤饧悻硎",
352
+"xiong :雄胸兄凶熊匈汹芎",
353
+"xiu   :修锈休袖秀朽羞嗅绣咻岫馐庥溴鸺貅髹",
354
+"xu    :续许须需序虚絮畜叙蓄绪徐墟戌嘘酗旭恤婿诩勖圩蓿洫溆顼栩煦盱胥糈醑",
355
+"xuan  :选旋宣悬玄轩喧癣眩绚儇谖萱揎泫渲漩璇楦暄炫煊碹铉镟痃",
356
+"xue   :学血雪穴靴薛谑泶踅鳕",
357
+"xun   :训旬迅讯寻循巡勋熏询驯殉汛逊巽埙荀蕈薰峋徇獯恂洵浔曛醺鲟",
358
+"ya    :压亚呀牙芽雅蚜鸭押鸦丫崖衙涯哑讶伢垭揠岈迓娅琊桠氩砑睚痖",
359
+"yan   :验研严眼言盐演岩沿烟延掩宴炎颜燕衍焉咽阉淹蜒阎奄艳堰厌砚雁唁彦焰谚厣赝俨偃兖谳郾鄢菸崦恹闫阏湮滟妍嫣琰檐晏胭焱罨筵酽魇餍鼹",
360
+"yang  :样养氧扬洋阳羊秧央杨仰殃鸯佯疡痒漾徉怏泱炀烊恙蛘鞅",
361
+"yao   :要药摇腰咬邀耀疟妖瑶尧遥窑谣姚舀夭爻吆崾徭幺珧杳轺曜肴鹞窈繇鳐",
362
+"ye    :也业页叶液夜野爷冶椰噎耶掖曳腋靥谒邺揶晔烨铘",
363
+"yi    :一以义意已移医议依易乙艺益异宜仪亿遗伊役衣疑亦谊翼译抑忆疫壹揖铱颐夷胰沂姨彝椅蚁倚矣邑屹臆逸肄裔毅溢诣翌绎刈劓佚佾诒圯埸懿苡荑薏弈奕挹弋呓咦咿噫峄嶷猗饴怿怡悒漪迤驿缢殪轶贻旖熠眙钇镒镱痍瘗癔翊蜴舣羿翳酏黟",
364
+"yin   :因引阴印音银隐饮荫茵殷姻吟淫寅尹胤鄞垠堙茚吲喑狺夤洇氤铟瘾窨蚓霪龈",
365
+"ying  :应影硬营英映迎樱婴鹰缨莹萤荧蝇赢盈颖嬴郢茔莺萦蓥撄嘤膺滢潆瀛瑛璎楹媵鹦瘿颍罂",
366
+"yo    :哟唷",
367
+"yong  :用勇永拥涌蛹庸佣臃痈雍踊咏泳恿俑壅墉喁慵邕镛甬鳙饔",
368
+"you   :有由又油右友优幼游尤诱犹幽悠忧邮铀酉佑釉卣攸侑莠莜莸呦囿宥柚猷牖铕疣蚰蚴蝣鱿黝鼬",
369
+"yu    :于与育鱼雨玉余遇预域语愈渔予羽愚御欲宇迂淤盂榆虞舆俞逾愉渝隅娱屿禹芋郁吁喻峪狱誉浴寓裕豫驭禺毓伛俣谀谕萸蓣揄圄圉嵛狳饫馀庾阈鬻妪妤纡瑜昱觎腴欤於煜熨燠聿钰鹆鹬瘐瘀窬窳蜮蝓竽臾舁雩龉",
370
+"yuan  :员原圆源元远愿院缘援园怨鸳渊冤垣袁辕猿苑垸塬芫掾沅媛瑗橼爰眢鸢螈箢鼋",
371
+"yue   :月越约跃曰阅钥岳粤悦龠瀹樾刖钺",
372
+"yun   :运云匀允孕耘郧陨蕴酝晕韵郓芸狁恽愠纭韫殒昀氲熨",
373
+"za    :杂咱匝砸咋咂",
374
+"zai   :在再载栽灾哉宰崽甾",
375
+"zan   :赞咱暂攒拶瓒昝簪糌趱錾",
376
+"zang  :脏葬赃奘驵臧",
377
+"zao   :造早遭燥凿糟枣皂藻澡蚤躁噪灶唣",
378
+"ze    :则择责泽仄赜啧帻迮昃笮箦舴",
379
+"zei   :贼",
380
+"zen   :怎谮",
381
+"zeng  :增曾憎赠缯甑罾锃",
382
+"zha   :扎炸闸铡轧渣喳札眨栅榨乍诈揸吒咤哳砟痄蚱齄",
383
+"zhai  :寨摘窄斋宅债砦瘵",
384
+"zhan  :战展站占瞻毡詹沾盏斩辗崭蘸栈湛绽谵搌旃",
385
+"zhang :张章掌仗障胀涨账樟彰漳杖丈帐瘴仉鄣幛嶂獐嫜璋蟑",
386
+"zhao  :照找招召赵爪罩沼兆昭肇诏棹钊笊",
387
+"zhe   :这着者折哲浙遮蛰辙锗蔗谪摺柘辄磔鹧褶蜇赭",
388
+"zhen  :真针阵镇振震珍诊斟甄砧臻贞侦枕疹圳蓁浈缜桢榛轸赈胗朕祯畛稹鸩箴",
389
+"zheng :争正政整证征蒸症郑挣睁狰怔拯帧诤峥徵钲铮筝",
390
+"zhi   :之制治只质指直支织止至置志值知执职植纸致枝殖脂智肢秩址滞汁芝吱蜘侄趾旨挚掷帜峙稚炙痔窒卮陟郅埴芷摭帙忮彘咫骘栉枳栀桎轵轾贽胝膣祉祗黹雉鸷痣蛭絷酯跖踬踯豸觯",
391
+"zhong :中种重众钟终忠肿仲盅衷冢锺螽舯踵",
392
+"zhou  :轴周洲州皱骤舟诌粥肘帚咒宙昼荮啁妯纣绉胄碡籀酎",
393
+"zhu   :主注著住助猪铸株筑柱驻逐祝竹贮珠朱诸蛛诛烛煮拄瞩嘱蛀伫侏邾茱洙渚潴杼槠橥炷铢疰瘃竺箸舳翥躅麈",
394
+"zhua  :抓",
395
+"zhuai :拽",
396
+"zhuan :转专砖撰赚篆啭馔颛",
397
+"zhuang:装状壮庄撞桩妆僮",
398
+"zhui  :追锥椎赘坠缀惴骓缒",
399
+"zhun  :准谆肫窀",
400
+"zhuo  :捉桌拙卓琢茁酌啄灼浊倬诼擢浞涿濯焯禚斫镯",
401
+"zi    :子自资字紫仔籽姿兹咨滋淄孜滓渍谘嵫姊孳缁梓辎赀恣眦锱秭耔笫粢趑觜訾龇鲻髭",
402
+"zong  :总纵宗综棕鬃踪偬枞腙粽",
403
+"zou   :走邹奏揍诹陬鄹驺鲰",
404
+"zu    :组族足阻祖租卒诅俎菹镞",
405
+"zuan  :钻纂攥缵躜",
406
+"zui   :最罪嘴醉蕞",
407
+"zun   :尊遵撙樽鳟",
408
+"zuo   :作做左座坐昨佐柞阼唑嘬怍胙祚"};
409
+  }
410
+}

+ 391
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/PyCode.ts 查看文件

@@ -0,0 +1,391 @@
1
+namespace NPinyin {
2
+    export class PyCode {
3
+        public static codes: string[] = [
4
+            "a     :阿啊吖嗄腌锕",
5
+            "ai    :爱埃碍矮挨唉哎哀皑癌蔼艾隘捱嗳嗌嫒瑷暧砹锿霭",
6
+            "an    :安按暗岸案俺氨胺鞍谙埯揞犴庵桉铵鹌黯",
7
+            "ang   :昂肮盎",
8
+            "ao    :凹奥敖熬翱袄傲懊澳坳拗嗷岙廒遨媪骜獒聱螯鏊鳌鏖",
9
+            "ba    :把八吧巴拔霸罢爸坝芭捌扒叭笆疤跋靶耙茇菝岜灞钯粑鲅魃",
10
+            "bai   :百白败摆柏佰拜稗捭掰",
11
+            "ban   :办半板班般版拌搬斑扳伴颁扮瓣绊阪坂钣瘢癍舨",
12
+            "bang  :帮棒邦榜梆膀绑磅蚌镑傍谤蒡浜",
13
+            "bao   :报保包剥薄胞暴宝饱抱爆堡苞褒雹豹鲍葆孢煲鸨褓趵龅",
14
+            "bei   :北被倍备背辈贝杯卑悲碑钡狈惫焙孛陂邶埤萆蓓呗悖碚鹎褙鐾鞴",
15
+            "ben   :本奔苯笨畚坌贲锛",
16
+            "beng  :泵崩绷甭蹦迸嘣甏",
17
+            "bi    :比必避闭辟笔壁臂毕彼逼币鼻蔽鄙碧蓖毙毖庇痹敝弊陛匕俾荜荸薜吡哔狴庳愎滗濞弼妣婢嬖璧畀铋秕裨筚箅篦舭襞跸髀",
18
+            "bian  :变边便编遍辩扁辨鞭贬卞辫匾弁苄忭汴缏飚煸砭碥窆褊蝙笾鳊",
19
+            "biao  :表标彪膘婊骠杓飑飙镖镳瘭裱鳔髟",
20
+            "bie   :别鳖憋瘪蹩",
21
+            "bin   :宾彬斌濒滨摈傧豳缤玢槟殡膑镔髌鬓",
22
+            "bing  :并病兵柄冰丙饼秉炳禀邴摒",
23
+            "bo    :波播伯拨博勃驳玻泊菠钵搏铂箔帛舶脖膊渤亳啵饽檗擘礴钹鹁簸跛踣",
24
+            "bu    :不部步布补捕卜哺埠簿怖卟逋瓿晡钚钸醭",
25
+            "ca    :擦嚓礤",
26
+            "cai   :采才材菜财裁彩猜睬踩蔡",
27
+            "can   :参残蚕灿餐惭惨孱骖璨粲黪",
28
+            "cang  :藏仓苍舱沧",
29
+            "cao   :草槽操糙曹嘈漕螬艚",
30
+            "ce    :测策侧册厕恻",
31
+            "cen   :岑涔",
32
+            "ceng  :层蹭",
33
+            "cha   :查差插察茶叉茬碴搽岔诧猹馇汊姹杈楂槎檫锸镲衩",
34
+            "chai  :柴拆豺侪钗瘥虿",
35
+            "chan  :产铲阐搀掺蝉馋谗缠颤冁谄蒇廛忏潺澶羼婵骣觇禅镡蟾躔",
36
+            "chang :长常场厂唱肠昌倡偿畅猖尝敞伥鬯苌菖徜怅惝阊娼嫦昶氅鲳",
37
+            "chao  :朝超潮巢抄钞嘲吵炒怊晁耖",
38
+            "che   :车彻撤扯掣澈坼砗",
39
+            "chen  :陈沉称衬尘臣晨郴辰忱趁伧谌谶抻嗔宸琛榇碜龀",
40
+            "cheng :成程称城承乘呈撑诚橙惩澄逞骋秤丞埕噌枨柽塍瞠铖铛裎蛏酲",
41
+            "chi   :持尺齿吃赤池迟翅斥耻痴匙弛驰侈炽傺坻墀茌叱哧啻嗤彳饬媸敕眵鸱瘛褫蚩螭笞篪豉踟魑",
42
+            "chong :虫充冲崇宠茺忡憧铳舂艟",
43
+            "chou  :抽仇臭酬畴踌稠愁筹绸瞅丑俦帱惆瘳雠",
44
+            "chu   :出处除初础触楚锄储橱厨躇雏滁矗搐亍刍怵憷绌杵楮樗褚蜍蹰黜",
45
+            "chuai :揣搋啜膪踹",
46
+            "chuan :传船穿串川椽喘舛遄巛氚钏舡",
47
+            "chuang:床创窗闯疮幢怆",
48
+            "chui  :吹垂锤炊捶陲棰槌",
49
+            "chun  :春纯醇椿唇淳蠢莼鹑蝽",
50
+            "chuo  :戳绰辍踔龊",
51
+            "ci    :此次刺磁雌词茨疵辞慈瓷赐茈呲祠鹚糍",
52
+            "cong  :从丛聪葱囱匆苁淙骢琮璁",
53
+            "cou   :凑楱辏腠",
54
+            "cu    :粗促醋簇蔟徂猝殂酢蹙蹴",
55
+            "cuan  :篡蹿窜汆撺爨镩",
56
+            "cui   :催脆淬粹摧崔瘁翠萃啐悴璀榱毳隹",
57
+            "cun   :存村寸忖皴",
58
+            "cuo   :错措撮磋搓挫厝嵯脞锉矬痤鹾蹉",
59
+            "da    :大打达答搭瘩耷哒嗒怛妲疸褡笪靼鞑",
60
+            "dai   :代带待袋戴呆歹傣殆贷逮怠埭甙呔岱迨骀绐玳黛",
61
+            "dan   :单但弹担蛋淡胆氮丹旦耽郸掸惮诞儋萏啖殚赕眈疸瘅聃箪",
62
+            "dang  :党当档挡荡谠凼菪宕砀裆",
63
+            "dao   :到道导刀倒稻岛捣盗蹈祷悼叨忉氘纛",
64
+            "de    :的得德锝",
65
+            "deng  :等灯登邓蹬瞪凳噔嶝戥磴镫簦",
66
+            "di    :地第低敌底帝抵滴弟递堤迪笛狄涤翟嫡蒂缔氐籴诋谛邸荻嘀娣绨柢棣觌砥碲睇镝羝骶",
67
+            "dia   :嗲",
68
+            "dian  :电点垫典店颠淀掂滇碘靛佃甸惦奠殿阽坫巅玷钿癜癫簟踮",
69
+            "diao  :调掉吊碉叼雕凋刁钓铞铫貂鲷",
70
+            "die   :迭跌爹碟蝶谍叠垤堞揲喋牒瓞耋蹀鲽",
71
+            "ding  :定顶钉丁订盯叮鼎锭仃啶玎腚碇町疔耵酊",
72
+            "diu   :丢铥",
73
+            "dong  :动东冬懂洞冻董栋侗恫垌咚岽峒氡胨胴硐鸫",
74
+            "dou   :斗豆兜抖陡逗痘蔸窦蚪篼",
75
+            "du    :度都毒独读渡杜堵镀顿督犊睹赌肚妒芏嘟渎椟牍蠹笃髑黩",
76
+            "duan  :断端段短锻缎椴煅簖",
77
+            "dui   :对队堆兑怼憝碓",
78
+            "dun   :盾吨顿蹲敦墩囤钝遁沌炖砘礅盹镦趸",
79
+            "duo   :多夺朵掇哆垛躲跺舵剁惰堕咄哚沲缍柁铎裰踱",
80
+            "e     :而二尔儿恶额恩俄耳饵蛾饿峨鹅讹娥厄扼遏鄂噩谔垩苊莪萼呃愕屙婀轭腭锇锷鹗颚鳄",
81
+            "ei    :诶",
82
+            "en    :恩蒽摁",
83
+            "er    :而二尔儿耳饵洱贰佴迩珥铒鸸鲕",
84
+            "fa    :发法阀乏伐罚筏珐垡砝",
85
+            "fan   :反翻范犯饭繁泛番凡烦返藩帆樊矾钒贩蕃蘩幡梵燔畈蹯",
86
+            "fang  :方放防访房纺仿妨芳肪坊邡枋钫舫鲂",
87
+            "fei   :非肥飞费废肺沸菲匪啡诽吠芾狒悱淝妃绯榧腓斐扉镄痱蜚篚翡霏鲱",
88
+            "fen   :分粉奋份粪纷芬愤酚吩氛坟焚汾忿偾瀵棼鲼鼢",
89
+            "feng  :风封蜂丰缝峰锋疯奉枫烽逢冯讽凤俸酆葑唪沣砜",
90
+            "fou   :否缶",
91
+            "fu    :复服副府夫负富附福伏符幅腐浮辅付腹妇孵覆扶辐傅佛缚父弗甫肤氟敷拂俘涪袱抚俯釜斧脯腑赴赋阜讣咐匐凫郛芙苻茯莩菔拊呋幞怫滏艴孚驸绂绋桴赙祓砩黻黼罘稃馥蚨蜉蝠蝮麸趺跗鲋鳆",
92
+            "ga    :噶嘎尬尕尜旮钆",
93
+            "gai   :改该盖概钙溉丐陔垓戤赅",
94
+            "gan   :干杆感敢赶甘肝秆柑竿赣坩苷尴擀泔淦澉绀橄旰矸疳酐",
95
+            "gang  :刚钢缸纲岗港杠冈肛戆罡筻",
96
+            "gao   :高搞告稿膏篙皋羔糕镐睾诰郜藁缟槔槁杲锆",
97
+            "ge    :个各革格割歌隔哥铬阁戈葛搁鸽胳疙蛤鬲仡哿圪塥嗝搿膈硌镉袼虼舸骼",
98
+            "gen   :根跟亘茛哏艮",
99
+            "geng  :更耕颈庚羹埂耿梗哽赓绠鲠",
100
+            "gong  :工公共供功攻巩贡汞宫恭龚躬弓拱珙肱蚣觥",
101
+            "gou   :够构沟狗钩勾购苟垢佝诟岣遘媾缑枸觏彀笱篝鞲",
102
+            "gu    :鼓固古骨故顾股谷估雇孤姑辜菇咕箍沽蛊嘏诂菰崮汩梏轱牯牿臌毂瞽罟钴锢鸪痼蛄酤觚鲴鹘",
103
+            "gua   :挂刮瓜剐寡褂卦诖呱栝胍鸹",
104
+            "guai  :怪乖拐",
105
+            "guan  :关管观官灌贯惯冠馆罐棺倌莞掼涫盥鹳矜鳏",
106
+            "guang :光广逛咣犷桄胱",
107
+            "gui   :规贵归硅鬼轨龟桂瑰圭闺诡癸柜跪刽匦刿庋宄妫桧炅晷皈簋鲑鳜",
108
+            "gun   :滚辊棍衮绲磙鲧",
109
+            "guo   :国过果锅郭裹馘埚掴呙帼崞猓椁虢聒蜾蝈",
110
+            "ha    :哈铪",
111
+            "hai   :还海害孩骸氦亥骇嗨胲醢",
112
+            "han   :含焊旱喊汉寒汗函韩酣憨邯涵罕翰撼捍憾悍邗菡撖阚瀚晗焓顸颔蚶鼾",
113
+            "hang  :航夯杭沆绗珩颃",
114
+            "hao   :好号毫耗豪郝浩壕嚎蒿薅嗥嚆濠灏昊皓颢蚝",
115
+            "he    :和合河何核赫荷褐喝贺呵禾盒菏貉阂涸鹤诃劾壑嗬阖纥曷盍颌蚵翮",
116
+            "hei   :黑嘿",
117
+            "hen   :很狠痕恨",
118
+            "heng  :横衡恒哼亨蘅桁",
119
+            "hong  :红洪轰烘哄虹鸿宏弘黉訇讧荭蕻薨闳泓",
120
+            "hou   :后候厚侯喉猴吼堠後逅瘊篌糇鲎骺",
121
+            "hu    :护互湖呼户弧乎胡糊虎忽瑚壶葫蝴狐唬沪冱唿囫岵猢怙惚浒滹琥槲轷觳烀煳戽扈祜瓠鹄鹕鹱笏醐斛",
122
+            "hua   :化花话划滑华画哗猾骅桦砉铧",
123
+            "huai  :坏怀淮槐徊踝",
124
+            "huan  :环换欢缓患幻焕桓唤痪豢涣宦郇奂萑擐圜獾洹浣漶寰逭缳锾鲩鬟",
125
+            "huang :黄簧荒皇慌蝗磺凰惶煌晃幌恍谎隍徨湟潢遑璜肓癀蟥篁鳇",
126
+            "hui   :会回灰挥辉汇毁慧恢绘惠徽蛔悔卉晦贿秽烩讳诲诙茴荟蕙咴哕喙隳洄浍彗缋珲晖恚虺蟪麾",
127
+            "hun   :混浑荤昏婚魂诨馄阍溷",
128
+            "huo   :活或火货获伙霍豁惑祸劐藿攉嚯夥钬锪镬耠蠖",
129
+            "ji    :级及机极几积给基记己计集即际季激济技击继急剂既纪寄挤鸡迹绩吉脊辑籍疾肌棘畸圾稽箕饥讥姬缉汲嫉蓟冀伎祭悸寂忌妓藉丌亟乩剞佶偈诘墼芨芰荠蒺蕺掎叽咭哜唧岌嵴洎屐骥畿玑楫殛戟戢赍觊犄齑矶羁嵇稷瘠虮笈笄暨跻跽霁鲚鲫髻麂",
130
+            "jia   :加家架价甲夹假钾贾稼驾嘉枷佳荚颊嫁伽郏葭岬浃迦珈戛胛恝铗镓痂瘕袷蛱笳袈跏",
131
+            "jian  :间件见建坚减检践尖简碱剪艰渐肩键健柬鉴剑歼监兼奸箭茧舰俭笺煎缄硷拣捡荐槛贱饯溅涧僭谏谫菅蒹搛湔蹇謇缣枧楗戋戬牮犍毽腱睑锏鹣裥笕翦趼踺鲣鞯",
132
+            "jiang :将降讲江浆蒋奖疆僵姜桨匠酱茳洚绛缰犟礓耩糨豇",
133
+            "jiao  :较教交角叫脚胶浇焦搅酵郊铰窖椒礁骄娇嚼矫侥狡饺缴绞剿轿佼僬艽茭挢噍峤徼姣敫皎鹪蛟醮跤鲛",
134
+            "jie   :结阶解接节界截介借届街揭洁杰竭皆秸劫桔捷睫姐戒藉芥疥诫讦拮喈嗟婕孑桀碣疖颉蚧羯鲒骱",
135
+            "jin   :进金近紧斤今尽仅劲浸禁津筋锦晋巾襟谨靳烬卺荩堇噤馑廑妗缙瑾槿赆觐衿",
136
+            "jing  :经精京径井静竟晶净境镜景警茎敬惊睛竞荆兢鲸粳痉靖刭儆阱菁獍憬泾迳弪婧肼胫腈旌",
137
+            "jiong :炯窘迥扃",
138
+            "jiu   :就九旧究久救酒纠揪玖韭灸厩臼舅咎疚僦啾阄柩桕鸠鹫赳鬏",
139
+            "ju    :具据局举句聚距巨居锯剧矩拒鞠拘狙疽驹菊咀沮踞俱惧炬倨讵苣苴莒掬遽屦琚椐榘榉橘犋飓钜锔窭裾趄醵踽龃雎鞫",
140
+            "juan  :卷捐鹃娟倦眷绢鄄狷涓桊蠲锩镌隽",
141
+            "jue   :决觉绝掘撅攫抉倔爵诀厥劂谲矍蕨噘噱崛獗孓珏桷橛爝镢蹶觖",
142
+            "jun   :军均菌君钧峻俊竣浚郡骏捃皲筠麇",
143
+            "ka    :卡喀咖咯佧咔胩",
144
+            "kai   :开凯揩楷慨剀垲蒈忾恺铠锎锴",
145
+            "kan   :看刊坎堪勘砍侃莰戡龛瞰",
146
+            "kang  :抗康炕慷糠扛亢伉闶钪",
147
+            "kao   :考靠拷烤尻栲犒铐",
148
+            "ke    :可克科刻客壳颗棵柯坷苛磕咳渴课嗑岢恪溘骒缂珂轲氪瞌钶锞稞疴窠颏蝌髁",
149
+            "ken   :肯啃垦恳裉",
150
+            "keng  :坑吭铿",
151
+            "kong  :孔空控恐倥崆箜",
152
+            "kou   :口扣抠寇芤蔻叩眍筘",
153
+            "ku    :苦库枯酷哭窟裤刳堀喾绔骷",
154
+            "kua   :跨夸垮挎胯侉",
155
+            "kuai  :快块筷侩蒯郐哙狯脍",
156
+            "kuan  :宽款髋",
157
+            "kuang :况矿狂框匡筐眶旷诓诳邝圹夼哐纩贶",
158
+            "kui   :奎溃馈亏盔岿窥葵魁傀愧馗匮夔隗蒉揆喹喟悝愦逵暌睽聩蝰篑跬",
159
+            "kun   :困昆坤捆悃阃琨锟醌鲲髡",
160
+            "kuo   :扩括阔廓蛞",
161
+            "la    :拉啦蜡腊蓝垃喇辣剌邋旯砬瘌",
162
+            "lai   :来赖莱崃徕涞濑赉睐铼癞籁",
163
+            "lan   :兰烂蓝览栏婪拦篮阑澜谰揽懒缆滥岚漤榄斓罱镧褴",
164
+            "lang  :浪朗郎狼琅榔廊莨蒗啷阆锒稂螂",
165
+            "lao   :老劳牢涝捞佬姥酪烙唠崂栳铑铹痨耢醪",
166
+            "le    :了乐勒肋仂叻泐鳓",
167
+            "lei   :类雷累垒泪镭蕾磊儡擂肋羸诔嘞嫘缧檑耒酹",
168
+            "leng  :冷棱楞塄愣",
169
+            "li    :理里利力立离例历粒厘礼李隶黎璃励犁梨丽厉篱狸漓鲤莉荔吏栗砾傈俐痢沥哩俪俚郦坜苈莅蓠藜呖唳喱猁溧澧逦娌嫠骊缡枥栎轹戾砺詈罹锂鹂疠疬蛎蜊蠡笠篥粝醴跞雳鲡鳢黧",
170
+            "lia   :俩",
171
+            "lian  :连联练炼脸链莲镰廉怜涟帘敛恋蔹奁潋濂琏楝殓臁裢裣蠊鲢",
172
+            "liang :量两粮良亮梁凉辆粱晾谅墚椋踉靓魉",
173
+            "liao  :料疗辽僚撩聊燎寥潦撂镣廖蓼尥嘹獠寮缭钌鹩",
174
+            "lie   :列裂烈劣猎冽埒捩咧洌趔躐鬣",
175
+            "lin   :林磷临邻淋麟琳霖鳞凛赁吝蔺啉嶙廪懔遴檩辚膦瞵粼躏",
176
+            "ling  :领另零令灵岭铃龄凌陵拎玲菱伶羚酃苓呤囹泠绫柃棂瓴聆蛉翎鲮",
177
+            "liu   :流六留刘硫柳馏瘤溜琉榴浏遛骝绺旒熘锍镏鹨鎏",
178
+            "long  :龙垄笼隆聋咙窿拢陇垅茏泷珑栊胧砻癃",
179
+            "lou   :漏楼娄搂篓陋偻蒌喽嵝镂瘘耧蝼髅",
180
+            "lu    :路率露绿炉律虑滤陆氯鲁铝录旅卢吕芦颅庐掳卤虏麓碌赂鹿潞禄戮驴侣履屡缕垆撸噜闾泸渌漉逯璐栌榈橹轳辂辘氇胪膂镥稆鸬鹭褛簏舻鲈",
181
+            "luan  :卵乱峦挛孪滦脔娈栾鸾銮",
182
+            "lue   :略掠锊",
183
+            "lun   :论轮伦抡仑沦纶囵",
184
+            "luo   :落罗螺洛络逻萝锣箩骡裸骆倮蠃荦捋摞猡泺漯珞椤脶镙瘰雒",
185
+            "m     :呒",
186
+            "ma    :马麻吗妈骂嘛码玛蚂唛犸嬷杩蟆",
187
+            "mai   :麦脉卖买埋迈劢荬霾",
188
+            "man   :满慢曼漫蔓瞒馒蛮谩墁幔缦熳镘颟螨鳗鞔",
189
+            "mang  :忙芒盲茫氓莽邙漭硭蟒",
190
+            "mao   :毛矛冒貌贸帽猫茅锚铆卯茂袤茆峁泖瑁昴牦耄旄懋瞀蟊髦",
191
+            "me    :么麽",
192
+            "mei   :没每美煤霉酶梅妹眉玫枚媒镁昧寐媚莓嵋猸浼湄楣镅鹛袂魅",
193
+            "men   :们门闷扪焖懑钔",
194
+            "meng  :孟猛蒙盟梦萌锰檬勐甍瞢懵朦礞虻蜢蠓艋艨",
195
+            "mi    :米密迷蜜秘眯醚靡糜谜弥觅泌幂芈谧蘼咪嘧猕汨宓弭脒祢敉糸縻麋",
196
+            "mian  :面棉免绵眠冕勉娩缅沔渑湎腼眄",
197
+            "miao  :苗秒描庙妙瞄藐渺喵邈缈缪杪淼眇鹋",
198
+            "mie   :灭蔑咩蠛篾",
199
+            "min   :民敏抿皿悯闽苠岷闵泯缗玟珉愍黾鳘",
200
+            "ming  :命明名鸣螟铭冥茗溟暝瞑酩",
201
+            "miu   :谬",
202
+            "mo    :磨末模膜摸墨摩莫抹默摹蘑魔沫漠寞陌谟茉蓦馍嫫殁镆秣瘼耱貊貘",
203
+            "mou   :某谋牟侔哞眸蛑蝥鍪",
204
+            "mu    :亩目木母墓幕牧姆穆拇牡暮募慕睦仫坶苜沐毪钼",
205
+            "n     :嗯",
206
+            "na    :那南哪拿纳钠呐娜捺肭镎衲",
207
+            "nai   :耐奶乃氖奈鼐艿萘柰",
208
+            "nan   :南难男喃囝囡楠腩蝻赧",
209
+            "nang  :囊攮囔馕曩",
210
+            "nao   :脑闹挠恼淖孬垴呶猱瑙硇铙蛲",
211
+            "ne    :呢讷",
212
+            "nei   :内馁",
213
+            "nen   :嫩恁",
214
+            "neng  :能",
215
+            "ni    :你泥尼逆拟尿妮霓倪匿腻溺伲坭猊怩昵旎慝睨铌鲵",
216
+            "nian  :年念粘蔫拈碾撵捻酿廿埝辇黏鲇鲶",
217
+            "niang :娘",
218
+            "niao  :尿鸟茑嬲脲袅",
219
+            "nie   :镍啮涅捏聂孽镊乜陧蘖嗫颞臬蹑",
220
+            "nin   :您",
221
+            "ning  :宁凝拧柠狞泞佞苎咛甯聍",
222
+            "niu   :牛扭钮纽狃忸妞",
223
+            "nong  :农弄浓脓侬哝",
224
+            "nou   :耨",
225
+            "nu    :女奴努怒弩胬孥驽恧钕衄",
226
+            "nuan  :暖",
227
+            "nue   :虐",
228
+            "nuo   :诺挪懦糯傩搦喏锘",
229
+            "o     :欧偶哦鸥殴藕呕沤讴噢怄瓯耦",
230
+            "ou    :欧偶鸥殴藕呕沤讴怄瓯耦",
231
+            "pa    :怕派爬帕啪趴琶葩杷筢",
232
+            "pai   :派排拍牌哌徘湃俳蒎",
233
+            "pan   :判盘叛潘攀磐盼畔胖爿泮袢襻蟠蹒",
234
+            "pang  :旁乓庞耪胖彷滂逄螃",
235
+            "pao   :跑炮刨抛泡咆袍匏狍庖脬疱",
236
+            "pei   :配培陪胚呸裴赔佩沛辔帔旆锫醅霈",
237
+            "pen   :喷盆湓",
238
+            "peng  :碰棚蓬朋捧膨砰抨烹澎彭硼篷鹏堋嘭怦蟛",
239
+            "pi    :批皮坯脾疲砒霹披劈琵毗啤匹痞僻屁譬丕仳陴邳郫圮鼙芘擗噼庀淠媲纰枇甓睥罴铍癖疋蚍蜱貔",
240
+            "pian  :片偏篇骗谝骈犏胼翩蹁",
241
+            "piao  :票漂飘瓢剽嘌嫖缥殍瞟螵",
242
+            "pie   :撇瞥丿苤氕",
243
+            "pin   :品贫频拼苹聘拚姘嫔榀牝颦",
244
+            "ping  :平评瓶凭苹乒坪萍屏俜娉枰鲆",
245
+            "po    :破迫坡泼颇婆魄粕叵鄱珀攴钋钷皤笸",
246
+            "pou   :剖裒掊",
247
+            "pu    :普谱扑埔铺葡朴蒲仆莆菩圃浦曝瀑匍噗溥濮璞氆镤镨蹼",
248
+            "qi    :起其气期七器齐奇汽企漆欺旗畦启弃歧栖戚妻凄柒沏棋崎脐祈祁骑岂乞契砌迄泣讫亓俟圻芑芪萁萋葺蕲嘁屺岐汔淇骐绮琪琦杞桤槭耆欹祺憩碛颀蛴蜞綦綮蹊鳍麒",
249
+            "qia   :恰掐洽葜髂",
250
+            "qian  :前千钱浅签迁铅潜牵钳谴扦钎仟谦乾黔遣堑嵌欠歉倩佥阡芊芡茜荨掮岍悭慊骞搴褰缱椠肷愆钤虔箬箝",
251
+            "qiang :强枪抢墙腔呛羌蔷戕嫱樯戗炝锖锵镪襁蜣羟跄",
252
+            "qiao  :桥瞧巧敲乔蕉橇锹悄侨鞘撬翘峭俏窍劁诮谯荞愀憔樵硗跷鞒",
253
+            "qie   :切且茄怯窃郄惬妾挈锲箧",
254
+            "qin   :亲侵勤秦钦琴芹擒禽寝沁芩揿吣嗪噙溱檎锓覃螓衾",
255
+            "qing  :情清青轻倾请庆氢晴卿擎氰顷苘圊檠磬蜻罄箐謦鲭黥",
256
+            "qiong :穷琼邛茕穹蛩筇跫銎",
257
+            "qiu   :求球秋丘邱囚酋泅俅巯犰湫逑遒楸赇虬蚯蝤裘糗鳅鼽",
258
+            "qu    :去区取曲渠屈趋驱趣蛆躯娶龋诎劬蕖蘧岖衢阒璩觑氍朐祛磲鸲癯蛐蠼麴瞿黢",
259
+            "quan  :全权圈劝泉醛颧痊拳犬券诠荃悛绻辁畎铨蜷筌鬈",
260
+            "que   :确却缺炔瘸鹊榷雀阕阙悫",
261
+            "qun   :群裙逡",
262
+            "ran   :然燃染冉苒蚺髯",
263
+            "rang  :让壤嚷瓤攘禳穰",
264
+            "rao   :绕扰饶荛娆桡",
265
+            "re    :热惹",
266
+            "ren   :人认任仁刃忍壬韧妊纫仞荏葚饪轫稔衽",
267
+            "reng  :仍扔",
268
+            "ri    :日",
269
+            "rong  :容溶荣熔融绒戎茸蓉冗嵘狨榕肜蝾",
270
+            "rou   :肉揉柔糅蹂鞣",
271
+            "ru    :如入儒乳茹蠕孺辱汝褥蓐薷嚅洳溽濡缛铷襦颥",
272
+            "ruan  :软阮朊",
273
+            "rui   :瑞锐蕊芮蕤枘睿蚋",
274
+            "run   :润闰",
275
+            "ruo   :弱若偌",
276
+            "sa    :撒萨洒卅仨挲脎飒",
277
+            "sai   :塞赛腮鳃噻",
278
+            "san   :三散叁伞馓毵糁",
279
+            "sang  :桑丧嗓搡磉颡",
280
+            "sao   :扫搔骚嫂埽缫缲臊瘙鳋",
281
+            "se    :色瑟涩啬铯穑",
282
+            "sen   :森",
283
+            "seng  :僧",
284
+            "sha   :沙杀砂啥纱莎刹傻煞杉唼歃铩痧裟霎鲨",
285
+            "shai  :筛晒",
286
+            "shan  :山闪善珊扇陕苫杉删煽衫擅赡膳汕缮剡讪鄯埏芟潸姗嬗骟膻钐疝蟮舢跚鳝",
287
+            "shang :上商伤尚墒赏晌裳垧绱殇熵觞",
288
+            "shao  :少烧稍绍哨梢捎芍勺韶邵劭苕潲蛸筲艄",
289
+            "she   :社设射摄舌涉舍蛇奢赊赦慑厍佘猞滠歙畲麝",
290
+            "shen  :深身神伸甚渗沈肾审申慎砷呻娠绅婶诜谂莘哂渖椹胂矧蜃",
291
+            "sheng :生胜声省升盛绳剩圣牲甥嵊晟眚笙",
292
+            "shi   :是时十使事实式识世试石什示市史师始施士势湿适食失视室氏蚀诗释拾饰驶狮尸虱矢屎柿拭誓逝嗜噬仕侍恃谥埘莳蓍弑轼贳炻铈螫舐筮酾豕鲥鲺",
293
+            "shou  :手受收首守授寿兽售瘦狩绶艏",
294
+            "shu   :数书树属术输述熟束鼠疏殊舒蔬薯叔署枢梳抒淑赎孰暑曙蜀黍戍竖墅庶漱恕丨倏塾菽摅沭澍姝纾毹腧殳秫",
295
+            "shua  :刷耍唰",
296
+            "shuai :衰帅摔甩蟀",
297
+            "shuan :栓拴闩涮",
298
+            "shuang:双霜爽孀",
299
+            "shui  :水谁睡税",
300
+            "shun  :顺吮瞬舜",
301
+            "shuo  :说硕朔烁蒴搠妁槊铄",
302
+            "si    :四思死斯丝似司饲私撕嘶肆寺嗣伺巳厮兕厶咝汜泗澌姒驷缌祀锶鸶耜蛳笥",
303
+            "song  :松送宋颂耸怂讼诵凇菘崧嵩忪悚淞竦",
304
+            "sou   :搜艘擞嗽叟薮嗖嗾馊溲飕瞍锼螋",
305
+            "su    :素速苏塑缩俗诉宿肃酥粟僳溯夙谡蔌嗉愫涑簌觫稣",
306
+            "suan  :算酸蒜狻",
307
+            "sui   :随穗碎虽岁隋绥髓遂隧祟谇荽濉邃燧眭睢",
308
+            "sun   :损孙笋荪狲飧榫隼",
309
+            "suo   :所缩锁索蓑梭唆琐唢嗦嗍娑桫睃羧",
310
+            "ta    :他它她塔踏塌獭挞蹋闼溻遢榻沓铊趿鳎",
311
+            "tai   :台太态胎抬泰苔酞汰邰薹肽炱钛跆鲐",
312
+            "tan   :谈碳探炭坦贪滩坍摊瘫坛檀痰潭谭毯袒叹郯澹昙忐钽锬",
313
+            "tang  :堂糖唐塘汤搪棠膛倘躺淌趟烫傥帑溏瑭樘铴镗耥螗螳羰醣",
314
+            "tao   :套讨逃陶萄桃掏涛滔绦淘鼗啕洮韬焘饕",
315
+            "te    :特忒忑铽",
316
+            "teng  :腾疼藤誊滕",
317
+            "ti    :提题体替梯惕剔踢锑蹄啼嚏涕剃屉倜悌逖缇鹈裼醍",
318
+            "tian  :天田添填甜恬舔腆掭忝阗殄畋",
319
+            "tiao  :条跳挑迢眺佻祧窕蜩笤粜龆鲦髫",
320
+            "tie   :铁贴帖萜餮",
321
+            "ting  :听停庭挺廷厅烃汀亭艇莛葶婷梃铤蜓霆",
322
+            "tong  :同通统铜痛筒童桶桐酮瞳彤捅佟仝茼嗵恸潼砼",
323
+            "tou   :头投透偷钭骰",
324
+            "tu    :图土突途徒凸涂吐兔屠秃堍荼菟钍酴",
325
+            "tuan  :团湍抟彖疃",
326
+            "tui   :推退腿颓蜕褪煺",
327
+            "tun   :吞屯臀氽饨暾豚",
328
+            "tuo   :脱拖托妥椭鸵陀驮驼拓唾乇佗坨庹沱柝橐砣箨酡跎鼍",
329
+            "wa    :瓦挖哇蛙洼娃袜佤娲腽",
330
+            "wai   :外歪",
331
+            "wan   :完万晚弯碗顽湾挽玩豌丸烷皖惋宛婉腕剜芄菀纨绾琬脘畹蜿",
332
+            "wang  :往王望网忘妄亡旺汪枉罔尢惘辋魍",
333
+            "wei   :为位委围维唯卫微伟未威危尾谓喂味胃魏伪违韦畏纬巍桅惟潍苇萎蔚渭尉慰偎诿隈葳薇囗帏帷崴嵬猥猬闱沩洧涠逶娓玮韪軎炜煨痿艉鲔",
334
+            "wen   :问温文稳纹闻蚊瘟吻紊刎阌汶璺雯",
335
+            "weng  :嗡翁瓮蓊蕹",
336
+            "wo    :我握窝蜗涡沃挝卧斡倭莴喔幄渥肟硪龌",
337
+            "wu    :无五物武务误伍舞污悟雾午屋乌吴诬钨巫呜芜梧吾毋捂侮坞戊晤勿兀仵阢邬圬芴唔庑怃忤浯寤迕妩婺骛杌牾焐鹉鹜痦蜈鋈鼯",
338
+            "xi    :系席西习细吸析喜洗铣稀戏隙希息袭锡烯牺悉惜溪昔熙硒矽晰嘻膝夕熄汐犀檄媳僖兮隰郗菥葸蓰奚唏徙饩阋浠淅屣嬉玺樨曦觋欷熹禊禧皙穸蜥螅蟋舄舾羲粞翕醯鼷",
339
+            "xia   :下夏吓狭霞瞎虾匣辖暇峡侠厦呷狎遐瑕柙硖罅黠",
340
+            "xian  :线现先县限显鲜献险陷宪纤掀弦腺锨仙咸贤衔舷闲涎嫌馅羡冼苋莶藓岘猃暹娴氙燹祆鹇痫蚬筅籼酰跣跹霰",
341
+            "xiang :想向相象响项箱乡香像详橡享湘厢镶襄翔祥巷芗葙饷庠骧缃蟓鲞飨",
342
+            "xiao  :小消削效笑校销硝萧肖孝霄哮嚣宵淆晓啸哓崤潇逍骁绡枭枵筱箫魈",
343
+            "xie   :些写斜谢协械卸屑鞋歇邪胁蟹泄泻楔蝎挟携谐懈偕亵勰燮薤撷獬廨渫瀣邂绁缬榭榍躞",
344
+            "xin   :新心信锌芯辛欣薪忻衅囟馨昕歆鑫",
345
+            "xing  :行性形型星兴醒姓幸腥猩惺刑邢杏陉荇荥擤饧悻硎",
346
+            "xiong :雄胸兄凶熊匈汹芎",
347
+            "xiu   :修锈休袖秀朽羞嗅绣咻岫馐庥溴鸺貅髹",
348
+            "xu    :续许须需序虚絮畜叙蓄绪徐墟戌嘘酗旭恤婿诩勖圩蓿洫溆顼栩煦盱胥糈醑",
349
+            "xuan  :选旋宣悬玄轩喧癣眩绚儇谖萱揎泫渲漩璇楦暄炫煊碹铉镟痃",
350
+            "xue   :学血雪穴靴薛谑泶踅鳕",
351
+            "xun   :训旬迅讯寻循巡勋熏询驯殉汛逊巽埙荀蕈薰峋徇獯恂洵浔曛醺鲟",
352
+            "ya    :压亚呀牙芽雅蚜鸭押鸦丫崖衙涯哑讶伢垭揠岈迓娅琊桠氩砑睚痖",
353
+            "yan   :验研严眼言盐演岩沿烟延掩宴炎颜燕衍焉咽阉淹蜒阎奄艳堰厌砚雁唁彦焰谚厣赝俨偃兖谳郾鄢菸崦恹闫阏湮滟妍嫣琰檐晏胭焱罨筵酽魇餍鼹",
354
+            "yang  :样养氧扬洋阳羊秧央杨仰殃鸯佯疡痒漾徉怏泱炀烊恙蛘鞅",
355
+            "yao   :要药摇腰咬邀耀疟妖瑶尧遥窑谣姚舀夭爻吆崾徭幺珧杳轺曜肴鹞窈繇鳐",
356
+            "ye    :也业页叶液夜野爷冶椰噎耶掖曳腋靥谒邺揶晔烨铘",
357
+            "yi    :一以义意已移医议依易乙艺益异宜仪亿遗伊役衣疑亦谊翼译抑忆疫壹揖铱颐夷胰沂姨彝椅蚁倚矣邑屹臆逸肄裔毅溢诣翌绎刈劓佚佾诒圯埸懿苡荑薏弈奕挹弋呓咦咿噫峄嶷猗饴怿怡悒漪迤驿缢殪轶贻旖熠眙钇镒镱痍瘗癔翊蜴舣羿翳酏黟",
358
+            "yin   :因引阴印音银隐饮荫茵殷姻吟淫寅尹胤鄞垠堙茚吲喑狺夤洇氤铟瘾窨蚓霪龈",
359
+            "ying  :应影硬营英映迎樱婴鹰缨莹萤荧蝇赢盈颖嬴郢茔莺萦蓥撄嘤膺滢潆瀛瑛璎楹媵鹦瘿颍罂",
360
+            "yo    :哟唷",
361
+            "yong  :用勇永拥涌蛹庸佣臃痈雍踊咏泳恿俑壅墉喁慵邕镛甬鳙饔",
362
+            "you   :有由又油右友优幼游尤诱犹幽悠忧邮铀酉佑釉卣攸侑莠莜莸呦囿宥柚猷牖铕疣蚰蚴蝣鱿黝鼬",
363
+            "yu    :于与育鱼雨玉余遇预域语愈渔予羽愚御欲宇迂淤盂榆虞舆俞逾愉渝隅娱屿禹芋郁吁喻峪狱誉浴寓裕豫驭禺毓伛俣谀谕萸蓣揄圄圉嵛狳饫馀庾阈鬻妪妤纡瑜昱觎腴欤於煜熨燠聿钰鹆鹬瘐瘀窬窳蜮蝓竽臾舁雩龉",
364
+            "yuan  :员原圆源元远愿院缘援园怨鸳渊冤垣袁辕猿苑垸塬芫掾沅媛瑗橼爰眢鸢螈箢鼋",
365
+            "yue   :月越约跃曰阅钥岳粤悦龠瀹樾刖钺",
366
+            "yun   :运云匀允孕耘郧陨蕴酝晕韵郓芸狁恽愠纭韫殒昀氲熨",
367
+            "za    :杂咱匝砸咋咂",
368
+            "zai   :在再载栽灾哉宰崽甾",
369
+            "zan   :赞咱暂攒拶瓒昝簪糌趱錾",
370
+            "zang  :脏葬赃奘驵臧",
371
+            "zao   :造早遭燥凿糟枣皂藻澡蚤躁噪灶唣",
372
+            "ze    :则择责泽仄赜啧帻迮昃笮箦舴",
373
+            "zei   :贼",
374
+            "zen   :怎谮",
375
+            "zeng  :增曾憎赠缯甑罾锃",
376
+            "zha   :扎炸闸铡轧渣喳札眨栅榨乍诈揸吒咤哳砟痄蚱齄",
377
+            "zhai  :寨摘窄斋宅债砦瘵",
378
+            "zhan  :战展站占瞻毡詹沾盏斩辗崭蘸栈湛绽谵搌旃",
379
+            "zhang :张章掌仗障胀涨账樟彰漳杖丈帐瘴仉鄣幛嶂獐嫜璋蟑",
380
+            "zhao  :照找招召赵爪罩沼兆昭肇诏棹钊笊",
381
+            "zhe   :这着者折哲浙遮蛰辙锗蔗谪摺柘辄磔鹧褶蜇赭",
382
+            "zhen  :真针阵镇振震珍诊斟甄砧臻贞侦枕疹圳蓁浈缜桢榛轸赈胗朕祯畛稹鸩箴",
383
+            "zheng :争正政整证征蒸症郑挣睁狰怔拯帧诤峥徵钲铮筝",
384
+            "zhi   :之制治只质指直支织止至置志值知执职植纸致枝殖脂智肢秩址滞汁芝吱蜘侄趾旨挚掷帜峙稚炙痔窒卮陟郅埴芷摭帙忮彘咫骘栉枳栀桎轵轾贽胝膣祉祗黹雉鸷痣蛭絷酯跖踬踯豸觯",
385
+            "zhong :中种重众钟终忠肿仲盅衷冢锺螽舯踵",
386
+            "zhou  :轴周洲州皱骤舟诌粥肘帚咒宙昼荮啁妯纣绉胄碡籀酎",
387
+            "zhu   :主注著住助猪铸株筑柱驻逐祝竹贮珠朱诸蛛诛烛煮拄瞩嘱蛀伫侏邾茱洙渚潴杼槠橥炷铢疰瘃竺箸舳翥躅麈",
388
+            "zhua  :抓",
389
+            "zhuai :拽",
390
+            "zhuan :转专砖撰赚篆啭馔颛",
391
+            "zhuang:

+ 411
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/PyHash.cs 查看文件

@@ -0,0 +1,411 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Text;
4
+
5
+namespace NPinyin
6
+{
7
+  internal class PyHash
8
+  {
9
+    internal static short[][] hashes = new short[][] {
10
+new short[]{23, 70, 96, 128, 154, 165, 172, 195},
11
+new short[]{25, 35, 87, 108, 120, 128, 132, 137, 168, 180, 325, 334, 336, 353, 361, 380},
12
+new short[]{23, 34, 46, 81, 82, 87, 134, 237, 255, 288, 317, 322, 354, 359},
13
+new short[]{7, 11, 37, 49, 53, 56, 131, 132, 146, 176, 315, 372},
14
+new short[]{11, 69, 73, 87, 96, 103, 159, 175, 195, 296, 298, 359, 361},
15
+new short[]{57, 87, 115, 126, 149, 244, 282, 298, 308, 345, 355},
16
+new short[]{19, 37, 117, 118, 141, 154, 196, 216, 267, 301, 327, 333, 337, 347},
17
+new short[]{4, 11, 59, 61, 62, 87, 119, 169, 183, 198, 262, 334, 362, 380},
18
+new short[]{37, 135, 167, 170, 246, 250, 334, 341, 351, 354, 386, 390, 398},
19
+new short[]{5, 6, 52, 55, 76, 146, 165, 244, 256, 266, 300, 318, 331},
20
+new short[]{6, 71, 94, 129, 137, 141, 169, 179, 225, 226, 235, 248, 289, 290, 333, 345, 391},
21
+new short[]{0, 33, 37, 62, 90, 131, 205, 246, 268, 343, 349, 380},
22
+new short[]{31, 62, 85, 115, 117, 150, 159, 167, 171, 204, 215, 252, 343},
23
+new short[]{69, 81, 98, 140, 165, 195, 239, 240, 259, 265, 329, 368, 375, 392, 393},
24
+new short[]{13, 81, 82, 123, 132, 144, 154, 165, 334, 336, 345, 348, 349, 355, 367, 377, 383},
25
+new short[]{31, 32, 44, 57, 76, 83, 87, 129, 151, 172, 176, 183, 184, 193, 221, 235, 285, 288, 305},
26
+new short[]{10, 14, 60, 76, 85, 97, 115, 125, 128, 130, 286, 288, 301, 313, 382},
27
+new short[]{62, 128, 136, 175, 211, 240, 254, 273, 274, 317, 330, 344, 349, 360, 380},
28
+new short[]{29, 47, 52, 116, 126, 127, 130, 133, 191, 284, 288, 306, 353, 361, 383},
29
+new short[]{1, 15, 25, 67, 83, 90, 117, 121, 150, 228, 308, 324, 336, 351, 386},
30
+new short[]{34, 37, 67, 101, 103, 117, 127, 165, 168, 254, 267, 272, 274, 288, 305, 310, 323, 329, 333, 358, 378},
31
+new short[]{5, 74, 103, 135, 163, 165, 171, 244, 262, 266, 334, 352, 390, 397},
32
+new short[]{4, 17, 95, 125, 165, 186, 203, 221, 252, 282, 317, 333, 339, 348, 351, 353},
33
+new short[]{74, 79, 81, 84, 92, 110, 116, 117, 131, 132, 154, 199, 241, 251, 300, 306, 349, 359, 383, 387},
34
+new short[]{40, 83, 127, 144, 161, 188, 249, 288, 344, 382, 388},
35
+new short[]{8, 55, 61, 76, 85, 98, 111, 127, 186, 230, 241, 247, 267, 287, 327, 341, 344, 347, 359, 364},
36
+new short[]{20, 59, 69, 80, 117, 129, 176, 186, 191, 237, 275, 289, 309, 338, 375, 380},
37
+new short[]{5, 15, 25, 35, 40, 129, 174, 236, 274, 337, 347},
38
+new short[]{14, 22, 47, 56, 87, 120, 129, 144, 155, 160, 237, 283, 284, 309, 327, 337, 365, 372},
39
+new short[]{1, 14, 47, 132, 198, 254, 255, 300, 310, 335, 336, 372},
40
+new short[]{2, 36, 64, 96, 125, 176, 184, 190, 211, 271, 308, 315, 367},
41
+new short[]{20, 76, 79, 81, 110, 117, 120, 129, 182, 192, 235, 353, 378},
42
+new short[]{37, 83, 88, 92, 111, 127, 243, 303, 324, 325, 348, 353, 359, 371, 377},
43
+new short[]{5, 87, 90, 124, 127, 180, 259, 288, 290, 302, 312, 313, 324, 332},
44
+new short[]{55, 62, 89, 98, 108, 132, 168, 240, 248, 322, 325, 327, 347, 353, 391, 396},
45
+new short[]{4, 8, 13, 35, 37, 39, 41, 64, 111, 174, 212, 245, 248, 251, 263, 288, 335, 373, 375},
46
+new short[]{10, 39, 93, 110, 168, 227, 228, 254, 288, 336, 378, 381},
47
+new short[]{75, 92, 122, 176, 198, 211, 214, 283, 334, 353, 359, 379, 386},
48
+new short[]{5, 8, 13, 19, 57, 87, 104, 125, 130, 176, 202, 249, 252, 290, 309, 391},
49
+new short[]{88, 132, 173, 176, 235, 247, 253, 292, 324, 328, 339, 359},
50
+new short[]{19, 32, 61, 84, 87, 118, 120, 125, 129, 132, 181, 190, 288, 290, 331, 355, 359, 366},
51
+new short[]{13, 25, 46, 126, 140, 157, 165, 225, 226, 252, 288, 304, 327, 353, 378},
52
+new short[]{12, 14, 26, 56, 72, 95, 131, 132, 134, 142, 253, 298, 337, 361, 391},
53
+new short[]{4, 18, 37, 49, 87, 93, 196, 225, 226, 246, 248, 250, 255, 310, 354, 358},
54
+new short[]{64, 87, 110, 111, 128, 135, 151, 165, 177, 188, 191, 268, 312, 334, 352, 354, 357, 371},
55
+new short[]{10, 17, 19, 30, 40, 48, 81, 97, 125, 129, 130, 182, 234, 305, 328, 393},
56
+new short[]{13, 69, 80, 114, 192, 200, 235, 343, 345, 353, 354, 360, 374, 378, 383},
57
+new short[]{83, 87, 94, 105, 107, 124, 144, 153, 219, 290, 298, 324, 349, 358, 367},
58
+new short[]{10, 36, 142, 169, 221, 232, 241, 246, 346, 347, 375, 383, 390},
59
+new short[]{26, 104, 126, 143, 176, 186, 241, 247, 250, 318, 320, 333, 360},
60
+new short[]{66, 92, 116, 148, 191, 215, 254, 333, 334, 335, 336, 351, 353, 358, 380},
61
+new short[]{9, 37, 55, 56, 76, 79, 90, 111, 122, 124, 161, 192, 247, 313, 353, 359, 374},
62
+new short[]{17, 30, 34, 56, 64, 68, 90, 125, 151, 168, 176, 188, 286, 333, 338, 360},
63
+new short[]{26, 143, 173, 182, 190, 194, 246, 284, 286, 328, 333, 355, 357, 360, 362, 363, 377, 380},
64
+new short[]{1, 13, 87, 122, 168, 171, 186, 201, 297, 328, 349, 352, 380},
65
+new short[]{18, 39, 61, 88, 98, 123, 129, 131, 148, 162, 165, 243, 285, 314, 340, 349, 360, 377, 378},
66
+new short[]{67, 98, 117, 118, 122, 128, 156, 174, 184, 207, 244, 250, 330, 335, 342, 372, 375},
67
+new short[]{13, 38, 63, 160, 180, 185, 189, 190, 219, 248, 253, 275, 297, 318, 355},
68
+new short[]{1, 44, 47, 93, 107, 172, 235, 276, 281, 287, 290, 306, 333, 334, 337, 347, 353, 376},
69
+new short[]{13, 15, 32, 125, 127, 157, 165, 176, 236, 344, 350, 381},
70
+new short[]{47, 65, 93, 134, 159, 174, 218, 282, 318, 336, 358, 373, 379},
71
+new short[]{7, 17, 40, 66, 102, 141, 154, 159, 165, 172, 174, 177, 328, 329, 334, 348, 379, 382},
72
+new short[]{4, 34, 36, 76, 79, 122, 127, 138, 176, 241, 267, 309, 334, 367, 382},
73
+new short[]{9, 17, 33, 46, 90, 103, 125, 138, 144, 157, 185, 198, 224, 250, 260, 291, 326, 343, 349, 377, 381},
74
+new short[]{29, 31, 53, 58, 134, 138, 193, 287, 305, 308, 333, 334},
75
+new short[]{13, 64, 83, 93, 129, 192, 227, 244, 397},
76
+new short[]{7, 8, 14, 78, 85, 103, 138, 175, 176, 200, 203, 234, 301, 313, 361},
77
+new short[]{13, 75, 87, 111, 244, 253, 288, 321, 339, 341, 357, 395},
78
+new short[]{4, 14, 42, 64, 69, 108, 110, 117, 122, 131, 159, 163, 188, 198, 200, 206, 244, 292, 300, 354, 390},
79
+new short[]{14, 37, 73, 87, 129, 135, 144, 176, 182, 300, 346, 352, 380, 383},
80
+new short[]{23, 50, 87, 143, 171, 186, 191, 223, 290, 333, 334, 364, 378, 380, 388, 391, 393},
81
+new short[]{5, 14, 23, 36, 62, 71, 76, 95, 99, 128, 176, 211, 229, 357},
82
+new short[]{12, 33, 47, 70, 81, 90, 97, 119, 122, 131, 189, 190, 191, 235, 244, 253, 320, 350, 359},
83
+new short[]{10, 13, 23, 93, 110, 120, 135, 171, 195, 250, 293, 298, 329, 344, 354},
84
+new short[]{13, 29, 37, 163, 169, 200, 211, 214, 217, 236, 246, 249, 282, 327, 349, 353, 362, 372},
85
+new short[]{5, 13, 23, 41, 57, 62, 76, 89, 111, 135, 195, 234, 248, 314, 334, 341, 349, 380},
86
+new short[]{17, 35, 57, 117, 121, 206, 235, 243, 265, 329, 358, 374},
87
+new short[]{13, 28, 41, 55, 69, 101, 103, 126, 138, 198, 267, 276, 288, 313, 334, 335, 339, 354, 376, 383, 394},
88
+new short[]{11, 13, 19, 36, 38, 58, 75, 124, 232, 235, 265, 286, 298, 330, 333, 359},
89
+new short[]{4, 19, 25, 43, 110, 125, 165, 331, 334, 341, 349, 355, 372},
90
+new short[]{40, 55, 64, 70, 117, 126, 127, 135, 160, 172, 173, 186, 270, 318, 338, 344, 378},
91
+new short[]{122, 176, 198, 238, 246, 284, 286, 290, 318, 329, 337, 381, 394},
92
+new short[]{23, 36, 37, 44, 117, 124, 198, 204, 233, 248, 282, 288, 297, 314, 332, 336, 388},
93
+new short[]{15, 33, 54, 64, 75, 85, 115, 127, 165, 196, 229, 237, 254, 307, 327, 335, 349, 383},
94
+new short[]{22, 87, 121, 127, 161, 180, 248, 250, 276, 313, 324, 347, 349, 355, 357, 359},
95
+new short[]{14, 48, 67, 88, 130, 131, 172, 188, 195, 203, 267, 282, 333, 339, 350, 392},
96
+new short[]{22, 31, 37, 98, 118, 132, 135, 137, 142, 151, 243, 244, 282, 305, 333, 349, 350, 351, 353, 358, 374},
97
+new short[]{15, 42, 67, 75, 125, 134, 189, 255, 261, 309, 334, 350, 380, 382},
98
+new short[]{10, 39, 87, 97, 105, 109, 125, 137, 225, 226, 253, 329, 341, 354, 363, 372},
99
+new short[]{5, 17, 42, 64, 80, 111, 120, 169, 175, 206, 237, 267, 288, 290, 324, 351, 364, 390},
100
+new short[]{3, 33, 55, 75, 91, 97, 103, 132, 187, 220, 232, 234, 240, 288, 301, 330, 336, 337, 338, 340, 359, 374, 380, 382},
101
+new short[]{13, 87, 98, 125, 126, 127, 128, 250, 330, 341, 353, 360, 374, 382, 391},
102
+new short[]{59, 66, 75, 125, 135, 172, 192, 230, 231, 255, 256, 276, 300, 306, 339, 349, 353, 390},
103
+new short[]{25, 36, 56, 90, 107, 125, 127, 142, 165, 195, 244, 246, 319, 347, 355, 375, 380},
104
+new short[]{2, 33, 35, 36, 72, 74, 87, 92, 111, 131, 145, 176, 244, 248, 282, 333, 355, 359},
105
+new short[]{5, 39, 127, 134, 137, 200, 240, 283, 284, 343, 344, 372},
106
+new short[]{9, 32, 37, 80, 96, 104, 110, 117, 154, 176, 244, 297, 298, 339, 353, 374, 381},
107
+new short[]{38, 51, 64, 76, 80, 93, 96, 134, 150, 173, 275, 290, 340, 347, 359, 363, 380},
108
+new short[]{55, 89, 111, 126, 157, 159, 162, 182, 188, 244, 253, 280, 334, 359, 384, 398},
109
+new short[]{59, 64, 75, 81, 97, 105, 115, 125, 155, 198, 248, 262, 319, 323, 376},
110
+new short[]{13, 41, 76, 125, 127, 130, 134, 135, 159, 167, 183, 229, 230, 240, 246, 308, 319, 329, 333, 334, 340, 344, 363, 382},
111
+new short[]{8, 13, 19, 31, 70, 76, 79, 96, 127, 153, 163, 165, 184, 227, 230, 247, 255, 336, 337, 348, 353, 357, 361, 362},
112
+new short[]{71, 87, 111, 121, 130, 142, 150, 160, 175, 224, 248, 314, 336, 353, 357, 359},
113
+new short[]{67, 84, 101, 130, 287, 288, 332, 333, 359, 361, 377},
114
+new short[]{34, 52, 90, 100, 125, 135, 165, 173, 320, 341, 352, 359, 382, 392},
115
+new short[]{13, 18, 39, 55, 62, 87, 248, 255, 290, 327, 349, 353, 355, 360, 383},
116
+new short[]{1, 9, 12, 29, 32, 36, 82, 139, 140, 149, 153, 165, 167, 180, 185, 231, 241, 244, 274, 299, 309, 329, 355, 362},
117
+new short[]{48, 66, 98, 107, 120, 122, 125, 135, 190, 195, 198, 215, 253, 256, 280, 282, 307, 320, 334, 349, 353, 355},
118
+new short[]{1, 7, 13, 25, 64, 98, 139, 144, 166, 176, 206, 236, 262, 330, 362},
119
+new short[]{37, 55, 116, 123, 125, 131, 165, 234, 266, 276, 328, 329, 342, 349, 353, 359, 391},
120
+new short[]{126, 137, 191, 215, 239, 288, 290, 321, 324, 333, 334, 338, 349, 353, 362, 379},
121
+new short[]{50, 57, 87, 93, 98, 115, 134, 148, 174, 229, 251, 260, 285, 298, 313, 348, 349, 350},
122
+new short[]{5, 13, 31, 45, 69, 81, 108, 122, 127, 160, 165, 176, 179, 237, 244, 301, 316, 352, 360},
123
+new short[]{5, 87, 95, 98, 101, 132, 135, 159, 167, 190, 203, 217, 234, 235, 247, 289, 333, 341, 343, 352},
124
+new short[]{22, 56, 66, 85, 87, 93, 126, 127, 163, 230, 243, 248, 254, 280, 301, 305, 334, 357},
125
+new short[]{13, 19, 53, 59, 76, 91, 117, 122, 195, 298, 303, 309, 337, 345, 398},
126
+new short[]{9, 54, 84, 107, 125, 127, 135, 144, 156, 173, 176, 202, 215, 231, 234, 246, 266, 282, 335, 336, 347, 351, 374},
127
+new short[]{11, 15, 30, 31, 40, 57, 58, 87, 88, 113, 186, 244, 245, 256, 308, 334, 377},
128
+new short[]{62, 111, 176, 196, 228, 231, 288, 294, 302, 306, 350, 353, 375, 378, 392},
129
+new short[]{119, 131, 133, 154, 161, 179, 198, 232, 234, 265, 301, 314, 344, 353, 378},
130
+new short[]{67, 84, 123, 172, 175, 176, 182, 229, 290, 359, 360, 375, 383, 393},
131
+new short[]{33, 36, 39, 102, 116, 136, 137, 208, 234, 256, 307, 329, 341, 347, 376, 380},
132
+new short[]{13, 27, 32, 80, 95, 108, 131, 165, 167, 180, 190, 200, 235, 241, 244, 323, 330, 339, 372},
133
+new short[]{1, 18, 37, 62, 67, 82, 85, 118, 125, 147, 159, 169, 174, 243, 284, 307, 313, 318, 355, 391, 396},
134
+new short[]{10, 87, 91, 135, 169, 176, 215, 246, 267, 282, 295, 320, 345, 353, 380},
135
+new short[]{2, 11, 13, 29, 90, 124, 131, 132, 170, 174, 176, 229, 246, 258, 298, 336, 344, 349},
136
+new short[]{14, 37, 42, 71, 128, 152, 185, 218, 288, 304, 315, 353, 362, 380, 391},
137
+new short[]{17, 20, 36, 73, 93, 128, 163, 194, 211, 217, 282, 290, 320, 354, 383},
138
+new short[]{9, 26, 32, 101, 127, 169, 178, 183, 191, 236, 244, 310, 330, 336, 345, 353, 360, 372, 380, 394},
139
+new short[]{7, 13, 64, 78, 81, 90, 115, 133, 164, 169, 244, 246, 269, 278, 290, 292, 310, 320, 353, 360, 364, 366, 380},
140
+new short[]{8, 65, 81, 84, 91, 126, 129, 158, 183, 184, 194, 254, 262, 333, 334, 339, 351, 363, 382},
141
+new short[]{44, 87, 96, 97, 125, 161, 173, 177, 183, 188, 189, 209, 235, 288, 315, 334, 351},
142
+new short[]{50, 56, 60, 62, 67, 71, 105, 149, 154, 158, 164, 167, 185, 221, 285, 288, 308, 337, 344, 353},
143
+new short[]{6, 10, 37, 62, 74, 79, 81, 128, 139, 154, 167, 198, 228, 244, 267, 290, 302, 368, 394},
144
+new short[]{6, 30, 35, 36, 62, 65, 71, 112, 153, 163, 167, 180, 186, 195, 249, 286, 303, 329, 334},
145
+new short[]{158, 241, 282, 324, 332, 334, 351, 353, 363, 365},
146
+new short[]{17, 89, 117, 144, 165, 180, 185, 198, 229, 244, 290, 334, 335, 380},
147
+new short[]{20, 32, 45, 57, 64, 66, 120, 135, 144, 176, 192, 244, 297, 301, 354, 381},
148
+new short[]{1, 7, 35, 62, 74, 122, 159, 170, 172, 238, 239, 307, 308, 338, 349, 350, 359, 366, 368, 375, 382, 383},
149
+new short[]{7, 9, 23, 66, 92, 103, 111, 135, 182, 203, 246, 247, 265, 285, 288, 303, 317, 329, 348},
150
+new short[]{13, 39, 74, 87, 127, 135, 144, 193, 212, 243, 270, 290, 303, 315, 375, 376},
151
+new short[]{33, 36, 40, 59, 101, 120, 127, 244, 285, 287, 309, 339, 391},
152
+new short[]{4, 10, 39, 195, 268, 284, 336, 354, 359, 375, 381},
153
+new short[]{39, 42, 62, 79, 83, 84, 101, 109, 132, 138, 202, 215, 277, 353, 358, 359},
154
+new short[]{10, 39, 46, 73, 84, 87, 132, 170, 192, 219, 232, 246, 288, 320, 337},
155
+new short[]{10, 12, 56, 87, 91, 101, 132, 227, 254, 301, 303, 333, 343, 347, 351},
156
+new short[]{7, 8, 15, 18, 82, 105, 130, 232, 250, 290, 316, 332, 348, 350},
157
+new short[]{36, 109, 110, 125, 154, 191, 193, 246, 265, 348, 349, 350, 378, 383},
158
+new short[]{12, 16, 45, 57, 87, 92, 101, 105, 129, 130, 155, 167, 218, 292, 293, 327, 349, 354, 361},
159
+new short[]{30, 59, 64, 121, 125, 149, 163, 188, 212, 250, 348, 350, 351, 352, 353, 378, 380},
160
+new short[]{1, 69, 130, 138, 194, 200, 239, 260, 264, 357, 380, 381, 382, 396},
161
+new short[]{7, 10, 19, 40, 57, 61, 125, 137, 141, 212, 239, 251, 310, 333, 347, 359, 380, 383},
162
+new short[]{20, 28, 50, 97, 109, 134, 157, 162, 184, 199, 244, 246, 286, 352, 353, 360, 373, 380},
163
+new short[]{35, 62, 87, 96, 122, 127, 136, 142, 148, 155, 165, 186, 196, 227, 354, 380, 388},
164
+new short[]{81, 82, 101, 115, 125, 200, 243, 313, 351, 359, 367},
165
+new short[]{7, 19, 40, 61, 107, 108, 124, 154, 161, 244, 309, 329, 345, 379, 394},
166
+new short[]{10, 27, 48, 66, 75, 103, 116, 122, 128, 221, 228, 319, 322, 350, 377, 398},
167
+new short[]{2, 64, 74, 117, 130, 165, 172, 180, 191, 218, 221, 288, 299, 325, 347, 353, 355, 360},
168
+new short[]{5, 76, 79, 87, 106, 111, 137, 168, 180, 235, 243, 288, 315, 321, 338, 344, 348, 378, 382, 383},
169
+new short[]{0, 29, 31, 37, 40, 50, 88, 100, 129, 134, 137, 144, 174, 186, 203, 254, 310, 313, 329, 341, 359, 364},
170
+new short[]{69, 70, 71, 96, 115, 121, 130, 157, 159, 200, 230, 246, 250, 299, 318, 324, 353, 359, 380, 391},
171
+new short[]{7, 90, 95, 116, 127, 128, 135, 137, 141, 154, 161, 254, 330, 359, 379, 388},
172
+new short[]{10, 14, 56, 91, 108, 125, 130, 167, 211, 228, 246, 258, 280, 306, 324, 333, 336, 338, 379},
173
+new short[]{4, 5, 14, 57, 85, 98, 125, 135, 136, 176, 254, 334, 336, 337, 351, 358, 362, 379, 383},
174
+new short[]{1, 4, 13, 18, 19, 32, 50, 60, 62, 87, 117, 176, 211, 251, 329, 343, 359},
175
+new short[]{38, 56, 94, 103, 117, 125, 129, 144, 159, 176, 244, 251, 253, 324, 345, 353, 386, 390},
176
+new short[]{4, 22, 38, 47, 59, 64, 82, 97, 110, 135, 153, 176, 235, 236, 241, 287, 288, 303, 333, 347, 358, 359, 361},
177
+new short[]{2, 5, 20, 52, 97, 125, 127, 132, 135, 137, 174, 188, 191, 243, 288, 310, 334, 346, 348, 349, 362, 372, 378},
178
+new short[]{19, 35, 55, 98, 125, 131, 134, 147, 153, 246, 255, 390},
179
+new short[]{5, 59, 62, 129, 136, 153, 198, 225, 235, 239, 254, 295, 334, 338, 341, 359, 361},
180
+new short[]{8, 13, 51, 94, 121, 122, 125, 126, 129, 240, 272, 290, 297, 323, 352, 358, 376, 391, 395},
181
+new short[]{6, 111, 116, 122, 125, 131, 135, 164, 175, 200, 212, 221, 267, 287, 319, 328, 334, 344, 378},
182
+new short[]{83, 108, 143, 172, 176, 192, 198, 246, 262, 286, 287, 308, 338, 340, 343, 348, 353, 367, 380, 383},
183
+new short[]{39, 82, 92, 118, 126, 128, 144, 171, 211, 234, 244, 253, 328, 333, 339, 357, 359, 380},
184
+new short[]{37, 62, 64, 81, 97, 122, 125, 127, 137, 211, 246, 344, 360},
185
+new short[]{7, 29, 62, 67, 69, 81, 87, 107, 132, 151, 160, 229, 244, 284, 285, 317, 358, 387, 390},
186
+new short[]{13, 75, 76, 83, 87, 154, 165, 190, 212, 258, 285, 308, 309, 316, 320, 332, 336, 340, 352, 353, 354, 358, 383},
187
+new short[]{9, 19, 29, 46, 122, 125, 127, 130, 170, 171, 174, 180, 182, 232, 282, 290, 359, 362, 367},
188
+new short[]{13, 40, 71, 98, 101, 116, 125, 127, 169, 172, 175, 283, 288, 309, 311, 313, 323, 334, 353, 391},
189
+new short[]{3, 9, 70, 104, 118, 173, 200, 219, 246, 262, 288, 297, 309, 328, 329, 334, 341, 353},
190
+new short[]{32, 89, 93, 131, 132, 142, 199, 200, 214, 246, 287, 298, 307, 339, 348, 349, 357, 358, 368, 372, 391},
191
+new short[]{103, 134, 159, 176, 186, 235, 261, 276, 282, 290, 301, 317, 329, 345, 356},
192
+new short[]{10, 59, 125, 129, 130, 192, 217, 283, 318, 343, 345, 349, 353, 380, 383, 392},
193
+new short[]{19, 76, 79, 102, 107, 126, 155, 161, 180, 253, 288, 289, 290, 314, 329, 333, 334, 360, 368, 378, 394},
194
+new short[]{12, 92, 98, 105, 137, 149, 172, 196, 198, 244, 260, 262, 282, 298, 329, 345, 353, 368, 390},
195
+new short[]{31, 39, 79, 83, 121, 125, 167, 171, 186, 198, 288, 303, 306, 334, 337, 376},
196
+new short[]{13, 20, 36, 57, 98, 108, 114, 165, 171, 225, 226, 262, 269, 305, 309, 351, 377, 389},
197
+new short[]{13, 51, 71, 93, 110, 129, 130, 156, 165, 170, 173, 183, 191, 200, 211, 212, 255, 266, 299, 301, 329, 336, 348},
198
+new short[]{31, 56, 97, 122, 125, 129, 160, 188, 202, 204, 206, 225, 235, 247, 254, 255, 288, 334, 350, 362, 365, 367},
199
+new short[]{9, 32, 37, 70, 75, 87, 88, 96, 125, 130, 162, 163, 168, 169, 257, 285, 308, 310, 337, 373, 392},
200
+new short[]{18, 40, 42, 47, 73, 76, 85, 105, 108, 125, 130, 132, 134, 167, 191, 284, 310, 311, 344, 358, 361, 374, 378, 379},
201
+new short[]{5, 19, 29, 31, 48, 65, 98, 129, 131, 143, 165, 171, 172, 196, 198, 277, 296, 311, 317, 327, 351, 380},
202
+new short[]{51, 69, 96, 98, 117, 123, 130, 131, 148, 161, 168, 172, 176, 184, 202, 324, 332, 336, 348, 392},
203
+new short[]{1, 20, 37, 57, 70, 76, 79, 87, 165, 176, 234, 251, 333, 388},
204
+new short[]{8, 13, 134, 135, 153, 165, 169, 193, 195, 255, 273, 337, 348, 359, 360, 382, 391},
205
+new short[]{2, 14, 53, 71, 83, 127, 136, 144, 149, 208, 234, 235, 293, 301, 347, 352},
206
+new short[]{20, 40, 42, 95, 135, 141, 165, 199, 250, 290, 299, 308, 337, 338, 350, 353, 354, 355, 358, 380},
207
+new short[]{13, 19, 33, 35, 36, 49, 85, 121, 122, 127, 137, 158, 165, 282, 303, 320, 328, 334, 365, 367, 374},
208
+new short[]{17, 37, 123, 126, 127, 139, 140, 143, 167, 185, 192, 235, 254, 275, 315, 340, 349, 353, 362},
209
+new short[]{57, 72, 127, 159, 163, 165, 176, 199, 215, 218, 238, 254, 284, 288, 336, 339, 347, 352, 380, 395},
210
+new short[]{54, 69, 81, 101, 114, 121, 165, 206, 236, 313, 332, 338, 349, 358, 360, 362, 377},
211
+new short[]{29, 37, 43, 120, 127, 176, 193, 244, 246, 254, 284, 288, 336, 339, 372},
212
+new short[]{36, 56, 85, 122, 125, 126, 154, 232, 282, 308, 314, 315, 324, 336, 353, 359, 382},
213
+new short[]{7, 99, 104, 117, 124, 125, 143, 176, 239, 298, 318, 383},
214
+new short[]{13, 20, 71, 90, 108, 122, 176, 186, 214, 231, 247, 262, 267, 280, 286, 300, 332, 358, 377, 380, 385, 390, 393},
215
+new short[]{31, 65, 75, 79, 85, 91, 109, 110, 120, 159, 229, 235, 288, 298, 347, 355, 359, 379, 381},
216
+new short[]{38, 75, 82, 90, 99, 202, 248, 265, 324, 329, 350, 354, 355, 365},
217
+new short[]{7, 15, 72, 90, 117, 125, 140, 144, 171, 198, 269, 271, 282, 305, 325, 338, 343, 353},
218
+new short[]{13, 14, 20, 29, 37, 42, 45, 47, 165, 184, 244, 329, 341, 347, 372},
219
+new short[]{31, 36, 82, 99, 149, 154, 173, 182, 185, 200, 217, 251, 298, 329, 332, 333, 349, 353, 354, 355, 377, 383},
220
+new short[]{32, 44, 45, 52, 93, 97, 108, 114, 120, 144, 155, 172, 236, 240, 267, 272, 282, 288, 329, 333, 334, 343, 381},
221
+new short[]{35, 55, 57, 62, 95, 96, 98, 127, 131, 177, 262, 317, 318, 357, 359, 380, 388},
222
+new short[]{22, 24, 68, 103, 115, 119, 120, 125, 128, 156, 162, 184, 186, 235, 244, 327, 353, 358, 378, 380, 393},
223
+new short[]{29, 37, 62, 67, 81, 83, 93, 104, 110, 129, 132, 142, 172, 274, 298, 354, 380},
224
+new short[]{19, 45, 66, 87, 104, 108, 118, 155, 170, 176, 234, 286, 310, 313, 327, 329, 333, 347, 358, 368, 380, 383, 386},
225
+new short[]{10, 14, 32, 83, 96, 131, 165, 180, 205, 211, 249, 255, 286, 288, 292, 299, 312, 336, 338, 349, 368, 375},
226
+new short[]{2, 13, 48, 75, 85, 98, 116, 125, 126, 128, 135, 136, 151, 188, 195, 243, 280, 289, 333, 339, 349, 378, 382},
227
+new short[]{9, 19, 39, 45, 87, 106, 117, 125, 126, 127, 154, 165, 202, 211, 256, 309, 360, 397, 398},
228
+new short[]{14, 21, 65, 76, 87, 93, 97, 105, 131, 177, 212, 254, 294, 336, 349, 359, 381},
229
+new short[]{36, 55, 65, 70, 87, 93, 96, 98, 108, 127, 254, 337, 352, 359, 375, 380},
230
+new short[]{22, 42, 62, 82, 131, 132, 136, 158, 168, 196, 267, 305, 336},
231
+new short[]{45, 69, 74, 75, 81, 120, 123, 126, 127, 130, 150, 171, 191, 194, 313, 339, 368, 378, 379, 389, 398},
232
+new short[]{35, 43, 85, 98, 122, 131, 135, 176, 189, 250, 259, 277, 288, 303, 333, 336, 345, 376, 381, 387},
233
+new short[]{1, 6, 34, 87, 115, 129, 131, 202, 235, 252, 256, 263, 317, 328, 349, 372, 391},
234
+new short[]{3, 18, 42, 48, 84, 90, 92, 138, 193, 227, 288, 310, 315, 353, 375},
235
+new short[]{2, 10, 31, 66, 124, 145, 240, 314, 334},
236
+new short[]{32, 38, 84, 141, 165, 188, 193, 212, 346, 359, 379, 380},
237
+new short[]{10, 75, 81, 96, 111, 140, 179, 298, 309, 353, 357, 359, 380, 396},
238
+new short[]{2, 34, 121, 127, 132, 134, 184, 234, 244, 251, 262, 290, 308, 359, 380},
239
+new short[]{17, 24, 93, 172, 186, 198, 218, 234, 239, 250, 252, 255, 307, 309, 325, 334, 354, 359},
240
+new short[]{14, 18, 45, 50, 131, 174, 211, 237, 252, 267, 309, 334, 348, 351, 377, 391},
241
+new short[]{32, 61, 87, 97, 125, 126, 132, 184, 249, 252, 273, 284, 288, 339, 383, 398},
242
+new short[]{76, 81, 87, 127, 147, 161, 163, 199, 206, 306, 329, 340, 349, 353, 360, 383},
243
+new short[]{14, 16, 76, 87, 101, 169, 188, 243, 246, 251, 253, 269, 298, 355, 375, 380},
244
+new short[]{32, 79, 87, 103, 117, 125, 127, 177, 244, 301, 305, 317, 333, 338, 340, 342, 391},
245
+new short[]{4, 67, 76, 121, 127, 130, 140, 158, 165, 186, 193, 251, 301, 303, 330, 336},
246
+new short[]{11, 76, 83, 84, 87, 214, 248, 276, 299, 311, 320, 329, 332, 335, 371},
247
+new short[]{2, 4, 19, 40, 42, 71, 98, 119, 121, 137, 167, 262, 288, 295, 306, 339, 350, 382},
248
+new short[]{14, 40, 54, 90, 125, 129, 132, 146, 147, 165, 169, 176, 190, 253, 284, 303, 307, 316, 339, 342, 359, 389},
249
+new short[]{47, 59, 71, 103, 125, 126, 129, 130, 200, 206, 240, 254, 276, 282, 299, 303, 307, 318, 320, 336, 338, 357, 362, 380, 387, 392},
250
+new short[]{4, 22, 58, 102, 113, 115, 153, 167, 188, 212, 262, 286, 305, 333, 348, 354, 360, 371, 379, 386},
251
+new short[]{5, 6, 56, 61, 108, 128, 129, 164, 165, 177, 182, 225, 226, 235, 244, 246, 249, 310, 333, 348, 349, 381, 391},
252
+new short[]{18, 32, 33, 53, 56, 176, 186, 199, 200, 244, 246, 248, 259, 285, 289, 306, 358, 371, 373, 375, 379},
253
+new short[]{40, 43, 70, 76, 83, 84, 90, 93, 101, 125, 159, 204, 276, 282, 304, 320, 339, 351, 353, 367, 391},
254
+new short[]{14, 19, 59, 71, 76, 87, 93, 97, 105, 111, 120, 121, 122, 154, 171, 211, 231, 244, 286, 288, 341, 351},
255
+new short[]{10, 56, 65, 72, 92, 108, 123, 129, 212, 258, 329, 353, 359},
256
+new short[]{5, 76, 124, 127, 161, 172, 188, 244, 250, 266, 290, 318, 347, 351, 369, 382, 391, 395},
257
+new short[]{1, 33, 86, 120, 121, 130, 154, 162, 173, 192, 241, 244, 262, 338, 339, 343, 353, 380, 390},
258
+new short[]{1, 15, 22, 54, 57, 85, 126, 127, 176, 188, 248, 305, 332, 347, 349, 358, 367},
259
+new short[]{91, 111, 122, 125, 130, 178, 190, 224, 225, 226, 235, 286, 308, 329, 334, 345, 346, 349, 358, 362, 367},
260
+new short[]{16, 26, 51, 54, 84, 85, 98, 120, 272, 319, 349, 359, 360, 362, 377, 391, 398},
261
+new short[]{73, 85, 102, 109, 128, 153, 171, 184, 248, 249, 256, 298, 300, 335, 338, 340, 355, 370},
262
+new short[]{9, 108, 122, 131, 164, 168, 173, 176, 195, 218, 235, 286, 341, 350, 353, 358, 375, 377},
263
+new short[]{25, 62, 125, 140, 165, 173, 200, 225, 226, 243, 283, 286, 329, 343, 357, 366, 377},
264
+new short[]{10, 35, 58, 64, 98, 103, 125, 127, 129, 135, 141, 165, 169, 175, 189, 244, 258, 259, 306, 331, 333, 378, 380, 391},
265
+new short[]{54, 87, 89, 99, 116, 125, 129, 221, 246, 269, 324, 335, 348, 351},
266
+new short[]{85, 90, 103, 115, 131, 134, 165, 207, 282, 307, 313, 328, 346, 349, 380, 383, 387, 398},
267
+new short[]{10, 40, 74, 84, 160, 239, 253, 272, 282, 333, 344, 351, 359, 360, 379},
268
+new short[]{32, 38, 54, 74, 76, 117, 163, 171, 176, 217, 227, 250, 251, 280, 329, 330, 350, 378},
269
+new short[]{13, 20, 40, 107, 129, 135, 154, 158, 161, 163, 179, 206, 281, 315, 325, 351, 355, 359, 397},
270
+new short[]{0, 4, 37, 49, 62, 98, 117, 129, 177, 244, 285, 289, 306, 338, 360, 381},
271
+new short[]{36, 38, 43, 61, 71, 87, 120, 128, 172, 200, 235, 247, 251, 282, 299, 329, 341, 352, 355},
272
+new short[]{43, 71, 83, 85, 108, 117, 118, 121, 133, 138, 165, 206, 231, 254, 290, 291, 335, 336, 359, 362, 377},
273
+new short[]{29, 32, 71, 103, 122, 125, 198, 224, 244, 285, 303, 333, 335, 337},
274
+new short[]{54, 55, 82, 87, 101, 108, 127, 229, 230, 269, 290, 306, 349, 353},
275
+new short[]{9, 117, 126, 137, 154, 165, 167, 186, 192, 229, 277, 283, 301, 317, 365, 367, 372, 378},
276
+new short[]{4, 11, 19, 47, 51, 92, 110, 132, 137, 140, 290, 298, 361, 377, 379},
277
+new short[]{23, 83, 98, 134, 165, 170, 186, 190, 253, 269, 308, 322, 327, 332, 335, 344, 398},
278
+new short[]{60, 83, 111, 129, 173, 176, 186, 232, 306, 327, 329, 349, 355},
279
+new short[]{25, 31, 40, 56, 72, 95, 126, 144, 149, 161, 173, 240, 262, 332, 333, 356, 368, 391, 394},
280
+new short[]{91, 127, 134, 144, 155, 158, 161, 232, 251, 280, 287, 353, 380, 394},
281
+new short[]{37, 43, 57, 84, 87, 149, 175, 288, 330, 380},
282
+new short[]{8, 9, 83, 97, 120, 128, 158, 171, 193, 232, 287, 308, 309, 334, 355},
283
+new short[]{39, 40, 62, 82, 94, 98, 101, 144, 147, 205, 290, 333, 339, 353, 372, 397},
284
+new short[]{10, 20, 38, 125, 135, 138, 168, 180, 191, 203, 231, 250, 280, 301, 328, 345, 388},
285
+new short[]{44, 54, 64, 87, 117, 122, 127, 154, 234, 239, 244, 298, 329, 378, 383},
286
+new short[]{13, 62, 70, 97, 121, 176, 244, 267, 282, 318, 324, 334, 341, 353, 386, 388},
287
+new short[]{40, 89, 91, 117, 125, 131, 155, 173, 193, 244, 273, 277, 328, 333, 360, 382},
288
+new short[]{30, 47, 95, 108, 127, 165, 188, 211, 273, 349, 354, 368, 391},
289
+new short[]{19, 52, 87, 98, 100, 122, 125, 157, 159, 215, 217, 235, 254, 309, 336, 344, 349, 382},
290
+new short[]{19, 85, 87, 136, 144, 180, 190, 229, 310, 345, 365, 376, 390},
291
+new short[]{35, 52, 87, 113, 124, 135, 145, 167, 174, 225, 226, 244, 247, 300, 359},
292
+new short[]{10, 35, 69, 103, 129, 144, 165, 180, 230, 232, 329, 335, 353, 359, 371, 390},
293
+new short[]{5, 13, 80, 83, 135, 139, 142, 176, 179, 190, 205, 217, 282, 298, 308, 334, 353, 359},
294
+new short[]{24, 52, 67, 108, 135, 138, 153, 176, 231, 249, 283, 304, 337, 351, 353, 355},
295
+new short[]{90, 93, 127, 132, 136, 163, 165, 196, 284, 306, 353, 383},
296
+new short[]{20, 37, 103, 126, 135, 184, 204, 215, 221, 288, 300, 329, 339, 358, 383},
297
+new short[]{16, 36, 52, 99, 117, 136, 171, 190, 243, 244, 303, 315, 333, 349, 373, 382},
298
+new short[]{0, 57, 69, 98, 125, 129, 132, 158, 165, 190, 191, 193, 198, 254, 256, 285, 288, 303, 339, 346, 351, 391},
299
+new short[]{1, 13, 21, 87, 125, 132, 150, 204, 240, 249, 253, 265, 288, 334, 343, 348, 349, 359},
300
+new short[]{29, 40, 71, 80, 91, 99, 122, 203, 289, 290, 298, 329, 353, 380, 390},
301
+new short[]{2, 5, 36, 57, 93, 102, 135, 140, 314, 343, 398},
302
+new short[]{20, 59, 107, 193, 204, 246, 247, 336, 341, 342, 354, 359, 360, 383},
303
+new short[]{47, 71, 93, 111, 116, 120, 122, 130, 251, 286, 298, 299, 348},
304
+new short[]{21, 52, 56, 69, 76, 118, 120, 125, 137, 274, 280, 324, 327, 335, 339, 340},
305
+new short[]{23, 29, 57, 75, 98, 132, 149, 157, 160, 235, 244, 288, 327, 340, 354, 372, 377},
306
+new short[]{4, 22, 97, 103, 111, 129, 131, 151, 158, 176, 204, 248, 265, 309, 359, 391, 392},
307
+new short[]{15, 17, 73, 105, 115, 170, 186, 228, 255, 317, 321, 339, 349, 379, 380, 381},
308
+new short[]{17, 52, 72, 103, 188, 329, 342, 353, 358, 359, 374, 376, 380, 393},
309
+new short[]{40, 48, 74, 124, 135, 191, 225, 226, 237, 291, 300, 304, 310, 347, 359, 380, 396},
310
+new short[]{2, 36, 47, 57, 122, 125, 174, 188, 203, 224, 255, 325, 353, 359, 387},
311
+new short[]{13, 58, 69, 83, 115, 120, 134, 161, 165, 174, 175, 191, 246, 255, 280, 353, 357, 358, 359, 379},
312
+new short[]{1, 29, 47, 87, 89, 135, 176, 190, 209, 236, 304, 344, 348, 358, 359, 378},
313
+new short[]{8, 13, 40, 52, 58, 61, 71, 125, 144, 168, 189, 210, 260, 337, 338, 340, 347, 376, 380},
314
+new short[]{29, 90, 126, 127, 129, 136, 145, 159, 165, 188, 274, 284, 288, 316, 329, 358, 380},
315
+new short[]{2, 19, 103, 120, 123, 159, 165, 175, 177, 180, 238, 244, 251, 294, 329, 342, 345, 349, 357, 376, 392},
316
+new short[]{41, 42, 59, 71, 81, 98, 101, 117, 159, 171, 180, 240, 285, 290, 299, 344, 353},
317
+new short[]{83, 103, 108, 142, 175, 248, 290, 300, 321, 354, 365, 374, 382},
318
+new short[]{12, 67, 105, 130, 140, 171, 188, 192, 244, 276, 290, 302, 348, 349, 357, 360, 380},
319
+new short[]{4, 13, 36, 65, 75, 160, 165, 185, 198, 235, 293, 324, 327, 333, 345, 347, 375, 383},
320
+new short[]{37, 61, 80, 125, 234, 283, 290, 353, 359, 378, 383},
321
+new short[]{9, 32, 83, 110, 155, 248, 252, 288, 313},
322
+new short[]{37, 48, 52, 93, 167, 170, 179, 244, 267, 288, 296, 333, 335, 355, 374},
323
+new short[]{35, 92, 98, 153, 165, 184, 215, 233, 242, 290, 339, 355},
324
+new short[]{9, 38, 83, 121, 127, 165, 176, 235, 253, 305, 330, 337, 355, 358, 359},
325
+new short[]{35, 117, 122, 125, 132, 136, 183, 235, 254, 280, 285, 286, 329, 334, 338, 353, 372},
326
+new short[]{6, 87, 117, 125, 141, 144, 153, 157, 179, 215, 267, 272, 289, 329, 336, 359},
327
+new short[]{7, 14, 37, 82, 135, 147, 154, 202, 244, 290, 297, 298, 345, 355, 368, 383},
328
+new short[]{105, 135, 173, 244, 255, 280, 288, 299, 304, 307, 337, 338, 341, 344},
329
+new short[]{19, 31, 33, 77, 92, 99, 114, 151, 173, 202, 253, 318, 329, 333, 358, 371},
330
+new short[]{1, 8, 14, 30, 39, 120, 157, 172, 227, 229, 251, 257, 272, 339, 380},
331
+new short[]{19, 98, 171, 191, 213, 246, 289, 353, 357, 366, 374, 383},
332
+new short[]{8, 98, 125, 126, 144, 152, 244, 277, 282, 290, 322, 393},
333
+new short[]{17, 206, 211, 224, 336, 338, 386},
334
+new short[]{52, 55, 71, 99, 105, 191, 211, 215, 224, 246, 290, 300, 336, 339, 361},
335
+new short[]{15, 16, 44, 66, 96, 121, 127, 162, 167, 202, 219, 243, 244, 254, 282, 320, 345, 390},
336
+new short[]{7, 83, 92, 121, 130, 160, 177, 280, 308, 309, 339, 350, 352, 358, 380, 390},
337
+new short[]{67, 122, 144, 148, 170, 173, 184, 222, 280, 374},
338
+new short[]{2, 4, 15, 19, 115, 130, 136, 148, 172, 180, 243, 251, 313, 329, 333, 359, 364},
339
+new short[]{90, 98, 108, 124, 167, 176, 202, 254, 286, 351, 359},
340
+new short[]{80, 126, 135, 167, 212, 242, 243, 256, 283, 286, 295, 327, 337, 340, 346, 357, 358, 364},
341
+new short[]{19, 108, 125, 132, 149, 172, 180, 186, 200, 254, 286, 296, 339, 344, 350, 359, 391},
342
+new short[]{62, 65, 67, 105, 127, 129, 132, 250, 298, 307, 334, 344, 359, 383},
343
+new short[]{31, 59, 87, 107, 121, 131, 132, 160, 244, 246, 247, 253, 344, 360, 394},
344
+new short[]{4, 39, 76, 125, 130, 148, 168, 170, 191, 196, 298, 306, 327, 338, 345, 349, 360, 375},
345
+new short[]{13, 14, 32, 84, 98, 122, 126, 156, 188, 235, 255, 330, 336, 338, 375, 380, 389},
346
+new short[]{5, 18, 31, 54, 71, 74, 76, 81, 87, 93, 126, 129, 182, 303, 327, 353, 359, 373, 391},
347
+new short[]{13, 37, 64, 137, 138, 180, 244, 247, 251, 253, 269, 284, 308, 344, 374, 376},
348
+new short[]{5, 7, 10, 23, 35, 125, 168, 169, 187, 191, 192, 313, 337, 340, 342, 365},
349
+new short[]{62, 67, 122, 125, 165, 190, 217, 243, 254, 256, 265, 299, 318, 353, 394},
350
+new short[]{4, 24, 62, 92, 109, 118, 134, 143, 144, 176, 190, 199, 221, 299, 349, 380},
351
+new short[]{22, 35, 64, 74, 92, 113, 161, 172, 193, 282, 287, 307, 359, 393},
352
+new short[]{37, 50, 66, 75, 76, 78, 82, 87, 139, 159, 172, 176, 188, 231, 352, 371},
353
+new short[]{19, 31, 75, 121, 144, 152, 163, 171, 172, 198, 243, 246, 285, 288, 289, 333, 344, 347, 357, 398},
354
+new short[]{1, 15, 17, 51, 57, 65, 69, 127, 241, 244, 254, 259, 329, 336, 358},
355
+new short[]{9, 95, 117, 121, 125, 137, 204, 242, 247, 301, 309, 314, 334, 339, 350, 354, 358},
356
+new short[]{9, 61, 96, 111, 130, 163, 180, 211, 225, 226, 241, 253, 282, 283, 346, 355, 359, 380, 383},
357
+new short[]{94, 117, 121, 124, 126, 130, 135, 172, 199, 232, 286, 325, 336, 352, 362, 375},
358
+new short[]{110, 125, 163, 250, 265, 303, 329, 334, 391},
359
+new short[]{47, 72, 76, 111, 125, 157, 169, 245, 254, 285, 287, 297, 298, 336, 353, 359, 383},
360
+new short[]{62, 93, 115, 125, 127, 130, 174, 231, 308, 310, 329, 333, 355, 359, 390},
361
+new short[]{44, 116, 163, 167, 180, 191, 200, 245, 254, 329, 343, 345, 354, 364},
362
+new short[]{31, 62, 105, 108, 144, 145, 162, 173, 177, 191, 198, 247, 249, 344, 345, 348, 353},
363
+new short[]{29, 65, 66, 74, 83, 87, 125, 148, 165, 228, 334, 353, 359, 380, 383, 391},
364
+new short[]{2, 15, 125, 130, 239, 290, 312, 336, 337, 341, 398},
365
+new short[]{40, 76, 87, 114, 119, 120, 165, 229, 265, 313, 324, 349, 358, 383},
366
+new short[]{48, 62, 87, 91, 103, 186, 195, 212, 214, 315, 322, 327, 330, 338, 339},
367
+new short[]{9, 32, 85, 108, 135, 191, 224, 237, 257, 288, 307, 310, 313, 318, 329, 337, 352, 395},
368
+new short[]{87, 93, 102, 112, 129, 154, 171, 236, 317, 320, 349, 350, 359, 380},
369
+new short[]{1, 14, 92, 111, 137, 140, 186, 290, 329, 336, 354, 355, 378, 379, 383},
370
+new short[]{7, 26, 37, 47, 84, 101, 144, 153, 175, 180, 198, 232, 243, 305, 333, 353, 357, 383},
371
+new short[]{20, 58, 76, 93, 99, 127, 134, 154, 188, 206, 246, 312, 313, 324},
372
+new short[]{2, 12, 117, 125, 160, 167, 188, 206, 279, 285, 287, 301, 329, 332, 333, 336, 344, 362},
373
+new short[]{2, 76, 126, 127, 137, 165, 244, 288, 290, 339, 346, 351, 359, 365, 383},
374
+new short[]{66, 108, 136, 151, 174, 265, 344, 351, 353, 357, 378, 386},
375
+new short[]{8, 76, 87, 90, 111, 116, 124, 176, 198, 334, 337, 349, 359, 379, 394},
376
+new short[]{32, 36, 42, 76, 81, 125, 127, 205, 227, 262, 280, 288, 326, 336, 390, 398},
377
+new short[]{9, 32, 65, 83, 89, 93, 97, 122, 129, 178, 180, 215, 241, 246, 323, 332, 353, 362, 364, 380},
378
+new short[]{5, 24, 56, 127, 130, 155, 184, 191, 217, 235, 245, 339, 344, 358, 359, 362, 380},
379
+new short[]{14, 40, 64, 71, 93, 108, 131, 165, 188, 204, 217, 235, 237, 241, 248, 308, 309, 318, 380, 387},
380
+new short[]{17, 29, 34, 74, 125, 175, 184, 196, 211, 275, 301, 318, 327, 334, 349, 355, 358, 368},
381
+new short[]{15, 45, 110, 111, 116, 129, 132, 211, 247, 275, 286, 317, 333, 334, 377, 383},
382
+new short[]{4, 5, 59, 87, 103, 124, 125, 127, 130, 165, 241, 265, 299, 353, 360},
383
+new short[]{31, 120, 124, 135, 154, 197, 235, 243, 247, 248, 258, 309, 320, 335, 357},
384
+new short[]{50, 125, 127, 130, 137, 147, 171, 172, 267, 289, 301, 308, 325, 334, 337, 353, 360, 374, 391},
385
+new short[]{62, 64, 69, 87, 111, 118, 129, 134, 212, 239, 244, 246, 250, 254, 307, 322, 329, 370, 372},
386
+new short[]{54, 92, 128, 160, 198, 244, 248, 255, 284, 314, 335, 349, 358, 360, 376, 380},
387
+new short[]{9, 13, 29, 54, 72, 89, 110, 122, 126, 139, 158, 159, 163, 230, 304, 306, 313},
388
+new short[]{1, 9, 54, 95, 108, 132, 176, 193, 243, 251, 339, 378},
389
+new short[]{0, 96, 99, 135, 137, 184, 212, 232, 251, 315, 334},
390
+new short[]{140, 157, 165, 182, 235, 294, 314, 349, 354, 365},
391
+new short[]{14, 18, 31, 56, 117, 125, 138, 227, 246, 283, 334, 345, 352, 357, 361},
392
+new short[]{0, 71, 82, 130, 131, 144, 161, 235, 247, 301, 333, 335, 345, 353, 355, 359, 360, 374},
393
+new short[]{6, 23, 35, 117, 125, 141, 169, 200, 244, 288, 298, 338, 353, 379},
394
+new short[]{10, 98, 125, 127, 138, 153, 219, 244, 307, 350, 353, 366, 367},
395
+new short[]{9, 32, 40, 122, 126, 127, 170, 176, 300, 334, 350, 391},
396
+new short[]{6, 13, 31, 87, 89, 97, 125, 165, 171, 173, 176, 244, 331, 348, 373},
397
+new short[]{10, 61, 87, 105, 123, 125, 127, 195, 260, 265, 323, 361, 362},
398
+new short[]{2, 20, 90, 124, 353, 354, 378, 382},
399
+new short[]{5, 48, 58, 83, 98, 117, 125, 126, 196, 198},
400
+new short[]{13, 37, 50, 64, 66, 79, 99, 132, 135, 244, 247, 380},
401
+new short[]{57, 165, 235, 238, 248, 272, 287, 299, 327, 329, 334, 350, 353, 380},
402
+new short[]{55, 66, 118, 125, 130, 169, 250, 255, 271, 314, 324, 338, 353},
403
+new short[]{7, 31, 62, 84, 103, 105, 111, 126, 132, 149, 154, 191, 250, 334, 372, 375},
404
+new short[]{56, 81, 114, 117, 120, 124, 127, 128, 154, 254, 290, 317, 345, 354},
405
+new short[]{4, 13, 86, 101, 153, 191, 193, 231, 243, 258, 283, 288, 308, 353, 387, 392},
406
+new short[]{5, 37, 58, 62, 67, 84, 87, 176, 237, 267, 333, 334, 347},
407
+new short[]{1, 7, 74, 110, 165, 168, 182, 233, 288, 305, 309, 315, 347, 351, 353, 358, 360, 375},
408
+new short[]{57, 84, 129, 138, 165, 243, 244, 259, 280, 282, 290, 380, 383}
409
+};
410
+  }
411
+}

+ 133
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/RegexRuleExtension.cs 查看文件

@@ -0,0 +1,133 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Windows;
6
+using Platform.Controls.ControlsHelper;
7
+
8
+namespace TellerSystem.Library.Ext.TradeExtension
9
+{
10
+    public class RegexRuleExtension
11
+    {
12
+        #region ctor
13
+        static RegexRuleExtension()
14
+        {
15
+            LoadData();
16
+        }
17
+
18
+        /// <summary>
19
+        /// 标志-防止重复加载
20
+        /// </summary>
21
+        static bool flag = false;
22
+
23
+        /// <summary>
24
+        /// 加载数据
25
+        /// </summary>
26
+        public static void LoadData()
27
+        {
28
+            if (flag) return;
29
+            flag = true;
30
+            //静态构造方法,加载输入规则
31
+            RegexValidationRules.Instance.AddRule(InputRules.None.ToString(), "", "");
32
+           // RegexValidationRules.Instance.AddRule(InputRules.Telephone.ToString(), @"^\s*$|(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7}", "请输入正确的固定电话号码!");
33
+            RegexValidationRules.Instance.AddRule(InputRules.Telephone.ToString(), @"^([0-9]{3,4}\-[0-9]{6,8}$)|(^\([0-9]{3,4}\)[0-9]{6,8}$)", "请输入正确的固定电话号码,电话加区号!");
34
+            RegexValidationRules.Instance.AddRule(InputRules.Fax.ToString(), @"^\s*$|(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7}", "请输入正确的传真号码!");
35
+            //RegexValidationRules.Instance.AddRule(InputRules.MobilePhone.ToString(), @"^\s*$|1[0-9]{10}", "请输入正确的手机号码!");
36
+            RegexValidationRules.Instance.AddRule(InputRules.MobilePhone.ToString(), @"^1[0-9]{10}$", "请输入正确的手机号码,11位!");
37
+            RegexValidationRules.Instance.AddRule(InputRules.NumberStr.ToString(), @"^\s*$|^[0-9]*$", "请输入数字串!");
38
+            RegexValidationRules.Instance.AddRule(InputRules.PaymentSystem.ToString(), "^[^:%'\"]*$", "不允许使用支付系统规定的保留字!");
39
+            RegexValidationRules.Instance.AddRule(InputRules.NumLetter.ToString(), @"^\s*$|^[A-Za-z0-9]*$", "只允许输入数字和字母!");
40
+            RegexValidationRules.Instance.AddRule(InputRules.NameLetter.ToString(), @"^\s*$|^[a-zA-Z0-9\u4e00-\u9fa5]*$", "只允许输入数字、字母、中文!");
41
+            RegexValidationRules.Instance.AddRule(InputType.Date.ToString(), @"(^99999999$)|(^(?:(?:(?:(?:(?:1[6-9]|[2-9]\d)(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(?:0229))|(?:(?:(?:1[6-9]|[2-9]\d)\d{2})(?:(?:(?:0[13578]|1[02])31)|(?:(?:0[13-9]|1[0-2])(?:29|30))|(?:(?:0[1-9])|(?:1[0-2]))(?:0[1-9]|1\d|2[0-8]))))$)", "日期格式20120101,请重新输入。");
42
+            RegexValidationRules.Instance.AddRule(InputRules.RateLetter.ToString(), @"^(-?\d+)(\.\d+)?{0,6}$", "只允许输入浮点数,且小数点后6位");
43
+            RegexValidationRules.Instance.AddRule(InputRules.NoChinese.ToString(), @"^\s*$|[^\u4e00-\u9fa5]", "不允许输入中文!");
44
+            RegexValidationRules.Instance.AddRule(InputRules.TelephoneOrMobilePhone.ToString(), @"^([0-9]{3,4}\-[0-9]{6,8}$)|(^1[0-9]{10}$)|(^\([0-9]{3,4}\)[0-9]{6,8}$)", "手机号11位,电话需要增加区号!");
45
+            RegexValidationRules.Instance.AddRule(InputRules.DoubleNumBer.ToString(), @"^\d+(\.\d+)?$", "只允许输入整数或小数");
46
+            RegexValidationRules.Instance.AddRule(InputRules.DateZM.ToString(), @"(^\d{4}(0[1-9]|1[0-2])$)|(^99999999$)|(^(?:(?:(?:(?:(?:1[6-9]|[2-9]\d)(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(?:0229))|(?:(?:(?:1[6-9]|[2-9]\d)\d{2})(?:(?:(?:0[13578]|1[02])31)|(?:(?:0[13-9]|1[0-2])(?:29|30))|(?:(?:0[1-9])|(?:1[0-2]))(?:0[1-9]|1\d|2[0-8]))))$)", "日期格式20120101或者201201,请重新输入。");
47
+            
48
+      }
49
+        #endregion
50
+
51
+        #region InputRule - 输入规则
52
+        /// <summary>
53
+        /// 指定用户可输入的数据类型
54
+        /// </summary>
55
+        public static readonly DependencyProperty InputRuleProperty =
56
+            DependencyProperty.RegisterAttached("InputRule", typeof(InputRules), typeof(RegexRuleExtension),
57
+                new UIPropertyMetadata((InputRules.None),
58
+                    new PropertyChangedCallback(OnInputRuleChanged)));
59
+        public static InputRules GetInputType(DependencyObject d)
60
+        {
61
+            return (InputRules)d.GetValue(InputRuleProperty);
62
+        }
63
+        public static void SetInputType(DependencyObject d, InputRules value)
64
+        {
65
+            d.SetValue(InputRuleProperty, value);
66
+        }
67
+        public static void OnInputRuleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
68
+        {
69
+            //直接引导到底层输入控制,具体规则由本类的静态构造方法产生
70
+            TextBoxHelper.SetInputRule(d, e.NewValue.ToString());
71
+        }
72
+        #endregion
73
+    }
74
+
75
+    /// <summary>
76
+    /// 输入规则
77
+    /// </summary>
78
+    public enum InputRules
79
+    {
80
+        /// <summary>
81
+        /// 无限制
82
+        /// </summary>
83
+        None,
84
+        /// <summary>
85
+        /// 固定电话
86
+        /// </summary>
87
+        Telephone,
88
+        /// <summary>
89
+        /// 移动电话
90
+        /// </summary>
91
+        MobilePhone,
92
+        /// <summary>
93
+        /// 传真
94
+        /// </summary>
95
+        Fax,
96
+        /// <summary>
97
+        /// 数字串
98
+        /// </summary>
99
+        NumberStr,
100
+        /// <summary>
101
+        /// 支付系统保留字控制
102
+        /// </summary>
103
+        PaymentSystem,
104
+        /// <summary>
105
+        /// 数字字母
106
+        /// </summary>
107
+        NumLetter,
108
+        /// <summary>
109
+        /// 名称串
110
+        /// </summary>
111
+        NameLetter,
112
+        /// <summary>
113
+        /// 正Double数字
114
+        /// </summary>
115
+        RateLetter,
116
+        /// <summary>
117
+        /// 非中文
118
+        /// </summary>
119
+        NoChinese,
120
+        /// <summary>
121
+        /// 电话或手机
122
+        /// </summary>
123
+        TelephoneOrMobilePhone,
124
+        /// <summary>
125
+        /// 正Double数字
126
+        /// </summary>
127
+        DoubleNumBer,
128
+        /// <summary>
129
+        /// 年月日或者年月
130
+        /// </summary>
131
+        DateZM
132
+    }
133
+}

+ 124
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/RegexRuleExtension.ts 查看文件

@@ -0,0 +1,124 @@
1
+// 模拟 DependencyObject 类
2
+class DependencyObject {
3
+    private properties: { [key: string]: any } = {};
4
+
5
+    getValue(key: string): any {
6
+        return this.properties[key];
7
+    }
8
+
9
+    setValue(key: string, value: any): void {
10
+        this.properties[key] = value;
11
+    }
12
+}
13
+
14
+// 模拟 UIPropertyMetadata 类
15
+class UIPropertyMetadata {
16
+    constructor(public defaultValue: any, public propertyChangedCallback?: (d: DependencyObject, e: any) => void) {}
17
+}
18
+
19
+// 模拟 DependencyProperty 类
20
+class DependencyProperty {
21
+    constructor(
22
+        public name: string,
23
+        public type: any,
24
+        public ownerType: any,
25
+        public metadata: UIPropertyMetadata
26
+    ) {}
27
+
28
+    static registerAttached(name: string, type: any, ownerType: any, metadata: UIPropertyMetadata): DependencyProperty {
29
+        return new DependencyProperty(name, type, ownerType, metadata);
30
+    }
31
+}
32
+
33
+// 模拟 RegexValidationRules 类
34
+class RegexValidationRules {
35
+    private static _instance: RegexValidationRules;
36
+    private rules: { [key: string]: { pattern: string; message: string } } = {};
37
+
38
+    private constructor() {}
39
+
40
+    static get Instance(): RegexValidationRules {
41
+        if (!this._instance) {
42
+            this._instance = new RegexValidationRules();
43
+        }
44
+        return this._instance;
45
+    }
46
+
47
+    AddRule(key: string, pattern: string, message: string): void {
48
+        this.rules[key] = { pattern, message };
49
+    }
50
+}
51
+
52
+// 模拟 TextBoxHelper 类
53
+class TextBoxHelper {
54
+    static SetInputRule(d: DependencyObject, value: string): void {
55
+        // 这里可以实现具体的输入规则设置逻辑
56
+        console.log(`Setting input rule: ${value}`);
57
+    }
58
+}
59
+
60
+// 定义 InputRules 枚举
61
+enum InputRules {
62
+    None,
63
+    Telephone,
64
+    MobilePhone,
65
+    Fax,
66
+    NumberStr,
67
+    PaymentSystem,
68
+    NumLetter,
69
+    NameLetter,
70
+    RateLetter,
71
+    NoChinese,
72
+    TelephoneOrMobilePhone,
73
+    DoubleNumBer,
74
+    DateZM
75
+}
76
+
77
+// 定义 RegexRuleExtension 类
78
+class RegexRuleExtension {
79
+    private static flag = false;
80
+
81
+    static readonly InputRuleProperty: DependencyProperty = DependencyProperty.registerAttached(
82
+        "InputRule",
83
+        InputRules,
84
+        RegexRuleExtension,
85
+        new UIPropertyMetadata(InputRules.None, RegexRuleExtension.OnInputRuleChanged)
86
+    );
87
+
88
+    static {
89
+        this.LoadData();
90
+    }
91
+
92
+    static LoadData(): void {
93
+        if (this.flag) return;
94
+        this.flag = true;
95
+
96
+        RegexValidationRules.Instance.AddRule(InputRules.None.toString(), "", "");
97
+        RegexValidationRules.Instance.AddRule(InputRules.Telephone.toString(), @"^([0-9]{3,4}\-[0-9]{6,8}$)|(^\([0-9]{3,4}\)[0-9]{6,8}$)", "请输入正确的固定电话号码,电话加区号!");
98
+        RegexValidationRules.Instance.AddRule(InputRules.Fax.toString(), @"^\s*$|(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7}", "请输入正确的传真号码!");
99
+        RegexValidationRules.Instance.AddRule(InputRules.MobilePhone.toString(), @"^1[0-9]{10}$", "请输入正确的手机号码,11位!");
100
+        RegexValidationRules.Instance.AddRule(InputRules.NumberStr.toString(), @"^\s*$|^[0-9]*$", "请输入数字串!");
101
+        RegexValidationRules.Instance.AddRule(InputRules.PaymentSystem.toString(), "^[^:%'\"]*$", "不允许使用支付系统规定的保留字!");
102
+        RegexValidationRules.Instance.AddRule(InputRules.NumLetter.toString(), @"^\s*$|^[A-Za-z0-9]*$", "只允许输入数字和字母!");
103
+        RegexValidationRules.Instance.AddRule(InputRules.NameLetter.toString(), @"^\s*$|^[a-zA-Z0-9\u4e00-\u9fa5]*$", "只允许输入数字、字母、中文!");
104
+        RegexValidationRules.Instance.AddRule(InputRules[InputRules.DateZM], @"(^\d{4}(0[1-9]|1[0-2])$)|(^99999999$)|(^(?:(?:(?:(?:(?:1[6-9]|[2-9]\d)(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(?:0229))|(?:(?:(?:1[6-9]|[2-9]\d)\d{2})(?:(?:(?:0[13578]|1[02])31)|(?:(?:0[13-9]|1[0-2])(?:29|30))|(?:(?:0[1-9])|(?:1[0-2]))(?:0[1-9]|1\d|2[0-8]))))$)", "日期格式20120101或者201201,请重新输入。");
105
+        RegexValidationRules.Instance.AddRule(InputRules.RateLetter.toString(), @"^(-?\d+)(\.\d+)?{0,6}$", "只允许输入浮点数,且小数点后6位");
106
+        RegexValidationRules.Instance.AddRule(InputRules.NoChinese.toString(), @"^\s*$|[^\u4e00-\u9fa5]", "不允许输入中文!");
107
+        RegexValidationRules.Instance.AddRule(InputRules.TelephoneOrMobilePhone.toString(), @"^([0-9]{3,4}\-[0-9]{6,8}$)|(^1[0-9]{10}$)|(^\([0-9]{3,4}\)[0-9]{6,8}$)", "手机号11位,电话需要增加区号!");
108
+        RegexValidationRules.Instance.AddRule(InputRules.DoubleNumBer.toString(), @"^\d+(\.\d+)?$", "只允许输入整数或小数");
109
+    }
110
+
111
+    static GetInputType(d: DependencyObject): InputRules {
112
+        return d.getValue(this.InputRuleProperty.name) as InputRules;
113
+    }
114
+
115
+    static SetInputType(d: DependencyObject, value: InputRules): void {
116
+        d.setValue(this.InputRuleProperty.name, value);
117
+    }
118
+
119
+    static OnInputRuleChanged(d: DependencyObject, e: any): void {
120
+        TextBoxHelper.SetInputRule(d, e.newValue.toString());
121
+    }
122
+}
123
+
124
+export { RegexRuleExtension, InputRules };

+ 59
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ReportWindow.xaml 查看文件

@@ -0,0 +1,59 @@
1
+<Window x:Class="TellerSystem.Library.Ext.TradeExtension.ReportWindow"
2
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5
+        xmlns:form="clr-namespace:Microsoft.Reporting.WinForms;assembly=Microsoft.ReportViewer.WinForms"
6
+        MinWidth="700"
7
+        MinHeight="500"
8
+        Icon="{DynamicResource Sys_Icon}"
9
+        TextOptions.TextFormattingMode="Display"
10
+        WindowStartupLocation="CenterScreen"
11
+        WindowState="Maximized">
12
+    <Grid>
13
+        <Grid.RowDefinitions>
14
+            <RowDefinition Height="Auto" />
15
+            <RowDefinition Height="*" />
16
+        </Grid.RowDefinitions>
17
+        <GroupBox Width="Auto"
18
+                  Margin="5"
19
+                  HorizontalAlignment="Stretch"
20
+                  Header="操作"
21
+                  Visibility="Collapsed">
22
+            <StackPanel Margin="5" Orientation="Horizontal">
23
+                <StackPanel.Resources>
24
+                    <Style BasedOn="{StaticResource {x:Type Button}}" TargetType="Button">
25
+                        <Setter Property="Width" Value="80" />
26
+                        <Setter Property="Height" Value="25" />
27
+                        <Setter Property="Margin" Value="5" />
28
+                    </Style>
29
+                </StackPanel.Resources>
30
+                <Button x:Name="btnPrint"
31
+                        Click="btnPrint_Click"
32
+                        Content="打印" />
33
+                <Button x:Name="btnExcel"
34
+                        Click="btnExcel_Click"
35
+                        Content="导出Excel" />
36
+                <Button x:Name="btnRefresh"
37
+                        Click="btnRefresh_Click"
38
+                        Content="刷新" />
39
+
40
+
41
+                <!--
42
+                    <Button x:Name="btnWord" Content="导出成Word" />
43
+                    <Button x:Name="btnPdf" Content="导出成pdf" />
44
+                -->
45
+            </StackPanel>
46
+        </GroupBox>
47
+        <GroupBox Grid.Row="1"
48
+                  Width="Auto"
49
+                  Margin="5"
50
+                  HorizontalAlignment="Stretch"
51
+                  VerticalAlignment="Stretch"
52
+                  Header="报表">
53
+            <WindowsFormsHost Margin="5">
54
+                <form:ReportViewer x:Name="Report" />
55
+            </WindowsFormsHost>
56
+        </GroupBox>
57
+
58
+    </Grid>
59
+</Window>

+ 95
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/ReportWindow.xaml.cs 查看文件

@@ -0,0 +1,95 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Windows;
6
+using System.Windows.Controls;
7
+using System.Windows.Data;
8
+using System.Windows.Documents;
9
+using System.Windows.Input;
10
+using System.Windows.Media;
11
+using System.Windows.Media.Imaging;
12
+using System.Windows.Shapes;
13
+using Microsoft.Reporting.WinForms;
14
+using System.Data;
15
+using Platform.Controls.ComponentContainer;
16
+using Platform.Controls.ControlsHelper;
17
+using TellerSystem.Library.Ext.TradeExtension;
18
+using TellerSystem.Library.Ext.Function;
19
+using System.Diagnostics;
20
+using TellerSystem.ServiceProxy.Ext.ServiceHelper;
21
+
22
+namespace TellerSystem.Library.Ext.TradeExtension
23
+{
24
+
25
+    /// <summary>
26
+    /// ReportWindow.xaml 的交互逻辑
27
+    /// </summary>
28
+    public partial class ReportWindow : Window
29
+    {
30
+        #region 属性
31
+        public DataBox Source { get; set; }
32
+        #endregion
33
+
34
+        public ReportWindow()
35
+        {
36
+            InitializeComponent();
37
+        }
38
+
39
+        private void btnPrint_Click(object sender, RoutedEventArgs e)
40
+        {
41
+            Process[] processes = Process.GetProcessesByName("Platform.PrintService");
42
+            if (processes.Length > 0)
43
+            {
44
+                foreach (Process process in processes)
45
+                {
46
+                    if (!process.HasExited)
47
+                        process.Kill();
48
+                }
49
+            }
50
+            Report.PrintDialog();
51
+            processes = Process.GetProcessesByName("Platform.PrintService");
52
+            if (processes.Length > 0)
53
+            {
54
+                foreach (Process process in processes)
55
+                {
56
+                    if (!process.HasExited)
57
+                        process.Kill();
58
+                }
59
+            }
60
+        }
61
+
62
+        private void btnExcel_Click(object sender, RoutedEventArgs e)
63
+        {
64
+            //Report.ExportDialog(new RenderingExtension());
65
+            if (Source != null)
66
+            {
67
+
68
+                DataTable table = Source.GetDataTableForPrint();
69
+                if (table != null)
70
+                {
71
+                    System.Windows.Forms.SaveFileDialog saveDialog = new System.Windows.Forms.SaveFileDialog { FileName = "fileName" };
72
+                    saveDialog.Filter = "Excel Files|*.xlsx;*.xls;";
73
+                    saveDialog.ShowDialog();
74
+                    var outputFile = saveDialog.FileName;
75
+                    if (outputFile.IndexOf(":", System.StringComparison.Ordinal) < 0)
76
+                        return; //被点了取消 
77
+                    var isByNPOI = TradeManagerHandle.TT_SYSCONFIG_GetConfigValueByConfigID("IsByNPOI");
78
+                    if (isByNPOI != null && isByNPOI.ToUpper() == "TRUE")
79
+                    {
80
+                        ExcelFuntion.ExportToExcel(table, outputFile);
81
+                    }
82
+                    else
83
+                    {
84
+                        ExcelFuntion.ExportExcelByDataTable(table, outputFile);
85
+                    }
86
+                }
87
+            }
88
+        }
89
+
90
+        private void btnRefresh_Click(object sender, RoutedEventArgs e)
91
+        {
92
+            Report.RefreshReport();
93
+        }
94
+    }
95
+}

+ 743
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/SSO/LoginAuthentication.cs 查看文件

@@ -0,0 +1,743 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Globalization;
4
+using System.Linq;
5
+using System.Text;
6
+using TellerSystem.ServiceProxy.Ext.ServiceHelper;
7
+using TellerSystem.Communication;
8
+using System.Management;
9
+using System.Security.Cryptography;
10
+using Platform.Common.RunningParameters;
11
+using System.Windows;
12
+using TellerSystem.Communication.SocketListener;
13
+using TellerSystem.ServiceProxy.Ext.TradeBusinessEntitys;
14
+using System.Runtime.Remoting.Contexts;
15
+using System.Runtime.CompilerServices;
16
+using System.Windows.Controls;
17
+using Platform.Presentation.Interfaces;
18
+using Microsoft.Win32;
19
+using System.Text.RegularExpressions;
20
+using Platform.Controls.ControlsHelper;
21
+
22
+namespace TellerSystem.Library.Ext.TradeExtension
23
+{
24
+    /// <summary>
25
+    /// 单点登录控制
26
+    /// </summary>
27
+    public class LoginAuthentication
28
+    {
29
+        #region 单例模式
30
+        private static LoginAuthentication _instance;
31
+        /// <summary>
32
+        /// 获取单列
33
+        /// </summary>
34
+        /// <returns></returns>
35
+        public static LoginAuthentication Instance
36
+        {
37
+            get
38
+            {
39
+                if (_instance == null)
40
+                    _instance = new LoginAuthentication();
41
+                return _instance;
42
+            }
43
+        }
44
+        #endregion
45
+
46
+        #region 私有变量
47
+        private string _tellerNo = string.Empty;
48
+        #endregion
49
+
50
+        #region 属性
51
+        /// <summary>
52
+        /// 开户行
53
+        /// </summary>
54
+        public string PaymentNo { get; set; }
55
+        /// <summary>
56
+        /// 用户ID
57
+        /// </summary>
58
+        public string USERID { get; private set; }
59
+        /// <summary>
60
+        /// 用户登录账号
61
+        /// </summary>
62
+        public string USERCODE { get; private set; }
63
+        /// <summary>
64
+        /// 姓名
65
+        /// </summary>
66
+        public string USERNAME { get; private set; }
67
+        /// <summary>
68
+        /// 是否单客户端
69
+        /// </summary>
70
+        public bool ISPIONT { get; private set; }
71
+        /// <summary>
72
+        /// 锁定标志
73
+        /// </summary>
74
+        public bool ISLOGIN { get; private set; }
75
+        /// <summary>
76
+        /// 所属机构
77
+        /// </summary>
78
+        public string KINBRID { get; private set; }
79
+        /// <summary>
80
+        /// ATM管理柜员
81
+        /// </summary>
82
+        public string MNGATMUSER { get; private set; }
83
+        /// <summary>
84
+        /// 用户密码
85
+        /// </summary>
86
+        public string USERPSW { get; private set; }
87
+        /// <summary>
88
+        /// IC卡ID
89
+        /// </summary>
90
+        public string CARDID { get; private set; }
91
+        /// <summary>
92
+        /// 上次修改密码日期
93
+        /// </summary>
94
+        public string PWDCHGDATE { get; private set; }
95
+        /// <summary>
96
+        /// 上次登录IP
97
+        /// </summary>
98
+        public string LOGINIP { get; private set; }
99
+        /// <summary>
100
+        /// 上次登录端口号
101
+        /// </summary>
102
+        public string PORTNO { get; private set; }
103
+        /// <summary>
104
+        /// 登录验证方式
105
+        /// </summary>
106
+        public string PSWLEVEL { get; private set; }
107
+        /// <summary>
108
+        /// 上次修改验证方式日期
109
+        /// </summary>
110
+        public string LEVELCHGDATE { get; private set; }
111
+        /// <summary>
112
+        /// 登录验证方式有效期
113
+        /// </summary>
114
+        public int LEVELDATE { get; private set; }
115
+        /// <summary>
116
+        /// IC卡管理级别
117
+        /// </summary>
118
+        public string CARDLEVEL { get; private set; }
119
+        /// <summary>
120
+        /// 登录修改密码
121
+        /// </summary>
122
+        public string ISCHANGEPSW { get; private set; }
123
+        /// <summary>
124
+        /// 上次登录时间
125
+        /// </summary>
126
+        public string BEFOREDATE { get; private set; }
127
+        /// <summary>
128
+        /// 连续密码错误次数
129
+        /// </summary>
130
+        public int PSWERRCOUNT { get; private set; }
131
+        /// <summary>
132
+        /// 上次密码错误时间
133
+        /// </summary>
134
+        public string PSWTIME { get; private set; }
135
+        /// <summary>
136
+        /// 当前系统日期
137
+        /// </summary>
138
+        public string DATE { get; private set; }
139
+        /// <summary>
140
+        /// 当前柜员状态
141
+        /// </summary>
142
+        public string CHENKSIGN { get; private set; }
143
+        /// <summary>
144
+        /// 最大密码修改周期
145
+        /// </summary>
146
+        public string MaxPswCycle { get; private set; }
147
+        /// <summary>
148
+        /// 是否允许强制登陆
149
+        /// </summary>
150
+        public bool CanForceLogin { get; private set; }
151
+        /// <summary>
152
+        /// 获取或设置机构号
153
+        /// </summary>
154
+        public string KinbrNo { get; private set; }
155
+        /// <summary>
156
+        /// 获取或设置是否跨终端登录
157
+        /// </summary>
158
+        public string IsAcross { get; private set; }
159
+
160
+        /// <summary>
161
+        /// 是否允许多角色登录
162
+        /// </summary>
163
+        public bool CanGroupsLogin { get; private set; }
164
+
165
+        /// <summary>
166
+        /// Gets IP addresss
167
+        /// </summary>
168
+        public string IPAddress { get; private set; }
169
+
170
+        /// <summary>
171
+        /// 用户角色
172
+        /// </summary>
173
+        public List<TT_RoleGroup> Usergroup { get; private set; }
174
+        /// <summary>
175
+        /// 执行强制下线操作
176
+        /// </summary>
177
+        public bool SetUserDown { get; private set; }
178
+        /// <summary>
179
+        /// 是否移动端
180
+        /// </summary>
181
+        public bool Ismobile { get; private set; }
182
+
183
+        /// <summary>
184
+        /// 柜员选择角色
185
+        /// </summary>
186
+        public string TellerGroupName
187
+        {
188
+            get
189
+            {
190
+                var ret = string.Empty;
191
+                if (Usergroup != null && Usergroup.Count > 0)
192
+                {
193
+                    var names = new StringBuilder();
194
+                    foreach (var item in Usergroup)
195
+                    {
196
+                        names.Append("," + item.GroupName);
197
+                    }
198
+                    ret = names.ToString().Substring(1);
199
+                }
200
+                return ret;
201
+            }
202
+        }
203
+
204
+        /// <summary>
205
+        /// 柜员选择角色值
206
+        /// </summary>
207
+        public string TellerGroupValue
208
+        {
209
+            get
210
+            {
211
+                var ret = string.Empty;
212
+                if (Usergroup != null && Usergroup.Count > 0)
213
+                {
214
+                    var values = new StringBuilder();
215
+                    foreach (var item in Usergroup)
216
+                    {
217
+                        values.Append("," + item.GroupId);
218
+                    }
219
+                    ret = values.ToString().Substring(1);
220
+                }
221
+                return ret;
222
+            }
223
+        }
224
+
225
+        /// <summary>
226
+        /// 凭证管理上级机构
227
+        /// </summary>
228
+        public string UpNoteKinbrno { get; private set; }
229
+        /// <summary>
230
+        /// 现金管理上级机构
231
+        /// </summary>
232
+        public string UpCashKinbrno { get; private set; }
233
+
234
+        /// <summary>
235
+        /// 上级机构凭证管理员
236
+        /// </summary>
237
+        public string UpNoteteller { get; private set; }
238
+        /// <summary>
239
+        /// 柜员选择角色值
240
+        /// </summary>
241
+        public string UpCashteller { get; private set; }
242
+        /// <summary>
243
+        /// 机构类型
244
+        /// </summary>
245
+        public string kinbrtype { get; private set; }
246
+
247
+        /// <summary>
248
+        /// 柜员表备用字段--旧柜员号
249
+        /// </summary>
250
+        public string UserComment { get; private set; }
251
+
252
+        /// <summary>
253
+        /// 机构表备用字段--旧机构号
254
+        /// </summary>
255
+        public string KinbrComment { get; private set; }
256
+        /// <summary>
257
+        /// 身份证号
258
+        /// </summary>
259
+        public string IdCarNO { get; private set; }
260
+
261
+        /// <summary>
262
+        /// 汇总机构
263
+        /// </summary>
264
+        public string GroupKinbrNo { get; private set; }
265
+        #endregion
266
+
267
+        #region 私有方法
268
+
269
+
270
+        ///<summary>
271
+        /// 获得MAC地址
272
+        ///</summary>
273
+        ///<returns></returns>
274
+        [MethodImplAttribute(MethodImplOptions.Synchronized)]
275
+        public string GetMacAddress()
276
+        {
277
+            //务必设置为同步方法,否则多线程调用会造成Com异常
278
+            string strMAC = "";
279
+            ManagementClass MC = new ManagementClass("Win32_NetworkAdapterConfiguration");
280
+            ManagementObjectCollection MOC = MC.GetInstances();
281
+            foreach (ManagementObject moc in MOC)
282
+            {
283
+                if (moc["IPEnabled"].ToString() == "True")
284
+                {
285
+                    strMAC = moc["MacAddress"].ToString();
286
+                }
287
+            }
288
+            return strMAC;
289
+        }
290
+
291
+        #endregion
292
+
293
+        /// <summary>
294
+        /// 读取注册表信息
295
+        /// </summary>
296
+        /// <returns>激活码</returns>
297
+        public string ReadZhuce()
298
+        {
299
+            string info = "";
300
+            RegistryKey Key;
301
+            Key = Registry.LocalMachine;
302
+            RegistryKey myreg = Key.OpenSubKey("SAM\\TellerSys");
303
+            if (myreg == null)
304
+            {
305
+                return "";
306
+            }
307
+            // myreg = Key.OpenSubKey("software\\test",true);
308
+            info = myreg.GetValue("TellerSys").ToString();
309
+            myreg.Close();
310
+            return info;
311
+        }
312
+        #region 验证方案
313
+        /// <summary>
314
+        /// 初始化数据
315
+        /// </summary>
316
+        /// <returns></returns>
317
+        public bool InitData(string tellerNo)
318
+        {
319
+            //string[] strData = null;
320
+            string zcm = "";
321
+            if (string.Compare(ConfigManager.GetInstance().GetConfigValue("IsStartHardDiskNumber", ConfigType.System), "true", true) == 0)
322
+            {
323
+                zcm = ReadZhuce();
324
+            }
325
+
326
+            if (string.IsNullOrEmpty(tellerNo)) return false;
327
+            var data = TellerSystem.ServiceProxy.Ext.ServiceHelper.TradeManagerHandle.GetLoginDataByUserCode(tellerNo, zcm);
328
+            if (data == null || data.Count == 0)
329
+                return false;
330
+            var loginData = data[0];
331
+            //解析数据
332
+            this.USERID = loginData.UserId;
333
+            this.USERCODE = loginData.UserCode;
334
+            this.USERNAME = loginData.UserName;
335
+            this.ISPIONT = loginData.IsPiont == "1";
336
+            this.ISLOGIN = loginData.IsLogin == "1";
337
+            this.KINBRID = loginData.KinbrId;
338
+            this.MNGATMUSER = loginData.MngatmUser;
339
+            this.USERPSW = loginData.UserPsw;
340
+            this.CARDID = loginData.CardId;
341
+            this.PWDCHGDATE = loginData.PwdChgDate;
342
+            this.LOGINIP = loginData.LoginIp;
343
+            this.PORTNO = string.IsNullOrEmpty(loginData.PortNo) ? "0" : loginData.PortNo;
344
+            this.PSWLEVEL = loginData.PswLevel;
345
+            this.LEVELCHGDATE = loginData.LevelChgDate;
346
+            this.LEVELDATE = string.IsNullOrEmpty(loginData.LevelDate) ? 0 : Convert.ToInt32(loginData.LevelDate);
347
+            this.CARDLEVEL = loginData.CardLevel;
348
+            this.ISCHANGEPSW = loginData.IsChangePsw;
349
+            this.BEFOREDATE = loginData.BeforeDate;
350
+            this.PSWERRCOUNT = string.IsNullOrEmpty(loginData.PswErrCount) ? 0 : Convert.ToInt32(loginData.PswErrCount);
351
+            this.PSWTIME = loginData.PswTime;
352
+            this.DATE = loginData.Date;
353
+            this.CanForceLogin = loginData.CanForceLogin;
354
+            this.MaxPswCycle = loginData.MaxPswCycle;
355
+            this.CHENKSIGN = loginData.ChenkSign;
356
+            this.KinbrNo = loginData.KinbrNo;
357
+            this.IsAcross = loginData.IsAcross;
358
+            this.CanGroupsLogin = loginData.CanGroupsLogin;
359
+            this.UpNoteKinbrno = loginData.UpNoteKinbrno;
360
+            this.UpCashKinbrno = loginData.UpCashKinbrno;
361
+            this.UpNoteteller = loginData.upnoteteller;
362
+            this.UpCashteller = loginData.upcashteller;
363
+            this.kinbrtype = loginData.kinbrtype;
364
+            this.KinbrComment = loginData.kinbrcomment;
365
+            this.UserComment = loginData.usercomment;
366
+            this.IdCarNO = loginData.idCarNo;
367
+            this.GroupKinbrNo = loginData.GroupKinbrNo;
368
+            this.Ismobile = loginData.IsMobile;
369
+            _tellerNo = tellerNo;
370
+            return true;
371
+        }
372
+
373
+        #endregion
374
+
375
+        #region 公共方法
376
+        /// <summary>
377
+        /// 登陆操作
378
+        /// </summary>
379
+        /// <param name="tellerNo"></param>
380
+        /// <param name="errorMsg"></param>
381
+        /// <returns></returns>
382
+        public bool LoginCheck(out string errorMsg)
383
+        {
384
+
385
+            SetUserDown = false;
386
+            errorMsg = string.Empty;
387
+            if (this.PSWLEVEL == "1")//柜员如果启用指纹校验,就没有必要进行密码验证
388
+            {
389
+                return true;
390
+            }
391
+            //是否允许登陆
392
+            if (!ISLOGIN)
393
+            {
394
+                errorMsg = "该柜员已被停用!";
395
+                return false;
396
+            }
397
+            //登陆方式是否过期
398
+            DateTime dateEnd;
399
+            var dateNow = DateTime.Parse(DATE);
400
+            if (DateTime.TryParse(LEVELCHGDATE, out dateEnd))
401
+            {
402
+                if (dateEnd.AddDays(LEVELDATE) < dateNow)
403
+                {
404
+                    errorMsg = "登录验证方式已过期,禁止登录!";
405
+                    return false;
406
+                }
407
+            }
408
+            //是否进行密码更新,决定于密码修改周期
409
+            DateTime lastPwdChangeData;
410
+            double maxPswCycle;
411
+
412
+            if (!DateTime.TryParse(PWDCHGDATE, out lastPwdChangeData)
413
+            || (double.TryParse(MaxPswCycle, out maxPswCycle) && lastPwdChangeData.AddDays(maxPswCycle) < dateNow))
414
+            {
415
+                var dialog = new UpdatePassword(this);
416
+                dialog.Owner = Application.Current.MainWindow;
417
+                dialog.ShowDialog();
418
+                if (!dialog.PageResult)
419
+                {
420
+                    errorMsg = "登陆密码过期,需要进行修改!";
421
+                    return false;
422
+                }
423
+                //密码修改完,要求重新加载
424
+                errorMsg = "密码修改成功!";
425
+                return false;
426
+            }
427
+            return true;
428
+        }
429
+
430
+        /// <summary>
431
+        /// 获取用户角色列表
432
+        /// </summary>
433
+        /// <param name="tellerNo"></param>
434
+        /// <param name="errorMsg"></param>
435
+        /// <returns></returns>
436
+        public bool GetTellerGroup(out string errorMsg)
437
+        {
438
+            errorMsg = string.Empty;
439
+            //获取角色列表
440
+            Usergroup = TradeManagerHandle.GetRolegroupsbyUsercode(_tellerNo)
441
+                .Where(ttRoleGroup => !string.IsNullOrEmpty(ttRoleGroup.GroupName))
442
+                 .Where(ttRoleGroup => !string.IsNullOrEmpty(ttRoleGroup.GroupId))
443
+                .ToList();
444
+            if (Usergroup == null || Usergroup.Count == 0)
445
+            {
446
+                errorMsg = "获取柜员角色列表出错,柜员角色列表为空!";
447
+                return false;
448
+            }
449
+            ////角色检查,当同时存在现金管理员和凭证管理员且仍存在其他角色时,做区分处理
450
+            //if (IsCashRole && IsVoucherRole && Usergroup.Count > 2)
451
+            //{
452
+            //    var list = Platform.Common.BasicFunctions.DependencyObjectExtensions.FindVisualTreeChildren(Application.Current.MainWindow, x => x is IPage);
453
+            //    if (list.Count == 0)
454
+            //    {
455
+            //        errorMsg = "未找到主界面,请联系科技部!";
456
+            //        return false;
457
+            //    }
458
+            //    //选择98角色
459
+            //    var ret = Platform.Library.MsgHelper.ShowPageMessageBoxMetro(list.First() as IPage, new TextBlock { FontWeight = FontWeights.Bold, FontSize = 20, Text = string.Format("登陆机构:{0}\n登陆柜员:{1}\n您拥有98柜员角色,请选择想要登陆的角色!", LoginUserInfo.KinbrName, LoginAuthentication.Instance.USERNAME) }, "柜员信息", null, "取消", 3, true, true, true, new string[] { "98柜员", "综合柜员", "取消" });
460
+            //    switch (ret)
461
+            //    {
462
+            //        case "98柜员": Usergroup.RemoveAll(x => x.GroupCode != "000001" && x.GroupCode != "000002"); break;
463
+            //        case "综合柜员": Usergroup.RemoveAll(x => x.GroupCode == "000001" || x.GroupCode == "000002"); break;
464
+            //        default:
465
+            //            return false;
466
+            //    }
467
+            //}
468
+            //TellerGroupName = Usergroup[0].GroupName;
469
+            //TellerGroupValue = Usergroup[0].GroupId;
470
+            return true;
471
+        }
472
+
473
+        /// <summary>
474
+        /// 现金管理员
475
+        /// </summary>
476
+        public bool IsCashRole
477
+        {
478
+            get
479
+            {
480
+                return Usergroup.Exists(x => x.GroupCode == "000005"); //TellerGroupCode.Contains("000001");
481
+            }
482
+        }
483
+
484
+        /// <summary>
485
+        /// 凭证管理员
486
+        /// </summary>
487
+        public bool IsVoucherRole
488
+        {
489
+            get
490
+            {
491
+                return Usergroup.Exists(x => x.GroupCode == "000005");
492
+            }
493
+        }
494
+
495
+        /// <summary>
496
+        /// 验证是否允许单柜员多角色多客户端登录
497
+        /// </summary>
498
+        /// <param name="errorMsg"></param>
499
+        /// <param name="tellerNo"></param>
500
+        /// <param name="group"></param>
501
+        /// <returns></returns>
502
+        public bool GroupCheck(string group, out string errorMsg)
503
+        {
504
+            errorMsg = string.Empty;
505
+            if (CHENKSIGN == "1")
506
+            {
507
+                //终端号判定,若终端号相等,则验证通过
508
+                if (String.CompareOrdinal(PORTNO.ToString(), LoginUserInfo.TtyName) == 0)
509
+                {
510
+                    //查找系统配置---是否允许同一柜员使用不同角色同时登录
511
+                    if (TradeManagerHandle.GetMultiRole() != "1")
512
+                    {
513
+                        //查找当前柜员已经登录的角色
514
+                        var groupstr = TradeManagerHandle.GetLogingroupsByUsercode(_tellerNo);
515
+                        //判断是否选择的角色已经登录
516
+                        if (!groupstr.Contains(group))
517
+                        {
518
+                            errorMsg = "用户已选择其他角色登录!";
519
+                            return false;
520
+                        }
521
+                    }
522
+                }
523
+            }
524
+            return true;
525
+        }
526
+
527
+        /// <summary>
528
+        /// 当前柜员状态已登录时的登录验证
529
+        /// </summary>
530
+        /// <param name="tellerNo"></param>
531
+        /// <param name="group"></param>
532
+        /// <param name="errorMsg"></param>
533
+        /// <returns></returns>
534
+        public bool SignCheck(string group, out string errorMsg)
535
+        {
536
+            errorMsg = string.Empty;
537
+            //是否已经登陆,若第一次登陆则验证通过
538
+            if (CHENKSIGN == "1")
539
+            {
540
+                //是否单客户端登陆 
541
+                if (ISPIONT)
542
+                {
543
+                    if (String.CompareOrdinal(PORTNO.ToString(), LoginUserInfo.TtyName) != 0)
544
+                    {
545
+                        //是否允许同一柜员使用不同角色同时登录
546
+                        if (CanGroupsLogin)
547
+                        {
548
+                            //查找当前柜员已经登录的角色
549
+                            var groupstr = TradeManagerHandle.GetLogingroupsByUsercode(_tellerNo);
550
+                            //判断是否选择的角色已经登录
551
+                            if (!groupstr.Contains(group))
552
+                            {
553
+                                return true;
554
+                            }
555
+                        }
556
+
557
+                        //是否强制登陆
558
+                        if (!CanForceLogin)
559
+                        {
560
+                            errorMsg = "该柜员已经在其他机器上登陆系统,请核查!";
561
+                            return false;
562
+                        }
563
+                        else
564
+                        {
565
+                            SetUserDown = true;
566
+                        }
567
+                    }
568
+                    //同一客户端可以直接登录
569
+                    //不考虑角色
570
+                }
571
+
572
+            }
573
+            return true;
574
+        }
575
+
576
+        /// <summary>
577
+        /// 验证密码
578
+        /// </summary>
579
+        /// <param name="password"></param>
580
+        /// <returns></returns>
581
+        public bool CheckPwd(string password, out string errMsg)
582
+        {
583
+            return CheckPwd(password, out errMsg, true);
584
+        }
585
+
586
+        public bool CheckPwd(string password, out string errMsg, bool check2Update)
587
+        {
588
+            errMsg = string.Empty;
589
+            if (PSWERRCOUNT >= 3)
590
+            {
591
+                errMsg = "柜员号或密码登陆错误超过3次,当天不允许继续登陆!请联系科技人员!";
592
+                return false;
593
+            }
594
+            string strPwd = _tellerNo + password;
595
+            byte[] b = Encoding.UTF8.GetBytes(strPwd);
596
+            b = new MD5CryptoServiceProvider().ComputeHash(b);
597
+            var ret = new StringBuilder();
598
+            for (int i = 0; i < b.Length; i++)
599
+                ret.Append(b[i].ToString("x").PadLeft(2, '0'));
600
+            if (string.Compare(ret.ToString(), USERPSW) != 0)
601
+            {
602
+                PSWERRCOUNT++;
603
+                TradeManagerHandle.RecordPSWError(USERID);
604
+                errMsg = string.Format("柜员号或密码错误!当日错误次数为{0}!", PSWERRCOUNT);
605
+                return false;
606
+            }
607
+            if (!check2Update) return true;
608
+            var firstLogin = TellerSystem.ServiceProxy.Ext.ServiceSettings.GetConfig("IsFirstLoginModify", "");
609
+            if (!string.IsNullOrEmpty(firstLogin) && firstLogin == "1")
610
+            {
611
+                //检查是否为原始密码
612
+                var systemPwd = TellerSystem.ServiceProxy.Ext.ServiceSettings.GetConfig("Sys003", "");
613
+                if (!string.IsNullOrEmpty(systemPwd) && password == systemPwd)
614
+                {
615
+                    var dialog = new UpdatePassword(this);
616
+                    dialog.Owner = Application.Current.MainWindow;
617
+                    dialog.Title = "首次登录,请修改密码";
618
+                    dialog.ShowDialog();
619
+                    if (!dialog.PageResult)
620
+                    {
621
+                        errMsg = "当前为重置后的原始密码,需要进行修改!";
622
+                        return false;
623
+                    }
624
+                }
625
+            }
626
+            return true;
627
+        }
628
+
629
+        static LoginAuthentication()
630
+        {
631
+            var tuple = ServiceProxy.Ext.ServiceSettings.GetConfig<Tuple<int, int>>("UserPwdLength", x =>
632
+            {
633
+                var min = 6;
634
+                var max = 6;
635
+                if (!string.IsNullOrEmpty(x))
636
+                {
637
+                    var tmp = x.Split(",,".ToArray());
638
+                    int.TryParse(tmp[0], out min);
639
+                    if (tmp.Length > 1)
640
+                        int.TryParse(tmp[1], out max);
641
+                    if (min < 6) min = 6;
642
+                    if (max < min) max = min;
643
+                }
644
+                return new Tuple<int, int>(min, max);
645
+            });
646
+            PwdMinLength = tuple.Item1;
647
+            PwdMaxLength = tuple.Item2;
648
+            //添加资源
649
+            var userPwdStyle = new Style(typeof(PasswordBox), Application.Current.TryFindResource(typeof(PasswordBox)) as Style);
650
+            userPwdStyle.Setters.Add(new Setter(Platform.Controls.ControlsHelper.PasswordBoxHelper.MinLengthProperty, PwdMinLength));
651
+            userPwdStyle.Setters.Add(new Setter(PasswordBox.MaxLengthProperty, PwdMaxLength));
652
+            userPwdStyle.Setters.Add(new Setter(Platform.Presentation.FocusManagers.FocusManagerExt.AssertNotEmptyProperty, true));
653
+            Application.Current.Resources.Add("UserPwdStyle", userPwdStyle);
654
+        }
655
+
656
+        public static int PwdMinLength { get; private set; }
657
+
658
+        public static int PwdMaxLength { get; private set; }
659
+
660
+        /// <summary>
661
+        /// 更新密码
662
+        /// </summary>
663
+        /// <param name="password"></param>
664
+        /// <param name="errMsg"></param>
665
+        /// <returns></returns>
666
+        public bool UpdatePwd(string password, out string errMsg)
667
+        {
668
+            errMsg = "密码不允许为空";
669
+            //密码复杂度检查
670
+            if (string.IsNullOrEmpty(password)) return false;
671
+            //1.去前后空格
672
+            password = password.Trim();
673
+            //2.检查密码长度
674
+            errMsg = "密码长度不符";
675
+            if (password.Length < PwdMinLength)
676
+            {
677
+                errMsg += ",不能小于" + PwdMinLength;
678
+                return false;
679
+            }
680
+            if (password.Length > PwdMaxLength)
681
+            {
682
+                errMsg += ",不能大于" + PwdMaxLength;
683
+                return false;
684
+            }
685
+            //3..密码应使用同时包含大小写字母、数字、符号中的三种类型的字符组合
686
+            errMsg = "密码必须同时包含大小写字母、数字、符号";
687
+            var regex = ServiceProxy.Ext.ServiceSettings.GetConfig("UserPwdRegex", "");//@"^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*\W)[A-Za-z\d\W]+$");
688
+            if (!string.IsNullOrEmpty(regex) && !Regex.IsMatch(password, regex)) return false;
689
+            //4.简单密码验证
690
+            errMsg = "密码认定简单规则,包含3位及以上连续数字、重复字符或其他情况";
691
+            regex = ServiceProxy.Ext.ServiceSettings.GetConfig("UserPwdRegex2Simple", "");//@"([\w])\1{2,}|012|123|234|345|456|567|678|789|987|876|765|654|543|432|321|210");
692
+            if (!string.IsNullOrEmpty(regex) && Regex.IsMatch(password, regex)) return false;
693
+            //更新操作
694
+            var b = Encoding.UTF8.GetBytes(this.USERCODE + password);
695
+            b = new MD5CryptoServiceProvider().ComputeHash(b);
696
+            var ret = new StringBuilder();
697
+            for (int i = 0; i < b.Length; i++)
698
+                ret.Append(b[i].ToString("x").PadLeft(2, '0'));
699
+            if (TradeManagerHandle.UpdatePSW(this.USERID, ret.ToString()))
700
+            {
701
+                this.USERPSW = ret.ToString();
702
+                ///这里,当修改密码成功后,给几个全局属性赋值,
703
+                if (this.USERCODE == Instance.USERCODE)
704
+                    LoginUserInfo.SetUserInfo("Passwd", password.Trim());
705
+                return true;
706
+            }
707
+            return false;
708
+        }
709
+
710
+        /// <summary>
711
+        /// 登记记录状态
712
+        /// </summary>
713
+        /// <param name="sign"></param>
714
+        /// <returns></returns>
715
+        public bool LoginSign(bool sign)
716
+        {
717
+            //if (!TradePowerManager.Instance.IsPowerCheckByUser) return true;
718
+            if (string.IsNullOrEmpty(_tellerNo)) return false;
719
+
720
+            if (sign) IPAddress = UserManagerHandle.SortSockAddress(SocketManager.GetLocalIpAddressList());
721
+
722
+            var parm = new TT_LoginSign
723
+            {
724
+                ChenkSign = sign ? "1" : "0",
725
+                LoginIp = IPAddress,//获取IP地址 ,
726
+                LoginMarc = GetMacAddress(),
727
+                LoginTime = DateTime.Now.ToString(),
728
+                PortNo = LoginUserInfo.TtyName,//说明:PortNo记录了终端号,用于柜员单客户端登陆。如果终端号相同,登陆不上去
729
+                UserCode = USERCODE,
730
+                UserID = USERID,
731
+                LoginGroups = this.TellerGroupValue
732
+            };
733
+            TradeManagerHandle.RecordLoginSign(
734
+                new List<TT_LoginSign>
735
+            {
736
+                parm
737
+            });
738
+            return true;
739
+        }
740
+
741
+        #endregion
742
+    }
743
+}

+ 0
- 0
ant-design-pro-vue3/src/views/front/develop/Library.Ext/TradeExtension/SSO/LoginAuthentication.ts 查看文件


部分文件因文件數量過多而無法顯示

Loading…
取消
儲存