package com.artfess.file.attachmentService; import cn.hutool.core.util.StrUtil; import com.artfess.base.attachment.Attachment; import com.artfess.base.attachment.AttachmentService; import com.artfess.base.exception.BaseException; import com.artfess.base.util.AppUtil; import com.artfess.base.util.BeanUtils; import com.artfess.base.util.StringUtil; import com.artfess.file.config.AliyunOssSettings; import com.artfess.file.config.MinioSetting; import com.artfess.file.model.FileStorage; import com.artfess.file.params.FlowUploadPropertiesStorageDTO; import com.artfess.file.persistence.manager.FileStorageManager; import com.artfess.file.persistence.manager.FlowUploadPropertiesManager; import com.artfess.file.util.CustomMinioClient; import com.artfess.file.util.MinioUtil; import com.google.common.collect.HashMultimap; import io.minio.GetPresignedObjectUrlArgs; import io.minio.ListPartsResponse; import io.minio.errors.ErrorResponseException; import io.minio.errors.InsufficientDataException; import io.minio.errors.InternalException; import io.minio.errors.InvalidResponseException; import io.minio.errors.ServerException; import io.minio.errors.XmlParserException; import io.minio.http.Method; import io.minio.messages.Part; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.file.Paths; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; @Slf4j @Service public class MinioAttachmentServiceImpl implements AttachmentService { @Autowired private CustomMinioClient customMinioClient; @Autowired private MinioSetting minioSetting; public MinioAttachmentServiceImpl(){} @Override public String getStoreType() { return "minio"; } private MinioSetting initMinioSettings(Attachment attachment, String propertiesId) { MinioSetting ossSettings = AppUtil.getBean(MinioSetting.class); if (StringUtil.isNotEmpty(propertiesId)) { FileStorageManager fileStorageManager = AppUtil.getBean(FileStorageManager.class); FileStorage fileStorage = fileStorageManager.get(propertiesId); if (BeanUtils.isNotEmpty(fileStorage)) { ossSettings.setMinioName(fileStorage.getUserName()); ossSettings.setMinioPass(fileStorage.getPassword()); String minioUrl =fileStorage.getUrl(); if(!minioUrl.startsWith("http")){ minioUrl = "http://" + minioUrl; } if(!minioUrl.endsWith("/")){ minioUrl = minioUrl.concat("/"); } ossSettings.setMinioUrl(minioUrl); ossSettings.setBucketName(fileStorage.getLocation()); attachment.setEntryptName(fileStorage.getEncryptName() == 0 ? false : true); }else{ FlowUploadPropertiesManager uploadPropertiesManager = AppUtil.getBean(FlowUploadPropertiesManager.class); FlowUploadPropertiesStorageDTO uploadProperties = uploadPropertiesManager.getById(propertiesId); if (BeanUtils.isNotEmpty(uploadProperties)) { ossSettings.setMinioName(uploadProperties.getUserName()); ossSettings.setMinioPass(uploadProperties.getPassword()); String minioUrl =uploadProperties.getUrl(); if(!minioUrl.startsWith("http")){ minioUrl = "http://" + minioUrl; } if(!minioUrl.endsWith("/")){ minioUrl = minioUrl.concat("/"); } ossSettings.setMinioUrl(minioUrl); ossSettings.setBucketName(uploadProperties.getLocation()); attachment.setEntryptName(uploadProperties.getEncryptName() == 0 ? false : true); } } } MinioUtil.setMinioUrl(ossSettings.getMinioUrl()); MinioUtil.setMinioName(ossSettings.getMinioName()); MinioUtil.setMinioPass(ossSettings.getMinioPass()); MinioUtil.setBucketName(ossSettings.getBucketName()); return ossSettings; } @Override public void remove(Attachment attachment, String propertiesId) throws Exception { String filePath = getFilePath(attachment); initMinioSettings(attachment,propertiesId); MinioUtil.removeObject(filePath,true); } @Override public void upload(Attachment attachment, InputStream inputStream, String propertiesId) throws Exception { String filePath = getFilePath(attachment); initMinioSettings(attachment,propertiesId); MinioUtil.uploadByInputStream(inputStream,filePath); } @Override public void download(Attachment attachment, OutputStream outStream, String propertiesId) throws Exception { String filePath = getFilePath(attachment); initMinioSettings(attachment,propertiesId); MinioUtil.downFile("",filePath,outStream,true); } @Override public boolean chekckFile(Attachment attachment, String propertiesId) throws Exception { initMinioSettings(attachment,propertiesId); return MinioUtil.checkFile("",attachment.getFilePath(),true); } @Override public byte[] getFileBytes(Attachment sysFile) throws Exception { return new byte[0]; } @Override public String getUrl(Attachment attachment) { return MinioUtil.getPresignedObjectUrl2upload(attachment.getFilePath()); } @Override public String initMultiPartUpload(Attachment attachment) { HashMultimap headers = HashMultimap.create(); if (StrUtil.isBlank(attachment.getContentType())) { headers.put("Content-Type", "application/octet-stream"); } String uploadId = null; try { uploadId = customMinioClient.initMultiPartUpload(attachment.getBucket(), null, attachment.getFileName(), headers, null); } catch (IOException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InsufficientDataException e) { e.printStackTrace(); } catch (ServerException e) { e.printStackTrace(); } catch (InternalException e) { e.printStackTrace(); } catch (XmlParserException e) { e.printStackTrace(); } catch (InvalidResponseException e) { e.printStackTrace(); } catch (ErrorResponseException e) { e.printStackTrace(); } return uploadId; } @Override public String getChunkUrl(Attachment attachment, Integer partNumber, String uploadId) { try { Map reqParams = new HashMap<>(); reqParams.put("partNumber", String.valueOf(partNumber)); reqParams.put("uploadId", uploadId); if(StringUtil.isEmpty(attachment.getBucket())) { attachment.setBucket(minioSetting.getBucketName()); } String uploadUrl = customMinioClient.getPresignedObjectUrl( GetPresignedObjectUrlArgs.builder() .method(Method.PUT) .bucket(attachment.getBucket()) .object(attachment.getFileName()) .expiry(1, TimeUnit.DAYS) .extraQueryParams(reqParams) .build()); return uploadUrl; } catch (ErrorResponseException e) { e.printStackTrace(); } catch (InsufficientDataException e) { e.printStackTrace(); } catch (InternalException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (InvalidResponseException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (XmlParserException e) { e.printStackTrace(); } catch (ServerException e) { e.printStackTrace(); } return null; } @Override public boolean mergeMultipartUpload(Attachment attachment,String uploadId, int realyPartNumber) { Integer maxPart = 1000; Part[] parts = new Part[maxPart]; ListPartsResponse partResult = null; try { partResult = customMinioClient.listMultipart(null, null, attachment.getFileName(), maxPart, 0, uploadId, null, null); int partNumber = 1; for (Part part : partResult.result().partList()) { parts[partNumber - 1] = new Part(partNumber, part.etag()); partNumber++; } Integer completedPartCount = partResult.result().partList().size(); // 若上传的分片少于实际分片数量,不能合并 if (completedPartCount < realyPartNumber) { // 分片文件不够,不能合并 log.info(">>>>>>>>>>{}分片文件不够,不能合并", uploadId); throw new BaseException("分片文件不够,不能合并!"); } customMinioClient.mergeMultipartUpload(null, null, attachment.getFileName(), uploadId, parts, null, null); } catch (Exception e) { e.printStackTrace(); return false; } return true; } /** * @Description: 获取文件相对路径 * @param attachment 附件信息 * @Return: 文件相对路径 * @Author: llj * @Date: 2021/3/23 11:36 */ public String getFilePath(Attachment attachment){ String fileParentPath = ""; String filePath = attachment.getFilePath(); if (StringUtil.isNotEmpty(filePath)) { String[] split = filePath.split("/"); if(null != split && split.length > 1) { fileParentPath = Paths.get(filePath).getParent().toString(); fileParentPath = fileParentPath.replaceAll("\\\\", "/"); if (fileParentPath.startsWith("/")) { fileParentPath = fileParentPath.substring(1); } } } String file =fileParentPath+ "/"+attachment.getId()+"."+attachment.getExtensionName(); return file; } }