后台异常处理优化

This commit is contained in:
wh
2026-05-08 16:07:12 +08:00
parent 83a412d3fd
commit 7fbe76559c
12 changed files with 1135 additions and 736 deletions

View File

@@ -43,145 +43,180 @@ public class AnnotationResultService {
private final ObjectMapper objectMapper;
public PageResult<AnnotationResultResponse> pageResults(LoginUser currentUser, AnnotationResultPageQuery query) {
List<String> allowedRoles = dataPermissionService.getAllowedRoles(currentUser);
boolean shouldFilterByUserId = dataPermissionService.shouldFilterByUserId(currentUser);
try {
List<String> allowedRoles = dataPermissionService.getAllowedRoles(currentUser);
boolean shouldFilterByUserId = dataPermissionService.shouldFilterByUserId(currentUser);
var wrapper = new LambdaQueryWrapper<AnnotationResult>()
.eq(AnnotationResult::getIsDeleted, Boolean.FALSE)
.eq(AnnotationResult::getCompanyId, currentUser.companyId())
.eq(query.taskId() != null, AnnotationResult::getTaskId, query.taskId())
.eq(query.resourceId() != null, AnnotationResult::getResourceId, query.resourceId())
.eq(query.requiresManualReview() != null, AnnotationResult::getRequiresManualReview,
query.requiresManualReview())
.orderByDesc(AnnotationResult::getCreatedAt);
var wrapper = new LambdaQueryWrapper<AnnotationResult>()
.eq(AnnotationResult::getIsDeleted, Boolean.FALSE)
.eq(AnnotationResult::getCompanyId, currentUser.companyId())
.eq(query.taskId() != null, AnnotationResult::getTaskId, query.taskId())
.eq(query.resourceId() != null, AnnotationResult::getResourceId, query.resourceId())
.eq(query.requiresManualReview() != null, AnnotationResult::getRequiresManualReview,
query.requiresManualReview())
.orderByDesc(AnnotationResult::getCreatedAt);
if (shouldFilterByUserId) {
wrapper.eq(AnnotationResult::getCreatorId, currentUser.userId());
} else if (!allowedRoles.isEmpty()) {
wrapper.in(AnnotationResult::getCreatorRole, allowedRoles);
if (shouldFilterByUserId) {
wrapper.eq(AnnotationResult::getCreatorId, currentUser.userId());
} else if (!allowedRoles.isEmpty()) {
wrapper.in(AnnotationResult::getCreatorRole, allowedRoles);
}
var page = new Page<AnnotationResult>(query.pageNo(), query.pageSize());
var resultPage = annotationResultMapper.selectPage(page, wrapper);
var records = resultPage.getRecords().stream()
.map(this::toResponse)
.filter(response -> query.runtimeStatus() == null
|| query.runtimeStatus().equals(response.runtimeStatus()))
.toList();
return new PageResult<>(records, resultPage.getTotal(), (int) resultPage.getCurrent(),
(int) resultPage.getSize());
} catch (Exception e) {
log.error("pageResults failed, companyId={}, userId={}, error={}",
currentUser.companyId(), currentUser.userId(), e.getMessage(), e);
throw e;
}
var page = new Page<AnnotationResult>(query.pageNo(), query.pageSize());
var resultPage = annotationResultMapper.selectPage(page, wrapper);
var records = resultPage.getRecords().stream()
.map(this::toResponse)
.filter(response -> query.runtimeStatus() == null
|| query.runtimeStatus().equals(response.runtimeStatus()))
.toList();
return new PageResult<>(records, resultPage.getTotal(), (int) resultPage.getCurrent(),
(int) resultPage.getSize());
}
public AnnotationResultResponse getResult(LoginUser currentUser, Long resultId) {
AnnotationResult result = annotationResultMapper.findActiveByIdAndCompanyId(resultId, currentUser.companyId());
if (result == null) {
log.warn("Result not found or cross-tenant access attempt: resultId={}, companyId={}, userId={}", resultId,
currentUser.companyId(), currentUser.userId());
throw new BusinessException(ResultCode.NOT_FOUND, "结果不存在");
try {
AnnotationResult result = annotationResultMapper.findActiveByIdAndCompanyId(resultId,
currentUser.companyId());
if (result == null) {
log.warn("Result not found or cross-tenant access attempt: resultId={}, companyId={}, userId={}",
resultId,
currentUser.companyId(), currentUser.userId());
throw new BusinessException(ResultCode.NOT_FOUND, "结果不存在");
}
//assertResultPermission(currentUser, result);
return toResponse(result);
} catch (BusinessException e) {
throw e;
} catch (Exception e) {
log.error("getResult failed, companyId={}, userId={}, resultId={}, error={}",
currentUser.companyId(), currentUser.userId(), resultId, e.getMessage(), e);
throw e;
}
//assertResultPermission(currentUser, result);
return toResponse(result);
}
public AnnotationResultCompareResponse compareResult(LoginUser currentUser, Long resultId) {
AnnotationResult result = annotationResultMapper.findActiveByIdAndCompanyId(resultId, currentUser.companyId());
if (result == null) {
log.warn("Result not found or cross-tenant access attempt: resultId={}, companyId={}, userId={}", resultId,
currentUser.companyId(), currentUser.userId());
throw new BusinessException(ResultCode.NOT_FOUND, "结果不存在");
try {
AnnotationResult result = annotationResultMapper.findActiveByIdAndCompanyId(resultId,
currentUser.companyId());
if (result == null) {
log.warn("Result not found or cross-tenant access attempt: resultId={}, companyId={}, userId={}",
resultId,
currentUser.companyId(), currentUser.userId());
throw new BusinessException(ResultCode.NOT_FOUND, "结果不存在");
}
//assertResultPermission(currentUser, result);
QaContent qaContent = loadQaContent(result);
DiffContent diffContent = Boolean.TRUE.equals(result.getRequiresManualReview()) ?
loadDiffSummary(result) : null;
SourceResource resource = sourceResourceMapper.selectById(result.getResourceId());
// 转换 QA 记录
List<AnnotationResultCompareResponse.QaRecord> qaRecords = qaContent.records().stream()
.map(qa -> new AnnotationResultCompareResponse.QaRecord(
qa.id(),
qa.question(),
qa.answer(),
qa.requiresReview()
)).toList();
// 转换差异记录
List<AnnotationResultCompareResponse.DiffRecord> diffRecords = diffContent != null ?
diffContent.records().stream()
.map(diff -> new AnnotationResultCompareResponse.DiffRecord(
diff.qaId(),
diff.question(),
diff.extractAnswer(),
diff.verifyAnswer(),
diff.diffReason(),
diff.mergedAnswer()
)).toList() : List.of();
return new AnnotationResultCompareResponse(
result.getId(),
result.getTaskId(),
result.getResourceId(),
qaRecords,
diffRecords,
resource == null ? null : resource.getFilePath()
);
} catch (BusinessException e) {
throw e;
} catch (Exception e) {
log.error("compareResult failed, companyId={}, userId={}, resultId={}, error={}",
currentUser.companyId(), currentUser.userId(), resultId, e.getMessage(), e);
throw e;
}
//assertResultPermission(currentUser, result);
QaContent qaContent = loadQaContent(result);
DiffContent diffContent = Boolean.TRUE.equals(result.getRequiresManualReview()) ?
loadDiffSummary(result) : null;
SourceResource resource = sourceResourceMapper.selectById(result.getResourceId());
// 转换 QA 记录
List<AnnotationResultCompareResponse.QaRecord> qaRecords = qaContent.records().stream()
.map(qa -> new AnnotationResultCompareResponse.QaRecord(
qa.id(),
qa.question(),
qa.answer(),
qa.requiresReview()
)).toList();
// 转换差异记录
List<AnnotationResultCompareResponse.DiffRecord> diffRecords = diffContent != null ?
diffContent.records().stream()
.map(diff -> new AnnotationResultCompareResponse.DiffRecord(
diff.qaId(),
diff.question(),
diff.extractAnswer(),
diff.verifyAnswer(),
diff.diffReason(),
diff.mergedAnswer()
)).toList() : List.of();
return new AnnotationResultCompareResponse(
result.getId(),
result.getTaskId(),
result.getResourceId(),
qaRecords,
diffRecords,
resource == null ? null : resource.getFilePath()
);
}
@Transactional
public void mergeReviewResult(LoginUser currentUser, Long resultId, MergeReviewResultRequest request) {
AnnotationResult result = annotationResultMapper.findActiveByIdAndCompanyId(resultId, currentUser.companyId());
if (result == null) {
throw new BusinessException(ResultCode.NOT_FOUND, "结果不存在");
try {
AnnotationResult result = annotationResultMapper.findActiveByIdAndCompanyId(resultId,
currentUser.companyId());
if (result == null) {
throw new BusinessException(ResultCode.NOT_FOUND, "结果不存在");
}
//assertResultPermission(currentUser, result);
// 读取当前 qa.json
QaContent qaContent = loadQaContent(result);
// 更新 qa.json 的 answer 字段
List<QaContent.QaRecord> updatedQaRecords = qaContent.records().stream()
.map(record -> {
String mergedAnswer = request.mergedAnswers().get(record.id());
if (mergedAnswer != null) {
return new QaContent.QaRecord(
record.id(),
record.question(),
mergedAnswer,
false
);
}
return record;
})
.toList();
QaContent updatedQaContent = new QaContent(
qaContent.taskId(),
qaContent.resourceId(),
updatedQaRecords,
new QaContent.Metadata(
qaContent.metadata().createdAt(),
LocalDateTime.now().toString()
)
);
saveQaContent(result, updatedQaContent);
// 更新数据库记录
result.setIsDeleted(Boolean.TRUE);
result.setReviewerId(currentUser.userId());
result.setReviewComment(request.reviewComment());
result.setReviewedAt(LocalDateTime.now());
result.setRequiresManualReview(false);
annotationResultMapper.updateById(result);
// 归档到历史表(人工审核后归档)
archiveToHistory(result, currentUser, "审核通过后归档", false);
log.info("merged review result, companyId={}, userId={}, resultId={}",
currentUser.companyId(), currentUser.userId(), resultId);
} catch (BusinessException e) {
throw e;
} catch (Exception e) {
log.error("mergeReviewResult failed, companyId={}, userId={}, resultId={}, error={}",
currentUser.companyId(), currentUser.userId(), resultId, e.getMessage(), e);
throw e;
}
//assertResultPermission(currentUser, result);
// 读取当前 qa.json
QaContent qaContent = loadQaContent(result);
// 更新 qa.json 的 answer 字段
List<QaContent.QaRecord> updatedQaRecords = qaContent.records().stream()
.map(record -> {
String mergedAnswer = request.mergedAnswers().get(record.id());
if (mergedAnswer != null) {
return new QaContent.QaRecord(
record.id(),
record.question(),
mergedAnswer,
false
);
}
return record;
})
.toList();
QaContent updatedQaContent = new QaContent(
qaContent.taskId(),
qaContent.resourceId(),
updatedQaRecords,
new QaContent.Metadata(
qaContent.metadata().createdAt(),
LocalDateTime.now().toString()
)
);
saveQaContent(result, updatedQaContent);
// 更新数据库记录
result.setIsDeleted(Boolean.TRUE);
result.setReviewerId(currentUser.userId());
result.setReviewComment(request.reviewComment());
result.setReviewedAt(LocalDateTime.now());
result.setRequiresManualReview(false);
annotationResultMapper.updateById(result);
// 归档到历史表(人工审核后归档)
archiveToHistory(result, currentUser, "审核通过后归档", false);
log.info("merged review result, companyId={}, userId={}, resultId={}",
currentUser.companyId(), currentUser.userId(), resultId);
}
private AnnotationResultResponse toResponse(AnnotationResult result) {
@@ -267,12 +302,14 @@ public class AnnotationResultService {
/**
* 归档到历史表
* @param result 标注结果
* @param currentUser 当前用户
*
* @param result 标注结果
* @param currentUser 当前用户
* @param archiveReason 归档原因
* @param isAutoArchive 是否自动归档true=自动归档false=人工审核后归档)
*/
private void archiveToHistory(AnnotationResult result, LoginUser currentUser, String archiveReason, boolean isAutoArchive) {
private void archiveToHistory(AnnotationResult result, LoginUser currentUser, String archiveReason,
boolean isAutoArchive) {
try {
// 读取 qa.json 内容用于归档
QaContent qaContent = loadQaContent(result);
@@ -312,7 +349,7 @@ public class AnnotationResultService {
annotationResultHistoryMapper.insert(historyBuilder.build());
log.info("archived result to history, resultId={}, historyId={}, isAutoArchive={}",
log.info("archived result to history, resultId={}, historyId={}, isAutoArchive={}",
result.getId(), historyBuilder.build().getId(), isAutoArchive);
} catch (Exception e) {
log.error("Failed to archive result to history, resultId={}", result.getId(), e);