Merge branch '27-file-upload' into 'master'

Resolve "Пример для загрузки файлов"

Closes #27

See merge request romanov73/ng-tracker!7
merge-requests/9/head
Anton Romanov 6 years ago
commit 2a493205f3

@ -3,7 +3,12 @@ package ru.ulstu.file;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
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 ru.ulstu.configuration.Constants;
import ru.ulstu.core.model.response.Response;
@ -13,7 +18,6 @@ import ru.ulstu.file.service.FileService;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import static java.nio.charset.StandardCharsets.UTF_8;
import static ru.ulstu.paper.controller.PaperController.URL;
@ -47,7 +51,7 @@ public class FileController {
}
@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));
}
}

@ -1,6 +1,8 @@
// from config.js
/* global urlVersions */
var urlFileUpload = "https://localhost:8443/api/1.0/papers/uploadTmpFile";
/* exported MessageTypesEnum */
var MessageTypesEnum = {
INFO: "info",

@ -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);
}
}

@ -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…
Cancel
Save