bri-components 1.4.92 → 1.4.93

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.
Files changed (156) hide show
  1. package/README.md +83 -83
  2. package/lib/styles/bundle.css +12 -12
  3. package/lib/styles/font/fontello.svg +31 -31
  4. package/package.json +125 -125
  5. package/src/components/Error/Error403.vue +42 -42
  6. package/src/components/Error/Error404.vue +40 -40
  7. package/src/components/Error/Error500.vue +51 -51
  8. package/src/components/Error/error.less +162 -162
  9. package/src/components/Error/errorBack.vue +40 -40
  10. package/src/components/controls/DshControlInput.vue +195 -195
  11. package/src/components/controls/base/BriUpload/BriUpload.vue +434 -434
  12. package/src/components/controls/base/BriUpload/BriUploadImage.vue +373 -373
  13. package/src/components/controls/base/BriUpload/uploadList.vue +724 -724
  14. package/src/components/controls/base/BriUpload/uploadMixin.js +446 -440
  15. package/src/components/controls/base/DshCascader/DshCascader.vue +210 -210
  16. package/src/components/controls/base/DshCascader/components/cascaderModal.vue +366 -366
  17. package/src/components/controls/base/DshCascader/components/cascaderPicker.vue +416 -416
  18. package/src/components/controls/base/DshCascader/components/cascaderSimple.vue +143 -143
  19. package/src/components/controls/base/DshCoordinates.vue +577 -577
  20. package/src/components/controls/base/DshDate/DshDate.vue +191 -191
  21. package/src/components/controls/base/DshDate/DshDaterange.vue +186 -186
  22. package/src/components/controls/base/DshDivider.vue +201 -201
  23. package/src/components/controls/base/DshEditor.vue +274 -274
  24. package/src/components/controls/base/DshInput/BriInputs.vue +166 -166
  25. package/src/components/controls/base/DshInput/DshInput.vue +255 -255
  26. package/src/components/controls/base/DshNumber/BriInputNumber/BriInputNumber.vue +435 -435
  27. package/src/components/controls/base/DshNumber/BriInputNumber/mixins/emitter.js +34 -34
  28. package/src/components/controls/base/DshNumber/BriInputNumber/mixins/form.js +14 -14
  29. package/src/components/controls/base/DshNumber/BriInputNumber/utils/assist.js +322 -322
  30. package/src/components/controls/base/DshNumber/DshNumber.vue +143 -143
  31. package/src/components/controls/base/DshNumber/DshNumberange.vue +109 -109
  32. package/src/components/controls/base/DshSelect/DshCheckbox.vue +168 -168
  33. package/src/components/controls/base/DshSelect/DshSelect.vue +180 -180
  34. package/src/components/controls/base/DshSwitch/DshSwitch.vue +115 -115
  35. package/src/components/controls/control.less +324 -324
  36. package/src/components/controls/controlMap.js +114 -114
  37. package/src/components/controls/extra/DshColor.vue +81 -81
  38. package/src/components/controls/extra/themeColor.vue +104 -104
  39. package/src/components/controls/extra/themeIcon.vue +114 -114
  40. package/src/components/controls/mixins/cascaderMixin.js +295 -295
  41. package/src/components/controls/mixins/cascaderPickerMixin.js +216 -216
  42. package/src/components/controls/mixins/cascaderTableMixin.js +130 -130
  43. package/src/components/controls/mixins/controlMixin.js +368 -368
  44. package/src/components/controls/mixins/dateMixin.js +149 -149
  45. package/src/components/controls/mixins/flatTableMixin.js +111 -111
  46. package/src/components/controls/mixins/numberMixin.js +112 -112
  47. package/src/components/controls/mixins/selectMixin.js +233 -233
  48. package/src/components/controls/mixins/switchMixin.js +87 -87
  49. package/src/components/controls/mixins/userAndDepartMixin.js +218 -218
  50. package/src/components/controls/senior/DshLabels.vue +331 -331
  51. package/src/components/controls/senior/DshPackage.vue +57 -57
  52. package/src/components/controls/senior/cascaderTable.vue +210 -210
  53. package/src/components/controls/senior/flatTable.vue +135 -135
  54. package/src/components/controls/senior/selectDepartments.vue +438 -438
  55. package/src/components/controls/senior/selectUsers/departMenu.vue +293 -293
  56. package/src/components/controls/senior/selectUsers/selectUsers.vue +752 -752
  57. package/src/components/controls/special/DshBack.vue +42 -42
  58. package/src/components/controls/special/DshUndeveloped.vue +41 -41
  59. package/src/components/form/DshAdvSearch.vue +510 -510
  60. package/src/components/form/DshDefaultSearch.vue +258 -258
  61. package/src/components/form/DshForm.vue +494 -494
  62. package/src/components/form/searchMixin.js +375 -375
  63. package/src/components/list/BriCard.vue +95 -95
  64. package/src/components/list/BriTable.vue +205 -205
  65. package/src/components/list/BriTree.vue +529 -529
  66. package/src/components/list/BriTreeItem.vue +163 -163
  67. package/src/components/list/DshBox/DshBox.vue +219 -219
  68. package/src/components/list/DshBox/DshCard.vue +446 -446
  69. package/src/components/list/DshBox/DshCrossTable.vue +827 -827
  70. package/src/components/list/DshBox/DshList.vue +404 -404
  71. package/src/components/list/DshBox/DshPanel.vue +669 -669
  72. package/src/components/list/DshBox/DshSingleData.vue +119 -119
  73. package/src/components/list/DshBox/DshTable.vue +239 -239
  74. package/src/components/list/DshCascaderTable.vue +115 -115
  75. package/src/components/list/DshFlatTable.vue +339 -339
  76. package/src/components/list/DshPage.vue +194 -194
  77. package/src/components/list/DshTreeTable.vue +113 -113
  78. package/src/components/list/common/importModal.vue +243 -243
  79. package/src/components/list/common/quoteListModal.vue +206 -206
  80. package/src/components/list/mixins/DshCascaderTableMixin.js +278 -278
  81. package/src/components/list/mixins/DshFlatTableMixin.js +493 -493
  82. package/src/components/list/mixins/DshTreeTableMixin.js +286 -286
  83. package/src/components/list/mixins/tableBaseMixin.js +1661 -1662
  84. package/src/components/list/mixins/treeTableBaseMixin.js +149 -149
  85. package/src/components/other/BriAvatar.vue +166 -166
  86. package/src/components/other/BriCode.vue +125 -125
  87. package/src/components/other/BriCollapseTree.vue +207 -207
  88. package/src/components/other/BriGantt.vue +1084 -1084
  89. package/src/components/other/BriIframe.vue +116 -116
  90. package/src/components/other/BriLoading.vue +171 -171
  91. package/src/components/other/BriSvg.vue +28 -28
  92. package/src/components/other/DshColorPanel.vue +128 -128
  93. package/src/components/other/DshMenuNav.vue +188 -188
  94. package/src/components/small/BriButton.vue +71 -71
  95. package/src/components/small/BriDrawer.vue +169 -169
  96. package/src/components/small/BriTooltip.vue +87 -87
  97. package/src/components/small/DshBtnModal.vue +68 -68
  98. package/src/components/small/DshButtons.vue +324 -324
  99. package/src/components/small/DshDropdown.vue +225 -225
  100. package/src/components/small/DshIcons.vue +59 -59
  101. package/src/components/small/DshListRender.js +21 -21
  102. package/src/components/small/DshModal.vue +160 -160
  103. package/src/components/small/DshSteps.vue +141 -141
  104. package/src/components/small/DshTabs.vue +598 -598
  105. package/src/components/small/DshTabsSet.vue +309 -309
  106. package/src/components/small/DshTags.vue +251 -251
  107. package/src/components/small/DshTitle.vue +50 -50
  108. package/src/components/small/render.js +20 -20
  109. package/src/components/unit/DshFormUnit.vue +398 -398
  110. package/src/components/unit/DshListUnit.vue +115 -115
  111. package/src/components/unit/unitMixin.js +86 -86
  112. package/src/data/index.js +9 -9
  113. package/src/index.js +271 -271
  114. package/src/styles/bundle.css +12 -12
  115. package/src/styles/components/BriButton.less +292 -292
  116. package/src/styles/components/BriTable.less +344 -344
  117. package/src/styles/components/DshModal.less +250 -250
  118. package/src/styles/components/index.less +3 -3
  119. package/src/styles/global/animate.less +11 -11
  120. package/src/styles/global/base.less +45 -45
  121. package/src/styles/global/box.less +186 -186
  122. package/src/styles/global/control.less +122 -122
  123. package/src/styles/global/flex.less +282 -282
  124. package/src/styles/global/global.less +8 -8
  125. package/src/styles/global/text.less +59 -59
  126. package/src/styles/global/variables.less +85 -85
  127. package/src/styles/iconfont/iconfont.css +254 -254
  128. package/src/styles/iconfont/iconfont.json +422 -422
  129. package/src/styles/iconfont/iconfont.svg +137 -137
  130. package/src/styles/index.less +11 -11
  131. package/src/styles/reset-easytable.less +21 -21
  132. package/src/styles/reset-iview-controls.less +145 -145
  133. package/src/styles/reset-iview-other.less +49 -49
  134. package/src/styles/reset-iview-variables.less +34 -34
  135. package/src/styles/reset.less +45 -45
  136. package/src/utils/index.js +5 -5
  137. package/src/utils/table.js +175 -175
  138. package/lib/0.bri-components.min.js +0 -1
  139. package/lib/1.bri-components.min.js +0 -1
  140. package/lib/10.bri-components.min.js +0 -1
  141. package/lib/11.bri-components.min.js +0 -1
  142. package/lib/2.bri-components.min.js +0 -1
  143. package/lib/3.bri-components.min.js +0 -1
  144. package/lib/4.bri-components.min.js +0 -1
  145. package/lib/5.bri-components.min.js +0 -1
  146. package/lib/6.bri-components.min.js +0 -1
  147. package/lib/7.bri-components.min.js +0 -1
  148. package/lib/8.bri-components.min.js +0 -1
  149. package/lib/9.bri-components.min.js +0 -1
  150. package/lib/bri-components.min.js +0 -18
  151. package/src/.DS_Store +0 -0
  152. package/src/components/.DS_Store +0 -0
  153. package/src/components/controls/.DS_Store +0 -0
  154. package/src/components/controls/senior/.DS_Store +0 -0
  155. package/src/styles/.DS_Store +0 -0
  156. package/src/styles/components/.DS_Store +0 -0
@@ -1,440 +1,446 @@
1
- import axios from "axios";
2
- import Oss from "ali-oss";
3
- const minio = require("minio");
4
- const stream = require("stream");
5
-
6
- export default {
7
- props: {
8
- groupKey: {
9
- type: String
10
- },
11
- urlModule: {
12
- type: Object,
13
- default: function () {
14
- return {
15
- module: "file",
16
- name: "ossToken"
17
- };
18
- }
19
- },
20
- ossType: {
21
- type: String,
22
- default: "multipartUpload"
23
- }
24
- },
25
- data () {
26
- return {
27
- percent: 0,
28
- uploadSuccess: false
29
- };
30
- },
31
- created () { },
32
- computed: {
33
- computedGroupKey () {
34
- return this.propsObj.groupKey || this.groupKey;
35
- },
36
- computedUrlModule () {
37
- return this.propsObj.urlModule || this.urlModule;
38
- },
39
- computedOssType () {
40
- return this.propsObj.ossType || this.ossType;
41
- },
42
- archiveKey () {
43
- return this.propsObj._archiveKey || [];
44
- },
45
- percentColor () {
46
- if (Number(this.percent) === 100) {
47
- return "#5cb85c";
48
- } else {
49
- return "#6090ed";
50
- }
51
- }
52
- },
53
- methods: {
54
- handlePost (file, callback) {
55
- this.$https({
56
- url: this.computedUrlModule,
57
- params: {
58
- token: this.$route.query && this.$route.query.token
59
- },
60
- callback: res => {
61
- this.inputType = "file";
62
- if (res.ossType === "ali-oss") {
63
- // 上传到阿里云res
64
- this[this.computedOssType](file, res, callback);
65
- } else if (res.ossType === "local") {
66
- this.localUpload(file, res, callback);
67
- } else if (res.ossType === "minio") {
68
- this.minioUpload(file, res, callback);
69
- } else {
70
- console.log(`请开发这种类型‘${res.ossType}’的上传模式`);
71
- }
72
-
73
- }
74
- });
75
- },
76
- localUpload (file, res, callback) {
77
- let fileBody = {
78
- groupKey: this.computedGroupKey,
79
- archiveKey: this.archiveKey[this.archiveKey.length - 1]
80
- };
81
-
82
- const url = `${res.ossHost}${res.uploadPath}`;
83
- let formData = new FormData();
84
- formData.append("file_stream", file);
85
-
86
- axios.post(url, formData, {
87
- headers: {
88
- filetoken: res.filetoken,
89
- filebody: JSON.stringify(fileBody)
90
- },
91
- onUploadProgress: progressEvent => {
92
- this.inProgress(Number((progressEvent.loaded / progressEvent.total * 100).toFixed(1)));
93
- }
94
- }).then(response => {
95
- this.uploadSuccess = true;
96
- this.percent = 100;
97
- setTimeout(() => {
98
- this.percent = 0;
99
- this.uploadSuccess = false;
100
- }, 500);
101
- this.successCb && this.successCb(response, response.data, file);
102
- callback && callback(response.data);
103
- }).catch(error => {
104
- this.handleError && this.handleError(error, {}, file);
105
- callback && callback(error);
106
- });
107
- },
108
- multipartUpload (file, res, callback) {
109
- let type = file.name.substring(file.name.lastIndexOf(".") + 1).toLowerCase();
110
- let remoteName = `${this.randomTimeStampFn()}.${type}`;
111
- let officeFileDefaultType = "";
112
- if (!file.type) {
113
- switch (type) {
114
- case "xls":
115
- officeFileDefaultType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
116
- break;
117
- case "xlsx":
118
- officeFileDefaultType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
119
- break;
120
- case "doc":
121
- officeFileDefaultType = "application/msword";
122
- break;
123
- case "docx":
124
- officeFileDefaultType = "application/msword";
125
- break;
126
- case "ppt":
127
- officeFileDefaultType = "application/vnd.ms-powerpoint";
128
- break;
129
- case "pptx":
130
- officeFileDefaultType = "application/vnd.ms-powerpoint";
131
- break;
132
- default:
133
- officeFileDefaultType = "";
134
- }
135
- }
136
-
137
- // 上传成功的回调参数
138
- let callbackBody = {
139
- name: file.name,
140
- mimetype: file.type || officeFileDefaultType,
141
- size: file.size,
142
- path: remoteName,
143
- bucket: res.ossConfig.bucket,
144
- filetoken: res.filetoken,
145
- groupKey: this.computedGroupKey,
146
- archiveKey: this.archiveKey[this.archiveKey.length - 1]
147
- };
148
-
149
- let ossCallback = {
150
- callbackUrl: res.ossHost + res.confirmPath,
151
- callbackBodyType: "application/json",
152
- callbackBody: this.transferCallBody(callbackBody)
153
- };
154
-
155
- let newOss = {
156
- ...res.ossConfig,
157
- refreshSTSToken: async () => {
158
- // 向您搭建的STS服务获取临时访问凭证。
159
- return {
160
- accessKeyId: res.ossConfig.accessKeyId, // 自己账户的accessKeyId或临时秘钥
161
- accessKeySecret: res.ossConfig.accessKeySecret, // 自己账户的accessKeySecret或临时秘钥
162
- stsToken: res.ossConfig.stsToken // 从STS服务获取的安全令牌(SecurityToken)。
163
- };
164
- },
165
- // 刷新临时访问凭证的时间间隔,单位为毫秒。
166
- refreshSTSTokenInterval: 3600 * 1000
167
- };
168
-
169
- new Oss(newOss).multipartUpload(remoteName, file, {
170
- progress: (percentage) => {
171
- this.inProgress(Number((percentage * 100).toFixed(1)));
172
- this.handleProgress && this.handleProgress(percentage, file);
173
- },
174
- headers: {
175
- "x-oss-callback": this.base64Encode(JSON.stringify(ossCallback)),
176
- "Content-Disposition": type === "pdf" ? `inline;filename=${encodeURI(file.name)}` : `attachment;filename=${encodeURI(file.name)}`
177
- }
178
- }).then(response => {
179
- this.uploadSuccess = true;
180
- this.percent = 100;
181
- setTimeout(() => {
182
- this.percent = 0;
183
- this.uploadSuccess = false;
184
- }, 500);
185
- this.successCb && this.successCb(response, response.data, file);
186
- callback && callback(response.data);
187
- }).catch((err, response) => {
188
- this.handleError && this.handleError(err, response, file);
189
- callback && callback(err);
190
- });
191
- },
192
- minioUpload (file, res, callback) {
193
- let type = file.name.substring(file.name.lastIndexOf(".") + 1).toLowerCase();
194
- let remoteName = `${this.randomTimeStampFn()}.${type}`;
195
- let officeFileDefaultType = "";
196
- if (!file.type) {
197
- switch (type) {
198
- case "xls":
199
- officeFileDefaultType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
200
- break;
201
- case "xlsx":
202
- officeFileDefaultType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
203
- break;
204
- case "doc":
205
- officeFileDefaultType = "application/msword";
206
- break;
207
- case "docx":
208
- officeFileDefaultType = "application/msword";
209
- break;
210
- case "ppt":
211
- officeFileDefaultType = "application/vnd.ms-powerpoint";
212
- break;
213
- case "pptx":
214
- officeFileDefaultType = "application/vnd.ms-powerpoint";
215
- break;
216
- default:
217
- officeFileDefaultType = "";
218
- }
219
- }
220
- const minioClient = new minio.Client({
221
- endPoint: res.ossConfig.endPoint,
222
- port: res.ossConfig.port,
223
- useSSL: res.ossConfig.useSSL,
224
- accessKey: window.config.minioAccessKey,
225
- secretKey: window.config.minioSecretKey
226
- });
227
- // 获取文件类型及大小
228
- const fileSize = file.size;
229
- // 将文件转换为minio可接收的格式
230
- const reader = new FileReader();
231
- reader.readAsDataURL(file);
232
- reader.onloadend = e => {
233
- const dataurl = e.target.result;
234
- // base64转blob
235
- const blob = this.toBlob(dataurl);
236
- // blob转arrayBuffer
237
- const reader2 = new FileReader();
238
- reader2.readAsArrayBuffer(blob);
239
- // 参数
240
- let metadata = {
241
- "content-type": file.type || officeFileDefaultType,
242
- "content-length": fileSize
243
- };
244
- reader2.onload = ex => {
245
- // 定义流
246
- const bufferStream = new stream.PassThrough();
247
- // 将buffer写入
248
- bufferStream.end(Buffer.from(ex.target.result));
249
- // 上传
250
- minioClient.putObject(res.ossConfig.bucket, remoteName, bufferStream, fileSize, metadata, (err, etag) => {
251
- if (err == null) {
252
- // if (file.type.startsWith("image")) {
253
- // let img = new Image();
254
- // // 改变图片的src
255
- // img.src = url;
256
- // // 加载完成执行
257
- // img.onload = function () {
258
- // // 打印
259
- // alert("width:" + img.width + ",height:" + img.height);
260
- // };
261
- // }
262
- let callbackBody = {
263
- name: file.name,
264
- mimetype: file.type || officeFileDefaultType,
265
- size: fileSize,
266
- path: remoteName,
267
- bucket: res.ossConfig.bucket,
268
- filetoken: res.filetoken,
269
- groupKey: this.computedGroupKey,
270
- archiveKey: this.archiveKey[this.archiveKey.length - 1]
271
- };
272
- axios.post(res.ossHost + res.confirmPath, { ...callbackBody })
273
- .then(response => {
274
- this.successCb && this.successCb(null, response, null);
275
- });
276
- }
277
- });
278
- };
279
- };
280
- },
281
- // bri-upload-image 用的是这种方式
282
- binaryMultipartUpload (file, res, callback) {
283
- let type = "jpg";
284
- let remoteName = `${this.randomTimeStampFn()}.${type}`;
285
- // 上传成功的回调参数
286
- let callbackBody = {
287
- name: remoteName,
288
- mimetype: "image/jpeg",
289
- size: file.length,
290
- path: remoteName,
291
- bucket: res.ossConfig.bucket,
292
- filetoken: res.filetoken,
293
- groupKey: this.computedGroupKey,
294
- archiveKey: this.archiveKey[this.archiveKey.length - 1]
295
- };
296
-
297
- let ossCallback = {
298
- callbackUrl: res.ossHost + res.confirmPath,
299
- callbackBodyType: "application/json",
300
- callbackBody: this.transferCallBody(callbackBody)
301
- };
302
-
303
- let newOss = {
304
- ...res.ossConfig,
305
- refreshSTSToken: async () => {
306
- // 向您搭建的STS服务获取临时访问凭证。
307
- return {
308
- accessKeyId: res.ossConfig.accessKeyId, // 自己账户的accessKeyId或临时秘钥
309
- accessKeySecret: res.ossConfig.accessKeySecret, // 自己账户的accessKeySecret或临时秘钥
310
- stsToken: res.ossConfig.stsToken // 从STS服务获取的安全令牌(SecurityToken)。
311
- };
312
- },
313
- // 刷新临时访问凭证的时间间隔,单位为毫秒。
314
- refreshSTSTokenInterval: 3600 * 1000
315
- };
316
-
317
- new Oss(newOss).multipartUpload(remoteName, file, {
318
- progress: (percentage) => {
319
- this.inProgress(Number((percentage * 100).toFixed(1)));
320
- this.handleProgress && this.handleProgress(percentage, file);
321
- },
322
- headers: {
323
- "x-oss-callback": this.base64Encode(JSON.stringify(ossCallback)),
324
- "Content-Disposition": type === "pdf" ? `inline;filename=${encodeURI(file.name)}` : `attachment;filename=${encodeURI(file.name)}`
325
- }
326
- }).then(response => {
327
- this.percent = 100;
328
- this.uploadSuccess = true;
329
- setTimeout(() => {
330
- this.percent = 0;
331
- this.uploadSuccess = false;
332
- }, 500);
333
- this.successCb && this.successCb(response, response.data, file);
334
- callback && callback(response.data);
335
- }).catch((err, response) => {
336
- this.handleError && this.handleError(err, response, file);
337
- callback && callback(err);
338
- });
339
-
340
- },
341
- inProgress (percent) {
342
- if (percent === 100 && !this.uploadSuccess) {
343
- this.percent = 99.9;
344
- } else {
345
- this.percent = percent;
346
- }
347
- if (this.percent >= 100) {
348
- this.percent = 100;
349
- setTimeout(() => {
350
- this.percent = 0;
351
- }, 500);
352
- }
353
- },
354
- // 以下为数据转换方法
355
- randomTimeStampFn () {
356
- let randomTimeStamp = new Date().getTime() + "" + Math.floor(Math.random() * 10000);
357
- return this.$md5(randomTimeStamp);
358
- },
359
- transferCallBody (obj) {
360
- let newObj = {};
361
- for (let attr in obj) {
362
- newObj[attr] = obj[attr];
363
- }
364
- return JSON.stringify(newObj);
365
- },
366
- // base64转换
367
- base64Encode (input) {
368
- let _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
369
-
370
- let output = "";
371
- let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
372
- let i = 0;
373
- input = this.utf8Encode(input);
374
- while (i < input.length) {
375
- chr1 = input.charCodeAt(i++);
376
- chr2 = input.charCodeAt(i++);
377
- chr3 = input.charCodeAt(i++);
378
- enc1 = chr1 >> 2;
379
- enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
380
- enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
381
- enc4 = chr3 & 63;
382
- if (isNaN(chr2)) {
383
- enc3 = enc4 = 64;
384
- } else if (isNaN(chr3)) {
385
- enc4 = 64;
386
- }
387
- output = output +
388
- _keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
389
- _keyStr.charAt(enc3) + _keyStr.charAt(enc4);
390
- }
391
- return output;
392
- },
393
- utf8Encode (str) {
394
- str = str.replace(/\r\n/g, "\n");
395
- let utftext = "";
396
- for (let n = 0; n < str.length; n++) {
397
- let c = str.charCodeAt(n);
398
- if (c < 128) {
399
- utftext += String.fromCharCode(c);
400
- } else if ((c > 127) && (c < 2048)) {
401
- utftext += String.fromCharCode((c >> 6) | 192);
402
- utftext += String.fromCharCode((c & 63) | 128);
403
- } else {
404
- utftext += String.fromCharCode((c >> 12) | 224);
405
- utftext += String.fromCharCode(((c >> 6) & 63) | 128);
406
- utftext += String.fromCharCode((c & 63) | 128);
407
- }
408
-
409
- }
410
- return utftext;
411
- },
412
- // base64转blob
413
- toBlob (base64Data) {
414
- let byteString = base64Data;
415
- if (base64Data.split(",")[0].indexOf("base64") >= 0) {
416
- byteString = atob(base64Data.split(",")[1]); // base64 解码
417
- } else {
418
- byteString = unescape(base64Data.split(",")[1]);
419
- }
420
- // 获取文件类型
421
- const mimeString = base64Data.split(";")[0].split(":")[1]; // mime类型
422
-
423
- // ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区
424
- // let arrayBuffer = new ArrayBuffer(byteString.length) // 创建缓冲数组
425
- // let uintArr = new Uint8Array(arrayBuffer) // 创建视图
426
-
427
- const uintArr = new Uint8Array(byteString.length); // 创建视图
428
-
429
- for (let i = 0; i < byteString.length; i += 1) {
430
- uintArr[i] = byteString.charCodeAt(i);
431
- }
432
- // 生成blob
433
- const blob = new Blob([uintArr], {
434
- type: mimeString
435
- });
436
- // 使用 Blob 创建一个指向类型化数组的URL, URL.createObjectURL是new Blob文件的方法,可以生成一个普通的url,可以直接使用,比如用在img.src上
437
- return blob;
438
- }
439
- }
440
- };
1
+ import axios from "axios";
2
+ import Oss from "ali-oss";
3
+ const minio = require("minio");
4
+ const stream = require("stream");
5
+
6
+ export default {
7
+ props: {
8
+ groupKey: {
9
+ type: String
10
+ },
11
+ urlModule: {
12
+ type: Object,
13
+ default: function () {
14
+ return {
15
+ module: "file",
16
+ name: "ossToken"
17
+ };
18
+ }
19
+ },
20
+ ossType: {
21
+ type: String,
22
+ default: "multipartUpload"
23
+ }
24
+ },
25
+ data () {
26
+ return {
27
+ percent: 0,
28
+ uploadSuccess: false
29
+ };
30
+ },
31
+ created () { },
32
+ computed: {
33
+ computedGroupKey () {
34
+ return this.propsObj.groupKey || this.groupKey;
35
+ },
36
+ computedUrlModule () {
37
+ return this.propsObj.urlModule || this.urlModule;
38
+ },
39
+ computedOssType () {
40
+ return this.propsObj.ossType || this.ossType;
41
+ },
42
+ archiveKey () {
43
+ return this.propsObj._archiveKey || [];
44
+ },
45
+ percentColor () {
46
+ if (Number(this.percent) === 100) {
47
+ return "#5cb85c";
48
+ } else {
49
+ return "#6090ed";
50
+ }
51
+ }
52
+ },
53
+ methods: {
54
+ handlePost (file, callback) {
55
+ this.$https({
56
+ url: this.computedUrlModule,
57
+ params: {
58
+ token: this.$route.query && this.$route.query.token
59
+ },
60
+ callback: res => {
61
+ this.inputType = "file";
62
+ if (res.ossType === "ali-oss") {
63
+ // 上传到阿里云res
64
+ this[this.computedOssType](file, res, callback);
65
+ } else if (res.ossType === "local") {
66
+ this.localUpload(file, res, callback);
67
+ } else if (res.ossType === "minio") {
68
+ this.minioUpload(file, res, callback);
69
+ } else {
70
+ console.log(`请开发这种类型‘${res.ossType}’的上传模式`);
71
+ }
72
+
73
+ }
74
+ });
75
+ },
76
+ localUpload (file, res, callback) {
77
+ let fileBody = {
78
+ groupKey: this.computedGroupKey,
79
+ archiveKey: this.archiveKey[this.archiveKey.length - 1]
80
+ };
81
+
82
+ const url = `${res.ossHost}${res.uploadPath}`;
83
+ let formData = new FormData();
84
+ formData.append("file_stream", file);
85
+
86
+ axios.post(url, formData, {
87
+ headers: {
88
+ filetoken: res.filetoken,
89
+ filebody: JSON.stringify(fileBody)
90
+ },
91
+ onUploadProgress: progressEvent => {
92
+ this.inProgress(Number((progressEvent.loaded / progressEvent.total * 100).toFixed(1)));
93
+ }
94
+ }).then(response => {
95
+ this.uploadSuccess = true;
96
+ this.percent = 100;
97
+ setTimeout(() => {
98
+ this.percent = 0;
99
+ this.uploadSuccess = false;
100
+ }, 500);
101
+ this.successCb && this.successCb(response, response.data, file);
102
+ callback && callback(response.data);
103
+ }).catch(error => {
104
+ this.percent = 0;
105
+ this.uploadSuccess = false;
106
+ this.handleError && this.handleError(error, {}, file);
107
+ callback && callback(error);
108
+ });
109
+ },
110
+ multipartUpload (file, res, callback) {
111
+ let type = file.name.substring(file.name.lastIndexOf(".") + 1).toLowerCase();
112
+ let remoteName = `${this.randomTimeStampFn()}.${type}`;
113
+ let officeFileDefaultType = "";
114
+ if (!file.type) {
115
+ switch (type) {
116
+ case "xls":
117
+ officeFileDefaultType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
118
+ break;
119
+ case "xlsx":
120
+ officeFileDefaultType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
121
+ break;
122
+ case "doc":
123
+ officeFileDefaultType = "application/msword";
124
+ break;
125
+ case "docx":
126
+ officeFileDefaultType = "application/msword";
127
+ break;
128
+ case "ppt":
129
+ officeFileDefaultType = "application/vnd.ms-powerpoint";
130
+ break;
131
+ case "pptx":
132
+ officeFileDefaultType = "application/vnd.ms-powerpoint";
133
+ break;
134
+ default:
135
+ officeFileDefaultType = "";
136
+ }
137
+ }
138
+
139
+ // 上传成功的回调参数
140
+ let callbackBody = {
141
+ name: file.name,
142
+ mimetype: file.type || officeFileDefaultType,
143
+ size: file.size,
144
+ path: remoteName,
145
+ bucket: res.ossConfig.bucket,
146
+ filetoken: res.filetoken,
147
+ groupKey: this.computedGroupKey,
148
+ archiveKey: this.archiveKey[this.archiveKey.length - 1]
149
+ };
150
+
151
+ let ossCallback = {
152
+ callbackUrl: res.ossHost + res.confirmPath,
153
+ callbackBodyType: "application/json",
154
+ callbackBody: this.transferCallBody(callbackBody)
155
+ };
156
+
157
+ let newOss = {
158
+ ...res.ossConfig,
159
+ refreshSTSToken: async () => {
160
+ // 向您搭建的STS服务获取临时访问凭证。
161
+ return {
162
+ accessKeyId: res.ossConfig.accessKeyId, // 自己账户的accessKeyId或临时秘钥
163
+ accessKeySecret: res.ossConfig.accessKeySecret, // 自己账户的accessKeySecret或临时秘钥
164
+ stsToken: res.ossConfig.stsToken // 从STS服务获取的安全令牌(SecurityToken)。
165
+ };
166
+ },
167
+ // 刷新临时访问凭证的时间间隔,单位为毫秒。
168
+ refreshSTSTokenInterval: 3600 * 1000
169
+ };
170
+
171
+ new Oss(newOss).multipartUpload(remoteName, file, {
172
+ progress: (percentage) => {
173
+ this.inProgress(Number((percentage * 100).toFixed(1)));
174
+ this.handleProgress && this.handleProgress(percentage, file);
175
+ },
176
+ headers: {
177
+ "x-oss-callback": this.base64Encode(JSON.stringify(ossCallback)),
178
+ "Content-Disposition": type === "pdf" ? `inline;filename=${encodeURI(file.name)}` : `attachment;filename=${encodeURI(file.name)}`
179
+ }
180
+ }).then(response => {
181
+ this.uploadSuccess = true;
182
+ this.percent = 100;
183
+ setTimeout(() => {
184
+ this.percent = 0;
185
+ this.uploadSuccess = false;
186
+ }, 500);
187
+ this.successCb && this.successCb(response, response.data, file);
188
+ callback && callback(response.data);
189
+ }).catch((err, response) => {
190
+ this.percent = 0;
191
+ this.uploadSuccess = false;
192
+ this.handleError && this.handleError(err, response, file);
193
+ callback && callback(err);
194
+ });
195
+ },
196
+ minioUpload (file, res, callback) {
197
+ let type = file.name.substring(file.name.lastIndexOf(".") + 1).toLowerCase();
198
+ let remoteName = `${this.randomTimeStampFn()}.${type}`;
199
+ let officeFileDefaultType = "";
200
+ if (!file.type) {
201
+ switch (type) {
202
+ case "xls":
203
+ officeFileDefaultType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
204
+ break;
205
+ case "xlsx":
206
+ officeFileDefaultType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
207
+ break;
208
+ case "doc":
209
+ officeFileDefaultType = "application/msword";
210
+ break;
211
+ case "docx":
212
+ officeFileDefaultType = "application/msword";
213
+ break;
214
+ case "ppt":
215
+ officeFileDefaultType = "application/vnd.ms-powerpoint";
216
+ break;
217
+ case "pptx":
218
+ officeFileDefaultType = "application/vnd.ms-powerpoint";
219
+ break;
220
+ default:
221
+ officeFileDefaultType = "";
222
+ }
223
+ }
224
+ const minioClient = new minio.Client({
225
+ endPoint: res.ossConfig.endPoint,
226
+ port: res.ossConfig.port,
227
+ useSSL: res.ossConfig.useSSL,
228
+ accessKey: window.config.minioAccessKey,
229
+ secretKey: window.config.minioSecretKey
230
+ });
231
+ // 获取文件类型及大小
232
+ const fileSize = file.size;
233
+ // 将文件转换为minio可接收的格式
234
+ const reader = new FileReader();
235
+ reader.readAsDataURL(file);
236
+ reader.onloadend = e => {
237
+ const dataurl = e.target.result;
238
+ // base64转blob
239
+ const blob = this.toBlob(dataurl);
240
+ // blob转arrayBuffer
241
+ const reader2 = new FileReader();
242
+ reader2.readAsArrayBuffer(blob);
243
+ // 参数
244
+ let metadata = {
245
+ "content-type": file.type || officeFileDefaultType,
246
+ "content-length": fileSize
247
+ };
248
+ reader2.onload = ex => {
249
+ // 定义流
250
+ const bufferStream = new stream.PassThrough();
251
+ // 将buffer写入
252
+ bufferStream.end(Buffer.from(ex.target.result));
253
+ // 上传
254
+ minioClient.putObject(res.ossConfig.bucket, remoteName, bufferStream, fileSize, metadata, (err, etag) => {
255
+ if (err == null) {
256
+ // if (file.type.startsWith("image")) {
257
+ // let img = new Image();
258
+ // // 改变图片的src
259
+ // img.src = url;
260
+ // // 加载完成执行
261
+ // img.onload = function () {
262
+ // // 打印
263
+ // alert("width:" + img.width + ",height:" + img.height);
264
+ // };
265
+ // }
266
+ let callbackBody = {
267
+ name: file.name,
268
+ mimetype: file.type || officeFileDefaultType,
269
+ size: fileSize,
270
+ path: remoteName,
271
+ bucket: res.ossConfig.bucket,
272
+ filetoken: res.filetoken,
273
+ groupKey: this.computedGroupKey,
274
+ archiveKey: this.archiveKey[this.archiveKey.length - 1]
275
+ };
276
+ axios.post(res.ossHost + res.confirmPath, { ...callbackBody })
277
+ .then(response => {
278
+ this.successCb && this.successCb(null, response, null);
279
+ });
280
+ }
281
+ });
282
+ };
283
+ };
284
+ },
285
+ // bri-upload-image 用的是这种方式
286
+ binaryMultipartUpload (file, res, callback) {
287
+ let type = "jpg";
288
+ let remoteName = `${this.randomTimeStampFn()}.${type}`;
289
+ // 上传成功的回调参数
290
+ let callbackBody = {
291
+ name: remoteName,
292
+ mimetype: "image/jpeg",
293
+ size: file.length,
294
+ path: remoteName,
295
+ bucket: res.ossConfig.bucket,
296
+ filetoken: res.filetoken,
297
+ groupKey: this.computedGroupKey,
298
+ archiveKey: this.archiveKey[this.archiveKey.length - 1]
299
+ };
300
+
301
+ let ossCallback = {
302
+ callbackUrl: res.ossHost + res.confirmPath,
303
+ callbackBodyType: "application/json",
304
+ callbackBody: this.transferCallBody(callbackBody)
305
+ };
306
+
307
+ let newOss = {
308
+ ...res.ossConfig,
309
+ refreshSTSToken: async () => {
310
+ // 向您搭建的STS服务获取临时访问凭证。
311
+ return {
312
+ accessKeyId: res.ossConfig.accessKeyId, // 自己账户的accessKeyId或临时秘钥
313
+ accessKeySecret: res.ossConfig.accessKeySecret, // 自己账户的accessKeySecret或临时秘钥
314
+ stsToken: res.ossConfig.stsToken // 从STS服务获取的安全令牌(SecurityToken)。
315
+ };
316
+ },
317
+ // 刷新临时访问凭证的时间间隔,单位为毫秒。
318
+ refreshSTSTokenInterval: 3600 * 1000
319
+ };
320
+
321
+ new Oss(newOss).multipartUpload(remoteName, file, {
322
+ progress: (percentage) => {
323
+ this.inProgress(Number((percentage * 100).toFixed(1)));
324
+ this.handleProgress && this.handleProgress(percentage, file);
325
+ },
326
+ headers: {
327
+ "x-oss-callback": this.base64Encode(JSON.stringify(ossCallback)),
328
+ "Content-Disposition": type === "pdf" ? `inline;filename=${encodeURI(file.name)}` : `attachment;filename=${encodeURI(file.name)}`
329
+ }
330
+ }).then(response => {
331
+ this.percent = 100;
332
+ this.uploadSuccess = true;
333
+ setTimeout(() => {
334
+ this.percent = 0;
335
+ this.uploadSuccess = false;
336
+ }, 500);
337
+ this.successCb && this.successCb(response, response.data, file);
338
+ callback && callback(response.data);
339
+ }).catch((err, response) => {
340
+ this.percent = 0;
341
+ this.uploadSuccess = false;
342
+ this.handleError && this.handleError(err, response, file);
343
+ callback && callback(err);
344
+ });
345
+
346
+ },
347
+ inProgress (percent) {
348
+ if (percent === 100 && !this.uploadSuccess) {
349
+ this.percent = 99.9;
350
+ } else {
351
+ this.percent = percent;
352
+ }
353
+ if (this.percent >= 100) {
354
+ this.percent = 100;
355
+ setTimeout(() => {
356
+ this.percent = 0;
357
+ }, 500);
358
+ }
359
+ },
360
+ // 以下为数据转换方法
361
+ randomTimeStampFn () {
362
+ let randomTimeStamp = new Date().getTime() + "" + Math.floor(Math.random() * 10000);
363
+ return this.$md5(randomTimeStamp);
364
+ },
365
+ transferCallBody (obj) {
366
+ let newObj = {};
367
+ for (let attr in obj) {
368
+ newObj[attr] = obj[attr];
369
+ }
370
+ return JSON.stringify(newObj);
371
+ },
372
+ // base64转换
373
+ base64Encode (input) {
374
+ let _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
375
+
376
+ let output = "";
377
+ let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
378
+ let i = 0;
379
+ input = this.utf8Encode(input);
380
+ while (i < input.length) {
381
+ chr1 = input.charCodeAt(i++);
382
+ chr2 = input.charCodeAt(i++);
383
+ chr3 = input.charCodeAt(i++);
384
+ enc1 = chr1 >> 2;
385
+ enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
386
+ enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
387
+ enc4 = chr3 & 63;
388
+ if (isNaN(chr2)) {
389
+ enc3 = enc4 = 64;
390
+ } else if (isNaN(chr3)) {
391
+ enc4 = 64;
392
+ }
393
+ output = output +
394
+ _keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
395
+ _keyStr.charAt(enc3) + _keyStr.charAt(enc4);
396
+ }
397
+ return output;
398
+ },
399
+ utf8Encode (str) {
400
+ str = str.replace(/\r\n/g, "\n");
401
+ let utftext = "";
402
+ for (let n = 0; n < str.length; n++) {
403
+ let c = str.charCodeAt(n);
404
+ if (c < 128) {
405
+ utftext += String.fromCharCode(c);
406
+ } else if ((c > 127) && (c < 2048)) {
407
+ utftext += String.fromCharCode((c >> 6) | 192);
408
+ utftext += String.fromCharCode((c & 63) | 128);
409
+ } else {
410
+ utftext += String.fromCharCode((c >> 12) | 224);
411
+ utftext += String.fromCharCode(((c >> 6) & 63) | 128);
412
+ utftext += String.fromCharCode((c & 63) | 128);
413
+ }
414
+
415
+ }
416
+ return utftext;
417
+ },
418
+ // base64转blob
419
+ toBlob (base64Data) {
420
+ let byteString = base64Data;
421
+ if (base64Data.split(",")[0].indexOf("base64") >= 0) {
422
+ byteString = atob(base64Data.split(",")[1]); // base64 解码
423
+ } else {
424
+ byteString = unescape(base64Data.split(",")[1]);
425
+ }
426
+ // 获取文件类型
427
+ const mimeString = base64Data.split(";")[0].split(":")[1]; // mime类型
428
+
429
+ // ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区
430
+ // let arrayBuffer = new ArrayBuffer(byteString.length) // 创建缓冲数组
431
+ // let uintArr = new Uint8Array(arrayBuffer) // 创建视图
432
+
433
+ const uintArr = new Uint8Array(byteString.length); // 创建视图
434
+
435
+ for (let i = 0; i < byteString.length; i += 1) {
436
+ uintArr[i] = byteString.charCodeAt(i);
437
+ }
438
+ // 生成blob
439
+ const blob = new Blob([uintArr], {
440
+ type: mimeString
441
+ });
442
+ // 使用 Blob 创建一个指向类型化数组的URL, URL.createObjectURL是new Blob文件的方法,可以生成一个普通的url,可以直接使用,比如用在img.src上
443
+ return blob;
444
+ }
445
+ }
446
+ };