/**
* 上传控件实现
* @example 该js还是依赖于以下js
<link href="~/bower_components/font-awesome/css/font-awesome.min.css" rel="stylesheet" />
<script src="~/bower_components/jquery/jquery.min.js"></script>
<script src="~/bower_components/layer/layer.js"></script>
<script src="~/Scripts/libs/abp.js"></script>
<script src="~/Scripts/libs/abp.layui-alert.js"></script>
*/
var webuploader = webuploader || {};
var abp = abp || {};
/*
* abp.webuploader.js 是扩展上传文件,有一定的上传样式效果,依赖于jquery,layer,abp.js,abp.layui-alert.js,font-awesomen.css
* 还改了webuploader.js 3949行,解决了fileNumLimit上传文件数量无效的问题 和webuploader.min.js对应的js文件
* 本文件会自动引用applicationPath目录下的webuploader.min.js和webuploader.css文件
*/
(function ($, window) {
var applicationPath = window.applicationPath === "" ? "" : window.applicationPath || "/bower_components/webuploader";
// var serviceUrl = "http://localhost:61816"
// webuploader.authorization = "GMyFTVCKRstZ0doyTQYVMTW6hprHTgRvjAIAiGATzaAsDLmj5_VO6isChVhTo6WaHKTS0fieCTINh6LYOD0KM2HFXMhns3JaFbUfXzZKWtqpxSxEYY6pk5J59CGjLxnl1QGxIhEvWCWd8fQ4gS5Zu3h5vQXZqi6wBt6GY7Yi15qr9ddV5-ynukLUYp2qqxs0p7CVeQgMAGk-ueBAi75sJhqHXWMR4KWzRzTj-r7o3f6KaWO5tpJTwlKl32zDwkp6mfKDtv9w9qP0b8IuTnJ-n0ABRua_6rdP9ngo_Jg--Ai7n-H2aChR4eaJRgLPdMAHk9OI7tIRY4pf1KkABqnrAylKRDUNiCotEOAwtlAZHwF6TZCd66L3QDyWiTkxRLY1brpofVsqoqKcqf_sMqlMJ1litLtTj47l66KKEcFWTlUPGwWNX7R7GFnL_f_4ugNmgrBoApUEWIlkVATtWMeX2F6wQYJIDhxoJ9tYgTBmZnXbBNLmRJud1qhqNafBG-UyAdflUVSy5He6wf6uiUxSKQ"
var serviceUrl = "";
webuploader.authorization = "";
var userInfo = {
md5: '',
index: '',
fileToken:''
},
uploaders = {};
// 大文件分片,断点续传,以及秒传功能
// 在文件开始发送前做些异步操作。做md5验证
// WebUploader会等待此异步操作完成后,开始发送文件。
WebUploader.Uploader.register({
"before-send-file": "beforeSendFile"
}, {
beforeSendFile: function (file) {
var task = new $.Deferred();
var $fileId = file.id;
uploaders[userInfo.index].md5File(file, 0, 10 * 1024 * 1024).progress(function (percentage) {
var uploadflieElement = $('#' + fileId);
if (opts.uploadType === 'file') {
var value = Math.round(percentage * 100);
uploadflieElement.find('div.webuploadstate .webupload-text').html('正在上传' + value + '%');
}
}).then(function (val) {
var $fileId = file.id;
userInfo.md5 = val;
$.ajax({
headers: {
"Authorization": "Bearer " + webuploader.authorization
},
type: "POST",
url: serviceUrl + '/File/Md5Validate',
data: {
md5: val,
fileName: file.name
},
cache: false,
timeout: 3000,
dataType: "json"
}).then(function (response, textStatus, jqXHR) {
//若存在,这返回失败给WebUploader,(后台操作)表明该文件不需要上传,然后就可以把数据库查询出的文件信息的物理路径给新文件
if (response.success == true) {
//task.reject('秒传成功'); 此处会执行uploadError
uploaders[userInfo.index].skipFile(file);
userInfo.fileToken = response.result;
//上传成功事件
if (uploaders[userInfo.index].options.uploadType === 'file') {
if ($('#' + $fileId + ' .webuploadstate .file-token').attr('data-filetoken') != '') {
return;
}
var limit = webuploader.bytesToSize(file.size);
var downUrl = serviceUrl + '/File/Download?fileToken=' + response.result + '&newName=' + file.name;
$('#' + $fileId).find('div.webuploadstate .webupload-text').html(limit + ' 秒传');
$('#' + $fileId).find('div.webuploadstate .file-token').attr('data-filetoken', response.result);
$('#' + $fileId)
.find('div.webuploadinfo .webupload-button a')
.after('<a href="' + downUrl + '" target="_blank"><span class="webupload-download">下载</span></a>');
} else {
window.setTimeout(function () {
$('#' + $fileId + ' img').attr('src', serviceUrl + '/File/Download?fileToken=' + response.result);
$('#' + $fileId + ' .webupload-list-img-cover .img-upload-state span.file-token').attr('data-filetoken', response.result);
}, 500);
}
}
task.resolve();
}, function (jqXHR, textStatus, errorThrown) { //任何形式的验证失败,都触发重新上传
task.resolve();
});
});
return $.when(task);
}
});
function initWebUpload(item, options) {
if (!WebUploader.Uploader.support()) {
var error = "上传控件不支持您的浏览器!请尝试升级flash版本或者使用Chrome引擎的浏览器。<a target='_blank' href='http://se.360.cn'>下载页面</a>";
if (window.console) {
window.console.log(error);
}
$(item).text(error);
return;
}
//创建默认参数
var defaults = {
auto: true,
onAllComplete: function (event) {}, // 当所有file都上传后执行的回调函数
onComplete: function (event) {}, // 每上传一个file的回调函数
innerOptions: {},
fileNumLimit: 20, //验证文件总数量, 超出则不允许加入队列
fileSizeLimit: 100 * 1024 * 1024, //验证文件总大小是否超出限制, 超出则不允许加入队列。
uploadType: 'file' //file、img
};
var opts = $.extend(defaults, options);
if (opts.uploadType === 'img') {
opts.accept = {
title: 'Images',
extensions: 'gif,jpg,jpeg,bmp,png',
mimeTypes: 'image/*'
};
}
var target = $(item);
var pickerid = webuploader.GUID();
var uploaderStrdiv = '<div class="webuploader">';
target.attr('data-uploadType', opts.uploadType);
var text = opts.uploadType === 'img' ? "选择图片" : "选择文件";
if (opts.auto) {
uploaderStrdiv =
'<div class="btns">' +
'<div id="' +
pickerid +
'">' + text + '</div>' +
'</div>' +
'<div class="uploader-list"></div>';
} else {
uploaderStrdiv =
'<div class="btns">' +
'<div id="' +
pickerid +
'">' + text + '</div>' +
'<button class="webuploadbtn" type="button">开始上传</button>' +
'</div>' +
'<div class="uploader-list"></div>';
}
target.append(uploaderStrdiv);
var $list = target.find('.uploader-list'),
$btn = target.find('.webuploadbtn'), //手动上传按钮备用
state = 'pending',
uploader;
var webuploaderoptions = $.extend({
// swf文件路径
swf: applicationPath + '/Uploader.swf',
// 文件接收服务端。
server: serviceUrl + '/File/UploadFile',
deleteServer: serviceUrl + '/File/Delete',
md5Server: serviceUrl + '/File/Md5Validate',
// 选择文件的按钮。可选。
// 内部根据当前运行是创建,可能是input元素,也可能是flash.
pick: '#' + pickerid,
//不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
resize: false,
fileNumLimit: opts.fileNumLimit,
fileSizeLimit: opts.fileSizeLimit,
fileSingleSizeLimit: opts.fileSingleSizeLimit,
accept: opts.accept,
withCredentials: true
}, opts.innerOptions);
uploader = WebUploader.create(webuploaderoptions);
uploaders[pickerid] = uploader;
$.extend(uploaders[pickerid].options, opts);
uploader.on('fileQueued',
function (file) {
var subName = file.name;
//主要解决名字太长,上传文件名会超出换行,导致样式问题,让字数在20个字符以内即可
if (subName.lastIndexOf('.') > 20) {
subName = subName.substring(0, 20);
} else {
subName = subName.substring(0, subName.lastIndexOf('.'));
}
subName += '.' + file.ext;
var fileId = file.id;
var fileUpload = "";
if (opts.uploadType === 'file') {
fileUpload = '<div id="' + fileId + '" class="item">\
<div class="nui-ico nui-ico-file32 nui-ico-file32-' + file.ext.toLowerCase() + '"></div>\
<div class="webuploadinfo"> <span title="' + file.name + '">' + subName + '</span>\
<div class="webupload-button"><a><span class="webupload-delete" data-id="' + fileId + '">删除</span></a></div>\
</div>\
<div class="webuploadstate"><span class="file-token" data-filetoken=""></span><span class="webupload-text">等待上传</span>\
<div id="progress-' + fileId + '" class="progressbar-animation"></div>\
</div>\
</div>';
} else {
/*/Content/images/default-profile-picture.png*/
fileUpload = '<div id="' + fileId + '" class="webupload-list-img">\
<img src = "" >\
<div class="webupload-list-img-cover">\
<i class="fa fa-eye img-show" title="预览" data-id="' + fileId + '"></i>\
<i class="fa fa-remove img-delete" title="删除" data-id="' + fileId + '"></i>\
<div class="img-upload-state" style="display:none;" >' +
'<span class="file-name" data-filename="' + file.name + '"></span>' +
'<span class="file-token" data-filetoken=""></span>' +
'</div>\
</div>\
</div>';
}
$list.append(fileUpload);
//自动上传
if (opts.auto) {
uploader.upload();
}
});
/*
* 验证文件格式以及文件大小
*/
uploader.on("error",
function (type) {
var limit = 0;
if (type === "Q_TYPE_DENIED") {
abp.message.warn("不支持您上传的文件格式!");
} else if (type === "F_EXCEED_SIZE") {
limit = opts.fileSingleSizeLimit / 1024 / 1024;
abp.message.warn("单个文件大小不能超过" + limit + "MB");
} else if (type === "Q_EXCEED_SIZE_LIMIT") {
limit = opts.fileSingleSizeLimit / 1024 / 1024;
abp.message.warn("添加的文件总大小超出" + limit + "MB");
} else if (type === "Q_EXCEED_NUM_LIMIT") {
abp.message.warn("添加的文件数量超出范围");
} else if (type === "F_DUPLICATE") {
abp.message.warn("该文件已存在,请勿重复添加!");
} else {
abp.message.warn("未知类型错误:" + type);
}
});
/*当文件被加入队列之前触发,此事件的handler返回值为false,则此文件不会被添加进入队列。*/
uploader.on("beforeFileQueued",
function (file) {
if (opts.fileNumLimit == undefined) {
return true;
}
var length;
if (opts.uploadType === 'file') {
//当有文件限制,在编辑时验证文件数量
length = target.find('.item').length;
} else {
length = target.find('.webupload-list-img').length;
}
if (length >= opts.fileNumLimit) {
abp.message.warn('添加的文件数量超出范围!');
return false;
}
userInfo.index = pickerid;
return true;
});
uploader.on('uploadProgress',
function (file, percentage) { //进度条事件
var fileId = file.id;
var uploadflieElement = target.find('#' + fileId);
if (opts.uploadType === 'file') {
var value = Math.round(percentage * 100);
uploadflieElement.find('div.webuploadstate .webupload-text').html('正在上传' + value + '%');
if ($.fn.progressbar != undefined) {
var $progressElement = uploadflieElement.find('div.webuploadstate #progress-' + fileId);
if ($progressElement.hasClass('progressbar')) {
$progressElement.progressbar('setValue', value);
} else {
$progressElement.progressbar({
value: value,
text: '',
height: 6
});
}
}
} else {
}
});
uploader.on('uploadSuccess',
function (file, response) {
if (response == undefined) {
opts.uploadSuccess && opts.uploadSuccess(file,userInfo.fileToken);
return;
};
//上传成功事件
//后台保存文件属性信息services 重构,后台上传文件的时候,就把数据存到后台
var $fileId = file.id;
if (opts.uploadType === 'file') {
if (response.success === false) {
abp.message.error(response.error.message);
target.find('#' + $fileId).find('div.webuploadstate .webupload-text').html(response.error.message).css('color', 'red');
} else {
var limit = webuploader.bytesToSize(file.size);
var downUrl = serviceUrl + '/File/Download?fileToken=' + response.result + '&newName=' + file.name;
target.find('#' + $fileId).find('div.webuploadstate .webupload-text').html(limit + ' 上传成功');
target.find('#' + $fileId).find('div.webuploadstate .file-token').attr('data-filetoken', response.result);
target.find('#' + $fileId).find('div.webuploadinfo .webupload-button a')
.after('<a href="' + downUrl + '" target="_blank"><span class="webupload-download">下载</span></a>');
}
} else {
if (response.success === false) {
target.find('#' + $fileId);
abp.message.error(response.error.message);
} else {
window.setTimeout(function () {
target.find('#' + $fileId + ' img').attr('src', serviceUrl + '/File/Download?fileToken=' + response.result);
target.find('#' + $fileId + ' .webupload-list-img-cover .img-upload-state span.file-token').attr('data-filetoken', response.result);
}, 500);
}
}
opts.uploadSuccess && opts.uploadSuccess(file, response.result);
});
uploader.on('uploadError',
function (file, reason) {
if (reason == undefined)
target.find('#' + file.id).find('div.webuploadstate .webupload-text').html(reason);
});
uploader.on('uploadComplete',
function (file) { //全部完成事件
var fileId = file.id;
target.find('#' + fileId).find('#progress-' + fileId).fadeOut();
});
uploader.on('all',
function (type) {
if (type === 'startUpload') {
state = 'uploading';
} else if (type === 'stopUpload') {
state = 'paused';
} else if (type === 'uploadFinished') {
state = 'done';
}
if (state === 'uploading') {
$btn.text('暂停上传');
} else {
$btn.text('开始上传');
}
});
var deleteFile = function (fileToken, callback) {
//callback && callback();
// 增加秒传后,不再执行删除后台数据及文件操作
//2018-10-17 后台接口调整,文件md5验证和token关联存储
if (!webuploader.isNullOrEmpty(fileToken)) {
abp.ajax({
url:webuploaderoptions.deleteServer,
data:JSON.stringify({
fileToken:fileToken
}),
headers:{
"Authorization": "Bearer " + webuploader.authorization
},
success:function(data){
if (data.Succeed == 0 && data.Message == "该文件不存在!") {
abp.message.warn(data.Message);
callback && callback();
return;
}
if (data.Succeed == 0) {
abp.message.warn(data.Message);
} else {
callback && callback();
}
}
});
} else {
callback && callback();
}
}
//删除时执行的方法
uploader.on('fileDequeued',
function (file) {
var fileToken;
var fileId = file.id;
if (target.data('uploadtype') === 'file') {
fileToken = target.find("#" + fileId + ' .webuploadstate .file-token').data('filetoken');
} else {
fileToken = target.find('#' + fileId + ' .webupload-list-img-cover .img-upload-state span.file-token').attr('data-filetoken');
}
debugger
deleteFile(fileToken, function () {
target.find("#" + fileId).hide(500,
function () {
$(this).remove();
});
});
});
uploader.on('uploadBeforeSend', function (object, data, headers) {
$.extend(headers, {
"Authorization": "Bearer " + webuploader.authorization
});
$.extend(data, {
md5: userInfo.md5,
__RequestVerificationToken: $('form input[name=__RequestVerificationToken]').val()
});
});
//多文件点击上传的方法
$btn.on('click',
function () {
if (state === 'uploading') {
uploader.stop();
} else {
uploader.upload();
}
});
//删除
if (opts.uploadType === 'file') {
$list.on("click",
".webupload-delete",
function () {
var $ele = $(this);
var fileId = $ele.attr("data-id");
var file = uploader.getFile(fileId);
if (file == undefined) {
//前台直接删除
$('#' + fileId).fadeOut(500,
function () {
$(this).remove();
});
var list = fileId.split('_');
var fileToken = $("#hiddenInput" + list[list.length - 1]).val();
if (list.length >= 1) {
$("#hiddenInput" + list[list.length - 1]).remove();
}
} else {
uploader.removeFile(file);
}
});
} else {
$list.on("click",
".img-delete",
function () {
var $ele = $(this);
var fileId = $ele.attr("data-id");
var file = uploader.getFile(fileId);
if (file == undefined) {
//前台直接删除
var filetoken = $ele.next().find('.file-token').data('filetoken');
deleteFile(filetoken, function () {
$('#' + fileId).hide(500,
function () {
$(this).remove();
});
});
} else {
uploader.removeFile(file);
}
});
$list.on("click",
".img-show",
function () {
var $ele = $(this);
webuploader.imagePreviewDialog($ele);
});
}
return uploader;
}
$.extend(webuploader, {
/**
* webuploader的图片预览效果
* @param {} $ele 当前点击的图片elem
*/
imagePreviewDialog: function ($ele) {
var id = '#' + $ele.attr("data-id");
var imgSrc = $(id).find('img').attr('src');
abp.imagePreviewDialog(imgSrc);
},
/**
* 动态加载webuploader控件
* @param {any} callback
*/
getWebUpload: function (callback) {
if (typeof WebUploader == 'undefined') {
var casspath = applicationPath + "/webuploader.css";
$("<link>").attr({
rel: "stylesheet",
type: "text/css",
href: casspath
}).appendTo("head");
var jspath = applicationPath + "/webuploader.min.js";
$.getScript(jspath).done(function () {
callback && callback();
}).fail(function () {
abp.message.warn("请检查webuploader的路径是否正确!");
});
} else {
callback && callback();
}
},
/**
* 上传文件模板
* @param {boolean} isCheck 是否是查看界面 true/false
* @returns {} 参数为空时,默认不是查看界面,有删除按钮。参数为true时,无删除按钮
*/
template: function (isCheck) {
//如果是查看,没有删除按钮
var template = '<div id="BinduploadflieWU_FILE_{0}" class="item">' +
'<div class="nui-ico nui-ico-file32 nui-ico-file32-{1}"></div>' +
'<div class="webuploadinfo">' +
'<span title="{2}">{3}</span>' +
'<div class="webupload-button">';
if (!isCheck) {
template += '<a><span class="webupload-delete" data-id="BinduploadflieWU_FILE_{0}">删除</span></a>';
}
template += '<a href="' + serviceUrl + '/File/Download?fileToken={4}&newName={2}" target="_blank"><span class="webupload-download">下载</span></a>' +
'</div>' +
'<div class="webuploadstate"><span class="file-token" data-filetoken="{4}"></span><span class="webupload-text">{5}</span></div>' +
'</div></div>';
return template;
},
/**
* 图片上传模板
* @param {} isCheck 是否是查看界面 true/false
* @returns {} 参数为空时,默认不是查看界面,有删除功能。参数为true时,无删除功能
*/
templateImg: function (isCheck) {
var template = '<div id="BinduploadflieWU_FILE_{0}" class="webupload-list-img">' +
'<img src="' + serviceUrl + '/File/Download?fileToken={2}">' +
'<div class="webupload-list-img-cover">' +
'<i class="fa fa-eye img-show" title="预览" data-id="BinduploadflieWU_FILE_{0}"></i>';
if (!isCheck) {
template += '<i class="fa fa-remove img-delete" title="删除" data-id="BinduploadflieWU_FILE_{0}"></i>';
}
template += '<div class="img-upload-state" style="display:none;"><span class="file-name" data-filename="{1}"></span><span class="file-token" data-filetoken="{2}"></span></div>' +
'</div>' +
'</div>';
return template;
},
/**
* 当图片没有时,会显示404图片
* @param {} img
* @returns {}
*/
show404: function (img) {
img.src = applicationPath + "/images/404.png";
img.onerror = null;
},
/**
* 编辑时,加载上传控件
* @param {Object<>} options
* 参数 | 默认值 | 说明
* {
* elem '#upload-file' 上传控件id
* rows []
* isCheck false 是否为查看 true/false
* uploadeFile 'file' 上传类型:'file' / 'img'
* }参数:
*/
loadFile: function (options) {
var defaults = {
elem: '#upload-files',
rows: [],
isCheck: false, //是否为查看
uploadType: 'file' //绑定文件类型 file 或 img
};
options = $.extend(defaults, options);
var rows = webuploader.getFiles(options.elem);
if (rows && rows.length === 0) {
rows = options.rows;
}
if (rows && rows.length > 0) {
webuploader.getWebUpload(function () {
//未找到webuploader的控件加载成功后的回调事件,采用setTimeout()延迟执行
setTimeout(function () {
var html = '';
var uploadType = $(options.elem).data('uploadtype');
if (options.isCheck === true) {
html += '<div class="uploader-list">';
uploadType = options.uploadType;
}
$.each(rows, function (i, v) {
var subName = v.FileName;
if (subName.lastIndexOf('.') > 20) {
subName = subName.substring(0, 20);
} else {
subName = subName.substring(0, subName.lastIndexOf('.'));
}
var d = v.FileName;
var ext = d.substr(d.lastIndexOf('.') + 1, d.length);
subName += '.' + ext;
var limit = webuploader.bytesToSize(v.FileSize);
if (uploadType === 'file') {
//参数(id,文件后缀,文件名,截取后的文件名,fileToken,上传状态(文件大小+上传成功))
html += webuploader.format(webuploader.template(options.isCheck), v.Id, ext.toLowerCase(), v.FileName, subName, v.FileToken, limit + "上传成功");
} else {
html += webuploader.format(webuploader.templateImg(options.isCheck), v.Id, v.FileName, v.FileToken);
}
});
if (options.isCheck === true) {
html += '</div>';
$(options.elem).append(html);
$(options.elem).find('.img-show').on('click',
function () {
var $ele = $(this);
webuploader.imagePreviewDialog($ele);
});
} else {
$(options.elem + ' div.uploader-list').append(html);
}
}, 400);
});
}
},
//<ul style="display:none;" id="abpfiles" >
//@foreach(var item in Model.AbpFileOutput)
//{
// <li data-filetoken="@item.FileToken" data-id="@item.Id" data-filesize="@item.FileSize">@item.FileName</li>
//}
//</ul>
//上面的格式,会得到当前已上传的文件数组
getFiles: function (elemId) {
var abpfiles = [];
$.each($(elemId + ' ul li'), function (i, v) {
abpfiles.push({
Id: $(v).attr('data-id'),
FileToken: $(v).attr('data-filetoken'),
FileSize: $(v).attr('data-filesize'),
FileName: $(v).text()
});
});
return abpfiles;
},
/**
* 格式化字符串
* @param {string} "{0}-{1}","a","b"
* @returns a-b
* @example 用法:
webuploader.format("{0}-{1}","a","b");
*/
format: function () {
for (var i = 1; i < arguments.length; i++) {
var exp = new RegExp('\\{' + (i - 1) + '\\}', 'gm');
arguments[0] = arguments[0].replace(exp, arguments[i]);
}
return arguments[0];
},
/**
* 判断变量是否为null或空
* @example 用法:
* webuploader.isNullOrEmpty(null)
*/
isNullOrEmpty: function (str) {
return str === undefined || str === null || str === "";
},
/**
* 生成一个guid数据
*/
GUID: function () {
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
},
/**
* 1024MB转换成1GB
* @param {number} bytes
* @returns {} 返回最小不可转换的单位的空间大小
*/
bytesToSize: function (bytes) {
if (bytes === undefined || bytes === null || bytes === "") return "";
if (bytes == 0) return '0B';
var k = 1024;
var sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
var i = Math.floor(Math.log(bytes) / Math.log(k));
return (bytes / Math.pow(k, i)).toPrecision(3) + sizes[i];
}
});
/**
* 扩展方法:得到当前控件已经上传成功的文件地址,多文件,中间以*分割
*/
$.fn.GetFilesAddress = function () {
var filesAddress = [];
if ($(this).data('uploadtype') === 'file') {
$(this).find(".uploader-list .webuploadstate .file-token").each(function () {
filesAddress.push($(this).data('filetoken'));
});
} else {
$(this).find('.uploader-list .webupload-list-img .webupload-list-img-cover .img-upload-state span.file-token').each(function () {
filesAddress.push($(this).data('filetoken'));
});
}
return filesAddress.join('*');
}
/**
* 扩展方法:初始化上传文件
* @param {Object<>} 参数为webuploader插件的所有参数
* @param 新增参数:uploadType:'file'或'img' 上传类型:file为文件;img为图片,有上传预览效果
*/
$.fn.powerWebUpload = function (options) {
var ele = this;
webuploader.getWebUpload(function () {
initWebUpload(ele, options);
options && options.callback && options.callback();
});
}
})(jQuery, window);