gistfile1.txt /// /// /// /// 'use strict';/*** 这个是oss的管理类** 事件:StartCalculatorMd5、CalculatorMd5Progress、CalculatorMd5Finished* StartCalculatorMd5 event:{File:"上传的文件对象"}* CalculatorMd5Progress event:
/// /// /// /// 'use strict'; /** * 这个是oss的管理类 * * 事件:StartCalculatorMd5、CalculatorMd5Progress、CalculatorMd5Finished * StartCalculatorMd5 event:{File:"上传的文件对象"} * CalculatorMd5Progress event: {File: "上传的文件对象",Percent: "上传的百分比"} * CalculatorMd5Finished event:{ File: "上传的文件对象",Md5: "计算出来的文件的md5码"} * UploadProgress event:{} * UploadSuccess event:{} * UploadFail event:{} * * parms: * url:获取token的url地址 * validtime:获取的token的有效时长 * chunkSize:文件进行分片上传时的分片大小 * bucket:文件上传的桶 * multipartuploadmaxRetry:分片上传时最大的重试次数 * keygeneratefunc:key的生成函数 参数:[OssUploadManager,进行上传的文件对象] * osshead_single_user:文件上传时用户自定义的head生成函数 参数:[ossmanager,预设的头信息, 上传文件对象] * osshead_single_user:文件上传时用户自定义的head生成函数 参数:[ossmanager,预设的头信息, 上传文件对象] * */ //token url //token有效时间 function OssUploadManager(parms) { if (typeof parms !== "object") { throw new Error("参数错误"); } ClassEvent.call(this);//属性继承 if (!parms.tokenurl || !parms.tokenvalidtime || !parms.bucket || !parms.endpoint) { throw new Error("参数错误"); } this.ststoken = new ststokenmanager({ requesturl: parms.tokenurl, //'http://sts.lichengsoft.com/GetSTS', tokenvalidtime: parms.tokenvalidtime // 30 * 1000 }); if (parms.tokenrequestsuccessfunc && typeof parms.tokenrequestsuccessfunc === "function") { this.ststoken.requestsuccessfunc = parms.tokenrequestsuccessfunc } this.chunkSize = parms.chunkSize || 1024 * 1024 * 4;//进行分片的大小 this.bucket = parms.bucket;// "hz-pub";//上传的bucket this.multipartuploadmaxRetry = parms.multipartuploadmaxRetry || 3;//分片上传时失败的最大重试次数 this.concurrency = parms.concurrency || 2; this.oss = new ALY.OSS({ endpoint: parms.endpoint, apiVersion: '2013-10-15' });//aliyun oss对象 this.FileArray = [];//文件上传数组 this.keygeneratefunc = parms.keygeneratefunc || function (ossm, file) { return file.OssUploadControlParm.MD5; //ossm.bucket + "/" + file.OssUploadControlParm.MD5; }//key生成函数 用户实现 } OssUploadManager.FileUploadState = { UnStart: 0, Uploading: 1, Success: 2, Fail: 3 } OssUploadManager.prototype.Upload = function (file) { //file = file || {}; if (this.FileArray.indexOf(file) != -1) { //文件已经添加到上传处理区 if (file.OssUploadControlParm.RelativeFileIndex !== undefined) { var relfile = this.FileArray[file.OssUploadControlParm.RelativeFileIndex]; if (relfile.OssUploadControlParm.OssUploadState === OssUploadManager.FileUploadState.Fail) { this.upload(relfile); } } else { if (file.OssUploadControlParm.OssUploadState === OssUploadManager.FileUploadState.Fail || file.OssUploadControlParm.OssUploadState === OssUploadManager.FileUploadState.UnStart) { this.upload(file); } } return; } file.OssUploadControlParm = {}; file.OssUploadControlParm.OssUploadIndex = this.getfileindex();//为每一个进行上传的文件设置一个编号 file.OssUploadControlParm.OssUploadState = OssUploadManager.FileUploadState.UnStart;//还为开始上传 this.FileArray.push(file);//将文件添加到文件队列中 this.calculatormd5(file);//计算文件的md5值 } OssUploadManager.prototype.Cancel = function (file) { var fileindex = this.FileArray.indexOf(file) if (fileindex != -1) { if (file.OssUploadControlParm.OssUploadState === OssUploadManager.FileUploadState.Uploading) { file.OssUploadControlParm.UploadRequest.abort(); delete file.OssUploadControlParm; this.FileArray.splice(fileindex, 1); this.ExcuteEvent("Cancel", this, { File: file }); } } } OssUploadManager.prototype.getfileindex = function () { return this.FileArray.length; } OssUploadManager.prototype.calculatormd5 = function (file) { var self = this; self.ExcuteEvent("StartCalculatorMd5", self, { File: file }); CalculatorFileMD5(file, function (calfile, block) { self.ExcuteEvent("CalculatorMd5Progress", self, { File: file, Percent: block.end / block.file_size }) }, function (calfile, result) { self.ExcuteEvent("CalculatorMd5Finished", self, { File: file, Md5: result.md5 }); file.OssUploadControlParm.MD5 = result.md5;//设置文件的md5 self.uploadfile(file);//上传文件 }); } OssUploadManager.prototype.uploadfile = function (file) { //判断是否有相同的文件已经上传或正在上传 this.relativefile(file); } OssUploadManager.prototype.relativefile = function (file) { //关联文件 相同的文件进行关联 var same = this.findallsamefile(file);//不包括自己 if (same.length == 0) { //表示没有相同的文件已经上传 直接进行文件上传操作 this.upload(file); } else { //表示有相同的文件,此时进行文件的关联操作 if (same[0].OssUploadControlParm.RelativeFileIndex !== undefined) { file.OssUploadControlParm.RelativeFileIndex = same[0].OssUploadControlParm.RelativeFileIndex; } else { file.OssUploadControlParm.RelativeFileIndex = same[0].OssUploadControlParm.OssUploadIndex; } var refile = this.FileArray[file.OssUploadControlParm.OssUploadIndex]; if (refile.OssUploadControlParm.OssUploadState === OssUploadManager.FileUploadState.Success) { //调文件上传完成函数 this.filesuccess(file, {}); } else if (refile.OssUploadControlParm.OssUploadState === OssUploadManager.FileUploadState.Fail) { //调文件上传失败函数 对失败的文件进行重新上传 this.filefail(file, {}); } } } OssUploadManager.prototype.findallsamefile = function (file) { var samefile = []; for (var i = 0; i < this.FileArray.lengt; i++) { if (file.OssUploadControlParm.MD5 && this.FileArray[i].OssUploadControlParm.MD5 && file.OssUploadControlParm.MD5 === this.FileArray[i].OssUploadControlParm.MD5 && file.OssUploadControlParm.OssUploadIndex !== this.FileArray[i].OssUploadControlParm.OssUploadIndex) { samefile.push(this.FileArray[i]); } } return samefile; } OssUploadManager.prototype.upload = function (file) { file.OssUploadControlParm.OssUploadState = OssUploadManager.FileUploadState.Uploading; var self = this; var self = this; this.ststoken.gettoken().done(function (data) { //this.oss set key start uploadfile file.OssUploadControlParm.Key = self.keygeneratefunc(self, file); self.oss.config.accessKeyId = data.Credentials.AccessKeyId; self.oss.config.secretAccessKey = data.Credentials.AccessKeySecret; self.oss.config.securityToken = data.Credentials.SecurityToken; //default 默认为进行文件是否已经存在的检测操作 //if (true) { // self.askisexists(file); //} else { self.ossupload(file); //} }).fail(function () { //文件上传状态改为失败 触发上传失败事件 self.filefail(file, {}); }) } //向远程服务器询问文件是否已经进行了上传 OssUploadManager.prototype.askisexists = function (uploadfile) { var self = this; this.oss.headObject({ Bucket: this.bucket, Key: uploadfile.OssUploadControlParm.Key,//需要一个key的实现函数 }, function (error, data) { if (error) { //表示文件不存在 self.ossupload(uploadfile); } else { //表示文件存在 self.filesuccess(uploadfile); } }) } OssUploadManager.prototype.ossupload = function (uploadfile) {//uploadfile:上传的文件 var self = this; var file = uploadfile; var readFile = function (callback) { var result = { chunksHash: {}, chunks: [] }; var blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice; var chunkSize = self.chunkSize; //self._config.chunkSize; var chunksNum = Math.ceil(file.size / chunkSize); var currentChunk = 0; var frOnload = function (e) { result.chunks[currentChunk] = e.target.result; currentChunk++; if (currentChunk < chunksNum) { loadNext(); } else { result.file_size = file.size; callback(null, result); } }; var frOnerror = function () { self.filefail(uploadfile, { ErrReason: "读取文件失败" }); }; function loadNext() { var fileReader = new FileReader(); fileReader.onload = frOnload; fileReader.onerror = frOnerror; var start = currentChunk * chunkSize, end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize; var blobPacket = blobSlice.call(file, start, end); fileReader.readAsArrayBuffer(blobPacket); } loadNext(); }; var uploadSingle = function (result, callback) { var params = self.osshead_single(uploadfile, result); if (typeof self.osshead_single_user === "function") self.osshead_single_user(self, params, uploadfile); var req = self.oss.putObject(params, callback); req.on('httpUploadProgress', function (p) { self.fileprocess(uploadfile, p); }); }; var uploadMultipart = function (result, callback) { var maxUploadTries = self.multipartuploadmaxRetry; var uploadId; var loadedNum = 0; var latestUploadNum = -1; var concurrency = 0; var multipartMap = { Parts: [] }; var init = function () { var params = self.osshead_multipart(uploadfile, result, callback); if (typeof self.osshead_multipart_user === "function") { self.osshead_multipart_user(self, params, uploadfile); } self.oss.createMultipartUpload(params, function (mpErr, res) { if (mpErr) { // console.log('Error!', mpErr); callback(mpErr); return; } // console.log("Got upload ID", res.UploadId); uploadId = res.UploadId; uploadPart(0); }); }; var uploadPart = function (partNum) { if (partNum >= result.chunks.length) { return; } concurrency++; if (latestUploadNum < partNum) { latestUploadNum = partNum; } if (concurrency < self.concurrency && (partNum < (result.chunks.length - 1))) { uploadPart(partNum + 1); } var partParams = { Body: result.chunks[partNum], Bucket: self.bucket, //self._config.bucket, Key: uploadfile.OssUploadControlParm.Key,//self.keygeneratefunc(this,uploadfile,result), // options.key, PartNumber: String(partNum + 1), UploadId: uploadId }; var tryNum = 1; var doUpload = function () { multipartMap.Parts[partNum] = { PartNumber: partNum + 1, loaded: 0 }; var req = self.oss.uploadPart(partParams, function (multiErr, mData) { if (multiErr) { // console.log('multiErr, upload part error:', multiErr); if (tryNum > maxUploadTries) { console.log('上传分片失败: #', partParams.PartNumber); callback(multiErr); } else { console.log('重新上传分片: #', partParams.PartNumber); multipartMap.Parts[partNum].loaded = 0; tryNum++; doUpload(); } return; } multipartMap.Parts[partNum].ETag = mData.ETag; multipartMap.Parts[partNum].loaded = partParams.Body.byteLength; // console.log(mData); concurrency--; console.log("Completed part", partNum + 1); //console.log('mData', mData); loadedNum++; if (loadedNum == result.chunks.length) { complete(); } else { uploadPart(latestUploadNum + 1); } }); req.on('httpUploadProgress', function (p) { multipartMap.Parts[partNum].loaded = p.loaded; var loaded = 0; for (var i in multipartMap.Parts) { loaded += multipartMap.Parts[i].loaded; } self.fileprocess(uploadfile, { loaded: loaded, total: uploadfile.size }); }); }; doUpload(); }; var complete = function () { // console.log("Completing upload..."); for (var i in multipartMap.Parts) { delete multipartMap.Parts[i].loaded; } var doneParams = { Bucket: self.bucket, //self._config.bucket, Key: uploadfile.OssUploadControlParm.Key, //self.keygeneratefunc(self,uploadfile), //options.key, CompleteMultipartUpload: multipartMap, UploadId: uploadId }; self.oss.listParts({//获取分片 UploadId: uploadId, Bucket: self.bucket, Key: uploadfile.OssUploadControlParm.Key }, function (err, data) { var parts = data.Parts; multipartMap.Parts = []; var part = null; for (var i = 0; i < parts.length; i++) { part = parts[i]; multipartMap.Parts.push({ PartNumber: part.PartNumber, ETag: part.ETag }); } self.oss.completeMultipartUpload(doneParams, callback); }); }; init(); }; readFile(function (err, result) { var callback = function (err, res) { if (err) { self.filefail(uploadfile, err);//上传失败处理 return; } self.filesuccess(uploadfile, res); }; if (result.chunks.length == 1) { uploadSingle(result, callback) } else { uploadMultipart(result, callback); } }); }; //文件上传百分比处理函数 OssUploadManager.prototype.fileprocess = function (file, event) { var relative = this.findallrelativefile(file); relative.push(file); for (var i = 0; i < relative.length; i++) { this.ExcuteEvent("UploadProgress", this, { File: relative[i], Percent: event.loaded / event.total * 100 }) } } //文件上传成功处理函数 OssUploadManager.prototype.filesuccess = function (file, event) { file.OssUploadControlParm.OssUploadState = OssUploadManager.FileUploadState.Success; var relative = this.findallrelativefile(file); relative.push(file); for (var i = 0; i < relative.length; i++) { this.ExcuteEvent("UploadSuccess", this, { File: relative[i] }) } } //文件上传失败处理函数 OssUploadManager.prototype.filefail = function (file, event) { file.OssUploadControlParm.OssUploadState = OssUploadManager.FileUploadState.Fail; var relative = this.findallrelativefile(file); relative.push(file); for (var i = 0; i < relative.length; i++) { this.ExcuteEvent("UploadFail", this, { File: relative[i] }) } } OssUploadManager.prototype.findallrelativefile = function (file) {//获取所有的关联在改文件上的文件 var relative = []; for (var i = 0; i < this.FileArray.length; i++) { if (this.FileArray[i].OssUploadControlParm.RelativeFileIndex !== undefined && this.FileArray[i].OssUploadControlParm.RelativeFileIndex === file.OssUploadControlParm.OssUploadIndex) { relative.push(this.FileArray[i]); } } return relative; } OssUploadManager.prototype.osshead_single = function (uploadfile, result, callback) { var params = { Bucket: this.bucket, Key: uploadfile.OssUploadControlParm.Key,//需要一个key的实现函数 Body: result.chunks[0], ContentType: uploadfile.type || '' }; return params; } OssUploadManager.prototype.osshead_multipart = function (uploadfile, result, callback) { var params = { Bucket: this.bucket, Key: uploadfile.OssUploadControlParm.Key, ContentType: uploadfile.type || '' }; return params; } OssUploadManager.prototype = Extend({}, ClassEvent.prototype, OssUploadManager.prototype) //OssUploadManager.prototype.ExtendFile = function (file) { // [{ "FILENAME": "test0 - 副本 (4).pdf", "FILEPATHNAME": "C:/Usersenk/Desktop/testPDF/test0 - 副本 (4).pdf", "FILETYPE": "PDF", "MD5": "9e95ad55d9e4f0e83d72ab3630e6316e", "SIZE": 161770, "UUID": "77f160fa-467d-49c1-ae3a-2182cf8c123d" }] //}