WebApp【公共组件库】@前端(For Git Submodule)
Tevin
2025-03-19 b82f583d8222f8740afa2d1532db93832c4a5274
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/**
 * 文件转换
 * @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 数据体(用于java通讯)
     * @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(用于java通讯)
     * @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;
    }
 
    /**
     * 读取文件 base64
     * @param {File} file
     * @param {Function} callback
     */
    getFileBase64(file, callback) {
        const reader = new FileReader();
        reader.onload = () => callback(reader.result);
        reader.onerror = error => callback(null, error);
        reader.readAsDataURL(file);
    }
 
}
 
export const $fileTrans = new FileTransform();