記錄關於圖片點選多張上傳的問題
阿新 • • 發佈:2018-12-15
/** * description: 騰訊雲上傳檔案 */ import { app } from '@/config/env' import Vue from 'vue' import { Message, Loading } from 'element-ui' /* eslint-disable */ /** * imageView2/w/300/q/60 */ const region = 'gz'; const filterImg = ['image/jpeg', 'image/png', 'image/gif', 'image/bmp']; const filter = ['image/jpeg', 'image/png', 'image/gif', 'image/bmp', 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document']; const UploadFileByTXY = { imgFile: null, verifyBase64: null, path: '/szajimgs/', imgURLdomain: app.domain, upload: function ({ id, callback, type, maxSize }, clip=false) { if(!id) return; let self = this, el = document.getElementById(id), file = null, size = null, fileName = null, fileType = null; let loading = null; // 監聽file元素改變事件 el.addEventListener('change',function (e) { let date = new Date().getTime() + (Math.random() * 1000000).toFixed(0); file = this.files[0]; self.imgFile = file; if(!file) return false size = file.size; fileName = date + '.' + file.name.substr(file.name.lastIndexOf('.') + 1) fileType = file.type; if (!type && filterImg.indexOf(fileType) < 0) { let docTip = '上傳支援jpg,png等格式檔案上傳'; el.value = ''; alert(docTip); return; } if (type === 'doc') { self.path = '/doc/' } else { self.path = '/szajimgs/' } console.log(self.path) console.log(fileType) if (type === 'doc' && filter.indexOf(fileType) < 0) { let docTip = '上傳支援jpg,png,doc等格式檔案上傳'; el.value = ''; alert(docTip); return; } //過濾檔案大小 console.log(size) if (maxSize) { if (size >= 1024*1024*maxSize) { Vue.prototype.$alert(`檔案大小不超過${maxSize}M`, '上傳檔案錯誤') el.value = '' return } } if (!type && window.FileReader) { var fr = new FileReader(); fr.onload = function(e) { var imgBase64 = e.target.result; self.verifyBase64 = imgBase64; let canvasImg = self.compressImg(imgBase64, size, fileType, self.convertBase64UrlToBlob, uploadImg); } fr.readAsDataURL(file); } console.log('fff') let c = '' let canvasPopup = '' let uploadImg = () => { Vue.Post('xxxxxxxxx', { cosPath: self.path + fileName, ...app }).then(json => { if (json.code === '0000') { // 請求成功 let sign = json.data.sign // 例項化 cos let cos = new CosCloud({ appid: app.appid, bucket: app.bucket, region: region, getAppSign: function (callback) { callback(sign) }, getAppSignOnce: function (callback) { callback(sign) } }) // 圖片上傳 cos.uploadFile(successCallBack, errorCallBack, progressCallBack, app.bucket, self.path + fileName, self.imgFile, 1); } else { // 請求失敗 alert('獲取檔案上傳簽名失敗!') } }) } if (type === 'doc') { loading = Loading.service({ fullscreen: true, text: `正在上傳` }); uploadImg() } }) // 上傳成功回撥 let successCallBack = (result) => { /* data.access_url 生成的檔案CDN下載url data.source_url 生成的檔案COS源站url data.url 操作檔案的url data.resource_path 資源路徑. 格式:/appid/bucket/xxx */ if (result.code === 0) { let obj = {}; let data = result.data; obj.verifyBase64 = this.verifyBase64; obj.url = app.domain + this.path + fileName; if (type === 'doc') { obj.url = data.source_url } obj.fileName = fileName; typeof callback === 'function' && callback(obj); } else { alert('上傳失敗'); } loading.close() } // 上傳失敗回撥 let errorCallBack = (result = {}) => { loading.close() alert(JSON.stringify(result)) alert('上傳失敗!請嘗試在穩定網路環境上傳!'); } // 上傳過程中回撥 let progressCallBack = (curr) => { // loading.text = `上傳中: ${(curr * 100).toFixed(2)}%` } }, multiUpload: function ({ id, callback, upLoadOver, maxSize}) { if(!id) return; let el = document.getElementById(id); let filess = ''; let self = this; let path = '/szajimgs/'; self.path = '/szajimgs/'; let fileName = ''; let fileType = ''; let loading = null; let date = new Date().getTime(); let fileNum = 0, upOrder = 0, files = null; const imgFilter = ['image/jpeg', 'image/png', 'image/gif'] // 監聽file元素改變事件 el.addEventListener('change',function (e) { self.path = '/szajimgs/'; files = this.files; if (files && files.length < 1) return false upOrder = 0 fileNum = files.length if (fileNum > 20) { Message({ showClose: true, message: '每次最多同時上傳20張圖片!', type: 'error' }); return false } for (var i = files.length - 1; i >= 0; i--) { if (imgFilter.indexOf(files[i].type) < 0) { el.value = ''; Message({ showClose: true, message: '僅支援JPEG、PNG圖片檔案格式上傳', type: 'error' }); return false; } //過濾檔案大小 if (maxSize) { if (files[i].size >= 1024*1024*maxSize) { Vue.prototype.$alert(`檔案大小不超過${maxSize}M`, '上傳檔案錯誤') el.value = '' return } } } loading = Loading.service({ fullscreen: true, text: `正在上傳第 ${upOrder + 1} 張圖片: 0%`}); uploadImg(); }) // 批量上傳圖片 const uploadImg = function () { if (upOrder === 0) { filess = Array.from(el.files) // 第二次呼叫被莫名清空 第一次進入用陣列的方式監聽方法內全域性儲存下來 } let file = filess[upOrder]; date = new Date().getTime(); fileName = date + '.' + file.name.substr(file.name.lastIndexOf('.') + 1) fileType = file.type; // axiosPost(getUploadSign, { cosPath: path + fileName }).then(json => { Vue.Post('xxxxxxxx', { cosPath: self.path + fileName, ...app }).then(json => { if (json.code === '0000') { // 請求成功 let sign = json.data.sign // 例項化 cos let cos = new CosCloud({ appid: app.appid, bucket: app.bucket, region: region, getAppSign: function (callback) { callback(sign) }, getAppSignOnce: function (callback) { callback(sign) } }) // 批量上傳圖片成功回撥 const successCallBack = (result) => { if (result.code === 0) { let upImgPath = app.domain + '/szajimgs/' + fileName; typeof callback === 'function' && callback(upImgPath); goNext() } else { console.error(`第 ${upOrder} 張圖片上傳失敗`) Message({ showClose: true, message: `第 ${upOrder} 張圖片上傳失敗`, type: 'error' }); } } // 批量上傳圖片過程中回撥 const progressCallBack = (curr) => { loading.text = `正在上傳第 ${upOrder+1} 張圖片: ${(curr * 100).toFixed(2)}%` } // 批量上傳圖片失敗回撥 const errorCallBack = (result = {}) => { goNext() } const goNext = () => { upOrder++ if (upOrder < fileNum) { uploadImg() } else { loading.close() typeof upLoadOver === 'function' && upLoadOver(); } } // 圖片上傳 cos.uploadFile(successCallBack, errorCallBack, progressCallBack, app.bucket, path + fileName, file, 1); } else { // 請求失敗 console.log('獲取檔案上傳簽名失敗!') Message({ showClose: true, message: `獲取檔案上傳簽名失敗!`, type: 'error' }); } }) } }, compressImg: function(imgBase64, size, fileType, buildFile, uploadImg, maxHeight = 600, quality = 0.7){ if(!imgBase64) return; let self = this let img = document.createElement('img'); img.src = imgBase64; img.onload = function(){ var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); //壓縮率設定 let s = size / 1024; if(s < 50){ maxHeight = img.height; }else if(s >= 50 && s < 500){ maxHeight = 600; }else if(s >= 500 && s < 1024){ maxHeight = 450; }else if(s >= 1024 && s < 2*1024){ maxHeight = 450; } else if(s >= 2*1024 && s < 3*1024) { maxHeight = 450; } else{ maxHeight = 600; } if(img.height > maxHeight) {//按最大高度等比縮放 img.width *= maxHeight / img.height; img.height = maxHeight; } // canvas drawImage 引數 let sx = 0; let sy = 0; let sWidth = img.width; let sHeight = img.height; canvas.width = img.width; canvas.height = img.height; // canvas清屏 context.clearRect(0, 0, canvas.width, canvas.height) context.drawImage(img, sx, sy, sWidth, sHeight) let imgBase64 = canvas.toDataURL('image/jpeg', quality) buildFile && (self.imgFile = buildFile(imgBase64, fileType)) uploadImg && uploadImg() return imgBase64 } }, convertBase64UrlToBlob: function (imgBase64, fileType){ var bytes=window.atob(imgBase64.split(',')[1]) // 去掉url的頭,並轉換為byte //處理異常,將ascii碼小於0的轉換為大於0 var ab = new ArrayBuffer(bytes.length); var ia = new Uint8Array(ab); for (var i = 0; i < bytes.length; i++) { ia[i] = bytes.charCodeAt(i); } return new Blob( [ab] , {fileType}); } } export default UploadFileByTXY; /* eslint-enable */