- 重构 TimelinePanel.vue 组件,使用 Tailwind CSS 替代 Less,简化样式代码 - 改进视觉设计:更新颜色方案、间距和图标,提升用户体验 - 移除音频结束位置标记,优化刻度尺和轨道显示逻辑 - 统一时长差异提示的样式和状态显示 feat(infra): 扩展文件预签名接口支持 Content-Type 参数 - 在 FileApi、FileClient、FileService 接口中新增带 Content-Type 参数的 presignGetUrl 方法 - 实现 S3FileClient 对 Content-Type 参数的支持,确保浏览器正确渲染媒体文件 - 在 TikUserFileServiceImpl 中为音视频文件生成预签名 URL 时自动推断 Content-Type - 支持公开访问和私有访问两种模式下的 Content-Type 参数传递
This commit is contained in:
@@ -52,6 +52,18 @@ public interface FileApi {
|
||||
String presignGetUrl(@NotEmpty(message = "URL 不能为空") String url,
|
||||
Integer expirationSeconds);
|
||||
|
||||
/**
|
||||
* 生成文件预签名地址(带 Content-Type),用于读取
|
||||
*
|
||||
* @param url 完整的文件访问地址
|
||||
* @param expirationSeconds 访问有效期,单位秒
|
||||
* @param contentType 响应的 Content-Type,为 null 时不设置
|
||||
* @return 文件预签名地址
|
||||
*/
|
||||
String presignGetUrl(@NotEmpty(message = "URL 不能为空") String url,
|
||||
Integer expirationSeconds,
|
||||
String contentType);
|
||||
|
||||
/**
|
||||
* 生成文件预签名地址(带 OSS 处理参数),用于读取
|
||||
* 用于阿里云 OSS 视频截帧等图片处理场景
|
||||
|
||||
@@ -31,7 +31,12 @@ public class FileApiImpl implements FileApi {
|
||||
|
||||
@Override
|
||||
public String presignGetUrl(String url, Integer expirationSeconds) {
|
||||
return fileService.presignGetUrl(url, expirationSeconds);
|
||||
return presignGetUrl(url, expirationSeconds, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String presignGetUrl(String url, Integer expirationSeconds, String contentType) {
|
||||
return fileService.presignGetUrl(url, expirationSeconds, contentType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -71,6 +71,18 @@ public interface FileClient {
|
||||
* @return 文件预签名地址
|
||||
*/
|
||||
default String presignGetUrl(String url, Integer expirationSeconds) {
|
||||
return presignGetUrl(url, expirationSeconds, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成文件预签名地址(带 Content-Type),用于读取
|
||||
*
|
||||
* @param url 完整的文件访问地址
|
||||
* @param expirationSeconds 访问有效期,单位秒
|
||||
* @param contentType 响应的 Content-Type,为 null 时不设置
|
||||
* @return 文件预签名地址
|
||||
*/
|
||||
default String presignGetUrl(String url, Integer expirationSeconds, String contentType) {
|
||||
throw new UnsupportedOperationException("不支持的操作");
|
||||
}
|
||||
|
||||
|
||||
@@ -200,12 +200,19 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String presignGetUrl(String url, Integer expirationSeconds) {
|
||||
return presignGetUrlWithProcess(url, expirationSeconds, null);
|
||||
public String presignGetUrl(String url, Integer expirationSeconds, String contentType) {
|
||||
return presignGetUrlWithProcess(url, expirationSeconds, null, contentType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String presignGetUrlWithProcess(String url, Integer expirationSeconds, String processParam) {
|
||||
return presignGetUrlWithProcess(url, expirationSeconds, processParam, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成文件预签名地址(带 OSS 处理参数和 Content-Type),用于读取
|
||||
*/
|
||||
private String presignGetUrlWithProcess(String url, Integer expirationSeconds, String processParam, String contentType) {
|
||||
// 1. 将 url 转换为 path(支持 CDN 域名和 OSS 原始域名)
|
||||
String path = extractPathFromUrl(url);
|
||||
String decodedPath = URLUtil.decode(path, StandardCharsets.UTF_8);
|
||||
@@ -213,11 +220,17 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
|
||||
// 2. 公开访问:无需签名,直接拼接参数
|
||||
if (!BooleanUtil.isFalse(config.getEnablePublicAccess())) {
|
||||
String encodedPath = UriUtils.encodePath(decodedPath, StandardCharsets.UTF_8);
|
||||
String resultUrl = config.getDomain() + "/" + encodedPath;
|
||||
StringBuilder resultUrl = new StringBuilder(config.getDomain()).append("/").append(encodedPath);
|
||||
char separator = '?';
|
||||
if (StrUtil.isNotBlank(processParam)) {
|
||||
resultUrl = resultUrl + "?x-oss-process=" + processParam;
|
||||
resultUrl.append(separator).append("x-oss-process=").append(processParam);
|
||||
separator = '&';
|
||||
}
|
||||
return resultUrl;
|
||||
if (StrUtil.isNotBlank(contentType)) {
|
||||
resultUrl.append(separator).append("response-content-type=").append(
|
||||
URLUtil.encode(contentType, StandardCharsets.UTF_8));
|
||||
}
|
||||
return resultUrl.toString();
|
||||
}
|
||||
|
||||
// 3. 私有访问:生成预签名 URL(需要将处理参数包含在签名中)
|
||||
@@ -229,10 +242,14 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
|
||||
com.aliyun.oss.model.GeneratePresignedUrlRequest request =
|
||||
new com.aliyun.oss.model.GeneratePresignedUrlRequest(config.getBucket(), decodedPath, HttpMethod.GET);
|
||||
request.setExpiration(expirationDate);
|
||||
// 关键:将 x-oss-process 参数包含在签名中
|
||||
// 将 x-oss-process 参数包含在签名中
|
||||
if (StrUtil.isNotBlank(processParam)) {
|
||||
request.addQueryParameter("x-oss-process", processParam);
|
||||
}
|
||||
// 设置 response-content-type,确保浏览器能正确渲染
|
||||
if (StrUtil.isNotBlank(contentType)) {
|
||||
request.addQueryParameter("response-content-type", contentType);
|
||||
}
|
||||
signedUrl = aliyunOssClient.generatePresignedUrl(request).toString();
|
||||
} else {
|
||||
// 非阿里云不支持 OSS 处理参数,直接返回普通预签名 URL
|
||||
|
||||
@@ -54,6 +54,16 @@ public interface FileService {
|
||||
*/
|
||||
String presignGetUrl(String url, Integer expirationSeconds);
|
||||
|
||||
/**
|
||||
* 生成文件预签名地址(带 Content-Type),用于读取
|
||||
*
|
||||
* @param url 完整的文件访问地址
|
||||
* @param expirationSeconds 访问有效期,单位秒
|
||||
* @param contentType 响应的 Content-Type,为 null 时不设置
|
||||
* @return 文件预签名地址
|
||||
*/
|
||||
String presignGetUrl(String url, Integer expirationSeconds, String contentType);
|
||||
|
||||
/**
|
||||
* 生成文件预签名地址(带 OSS 处理参数),用于读取
|
||||
* 用于阿里云 OSS 视频截帧等图片处理场景
|
||||
|
||||
@@ -142,8 +142,13 @@ public class FileServiceImpl implements FileService {
|
||||
|
||||
@Override
|
||||
public String presignGetUrl(String url, Integer expirationSeconds) {
|
||||
return presignGetUrl(url, expirationSeconds, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String presignGetUrl(String url, Integer expirationSeconds, String contentType) {
|
||||
FileClient fileClient = fileConfigService.getMasterFileClient();
|
||||
return fileClient.presignGetUrl(url, expirationSeconds);
|
||||
return fileClient.presignGetUrl(url, expirationSeconds, contentType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user