@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.
- package/dist/index.esm.js +2 -1
- package/dist/index.system.min.js +1 -1
- package/out/environment/environment.d.ts.map +1 -1
- package/out/environment/environment.js +1 -0
- package/out/interface/api/environment/i-environment.d.ts +8 -0
- package/out/interface/api/environment/i-environment.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/command/command-register.ts +121 -0
- package/src/command/command.ts +78 -0
- package/src/command/index.ts +8 -0
- package/src/command/utils/index.ts +2 -0
- package/src/command/utils/linked-list.ts +136 -0
- package/src/command/utils/util.ts +103 -0
- package/src/constant/core/core.ts +54 -0
- package/src/constant/emoji/emoji.ts +2929 -0
- package/src/constant/http-status-message/http-status-message.ts +18 -0
- package/src/constant/index.ts +4 -0
- package/src/constant/util/util.ts +3 -0
- package/src/context/index.ts +231 -0
- package/src/environment/environment.ts +65 -0
- package/src/error/http-error/entity-error.ts +29 -0
- package/src/error/http-error/http-error-factory.ts +24 -0
- package/src/error/http-error/http-error.ts +52 -0
- package/src/error/index.ts +7 -0
- package/src/error/model-error/model-error.ts +27 -0
- package/src/error/notice-error/notice-error.ts +16 -0
- package/src/error/runtime-error/runtime-error.ts +13 -0
- package/src/error/runtime-model-error/runtime-model-error.ts +27 -0
- package/src/ibizsys.ts +82 -0
- package/src/index.ts +14 -0
- package/src/install.ts +12 -0
- package/src/interface/api/chat-message/i-api-chat-message.ts +71 -0
- package/src/interface/api/chat-message/index.ts +1 -0
- package/src/interface/api/constant/index.ts +2 -0
- package/src/interface/api/constant/login-mode/login-mode.ts +25 -0
- package/src/interface/api/constant/menu-permission-mode/menu-permission-mode.ts +20 -0
- package/src/interface/api/environment/i-devtool-config.ts +56 -0
- package/src/interface/api/environment/i-environment.ts +532 -0
- package/src/interface/api/environment/index.ts +2 -0
- package/src/interface/api/global-param/i-api-context.ts +37 -0
- package/src/interface/api/global-param/i-global-param.ts +27 -0
- package/src/interface/api/global-param/index.ts +2 -0
- package/src/interface/api/ibizsys/i-api-ibizsys.ts +54 -0
- package/src/interface/api/ibizsys/i-app-data.ts +64 -0
- package/src/interface/api/ibizsys/i-org-data.ts +31 -0
- package/src/interface/api/ibizsys/index.ts +3 -0
- package/src/interface/api/index.ts +6 -0
- package/src/interface/api/utils/i-api-i18n.ts +56 -0
- package/src/interface/api/utils/index.ts +5 -0
- package/src/interface/api/utils/message-center/base/i-message-all.ts +8 -0
- package/src/interface/api/utils/message-center/base/i-message-base.ts +29 -0
- package/src/interface/api/utils/message-center/base/index.ts +2 -0
- package/src/interface/api/utils/message-center/command/add-in-changed/i-add-in-changed.ts +25 -0
- package/src/interface/api/utils/message-center/command/add-in-changed/i-command-add-in-changed.ts +16 -0
- package/src/interface/api/utils/message-center/command/async-action/i-command-async-action.ts +17 -0
- package/src/interface/api/utils/message-center/command/change/i-command-change.ts +8 -0
- package/src/interface/api/utils/message-center/command/create/i-command-create.ts +18 -0
- package/src/interface/api/utils/message-center/command/i-command-base.ts +23 -0
- package/src/interface/api/utils/message-center/command/i-message-command.ts +94 -0
- package/src/interface/api/utils/message-center/command/index.ts +20 -0
- package/src/interface/api/utils/message-center/command/internal-message/i-command-internal-message.ts +17 -0
- package/src/interface/api/utils/message-center/command/internal-message/i-internal-message.ts +132 -0
- package/src/interface/api/utils/message-center/command/mark-open-data/i-command-mark-open-data.ts +17 -0
- package/src/interface/api/utils/message-center/command/mark-open-data/i-mark-open-data.ts +47 -0
- package/src/interface/api/utils/message-center/command/remove/i-command-remove.ts +18 -0
- package/src/interface/api/utils/message-center/command/update/i-command-update.ts +18 -0
- package/src/interface/api/utils/message-center/common/i-app-data-entity.ts +16 -0
- package/src/interface/api/utils/message-center/common/i-message-center-event.ts +15 -0
- package/src/interface/api/utils/message-center/common/i-msg-meta-data.ts +13 -0
- package/src/interface/api/utils/message-center/common/i-portal-async-action.ts +144 -0
- package/src/interface/api/utils/message-center/common/i-portal-message.ts +84 -0
- package/src/interface/api/utils/message-center/common/index.ts +5 -0
- package/src/interface/api/utils/message-center/console/i-message-console.ts +17 -0
- package/src/interface/api/utils/message-center/error/i-message-error.ts +17 -0
- package/src/interface/api/utils/message-center/i-message-center.ts +53 -0
- package/src/interface/api/utils/message-center/index.ts +6 -0
- package/src/interface/api/utils/net/i-api-http-error.ts +43 -0
- package/src/interface/api/utils/net/i-api-net.ts +93 -0
- package/src/interface/api/utils/net/i-http-response.ts +67 -0
- package/src/interface/click-outside/click-outside.ts +51 -0
- package/src/interface/command/command/i-command-option.ts +47 -0
- package/src/interface/command/command/i-command.ts +68 -0
- package/src/interface/command/disposable/i-disposable.ts +12 -0
- package/src/interface/command/i-command-controller.ts +50 -0
- package/src/interface/command/index.ts +11 -0
- package/src/interface/context/index.ts +42 -0
- package/src/interface/error/index.ts +13 -0
- package/src/interface/i-chat-message/i-chat-message.ts +16 -0
- package/src/interface/ibizsys/i-ibizsys.ts +33 -0
- package/src/interface/ibizsys/index.ts +1 -0
- package/src/interface/index.ts +11 -0
- package/src/interface/utils/i-18n.ts +22 -0
- package/src/interface/utils/index.ts +1 -0
- package/src/locale/en/index.ts +30 -0
- package/src/locale/index.ts +2 -0
- package/src/locale/zh-CN/index.ts +28 -0
- package/src/params/params.ts +131 -0
- package/src/types.ts +26 -0
- package/src/utils/bit-mask/bit-mask.ts +87 -0
- package/src/utils/click-outside/click-outside.ts +108 -0
- package/src/utils/clone/clone.ts +38 -0
- package/src/utils/color/color.ts +84 -0
- package/src/utils/cookie-util/cookie-util.ts +192 -0
- package/src/utils/data-type/data-types.ts +93 -0
- package/src/utils/download-file/download-file.ts +110 -0
- package/src/utils/event/event.ts +69 -0
- package/src/utils/history-list/history-item.ts +41 -0
- package/src/utils/history-list/history-list.ts +137 -0
- package/src/utils/index.ts +24 -0
- package/src/utils/interceptor/core-interceptor.ts +127 -0
- package/src/utils/interceptor/index.ts +2 -0
- package/src/utils/interceptor/interceptor.ts +122 -0
- package/src/utils/logger/logger.ts +34 -0
- package/src/utils/message-center/base/message-all.ts +10 -0
- package/src/utils/message-center/base/message-base.ts +73 -0
- package/src/utils/message-center/command/add-in-changed/command-add-in-changed.ts +23 -0
- package/src/utils/message-center/command/async-action/command-async-action.ts +23 -0
- package/src/utils/message-center/command/change/command-change.ts +11 -0
- package/src/utils/message-center/command/command-base/command-base.ts +35 -0
- package/src/utils/message-center/command/create/command-create.ts +25 -0
- package/src/utils/message-center/command/internal-message/command-internal-message.ts +26 -0
- package/src/utils/message-center/command/mark-open-data/command-mark-open-data.ts +23 -0
- package/src/utils/message-center/command/message-command.ts +162 -0
- package/src/utils/message-center/command/remove/command-remove.ts +25 -0
- package/src/utils/message-center/command/update/command-update.ts +25 -0
- package/src/utils/message-center/console/message-console.ts +27 -0
- package/src/utils/message-center/error/message-error.ts +27 -0
- package/src/utils/message-center/index.ts +1 -0
- package/src/utils/message-center/message-center.ts +77 -0
- package/src/utils/namespace/namespace.ts +217 -0
- package/src/utils/net/http-response.ts +60 -0
- package/src/utils/net/net.ts +448 -0
- package/src/utils/recursive/find-recursive-child.ts +238 -0
- package/src/utils/string-util/string-util.ts +76 -0
- package/src/utils/style/remote-style.ts +17 -0
- package/src/utils/sync/await-timeout.ts +29 -0
- package/src/utils/sync/count-latch.ts +79 -0
- package/src/utils/sync/index.ts +2 -0
- package/src/utils/types/types.ts +24 -0
- package/src/utils/upload/select-file.ts +93 -0
- package/src/utils/upload/upload-file.ts +194 -0
- package/src/utils/url-helper/url-helper.ts +52 -0
- package/src/utils/util/util.ts +580 -0
|
@@ -0,0 +1,580 @@
|
|
|
1
|
+
/* eslint-disable no-useless-escape */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
|
+
import { debounce } from 'lodash-es';
|
|
4
|
+
import { isNotNil, isNil } from 'ramda';
|
|
5
|
+
import { CoreConst, EMOJIMAP } from '../../constant';
|
|
6
|
+
import { getAppCookie } from '../cookie-util/cookie-util';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @description 获取认证令牌
|
|
10
|
+
* @export
|
|
11
|
+
* @returns {*} {(string | null)}
|
|
12
|
+
*/
|
|
13
|
+
export function getToken(): string | null {
|
|
14
|
+
return getAppCookie(CoreConst.TOKEN);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @description 判断两个数组是否有相同的元素, 用法: 传入两个数组 返回值为boolean类型
|
|
19
|
+
* @example
|
|
20
|
+
* ```
|
|
21
|
+
* isOverlap([1, 2, 3], [3, 4, 5]) // => true
|
|
22
|
+
* isOverlap([1, 2, 3], [4, 5, 6]) // => false
|
|
23
|
+
* ```
|
|
24
|
+
* @export
|
|
25
|
+
* @param {any[]} arr1
|
|
26
|
+
* @param {any[]} arr2
|
|
27
|
+
* @returns {*} {boolean}
|
|
28
|
+
*/
|
|
29
|
+
export function isOverlap(arr1: any[], arr2: any[]): boolean {
|
|
30
|
+
const newArr = Array.from(new Set([...arr1, ...arr2]));
|
|
31
|
+
return newArr.length !== arr1.length + arr2.length;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @description 判断两个数组是否元素相同, 用法:传入需要判断的数组 返回值是boolean类型
|
|
36
|
+
* @example
|
|
37
|
+
* isOverlap([1, 2, 3], [1, 2, 3]) // => true
|
|
38
|
+
* isOverlap([{ test1: 1, test2: 2, test3: 3 }, { test1: 2, test2: 2, test3: 3 }], [{ test1: 1, test2: 2, test3: 3 }, { test1: 2, test2: 2, test3: 3 }], 'test1') // => true
|
|
39
|
+
* @export
|
|
40
|
+
* @param {any[]} arr1
|
|
41
|
+
* @param {any[]} arr2
|
|
42
|
+
* @param {string} [field] 比较元素里的某个固定属性
|
|
43
|
+
* @return {*} {boolean}
|
|
44
|
+
*/
|
|
45
|
+
export function isElementSame(
|
|
46
|
+
arr1: any[],
|
|
47
|
+
arr2: any[],
|
|
48
|
+
field?: string,
|
|
49
|
+
): boolean {
|
|
50
|
+
if (arr1.length !== arr2.length) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
const allElements = field
|
|
54
|
+
? [...arr1.map(item => item[field]), ...arr2.map(item => item[field])]
|
|
55
|
+
: [...arr1, ...arr2];
|
|
56
|
+
|
|
57
|
+
const newArr = Array.from(new Set(allElements));
|
|
58
|
+
return newArr.length === arr1.length;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @description 防抖并合并每次的参数,最后一次才会执行 用法:传入要防抖的函数和合并参数函数 有需要又可以传入时间 返回防抖函数执行值
|
|
63
|
+
* @example
|
|
64
|
+
* ```
|
|
65
|
+
* // 定义测试函数
|
|
66
|
+
* function testFunc(a, b) {
|
|
67
|
+
* console.log(`testFunc called with (${a}, ${b})`);
|
|
68
|
+
* }
|
|
69
|
+
*
|
|
70
|
+
* function testMerge(oldParams, newParams) {
|
|
71
|
+
* // 将相邻的重复函数调用合并为一个函数调用,只取第一个参数 a,第二个参数 b 取最后一次调用时的值
|
|
72
|
+
* const [a] = oldParams;
|
|
73
|
+
* const [, b] = newParams;
|
|
74
|
+
* return [a, b];
|
|
75
|
+
* }
|
|
76
|
+
*
|
|
77
|
+
* // 创建一个节流后的函数
|
|
78
|
+
* const debouncedTestFunc = debounceAndMerge(testFunc, testMerge, 1000);
|
|
79
|
+
*
|
|
80
|
+
* // 连续调用多次,但只会在最后一次调用时输出
|
|
81
|
+
* debouncedTestFunc(1, 2);
|
|
82
|
+
* debouncedTestFunc(2, 3);
|
|
83
|
+
* debouncedTestFunc(3, 4);
|
|
84
|
+
* debouncedTestFunc(4, 5); // testFunc called with (1, 5)
|
|
85
|
+
* ```
|
|
86
|
+
* @export
|
|
87
|
+
* @template T
|
|
88
|
+
* @param {T} func 要防抖的函数
|
|
89
|
+
* @param {(
|
|
90
|
+
* oldParams: Parameters<T>,
|
|
91
|
+
* newParams: Parameters<T>,
|
|
92
|
+
* ) => Parameters<T>} mergeFunc 合并的回调函数
|
|
93
|
+
* @param {number} [wait] 防抖的延迟毫秒数
|
|
94
|
+
* @returns {*}
|
|
95
|
+
*/
|
|
96
|
+
export function debounceAndMerge<T extends (...args: any[]) => any>(
|
|
97
|
+
func: T,
|
|
98
|
+
mergeFunc: (
|
|
99
|
+
oldParams: Parameters<T>,
|
|
100
|
+
newParams: Parameters<T>,
|
|
101
|
+
) => Parameters<T>,
|
|
102
|
+
wait?: number,
|
|
103
|
+
): (...args: Parameters<T>) => any {
|
|
104
|
+
// 缓存上一次的函数参数
|
|
105
|
+
let oldParams: Parameters<T> | undefined;
|
|
106
|
+
const debounceFunc = debounce((...params: Parameters<T>) => {
|
|
107
|
+
// 防抖函数执行的时候清空缓存参数
|
|
108
|
+
oldParams = undefined;
|
|
109
|
+
return func(...params);
|
|
110
|
+
}, wait);
|
|
111
|
+
return (...args: Parameters<T>) => {
|
|
112
|
+
// 合并参数,并把参数缓存到oldParams里,用新参数调用防抖函数
|
|
113
|
+
let newParams = args;
|
|
114
|
+
if (oldParams) {
|
|
115
|
+
newParams = mergeFunc(oldParams, newParams);
|
|
116
|
+
}
|
|
117
|
+
oldParams = newParams;
|
|
118
|
+
return debounceFunc(...newParams);
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @description 防抖并合并每次的参数,最后一次才会执行,绑定方法为异步方法,给每次调用返回最终执行那次的结果 用法:传入要防抖的函数和合并参数函数 返回Promise
|
|
124
|
+
* @example
|
|
125
|
+
* ```
|
|
126
|
+
* // 定义一个异步函数
|
|
127
|
+
* async function logData(params) {
|
|
128
|
+
* return new Promise(resolve => {
|
|
129
|
+
* setTimeout(() => {
|
|
130
|
+
* resolve(params);
|
|
131
|
+
* }, 1000);
|
|
132
|
+
* });
|
|
133
|
+
* }
|
|
134
|
+
*
|
|
135
|
+
* // 定义合并参数的函数,每次只保留最后一次的参数
|
|
136
|
+
* function mergeParams(oldParams, newParams) {
|
|
137
|
+
* return newParams;
|
|
138
|
+
* }
|
|
139
|
+
*
|
|
140
|
+
* // 创建防抖函数
|
|
141
|
+
* const debouncedLogData = debounceAndAsyncMerge(logData, mergeParams, 500);
|
|
142
|
+
*
|
|
143
|
+
* // 模拟连续3次调用
|
|
144
|
+
* debouncedLogData('a').then(result => {
|
|
145
|
+
* console.log('Result of first call:', result); // => Result of first call: c
|
|
146
|
+
* });
|
|
147
|
+
* debouncedLogData('b').then(result => {
|
|
148
|
+
* console.log('Result of second call:', result); // => Result of first call: c
|
|
149
|
+
* });
|
|
150
|
+
* debouncedLogData('c').then(result => {
|
|
151
|
+
* console.log('Result of third call:', result); // => Result of first call: c
|
|
152
|
+
* });
|
|
153
|
+
*
|
|
154
|
+
* // 等待 2000 毫秒后再次调用,会再次输出
|
|
155
|
+
* setTimeout(() => {
|
|
156
|
+
* debouncedLogData('d').then(result => {
|
|
157
|
+
* console.log('Result of fourth call:', result); // => Result of fourth call: d
|
|
158
|
+
* });
|
|
159
|
+
* }, 2000);
|
|
160
|
+
* ```
|
|
161
|
+
* @export
|
|
162
|
+
* @template T
|
|
163
|
+
* @param {T} func 要防抖的函数
|
|
164
|
+
* @param {(
|
|
165
|
+
* oldParams: Parameters<T>,
|
|
166
|
+
* newParams: Parameters<T>,
|
|
167
|
+
* ) => Parameters<T>} mergeFunc 合并的回调函数
|
|
168
|
+
* @param {number} [wait] 防抖的延迟毫秒数
|
|
169
|
+
* @returns {*}
|
|
170
|
+
*/
|
|
171
|
+
export function debounceAndAsyncMerge<
|
|
172
|
+
T extends (...args: any[]) => Promise<any>,
|
|
173
|
+
>(
|
|
174
|
+
func: T,
|
|
175
|
+
mergeFunc: (
|
|
176
|
+
oldParams: Parameters<T>,
|
|
177
|
+
newParams: Parameters<T>,
|
|
178
|
+
) => Parameters<T>,
|
|
179
|
+
wait?: number,
|
|
180
|
+
): T {
|
|
181
|
+
// 缓存上一次的函数参数
|
|
182
|
+
let oldParams: Parameters<T> | undefined;
|
|
183
|
+
let promises: Array<{ resolve: any; reject: any }> = [];
|
|
184
|
+
const debounceFunc = debounce(async (...params: Parameters<T>) => {
|
|
185
|
+
// 防抖函数执行的时候清空缓存参数
|
|
186
|
+
oldParams = undefined;
|
|
187
|
+
try {
|
|
188
|
+
const result = await func(...params);
|
|
189
|
+
promises.forEach(promise => {
|
|
190
|
+
promise.resolve(result);
|
|
191
|
+
});
|
|
192
|
+
promises = [];
|
|
193
|
+
return result;
|
|
194
|
+
} catch (error) {
|
|
195
|
+
promises.forEach(promise => {
|
|
196
|
+
promise.reject(error);
|
|
197
|
+
});
|
|
198
|
+
promises = [];
|
|
199
|
+
}
|
|
200
|
+
}, wait);
|
|
201
|
+
const fun = async (...args: Parameters<T>): Promise<unknown> => {
|
|
202
|
+
// 合并参数,并把参数缓存到oldParams里,用新参数调用防抖函数
|
|
203
|
+
let newParams = args;
|
|
204
|
+
if (oldParams) {
|
|
205
|
+
newParams = mergeFunc(oldParams, newParams);
|
|
206
|
+
}
|
|
207
|
+
oldParams = newParams;
|
|
208
|
+
// 执行防抖函数
|
|
209
|
+
debounceFunc(...newParams);
|
|
210
|
+
return new Promise((resolve, reject) => {
|
|
211
|
+
// 阻塞当前调用,当防抖函数被执行后返回
|
|
212
|
+
promises.push({ resolve, reject });
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
return fun as T;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* @description 把右侧的对象里非空的属性合并到左侧对象里, 用法:传入需要合并的数组 无返回值
|
|
220
|
+
* @example
|
|
221
|
+
* ```
|
|
222
|
+
* obj1 = { a: 1, b: 2 }; obj2 = { c: null, d: false, e: undefined, f: 0, g: {} }; mergeInLeft(obj1, obj2); // => obj1 修改为 { a: 1, b: 2, d: false, f: 0, g: {} }
|
|
223
|
+
* obj1 = { a: 1, b: 2 }; obj2 = { a: 2, b: 3, c: null, d: false, e: undefined, f: 0, g: {} }; // => obj1 修改为 { a: 2, b: 3, d: false, f: 0, g: {} }
|
|
224
|
+
* ```
|
|
225
|
+
* @param {IData} l
|
|
226
|
+
* @param {IData} r
|
|
227
|
+
*/
|
|
228
|
+
export function mergeInLeft(l: IData, r: IData): void {
|
|
229
|
+
Object.keys(r).forEach(key => {
|
|
230
|
+
if (isNotNil(r[key])) {
|
|
231
|
+
l[key] = r[key];
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* @description 把右侧的对象里非空的属性合并到左侧对象属性为空里, 用法:传入需要合并的数组 无返回值
|
|
238
|
+
* @example
|
|
239
|
+
* ```
|
|
240
|
+
* obj1 = { a: 1, b: 2 }; obj2 = { c: null, d: false, e: undefined, f: 0, g: {} }; mergeInLeft(obj1, obj2); // => obj1 修改为 { a: 1, b: 2, d: false, f: 0, g: {} }
|
|
241
|
+
* obj1 = { a: 1, b: 2 }; obj2 = { a: 2, b: 3, c: null, d: false, e: undefined, f: 0, g: {} }; // => obj1 修改为 { a: 1, b: 2, d: false, f: 0, g: {} }
|
|
242
|
+
* ```
|
|
243
|
+
* @export
|
|
244
|
+
* @param {IData} l
|
|
245
|
+
* @param {IData} r
|
|
246
|
+
*/
|
|
247
|
+
export function mergeDefaultInLeft(l: IData, r: IData): void {
|
|
248
|
+
Object.keys(r).forEach(key => {
|
|
249
|
+
if (isNotNil(r[key]) && isNil(l[key])) {
|
|
250
|
+
l[key] = r[key];
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* @description 比较两个数组集合,找出相同和不同的元素 用法:传入需要比较的两个数组 返回值是{more: IData[], less: IData[], same: IData[]}
|
|
257
|
+
* @example
|
|
258
|
+
* ```
|
|
259
|
+
* 数组中没有引用对象
|
|
260
|
+
* compareArr([1, 2, false, true, undefined, null], [1, false, undefined]); // => {more: [2, true, null], less: [], same: [1, false, undefined]}
|
|
261
|
+
* 数组中有引用对象
|
|
262
|
+
* compareArr([{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }], [{ id: 2, name: 'Jane' }, { id: 3, name: 'Bob' }], 'id') // => {more: [{ id: 1, name: 'John' }], less: [{ id: 3, name: 'Bob' }], same: [{ id: 2, name: 'Jane' }, { id: 2, name: 'Jane' }]}
|
|
263
|
+
* ```
|
|
264
|
+
* @export
|
|
265
|
+
* @param {IData[]} arr1 数组一
|
|
266
|
+
* @param {IData[]} arr2 数组二
|
|
267
|
+
* @param {string} [keyField] 主键属性,有主键比较主键
|
|
268
|
+
* @return {*} {{
|
|
269
|
+
* more: IData[]; arr1多的元素
|
|
270
|
+
* less: IData[]; arr1少的元素
|
|
271
|
+
* same: IData[]; 相同的元素
|
|
272
|
+
* }}
|
|
273
|
+
*/
|
|
274
|
+
export function compareArr(
|
|
275
|
+
arr1: IData[],
|
|
276
|
+
arr2: IData[],
|
|
277
|
+
keyField?: string,
|
|
278
|
+
): {
|
|
279
|
+
more: IData[];
|
|
280
|
+
less: IData[];
|
|
281
|
+
same: IData[];
|
|
282
|
+
} {
|
|
283
|
+
const all = new Set([...arr1, ...arr2]);
|
|
284
|
+
const more: IData[] = [];
|
|
285
|
+
const less: IData[] = [];
|
|
286
|
+
const same: IData[] = [];
|
|
287
|
+
|
|
288
|
+
if (keyField) {
|
|
289
|
+
const arr1Keys = arr1.map(item => item[keyField]);
|
|
290
|
+
const arr2Keys = arr2.map(item => item[keyField]);
|
|
291
|
+
all.forEach(item => {
|
|
292
|
+
if (!arr1Keys.includes(item[keyField])) {
|
|
293
|
+
less.push(item);
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
if (!arr2Keys.includes(item[keyField])) {
|
|
297
|
+
more.push(item);
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
same.push(item);
|
|
301
|
+
});
|
|
302
|
+
} else {
|
|
303
|
+
all.forEach(item => {
|
|
304
|
+
if (!arr1.includes(item)) {
|
|
305
|
+
less.push(item);
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
if (!arr2.includes(item)) {
|
|
309
|
+
more.push(item);
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
same.push(item);
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return {
|
|
317
|
+
more,
|
|
318
|
+
less,
|
|
319
|
+
same,
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* @description 转换为数字或undefined,如果是undefined或null 返回undefined,其他情况转成数字,能转成数字的返回数字,NaN的返回undefined 用法:传入任意值 返回值为number或undefined类型
|
|
325
|
+
* @example
|
|
326
|
+
* ```
|
|
327
|
+
* toNumberOrNil(5); // => 5
|
|
328
|
+
* toNumberOrNil(undefined); // => undefined
|
|
329
|
+
* ```
|
|
330
|
+
* @param {unknown} value 值
|
|
331
|
+
* @return {*} {(number | undefined)}
|
|
332
|
+
*/
|
|
333
|
+
export function toNumberOrNil(value: unknown): number | undefined {
|
|
334
|
+
if (isNil(value)) {
|
|
335
|
+
return undefined;
|
|
336
|
+
}
|
|
337
|
+
const num = Number(value);
|
|
338
|
+
if (Number.isNaN(num)) {
|
|
339
|
+
return undefined;
|
|
340
|
+
}
|
|
341
|
+
return num;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const SvgPattern = /<svg\b[^>]*>[\s\S]*?<\/svg>/;
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* @description 判断字符串是否是svg的格式 用法:传入svg字符串 返回值为Boolean类型
|
|
348
|
+
* @example
|
|
349
|
+
* ```
|
|
350
|
+
* isSvg('<svg xmlns="http://www.w3.org/2000/svg"><rect x="10" y="10" width="100" height="100" fill="red" /></svg>'); // => true
|
|
351
|
+
* isSvg('<svg1 xmlns="http://www.w3.org/2000/svg"><rect x="10" y="10" width="100" height="100" fill="red" /></svg1>'); // => false
|
|
352
|
+
* ```
|
|
353
|
+
* @export
|
|
354
|
+
* @param {string} str
|
|
355
|
+
* @return {*} {boolean}
|
|
356
|
+
*/
|
|
357
|
+
export function isSvg(str: string): boolean {
|
|
358
|
+
return SvgPattern.test(str);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* @description 处理浮点数相加 用法:传入需要相加的数值 返回值为number类型
|
|
363
|
+
* @example
|
|
364
|
+
* ```
|
|
365
|
+
* plus(10, 10); // => 20
|
|
366
|
+
* plus(99.99, -99.999); // => -0.009
|
|
367
|
+
* ```
|
|
368
|
+
* @param {number} a
|
|
369
|
+
* @param {number} b
|
|
370
|
+
* @return {*}
|
|
371
|
+
*/
|
|
372
|
+
export function plus(a: number, b: number): number {
|
|
373
|
+
let c;
|
|
374
|
+
let d;
|
|
375
|
+
try {
|
|
376
|
+
c = a.toString().split('.')[1].length;
|
|
377
|
+
} catch (f) {
|
|
378
|
+
c = 0;
|
|
379
|
+
}
|
|
380
|
+
try {
|
|
381
|
+
d = b.toString().split('.')[1].length;
|
|
382
|
+
} catch (f) {
|
|
383
|
+
d = 0;
|
|
384
|
+
}
|
|
385
|
+
const e = 10 ** Math.max(c, d);
|
|
386
|
+
return (a * e + b * e) / e;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* @description 根据给定的属性名称集合,查看目标对象是否具有该属性,如果没有设置undefined的定义 ,用法:传入对象和字符串 无返回值
|
|
391
|
+
* @example
|
|
392
|
+
* ```
|
|
393
|
+
* obj = { a: '' }; updateKeyDefine(obj, ['b']); // => obj 修改为 {a: '', b: undefined}
|
|
394
|
+
* obj = { a: '' }; updateKeyDefine(obj, ['a', 'b']) // => obj 修改为 {a: '', b: undefined}
|
|
395
|
+
* ```
|
|
396
|
+
* @export
|
|
397
|
+
* @param {IParams} target 目标对象
|
|
398
|
+
* @param {s(string | symbol)[]} keys 需要支持的属性名称集合
|
|
399
|
+
*/
|
|
400
|
+
export function updateKeyDefine(
|
|
401
|
+
target: IParams,
|
|
402
|
+
keys: (string | symbol)[],
|
|
403
|
+
): void {
|
|
404
|
+
keys.forEach(key => {
|
|
405
|
+
if (!Object.prototype.hasOwnProperty.call(target, key)) {
|
|
406
|
+
Object.defineProperty(target, key, {
|
|
407
|
+
enumerable: true,
|
|
408
|
+
configurable: true,
|
|
409
|
+
writable: true,
|
|
410
|
+
value: undefined,
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* @description 判断字符串是否为Base64图片格式, 用法传入字符串 返回值为boolean类型
|
|
418
|
+
* @example
|
|
419
|
+
* ```
|
|
420
|
+
* isBase64Image('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAmklEQVQ4T2NkoBAwUqifYt4q8ogcCQ3NjY2BgYGBgZmBgY9oRk5Ojy8vLz8+PjQ2NjYGBgYGBhZmBggcCQ3NjY2BgYGhnb4FlDyECYAw6fQGp7QUhYGAQ0AC8Dtdu4AxsAAAAAElFTkSuQmCC'); // => true
|
|
421
|
+
* isBase64Image('data:image/png;,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAmklEQVQ4T2NkoBAwUqifYt4q8ogcCQ3NjY2BgYGBgZmBgY9oRk5Ojy8vLz8+PjQ2NjYGBgYGBhZmBggcCQ3NjY2BgYGhnb4FlDyECYAw6fQGp7QUhYGAQ0AC8Dtdu4AxsAAAAAElFTkSuQmCC'); // => false
|
|
422
|
+
* ```
|
|
423
|
+
* @param {string} str
|
|
424
|
+
* @return {*}
|
|
425
|
+
*/
|
|
426
|
+
export function isBase64Image(str: string): boolean {
|
|
427
|
+
// 使用正则表达式检查字符串是否以"data:image/"开头,后面紧跟着base64编码
|
|
428
|
+
return /^data:image\/[a-zA-Z+]+;base64,([/+=\w\s]+|[^,]+)$/.test(str);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* @description 判断字符串是否为Base64格式, 用法传入字符串 返回值为boolean类型
|
|
433
|
+
* ```
|
|
434
|
+
* isBase64('JUYwJTlGJTk4JTg0') => true
|
|
435
|
+
* isBase64('Hello World!') => false
|
|
436
|
+
* ```
|
|
437
|
+
* @export
|
|
438
|
+
* @param {string} str
|
|
439
|
+
* @return {*} {boolean}
|
|
440
|
+
*/
|
|
441
|
+
export function isBase64(str: string): boolean {
|
|
442
|
+
// Base64 编码规则:包含字母、数字、+、/、=,并且长度通常是 4 的倍数(最后可能有 1 或 2 个等号)
|
|
443
|
+
return /^[A-Za-z0-9+/=]+$/.test(str) && str.length % 4 === 0;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* @description 判断字符串是否为表情符号格式, 用法传入字符串 返回值为boolean类型
|
|
448
|
+
* ```
|
|
449
|
+
* isEmoji('JUYwJTlGJTk4JTg0') => true
|
|
450
|
+
* isEmoji('Hello World!') => false
|
|
451
|
+
* ```
|
|
452
|
+
* @export
|
|
453
|
+
* @param {string} str
|
|
454
|
+
* @return {*} {boolean}
|
|
455
|
+
*/
|
|
456
|
+
export function isEmoji(str: string): boolean {
|
|
457
|
+
return EMOJIMAP.has(str);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* @description 字符串转Base64格式字符串,主要用于将UTF-8字符串转为Base64格式字符串
|
|
462
|
+
* ```
|
|
463
|
+
* strToBase64('😄') => 'JUYwJTlGJTk4JTg0'
|
|
464
|
+
* ```
|
|
465
|
+
* @export
|
|
466
|
+
* @param {string} str
|
|
467
|
+
* @return {*} {string}
|
|
468
|
+
*/
|
|
469
|
+
export function strToBase64(str: string): string {
|
|
470
|
+
return btoa(encodeURIComponent(str));
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* @description Base64格式字符串转普通字符串,主要用于将UTF-8字符串转为的Base64格式字符串转回UTF-8字符串
|
|
475
|
+
* ```
|
|
476
|
+
* base64ToStr('JUYwJTlGJTk4JTg0') => '😄'
|
|
477
|
+
* ```
|
|
478
|
+
* @export
|
|
479
|
+
* @param {string} base64
|
|
480
|
+
* @return {*} {string}
|
|
481
|
+
*/
|
|
482
|
+
export function base64ToStr(base64: string): string {
|
|
483
|
+
return decodeURIComponent(atob(base64));
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* @description base64转blob
|
|
488
|
+
* @export
|
|
489
|
+
* @param {string} base64
|
|
490
|
+
* @return {*} {Blob}
|
|
491
|
+
*/
|
|
492
|
+
export function base64ToBlob(base64: string): Blob {
|
|
493
|
+
const binStr = atob(base64.split(',')[1]);
|
|
494
|
+
const len = binStr.length;
|
|
495
|
+
const arr = new Uint8Array(len);
|
|
496
|
+
for (let i = 0; i < len; i++) {
|
|
497
|
+
arr[i] = binStr.charCodeAt(i);
|
|
498
|
+
}
|
|
499
|
+
return new Blob([arr]);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* @description 用于计算各种视图打开方式的样式, 用法:传入数值和视图类型 返回值为number或string类型
|
|
504
|
+
* @example
|
|
505
|
+
* ```
|
|
506
|
+
* calcOpenModeStyle(0, 'drawer'); // => '0%'
|
|
507
|
+
* calcOpenModeStyle(150, 'drawer'); // => 150
|
|
508
|
+
* ```
|
|
509
|
+
* @param {number} value
|
|
510
|
+
* @return {*}
|
|
511
|
+
*/
|
|
512
|
+
export function calcOpenModeStyle(
|
|
513
|
+
value: number,
|
|
514
|
+
type: 'drawer' | 'modal' | 'popover',
|
|
515
|
+
): string | number {
|
|
516
|
+
if (value >= 0 && value <= 100) {
|
|
517
|
+
return `${value}%`;
|
|
518
|
+
}
|
|
519
|
+
if (value > 100) {
|
|
520
|
+
return type === 'drawer' ? value : `${value}px`;
|
|
521
|
+
}
|
|
522
|
+
// 处理其他情况,例如负值等
|
|
523
|
+
ibiz.log.error(ibiz.i18n.t('core.utils.invalidInputValue'));
|
|
524
|
+
return '';
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* @description 根据环境变量判断是否展示title, 返回值为string或undefined类型
|
|
529
|
+
* ```
|
|
530
|
+
* enableTitle: true
|
|
531
|
+
* showTitle('title') => str
|
|
532
|
+
* enableTitle: false
|
|
533
|
+
* showTitle('title') => undefined
|
|
534
|
+
* ```
|
|
535
|
+
* @export
|
|
536
|
+
* @param {string | undefined} str
|
|
537
|
+
* @return {*} {string | undefined}
|
|
538
|
+
*/
|
|
539
|
+
export function showTitle(str: string | undefined): string | undefined {
|
|
540
|
+
return ibiz.env.enableTitle ? str : undefined;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* @description 将非标准JSON字符串转为JSON对象(自动修复常见的格式问题)。1. 将单引号替换为双引号,2. 给对象的属性名加上双引号,3. 去除最后一个元素后的多余逗号,4. 去除多余的空格和换行符
|
|
545
|
+
* @export
|
|
546
|
+
* @param {string} str
|
|
547
|
+
* @return {*} {*}
|
|
548
|
+
*/
|
|
549
|
+
export function fixJsonString(str: string): any {
|
|
550
|
+
// 1. 将单引号替换为双引号
|
|
551
|
+
let fixedString = str.replace(/'/g, '"');
|
|
552
|
+
|
|
553
|
+
// 2. 给对象的属性名加上双引号
|
|
554
|
+
fixedString = fixedString.replace(/([{,])\s*([a-zA-Z0-9_]+)\s*:/g, '$1"$2":');
|
|
555
|
+
|
|
556
|
+
// 3. 去除最后一个元素后的多余逗号
|
|
557
|
+
fixedString = fixedString.replace(/,(\s*[\}\]])/g, '$1');
|
|
558
|
+
|
|
559
|
+
// 4. 去除多余的空格和换行符
|
|
560
|
+
fixedString = fixedString.trim();
|
|
561
|
+
|
|
562
|
+
// 5. 尝试解析为有效的 JSON 字符串
|
|
563
|
+
try {
|
|
564
|
+
return JSON.parse(fixedString);
|
|
565
|
+
} catch (e) {
|
|
566
|
+
ibiz.log.error(str);
|
|
567
|
+
return null;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* @description 获取随机数,默认获取 0 - 1000 的随机数
|
|
573
|
+
* @export
|
|
574
|
+
* @param {number} [min=0] 随机数最小值
|
|
575
|
+
* @param {number} [max=1000] 随机数最大值
|
|
576
|
+
* @return {*} {number}
|
|
577
|
+
*/
|
|
578
|
+
export function getRandomInt(min: number = 0, max: number = 1000): number {
|
|
579
|
+
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
580
|
+
}
|