@hzab/utils 1.0.6 → 1.0.8-beta
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/README.md +137 -137
- package/changelog.md +10 -1
- package/package.json +1 -1
- package/src/formily/cloneSchema.ts +63 -0
- package/src/upload/OssUploadUtil.ts +203 -204
package/README.md
CHANGED
|
@@ -1,137 +1,137 @@
|
|
|
1
|
-
# @hzab/utils
|
|
2
|
-
|
|
3
|
-
组件模板
|
|
4
|
-
|
|
5
|
-
- node@16.16.0
|
|
6
|
-
|
|
7
|
-
- 注意:首次克隆先执行 npm run prepare 命令
|
|
8
|
-
|
|
9
|
-
# 组件
|
|
10
|
-
|
|
11
|
-
## ossUpload 示例
|
|
12
|
-
|
|
13
|
-
```jsx
|
|
14
|
-
import OssUpload from "@hzab/utils/src/ossUpload";
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* 批量文件上传
|
|
18
|
-
* @param {Array} files
|
|
19
|
-
* @param {Object} opt
|
|
20
|
-
* @returns
|
|
21
|
-
*/
|
|
22
|
-
export async function handleOssUpload(files, opt) {
|
|
23
|
-
const _files = files;
|
|
24
|
-
const { ossUrl, signatureParams, ossParams, axiosConf, useHashName } = opt || {};
|
|
25
|
-
const ossUpload = new OssUpload({
|
|
26
|
-
axios: opt.axios,
|
|
27
|
-
axiosConf: axiosConf,
|
|
28
|
-
serverUrl: ossUrl || "/api/v1/
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
const promise = [];
|
|
32
|
-
_files?.forEach((file) => {
|
|
33
|
-
if (!file) {
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
// 数据已经是 url 的情况
|
|
37
|
-
if (typeof file === "string" || file.ossUrl || file.url) {
|
|
38
|
-
promise.push(Promise.resolve(file));
|
|
39
|
-
} else {
|
|
40
|
-
promise.push(
|
|
41
|
-
ossUpload
|
|
42
|
-
.upload(file, {
|
|
43
|
-
signatureParams: {
|
|
44
|
-
isPublic: 1,
|
|
45
|
-
...(signatureParams || {}),
|
|
46
|
-
},
|
|
47
|
-
ossParams,
|
|
48
|
-
axiosConf,
|
|
49
|
-
useHashName,
|
|
50
|
-
})
|
|
51
|
-
.then((res) => {
|
|
52
|
-
return Promise.resolve(res?.data?.data?.fileUrl);
|
|
53
|
-
}),
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
return Promise.all(promise).then((filePromises) => {
|
|
59
|
-
filePromises?.forEach((fileUrl, idx) => {
|
|
60
|
-
if (typeof fileUrl === "string") {
|
|
61
|
-
_files[idx].ossUrl = fileUrl;
|
|
62
|
-
_files[idx].url = fileUrl;
|
|
63
|
-
} else if (_files[idx].url) {
|
|
64
|
-
_files[idx].ossUrl = _files[idx].url;
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
return Promise.resolve(_files);
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
## API
|
|
73
|
-
|
|
74
|
-
### InfoPanel Attributes
|
|
75
|
-
|
|
76
|
-
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
|
77
|
-
| ------ | ------ | ---- | ------ | ----------------- |
|
|
78
|
-
| schema | Object | 是 | - | 数据信息的 schema |
|
|
79
|
-
|
|
80
|
-
# 组件开发流程
|
|
81
|
-
|
|
82
|
-
- 在 config/webpack.config.js 中按需修改 library 配置的文件名
|
|
83
|
-
- 在 config/webpack.config.js 中按需修改 alias 配置的包名,便于本地调试
|
|
84
|
-
- 在 tsconfig.json 中按需修改 paths 配置的包名,解决 ts 报错问题
|
|
85
|
-
- npm run dev
|
|
86
|
-
|
|
87
|
-
## 文件目录
|
|
88
|
-
|
|
89
|
-
- example 本地开发测试代码
|
|
90
|
-
- src 组件源码
|
|
91
|
-
|
|
92
|
-
## 命令
|
|
93
|
-
|
|
94
|
-
- Mac 执行该命令,设置 pre-commit 为可执行文件
|
|
95
|
-
|
|
96
|
-
- npm run mac-chmod
|
|
97
|
-
- chmod +x .husky && chmod +x .husky/pre-commit
|
|
98
|
-
|
|
99
|
-
- 生成文档:npm run docs
|
|
100
|
-
- 本地运行:npm run dev
|
|
101
|
-
|
|
102
|
-
## 发布
|
|
103
|
-
|
|
104
|
-
- npm 源和云效源都需要发布
|
|
105
|
-
|
|
106
|
-
- 命令:npm publish --access public
|
|
107
|
-
- 发布目录:
|
|
108
|
-
- src
|
|
109
|
-
|
|
110
|
-
### 迭代发布命令-版本自增
|
|
111
|
-
|
|
112
|
-
- beta: 需要手动修改 package.json 中的 version,添加 -betaX 版本号。使用 npm publish --beta 发布
|
|
113
|
-
- 0.0.x: npm run publish-patch
|
|
114
|
-
- 0.x.0: npm run publish-minor
|
|
115
|
-
- x.0.0: npm run publish-major
|
|
116
|
-
|
|
117
|
-
### nrm
|
|
118
|
-
|
|
119
|
-
- 安装
|
|
120
|
-
npm install -g nrm
|
|
121
|
-
- 增加源
|
|
122
|
-
nrm add aliyun https://packages.aliyun.com/62046985b3ead41b374a17f7/npm/npm-registry/
|
|
123
|
-
- 切换源
|
|
124
|
-
nrm use aliyun
|
|
125
|
-
nrm use npm
|
|
126
|
-
- 登录(账号密码在 https://packages.aliyun.com/npm/npm-registry/guide 查看)
|
|
127
|
-
npm login --registry=https://packages.aliyun.com/62046985b3ead41b374a17f7/npm/npm-registry/
|
|
128
|
-
|
|
129
|
-
## 配置
|
|
130
|
-
|
|
131
|
-
### 配置文件
|
|
132
|
-
|
|
133
|
-
- 本地配置文件:config/config.js
|
|
134
|
-
|
|
135
|
-
### webpack 配置文件
|
|
136
|
-
|
|
137
|
-
- config/webpack.config.js
|
|
1
|
+
# @hzab/utils
|
|
2
|
+
|
|
3
|
+
组件模板
|
|
4
|
+
|
|
5
|
+
- node@16.16.0
|
|
6
|
+
|
|
7
|
+
- 注意:首次克隆先执行 npm run prepare 命令
|
|
8
|
+
|
|
9
|
+
# 组件
|
|
10
|
+
|
|
11
|
+
## ossUpload 示例
|
|
12
|
+
|
|
13
|
+
```jsx
|
|
14
|
+
import OssUpload from "@hzab/utils/src/ossUpload";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 批量文件上传
|
|
18
|
+
* @param {Array} files
|
|
19
|
+
* @param {Object} opt
|
|
20
|
+
* @returns
|
|
21
|
+
*/
|
|
22
|
+
export async function handleOssUpload(files, opt) {
|
|
23
|
+
const _files = files;
|
|
24
|
+
const { ossUrl, signatureParams, ossParams, axiosConf, useHashName } = opt || {};
|
|
25
|
+
const ossUpload = new OssUpload({
|
|
26
|
+
axios: opt.axios,
|
|
27
|
+
axiosConf: axiosConf,
|
|
28
|
+
serverUrl: ossUrl || "/api/v1/common/oss/getWebOssConfig",
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const promise = [];
|
|
32
|
+
_files?.forEach((file) => {
|
|
33
|
+
if (!file) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
// 数据已经是 url 的情况
|
|
37
|
+
if (typeof file === "string" || file.ossUrl || file.url) {
|
|
38
|
+
promise.push(Promise.resolve(file));
|
|
39
|
+
} else {
|
|
40
|
+
promise.push(
|
|
41
|
+
ossUpload
|
|
42
|
+
.upload(file, {
|
|
43
|
+
signatureParams: {
|
|
44
|
+
isPublic: 1,
|
|
45
|
+
...(signatureParams || {}),
|
|
46
|
+
},
|
|
47
|
+
ossParams,
|
|
48
|
+
axiosConf,
|
|
49
|
+
useHashName,
|
|
50
|
+
})
|
|
51
|
+
.then((res) => {
|
|
52
|
+
return Promise.resolve(res?.data?.data?.fileUrl);
|
|
53
|
+
}),
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
return Promise.all(promise).then((filePromises) => {
|
|
59
|
+
filePromises?.forEach((fileUrl, idx) => {
|
|
60
|
+
if (typeof fileUrl === "string") {
|
|
61
|
+
_files[idx].ossUrl = fileUrl;
|
|
62
|
+
_files[idx].url = fileUrl;
|
|
63
|
+
} else if (_files[idx].url) {
|
|
64
|
+
_files[idx].ossUrl = _files[idx].url;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
return Promise.resolve(_files);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## API
|
|
73
|
+
|
|
74
|
+
### InfoPanel Attributes
|
|
75
|
+
|
|
76
|
+
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
|
77
|
+
| ------ | ------ | ---- | ------ | ----------------- |
|
|
78
|
+
| schema | Object | 是 | - | 数据信息的 schema |
|
|
79
|
+
|
|
80
|
+
# 组件开发流程
|
|
81
|
+
|
|
82
|
+
- 在 config/webpack.config.js 中按需修改 library 配置的文件名
|
|
83
|
+
- 在 config/webpack.config.js 中按需修改 alias 配置的包名,便于本地调试
|
|
84
|
+
- 在 tsconfig.json 中按需修改 paths 配置的包名,解决 ts 报错问题
|
|
85
|
+
- npm run dev
|
|
86
|
+
|
|
87
|
+
## 文件目录
|
|
88
|
+
|
|
89
|
+
- example 本地开发测试代码
|
|
90
|
+
- src 组件源码
|
|
91
|
+
|
|
92
|
+
## 命令
|
|
93
|
+
|
|
94
|
+
- Mac 执行该命令,设置 pre-commit 为可执行文件
|
|
95
|
+
|
|
96
|
+
- npm run mac-chmod
|
|
97
|
+
- chmod +x .husky && chmod +x .husky/pre-commit
|
|
98
|
+
|
|
99
|
+
- 生成文档:npm run docs
|
|
100
|
+
- 本地运行:npm run dev
|
|
101
|
+
|
|
102
|
+
## 发布
|
|
103
|
+
|
|
104
|
+
- npm 源和云效源都需要发布
|
|
105
|
+
|
|
106
|
+
- 命令:npm publish --access public
|
|
107
|
+
- 发布目录:
|
|
108
|
+
- src
|
|
109
|
+
|
|
110
|
+
### 迭代发布命令-版本自增
|
|
111
|
+
|
|
112
|
+
- beta: 需要手动修改 package.json 中的 version,添加 -betaX 版本号。使用 npm publish --beta 发布
|
|
113
|
+
- 0.0.x: npm run publish-patch
|
|
114
|
+
- 0.x.0: npm run publish-minor
|
|
115
|
+
- x.0.0: npm run publish-major
|
|
116
|
+
|
|
117
|
+
### nrm
|
|
118
|
+
|
|
119
|
+
- 安装
|
|
120
|
+
npm install -g nrm
|
|
121
|
+
- 增加源
|
|
122
|
+
nrm add aliyun https://packages.aliyun.com/62046985b3ead41b374a17f7/npm/npm-registry/
|
|
123
|
+
- 切换源
|
|
124
|
+
nrm use aliyun
|
|
125
|
+
nrm use npm
|
|
126
|
+
- 登录(账号密码在 https://packages.aliyun.com/npm/npm-registry/guide 查看)
|
|
127
|
+
npm login --registry=https://packages.aliyun.com/62046985b3ead41b374a17f7/npm/npm-registry/
|
|
128
|
+
|
|
129
|
+
## 配置
|
|
130
|
+
|
|
131
|
+
### 配置文件
|
|
132
|
+
|
|
133
|
+
- 本地配置文件:config/config.js
|
|
134
|
+
|
|
135
|
+
### webpack 配置文件
|
|
136
|
+
|
|
137
|
+
- config/webpack.config.js
|
package/changelog.md
CHANGED
package/package.json
CHANGED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 检测是否为原生 HTML DOM 节点
|
|
5
|
+
* @param {any} node 待检测对象
|
|
6
|
+
* @returns {boolean} 是否为原生 DOM 节点
|
|
7
|
+
*/
|
|
8
|
+
function isHtmlDomNode(node) {
|
|
9
|
+
// 先判断浏览器环境,避免 SSR 报错;兼容 Node/HTMLElement 类型
|
|
10
|
+
return !!(typeof window !== "undefined" && node && (node instanceof HTMLElement || node instanceof Node));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 增强版 Formily Schema 克隆函数
|
|
15
|
+
* 解决 lodash cloneDeep 丢失 React DOM/原生 DOM 的问题,兼容多种特殊类型
|
|
16
|
+
* @param {object} schema 待克隆的 Formily Schema
|
|
17
|
+
* @returns {object} 克隆后的 Schema
|
|
18
|
+
*/
|
|
19
|
+
export function cloneSchema(schema) {
|
|
20
|
+
// 1. 基础类型(null/undefined/字符串/数字/布尔)直接返回
|
|
21
|
+
if (schema === null || typeof schema !== "object") {
|
|
22
|
+
return schema;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// 2. React 虚拟DOM:直接保留原引用,不拷贝
|
|
26
|
+
if (React.isValidElement(schema)) {
|
|
27
|
+
return schema;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// 3. 原生 HTML DOM 节点:直接保留原引用
|
|
31
|
+
if (isHtmlDomNode(schema)) {
|
|
32
|
+
return schema;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// 4. 函数:Formily Schema 中的校验/格式化函数等,保留原引用
|
|
36
|
+
if (typeof schema === "function") {
|
|
37
|
+
return schema;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 5. 日期对象:创建新的 Date 实例,保证值相同但引用不同
|
|
41
|
+
if (schema instanceof Date) {
|
|
42
|
+
return new Date(schema.getTime());
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// 6. 正则对象:创建新的 RegExp 实例,保留源和标志
|
|
46
|
+
if (schema instanceof RegExp) {
|
|
47
|
+
return new RegExp(schema.source, schema.flags);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 7. 数组:递归克隆每一项
|
|
51
|
+
if (Array.isArray(schema)) {
|
|
52
|
+
return schema.map((item) => cloneSchema(item));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// 8. 普通对象:递归克隆自有属性
|
|
56
|
+
const clonedObj = {};
|
|
57
|
+
for (const key in schema) {
|
|
58
|
+
if (Object.prototype.hasOwnProperty.call(schema, key)) {
|
|
59
|
+
clonedObj[key] = cloneSchema(schema[key]);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return clonedObj;
|
|
63
|
+
}
|
|
@@ -1,204 +1,203 @@
|
|
|
1
|
-
import dayjs from "dayjs";
|
|
2
|
-
|
|
3
|
-
import { axios } from "@hzab/data-model";
|
|
4
|
-
import { formatDirStr } from "./uploadUtils";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
this.
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
formData.set("
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
reject(err);
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
export default OssUploadUtil;
|
|
1
|
+
import dayjs from "dayjs";
|
|
2
|
+
|
|
3
|
+
import { axios } from "@hzab/data-model";
|
|
4
|
+
import { formatDirStr } from "./uploadUtils";
|
|
5
|
+
const isPublicMap = {
|
|
6
|
+
0: "&",
|
|
7
|
+
1: "?"
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* getSignature 配置
|
|
11
|
+
*/
|
|
12
|
+
export interface IGetSignatureOpt {
|
|
13
|
+
/** 获取配置的接口地址 */
|
|
14
|
+
serverUrl?: string;
|
|
15
|
+
/** axios 实例 */
|
|
16
|
+
axios?: typeof axios;
|
|
17
|
+
/** axios 配置参数 */
|
|
18
|
+
axiosConf?: Object;
|
|
19
|
+
/** 获取配置的接口自定义入参 */
|
|
20
|
+
params?: {
|
|
21
|
+
/** 文件路径 */
|
|
22
|
+
dir?: string;
|
|
23
|
+
/** 是否是公开库 */
|
|
24
|
+
isPublic?: number;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* OssUpload props 参数
|
|
30
|
+
*/
|
|
31
|
+
export interface IOssUploadProps {
|
|
32
|
+
/** axios 实例 */
|
|
33
|
+
axios?: typeof axios;
|
|
34
|
+
/** axios 配置参数 */
|
|
35
|
+
axiosConf?: Object;
|
|
36
|
+
/** 获取配置的接口地址 */
|
|
37
|
+
serverUrl?: string;
|
|
38
|
+
/** 获取配置的接口自定义入参 */
|
|
39
|
+
signatureParams?: {
|
|
40
|
+
/** 文件路径 */
|
|
41
|
+
dir?: string;
|
|
42
|
+
/** 是否是公开库 */
|
|
43
|
+
isPublic?: number;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface IUploadOpt {
|
|
48
|
+
fileName?: string;
|
|
49
|
+
/** axios 实例 */
|
|
50
|
+
axios?: typeof axios;
|
|
51
|
+
/** axios 配置参数 */
|
|
52
|
+
axiosConf?: Object;
|
|
53
|
+
/** 获取配置的接口地址 */
|
|
54
|
+
serverUrl?: string;
|
|
55
|
+
/** 获取配置的接口自定义入参 */
|
|
56
|
+
params?: {
|
|
57
|
+
/** 文件路径 */
|
|
58
|
+
dir?: string;
|
|
59
|
+
/** 是否是公开库 */
|
|
60
|
+
isPublic?: number;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* 获取配置接口请求入参
|
|
64
|
+
*/
|
|
65
|
+
signatureParams?: {
|
|
66
|
+
/** 公开还是私有 */
|
|
67
|
+
isPublic?: number;
|
|
68
|
+
};
|
|
69
|
+
/** 文件上传的接口自定义入参 */
|
|
70
|
+
ossParams?: {};
|
|
71
|
+
/** 是否使用 hash 文件名 */
|
|
72
|
+
useHashName?: boolean;
|
|
73
|
+
/**缩略图参数 */
|
|
74
|
+
thumbnailParams?: string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function getSignature(opt: IGetSignatureOpt = {}) {
|
|
78
|
+
const { serverUrl = "/api/v1/common/oss/getWebOssConfig" } = opt;
|
|
79
|
+
// 减 10 秒,避免发起请求时 刚好过期的情况
|
|
80
|
+
if (
|
|
81
|
+
window._$ossSignatureRes &&
|
|
82
|
+
serverUrl === window._$ossSignatureRes.serverUrl &&
|
|
83
|
+
dayjs().valueOf() - window._$ossSignatureRes.__saveTime < window._$ossSignatureRes.expireTimeMilles - 10000
|
|
84
|
+
) {
|
|
85
|
+
return Promise.resolve(window._$ossSignatureRes);
|
|
86
|
+
}
|
|
87
|
+
const { axios: _ax = axios, params = {}, axiosConf } = opt;
|
|
88
|
+
// 处理 dir 格式,必须为非 / 开头, / 结尾。如: test/
|
|
89
|
+
params.dir = formatDirStr(params.dir);
|
|
90
|
+
|
|
91
|
+
return _ax
|
|
92
|
+
.get(serverUrl, {
|
|
93
|
+
...axiosConf,
|
|
94
|
+
params: {
|
|
95
|
+
isPublic: 1,
|
|
96
|
+
...params,
|
|
97
|
+
},
|
|
98
|
+
})
|
|
99
|
+
.then((res) => {
|
|
100
|
+
window._$ossSignatureRes = res?.data?.data ?? res?.data ?? res;
|
|
101
|
+
if (window._$ossSignatureRes) {
|
|
102
|
+
window._$ossSignatureRes.__saveTime = dayjs().valueOf();
|
|
103
|
+
window._$ossSignatureRes.serverUrl = serverUrl;
|
|
104
|
+
}
|
|
105
|
+
return window._$ossSignatureRes;
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* oss 上传工具类
|
|
111
|
+
*/
|
|
112
|
+
class OssUploadUtil {
|
|
113
|
+
/** axios 实例 */
|
|
114
|
+
axios: typeof axios;
|
|
115
|
+
/** axios 配置参数 */
|
|
116
|
+
axiosConf: Object;
|
|
117
|
+
/** 获取配置的接口地址 */
|
|
118
|
+
serverUrl: string;
|
|
119
|
+
/** 获取配置的接口自定义入参 */
|
|
120
|
+
signatureParams?: {
|
|
121
|
+
/** 文件路径 */
|
|
122
|
+
dir?: string;
|
|
123
|
+
/** 是否是公开库 */
|
|
124
|
+
isPublic?: number;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
constructor(props: IOssUploadProps = {}) {
|
|
128
|
+
this.axios = props.axios || axios;
|
|
129
|
+
this.axiosConf = props.axiosConf || {};
|
|
130
|
+
this.serverUrl = props.serverUrl || "/api/v1/common/oss/getWebOssConfig";
|
|
131
|
+
this.signatureParams = props.signatureParams || {};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
getSignature(serverUrl = this.serverUrl, opt) {
|
|
135
|
+
return this._getSignature(serverUrl, opt);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
upload(file, opt: IUploadOpt = {}): Promise<{ fileUrl: string }> {
|
|
139
|
+
return this._upload(file, { ...opt });
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
_getSignature(serverUrl = this.serverUrl, opt) {
|
|
143
|
+
return getSignature({
|
|
144
|
+
...opt,
|
|
145
|
+
serverUrl,
|
|
146
|
+
axios: opt?.axios || this.axios,
|
|
147
|
+
axiosConf: { ...this.axiosConf, ...opt?.axiosConf },
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
_upload(file, opt: IUploadOpt = {}): Promise<{ fileUrl: string }> {
|
|
152
|
+
return new Promise(async (resolve, reject) => {
|
|
153
|
+
const ossParams = await this._getSignature(opt.serverUrl || this.serverUrl, {
|
|
154
|
+
...opt,
|
|
155
|
+
params: { ...this.signatureParams, ...opt.params },
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const { ossParams: propOssParams, fileName } = opt || {};
|
|
159
|
+
const formData = new FormData();
|
|
160
|
+
// key 表示上传到 Bucket 内的 Object 的完整路径,例如 exampledir/exampleobject.txtObject,完整路径中不能包含 Bucket 名称。
|
|
161
|
+
// filename 表示待上传的本地文件名称。
|
|
162
|
+
const filename = fileName || file.name;
|
|
163
|
+
const key = `${ossParams?.dir}${filename}`;
|
|
164
|
+
formData.set("key", key);
|
|
165
|
+
formData.set("OSSAccessKeyId", ossParams.accessid);
|
|
166
|
+
formData.set("policy", ossParams.policy);
|
|
167
|
+
formData.set("Signature", ossParams.signature);
|
|
168
|
+
if (ossParams.callback) {
|
|
169
|
+
formData.set("callback", ossParams.callback);
|
|
170
|
+
}
|
|
171
|
+
// @ts-ignore
|
|
172
|
+
formData.set("success_action_status", 200);
|
|
173
|
+
formData.set("file", file);
|
|
174
|
+
|
|
175
|
+
if (propOssParams) {
|
|
176
|
+
for (const key in propOssParams) {
|
|
177
|
+
if (Object.hasOwnProperty.call(propOssParams, key)) {
|
|
178
|
+
formData.set(key, propOssParams[key]);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const _axios = opt?.axios || this.axios;
|
|
184
|
+
|
|
185
|
+
return _axios
|
|
186
|
+
.post(ossParams.host, formData, { ...this.axiosConf, ...opt?.axiosConf })
|
|
187
|
+
.then((res) => {
|
|
188
|
+
res.data.data.thumbnailUrl = `${res?.data?.data?.fileUrl}${opt?.thumbnailParams ? isPublicMap[opt?.signatureParams?.isPublic] + opt?.thumbnailParams : ""}`;
|
|
189
|
+
resolve(res);
|
|
190
|
+
return res;
|
|
191
|
+
})
|
|
192
|
+
.catch((err) => {
|
|
193
|
+
console.error("oss upload err", err);
|
|
194
|
+
reject(err);
|
|
195
|
+
return Promise.reject(err);
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export { axios };
|
|
202
|
+
|
|
203
|
+
export default OssUploadUtil;
|