标注结果比较优化
This commit is contained in:
@@ -50,7 +50,7 @@ public class AnnotationResultController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "查询标注结果比对信息")
|
@Operation(summary = "查询标注结果比对信息")
|
||||||
@RequirePosition(UserPosition.REVIEWER)
|
//@RequirePosition(UserPosition.REVIEWER)
|
||||||
@GetMapping("/{id}/compare")
|
@GetMapping("/{id}/compare")
|
||||||
public Result<AnnotationResultCompareResponse> compare(
|
public Result<AnnotationResultCompareResponse> compare(
|
||||||
@Parameter(description = "结果ID", example = "191000000000000401")
|
@Parameter(description = "结果ID", example = "191000000000000401")
|
||||||
@@ -60,7 +60,7 @@ public class AnnotationResultController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "提交合并审核结果")
|
@Operation(summary = "提交合并审核结果")
|
||||||
@RequirePosition(UserPosition.REVIEWER)
|
//@RequirePosition(UserPosition.REVIEWER)
|
||||||
@PostMapping("/{id}/merge-review")
|
@PostMapping("/{id}/merge-review")
|
||||||
public Result<MergeReviewResultResponse> mergeReview(
|
public Result<MergeReviewResultResponse> mergeReview(
|
||||||
@Parameter(description = "结果ID", example = "191000000000000401")
|
@Parameter(description = "结果ID", example = "191000000000000401")
|
||||||
|
|||||||
@@ -3,12 +3,14 @@ package com.labelsys.backend.dto.response;
|
|||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import com.labelsys.backend.enums.AnnotationResultStatus;
|
||||||
|
|
||||||
@Schema(description = "标注结果响应")
|
@Schema(description = "标注结果响应")
|
||||||
public record AnnotationResultResponse(
|
public record AnnotationResultResponse(
|
||||||
@Schema(description = "结果ID", example = "191000000000000401") Long id,
|
@Schema(description = "结果ID", example = "191000000000000401") Long id,
|
||||||
@Schema(description = "任务ID", example = "191000000000000301") Long taskId,
|
@Schema(description = "任务ID", example = "191000000000000301") Long taskId,
|
||||||
@Schema(description = "资源ID", example = "191000000000000101") Long resourceId,
|
@Schema(description = "资源ID", example = "191000000000000101") Long resourceId,
|
||||||
@Schema(description = "运行态状态", example = "MANUAL_REVIEW_PENDING") String runtimeStatus,
|
@Schema(description = "标注结果状态", example = "MANUAL_REVIEW_PENDING") AnnotationResultStatus runtimeStatus,
|
||||||
@Schema(description = "是否需要人工审核", example = "true") Boolean requiresManualReview,
|
@Schema(description = "是否需要人工审核", example = "true") Boolean requiresManualReview,
|
||||||
@Schema(description = "是否已删除", example = "false") Boolean isDeleted,
|
@Schema(description = "是否已删除", example = "false") Boolean isDeleted,
|
||||||
@Schema(description = "问答存储模式", example = "INLINE") String qaContentStorageMode,
|
@Schema(description = "问答存储模式", example = "INLINE") String qaContentStorageMode,
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.labelsys.backend.enums;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "标注结果状态枚举值:MANUAL_REVIEW_PENDING待人工审核、MANUAL_REVIEW_PENDING待自动归档、ARCHIVED已归档")
|
||||||
|
public enum AnnotationResultStatus {
|
||||||
|
MANUAL_REVIEW_PENDING,
|
||||||
|
AUTO_ARCHIVE_PENDING,
|
||||||
|
ARCHIVED
|
||||||
|
}
|
||||||
@@ -2,11 +2,8 @@ package com.labelsys.backend.enums;
|
|||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
@Schema(description = "模型配置模式,枚举值:SELECT:选择已有模型配置、MANUAL:手动配置新模型")
|
@Schema(description = "模型配置模式,枚举值:SELECT:选择已有模型配置、MANUAL:手动录入新模型")
|
||||||
public enum ConfigMode {
|
public enum ConfigMode {
|
||||||
@Schema(description = "从已有配置中选择")
|
|
||||||
SELECT,
|
SELECT,
|
||||||
|
|
||||||
@Schema(description = "手动录入配置")
|
|
||||||
MANUAL
|
MANUAL
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package com.labelsys.backend.enums;
|
package com.labelsys.backend.enums;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "系统配置类型,枚举值:model:大模型配置、prompt:提示词配置, system:其他配置项")
|
||||||
public enum ConfigType {
|
public enum ConfigType {
|
||||||
MODEL,
|
MODEL,
|
||||||
PROMPT,
|
PROMPT,
|
||||||
|
|||||||
@@ -2,20 +2,11 @@ package com.labelsys.backend.enums;
|
|||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
@Schema(description = "行业类型")
|
@Schema(description = "行业类型,枚举值:TRANSPORT:交通、ELECTRICITY:电力、FINANCE:金融、MEDICAL:医疗、EDUCATION:教育")
|
||||||
public enum IndustryType {
|
public enum IndustryType {
|
||||||
@Schema(description = "交通运输")
|
|
||||||
TRANSPORT,
|
TRANSPORT,
|
||||||
|
|
||||||
@Schema(description = "电力")
|
|
||||||
ELECTRICITY,
|
ELECTRICITY,
|
||||||
|
|
||||||
@Schema(description = "金融")
|
|
||||||
FINANCE,
|
FINANCE,
|
||||||
|
|
||||||
@Schema(description = "医疗")
|
|
||||||
MEDICAL,
|
MEDICAL,
|
||||||
|
|
||||||
@Schema(description = "教育")
|
|
||||||
EDUCATION
|
EDUCATION
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
package com.labelsys.backend.enums;
|
package com.labelsys.backend.enums;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "问答对存储形式,枚举值:INLINE:记录中保存、EXTERNAL:外部存储器rustfs")
|
||||||
public enum QaContentStorageMode {
|
public enum QaContentStorageMode {
|
||||||
INLINE,
|
INLINE,
|
||||||
EXTERNAL;
|
EXTERNAL;
|
||||||
|
|
||||||
public static boolean isValid(String value) {
|
public static boolean isValid(String value) {
|
||||||
return Arrays.stream(values()).anyMatch(mode -> mode.name().equals(value));
|
return Arrays.stream(values()).anyMatch(mode -> mode.name().equals(value));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ package com.labelsys.backend.enums;
|
|||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "资源类型,枚举值:TEXT:文本、IMAGE:图片、VIDEO:视频")
|
||||||
public enum ResourceType {
|
public enum ResourceType {
|
||||||
TEXT,
|
TEXT,
|
||||||
IMAGE,
|
IMAGE,
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
package com.labelsys.backend.enums;
|
|
||||||
|
|
||||||
public enum RuntimeResultStatus {
|
|
||||||
MANUAL_REVIEW_PENDING,
|
|
||||||
AUTO_ARCHIVE_PENDING,
|
|
||||||
ARCHIVED
|
|
||||||
}
|
|
||||||
@@ -2,6 +2,9 @@ package com.labelsys.backend.enums;
|
|||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "资源状态,暂不使用,枚举值:UPLOADED:已上传、PROCESSING:处理中、READY:已完成、ARCHIVED:已归档")
|
||||||
public enum SourceStatus {
|
public enum SourceStatus {
|
||||||
UPLOADED,
|
UPLOADED,
|
||||||
PROCESSING,
|
PROCESSING,
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ package com.labelsys.backend.enums;
|
|||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "任务状态枚举值:PENDING:待执行、RUNNING:处理中、COMPLETED:已完成、FAILED:失败")
|
||||||
public enum TaskStatus {
|
public enum TaskStatus {
|
||||||
PENDING,
|
PENDING,
|
||||||
RUNNING,
|
RUNNING,
|
||||||
|
|||||||
@@ -2,11 +2,8 @@ package com.labelsys.backend.enums;
|
|||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
@Schema(description = "标注任务类型")
|
@Schema(description = "标注任务类型枚举值:EXTRACT_QA:抽取任务、FINE_TUNE:微调任务")
|
||||||
public enum TaskType {
|
public enum TaskType {
|
||||||
@Schema(description = "抽取问答对")
|
|
||||||
EXTRACT_QA,
|
EXTRACT_QA,
|
||||||
|
|
||||||
@Schema(description = "大模型微调")
|
|
||||||
FINE_TUNE
|
FINE_TUNE
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.labelsys.backend.service;
|
package com.labelsys.backend.service;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -15,7 +16,8 @@ import com.labelsys.backend.dto.response.AnnotationResultCompareResponse;
|
|||||||
import com.labelsys.backend.dto.response.AnnotationResultResponse;
|
import com.labelsys.backend.dto.response.AnnotationResultResponse;
|
||||||
import com.labelsys.backend.entity.AnnotationResult;
|
import com.labelsys.backend.entity.AnnotationResult;
|
||||||
import com.labelsys.backend.entity.SourceResource;
|
import com.labelsys.backend.entity.SourceResource;
|
||||||
import com.labelsys.backend.enums.RuntimeResultStatus;
|
import com.labelsys.backend.enums.AnnotationResultStatus;
|
||||||
|
import com.labelsys.backend.enums.QaContentStorageMode;
|
||||||
import com.labelsys.backend.mapper.AnnotationResultMapper;
|
import com.labelsys.backend.mapper.AnnotationResultMapper;
|
||||||
import com.labelsys.backend.mapper.SourceResourceMapper;
|
import com.labelsys.backend.mapper.SourceResourceMapper;
|
||||||
|
|
||||||
@@ -30,13 +32,14 @@ public class AnnotationResultService {
|
|||||||
private final AnnotationResultMapper annotationResultMapper;
|
private final AnnotationResultMapper annotationResultMapper;
|
||||||
private final SourceResourceMapper sourceResourceMapper;
|
private final SourceResourceMapper sourceResourceMapper;
|
||||||
private final DataPermissionService dataPermissionService;
|
private final DataPermissionService dataPermissionService;
|
||||||
|
private final ObjectStorageService objectStorageService;
|
||||||
|
|
||||||
public PageResult<AnnotationResultResponse> pageResults(LoginUser currentUser, AnnotationResultPageQuery query) {
|
public PageResult<AnnotationResultResponse> pageResults(LoginUser currentUser, AnnotationResultPageQuery query) {
|
||||||
List<String> allowedRoles = dataPermissionService.getAllowedRoles(currentUser);
|
List<String> allowedRoles = dataPermissionService.getAllowedRoles(currentUser);
|
||||||
boolean shouldFilterByUserId = dataPermissionService.shouldFilterByUserId(currentUser);
|
boolean shouldFilterByUserId = dataPermissionService.shouldFilterByUserId(currentUser);
|
||||||
|
|
||||||
LambdaQueryWrapper<AnnotationResult> wrapper =
|
LambdaQueryWrapper<AnnotationResult> wrapper = new LambdaQueryWrapper<AnnotationResult>()
|
||||||
new LambdaQueryWrapper<AnnotationResult>().eq(AnnotationResult::getCompanyId, currentUser.companyId())
|
.eq(AnnotationResult::getCompanyId, currentUser.companyId())
|
||||||
.eq(query.taskId() != null, AnnotationResult::getTaskId, query.taskId())
|
.eq(query.taskId() != null, AnnotationResult::getTaskId, query.taskId())
|
||||||
.eq(query.resourceId() != null, AnnotationResult::getResourceId, query.resourceId())
|
.eq(query.resourceId() != null, AnnotationResult::getResourceId, query.resourceId())
|
||||||
.eq(query.requiresManualReview() != null, AnnotationResult::getRequiresManualReview,
|
.eq(query.requiresManualReview() != null, AnnotationResult::getRequiresManualReview,
|
||||||
@@ -54,11 +57,12 @@ public class AnnotationResultService {
|
|||||||
Page<AnnotationResult> resultPage = annotationResultMapper.selectPage(page, wrapper);
|
Page<AnnotationResult> resultPage = annotationResultMapper.selectPage(page, wrapper);
|
||||||
|
|
||||||
List<AnnotationResultResponse> records = resultPage.getRecords().stream().map(this::toResponse)
|
List<AnnotationResultResponse> records = resultPage.getRecords().stream().map(this::toResponse)
|
||||||
.filter(response -> query.runtimeStatus() == null || query.runtimeStatus().equals(response.runtimeStatus()))
|
.filter(response -> query.runtimeStatus() == null
|
||||||
|
|| query.runtimeStatus().equals(response.runtimeStatus()))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
return new PageResult<>(records, resultPage.getTotal(), (int)resultPage.getCurrent(),
|
return new PageResult<>(records, resultPage.getTotal(), (int) resultPage.getCurrent(),
|
||||||
(int)resultPage.getSize());
|
(int) resultPage.getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
public AnnotationResultResponse getResult(LoginUser currentUser, Long resultId) {
|
public AnnotationResultResponse getResult(LoginUser currentUser, Long resultId) {
|
||||||
@@ -71,6 +75,23 @@ public class AnnotationResultService {
|
|||||||
return toResponse(result);
|
return toResponse(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AnnotationResultResponse toResponse(AnnotationResult result) {
|
||||||
|
return new AnnotationResultResponse(result.getId(), result.getTaskId(), result.getResourceId(),
|
||||||
|
deriveStatus(result), result.getRequiresManualReview(), result.getIsDeleted(),
|
||||||
|
result.getQaContentStorageMode(), result.getReviewComment(), result.getReviewedAt(),
|
||||||
|
result.getCreatedAt());
|
||||||
|
}
|
||||||
|
|
||||||
|
private AnnotationResultStatus deriveStatus(AnnotationResult result) {
|
||||||
|
if (Boolean.TRUE.equals(result.getIsDeleted())) {
|
||||||
|
return AnnotationResultStatus.ARCHIVED;
|
||||||
|
}
|
||||||
|
if (Boolean.TRUE.equals(result.getRequiresManualReview())) {
|
||||||
|
return AnnotationResultStatus.MANUAL_REVIEW_PENDING;
|
||||||
|
}
|
||||||
|
return AnnotationResultStatus.AUTO_ARCHIVE_PENDING;
|
||||||
|
}
|
||||||
|
|
||||||
public AnnotationResultCompareResponse compareResult(LoginUser currentUser, Long resultId) {
|
public AnnotationResultCompareResponse compareResult(LoginUser currentUser, Long resultId) {
|
||||||
AnnotationResult result = annotationResultMapper.findActiveByIdAndCompanyId(resultId, currentUser.companyId());
|
AnnotationResult result = annotationResultMapper.findActiveByIdAndCompanyId(resultId, currentUser.companyId());
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
@@ -78,25 +99,62 @@ public class AnnotationResultService {
|
|||||||
currentUser.companyId(), currentUser.userId());
|
currentUser.companyId(), currentUser.userId());
|
||||||
throw new BusinessException(ResultCode.NOT_FOUND, "结果不存在");
|
throw new BusinessException(ResultCode.NOT_FOUND, "结果不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String qaContentJson = resolveQaContent(result);
|
||||||
|
|
||||||
SourceResource resource = sourceResourceMapper.selectById(result.getResourceId());
|
SourceResource resource = sourceResourceMapper.selectById(result.getResourceId());
|
||||||
return new AnnotationResultCompareResponse(result.getId(), result.getTaskId(), result.getResourceId(),
|
return new AnnotationResultCompareResponse(
|
||||||
result.getQaContentJson(), result.getDiffSummary(), result.getQaContentStorageMode(),
|
result.getId(),
|
||||||
result.getQaContentFilePath(), resource == null ? null : resource.getFilePath());
|
result.getTaskId(),
|
||||||
|
result.getResourceId(),
|
||||||
|
qaContentJson,
|
||||||
|
result.getDiffSummary(),
|
||||||
|
result.getQaContentStorageMode(),
|
||||||
|
result.getQaContentFilePath(),
|
||||||
|
resource == null ? null : resource.getFilePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
private AnnotationResultResponse toResponse(AnnotationResult result) {
|
private String resolveQaContent(AnnotationResult result) {
|
||||||
return new AnnotationResultResponse(result.getId(), result.getTaskId(), result.getResourceId(),
|
if (QaContentStorageMode.EXTERNAL.name().equals(result.getQaContentStorageMode())) {
|
||||||
deriveStatus(result), result.getRequiresManualReview(), result.getIsDeleted(),
|
if (result.getQaContentFilePath() == null || result.getQaContentFilePath().isBlank()) {
|
||||||
result.getQaContentStorageMode(), result.getReviewComment(), result.getReviewedAt(), result.getCreatedAt());
|
log.warn("External storage mode but file path is empty, resultId={}", result.getId());
|
||||||
|
return "{}";
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
String filePath = result.getQaContentFilePath();
|
||||||
|
String bucketName = extractBucketName(filePath);
|
||||||
|
String objectKey = extractObjectKey(filePath);
|
||||||
|
byte[] content = objectStorageService.download(bucketName, objectKey);
|
||||||
|
return new String(content, StandardCharsets.UTF_8);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Failed to download external qa content, resultId={}, filePath={}",
|
||||||
|
result.getId(), result.getQaContentFilePath(), e);
|
||||||
|
throw new BusinessException(ResultCode.ERROR, "下载问答内容失败");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return result.getQaContentJson() != null ? result.getQaContentJson() : "{}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String deriveStatus(AnnotationResult result) {
|
private String extractBucketName(String filePath) {
|
||||||
if (Boolean.TRUE.equals(result.getIsDeleted())) {
|
if (filePath.startsWith("/")) {
|
||||||
return RuntimeResultStatus.ARCHIVED.name();
|
filePath = filePath.substring(1);
|
||||||
}
|
}
|
||||||
if (Boolean.TRUE.equals(result.getRequiresManualReview())) {
|
int firstSlash = filePath.indexOf("/");
|
||||||
return RuntimeResultStatus.MANUAL_REVIEW_PENDING.name();
|
if (firstSlash > 0) {
|
||||||
|
return filePath.substring(0, firstSlash);
|
||||||
}
|
}
|
||||||
return RuntimeResultStatus.AUTO_ARCHIVE_PENDING.name();
|
throw new BusinessException(ResultCode.BAD_REQUEST, "无效的文件路径格式");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String extractObjectKey(String filePath) {
|
||||||
|
if (filePath.startsWith("/")) {
|
||||||
|
filePath = filePath.substring(1);
|
||||||
|
}
|
||||||
|
int firstSlash = filePath.indexOf("/");
|
||||||
|
if (firstSlash > 0 && firstSlash < filePath.length() - 1) {
|
||||||
|
return filePath.substring(firstSlash + 1);
|
||||||
|
}
|
||||||
|
throw new BusinessException(ResultCode.BAD_REQUEST, "无效的文件路径格式");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,4 +5,6 @@ public interface ObjectStorageService {
|
|||||||
String upload(String bucketName, String objectKey, byte[] content, String contentType);
|
String upload(String bucketName, String objectKey, byte[] content, String contentType);
|
||||||
|
|
||||||
void delete(String bucketName, String objectKey);
|
void delete(String bucketName, String objectKey);
|
||||||
|
|
||||||
|
byte[] download(String bucketName, String objectKey);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ import com.labelsys.backend.common.exception.BusinessException;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import software.amazon.awssdk.core.sync.RequestBody;
|
import software.amazon.awssdk.core.sync.RequestBody;
|
||||||
|
import software.amazon.awssdk.core.sync.ResponseTransformer;
|
||||||
import software.amazon.awssdk.services.s3.S3Client;
|
import software.amazon.awssdk.services.s3.S3Client;
|
||||||
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
|
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
|
||||||
|
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
|
||||||
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
|
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -42,4 +44,17 @@ public class RustfsObjectStorageService implements ObjectStorageService {
|
|||||||
throw new BusinessException(ResultCode.ERROR, "对象存储删除失败");
|
throw new BusinessException(ResultCode.ERROR, "对象存储删除失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] download(String bucketName, String objectKey) {
|
||||||
|
try {
|
||||||
|
GetObjectRequest request = GetObjectRequest.builder()
|
||||||
|
.bucket(bucketName)
|
||||||
|
.key(objectKey)
|
||||||
|
.build();
|
||||||
|
return s3Client.getObject(request, ResponseTransformer.toBytes()).asByteArray();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new BusinessException(ResultCode.ERROR, "对象存储下载失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user