You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

MinioUploader.vue 16 kB

5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. <template>
  2. <div class="dropzone-wrapper dataset-files">
  3. <div
  4. id="dataset"
  5. class="dropzone"
  6. />
  7. <p class="upload-info">
  8. {{ file_status_text }}
  9. <span class="success">{{ status }}</span>
  10. </p>
  11. </div>
  12. </template>
  13. <script>
  14. /* eslint-disable eqeqeq */
  15. // import Dropzone from 'dropzone/dist/dropzone.js';
  16. // import 'dropzone/dist/dropzone.css'
  17. import SparkMD5 from 'spark-md5';
  18. import axios from 'axios';
  19. import qs from 'qs';
  20. import createDropzone from '../features/dropzone.js';
  21. const {_AppSubUrl, _StaticUrlPrefix, csrf} = window.config;
  22. const cloud_brain_type = 1;
  23. export default {
  24. data() {
  25. return {
  26. dropzoneUploader: null,
  27. maxFiles: 1,
  28. maxFilesize: 1 * 1024 * 1024 * 1024 * 1024,
  29. acceptedFiles: '*/*',
  30. progress: 0,
  31. status: '',
  32. dropzoneParams: {},
  33. file_status_text: ''
  34. };
  35. },
  36. async mounted() {
  37. this.dropzoneParams = $('div#minioUploader-params');
  38. this.file_status_text = this.dropzoneParams.data('file-status');
  39. this.status = this.dropzoneParams.data('file-init-status');
  40. let previewTemplate = '';
  41. previewTemplate += '<div class="dz-preview dz-file-preview">\n ';
  42. previewTemplate += ' <div class="dz-details">\n ';
  43. previewTemplate += ' <div class="dz-filename">';
  44. previewTemplate +=
  45. ' <span data-dz-name data-dz-thumbnail></span>';
  46. previewTemplate += ' </div>\n ';
  47. previewTemplate += ' <div class="dz-size" data-dz-size></div>\n ';
  48. previewTemplate += ' </div>\n ';
  49. previewTemplate += ' <div class="dz-progress ui active progress">';
  50. previewTemplate +=
  51. ' <div class="dz-upload bar" data-dz-uploadprogress><div class="progress"></div></div>\n ';
  52. previewTemplate += ' </div>\n ';
  53. previewTemplate += ' <div class="dz-success-mark">';
  54. previewTemplate += ' <span>上传成功</span>';
  55. previewTemplate += ' </div>\n ';
  56. previewTemplate += ' <div class="dz-error-mark">';
  57. previewTemplate += ' <span>上传失败</span>';
  58. previewTemplate += ' </div>\n ';
  59. previewTemplate += ' <div class="dz-error-message">';
  60. previewTemplate += ' <span data-dz-errormessage></span>';
  61. previewTemplate += ' </div>\n';
  62. previewTemplate += '</div>';
  63. const $dropzone = $('div#dataset');
  64. console.log('createDropzone');
  65. const dropzoneUploader = await createDropzone($dropzone[0], {
  66. url: '/todouploader',
  67. maxFiles: this.maxFiles,
  68. maxFilesize: this.maxFileSize,
  69. timeout: 0,
  70. autoQueue: false,
  71. dictDefaultMessage: this.dropzoneParams.data('default-message'),
  72. dictInvalidFileType: this.dropzoneParams.data('invalid-input-type'),
  73. dictFileTooBig: this.dropzoneParams.data('file-too-big'),
  74. dictRemoveFile: this.dropzoneParams.data('remove-file'),
  75. previewTemplate
  76. });
  77. dropzoneUploader.on('addedfile', (file) => {
  78. setTimeout(() => {
  79. // eslint-disable-next-line no-unused-expressions
  80. file.accepted && this.onFileAdded(file);
  81. }, 200);
  82. });
  83. dropzoneUploader.on('maxfilesexceeded', function (file) {
  84. if (this.files[0].status !== 'success') {
  85. alert(this.dropzoneParams.data('waitting-uploading'));
  86. this.removeFile(file);
  87. return;
  88. }
  89. this.removeAllFiles();
  90. this.addFile(file);
  91. });
  92. this.dropzoneUploader = dropzoneUploader;
  93. },
  94. methods: {
  95. resetStatus() {
  96. this.progress = 0;
  97. this.status = '';
  98. },
  99. updateProgress(file, progress) {
  100. file.previewTemplate.querySelector(
  101. '.dz-upload'
  102. ).style.width = `${progress}%`;
  103. },
  104. emitDropzoneSuccess(file) {
  105. file.status = 'success';
  106. this.dropzoneUploader.emit('success', file);
  107. this.dropzoneUploader.emit('complete', file);
  108. },
  109. emitDropzoneFailed(file) {
  110. this.status = this.dropzoneParams.data('falied');
  111. file.status = 'error';
  112. this.dropzoneUploader.emit('error', file);
  113. // this.dropzoneUploader.emit('complete', file);
  114. },
  115. onFileAdded(file) {
  116. file.datasetId = document
  117. .getElementById('datasetId')
  118. .getAttribute('datasetId');
  119. this.resetStatus();
  120. this.computeMD5(file);
  121. },
  122. finishUpload(file) {
  123. this.emitDropzoneSuccess(file);
  124. // setTimeout(() => {
  125. // window.location.reload();
  126. // }, 1000);
  127. },
  128. // computeMD5(file) {
  129. // this.resetStatus();
  130. // const blobSlice =
  131. // File.prototype.slice ||
  132. // File.prototype.mozSlice ||
  133. // File.prototype.webkitSlice,
  134. // chunkSize = 1024 * 1024 * 64,
  135. // chunks = Math.ceil(file.size / chunkSize),
  136. // spark = new SparkMD5.ArrayBuffer(),
  137. // fileReader = new FileReader();
  138. // let currentChunk = 0;
  139. // const time = new Date().getTime();
  140. // // console.log('计算MD5...')
  141. // this.status = this.dropzoneParams.data('md5-computing');
  142. // file.totalChunkCounts = chunks;
  143. // loadNext();
  144. // fileReader.onload = (e) => {
  145. // fileLoaded.call(this, e);
  146. // };
  147. // fileReader.onerror = (err) => {
  148. // console.warn('oops, something went wrong.', err);
  149. // file.cancel();
  150. // };
  151. // function fileLoaded(e) {
  152. // spark.append(e.target.result); // Append array buffer
  153. // currentChunk++;
  154. // if (currentChunk < chunks) {
  155. // // console.log(`第${currentChunk}分片解析完成, 开始第${currentChunk +1}/${chunks}分片解析`);
  156. // this.status = `${this.dropzoneParams.data('loading-file')} ${(
  157. // (currentChunk / chunks) *
  158. // 100
  159. // ).toFixed(2)}% (${currentChunk}/${chunks})`;
  160. // this.updateProgress(file, ((currentChunk / chunks) * 100).toFixed(2));
  161. // loadNext();
  162. // return;
  163. // }
  164. // const md5 = spark.end();
  165. // console.log(
  166. // `MD5计算完成:${file.name} \nMD5:${md5} \n分片:${chunks} 大小:${
  167. // file.size
  168. // } 用时:${(new Date().getTime() - time) / 1000} s`
  169. // );
  170. // spark.destroy(); // 释放缓存
  171. // file.uniqueIdentifier = md5; // 将文件md5赋值给文件唯一标识
  172. // file.cmd5 = false; // 取消计算md5状态
  173. // this.computeMD5Success(file);
  174. // }
  175. // function loadNext() {
  176. // const start = currentChunk * chunkSize;
  177. // const end =
  178. // start + chunkSize >= file.size ? file.size : start + chunkSize;
  179. // fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
  180. // }
  181. // },
  182. // async computeMD5Success(md5edFile) {
  183. // const file = await this.getSuccessChunks(md5edFile);
  184. // try {
  185. // if (file.uploadID == '' || file.uuid == '') {
  186. // // 未上传过
  187. // await this.newMultiUpload(file);
  188. // if (file.uploadID != '' && file.uuid != '') {
  189. // file.chunks = '';
  190. // this.multipartUpload(file);
  191. // } else {
  192. // // 失败如何处理
  193. // return;
  194. // }
  195. // return;
  196. // }
  197. // if (file.uploaded == '1') {
  198. // // 已上传成功
  199. // // 秒传
  200. // if (file.attachID == '0') {
  201. // // 删除数据集记录,未删除文件
  202. // await addAttachment(file);
  203. // }
  204. // //不同数据集上传同一个文件
  205. // if (file.datasetID != '') {
  206. // if (Number(file.datasetID) != file.datasetId) {
  207. // var info = "该文件已上传,对应数据集(" + file.datasetName + ")-文件(" + file.realName + ")";
  208. // window.alert(info);
  209. // window.location.reload();
  210. // }
  211. // }
  212. // console.log('文件已上传完成');
  213. // this.progress = 100;
  214. // this.status = this.dropzoneParams.data('upload-complete');
  215. // this.finishUpload(file);
  216. // } else {
  217. // // 断点续传
  218. // this.multipartUpload(file);
  219. // }
  220. // } catch (error) {
  221. // this.emitDropzoneFailed(file);
  222. // console.log(error);
  223. // }
  224. // async function addAttachment(file) {
  225. // return await axios.post(
  226. // '/attachments/add',
  227. // qs.stringify({
  228. // uuid: file.uuid,
  229. // file_name: file.name,
  230. // size: file.size,
  231. // dataset_id: file.datasetId,
  232. // _csrf: csrf
  233. // })
  234. // );
  235. // }
  236. // },
  237. // async getSuccessChunks(file) {
  238. // const params = {
  239. // params: {
  240. // md5: file.uniqueIdentifier,
  241. // type: cloud_brain_type,
  242. // _csrf: csrf
  243. // }
  244. // };
  245. // try {
  246. // const response = await axios.get('/attachments/get_chunks', params);
  247. // file.uploadID = response.data.uploadID;
  248. // file.uuid = response.data.uuid;
  249. // file.uploaded = response.data.uploaded;
  250. // file.chunks = response.data.chunks;
  251. // file.attachID = response.data.attachID;
  252. // file.datasetID = response.data.datasetID;
  253. // file.datasetName = response.data.datasetName;
  254. // file.realName = response.data.fileName;
  255. // return file;
  256. // } catch (error) {
  257. // this.emitDropzoneFailed(file);
  258. // console.log('getSuccessChunks catch: ', error);
  259. // return null;
  260. // }
  261. // },
  262. // async newMultiUpload(file) {
  263. // const res = await axios.get('/attachments/new_multipart', {
  264. // params: {
  265. // totalChunkCounts: file.totalChunkCounts,
  266. // md5: file.uniqueIdentifier,
  267. // size: file.size,
  268. // fileType: file.type,
  269. // type: cloud_brain_type,
  270. // _csrf: csrf
  271. // }
  272. // });
  273. // console.log("dsnjs", res)
  274. // file.uploadID = res.data.uploadID;
  275. // file.uuid = res.data.uuid;
  276. // },
  277. // multipartUpload(file) {
  278. // const blobSlice =
  279. // File.prototype.slice ||
  280. // File.prototype.mozSlice ||
  281. // File.prototype.webkitSlice,
  282. // chunkSize = 1024 * 1024 * 64,
  283. // chunks = Math.ceil(file.size / chunkSize),
  284. // fileReader = new FileReader(),
  285. // time = new Date().getTime();
  286. // let currentChunk = 0;
  287. // function loadNext() {
  288. // const start = currentChunk * chunkSize;
  289. // const end =
  290. // start + chunkSize >= file.size ? file.size : start + chunkSize;
  291. // fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
  292. // }
  293. // function checkSuccessChunks() {
  294. // const index = successChunks.indexOf((currentChunk + 1).toString());
  295. // if (index == -1) {
  296. // return false;
  297. // }
  298. // return true;
  299. // }
  300. // // async function getUploadChunkUrl(currentChunk, partSize) {
  301. // // const res = await axios.get('/attachments/get_multipart_url', {
  302. // // params: {
  303. // // uuid: file.uuid,
  304. // // uploadID: file.uploadID,
  305. // // size: partSize,
  306. // // chunkNumber: currentChunk + 1,
  307. // // type: cloud_brain_type,
  308. // // _csrf: csrf
  309. // // }
  310. // // });
  311. // // urls[currentChunk] = res.data.url;
  312. // // }
  313. // // async function uploadMinio(url, e) {
  314. // // const res = await axios.put(url, e.target.result);
  315. // // etags[currentChunk] = res.headers.etag;
  316. // // }
  317. // // async function updateChunk(currentChunk) {
  318. // // await axios.post(
  319. // // '/attachments/update_chunk',
  320. // // qs.stringify({
  321. // // uuid: file.uuid,
  322. // // chunkNumber: currentChunk + 1,
  323. // // etag: etags[currentChunk],
  324. // // _csrf: csrf
  325. // // })
  326. // // );
  327. // // }
  328. // async function uploadPart(currentChunk, partSize, e) {
  329. // console.log(e);
  330. // let params = new FormData();
  331. // params.append("uuid", file.uuid);
  332. // params.append("uploadId", file.uploadID);
  333. // params.append("size", partSize);
  334. // params.append("chunkNumber", currentChunk + 1);
  335. // params.append("file", e.target.file);
  336. // params.append("_csrf", csrf);
  337. // return await axios.post('/attachments/upload_part',
  338. // params,
  339. // {headers: {'Content-Type': 'multipart/form-data'}}
  340. // );
  341. // }
  342. // async function uploadChunk(e) {
  343. // try {
  344. // if (!checkSuccessChunks()) {
  345. // const start = currentChunk * chunkSize;
  346. // const partSize =
  347. // start + chunkSize >= file.size ? file.size - start : chunkSize;
  348. // await uploadPart(currentChunk, partSize, e);
  349. // // 获取分片上传url
  350. // // await getUploadChunkUrl(currentChunk, partSize);
  351. // // if (urls[currentChunk] != '') {
  352. // // // 上传到minio
  353. // // await uploadMinio(urls[currentChunk], e);
  354. // // if (etags[currentChunk] != '') {
  355. // // // 更新数据库:分片上传结果
  356. // // //await updateChunk(currentChunk);
  357. // // } else {
  358. // // console.log("上传到minio uploadChunk etags[currentChunk] == ''");// TODO
  359. // // }
  360. // // } else {
  361. // // console.log("uploadChunk urls[currentChunk] != ''");// TODO
  362. // // }
  363. // }
  364. // } catch (error) {
  365. // console.log(error);
  366. // this.emitDropzoneFailed(file);
  367. // }
  368. // }
  369. // async function completeUpload() {
  370. // return await axios.post(
  371. // '/attachments/complete_multipart',
  372. // qs.stringify({
  373. // uuid: file.uuid,
  374. // uploadID: file.uploadID,
  375. // file_name: file.name,
  376. // size: file.size,
  377. // dataset_id: file.datasetId,
  378. // type: cloud_brain_type,
  379. // _csrf: csrf
  380. // })
  381. // );
  382. // }
  383. // const successChunks = [];
  384. // let successParts = [];
  385. // successParts = file.chunks.split(',');
  386. // for (let i = 0; i < successParts.length; i++) {
  387. // successChunks[i] = successParts[i].split('-')[0];
  388. // }
  389. // const urls = []; // TODO const ?
  390. // const etags = [];
  391. // console.log('上传分片...');
  392. // this.status = this.dropzoneParams.data('uploading');
  393. // loadNext();
  394. // fileReader.onload = async (e) => {
  395. // await uploadChunk(e);
  396. // fileReader.abort();
  397. // currentChunk++;
  398. // if (currentChunk < chunks) {
  399. // console.log(
  400. // `第${currentChunk}个分片上传完成, 开始第${currentChunk +
  401. // 1}/${chunks}个分片上传`
  402. // );
  403. // this.progress = Math.ceil((currentChunk / chunks) * 100);
  404. // this.updateProgress(file, ((currentChunk / chunks) * 100).toFixed(2));
  405. // this.status = `${this.dropzoneParams.data('uploading')} ${(
  406. // (currentChunk / chunks) *
  407. // 100
  408. // ).toFixed(2)}%`;
  409. // await loadNext();
  410. // } else {
  411. // await completeUpload();
  412. // console.log(
  413. // `文件上传完成:${file.name} \n分片:${chunks} 大小:${
  414. // file.size
  415. // } 用时:${(new Date().getTime() - time) / 1000} s`
  416. // );
  417. // this.progress = 100;
  418. // this.status = this.dropzoneParams.data('upload-complete');
  419. // this.finishUpload(file);
  420. // }
  421. // };
  422. // }
  423. // }
  424. // };
  425. // </script>
  426. <style>
  427. .dropzone-wrapper {
  428. margin: 2em auto;
  429. }
  430. .ui .dropzone {
  431. border: 2px dashed #0087f5;
  432. box-shadow: none !important;
  433. padding: 0;
  434. min-height: 5rem;
  435. border-radius: 4px;
  436. }
  437. .dataset .dataset-files #dataset .dz-preview.dz-file-preview,
  438. .dataset .dataset-files #dataset .dz-preview.dz-processing {
  439. display: flex;
  440. align-items: center;
  441. }
  442. .dataset .dataset-files #dataset .dz-preview {
  443. border-bottom: 1px solid #dadce0;
  444. min-height: 0;
  445. }
  446. </style>