init
This commit is contained in:
@@ -3,6 +3,7 @@ package com.timeline.file.controller;
|
||||
import com.timeline.file.service.FileService;
|
||||
import com.timeline.file.vo.ImageInfoVo;
|
||||
import com.timeline.common.response.ResponseEntity;
|
||||
import com.timeline.common.utils.UserContextUtils;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.compress.utils.IOUtils;
|
||||
@@ -32,6 +33,19 @@ public class FileController {
|
||||
fileService.createBucketIfNotExist();
|
||||
return "create default bucket success";
|
||||
}
|
||||
|
||||
@PostMapping("/bucket/{userId}")
|
||||
public ResponseEntity<String> createBucketForUser(@PathVariable String userId) throws Throwable {
|
||||
fileService.createUserBucket(userId);
|
||||
return ResponseEntity.success("bucket created for user " + userId);
|
||||
}
|
||||
|
||||
@PostMapping("/bucket/self")
|
||||
public ResponseEntity<String> createBucketForCurrentUser() throws Throwable {
|
||||
String userId = UserContextUtils.getCurrentUserId();
|
||||
fileService.createUserBucket(userId);
|
||||
return ResponseEntity.success("bucket created for current user");
|
||||
}
|
||||
@GetMapping("/get-upload-url/{fileName}")
|
||||
public ResponseEntity<String> getUploadUrl(@PathVariable String fileName) throws Throwable {
|
||||
String uploadUrl = fileService.generateUploadUrl(fileName);
|
||||
@@ -77,7 +91,8 @@ public class FileController {
|
||||
fileService.saveFileMetadata(imageInfoVo);
|
||||
|
||||
// 2. 关联图片和 StoryItem
|
||||
fileService.associateImageWithStoryItem(imageInfoVo.getInstanceId(), storyItemId, "9999");
|
||||
String userId = UserContextUtils.getCurrentUserId();
|
||||
fileService.associateImageWithStoryItem(imageInfoVo.getInstanceId(), storyItemId, userId);
|
||||
|
||||
return ResponseEntity.success("上传并绑定成功");
|
||||
}
|
||||
@@ -105,9 +120,9 @@ public class FileController {
|
||||
return ResponseEntity.success("图片已从故事项中移除");
|
||||
}
|
||||
@GetMapping("/image/list")
|
||||
public ResponseEntity<Map> getImagesListByOwnerId(@SpringQueryMap ImageInfoVo imageInfoVo) throws Throwable {
|
||||
imageInfoVo.setOwnerId("9999");
|
||||
Map images = fileService.getImagesListByOwnerId(imageInfoVo);
|
||||
public ResponseEntity<Map<String, Object>> getImagesListByOwnerId(@SpringQueryMap ImageInfoVo imageInfoVo) throws Throwable {
|
||||
imageInfoVo.setOwnerId(UserContextUtils.getCurrentUserId());
|
||||
Map<String, Object> images = fileService.getImagesListByOwnerId(imageInfoVo);
|
||||
return ResponseEntity.success(images);
|
||||
}
|
||||
@DeleteMapping("/image/{imageInstanceId}")
|
||||
|
||||
@@ -13,6 +13,7 @@ import java.util.Map;
|
||||
@Service
|
||||
public interface FileService {
|
||||
void createBucketIfNotExist() throws Throwable;
|
||||
void createUserBucket(String userId) throws Throwable;
|
||||
String generateUploadUrl(String fileName) throws Throwable;
|
||||
String generateDownloadUrl(String fileName) throws Throwable;
|
||||
void saveFileMetadata(ImageInfoVo imageInfoVo);
|
||||
@@ -27,5 +28,5 @@ public interface FileService {
|
||||
|
||||
InputStream fetchImageLowRes(String instanceId) throws Throwable;
|
||||
|
||||
Map getImagesListByOwnerId(ImageInfoVo imageInfoVo);
|
||||
Map<String, Object> getImagesListByOwnerId(ImageInfoVo imageInfoVo);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.timeline.common.exception.CustomException;
|
||||
import com.timeline.common.response.ResponseEnum;
|
||||
import com.timeline.common.utils.CommonUtils;
|
||||
import com.timeline.common.utils.PageUtils;
|
||||
import com.timeline.common.utils.UserContextUtils;
|
||||
import com.timeline.file.config.MinioConfig;
|
||||
import com.timeline.file.dao.CommonRelationMapper;
|
||||
import com.timeline.file.dao.FileHashMapper;
|
||||
@@ -41,12 +42,23 @@ public class FileServiceImpl implements FileService {
|
||||
private CommonRelationMapper commonRelationMapper;
|
||||
@Autowired
|
||||
private FileHashMapper fileHashMapper;
|
||||
@Autowired
|
||||
public FileServiceImpl(MinioClient minioClient, MinioConfig minioConfig) {
|
||||
this.minioClient = minioClient;
|
||||
this.minioConfig = minioConfig;
|
||||
}
|
||||
|
||||
private String currentUserId() {
|
||||
String userId = UserContextUtils.getCurrentUserId();
|
||||
if (userId == null || userId.isEmpty()) {
|
||||
throw new CustomException(ResponseEnum.UNAUTHORIZED, "未获取到用户身份");
|
||||
}
|
||||
return userId;
|
||||
}
|
||||
|
||||
private String userBucket(String userId) {
|
||||
return (minioConfig.getBucketName() + "-" + userId).toLowerCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createBucketIfNotExist() throws Throwable {
|
||||
try {
|
||||
@@ -61,22 +73,42 @@ public class FileServiceImpl implements FileService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createUserBucket(String userId) throws Throwable {
|
||||
String bucket = userBucket(userId);
|
||||
try {
|
||||
boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
|
||||
if (!found) {
|
||||
log.info("bucket不存在,为用户{}创建bucket:{}", userId, bucket);
|
||||
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
|
||||
}
|
||||
} catch (MinioException e) {
|
||||
log.error("MinIO 操作失败:", e);
|
||||
throw new CustomException(500, "创建bucket失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateUploadUrl(String fileName) throws Throwable {
|
||||
String userId = currentUserId();
|
||||
String bucket = userBucket(userId);
|
||||
createUserBucket(userId);
|
||||
return minioClient.getPresignedObjectUrl(
|
||||
GetPresignedObjectUrlArgs.builder()
|
||||
.method(Method.PUT)
|
||||
.bucket(minioConfig.getBucketName())
|
||||
.bucket(bucket)
|
||||
.object(fileName).build()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateDownloadUrl(String fileName) throws Throwable {
|
||||
String userId = currentUserId();
|
||||
String bucket = userBucket(userId);
|
||||
return minioClient.getPresignedObjectUrl(
|
||||
GetPresignedObjectUrlArgs.builder()
|
||||
.method(Method.GET)
|
||||
.bucket(minioConfig.getBucketName())
|
||||
.bucket(bucket)
|
||||
.object(fileName).build()
|
||||
);
|
||||
}
|
||||
@@ -91,7 +123,7 @@ public class FileServiceImpl implements FileService {
|
||||
imageInfo.setContentType(imageInfoVo.getContentType());
|
||||
imageInfo.setSize(imageInfoVo.getSize());
|
||||
imageInfo.setUploadTime(LocalDateTime.now());
|
||||
imageInfo.setUserId("9999");
|
||||
imageInfo.setUserId(currentUserId());
|
||||
imageInfoMapper.insert(imageInfo);
|
||||
} catch (Exception e) {
|
||||
log.error("保存图片元数据失败", e);
|
||||
@@ -114,15 +146,16 @@ public class FileServiceImpl implements FileService {
|
||||
|
||||
} else {
|
||||
// 不存在其他image_info使用则删除 MinIO 中的对象
|
||||
log.info("删除 MinIO 中的对象:{}", imageInfo.getObjectKey());
|
||||
String bucket = userBucket(imageInfo.getUserId());
|
||||
log.info("删除 MinIO 中的对象:{} from bucket {}", imageInfo.getObjectKey(), bucket);
|
||||
minioClient.removeObject(RemoveObjectArgs.builder()
|
||||
.bucket(minioConfig.getBucketName())
|
||||
.bucket(bucket)
|
||||
.object(imageInfo.getObjectKey())
|
||||
.build());
|
||||
// 删除低分辨率图像
|
||||
log.info("删除 MinIO 中的低分辨率对象:{}", CommonConstants.LOW_RESOLUTION_PREFIX + imageInfo.getObjectKey());
|
||||
minioClient.removeObject(RemoveObjectArgs.builder()
|
||||
.bucket(minioConfig.getBucketName())
|
||||
.bucket(bucket)
|
||||
.object(CommonConstants.LOW_RESOLUTION_PREFIX + imageInfo.getObjectKey())
|
||||
.build());
|
||||
}
|
||||
@@ -168,8 +201,18 @@ public class FileServiceImpl implements FileService {
|
||||
ArrayList<String> urls = new ArrayList<>();
|
||||
|
||||
for (String imageInstanceId : imageIds) {
|
||||
String objectKey = imageInfoMapper.selectObjectKeyById(imageInstanceId);
|
||||
String url = this.generateDownloadUrl(objectKey);
|
||||
ImageInfo info = imageInfoMapper.selectByInstanceId(imageInstanceId);
|
||||
if (info == null) {
|
||||
continue;
|
||||
}
|
||||
String bucket = userBucket(info.getUserId());
|
||||
String url = minioClient.getPresignedObjectUrl(
|
||||
GetPresignedObjectUrlArgs.builder()
|
||||
.method(Method.GET)
|
||||
.bucket(bucket)
|
||||
.object(info.getObjectKey())
|
||||
.build()
|
||||
);
|
||||
urls.add(url);
|
||||
}
|
||||
return urls;
|
||||
@@ -183,6 +226,9 @@ public class FileServiceImpl implements FileService {
|
||||
String lowResolutionObjectKey = CommonConstants.LOW_RESOLUTION_PREFIX + hash + suffix;
|
||||
log.info("上传图片的ObjectKey值为:{}", objectKey);
|
||||
List<FileHash> hashByFileHash = fileHashMapper.getFileHashByFileHash(hash);
|
||||
String userId = currentUserId();
|
||||
String bucket = userBucket(userId);
|
||||
createUserBucket(userId);
|
||||
// 2. 保存元数据到 MySQL
|
||||
ImageInfo imageInfo = new ImageInfo();
|
||||
imageInfo.setInstanceId(IdUtils.randomUuidUpper());
|
||||
@@ -190,14 +236,14 @@ public class FileServiceImpl implements FileService {
|
||||
imageInfo.setImageName(image.getOriginalFilename());
|
||||
imageInfo.setContentType(image.getContentType());
|
||||
imageInfo.setSize(image.getSize());
|
||||
imageInfo.setUserId("9999");
|
||||
imageInfo.setUserId(userId);
|
||||
imageInfo.setUploadTime(LocalDateTime.now());
|
||||
if (hashByFileHash != null && !hashByFileHash.isEmpty()) {
|
||||
log.info("当前文件已存在,不进行minio文件上传");
|
||||
} else {
|
||||
// 1. 上传到 MinIO
|
||||
minioClient.putObject(PutObjectArgs.builder()
|
||||
.bucket(minioConfig.getBucketName())
|
||||
.bucket(bucket)
|
||||
.object(objectKey)
|
||||
.stream(image.getInputStream(), image.getSize(), -1)
|
||||
.contentType(image.getContentType())
|
||||
@@ -212,7 +258,7 @@ public class FileServiceImpl implements FileService {
|
||||
|
||||
ByteArrayInputStream lowResInputStream = new ByteArrayInputStream(lowResOutputStream.toByteArray());
|
||||
minioClient.putObject(PutObjectArgs.builder()
|
||||
.bucket(minioConfig.getBucketName())
|
||||
.bucket(bucket)
|
||||
.object(lowResolutionObjectKey)
|
||||
.stream(lowResInputStream, lowResInputStream.available(), -1)
|
||||
.contentType(image.getContentType())
|
||||
@@ -236,8 +282,10 @@ public class FileServiceImpl implements FileService {
|
||||
if (objectKey == null) {
|
||||
throw new CustomException(ResponseEnum.NOT_FOUND_ERROR);
|
||||
}
|
||||
ImageInfo imageInfo = imageInfoMapper.selectByInstanceId(instanceId);
|
||||
String bucket = userBucket(imageInfo.getUserId());
|
||||
return minioClient.getObject(GetObjectArgs.builder()
|
||||
.bucket(minioConfig.getBucketName())
|
||||
.bucket(bucket)
|
||||
.object(objectKey)
|
||||
.build());
|
||||
}
|
||||
@@ -249,26 +297,29 @@ public class FileServiceImpl implements FileService {
|
||||
throw new CustomException(ResponseEnum.NOT_FOUND_ERROR);
|
||||
}
|
||||
String lowResObjectKey = CommonConstants.LOW_RESOLUTION_PREFIX + objectKey;
|
||||
ImageInfo imageInfo = imageInfoMapper.selectByInstanceId(instanceId);
|
||||
String bucket = userBucket(imageInfo.getUserId());
|
||||
|
||||
// 优先返回低分辨率版本,如果不存在则返回原图
|
||||
if (doesObjectExist(lowResObjectKey)) {
|
||||
if (doesObjectExist(bucket, lowResObjectKey)) {
|
||||
return minioClient.getObject(GetObjectArgs.builder()
|
||||
.bucket(minioConfig.getBucketName())
|
||||
.bucket(bucket)
|
||||
.object(lowResObjectKey)
|
||||
.build());
|
||||
} else {
|
||||
log.warn("低分辨率版本不存在,返回原图: {}", objectKey);
|
||||
return minioClient.getObject(GetObjectArgs.builder()
|
||||
.bucket(minioConfig.getBucketName())
|
||||
.bucket(bucket)
|
||||
.object(objectKey)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Map getImagesListByOwnerId(ImageInfoVo imageInfoVo) {
|
||||
public Map<String, Object> getImagesListByOwnerId(ImageInfoVo imageInfoVo) {
|
||||
HashMap<String, String> map = new HashMap<>();
|
||||
map.put("ownerId", imageInfoVo.getOwnerId());
|
||||
Map resultMap = PageUtils.pageQuery(imageInfoVo.getCurrent(), imageInfoVo.getPageSize(), ImageInfoMapper.class, "selectListByOwnerId",
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> resultMap = (Map<String, Object>) PageUtils.pageQuery(imageInfoVo.getCurrent(), imageInfoVo.getPageSize(), ImageInfoMapper.class, "selectListByOwnerId",
|
||||
map, "list");
|
||||
return resultMap;
|
||||
}
|
||||
@@ -278,10 +329,10 @@ public class FileServiceImpl implements FileService {
|
||||
* @param objectKey 对象键
|
||||
* @return true表示存在,false表示不存在
|
||||
*/
|
||||
private boolean doesObjectExist(String objectKey) {
|
||||
private boolean doesObjectExist(String bucket, String objectKey) {
|
||||
try {
|
||||
minioClient.statObject(StatObjectArgs.builder()
|
||||
.bucket(minioConfig.getBucketName())
|
||||
.bucket(bucket)
|
||||
.object(objectKey)
|
||||
.build());
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user