自定义分片上传字段
有用户说要断点续传,然后自己没研究过,但是发现webupload里支持分片上传的,就研究实现了下,本来试了一个stream js 但是在海豚里各种ui没调通。
还有官方手册,终于把他搞出来了。
思路,第一自己扩展sendFile 事件第二,改变分片上传参数,包括上传地址
第三 实现分片上传的方法。
WebUploader.Uploader.register({注册send-file事件
"name": "cutfile_uploader",
"before-send": "beforeSend" // 整个文件上传前
}, {
beforeSend:function(block){
var deferred = WebUploader.Deferred();
if(is_upload)//跳过到开始上传的哪一个分片时
{
deferred.resolve();
}else if(totalFiles) {
//已经获取过文件数量则直接判断是否跳过
//当前分片下标小于等于目录下的文件数量就认为分块存在,因为分块上传下标是由小到大
// console.log(block.chunk);
// console.log(totalFiles);
// console.log(!totalFiles.in_array(block.chunk));
if (!totalFiles.in_array(block.chunk - 1)) {
deferred.resolve();
} else {
//分块存在,跳过
deferred.reject();
}
} else {
$.post(cutfile_conf.check_upload_url, {md5: fileMd5}, function (data) {
console.log(data);
if (data.code) {
totalFiles = data.data;
//当前分片下标小于等于目录下的文件数量就认为分块存在,因为分块上传下标是由小到大
if (!data.data.in_array(block.chunk-1)) {
deferred.resolve();
} else {
//分块存在,跳过
deferred.reject();
}
} else {
is_upload = true;
deferred.resolve();
}
}, 'json');
}
}
});
// 当有文件添加进来的时候修改file-queueshi事件,主要是每次上传时不光传file 对象还将原始md5传过去用于组成分片的文件用,方便最终检测是否存在已传过的分片。这里面有一个大坑,
uploader.on( 'fileQueued', function( file ) {
console.log(new Date());
// 设置当前上传对象
curr_uploader = uploader;
uploader.md5File( file )
// 完成
.then(function(val) {
fileMd5 = val;
var formData = uploader.option('formData');
// console.log('md5 result:', val);
formData.md5 = fileMd5;
// console.log(formData);
uploader.option('formData',formData);
// console.log(uploader.option('formData'));
});
var $li = '<li id="' + file.id + '" class="list-group-item file-item">' +
'<span class="pull-right file-state"><span class="text-info"><i class="fa fa-sun-o fa-spin"></i> 正在读取文件信息...</span></span>' +
'<i class="fa fa-file"></i> ' +
file.name +
' [<a href="javascript:void(0);" class="download-file">下载</a>] [<a href="javascript:void(0);" class="remove-file">删除</a>]' +
'<div class="progress progress-mini remove-margin active" style="display: none"><div class="progress-bar progress-bar-primary progress-bar-striped" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%"></div></div>'+
'</li>';
if ($multiple) {
$file_list.append($li);
} else {
$file_list.html($li);
// 清空原来的数据
$input_file.val('');
}
});
curr_uploader = uploader; 这个设置的在form.js里
WebUploader.Uploader.register({
"before-send-file": "beforeSendFile" // 整个文件上传前
}, {
beforeSendFile:function(file){
var $li = $( '#'+file.id );
var deferred = WebUploader.Deferred();
var owner = this.owner;
owner.md5File(file).then(function(val){
$.ajax({
type: "POST",
url: dolphin.upload_check_url,
data: {
md5: val
},
cache: false,
timeout: 10000, // 超时的话,只能认为该文件不曾上传过
dataType: "json"
}).then(function(res, textStatus, jqXHR){
if(res.code){
// 已上传,触发上传完成事件,实现秒传
deferred.reject();
curr_uploader.trigger('uploadSuccess', file, res);
curr_uploader.trigger('uploadComplete', file);
}else{
// 文件不存在,触发上传
deferred.resolve();
$li.find('.file-state').html('<span class="text-info">正在上传...</span>');
$li.find('.img-state').html('<div class="bg-info">正在上传...</div>');
$li.find('.progress').show();
}
}, function(jqXHR, textStatus, errorThrown){
// 任何形式的验证失败,都触发重新上传
deferred.resolve();
$li.find('.file-state').html('<span class="text-info">正在上传...</span>');
$li.find('.img-state').html('<div class="bg-info">正在上传...</div>');
$li.find('.progress').show();
});
});
return deferred.promise();
}
});
里面的 妙传实现时 出发已有的webload uploadSuccess 会报为定义的方法,必须修改 form.js
将var curr_uploader = {}; 这个定义提到$(function(){ 外,变为全局变量。前端我也不太懂,
总之官方的实现 不管表单里有没有webupload 都跑去注册了一下事件,然后才加载init.js 自定义表单项的js 并且我试了用官方的 unregistered webupload 都无效。官方要考虑一下扩展性,或者官方支持分片最好。对应的上传和检测 方法我已经更改了admin里的ajax 实现了。
所以官方的自定义字段的后端实现 也不知道如何去扩展一个控制器方法。
大家把我的附件解压放到项目里,只支持1.1.0 以上。 然后修改一行form.js 就可以了。
参考页面:
public function index(){有个疑惑,看了很多文章,chunk 发现upload都是1开始 而webupload里是从0开始的。
return ZBuilder::make('form')
->setPageTitle('分片上传')
->addCutfile('file', '上传')
->fetch();
}
还有感觉获取本地信息检查妙传总感觉卡,还有断电续传的进度 不想现象的 自动晚上长,但是请求数确实会比重新传的分片数要少。希望官方参考本文章增加一个分片上传的字段体验完整的功能
1 个评论
参考着基于THINKPHP5 使用webuploader 大文件分片上传合并和php结合webuploader断点续传的实现