From 4470052c3b6bdeb18e45987f8aa293d1e93d0552 Mon Sep 17 00:00:00 2001
From: Ludc <2870569285@qq.com>
Date: 星期二, 18 十一月 2025 11:59:12 +0800
Subject: [PATCH] 所有文件上传接口增加文件安全校验逻辑。

---
 Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/controller/CodeClassifyController.java   |   14 +
 Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/controller/FileController.java       |   19 +
 Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/controller/RegionController.java     |   13 +
 Source/UBCS/ubcs-service/ubcs-user/src/main/java/com/vci/ubcs/system/user/controller/UserController.java    |   19 +
 Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/endpoint/OssEndpoint.java            |   50 +--
 Source/UBCS/ubcs-common/src/main/java/com/vci/ubcs/common/validator/ComprehensiveFileValidator.java         |  477 +++++++++++++++++++++++++++++++++++++++
 Source/UBCS/ubcs-gateway/src/main/java/com/vci/ubcs/gateway/filter/EssentialSecurityFilter.java             |   42 +++
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowManagerController.java |   19 +
 Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/controller/MdmEngineController.java      |   40 +++
 Source/UBCS/ubcs-service/ubcs-deploy/src/main/java/com/vci/ubcs/deploy/controller/DeployAppsController.java |   13 +
 10 files changed, 663 insertions(+), 43 deletions(-)

diff --git a/Source/UBCS/ubcs-common/src/main/java/com/vci/ubcs/common/validator/ComprehensiveFileValidator.java b/Source/UBCS/ubcs-common/src/main/java/com/vci/ubcs/common/validator/ComprehensiveFileValidator.java
new file mode 100644
index 0000000..96b19cc
--- /dev/null
+++ b/Source/UBCS/ubcs-common/src/main/java/com/vci/ubcs/common/validator/ComprehensiveFileValidator.java
@@ -0,0 +1,477 @@
+package com.vci.ubcs.common.validator;
+
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.PostConstruct;
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 鏂囦欢瀹夊叏楠岃瘉鍣�
+ */
+@Component
+@Slf4j
+public class ComprehensiveFileValidator {
+
+	/**
+	 * 鏂囦欢鐧藉悕鍗�
+	 */
+	@Value("${app.upload.security.allowed-extensions:jpg,jpeg,png,pdf}")
+	private String allowedExtensionsConfig;
+
+	/**
+	 * 澶氶噸鎵╁睍鍚嶆枃浠剁姝�
+	 */
+	@Value("${app.upload.security.prevent-multiple-extensions:true}")
+	private boolean preventMultipleExtensions;
+
+	/**
+	 * 闄愬埗鐨勫嵄闄╂枃浠剁被鍨�
+	 */
+	@Value("${app.upload.security.dangerous-primary-extensions:jsp,jspx,php,asp,aspx,war,exe,sh,bat}")
+	private String dangerousExtensionsConfig;
+
+	/**
+	 * 鏂囦欢鍐呭绫诲瀷鏄惁鍖归厤鏍¢獙
+	 */
+	@Value("${app.upload.security.validate-content-type:true}")
+	private boolean validateContentType;
+
+	/**
+	 * 鏂囦欢澶撮獙璇�
+	 */
+	@Value("${app.upload.security.validate-file-header:true}")
+	private boolean validateFileHeader;
+
+	/**
+	 * 涓ユ牸妯″紡
+	 */
+	@Value("${app.upload.security.strict-mode:false}")
+	private boolean strictMode;
+
+	/**
+	 * 鍏佽涓婁紶鐨勫悗缂�
+	 */
+	private Set<String> allowedExtensions;
+
+	/**
+	 * 鍗遍櫓鐨勬枃浠跺悗缂�
+	 */
+	private Set<String> dangerousPrimaryExtensions;
+
+	@PostConstruct
+	public void init() {
+		// 瑙f瀽閫楀彿鍒嗛殧鐨勯厤缃�
+		this.allowedExtensions = parseCommaSeparatedConfig(allowedExtensionsConfig);
+		this.dangerousPrimaryExtensions = parseCommaSeparatedConfig(dangerousExtensionsConfig);
+
+		log.info("鏂囦欢涓婁紶楠岃瘉鍣ㄥ垵濮嬪寲瀹屾垚");
+		log.info("鍏佽鐨勬墿灞曞悕: {}", allowedExtensions);
+		log.info("鍗遍櫓鎵╁睍鍚�: {}", dangerousPrimaryExtensions);
+	}
+
+	private Set<String> parseCommaSeparatedConfig(String config) {
+		if (config == null || config.trim().isEmpty()) {
+			return new HashSet<>();
+		}
+		return Arrays.stream(config.split(","))
+			.map(String::trim)
+			.map(String::toLowerCase)
+			.collect(Collectors.toSet());
+	}
+
+	/**
+	 * 楠岃瘉鍗曚釜鏂囦欢
+	 */
+	public UploadValidationResult validateFile(MultipartFile file) {
+		UploadValidationResult result = new UploadValidationResult();
+
+		try {
+			// 鍩虹妫�鏌�
+			if (!basicValidation(file, result)) {
+				return result;
+			}
+
+			String filename = file.getOriginalFilename();
+
+			// 鏂囦欢鍚嶅畨鍏ㄩ獙璇�
+			if (!filenameSecurityValidation(filename, result)) {
+				return result;
+			}
+
+			// 鍐呭瀹夊叏楠岃瘉
+			if (!contentSecurityValidation(file, result)) {
+				return result;
+			}
+
+			result.setValid(true);
+			result.setMessage("鏂囦欢楠岃瘉閫氳繃");
+
+		} catch (Exception e) {
+			log.error("鏂囦欢楠岃瘉寮傚父", e);
+			result.setValid(false);
+			result.setMessage("楠岃瘉杩囩▼鍙戠敓寮傚父");
+		}
+
+		return result;
+	}
+
+	/**
+	 * 楠岃瘉澶氫釜鏂囦欢
+	 * @param files 鏂囦欢鍒楄〃
+	 * @return 澶氫釜鏂囦欢鐨勯獙璇佺粨鏋�
+	 */
+	public MultiUploadValidationResult validateFiles(List<MultipartFile> files) {
+		return validateFiles(files, false);
+	}
+
+	/**
+	 * 楠岃瘉澶氫釜鏂囦欢
+	 * @param files 鏂囦欢鍒楄〃
+	 * @param stopOnFirstError 閬囧埌绗竴涓敊璇槸鍚﹀仠姝㈤獙璇�
+	 * @return 澶氫釜鏂囦欢鐨勯獙璇佺粨鏋�
+	 */
+	public MultiUploadValidationResult validateFiles(List<MultipartFile> files, boolean stopOnFirstError) {
+		MultiUploadValidationResult result = new MultiUploadValidationResult();
+
+		if (files == null || files.isEmpty()) {
+			result.setValid(false);
+			result.setMessage("鏂囦欢鍒楄〃涓虹┖");
+			return result;
+		}
+
+		List<FileValidationDetail> details = new ArrayList<>();
+		boolean allValid = true;
+
+		for (int i = 0; i < files.size(); i++) {
+			MultipartFile file = files.get(i);
+			FileValidationDetail detail = new FileValidationDetail();
+			detail.setFileName(file.getOriginalFilename());
+			detail.setFileIndex(i);
+			detail.setFileSize(file.getSize());
+
+			// 楠岃瘉鍗曚釜鏂囦欢
+			UploadValidationResult singleResult = validateFile(file);
+			detail.setValid(singleResult.isValid());
+			detail.setMessage(singleResult.getMessage());
+			detail.setDetectedType(singleResult.getDetectedType());
+
+			details.add(detail);
+
+			if (!singleResult.isValid()) {
+				allValid = false;
+				if (stopOnFirstError) {
+					// 閬囧埌閿欒涓旇缃负蹇�熷け璐ワ紝绔嬪嵆杩斿洖
+					result.setValid(false);
+					result.setMessage("绗�" + (i + 1) + "涓枃浠堕獙璇佸け璐�: " + file.getOriginalFilename());
+					result.setDetails(details);
+					result.setFailedIndex(i);
+					return result;
+				}
+			}
+		}
+
+		result.setValid(allValid);
+		result.setMessage(allValid ? "鎵�鏈夋枃浠堕獙璇侀�氳繃" : "閮ㄥ垎鏂囦欢楠岃瘉澶辫触");
+		result.setDetails(details);
+		result.setTotalFiles(files.size());
+		result.setValidFiles((int) details.stream().filter(FileValidationDetail::isValid).count());
+		result.setInvalidFiles((int) details.stream().filter(d -> !d.isValid()).count());
+
+		return result;
+	}
+
+	/**
+	 * 楠岃瘉澶氫釜鏂囦欢锛堟暟缁勭増鏈級
+	 */
+	public MultiUploadValidationResult validateFiles(MultipartFile[] files) {
+		return validateFiles(Arrays.asList(files));
+	}
+
+	/**
+	 * 楠岃瘉澶氫釜鏂囦欢锛堟暟缁勭増鏈紝鍙缃槸鍚﹀揩閫熷け璐ワ級
+	 */
+	public MultiUploadValidationResult validateFiles(MultipartFile[] files, boolean stopOnFirstError) {
+		return validateFiles(Arrays.asList(files), stopOnFirstError);
+	}
+
+	/**
+	 * 鎵归噺楠岃瘉鏂囦欢骞惰繑鍥炴湁鏁堢殑鏂囦欢鍒楄〃
+	 */
+	public List<MultipartFile> getValidFiles(List<MultipartFile> files) {
+		MultiUploadValidationResult result = validateFiles(files);
+		List<MultipartFile> validFiles = new ArrayList<>();
+
+		for (int i = 0; i < files.size(); i++) {
+			if (result.getDetails().get(i).isValid()) {
+				validFiles.add(files.get(i));
+			}
+		}
+
+		return validFiles;
+	}
+
+	/**
+	 * 妫�鏌ユ槸鍚︽墍鏈夋枃浠堕兘鏈夋晥
+	 */
+	public boolean areAllFilesValid(List<MultipartFile> files) {
+		MultiUploadValidationResult result = validateFiles(files);
+		return result.isValid();
+	}
+
+	// 鍘熸湁鐨勭鏈夋柟娉曚繚鎸佷笉鍙�
+	private boolean basicValidation(MultipartFile file, UploadValidationResult result) {
+		if (file == null || file.isEmpty()) {
+			result.setMessage("鏂囦欢涓虹┖");
+			return false;
+		}
+
+		String filename = file.getOriginalFilename();
+		if (filename == null || filename.trim().isEmpty()) {
+			result.setMessage("鏂囦欢鍚嶄负绌�");
+			return false;
+		}
+
+		return true;
+	}
+
+	private boolean filenameSecurityValidation(String filename, UploadValidationResult result) {
+		// 璺緞閬嶅巻妫�鏌�
+		if (filename.contains("..") || filename.contains("/") || filename.contains("\\")) {
+			result.setMessage("鏂囦欢鍚嶅寘鍚嵄闄╁瓧绗�");
+			return false;
+		}
+
+		// 鎵╁睍鍚嶆鏌�
+		String finalExtension = getFinalExtension(filename);
+		if (finalExtension.isEmpty() || !allowedExtensions.contains(finalExtension.toLowerCase())) {
+			result.setMessage("涓嶆敮鎸佺殑鏂囦欢绫诲瀷: " + finalExtension);
+			return false;
+		}
+
+		// 澶氶噸鎵╁睍鍚嶆鏌�
+		if (preventMultipleExtensions && hasMultipleExtensions(filename)) {
+			if (strictMode) {
+				// 涓ユ牸妯″紡锛氭嫤鎴墍鏈夊閲嶆墿灞曞悕
+				result.setMessage("澶氶噸鎵╁睍鍚嶆枃浠惰绂佹");
+				return false;
+			} else {
+				// 鏅�氭ā寮忥細鍙嫤鎴寘鍚嵄闄╂墿灞曞悕鐨勫閲嶆墿灞曞悕
+				if (containsDangerousExtension(filename)) {
+					result.setMessage("妫�娴嬪埌浼Webshell鏂囦欢: " + filename);
+					return false;
+				}
+			}
+		}
+
+		return true;
+	}
+
+	private boolean contentSecurityValidation(MultipartFile file, UploadValidationResult result) {
+		// 鍐呭绫诲瀷楠岃瘉
+		if (validateContentType && !validateContentType(file)) {
+			result.setMessage("鏂囦欢鍐呭绫诲瀷涓嶅尮閰�");
+			return false;
+		}
+
+		// 鏂囦欢澶撮獙璇�
+		if (validateFileHeader && !validateFileHeader(file)) {
+			result.setMessage("鏂囦欢澶撮獙璇佸け璐�");
+			return false;
+		}
+
+		return true;
+	}
+
+	private boolean hasMultipleExtensions(String filename) {
+		String name = getFileNameWithoutPath(filename);
+		return name.chars().filter(ch -> ch == '.').count() > 1;
+	}
+
+	private boolean containsDangerousExtension(String filename) {
+		String name = getFileNameWithoutPath(filename);
+		String[] parts = name.split("\\.");
+
+		// 妫�鏌ラ櫎鏈�鍚庝竴涓墿灞曞悕涔嬪鐨勬墍鏈夐儴鍒�
+		for (int i = 0; i < parts.length - 1; i++) {
+			String part = parts[i].toLowerCase();
+			if (dangerousPrimaryExtensions.contains(part)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private boolean validateContentType(MultipartFile file) {
+		try {
+			String declaredType = file.getContentType();
+			if (declaredType == null) {
+				return true; // 娌℃湁澹版槑绫诲瀷锛屾斁杩�
+			}
+
+			// 绠�鍗曠殑绫诲瀷鍖归厤妫�鏌�
+			String finalExtension = getFinalExtension(file.getOriginalFilename()).toLowerCase();
+			return isContentTypeConsistent(declaredType, finalExtension);
+		} catch (Exception e) {
+			log.error("鍐呭绫诲瀷楠岃瘉澶辫触", e);
+			return false;
+		}
+	}
+
+	/**
+	 * 楠岃瘉鏂囦欢鐨勫唴瀹圭被鍨嬶紙Content-Type锛夋槸鍚︿笌鏂囦欢鎵╁睍鍚嶄竴鑷�
+	 * @param contentType
+	 * @param extension
+	 * @return
+	 */
+	private boolean isContentTypeConsistent(String contentType, String extension) {
+		// 鎵╁睍鏇村叏闈㈢殑绫诲瀷鏄犲皠
+		Map<String, String> expectedTypes = new HashMap<>();
+
+		// 鍥剧墖绫诲瀷
+		expectedTypes.put("jpg", "image/jpeg");
+		expectedTypes.put("jpeg", "image/jpeg");
+		expectedTypes.put("png", "image/png");
+		expectedTypes.put("gif", "image/gif");
+		expectedTypes.put("bmp", "image/bmp");
+		expectedTypes.put("webp", "image/webp");
+		expectedTypes.put("svg", "image/svg+xml");
+
+		// 鏂囨。绫诲瀷
+		expectedTypes.put("pdf", "application/pdf");
+		expectedTypes.put("doc", "application/msword");
+		expectedTypes.put("docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
+		expectedTypes.put("xls", "application/vnd.ms-excel");
+		expectedTypes.put("xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+		expectedTypes.put("ppt", "application/vnd.ms-powerpoint");
+		expectedTypes.put("pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation");
+		expectedTypes.put("txt", "text/plain");
+
+		// 鍘嬬缉鏂囦欢
+		expectedTypes.put("zip", "application/zip");
+		expectedTypes.put("rar", "application/x-rar-compressed");
+		expectedTypes.put("7z", "application/x-7z-compressed");
+
+		String expectedType = expectedTypes.get(extension);
+		return expectedType == null || expectedType.equalsIgnoreCase(contentType);
+	}
+
+	private boolean validateFileHeader(MultipartFile file) {
+		try {
+			byte[] header = new byte[8];
+			int bytesRead = file.getInputStream().read(header);
+
+			if (bytesRead < 4) {
+				return false;
+			}
+
+			String finalExtension = getFinalExtension(file.getOriginalFilename()).toLowerCase();
+
+			// 鍩虹鐨勬枃浠跺ご楠岃瘉
+			switch (finalExtension) {
+				case "jpg":
+				case "jpeg":
+					return isJpeg(header);
+				case "png":
+					return isPng(header);
+				case "pdf":
+					return isPdf(header);
+				case "gif":
+					return isGif(header);
+				default:
+					return true; // 鍏朵粬绫诲瀷涓嶉獙璇佹枃浠跺ご
+			}
+		} catch (IOException e) {
+			log.error("鏂囦欢澶撮獙璇佸け璐�", e);
+			return false;
+		}
+	}
+
+	/**
+	 * 鏂囦欢澶撮獙璇佹柟娉�
+	 * @param header
+	 * @return
+	 */
+	private boolean isJpeg(byte[] header) {
+		return (header[0] & 0xFF) == 0xFF && (header[1] & 0xFF) == 0xD8;
+	}
+
+	private boolean isPng(byte[] header) {
+		return header[0] == (byte) 0x89 && header[1] == 0x50 &&
+			header[2] == 0x4E && header[3] == 0x47;
+	}
+
+	private boolean isPdf(byte[] header) {
+		return header[0] == 0x25 && header[1] == 0x50 &&
+			header[2] == 0x44 && header[3] == 0x46;
+	}
+
+	private boolean isGif(byte[] header) {
+		return header[0] == 'G' && header[1] == 'I' &&
+			header[2] == 'F' && header[3] == '8';
+	}
+
+	// 杈呭姪鏂规硶
+	private String getFinalExtension(String filename) {
+		if (filename == null || !filename.contains(".")) return "";
+		String[] parts = filename.split("\\.");
+		return parts[parts.length - 1];
+	}
+
+	private String getFileNameWithoutPath(String filename) {
+		if (filename == null) return "";
+		filename = filename.replace('\\', '/');
+		int lastSlash = filename.lastIndexOf('/');
+		return lastSlash >= 0 ? filename.substring(lastSlash + 1) : filename;
+	}
+
+	@Data
+	public static class UploadValidationResult {
+		private boolean valid;
+		private String message;
+		private String detectedType;
+
+		public UploadValidationResult() {
+			this.valid = false;
+			this.message = "";
+		}
+	}
+
+	/**
+	 * 澶氭枃浠堕獙璇佺粨鏋�
+	 */
+	@Data
+	public static class MultiUploadValidationResult {
+		private boolean valid;
+		private String message;
+		private int totalFiles;
+		private int validFiles;
+		private int invalidFiles;
+		private int failedIndex = -1; // 绗竴涓け璐ョ殑鏂囦欢绱㈠紩
+		private List<FileValidationDetail> details;
+
+		public MultiUploadValidationResult() {
+			this.valid = false;
+			this.message = "";
+			this.details = new ArrayList<>();
+		}
+	}
+
+	/**
+	 * 鍗曚釜鏂囦欢楠岃瘉璇︽儏
+	 */
+	@Data
+	public static class FileValidationDetail {
+		private String fileName;
+		private int fileIndex;
+		private long fileSize;
+		private boolean valid;
+		private String message;
+		private String detectedType;
+	}
+}
diff --git a/Source/UBCS/ubcs-gateway/src/main/java/com/vci/ubcs/gateway/filter/EssentialSecurityFilter.java b/Source/UBCS/ubcs-gateway/src/main/java/com/vci/ubcs/gateway/filter/EssentialSecurityFilter.java
new file mode 100644
index 0000000..9813539
--- /dev/null
+++ b/Source/UBCS/ubcs-gateway/src/main/java/com/vci/ubcs/gateway/filter/EssentialSecurityFilter.java
@@ -0,0 +1,42 @@
+package com.vci.ubcs.gateway.filter;
+
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+/**
+ * 缃戝叧杩囨护鍣紝鎷︽埅鏄庣‘鐨勬敾鍑荤壒寰�
+ */
+public class EssentialSecurityFilter implements GlobalFilter {
+
+	@Override
+	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+		ServerHttpRequest request = exchange.getRequest();
+		String path = request.getPath().value();
+
+		// 鍙嫤鎴渶鍗遍櫓鐨勮姹�
+		if (isDefinitelyDangerous(path)) {
+			return blockRequest(exchange, "鍗遍櫓璇锋眰琚嫤鎴紒");
+		}
+
+		return chain.filter(exchange);
+	}
+
+	private boolean isDefinitelyDangerous(String path) {
+		// 鍙嫤鎴槑纭殑鏀诲嚮鐗瑰緛
+		return path.contains("../") ||
+			path.contains("/WEB-INF/") ||
+			path.matches(".*\\.(jsp|war|sh|bat|exe)$") ||
+			path.contains("cmd.exe") ||
+			path.contains("/bin/");
+	}
+
+	private Mono<Void> blockRequest(ServerWebExchange exchange, String message) {
+		exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
+		return exchange.getResponse().setComplete();
+	}
+
+}
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowManagerController.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowManagerController.java
index 6c41ebc..c46518a 100644
--- a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowManagerController.java
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowManagerController.java
@@ -18,6 +18,7 @@
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import com.vci.ubcs.common.validator.ComprehensiveFileValidator;
 import com.vci.ubcs.flow.engine.entity.FlowProcess;
 import com.vci.ubcs.flow.engine.service.FlowEngineService;
 import io.swagger.annotations.Api;
@@ -31,6 +32,7 @@
 import org.springblade.core.tool.support.Kv;
 import org.springblade.core.tool.utils.Func;
 import com.vci.ubcs.flow.engine.constant.FlowEngineConstant;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -47,10 +49,15 @@
 @RequestMapping("manager")
 @AllArgsConstructor
 @Api(value = "娴佺▼绠$悊鎺ュ彛", tags = "娴佺▼绠$悊鎺ュ彛")
-//@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR)
 public class FlowManagerController {
 
 	private final FlowEngineService flowEngineService;
+
+	/**
+	 * 鏂囦欢瀹夊叏妫�鏌�
+	 */
+	@Autowired
+	private ComprehensiveFileValidator fileValidator;
 
 	/**
 	 * 鍒嗛〉
@@ -98,6 +105,11 @@
 	@ApiOperationSupport(order = 4)
 	@ApiOperation(value = "涓婁紶閮ㄧ讲娴佺▼鏂囦欢", notes = "浼犲叆鏂囦欢")
 	public R checkUpload(@RequestParam MultipartFile file) {
+		// 浣跨敤鏂囦欢瀹夊叏楠岃瘉鍣�
+		ComprehensiveFileValidator.UploadValidationResult result = fileValidator.validateFile(file);
+		if (!result.isValid()) {
+			return R.fail(result.getMessage());
+		}
 		boolean temp = Objects.requireNonNull(file.getOriginalFilename()).endsWith(FlowEngineConstant.SUFFIX);
 		return R.data(Kv.create().set("name", file.getOriginalFilename()).set("success", temp));
 	}
@@ -114,6 +126,11 @@
 	public R deployUpload(@RequestParam List<MultipartFile> files,
 						  @RequestParam String category,
 						  @RequestParam(required = false, defaultValue = "") String tenantIds) {
+		// 浣跨敤鏂囦欢瀹夊叏楠岃瘉鍣�
+		ComprehensiveFileValidator.MultiUploadValidationResult result = fileValidator.validateFiles(files,true);
+		if (!result.isValid()) {
+			return R.fail(result.getMessage());
+		}
 		return R.status(flowEngineService.deployUpload(files, category, Func.toStrList(tenantIds)));
 	}
 
diff --git a/Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/controller/FileController.java b/Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/controller/FileController.java
index 626effe..42a7ba4 100644
--- a/Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/controller/FileController.java
+++ b/Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/controller/FileController.java
@@ -1,8 +1,8 @@
 package com.vci.ubcs.resource.controller;
 
-import com.alibaba.fastjson.JSON;
 import com.alibaba.nacos.common.utils.StringUtils;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.vci.ubcs.common.validator.ComprehensiveFileValidator;
 import com.vci.ubcs.resource.dto.FileObjectDTO;
 import com.vci.ubcs.resource.dto.FileReleaseDTO;
 import com.vci.ubcs.resource.dto.FileShareDTO;
@@ -10,14 +10,11 @@
 import com.vci.ubcs.resource.service.IFileService;
 import com.vci.ubcs.resource.utils.FileDownloadUtil;
 import com.vci.ubcs.resource.vo.FileObjectVO;
-import com.vci.ubcs.starter.exception.VciBaseException;
 import com.vci.ubcs.starter.web.util.ControllerUtil;
 import com.vci.ubcs.starter.web.util.LangBaseUtil;
 import com.vci.ubcs.starter.web.util.VciBaseUtil;
-import lombok.extern.java.Log;
 import lombok.extern.slf4j.Slf4j;
 import org.springblade.core.mp.support.Query;
-import org.springblade.core.oss.MinioTemplate;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.StringUtil;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -45,6 +42,12 @@
 	 */
 	@Autowired
 	private IFileService fileService;
+
+	/**
+	 * 鏂囦欢瀹夊叏妫�鏌�
+	 */
+	@Autowired
+	private ComprehensiveFileValidator fileValidator;
 
 	/**
 	 * 鏍规嵁鏂囦欢涓婚敭涓嬭浇鏂囦欢
@@ -82,7 +85,7 @@
 			if(StringUtil.isBlank(msg)){
 				msg = "鏈煡閿欒";
 			}
-			log.debug(msg);
+			log.error(msg);
 			return R.fail(msg);
 		}
 		return R.success("鍒犻櫎鎴愬姛");
@@ -97,6 +100,12 @@
 	@PostMapping("/uploadFile")
 	public R<FileObjectVO> uploadFile(MultipartFile file, FileObjectDTO fileObjectDTO){
 		if (file != null ) {
+			// 浣跨敤鏂囦欢瀹夊叏楠岃瘉鍣�
+			ComprehensiveFileValidator.UploadValidationResult result = fileValidator.validateFile(file);
+			if (!result.isValid()) {
+				return R.fail(result.getMessage());
+			}
+			//涓婁紶鏂囦欢
 			return fileService.uploadFile(file, fileObjectDTO);
 		} else {
 			return R.fail("鏃犱笂浼犵殑鏂囦欢");
diff --git a/Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/endpoint/OssEndpoint.java b/Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/endpoint/OssEndpoint.java
index 1bdefc5..909f7f1 100644
--- a/Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/endpoint/OssEndpoint.java
+++ b/Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/endpoint/OssEndpoint.java
@@ -17,6 +17,7 @@
 package com.vci.ubcs.resource.endpoint;
 
 import com.vci.ubcs.resource.entity.Attach;
+import com.vci.ubcs.common.validator.ComprehensiveFileValidator;
 import io.swagger.annotations.Api;
 import lombok.AllArgsConstructor;
 import lombok.SneakyThrows;
@@ -31,8 +32,6 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
-
-import javax.servlet.http.HttpServletResponse;
 
 /**
  * 瀵硅薄瀛樺偍绔偣
@@ -59,6 +58,11 @@
 	 */
 	private final IAttachService attachService;
 
+	/**
+	 * 鏂囦欢瀹夊叏妫�鏌�
+	 */
+	@Autowired
+	private ComprehensiveFileValidator fileValidator;
 
 	/**
 	 * 鍒涘缓瀛樺偍妗�
@@ -150,6 +154,11 @@
 	@SneakyThrows
 	@PostMapping("/put-file")
 	public R<BladeFile> putFile(@RequestParam MultipartFile file) {
+		// 浣跨敤鏂囦欢瀹夊叏楠岃瘉鍣�
+		ComprehensiveFileValidator.UploadValidationResult result = fileValidator.validateFile(file);
+		if (!result.isValid()) {
+			return R.fail(result.getMessage());
+		}
 		BladeFile bladeFile = ossBuilder.template().putFile(file.getOriginalFilename(), file.getInputStream());
 		return R.data(bladeFile);
 	}
@@ -164,41 +173,14 @@
 	@SneakyThrows
 	@PostMapping("/put-file-by-name")
 	public R<BladeFile> putFile(@RequestParam String fileName, @RequestParam MultipartFile file) {
+		// 浣跨敤鏂囦欢瀹夊叏楠岃瘉鍣�
+		ComprehensiveFileValidator.UploadValidationResult result = fileValidator.validateFile(file);
+		if (!result.isValid()) {
+			return R.fail(result.getMessage());
+		}
 		BladeFile bladeFile = ossBuilder.template().putFile(fileName, file.getInputStream());
 		return R.data(bladeFile);
 	}
-
-//	/**
-//	 * 涓婁紶鏂囦欢骞朵繚瀛樿嚦闄勪欢琛�
-//	 *
-//	 * @param file 鏂囦欢
-//	 * @return ObjectStat
-//	 */
-//	@SneakyThrows
-//	@PostMapping("/put-file-attach")
-//	public R<BladeFile> putFileAttach(@RequestParam MultipartFile file) {
-//		String fileName = file.getOriginalFilename();
-//		BladeFile bladeFile = ossBuilder.template().putFile(fileName, file.getInputStream());
-//		Long attachId = buildAttach(fileName, file.getSize(), bladeFile);
-//		bladeFile.setAttachId(attachId);
-//		return R.data(bladeFile);
-//	}
-
-//	/**
-//	 * 涓婁紶鏂囦欢骞朵繚瀛樿嚦闄勪欢琛�
-//	 *
-//	 * @param fileName 瀛樺偍妗跺璞″悕绉�
-//	 * @param file     鏂囦欢
-//	 * @return ObjectStat
-//	 */
-//	@SneakyThrows
-//	@PostMapping("/put-file-attach-by-name")
-//	public R<BladeFile> putFileAttach(@RequestParam String fileName, @RequestParam MultipartFile file) {
-//		BladeFile bladeFile = ossBuilder.template().putFile(fileName, file.getInputStream());
-//		Long attachId = buildAttach(fileName, file.getSize(), bladeFile);
-//		bladeFile.setAttachId(attachId);
-//		return R.data(bladeFile);
-//	}
 
 	/**
 	 * 鏋勫缓闄勪欢琛�
diff --git a/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/controller/CodeClassifyController.java b/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/controller/CodeClassifyController.java
index df82de1..06ddc94 100644
--- a/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/controller/CodeClassifyController.java
+++ b/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/controller/CodeClassifyController.java
@@ -25,6 +25,7 @@
 import com.vci.ubcs.code.vo.pagemodel.CodeClassifyVO;
 import com.vci.ubcs.code.vo.pagemodel.CodeImProtRusultVO;
 import com.vci.ubcs.code.wrapper.CodeClassifyWrapper;
+import com.vci.ubcs.common.validator.ComprehensiveFileValidator;
 import com.vci.ubcs.omd.vo.BtmTypeAttributeVO;
 import com.vci.ubcs.starter.revision.model.TreeQueryObject;
 import com.vci.ubcs.starter.util.LocalFileUtil;
@@ -47,6 +48,7 @@
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.StringUtil;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 import javax.servlet.http.HttpServletResponse;
@@ -77,6 +79,12 @@
 	private final ICodeClassifyService codeClassifyService;
 
 	CodeClassifyMapper codeClassifyMapper;
+
+	/**
+	 * 鏂囦欢瀹夊叏妫�鏌�
+	 */
+	@Autowired
+	private ComprehensiveFileValidator fileValidator;
 
 	/**
 	 * 涓婚搴撳畾涔夎〃 璇︽儏
@@ -277,6 +285,12 @@
 	 */
 	@PostMapping("/importClassify")
 	public R importClassify(MultipartFile file) {
+		// 浣跨敤鏂囦欢瀹夊叏楠岃瘉鍣�
+		ComprehensiveFileValidator.UploadValidationResult result = fileValidator.validateFile(file);
+		if (!result.isValid()) {
+			return R.fail(result.getMessage());
+		}
+
 		String excelFileName = LocalFileUtil.getDefaultTempFolder() + File.separator + LocalFileUtil.getFileNameForIE(file.getOriginalFilename());
 		File file1 = new File(excelFileName);
 		try {
diff --git a/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/controller/MdmEngineController.java b/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/controller/MdmEngineController.java
index 7e3cf21..623570c 100644
--- a/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/controller/MdmEngineController.java
+++ b/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/controller/MdmEngineController.java
@@ -10,6 +10,7 @@
 import com.vci.ubcs.code.service.MdmEngineService;
 import com.vci.ubcs.code.service.MdmIOService;
 import com.vci.ubcs.code.vo.pagemodel.*;
+import com.vci.ubcs.common.validator.ComprehensiveFileValidator;
 import com.vci.ubcs.flow.core.dto.FlowStatusDTO;
 import com.vci.ubcs.starter.annotation.VciBusinessLog;
 import com.vci.ubcs.starter.revision.model.BaseModel;
@@ -43,21 +44,31 @@
 	 * 鏃ュ織
 	 */
 	private Logger logger = LoggerFactory.getLogger(getClass());
+
 	/**
 	 * 涓绘暟鎹紩鎿庢湇鍔�
 	 */
 	@Autowired
 	private MdmEngineService engineService;
+
 	/**
 	 * 涓绘暟鎹鍏ュ鍑烘湇鍔�
 	 */
 	@Autowired
 	private MdmIOService mdmIOService;
+
 	/**
 	 * 鏃ュ織淇濆瓨宸ュ叿绫�
 	 */
 	@Autowired
 	private SaveLogUtil saveLogUtil;
+
+	/**
+	 * 鏂囦欢瀹夊叏妫�鏌�
+	 */
+	@Autowired
+	private ComprehensiveFileValidator fileValidator;
+
 
 	/**
 	 * 涓嬭浇鎵归噺鐢宠鐨勫鍏ユā鏉�
@@ -112,6 +123,12 @@
 	@VciBusinessLog(operateName = "瀵煎叆鎵归噺缂栬緫鏁版嵁")
 	@PostMapping("/batchImportEdit")
 	public R batchImportEdit(String codeClassifyOid, String classifyAttr,MultipartFile file,HttpServletResponse response) throws Throwable {
+		// 浣跨敤鏂囦欢瀹夊叏楠岃瘉鍣�
+		ComprehensiveFileValidator.UploadValidationResult validationResult = fileValidator.validateFile(file);
+		if (!validationResult.isValid()) {
+			return R.fail(validationResult.getMessage());
+		}
+
 		String excelFileName = LocalFileUtil.getDefaultTempFolder() + File.separator + file.getOriginalFilename();
 		File file1 = new File(excelFileName);
 		try {
@@ -218,6 +235,12 @@
 	@VciBusinessLog(operateName = "鎵归噺鐢宠缂栫爜鐨勪俊鎭�")
 	@PostMapping("/batchImportCode")
 	public R batchImportCode(String secDTOList, String codeClassifyOid, MultipartFile file, HttpServletResponse response) throws Throwable {
+		// 浣跨敤鏂囦欢瀹夊叏楠岃瘉鍣�
+		ComprehensiveFileValidator.UploadValidationResult validationResult = fileValidator.validateFile(file);
+		if (!validationResult.isValid()) {
+			return R.fail(validationResult.getMessage());
+		}
+
 		CodeOrderDTO orderDTO = new CodeOrderDTO();
 		orderDTO.setCodeClassifyOid(codeClassifyOid);
 		if(StringUtils.isNotBlank(secDTOList)){
@@ -269,6 +292,12 @@
 	@VciBusinessLog(operateName = "瀵煎叆缂栫爜鐨勫巻鍙叉暟鎹�")
 	@PostMapping("/batchImportHistoryData")
 	public R batchImportHistoryData(String codeClassifyOid, String classifyAttr,MultipartFile file,HttpServletResponse response) throws Throwable {
+		// 浣跨敤鏂囦欢瀹夊叏楠岃瘉鍣�
+		ComprehensiveFileValidator.UploadValidationResult validationResult = fileValidator.validateFile(file);
+		if (!validationResult.isValid()) {
+			return R.fail(validationResult.getMessage());
+		}
+
 		String excelFileName = LocalFileUtil.getDefaultTempFolder() + File.separator + file.getOriginalFilename();
 		File file1 = new File(excelFileName);
 		try {
@@ -312,6 +341,12 @@
 	@VciBusinessLog(operateName = "鎵归噺鐢宠缂栫爜鐨勪俊鎭�")
 	@PostMapping("/batchTopImportCode")
 	public R batchTopImportCode(String codeClassifyOid, String classifyAttr,MultipartFile file,HttpServletResponse response) throws Throwable {
+		// 浣跨敤鏂囦欢瀹夊叏楠岃瘉鍣�
+		ComprehensiveFileValidator.UploadValidationResult result = fileValidator.validateFile(file);
+		if (!result.isValid()) {
+			return R.fail(result.getMessage());
+		}
+
 		String excelFileName = LocalFileUtil.getDefaultTempFolder() + File.separator + file.getOriginalFilename();
 		File file1 = new File(excelFileName);
 		try {
@@ -867,6 +902,11 @@
 	 */
 	@PostMapping("/importGroupCode")
 	public R  importGroupCode(String codeClassifyOid,MultipartFile file,HttpServletResponse response){
+		// 浣跨敤鏂囦欢瀹夊叏楠岃瘉鍣�
+		ComprehensiveFileValidator.UploadValidationResult result = fileValidator.validateFile(file);
+		if (!result.isValid()) {
+			return R.fail(result.getMessage());
+		}
 
 		String excelFileName = LocalFileUtil.getDefaultTempFolder() + File.separator + file.getOriginalFilename();
 		File file1 = new File(excelFileName);
diff --git a/Source/UBCS/ubcs-service/ubcs-deploy/src/main/java/com/vci/ubcs/deploy/controller/DeployAppsController.java b/Source/UBCS/ubcs-service/ubcs-deploy/src/main/java/com/vci/ubcs/deploy/controller/DeployAppsController.java
index 5c13be2..05dd46f 100644
--- a/Source/UBCS/ubcs-service/ubcs-deploy/src/main/java/com/vci/ubcs/deploy/controller/DeployAppsController.java
+++ b/Source/UBCS/ubcs-service/ubcs-deploy/src/main/java/com/vci/ubcs/deploy/controller/DeployAppsController.java
@@ -1,6 +1,7 @@
 package com.vci.ubcs.deploy.controller;
 
 import com.alibaba.nacos.shaded.com.google.protobuf.ServiceException;
+import com.vci.ubcs.common.validator.ComprehensiveFileValidator;
 import com.vci.ubcs.deploy.entity.DeployApps;
 import com.vci.ubcs.deploy.service.IDeployAppsService;
 import com.vci.ubcs.deploy.vo.DeployAppsVO;
@@ -10,6 +11,7 @@
 import org.springblade.core.tenant.annotation.NonDS;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.Func;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 import springfox.documentation.annotations.ApiIgnore;
@@ -32,6 +34,12 @@
 public class DeployAppsController {
 
 	private final IDeployAppsService deployAppsService;
+
+	/**
+	 * 鏂囦欢瀹夊叏妫�鏌�
+	 */
+	@Autowired
+	private ComprehensiveFileValidator fileValidator;
 
 	/**
 	 * 鑾峰彇鏈嶅姟杩愯鍒楄〃
@@ -86,6 +94,11 @@
 	 */
 	@PostMapping("/importUpdateServiceJar")
 	public R importClassify(@RequestParam("files") MultipartFile[] files,@RequestParam String serverName) throws ServiceException {
+		// 浣跨敤鏂囦欢瀹夊叏楠岃瘉鍣�
+		ComprehensiveFileValidator.MultiUploadValidationResult quickResult = fileValidator.validateFiles(files, true);
+		if (!quickResult.isValid()) {
+			return R.fail(quickResult.getMessage());
+		}
 		if(Func.isBlank(serverName)){
 			return R.fail("Mandatory parameter service name not found!");
 		}
diff --git a/Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/controller/RegionController.java b/Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/controller/RegionController.java
index 80044f3..61186aa 100644
--- a/Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/controller/RegionController.java
+++ b/Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/controller/RegionController.java
@@ -20,6 +20,7 @@
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import com.vci.ubcs.common.validator.ComprehensiveFileValidator;
 import com.vci.ubcs.system.entity.Region;
 import com.vci.ubcs.system.excel.RegionExcel;
 import com.vci.ubcs.system.excel.RegionImporter;
@@ -35,6 +36,7 @@
 import org.springblade.core.tenant.annotation.NonDS;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.DateUtil;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 import springfox.documentation.annotations.ApiIgnore;
@@ -58,6 +60,12 @@
 public class RegionController extends BladeController {
 
 	private final IRegionService regionService;
+
+	/**
+	 * 鏂囦欢瀹夊叏妫�鏌�
+	 */
+	@Autowired
+	private ComprehensiveFileValidator fileValidator;
 
 	/**
 	 * 璇︽儏
@@ -170,6 +178,11 @@
 	@ApiOperationSupport(order = 10)
 	@ApiOperation(value = "瀵煎叆琛屾斂鍖哄垝", notes = "浼犲叆excel")
 	public R importRegion(MultipartFile file, Integer isCovered) {
+		// 浣跨敤鏂囦欢瀹夊叏楠岃瘉鍣�
+		ComprehensiveFileValidator.UploadValidationResult result = fileValidator.validateFile(file);
+		if (!result.isValid()) {
+			return R.fail(result.getMessage());
+		}
 		RegionImporter regionImporter = new RegionImporter(regionService, isCovered == 1);
 		ExcelUtil.save(file, regionImporter, RegionExcel.class);
 		return R.success("鎿嶄綔鎴愬姛");
diff --git a/Source/UBCS/ubcs-service/ubcs-user/src/main/java/com/vci/ubcs/system/user/controller/UserController.java b/Source/UBCS/ubcs-service/ubcs-user/src/main/java/com/vci/ubcs/system/user/controller/UserController.java
index 9bfdd3c..bf38725 100644
--- a/Source/UBCS/ubcs-service/ubcs-user/src/main/java/com/vci/ubcs/system/user/controller/UserController.java
+++ b/Source/UBCS/ubcs-service/ubcs-user/src/main/java/com/vci/ubcs/system/user/controller/UserController.java
@@ -21,6 +21,7 @@
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import com.vci.ubcs.common.validator.ComprehensiveFileValidator;
 import com.vci.ubcs.system.cache.NacosConfigCache;
 import com.vci.ubcs.system.user.entity.User;
 import com.vci.ubcs.system.user.excel.UserExcel;
@@ -32,8 +33,7 @@
 import io.swagger.annotations.ApiParam;
 import lombok.AllArgsConstructor;
 import com.vci.ubcs.common.cache.CacheNames;
-import org.apache.ibatis.annotations.Param;
-import org.hibernate.validator.internal.util.logging.Log;
+import lombok.extern.slf4j.Slf4j;
 import org.springblade.core.cache.utils.CacheUtil;
 import org.springblade.core.excel.util.ExcelUtil;
 import org.springblade.core.mp.support.Condition;
@@ -50,6 +50,7 @@
 import org.springblade.core.tool.utils.StringUtil;
 import com.vci.ubcs.system.user.service.IUserService;
 import com.vci.ubcs.system.user.vo.UserVO;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 import springfox.documentation.annotations.ApiIgnore;
@@ -71,12 +72,19 @@
 @RestController
 @RequestMapping
 @AllArgsConstructor
-@lombok.extern.java.Log
+@Slf4j
 public class UserController {
 
 	private final IUserService userService;
+
 	private final BladeRedis bladeRedis;
+
 	private final NacosConfigCache nacosConfigCache;
+
+	/**
+	 * 鏂囦欢瀹夊叏妫�鏌�
+	 */
+	private ComprehensiveFileValidator fileValidator;
 
 	/**
 	 * 鏌ヨ鍗曟潯
@@ -263,6 +271,11 @@
 	@ApiOperationSupport(order = 12)
 	@ApiOperation(value = "瀵煎叆鐢ㄦ埛", notes = "浼犲叆excel")
 	public R importUser(MultipartFile file, Integer isCovered) {
+		// 浣跨敤鏂囦欢瀹夊叏楠岃瘉鍣�
+		ComprehensiveFileValidator.UploadValidationResult result = fileValidator.validateFile(file);
+		if (!result.isValid()) {
+			return R.fail(result.getMessage());
+		}
 		UserImporter userImporter = new UserImporter(userService, isCovered == 1);
 		ExcelUtil.save(file, userImporter, UserExcel.class);
 		return R.success("鎿嶄綔鎴愬姛");

--
Gitblit v1.9.3