import { Constants } from './contants' import getFilemd5sum from './utils' function FileFactory(file) { this.offset = 0; //用于断点续传,默认为 0 this.BYTES_PER_CHUNK = 1024 * 1024 this.file = file this.fileSize = file.size this.fileType = (file.name.split('.')[1]).toLowerCase() this.chunkNum = this.BYTES_PER_CHUNK > this.fileSize ? Math.ceil(this.fileSize / this.BYTES_PER_CHUNK) : 1 this.chunkSize = this.BYTES_PER_CHUNK > this.fileSize ? this.fileSize : this.BYTES_PER_CHUNK } FileFactory.prototype.setOffset = function (offset) { this.offset = offset } export default function UploadSdk(host, origin, token, file) { this.handlers = [] //用于处理出触发事件 this.host = host.indexOf('http:') > -1 ? 'http:'+ host: host this.origin = origin this.token = token this.file = file this.generateMd5 = function (callback) { getFilemd5sum(this.file).then(result => { callback(result) }) } this.imageUploadAction = function () { return new Promise((resolve, reject) => { let fileFactory = new FileFactory(this.file) if (!fileFactory.fileType.match('[(jpg)|(png)|(gif)]+$')) { reject(Constants.IMAGE_TYPE_ERROR) } this.generateMd5((md5) => { this.md5 = md5 this.postImage(this.md5, fileFactory).then(res => { resolve(res) }).catch((err) => { reject(err) }) }) }) } this.videoUploadAction = function () { return new Promise((resolve, reject) => { if (!this.file.type.match('[(mp4)|(rmvb)|(flv)|(mpeg)|(avi)]+$')) { reject(Constants.VIDOE_TYPE_ERROR) } this.postVideo().then(res => { resolve(res) }).catch((err) => { reject(err) }) }) } this.postVideo = function () { const self = this return new Promise((resolve, reject) => { let xhr = new XMLHttpRequest() xhr.open('POST', this.host + Constants.VIDEO_MULTIPART + this.origin, true) xhr.withCredentials = true; xhr.setRequestHeader('Authorization', `Bearer ${this.token}`) xhr.setRequestHeader('Content-type', 'application/json') xhr.upload.addEventListener("progress", function updateProgress(oEvent) { if (oEvent.lengthComputable) { let percentComplete = oEvent.loaded / oEvent.total * 100; self.emitUpdateProgress(percentComplete) } }, false) let fd = new FormData() fd.append('file', this.file) fd.append('code_rate', 'ld,sd,hd') xhr.send(fd) xhr.onreadystatechange = function () { if (xhr.readyState === 4) { let obj = JSON.parse(xhr.responseText) if (xhr.status === 304 || (xhr.status >= 200 && xhr.status < 300)) { resolve({ code: Constants.UPLOAD_SUCCESS_CODE, url: obj.url, msg: 'success' }) } else { reject({ code: Constants.UPLOAD_FAILED_CODE, url: '', msg: obj.message }) } } } }) } this.postImage = function (md5, fileFactory) { const self = this return new Promise((resolve, reject) => { let xhr = new XMLHttpRequest() xhr.upload.addEventListener("progress", function updateProgress(oEvent) { if (oEvent.lengthComputable) { let percentComplete = oEvent.loaded / oEvent.total * 100; self.emitUpdateProgress(percentComplete) } }, false) xhr.open('POSt', this.host + Constants.IMAGE_MULTIPART + this.origin, true) xhr.withCredentials = true xhr.setRequestHeader('Authorization', `Bearer ${this.token}`) xhr.setRequestHeader('X-Upload-File-Size', fileFactory.fileSize) xhr.setRequestHeader('X-Upload-Chunk-Index', 1 + '') xhr.setRequestHeader('X-Upload-Chunk-Num', fileFactory.chunkNum) xhr.setRequestHeader('X-Upload-Chunk-Size', fileFactory.chunkSize) xhr.setRequestHeader('X-Upload-Offset', fileFactory.offset + '') xhr.setRequestHeader('X-Upload-File-Md5', md5) xhr.setRequestHeader('X-Upload-File-Type', fileFactory.fileType) let fd = new FormData() fd.append('file', this.file) xhr.send(fd) xhr.onreadystatechange = function () { if (xhr.readyState === 4) { let obj = JSON.parse(xhr.responseText) if (xhr.status === 304 || (xhr.status >= 200 && xhr.status < 300)) { if (obj.status === 1) { resolve({ code: Constants.UPLOAD_SUCCESS_CODE, url: obj.url, msg: 'success' }) } else if (obj.status === 0) { fileFactory.setOffset(obj.msg) this.getAllResponseHeaders.postImage(md5, fileFactory) } } else { reject({ code: Constants.UPLOAD_FAILED_CODE, url: '', msg: obj.message }) } } } }) } } UploadSdk.prototype = { onUpdateProgress: function(subscriber){ let isExist = this.handlers.some(function(item){ return item == subscriber; }) if(!isExist){ this.handlers.push(subscriber); } return this; }, emitUpdateProgress: function(data){ this.handlers.forEach(function(fn){ fn(data) }) return this; } }