xianniu-ui 0.9.13 → 2.0.1
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/style/basic.css +1 -1
- package/lib/style/ellipsis.css +1 -1
- package/lib/style/fonts/element-icons.ttf +0 -0
- package/lib/style/fonts/element-icons.woff +0 -0
- package/lib/style/index.css +1 -0
- package/lib/style/index.js +1 -0
- package/lib/style/page.css +1 -0
- package/lib/style/search.css +1 -0
- package/lib/style/table.css +1 -0
- package/lib/style/tag.css +1 -0
- package/lib/style/theme/element-variables.scss +13 -11
- package/lib/style/theme/theme.scss +5 -4
- package/lib/style/tip.css +1 -0
- package/lib/style/tree.css +1 -0
- package/lib/style/upload.css +1 -0
- package/lib/xianniu-ui.common.js +19609 -69544
- package/lib/xianniu-ui.css +1 -1
- package/lib/xianniu-ui.umd.js +19614 -69549
- package/lib/xianniu-ui.umd.min.js +2 -72
- package/package.json +20 -12
- package/packages/card/main.vue +1 -1
- package/packages/page/main.vue +2 -2
- package/packages/search/main.vue +391 -293
- package/packages/style/gulpfile.js +6 -6
- package/packages/style/src/index.scss +3 -5
- package/packages/style/src/search.scss +127 -15
- package/packages/style/src/theme/element-variables.scss +13 -11
- package/packages/style/src/theme/theme.scss +5 -4
- package/packages/style/src/upload.scss +47 -8
- package/packages/table/main.vue +84 -34
- package/packages/tag/main.vue +1 -1
- package/packages/upload/main.vue +165 -35
- package/src/area/data.js +3890 -0
- package/src/area/index.js +71 -1
- package/src/oss/index.js +93 -60
- package/src/plugins/index.js +5 -2
package/src/oss/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
const OSS = require('ali-oss');
|
|
2
2
|
import $dayjs from '@/utils/dayjs';
|
|
3
|
-
const { v4: uuidv4 } = require('uuid');
|
|
4
3
|
|
|
5
4
|
class Client {
|
|
6
5
|
constructor(params = {}) {
|
|
@@ -14,15 +13,11 @@ class Client {
|
|
|
14
13
|
const _token = localStorage.getItem('xnToken');
|
|
15
14
|
if (!_token) return '';
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
} catch (error) {
|
|
22
|
-
token = _token
|
|
23
|
-
}
|
|
16
|
+
try {
|
|
17
|
+
return JSON.parse(_token);
|
|
18
|
+
} catch (error) {
|
|
19
|
+
return _token;
|
|
24
20
|
}
|
|
25
|
-
return token
|
|
26
21
|
}
|
|
27
22
|
|
|
28
23
|
getExt(file) {
|
|
@@ -37,34 +32,72 @@ class Client {
|
|
|
37
32
|
return file.type.startsWith('audio') || file.type.startsWith('video');
|
|
38
33
|
}
|
|
39
34
|
|
|
40
|
-
|
|
41
|
-
|
|
35
|
+
generateFileName(originalName) {
|
|
36
|
+
const random = Math.random().toString(36).substring(2, 8);
|
|
37
|
+
const ext = this.getExt({ name: originalName });
|
|
38
|
+
const nameWithoutExt = originalName.substring(0, originalName.lastIndexOf('.'));
|
|
39
|
+
// 清理文件名中的特殊字符,保留中文、字母、数字、下划线和连字符
|
|
40
|
+
const cleanName = nameWithoutExt.replace(/[^\u4e00-\u9fa5a-zA-Z0-9_-]/g, '_');
|
|
41
|
+
return `${cleanName}_${random}.${ext}`;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
async getStsToken(
|
|
44
|
+
async getStsToken() {
|
|
45
45
|
if (!this.stsUrl) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
const error = new Error('获取临时凭证地址不能为空');
|
|
47
|
+
// eslint-disable-next-line no-console
|
|
48
|
+
console.error(error.message);
|
|
49
|
+
throw error;
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
try {
|
|
52
|
-
const response = await fetch(this.stsUrl
|
|
53
|
+
const response = await fetch(this.stsUrl, {
|
|
54
|
+
headers: {
|
|
55
|
+
'xnToken': this.getToken()
|
|
56
|
+
}
|
|
57
|
+
});
|
|
53
58
|
const res = await response.json();
|
|
54
59
|
const { accessKeyId, accessKeySecret, securityToken: stsToken, uploadHost, bucket, region } = res.data;
|
|
55
60
|
this.uploadHost = uploadHost;
|
|
61
|
+
|
|
62
|
+
// 保存当前的凭证信息,用于自动刷新
|
|
63
|
+
this.currentCredentials = { accessKeyId, accessKeySecret, stsToken, bucket, region };
|
|
64
|
+
|
|
56
65
|
this.oss = new OSS({
|
|
57
66
|
accessKeyId,
|
|
58
67
|
accessKeySecret,
|
|
59
68
|
stsToken,
|
|
60
69
|
bucket,
|
|
61
|
-
region
|
|
70
|
+
region,
|
|
71
|
+
// 配置自动刷新STS Token
|
|
72
|
+
refreshSTSToken: async () => {
|
|
73
|
+
try {
|
|
74
|
+
const response = await fetch(this.stsUrl, {
|
|
75
|
+
headers: {
|
|
76
|
+
'xnToken': this.getToken()
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
const res = await response.json();
|
|
80
|
+
const { accessKeyId, accessKeySecret, securityToken: stsToken } = res.data;
|
|
81
|
+
return {
|
|
82
|
+
accessKeyId,
|
|
83
|
+
accessKeySecret,
|
|
84
|
+
stsToken
|
|
85
|
+
};
|
|
86
|
+
} catch (err) {
|
|
87
|
+
// eslint-disable-next-line no-console
|
|
88
|
+
console.error('刷新STS Token失败:', err);
|
|
89
|
+
throw err;
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
// STS Token刷新间隔(毫秒),默认在过期前5分钟刷新
|
|
93
|
+
refreshSTSTokenInterval: 300000 // 5分钟
|
|
62
94
|
});
|
|
63
95
|
return this;
|
|
64
96
|
} catch (err) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
97
|
+
const error = new Error(`获取临时凭证失败: ${err.message}`);
|
|
98
|
+
// eslint-disable-next-line no-console
|
|
99
|
+
console.error(error.message, err);
|
|
100
|
+
throw error;
|
|
68
101
|
}
|
|
69
102
|
}
|
|
70
103
|
|
|
@@ -86,49 +119,49 @@ class Client {
|
|
|
86
119
|
const { data } = await response.json();
|
|
87
120
|
return data;
|
|
88
121
|
} catch (err) {
|
|
89
|
-
|
|
90
|
-
|
|
122
|
+
const error = new Error(`设置文件ID失败: ${err.message}`);
|
|
123
|
+
// eslint-disable-next-line no-console
|
|
124
|
+
console.error(error.message, err);
|
|
125
|
+
throw error;
|
|
91
126
|
}
|
|
92
127
|
}
|
|
93
128
|
|
|
94
|
-
upload(file, headers = {}) {
|
|
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
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
});
|
|
129
|
+
async upload(file, headers = {}) {
|
|
130
|
+
const currentFile = file.file;
|
|
131
|
+
const fileName = currentFile.name;
|
|
132
|
+
const newFileName = this.generateFileName(fileName);
|
|
133
|
+
const path = `accessory/${$dayjs().format('YYYY/MM/DD')}/`;
|
|
134
|
+
|
|
135
|
+
try {
|
|
136
|
+
await this.getStsToken();
|
|
137
|
+
const res = await this.oss.multipartUpload(path + newFileName, currentFile, {
|
|
138
|
+
...headers,
|
|
139
|
+
progress: (p) => {
|
|
140
|
+
const _progress = parseFloat(p * 100);
|
|
141
|
+
file.onProgress({ percent: _progress });
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
const fileObj = {
|
|
146
|
+
name: fileName,
|
|
147
|
+
size: currentFile.size,
|
|
148
|
+
ext: this.getExt(currentFile),
|
|
149
|
+
imgFlag: this.isImg(currentFile) ? 1 : 0,
|
|
150
|
+
isAV: this.isAV(currentFile) ? 1 : 0,
|
|
151
|
+
url: this.uploadHost + res.name,
|
|
152
|
+
accessoryName: fileName,
|
|
153
|
+
accessorySize: currentFile.size
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const fileIdResponse = await this.setFileId(fileObj);
|
|
157
|
+
file.onSuccess();
|
|
158
|
+
return { ...fileObj, fileId: fileIdResponse.fileId, file: currentFile };
|
|
159
|
+
} catch (err) {
|
|
160
|
+
// eslint-disable-next-line no-console
|
|
161
|
+
console.error('上传文件失败:', err);
|
|
162
|
+
// 不调用 file.onError(),避免文件被 Element UI 移除,在组件层面处理失败状态
|
|
163
|
+
throw { file, fileName, err, message: err.message || '上传失败' };
|
|
164
|
+
}
|
|
132
165
|
}
|
|
133
166
|
}
|
|
134
167
|
|
package/src/plugins/index.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import Vue from 'vue'
|
|
2
|
-
import Element from 'element-ui'
|
|
3
|
-
|
|
2
|
+
import Element from '@liuzengwei/element-ui'
|
|
3
|
+
|
|
4
|
+
// 始终导入 Element UI 样式(不使用 CDN)
|
|
5
|
+
require('@liuzengwei/element-ui/packages/theme-chalk/src/index.scss')
|
|
6
|
+
|
|
4
7
|
Vue.use(Element, {
|
|
5
8
|
size: 'small'
|
|
6
9
|
})
|