xianniu-ui 0.8.52 → 0.8.54
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/lib/xianniu-ui.common.js +199 -161
- package/lib/xianniu-ui.umd.js +199 -161
- package/lib/xianniu-ui.umd.min.js +2 -2
- package/package.json +1 -1
- package/packages/upload/main.vue +37 -12
- package/src/oss/index.js +102 -95
package/package.json
CHANGED
package/packages/upload/main.vue
CHANGED
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
v-bind="$attrs"
|
|
14
14
|
:file-list.sync="fileList"
|
|
15
15
|
:http-request="onHttpUpload"
|
|
16
|
-
:on-error="onError"
|
|
17
16
|
:before-upload="onBeforeUpload"
|
|
18
17
|
:style="{ ...styles, ...idCardSizeData }"
|
|
19
18
|
:on-exceed="onExceed"
|
|
@@ -38,7 +37,13 @@
|
|
|
38
37
|
</slot>
|
|
39
38
|
</template>
|
|
40
39
|
|
|
41
|
-
<div
|
|
40
|
+
<div
|
|
41
|
+
slot="file"
|
|
42
|
+
slot-scope="{ file }"
|
|
43
|
+
:class="{
|
|
44
|
+
'xn-upload--slot': ['picture-card', 'idcard'].includes(listType),
|
|
45
|
+
}"
|
|
46
|
+
>
|
|
42
47
|
<template v-if="['list'].includes(listType)">
|
|
43
48
|
<a
|
|
44
49
|
class="el-upload-list__item-name"
|
|
@@ -89,6 +94,7 @@
|
|
|
89
94
|
</template>
|
|
90
95
|
<template v-if="['picture-card', 'idcard'].includes(listType)">
|
|
91
96
|
<uploadPop :file="file" @on-download="handleDownload(file)"></uploadPop>
|
|
97
|
+
<div v-if="file.status === 'fail'">失败</div>
|
|
92
98
|
<template v-if="$utils.isImg(file)">
|
|
93
99
|
<el-image
|
|
94
100
|
class="el-upload-list__item-thumbnail"
|
|
@@ -245,7 +251,6 @@ export default {
|
|
|
245
251
|
imageView: "",
|
|
246
252
|
isHidden: false,
|
|
247
253
|
viewList: [],
|
|
248
|
-
files: [],
|
|
249
254
|
successFiles: [],
|
|
250
255
|
isUploading: false,
|
|
251
256
|
file: {},
|
|
@@ -254,6 +259,8 @@ export default {
|
|
|
254
259
|
idCardSizeData: {},
|
|
255
260
|
isShowAV: false,
|
|
256
261
|
avUrl: "",
|
|
262
|
+
realFileList: [],
|
|
263
|
+
reUploadFile: {},
|
|
257
264
|
};
|
|
258
265
|
},
|
|
259
266
|
computed: {
|
|
@@ -265,11 +272,14 @@ export default {
|
|
|
265
272
|
fileSize() {
|
|
266
273
|
return this.$format.bytesToSize(this.file.size);
|
|
267
274
|
},
|
|
275
|
+
isMultiple() {
|
|
276
|
+
return this.$attrs.multiple;
|
|
277
|
+
},
|
|
268
278
|
},
|
|
269
279
|
watch: {
|
|
270
280
|
fileList: {
|
|
271
281
|
handler(n) {
|
|
272
|
-
this.successFiles = n;
|
|
282
|
+
// this.successFiles = n;
|
|
273
283
|
this.isHidden = this.limit === n.length;
|
|
274
284
|
},
|
|
275
285
|
immediate: true,
|
|
@@ -344,29 +354,44 @@ export default {
|
|
|
344
354
|
});
|
|
345
355
|
},
|
|
346
356
|
onChange(file, fileList) {
|
|
347
|
-
this.
|
|
357
|
+
this.realFileList = fileList;
|
|
348
358
|
},
|
|
349
359
|
async onHttpUpload(file) {
|
|
360
|
+
this.handleUpload(file);
|
|
361
|
+
},
|
|
362
|
+
handleUpload(file) {
|
|
350
363
|
this.isUploading = true;
|
|
351
364
|
this.$emit("on-uploaded", false);
|
|
352
365
|
this.oss
|
|
353
366
|
.upload(file)
|
|
354
367
|
.then((res) => {
|
|
355
368
|
this.successFiles.push(res);
|
|
356
|
-
|
|
369
|
+
|
|
370
|
+
this.realFileList.forEach((item) => {
|
|
371
|
+
if (item.uid === res.file.uid) {
|
|
372
|
+
const obj = JSON.parse(JSON.stringify(res));
|
|
373
|
+
delete obj.file;
|
|
374
|
+
item = Object.assign(item, obj);
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
this.$emit("update:fileList", this.realFileList);
|
|
357
379
|
this.$emit("on-file", this.res);
|
|
358
380
|
this.$emit("on-success", this.successFiles);
|
|
359
381
|
this.$emit("on-uploaded", true);
|
|
360
382
|
this.isUploading = false;
|
|
361
383
|
})
|
|
362
|
-
.catch(() => {
|
|
363
|
-
this.$
|
|
384
|
+
.catch(({fileName}) => {
|
|
385
|
+
this.$notify.error({
|
|
386
|
+
title: "上传失败",
|
|
387
|
+
dangerouslyUseHTMLString: true,
|
|
388
|
+
message:`<div><p>文件名:</p>${fileName}</div>`,
|
|
389
|
+
});
|
|
364
390
|
});
|
|
365
391
|
},
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
},
|
|
392
|
+
// onError() {
|
|
393
|
+
// this.$message.error("上传失败,请重试");
|
|
394
|
+
// },
|
|
370
395
|
onSubmitUpload() {
|
|
371
396
|
this.$refs.upload.submit();
|
|
372
397
|
},
|
package/src/oss/index.js
CHANGED
|
@@ -1,130 +1,137 @@
|
|
|
1
|
-
const OSS = require('ali-oss')
|
|
2
|
-
import $dayjs from '@/utils/dayjs'
|
|
1
|
+
const OSS = require('ali-oss');
|
|
2
|
+
import $dayjs from '@/utils/dayjs';
|
|
3
3
|
const { v4: uuidv4 } = require('uuid');
|
|
4
|
+
|
|
4
5
|
class Client {
|
|
5
6
|
constructor(params = {}) {
|
|
6
|
-
this.uploadHost = null
|
|
7
|
-
this.stsUrl = params.stsUrl || ''
|
|
8
|
-
this.setFileIdUrl = params.setFileIdUrl || ''
|
|
9
|
-
this.oss = null
|
|
7
|
+
this.uploadHost = null;
|
|
8
|
+
this.stsUrl = params.stsUrl || '';
|
|
9
|
+
this.setFileIdUrl = params.setFileIdUrl || '';
|
|
10
|
+
this.oss = null;
|
|
10
11
|
}
|
|
12
|
+
|
|
11
13
|
getToken() {
|
|
12
|
-
const _token = localStorage.getItem('xnToken')
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
const _token = localStorage.getItem('xnToken');
|
|
15
|
+
if (!_token) return '';
|
|
16
|
+
|
|
17
|
+
const isQuotedString = /^".*"$/.test(_token);
|
|
18
|
+
try {
|
|
19
|
+
if (isQuotedString) {
|
|
20
|
+
return _token.slice(1, -1);
|
|
21
|
+
} else {
|
|
22
|
+
return JSON.parse(_token);
|
|
19
23
|
}
|
|
24
|
+
} catch (error) {
|
|
25
|
+
console.error('Failed to parse token:', error);
|
|
26
|
+
return _token;
|
|
20
27
|
}
|
|
21
|
-
return token
|
|
22
28
|
}
|
|
29
|
+
|
|
23
30
|
getExt(file) {
|
|
24
|
-
|
|
25
|
-
// 判断上传格式
|
|
26
|
-
return `${fileExt}`.toLowerCase();
|
|
31
|
+
return file.name.split('.').pop().toLowerCase();
|
|
27
32
|
}
|
|
33
|
+
|
|
28
34
|
isImg(file) {
|
|
29
|
-
return file.type.
|
|
35
|
+
return file.type.startsWith('image');
|
|
30
36
|
}
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
|
|
38
|
+
isAV(file) {
|
|
39
|
+
return file.type.startsWith('audio') || file.type.startsWith('video');
|
|
33
40
|
}
|
|
41
|
+
|
|
34
42
|
getFileNameUUID() {
|
|
35
|
-
|
|
36
|
-
return uuid
|
|
43
|
+
return uuidv4();
|
|
37
44
|
}
|
|
38
|
-
getStsToken(file) {
|
|
39
|
-
return new Promise((resolve, reject) => {
|
|
40
|
-
if (!this.stsUrl) {
|
|
41
|
-
console.error('获取临时凭证地址不能为空');
|
|
42
|
-
file.onError()
|
|
43
|
-
return
|
|
44
|
-
}
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
46
|
+
async getStsToken(file) {
|
|
47
|
+
if (!this.stsUrl) {
|
|
48
|
+
console.error('获取临时凭证地址不能为空');
|
|
49
|
+
file.onError();
|
|
50
|
+
return Promise.reject('获取临时凭证地址不能为空');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
const response = await fetch(this.stsUrl + '?xnToken=' + this.getToken());
|
|
55
|
+
const res = await response.json();
|
|
56
|
+
const { accessKeyId, accessKeySecret, securityToken: stsToken, uploadHost, bucket, region } = res.data;
|
|
57
|
+
this.uploadHost = uploadHost;
|
|
58
|
+
this.oss = new OSS({
|
|
59
|
+
accessKeyId,
|
|
60
|
+
accessKeySecret,
|
|
61
|
+
stsToken,
|
|
62
|
+
bucket,
|
|
63
|
+
region
|
|
64
|
+
});
|
|
65
|
+
return this;
|
|
66
|
+
} catch (err) {
|
|
67
|
+
console.error('获取临时凭证失败:', err);
|
|
68
|
+
file.onError();
|
|
69
|
+
return Promise.reject(err);
|
|
70
|
+
}
|
|
66
71
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
72
|
+
|
|
73
|
+
async setFileId(params) {
|
|
74
|
+
try {
|
|
75
|
+
const response = await fetch(this.setFileIdUrl, {
|
|
70
76
|
method: 'POST',
|
|
71
77
|
headers: {
|
|
72
78
|
'Content-Type': 'application/json',
|
|
73
79
|
'xnToken': this.getToken()
|
|
74
80
|
},
|
|
75
81
|
body: JSON.stringify(params)
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
})
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
if (!response.ok) {
|
|
85
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const { data } = await response.json();
|
|
89
|
+
return data;
|
|
90
|
+
} catch (err) {
|
|
91
|
+
console.error('设置文件ID失败:', err);
|
|
92
|
+
return Promise.reject(err);
|
|
93
|
+
}
|
|
89
94
|
}
|
|
95
|
+
|
|
90
96
|
upload(file, headers = {}) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
97
|
+
// eslint-disable-next-line no-async-promise-executor
|
|
98
|
+
return new Promise(async (resolve, reject) => {
|
|
99
|
+
const currentFile = file.file;
|
|
100
|
+
const fileName = currentFile.name;
|
|
101
|
+
const newFileName = this.getFileNameUUID() + '.' + this.getExt(currentFile);
|
|
102
|
+
const path = `accessory/${$dayjs().format('YYYY/MM/DD')}/`;
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
await this.getStsToken(file);
|
|
106
|
+
const res = await this.oss.multipartUpload(path + newFileName, currentFile, {
|
|
107
|
+
...headers,
|
|
108
|
+
progress: (p) => {
|
|
109
|
+
const _progress = parseFloat(p * 100);
|
|
110
|
+
file.onProgress({ percent: _progress });
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const fileObj = {
|
|
105
115
|
name: fileName,
|
|
106
116
|
size: currentFile.size,
|
|
107
117
|
ext: this.getExt(currentFile),
|
|
108
|
-
imgFlag:
|
|
109
|
-
isAV:
|
|
118
|
+
imgFlag: Number(this.isImg(currentFile)),
|
|
119
|
+
isAV: Number(this.isAV(currentFile)),
|
|
110
120
|
url: this.uploadHost + res.name,
|
|
111
121
|
accessoryName: fileName,
|
|
112
122
|
accessorySize: currentFile.size
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}).catch(err => {
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const fileIdResponse = await this.setFileId(fileObj);
|
|
126
|
+
file.onSuccess();
|
|
127
|
+
resolve({ ...fileObj, fileId: fileIdResponse.fileId, file: currentFile });
|
|
128
|
+
} catch (err) {
|
|
129
|
+
console.error('上传文件失败:', err);
|
|
122
130
|
file.onError();
|
|
123
|
-
reject(err)
|
|
124
|
-
}
|
|
125
|
-
})
|
|
131
|
+
reject({ file, fileName, err });
|
|
132
|
+
}
|
|
133
|
+
});
|
|
126
134
|
}
|
|
127
135
|
}
|
|
128
136
|
|
|
129
|
-
|
|
130
|
-
export default Client
|
|
137
|
+
export default Client;
|