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" }]
//}
