WebApp【公共组件库】@前端(For Git Submodule)
Tevin
2022-07-16 1df4c2f070e8105aedf16437f8124b4d692b47d0
实现文件转换组件
1 files added
148 ■■■■■ changed files
common/FileTransform.js 148 ●●●●● patch | view | raw | blame | history
common/FileTransform.js
New file
@@ -0,0 +1,148 @@
/**
 * 文件转换
 * @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();