前言
项目需求完成文件上传,可以拖拽上传文件/文件夹,基于layui的upload.js增强完成该需求
js代码
layui的引入和使用就不说了,懂的都懂,不懂去学习一下,废话不多说,直接上代码.基于upload.js自定义uploadFile.js用于实现需求功能
/**
* author: wz
* referenceAddress:文件,文件夹上传
*/
layui.define(["layer", "upload",'element','table'], function (e) {
"use strict";
var $ = layui.$, layer = layui.layer, upload = layui.upload,element=layui.element,table=layui.table,
tableArr=[],datas=[],model={
},unfinishedList=[],beingList=[],timer=null,beingCount=10,beingFlag=false,timerTable=null,keepTime=0;
//配置server token
var conf = JSON.parse(localStorage.conf);
var server = conf.file.server;
var token = conf.file.token;
function renderFile(option) {
var uploadInst=upload.render({
elem: '#' + option.id,
auto: option.auto||false,
accept: option.accept,
acceptMime: option.acceptMime,
exts: option.exts,
size: option.size||0,
multiple: option.multiple||true,
number: option.number||0,
choose:function (obj) {
var loadingIndex = layer.load(2, {
//icon支持传入0-2
shade: [0.5, 'gray'], //0.5透明度的灰色背景
content: '读取文件...',
success: function (layero) {
}
});
obj.preview(function (index, file) {
loadingIndex="";
layer.closeAll();
var fileUuid=uuid();
uploadServer(file,fileUuid,"0",file.webkitRelativePath,option);
});
setTimeout(function () {
if(loadingIndex){
layer.closeAll();
layer.msg("上传类型错误,请检查!", {
icon: 5});
}
},20000);
}
});
selectEvent(option.id);
}
function selectEvent(id) {
$('#' + id).bind("dragover",function (e) {
$(this).css("background","#e9f5fe");
})
$('#' + id).bind("dragleave",function (e) {
$(this).css("background","");
})
$('#' + id).bind("mouseover",function (e) {
$(this).css("background","#e9f5fe");
})
$('#' + id).bind("mouseout",function (e) {
$(this).css("background","");
})
}
//上传中转站
function uploadServer(file,fileUuid,type,path,option,serialNumber) {
var parentId=option.parentId;
if(type=='0'){
//文件上传
tableData(file,fileUuid,option.parentId,option.nodeId,"0");
}else {
//文件夹上传
if(path){
var split=path.split("/");
for (var i = 0; i < split.length; i++) {
if(i<=split.length-2){
parentId=folderLoading(split[i],parentId,option.nodeId,serialNumber);
}else {
tableData(file,fileUuid,parentId,option.nodeId,"1");
}
}
}
}
unfinishedList.push({
file:file,//文件对象
type:type,//文件上传
path:path,//文件路径
uuid:fileUuid,//唯一标识
parentId:parentId
});
if(timer==null){
timer=setInterval(function (d) {
if(unfinishedList.length>0){
if(beingList.length<beingCount){
//控制同时上传个数
var diff=beingCount-beingList.length;
for (let i = 0; i <diff ; i++) {
if(unfinishedList.length>i){
beingList.push(unfinishedList[i].uuid);
uploadDone(option,unfinishedList[i].file,unfinishedList[i].uuid,unfinishedList[i].parentId);
}
}
for (let i = 0; i <diff; i++) {
if(unfinishedList.length>0){
unfinishedList.splice(0,1);
}
}
}
}else {
//上传完成
if(timer!=null){
clearInterval(timer);
timer=null;
}
}
},500);
}
if(timerTable==null){
timerTable=setInterval(function (d) {
keepTime++;//计时
if(unfinishedList.length==0&&beingList.length==0){
reloadTable(option,true);
clearInterval(timerTable);
timerTable=null;
}else {
reloadTable(option,false);
}
},1000);
}
}
/*
文件夹拖拽上传
在 drop 事件中获取 e.dataTransfer.items ,是一个 DataTransferItemList 对象,遍历得到 DataTransferItem 对象
用 webkitGetAsEntry 方法得到 FileSystemEntry 对象
根据 isFile 属性判断 entry 是文件还是文件夹。是文件的话,用 file 方法获取 File 对象;是文件夹的话,递归地用 reader 读取包含的文件
原文链接:https://blog.csdn.net/tangran0526/article/details/104156857
* */
function scanFiles(e,option) {
e.preventDefault();
//var files=[];
var item=e.dataTransfer.items;//获取DataTransferItemList 对象
if(item&&item.length>0){
var serialNumber=uuid();//同一上传批次序列号下的同名文件夹不重复添加
for (var it of item) {
var entry=it.webkitGetAsEntry();//获取 FileSystemEntry 对象
fileReader(entry,function (file, path) {
uploadServer(file,uuid(),"1",path,option,serialNumber);
});
}
}
}
function fileReader(entry,succ) {
if (entry.isFile) {
entry.file(file => {
// 这里的 file.webkitRelativePath 都是 "" ,不是我们想要的.
// entry.fullPath 是前面带斜杠的,要把斜杠去掉的
let path = entry.fullPath.substring(1);
succ(file,path);
});
} else {
getEntryDirectoryFiles(entry).then(data=>{
data.forEach(_this=>{
fileReader(_this,succ);});
});
}
}
// 获取文件夹所有子集
function getEntryDirectoryFiles(entry) {
const reader = entry.createReader()
// 一次最多只能读100,防止出现文件夹内文件个数过多,加一个变量收集最新的结果
let res = []
return read();
async function read() {
const files = await new Promise((resolve, reject) =>
reader.readEntries((entries) => {
// 只上传一层文件,过滤文件夹中包含的文件夹
//const fileEntries = entries.filter((entry) => entry.isFile)
const filesPromise = entries.map((e) => new Promise((resolve) =>resolve(e)))
Promise.all(filesPromise).then(resolve)
}, reject)
)
// 保存当前读取文件
res = [...res, ...files]
// chrome浏览器一次读取最多获取100个文件,多于100个需要再次读取
if (files.length < 100) {
return res
}
return read()
}
}
async function read(entry,res) {
const reader = entry.createReader();
for (let i = 0; i < 3; i++) {
await new Promise((resolve, reject) =>{
debugger;
reader.readEntries((entries) => {
debugger;
console.log(entries.length);
// 只上传一层文件,过滤文件夹中包含的文件夹
})
}
)
}
}
function renderDrop(option) {
$("#"+option.dropId).click(function (e) {