Merge branch '27-file-upload' into 'master'
Resolve "Пример для загрузки файлов" Closes #27 See merge request romanov73/ng-tracker!7
This commit is contained in:
commit
2a493205f3
@ -3,7 +3,12 @@ package ru.ulstu.file;
|
|||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import ru.ulstu.configuration.Constants;
|
import ru.ulstu.configuration.Constants;
|
||||||
import ru.ulstu.core.model.response.Response;
|
import ru.ulstu.core.model.response.Response;
|
||||||
@ -13,7 +18,6 @@ import ru.ulstu.file.service.FileService;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
import static ru.ulstu.paper.controller.PaperController.URL;
|
import static ru.ulstu.paper.controller.PaperController.URL;
|
||||||
@ -47,7 +51,7 @@ public class FileController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/uploadTmpFile")
|
@PostMapping("/uploadTmpFile")
|
||||||
public Response<String> upload(@RequestBody MultipartFile multipartFile) throws IOException {
|
public Response<String> upload(@RequestParam("file") MultipartFile multipartFile) throws IOException {
|
||||||
return new Response(fileService.uploadToTmpDir(multipartFile));
|
return new Response(fileService.uploadToTmpDir(multipartFile));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
// from config.js
|
// from config.js
|
||||||
/* global urlVersions */
|
/* global urlVersions */
|
||||||
|
|
||||||
|
var urlFileUpload = "https://localhost:8443/api/1.0/papers/uploadTmpFile";
|
||||||
|
|
||||||
/* exported MessageTypesEnum */
|
/* exported MessageTypesEnum */
|
||||||
var MessageTypesEnum = {
|
var MessageTypesEnum = {
|
||||||
INFO: "info",
|
INFO: "info",
|
||||||
|
130
src/main/resources/public/js/file-loader.js
Normal file
130
src/main/resources/public/js/file-loader.js
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
// form core.js
|
||||||
|
/* global isEmpty, errorHandler, showFeedbackMessage, MessageTypesEnum */
|
||||||
|
|
||||||
|
/* exported FileLoader */
|
||||||
|
function FileLoader(args) {
|
||||||
|
var MAX_FILE_SIZE_MB = 20;
|
||||||
|
var SIZE_TO_MB = 1048576;
|
||||||
|
var CHOOSE_FILE_TEXT = "Выберите файл";
|
||||||
|
var ALERT_CHOOSE_FILE = "Необходимо выбрать файл";
|
||||||
|
var ALERT_UNKNOWN_FILE_EXT = "Неизвестный тип файлов";
|
||||||
|
var ALERT_MAX_FILE = "Файл превышает разрешенный размер";
|
||||||
|
var ALERT_EMPTY_FILE = "Файл пуст";
|
||||||
|
var ERROR = "Ошибка загрузки файла";
|
||||||
|
|
||||||
|
if (isEmpty(args)) {
|
||||||
|
throw "Empty arguments";
|
||||||
|
}
|
||||||
|
var divId = args.div;
|
||||||
|
if (isEmpty(divId)) {
|
||||||
|
throw "Div id parameter is not set";
|
||||||
|
}
|
||||||
|
var url = args.url;
|
||||||
|
if (isEmpty(url)) {
|
||||||
|
throw "URL parameter is not set";
|
||||||
|
}
|
||||||
|
var callback = args.callback;
|
||||||
|
var maxFileSize = args.maxSize;
|
||||||
|
MAX_FILE_SIZE_MB = Math.min((isEmpty(maxFileSize) ? MAX_FILE_SIZE_MB : maxFileSize), MAX_FILE_SIZE_MB);
|
||||||
|
var fileExtensions = args.extensions;
|
||||||
|
fileExtensions = isEmpty(fileExtensions) ? [] : fileExtensions;
|
||||||
|
|
||||||
|
var div = $("#" + divId).addClass("input-group");
|
||||||
|
if (isEmpty(div)) {
|
||||||
|
throw "Div with id " + divId + " is not found";
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileLabel = $("<input>")
|
||||||
|
.attr("type", "text")
|
||||||
|
.attr("placeholder", CHOOSE_FILE_TEXT)
|
||||||
|
.attr("disabled", true)
|
||||||
|
.addClass("form-control");
|
||||||
|
div.append(fileLabel);
|
||||||
|
var fileInput = $("<input>")
|
||||||
|
.attr("type", "file")
|
||||||
|
.hide();
|
||||||
|
fileInput.change(function () {
|
||||||
|
var files = $(this).prop("files");
|
||||||
|
if (isEmpty(files)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fileLabel.val(files[0].name);
|
||||||
|
});
|
||||||
|
div.append(fileInput);
|
||||||
|
|
||||||
|
var buttonGroup = $("<div>")
|
||||||
|
.addClass("input-group-btn");
|
||||||
|
div.append(buttonGroup);
|
||||||
|
|
||||||
|
var chooseButton = $("<button>")
|
||||||
|
.attr("type", "button")
|
||||||
|
.addClass("btn btn-default")
|
||||||
|
.append($("<i>").addClass("fa fa-ellipsis-h"));
|
||||||
|
chooseButton.click(function () {
|
||||||
|
fileInput.click();
|
||||||
|
});
|
||||||
|
buttonGroup.append(chooseButton);
|
||||||
|
|
||||||
|
var uploadButton = $("<button>")
|
||||||
|
.attr("type", "button")
|
||||||
|
.addClass("btn btn-default")
|
||||||
|
.append($("<i>").addClass("fa fa-upload"));
|
||||||
|
uploadButton.click(function () {
|
||||||
|
var files = fileInput.prop("files");
|
||||||
|
if (isEmpty(files)) {
|
||||||
|
showFeedbackMessage(ALERT_CHOOSE_FILE, MessageTypesEnum.DANGER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var currentFile = files[0];
|
||||||
|
if (!isEmpty(fileExtensions) && fileExtensions.indexOf(getFileExt(currentFile)) === -1) {
|
||||||
|
showFeedbackMessage(ALERT_UNKNOWN_FILE_EXT, MessageTypesEnum.DANGER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (currentFile.size === 0) {
|
||||||
|
showFeedbackMessage(ALERT_EMPTY_FILE, MessageTypesEnum.DANGER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (currentFile.size / SIZE_TO_MB > MAX_FILE_SIZE_MB) {
|
||||||
|
showFeedbackMessage(ALERT_MAX_FILE + " " + MAX_FILE_SIZE_MB + "Mb", MessageTypesEnum.DANGER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
upload(currentFile);
|
||||||
|
});
|
||||||
|
buttonGroup.append(uploadButton);
|
||||||
|
|
||||||
|
var progressDiv = $("<div>")
|
||||||
|
.addClass("progress margined-top-10");
|
||||||
|
progressDiv.insertAfter(div);
|
||||||
|
var progressBar = $("<div>")
|
||||||
|
.addClass("progress-bar")
|
||||||
|
.attr("role", "progressbar")
|
||||||
|
.css("width", "0%");
|
||||||
|
progressDiv.append(progressBar);
|
||||||
|
|
||||||
|
function getFileExt(file) {
|
||||||
|
return file.name.slice((Math.max(0, file.name.lastIndexOf(".")) || Infinity) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function upload(file) {
|
||||||
|
progressBar.css("width", "0%");
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.upload.onprogress = function (event) {
|
||||||
|
var curProgress = Math.floor(event.loaded / event.total * 100) + "%";
|
||||||
|
progressBar
|
||||||
|
.css("width", curProgress)
|
||||||
|
.text(curProgress);
|
||||||
|
};
|
||||||
|
xhr.onload = xhr.onerror = function () {
|
||||||
|
if (this.status === 200) {
|
||||||
|
errorHandler(JSON.parse(this.responseText), callback);
|
||||||
|
} else {
|
||||||
|
showFeedbackMessage(ERROR, MessageTypesEnum.DANGER);
|
||||||
|
console.error("error " + this.status);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.open("POST", url, true);
|
||||||
|
var formData = new FormData();
|
||||||
|
formData.append("file", file);
|
||||||
|
xhr.send(formData);
|
||||||
|
}
|
||||||
|
}
|
42
src/main/resources/templates/load.html
Normal file
42
src/main/resources/templates/load.html
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en"
|
||||||
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
layout:decorator="default">
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container" layout:fragment="content">
|
||||||
|
<section id="load">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row" id="paper-list">
|
||||||
|
<div class="col-lg-12 text-center">
|
||||||
|
<h2 class="section-heading text-uppercase">Статьи</h2>
|
||||||
|
<div id="loader">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="/js/file-loader.js"></script>
|
||||||
|
<script>
|
||||||
|
/*<![CDATA[*/
|
||||||
|
$(document).ready(function () {
|
||||||
|
new FileLoader({
|
||||||
|
div: "loader",
|
||||||
|
url: urlFileUpload,
|
||||||
|
maxSize: 1.5,
|
||||||
|
extensions: ["xls", "jpg", "pdf", "txt", "png"],
|
||||||
|
callback: function (response) {
|
||||||
|
showFeedbackMessage("Файл успешно загружен");
|
||||||
|
console.debug(response);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
/*]]>*/
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user