@ibiz-template/core 0.0.1-beta.1 → 0.0.1-beta.130
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/system/index.system.js +1 -1
- package/out/constant/core/core.d.ts +9 -0
- package/out/constant/core/core.d.ts.map +1 -1
- package/out/constant/core/core.js +9 -0
- package/out/context/index.d.ts +63 -4
- package/out/context/index.d.ts.map +1 -1
- package/out/context/index.js +73 -3
- package/out/environment/environment.d.ts.map +1 -1
- package/out/environment/environment.js +5 -0
- package/out/error/http-error/http-error.d.ts.map +1 -1
- package/out/error/http-error/http-error.js +0 -4
- package/out/interface/click-outside/click-outside.d.ts +1 -1
- package/out/interface/click-outside/click-outside.d.ts.map +1 -1
- package/out/interface/i-environment/i-environment.d.ts +36 -0
- package/out/interface/i-environment/i-environment.d.ts.map +1 -1
- package/out/types.d.ts +31 -0
- package/out/types.d.ts.map +1 -1
- package/out/utils/download-file/download-file.d.ts +10 -0
- package/out/utils/download-file/download-file.d.ts.map +1 -1
- package/out/utils/download-file/download-file.js +20 -0
- package/out/utils/index.d.ts +4 -0
- package/out/utils/index.d.ts.map +1 -1
- package/out/utils/index.js +4 -0
- package/out/utils/net/net.d.ts +18 -1
- package/out/utils/net/net.d.ts.map +1 -1
- package/out/utils/net/net.js +29 -3
- package/out/utils/plural/plural.d.ts.map +1 -1
- package/out/utils/plural/plural.js +2 -0
- package/out/utils/string-util/string-util.d.ts +46 -0
- package/out/utils/string-util/string-util.d.ts.map +1 -0
- package/out/utils/string-util/string-util.js +71 -0
- package/out/utils/sync/await-timeout.d.ts +14 -0
- package/out/utils/sync/await-timeout.d.ts.map +1 -0
- package/out/utils/sync/await-timeout.js +23 -0
- package/out/utils/sync/count-latch.d.ts +60 -0
- package/out/utils/sync/count-latch.d.ts.map +1 -0
- package/out/utils/sync/count-latch.js +90 -0
- package/out/utils/sync/index.d.ts +3 -0
- package/out/utils/sync/index.d.ts.map +1 -0
- package/out/utils/sync/index.js +2 -0
- package/out/utils/upload/select-file.d.ts +53 -0
- package/out/utils/upload/select-file.d.ts.map +1 -0
- package/out/utils/upload/select-file.js +47 -0
- package/out/utils/upload/upload-file.d.ts +46 -0
- package/out/utils/upload/upload-file.d.ts.map +1 -0
- package/out/utils/upload/upload-file.js +150 -0
- package/package.json +7 -6
- package/src/constant/core/core.ts +10 -0
- package/src/context/index.ts +115 -5
- package/src/environment/environment.ts +5 -0
- package/src/error/http-error/http-error.ts +0 -4
- package/src/interface/i-environment/i-environment.ts +41 -0
- package/src/types.ts +35 -0
- package/src/utils/download-file/download-file.ts +21 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/net/net.ts +31 -3
- package/src/utils/plural/plural.ts +3 -0
- package/src/utils/string-util/string-util.ts +75 -0
- package/src/utils/sync/await-timeout.ts +27 -0
- package/src/utils/sync/count-latch.ts +96 -0
- package/src/utils/sync/index.ts +2 -0
- package/src/utils/upload/select-file.ts +86 -0
- package/src/utils/upload/upload-file.ts +206 -0
- package/LICENSE +0 -21
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
2
|
+
/* eslint-disable no-param-reassign */
|
|
3
|
+
import { cloneDeep, isFunction, merge, round, uniqueId } from 'lodash-es';
|
|
4
|
+
import { selectFile } from './select-file';
|
|
5
|
+
/**
|
|
6
|
+
* 使用上传文件逻辑
|
|
7
|
+
*
|
|
8
|
+
* @author lxm
|
|
9
|
+
* @date 2022-11-20 21:11:52
|
|
10
|
+
* @export
|
|
11
|
+
* @param {IUploadFileOpts} _opts
|
|
12
|
+
* @returns {*}
|
|
13
|
+
*/
|
|
14
|
+
export function uploadFile(_opts) {
|
|
15
|
+
const opts = merge({
|
|
16
|
+
multiple: true,
|
|
17
|
+
accept: '',
|
|
18
|
+
separate: true,
|
|
19
|
+
beforeUpload: (_fileData, _files) => true,
|
|
20
|
+
finish: (_resultFiles) => { },
|
|
21
|
+
success: (_resultFiles, _res) => { },
|
|
22
|
+
error: (_resultFiles, _error) => { },
|
|
23
|
+
progress: (_files) => { },
|
|
24
|
+
}, _opts);
|
|
25
|
+
/**
|
|
26
|
+
* 进度条回调
|
|
27
|
+
*
|
|
28
|
+
* @author lxm
|
|
29
|
+
* @date 2022-11-20 21:11:47
|
|
30
|
+
* @param {IParams} event
|
|
31
|
+
* @param {IUploadFile[]} files
|
|
32
|
+
*/
|
|
33
|
+
const onUploadProgress = (event, files) => {
|
|
34
|
+
files.forEach(file => {
|
|
35
|
+
file.percentage = round(event.progress * 100);
|
|
36
|
+
});
|
|
37
|
+
opts.progress(cloneDeep(files));
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* 上传请求方法,返回响应对象
|
|
41
|
+
*
|
|
42
|
+
* @author lxm
|
|
43
|
+
* @date 2022-11-18 13:11:57
|
|
44
|
+
* @param {File[]} files
|
|
45
|
+
* @returns {*} {Promise<HttpResponse>}
|
|
46
|
+
*/
|
|
47
|
+
const uploadRequest = async (files, onProgress) => {
|
|
48
|
+
// 自定义上传请求
|
|
49
|
+
if (opts.request && isFunction(opts.request)) {
|
|
50
|
+
return opts.request(files);
|
|
51
|
+
}
|
|
52
|
+
// 默认每次单个文件上传,可能存在接口一次上传多个文件,
|
|
53
|
+
const data = new FormData();
|
|
54
|
+
files.forEach(file => {
|
|
55
|
+
data.append('file', file);
|
|
56
|
+
});
|
|
57
|
+
const res = await ibiz.net.request(opts.uploadUrl, {
|
|
58
|
+
method: 'post',
|
|
59
|
+
baseURL: '',
|
|
60
|
+
data,
|
|
61
|
+
headers: { 'Content-Type': 'multipart/form-data' },
|
|
62
|
+
onUploadProgress: onProgress,
|
|
63
|
+
});
|
|
64
|
+
return res;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* 执行一次上传,可能是一个文件也可能是多个文件
|
|
68
|
+
*
|
|
69
|
+
* @author lxm
|
|
70
|
+
* @date 2022-11-18 14:11:54
|
|
71
|
+
* @param {File[]} files 此次上传文件的集合
|
|
72
|
+
* @returns {*} {Promise<IUploadFile[]>}
|
|
73
|
+
*/
|
|
74
|
+
const executeSingleUpload = async (files) => {
|
|
75
|
+
const resultFiles = files.map(file => {
|
|
76
|
+
return {
|
|
77
|
+
status: 'uploading',
|
|
78
|
+
name: file.name,
|
|
79
|
+
uid: uniqueId(),
|
|
80
|
+
percentage: 0,
|
|
81
|
+
};
|
|
82
|
+
});
|
|
83
|
+
// 上传前回调,可以取消此次下载
|
|
84
|
+
const pass = opts.beforeUpload(files, resultFiles);
|
|
85
|
+
if (!pass) {
|
|
86
|
+
resultFiles.forEach(file => {
|
|
87
|
+
file.status = 'cancel';
|
|
88
|
+
});
|
|
89
|
+
ibiz.log.debug('取消上传', resultFiles);
|
|
90
|
+
return resultFiles;
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
const res = await uploadRequest(files, event => {
|
|
94
|
+
onUploadProgress(event, resultFiles);
|
|
95
|
+
});
|
|
96
|
+
resultFiles.forEach(file => {
|
|
97
|
+
file.status = 'finished';
|
|
98
|
+
});
|
|
99
|
+
// 上传成功事件
|
|
100
|
+
opts.success(resultFiles, res);
|
|
101
|
+
resultFiles.forEach(file => {
|
|
102
|
+
file.response = res;
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
resultFiles.forEach(file => {
|
|
107
|
+
file.status = 'fail';
|
|
108
|
+
});
|
|
109
|
+
// 上传失败事件
|
|
110
|
+
opts.error(resultFiles, error);
|
|
111
|
+
resultFiles.forEach(file => {
|
|
112
|
+
file.error = error;
|
|
113
|
+
});
|
|
114
|
+
ibiz.log.error(error);
|
|
115
|
+
ibiz.log.error(`${files.map(file => file.name).join(',')}上传失败`);
|
|
116
|
+
}
|
|
117
|
+
return resultFiles;
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* 执行上传文件逻辑
|
|
121
|
+
*
|
|
122
|
+
* @author lxm
|
|
123
|
+
* @date 2022-11-18 13:11:21
|
|
124
|
+
* @param {files} File[] 文件集合
|
|
125
|
+
*/
|
|
126
|
+
const uploadFiles = async (files) => {
|
|
127
|
+
const uploadSequence = opts.separate ? files.map(file => [file]) : [files];
|
|
128
|
+
const res = await Promise.allSettled(uploadSequence.map(async (sequence) => {
|
|
129
|
+
return executeSingleUpload(sequence);
|
|
130
|
+
}));
|
|
131
|
+
// 整合所有的返回文件
|
|
132
|
+
const resultFiles = [];
|
|
133
|
+
res.forEach(result => {
|
|
134
|
+
if (result.status === 'fulfilled') {
|
|
135
|
+
resultFiles.push(...result.value);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
opts.finish(resultFiles);
|
|
139
|
+
};
|
|
140
|
+
const select = () => {
|
|
141
|
+
selectFile({
|
|
142
|
+
accept: opts.accept,
|
|
143
|
+
multiple: opts.multiple,
|
|
144
|
+
onSelected: files => {
|
|
145
|
+
uploadFiles(files);
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
};
|
|
149
|
+
select();
|
|
150
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ibiz-template/core",
|
|
3
|
-
"version": "0.0.1-beta.
|
|
3
|
+
"version": "0.0.1-beta.130",
|
|
4
4
|
"description": "核心包",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "out/index.js",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"author": "chitanda",
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"axios": "^1.1
|
|
33
|
+
"axios": "^1.2.1",
|
|
34
34
|
"loglevel": "^1.8.0",
|
|
35
35
|
"pluralize": "^8.0.0",
|
|
36
36
|
"qs": "^6.11.0"
|
|
@@ -39,11 +39,12 @@
|
|
|
39
39
|
"@types/pluralize": "^0.0.29",
|
|
40
40
|
"@types/qs": "^6.9.7",
|
|
41
41
|
"lodash-es": "^4.17.21",
|
|
42
|
-
"qx-util": "^0.4.
|
|
42
|
+
"qx-util": "^0.4.8",
|
|
43
|
+
"ramda": "^0.28.0"
|
|
43
44
|
},
|
|
44
45
|
"peerDependencies": {
|
|
45
46
|
"lodash-es": "^4.17.21",
|
|
46
|
-
"qx-util": "^0.4.
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
"qx-util": "^0.4.8",
|
|
48
|
+
"ramda": "^0.28.0"
|
|
49
|
+
}
|
|
49
50
|
}
|
|
@@ -20,4 +20,14 @@ export class CoreConst {
|
|
|
20
20
|
* @static
|
|
21
21
|
*/
|
|
22
22
|
static readonly TOKEN = 'access_token';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 访问令牌标识过期时间
|
|
26
|
+
*
|
|
27
|
+
* @author lxm
|
|
28
|
+
* @date 2023-02-13 07:11:33
|
|
29
|
+
* @static
|
|
30
|
+
* @memberof CoreConst
|
|
31
|
+
*/
|
|
32
|
+
static readonly TOKEN_EXPIRES = 'access_token_expires';
|
|
23
33
|
}
|
package/src/context/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { clone } from 'ramda';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* 上下文处理类
|
|
3
5
|
*
|
|
@@ -10,24 +12,65 @@ export class IBizContext implements IContext {
|
|
|
10
12
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
11
13
|
[key: string | symbol]: any;
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
/**
|
|
16
|
+
* clone 后引用的上下文实例,需要在实例销毁时,同时销毁
|
|
17
|
+
*
|
|
18
|
+
* @author chitanda
|
|
19
|
+
* @date 2023-03-13 16:03:31
|
|
20
|
+
* @protected
|
|
21
|
+
* @type {IBizContext[]}
|
|
22
|
+
*/
|
|
23
|
+
protected declare _associationContext: IBizContext[];
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 修改的父上下文
|
|
27
|
+
*
|
|
28
|
+
* @author lxm
|
|
29
|
+
* @date 2022-12-08 18:12:16
|
|
30
|
+
* @protected
|
|
31
|
+
* @type {IData}
|
|
32
|
+
*/
|
|
33
|
+
protected declare _context: IData;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 父的上下文源对象
|
|
37
|
+
*
|
|
38
|
+
* @author lxm
|
|
39
|
+
* @date 2022-12-08 18:12:31
|
|
40
|
+
* @type {IContext}
|
|
41
|
+
*/
|
|
42
|
+
declare _parent?: IContext;
|
|
14
43
|
|
|
15
44
|
/**
|
|
16
45
|
* Creates an instance of IBizContext.
|
|
17
46
|
*
|
|
18
47
|
* @author chitanda
|
|
19
48
|
* @date 2022-07-14 10:07:15
|
|
20
|
-
* @param {
|
|
21
|
-
* @param {
|
|
49
|
+
* @param {IData} [context={}] 自身的上下文
|
|
50
|
+
* @param {IContext} [parent]
|
|
22
51
|
*/
|
|
23
52
|
// eslint-disable-next-line default-param-last
|
|
24
|
-
constructor(context:
|
|
53
|
+
private constructor(context: IData = {}, parent?: IContext) {
|
|
54
|
+
Object.defineProperty(this, '_associationContext', {
|
|
55
|
+
enumerable: false,
|
|
56
|
+
value: [],
|
|
57
|
+
});
|
|
58
|
+
|
|
25
59
|
if (parent) {
|
|
26
60
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
27
61
|
const self = this;
|
|
28
|
-
|
|
62
|
+
|
|
63
|
+
// 定义私有变量,存放父上下文源对象
|
|
64
|
+
Object.defineProperty(this, '_parent', {
|
|
65
|
+
enumerable: false,
|
|
66
|
+
writable: true,
|
|
67
|
+
value: parent,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// 定义私有变量,用于存储对父已有上下文的修改。
|
|
29
71
|
Object.defineProperty(this, '_context', {
|
|
30
72
|
enumerable: false,
|
|
73
|
+
writable: true,
|
|
31
74
|
value: {},
|
|
32
75
|
});
|
|
33
76
|
// 监控父上下文参数,自身不存在时从父取
|
|
@@ -56,4 +99,71 @@ export class IBizContext implements IContext {
|
|
|
56
99
|
// 合并给入上下文
|
|
57
100
|
Object.assign(this, context);
|
|
58
101
|
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* 返回自身的上下文,独有的和与父有差异的。
|
|
105
|
+
*
|
|
106
|
+
* @author lxm
|
|
107
|
+
* @date 2022-12-08 17:12:26
|
|
108
|
+
* @returns {*} {IData}
|
|
109
|
+
*/
|
|
110
|
+
getOwnContext(): IData {
|
|
111
|
+
const result: IData = {};
|
|
112
|
+
Object.keys(this).forEach(key => {
|
|
113
|
+
// 父没有的,或者修改了父的上下文
|
|
114
|
+
// 父不存在则返回所有自身的属性
|
|
115
|
+
if (
|
|
116
|
+
!this._parent ||
|
|
117
|
+
!Object.prototype.hasOwnProperty.call(this._parent, key) ||
|
|
118
|
+
Object.prototype.hasOwnProperty.call(this._context, key)
|
|
119
|
+
) {
|
|
120
|
+
result[key] = this[key];
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* 销毁当前上下文对象
|
|
128
|
+
*
|
|
129
|
+
* @author chitanda
|
|
130
|
+
* @date 2023-03-13 15:03:04
|
|
131
|
+
*/
|
|
132
|
+
destroy(): void {
|
|
133
|
+
this._parent = undefined;
|
|
134
|
+
this._context = {};
|
|
135
|
+
this._associationContext.forEach(item => {
|
|
136
|
+
item.destroy();
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* 在非视图中,需要断开视图上下文联系时。只能使用 clone 创建新的局部上下文
|
|
142
|
+
*
|
|
143
|
+
* @author chitanda
|
|
144
|
+
* @date 2023-03-13 16:03:13
|
|
145
|
+
* @return {*} {IBizContext}
|
|
146
|
+
*/
|
|
147
|
+
clone(): IBizContext {
|
|
148
|
+
const newContext = new IBizContext(
|
|
149
|
+
clone(this.getOwnContext()),
|
|
150
|
+
this._parent,
|
|
151
|
+
);
|
|
152
|
+
this._associationContext.push(newContext);
|
|
153
|
+
return newContext;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* 上下文只有在视图初始化时,调用 create 方法
|
|
158
|
+
*
|
|
159
|
+
* @author chitanda
|
|
160
|
+
* @date 2023-03-13 16:03:32
|
|
161
|
+
* @static
|
|
162
|
+
* @param {IData} [context]
|
|
163
|
+
* @param {IContext} [parent]
|
|
164
|
+
* @return {*} {IContext}
|
|
165
|
+
*/
|
|
166
|
+
static create(context?: IData, parent?: IContext): IBizContext {
|
|
167
|
+
return new IBizContext(context, parent);
|
|
168
|
+
}
|
|
59
169
|
}
|
|
@@ -19,4 +19,9 @@ export const Environment: IEnvironment = {
|
|
|
19
19
|
loginMode: LoginMode.DEFAULT,
|
|
20
20
|
menuPermissionMode: MenuPermissionMode.MIXIN,
|
|
21
21
|
enablePermission: true,
|
|
22
|
+
enableWfAllHistory: false,
|
|
23
|
+
routePlaceholder: '-',
|
|
24
|
+
loginViewName: 'AppLoginView',
|
|
25
|
+
version: '0.0.1',
|
|
26
|
+
favicon: './favicon.ico',
|
|
22
27
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { AxiosError, AxiosResponse } from 'axios';
|
|
2
|
-
import { HttpStatusMessageConst } from '../../constant';
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
* 请求异常
|
|
@@ -28,9 +27,6 @@ export class HttpError implements Error {
|
|
|
28
27
|
} else {
|
|
29
28
|
this.message = res.statusText;
|
|
30
29
|
}
|
|
31
|
-
if (!this.message) {
|
|
32
|
-
this.message = HttpStatusMessageConst[res.status];
|
|
33
|
-
}
|
|
34
30
|
if (!this.message) {
|
|
35
31
|
this.message = '网络异常,请稍后重试!';
|
|
36
32
|
}
|
|
@@ -146,4 +146,45 @@ export interface IEnvironment {
|
|
|
146
146
|
* @type {MenuPermissionMode}
|
|
147
147
|
*/
|
|
148
148
|
menuPermissionMode: MenuPermissionMode;
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* 是否让所有工作流history接口走all
|
|
152
|
+
*
|
|
153
|
+
* @type {boolean}
|
|
154
|
+
* @memberof IEnvironment
|
|
155
|
+
*/
|
|
156
|
+
enableWfAllHistory: boolean;
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* 路由占位符
|
|
160
|
+
*
|
|
161
|
+
* @type {string}
|
|
162
|
+
* @memberof IEnvironment
|
|
163
|
+
*/
|
|
164
|
+
routePlaceholder: string;
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* 登录页视图组件名称
|
|
168
|
+
*
|
|
169
|
+
* @type {string}
|
|
170
|
+
* @memberof IEnvironment
|
|
171
|
+
*/
|
|
172
|
+
loginViewName: string;
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* 版本
|
|
176
|
+
*
|
|
177
|
+
* @type {string}
|
|
178
|
+
* @memberof IEnvironment
|
|
179
|
+
*/
|
|
180
|
+
version: string;
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* 应用图标地址
|
|
184
|
+
*
|
|
185
|
+
* @author chitanda
|
|
186
|
+
* @date 2023-07-17 17:07:23
|
|
187
|
+
* @type {string}
|
|
188
|
+
*/
|
|
189
|
+
favicon?: string;
|
|
149
190
|
}
|
package/src/types.ts
CHANGED
|
@@ -27,6 +27,41 @@ declare global {
|
|
|
27
27
|
*/
|
|
28
28
|
interface IContext {
|
|
29
29
|
[key: string | symbol]: any;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* 沙箱标识
|
|
33
|
+
*
|
|
34
|
+
* @author chitanda
|
|
35
|
+
* @date 2022-07-22 15:07:23
|
|
36
|
+
* @type {string}
|
|
37
|
+
*/
|
|
38
|
+
srfsandbox?: string;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* 返回自身的上下文,独有的和与父有差异的
|
|
42
|
+
*
|
|
43
|
+
* @author chitanda
|
|
44
|
+
* @date 2023-03-13 17:03:10
|
|
45
|
+
* @return {*} {IData}
|
|
46
|
+
*/
|
|
47
|
+
getOwnContext(): IData;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* 销毁当前上下文
|
|
51
|
+
*
|
|
52
|
+
* @author chitanda
|
|
53
|
+
* @date 2023-03-13 17:03:37
|
|
54
|
+
*/
|
|
55
|
+
destroy(): void;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* 克隆当前上下文
|
|
59
|
+
*
|
|
60
|
+
* @author chitanda
|
|
61
|
+
* @date 2023-03-13 17:03:45
|
|
62
|
+
* @return {*} {IContext}
|
|
63
|
+
*/
|
|
64
|
+
clone(): IContext;
|
|
30
65
|
}
|
|
31
66
|
|
|
32
67
|
/**
|
|
@@ -51,12 +51,33 @@ export function calcMimeByFileName(fileName: string) {
|
|
|
51
51
|
case '.tar':
|
|
52
52
|
mime = 'application/x-tar';
|
|
53
53
|
break;
|
|
54
|
+
case '.xlsx':
|
|
55
|
+
mime = 'application/vnd.ms-excel';
|
|
56
|
+
break;
|
|
54
57
|
default:
|
|
55
58
|
mime = '';
|
|
56
59
|
}
|
|
57
60
|
return mime;
|
|
58
61
|
}
|
|
59
62
|
|
|
63
|
+
/**
|
|
64
|
+
* 判断是否是图片格式
|
|
65
|
+
*
|
|
66
|
+
* @author lxm
|
|
67
|
+
* @date 2022-11-21 13:11:23
|
|
68
|
+
* @export
|
|
69
|
+
* @param {string} fileName
|
|
70
|
+
* @returns {*} {boolean}
|
|
71
|
+
*/
|
|
72
|
+
export function isImage(fileName: string): boolean {
|
|
73
|
+
const ext = fileName.split('.').pop();
|
|
74
|
+
if (!ext) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
const imageTypes = ['.jpeg', 'jpg', 'gif', 'png', 'bmp', 'svg'];
|
|
78
|
+
return imageTypes.includes(ext);
|
|
79
|
+
}
|
|
80
|
+
|
|
60
81
|
/**
|
|
61
82
|
* 纯JS触发下载文件
|
|
62
83
|
*
|
package/src/utils/index.ts
CHANGED
|
@@ -10,3 +10,7 @@ export * from './event/event';
|
|
|
10
10
|
export * from './click-outside/click-outside';
|
|
11
11
|
export * from './color/color';
|
|
12
12
|
export * from './download-file/download-file';
|
|
13
|
+
export * from './upload/select-file';
|
|
14
|
+
export * from './upload/upload-file';
|
|
15
|
+
export * from './sync';
|
|
16
|
+
export { StringUtil } from './string-util/string-util';
|
package/src/utils/net/net.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { merge } from 'lodash-es';
|
|
|
10
10
|
import { stringify } from 'qs';
|
|
11
11
|
import { notNilEmpty } from 'qx-util';
|
|
12
12
|
import { HttpError } from '../../error';
|
|
13
|
+
import { CoreInterceptor } from '../interceptor';
|
|
13
14
|
import { Interceptor } from '../interceptor/interceptor';
|
|
14
15
|
import { IHttpResponse } from './http-response';
|
|
15
16
|
|
|
@@ -32,6 +33,15 @@ export class Net {
|
|
|
32
33
|
*/
|
|
33
34
|
protected instance: AxiosInstance;
|
|
34
35
|
|
|
36
|
+
/**
|
|
37
|
+
* 是否为 http || https 开头
|
|
38
|
+
*
|
|
39
|
+
* @author chitanda
|
|
40
|
+
* @date 2022-11-07 14:11:28
|
|
41
|
+
* @protected
|
|
42
|
+
*/
|
|
43
|
+
protected urlReg = /^http[s]?:\/\/[^\s]*/;
|
|
44
|
+
|
|
35
45
|
/**
|
|
36
46
|
* Creates an instance of Net.
|
|
37
47
|
* @author lxm
|
|
@@ -40,6 +50,7 @@ export class Net {
|
|
|
40
50
|
*/
|
|
41
51
|
constructor(config?: CreateAxiosDefaults) {
|
|
42
52
|
this.instance = axios.create(config);
|
|
53
|
+
this.addInterceptor('Default', new CoreInterceptor());
|
|
43
54
|
}
|
|
44
55
|
|
|
45
56
|
/**
|
|
@@ -91,7 +102,7 @@ export class Net {
|
|
|
91
102
|
protected get presetConfig(): AxiosRequestConfig {
|
|
92
103
|
return {
|
|
93
104
|
// 请求前缀路径
|
|
94
|
-
baseURL:
|
|
105
|
+
baseURL: ibiz.env.baseUrl,
|
|
95
106
|
headers: {
|
|
96
107
|
'Content-Type': 'application/json;charset=UTF-8',
|
|
97
108
|
Accept: 'application/json',
|
|
@@ -109,10 +120,15 @@ export class Net {
|
|
|
109
120
|
* @returns {*}
|
|
110
121
|
*/
|
|
111
122
|
protected mergeConfig(...configs: AxiosRequestConfig[]) {
|
|
123
|
+
const config = this.presetConfig;
|
|
112
124
|
if (configs.length === 0) {
|
|
113
|
-
return
|
|
125
|
+
return config;
|
|
126
|
+
}
|
|
127
|
+
const { url } = configs[0];
|
|
128
|
+
if (url && this.urlReg.test(url)) {
|
|
129
|
+
delete config.baseURL;
|
|
114
130
|
}
|
|
115
|
-
return merge(
|
|
131
|
+
return merge(config, ...configs);
|
|
116
132
|
}
|
|
117
133
|
|
|
118
134
|
/**
|
|
@@ -278,6 +294,18 @@ export class Net {
|
|
|
278
294
|
}
|
|
279
295
|
}
|
|
280
296
|
|
|
297
|
+
/**
|
|
298
|
+
* 创建标准 axios 请求
|
|
299
|
+
*
|
|
300
|
+
* @author chitanda
|
|
301
|
+
* @date 2023-01-30 15:01:27
|
|
302
|
+
* @param {AxiosRequestConfig<IData>} config
|
|
303
|
+
* @return {*}
|
|
304
|
+
*/
|
|
305
|
+
axios(config: AxiosRequestConfig<IData>) {
|
|
306
|
+
return axios(config);
|
|
307
|
+
}
|
|
308
|
+
|
|
281
309
|
/**
|
|
282
310
|
* 统一处理请求返回
|
|
283
311
|
*
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { notNilEmpty } from 'qx-util';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 字符串工具类
|
|
5
|
+
*
|
|
6
|
+
* @author chitanda
|
|
7
|
+
* @date 2021-04-23 20:04:27
|
|
8
|
+
* @export
|
|
9
|
+
* @class StringUtil
|
|
10
|
+
*/
|
|
11
|
+
export class StringUtil {
|
|
12
|
+
/**
|
|
13
|
+
* 上下文替换正则
|
|
14
|
+
*
|
|
15
|
+
* @author chitanda
|
|
16
|
+
* @date 2021-04-23 20:04:01
|
|
17
|
+
* @static
|
|
18
|
+
*/
|
|
19
|
+
static contextReg = /\$\{context.[a-zA-Z_$][a-zA-Z0-9_$]{1,}\}/g;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 数据替换正则
|
|
23
|
+
*
|
|
24
|
+
* @author chitanda
|
|
25
|
+
* @date 2021-04-23 20:04:09
|
|
26
|
+
* @static
|
|
27
|
+
*/
|
|
28
|
+
static dataReg = /\$\{data.[a-zA-Z_$][a-zA-Z0-9_$]{1,}\}/g;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 填充字符串中的数据
|
|
32
|
+
*
|
|
33
|
+
* @author chitanda
|
|
34
|
+
* @date 2021-04-23 20:04:17
|
|
35
|
+
* @static
|
|
36
|
+
* @param {string} str
|
|
37
|
+
* @param {*} [context]
|
|
38
|
+
* @param {*} [data]
|
|
39
|
+
* @return {*} {string}
|
|
40
|
+
*/
|
|
41
|
+
static fill(str: string, context?: IContext, data?: IData): string {
|
|
42
|
+
if (notNilEmpty(str)) {
|
|
43
|
+
if (notNilEmpty(context)) {
|
|
44
|
+
const strArr = str.match(this.contextReg);
|
|
45
|
+
strArr?.forEach(_key => {
|
|
46
|
+
const key = _key.slice(10, _key.length - 1);
|
|
47
|
+
str = str.replace(`\${context.${key}}`, context![key] || '');
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
if (notNilEmpty(data)) {
|
|
51
|
+
const strArr = str.match(this.dataReg);
|
|
52
|
+
strArr?.forEach(_key => {
|
|
53
|
+
const key = _key.slice(7, _key.length - 1);
|
|
54
|
+
str = str.replace(`\${data.${key}}`, data![key] || '');
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return str;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 动态匹配${}
|
|
63
|
+
*
|
|
64
|
+
* @param str
|
|
65
|
+
* @param values
|
|
66
|
+
*/
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
68
|
+
static dynamicMatch(str: string, values: any): string {
|
|
69
|
+
return str.replace(/\${(.*?)}/g, (_, key) => {
|
|
70
|
+
const [objKey, propName] = key.split('.');
|
|
71
|
+
const obj = values[objKey];
|
|
72
|
+
return obj ? obj[propName] : '';
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
/**
|
|
3
|
+
* 设置延迟wait毫米后执行fun方法,返回fun的返回值
|
|
4
|
+
*
|
|
5
|
+
* @author lxm
|
|
6
|
+
* @date 2023-03-06 08:20:57
|
|
7
|
+
* @export
|
|
8
|
+
* @template T
|
|
9
|
+
* @param {number} wait
|
|
10
|
+
* @param {T} fun
|
|
11
|
+
* @param {any[]} params
|
|
12
|
+
* @returns {*} {Promise<ReturnType<T>>}
|
|
13
|
+
*/
|
|
14
|
+
export async function awaitTimeout<T extends (...args: any) => any>(
|
|
15
|
+
wait: number,
|
|
16
|
+
fun?: T,
|
|
17
|
+
params?: any[],
|
|
18
|
+
): Promise<ReturnType<T> | undefined> {
|
|
19
|
+
await new Promise(resolve => {
|
|
20
|
+
setTimeout(() => {
|
|
21
|
+
resolve(true);
|
|
22
|
+
}, wait);
|
|
23
|
+
});
|
|
24
|
+
if (fun) {
|
|
25
|
+
return fun(...(params || []));
|
|
26
|
+
}
|
|
27
|
+
}
|