@ibiz-template/core 0.7.41-alpha.101 → 0.7.41-alpha.113

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 (143) hide show
  1. package/dist/index.esm.js +2 -1
  2. package/dist/index.system.min.js +1 -1
  3. package/out/environment/environment.d.ts.map +1 -1
  4. package/out/environment/environment.js +1 -0
  5. package/out/interface/api/environment/i-environment.d.ts +8 -0
  6. package/out/interface/api/environment/i-environment.d.ts.map +1 -1
  7. package/package.json +3 -2
  8. package/src/command/command-register.ts +121 -0
  9. package/src/command/command.ts +78 -0
  10. package/src/command/index.ts +8 -0
  11. package/src/command/utils/index.ts +2 -0
  12. package/src/command/utils/linked-list.ts +136 -0
  13. package/src/command/utils/util.ts +103 -0
  14. package/src/constant/core/core.ts +54 -0
  15. package/src/constant/emoji/emoji.ts +2929 -0
  16. package/src/constant/http-status-message/http-status-message.ts +18 -0
  17. package/src/constant/index.ts +4 -0
  18. package/src/constant/util/util.ts +3 -0
  19. package/src/context/index.ts +231 -0
  20. package/src/environment/environment.ts +65 -0
  21. package/src/error/http-error/entity-error.ts +29 -0
  22. package/src/error/http-error/http-error-factory.ts +24 -0
  23. package/src/error/http-error/http-error.ts +52 -0
  24. package/src/error/index.ts +7 -0
  25. package/src/error/model-error/model-error.ts +27 -0
  26. package/src/error/notice-error/notice-error.ts +16 -0
  27. package/src/error/runtime-error/runtime-error.ts +13 -0
  28. package/src/error/runtime-model-error/runtime-model-error.ts +27 -0
  29. package/src/ibizsys.ts +82 -0
  30. package/src/index.ts +14 -0
  31. package/src/install.ts +12 -0
  32. package/src/interface/api/chat-message/i-api-chat-message.ts +71 -0
  33. package/src/interface/api/chat-message/index.ts +1 -0
  34. package/src/interface/api/constant/index.ts +2 -0
  35. package/src/interface/api/constant/login-mode/login-mode.ts +25 -0
  36. package/src/interface/api/constant/menu-permission-mode/menu-permission-mode.ts +20 -0
  37. package/src/interface/api/environment/i-devtool-config.ts +56 -0
  38. package/src/interface/api/environment/i-environment.ts +532 -0
  39. package/src/interface/api/environment/index.ts +2 -0
  40. package/src/interface/api/global-param/i-api-context.ts +37 -0
  41. package/src/interface/api/global-param/i-global-param.ts +27 -0
  42. package/src/interface/api/global-param/index.ts +2 -0
  43. package/src/interface/api/ibizsys/i-api-ibizsys.ts +54 -0
  44. package/src/interface/api/ibizsys/i-app-data.ts +64 -0
  45. package/src/interface/api/ibizsys/i-org-data.ts +31 -0
  46. package/src/interface/api/ibizsys/index.ts +3 -0
  47. package/src/interface/api/index.ts +6 -0
  48. package/src/interface/api/utils/i-api-i18n.ts +56 -0
  49. package/src/interface/api/utils/index.ts +5 -0
  50. package/src/interface/api/utils/message-center/base/i-message-all.ts +8 -0
  51. package/src/interface/api/utils/message-center/base/i-message-base.ts +29 -0
  52. package/src/interface/api/utils/message-center/base/index.ts +2 -0
  53. package/src/interface/api/utils/message-center/command/add-in-changed/i-add-in-changed.ts +25 -0
  54. package/src/interface/api/utils/message-center/command/add-in-changed/i-command-add-in-changed.ts +16 -0
  55. package/src/interface/api/utils/message-center/command/async-action/i-command-async-action.ts +17 -0
  56. package/src/interface/api/utils/message-center/command/change/i-command-change.ts +8 -0
  57. package/src/interface/api/utils/message-center/command/create/i-command-create.ts +18 -0
  58. package/src/interface/api/utils/message-center/command/i-command-base.ts +23 -0
  59. package/src/interface/api/utils/message-center/command/i-message-command.ts +94 -0
  60. package/src/interface/api/utils/message-center/command/index.ts +20 -0
  61. package/src/interface/api/utils/message-center/command/internal-message/i-command-internal-message.ts +17 -0
  62. package/src/interface/api/utils/message-center/command/internal-message/i-internal-message.ts +132 -0
  63. package/src/interface/api/utils/message-center/command/mark-open-data/i-command-mark-open-data.ts +17 -0
  64. package/src/interface/api/utils/message-center/command/mark-open-data/i-mark-open-data.ts +47 -0
  65. package/src/interface/api/utils/message-center/command/remove/i-command-remove.ts +18 -0
  66. package/src/interface/api/utils/message-center/command/update/i-command-update.ts +18 -0
  67. package/src/interface/api/utils/message-center/common/i-app-data-entity.ts +16 -0
  68. package/src/interface/api/utils/message-center/common/i-message-center-event.ts +15 -0
  69. package/src/interface/api/utils/message-center/common/i-msg-meta-data.ts +13 -0
  70. package/src/interface/api/utils/message-center/common/i-portal-async-action.ts +144 -0
  71. package/src/interface/api/utils/message-center/common/i-portal-message.ts +84 -0
  72. package/src/interface/api/utils/message-center/common/index.ts +5 -0
  73. package/src/interface/api/utils/message-center/console/i-message-console.ts +17 -0
  74. package/src/interface/api/utils/message-center/error/i-message-error.ts +17 -0
  75. package/src/interface/api/utils/message-center/i-message-center.ts +53 -0
  76. package/src/interface/api/utils/message-center/index.ts +6 -0
  77. package/src/interface/api/utils/net/i-api-http-error.ts +43 -0
  78. package/src/interface/api/utils/net/i-api-net.ts +93 -0
  79. package/src/interface/api/utils/net/i-http-response.ts +67 -0
  80. package/src/interface/click-outside/click-outside.ts +51 -0
  81. package/src/interface/command/command/i-command-option.ts +47 -0
  82. package/src/interface/command/command/i-command.ts +68 -0
  83. package/src/interface/command/disposable/i-disposable.ts +12 -0
  84. package/src/interface/command/i-command-controller.ts +50 -0
  85. package/src/interface/command/index.ts +11 -0
  86. package/src/interface/context/index.ts +42 -0
  87. package/src/interface/error/index.ts +13 -0
  88. package/src/interface/i-chat-message/i-chat-message.ts +16 -0
  89. package/src/interface/ibizsys/i-ibizsys.ts +33 -0
  90. package/src/interface/ibizsys/index.ts +1 -0
  91. package/src/interface/index.ts +11 -0
  92. package/src/interface/utils/i-18n.ts +22 -0
  93. package/src/interface/utils/index.ts +1 -0
  94. package/src/locale/en/index.ts +30 -0
  95. package/src/locale/index.ts +2 -0
  96. package/src/locale/zh-CN/index.ts +28 -0
  97. package/src/params/params.ts +131 -0
  98. package/src/types.ts +26 -0
  99. package/src/utils/bit-mask/bit-mask.ts +87 -0
  100. package/src/utils/click-outside/click-outside.ts +108 -0
  101. package/src/utils/clone/clone.ts +38 -0
  102. package/src/utils/color/color.ts +84 -0
  103. package/src/utils/cookie-util/cookie-util.ts +192 -0
  104. package/src/utils/data-type/data-types.ts +93 -0
  105. package/src/utils/download-file/download-file.ts +110 -0
  106. package/src/utils/event/event.ts +69 -0
  107. package/src/utils/history-list/history-item.ts +41 -0
  108. package/src/utils/history-list/history-list.ts +137 -0
  109. package/src/utils/index.ts +24 -0
  110. package/src/utils/interceptor/core-interceptor.ts +127 -0
  111. package/src/utils/interceptor/index.ts +2 -0
  112. package/src/utils/interceptor/interceptor.ts +122 -0
  113. package/src/utils/logger/logger.ts +34 -0
  114. package/src/utils/message-center/base/message-all.ts +10 -0
  115. package/src/utils/message-center/base/message-base.ts +73 -0
  116. package/src/utils/message-center/command/add-in-changed/command-add-in-changed.ts +23 -0
  117. package/src/utils/message-center/command/async-action/command-async-action.ts +23 -0
  118. package/src/utils/message-center/command/change/command-change.ts +11 -0
  119. package/src/utils/message-center/command/command-base/command-base.ts +35 -0
  120. package/src/utils/message-center/command/create/command-create.ts +25 -0
  121. package/src/utils/message-center/command/internal-message/command-internal-message.ts +26 -0
  122. package/src/utils/message-center/command/mark-open-data/command-mark-open-data.ts +23 -0
  123. package/src/utils/message-center/command/message-command.ts +162 -0
  124. package/src/utils/message-center/command/remove/command-remove.ts +25 -0
  125. package/src/utils/message-center/command/update/command-update.ts +25 -0
  126. package/src/utils/message-center/console/message-console.ts +27 -0
  127. package/src/utils/message-center/error/message-error.ts +27 -0
  128. package/src/utils/message-center/index.ts +1 -0
  129. package/src/utils/message-center/message-center.ts +77 -0
  130. package/src/utils/namespace/namespace.ts +217 -0
  131. package/src/utils/net/http-response.ts +60 -0
  132. package/src/utils/net/net.ts +448 -0
  133. package/src/utils/recursive/find-recursive-child.ts +238 -0
  134. package/src/utils/string-util/string-util.ts +76 -0
  135. package/src/utils/style/remote-style.ts +17 -0
  136. package/src/utils/sync/await-timeout.ts +29 -0
  137. package/src/utils/sync/count-latch.ts +79 -0
  138. package/src/utils/sync/index.ts +2 -0
  139. package/src/utils/types/types.ts +24 -0
  140. package/src/utils/upload/select-file.ts +93 -0
  141. package/src/utils/upload/upload-file.ts +194 -0
  142. package/src/utils/url-helper/url-helper.ts +52 -0
  143. package/src/utils/util/util.ts +580 -0
@@ -0,0 +1,448 @@
1
+ import axios, {
2
+ AxiosError,
3
+ RawAxiosRequestHeaders,
4
+ AxiosResponse,
5
+ AxiosRequestConfig,
6
+ AxiosInstance,
7
+ CreateAxiosDefaults,
8
+ } from 'axios';
9
+ import {
10
+ FetchEventSourceInit,
11
+ fetchEventSource,
12
+ } from '@microsoft/fetch-event-source';
13
+ import { merge } from 'lodash-es';
14
+ import qs from 'qs';
15
+ import { notNilEmpty } from 'qx-util';
16
+ import { mergeDeepRight } from 'ramda';
17
+ import { HttpErrorFactory } from '../../error';
18
+ import { CoreInterceptor } from '../interceptor';
19
+ import { Interceptor } from '../interceptor/interceptor';
20
+ import { getToken } from '../util/util';
21
+ import { IApiNet, IHttpResponse } from '../../interface';
22
+
23
+ /**
24
+ * @description 全局请求工具类
25
+ * @export
26
+ * @class Net
27
+ * @implements {IApiNet}
28
+ */
29
+ export class Net implements IApiNet {
30
+ /**
31
+ * @description axios实例
32
+ * @protected
33
+ * @type {AxiosInstance}
34
+ * @memberof Net
35
+ */
36
+ protected instance: AxiosInstance;
37
+
38
+ /**
39
+ * @description 是否为 http || https 开头
40
+ * @protected
41
+ * @memberof Net
42
+ */
43
+ protected urlReg = /^http[s]?:\/\/[^\s]*/;
44
+
45
+ /**
46
+ * @description 请求等待队列,防止重复请求。当有完全相同请求参数的请求时,会等待上一个请求完成后把结果返回给当前请求,不会重复请求(key: 由请求的 config 生成的字符串,用于唯一标识请求,value: 当前正在请求的 Promise)
47
+ * @protected
48
+ * @memberof Net
49
+ */
50
+ protected waitRequest = new Map<string, Promise<AxiosResponse>>();
51
+
52
+ protected get baseUrl(): string {
53
+ return (
54
+ this.instance.defaults.baseURL || `${ibiz.env.baseUrl}/${ibiz.env.appId}`
55
+ );
56
+ }
57
+
58
+ /**
59
+ * Creates an instance of Net.
60
+ * @param {CreateAxiosDefaults} [config] 创建实例用的默认配置
61
+ * @memberof Net
62
+ */
63
+ constructor(config?: CreateAxiosDefaults) {
64
+ this.instance = axios.create(config);
65
+ this.addInterceptor('Default', new CoreInterceptor());
66
+ }
67
+
68
+ /**
69
+ * @description 注册的拦截器
70
+ * @type {Map<string, Interceptor>}
71
+ * @memberof Net
72
+ */
73
+ interceptors: Map<string, Interceptor> = new Map();
74
+
75
+ /**
76
+ * @description 添加拦截器
77
+ * @param {string} name 唯一标识
78
+ * @param {Interceptor} interceptor 拦截器
79
+ * @memberof Net
80
+ */
81
+ addInterceptor(name: string, interceptor: Interceptor): void {
82
+ interceptor.use(this.instance);
83
+ this.interceptors.set(name, interceptor);
84
+ }
85
+
86
+ /**
87
+ * @description 删除拦截器
88
+ * @param {string} name 唯一标识
89
+ * @memberof Net
90
+ */
91
+ removeInterceptor(name: string): void {
92
+ const interceptor = this.interceptors.get(name);
93
+ if (interceptor) {
94
+ interceptor.eject(this.instance);
95
+ this.interceptors.delete(name);
96
+ }
97
+ }
98
+
99
+ /**
100
+ * @description 预置config,绑定动态的配置
101
+ * @readonly
102
+ * @protected
103
+ * @type {AxiosRequestConfig}
104
+ * @memberof Net
105
+ */
106
+ protected get presetConfig(): AxiosRequestConfig {
107
+ return {
108
+ // 请求前缀路径
109
+ baseURL: this.baseUrl,
110
+ headers: {
111
+ 'Content-Type': 'application/json;charset=UTF-8',
112
+ Accept: 'application/json',
113
+ },
114
+ };
115
+ }
116
+
117
+ /**
118
+ * @description 从左到右递归合并配置参数(内置第一个合并的预置参数)
119
+ * @protected
120
+ * @param {...AxiosRequestConfig[]} configs
121
+ * @returns {*} {AxiosRequestConfig}
122
+ * @memberof Net
123
+ */
124
+ protected mergeConfig(...configs: AxiosRequestConfig[]): AxiosRequestConfig {
125
+ const config = this.presetConfig;
126
+ if (configs.length === 0) {
127
+ return config;
128
+ }
129
+ const { url } = configs[0];
130
+ if (url && this.urlReg.test(url)) {
131
+ delete config.baseURL;
132
+ }
133
+ return merge(config, ...configs);
134
+ }
135
+
136
+ /**
137
+ * @description Post 请求
138
+ * @param {string} url
139
+ * @param {IData} data
140
+ * @param {IParams} [params={}]
141
+ * @param {RawAxiosRequestHeaders} [headers={}]
142
+ * @returns {*} {Promise<IHttpResponse>}
143
+ * @memberof Net
144
+ */
145
+ async post(
146
+ url: string,
147
+ data: IData,
148
+ params: IParams = {},
149
+ headers: RawAxiosRequestHeaders = {},
150
+ ): Promise<IHttpResponse> {
151
+ url = this.handleAppPresetParam(url, params, data);
152
+ try {
153
+ const response = await this.request(url, {
154
+ method: 'post',
155
+ data,
156
+ headers,
157
+ });
158
+ return this.doResponseResult(response);
159
+ } catch (error) {
160
+ throw HttpErrorFactory.getInstance(error as AxiosError);
161
+ }
162
+ }
163
+
164
+ /**
165
+ * @description Get 请求
166
+ * @param {string} url
167
+ * @param {IParams} [params={}]
168
+ * @param {RawAxiosRequestHeaders} [headers={}]
169
+ * @param {AxiosRequestConfig} [option={}]
170
+ * @returns {*} {Promise<IHttpResponse>}
171
+ * @memberof Net
172
+ */
173
+ async get(
174
+ url: string,
175
+ params: IParams = {},
176
+ headers: RawAxiosRequestHeaders = {},
177
+ option: AxiosRequestConfig = {},
178
+ ): Promise<IHttpResponse> {
179
+ url = this.attachUrlParam(url, params);
180
+ try {
181
+ const response = await this.request(
182
+ url,
183
+ merge({ method: 'get', headers }, option),
184
+ );
185
+ return this.doResponseResult(response);
186
+ } catch (error) {
187
+ throw HttpErrorFactory.getInstance(error as AxiosError);
188
+ }
189
+ }
190
+
191
+ /**
192
+ * @description Delete 请求
193
+ * @param {string} url
194
+ * @param {IParams} [params={}]
195
+ * @param {RawAxiosRequestHeaders} [headers={}]
196
+ * @returns {*} {Promise<IHttpResponse>}
197
+ * @memberof Net
198
+ */
199
+ async delete(
200
+ url: string,
201
+ params: IParams = {},
202
+ headers: RawAxiosRequestHeaders = {},
203
+ ): Promise<IHttpResponse> {
204
+ url = this.handleAppPresetParam(url, params);
205
+ try {
206
+ const response = await this.request(url, { method: 'delete', headers });
207
+ return this.doResponseResult(response);
208
+ } catch (error) {
209
+ throw HttpErrorFactory.getInstance(error as AxiosError);
210
+ }
211
+ }
212
+
213
+ /**
214
+ * @description Put 请求
215
+ * @param {string} url
216
+ * @param {IData} data
217
+ * @param {IParams} [params={}]
218
+ * @param {RawAxiosRequestHeaders} [headers={}]
219
+ * @returns {*} {Promise<IHttpResponse>}
220
+ * @memberof Net
221
+ */
222
+ async put(
223
+ url: string,
224
+ data: IData,
225
+ params: IParams = {},
226
+ headers: RawAxiosRequestHeaders = {},
227
+ ): Promise<IHttpResponse> {
228
+ url = this.handleAppPresetParam(url, params);
229
+ try {
230
+ const response = await this.request(url, {
231
+ method: 'put',
232
+ data,
233
+ headers,
234
+ });
235
+ return this.doResponseResult(response);
236
+ } catch (error) {
237
+ throw HttpErrorFactory.getInstance(error as AxiosError);
238
+ }
239
+ }
240
+
241
+ /**
242
+ * @description 获取模型数据
243
+ * @param {string} url
244
+ * @param {RawAxiosRequestHeaders} [headers={}]
245
+ * @returns {*} {Promise<IHttpResponse>}
246
+ * @memberof Net
247
+ */
248
+ async getModel(
249
+ url: string,
250
+ headers: RawAxiosRequestHeaders = {},
251
+ ): Promise<IHttpResponse> {
252
+ try {
253
+ const response = await this.instance.get(url, {
254
+ headers,
255
+ });
256
+ return this.doResponseResult(response);
257
+ } catch (error) {
258
+ throw HttpErrorFactory.getInstance(error as AxiosError);
259
+ }
260
+ }
261
+
262
+ /**
263
+ * @description 基础请求方法,会合并预置配置
264
+ * @param {string} url
265
+ * @param {AxiosRequestConfig} [config={}]
266
+ * @returns {*} {Promise<IHttpResponse>}
267
+ * @memberof Net
268
+ */
269
+ async request(
270
+ url: string,
271
+ config: AxiosRequestConfig = {},
272
+ ): Promise<IHttpResponse> {
273
+ // axios 请求参数配置
274
+ const cfg = this.mergeConfig({ url }, config);
275
+ // 当前请求的唯一标识
276
+ const key = JSON.stringify(cfg);
277
+ try {
278
+ let requestPromise: Promise<AxiosResponse> | null = null;
279
+ if (!this.waitRequest.has(key)) {
280
+ requestPromise = this.instance.request(cfg);
281
+ this.waitRequest.set(key, requestPromise);
282
+ } else {
283
+ requestPromise = this.waitRequest.get(key)!;
284
+ }
285
+ const response = await requestPromise;
286
+ // 当第一个请求完成后就删除等待队列中的请求
287
+ if (this.waitRequest.has(key)) {
288
+ this.waitRequest.delete(key);
289
+ }
290
+ return this.doResponseResult(response);
291
+ } catch (error) {
292
+ // 请求异常删除等待队列中的请求体
293
+ if (this.waitRequest.has(key)) {
294
+ this.waitRequest.delete(key);
295
+ }
296
+ throw HttpErrorFactory.getInstance(error as AxiosError);
297
+ }
298
+ }
299
+
300
+ /**
301
+ * @description 创建标准 axios 请求
302
+ * @param {AxiosRequestConfig<IData>} config
303
+ * @returns {*} {Promise<AxiosResponse>}
304
+ * @memberof Net
305
+ */
306
+ axios(config: AxiosRequestConfig<IData>): Promise<AxiosResponse> {
307
+ return axios(config);
308
+ }
309
+
310
+ /**
311
+ * @description 触发 sse 请求
312
+ * @param {string} url
313
+ * @param {IParams} params
314
+ * @param {FetchEventSourceInit} [options={}]
315
+ * @returns {*} {Promise<void>}
316
+ * @memberof Net
317
+ */
318
+ async sse(
319
+ url: string,
320
+ params: IParams,
321
+ options: FetchEventSourceInit = {},
322
+ ): Promise<void> {
323
+ url = this.attachUrlParam(this.baseUrl + url, params);
324
+ if (!options.headers) {
325
+ options.headers = {};
326
+ }
327
+ const headers = options.headers!;
328
+ // 补充基本认证信息
329
+ {
330
+ const token = getToken();
331
+ if (token) {
332
+ headers[`${ibiz.env.tokenHeader}Authorization`] =
333
+ `${ibiz.env.tokenPrefix}Bearer ${getToken()}`;
334
+ }
335
+ let systemId = ibiz.env.dcSystem;
336
+ const { orgData } = ibiz;
337
+ if (orgData) {
338
+ if (orgData.systemid) {
339
+ systemId = orgData.systemid;
340
+ }
341
+ if (orgData.orgid) {
342
+ headers.srforgid = orgData.orgid;
343
+ }
344
+ }
345
+ headers.srfsystemid = systemId;
346
+ }
347
+ const config = mergeDeepRight(
348
+ {
349
+ openWhenHidden: true,
350
+ method: 'POST',
351
+ },
352
+ options,
353
+ );
354
+ await fetchEventSource(url, config);
355
+ }
356
+
357
+ /**
358
+ * @description 统一处理请求返回
359
+ * @private
360
+ * @param {AxiosResponse} response
361
+ * @returns {*} {IHttpResponse}
362
+ * @memberof Net
363
+ */
364
+ private doResponseResult(response: AxiosResponse): IHttpResponse {
365
+ const res = response as IHttpResponse;
366
+ if (res.status >= 200 && res.status <= 299) {
367
+ res.ok = true;
368
+ const resData = res.data as unknown;
369
+ if (resData === '' || resData === null) {
370
+ res.data = undefined as unknown as IData;
371
+ }
372
+ }
373
+ return res;
374
+ }
375
+
376
+ /**
377
+ * @description 处理平台预定义参数
378
+ * @private
379
+ * @param {string} url
380
+ * @param {IParams} params
381
+ * @param {IData} [data={}]
382
+ * @returns {*} {string}
383
+ * @memberof Net
384
+ */
385
+ private handleAppPresetParam(
386
+ url: string,
387
+ params: IParams,
388
+ data: IData = {},
389
+ ): string {
390
+ // [特殊参数识别]post请求时将srfversionid视图参数或编辑器中的视图参数以请求问号参数传递
391
+ if (data && Object.prototype.hasOwnProperty.call(data, 'srfversionid')) {
392
+ params.srfversionid = data.srfversionid;
393
+ }
394
+ // [特殊参数识别]删除界面使用视图参数srfmenuitem
395
+ if (data && Object.prototype.hasOwnProperty.call(data, 'srfmenuitem')) {
396
+ delete data.srfmenuitem;
397
+ }
398
+ // [特殊参数识别]删除界面使用视图参数srfdefdata
399
+ if (params && Object.prototype.hasOwnProperty.call(params, 'srfdefdata')) {
400
+ delete params.srfdefdata;
401
+ }
402
+ if (params) {
403
+ return this.attachUrlParam(url, params);
404
+ }
405
+ return url;
406
+ }
407
+
408
+ /**
409
+ * @description url 附加请求参数,并处理路径的字符转换 encode
410
+ * @private
411
+ * @param {string} url
412
+ * @param {IParams} params
413
+ * @returns {*} {string}
414
+ * @memberof Net
415
+ */
416
+ private attachUrlParam(url: string, params: IParams): string {
417
+ // [特殊参数识别]删除界面使用视图参数srfdefdata
418
+ if (params && Object.prototype.hasOwnProperty.call(params, 'srfdefdata')) {
419
+ delete params.srfdefdata;
420
+ }
421
+ // [特殊参数识别]删除界面使用视图参数srfmenuitem
422
+ if (params && Object.prototype.hasOwnProperty.call(params, 'srfmenuitem')) {
423
+ delete params.srfmenuitem;
424
+ }
425
+ {
426
+ // url 转码
427
+ const urlSplit = url.split('?');
428
+ urlSplit[0] = urlSplit[0]
429
+ .split('/')
430
+ .map(item => encodeURIComponent(item))
431
+ .join('/');
432
+ url = urlSplit.length > 1 ? urlSplit.join('?') : urlSplit[0];
433
+ }
434
+ const strParams: string = qs.stringify(params);
435
+ if (notNilEmpty(strParams)) {
436
+ if (url.endsWith('?')) {
437
+ url = `${url}${strParams}`;
438
+ } else if (url.indexOf('?') !== -1 && url.endsWith('&')) {
439
+ url = `${url}${strParams}`;
440
+ } else if (url.indexOf('?') !== -1 && !url.endsWith('&')) {
441
+ url = `${url}&${strParams}`;
442
+ } else {
443
+ url = `${url}?${strParams}`;
444
+ }
445
+ }
446
+ return url;
447
+ }
448
+ }
@@ -0,0 +1,238 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { mergeDeepRight } from 'ramda';
3
+
4
+ /** 默认配置参数 */
5
+ const IterateOpts = {
6
+ /** 子集合属性数组 */
7
+ childrenFields: ['children'],
8
+ /** 是否跳出当前操作 */
9
+ isBreak: false,
10
+ };
11
+
12
+ const ReturnError = new Error('中断操作');
13
+ /**
14
+ * @description 获取子属性集合
15
+ * @param {IData} parent
16
+ * @param {string[]} fields 子集合可能的属性名称
17
+ * @returns {*} {(IData[] | undefined)}
18
+ */
19
+ function getChildField(parent: IData, fields: string[]): IData[] | undefined {
20
+ for (const field of fields) {
21
+ if (parent[field]?.length) {
22
+ return parent[field];
23
+ }
24
+ }
25
+ }
26
+
27
+ /**
28
+ * @description 获取子属性对象
29
+ * @param {IData} parent
30
+ * @param {string[]} fields
31
+ * @returns {*} {(IData[] | undefined)}
32
+ */
33
+ function getChildFieldObj(
34
+ parent: IData,
35
+ fields: string[],
36
+ ): IData[] | undefined {
37
+ for (const field of fields) {
38
+ if (parent[field]) {
39
+ return parent[field];
40
+ }
41
+ }
42
+ }
43
+
44
+ function _recursiveIterate(
45
+ parent: IData,
46
+ callback: (item: any, _parent?: any) => boolean | void,
47
+ opts?: Partial<typeof IterateOpts>,
48
+ ): void {
49
+ const { childrenFields } = mergeDeepRight(IterateOpts, opts || {});
50
+ const children = getChildField(parent, childrenFields);
51
+ if (children?.length) {
52
+ for (let i = 0; i < children.length; i++) {
53
+ const child = children[i];
54
+ // 递归自身的子成员
55
+ const result = callback(child, parent);
56
+ // 回调返回true若未启用跳出当次操作则退出,启用跳出当次操作则跳出本次循环
57
+ if (result) {
58
+ if (opts?.isBreak) {
59
+ break;
60
+ }
61
+ throw ReturnError;
62
+ }
63
+ // 递归孙的成员
64
+ recursiveIterate(child, callback, opts);
65
+ }
66
+ }
67
+ }
68
+
69
+ /**
70
+ * @description 递归遍历子元素,递归遍历子元素 用法:传入数组和回调函数 无返回值
71
+ * @example
72
+ * ```
73
+ * const parent = {
74
+ * name: 'parent',
75
+ * children: [
76
+ * {
77
+ * name: 'child1',
78
+ * children: [{ name: 'grandchild1' }, { name: 'grandchild2' }],
79
+ * },
80
+ * { name: 'child2', children: [{ name: 'grandchild3' }] },
81
+ * ],
82
+ * };
83
+ *
84
+ * const result: string[] = [];
85
+ *
86
+ * recursiveIterate(parent, item => {
87
+ * result.push(item.name);
88
+ * });
89
+ *
90
+ * result // => ['child1', 'grandchild1', 'grandchild2', 'child2', 'grandchild3']
91
+ * ```
92
+ * @export
93
+ * @param {IData} parent 父元素
94
+ * @param {(item: any) => boolean} callback 每一个子元素的回调
95
+ * @param {Partial<typeof IterateOpts>} [opts]
96
+ */
97
+ export function recursiveIterate(
98
+ parent: IData,
99
+ callback: (item: any, _parent: any) => boolean | void,
100
+ opts?: Partial<typeof IterateOpts>,
101
+ ): void {
102
+ try {
103
+ _recursiveIterate(parent, callback, opts);
104
+ } catch (error) {
105
+ if (error !== ReturnError) {
106
+ throw error;
107
+ }
108
+ }
109
+ }
110
+
111
+ /**
112
+ * @description 递归执行,处理对象结构
113
+ * @export
114
+ * @param {IData} parent
115
+ * @param {((item: any, _parent?: any) => boolean | void)} callback
116
+ * @param {Partial<typeof IterateOpts>} [opts]
117
+ */
118
+ export function _recursiveExecute(
119
+ parent: IData,
120
+ callback: (item: any, _parent?: any) => boolean | void,
121
+ opts?: Partial<typeof IterateOpts>,
122
+ ): void {
123
+ const { childrenFields } = mergeDeepRight(IterateOpts, opts || {});
124
+ const children = getChildFieldObj(parent, childrenFields);
125
+ if (children) {
126
+ for (let i = 0; i < Object.values(children).length; i++) {
127
+ const child = Object.values(children)[i];
128
+ const result = callback(child, parent);
129
+ // 回调返回true若未启用跳出当次操作则退出,启用跳出当次操作则跳出本次循环
130
+ if (result) {
131
+ if (opts?.isBreak) {
132
+ break;
133
+ }
134
+ throw ReturnError;
135
+ }
136
+ // 递归孙的成员
137
+ _recursiveExecute(child, callback, opts);
138
+ }
139
+ }
140
+ }
141
+
142
+ /**
143
+ * @description 递归执行,处理对象结构
144
+ * @export
145
+ * @param {IData} parent
146
+ * @param {((item: any, _parent: any) => boolean | void)} callback
147
+ * @param {Partial<typeof IterateOpts>} [opts]
148
+ */
149
+ export function recursiveExecute(
150
+ parent: IData,
151
+ callback: (item: any, _parent: any) => boolean | void,
152
+ opts?: Partial<typeof IterateOpts>,
153
+ ): void {
154
+ try {
155
+ _recursiveExecute(parent, callback, opts);
156
+ } catch (error) {
157
+ if (error !== ReturnError) {
158
+ throw error;
159
+ }
160
+ }
161
+ }
162
+
163
+ /** 默认配置参数 */
164
+ const CompareOpts = {
165
+ ...IterateOpts,
166
+ /** 比较的属性 */
167
+ compareField: 'name',
168
+ };
169
+
170
+ type ICompareOpts = Partial<typeof CompareOpts> & {
171
+ /**
172
+ * 自定义比较回调
173
+ * @author lxm
174
+ * @date 2023-04-23 09:06:42
175
+ */
176
+ compareCallback?: (
177
+ child: IData,
178
+ key: string,
179
+ compareField: string,
180
+ ) => boolean;
181
+ };
182
+
183
+ /**
184
+ * @description 递归查找子元素,递归查找子元素 用法:传入数组和查找条件 返回值匹配的子元素或undefined
185
+ * @example
186
+ * ```
187
+ * const parent = {
188
+ * name: 'parent',
189
+ * children: [
190
+ * {
191
+ * name: 'child1',
192
+ * children: [{ name: 'grandchild1' }, { name: 'grandchild2' }],
193
+ * },
194
+ * { name: 'child2', children: [{ name: 'grandchild3' }] },
195
+ * ],
196
+ * };
197
+ *
198
+ * const result = findRecursiveChild(parent, 'child1');
199
+ *
200
+ * result // => { name: 'child1', children: [{ name: 'grandchild1' }, { name: 'grandchild2' }] }
201
+ * ```
202
+ * @export
203
+ * @param {IData} parent 父对象
204
+ * @param {string} key 子元素的比较属性的值
205
+ * @param {ICompareOpts} [opts]
206
+ * @return {*} {(IData | undefined)}
207
+ */
208
+ export function findRecursiveChild(
209
+ parent: IData,
210
+ key: string,
211
+ opts?: ICompareOpts,
212
+ ): IData | undefined {
213
+ const { compareField, compareCallback } = mergeDeepRight(
214
+ CompareOpts,
215
+ opts || {},
216
+ );
217
+
218
+ // 默认比较方法
219
+ const _compareCallback =
220
+ compareCallback ||
221
+ ((child: IData): boolean => {
222
+ return child[compareField] === key;
223
+ });
224
+
225
+ // 递归遍历,找到后中断遍历,返回找到项
226
+ let find;
227
+ recursiveIterate(
228
+ parent,
229
+ item => {
230
+ if (_compareCallback(item, key, compareField)) {
231
+ find = item;
232
+ return true;
233
+ }
234
+ },
235
+ opts,
236
+ );
237
+ return find;
238
+ }