Browse Source

模板查看页面支持上传文件

sunyj 9 years ago
parent
commit
39e8cf5389

+ 8 - 2
src/main/java/com/uas/report/controller/FileController.java

@@ -42,8 +42,14 @@ public class FileController {
 
 	@RequestMapping("/upload")
 	@ResponseBody
-	public String upload(String userName, String fileType, MultipartFile file) {
-		return fileService.upload(userName, fileType, file);
+	public String upload(String userName, String fileType, String filePath, Boolean isAbsolutePath,
+			MultipartFile file) {
+		// 未指定上传文件路径,则按照账套名称上传
+		if (StringUtils.isEmpty(filePath)) {
+			return fileService.upload(userName, fileType, file);
+		} else {
+			return fileService.upload(filePath, isAbsolutePath, file);
+		}
 	}
 
 	/**

+ 19 - 4
src/main/java/com/uas/report/service/FileService.java

@@ -25,16 +25,31 @@ public interface FileService {
 	public String autoDeploy(String userNames);
 
 	/**
-	 * 上传文件
+	 * 上传文件至指定的账套下
 	 * 
 	 * @param userName
 	 *            账套名,文件上传至相应账套路径下
+	 * @param fileType
+	 *            上传的文件的类型:jrxml、image、zip、other
 	 * @param file
 	 *            上传的文件
 	 * @return 上传结果
 	 */
 	public String upload(String userName, String fileType, MultipartFile file);
 
+	/**
+	 * 上传文件至指定的路径下
+	 * 
+	 * @param filePath
+	 *            指定的文件路径
+	 * @param isAbsolutePath
+	 *            文件路径是否为绝对路径,不传的话默认为假
+	 * @param file
+	 *            上传的文件
+	 * @return 上传结果
+	 */
+	public String upload(String filePath, Boolean isAbsolutePath, MultipartFile file);
+
 	/**
 	 * 获取账套下的模板路径
 	 * 
@@ -77,7 +92,7 @@ public interface FileService {
 	 * @param filePath
 	 *            文件路径
 	 * @param isAbsolutePath
-	 *            文件路径是否为绝对路径
+	 *            文件路径是否为绝对路径,不传的话默认为假
 	 * @param response
 	 */
 	public void download(String filePath, Boolean isAbsolutePath, HttpServletResponse response);
@@ -88,7 +103,7 @@ public interface FileService {
 	 * @param filePath
 	 *            文件(夹)路径
 	 * @param isAbsolutePath
-	 *            文件(夹)路径是否为绝对路径
+	 *            文件(夹)路径是否为绝对路径,不传的话默认为假
 	 * @return 文件(夹)绝对路径
 	 */
 	public String delete(String filePath, Boolean isAbsolutePath);
@@ -99,7 +114,7 @@ public interface FileService {
 	 * @param filePath
 	 *            指定的路径
 	 * @param isAbsolutePath
-	 *            文件路径是否为绝对路径
+	 *            文件路径是否为绝对路径,不传的话默认为假
 	 * @return 文件信息,包括name(String)、lastModified(String)、size(Long)、filePath(
 	 *         String,可能是相对路径,也可能是绝对路径,具体取决于isAbsolutePath)、isDirectory(Boolean)
 	 */

+ 38 - 3
src/main/java/com/uas/report/service/impl/FileServiceImpl.java

@@ -127,8 +127,8 @@ public class FileServiceImpl implements FileService {
 		stringBuilder.append(fileName);
 		String targetFilePath = stringBuilder.toString();
 		final File targetFile = new File(targetFilePath);
-		if (!targetFile.exists()) {
-			targetFile.mkdirs();
+		if (!targetFile.getParentFile().exists()) {
+			targetFile.getParentFile().mkdirs();
 		}
 		try {
 			file.transferTo(targetFile);
@@ -154,6 +154,41 @@ public class FileServiceImpl implements FileService {
 		return message;
 	}
 
+	@Override
+	public String upload(String filePath, Boolean isAbsolutePath, MultipartFile file) {
+		logger.info("request... " + filePath);
+		String message;
+		if (file == null || file.isEmpty()) {
+			message = "文件为空,无法进行上传!";
+			logger.error(message);
+			return message;
+		}
+		filePath = getAbsolutePath(filePath, isAbsolutePath);
+		File targetFile = new File(filePath);
+		// 根据所上传的文件名称创建文件
+		if (targetFile.exists() && targetFile.isFile()) {
+			targetFile = new File(targetFile.getParent() + "/" + file.getOriginalFilename());
+		} else {
+			targetFile = new File(targetFile.getPath() + "/" + file.getOriginalFilename());
+		}
+		// 检查路径是否存在
+		if (!targetFile.getParentFile().exists()) {
+			targetFile.getParentFile().mkdirs();
+		}
+		try {
+			file.transferTo(targetFile);
+			message = "成功上传文件至:" + targetFile.getPath();
+			logger.info(message);
+			return message;
+		} catch (IllegalStateException | IOException e) {
+			e.printStackTrace();
+		}
+
+		message = "上传文件失败: " + targetFile.getPath();
+		logger.error(message);
+		return message;
+	}
+
 	@Override
 	public String getJrxmlFilePath(String userName, String reportName) {
 		ReportUtils.checkParameters(userName, reportName);
@@ -264,7 +299,7 @@ public class FileServiceImpl implements FileService {
 	public List<Map<String, Object>> listFiles(String filePath, Boolean isAbsolutePath) {
 		logger.info("request... " + filePath);
 		filePath = getAbsolutePath(filePath, isAbsolutePath);
-		final File file = new File(filePath);
+		File file = new File(filePath);
 		if (!file.exists()) {
 			throw new ReportException("文件不存在:" + filePath);
 		}

+ 1 - 0
src/main/webapp/WEB-INF/views/console.html

@@ -41,6 +41,7 @@
 					<li><a target="_blank">files</a></li>
 					<li><a target="_blank">files?filePath=C:/sunyj/reports</a></li>
 					<li><a target="_blank">files?filePath=C:\Users\sunyj-pc\Downloads&showDelete=true</a></li>
+					<li><a target="_blank">files?filePath=C:\Users\sunyj-pc\Downloads&showDelete=true&showUpload=true</a></li>
 				</ol>
 
 				<strong><li class="title1">上传</li></strong>

+ 1 - 0
src/main/webapp/WEB-INF/views/fileUpload.html

@@ -30,5 +30,6 @@
 	<p id="result"></p>
 </body>
 <script src="static/lib/jquery/jquery.min.js"></script>
+<script src="static/js/util/utils.js"></script>
 <script src="static/js/upload/app.js"></script>
 </html>

+ 7 - 2
src/main/webapp/WEB-INF/views/files.html

@@ -10,11 +10,11 @@
 <body>
 	<div id="listContainer">
 		<div id="topContainer">
-			<div id="currentPathContainer">
+			<div id="currentPathContainer" class="overflowHidden">
 				<span>当前路径:<span id="currentPath"></span></span>
 			</div>
 			<div id="searchContainer" hidden="true">
-				<span>搜索: <input class="search" /></span>
+				<span>搜索: <input id="search" class="search" /></span>
 			</div>
 			<br /> <br />
 			<div id="listHeaderContainer">
@@ -44,6 +44,11 @@
 		<button id="detailedMessageButton" title="获取更多错误信息" hidden="true">更多信息</button>
 		<p id="detailedMessage" hidden="true"></p>
 	</div>
+	<div id="uploadContainer" hidden="true">
+		<button id="uploadButton" title="上传">
+			<i class="fa fa-cloud-upload upload" aria-hidden="true"> </i>
+		</button>
+	</div>
 </body>
 
 <script src="static/lib/jquery/jquery.min.js"></script>

+ 0 - 1
src/main/webapp/WEB-INF/views/preview.html

@@ -77,7 +77,6 @@
 <script src="static/lib/pdf.js/build/pdf.js"></script>
 <script src="static/lib/jquery/jquery.min.js"></script>
 <script src="static/lib/jquery/ba-tiny-pubsub.min.js"></script>
-<script src="static/lib/spin/spin.min.js"></script>
 <script src="static/js/util/utils.js"></script>
 <script src="static/js/preview/app.js"></script>
 </html>

+ 11 - 0
src/main/webapp/resources/css/files.css

@@ -10,6 +10,7 @@ body {
 
 #searchContainer {
 	float: right;
+	margin-right: 3%;
 }
 
 .columnNameHeader {
@@ -79,4 +80,14 @@ button {
 	border: 0px;
 	outline: none;
 	cursor: pointer;
+}
+
+#uploadContainer {
+	position: fixed;
+	top: 85%;
+	left: 90%;
+}
+
+i.upload {
+	font-size: 50px;
 }

+ 55 - 9
src/main/webapp/resources/js/files/app.js

@@ -1,5 +1,12 @@
-//获取链接中的参数,如果存在,则表示进入指定的绝对路径
+// 用于显示正在加载的提示
+var spinner;
+var spinnerContainer = document.getElementById("listContainer");
+
+// 获取链接中的filePath参数,如果存在,则表示进入指定的绝对路径
 var filePathParameter = getParameter("filePath");
+// 是否显示上传按钮
+var showUpload = getParameter("showUpload");
+// 是否显示删除按钮
 var showDelete = getParameter("showDelete");
 var currentPath = new Object();
 // 如果不存在filePath参数,表示进入相对路径(相对于所配置的本地资源根路径)
@@ -15,6 +22,35 @@ $("#parentPath").click(function() {
 	}
 });
 
+$("#uploadButton").click(function() {
+	var uploadUrl = "file/upload";
+	var params = new Object();
+	// 传递参数
+	params.filePath = currentPath.value;
+	if (filePathParameter) {
+		params.isAbsolutePath = true;
+	}
+	var fileInvalid = upload({
+		url : uploadUrl,
+		multiple : false,// 是否上传多个文件
+		maxSize : 1000,// 单个文件大小的上限(MB)
+		params : params,// 其他参数
+		success : function(data) {
+			spinner = hideLoading(spinner);
+			listFiles(currentPath.value);
+		},
+		error : function(xhr) {
+			console.log(xhr);
+			alert("上传失败");
+			spinner = hideLoading(spinner);
+		},
+		showLoading : function() {
+			console.log("fileInvlid");
+			spinner = showLoading(spinner, spinnerContainer);
+		}
+	});
+});
+
 /**
  * 请求文件信息
  * 
@@ -22,7 +58,8 @@ $("#parentPath").click(function() {
  *            文件路径
  */
 function listFiles(path) {
-	console.log(JSON.stringify(currentPath));
+	console.log("request... " + JSON.stringify(currentPath));
+	$("#errorMessageContainer").attr("hidden", "true");
 	$("#currentPath").text(currentPath.value);
 	if (!currentPath.parent) {
 		$("#parentPathContainer").attr("hidden", "true");
@@ -44,10 +81,15 @@ function listFiles(path) {
 			$(".listItem").remove();
 			if (!data.length) {
 				showErrorMessage("文件数量为0");
-			}
-			for (var i = 0; i < data.length; i++) {
-				addList(data[i].name, data[i].size, data[i].lastModified,
-						data[i].filePath, data[i].isDirectory);
+			} else {
+				// 如果在参数中指定显示上传按钮,则不再隐藏
+				if (showUpload) {
+					$("#uploadContainer").removeAttr("hidden");
+				}
+				for (var i = 0; i < data.length; i++) {
+					addList(data[i].name, data[i].size, data[i].lastModified,
+							data[i].filePath, data[i].isDirectory);
+				}
 			}
 		},
 		error : function(XMLHttpRequest) {
@@ -97,13 +139,14 @@ function addList(name, size, lastModified, filePath, isDirectory) {
 			+ fileIcon
 			+ "' aria-hidden='true'></i>&nbsp&nbsp&nbsp&nbsp<span class='likeHref'>"
 			+ name + "</span></div>");
-	var sizeDiv = $("<div class='columnSize'><span>" + size + "</span></div>");
-	var lastModifiedDiv = $("<div class='columnLastModified'><span>"
+	var sizeDiv = $("<div class='columnSize' overflowHidden><span>" + size
+			+ "</span></div>");
+	var lastModifiedDiv = $("<div class='columnLastModified overflowHidden'><span>"
 			+ lastModified + "</span></div>");
 
 	var downloadButton = $("<button id='downloadButton' title='下载'><i class='fa fa-cloud-download fa-lg' aria-hidden='true'></i></button>");
 	var deleteButton = $("<button id='deleteButton' title='删除'><i class='fa fa-trash fa-lg' aria-hidden='true'></i>");
-	var operationDiv = $("<div class='columnOperation'></div>");
+	var operationDiv = $("<div class='columnOperation' overflowHidden></div>");
 	operationDiv.append(downloadButton);
 
 	listItemDiv.append(nameDiv);
@@ -158,6 +201,7 @@ function download(path) {
  * @param path
  */
 function deleteFile(path, listItemDiv) {
+	spinner = showLoading(spinner, spinnerContainer);
 	var deleteUrl = "file/delete?filePath=" + path;
 	// 如果链接中指定路径,则表示请求的绝对路径
 	if (filePathParameter) {
@@ -168,9 +212,11 @@ function deleteFile(path, listItemDiv) {
 		url : deleteUrl,
 		success : function(data) {
 			listItemDiv.remove();
+			spinner = hideLoading(spinner);
 		},
 		error : function(XMLHttpRequest) {
 			showErrorMessage(XMLHttpRequest);
+			spinner = hideLoading(spinner);
 		}
 	});
 }

+ 12 - 73
src/main/webapp/resources/js/preview/app.js

@@ -7,6 +7,7 @@ var ctx = canvas.getContext('2d');
 var hiddenFrame = document.getElementById("hiddenFrame");
 // 用于显示正在加载的提示
 var spinner;
+var spinnerContainer = document.getElementById('viewerContainer');
 
 // 能打印的最大页数(页数超过,需要先下载pdf,再打印)
 var PRINT_MAX_PAGE_SIZE = 200;
@@ -109,7 +110,7 @@ $("#downloadPdf").click(
 			console.log(new Date().format()
 					+ " ---- subscribed wholePdfGeneratedSignal");
 			$.subscribe("wholePdfGeneratedSignal", downloadPdf);
-			showLoading();
+			spinner = showLoading(spinner,spinnerContainer);
 			waitWholePdfGenerated();
 		});
 
@@ -117,7 +118,7 @@ $("#downloadPdf").click(
  * 下载文件
  */
 function downloadPdf() {
-	hideLoading();
+	spinner = hideLoading(spinner);
 	console.log(new Date().format()
 			+ " ---- received and unsubscribe wholePdfGeneratedSignal");
 	$.unsubscribe("wholePdfGeneratedSignal", downloadPdf);
@@ -181,7 +182,7 @@ function getWindowWidth() {
  * 打印
  */
 function printPdf() {
-	hideLoading();
+	spinner = hideLoading(spinner);
 	if (pageSize > PRINT_MAX_PAGE_SIZE) {
 		alert(ALERT_FILE_TOO_LARGE);
 		return;
@@ -192,7 +193,7 @@ function printPdf() {
 	console.log(new Date().format()
 			+ " ---- subscribed wholePdfGeneratedSignal");
 	$.subscribe("wholePdfGeneratedSignal", print);
-	showLoading();
+	spinner = showLoading(spinner,spinnerContainer);
 	waitWholePdfGenerated();
 }
 
@@ -204,7 +205,7 @@ function print() {
 			+ " ---- received and unsubscribe wholePdfGeneratedSignal");
 	$.unsubscribe("wholePdfGeneratedSignal", print);
 	console.log(new Date().format() + " ---- start print...");
-	setTimeout("hiddenFrame.contentWindow.print();hideLoading()", 1000);
+	setTimeout("hiddenFrame.contentWindow.print();spinner = hideLoading(spinner)", 1000);
 }
 
 /**
@@ -229,14 +230,14 @@ function loadPagedPdf(pagedPdfPath, ifPreloadWholePdf) {
 							if (printType == 'PRINT'
 									&& pageSize > PRINT_MAX_PAGE_SIZE) {
 								alert(ALERT_FILE_TOO_LARGE);
-								hideLoading();
+								spinner = hideLoading(spinner);
 							} else {
 								console
 										.log(new Date().format()
 												+ " ---- subscribed wholePdfGeneratedSignal");
 								$.subscribe("wholePdfGeneratedSignal",
 										loadWholePdf);
-								showLoading();
+								spinner = showLoading(spinner,spinnerContainer);
 								waitWholePdfGenerated();
 							}
 						}
@@ -254,7 +255,7 @@ function loadPagedPdf(pagedPdfPath, ifPreloadWholePdf) {
  */
 function loadData(page) {
 	ctx.clearRect(0, 0, canvas.width, canvas.height);
-	showLoading();
+	spinner = showLoading(spinner,spinnerContainer);
 	pageIndex = page || 1;
 	var loadPdfDataUrl = "print/loadPdfData" + window.location.search;
 	loadPdfDataUrl = loadPdfDataUrl + "&pageIndex=" + pageIndex;
@@ -282,7 +283,7 @@ function loadData(page) {
 		},
 		error : function(XMLHttpRequest) {
 			$("#theCanvas").remove();
-			hideLoading();
+			spinner = hideLoading(spinner);
 			$("#errorMessageContainer").removeAttr("hidden");
 
 			// 处理后台传输的自定义的换行标志
@@ -359,9 +360,9 @@ function getGeneratedPdfOrXlsInformation(fileType) {
  * Get page info from document, resize canvas accordingly, and render page
  */
 function renderPage() {
-	hideLoading();
+	spinner = hideLoading(spinner);
 	if (firstRequest && printType == "PRINT" && pageSize <= PRINT_MAX_PAGE_SIZE) {
-		showLoading();
+		spinner = showLoading(spinner,spinnerContainer);
 	}
 	if (!pdfDoc) {
 		return;
@@ -478,65 +479,3 @@ function downloadUrl(exportFileType) {
 	downloadUrl += "&exportFileType=" + exportFileType;
 	return downloadUrl;
 }
-
-/**
- * 显示正在载入的动画
- */
-function showLoading() {
-	if (spinner) {
-		return;
-	}
-	var opts = {
-		lines : 9 // The number of lines to draw
-		,
-		length : 17 // The length of each line
-		,
-		width : 10 // The line thickness
-		,
-		radius : 26 // The radius of the inner circle
-		,
-		scale : 1 // Scales overall size of the spinner
-		,
-		corners : 1 // Corner roundness (0..1)
-		,
-		color : '#000' // #rgb or #rrggbb or array of colors
-		,
-		opacity : 0.5 // Opacity of the lines
-		,
-		rotate : 0 // The rotation offset
-		,
-		direction : 1 // 1: clockwise, -1: counterclockwise
-		,
-		speed : 1 // Rounds per second
-		,
-		trail : 60 // Afterglow percentage
-		,
-		fps : 20 // Frames per second when using setTimeout() as a fallback
-		// for CSS
-		,
-		zIndex : 2e9 // The z-index (defaults to 2000000000)
-		,
-		className : 'spinner' // The CSS class to assign to the spinner
-		,
-		top : '50%' // Top position relative to parent
-		,
-		left : '50%' // Left position relative to parent
-		,
-		shadow : false // Whether to render a shadow
-		,
-		hwaccel : false // Whether to use hardware acceleration
-		,
-		position : 'absolute' // Element positioning
-	}
-	var target = document.getElementById('viewerContainer');
-	spinner = new Spinner(opts).spin(target);
-}
-/**
- * 关闭正在载入的动画
- */
-function hideLoading() {
-	if (spinner) {
-		spinner.stop();
-		spinner = null;
-	}
-}

+ 0 - 15
src/main/webapp/resources/js/upload/app.js

@@ -89,18 +89,3 @@ function progressHandlingFunction(e) {
 						+ "%");
 	}
 }
-
-/**
- * 获取链接参数
- * 
- * @param key
- *            参数名
- * @returns 参数值
- */
-function getParameter(key) {
-	var reg = new RegExp("(^|&)" + key + "=([^&]*)(&|$)");
-	var r = window.location.search.substr(1).match(reg);
-	if (r != null)
-		return unescape(r[2]);
-	return null;
-};

+ 138 - 0
src/main/webapp/resources/js/util/utils.js

@@ -1,3 +1,5 @@
+document.write("<script src='static/lib/spin/spin.min.js'></script>");
+
 /**
  * 获取链接参数
  * 
@@ -48,4 +50,140 @@ Date.prototype.format = function(fmt) { // author: meizz
 			fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k])
 					: (("00" + o[k]).substr(("" + o[k]).length)));
 	return fmt;
+}
+
+/**
+ * 上传文件
+ * 
+ * @param option
+ *            上传选项
+ */
+function upload(option) {
+	// 文件选择框
+	var input = document.getElementById("inputFile");
+	if (!input) {
+		input = document.createElement("input");
+		input.setAttribute("id", "inputFile");
+		input.setAttribute("type", "file");
+		input.setAttribute("name", "file");
+		input.setAttribute("hidden", "true");
+	}
+	if (option.multiple) {
+		input.setAttribute("multiple", true);
+	}
+	document.body.appendChild(input);
+	input.click();
+	input.onchange = function() {
+		if (!input.value) {
+			return;
+		}
+		// 验证文件大小
+		console.log("selected... " + input.value);
+		for (var i = 0; i < input.files.length; i++) {
+			var file = input.files[i];
+			if (option.maxSize && file.size > option.maxSize * 1024 * 1024) {
+				alert("单个文件大小不能超过" + option.maxSize + "MB");
+				return;
+			}
+		}
+		// 指定的参数
+		var formData = new FormData();
+		formData.append("file", input.files[0]);
+		if (option.params) {
+			for ( var param in option.params) {
+				formData.append(param, option.params[param]);
+			}
+		}
+		var xhr = new XMLHttpRequest();
+		xhr.open("POST", option.url);
+		xhr.onreadystatechange = function() {
+			if (xhr.readyState == 4) {
+				if (xhr.status == 200) {
+					if (option.success instanceof Function) {
+						option.success(xhr.responseText);
+					}
+				} else {
+					if (option.error instanceof Function) {
+						option.error(xhr);
+					}
+				}
+			}
+		}
+		if (option.showLoading) {
+			option.showLoading();
+		}
+		xhr.send(formData);
+	}
+}
+
+/**
+ * 显示正在载入的动画
+ * 
+ * @param spinner
+ *            载入的动画
+ * @param container
+ *            动画所在的容器
+ * @returns 动画
+ */
+function showLoading(spinner, container) {
+	if (spinner) {
+		return spinner;
+	}
+	var opts = {
+		lines : 9 // The number of lines to draw
+		,
+		length : 17 // The length of each line
+		,
+		width : 10 // The line thickness
+		,
+		radius : 26 // The radius of the inner circle
+		,
+		scale : 1 // Scales overall size of the spinner
+		,
+		corners : 1 // Corner roundness (0..1)
+		,
+		color : '#000' // #rgb or #rrggbb or array of colors
+		,
+		opacity : 0.5 // Opacity of the lines
+		,
+		rotate : 0 // The rotation offset
+		,
+		direction : 1 // 1: clockwise, -1: counterclockwise
+		,
+		speed : 1 // Rounds per second
+		,
+		trail : 60 // Afterglow percentage
+		,
+		fps : 20 // Frames per second when using setTimeout() as a fallback
+		// for CSS
+		,
+		zIndex : 2e9 // The z-index (defaults to 2000000000)
+		,
+		className : 'spinner' // The CSS class to assign to the spinner
+		,
+		top : '50%' // Top position relative to parent
+		,
+		left : '50%' // Left position relative to parent
+		,
+		shadow : false // Whether to render a shadow
+		,
+		hwaccel : false // Whether to use hardware acceleration
+		,
+		position : 'absolute' // Element positioning
+	}
+	return new Spinner(opts).spin(container);
+}
+
+/**
+ * 关闭正在载入的动画
+ * 
+ * @param spinner
+ *            载入的动画
+ * @returns 动画
+ */
+function hideLoading(spinner) {
+	if (spinner) {
+		spinner.stop();
+	}
+	return null;
 }