New file |
| | |
| | | /** |
| | | * 文件转换 |
| | | * @author Tevin |
| | | */ |
| | | |
| | | import moment from 'moment'; |
| | | |
| | | export class FileTransform { |
| | | |
| | | constructor() { |
| | | this._data = { |
| | | chunkSize: 20 * 1024, |
| | | }; |
| | | } |
| | | |
| | | getChunkSize() { |
| | | return this._data.chunkSize; |
| | | } |
| | | |
| | | setChunkSize() { |
| | | return this._data.chunkSize; |
| | | } |
| | | |
| | | /** |
| | | * 转换 ObjectURL 为 base64 数据体 |
| | | * @param objUrl |
| | | * @param callback |
| | | */ |
| | | transObjUrlToBaseData(objUrl, callback) { |
| | | this.convertObjectUrlToBlob(objUrl, blob => { |
| | | this.convertBlobToBase64(blob, base64 => { |
| | | const mime = base64.split(',')[0].match(/:(.*?);/)[1]; |
| | | const fileName = this._makeFileName(mime); |
| | | const baseArr = this.splitBase64ToArray(base64); |
| | | callback && callback({ |
| | | fileName, |
| | | baseArr, |
| | | total: baseArr.length, |
| | | }); |
| | | }); |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * 转换 base64 数据体为 ObjectURL |
| | | * @param baseData |
| | | * @param callback |
| | | */ |
| | | transBaseDataToObjUrl(baseData, callback) { |
| | | const base64 = baseData.baseArr.join(''); |
| | | this.convertBase64ToFile(base64, baseData.fileName, file => { |
| | | this.convertFileToObjectUrl(file, objUrl => { |
| | | callback && callback(objUrl); |
| | | }); |
| | | }); |
| | | } |
| | | |
| | | convertBlobToBase64(blob, callback) { |
| | | const reader = new FileReader(); |
| | | reader.onload = evt => { |
| | | callback && callback(evt.target.result); |
| | | }; |
| | | reader.readAsDataURL(blob); |
| | | } |
| | | |
| | | convertObjectUrlToBlob(objUrl, callback) { |
| | | const xhr = new XMLHttpRequest(); |
| | | xhr.open('GET', objUrl, true); |
| | | xhr.responseType = 'blob'; |
| | | xhr.onload = function () { |
| | | if (this.status === 200) { |
| | | callback && callback(this.response); |
| | | } else { |
| | | /* eslint-disable prefer-promise-reject-errors */ |
| | | callback && callback(null, { status: this.status }); |
| | | } |
| | | }; |
| | | xhr.send(); |
| | | } |
| | | |
| | | convertBase64ToFile(base64, fileName, callback) { |
| | | const arr = base64.split(','); |
| | | const mime = arr[0].match(/:(.*?);/)[1]; |
| | | const bstr = atob(arr[1]); |
| | | let n = bstr.length; |
| | | const u8arr = new Uint8Array(n); |
| | | while (n--) { |
| | | u8arr[n] = bstr.charCodeAt(n); |
| | | } |
| | | fileName = fileName || this._makeFileName(mime); |
| | | const file = new File([u8arr], fileName, { type: mime }); |
| | | callback && callback(file); |
| | | } |
| | | |
| | | convertFileToObjectUrl(file, callback) { |
| | | let URLMaker = URL; |
| | | if (window) { |
| | | URLMaker = window.URL || window.webkitURL; |
| | | } |
| | | const url = URLMaker.createObjectURL(file); |
| | | callback && callback(url); |
| | | } |
| | | |
| | | // 生成文件名 |
| | | _makeFileName(mime) { |
| | | const curMoment = moment(); |
| | | const name = 'IMG' + curMoment.format('-YYYYMMDD-HHmmss-') + |
| | | curMoment.format('x').substr(-3) + '-' + parseInt(Math.random() * 10000); |
| | | const mimeTypes = { |
| | | 'image/jpeg': 'jpg', |
| | | 'image/gif': 'gif', |
| | | 'image/png': 'png', |
| | | 'image/svg+xml': 'svg', |
| | | 'image/webp': 'webp', |
| | | 'image/tiff': 'tif', |
| | | 'text/plain': 'txt', |
| | | 'text/css': 'css', |
| | | 'text/html': 'html', |
| | | 'text/xml': 'xml', |
| | | 'text/javascript': 'js', |
| | | 'application/x-javascript': 'js', |
| | | 'audio/mpeg': 'mp3', |
| | | 'video/mp4': 'mp4', |
| | | 'video/webm': 'webm', |
| | | 'application/zip': 'zip', |
| | | 'application/rar': 'rar', |
| | | 'application/pdf': 'pdf', |
| | | 'application/rtf': 'rtf', |
| | | }; |
| | | return name + '.' + mimeTypes[mime]; |
| | | } |
| | | |
| | | splitBase64ToArray(base64) { |
| | | const count = Math.ceil(base64.length / this._data.chunkSize); |
| | | if (count === 1) { |
| | | return [base64]; |
| | | } |
| | | const array = []; |
| | | for (let i = 0; i < count; i++) { |
| | | const chunk = base64.substr(this._data.chunkSize * i, this._data.chunkSize); |
| | | array.push(chunk); |
| | | } |
| | | return array; |
| | | } |
| | | |
| | | } |
| | | |
| | | export const $fileTrans = new FileTransform(); |