feat: 添加项目配置和依赖更新
配置更新: 1. 前端配置 - 添加 hook-fetch 依赖用于 HTTP 请求 - 更新 vite.config.mts 配置 - 添加 .npmrc 配置文件 2. 后端配置 - 更新 application.yml 和 application-dev.yml 配置 - 更新 docker-compose.yml 配置 3. 代码优化 - OSS 客户端优化 - SSE 管理器优化 - 聊天服务和向量存储策略优化 4. 项目文档 - 添加 CLAUDE.md 项目指南 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,7 @@ import org.hzhub.common.oss.properties.OssProperties;
|
||||
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
|
||||
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
|
||||
import software.amazon.awssdk.core.async.*;
|
||||
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
|
||||
import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient;
|
||||
import software.amazon.awssdk.regions.Region;
|
||||
import software.amazon.awssdk.services.s3.S3AsyncClient;
|
||||
@@ -94,7 +95,14 @@ public class OssClient {
|
||||
.region(of())
|
||||
.forcePathStyle(isStyle)
|
||||
.httpClient(NettyNioAsyncHttpClient.builder()
|
||||
.connectionTimeout(Duration.ofSeconds(60)).build())
|
||||
.connectionTimeout(Duration.ofMinutes(5))
|
||||
.readTimeout(Duration.ofMinutes(5))
|
||||
.writeTimeout(Duration.ofMinutes(5))
|
||||
.build())
|
||||
.overrideConfiguration(ClientOverrideConfiguration.builder()
|
||||
.apiCallTimeout(Duration.ofMinutes(10))
|
||||
.apiCallAttemptTimeout(Duration.ofMinutes(5))
|
||||
.build())
|
||||
.build();
|
||||
|
||||
//AWS基于 CRT 的 S3 AsyncClient 实例用作 S3 传输管理器的底层客户端
|
||||
@@ -172,36 +180,22 @@ public class OssClient {
|
||||
* @throws OssException 如果上传失败,抛出自定义异常
|
||||
*/
|
||||
public UploadResult upload(InputStream inputStream, String key, Long length, String contentType) {
|
||||
// 如果输入流不是 ByteArrayInputStream,则将其读取为字节数组再创建 ByteArrayInputStream
|
||||
if (!(inputStream instanceof ByteArrayInputStream)) {
|
||||
inputStream = new ByteArrayInputStream(IoUtil.readBytes(inputStream));
|
||||
}
|
||||
// 将输入流转换为字节数组,使用异步字节数组上传方式
|
||||
try {
|
||||
// 创建异步请求体(length如果为空会报错)
|
||||
BlockingInputStreamAsyncRequestBody body = BlockingInputStreamAsyncRequestBody.builder()
|
||||
.contentLength(length)
|
||||
.subscribeTimeout(Duration.ofSeconds(120))
|
||||
.build();
|
||||
byte[] bytes = IoUtil.readBytes(inputStream);
|
||||
|
||||
// 使用 transferManager 进行上传
|
||||
Upload upload = transferManager.upload(
|
||||
x -> x.requestBody(body).addTransferListener(LoggingTransferListener.create())
|
||||
.putObjectRequest(
|
||||
y -> y.bucket(properties.getBucketName())
|
||||
.key(key)
|
||||
.contentType(contentType)
|
||||
// 用于设置对象的访问控制列表(ACL)。不同云厂商对ACL的支持和实现方式有所不同,
|
||||
// 因此根据具体的云服务提供商,你可能需要进行不同的配置(自行开启,阿里云有acl权限配置,腾讯云没有acl权限配置)
|
||||
//.acl(getAccessPolicy().getObjectCannedACL())
|
||||
.build())
|
||||
.build());
|
||||
// 使用异步方式上传字节数组
|
||||
software.amazon.awssdk.services.s3.model.PutObjectResponse response = client.putObject(
|
||||
software.amazon.awssdk.services.s3.model.PutObjectRequest.builder()
|
||||
.bucket(properties.getBucketName())
|
||||
.key(key)
|
||||
.contentType(contentType)
|
||||
.contentLength((long) bytes.length)
|
||||
.build(),
|
||||
software.amazon.awssdk.core.async.AsyncRequestBody.fromBytes(bytes)
|
||||
).join();
|
||||
|
||||
// 将输入流写入请求体
|
||||
body.writeInputStream(inputStream);
|
||||
|
||||
// 等待文件上传操作完成
|
||||
CompletedUpload uploadResult = upload.completionFuture().join();
|
||||
String eTag = uploadResult.response().eTag();
|
||||
String eTag = response.eTag();
|
||||
|
||||
// 提取上传结果中的 ETag,并构建一个自定义的 UploadResult 对象
|
||||
return UploadResult.builder().url(getUrl() + StringUtils.SLASH + key).filename(key).eTag(eTag).build();
|
||||
|
||||
Reference in New Issue
Block a user