|
@@ -0,0 +1,75 @@
|
|
|
|
+package com.citu.module.menduner.system.controller.app.common.file;
|
|
|
|
+
|
|
|
|
+import cn.hutool.core.io.IoUtil;
|
|
|
|
+import com.citu.framework.common.pojo.CommonResult;
|
|
|
|
+import com.citu.framework.security.core.annotations.PreAuthenticated;
|
|
|
|
+import com.citu.module.infra.api.file.FileApi;
|
|
|
|
+import com.citu.module.menduner.system.controller.app.common.file.vo.AppFileUploadReqVO;
|
|
|
|
+import io.swagger.v3.oas.annotations.Operation;
|
|
|
|
+import io.swagger.v3.oas.annotations.tags.Tag;
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
+import org.apache.tika.Tika;
|
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
|
+import org.springframework.validation.annotation.Validated;
|
|
|
|
+import org.springframework.web.bind.annotation.PostMapping;
|
|
|
|
+import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
|
+import org.springframework.web.bind.annotation.RestController;
|
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
|
+
|
|
|
|
+import javax.annotation.Resource;
|
|
|
|
+
|
|
|
|
+import static com.citu.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
|
|
+import static com.citu.framework.common.pojo.CommonResult.success;
|
|
|
|
+import static com.citu.module.menduner.system.enums.ErrorCodeConstants.MDE_FILE_FORMAT_ERROR;
|
|
|
|
+
|
|
|
|
+@Tag(name = "公共 - 文件存储")
|
|
|
|
+@RestController
|
|
|
|
+@RequestMapping("/menduner/system/file")
|
|
|
|
+@Validated
|
|
|
|
+@Slf4j
|
|
|
|
+public class AppFileController {
|
|
|
|
+
|
|
|
|
+ @Resource
|
|
|
|
+ private FileApi fileApi;
|
|
|
|
+
|
|
|
|
+ @PreAuthenticated
|
|
|
|
+ @PostMapping("/upload")
|
|
|
|
+ @Operation(summary = "上传文件")
|
|
|
|
+ public CommonResult<String> uploadFile(AppFileUploadReqVO reqVO) throws Exception {
|
|
|
|
+ MultipartFile file = reqVO.getFile();
|
|
|
|
+ String path = reqVO.getPath();
|
|
|
|
+ if (!isSupportedDocument(file)) {
|
|
|
|
+ throw exception(MDE_FILE_FORMAT_ERROR);
|
|
|
|
+ }
|
|
|
|
+ return success(fileApi.createFile(file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream())));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private boolean isSupportedDocument(MultipartFile file) throws Exception {
|
|
|
|
+ // 检查文件扩展名
|
|
|
|
+ String originalFilename = file.getOriginalFilename();
|
|
|
|
+ if (originalFilename == null || originalFilename.isEmpty()) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ String extension = originalFilename.toLowerCase();
|
|
|
|
+ if (!extension.endsWith(".doc") && !extension.endsWith(".docx") && !extension.endsWith(".pdf")) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 使用Apache Tika检测文件的实际MIME类型
|
|
|
|
+ String detectedMimeType = new Tika().detect(file.getInputStream(), originalFilename);
|
|
|
|
+ if (!StringUtils.hasText(detectedMimeType)) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ switch (detectedMimeType.toLowerCase()) {
|
|
|
|
+ case "application/msword":
|
|
|
|
+ case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
|
|
|
|
+ case "application/pdf":
|
|
|
|
+ return true;
|
|
|
|
+ default:
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+}
|