diff --git a/src/main/java/com/cultural/heritage/controller/file/FileController.java b/src/main/java/com/cultural/heritage/controller/file/FileController.java index 9a422ab..a891384 100644 --- a/src/main/java/com/cultural/heritage/controller/file/FileController.java +++ b/src/main/java/com/cultural/heritage/controller/file/FileController.java @@ -4,14 +4,12 @@ import cn.hutool.core.io.FileUtil; import com.cultural.heritage.common.BaseResponse; import com.cultural.heritage.common.ErrorCode; import com.cultural.heritage.common.ResultUtils; -import com.cultural.heritage.constant.FileConstant; import com.cultural.heritage.exception.BusinessException; import com.cultural.heritage.model.dto.file.UploadFileRequest; import com.cultural.heritage.model.entity.User; import com.cultural.heritage.model.enums.FileUploadBizEnum; import com.cultural.heritage.service.file.IHweiYunOBSService; import com.cultural.heritage.service.user.UserService; -import com.google.gson.Gson; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; @@ -22,10 +20,7 @@ import org.apache.commons.lang3.RandomStringUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; -import java.io.File; import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; @RestController @RequestMapping("/file") @@ -41,118 +36,167 @@ public class FileController { @Resource private IHweiYunOBSService iHweiYunOBSService; +// +// /** +// * 未登录的情况下的文件上传 +// * +// * @param multipartFile 文件上传参数 +// * @param uploadFileRequest 文件业务类型请求体 +// * @return 图片可访问地址 +// */ +// @PostMapping("/upload/server/not_login") +// @Operation(summary = "(未使用)未登录情况下的文件上传", description = "参数:(文档上是false,但biz是必传的),文件对象(multipartFile), 业务类型(biz),权限:所有人,方法名:uploadServerFileNotLogin") +// private BaseResponse uploadServerFileNotLogin(@RequestPart("file") MultipartFile multipartFile, UploadFileRequest uploadFileRequest) { +// // 获取业务名称 +// String biz = uploadFileRequest.getBiz(); +// FileUploadBizEnum fileUploadBizEnum = FileUploadBizEnum.getEnumByValue(biz); +// if (fileUploadBizEnum == null) { +// throw new BusinessException(ErrorCode.PARAMS_ERROR, "业务名称错误"); +// } +// // 校验文件 +// validFile(multipartFile, fileUploadBizEnum); +// // 文件目录:根据业务、用户来划分 +// String uuid = RandomStringUtils.randomAlphabetic(8); +// String filename = uuid + "-" + multipartFile.getOriginalFilename(); +// String filepath = String.format("/%s/%s/%s", fileUploadBizEnum.getValue(), 0, filename); +// +// // 判断目录是否存在 +// File file = new File(FileConstant.SERVER_UPLOAD_DIR, filepath); +// if (!file.exists()) { +// // 创建目录 +// boolean mkdirs = file.mkdirs(); +// if (!mkdirs) { +// throw new BusinessException(ErrorCode.SYSTEM_ERROR, "创建目录失败"); +// } +// } +// // 返回可访问地址 +// String url = iHweiYunOBSService.fileUpload(multipartFile, "feiyi" + filepath); +// return ResultUtils.success(url); +// } +// +// +// @PostMapping("/upload/server") +// @Operation(summary = "已登录情况下的文件上传", description = "参数:(文档上是false,但biz是必传的),文件对象(multipartFile), 业务类型(biz),权限:所有人,方法名:uploadServerFile") +// public BaseResponse uploadServerFile(@RequestPart("file") MultipartFile multipartFile, UploadFileRequest uploadFileRequest, HttpServletRequest request) { +// // 获取业务名称 +// String biz = uploadFileRequest.getBiz(); +// FileUploadBizEnum fileUploadBizEnum = FileUploadBizEnum.getEnumByValue(biz); +// if (fileUploadBizEnum == null) { +// throw new BusinessException(ErrorCode.PARAMS_ERROR, "业务名称错误"); +// } +// // 校验文件 +// validFile(multipartFile, fileUploadBizEnum); +// // 校验用户是否登录 +// User loginUser = userService.getLoginUser(request); +// if (loginUser == null) { +// throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR, "未登录"); +// } +// // 文件目录:根据业务、用户来划分 +// String uuid = RandomStringUtils.randomAlphabetic(8); +// String filename = uuid + "-" + multipartFile.getOriginalFilename(); +// String filepath = String.format("/%s/%s/%s", fileUploadBizEnum.getValue(), loginUser.getId(), filename); +// +// // 判断目录是否存在 +// File file = new File(FileConstant.SERVER_UPLOAD_DIR, filepath); +// if (!file.exists()) { +// // 创建目录 +// boolean mkdirs = file.mkdirs(); +// if (!mkdirs) { +// throw new BusinessException(ErrorCode.SYSTEM_ERROR, "创建目录失败"); +// } +// } +// // 返回可访问地址 +// String url = iHweiYunOBSService.fileUpload(multipartFile, "feiyi" + filepath); +// return ResultUtils.success(url); +// } +// +// +// @PostMapping("/upload/single") +// @Operation(summary = "单独文件上传", description = "参数:file,文件对象(multipartFile),权限:所有人,方法名:uploadServerFile") +// public Object uploadSingleServerFile(@RequestPart("file") MultipartFile multipartFile, HttpServletRequest request) { +//// +// // 校验文件 +// validFile(multipartFile, null); +// // 文件目录:根据业务、用户来划分 +// String uuid = RandomStringUtils.randomAlphabetic(8); +// String filename = uuid + "-" + multipartFile.getOriginalFilename(); +// String filepath = String.format("/%s/%s/%s", "single", "yt", filename); +// +// // 判断目录是否存在 +// File file = new File(FileConstant.SERVER_UPLOAD_DIR, filepath); +// if (!file.exists()) { +// // 创建目录 +// boolean mkdirs = file.mkdirs(); +// if (!mkdirs) { +// throw new BusinessException(ErrorCode.SYSTEM_ERROR, "创建目录失败"); +// } +// } +// // 返回可访问地址 +// String url = iHweiYunOBSService.fileUpload(multipartFile, "feiyi" + filepath); +// +// Map data = new HashMap<>(); +// data.put("url", url); +// +// // 创建最终地响应对象 +// Map response = new HashMap<>(); +// response.put("errno", 0); +// response.put("data", data); +// Gson gson = new Gson(); +// return gson.fromJson(gson.toJson(response), Object.class); +// } + /** - * 未登录的情况下的文件上传 - * - * @param multipartFile 文件上传参数 - * @param uploadFileRequest 文件业务类型请求体 - * @return 图片可访问地址 + * Web端文件上传 + * @param multipartFile 文件对象 + * @param uploadFileRequest 业务类型 + * @return PutObjectResult */ - @PostMapping("/upload/server/not_login") - @Operation(summary = "(未使用)未登录情况下的文件上传", description = "参数:(文档上是false,但biz是必传的),文件对象(multipartFile), 业务类型(biz),权限:所有人,方法名:uploadServerFileNotLogin") - private BaseResponse uploadServerFileNotLogin(@RequestPart("file") MultipartFile multipartFile, UploadFileRequest uploadFileRequest) { - // 获取业务名称 - String biz = uploadFileRequest.getBiz(); - FileUploadBizEnum fileUploadBizEnum = FileUploadBizEnum.getEnumByValue(biz); - if (fileUploadBizEnum == null) { - throw new BusinessException(ErrorCode.PARAMS_ERROR, "业务名称错误"); - } - // 校验文件 - validFile(multipartFile, fileUploadBizEnum); - // 文件目录:根据业务、用户来划分 - String uuid = RandomStringUtils.randomAlphabetic(8); - String filename = uuid + "-" + multipartFile.getOriginalFilename(); - String filepath = String.format("/%s/%s/%s", fileUploadBizEnum.getValue(), 0, filename); - - // 判断目录是否存在 - File file = new File(FileConstant.SERVER_UPLOAD_DIR, filepath); - if (!file.exists()) { - // 创建目录 - boolean mkdirs = file.mkdirs(); - if (!mkdirs) { - throw new BusinessException(ErrorCode.SYSTEM_ERROR, "创建目录失败"); - } - } - // 返回可访问地址 - String url = iHweiYunOBSService.fileUpload(multipartFile, "feiyi" + filepath); - return ResultUtils.success(url); - } - - - @PostMapping("/upload/server") - @Operation(summary = "已登录情况下的文件上传", description = "参数:(文档上是false,但biz是必传的),文件对象(multipartFile), 业务类型(biz),权限:所有人,方法名:uploadServerFile") - public BaseResponse uploadServerFile(@RequestPart("file") MultipartFile multipartFile, UploadFileRequest uploadFileRequest, HttpServletRequest request) { - // 获取业务名称 - String biz = uploadFileRequest.getBiz(); - FileUploadBizEnum fileUploadBizEnum = FileUploadBizEnum.getEnumByValue(biz); - if (fileUploadBizEnum == null) { - throw new BusinessException(ErrorCode.PARAMS_ERROR, "业务名称错误"); - } - // 校验文件 - validFile(multipartFile, fileUploadBizEnum); + @PostMapping("/uploadFile") + @Operation(summary = "Web端文件上传", description = "参数:文件对象(multipartFile), 业务类型(biz),权限:所有人,方法名:uploadFile") + public BaseResponse uploadFile(@RequestPart("file") MultipartFile multipartFile, UploadFileRequest uploadFileRequest, HttpServletRequest request) { // 校验用户是否登录 User loginUser = userService.getLoginUser(request); if (loginUser == null) { throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR, "未登录"); } - // 文件目录:根据业务、用户来划分 - String uuid = RandomStringUtils.randomAlphabetic(8); - String filename = uuid + "-" + multipartFile.getOriginalFilename(); - String filepath = String.format("/%s/%s/%s", fileUploadBizEnum.getValue(), loginUser.getId(), filename); + String filePath = getFilePath(multipartFile, uploadFileRequest); - // 判断目录是否存在 - File file = new File(FileConstant.SERVER_UPLOAD_DIR, filepath); - if (!file.exists()) { - // 创建目录 - boolean mkdirs = file.mkdirs(); - if (!mkdirs) { - throw new BusinessException(ErrorCode.SYSTEM_ERROR, "创建目录失败"); - } - } - // 返回可访问地址 - String url = iHweiYunOBSService.fileUpload(multipartFile, "feiyi" + filepath); - return ResultUtils.success(url); + iHweiYunOBSService.fileUpload(multipartFile, filePath); + + return ResultUtils.success(filePath, "上传成功,返回给前端filePath,前端需存储"); } - @PostMapping("/upload/single") - @Operation(summary = "单独文件上传", description = "参数:file,文件对象(multipartFile),权限:所有人,方法名:uploadServerFile") - public Object uploadSingleServerFile(@RequestPart("file") MultipartFile multipartFile, HttpServletRequest request) { -// - // 校验文件 - validFile(multipartFile, null); - // 文件目录:根据业务、用户来划分 - String uuid = RandomStringUtils.randomAlphabetic(8); - String filename = uuid + "-" + multipartFile.getOriginalFilename(); - String filepath = String.format("/%s/%s/%s", "single", "yt", filename); - // 判断目录是否存在 - File file = new File(FileConstant.SERVER_UPLOAD_DIR, filepath); - if (!file.exists()) { - // 创建目录 - boolean mkdirs = file.mkdirs(); - if (!mkdirs) { - throw new BusinessException(ErrorCode.SYSTEM_ERROR, "创建目录失败"); - } - } - // 返回可访问地址 - String url = iHweiYunOBSService.fileUpload(multipartFile, "feiyi" + filepath); - - Map data = new HashMap<>(); - data.put("url", url); - - // 创建最终的响应对象 - Map response = new HashMap<>(); - response.put("errno", 0); - response.put("data", data); - Gson gson = new Gson(); - return gson.fromJson(gson.toJson(response), Object.class); + /** + * 文件下载接口 + * @param objectKey 具体的文件名(含存储路径) + */ + @GetMapping("downloadFile") + public void downloadFile(@RequestParam String objectKey, HttpServletResponse response) { + iHweiYunOBSService.downloadFile(objectKey, response); } + + + + + + + + + + + + + + + + + /** * 校验文件 - * * @param multipartFile 文件 * @param fileUploadBizEnum 业务类型 */ @@ -161,18 +205,33 @@ public class FileController { long fileSize = multipartFile.getSize(); // 文件后缀 String fileSuffix = FileUtil.getSuffix(multipartFile.getOriginalFilename()); - final long LIMIT = 30 * 1024 * 1024L; + final long LIMIT = 20 * 1024 * 1024L; if (fileSize > LIMIT) { - throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件大小不能超过30MB"); + throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件大小不能超过20MB"); } if (!Arrays.asList("jpeg", "jpg", "svg", "png", "webp", "JPG").contains(fileSuffix)) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件类型错误"); } } - @GetMapping("downloadFile") - public void downloadFile(@RequestParam String objectKey, HttpServletResponse response) { - iHweiYunOBSService.downloadFile(objectKey, response); - } + /** + * @param uploadFileRequest 业务名称 + * @param multipartFile 文件 + * @return 文件后缀路径 + */ + private String getFilePath(MultipartFile multipartFile, UploadFileRequest uploadFileRequest) { + // 获取业务名称 + String biz = uploadFileRequest.getBiz(); + FileUploadBizEnum fileUploadBizEnum = FileUploadBizEnum.getEnumByValue(biz); + if (fileUploadBizEnum == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "业务名称错误"); + } + // 校验文件 + validFile(multipartFile, fileUploadBizEnum); + // 文件目录:根据业务、用户来划分 + String uuid = RandomStringUtils.randomAlphabetic(8); + String filename = uuid + "-" + multipartFile.getOriginalFilename(); + return String.format("/%s/%s", fileUploadBizEnum.getValue(), filename); + } } diff --git a/src/main/java/com/cultural/heritage/service/file/IHweiYunOBSService.java b/src/main/java/com/cultural/heritage/service/file/IHweiYunOBSService.java index 039d63f..fbeb399 100644 --- a/src/main/java/com/cultural/heritage/service/file/IHweiYunOBSService.java +++ b/src/main/java/com/cultural/heritage/service/file/IHweiYunOBSService.java @@ -1,5 +1,6 @@ package com.cultural.heritage.service.file; +import com.obs.services.model.PutObjectResult; import jakarta.servlet.http.HttpServletResponse; import org.springframework.web.multipart.MultipartFile; @@ -8,38 +9,22 @@ import org.springframework.web.multipart.MultipartFile; */ public interface IHweiYunOBSService { - /** - * @Description 删除文件 - * @param: objectKey 文件名 - * @return: boolean 执行结果 - */ -// boolean delete(String objectKey); -// boolean deleteFileByPath(String objectKey); - - /** - * @Description 批量删除文件 - * @param: objectKeys 文件名集合 - * @return: boolean 执行结果 - */ -// boolean delete(List objectKeys); /** * @Description 上传文件 * @param: uploadFile 上传文件 - * @param: objectKey 文件名称 - * @return: java.lang.String url访问路径 + * @param: objectKey 具体的文件名(含存储路径) + * @return PutObjectResult */ - String fileUpload(MultipartFile uploadFile, String objectKey); + PutObjectResult fileUpload(MultipartFile uploadFile, String objectKey); - // String uploadFileByte(byte data[], String objectKey); -// String uploadFile(File file); -// -// /** -// * @Description 文件下载 -// * @param: objectKey -// * @return: java.io.InputStream -// */ -// InputStream fileDownload(String objectKey); + + + /** + * + * @param objectKey 具体的文件名(含存储路径) + * @param response + */ void downloadFile(String objectKey, HttpServletResponse response); } diff --git a/src/main/java/com/cultural/heritage/service/file/impl/HweiYunOBSServiceImpl.java b/src/main/java/com/cultural/heritage/service/file/impl/HweiYunOBSServiceImpl.java index 79d806f..acc13c3 100644 --- a/src/main/java/com/cultural/heritage/service/file/impl/HweiYunOBSServiceImpl.java +++ b/src/main/java/com/cultural/heritage/service/file/impl/HweiYunOBSServiceImpl.java @@ -5,10 +5,10 @@ import com.cultural.heritage.service.file.IHweiYunOBSService; import com.obs.services.ObsClient; import com.obs.services.exception.ObsException; import com.obs.services.model.*; +import jakarta.annotation.Resource; import jakarta.servlet.ServletOutputStream; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @@ -27,96 +27,42 @@ import java.nio.charset.StandardCharsets; public class HweiYunOBSServiceImpl implements IHweiYunOBSService { - @Autowired + @Resource private HweiOBSConfig hweiOBSConfig; -// @Override -// public boolean delete(String objectKey) { -// ObsClient obsClient = null; -// try { -// // 创建ObsClient实例 -// obsClient = hweiOBSConfig.getInstance(); -// // obs删除 -// obsClient.deleteObject(hweiOBSConfig.getBucketName(), objectKey); -// } catch (ObsException e) { -// } finally { -// hweiOBSConfig.destroy(obsClient); -// } -// return true; -// } -// @Override -// public boolean deleteFileByPath(String path) { -// //path:https://wwwbak.obs.ap-southeast-1.myhuaweicloud.com/uploadFiles/xiehui/yongjiu/fujian/wode.jpg -// ObsClient obsClient = null; -// try { -// // 创建ObsClient实例 -// obsClient = hweiOBSConfig.getInstance(); -// -// String file_http_url = PropertiesUtil.readValue("file_http_url"); -// -// File file = new File(path); -// String key = file.getName();//wode.jpg -// -// //realPath : uploadFiles/xiehui/yongjiu/fujian -// String realPath = path.replace(file_http_url, ""); -// realPath = realPath.substring(0, realPath.lastIndexOf('/')); -// -// // obs删除 -// obsClient.deleteObject(hweiOBSConfig.getBucketName(), realPath + "/" + key); -// } catch (ObsException e) { -// } finally { -// hweiOBSConfig.destroy(obsClient); -// } -// return false; -// } -// @Override -// public boolean delete(List objectKeys) { -// ObsClient obsClient = null; -// try { -// obsClient = hweiOBSConfig.getInstance(); -// DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(hweiOBSConfig.getBucketName()); -// objectKeys.forEach(x -> deleteObjectsRequest.addKeyAndVersion(x)); -// // 批量删除请求 -// obsClient.deleteObjects(deleteObjectsRequest); -// return true; -// } catch (ObsException e) { -// } finally { -// hweiOBSConfig.destroy(obsClient); -// } -// return false; -// } + /** + * OBS-文件上传 + * @param uploadFile 文件对象 + * @param objectKey 具体的文件名(含存储路径) + * @return PutObjectResult + */ @Override - public String fileUpload(MultipartFile uploadFile, String objectKey) { + public PutObjectResult fileUpload(MultipartFile uploadFile, String objectKey) { ObsClient obsClient = null; + PutObjectResult putObjectResult = null; try { String bucketName = hweiOBSConfig.getBucketName(); obsClient = hweiOBSConfig.getInstance(); - // 判断桶是否存在 - boolean exists = obsClient.headBucket(bucketName); - if (!exists) { - // 若不存在,则创建桶 - HeaderResponse response = obsClient.createBucket(bucketName); - } InputStream inputStream = uploadFile.getInputStream(); long available = inputStream.available(); - PutObjectRequest request = new PutObjectRequest(bucketName, objectKey, inputStream); + PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectKey, inputStream); ObjectMetadata objectMetadata = new ObjectMetadata(); objectMetadata.setContentLength(available); - request.setMetadata(objectMetadata); + putObjectRequest.setMetadata(objectMetadata); // 设置对象访问权限为公共读 - request.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ); - PutObjectResult result = obsClient.putObject(request); + putObjectRequest.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ); + putObjectResult = obsClient.putObject(putObjectRequest); // 读取该已上传对象的URL - return result.getObjectUrl(); } catch (ObsException | IOException e) { + log.info("上传文件失败"); } finally { hweiOBSConfig.destroy(obsClient); } - return null; + return putObjectResult; } /* @@ -156,75 +102,5 @@ public class HweiYunOBSServiceImpl implements IHweiYunOBSService { } } -// @Override -// public String uploadFileByte(byte[] data, String fileName) { -// try { -// ObsClient obsClient = null; -// String bucketName = hweiOBSConfig.getBucketName(); -// obsClient = hweiOBSConfig.getInstance(); -// // 判断桶是否存在 -// boolean exists = obsClient.headBucket(bucketName); -// if (!exists) { -// // 若不存在,则创建桶 -// HeaderResponse response = obsClient.createBucket(bucketName); -// } -// -// String file_http_url = PropertiesUtil.readValue("file_http_url"); -// -// //转为File -// InputStream inputStream = new ByteArrayInputStream(data); -// String prefix = fileName.substring(fileName.lastIndexOf(".") + 1);//后缀 -// String uuid = UUID.randomUUID().toString().replace("-", "");//customer_YYYYMMDDHHMM -// fileName = uuid + "." + prefix; //文件全路径 -// obsClient.putObject(bucketName, fileName.substring(0, fileName.lastIndexOf("/")) + "/" + fileName, inputStream); -// return file_http_url + fileName; -// } catch (ObsException e) { -// } -// return null; -// } - -// @Override -// public String uploadFile(File file) { -// ObsClient obsClient = null; -// try { -// String bucketName = hweiOBSConfig.getBucketName(); -// obsClient = hweiOBSConfig.getInstance(); -// // 判断桶是否存在 -// boolean exists = obsClient.headBucket(bucketName); -// if (!exists) { -// // 若不存在,则创建桶 -// HeaderResponse response = obsClient.createBucket(bucketName); -// } -// -// String file_http_url = PropertiesUtil.readValue("file_http_url"); -// -// //转为File -// String filename = file.getName(); -// String prefix = filename.substring(filename.lastIndexOf(".") + 1);//后缀 -// String uuid = UUID.randomUUID().toString().replace("-", "");//customer_YYYYMMDDHHMM -// String fileName = uuid + "." + prefix; //文件全路径 -// obsClient.putObject(bucketName, fileName.substring(0, fileName.lastIndexOf("/")) + "/" + fileName, file); -// return file_http_url + fileName; -// } catch (Exception e) { -// } finally { -// hweiOBSConfig.destroy(obsClient); -// } -// return null; -// } - -// @Override -// public InputStream fileDownload(String objectKey) { -// ObsClient obsClient = null; -// try { -// String bucketName = hweiOBSConfig.getBucketName(); -// obsClient = hweiOBSConfig.getInstance(); -// ObsObject obsObject = obsClient.getObject(bucketName, objectKey); -// return obsObject.getObjectContent(); -// } catch (ObsException e) { -// } finally { -// hweiOBSConfig.destroy(obsClient); -// } -// return null; -// } }