|
|
|
@ -1,25 +1,23 @@
|
|
|
|
|
package com.unilife.utils;
|
|
|
|
|
|
|
|
|
|
import com.aliyun.oss.OSS;
|
|
|
|
|
import com.aliyun.oss.model.DeleteObjectRequest;
|
|
|
|
|
import com.aliyun.oss.model.OSSObject;
|
|
|
|
|
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
|
|
|
|
|
import com.aliyun.oss.model.PutObjectRequest;
|
|
|
|
|
import com.unilife.config.OssConfig;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
import java.io.InputStream;
|
|
|
|
|
import java.net.URL;
|
|
|
|
|
import java.time.LocalDateTime;
|
|
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
|
|
import java.text.SimpleDateFormat;
|
|
|
|
|
import java.util.Date;
|
|
|
|
|
import java.util.UUID;
|
|
|
|
|
|
|
|
|
|
@Service
|
|
|
|
|
@Slf4j
|
|
|
|
|
@Component
|
|
|
|
|
public class OssService {
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
@ -30,94 +28,112 @@ public class OssService {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 上传文件到OSS
|
|
|
|
|
* @param file 文件
|
|
|
|
|
* @param dir 存储目录
|
|
|
|
|
* @return 返回文件访问URL
|
|
|
|
|
*/
|
|
|
|
|
public String uploadFile(MultipartFile file) throws IOException {
|
|
|
|
|
// 生成文件名
|
|
|
|
|
String originalFilename = file.getOriginalFilename();
|
|
|
|
|
String extension = "";
|
|
|
|
|
if (originalFilename != null && originalFilename.contains(".")) {
|
|
|
|
|
extension = originalFilename.substring(originalFilename.lastIndexOf("."));
|
|
|
|
|
}
|
|
|
|
|
public String uploadFile(MultipartFile file, String dir) {
|
|
|
|
|
String bucketName = ossConfig.getBucketName();
|
|
|
|
|
String urlPrefix = ossConfig.getUrlPrefix();
|
|
|
|
|
|
|
|
|
|
// 按日期组织文件夹
|
|
|
|
|
String dateFolder = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
|
|
|
|
|
String fileName = dateFolder + "/" + UUID.randomUUID().toString() + extension;
|
|
|
|
|
|
|
|
|
|
try (InputStream inputStream = file.getInputStream()) {
|
|
|
|
|
// 创建上传请求
|
|
|
|
|
PutObjectRequest putObjectRequest = new PutObjectRequest(
|
|
|
|
|
ossConfig.getBucketName(),
|
|
|
|
|
fileName,
|
|
|
|
|
inputStream
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 执行上传
|
|
|
|
|
ossClient.putObject(putObjectRequest);
|
|
|
|
|
|
|
|
|
|
// 返回文件URL
|
|
|
|
|
String fileUrl = ossConfig.getUrlPrefix() + fileName;
|
|
|
|
|
log.info("文件上传成功: {}", fileUrl);
|
|
|
|
|
return fileUrl;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("文件上传失败: {}", e.getMessage(), e);
|
|
|
|
|
throw new RuntimeException("文件上传失败: " + e.getMessage());
|
|
|
|
|
try {
|
|
|
|
|
// 获取文件原始名称
|
|
|
|
|
String originalFilename = file.getOriginalFilename();
|
|
|
|
|
// 获取文件后缀
|
|
|
|
|
String suffix = "";
|
|
|
|
|
if (originalFilename != null && originalFilename.contains(".")) {
|
|
|
|
|
suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 构建OSS存储路径:目录/日期/随机UUID.后缀
|
|
|
|
|
String dateDir = new SimpleDateFormat("yyyy/MM/dd").format(new Date());
|
|
|
|
|
String filename = UUID.randomUUID().toString().replaceAll("-", "") + suffix;
|
|
|
|
|
String objectName = dir + "/" + dateDir + "/" + filename;
|
|
|
|
|
|
|
|
|
|
// 获取文件输入流
|
|
|
|
|
InputStream inputStream = file.getInputStream();
|
|
|
|
|
|
|
|
|
|
// 上传文件到OSS
|
|
|
|
|
ossClient.putObject(bucketName, objectName, inputStream);
|
|
|
|
|
|
|
|
|
|
// 关闭输入流
|
|
|
|
|
inputStream.close();
|
|
|
|
|
|
|
|
|
|
// 返回文件访问URL
|
|
|
|
|
return urlPrefix + objectName;
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
log.error("上传文件到OSS失败: ", e);
|
|
|
|
|
throw new RuntimeException("上传文件失败");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 删除OSS文件
|
|
|
|
|
* 从OSS删除文件
|
|
|
|
|
* @param fileUrl 文件URL
|
|
|
|
|
*/
|
|
|
|
|
public void deleteFile(String fileUrl) {
|
|
|
|
|
try {
|
|
|
|
|
// 从URL中提取对象名称
|
|
|
|
|
String objectName = getObjectNameFromUrl(fileUrl);
|
|
|
|
|
if (objectName != null) {
|
|
|
|
|
DeleteObjectRequest deleteObjectRequest = new DeleteObjectRequest(
|
|
|
|
|
ossConfig.getBucketName(),
|
|
|
|
|
objectName
|
|
|
|
|
);
|
|
|
|
|
ossClient.deleteObject(deleteObjectRequest);
|
|
|
|
|
log.info("文件删除成功: {}", fileUrl);
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("文件删除失败: {}", e.getMessage(), e);
|
|
|
|
|
String bucketName = ossConfig.getBucketName();
|
|
|
|
|
String urlPrefix = ossConfig.getUrlPrefix();
|
|
|
|
|
|
|
|
|
|
if (fileUrl.startsWith(urlPrefix)) {
|
|
|
|
|
String objectName = fileUrl.substring(urlPrefix.length());
|
|
|
|
|
ossClient.deleteObject(bucketName, objectName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 生成预签名URL(临时访问链接)
|
|
|
|
|
* 获取OSS文件输入流
|
|
|
|
|
* @param fileUrl 文件URL
|
|
|
|
|
* @return 文件输入流
|
|
|
|
|
*/
|
|
|
|
|
public String generatePresignedUrl(String fileUrl) {
|
|
|
|
|
try {
|
|
|
|
|
String objectName = getObjectNameFromUrl(fileUrl);
|
|
|
|
|
if (objectName == null) {
|
|
|
|
|
return fileUrl;
|
|
|
|
|
}
|
|
|
|
|
public InputStream getFileStream(String fileUrl) {
|
|
|
|
|
String bucketName = ossConfig.getBucketName();
|
|
|
|
|
String urlPrefix = ossConfig.getUrlPrefix();
|
|
|
|
|
|
|
|
|
|
if (fileUrl.startsWith(urlPrefix)) {
|
|
|
|
|
String objectName = fileUrl.substring(urlPrefix.length());
|
|
|
|
|
OSSObject ossObject = ossClient.getObject(bucketName, objectName);
|
|
|
|
|
return ossObject.getObjectContent();
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置URL过期时间为1小时
|
|
|
|
|
Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000);
|
|
|
|
|
/**
|
|
|
|
|
* 获取文件的临时访问URL(适用于私有bucket)
|
|
|
|
|
* @param objectName 对象名称
|
|
|
|
|
* @param expiration 过期时间(毫秒)
|
|
|
|
|
* @return 带签名的临时URL
|
|
|
|
|
*/
|
|
|
|
|
public String generatePresignedUrl(String objectName, long expiration) {
|
|
|
|
|
String bucketName = ossConfig.getBucketName();
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 计算过期时间
|
|
|
|
|
Date expirationDate = new Date(System.currentTimeMillis() + expiration);
|
|
|
|
|
|
|
|
|
|
GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(
|
|
|
|
|
ossConfig.getBucketName(),
|
|
|
|
|
objectName
|
|
|
|
|
);
|
|
|
|
|
generatePresignedUrlRequest.setExpiration(expiration);
|
|
|
|
|
// 创建请求
|
|
|
|
|
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectName);
|
|
|
|
|
request.setExpiration(expirationDate);
|
|
|
|
|
|
|
|
|
|
URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest);
|
|
|
|
|
// 生成URL
|
|
|
|
|
URL url = ossClient.generatePresignedUrl(request);
|
|
|
|
|
return url.toString();
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("生成预签名URL失败: {}", e.getMessage(), e);
|
|
|
|
|
return fileUrl;
|
|
|
|
|
log.error("生成临时访问URL失败: ", e);
|
|
|
|
|
throw new RuntimeException("生成临时访问URL失败");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 从URL中提取对象名称
|
|
|
|
|
* 从完整URL中提取对象名称
|
|
|
|
|
* @param fileUrl 完整的文件URL
|
|
|
|
|
* @return 对象名称
|
|
|
|
|
*/
|
|
|
|
|
public String getObjectNameFromUrl(String fileUrl) {
|
|
|
|
|
if (fileUrl == null || !fileUrl.startsWith(ossConfig.getUrlPrefix())) {
|
|
|
|
|
return null;
|
|
|
|
|
String urlPrefix = ossConfig.getUrlPrefix();
|
|
|
|
|
if (fileUrl != null && fileUrl.startsWith(urlPrefix)) {
|
|
|
|
|
return fileUrl.substring(urlPrefix.length());
|
|
|
|
|
}
|
|
|
|
|
return fileUrl.substring(ossConfig.getUrlPrefix().length());
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|