前端代码
input的选择文件会覆盖上次的选择,而且涉及拖拽上传,故自定义数组保存文件。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<div>
<form id="form" method="post" enctype="multipart/form-data">
<div id="uploader">
<input id="productCode" name="productCode">
<div class="uploader__text">拖拽上传至此处,或
<a href="javascript:void(0)" onclick="selectFile()">选择文件</a>
<span>(最多可上传3个附件)</span>
</div>
<div class="uploader__list"></div>
<input id="fileList" type="file" name="fileList" multiple="multiple" style="display: none;">
</div>
</form>
<div onclick="submit()">上传</div>
</div>
<script>
var fileList = new Array();
window.onload = function () {
var uploader = document.getElementById('uploader')
var uploadInput = uploader.getElementsByTagName('input')[0];
uploader.addEventListener('drop', function (e) {
e.preventDefault();
const files = e.dataTransfer.files;
for (var i = 0; i < files.length; i++) {
if (fileList.length >= 3) {
break
}
fileList.push(files[i]);
}
renderFileList();
});
uploader.addEventListener('dragover', function (e) {
e.preventDefault(); //阻止浏览器拖拽事件
});
uploadInput.addEventListener('change', function (e) {
const files = e.target.files;
for (var i = 0; i < files.length; i++) {
if (fileList.length >= 3) {
break
}
fileList.push(files[i]);
}
// 清空input选中的文件
e.target.value = '';
renderFileList();
});
}
function renderFileList() {
var fileListEl = document.getElementById('uploader').getElementsByClassName('uploader__list')[0];
fileListEl.innerHTML = '';
for (var i = 0; i < fileList.length; i++) {
var fileNameEl = document.createElement('span');
fileNameEl.innerHTML = fileList[i].name;
var deleteEl = document.createElement('i');
deleteEl.classList.add(`file${i}`);
deleteEl.onclick = function (e) {
const index = parseInt(e.target.className.replace('file', ''));
fileList.splice(index, 1);
renderFileList();
}
fileNameEl.append(deleteEl);
fileNameEl.addEventListener('mouseenter', function(e) {
const del = e.target.getElementsByTagName('i')[0]
del.style.display = 'block';
});
fileNameEl.addEventListener('mouseleave', function(e) {
const del = e.target.getElementsByTagName('i')[0]
del.style.display = 'none';
});
fileListEl.append(fileNameEl);
}
}
function selectFile() {
document.getElementById('uploader').getElementsByTagName('input')[0].click();
}
function submit() {
const form = document.getElementById("form");
var formData = new FormData(form);
formData.delete("fileList");
for (let i = 0; i < fileList.length; i++) {
formData.append('fileList', fileList[i]);
}
$.ajax({
type: "POST",
url: "/submit",
data: formData,
cache: false,
processData: false,
contentType: false,
dataType: "json",
mineType: "multipart/form-data",
success: function (result) {
console.log(result);
var resultInfo = result;
if (resultInfo.status) {
BootstrapDialog.alert("提交成功!", function () {
window.location.href = "/customerProduct/list";
});
} else {
BootstrapDialog.alert("提交信息失败! " + resultInfo.message);
}
}
});
}
</script>
<style>
#uploader {
border-radius: 0 4px 4px 0;
border: 1px solid gray;
text-align: center;
}
.uploader__text {
color: #9d9d9d;
font-size: 14px;
}
.uploader__text a {
color: blue;
text-decoration: underline;
}
.uploader__text span {
text-decoration: underline;
display: block;
}
.uploader__list {
margin-top: 4px;
}
.uploader__list span {
color: rgba(0,0,0,.65);
line-height: 20px;
font-size: 14px;
position: relative;
cursor: pointer;
}
.uploader__list span i {
position: absolute;
right: -12px;
top: -2px;
width: 14px;
height: 14px;
text-align: center;
display: none;
font-style: normal;
border-radius: 20px;
background: url(https://static-ftcms.jd.com/p/files/64198787e1fec54ed5df7bc3.png) no-repeat center;
background-size: contain;
}
.uploader__list span + span {
margin-left: 8px;
}
</style>
</body>
</html>
后端代码
// 定义对象
public class Obj {
@NotBlank
private String customerNo;
private String productCode;
}
//接口
@ResponseBody
@RequestMapping(value = "submit", produces = "text/html;charset=UTF-8")
public String submit(@Valid Obj obj, @RequestParam(value = "fileList", required = false) List<MultipartFile> fileList, BindingResult bindingResult) { //...业务代码 }