Browse Source

platfrom common

main
hulei 3 weeks ago
parent
commit
c6cdca2322
34 changed files with 2340 additions and 0 deletions
  1. 22
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/Base/IconBox.xaml
  2. 97
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/Base/IconBox.xaml.cs
  3. BIN
      ant-design-pro-vue3/src/views/front/platfrom/common/Base/fontawesome-webfont.ttf
  4. 38
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/BaseClasses/AnimationsManager.ts
  5. 24
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/BaseClasses/BaseCommand.ts
  6. 83
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/BaseClasses/CacheManager.ts
  7. 214
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/BaseClasses/EncrypDecryptHelper.ts
  8. 117
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/BaseClasses/EventAggregator.ts
  9. 47
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/BaseClasses/NotificationObject.ts
  10. 61
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/BaseClasses/ObservableObject.ts
  11. 29
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/BaseClasses/ThemesManager.ts
  12. 80
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/BaseClasses/TimerManager.ts
  13. 109
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/Extensions/DependencyObjectExtensions.ts
  14. 29
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/Extensions/DictionaryExtension.ts
  15. 91
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/Extensions/DispatcherObjectExtension.ts
  16. 7
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/Extensions/ICollectionExtensions.ts
  17. 14
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/Extensions/IEnumerableExtensions.ts
  18. 26
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/Handles/BoolToVisibilityConverter.ts
  19. 8
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/Handles/EncryptAndDecryptHandle.ts
  20. 85
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/Handles/FileHandle.ts
  21. 36
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/Handles/IndexOfIListConverter.ts
  22. 23
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/Handles/TextToEncodingLengthConverter.ts
  23. 109
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/PageFunctions/TradeModel.ts
  24. 36
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/PageFunctions/TradeModelHelper.ts
  25. 128
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/PageFunctions/TradeViewModel.ts
  26. 124
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/LogSystem/LogWriter.ts
  27. 156
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/LogSystem/PlatformLogger.ts
  28. 10
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/LogSystem/winston.ts
  29. 61
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/RunningParameters/CommonParames.ts
  30. 184
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/RunningParameters/ConfigManager.ts
  31. 60
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/RunningParameters/LoginUserInfo.ts
  32. 143
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/RunningParameters/PlatformSettings.ts
  33. 72
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/RunningParameters/TradeParames.ts
  34. 17
    0
      ant-design-pro-vue3/src/views/front/platfrom/common/RunningParameters/transit.ts

+ 22
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/Base/IconBox.xaml View File

@@ -0,0 +1,22 @@
1
+<UserControl x:Class="Platform.Common.Base.IconBox"
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:local="clr-namespace:Platform.Common.Base"
6
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
7
+             Name="this"
8
+             d:DesignHeight="300"
9
+             d:DesignWidth="300"
10
+             mc:Ignorable="d">
11
+    <UserControl.Resources>
12
+        <Style x:Key="style_iconfont">
13
+            <Setter Property="TextBlock.FontFamily" Value="/Platform.Common;component/Base/#FontAwesome" />
14
+        </Style>
15
+    </UserControl.Resources>
16
+    <Viewbox>
17
+        <TextBlock FontSize="72"
18
+                   Style="{StaticResource style_iconfont}"
19
+                   Text="{Binding ElementName=this,
20
+                                  Path=Code}" />
21
+    </Viewbox>
22
+</UserControl>

+ 97
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/Base/IconBox.xaml.cs View File

@@ -0,0 +1,97 @@
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
+
15
+namespace Platform.Common.Base
16
+{
17
+    /// <summary>
18
+    /// IconBox.xaml 的交互逻辑
19
+    /// </summary>
20
+    public partial class IconBox : UserControl
21
+    {
22
+        #region Ctor
23
+        public IconBox()
24
+        {
25
+            InitializeComponent();
26
+        }
27
+        #endregion
28
+
29
+        #region Code
30
+        /// <summary>
31
+        /// 图标字体的值
32
+        /// </summary>
33
+        public string Code
34
+        {
35
+            get { return (string)GetValue(CodeProperty); }
36
+            set { SetValue(CodeProperty, value); }
37
+        }
38
+
39
+        // Using a DependencyProperty as the backing store for Code.  This enables animation, styling, binding, etc...
40
+        public static readonly DependencyProperty CodeProperty =
41
+            DependencyProperty.Register("Code", typeof(string), typeof(IconBox), new PropertyMetadata(""));
42
+        #endregion
43
+
44
+        #region Static
45
+        /// <summary>
46
+        /// 获取参数指定的图标画刷
47
+        /// </summary>
48
+        /// <param name="code"></param>
49
+        /// <returns></returns>
50
+        public static Brush GetIconBrush(string code, Brush foreground)
51
+        {
52
+            var icon = new IconBox();
53
+            icon.Code = code;
54
+            icon.Foreground = foreground;
55
+            return new VisualBrush(icon);
56
+        }
57
+
58
+        /// <summary>
59
+        /// 获取参数指定的图像源
60
+        /// </summary>
61
+        /// <param name="code"></param>
62
+        /// <param name="foreground"></param>
63
+        /// <returns></returns>
64
+        public static ImageSource GetIconSource(string code, Brush foreground)
65
+        {
66
+            var icon = new IconBox();
67
+            icon.Code = code;
68
+            icon.Foreground = foreground;
69
+            var window = new Window
70
+            {
71
+                Content = new ScrollViewer
72
+                {
73
+                    Content = icon,
74
+                    VerticalScrollBarVisibility = ScrollBarVisibility.Visible,
75
+                    HorizontalScrollBarVisibility = ScrollBarVisibility.Visible
76
+                },
77
+                SizeToContent = SizeToContent.WidthAndHeight
78
+            };
79
+            window.ShowInTaskbar = false;
80
+            window.WindowState = WindowState.Normal;
81
+            window.Top = 0 - 768;
82
+            window.Left = 0 - 1024;
83
+            window.Show();
84
+            window.Close();
85
+            //开始创建对象
86
+            var rtb = new RenderTargetBitmap((int)icon.ActualWidth, (int)icon.ActualHeight, 96, 96, PixelFormats.Pbgra32);
87
+            rtb.Render(icon);
88
+            return rtb;
89
+        }
90
+        #endregion
91
+
92
+        public enum IconType
93
+        {
94
+
95
+        }
96
+    }
97
+}

BIN
ant-design-pro-vue3/src/views/front/platfrom/common/Base/fontawesome-webfont.ttf View File


+ 38
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/BaseClasses/AnimationsManager.ts View File

@@ -0,0 +1,38 @@
1
+// 假设 AnimationResource 是一个自定义的动画资源类型
2
+interface AnimationResource {
3
+  source: string;
4
+  // 可以根据实际需求添加更多属性
5
+}
6
+
7
+class AnimationsManager {
8
+  private static currentAnimation: AnimationResource | null = null;
9
+
10
+  /**
11
+   * 加载动画资源
12
+   * @param animation 动画资源对象
13
+   */
14
+  public static loadAnimation(animation: AnimationResource): void {
15
+    if (
16
+      !this.currentAnimation ||
17
+      this.currentAnimation.source !== animation.source
18
+    ) {
19
+      // 这里可以添加移除当前动画资源的逻辑,例如清理 DOM 中的动画元素等
20
+      this.currentAnimation = animation;
21
+      // 这里可以添加加载新动画资源的逻辑,例如动态引入 CSS 或 JS 文件等
22
+      console.log(`Loading animation from source: ${animation.source}`);
23
+    }
24
+  }
25
+
26
+  /**
27
+   * 根据 URI 加载动画资源
28
+   * @param animationUri 动画资源的 URI
29
+   */
30
+  public static loadAnimationByUri(animationUri: string): void {
31
+    const animationResource: AnimationResource = {
32
+      source: animationUri,
33
+    };
34
+    this.loadAnimation(animationResource);
35
+  }
36
+}
37
+
38
+export default AnimationsManager;

+ 24
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/BaseClasses/BaseCommand.ts View File

@@ -0,0 +1,24 @@
1
+// 定义 CanExecuteHandler 类型
2
+type CanExecuteHandler = (parameter: any) => boolean;
3
+// 定义 ExecuteHandler 类型
4
+type ExecuteHandler = (parameter: any) => void;
5
+
6
+export class BaseCommand {
7
+    private canExecuteHandler: CanExecuteHandler | null;
8
+    private executeHandler: ExecuteHandler;
9
+
10
+    constructor(executeHandler: ExecuteHandler, canExecuteHandler: CanExecuteHandler | null = null) {
11
+        this.canExecuteHandler = canExecuteHandler;
12
+        this.executeHandler = executeHandler;
13
+    }
14
+
15
+    public canExecute(parameter: any): boolean {
16
+        return this.canExecuteHandler === null ? true : this.canExecuteHandler(parameter);
17
+    }
18
+
19
+    public execute(parameter: any): void {
20
+        if (this.executeHandler) {
21
+            this.executeHandler(parameter);
22
+        }
23
+    }
24
+}

+ 83
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/BaseClasses/CacheManager.ts View File

@@ -0,0 +1,83 @@
1
+// 模拟 CacheItemRemovedReason 枚举
2
+enum CacheItemRemovedReason {
3
+    DependencyChanged,
4
+    Expired,
5
+    Removed,
6
+    Underused
7
+}
8
+
9
+class CacheManager {
10
+    private static webCache: Storage = localStorage;
11
+
12
+    static get GetWebCacheObj(): Storage {
13
+        return this.webCache;
14
+    }
15
+
16
+    static GetCache(cacheKey: string): any {
17
+        if (cacheKey.trim() === '') return null;
18
+        const item = this.webCache.getItem(cacheKey);
19
+        if (item) {
20
+            const { value, expiration } = JSON.parse(item);
21
+            if (expiration === null || Date.now() < expiration) {
22
+                return value;
23
+            } else {
24
+                this.RemoveCache(cacheKey);
25
+            }
26
+        }
27
+        return null;
28
+    }
29
+
30
+    static GetCacheWithFactory(cacheKey: string, valueFactory: (key: string) => any): any {
31
+        if (cacheKey.trim() === '') return null;
32
+        let ret = this.GetCache(cacheKey);
33
+        if (ret === null) {
34
+            ret = valueFactory(cacheKey);
35
+            this.SetCache(cacheKey, ret);
36
+        }
37
+        return ret;
38
+    }
39
+
40
+    static SetCache(cacheKey: string, objObject: any, timeOut: number = 3600): void {
41
+        if (cacheKey.trim() === '') return;
42
+        const expiration = timeOut === 0 ? null : Date.now() + timeOut * 1000;
43
+        const item = JSON.stringify({ value: objObject, expiration });
44
+        this.webCache.setItem(cacheKey, item);
45
+    }
46
+
47
+    static RemoveCache(cacheKey: string): void {
48
+        if (cacheKey.trim() === '') return;
49
+        this.webCache.removeItem(cacheKey);
50
+        this.onRemove(cacheKey, null, CacheItemRemovedReason.Removed);
51
+    }
52
+
53
+    static RemoveCacheByRegex(regexCacheKey: string): void {
54
+        if (regexCacheKey.trim() === '') return;
55
+        const reg = new RegExp(regexCacheKey);
56
+        for (let i = 0; i < this.webCache.length; i++) {
57
+            const cacheKey = this.webCache.key(i);
58
+            if (cacheKey && reg.test(cacheKey)) {
59
+                this.webCache.removeItem(cacheKey);
60
+                this.onRemove(cacheKey, null, CacheItemRemovedReason.Removed);
61
+            }
62
+        }
63
+    }
64
+
65
+    private static onRemove(key: string, val: any, reason: CacheItemRemovedReason): void {
66
+        switch (reason) {
67
+            case CacheItemRemovedReason.DependencyChanged:
68
+                break;
69
+            case CacheItemRemovedReason.Expired:
70
+                console.log(`[${key}]已过期`);
71
+                break;
72
+            case CacheItemRemovedReason.Removed:
73
+                console.log(`[${key}]已移除`);
74
+                break;
75
+            case CacheItemRemovedReason.Underused:
76
+                break;
77
+            default:
78
+                break;
79
+        }
80
+    }
81
+}
82
+
83
+export default CacheManager;

+ 214
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/BaseClasses/EncrypDecryptHelper.ts View File

@@ -0,0 +1,214 @@
1
+// 假设这些类型和函数在前端可以找到替代实现
2
+type Dictionary<T> = { [key: string]: T };
3
+type Tuple<T1, T2> = [T1, T2];
4
+type Func<T, R> = (arg: T) => R;
5
+
6
+// 假设这些配置和工具类在前端有相应的实现
7
+class PlatformSettings {
8
+    static EncryptsKey: string;
9
+    static Encoding: {
10
+        GetBytes: (str: string) => Uint8Array;
11
+        GetString: (bytes: Uint8Array) => string;
12
+    };
13
+}
14
+
15
+class ConfigManager {
16
+    static GetInstance(): ConfigManager {
17
+        return new ConfigManager();
18
+    }
19
+    GetConfigValue(key: string, type: any): string {
20
+        // 实现配置获取逻辑
21
+        return '';
22
+    }
23
+}
24
+
25
+// 假设 MsgEncryptionKitLib 在前端有相应的实现
26
+namespace MsgEncryptionKitLib {
27
+    export class CryptoAgent {
28
+        GenSymKey(): string {
29
+            // 实现生成对称密钥逻辑
30
+            return '';
31
+        }
32
+        GenServerRandomRequest(genSymKey: string, publicKey: string): string {
33
+            // 实现生成服务器随机请求逻辑
34
+            return '';
35
+        }
36
+        ExchangeKey(genSymKey: string, serverRandom: string): string {
37
+            // 实现密钥交换逻辑
38
+            return '';
39
+        }
40
+        EncryptMessage(key: string, msg: string, publicKey: string): string {
41
+            // 实现加密逻辑
42
+            return '';
43
+        }
44
+        DecryptMessage(key: string, msg: string): string {
45
+            // 实现解密逻辑
46
+            return '';
47
+        }
48
+    }
49
+}
50
+
51
+// 加解密模式枚举
52
+enum Mode {
53
+    Des2FixKey = 0,
54
+    Sm2 = 1,
55
+}
56
+
57
+export default class EncrypDecryptHelper {
58
+
59
+
60
+
61
+    private static _instance: EncrypDecryptHelper;
62
+    private KEY = PlatformSettings.EncryptsKey;
63
+    private defaultMode: Mode;
64
+    private publicKeyFileInfo = null;// new FileInfo('Devices/Cfca/Platform.PublicKey.sm2');//TODO:加密
65
+    private msgEncrypt: MsgEncryptionKitLib.CryptoAgent | null = null;
66
+    private publicKey = '';
67
+    private genSymKey = '';
68
+    private clientKey = '';
69
+    private serverHandle = '';
70
+
71
+    private constructor() {
72
+        this.initDefaultMode();
73
+    }
74
+
75
+    static get Instance(): EncrypDecryptHelper {
76
+        if (!this._instance) {
77
+            this._instance = new EncrypDecryptHelper();
78
+        }
79
+        return this._instance;
80
+    }
81
+
82
+    get DefaultMode(): Mode {
83
+        return this.defaultMode;
84
+    }
85
+
86
+    private initDefaultMode() {
87
+        const configValue = ConfigManager.GetInstance().GetConfigValue('EncryptMode', null);
88
+        if (!Object.values(Mode).includes(parseInt(configValue))) {
89
+            this.defaultMode = Mode.Des2FixKey;
90
+        } else {
91
+            this.defaultMode = parseInt(configValue) as Mode;
92
+        }
93
+    }
94
+
95
+    Init(mode: Mode, init: Func<Dictionary<string>, Dictionary<string>>): boolean | null {
96
+        if (mode !== this.defaultMode) return null;
97
+        switch (mode) {
98
+            case Mode.Des2FixKey:
99
+                break;
100
+            case Mode.Sm2:
101
+                const exchange: Func<string, Tuple<string, string>> = (rqt) => {
102
+                    const rst = init({ ServerRandomRequest: rqt });
103
+                    return [rst['ServerRandom'], rst['ServerHandle']];
104
+                };
105
+                if (!this.Sm2ExchangeKey(exchange)) {
106
+                    this.defaultMode = Mode.Des2FixKey;
107
+                }
108
+                break;
109
+            default:
110
+                break;
111
+        }
112
+        return true;
113
+    }
114
+    //TODO 加密方式
115
+    static Encrypt(msgByte: Uint8Array<ArrayBuffer>, arg1: boolean): Uint8Array<ArrayBuffer> {
116
+        throw new Error('Method not implemented.');
117
+    }
118
+    static Decrypt(message: Uint8Array<ArrayBuffer>, arg1: boolean): Uint8Array<ArrayBuffer> {
119
+        throw new Error('Method not implemented.');
120
+    }
121
+
122
+    Encrypt(msg: Uint8Array, toServer = false): Uint8Array {
123
+        let data: Uint8Array | null = null;
124
+        switch (this.defaultMode) {
125
+            case Mode.Des2FixKey:
126
+                data = this.DesEncryptFixKey(msg);
127
+                break;
128
+            case Mode.Sm2:
129
+                data = this.Sm2Encrypt(msg, toServer);
130
+                break;
131
+            default:
132
+                throw new Error(`不支持的加解方式:${this.defaultMode}`);
133
+        }
134
+        return data;
135
+    }
136
+
137
+    Decrypt(msg: Uint8Array, toServer = false): Uint8Array {
138
+        let data: Uint8Array | null = null;
139
+        switch (this.defaultMode) {
140
+            case Mode.Des2FixKey:
141
+                data = this.DesDecryptFixKey(msg);
142
+                break;
143
+            case Mode.Sm2:
144
+                data = this.Sm2Decrypt(msg, toServer);
145
+                break;
146
+            default:
147
+                throw new Error(`不支持的加解密方式:${this.defaultMode}`);
148
+        }
149
+        return data;
150
+    }
151
+
152
+    private DesEncryptFixKey(msg: Uint8Array): Uint8Array {
153
+        const byKey = PlatformSettings.Encoding.GetBytes(this.KEY);
154
+        const IV = new Uint8Array([0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
155
+        // 这里需要使用前端可用的 DES 加密库实现
156
+        const encrypted = new Uint8Array();
157
+        return PlatformSettings.Encoding.GetBytes(btoa(String.fromCharCode.apply(null, encrypted)));
158
+    }
159
+
160
+    private DesDecryptFixKey(msg: Uint8Array): Uint8Array {
161
+        const byKey = PlatformSettings.Encoding.GetBytes(this.KEY);
162
+        const IV = new Uint8Array([0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
163
+        const inputByteArray = Uint8Array.from(atob(PlatformSettings.Encoding.GetString(msg)).split('').map(c => c.charCodeAt(0)));
164
+        // 这里需要使用前端可用的 DES 解密库实现
165
+        const decrypted = new Uint8Array();
166
+        return decrypted;
167
+    }
168
+
169
+    private Sm2Init(): boolean {
170
+        if (!this.msgEncrypt) {
171
+            try {
172
+                // 这里需要使用前端可用的文件读取方式实现
173
+                this.publicKey = '';
174
+                this.msgEncrypt = new MsgEncryptionKitLib.CryptoAgent();
175
+                this.genSymKey = this.msgEncrypt.GenSymKey();
176
+            } catch (error) {
177
+                return false;
178
+            }
179
+        }
180
+        return true;
181
+    }
182
+
183
+    private Sm2ExchangeKey(exChange: Func<string, Tuple<string, string>>): boolean {
184
+        if (this.Sm2Init()) {
185
+            if (this.clientKey) return true;
186
+            const rqt = this.msgEncrypt!.GenServerRandomRequest(this.genSymKey, this.publicKey);
187
+            const [serverRandom, serverHandle] = exChange(rqt);
188
+            this.clientKey = this.msgEncrypt!.ExchangeKey(this.genSymKey, serverRandom);
189
+            this.serverHandle = serverHandle;
190
+            return true;
191
+        }
192
+        return false;
193
+    }
194
+
195
+    private Sm2Encrypt(msg: Uint8Array, exChange = true): Uint8Array {
196
+        if (!this.Sm2Init()) return new Uint8Array();
197
+        const key = exChange && this.clientKey ? this.clientKey : this.genSymKey;
198
+        const rst = this.msgEncrypt!.EncryptMessage(key, btoa(String.fromCharCode.apply(null, msg)), this.publicKey);
199
+        if (exChange) {
200
+            const prefix = `SM2${this.serverHandle.length.toString().padStart(4, '0')}${this.serverHandle}`;
201
+            return PlatformSettings.Encoding.GetBytes(prefix + rst);
202
+        }
203
+        return PlatformSettings.Encoding.GetBytes(rst);
204
+    }
205
+
206
+    private Sm2Decrypt(msg: Uint8Array, exChange = true): Uint8Array {
207
+        if (!this.Sm2Init()) return new Uint8Array();
208
+        const key = exChange && this.clientKey ? this.clientKey : this.genSymKey;
209
+        const rst = this.msgEncrypt!.DecryptMessage(key, btoa(String.fromCharCode.apply(null, msg)));
210
+        return Uint8Array.from(atob(rst).split('').map(c => c.charCodeAt(0)));
211
+    }
212
+}
213
+
214
+export { EncrypDecryptHelper, Mode };

+ 117
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/BaseClasses/EventAggregator.ts View File

@@ -0,0 +1,117 @@
1
+// 标记接口,用于标识实现了消息处理功能的类 TODO 注调了
2
+//interface IHandle {}
3
+
4
+// 泛型接口,用于处理特定类型的消息
5
+interface IHandle<TMessage> {//extends IHandle TODO 报错
6
+    // 处理传入的消息
7
+    Handle(message: TMessage): void;
8
+}
9
+
10
+// 事件聚合器接口,定义了事件聚合器的基本功能
11
+interface IEventAggregator {
12
+    // 默认的线程调度器,用于消息发布时的线程管理
13
+    PublicationThreadMarshaller: (action: () => void) => void;
14
+    // 订阅消息,将实现了 IHandle<T> 接口的实例添加到事件聚合器中
15
+    Subscribe(instance: any): void;
16
+    // 取消订阅,将指定的实例从事件聚合器中移除
17
+    Unsubscribe(instance: any): void;
18
+    // 使用默认的线程调度器发布消息
19
+    Publish(message: any): void;
20
+    // 使用指定的线程调度器发布消息
21
+    Publish(message: any, marshal: (action: () => void) => void): void;
22
+}
23
+
24
+// 事件聚合器的具体实现
25
+class EventAggregator implements IEventAggregator {
26
+    // 存储所有的消息处理程序
27
+    private handlers: Handler[] = [];
28
+    // 默认的线程调度器,直接执行传入的操作
29
+    public static DefaultPublicationThreadMarshaller: (action: () => void) => void = (action) => action();
30
+    // 用于设置默认的线程调度器
31
+    public PublicationThreadMarshaller: (action: () => void) => void;
32
+
33
+    constructor() {
34
+        // 初始化 PublicationThreadMarshaller 为默认的线程调度器
35
+        this.PublicationThreadMarshaller = EventAggregator.DefaultPublicationThreadMarshaller;
36
+    }
37
+
38
+    // 订阅消息
39
+    public Subscribe(instance: any): void {
40
+        if (this.handlers.some(x => x.Matches(instance))) {
41
+            return;
42
+        }
43
+        // 创建一个新的 Handler 实例并添加到 handlers 列表中
44
+        this.handlers.push(new Handler(instance));
45
+    }
46
+
47
+    // 取消订阅
48
+    public Unsubscribe(instance: any): void {
49
+        const found = this.handlers.find(x => x.Matches(instance));
50
+        if (found) {
51
+            // 从 handlers 列表中移除指定的实例
52
+            this.handlers = this.handlers.filter(x => x !== found);
53
+        }
54
+    }
55
+
56
+    // 使用默认的线程调度器发布消息 TODO
57
+    public Publish(message: any): void {
58
+        //this.Publish(message, this.PublicationThreadMarshaller);
59
+    }
60
+    //TODO 线程消息发布订阅的模式是否ts中是否有其他的方式能实现
61
+    //使用指定的线程调度器发布消息
62
+    // public Publish(message: any, marshal: (action: () => void) => void): void {
63
+    //     const toNotify = [...this.handlers];
64
+    //     marshal(() => {
65
+    //         const messageType = message.constructor;
66
+    //         const dead = toNotify
67
+    //             .filter(handler => !handler.Handle(messageType, message))
68
+    //             .toArray();
69
+    //         if (dead.length > 0) {
70
+    //             this.handlers = this.handlers.filter(x => !dead.includes(x));
71
+    //         }
72
+    //     });
73
+    // }
74
+}
75
+
76
+// 用于存储订阅者的信息和处理方法
77
+class Handler {
78
+    // 存储订阅者的实例
79
+    private reference: WeakRef<any>;
80
+    // 存储订阅者支持处理的消息类型和对应的处理方法
81
+    private supportedHandlers: Map<Function, ((message: any) => void)> = new Map();
82
+
83
+    constructor(handler: any) {
84
+        this.reference = new WeakRef(handler);
85
+        const handlerInfo = null;//(IHandle as any).prototype; TODO 这个IHandle
86
+        const interfaces = Object.getPrototypeOf(handler).constructor
87
+            .getInterfaces()
88
+            .filter(x => x.prototype instanceof handlerInfo && x.typeParameters.length > 0);
89
+        // interfaces.forEach((@interface: any) => { TODO注掉了
90
+        //     const type = @interface.typeParameters[0];
91
+        //     const method = @interface.prototype.Handle;
92
+        //     this.supportedHandlers.set(type, method.bind(handler));
93
+        // });
94
+    }
95
+
96
+    // 检查 reference 指向的实例是否与指定的实例相同
97
+    public Matches(instance: any): boolean {
98
+        return this.reference.deref() === instance;
99
+    }
100
+
101
+    // 处理消息
102
+    public Handle(messageType: Function, message: any): boolean {
103
+        const target = this.reference.deref();
104
+        if (!target) {
105
+            return false;
106
+        }
107
+        for (const [key, value] of this.supportedHandlers) {
108
+            if (key.prototype.isPrototypeOf(message)) {
109
+                value(message);
110
+                return true;
111
+            }
112
+        }
113
+        return true;
114
+    }
115
+}
116
+
117
+export { IHandle, IHandle as IHandleGeneric, IEventAggregator, EventAggregator };

+ 47
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/BaseClasses/NotificationObject.ts View File

@@ -0,0 +1,47 @@
1
+import { reactive, watch } from 'vue';
2
+
3
+// 定义一个接口,用于表示属性更改事件处理函数
4
+type PropertyChangedEventHandler = (propertyName: string) => void;
5
+
6
+// 定义 NotificationObject 类
7
+export class NotificationObject {
8
+    private _properties: { [key: string]: any };
9
+    public PropertyChanged: PropertyChangedEventHandler | null = null;
10
+
11
+    constructor() {
12
+        // 使用 Vue 的 reactive 创建响应式对象
13
+        this._properties = reactive({});
14
+        // 监听属性变化
15
+        watch(
16
+            () => this._properties,
17
+            (newValue, oldValue, onCleanup) => {
18
+                const changedProperties = Object.keys(newValue).filter(
19
+                    (key) => newValue[key] !== oldValue[key]
20
+                );
21
+                changedProperties.forEach((propertyName) => {
22
+                    if (this.PropertyChanged) {
23
+                        this.PropertyChanged(propertyName);
24
+                    }
25
+                });
26
+            },
27
+            { deep: true }
28
+        );
29
+    }
30
+
31
+    // 获取属性值
32
+    public getProperty(propertyName: string): any {
33
+        return this._properties[propertyName];
34
+    }
35
+
36
+    // 设置属性值
37
+    public setProperty(propertyName: string, value: any): void {
38
+        this._properties[propertyName] = value;
39
+    }
40
+
41
+    // 触发属性更改事件
42
+    public RaisePropertyChanged(propertyName: string): void {
43
+        if (this.PropertyChanged) {
44
+            this.PropertyChanged(propertyName);
45
+        }
46
+    }
47
+}

+ 61
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/BaseClasses/ObservableObject.ts View File

@@ -0,0 +1,61 @@
1
+import { reactive, watch } from '@vue/reactivity';
2
+
3
+// 定义 PropertyChangedEventHandler 类型
4
+type PropertyChangedEventHandler = (sender: any, propertyName: string) => void;
5
+
6
+class ObservableObject {
7
+    // 存储属性更改事件的处理函数
8
+    private _propertyChangedHandlers: PropertyChangedEventHandler[] = [];
9
+
10
+    // 添加事件处理函数
11
+    onPropertyChanged(handler: PropertyChangedEventHandler) {
12
+        this._propertyChangedHandlers.push(handler);
13
+    }
14
+
15
+    // 移除事件处理函数
16
+    offPropertyChanged(handler: PropertyChangedEventHandler) {
17
+        const index = this._propertyChangedHandlers.indexOf(handler);
18
+        if (index > -1) {
19
+            this._propertyChangedHandlers.splice(index, 1);
20
+        }
21
+    }
22
+
23
+    // 获取属性名称
24
+    static getPropertyName<T>(getter: () => T): string {
25
+        const propertyName = Object.keys(new Proxy({}, {
26
+            get(target, prop) {
27
+                return prop;
28
+            }
29
+        })).find(prop => getter() === prop);
30
+        return propertyName || '';
31
+    }
32
+
33
+    // 触发属性更改事件
34
+    protected raisePropertyChanged(propertyName: string) {
35
+        this._propertyChangedHandlers.forEach(handler => {
36
+            handler(this, propertyName);
37
+        });
38
+    }
39
+
40
+    // 通过表达式触发属性更改事件
41
+    protected raisePropertyChangedByExpression<T>(getter: () => T) {
42
+        const propertyName = ObservableObject.getPropertyName(getter);
43
+        if (propertyName) {
44
+            this.raisePropertyChanged(propertyName);
45
+        }
46
+    }
47
+
48
+    // 创建响应式对象
49
+    createReactive<T extends object>(obj: T): object {//TODO这里由T泛型改为 object
50
+        const reactiveObj = reactive(obj);
51
+        // 监听所有属性的变化
52
+        watch(() => Object.values(reactiveObj), () => {
53
+            Object.keys(reactiveObj).forEach(key => {
54
+                this.raisePropertyChanged(key);
55
+            });
56
+        }, { deep: true });
57
+        return reactiveObj;
58
+    }
59
+}
60
+
61
+export default ObservableObject;

+ 29
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/BaseClasses/ThemesManager.ts View File

@@ -0,0 +1,29 @@
1
+class ThemesManager {
2
+    private static CurrentThemeAssemblyName: string;
3
+
4
+    public static LoadTheme(themeAssemblyName: string): void {
5
+        if (ThemesManager.CurrentThemeAssemblyName !== themeAssemblyName) {
6
+            ThemesManager.CurrentThemeAssemblyName = themeAssemblyName;
7
+
8
+            // 清除现有的主题样式
9
+            const existingLinks = document.querySelectorAll('link[rel="stylesheet"][data-theme]');
10
+            existingLinks.forEach(link => link.parentNode?.removeChild(link));
11
+
12
+            // 加载基本主题
13
+            const baseThemeLink = document.createElement('link');
14
+            baseThemeLink.rel = 'stylesheet';
15
+            baseThemeLink.href = '/Platform.BaseTheme/CommonResources.css';
16
+            baseThemeLink.dataset.theme = 'base';
17
+            document.head.appendChild(baseThemeLink);
18
+
19
+            // 加载指定主题
20
+            const projectThemeLink = document.createElement('link');
21
+            projectThemeLink.rel = 'stylesheet';
22
+            projectThemeLink.href = `/${themeAssemblyName}/CommonResources.css`;
23
+            projectThemeLink.dataset.theme = 'project';
24
+            document.head.appendChild(projectThemeLink);
25
+        }
26
+    }
27
+}
28
+
29
+export default ThemesManager;

+ 80
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/BaseClasses/TimerManager.ts View File

@@ -0,0 +1,80 @@
1
+class TimerManager {
2
+    private static _instance: TimerManager;
3
+    public static get Instance(): TimerManager {
4
+        if (!this._instance) {
5
+            this._instance = new TimerManager();
6
+        }
7
+        return this._instance;
8
+    }
9
+
10
+    private interval = 1000; // 1 秒
11
+    private counter = 0;
12
+    private timer: NodeJS.Timeout | null = null;
13
+    private timerPolicies: TimerPolicy[] = [];
14
+
15
+    private constructor() {
16
+        this.timer = setInterval(() => {
17
+            this.timerPolicies.forEach(item => {
18
+                if (this.counter * this.interval % item.interval === 0) {
19
+                    if (item.isAsynchronization) {
20
+                        setTimeout(item.action, 0);
21
+                    } else {
22
+                        item.action();
23
+                    }
24
+                }
25
+            });
26
+            if (this.counter === Number.MAX_SAFE_INTEGER) {
27
+                this.counter = 0;
28
+            }
29
+            this.counter++;
30
+        }, this.interval);
31
+    }
32
+
33
+    public addTimerPolicy(policy: TimerPolicy) {
34
+        if (!policy || !policy.action) return;
35
+        this.timerPolicies.push(policy);
36
+        if (!this.timer) {
37
+            this.timer = setInterval(() => {
38
+                this.timerPolicies.forEach(item => {
39
+                    if (this.counter * this.interval % item.interval === 0) {
40
+                        if (item.isAsynchronization) {
41
+                            setTimeout(item.action, 0);
42
+                        } else {
43
+                            item.action();
44
+                        }
45
+                    }
46
+                });
47
+                if (this.counter === Number.MAX_SAFE_INTEGER) {
48
+                    this.counter = 0;
49
+                }
50
+                this.counter++;
51
+            }, this.interval);
52
+        }
53
+    }
54
+
55
+    public removeTimerPolicy(policy: TimerPolicy) {
56
+        if (!policy) return;
57
+        const index = this.timerPolicies.indexOf(policy);
58
+        if (index !== -1) {
59
+            this.timerPolicies.splice(index, 1);
60
+        }
61
+        if (this.timer && this.timerPolicies.length === 0) {
62
+            clearInterval(this.timer);
63
+            this.timer = null;
64
+        }
65
+    }
66
+}
67
+
68
+class TimerPolicy {
69
+    constructor(
70
+        public action: () => void,
71
+        public interval: number,
72
+        public isAsynchronization = false
73
+    ) {
74
+        if (!interval) {
75
+            this.interval = this.interval * 100;
76
+        }
77
+    }
78
+}
79
+
80
+export { TimerManager, TimerPolicy };

+ 109
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/Extensions/DependencyObjectExtensions.ts View File

@@ -0,0 +1,109 @@
1
+// 由于 Vue 没有直接的 DependencyObject 概念,这里使用 HTMLElement 代替
2
+// 同时由于没有 VisualTreeHelper 等,需要手动实现一些查找逻辑
3
+
4
+// 模拟 Predicate 类型
5
+type Predicate<T> = (item: T) => boolean;
6
+
7
+// 视觉树查找子元素
8
+function findVisualTreeChildren(target: HTMLElement, predicate?: Predicate<HTMLElement>): HTMLElement[] {
9
+    const result: HTMLElement[] = [];
10
+    if (target) {
11
+        const children = target.children;
12
+        for (let i = 0; i < children.length; i++) {
13
+            const element = children[i] as HTMLElement;
14
+            if (element) {
15
+                if (!predicate || predicate(element)) {
16
+                    result.push(element);
17
+                }
18
+                result.push(...findVisualTreeChildren(element, predicate));
19
+            }
20
+        }
21
+    }
22
+    return result;
23
+}
24
+
25
+// 视觉树查找第一个子元素
26
+function firstVisualTreeChild(target: HTMLElement, predicate?: Predicate<HTMLElement>): HTMLElement | null {
27
+    if (target) {
28
+        const children = target.children;
29
+        for (let i = 0; i < children.length; i++) {
30
+            const element = children[i] as HTMLElement;
31
+            if (element) {
32
+                if (!predicate || predicate(element)) {
33
+                    return element;
34
+                }
35
+                const childResult = firstVisualTreeChild(element, predicate);
36
+                if (childResult) {
37
+                    return childResult;
38
+                }
39
+            }
40
+        }
41
+    }
42
+    return null;
43
+}
44
+
45
+// 视觉树查找父元素
46
+function findVisualTreeAncestor(target: HTMLElement, predicate?: Predicate<HTMLElement>): HTMLElement | null {
47
+    if (target) {
48
+        const parent = target.parentElement;
49
+        if (!predicate) {
50
+            return parent;
51
+        } else if (parent) {
52
+            return predicate(parent) ? parent : findVisualTreeAncestor(parent, predicate);
53
+        }
54
+    }
55
+    return null;
56
+}
57
+
58
+// 模拟路由事件触发(在 Vue 中可以使用自定义事件)
59
+function raiseEvent(target: HTMLElement, event: Event) {
60
+    target.dispatchEvent(event);
61
+}
62
+
63
+// 模拟添加路由事件处理程序
64
+function addHandler(target: HTMLElement, eventType: string, handler: EventListenerOrEventListenerObject) {
65
+    target.addEventListener(eventType, handler);
66
+}
67
+
68
+// 模拟移除路由事件处理程序
69
+function removeHandler(target: HTMLElement, eventType: string, handler: EventListenerOrEventListenerObject) {
70
+    target.removeEventListener(eventType, handler);
71
+}
72
+
73
+// 在逻辑树中查找父窗口(这里简单返回 document.body)
74
+function getOwnerWindow(target: HTMLElement): HTMLElement | null {
75
+    return document.body;
76
+}
77
+
78
+// 查找视觉父元素
79
+function findVisualParent<T extends HTMLElement>(element: HTMLElement): T | null {
80
+    let parent: HTMLElement | null = element;
81
+    while (parent) {
82
+        if (parent instanceof HTMLElement) {
83
+            return parent as T;
84
+        }
85
+        parent = null;//parent.parentElement;TODO VUE上有视觉树的概念吗?
86
+    }
87
+    return null;
88
+}
89
+
90
+// 获取鼠标悬停的元素
91
+function getElementUnderMouse<T extends HTMLElement>(): T | null {
92
+    const element = document.elementFromPoint(window.innerWidth / 2, window.innerHeight / 2);
93
+    if (element instanceof HTMLElement) {
94
+        return findVisualParent<T>(element);
95
+    }
96
+    return null;
97
+}
98
+
99
+export {
100
+    findVisualTreeChildren,
101
+    firstVisualTreeChild,
102
+    findVisualTreeAncestor,
103
+    raiseEvent,
104
+    addHandler,
105
+    removeHandler,
106
+    getOwnerWindow,
107
+    findVisualParent,
108
+    getElementUnderMouse
109
+};

+ 29
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/Extensions/DictionaryExtension.ts View File

@@ -0,0 +1,29 @@
1
+// 定义扩展方法所在的命名空间
2
+//namespace Platform.Common.BasicFunctions {
3
+// 扩展方法,用于获取字典中的元素
4
+export function GetDictionaryItem<T>(dict: { [key: string]: any }, key: string): T {
5
+    let result: T = null as any;
6
+    if (dict && dict.hasOwnProperty(key)) {
7
+        result = dict[key] as T;
8
+    }
9
+    return result;
10
+}
11
+
12
+// 扩展方法,用于设置字典中的元素
13
+export function SetDictionaryItem(dict: { [key: string]: any }, key: string, value: any): void {
14
+    if (!dict) {
15
+        dict = {};
16
+    }
17
+    if (!dict.hasOwnProperty(key)) {
18
+        dict[key] = value;
19
+    } else {
20
+        dict[key] = value;
21
+    }
22
+}
23
+//}
24
+
25
+// // 示例使用
26
+// const myDict: { [key: string]: any } = {};
27
+// Platform.Common.BasicFunctions.setDictionaryItem(myDict, "testKey", "testValue");
28
+// const value = Platform.Common.BasicFunctions.getDictionaryItem<string>(myDict, "testKey");
29
+// console.log(value);

+ 91
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/Extensions/DispatcherObjectExtension.ts View File

@@ -0,0 +1,91 @@
1
+// 模拟 DispatcherObject
2
+class DispatcherObject {
3
+    // 模拟 Dispatcher
4
+    public dispatcher: {
5
+        checkAccess: () => boolean;
6
+        invoke: (callback: () => void) => void;
7
+    };
8
+
9
+    constructor() {
10
+        this.dispatcher = {
11
+            checkAccess: () => true, // 简单模拟,始终返回 true
12
+            invoke: (callback) => {
13
+                setTimeout(callback, 0); // 模拟在主线程执行
14
+            },
15
+        };
16
+    }
17
+}
18
+
19
+// 扩展方法实现
20
+class DispatcherObjectExtension {
21
+    public static UIInvoke(target: DispatcherObject, method: (...args: any[]) => any): any {
22
+        if (target.dispatcher.checkAccess()) {
23
+            return method();
24
+        } else {
25
+            return new Promise((resolve) => {
26
+                target.dispatcher.invoke(() => {
27
+                    const result = method();
28
+                    resolve(result);
29
+                });
30
+            });
31
+        }
32
+    }
33
+
34
+    public static UIInvokeWithType<T>(target: DispatcherObject, method: (...args: any[]) => T): T | Promise<T> {
35
+        if (target.dispatcher.checkAccess()) {
36
+            return method();
37
+        } else {
38
+            return new Promise((resolve) => {
39
+                target.dispatcher.invoke(() => {
40
+                    const result = method();
41
+                    resolve(result);
42
+                });
43
+            });
44
+        }
45
+    }
46
+
47
+    public static UIInvokeAction(target: DispatcherObject, action: () => void): void | Promise<void> {
48
+        if (target.dispatcher.checkAccess()) {
49
+            action();
50
+        } else {
51
+            return new Promise((resolve) => {
52
+                target.dispatcher.invoke(() => {
53
+                    action();
54
+                    resolve();
55
+                });
56
+            });
57
+        }
58
+    }
59
+}
60
+
61
+// 示例使用
62
+const obj = new DispatcherObject();
63
+const method = () => {
64
+    console.log('Method executed');
65
+    return 42;
66
+};
67
+const action = () => console.log('Action executed');
68
+
69
+// 调用 UIInvoke
70
+const result = DispatcherObjectExtension.UIInvoke(obj, method);
71
+if (result instanceof Promise) {
72
+    result.then((value) => console.log('Result:', value));
73
+} else {
74
+    console.log('Result:', result);
75
+}
76
+
77
+// 调用 UIInvokeWithType
78
+const typedResult = DispatcherObjectExtension.UIInvokeWithType<number>(obj, method);
79
+if (typedResult instanceof Promise) {
80
+    typedResult.then((value) => console.log('Typed Result:', value));
81
+} else {
82
+    console.log('Typed Result:', typedResult);
83
+}
84
+
85
+// 调用 UIInvokeAction
86
+const actionResult = DispatcherObjectExtension.UIInvokeAction(obj, action);
87
+if (actionResult instanceof Promise) {
88
+    actionResult.then(() => console.log('Action completed'));
89
+} else {
90
+    console.log('Action completed');
91
+}

+ 7
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/Extensions/ICollectionExtensions.ts View File

@@ -0,0 +1,7 @@
1
+// 虽然 TypeScript 没有直接等价于 using System; 的概念,但在实际使用中,内置类型是全局可用的
2
+// 这里无需特殊处理
3
+
4
+// 定义接口
5
+export interface ICollectionExtensions {
6
+    // 目前接口为空,没有成员
7
+}

+ 14
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/Extensions/IEnumerableExtensions.ts View File

@@ -0,0 +1,14 @@
1
+namespace Platform.Common.BasicFunctions {
2
+    export class __LINQ__ {
3
+        /**
4
+         * Applies the action to each element in the list.
5
+         * @param enumerable The elements to enumerate.
6
+         * @param action The action to apply to each item in the list.
7
+         */
8
+        static Apply<T>(enumerable: T[], action: (item: T) => void): void {
9
+            enumerable.forEach(item => {
10
+                action(item);
11
+            });
12
+        }
13
+    }
14
+}

+ 26
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/Handles/BoolToVisibilityConverter.ts View File

@@ -0,0 +1,26 @@
1
+// 定义 Visibility 枚举
2
+enum Visibility {
3
+    Visible = 'visible',
4
+    Collapsed = 'collapsed'
5
+}
6
+
7
+// 定义 IValueConverter 接口
8
+interface IValueConverter {
9
+    convert(value: any, targetType: any, parameter: any, culture: any): any;
10
+    convertBack(value: any, targetType: any, parameter: any, culture: any): any;
11
+}
12
+
13
+// 实现 BoolToVisibilityConverter 类
14
+export class BoolToVisibilityConverter implements IValueConverter {
15
+    convert(value: boolean, targetType: any, parameter: any, culture: any): Visibility {
16
+        if (value) {
17
+            return Visibility.Visible;
18
+        } else {
19
+            return Visibility.Collapsed;
20
+        }
21
+    }
22
+
23
+    convertBack(value: Visibility, targetType: any, parameter: any, culture: any): boolean {
24
+        throw new Error('Not implemented');
25
+    }
26
+}

+ 8
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/Handles/EncryptAndDecryptHandle.ts View File

@@ -0,0 +1,8 @@
1
+namespace Platform.Common.BasicFunctions {
2
+    export class EncryptAndDecryptHandle {
3
+        // 这里可以添加具体的加密和解密方法
4
+    }
5
+}
6
+
7
+// 示例使用 TODO报错暂时先注释调
8
+//const result = Platform.Common.BasicFunctions.EncryptAndDecryptHandle;

+ 85
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/Handles/FileHandle.ts View File

@@ -0,0 +1,85 @@
1
+import * as fs from 'fs';
2
+import * as path from 'path';
3
+import * as crypto from 'crypto';
4
+
5
+export default class FileHandle {
6
+    /**
7
+     * 获取参数指定文件的MD5码
8
+     * @param filePath 文件路径
9
+     * @returns 文件的 MD5 码
10
+     */
11
+    public static async GetFileMD5(filePath: string): Promise<string> {
12
+        return new Promise((resolve, reject) => {
13
+            fs.stat(filePath, (err, stats) => {
14
+                if (err || !stats.isFile()) {
15
+                    resolve('');
16
+                    return;
17
+                }
18
+                const hash = crypto.createHash('md5');
19
+                const stream = fs.createReadStream(filePath);
20
+                stream.on('data', (data) => hash.update(data));
21
+                stream.on('end', () => {
22
+                    const md5 = hash.digest('hex');
23
+                    resolve(md5);
24
+                });
25
+                stream.on('error', (error) => {
26
+                    reject(error);
27
+                });
28
+            });
29
+        });
30
+    }
31
+
32
+    /**
33
+     * 获取参数指定文件的字节数组
34
+     * @param filePath 文件路径
35
+     * @returns 文件的字节数组
36
+     */
37
+    public static async GetBytes(filePath: string): Promise<Buffer | null> {
38
+        return new Promise((resolve, reject) => {
39
+            fs.stat(filePath, (err, stats) => {
40
+                if (err || !stats.isFile()) {
41
+                    resolve(null);
42
+                    return;
43
+                }
44
+                fs.readFile(filePath, (error, data) => {
45
+                    if (error) {
46
+                        reject(error);
47
+                    } else {
48
+                        resolve(data);
49
+                    }
50
+                });
51
+            });
52
+        });
53
+    }
54
+
55
+    /**
56
+     * 保存文件
57
+     * @param filePath 文件路径
58
+     * @param data 写入数据
59
+     * @param appendFlag 模式(true:追加   false:覆写)
60
+     * @returns 是否保存成功
61
+     */
62
+    public static async SaveFile(filePath: string, data: Buffer, appendFlag: boolean): Promise<boolean> {
63
+        return new Promise((resolve, reject) => {
64
+            if (!filePath) {
65
+                resolve(false);
66
+                return;
67
+            }
68
+            const dir = path.dirname(filePath);
69
+            fs.mkdir(dir, { recursive: true }, (err) => {
70
+                if (err) {
71
+                    reject(err);
72
+                    return;
73
+                }
74
+                const flags = appendFlag ? 'a' : 'w';
75
+                fs.writeFile(filePath, data, { flag: flags }, (error) => {
76
+                    if (error) {
77
+                        reject(error);
78
+                    } else {
79
+                        resolve(true);
80
+                    }
81
+                });
82
+            });
83
+        });
84
+    }
85
+}

+ 36
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/Handles/IndexOfIListConverter.ts View File

@@ -0,0 +1,36 @@
1
+// 定义一个 IndexOfIListConverter 类
2
+class IndexOfIListConverter {
3
+    // 实现 Convert 方法
4
+    public Convert(values: any[], targetType: any, parameter: any, culture: any): any {
5
+        // 检查 values 数组长度是否小于 2
6
+        if (values.length < 2) {
7
+            return '';
8
+        }
9
+        // 检查 values[0] 是否为数组
10
+        if (!Array.isArray(values[0])) {
11
+            return '';
12
+        }
13
+        const list = values[0];
14
+        // 查找 values[1] 在 list 中的索引
15
+        const index = list.indexOf(values[1]);
16
+        // 若未找到,返回空字符串
17
+        if (index < 0) {
18
+            return '';
19
+        }
20
+        // 根据 list 长度格式化索引
21
+        if (list.length > 10) {
22
+            const paddingLength = list.length.toString().length;
23
+            return index.toString().padStart(paddingLength, '0');
24
+        } else {
25
+            return index.toString();
26
+        }
27
+    }
28
+
29
+    // 实现 ConvertBack 方法
30
+    public ConvertBack(value: any, targetTypes: any[], parameter: any, culture: any): any[] {
31
+        throw new Error("IndexOfCollectionConverter不支持反向绑定!");
32
+    }
33
+}
34
+
35
+// 导出该类
36
+export default IndexOfIListConverter;

+ 23
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/Handles/TextToEncodingLengthConverter.ts View File

@@ -0,0 +1,23 @@
1
+// 定义 IValueConverter 接口
2
+interface IValueConverter {
3
+    convert(value: any, targetType: any, parameter: any, culture: any): any;
4
+    convertBack(value: any, targetType: any, parameter: any, culture: any): any;
5
+}
6
+
7
+// 定义 TextToEncodingLengthConverter 类
8
+export class TextToEncodingLengthConverter implements IValueConverter {
9
+    // 实现 convert 方法
10
+    convert(value: any, targetType: any, parameter: any, culture: any): any {
11
+        const text = typeof value === 'string' ? value : null;
12
+        if (text === null) return 0;
13
+
14
+        // 使用 TextEncoder 计算字符串的字节长度
15
+        const encoder = new TextEncoder();
16
+        return encoder.encode(text).length;
17
+    }
18
+
19
+    // 实现 convertBack 方法
20
+    convertBack(value: any, targetType: any, parameter: any, culture: any): any {
21
+        throw new Error('Not implemented');
22
+    }
23
+}

+ 109
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/PageFunctions/TradeModel.ts View File

@@ -0,0 +1,109 @@
1
+// 假设 NotificationObject 类的定义如下
2
+class NotificationObject {
3
+    protected raisePropertyChanged(propertyName: string) {
4
+        // 这里可以实现属性变更通知的逻辑
5
+        console.log(`Property ${propertyName} has changed.`);
6
+    }
7
+}
8
+
9
+// 假设 TradeModelHelper 类的定义如下
10
+class TradeModelHelper {
11
+    static GetMetadata(model: TradeModel): { [key: string]: string } {
12
+        // 实现获取元数据的逻辑
13
+        return {};
14
+    }
15
+
16
+    static SetMetadata(model: TradeModel, dic: { [key: string]: string }) {
17
+        // 实现设置元数据的逻辑
18
+    }
19
+
20
+    static GetRight(model: TradeModel): string[] {
21
+        // 实现获取权限的逻辑
22
+        return [];
23
+    }
24
+
25
+    static SetRight(model: TradeModel, right: string[]) {
26
+        // 实现设置权限的逻辑
27
+    }
28
+}
29
+
30
+class TradeModel extends NotificationObject {
31
+    private _guid: string;
32
+    private _name: string;
33
+    private _code: string;
34
+    private _action: string;
35
+    private _type: string;
36
+    private _parentID: string;
37
+
38
+    get GUID(): string {
39
+        return this._guid;
40
+    }
41
+
42
+    set GUID(value: string) {
43
+        this._guid = value;
44
+    }
45
+
46
+    get Name(): string {
47
+        return this._name;
48
+    }
49
+
50
+    set Name(value: string) {
51
+        this._name = value;
52
+        this.raisePropertyChanged("Name");
53
+    }
54
+
55
+    get Code(): string {
56
+        return this._code;
57
+    }
58
+
59
+    set Code(value: string) {
60
+        this._code = value;
61
+        this.raisePropertyChanged("Code");
62
+    }
63
+
64
+    get Action(): string {
65
+        return this._action;
66
+    }
67
+
68
+    set Action(value: string) {
69
+        this._action = value;
70
+    }
71
+
72
+    get Metadata(): { [key: string]: string } {
73
+        return TradeModelHelper.GetMetadata(this);
74
+    }
75
+
76
+    SetMetadata(dic: { [key: string]: string }) {
77
+        TradeModelHelper.SetMetadata(this, dic);
78
+    }
79
+
80
+    get Right(): string[] {
81
+        return TradeModelHelper.GetRight(this);
82
+    }
83
+
84
+    SetRight(right: string[]) {
85
+        TradeModelHelper.SetRight(this, right);
86
+    }
87
+
88
+    get Type(): string {
89
+        return this._type;
90
+    }
91
+
92
+    set Type(value: string) {
93
+        this._type = value;
94
+    }
95
+
96
+    get ParentID(): string {
97
+        return this._parentID;
98
+    }
99
+
100
+    set ParentID(value: string) {
101
+        this._parentID = value;
102
+    }
103
+
104
+    constructor() {
105
+        super();
106
+    }
107
+}
108
+
109
+export default TradeModel;

+ 36
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/PageFunctions/TradeModelHelper.ts View File

@@ -0,0 +1,36 @@
1
+// 假设 TradeModel 类型已经定义
2
+interface TradeModel {
3
+    // 这里可以根据实际情况定义 TradeModel 的属性
4
+}
5
+
6
+class TradeModelHelper {
7
+    // 模拟 Metadata 附加属性
8
+    private static metadataMap = new WeakMap<object, { [key: string]: string }>();
9
+
10
+    static getMetadata(obj: object): { [key: string]: string } | null {
11
+        return this.metadataMap.get(obj) || null;
12
+    }
13
+
14
+    static setMetadata(obj: object, value: { [key: string]: string }): void {
15
+        this.metadataMap.set(obj, value);
16
+    }
17
+
18
+    // 模拟 Right 附加属性
19
+    private static rightMap = new WeakMap<object, string[]>();
20
+
21
+    static getRight(obj: object): string[] | null {
22
+        return this.rightMap.get(obj) || null;
23
+    }
24
+
25
+    static setRight(obj: object, value: string[]): void {
26
+        this.rightMap.set(obj, value);
27
+    }
28
+
29
+    // 获取交易模型列表
30
+    static getTradeModelList(parentModel: TradeModel): TradeModel[] {
31
+        let lstResult: TradeModel[] = [];
32
+        return lstResult;
33
+    }
34
+}
35
+
36
+export default TradeModelHelper;

+ 128
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/BasicFunctions/PageFunctions/TradeViewModel.ts View File

@@ -0,0 +1,128 @@
1
+// 假设 NotificationObject 类的定义如下
2
+class NotificationObject {
3
+    protected raisePropertyChanged(propertyName: string) {
4
+        // 实现属性变更通知逻辑
5
+    }
6
+}
7
+
8
+// 假设 TradeModel 类的定义如下
9
+class TradeModel {
10
+    GUID: string;
11
+    ParentID: string;
12
+    Name: string;
13
+    Code: string;
14
+    Type: string;
15
+}
16
+
17
+// 假设 ConfigManager 类的定义如下
18
+class ConfigManager {
19
+    private static instance: ConfigManager;
20
+    private constructor() {}
21
+
22
+    public static GetInstance() {
23
+        if (!this.instance) {
24
+            this.instance = new ConfigManager();
25
+        }
26
+        return this.instance;
27
+    }
28
+
29
+    public GetConfigValue(key: string, type: string) {
30
+        // 实现获取配置值的逻辑
31
+        return "";
32
+    }
33
+}
34
+
35
+class TradeViewModel extends NotificationObject {
36
+    private _isleaf: boolean = false;
37
+    private _node: TradeModel | null = null;
38
+    public Parent: TradeViewModel | null = null;
39
+    public IsSelected: boolean = false;
40
+    public IsExpanded: boolean = false;
41
+    private _children: TradeViewModel[] = [];
42
+
43
+    get Node() {
44
+        return this._node;
45
+    }
46
+
47
+    set Node(value: TradeModel | null) {
48
+        this._node = value;
49
+        this.raisePropertyChanged("Node");
50
+    }
51
+
52
+    get IsLeaf() {
53
+        return this._isleaf;
54
+    }
55
+
56
+    set IsLeaf(value: boolean) {
57
+        this._isleaf = value;
58
+        this.raisePropertyChanged("IsLeaf");
59
+    }
60
+
61
+    get Children() {
62
+        return this._children;
63
+    }
64
+
65
+    set Children(value: TradeViewModel[]) {
66
+        this._children = value;
67
+        this.raisePropertyChanged("Children");
68
+    }
69
+
70
+    public static GetRootNode(ModelList: TradeModel[]): TradeViewModel[] {
71
+        const VMList: TradeViewModel[] = [];
72
+        const list = ModelList.filter(x => !x.ParentID);
73
+        for (const item of list) {
74
+            const vm = TradeViewModel.CreateVm(ModelList, item);
75
+            if (vm) {
76
+                VMList.push(vm);
77
+            }
78
+        }
79
+
80
+        // 常用交易菜单添加
81
+        // const tradeModel = new TradeModel();
82
+        // tradeModel.Name = "常用交易";
83
+        // const tradeViewModel = new TradeViewModel();
84
+        // tradeViewModel.Node = tradeModel;
85
+        // const commonTradeCodes = ConfigManager.GetInstance().GetConfigValue("CommonTrade", "User").split('|').filter(s => s);
86
+        // for (const code of commonTradeCodes) {
87
+        //     const matchingModels = ModelList.filter(x => x.Code === code);
88
+        //     for (const b of matchingModels) {
89
+        //         const child = new TradeViewModel();
90
+        //         child.Node = b;
91
+        //         child.IsLeaf = true;
92
+        //         child.Children = [];
93
+        //         tradeViewModel.Children.push(child);
94
+        //     }
95
+        // }
96
+        // VMList.push(tradeViewModel);
97
+
98
+        return VMList;
99
+    }
100
+
101
+    private static CreateVm(models: TradeModel[], current: TradeModel): TradeViewModel | null {
102
+        const result = new TradeViewModel();
103
+        result.Node = current;
104
+        const list = models.filter(x => x.ParentID === result.Node?.GUID);
105
+        if (list.length === 0) {
106
+            if (current.Type === "category") {
107
+                return null;
108
+            }
109
+            result.IsLeaf = true;
110
+            result.Children = [];
111
+        } else {
112
+            result.IsLeaf = false;
113
+            for (const item of list) {
114
+                const child = TradeViewModel.CreateVm(models, item);
115
+                if (child) {
116
+                    child.Parent = result;
117
+                    result.Children.push(child);
118
+                }
119
+            }
120
+            if (result.Children.length === 0) {
121
+                return null;
122
+            }
123
+        }
124
+        return result;
125
+    }
126
+}
127
+
128
+export { TradeViewModel, TradeModel };

+ 124
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/LogSystem/LogWriter.ts View File

@@ -0,0 +1,124 @@
1
+//import { ILog, Level } from 'log4net'; // 假设 log4net 有对应的 TypeScript 定义//TODO日志信息可以先不登记
2
+
3
+// 假设的 LoginUserInfo 类
4
+class LoginUserInfo {
5
+    static TellerNo: string;
6
+}
7
+
8
+// 假设的 PlatformSettings 类
9
+class PlatformSettings {
10
+    static IsDebugMode: boolean;
11
+    static Encoding: {
12
+        GetBytes: (str: string) => Uint8Array;
13
+        GetString: (bytes: Uint8Array) => string;
14
+    };
15
+}
16
+
17
+// 假设的 EncrypDecryptHelper 类
18
+class EncrypDecryptHelper {
19
+    static Instance: {
20
+        DesEncryptFixKey: (bytes: Uint8Array) => Uint8Array;
21
+    };
22
+}
23
+
24
+// 日志数据类
25
+class LogData {
26
+    constructor(
27
+        //public LogObject: ILog,//TODO日志信息可以先不登记
28
+        //public LogLevel: Level,//TODO日志信息可以先不登记
29
+        public Content: string,
30
+        public TradeNo: string = null,
31
+        public LogException: Error = null
32
+    ) {
33
+        this.TellerNo = LoginUserInfo.TellerNo;
34
+        this.LogDate = new Date().toISOString().replace('T', ' ').substring(0, 19);
35
+    }
36
+
37
+    //public LogObject: ILog;//TODO日志信息可以先不登记
38
+    //ublic LogLevel: Level;
39
+    //public TradeNo: string;
40
+    public LogDate: string;
41
+    public TellerNo: string;
42
+    //public Content: string;
43
+    //public LogException: Error;
44
+    public AttachData: any;
45
+}
46
+
47
+// 日志记录器类
48
+class LogWriter {
49
+    private static _instance: LogWriter;
50
+    private static _LogDataList: LogData[] = [];
51
+
52
+    public static get Instance(): LogWriter {
53
+        if (!this._instance) {
54
+            this._instance = new LogWriter();
55
+        }
56
+        return this._instance;
57
+    }
58
+
59
+    private constructor() {
60
+        // 定时任务部分暂时无法实现,因为 JavaScript 没有直接对应的 TimeSpan 和 TimerManager
61
+    }
62
+
63
+    public AddLogData(data: LogData) {
64
+        LogWriter._LogDataList.push(data);
65
+    }
66
+
67
+    public SaveLog() {
68
+        if (!LogWriter._LogDataList || LogWriter._LogDataList.length === 0) return;
69
+
70
+        const list = [...LogWriter._LogDataList];
71
+        LogWriter._LogDataList = [];
72
+
73
+        list.forEach(item => {
74
+            const target = item;
75
+            let data = '';
76
+            if (target.TradeNo) {
77
+                data += `交易号:${target.TradeNo}\n`;
78
+            }
79
+            data += `操作柜员:${target.TellerNo}\n`;
80
+            data += `发生时间:${target.LogDate}\n`;
81
+            data += `日志信息:${target.Content}\n`;
82
+            if (target.LogException) {
83
+                data += `异常信息:${target.LogException}\n`;
84
+            }
85
+
86
+            let msg = data;
87
+            if (!PlatformSettings.IsDebugMode) {
88
+                const bytes = PlatformSettings.Encoding.GetBytes(msg);
89
+                const encryptedBytes = EncrypDecryptHelper.Instance.DesEncryptFixKey(bytes);
90
+                msg = PlatformSettings.Encoding.GetString(encryptedBytes);
91
+            }
92
+
93
+            let stringBuilder = 'Start\n';
94
+            stringBuilder += msg;
95
+            stringBuilder += 'End\n';
96
+
97
+            // this.SendToLog4net(target.LogObject, target.LogLevel, stringBuilder, null);//TODO日志信息可以先不登记
98
+        });
99
+    }
100
+
101
+    private SendToLog4net(log: "", level: "", msg: any, exception: Error) {//TODO日志信息可以先不登记(log: ILog, level: Level, msg: any, exception: Error)
102
+        // switch (level.Name) {
103
+        //     case 'DEBUG':
104
+        //         log.Debug(msg, exception);
105
+        //         break;
106
+        //     case 'ERROR':
107
+        //         log.Error(msg, exception);
108
+        //         break;
109
+        //     case 'FATAL':
110
+        //         log.Fatal(msg, exception);
111
+        //         break;
112
+        //     case 'INFO':
113
+        //         log.Info(msg, exception);
114
+        //         break;
115
+        //     case 'WARN':
116
+        //         log.Warn(msg, exception);
117
+        //         break;
118
+        //     default:
119
+        //         break;
120
+        // }
121
+    }
122
+}
123
+
124
+export { LogWriter, LogData };

+ 156
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/LogSystem/PlatformLogger.ts View File

@@ -0,0 +1,156 @@
1
+import winston from './winston'; //TODO这里日志记录使用了log4net.dll需要解决对应的方案 可以使用vuejs-logger来代替
2
+import LoginUserInfo from '../RunningParameters/LoginUserInfo'; // 假设 LoginUserInfo 定义在该文件中TODO:缺用户模块
3
+
4
+// 假设 LogWriter 类的实现
5
+class LogWriter {
6
+    private static instance: LogWriter;
7
+    private logData: any[] = [];
8
+
9
+    private constructor() { }
10
+
11
+    public static get Instance() {
12
+        return this.instance || (this.instance = new this());
13
+    }
14
+
15
+    public AddLogData(data: any) {
16
+        this.logData.push(data);
17
+    }
18
+
19
+    public SaveLog() {
20
+        // 实现保存日志的逻辑
21
+    }
22
+}
23
+
24
+// 定义日志记录器
25
+const lg1 = winston.createLogger("lg1");
26
+const lg2 = winston.createLogger("lg2");
27
+const lg3 = winston.createLogger("lg3");
28
+const lg4 = winston.createLogger("lg4");
29
+const lg5 = winston.createLogger("lg5");
30
+
31
+// 日志文件开关状态
32
+const dics: { [key: string]: string } = {
33
+    'System.log': 'on',
34
+    'Debug.log': 'on',
35
+    'Message.log': 'on',
36
+    'Error.log': 'on',
37
+};
38
+
39
+// 创建连接
40
+function CreateConnection(tellerNo: string, tradeDate: string) {
41
+    // 实现创建连接的逻辑
42
+}
43
+
44
+// 关闭连接
45
+function CloseConnection() {
46
+    // 实现关闭连接的逻辑
47
+}
48
+
49
+// 系统正常运行的输出日志
50
+export function SystemInfo(logDetail: string) {
51
+    CreateConnection(LoginUserInfo.TellerNo, LoginUserInfo.TradeDate);
52
+    LogWriter.Instance.AddLogData({ logger: lg1, level: 'debug', message: logDetail });
53
+    LogWriter.Instance.SaveLog();
54
+    CloseConnection();
55
+}
56
+
57
+// 交易正常运行的输出日志
58
+export function TradeInfo(logDetail: string, tradeNum = '****') {
59
+    CreateConnection(LoginUserInfo.TellerNo, LoginUserInfo.TradeDate);
60
+    LogWriter.Instance.AddLogData({ logger: lg2, level: 'debug', message: logDetail, tradeNum });
61
+    LogWriter.Instance.SaveLog();
62
+    CloseConnection();
63
+}
64
+
65
+// 交易异常的输出日志
66
+export function TradeErrorInfo(errMsg: string, ex: Error, tradeNum = '****') {
67
+    CreateConnection(LoginUserInfo.TellerNo, LoginUserInfo.TradeDate);
68
+    LogWriter.Instance.AddLogData({ logger: lg3, level: 'error', message: errMsg, tradeNum, ex });
69
+    LogWriter.Instance.SaveLog();
70
+    CloseConnection();
71
+}
72
+
73
+// 普通异常(不属于交易异常)的输出日志
74
+export function SystemErrorInfo(errMsg: string, ex: Error) {
75
+    CreateConnection(LoginUserInfo.TellerNo, LoginUserInfo.TradeDate);
76
+    LogWriter.Instance.AddLogData({ logger: lg5, level: 'error', message: errMsg, ex });
77
+    LogWriter.Instance.SaveLog();
78
+    CloseConnection();
79
+}
80
+
81
+// 通讯内容的输出日志
82
+export function CommunicationInfo(msg: string, tradeNum = '****') {
83
+    CreateConnection(LoginUserInfo.TellerNo, LoginUserInfo.TradeDate);
84
+    LogWriter.Instance.AddLogData({ logger: lg4, level: 'debug', message: msg, tradeNum });
85
+    LogWriter.Instance.SaveLog();
86
+    CloseConnection();
87
+}
88
+
89
+// 获取待上传的目录路径
90
+export function GetUploadDataPath(isChecked: boolean): string {
91
+    CloseConnection();
92
+    if (isChecked) {
93
+        if (CanbeSent(LoginUserInfo.TellerNo, LoginUserInfo.TradeDate)) {
94
+            return GetBackUp();
95
+        }
96
+    } else {
97
+        return GetBackUp();
98
+    }
99
+    CreateConnection(LoginUserInfo.TellerNo, LoginUserInfo.TradeDate);
100
+    return '';
101
+}
102
+
103
+// 更改输出配置
104
+export function ChangeOutput() {
105
+    CloseConnection();
106
+    CreateConnection(LoginUserInfo.TellerNo, LoginUserInfo.TradeDate);
107
+}
108
+
109
+// 判断日志文件是否满足上传条件
110
+function CanbeSent(path: string, tradeDate: string): boolean {
111
+    // 实现判断逻辑
112
+    return false;
113
+}
114
+
115
+// 检查日志文件是否能写入
116
+function CheckSwitchOfFile(logger: "", dic: { [key: string]: string }) {//TODO(logger: winston.Logger, dic: { [key: string]: string })
117
+    // 实现检查逻辑
118
+}
119
+
120
+// 获取日志文件的最近上传时间
121
+function GetLastSentTime(fInfo: any): Date {
122
+    // 实现获取时间逻辑
123
+    return new Date();
124
+}
125
+
126
+// 获取日志文件的大小
127
+function GetSizeOfFile(fInfo: any): number {
128
+    // 实现获取大小逻辑
129
+    return 0;
130
+}
131
+const enum Enum {
132
+    A = 1,
133
+    B = A * 2,
134
+}
135
+// 为指定的日志记录器添加输出文件
136
+function SetAppender(logger: "", appender: any) {//TODO(logger: winston.Logger, appender: any)
137
+    // 实现添加输出文件逻辑
138
+}
139
+
140
+// 创建输出文件
141
+function CreateAppender(tellerNo: string, fileName: string): any {
142
+    // 实现创建输出文件逻辑
143
+    return {};
144
+}
145
+
146
+// 截屏函数
147
+function CutScreen(): string {
148
+    // 实现截屏逻辑
149
+    return '';
150
+}
151
+
152
+// 对待上传的目录进行备份,并返回目录路径
153
+function GetBackUp(): string {
154
+    // 实现备份逻辑
155
+    return '';
156
+}

+ 10
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/LogSystem/winston.ts View File

@@ -0,0 +1,10 @@
1
+///此文件是为了platformLogger报错写的问题件为了解决日志登记的问题
2
+export default class winston {
3
+
4
+    static createLogger<T>(key: string): string {
5
+        return "";
6
+    }
7
+    //日志类型枚举
8
+
9
+
10
+}

+ 61
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/RunningParameters/CommonParames.ts View File

@@ -0,0 +1,61 @@
1
+// 定义 CommonParames 命名空间,用于存储平台运行参数
2
+namespace Platform.Common.RunningParameters {
3
+    // 定义 CommonParames 类,用于存储各种参数
4
+    export class CommonParames {
5
+        // 字符编码
6
+        public static Coding: string = "gb2312";
7
+        // 交易日志配置节点名称
8
+        public static readonly TradeLog: string = "TradeLogger";
9
+        // 错误日志配置节点名称
10
+        public static readonly ErrLog: string = "ErrLogger";
11
+        // 系统名称
12
+        public static SysName: string = "东华商业银行核心业务系统";
13
+        // 更新程序名
14
+        public static readonly UpdateAppName: string = "TellerSys.Update.exe";
15
+        // 更新进程名
16
+        public static readonly UpdateProcName: string = "TellerSys.Update";
17
+        // 客户端程序名
18
+        public static readonly ClientAppName: string = "TellerSys.Client.exe";
19
+        // 客户端进程名
20
+        public static readonly ClientProcName: string = "TellerSys.Client";
21
+        // 主程序目录
22
+        public static MainDir: string = "TradeDll/";
23
+        // 服务端---交易Dll文件存放目录
24
+        public static TradeInfoPath: string = "pages";
25
+        // 服务端---客户端更新文件所在路径
26
+        public static UpdatedClientPath: string = "updatedfile";
27
+        // 服务端---配置文件所在目录
28
+        public static ConfigFilePath: string = "serverconfig";
29
+        // 帮助文件目录
30
+        public static TellerSysHelp: string = "TellerSysHelp";
31
+        // 服务端---临时文件所在目录
32
+        public static TempFilePath: string = "tmp";
33
+        // 与核心通讯方法名
34
+        public static CallServerName: string = "callserver";
35
+        // 与支付平台通讯方法名
36
+        public static CallAgnName: string = "callserver";
37
+        // 与财税库银通讯方法名
38
+        public static CallTipsName: string = "callserver";
39
+        // 菜单配置文件名称
40
+        public static MenuFileName: string = "Menu.xml";
41
+        // 任务菜单配置文件名称
42
+        public static TaskMenuFileName: string = "TaskMenu.xml";
43
+        // 服务器端存放交易文件附件的默认路径
44
+        public static TradeFilePath: string = "tmp";
45
+        // 错误码/错误信息映射关系Map
46
+        public static MsgErrorMap: { [key: string]: string } = {};
47
+        // 登录界面标题
48
+        public static LoginTitle: string = "商业银行核心业务系统登录界面";
49
+        // 系统采用的默认字体,用于交易和打印项的设计时与运行时呈现
50
+        public static DefaultFontFamily: string = "Microsoft YaHei";
51
+        // 系统采用的默认字体大小,用于交易和打印项的设计时与运行时呈现
52
+        public static DefaultFontSize: number = 14;
53
+        // 系统设计和打印表单采用的字体
54
+        public static DefaultPrintFontFamily: string = "宋体";
55
+        // 系统设计和打印表单采用的字体大小
56
+        public static DefaultPrintFontSize: number = 12;
57
+    }
58
+}
59
+
60
+// 导出 CommonParames 类,方便在其他地方使用
61
+export default Platform.Common.RunningParameters.CommonParames;

+ 184
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/RunningParameters/ConfigManager.ts View File

@@ -0,0 +1,184 @@
1
+// 假设 EncrypDecryptHelper 类的实现
2
+class EncrypDecryptHelper {
3
+    static Instance = new EncrypDecryptHelper();
4
+
5
+    DesDecryptFixKey(data: Uint8Array): Uint8Array {
6
+        // 实现解密逻辑
7
+        return data;
8
+    }
9
+
10
+    DesEncryptFixKey(data: Uint8Array): Uint8Array {
11
+        // 实现加密逻辑
12
+        return data;
13
+    }
14
+}
15
+
16
+// 配置文件类型枚举
17
+enum ConfigType {
18
+    System,
19
+    Client,
20
+    User
21
+}
22
+
23
+class ConfigManager {
24
+    private static instance: ConfigManager;
25
+    private readonly _dirName = "Config";
26
+    private readonly _clientFileInfo = `${this._dirName}/Platform.Client.Config`;
27
+    private _clientDictionary: { [key: string]: string } = {};
28
+    private readonly _systemFileInfo = `${this._dirName}/Platform.System.Config`;
29
+    private _systemDictionary: { [key: string]: string } = {};
30
+    private readonly _userFileInfo = `${this._dirName}/Platform.User.Config`;
31
+    private _userDictionary: { [key: string]: string } = {};
32
+
33
+    private constructor() { }
34
+
35
+    public static GetInstance(): ConfigManager {
36
+        if (!this.instance) {
37
+            this.instance = new ConfigManager();
38
+        }
39
+        return this.instance;
40
+    }
41
+
42
+    public async LoadConfig(configType: ConfigType, isEncryptedFile = false): Promise<boolean> {
43
+        switch (configType) {
44
+            case ConfigType.System:
45
+                return this.Load(this._systemFileInfo, this._systemDictionary, isEncryptedFile);
46
+            case ConfigType.Client:
47
+                return this.Load(this._clientFileInfo, this._clientDictionary);
48
+            case ConfigType.User:
49
+                return this.Load(this._userFileInfo, this._userDictionary, isEncryptedFile);
50
+            default:
51
+                return false;
52
+        }
53
+    }
54
+
55
+    private async Load(from: string, to: { [key: string]: string }, isEncryptedFile = false): Promise<boolean> {
56
+        try {
57
+            const response = await fetch(from);
58
+            if (response.ok) {
59
+                const data = new Uint8Array(await response.arrayBuffer());
60
+                let decryptedData = isEncryptedFile ? EncrypDecryptHelper.Instance.DesDecryptFixKey(data) : data;
61
+                const xmlString = new TextDecoder().decode(decryptedData);
62
+                const parser = new DOMParser();
63
+                const doc = parser.parseFromString(xmlString, "application/xml");
64
+                const elementCollection = doc.documentElement.children;
65
+                for (let i = 0; i < elementCollection.length; i++) {
66
+                    const element = elementCollection[i];
67
+                    const elementKey = element.getAttribute("key");
68
+                    const elementValue = element.getAttribute("value");
69
+                    if (!elementKey) break;
70
+                    if (to.hasOwnProperty(elementKey)) {
71
+                        to[elementKey] = elementValue || "";
72
+                    } else {
73
+                        to[elementKey] = elementValue || "";
74
+                    }
75
+                }
76
+                return true;
77
+            } else {
78
+                return false;
79
+            }
80
+        } catch (error) {
81
+            return false;
82
+        }
83
+    }
84
+
85
+    public async SaveConfig(configType: ConfigType, isEncryptedFile = false): Promise<string | null> {
86
+        switch (configType) {
87
+            case ConfigType.System:
88
+                return this.Save(this._systemDictionary, this._systemFileInfo, isEncryptedFile);
89
+            case ConfigType.Client:
90
+                return this.Save(this._clientDictionary, this._clientFileInfo);
91
+            case ConfigType.User:
92
+                return this.Save(this._userDictionary, this._userFileInfo, isEncryptedFile);
93
+            default:
94
+                return null;
95
+        }
96
+    }
97
+
98
+    private async Save(from: { [key: string]: string }, to: string, isEncryptedFile = false): Promise<string | null> {
99
+        const xmlDoc = document.implementation.createDocument(null, "elements");
100
+        xmlDoc.appendChild(xmlDoc.createProcessingInstruction("xml", 'version="1.0" encoding="UTF-8"'));
101
+        for (const [key, value] of Object.entries(from)) {
102
+            const element = xmlDoc.createElement("element");
103
+            element.setAttribute("key", key);
104
+            element.setAttribute("value", value);
105
+            xmlDoc.documentElement.appendChild(element);
106
+        }
107
+        const serializer = new XMLSerializer();
108
+        const xmlString = serializer.serializeToString(xmlDoc);
109
+        let data = new TextEncoder().encode(xmlString);
110
+        if (isEncryptedFile) {
111
+            data = EncrypDecryptHelper.Instance.DesEncryptFixKey(data);
112
+        }
113
+        try {
114
+            await fetch(to, {
115
+                method: "PUT",
116
+                body: data
117
+            });
118
+            return to;
119
+        } catch (error) {
120
+            return null;
121
+        }
122
+    }
123
+
124
+    public GetConfigValue(key: string, configType: ConfigType): string {
125
+        let ret = "";
126
+        if (key) {
127
+            switch (configType) {
128
+                case ConfigType.System:
129
+                    if (this._systemDictionary.hasOwnProperty(key)) {
130
+                        ret = this._systemDictionary[key];
131
+                    }
132
+                    break;
133
+                case ConfigType.Client:
134
+                    if (this._clientDictionary.hasOwnProperty(key)) {
135
+                        ret = this._clientDictionary[key];
136
+                    }
137
+                    break;
138
+                case ConfigType.User:
139
+                    if (this._userDictionary.hasOwnProperty(key)) {
140
+                        ret = this._userDictionary[key];
141
+                    }
142
+                    break;
143
+                default: break;
144
+            }
145
+        }
146
+        return ret;
147
+    }
148
+
149
+    public SetConfigValue(key: string, value: string, configType: ConfigType): boolean {
150
+        let ret = false;
151
+        if (key) {
152
+            switch (configType) {
153
+                case ConfigType.System:
154
+                    if (this._systemDictionary.hasOwnProperty(key)) {
155
+                        this._systemDictionary[key] = value;
156
+                    } else {
157
+                        this._systemDictionary[key] = value;
158
+                    }
159
+                    ret = true;
160
+                    break;
161
+                case ConfigType.Client:
162
+                    if (this._clientDictionary.hasOwnProperty(key)) {
163
+                        this._clientDictionary[key] = value;
164
+                    } else {
165
+                        this._clientDictionary[key] = value;
166
+                    }
167
+                    ret = true;
168
+                    break;
169
+                case ConfigType.User:
170
+                    if (this._userDictionary.hasOwnProperty(key)) {
171
+                        this._userDictionary[key] = value;
172
+                    } else {
173
+                        this._userDictionary[key] = value;
174
+                    }
175
+                    ret = true;
176
+                    break;
177
+                default: break;
178
+            }
179
+        }
180
+        return ret;
181
+    }
182
+}
183
+
184
+export { ConfigManager, ConfigType };

+ 60
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/RunningParameters/LoginUserInfo.ts View File

@@ -0,0 +1,60 @@
1
+import { GetDictionaryItem, SetDictionaryItem } from "../BasicFunctions/Extensions/DictionaryExtension";
2
+
3
+// 假设 TradeModel 类型已经定义
4
+interface TradeModel {
5
+    // 这里可以根据实际情况定义 TradeModel 的属性
6
+}
7
+
8
+export default class LoginUserInfo {
9
+    // 缓存数据,柜员登陆时加载
10
+    private static _dict: { [key: string]: any } = {};
11
+
12
+    // 操作员基础信息
13
+    static get KinbrNo(): string {
14
+        return this.GetUserInfo('KinbrNo');
15
+    }
16
+
17
+    static get KinbrName(): string {
18
+        return this.GetUserInfo('KinbrName');
19
+    }
20
+
21
+    static get TellerNo(): string {
22
+        return this.GetUserInfo('TellerNo');
23
+    }
24
+
25
+    static get TellerName(): string {
26
+        return this.GetUserInfo('TellerName');
27
+    }
28
+
29
+    static get TtyName(): string {
30
+        return this.GetUserInfo('TtyName');
31
+    }
32
+
33
+    static get TradeDate(): string {
34
+        return this.GetUserInfo('TradeDate');
35
+    }
36
+
37
+    static get TradeRight(): TradeModel[] {
38
+        return this.GetUserInfo<TradeModel[]>('TradeRight');
39
+    }
40
+
41
+    // // 获取参数指定的缓存配置项 //TODO此处有两种方法 不能重载
42
+    // static GetUserInfo(key: string): string {
43
+    //     let ret = '';
44
+    //     if (key && this._dict.hasOwnProperty(key)) {
45
+    //         ret = this._dict[key] || '';
46
+    //     }
47
+    //     return ret;
48
+    // }
49
+
50
+    // 获取参数指定的缓冲配置项,并转换成相应类型
51
+    static GetUserInfo<T>(key: string): T {
52
+        return GetDictionaryItem<T>(this._dict, key);
53
+    }
54
+
55
+    // 设置参数指定的缓冲配置项
56
+    static SetUserInfo(key: string, value: any): boolean {
57
+        SetDictionaryItem(this._dict, key, value);
58
+        return true;
59
+    }
60
+}

+ 143
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/RunningParameters/PlatformSettings.ts View File

@@ -0,0 +1,143 @@
1
+// 假设 ConfigManager 和 PlatformLogger 已经在其他地方定义
2
+class ConfigManager {
3
+    private static instance: ConfigManager;
4
+    private constructor() { }
5
+
6
+    public static GetInstance(): ConfigManager {
7
+        if (!this.instance) {
8
+            this.instance = new ConfigManager();
9
+        }
10
+        return this.instance;
11
+    }
12
+
13
+    public GetConfigValue(key: string, configType: ConfigType): string {
14
+        // 这里需要实现从配置文件读取值的逻辑
15
+        return '';
16
+    }
17
+}
18
+
19
+enum ConfigType {
20
+    Client,
21
+    System
22
+}
23
+
24
+export default class PlatformLogger {
25
+    public static SystemErrorInfo(message: string, error: Error): void {
26
+        console.error(message, error);
27
+    }
28
+}
29
+
30
+export class PlatformSettings {
31
+    private static _encoding: BufferEncoding;
32
+
33
+    /**
34
+     * 字符编码,默认值是系统默认
35
+     */
36
+    public static get Encoding(): BufferEncoding {
37
+        const encName = ConfigManager.GetInstance().GetConfigValue('Encoding', ConfigType.Client);
38
+        if (!this._encoding) {
39
+            this._encoding = 'utf8'; // 假设系统默认编码为 utf8
40
+        }
41
+        if (encName !== this._encoding) {
42
+            try {
43
+                // 若编码发生变化,则更新
44
+                this._encoding = encName as BufferEncoding;
45
+            } catch (e) {
46
+                PlatformLogger.SystemErrorInfo(`PlatformSettings.Encoding系统参数转换异常!${encName}`, e as Error);
47
+            }
48
+        }
49
+        return this._encoding;
50
+    }
51
+
52
+    /**
53
+     * 是否启用调试模式,默认为不启用
54
+     */
55
+    public static get IsDebugMode(): boolean {
56
+        let debugModeBoolean = false;
57
+        const debugMode = ConfigManager.GetInstance().GetConfigValue('IsDebugMode', ConfigType.System);
58
+        if (debugMode) {
59
+            debugModeBoolean = debugMode.toLowerCase() === 'true';
60
+        }
61
+        return debugModeBoolean;
62
+    }
63
+
64
+    /**
65
+     * 平台项目名称,默认为空
66
+     */
67
+    public static get PlatformTitle(): string {
68
+        return ConfigManager.GetInstance().GetConfigValue('PlatformTitle', ConfigType.System);
69
+    }
70
+
71
+    /**
72
+     * 打印偏移量,默认为(0,0)
73
+     */
74
+    public static get PrinterOffset(): { x: number; y: number } {
75
+        let offsetPoint = { x: 0, y: 0 };
76
+        const offset = ConfigManager.GetInstance().GetConfigValue('PrinterOffset', ConfigType.Client);
77
+        if (offset) {
78
+            const index = offset.indexOf(',');
79
+            if (index > 0) {
80
+                const offsetX = parseFloat(offset.substring(0, index));
81
+                const offsetY = parseFloat(offset.slice(index + 1));
82
+                if (!isNaN(offsetX) && !isNaN(offsetY)) {
83
+                    offsetPoint = { x: offsetX, y: offsetY };
84
+                }
85
+            }
86
+        }
87
+        return offsetPoint;
88
+    }
89
+
90
+    /**
91
+     * 服务器端通讯地址
92
+     */
93
+    public static get ServiceAddress(): string {
94
+        return ConfigManager.GetInstance().GetConfigValue('SocketServiceAddress', ConfigType.Client);
95
+    }
96
+
97
+    /**
98
+     * 通讯超时时间,默认是1分钟,单位是毫秒
99
+     */
100
+    public static get Timeout(): number {
101
+        let timeout = 6000;
102
+        const time = ConfigManager.GetInstance().GetConfigValue('SocketTimeOut', ConfigType.Client);
103
+        const parsedTime = parseInt(time, 10);
104
+        if (!isNaN(parsedTime)) {
105
+            timeout = parsedTime;
106
+        }
107
+        return timeout;
108
+    }
109
+
110
+    /**
111
+     * 交易文件dll路径,默认为Pages
112
+     */
113
+    public static get PagesDirectory(): string {
114
+        let procName = ConfigManager.GetInstance().GetConfigValue('PagesDirectory', ConfigType.System);
115
+        if (!procName) {
116
+            procName = 'Pages';
117
+        }
118
+        return procName;
119
+    }
120
+
121
+    /**
122
+     * 是否对报文加密标志
123
+     */
124
+    public static get IsEncrypt(): boolean {
125
+        let EncryptBoolean = false;
126
+        const Encrypt = ConfigManager.GetInstance().GetConfigValue('IsEncrypt', ConfigType.Client);
127
+        if (Encrypt) {
128
+            EncryptBoolean = Encrypt.toLowerCase() === 'true';
129
+        }
130
+        return EncryptBoolean;
131
+    }
132
+
133
+    /**
134
+     * 服务端通讯报文加密KEY
135
+     */
136
+    public static get EncryptsKey(): string {
137
+        let encryptskey = ConfigManager.GetInstance().GetConfigValue('EncryptsKey', ConfigType.Client);
138
+        if (!encryptskey) {
139
+            encryptskey = 'DHCCSoft';
140
+        }
141
+        return encryptskey;
142
+    }
143
+}

+ 72
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/RunningParameters/TradeParames.ts View File

@@ -0,0 +1,72 @@
1
+// 假设 Transit 类型定义如下
2
+type Transit = string; 
3
+
4
+export class TradeParames {
5
+    // 8583报文类型标识串
6
+    public static MsgType: string = "01001";
7
+    // 加减密字符串
8
+    public static KeyStr: string = "dhccnew";
9
+    // 交易数据日志配置节点名称
10
+    public static TradeDataLog: string = "TradeData";
11
+    // 1参数:渠道callserver,callagn,calltips
12
+    // 2参数:对应渠道的详细报文类型信息
13
+    public static MsgFormat: { [key in Transit]: { [key: string]: object } } | null = null;
14
+
15
+    // 交易参数字典
16
+    private static _tradeParames: Map<string, string> = new Map<string, string>();
17
+
18
+    // 机构号
19
+    public static get KinbrNo(): string {
20
+        return this.getValue("KinbrNo");
21
+    }
22
+    // 机构名称
23
+    public static get KinbrName(): string {
24
+        return this.getValue("KinbrName");
25
+    }
26
+    // 柜员号
27
+    public static get TellerNo(): string {
28
+        return this.getValue("TellerNo");
29
+    }
30
+    // 柜员姓名
31
+    public static get TellerName(): string {
32
+        return this.getValue("TellerName");
33
+    }
34
+    // 终端号
35
+    public static get TtyName(): string {
36
+        return this.getValue("TtyName");
37
+    }
38
+    // 交易日期
39
+    public static get TradeDate(): string {
40
+        return this.getValue("TradeDate");
41
+    }
42
+    // 权限
43
+    public static get Rights(): string {
44
+        return this.getValue("Rights");
45
+    }
46
+    // 开户局号
47
+    public static get Opnbr(): string {
48
+        return this.getValue("Opnbr");
49
+    }
50
+    // 密码
51
+    public static get Passwd(): string {
52
+        return this.getValue("Passwd");
53
+    }
54
+    // 柜员级别
55
+    public static get Tlrlvl(): string {
56
+        return this.getValue("Tlrlvl");
57
+    }
58
+
59
+    // 获取key对应的value
60
+    private static getValue(key: string): string {
61
+        if (!this._tradeParames.has(key)) {
62
+            this._tradeParames.set(key, "");
63
+        }
64
+        return this._tradeParames.get(key)!;
65
+    }
66
+
67
+    // 设置交易参数
68
+    public static setValue(key: string, value: string): boolean {
69
+        this._tradeParames.set(key, value);
70
+        return true;
71
+    }
72
+}

+ 17
- 0
ant-design-pro-vue3/src/views/front/platfrom/common/RunningParameters/transit.ts View File

@@ -0,0 +1,17 @@
1
+/**
2
+ * 通讯外端列表
3
+ */
4
+export enum Transit {
5
+    /**
6
+     * 核心后台
7
+     */
8
+    CallServer,
9
+    /**
10
+     * 平台渠道
11
+     */
12
+    CallAgn,
13
+    /**
14
+     * 财税平台
15
+     */
16
+    CallTips
17
+}

Loading…
Cancel
Save