@ibiz-template/core 0.0.4-beta.5 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/index.esm.js +427 -96
  2. package/dist/index.system.min.js +2 -1
  3. package/dist/index.system.min.js.map +1 -0
  4. package/out/constant/core/core.d.ts +2 -2
  5. package/out/constant/core/core.js +3 -4
  6. package/out/constant/util/util.d.ts.map +1 -1
  7. package/out/context/index.d.ts +17 -7
  8. package/out/context/index.d.ts.map +1 -1
  9. package/out/context/index.js +82 -40
  10. package/out/environment/environment.d.ts.map +1 -1
  11. package/out/environment/environment.js +5 -0
  12. package/out/error/model-error/model-error.d.ts +2 -2
  13. package/out/error/model-error/model-error.d.ts.map +1 -1
  14. package/out/error/model-error/model-error.js +0 -1
  15. package/out/error/runtime-model-error/runtime-model-error.d.ts +2 -2
  16. package/out/error/runtime-model-error/runtime-model-error.d.ts.map +1 -1
  17. package/out/error/runtime-model-error/runtime-model-error.js +0 -1
  18. package/out/ibizsys.d.ts +6 -4
  19. package/out/ibizsys.d.ts.map +1 -1
  20. package/out/ibizsys.js +6 -4
  21. package/out/index.d.ts +0 -1
  22. package/out/index.d.ts.map +1 -1
  23. package/out/index.js +0 -1
  24. package/out/install.d.ts.map +1 -1
  25. package/out/install.js +0 -2
  26. package/out/interface/i-environment/i-environment.d.ts +39 -0
  27. package/out/interface/i-environment/i-environment.d.ts.map +1 -1
  28. package/out/types.d.ts +11 -22
  29. package/out/types.d.ts.map +1 -1
  30. package/out/utils/download-file/download-file.d.ts.map +1 -1
  31. package/out/utils/index.d.ts +1 -1
  32. package/out/utils/index.d.ts.map +1 -1
  33. package/out/utils/index.js +1 -1
  34. package/out/utils/interceptor/core-interceptor.d.ts.map +1 -1
  35. package/out/utils/interceptor/core-interceptor.js +6 -2
  36. package/out/utils/interceptor/interceptor.d.ts +2 -2
  37. package/out/utils/interceptor/interceptor.d.ts.map +1 -1
  38. package/out/utils/logger/logger.d.ts +2 -2
  39. package/out/utils/logger/logger.d.ts.map +1 -1
  40. package/out/utils/logger/logger.js +5 -1
  41. package/out/utils/namespace/namespace.d.ts.map +1 -1
  42. package/out/utils/net/net.d.ts +12 -2
  43. package/out/utils/net/net.d.ts.map +1 -1
  44. package/out/utils/net/net.js +31 -5
  45. package/out/utils/recursive/find-recursive-child.d.ts +43 -0
  46. package/out/utils/recursive/find-recursive-child.d.ts.map +1 -0
  47. package/out/utils/recursive/find-recursive-child.js +90 -0
  48. package/out/utils/string-util/string-util.js +1 -2
  49. package/out/utils/style/remote-style.d.ts.map +1 -1
  50. package/out/utils/style/remote-style.js +1 -2
  51. package/out/utils/sync/count-latch.d.ts.map +1 -1
  52. package/out/utils/upload/select-file.d.ts.map +1 -1
  53. package/out/utils/upload/select-file.js +1 -1
  54. package/out/utils/upload/upload-file.d.ts.map +1 -1
  55. package/out/utils/upload/upload-file.js +2 -1
  56. package/out/utils/url-helper/url-helper.d.ts.map +1 -1
  57. package/out/utils/util/util.d.ts +58 -0
  58. package/out/utils/util/util.d.ts.map +1 -1
  59. package/out/utils/util/util.js +123 -0
  60. package/package.json +9 -8
  61. package/src/constant/core/core.ts +2 -2
  62. package/src/constant/util/util.ts +1 -1
  63. package/src/context/index.ts +91 -47
  64. package/src/environment/environment.ts +5 -0
  65. package/src/error/model-error/model-error.ts +4 -2
  66. package/src/error/runtime-model-error/runtime-model-error.ts +4 -2
  67. package/src/ibizsys.ts +7 -4
  68. package/src/index.ts +0 -1
  69. package/src/install.ts +0 -2
  70. package/src/interface/i-environment/i-environment.ts +44 -0
  71. package/src/types.ts +12 -23
  72. package/src/utils/click-outside/click-outside.ts +6 -6
  73. package/src/utils/download-file/download-file.ts +2 -2
  74. package/src/utils/event/event.ts +1 -1
  75. package/src/utils/index.ts +1 -1
  76. package/src/utils/interceptor/core-interceptor.ts +7 -2
  77. package/src/utils/interceptor/interceptor.ts +3 -3
  78. package/src/utils/logger/logger.ts +8 -1
  79. package/src/utils/namespace/namespace.ts +4 -1
  80. package/src/utils/net/net.ts +35 -11
  81. package/src/utils/recursive/find-recursive-child.ts +133 -0
  82. package/src/utils/style/remote-style.ts +1 -3
  83. package/src/utils/sync/count-latch.ts +5 -5
  84. package/src/utils/upload/select-file.ts +2 -2
  85. package/src/utils/upload/upload-file.ts +6 -5
  86. package/src/utils/url-helper/url-helper.ts +4 -4
  87. package/src/utils/util/util.ts +144 -2
  88. package/out/factory-center.d.ts +0 -11
  89. package/out/factory-center.d.ts.map +0 -1
  90. package/out/factory-center.js +0 -10
  91. package/src/factory-center.ts +0 -9
@@ -28,9 +28,9 @@ export class IBizContext implements IContext {
28
28
  * @author lxm
29
29
  * @date 2022-12-08 18:12:16
30
30
  * @protected
31
- * @type {IDatum}
31
+ * @type {IData}
32
32
  */
33
- protected declare _context: IDatum;
33
+ protected declare _context: IData;
34
34
 
35
35
  /**
36
36
  * 父的上下文源对象
@@ -46,69 +46,78 @@ export class IBizContext implements IContext {
46
46
  *
47
47
  * @author chitanda
48
48
  * @date 2022-07-14 10:07:15
49
- * @param {IDatum} [context={}] 自身的上下文
49
+ * @param {IData} [context={}] 自身的上下文
50
50
  * @param {IContext} [parent]
51
51
  */
52
52
  // eslint-disable-next-line default-param-last
53
- private constructor(context: IDatum = {}, parent?: IContext) {
53
+ private constructor(context: IData = {}, parent?: IContext) {
54
54
  Object.defineProperty(this, '_associationContext', {
55
55
  enumerable: false,
56
56
  value: [],
57
57
  });
58
58
 
59
59
  if (parent) {
60
- // eslint-disable-next-line @typescript-eslint/no-this-alias
61
- const self = this;
62
-
63
- // 定义私有变量,存放父上下文源对象
64
- Object.defineProperty(this, '_parent', {
65
- enumerable: false,
66
- writable: true,
67
- value: parent,
68
- });
69
-
70
- // 定义私有变量,用于存储对父已有上下文的修改。
71
- Object.defineProperty(this, '_context', {
72
- enumerable: false,
73
- writable: true,
74
- value: {},
75
- });
76
- // 监控父上下文参数,自身不存在时从父取
77
- const properties: { [key: string]: PropertyDescriptor } = {};
78
- const keys = Object.keys(parent);
79
- keys.forEach(key => {
80
- properties[key] = {
81
- enumerable: true,
82
- set(val: unknown) {
83
- if (val == null) {
84
- self._context[key] = null;
85
- } else {
86
- self._context[key] = val;
87
- }
88
- },
89
- get() {
90
- if (self._context[key] !== undefined) {
91
- return self._context[key];
92
- }
93
- return parent[key];
94
- },
95
- };
96
- });
97
- Object.defineProperties(this, properties);
60
+ this.initWithParent(parent);
98
61
  }
62
+
99
63
  // 合并给入上下文
100
64
  Object.assign(this, context);
101
65
  }
102
66
 
67
+ private initWithParent(parent: IContext): void {
68
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
69
+ const self = this;
70
+
71
+ // 定义私有变量,存放父上下文源对象
72
+ Object.defineProperty(this, '_parent', {
73
+ enumerable: false,
74
+ writable: true,
75
+ value: parent,
76
+ });
77
+
78
+ // 定义私有变量,用于存储对父已有上下文的修改。
79
+ Object.defineProperty(this, '_context', {
80
+ enumerable: false,
81
+ writable: true,
82
+ value: {},
83
+ });
84
+ // 监控父上下文参数,自身不存在时从父取
85
+ const properties: { [key: string]: PropertyDescriptor } = {};
86
+ const keys = Object.keys(parent);
87
+ keys.forEach(key => {
88
+ if (Object.prototype.hasOwnProperty.call(this, key)) {
89
+ // !已经定义的不重复定义,会报错
90
+ return;
91
+ }
92
+ properties[key] = {
93
+ enumerable: true,
94
+ set(val: unknown): void {
95
+ if (val == null) {
96
+ self._context[key] = null;
97
+ } else {
98
+ self._context[key] = val;
99
+ }
100
+ },
101
+ get(): IContext {
102
+ if (self._context[key] !== undefined) {
103
+ return self._context[key];
104
+ }
105
+ return self._parent![key];
106
+ },
107
+ };
108
+ });
109
+ Object.defineProperties(this, properties);
110
+ }
111
+
103
112
  /**
104
113
  * 返回自身的上下文,独有的和与父有差异的。
105
114
  *
106
115
  * @author lxm
107
116
  * @date 2022-12-08 17:12:26
108
- * @returns {*} {IDatum}
117
+ * @returns {*} {IData}
109
118
  */
110
- getOwnContext(): IDatum {
111
- const result: IDatum = {};
119
+ getOwnContext(): IData {
120
+ const result: IData = {};
112
121
  Object.keys(this).forEach(key => {
113
122
  // 父没有的,或者修改了父的上下文
114
123
  // 父不存在则返回所有自身的属性
@@ -153,17 +162,52 @@ export class IBizContext implements IContext {
153
162
  return newContext;
154
163
  }
155
164
 
165
+ /**
166
+ * 在不改变对象引用的情况下,重置上下文
167
+ * 等效于重新实例化,但是引用不变
168
+ * @author lxm
169
+ * @date 2023-05-24 10:30:40
170
+ * @param {IData} [context={}]
171
+ * @param {IContext} [parent]
172
+ */
173
+ // eslint-disable-next-line default-param-last
174
+ reset(context: IData = {}, parent?: IContext): void {
175
+ // 清空_associationContext
176
+ this._associationContext.forEach(item => {
177
+ item.destroy();
178
+ });
179
+ // 置空parent相关属性
180
+ if (this._parent) {
181
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
182
+ this._parent = {} as any;
183
+ this._context = {};
184
+ }
185
+ // 删除自身的属性,define的删不掉,上面置空了就不管了
186
+ Object.keys(this).forEach(key => {
187
+ try {
188
+ delete this[key];
189
+ } catch (error) {
190
+ // 删不掉的不管了,上面已经变成uneducated了
191
+ }
192
+ });
193
+ if (parent) {
194
+ this.initWithParent(parent);
195
+ }
196
+ // 合并默认值
197
+ Object.assign(this, context);
198
+ }
199
+
156
200
  /**
157
201
  * 上下文只有在视图初始化时,调用 create 方法
158
202
  *
159
203
  * @author chitanda
160
204
  * @date 2023-03-13 16:03:32
161
205
  * @static
162
- * @param {IDatum} [context]
206
+ * @param {IData} [context]
163
207
  * @param {IContext} [parent]
164
208
  * @return {*} {IContext}
165
209
  */
166
- static create(context?: IDatum, parent?: IContext): IBizContext {
210
+ static create(context?: IData, parent?: IContext): IBizContext {
167
211
  return new IBizContext(context, parent);
168
212
  }
169
213
  }
@@ -11,6 +11,7 @@ export const Environment: IEnvironment = {
11
11
  baseUrl: '/api',
12
12
  appId: '',
13
13
  pluginBaseUrl: './plugins',
14
+ isLocalModel: false,
14
15
  remoteModelUrl: '/remotemodel',
15
16
  assetsUrl: './assets',
16
17
  dcSystem: '',
@@ -22,4 +23,8 @@ export const Environment: IEnvironment = {
22
23
  enablePermission: true,
23
24
  routePlaceholder: '-',
24
25
  enableWfAllHistory: false,
26
+ isMob: false,
27
+ isSaaSMode: true,
28
+ AppTitle: '应用',
29
+ favicon: './favicon.ico',
25
30
  };
@@ -17,8 +17,10 @@ export class ModelError extends Error {
17
17
  * @param {IModelObject} model 模板未支持的模型
18
18
  * @param {string} [msg]
19
19
  */
20
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
- constructor(public model: any, msg?: string) {
20
+ constructor(
21
+ public model: IData,
22
+ msg?: string,
23
+ ) {
22
24
  super(`「${model.id}」模型${msg ? `: ${msg}` : ''}`);
23
25
  }
24
26
  }
@@ -18,8 +18,10 @@ export class RuntimeModelError extends Error {
18
18
  * @param {IModelObject} model 丢失配置的模型
19
19
  * @param {string} [msg] 缺失配置描述
20
20
  */
21
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
- constructor(public model: any, msg?: string) {
21
+ constructor(
22
+ public model: IData,
23
+ msg?: string,
24
+ ) {
23
25
  super(`「${model.id}」模型${msg ? `: ${msg}` : ''}`);
24
26
  }
25
27
  }
package/src/ibizsys.ts CHANGED
@@ -1,7 +1,9 @@
1
+ import { Logger } from 'loglevel';
1
2
  import { CommandController } from './command';
2
3
  import { Environment } from './environment/environment';
3
4
  import { OrgData } from './interface';
4
- import { Logger, Net } from './utils';
5
+ import { Net } from './utils';
6
+ import { logger } from './utils/logger/logger';
5
7
 
6
8
  /**
7
9
  * 全局对象
@@ -21,12 +23,13 @@ export class IBizSys {
21
23
  env = Environment;
22
24
 
23
25
  /**
24
- * 日志对象
26
+ * 日志输出工具类
25
27
  *
26
28
  * @author chitanda
27
- * @date 2022-10-25 20:10:22
29
+ * @date 2023-07-10 18:07:05
30
+ * @type {Logger}
28
31
  */
29
- log = Logger;
32
+ log: Logger = logger;
30
33
 
31
34
  /**
32
35
  * 网络请求工具类(发送默认请求)
package/src/index.ts CHANGED
@@ -8,5 +8,4 @@ export * from './error';
8
8
  export * from './interface';
9
9
  export * from './utils';
10
10
  export { IBizSys } from './ibizsys';
11
- export { FactoryCenter } from './factory-center';
12
11
  export { install } from './install';
package/src/install.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { FactoryCenter } from './factory-center';
2
1
  import { IBizSys } from './ibizsys';
3
2
 
4
3
  /**
@@ -13,5 +12,4 @@ export function install(): void {
13
12
  throw new Error('ibiz 已经存在, 无需重复安装');
14
13
  }
15
14
  window.ibiz = new IBizSys();
16
- window.___fc = new FactoryCenter();
17
15
  }
@@ -92,6 +92,15 @@ export interface IEnvironment {
92
92
  */
93
93
  casLoginUrl: string;
94
94
 
95
+ /**
96
+ * 模型是否为本地模型(走静态资源模式)
97
+ *
98
+ * @author chitanda
99
+ * @date 2023-07-06 15:07:19
100
+ * @type {boolean}
101
+ */
102
+ isLocalModel: boolean;
103
+
95
104
  /**
96
105
  * 远程模型路径
97
106
  *
@@ -170,4 +179,39 @@ export interface IEnvironment {
170
179
  * @memberof IEnvironment
171
180
  */
172
181
  enableWfAllHistory: boolean;
182
+
183
+ /**
184
+ * 应用标题
185
+ *
186
+ * @type {string}
187
+ * @memberof IEnvironment
188
+ */
189
+ AppTitle?: string;
190
+
191
+ /**
192
+ * 是否为 SaaS 模式
193
+ *
194
+ * @author chitanda
195
+ * @date 2023-07-11 16:07:23
196
+ * @type {boolean}
197
+ */
198
+ isSaaSMode?: boolean;
199
+
200
+ /**
201
+ * 是否为移动端应用
202
+ *
203
+ * @author chitanda
204
+ * @date 2023-06-20 12:06:15
205
+ * @type {boolean}
206
+ */
207
+ isMob?: boolean;
208
+
209
+ /**
210
+ * 应用图标地址
211
+ *
212
+ * @author chitanda
213
+ * @date 2023-07-17 17:07:23
214
+ * @type {string}
215
+ */
216
+ favicon?: string;
173
217
  }
package/src/types.ts CHANGED
@@ -1,21 +1,11 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { FactoryCenter } from './factory-center';
3
2
  import { IBizSys } from './ibizsys';
4
3
 
5
4
  declare global {
6
5
  const ibiz: IBizSys;
7
- const ___fc: FactoryCenter;
8
6
 
9
7
  interface Window {
10
8
  ibiz: IBizSys;
11
- /**
12
- * 全局工厂中心
13
- *
14
- * @author lxm
15
- * @date 2022-10-17 15:10:43
16
- * @type {FactoryCenter}
17
- */
18
- ___fc: FactoryCenter;
19
9
  }
20
10
 
21
11
  /**
@@ -51,9 +41,9 @@ declare global {
51
41
  *
52
42
  * @author chitanda
53
43
  * @date 2023-03-13 17:03:10
54
- * @return {*} {IDatum}
44
+ * @return {*} {IData}
55
45
  */
56
- getOwnContext(): IDatum;
46
+ getOwnContext(): IData;
57
47
 
58
48
  /**
59
49
  * 销毁当前上下文
@@ -71,6 +61,16 @@ declare global {
71
61
  * @return {*} {IContext}
72
62
  */
73
63
  clone(): IContext;
64
+
65
+ /**
66
+ * 在不改变对象引用的情况下,重置上下文
67
+ * 等效于重新实例化,但是引用不变
68
+ * @author lxm
69
+ * @date 2023-05-24 10:30:40
70
+ * @param {IData} [context={}] 默认值
71
+ * @param {IContext} [parent] 父上下文
72
+ */
73
+ reset(context?: IData, parent?: IContext): void;
74
74
  }
75
75
 
76
76
  /**
@@ -95,17 +95,6 @@ declare global {
95
95
  [key: string | symbol]: any;
96
96
  }
97
97
 
98
- /**
99
- * 数据
100
- *
101
- * @author chitanda
102
- * @date 2023-03-13 17:03:50
103
- * @interface IDatum
104
- */
105
- interface IDatum {
106
- [key: string | symbol]: any;
107
- }
108
-
109
98
  /**
110
99
  * 任意对象结构
111
100
  *
@@ -37,7 +37,7 @@ export function onClickOutside(
37
37
  * @param event 事件对象
38
38
  * @returns
39
39
  */
40
- const isOutside = (event: MouseEvent) => {
40
+ const isOutside = (event: MouseEvent): boolean => {
41
41
  // 有一个判断是在内部,则不算外部,返回false
42
42
  return ![target, ...ignore].some(el => {
43
43
  return isEventInside(event, el);
@@ -46,10 +46,10 @@ export function onClickOutside(
46
46
 
47
47
  /** 暂停,所有监听的回调都不执行,用于增强某些ignore无法实现的场景 */
48
48
  let isPaused = false;
49
- const pause = () => {
49
+ const pause = (): void => {
50
50
  isPaused = true;
51
51
  };
52
- const proceed = () => {
52
+ const proceed = (): void => {
53
53
  isPaused = false;
54
54
  };
55
55
 
@@ -61,7 +61,7 @@ export function onClickOutside(
61
61
  * @param event 事件对象
62
62
  * @returns
63
63
  */
64
- const listener = (event: MouseEvent) => {
64
+ const listener = (event: MouseEvent): void => {
65
65
  if (isPaused) return;
66
66
  window.clearTimeout(fallback);
67
67
 
@@ -94,7 +94,7 @@ export function onClickOutside(
94
94
  if (e.button === 0) {
95
95
  // 锁死结果避免延时执行时变更
96
96
  const path = eventPath(e);
97
- e.composedPath = () => path;
97
+ e.composedPath = (): (EventTarget | null)[] => path;
98
98
  fallback = window.setTimeout(() => listener(e), 50);
99
99
  }
100
100
  },
@@ -105,6 +105,6 @@ export function onClickOutside(
105
105
  /**
106
106
  * 停止事件监听,移除监听
107
107
  */
108
- const stop = () => cleanups.forEach(fn => fn());
108
+ const stop = (): void => cleanups.forEach(fn => fn());
109
109
  return { stop, pause, proceed };
110
110
  }
@@ -7,7 +7,7 @@
7
7
  * @param {string} fileName
8
8
  * @returns {*}
9
9
  */
10
- export function calcMimeByFileName(fileName: string) {
10
+ export function calcMimeByFileName(fileName: string): string {
11
11
  const ext = fileName.split('.').pop();
12
12
  let mime = '';
13
13
  switch (ext) {
@@ -87,7 +87,7 @@ export function isImage(fileName: string): boolean {
87
87
  * @param {Blob} file 文件流Blob
88
88
  * @param {string} fileName 文件名称
89
89
  */
90
- export function downloadFileFromBlob(file: Blob, fileName: string) {
90
+ export function downloadFileFromBlob(file: Blob, fileName: string): void {
91
91
  // 获取文件名
92
92
  const filetype = calcMimeByFileName(fileName);
93
93
  // 用blob对象获取文件流
@@ -51,7 +51,7 @@ export function listenJSEvent(
51
51
  ): () => void {
52
52
  target.addEventListener(eventName, listener, options);
53
53
 
54
- let cleanup = () => {
54
+ let cleanup = (): void => {
55
55
  target.removeEventListener(eventName, listener, options);
56
56
  // cleanup方法只能调用一次
57
57
  cleanup = NOOP;
@@ -1,5 +1,4 @@
1
1
  export * from './interceptor';
2
- export { Logger } from './logger/logger';
3
2
  export { Namespace } from './namespace/namespace';
4
3
  export { IHttpResponse, HttpResponse } from './net/http-response';
5
4
  export { Net } from './net/net';
@@ -15,3 +14,4 @@ export * from './upload/select-file';
15
14
  export * from './upload/upload-file';
16
15
  export * from './sync';
17
16
  export * from './style/remote-style';
17
+ export * from './recursive/find-recursive-child';
@@ -15,21 +15,26 @@ export class CoreInterceptor extends Interceptor {
15
15
  protected async onBeforeRequest(
16
16
  config: InternalAxiosRequestConfig,
17
17
  ): Promise<InternalAxiosRequestConfig> {
18
- await super.onBeforeRequest(config);
18
+ config = await super.onBeforeRequest(config);
19
19
 
20
20
  const { headers } = config;
21
21
 
22
+ // Set the access token.
22
23
  headers.set('Authorization', `Bearer ${getToken()}`);
23
24
 
25
+ // Set the system ID.
26
+ let systemId = ibiz.env.dcSystem;
24
27
  const { orgData } = ibiz;
25
28
  if (orgData) {
26
29
  if (orgData.systemid) {
27
- headers.set('srfsystemid', orgData.systemid);
30
+ systemId = orgData.systemid;
28
31
  }
29
32
  if (orgData.orgid) {
30
33
  headers.set('srforgid', orgData.orgid);
31
34
  }
32
35
  }
36
+ headers.set('srfsystemid', systemId);
37
+
33
38
  return config;
34
39
  }
35
40
  }
@@ -57,7 +57,7 @@ export class Interceptor {
57
57
  * @protected
58
58
  * @param {*} error
59
59
  */
60
- protected onRequestError(error: any) {
60
+ protected onRequestError(error: Error): Promise<never> {
61
61
  // 处理请求错误
62
62
  return Promise.reject(error);
63
63
  }
@@ -85,7 +85,7 @@ export class Interceptor {
85
85
  * @protected
86
86
  * @param {*} _error
87
87
  */
88
- protected onResponseError(error: any) {
88
+ protected onResponseError(error: Error): Promise<never> {
89
89
  // 处理响应错误
90
90
  return Promise.reject(error);
91
91
  }
@@ -115,7 +115,7 @@ export class Interceptor {
115
115
  * @date 2022-10-27 17:10:27
116
116
  * @param {AxiosInstance} instance
117
117
  */
118
- eject(instance: AxiosInstance) {
118
+ eject(instance: AxiosInstance): void {
119
119
  if (this.requestTag) {
120
120
  instance.interceptors.request.eject(this.requestTag);
121
121
  }
@@ -1,3 +1,10 @@
1
1
  import * as Logger from 'loglevel';
2
+ import * as prefix from 'loglevel-plugin-prefix';
2
3
 
3
- export { Logger };
4
+ const logger = Logger.noConflict();
5
+
6
+ prefix.reg(logger);
7
+
8
+ prefix.apply(logger);
9
+
10
+ export { logger };
@@ -64,7 +64,10 @@ export class Namespace {
64
64
  * @param {string} block 当前命名空间的根模块,例如组件的名称
65
65
  * @param {string} [namespace] 指定命名空间,未指定使用默认值 ibiz
66
66
  */
67
- constructor(protected block: string, namespace?: string) {
67
+ constructor(
68
+ protected block: string,
69
+ namespace?: string,
70
+ ) {
68
71
  this.namespace = namespace || defaultNamespace;
69
72
  }
70
73
 
@@ -42,6 +42,17 @@ export class Net {
42
42
  */
43
43
  protected urlReg = /^http[s]?:\/\/[^\s]*/;
44
44
 
45
+ /**
46
+ * 请求等待队列,防止重复请求。当有完全相同请求参数的请求时,会等待上一个请求完成后把结果返回给当前请求,不会重复请求
47
+ * key: 由请求的 config 生成的字符串,用于唯一标识请求
48
+ * value: 当前正在请求的 Promise
49
+ *
50
+ * @author chitanda
51
+ * @date 2023-06-07 14:06:19
52
+ * @protected
53
+ */
54
+ protected waitRequest = new Map<string, Promise<AxiosResponse>>();
55
+
45
56
  /**
46
57
  * Creates an instance of Net.
47
58
  * @author lxm
@@ -70,7 +81,7 @@ export class Net {
70
81
  * @param {string} name 唯一标识
71
82
  * @param {Interceptor} interceptor 拦截器
72
83
  */
73
- addInterceptor(name: string, interceptor: Interceptor) {
84
+ addInterceptor(name: string, interceptor: Interceptor): void {
74
85
  interceptor.use(this.instance);
75
86
  this.interceptors.set(name, interceptor);
76
87
  }
@@ -82,7 +93,7 @@ export class Net {
82
93
  * @date 2022-10-27 17:10:27
83
94
  * @param {string} name 唯一标识
84
95
  */
85
- removeInterceptor(name: string) {
96
+ removeInterceptor(name: string): void {
86
97
  const interceptor = this.interceptors.get(name);
87
98
  if (interceptor) {
88
99
  interceptor.eject(this.instance);
@@ -121,7 +132,7 @@ export class Net {
121
132
  * @param {...AxiosRequestConfig[]} configs
122
133
  * @returns {*}
123
134
  */
124
- protected mergeConfig(...configs: AxiosRequestConfig[]) {
135
+ protected mergeConfig(...configs: AxiosRequestConfig[]): AxiosRequestConfig {
125
136
  const config = this.presetConfig;
126
137
  if (configs.length === 0) {
127
138
  return config;
@@ -180,10 +191,6 @@ export class Net {
180
191
  headers: RawAxiosRequestHeaders = {},
181
192
  option: AxiosRequestConfig = {},
182
193
  ): Promise<IHttpResponse> {
183
- // if (params.srfparentdata) {
184
- // Object.assign(params, params.srfparentdata);
185
- // delete params.srfparentdata;
186
- // }
187
194
  url = this.attachUrlParam(url, params);
188
195
  try {
189
196
  const response = await this.request(
@@ -286,12 +293,29 @@ export class Net {
286
293
  url: string,
287
294
  config: AxiosRequestConfig = {},
288
295
  ): Promise<IHttpResponse> {
296
+ // axios 请求参数配置
297
+ const cfg = this.mergeConfig({ url }, config);
298
+ // 当前请求的唯一标识
299
+ const key = JSON.stringify(cfg);
289
300
  try {
290
- const response = await this.instance.request(
291
- this.mergeConfig({ url }, config),
292
- );
301
+ let requestPromise: Promise<AxiosResponse> | null = null;
302
+ if (!this.waitRequest.has(key)) {
303
+ requestPromise = this.instance.request(cfg);
304
+ this.waitRequest.set(key, requestPromise);
305
+ } else {
306
+ requestPromise = this.waitRequest.get(key)!;
307
+ }
308
+ const response = await requestPromise;
309
+ // 当第一个请求完成后就删除等待队列中的请求
310
+ if (this.waitRequest.has(key)) {
311
+ this.waitRequest.delete(key);
312
+ }
293
313
  return this.doResponseResult(response);
294
314
  } catch (error) {
315
+ // 请求异常删除等待队列中的请求体
316
+ if (this.waitRequest.has(key)) {
317
+ this.waitRequest.delete(key);
318
+ }
295
319
  throw new HttpError(error as AxiosError);
296
320
  }
297
321
  }
@@ -304,7 +328,7 @@ export class Net {
304
328
  * @param {AxiosRequestConfig<IData>} config
305
329
  * @return {*}
306
330
  */
307
- axios(config: AxiosRequestConfig<IData>) {
331
+ axios(config: AxiosRequestConfig<IData>): Promise<AxiosResponse> {
308
332
  return axios(config);
309
333
  }
310
334