diff --git a/deploy/update_image_info.sql b/deploy/update_image_info.sql
new file mode 100644
index 0000000..77319ce
--- /dev/null
+++ b/deploy/update_image_info.sql
@@ -0,0 +1,8 @@
+ALTER TABLE `image_info`
+ADD COLUMN `thumbnail_instance_id` varchar(32) DEFAULT NULL COMMENT '视频缩略图ID',
+ADD COLUMN `duration` bigint DEFAULT NULL COMMENT '视频时长(秒)';ALTER TABLE `story_item`
+ADD COLUMN `video_url` VARCHAR(64) COMMENT '视频文件 Instance ID',
+ADD COLUMN `duration` BIGINT COMMENT '视频时长(秒)',
+ADD COLUMN `thumbnail_url` VARCHAR(64) COMMENT '视频封面 Instance ID';ALTALTER TABLE story_item ADD COLUMN share_id VARCHAR(64) DEFAULT NULL COMMENT '分享ID';ER TABLE `image_info`
+ADD COLUMN `thumbnail_instance_id` varchar(32) DEFAULT NULL COMMENT '视频缩略图ID',
+ADD COLUMN `duration` bigint DEFAULT NULL COMMENT '视频时长(秒)';
diff --git a/timeline-file-service/src/main/java/com/timeline/file/config/MinioConfig.java b/timeline-file-service/src/main/java/com/timeline/file/config/MinioConfig.java
index 5c9b650..58cbde5 100644
--- a/timeline-file-service/src/main/java/com/timeline/file/config/MinioConfig.java
+++ b/timeline-file-service/src/main/java/com/timeline/file/config/MinioConfig.java
@@ -11,6 +11,7 @@ import org.springframework.context.annotation.Configuration;
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {
private String endpoint;
+ private String externalEndpoint;
private String accessKey;
private String secretKey;
private String bucketName;
diff --git a/timeline-file-service/src/main/java/com/timeline/file/service/impl/FileServiceImpl.java b/timeline-file-service/src/main/java/com/timeline/file/service/impl/FileServiceImpl.java
index 3ec8972..bfc60af 100644
--- a/timeline-file-service/src/main/java/com/timeline/file/service/impl/FileServiceImpl.java
+++ b/timeline-file-service/src/main/java/com/timeline/file/service/impl/FileServiceImpl.java
@@ -90,27 +90,44 @@ public class FileServiceImpl implements FileService {
}
}
+ private String replaceWithExternalEndpoint(String url) {
+ String externalEndpoint = minioConfig.getExternalEndpoint();
+ if (externalEndpoint != null && !externalEndpoint.isEmpty()) {
+ String internalEndpoint = minioConfig.getEndpoint();
+ // 简单替换:将内部 Endpoint 替换为外部 Endpoint
+ // 注意:MinIO 生成的 URL 肯定以配置的 Endpoint 开头
+ if (url.startsWith(internalEndpoint)) {
+ return url.replaceFirst(java.util.regex.Pattern.quote(internalEndpoint), externalEndpoint);
+ }
+ }
+ return url;
+ }
+
@Override
public String generateUploadUrl(String fileName) throws Throwable {
String userId = currentUserId();
String bucket = userBucket(userId);
createUserBucket(userId);
- return minioClient.getPresignedObjectUrl(
+ String url = minioClient.getPresignedObjectUrl(
GetPresignedObjectUrlArgs.builder()
.method(Method.PUT)
.bucket(bucket)
- .object(fileName).build());
+ .object(fileName)
+ .expiry(30 * 60) // 30 minutes
+ .build());
+ return replaceWithExternalEndpoint(url);
}
@Override
public String generateDownloadUrl(String fileName) throws Throwable {
String userId = currentUserId();
String bucket = userBucket(userId);
- return minioClient.getPresignedObjectUrl(
+ String url = minioClient.getPresignedObjectUrl(
GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(bucket)
.object(fileName).build());
+ return replaceWithExternalEndpoint(url);
}
@Override
@@ -121,13 +138,14 @@ public class FileServiceImpl implements FileService {
}
String bucket = userBucket(imageInfo.getUserId());
// 生成预签名 URL,有效期例如 1 小时
- return minioClient.getPresignedObjectUrl(
+ String url = minioClient.getPresignedObjectUrl(
GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(bucket)
.object(imageInfo.getObjectKey())
.expiry(3600) // 1小时
.build());
+ return replaceWithExternalEndpoint(url);
}
@Override
@@ -237,7 +255,7 @@ public class FileServiceImpl implements FileService {
.bucket(bucket)
.object(info.getObjectKey())
.build());
- urls.add(url);
+ urls.add(replaceWithExternalEndpoint(url));
}
return urls;
}
@@ -267,20 +285,39 @@ public class FileServiceImpl implements FileService {
log.info("当前文件已存在,不进行minio文件上传");
} else {
// 1. 上传到 MinIO
- // 对原图进行压缩
+ // 尝试对原图进行压缩
ByteArrayOutputStream compressedOutputStream = new ByteArrayOutputStream();
- Thumbnails.of(image.getInputStream())
- .scale(1.0) // 保持原图尺寸
- .outputQuality(0.8) // 设置压缩质量
- .toOutputStream(compressedOutputStream);
- ByteArrayInputStream compressedInputStream = new ByteArrayInputStream(compressedOutputStream.toByteArray());
+ boolean compressionSuccess = false;
+ try {
+ Thumbnails.of(image.getInputStream())
+ .scale(1.0) // 保持原图尺寸
+ .outputQuality(0.8) // 设置压缩质量
+ .toOutputStream(compressedOutputStream);
+ compressionSuccess = true;
+ } catch (Exception e) {
+ log.warn("图片压缩失败(可能是格式不支持或非图片文件),降级为直接上传原图: {}", image.getOriginalFilename(), e);
+ }
- minioClient.putObject(PutObjectArgs.builder()
- .bucket(bucket)
- .object(objectKey)
- .stream(compressedInputStream, compressedInputStream.available(), -1)
- .contentType(image.getContentType())
- .build());
+ if (compressionSuccess) {
+ ByteArrayInputStream compressedInputStream = new ByteArrayInputStream(
+ compressedOutputStream.toByteArray());
+ minioClient.putObject(PutObjectArgs.builder()
+ .bucket(bucket)
+ .object(objectKey)
+ .stream(compressedInputStream, compressedInputStream.available(), -1)
+ .contentType(image.getContentType())
+ .build());
+ } else {
+ // 压缩失败,直接上传原图
+ try (InputStream inputStream = image.getInputStream()) {
+ minioClient.putObject(PutObjectArgs.builder()
+ .bucket(bucket)
+ .object(objectKey)
+ .stream(inputStream, image.getSize(), -1)
+ .contentType(image.getContentType())
+ .build());
+ }
+ }
// 生成并上传低分辨率版本
try (InputStream inputStream = image.getInputStream()) {
ByteArrayOutputStream lowResOutputStream = new ByteArrayOutputStream();
@@ -296,10 +333,10 @@ public class FileServiceImpl implements FileService {
.stream(lowResInputStream, lowResInputStream.available(), -1)
.contentType(image.getContentType())
.build());
-
log.info("低分辨率版本已生成并上传: {}", lowResolutionObjectKey);
} catch (Exception e) {
log.error("生成低分辨率版本失败", e);
+ // 低分辨率生成失败不影响主流程
}
}
fileHashMapper.insertFileHash(new FileHash(imageInfo.getInstanceId(), hash));
diff --git a/timeline-file-service/src/main/resources/com/timeline/file/dao/ImageInfoMapper.xml b/timeline-file-service/src/main/resources/com/timeline/file/dao/ImageInfoMapper.xml
index 14569dd..8ca16cc 100644
--- a/timeline-file-service/src/main/resources/com/timeline/file/dao/ImageInfoMapper.xml
+++ b/timeline-file-service/src/main/resources/com/timeline/file/dao/ImageInfoMapper.xml
@@ -22,7 +22,14 @@