Files
sentcms/public/static/plugins/webuploader/webuploader.custom.js
2020-03-21 11:17:53 +08:00

484 lines
19 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 以百度上传组件为基础二次封装 插件
* @file webuploader.custom.js
* @author molong <molong@tensent.cn>
* @time 2016年1月12日18:04:09
* @Copyright (c) 2007-2014 http://www.tensent.cn All rights reserved.
*/
/***
* 传递服务器参数
* fileType 文件类型 'sys' 系统文件或 'space' 用户空间图片
* objType sys类型文件存储的路径 'ad' 广告图片 'auth' 认证图片 'mark' 等级图片存放目录 'tools' 增值服务图片存放目录
* filename 文件表单name
* taskId 任务编号
* workId 稿件编号
* 服务器回调json数据
* msg : {url : 文件存储路径, filename : 文件上传表单name, name : 文件名, field : 文件上传后数据表记录id值 }
*/
;(function($, w) {
"use strict";
var pluginName = 'SentUploader';
function Upload($fileInput, options, seropts) {
this.options = $.extend({}, $.fn[pluginName].defaults, options);
this.seropts = seropts; //传递给服务器的参数
this.fileInput = $fileInput;
this.BDUploader = undefined;
this.baseUrl = w.baseurl !== undefined ? w.baseurl : '';
this.allowNum = this.options.fileNumLimit; //剩余上传的个数
}
//插件扩展方法
$.extend(Upload.prototype, {
/**
* 调试开关
*/
debug: false,
/**
* 上传调试输出
*/
dump: function(object) {
if (this.debug) {
if (typeof object == 'object') {
console.dir(object);
} else {
console.log(object);
}
}
},
/**
* 拼接到上传组件的server地址参数 传递给服务器的数据
*/
postData: function() {
var parm = '';
for (var serv in this.seropts) {
parm += "&" + serv + "=" + this.seropts[serv];
}
if (parm != '') {
this.options.server += parm
};
},
absolutePath: function() {
if (this.baseUrl != '') {
this.options.server = this.baseUrl + '/' + this.options.server;
this.options.delUrl = this.baseUrl + '/' + this.options.delUrl;
this.options.swf = this.baseUrl + '/' + this.options.swf;
}
},
/**
* 初始化上传组件,监听各种事件
*/
initUploader: function() {
var self = this;
self.absolutePath();
self.postData();
self.BDUploader = WebUploader.create(self.options);
for (var funcName in self.options.uploadEvents) {
if (typeof self.options.uploadEvents[funcName] == 'function') {
switch (funcName) {
case 'dndAccept': //阻止此事件可以拒绝某些类型的文件拖入进来。目前只有 chrome 提供这样的 API且只能通过 mime-type 验证。
self.BDUploader.on(funcName, function(items) {
self.options.uploadEvents[funcName](items);
});
break;
case 'filesQueued': //当一批文件添加进队列以后触发。
self.BDUploader.on(funcName, function(files) {
self.options.uploadEvents[funcName](files);
});
break;
case 'reset': //当 uploader 被重置的时候触发。
case 'startUpload': //当开始上传流程时触发。
case 'stopUpload': //当开始上传流程暂停时触发。
case 'uploadFinished': //当所有文件上传结束时触发。
self.BDUploader.on(funcName, function() {
self.options.uploadEvents[funcName]();
});
break;
case 'uploadBeforeSend': //当某个文件的分块在发送前触发,主要用来询问是否要添加附带参数,大文件在开起分片上传的前提下此事件可能会触发多次。
self.BDUploader.on(funcName, function(object, data, headers) {
self.options.uploadEvents[funcName](object, data, headers);
});
break;
case 'uploadAccept': //当某个文件上传到服务端响应后会派送此事件来询问服务端响应是否有效。如果此事件handler返回值为false, 则此文件将派送server类型的uploadError事件。
self.BDUploader.on(funcName, function(object, ret) {
self.options.uploadEvents[funcName](object, ret);
});
break;
case 'uploadProgress': //上传过程中触发,携带上传进度。
self.BDUploader.on(funcName, function(file, percentage) {
self.options.uploadEvents[funcName](file, percentage);
});
break;
case 'uploadError': //当文件上传出错时触发。
self.BDUploader.on(funcName, function(file, reason) {
self.options.uploadEvents[funcName](file, reason);
});
break;
case 'uploadSuccess': //当文件上传成功时触发。//用户自定义回调处理
self.BDUploader.on(funcName, function(file, response) {
self.options.uploadEvents[funcName](file, response);
});
break;
case 'error': //当validate不通过时会以派送错误事件的形式通知调用者。通过upload.on('error', handler)可以捕获到此类错误,目前有以下错误会在特定的情况下派送错来。
self.BDUploader.on(funcName, function(type) {
self.options.uploadEvents[funcName](type);
});
break;
case 'beforeFileQueued': //当文件被加入队列之前触发此事件的handler返回值为false则此文件不会被添加进入队列。
case 'fileQueued': //当一批文件添加进队列以后触发。
case 'fileDequeued': //当文件被移除队列后触发。
case 'uploadStart': //某个文件开始上传前触发,一个文件只会触发一次。
case 'uploadComplete': //不管成功或者失败,文件上传完成时触发。
default:
self.BDUploader.on(funcName, function(file) {
self.options.uploadEvents[funcName](file);
});
break;
}
}
}
/**
* 默认上传添加队列处理
*/
if (!self.options.uploadEvents.fileQueued) {
self.BDUploader.on('fileQueued', function(file) {
if (self.allowNum == 0 || self.isAllowUpload() == 0) {
self.BDUploader.removeFile(file);
$.messager.show('上传文件数量超出限制,最多上传' + self.options.fileNumLimit + '个文件', {
placement: 'bottom'
});
return false;
}
if ($("#" + self.options.listName).length > 0) {
//文件上传后 列表显示效果
var divProgress = '<div class="progress file-progress"><div class="progress-bar progress-bar-striped active" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100" style="width: 1%"></div></div>';
var closeHtml = '<span class="webuploader-pick-file-close" data-queued-id="' + file.id + '"><i class="close"></i></span>';
var fileName = '<span class="fname">' + file.name + '</span>';
var fileSize = '<span class="fsize">大小:' + WebUploader.formatSize(file.size) + '</span>';
var fileBox = '<div class="filebox"></div>';
var clearfix = '<div class="clearfix"></div>';
var liHtml = '<li class="affix-list-item" id=' + file.id + '>' + '<div class="upload-file-info">' + closeHtml + fileName + fileSize + clearfix + '</div>' + fileBox + divProgress + '</li>';
$("#" + self.options.listName).append(liHtml);
}
});
}
/**
* 默认上传进度处理
*/
if (!self.options.uploadEvents.uploadProgress) {
self.BDUploader.on('uploadProgress', function(file, percentage) {
var $li = $('#' + file.id),
$percent = $li.find('.progress .progress-bar');
if (percentage > 0.2) {
$percent.text('已上传' + parseInt(percentage * 100, 10) + '%');
}
$percent.css('width', percentage * 100 + '%');
if (percentage == 1) {
$percent.text('上传完成100%').removeClass('active').attr('aria-valuenow', parseInt(percentage * 100, 10));
}
});
}
/**
* 默认文件上传验证错误提示
*/
if (!self.options.uploadEvents.error) {
self.BDUploader.on('error', function(type) {
var title = '',
msg = '',
errtype = 'error';
switch (type) {
case 'Q_EXCEED_NUM_LIMIT':
title = '上传文件数量超出限制';
msg = '最多上传' + self.options.fileNumLimit + '个文件';
break;
case 'F_EXCEED_SIZE':
title = '单个文件大小超出限制';
msg = '最大上传' + WebUploader.formatSize(self.options.fileSingleSizeLimit);
break;
case 'Q_EXCEED_SIZE_LIMIT':
title = '文件总大小超出限制';
msg = '最大上传' + WebUploader.formatSize(self.options.fileSizeLimit);
break;
case 'Q_TYPE_DENIED':
title = '文件类型限制';
msg = self.options.accept.extensions;
break;
case 'F_DUPLICATE':
title = '同名文件已存在';
break;
default:
title = '未知类型上传错误' + type;
break;
}
$.messager.show(title + msg, {
placement: 'bottom'
});
});
}
/**
* 默认文件上传出错时处理
*/
if (!self.options.uploadEvents.uploadError) {
self.BDUploader.on('uploadError', function(file, reason) {
self.dump(file);
self.dump(reason);
});
}
/**
* 默认文件上传成功处理
*/
if (!self.options.uploadEvents.uploadSuccess) {
self.BDUploader.on('uploadSuccess', function(file, response) {
self.dump(file);
//客户端完成上传,服务端返回错误信息
if (response.status == 0) {
$('#' + file.id).remove();
self.BDUploader.removeFile(file.id, true);
$.messager.show(response.info, {
placement: 'bottom'
});
self.dump('上传完成但服务端有错误');
return false;
}
self.dump('上传成功');
var fileVal = self.getHiddenValue();
var fileItem = "#" + this.options.listName + " #" + file.id;
var $fileItem = $(fileItem);
var type = (file.type).split('/')[0];
//类型为图片时
var filebox_html = '';
if (type == 'image') {
filebox_html = '<img src="' + BASE_URL + response.info.path + '" class="img-responsive" />';
}else{
filebox_html = '';
}
$fileItem.find('div.filebox').addClass(type).html(filebox_html);
$fileItem.find('.upload-file-info span').eq(0).attr('data-id', response.info.id).attr('data-fileurl', response.info.path);
var responseVal = '';
responseVal = self.options.hiddenValType == '1' ? response.info.id : response.info.path
fileVal = fileVal != '' ? fileVal + self.options.separator + responseVal : responseVal;
self.setHiddenValue(fileVal);
self.allowNum--;
});
}
/**
* 默认文件上传完成时触发。不管成功或者失败
*/
if (!self.options.uploadEvents.uploadComplete) {
self.BDUploader.on('uploadComplete', function(file) {
self.dump('上传完成');
});
}
}
,
delFile: function() {
var self = this;
var selecter = '';
if (self.options.listName) {
selecter = '#' + self.options.listName;
}
if (self.options.editListName) {
selecter += ',#' + self.options.editListName;
}
$(selecter).on('click', '.webuploader-pick-file-close', function() {
var thisClose = $(this);
var fid = parseInt(thisClose.attr('data-id'), 10);
var furl = $.trim(thisClose.attr('data-fileurl'));
var qfid = $.trim(thisClose.attr('data-queued-id')); //文件所在队列id
thisClose.html('<i class="loading"></i>'); //load加载标识
if (fid > 0) {
$.post(self.options.delUrl, {
"id": fid
}, function(json) {
if (json.status == '1') {
if (self.options.hiddenValType == '1') {
self.resetHiddenVal(fid);
} else {
self.resetHiddenVal(furl);
}
$('#'+self.options.listName+' #'+qfid).remove();
// if (qfid.substring(0, 7) == 'WU_FILE') {
// self.BDUploader.removeFile(qfid, true);
// }
self.allowNum++;
} else {
$.messager.show(json.msg, {
placement: 'bottom'
});
thisClose.html('<i class="close"></i>'); //load加载标识
}
}, 'json');
}
});
}
//重置隐藏域的值
,
resetHiddenVal: function(val) {
var self = this;
var hdnVal = self.getHiddenValue();
var valArr = hdnVal.split(self.options.separator);
valArr = self.returnNewArr(val, valArr);
self.setHiddenValue(valArr.join(self.options.separator));
}
//删除数组中的指定的值
,
returnNewArr: function(value, arr) {
var tmpArr = new Array();
for (var i = 0; i < arr.length; i++) {
if (arr[i] != value) {
tmpArr.push(arr[i]);
}
}
return tmpArr;
}
//获取隐藏域中的值的个数
,
getHiddenValNum: function() {
var self = this,
existsVal = new Array();
var hdnVal = self.getHiddenValue();
if (hdnVal) {
existsVal = hdnVal.split(self.options.separator);
}
return existsVal.length;
}
//是否允许上传
,
isAllowUpload: function() {
return this.options.fileNumLimit - this.getHiddenValNum();
},
getHiddenValue: function() {
return $("#" + this.options.hiddenName).val();
},
setHiddenValue: function(val) {
return $("#" + this.options.hiddenName).val(val);
}
});
//插件入口
$.fn[pluginName] = function(options, seropts) {
var opts = $.extend({
pick: '#' + this.attr("id")
}, options);
var uploader = new Upload(this, opts, seropts);
uploader.initUploader();
if (uploader.options.delFile == true) {
uploader.delFile();
}
}
//插件默认参数
$.fn[pluginName].defaults = {
dnd: undefined, //指定Drag And Drop拖拽的容器如果不指定则不启动
disableGlobalDnd: false, //是否禁掉整个页面的拖拽功能,如果不禁用,图片拖进来的时候会默认被浏览器打开
paste: undefined, //指定监听paste事件的容器如果不指定不启用此功能。此功能为通过粘贴来添加截屏的图片。建议设置为document.body.
/**
* pick :undefined,//指定选择文件的按钮容器,不指定则不创建按钮。
* id {Seletor|dom} 指定选择文件的按钮容器,不指定则不创建按钮。注意 这里虽然写的是 id, 但是不是只支持 id, 还支持 class, 或者 dom 节点。
* label {String} 请采用 innerHTML 代替
* innerHTML {String} 指定按钮文字。不指定时优先从指定的容器中看是否自带文字。
* multiple {Boolean} 是否开起同时选择多个文件能力。
*/
accept: null, //指定接受哪些类型的文件。 由于目前还有ext转mimeType表所以这里需要分开指定。
/**
*
* title {String} 文字描述
* extensions {String} 允许的文件后缀,不带点,多个用逗号分割。
* mimeTypes {String} 多个用逗号分割。
* 如:{
title: 'Images',
extensions: 'gif,jpg,jpeg,bmp,png',
mimeTypes: 'image/*'
}
*/
thumb: {}, //配置生成缩略图的选项。
/**
* {
width: 110,
height: 110,
// 图片质量只有type为`image/jpeg`的时候才有效。
quality: 70,
// 是否允许放大如果想要生成小图的时候不失真此选项应该设置为false.
allowMagnify: true,
// 是否允许裁剪。
crop: true,
// 为空的话则保留原有图片格式。
// 否则强制转换成指定的类型。
type: 'image/jpeg'
}
*/
compress: {}, // {Object} [可选] 配置压缩的图片的选项。如果此选项为false, 则图片在上传前不进行压缩。
/**
* {
width: 1600,
height: 1600,
// 图片质量只有type为`image/jpeg`的时候才有效。
quality: 90,
// 是否允许放大如果想要生成小图的时候不失真此选项应该设置为false.
allowMagnify: false,
// 是否允许裁剪。
crop: false,
// 是否保留头部meta信息。
preserveHeaders: true,
// 如果发现压缩后文件大小比原来还大,则使用原来图片
// 此属性可能会影响图片自动纠正功能
noCompressIfLarger: false,
// 单位字节,如果图片大小小于此值,不会采用压缩。
compressSize: 0
}
*/
auto: true, //设置为 true 后,不需要手动调用上传,有文件选择即开始上传。
runtimeOrder: 'html5,flash', //指定运行时启动顺序。默认会想尝试 html5 是否支持,如果支持则使用 html5, 否则则使用 flash.可以将此值设置成 flash来强制使用 flash 运行时。
prepareNextFile: true, //是否允许在文件传输时提前把下一个文件准备好。 对于一个文件的准备工作比较耗时比如图片压缩md5序列化。 如果能提前在当前文件传输期处理,可以节省总体耗时。
chunked: false, //是否要分片处理大文件上传。
chunkSize: 5242880, //如果要分片,分多大一片? 默认大小为5M.
chunkRetry: 2, //如果某个分片由于网络问题出错,允许自动重传多少次?
threads: 3, //上传并发数。允许同时最大上传进程数。
formData: {}, //文件上传请求的参数表,每次发送都会发送此对象中的参数。
fileVal: 'file', //设置文件上传域的name。
method: 'POST', //文件上传方式POST或者GET。
sendAsBinary: false, //是否已二进制的流的方式发送文件这样整个上传内容php://input都为文件内容 其他参数在$_GET数组中。
fileNumLimit: undefined, //验证文件总数量, 超出则不允许加入队列。
fileSizeLimit: undefined, //验证文件总大小是否超出限制, 超出则不允许加入队列。以字节为单位
fileSingleSizeLimit: undefined, //验证单个文件大小是否超出限制, 超出则不允许加入队列。以字节为单位
duplicate: undefined, //去重, 根据文件名字、文件大小和最后修改时间来生成hash Key.
disableWidgets: undefined, //默认所有 Uploader.register 了的 widget 都会被加载,如果禁用某一部分,请通过此 option 指定黑名单。
swf: 'static/js/webuploader/Uploader.swf',
server: BASE_URL + '/admin/upload/upload.html?flash=1', // 文件接收服务端。
/**
* ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ
* 以上参数是百度上传组件默认参数
* 以下参数是非百度上传组件参数(即本插件根据实际开发设置的参数)
*
*/
uploadEvents: {}, //上传事件
delFile: true, //文件删除是否开启,开启后上传文件显示列表有删除文件按钮,默认开启
hiddenName: 'fileid', //文件上传隐藏域ID
hiddenValType: '1', //文件上传隐藏域保存的值的类型 1=保存的是file表的文件编号ID2=保存的是文件的实际路径
listName: 'fileList', //文件上传完成显示列表区域id
editListName: 'editfileList', //文件上传完成显示列表区域id
delUrl: BASE_URL + '/admin/upload/delete.html',
separator: ',', //默认逗号
}
})(jQuery, window);