@hzab/form-render 1.6.19 → 1.6.21-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/CHANGELOG.md +9 -1
- package/README.md +29 -21
- package/package.json +3 -2
- package/src/components/TreeCheckbox/components/CheckboxTable/index.tsx +10 -4
- package/src/components/TreeCheckbox/components/Render/index.tsx +28 -28
- package/src/components/TreeCheckbox/components/TabsRender/index.tsx +10 -7
- package/src/components/TreeCheckbox/index.less +6 -0
- package/src/components/Upload/common/OfflineUpload.ts +2 -336
- package/src/components/Upload/common/fileName.ts +3 -3
- package/src/components/Upload/common/handleIOFileList.ts +2 -2
- package/src/components/Upload/common/nanoid.ts +4 -6
- package/src/components/Upload/common/ossUpload.js +6 -106
- package/src/components/Upload/common/utils.js +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
+
# @hzab/form-render@1.6.21
|
|
2
|
+
|
|
3
|
+
refactor: upload 接入 utils upload utils
|
|
4
|
+
|
|
5
|
+
# @hzab/form-render@1.6.20
|
|
6
|
+
|
|
7
|
+
feat: 新增 TreeCheckbox 的 readOnly 属性
|
|
8
|
+
|
|
1
9
|
# @hzab/form-render@1.6.19
|
|
2
10
|
|
|
3
|
-
fix: 搜索新增时在搜索项切换地址异常问题修复
|
|
11
|
+
fix: LocationListPicker 搜索新增时在搜索项切换地址异常问题修复
|
|
4
12
|
|
|
5
13
|
# @hzab/form-render@1.6.18
|
|
6
14
|
|
package/README.md
CHANGED
|
@@ -116,18 +116,18 @@ import FormRender from "@hzab/form-render";
|
|
|
116
116
|
|
|
117
117
|
### InfoPanel Attributes
|
|
118
118
|
|
|
119
|
-
| 参数 | 类型 | 必填 | 默认值 | 说明
|
|
120
|
-
| ------------------ | -------- | ---- | ---------- |
|
|
121
|
-
| schema | Object | 是 | - | 数据信息的 schema
|
|
122
|
-
| schemaScope | Object | 否 | - | 全局作用域,用于实现协议表达式变量注入
|
|
123
|
-
| layout | Object | 否 | horizontal | 表单布局,horizontal vertical \ inline
|
|
124
|
-
| initialValues | Object | 否 | - | form 初始值
|
|
125
|
-
| components | Object | 否 | - | 自定义组件
|
|
126
|
-
| formOptions | Object | 否 | - | createForm 的参数
|
|
127
|
-
| disabled | boolean | 否 | - | 禁用状态
|
|
128
|
-
| readOnly | boolean | 否 | - | 只读状态
|
|
129
|
-
| onFormValuesChange | Function | 否 | - | 表单事件 (form)=>{}
|
|
130
|
-
| onFieldValueChange | Function | 否 | - | 表单项事件 (field, form)=>{} https://core.formilyjs.org/zh-CN/api/entry/field-effect-hooks
|
|
119
|
+
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
|
120
|
+
| ------------------ | -------- | ---- | ---------- | ------------------------------------------------------------------------------------------ |
|
|
121
|
+
| schema | Object | 是 | - | 数据信息的 schema |
|
|
122
|
+
| schemaScope | Object | 否 | - | 全局作用域,用于实现协议表达式变量注入 |
|
|
123
|
+
| layout | Object | 否 | horizontal | 表单布局,horizontal vertical \ inline |
|
|
124
|
+
| initialValues | Object | 否 | - | form 初始值 |
|
|
125
|
+
| components | Object | 否 | - | 自定义组件 |
|
|
126
|
+
| formOptions | Object | 否 | - | createForm 的参数 |
|
|
127
|
+
| disabled | boolean | 否 | - | 禁用状态 |
|
|
128
|
+
| readOnly | boolean | 否 | - | 只读状态 |
|
|
129
|
+
| onFormValuesChange | Function | 否 | - | 表单事件 (form)=>{} https://core.formilyjs.org/zh-CN/api/entry/form-effect-hooks |
|
|
130
|
+
| onFieldValueChange | Function | 否 | - | 表单项事件 (field, form)=>{} https://core.formilyjs.org/zh-CN/api/entry/field-effect-hooks |
|
|
131
131
|
|
|
132
132
|
### 方法 Methods
|
|
133
133
|
|
|
@@ -209,30 +209,38 @@ import FormRender from "@hzab/form-render";
|
|
|
209
209
|
|
|
210
210
|
- example 本地测试代码
|
|
211
211
|
- src 组件源码
|
|
212
|
-
- lib 组件打包编译后的代码
|
|
213
212
|
|
|
214
213
|
## 命令
|
|
215
214
|
|
|
215
|
+
- 生成文档:npm run docs
|
|
216
216
|
- 本地运行:npm run dev
|
|
217
|
-
-
|
|
218
|
-
- 生产环境打包编译:npm run build
|
|
217
|
+
- 打包编译:npm run build
|
|
219
218
|
|
|
220
219
|
## 发布
|
|
221
220
|
|
|
222
|
-
-
|
|
223
|
-
|
|
221
|
+
- npm 源和云效源都需要发布
|
|
222
|
+
|
|
224
223
|
- 命令:npm publish --access public
|
|
225
224
|
- 发布目录:
|
|
226
|
-
- lib
|
|
227
225
|
- src
|
|
228
226
|
|
|
227
|
+
### nrm
|
|
228
|
+
|
|
229
|
+
- 安装
|
|
230
|
+
npm install -g nrm
|
|
231
|
+
- 增加源
|
|
232
|
+
nrm add aliyun https://packages.aliyun.com/62046985b3ead41b374a17f7/npm/npm-registry/
|
|
233
|
+
- 切换源
|
|
234
|
+
nrm use aliyun
|
|
235
|
+
nrm use npm
|
|
236
|
+
- 登录(账号密码在 https://packages.aliyun.com/npm/npm-registry/guide 查看)
|
|
237
|
+
npm login --registry=https://packages.aliyun.com/62046985b3ead41b374a17f7/npm/npm-registry/
|
|
238
|
+
|
|
229
239
|
## 配置
|
|
230
240
|
|
|
231
241
|
### 配置文件
|
|
232
242
|
|
|
233
|
-
- 本地配置文件:config/
|
|
234
|
-
- 测试环境配置文件:config/global-config/config.flowDev.js
|
|
235
|
-
- 生产环境配置文件:config/global-config/config.production.js
|
|
243
|
+
- 本地配置文件:config/config.js
|
|
236
244
|
|
|
237
245
|
### webpack 配置文件
|
|
238
246
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hzab/form-render",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.21-beta",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "src",
|
|
6
6
|
"scripts": {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"author": "CaiYansong",
|
|
20
20
|
"license": "ISC",
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@hzab/data-model": "^1.
|
|
22
|
+
"@hzab/data-model": "^1.8.8",
|
|
23
23
|
"@hzab/permissions": "^0.1.1",
|
|
24
24
|
"@hzab/webpack-config": "0.0.12",
|
|
25
25
|
"@types/react": "^17.0.62",
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"@formily/core": "2.3.1",
|
|
45
45
|
"@formily/react": "2.3.1",
|
|
46
46
|
"@formily/reactive-react": "2.3.1",
|
|
47
|
+
"@hzab/utils": "^1.0.4",
|
|
47
48
|
"@turf/turf": "^6.5.0",
|
|
48
49
|
"@wangeditor/editor": "^5.1.23",
|
|
49
50
|
"@wangeditor/editor-for-react": "^1.0.6",
|
|
@@ -26,20 +26,26 @@ export const CheckboxTable = (props) => {
|
|
|
26
26
|
{col?.map((it, itIdx) => {
|
|
27
27
|
const itKey = it?.value;
|
|
28
28
|
return (
|
|
29
|
-
it &&
|
|
29
|
+
it &&
|
|
30
|
+
(it?.readOnly ? (
|
|
31
|
+
<span className="tree-checkbox-read-only">{it.label}</span>
|
|
32
|
+
) : (
|
|
30
33
|
<Checkbox onChange={onChange} value={itKey} key={itKey}>
|
|
31
34
|
{it.label}
|
|
32
35
|
</Checkbox>
|
|
33
|
-
)
|
|
36
|
+
))
|
|
34
37
|
);
|
|
35
38
|
})}
|
|
36
39
|
</>
|
|
37
40
|
) : (
|
|
38
|
-
col &&
|
|
41
|
+
col &&
|
|
42
|
+
(col?.readOnly ? (
|
|
43
|
+
<span className="tree-checkbox-read-only">{col.label}</span>
|
|
44
|
+
) : (
|
|
39
45
|
<Checkbox onChange={onChange} value={colKey} key={colKey}>
|
|
40
46
|
{col.label}
|
|
41
47
|
</Checkbox>
|
|
42
|
-
)
|
|
48
|
+
))
|
|
43
49
|
)}
|
|
44
50
|
</td>
|
|
45
51
|
);
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import CheckboxTable from "../CheckboxTable";
|
|
2
|
-
|
|
3
|
-
import TabsRender from "../TabsRender";
|
|
4
|
-
|
|
5
|
-
export const Render = (props) => {
|
|
6
|
-
const { list, fieldNames, tabConfList = [], emptyNode = "暂无数据" } = props;
|
|
7
|
-
const { label: labelKey, value: valueKey, children: childrenKey } = fieldNames || {};
|
|
8
|
-
|
|
9
|
-
if (!list) {
|
|
10
|
-
return <div className="tree-checkbox-empty">{emptyNode}</div>;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
return (
|
|
14
|
-
<>
|
|
15
|
-
{list?.map((item, i) => {
|
|
16
|
-
if (item?.tabList) {
|
|
17
|
-
return <TabsRender {...props} key={i} item={item} index={i} />;
|
|
18
|
-
}
|
|
19
|
-
if (item.tableData) {
|
|
20
|
-
return <CheckboxTable key={i} {...props} data={item.tableData || []} />;
|
|
21
|
-
}
|
|
22
|
-
return null;
|
|
23
|
-
})}
|
|
24
|
-
</>
|
|
25
|
-
);
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export default Render;
|
|
1
|
+
import CheckboxTable from "../CheckboxTable";
|
|
2
|
+
|
|
3
|
+
import TabsRender from "../TabsRender";
|
|
4
|
+
|
|
5
|
+
export const Render = (props) => {
|
|
6
|
+
const { list, fieldNames, tabConfList = [], emptyNode = "暂无数据" } = props;
|
|
7
|
+
const { label: labelKey, value: valueKey, children: childrenKey } = fieldNames || {};
|
|
8
|
+
|
|
9
|
+
if (!list) {
|
|
10
|
+
return <div className="tree-checkbox-empty">{emptyNode}</div>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<>
|
|
15
|
+
{list?.map((item, i) => {
|
|
16
|
+
if (item?.tabList) {
|
|
17
|
+
return <TabsRender {...props} key={i} item={item} index={i} />;
|
|
18
|
+
}
|
|
19
|
+
if (item.tableData) {
|
|
20
|
+
return <CheckboxTable key={i} {...props} data={item.tableData || []} />;
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
})}
|
|
24
|
+
</>
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export default Render;
|
|
@@ -36,13 +36,16 @@ export const TabRender = (props) => {
|
|
|
36
36
|
forceRender
|
|
37
37
|
tab={
|
|
38
38
|
<>
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
{!it?.readOnly && (
|
|
40
|
+
<Checkbox
|
|
41
|
+
className="tab-level-checkbox-item"
|
|
42
|
+
value={it[valueKey]}
|
|
43
|
+
onChange={props?.onChange}
|
|
44
|
+
key={it[valueKey]}
|
|
45
|
+
onClick={onStopPropagation}
|
|
46
|
+
></Checkbox>
|
|
47
|
+
)}
|
|
48
|
+
{it[labelKey]}
|
|
46
49
|
</>
|
|
47
50
|
}
|
|
48
51
|
key={"" + it[valueKey]}
|
|
@@ -1,339 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { OfflineUpload } from "@hzab/utils/src/upload/OfflineUpload";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
import { formatDirStr, mergeDirStr } from "./utils";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* 获取上传相关配置入参
|
|
8
|
-
*/
|
|
9
|
-
export interface IGetSignatureOpt {
|
|
10
|
-
/**
|
|
11
|
-
* 配置接口地址
|
|
12
|
-
*/
|
|
13
|
-
serverUrl?: string;
|
|
14
|
-
/**
|
|
15
|
-
* axios 实例
|
|
16
|
-
*/
|
|
17
|
-
axios?: Object;
|
|
18
|
-
/**
|
|
19
|
-
* axios 配置
|
|
20
|
-
*/
|
|
21
|
-
axiosConf?: Object;
|
|
22
|
-
/**
|
|
23
|
-
* 请求入参
|
|
24
|
-
*/
|
|
25
|
-
params?: {
|
|
26
|
-
path?: string;
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface IOfflineUploadProps {
|
|
31
|
-
/**
|
|
32
|
-
* axios 实例
|
|
33
|
-
*/
|
|
34
|
-
axios?: Object;
|
|
35
|
-
/**
|
|
36
|
-
* axios 配置
|
|
37
|
-
*/
|
|
38
|
-
axiosConf?: Object;
|
|
39
|
-
/**
|
|
40
|
-
* 配置接口地址
|
|
41
|
-
*/
|
|
42
|
-
serverUrl?: string;
|
|
43
|
-
/**
|
|
44
|
-
* 获取配置接口请求入参
|
|
45
|
-
*/
|
|
46
|
-
signatureParams?: {
|
|
47
|
-
path?: string;
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* 文件上传入参
|
|
53
|
-
*/
|
|
54
|
-
export interface IUploadOpt {
|
|
55
|
-
/**
|
|
56
|
-
* 配置接口地址
|
|
57
|
-
*/
|
|
58
|
-
serverUrl?: string;
|
|
59
|
-
/**
|
|
60
|
-
* 是否开启 Hash 命名
|
|
61
|
-
*/
|
|
62
|
-
useHashName?: boolean;
|
|
63
|
-
/**
|
|
64
|
-
* 文件上传接口地址
|
|
65
|
-
*/
|
|
66
|
-
uploadUrl?: string;
|
|
67
|
-
/**
|
|
68
|
-
* 获取配置接口请求入参
|
|
69
|
-
*/
|
|
70
|
-
params?: {
|
|
71
|
-
path?: string;
|
|
72
|
-
// 兼容 老数据
|
|
73
|
-
dir?: string;
|
|
74
|
-
};
|
|
75
|
-
/**
|
|
76
|
-
* 文件上传请求入参
|
|
77
|
-
*/
|
|
78
|
-
ossParams?: {
|
|
79
|
-
path?: string;
|
|
80
|
-
// 兼容 老数据
|
|
81
|
-
dir?: string;
|
|
82
|
-
};
|
|
83
|
-
/**
|
|
84
|
-
* axios 实例
|
|
85
|
-
*/
|
|
86
|
-
axios?: Object;
|
|
87
|
-
/**
|
|
88
|
-
* axios 配置
|
|
89
|
-
*/
|
|
90
|
-
axiosConf?: Object;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* 获取上传配置
|
|
95
|
-
* @param opt
|
|
96
|
-
* @returns
|
|
97
|
-
*/
|
|
98
|
-
export function getSignature(opt: IGetSignatureOpt = {}) {
|
|
99
|
-
const { serverUrl = "/api/v1/upload/init" } = opt;
|
|
100
|
-
// 减 10 秒,避免发起请求时 刚好过期的情况
|
|
101
|
-
const { axios: _ax = axios, params = {}, axiosConf } = opt;
|
|
102
|
-
if (
|
|
103
|
-
window._$offlineSignatureRes &&
|
|
104
|
-
window._$offlineSignatureRes.data &&
|
|
105
|
-
serverUrl + JSON.stringify(params) === window._$offlineSignatureRes.serverUrlParams &&
|
|
106
|
-
Date.now() - window._$offlineSignatureRes.__saveTime < window._$offlineSignatureRes.expireTimeMillis - 10000
|
|
107
|
-
) {
|
|
108
|
-
return Promise.resolve(window._$offlineSignatureRes.data);
|
|
109
|
-
}
|
|
110
|
-
// 处理 path 格式,必须为非 / 开头, / 结尾。如: test/
|
|
111
|
-
params.path = formatDirStr(params.path);
|
|
112
|
-
|
|
113
|
-
return _ax
|
|
114
|
-
.post(
|
|
115
|
-
serverUrl,
|
|
116
|
-
{
|
|
117
|
-
...params,
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
...axiosConf,
|
|
121
|
-
},
|
|
122
|
-
)
|
|
123
|
-
.then((res) => {
|
|
124
|
-
if (res?.data?.code === 500) {
|
|
125
|
-
return Promise.reject(res.data);
|
|
126
|
-
}
|
|
127
|
-
if (res?.data?.code === 200) {
|
|
128
|
-
window._$offlineSignatureRes = {
|
|
129
|
-
data: res?.data?.data,
|
|
130
|
-
};
|
|
131
|
-
if (window._$offlineSignatureRes) {
|
|
132
|
-
window._$offlineSignatureRes.__saveTime = Date.now();
|
|
133
|
-
window._$offlineSignatureRes.serverUrlParams = serverUrl + JSON.stringify(params);
|
|
134
|
-
}
|
|
135
|
-
return window._$offlineSignatureRes.data;
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export interface IGetPreviewUrlsOpt {
|
|
141
|
-
previewUrl?: string;
|
|
142
|
-
params?: Object;
|
|
143
|
-
axios?: Object;
|
|
144
|
-
axiosConf?: Object;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* 获取预览地址-批量
|
|
149
|
-
* @param urlList
|
|
150
|
-
* @param opt
|
|
151
|
-
* @returns
|
|
152
|
-
*/
|
|
153
|
-
export const getPreviewUrls = function (urlList, opt: IGetPreviewUrlsOpt = {}) {
|
|
154
|
-
return new Promise(async (resolve, reject) => {
|
|
155
|
-
const { axios: _ax = axios, axiosConf, previewUrl } = opt || {};
|
|
156
|
-
|
|
157
|
-
const _axios = _ax;
|
|
158
|
-
|
|
159
|
-
let _list = urlList;
|
|
160
|
-
if (_list && !Array.isArray(_list)) {
|
|
161
|
-
_list = [_list];
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
return _axios
|
|
165
|
-
.post(previewUrl || "/api/v1/upload/preview", _list, { ...axiosConf })
|
|
166
|
-
.then((res) => {
|
|
167
|
-
if (res?.data?.code == 200) {
|
|
168
|
-
resolve(res?.data?.data);
|
|
169
|
-
} else {
|
|
170
|
-
reject(res);
|
|
171
|
-
}
|
|
172
|
-
return res;
|
|
173
|
-
})
|
|
174
|
-
.catch((err) => {
|
|
175
|
-
console.error("offline upload err", err);
|
|
176
|
-
reject(err);
|
|
177
|
-
return Promise.reject(err);
|
|
178
|
-
});
|
|
179
|
-
});
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* 获取预览地址
|
|
184
|
-
* @param url
|
|
185
|
-
* @param opt
|
|
186
|
-
* @returns
|
|
187
|
-
*/
|
|
188
|
-
export const getPreviewUrl = function (url, opt: IGetPreviewUrlsOpt = {}) {
|
|
189
|
-
return new Promise(async (resolve, reject) => {
|
|
190
|
-
const { axios: _ax = axios, axiosConf, previewUrl } = opt || {};
|
|
191
|
-
|
|
192
|
-
const _axios = _ax;
|
|
193
|
-
|
|
194
|
-
return _axios
|
|
195
|
-
.post(previewUrl || "/api/v1/upload/preview", [url], { ...axiosConf })
|
|
196
|
-
.then((res) => {
|
|
197
|
-
if (res?.data?.code == 200) {
|
|
198
|
-
resolve(res?.data?.data?.[0]);
|
|
199
|
-
} else {
|
|
200
|
-
reject(res);
|
|
201
|
-
}
|
|
202
|
-
return res;
|
|
203
|
-
})
|
|
204
|
-
.catch((err) => {
|
|
205
|
-
console.error("offline upload err", err);
|
|
206
|
-
reject(err);
|
|
207
|
-
return Promise.reject(err);
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
};
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* 私有部署版文件上传
|
|
214
|
-
*/
|
|
215
|
-
export class OfflineUpload {
|
|
216
|
-
axios;
|
|
217
|
-
axiosConf;
|
|
218
|
-
serverUrl;
|
|
219
|
-
signatureParams;
|
|
220
|
-
constructor(props: IOfflineUploadProps = {}) {
|
|
221
|
-
this.axios = props.axios || axios;
|
|
222
|
-
this.axiosConf = props.axiosConf || {};
|
|
223
|
-
this.serverUrl = props.serverUrl || "/api/v1/upload/init";
|
|
224
|
-
this.signatureParams = props.signatureParams || {};
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
getSignature(serverUrl = this.serverUrl, opt) {
|
|
228
|
-
// path 前缀 oss-upload 文件目录
|
|
229
|
-
opt.params.path = mergeDirStr("web-upload/", opt.params.path ?? opt.params.dir);
|
|
230
|
-
return getSignature({
|
|
231
|
-
...opt,
|
|
232
|
-
serverUrl,
|
|
233
|
-
axios: opt?.axios || this.axios,
|
|
234
|
-
axiosConf: { ...this.axiosConf, ...opt?.axiosConf },
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
upload(file, opt: IUploadOpt = {}) {
|
|
239
|
-
return new Promise(async (resolve, reject) => {
|
|
240
|
-
// filename 表示待上传的本地文件名称。
|
|
241
|
-
const filename = getFileNameByFileObj(file, opt);
|
|
242
|
-
try {
|
|
243
|
-
const fileInfo = await this.getSignature(opt.serverUrl || this.serverUrl, {
|
|
244
|
-
...opt,
|
|
245
|
-
params: {
|
|
246
|
-
/** 最终保存的文件名称(不传默认文件名) */
|
|
247
|
-
filename,
|
|
248
|
-
/** 存储路径(不传默认基础路径) */
|
|
249
|
-
path: opt.params?.dir || this.signatureParams?.dir,
|
|
250
|
-
/** 文件存储平台(1、s3,2、本地存储,3、FTP,默认s3) */
|
|
251
|
-
platformCode: undefined,
|
|
252
|
-
...this.signatureParams,
|
|
253
|
-
...opt.params,
|
|
254
|
-
},
|
|
255
|
-
});
|
|
256
|
-
const { uploadUrl, ossParams: propOssParams } = opt || {};
|
|
257
|
-
const formData = new FormData();
|
|
258
|
-
formData.set("fileInfo", fileInfo);
|
|
259
|
-
formData.set("file", file);
|
|
260
|
-
|
|
261
|
-
if (propOssParams) {
|
|
262
|
-
for (const key in propOssParams) {
|
|
263
|
-
if (Object.hasOwnProperty.call(propOssParams, key)) {
|
|
264
|
-
formData.set(key, propOssParams[key]);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
const _axios = opt?.axios || this.axios;
|
|
270
|
-
|
|
271
|
-
return _axios
|
|
272
|
-
.post(uploadUrl || "/api/v1/upload/execute", formData, { ...this.axiosConf, ...opt?.axiosConf })
|
|
273
|
-
.then((res) => {
|
|
274
|
-
if (res?.data?.code == 200) {
|
|
275
|
-
resolve(res?.data?.data);
|
|
276
|
-
} else {
|
|
277
|
-
reject(res);
|
|
278
|
-
}
|
|
279
|
-
return res;
|
|
280
|
-
})
|
|
281
|
-
.catch((err) => {
|
|
282
|
-
console.error("offline upload err", err);
|
|
283
|
-
reject(err);
|
|
284
|
-
return Promise.reject(err);
|
|
285
|
-
});
|
|
286
|
-
} catch (error) {
|
|
287
|
-
reject(error);
|
|
288
|
-
return Promise.reject(error);
|
|
289
|
-
}
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
* 获取预览地址
|
|
295
|
-
* @param urlList
|
|
296
|
-
* @param opt
|
|
297
|
-
* @returns
|
|
298
|
-
*/
|
|
299
|
-
getPreviewUrls(urlList, opt) {
|
|
300
|
-
return getPreviewUrls(urlList, {
|
|
301
|
-
...opt,
|
|
302
|
-
axios: opt?.axios || this.axios,
|
|
303
|
-
axiosConf: { ...this.axiosConf, ...opt?.axiosConf },
|
|
304
|
-
});
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* 批量处理预览地址
|
|
310
|
-
* @param fileList
|
|
311
|
-
* @param opt
|
|
312
|
-
* @returns
|
|
313
|
-
*/
|
|
314
|
-
export const handlePreviewUrls = async function (fileList, opt: IGetPreviewUrlsOpt) {
|
|
315
|
-
const res = await getPreviewUrls(
|
|
316
|
-
fileList?.map((it) => it.storeUrl || it.url),
|
|
317
|
-
{
|
|
318
|
-
...opt,
|
|
319
|
-
},
|
|
320
|
-
);
|
|
321
|
-
|
|
322
|
-
fileList.forEach((it, i) => {
|
|
323
|
-
// TODO: storeUrl 来源于【本地 url 直接使用预览地址,解决 previewFile 无法正常使用 previewUrl 的问题】
|
|
324
|
-
if (!it.storeUrl) {
|
|
325
|
-
it.storeUrl = it.url;
|
|
326
|
-
}
|
|
327
|
-
// TODO: 本地 url 直接使用预览地址,解决 previewFile 无法正常使用 previewUrl 的问题
|
|
328
|
-
it.url = res[i].presignedUrl;
|
|
329
|
-
|
|
330
|
-
// 常规预览地址写法
|
|
331
|
-
it.previewUrl = res[i].presignedUrl;
|
|
332
|
-
if (it.uploadInfo) {
|
|
333
|
-
it.uploadInfo.previewUrl = it.previewUrl;
|
|
334
|
-
}
|
|
335
|
-
});
|
|
336
|
-
return fileList;
|
|
337
|
-
};
|
|
3
|
+
export * from "@hzab/utils/src/upload/OfflineUpload";
|
|
338
4
|
|
|
339
5
|
export default OfflineUpload;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { nanoidNumALetters } from "./nanoid";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* 获取文件后缀
|
|
@@ -72,7 +72,7 @@ export const mergeFileName = function (fileName, str = "") {
|
|
|
72
72
|
* @returns
|
|
73
73
|
*/
|
|
74
74
|
export const getUFileName = function (fileName) {
|
|
75
|
-
return mergeFileName(getFileName(fileName) || "rc-upload", "-" + `~kid-${
|
|
75
|
+
return mergeFileName(getFileName(fileName) || "rc-upload", "-" + `~kid-${nanoidNumALetters()}~` + `${Date.now()}`);
|
|
76
76
|
};
|
|
77
77
|
|
|
78
78
|
/**
|
|
@@ -88,7 +88,7 @@ export const getFileNameByFileObj = (file, opt: any) => {
|
|
|
88
88
|
return _fileName;
|
|
89
89
|
}
|
|
90
90
|
// id、时间、文件类型
|
|
91
|
-
const id = file.id || file.uid ||
|
|
91
|
+
const id = file.id || file.uid || nanoidNumALetters();
|
|
92
92
|
return mergeFileName(
|
|
93
93
|
_fileName,
|
|
94
94
|
"-" +
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getFileURL, getFileType, isBase64Str } from "./utils";
|
|
2
2
|
import { getUFileName, getFileName, getFullFileName, getFileExt, getFileNameObj } from "./fileName";
|
|
3
|
-
import {
|
|
3
|
+
import { nanoidNumALetters } from "./nanoid";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* 出入参归一化
|
|
@@ -218,7 +218,7 @@ export const handleInputItem = (data, opt: IHandlerOpt) => {
|
|
|
218
218
|
}
|
|
219
219
|
if (!file.id) {
|
|
220
220
|
file.id =
|
|
221
|
-
file.uid || `${getFileName(file.url || file.name || file.filename) || "rc-upload"}-${Date.now()}-${
|
|
221
|
+
file.uid || `${getFileName(file.url || file.name || file.filename) || "rc-upload"}-${Date.now()}-${nanoidNumALetters()}`;
|
|
222
222
|
}
|
|
223
223
|
if (!file.name) {
|
|
224
224
|
file.name = file.id;
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* 指定 nanoid 字符集合
|
|
4
|
-
*/
|
|
5
|
-
export const alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
1
|
+
export * from "@hzab/utils/src/nanoid";
|
|
6
2
|
|
|
7
|
-
|
|
3
|
+
import { nanoidNumALetters } from "@hzab/utils/src/nanoid";
|
|
4
|
+
|
|
5
|
+
export const nanoid = nanoidNumALetters;
|
|
@@ -1,106 +1,5 @@
|
|
|
1
|
-
import { axios } from "@hzab/
|
|
2
|
-
|
|
3
|
-
import { formatDirStr, mergeDirStr } from "./utils";
|
|
4
|
-
|
|
5
|
-
export function getSignature(opt = {}) {
|
|
6
|
-
const { serverUrl = "/api/v1/user/oss/getWebOssConfig" } = opt;
|
|
7
|
-
// 减 10 秒,避免发起请求时 刚好过期的情况
|
|
8
|
-
if (
|
|
9
|
-
window.__ossSignatureRes &&
|
|
10
|
-
serverUrl === window.__ossSignatureRes.serverUrl &&
|
|
11
|
-
Date.now() - window.__ossSignatureRes.__saveTime < window.__ossSignatureRes.expireTimeMillis - 10000
|
|
12
|
-
) {
|
|
13
|
-
return Promise.resolve(window.__ossSignatureRes);
|
|
14
|
-
}
|
|
15
|
-
const { axios: _ax = axios, params = {}, axiosConf } = opt;
|
|
16
|
-
// 处理 dir 格式,必须为非 / 开头, / 结尾。如: test/
|
|
17
|
-
params.dir = formatDirStr(params.dir);
|
|
18
|
-
|
|
19
|
-
return _ax
|
|
20
|
-
.get(serverUrl, {
|
|
21
|
-
...axiosConf,
|
|
22
|
-
params: {
|
|
23
|
-
isPublic: 1,
|
|
24
|
-
...params,
|
|
25
|
-
},
|
|
26
|
-
})
|
|
27
|
-
.then((res) => {
|
|
28
|
-
window.__ossSignatureRes = res?.data?.data ?? res?.data ?? res;
|
|
29
|
-
if (window.__ossSignatureRes) {
|
|
30
|
-
window.__ossSignatureRes.__saveTime = Date.now();
|
|
31
|
-
window.__ossSignatureRes.serverUrl = serverUrl;
|
|
32
|
-
}
|
|
33
|
-
return window.__ossSignatureRes;
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
class OssUpload {
|
|
38
|
-
constructor(props = {}) {
|
|
39
|
-
this.axios = props.axios || axios;
|
|
40
|
-
this.axiosConf = props.axiosConf || {};
|
|
41
|
-
this.serverUrl = props.serverUrl || "/api/v1/user/oss/getWebOssConfig";
|
|
42
|
-
this.signatureParams = props.signatureParams || {};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
getSignature(serverUrl = this.serverUrl, opt) {
|
|
46
|
-
// dir 前缀 oss-upload 文件目录
|
|
47
|
-
opt.params.dir = mergeDirStr("web-upload/", opt.params.dir);
|
|
48
|
-
return getSignature({
|
|
49
|
-
...opt,
|
|
50
|
-
serverUrl,
|
|
51
|
-
axios: opt?.axios || this.axios,
|
|
52
|
-
axiosConf: { ...this.axiosConf, ...opt?.axiosConf },
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
upload(file, opt = {}) {
|
|
57
|
-
|
|
58
|
-
return new Promise(async (resolve, reject) => {
|
|
59
|
-
const ossParams = await this.getSignature(opt.serverUrl || this.serverUrl, {
|
|
60
|
-
...opt,
|
|
61
|
-
params: { ...this.signatureParams, ...opt.params },
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
const { ossParams: propOssParams, useHashName } = opt || {};
|
|
65
|
-
const formData = new FormData();
|
|
66
|
-
// key 表示上传到 Bucket 内的 Object 的完整路径,例如 exampledir/exampleobject.txtObject,完整路径中不能包含 Bucket 名称。
|
|
67
|
-
// filename 表示待上传的本地文件名称。
|
|
68
|
-
const filename = getFileNameByFileObj(file, opt);
|
|
69
|
-
const key = `${ossParams?.dir}${filename}`;
|
|
70
|
-
formData.set("key", key);
|
|
71
|
-
formData.set("OSSAccessKeyId", ossParams.accessid);
|
|
72
|
-
formData.set("policy", ossParams.policy);
|
|
73
|
-
formData.set("Signature", ossParams.signature);
|
|
74
|
-
if (ossParams.callback) {
|
|
75
|
-
formData.set("callback", ossParams.callback);
|
|
76
|
-
}
|
|
77
|
-
formData.set("success_action_status", 200);
|
|
78
|
-
formData.set("file", file);
|
|
79
|
-
|
|
80
|
-
if (propOssParams) {
|
|
81
|
-
for (const key in propOssParams) {
|
|
82
|
-
if (Object.hasOwnProperty.call(propOssParams, key)) {
|
|
83
|
-
formData.set(key, propOssParams[key]);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const _axios = opt?.axios || this.axios;
|
|
89
|
-
|
|
90
|
-
return _axios
|
|
91
|
-
.post(ossParams.host, formData, { ...this.axiosConf, ...opt?.axiosConf })
|
|
92
|
-
.then((res) => {
|
|
93
|
-
resolve(res);
|
|
94
|
-
return res;
|
|
95
|
-
})
|
|
96
|
-
.catch((err) => {
|
|
97
|
-
console.error("oss upload err", err);
|
|
98
|
-
reject(err);
|
|
99
|
-
return Promise.reject(err);
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
}
|
|
1
|
+
import { axios, getSignature, OssUploadUtil } from "@hzab/utils/src/upload/OssUploadUtil";
|
|
2
|
+
console.log('OssUploadUtil', OssUploadUtil);
|
|
104
3
|
|
|
105
4
|
/**
|
|
106
5
|
* 处理文件上传逻辑
|
|
@@ -111,7 +10,8 @@ class OssUpload {
|
|
|
111
10
|
export async function handleOssUpload(files, opt) {
|
|
112
11
|
const _files = files;
|
|
113
12
|
const { ossUrl, signatureParams, ossParams, axiosConf, useHashName } = opt || {};
|
|
114
|
-
const ossUpload = new
|
|
13
|
+
const ossUpload = new OssUploadUtil({
|
|
14
|
+
...opt,
|
|
115
15
|
axios: opt.axios,
|
|
116
16
|
axiosConf: axiosConf,
|
|
117
17
|
serverUrl: ossUrl || "/api/v1/user/oss/getWebOssConfig",
|
|
@@ -154,6 +54,6 @@ export async function handleOssUpload(files, opt) {
|
|
|
154
54
|
});
|
|
155
55
|
}
|
|
156
56
|
|
|
157
|
-
export { axios };
|
|
57
|
+
export { axios, getSignature };
|
|
158
58
|
|
|
159
|
-
export default
|
|
59
|
+
export default OssUploadUtil;
|