package com.yami.trading.service.impl; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson2.JSONObject; import com.yami.trading.common.exception.BusinessException; import com.yami.trading.common.exception.YamiShopBindException; import com.yami.trading.common.util.PropertiesUtil; import com.yami.trading.service.AwsS3OSSFileService; import lombok.extern.slf4j.Slf4j; import net.coobird.thumbnailator.Thumbnails; import org.apache.commons.io.FilenameUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import software.amazon.awssdk.auth.credentials.AwsCredentials; import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider; import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; import software.amazon.awssdk.core.sync.RequestBody; import software.amazon.awssdk.core.waiters.WaiterResponse; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.s3.S3Client; import software.amazon.awssdk.services.s3.model.*; import software.amazon.awssdk.services.s3.waiters.S3Waiter; import java.io.*; import java.net.URL; import java.nio.file.Files; import java.time.LocalDate; import java.util.*; @Service @Slf4j public class AwsS3OSSFileServiceImpl implements AwsS3OSSFileService { @Value("${oss.aws.s3.bucketName}") private String bucketName; @Value("${http.prefix}") private String httpPrefix; // // @Value("${images.dir}") // private String tempFilePath; public static String policyText = "{ \n" + " \"Version\": \"2012-10-17\",\n" + " \"Statement\": [\n" + " {\n" + " \"Effect\": \"Allow\",\n" + " \"Action\": \"s3:*\",\n" + " \"Principal\": \"*\",\n" + " \"Resource\": [\n" + " \"arn:aws:s3:::%s/*\"\n" + " ]\n" + " }\n" + " ]\n" + "}"; /** * 获取操作客户端 * * @return */ private S3Client getS3Client() { AwsCredentials awsCredentials = new AwsCredentials() { @Override public String accessKeyId() { return "AKIARM6B3X65CX7HTKUL"; } @Override public String secretAccessKey() { return "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"; } }; Region region = Region.US_WEST_1; S3Client s3 = S3Client.builder() .region(region) .credentialsProvider(StaticCredentialsProvider.create(awsCredentials)) .build(); return s3; } /** * 创建存储桶 * * @param bucketName */ public void createBucket(String bucketName) { log.debug("AwsS3OSSFileService createBucket bucketName:{}", bucketName); try { S3Client s3Client = getS3Client(); S3Waiter s3Waiter = s3Client.waiter(); CreateBucketRequest bucketRequest = CreateBucketRequest.builder() .bucket(bucketName) .build(); s3Client.createBucket(bucketRequest); HeadBucketRequest bucketRequestWait = HeadBucketRequest.builder() .bucket(bucketName) .build(); WaiterResponse r = s3Waiter.waitUntilBucketExists(bucketRequestWait); log.info("AwsS3OSSFileService createBucket result :{}", JSONObject.toJSONString(r)); } catch (S3Exception e) { log.error("AwsS3OSSFileService createBucket Exception", e.getMessage(), e.awsErrorDetails().errorMessage(), e); } } /** * 设置存储桶策略 * * @param bucketName */ public void setPolicy(String bucketName) { log.info("AwsS3OSSFileService setPolicy bucketName:{},policyText:{}", bucketName, policyText); try { S3Client s3Client = getS3Client(); PutBucketPolicyRequest policyReq = PutBucketPolicyRequest.builder() .bucket(bucketName) .policy(String.format(policyText, bucketName)) .build(); PutBucketPolicyResponse r = s3Client.putBucketPolicy(policyReq); log.info("AwsS3OSSFileService setPolicy result :{}", r.toString()); log.info("AwsS3OSSFileService setPolicy result :{}", JSONObject.toJSONString(r)); } catch (S3Exception e) { log.error("AwsS3OSSFileService setPolicy Exception", e.getMessage(), e.awsErrorDetails().errorMessage(), e); } } /** * 获取文件访问链接 * * @param keyName */ @Override public String getUrl(String keyName) { if (StrUtil.isEmpty(keyName)) { return null; } return httpPrefix + keyName; } /** * 上传本地文件 * * @return */ @Override public String uploadFile(String moduleName, MultipartFile file) { // 兼容c端组件上传原理 String fileType = file.getOriginalFilename(); if (StrUtil.isEmpty(fileType) || fileType.contains("blob")) { fileType = "blob.png"; } // 生成唯一的文件名 String id = UUID.randomUUID().toString(); String path = LocalDate.now() + "/" + id + fileType; // 确保目标文件夹存在 File targetDir = new File(PropertiesUtil.getProperty("loca.images.dir") + "/" + LocalDate.now()); if (!targetDir.exists()) { targetDir.mkdirs(); } // 构建本地文件路径 File localFile = new File(targetDir, id + fileType); // 打印上传路径 log.info("LocalFileUploadService uploadFile localFilePath: {}", localFile.getAbsolutePath()); try { // 将文件保存到本地 file.transferTo(localFile); // 如果需要自定义元数据,可以在此处理 Map metadata = new HashMap<>(); metadata.put("x-amz-meta-myVal", "test"); // 如果需要元数据,可以放在文件名或其他地方 // 返回相对路径 return path; } catch (IOException e) { log.error("LocalFileUploadService uploadFile IOException", e.getMessage(), e); throw new YamiShopBindException("文件上传失败"); } } // /** // * 上传本地文件 // * // * @return // */ // public String putS3Object(String moduleName, MultipartFile file, Float quality) { // String fileType = FilenameUtils.getExtension(file.getOriginalFilename()); // String id = UUID.randomUUID().toString(); // String path = moduleName + "/" + LocalDate.now() + "/" + id + "." + fileType; // String thumbnailPath = moduleName + "/" + LocalDate.now() + "/" + id + "_thumbnail." + fileType; // // log.info("AwsS3OSSFileService putS3Object bucketName:{},objectKey:{},objectPath:{}", bucketName, path, file.getName()); // try { // ByteArrayOutputStream bs = cloneInputStream(file.getInputStream()); // // InputStream orgIS = new ByteArrayInputStream(bs.toByteArray()); // // Map metadata = new HashMap<>(); // metadata.put("x-amz-meta-myVal", "test"); // PutObjectRequest putOb = PutObjectRequest.builder() // .bucket(bucketName) // .key(path) // .metadata(metadata) // .build(); // S3Client s3Client = getS3Client(); // s3Client.putObject(putOb, RequestBody.fromInputStream(orgIS, file.getSize())); // // InputStream thumbnailIS = new ByteArrayInputStream(bs.toByteArray()); // // File tempFile = new File(tempFilePath + "/temp-img/"); // if (!tempFile.exists()) { // tempFile.mkdirs(); // } // Thumbnails.of(thumbnailIS).scale(1D).outputQuality(quality).toFile(tempFilePath + "/temp-img/" + id + "_thumbnail." + fileType); // // PutObjectRequest putThumbnailOb = PutObjectRequest.builder() // .bucket(bucketName) // .key(thumbnailPath) // .metadata(metadata) // .build(); // File thumbnailFile = new File(tempFilePath + "/temp-img/" + id + "_thumbnail." + fileType); // s3Client.putObject(putThumbnailOb, RequestBody.fromInputStream(Files.newInputStream(thumbnailFile.toPath()), thumbnailFile.length())); // return path; // } catch (S3Exception e) { // log.error("AwsS3OSSFileService putS3Object S3Exception", e.getMessage(), e.awsErrorDetails().errorMessage(), e); // throw new BusinessException("文件上传失败"); // } catch (IOException e) { // log.error("AwsS3OSSFileService putS3Object IOException", e.getMessage(), e); // throw new BusinessException("文件上传失败"); // } // } private static ByteArrayOutputStream cloneInputStream(InputStream input) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len; while ((len = input.read(buffer)) > -1) { baos.write(buffer, 0, len); } baos.flush(); return baos; } catch (IOException e) { log.error("cloneInputStream IOException", e.getMessage(), e); } return null; } /** * 判断文件是否为图片 * * @param fileName * @return */ public boolean isImageFile(String fileName) { List imgTypes = Arrays.asList("jpg", "jpeg", "png", "gif", "bmp"); if (StrUtil.isEmpty(fileName)) { return false; } String fileType = FilenameUtils.getExtension(fileName); return imgTypes.contains(fileType.toLowerCase()); } }