Merge branch 'dev54'
# Conflicts: # src/main/resources/sql/schema.sql
This commit is contained in:
@@ -3,8 +3,8 @@ package com.labelsys.backend.controller;
|
||||
import com.labelsys.backend.context.UserContext;
|
||||
import com.labelsys.backend.dto.common.PageResult;
|
||||
import com.labelsys.backend.dto.request.AnnotationResultHistoryPageQuery;
|
||||
import com.labelsys.backend.dto.response.AnnotationResultHistoryDetailResponse;
|
||||
import com.labelsys.backend.dto.response.AnnotationResultHistoryResponse;
|
||||
import com.labelsys.backend.dto.response.FileContentResponse;
|
||||
import com.labelsys.backend.service.AnnotationResultArchiveService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@@ -34,17 +34,18 @@ public class AnnotationResultArchiveController {
|
||||
|
||||
@Operation(summary = "查询归档历史详情")
|
||||
@GetMapping("/{id}")
|
||||
public ResponseEntity<AnnotationResultHistoryResponse> getHistory(
|
||||
public ResponseEntity<AnnotationResultHistoryDetailResponse> getHistory(
|
||||
@Parameter(description = "历史记录ID", example = "901")
|
||||
@PathVariable Long id) {
|
||||
return ResponseEntity.ok(annotationResultArchiveService.getHistory(UserContext.requireUser(), id));
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "加载归档文件内容")
|
||||
@GetMapping("/{id}/content")
|
||||
public ResponseEntity<FileContentResponse> loadFileContent(
|
||||
@Parameter(description = "历史记录ID", example = "901")
|
||||
@PathVariable Long id) {
|
||||
return ResponseEntity.ok(annotationResultArchiveService.loadFileContent(UserContext.requireUser(), id));
|
||||
}
|
||||
}
|
||||
// @Operation(summary = "加载归档文件内容")
|
||||
// @GetMapping("/{id}/content")
|
||||
// public ResponseEntity<FileContentResponse> loadFileContent(
|
||||
// @Parameter(description = "历史记录ID", example = "901")
|
||||
// @PathVariable Long id) {
|
||||
// return ResponseEntity.ok(annotationResultArchiveService.loadFileContent(UserContext.requireUser(), id));
|
||||
// }
|
||||
//}
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.labelsys.backend.dto.request;
|
||||
|
||||
import com.labelsys.backend.enums.IndustryType;
|
||||
import com.labelsys.backend.enums.TaskType;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
@@ -12,7 +11,6 @@ import java.util.List;
|
||||
@Schema(description = "创建标注任务请求")
|
||||
public record CreateAnnotationTaskRequest(
|
||||
@Schema(description = "任务名称", example = "运输文档问答抽取任务") @NotBlank(message = "任务名称不能为空") String taskName,
|
||||
@Schema(description = "行业类型", defaultValue = "TRANSPORT", example = "TRANSPORT") @NotNull(message = "行业类型不能为空") IndustryType industryType,
|
||||
@Schema(description = "任务类型", defaultValue = "EXTRACT_QA", example = "EXTRACT_QA") @NotNull(message = "任务类型不能为空") TaskType taskType,
|
||||
@Schema(description = "资源ID列表", example = "[191000000000000101,191000000000000102]") @NotEmpty(message = "资源列表不能为空") List<Long> resourceIds) {
|
||||
}
|
||||
@@ -9,7 +9,7 @@ public record MergeReviewResultRequest(
|
||||
@Schema(description = "合并后的答案映射,key为qa记录ID,value为合并后的答案")
|
||||
Map<String, String> mergedAnswers,
|
||||
|
||||
@Schema(description = "审核备注")
|
||||
String reviewComment
|
||||
@Schema(description = "每条QA记录的审核评论映射,key为qa记录ID,value为审核评论")
|
||||
Map<String, String> reviewComments
|
||||
) {
|
||||
}
|
||||
@@ -2,14 +2,12 @@ package com.labelsys.backend.dto.request;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.labelsys.backend.enums.IndustryType;
|
||||
import com.labelsys.backend.enums.TaskType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(description = "更新标注任务请求")
|
||||
public record UpdateAnnotationTaskRequest(
|
||||
@Schema(description = "行业类型", example = "TRANSPORT") IndustryType industryType,
|
||||
@Schema(description = "任务类型", example = "EXTRACT_QA") TaskType taskType,
|
||||
@Schema(description = "资源ID列表", example = "[191000000000000101,191000000000000102]") List<Long> resourceIds) {
|
||||
}
|
||||
@@ -18,10 +18,25 @@ public record AnnotationResultCompareResponse(
|
||||
@Schema(description = "问答记录")
|
||||
public record QaRecord(
|
||||
@Schema(description = "记录ID", example = "qa_001") String id,
|
||||
@Schema(description = "批次ID", example = "50") Long batchId,
|
||||
@Schema(description = "问题", example = "运输时效是多久?") String question,
|
||||
@Schema(description = "答案", example = "3天") String answer,
|
||||
@Schema(description = "是否需要审核", example = "true") Boolean requiresReview
|
||||
) {}
|
||||
@Schema(description = "是否需要审核", example = "true") Boolean requiresReview,
|
||||
@Schema(description = "源片段信息") SourceSegments sourceSegments,
|
||||
@Schema(description = "问题分类") String questionCategory,
|
||||
@Schema(description = "评分") Scores scores,
|
||||
@Schema(description = "审核评论") String reviewComment
|
||||
) {
|
||||
}
|
||||
|
||||
@Schema(description = "源片段信息")
|
||||
public record SourceSegments(
|
||||
@Schema(description = "片段内容") String segment,
|
||||
@Schema(description = "块索引", example = "0") Integer chunkIndex,
|
||||
@Schema(description = "块标题") String chunkTitle,
|
||||
@Schema(description = "块内容") String chunkContent
|
||||
) {
|
||||
}
|
||||
|
||||
@Schema(description = "差异记录")
|
||||
public record DiffRecord(
|
||||
@@ -30,6 +45,19 @@ public record AnnotationResultCompareResponse(
|
||||
@Schema(description = "提取模型答案", example = "3天") String extractAnswer,
|
||||
@Schema(description = "校验模型答案", example = "72小时") String verifyAnswer,
|
||||
@Schema(description = "差异原因", example = "时间单位不一致") String diffReason,
|
||||
@Schema(description = "合并后的最终答案", example = "72小时(3天)") String mergedAnswer
|
||||
) {}
|
||||
@Schema(description = "合并后的最终答案", example = "72小时(3天)") String mergedAnswer,
|
||||
@Schema(description = "问题分类") String questionCategory,
|
||||
@Schema(description = "评分") Scores scores
|
||||
) {
|
||||
}
|
||||
|
||||
@Schema(description = "评分结构")
|
||||
public record Scores(
|
||||
@Schema(description = "相似度", example = "0.7") Double similarity,
|
||||
@Schema(description = "置信度1", example = "0.9") Double confidence1,
|
||||
@Schema(description = "置信度2", example = "0.85") Double confidence2,
|
||||
@Schema(description = "幻觉检测", example = "0.9") Double hallucination,
|
||||
@Schema(description = "信任度", example = "0.64") Double trust
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -25,8 +25,6 @@ public record AnnotationResultDetailResponse(
|
||||
@Schema(description = "问答内容") QaContentDto qaContent,
|
||||
@Schema(description = "差异摘要(需要审核时有值)") DiffContentDto diffSummary,
|
||||
|
||||
@Schema(description = "审核备注", example = "需统一时间字段口径。") String reviewComment,
|
||||
@Schema(description = "审核时间", example = "2026-04-27T11:00:00") LocalDateTime reviewedAt,
|
||||
@Schema(description = "创建时间", example = "2026-04-27T10:40:00") LocalDateTime createdAt
|
||||
) {
|
||||
@Schema(description = "问答内容结构")
|
||||
@@ -38,9 +36,23 @@ public record AnnotationResultDetailResponse(
|
||||
@Schema(description = "问答记录")
|
||||
public record QaRecordDto(
|
||||
@Schema(description = "记录ID", example = "q1") String id,
|
||||
@Schema(description = "批次ID", example = "50") Long batchId,
|
||||
@Schema(description = "问题", example = "产品重量是多少?") String question,
|
||||
@Schema(description = "答案", example = "5kg") String answer,
|
||||
@Schema(description = "是否需要审核", example = "false") Boolean requiresReview
|
||||
@Schema(description = "是否需要审核", example = "false") Boolean requiresReview,
|
||||
@Schema(description = "源片段信息") SourceSegmentsDto sourceSegments,
|
||||
@Schema(description = "问题分类") String questionCategory,
|
||||
@Schema(description = "评分") ScoresDto scores,
|
||||
@Schema(description = "审核评论") String reviewComment
|
||||
) {
|
||||
}
|
||||
|
||||
@Schema(description = "源片段信息")
|
||||
public record SourceSegmentsDto(
|
||||
@Schema(description = "片段内容") String segment,
|
||||
@Schema(description = "块索引", example = "0") Integer chunkIndex,
|
||||
@Schema(description = "块标题") String chunkTitle,
|
||||
@Schema(description = "块内容") String chunkContent
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -57,7 +69,19 @@ public record AnnotationResultDetailResponse(
|
||||
@Schema(description = "抽取答案", example = "2年") String extractAnswer,
|
||||
@Schema(description = "验证答案", example = "3年") String verifyAnswer,
|
||||
@Schema(description = "差异原因", example = "抽取与验证结果不一致") String diffReason,
|
||||
@Schema(description = "合并后答案") String mergedAnswer
|
||||
@Schema(description = "合并后答案") String mergedAnswer,
|
||||
@Schema(description = "问题分类") String questionCategory,
|
||||
@Schema(description = "评分") ScoresDto scores
|
||||
) {
|
||||
}
|
||||
|
||||
@Schema(description = "评分结构")
|
||||
public record ScoresDto(
|
||||
@Schema(description = "相似度", example = "0.7") Double similarity,
|
||||
@Schema(description = "置信度1", example = "0.9") Double confidence1,
|
||||
@Schema(description = "置信度2", example = "0.85") Double confidence2,
|
||||
@Schema(description = "幻觉检测", example = "0.9") Double hallucination,
|
||||
@Schema(description = "信任度", example = "0.64") Double trust
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.labelsys.backend.dto.response;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "归档历史详情响应")
|
||||
public record AnnotationResultHistoryDetailResponse(
|
||||
@Schema(description = "历史记录ID", example = "901") Long id,
|
||||
@Schema(description = "任务ID", example = "191000000000000301") Long taskId,
|
||||
@Schema(description = "任务名称", example = "产品说明书标注") String taskName,
|
||||
@Schema(description = "资源ID", example = "191000000000000101") Long resourceId,
|
||||
@Schema(description = "资源名称", example = "产品A说明书.pdf") String resourceName,
|
||||
|
||||
@Schema(description = "问答内容文件路径", example = "annotation-results/2/qa/802.json") String qaContentFilePath,
|
||||
@Schema(description = "问答内容") QaContentDto qaContent,
|
||||
@Schema(description = "归档原因", example = "审核通过后归档") String archiveReason,
|
||||
@Schema(description = "归档操作人ID", example = "5") Long archivedBy,
|
||||
@Schema(description = "归档时间", example = "2026-05-06T10:30:00") LocalDateTime archivedAt,
|
||||
@Schema(description = "创建时间", example = "2026-05-06T10:30:00") LocalDateTime createdAt,
|
||||
@Schema(description = "审核人ID,自动归档时为null", example = "5") Long reviewerId,
|
||||
@Schema(description = "审核人姓名,自动归档时为auto", example = "张三") String reviewerName
|
||||
) {
|
||||
@Schema(description = "问答内容结构")
|
||||
public record QaContentDto(
|
||||
@Schema(description = "问答记录列表") List<QaRecordDto> records
|
||||
) {
|
||||
}
|
||||
|
||||
@Schema(description = "问答记录")
|
||||
public record QaRecordDto(
|
||||
@Schema(description = "记录ID", example = "q1") String id,
|
||||
@Schema(description = "批次ID", example = "50") Long batchId,
|
||||
@Schema(description = "问题", example = "产品重量是多少?") String question,
|
||||
@Schema(description = "答案", example = "5kg") String answer,
|
||||
@Schema(description = "是否需要审核", example = "false") Boolean requiresReview,
|
||||
@Schema(description = "源片段信息") SourceSegmentsDto sourceSegments,
|
||||
@Schema(description = "问题分类") String questionCategory,
|
||||
@Schema(description = "评分") ScoresDto scores,
|
||||
@Schema(description = "审核评论") String reviewComment
|
||||
) {
|
||||
}
|
||||
|
||||
@Schema(description = "源片段信息")
|
||||
public record SourceSegmentsDto(
|
||||
@Schema(description = "片段内容") String segment,
|
||||
@Schema(description = "块索引", example = "0") Integer chunkIndex,
|
||||
@Schema(description = "块标题") String chunkTitle,
|
||||
@Schema(description = "块内容") String chunkContent
|
||||
) {
|
||||
}
|
||||
|
||||
@Schema(description = "评分结构")
|
||||
public record ScoresDto(
|
||||
@Schema(description = "相似度", example = "0.7") Double similarity,
|
||||
@Schema(description = "置信度1", example = "0.9") Double confidence1,
|
||||
@Schema(description = "置信度2", example = "0.85") Double confidence2,
|
||||
@Schema(description = "幻觉检测", example = "0.9") Double hallucination,
|
||||
@Schema(description = "信任度", example = "0.64") Double trust
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,6 @@ public record AnnotationResultHistoryResponse(
|
||||
@Schema(description = "归档时间", example = "2026-05-06T10:30:00") LocalDateTime archivedAt,
|
||||
@Schema(description = "创建时间", example = "2026-05-06T10:30:00") LocalDateTime createdAt,
|
||||
@Schema(description = "审核人ID,自动归档时为null", example = "5") Long reviewerId,
|
||||
@Schema(description = "审核人姓名,自动归档时为auto", example = "张三") String reviewerName,
|
||||
@Schema(description = "审核意见,自动归档时为auto", example = "内容符合要求") String reviewerComment
|
||||
@Schema(description = "审核人姓名,自动归档时为auto", example = "张三") String reviewerName
|
||||
) {
|
||||
}
|
||||
@@ -17,8 +17,6 @@ public record AnnotationResultResponse(
|
||||
@Schema(description = "是否已删除", example = "false") Boolean isDeleted,
|
||||
@Schema(description = "问答内容文件路径", example = "annotation-results/2/qa/801.json") String qaContentFilePath,
|
||||
@Schema(description = "差异摘要文件路径", example = "annotation-results/2/diff/801.json") String diffSummaryFilePath,
|
||||
@Schema(description = "审核备注", example = "需统一时间字段口径。") String reviewComment,
|
||||
@Schema(description = "审核时间", example = "2026-04-27T11:00:00") LocalDateTime reviewedAt,
|
||||
@Schema(description = "创建时间", example = "2026-04-27T10:40:00") LocalDateTime createdAt
|
||||
) {
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.labelsys.backend.dto.response;
|
||||
|
||||
import com.labelsys.backend.enums.IndustryType;
|
||||
import com.labelsys.backend.enums.TaskType;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@@ -11,7 +10,6 @@ import java.util.List;
|
||||
public record AnnotationTaskResponse(
|
||||
@Schema(description = "任务ID", example = "191000000000000301") Long id,
|
||||
@Schema(description = "任务名称", example = "运输文档问答抽取任务") String taskName,
|
||||
@Schema(description = "行业类型", example = "transport") IndustryType industryType,
|
||||
@Schema(description = "任务类型", example = "EXTRACT_QA") TaskType taskType,
|
||||
@Schema(description = "任务状态", example = "PENDING") String taskStatus,
|
||||
@Schema(description = "资源ID列表", example = "[191000000000000101,191000000000000102]") List<Long> resourceIds,
|
||||
|
||||
@@ -56,12 +56,6 @@ public class AnnotationResult {
|
||||
@TableField("reviewer_id")
|
||||
private Long reviewerId;
|
||||
|
||||
@TableField("review_comment")
|
||||
private String reviewComment;
|
||||
|
||||
@TableField("reviewed_at")
|
||||
private LocalDateTime reviewedAt;
|
||||
|
||||
@TableField("created_at")
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
|
||||
@@ -37,5 +37,4 @@ public class AnnotationResultHistory {
|
||||
// 新增审核人相关字段
|
||||
private Long reviewerId;
|
||||
private String reviewerName;
|
||||
private String reviewerComment;
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.labelsys.backend.enums.IndustryType;
|
||||
import com.labelsys.backend.enums.TaskType;
|
||||
import com.labelsys.backend.enums.UserRole;
|
||||
import lombok.AllArgsConstructor;
|
||||
@@ -26,7 +25,6 @@ public class AnnotationTask {
|
||||
private Long creatorId;
|
||||
private UserRole creatorRole;
|
||||
private String taskName;
|
||||
private IndustryType industryType;
|
||||
private TaskType taskType;
|
||||
private String taskStatus;
|
||||
@TableLogic(value = "false", delval = "true")
|
||||
|
||||
@@ -11,7 +11,9 @@ public interface AnnotationResultMapper extends BaseMapper<AnnotationResult> {
|
||||
|
||||
int markArchived(@Param("id") Long id,
|
||||
@Param("companyId") Long companyId,
|
||||
@Param("reviewerId") Long reviewerId,
|
||||
@Param("reviewComment") String reviewComment,
|
||||
@Param("reviewedAt") LocalDateTime reviewedAt);
|
||||
}
|
||||
@Param("reviewerId") Long reviewerId);
|
||||
|
||||
int markReviewedAndArchived(@Param("id") Long id,
|
||||
@Param("companyId") Long companyId,
|
||||
@Param("reviewerId") Long reviewerId);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.labelsys.backend.common.exception.BusinessException;
|
||||
import com.labelsys.backend.context.LoginUser;
|
||||
import com.labelsys.backend.dto.common.PageResult;
|
||||
import com.labelsys.backend.dto.request.AnnotationResultHistoryPageQuery;
|
||||
import com.labelsys.backend.dto.response.AnnotationResultHistoryDetailResponse;
|
||||
import com.labelsys.backend.dto.response.AnnotationResultHistoryResponse;
|
||||
import com.labelsys.backend.dto.response.FileContentResponse;
|
||||
import com.labelsys.backend.dto.response.MergeReviewResultResponse;
|
||||
@@ -29,6 +30,8 @@ import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static org.springframework.util.StringUtils.hasText;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@@ -66,6 +69,7 @@ public class AnnotationResultArchiveService {
|
||||
var page = new Page<AnnotationResultHistory>(query.pageNo(), query.pageSize());
|
||||
var resultPage = annotationResultHistoryMapper.selectPage(page, wrapper);
|
||||
|
||||
// 分页查询不加载 qa 内容
|
||||
var records = resultPage.getRecords().stream()
|
||||
.map(this::toResponse)
|
||||
.toList();
|
||||
@@ -79,14 +83,17 @@ public class AnnotationResultArchiveService {
|
||||
}
|
||||
}
|
||||
|
||||
public AnnotationResultHistoryResponse getHistory(LoginUser currentUser, Long historyId) {
|
||||
public AnnotationResultHistoryDetailResponse getHistory(LoginUser currentUser, Long historyId) {
|
||||
try {
|
||||
AnnotationResultHistory history = annotationResultHistoryMapper.selectById(historyId);
|
||||
if (history == null || !history.getCompanyId().equals(currentUser.companyId())) {
|
||||
throw new BusinessException(ResultCode.NOT_FOUND, "历史记录不存在");
|
||||
}
|
||||
assertHistoryPermission(currentUser, history);
|
||||
return toResponse(history);
|
||||
|
||||
// 详情查询加载 QA 内容
|
||||
QaContent qaContent = loadQaContent(history.getQaContentFilePath());
|
||||
return toDetailResponse(history, qaContent);
|
||||
} catch (Exception e) {
|
||||
log.error("getHistory failed, companyId={}, userId={}, historyId={}, error={}",
|
||||
currentUser.companyId(), currentUser.userId(), historyId, e.getMessage(), e);
|
||||
@@ -104,19 +111,66 @@ public class AnnotationResultArchiveService {
|
||||
private AnnotationResultHistoryResponse toResponse(AnnotationResultHistory history) {
|
||||
return new AnnotationResultHistoryResponse(
|
||||
history.getId(),
|
||||
// history.getSourceResultId(),
|
||||
history.getTaskId(),
|
||||
history.getTaskName(), // 新增
|
||||
history.getTaskName(),
|
||||
history.getResourceId(),
|
||||
history.getResourceName(), // 新增
|
||||
history.getResourceName(),
|
||||
history.getQaContentFilePath(),
|
||||
history.getArchiveReason(),
|
||||
history.getArchivedBy(),
|
||||
history.getArchivedAt(),
|
||||
history.getCreatedAt(),
|
||||
history.getReviewerId(),
|
||||
history.getReviewerName(),
|
||||
history.getReviewerComment()
|
||||
history.getReviewerName()
|
||||
);
|
||||
}
|
||||
|
||||
private AnnotationResultHistoryDetailResponse toDetailResponse(AnnotationResultHistory history,
|
||||
QaContent qaContent) {
|
||||
// 转换 QA 内容
|
||||
AnnotationResultHistoryDetailResponse.QaContentDto qaContentDto = null;
|
||||
if (qaContent != null && qaContent.records() != null) {
|
||||
qaContentDto = new AnnotationResultHistoryDetailResponse.QaContentDto(
|
||||
qaContent.records().stream()
|
||||
.map(r -> new AnnotationResultHistoryDetailResponse.QaRecordDto(
|
||||
r.id(),
|
||||
r.batchId(),
|
||||
r.question(),
|
||||
r.answer(),
|
||||
r.requiresReview(),
|
||||
r.sourceSegments() != null ?
|
||||
new AnnotationResultHistoryDetailResponse.SourceSegmentsDto(
|
||||
r.sourceSegments().segment(),
|
||||
r.sourceSegments().chunkIndex(),
|
||||
r.sourceSegments().chunkTitle(),
|
||||
r.sourceSegments().chunkContent()) :
|
||||
null,
|
||||
r.questionCategory(),
|
||||
r.scores() != null ? new AnnotationResultHistoryDetailResponse.ScoresDto(
|
||||
r.scores().similarity(),
|
||||
r.scores().confidence1(),
|
||||
r.scores().confidence2(),
|
||||
r.scores().hallucination(),
|
||||
r.scores().trust()) : null,
|
||||
r.reviewComment()))
|
||||
.toList()
|
||||
);
|
||||
}
|
||||
|
||||
return new AnnotationResultHistoryDetailResponse(
|
||||
history.getId(),
|
||||
history.getTaskId(),
|
||||
history.getTaskName(),
|
||||
history.getResourceId(),
|
||||
history.getResourceName(),
|
||||
history.getQaContentFilePath(),
|
||||
qaContentDto,
|
||||
history.getArchiveReason(),
|
||||
history.getArchivedBy(),
|
||||
history.getArchivedAt(),
|
||||
history.getCreatedAt(),
|
||||
history.getReviewerId(),
|
||||
history.getReviewerName()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -124,13 +178,14 @@ public class AnnotationResultArchiveService {
|
||||
public int autoArchiveEligibleResults() {
|
||||
try {
|
||||
LocalDateTime cutoff = LocalDateTime.now().minus(autoArchiveTimeout);
|
||||
List<AnnotationResult> results = annotationResultMapper.selectList(new LambdaQueryWrapper<AnnotationResult>()
|
||||
.eq(AnnotationResult::getIsDeleted, false)
|
||||
.eq(AnnotationResult::getRequiresManualReview, false)
|
||||
.lt(AnnotationResult::getCreatedAt, cutoff));
|
||||
List<AnnotationResult> results = annotationResultMapper.selectList(
|
||||
new LambdaQueryWrapper<AnnotationResult>()
|
||||
.eq(AnnotationResult::getIsDeleted, false)
|
||||
.eq(AnnotationResult::getRequiresManualReview, false)
|
||||
.lt(AnnotationResult::getCreatedAt, cutoff));
|
||||
int archivedCount = 0;
|
||||
for (AnnotationResult result : results) {
|
||||
if (archiveRuntimeResult(result, null, "AUTO_ARCHIVE", null) != null) {
|
||||
if (archiveRuntimeResult(result, null, "AUTO_ARCHIVE") != null) {
|
||||
archivedCount++;
|
||||
}
|
||||
}
|
||||
@@ -153,12 +208,16 @@ public class AnnotationResultArchiveService {
|
||||
*/
|
||||
private MergeReviewResultResponse archiveRuntimeResult(AnnotationResult result,
|
||||
Long reviewerId,
|
||||
String archiveReason,
|
||||
String reviewComment) {
|
||||
String archiveReason) {
|
||||
LocalDateTime archivedAt = LocalDateTime.now();
|
||||
|
||||
// 从对象存储读取 qa.json 内容
|
||||
// String qaContentJson = loadQaContentJson(result);
|
||||
int updated = annotationResultMapper.markArchived(
|
||||
result.getId(),
|
||||
result.getCompanyId(),
|
||||
reviewerId);
|
||||
if (updated == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
AnnotationResultHistory history = AnnotationResultHistory.builder()
|
||||
.id(IdGenerator.nextId())
|
||||
@@ -175,24 +234,59 @@ public class AnnotationResultArchiveService {
|
||||
.archiveReason(archiveReason)
|
||||
.archivedBy(reviewerId)
|
||||
.archivedAt(archivedAt)
|
||||
.createdAt(archivedAt)
|
||||
.reviewerId(null)
|
||||
.reviewerName("auto")
|
||||
.reviewerComment("auto")
|
||||
.build();
|
||||
annotationResultHistoryMapper.insert(history);
|
||||
|
||||
int updated = annotationResultMapper.markArchived(
|
||||
result.getId(),
|
||||
result.getCompanyId(),
|
||||
reviewerId,
|
||||
reviewComment,
|
||||
archivedAt);
|
||||
if (updated == 0) {
|
||||
return null;
|
||||
}
|
||||
return new MergeReviewResultResponse(result.getId(), history.getId(), archiveReason, archivedAt);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载 QA 内容
|
||||
*/
|
||||
private QaContent loadQaContent(String filePath) {
|
||||
try {
|
||||
if (!hasText(filePath)) {
|
||||
log.warn("QA content file path is empty");
|
||||
return new QaContent(null, null, List.of(), null);
|
||||
}
|
||||
String bucketName = extractBucketName(filePath);
|
||||
String objectKey = extractObjectKey(filePath);
|
||||
byte[] content = objectStorageService.download(bucketName, objectKey);
|
||||
String jsonContent = new String(content, StandardCharsets.UTF_8);
|
||||
return objectMapper.readValue(jsonContent, new com.fasterxml.jackson.core.type.TypeReference<QaContent>() {
|
||||
});
|
||||
} catch (Exception e) {
|
||||
log.warn("Failed to load QA content, returning empty content. filePath={}, error={}", filePath,
|
||||
e.getMessage());
|
||||
return new QaContent(null, null, List.of(), null);
|
||||
}
|
||||
}
|
||||
|
||||
// 内部类:qa.json 结构
|
||||
private record QaContent(
|
||||
Long taskId,
|
||||
Long resourceId,
|
||||
List<QaRecord> records,
|
||||
Metadata metadata
|
||||
) {
|
||||
private record QaRecord(String id, Long batchId, String question, String answer,
|
||||
Boolean requiresReview, SourceSegments sourceSegments,
|
||||
String questionCategory, Scores scores, String reviewComment) {
|
||||
}
|
||||
|
||||
private record SourceSegments(String segment, Integer chunkIndex, String chunkTitle, String chunkContent) {
|
||||
}
|
||||
|
||||
private record Scores(Double similarity, Double confidence1, Double confidence2,
|
||||
Double hallucination, Double trust) {
|
||||
}
|
||||
|
||||
private record Metadata(String createdAt, String updatedAt) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从对象存储读取 qa.json 内容
|
||||
*/
|
||||
@@ -239,8 +333,9 @@ public class AnnotationResultArchiveService {
|
||||
|
||||
/**
|
||||
* 加载归档记录的文件内容
|
||||
*
|
||||
* @param currentUser 当前用户
|
||||
* @param historyId 历史记录ID
|
||||
* @param historyId 历史记录ID
|
||||
* @return 文件内容响应
|
||||
*/
|
||||
public FileContentResponse loadFileContent(LoginUser currentUser, Long historyId) {
|
||||
@@ -250,17 +345,17 @@ public class AnnotationResultArchiveService {
|
||||
throw new BusinessException(ResultCode.NOT_FOUND, "历史记录不存在");
|
||||
}
|
||||
//assertHistoryPermission(currentUser, history);
|
||||
|
||||
|
||||
String filePath = history.getQaContentFilePath();
|
||||
if (filePath == null || filePath.isEmpty()) {
|
||||
throw new BusinessException(ResultCode.ERROR, "文件路径为空");
|
||||
}
|
||||
|
||||
|
||||
String bucketName = extractBucketName(filePath);
|
||||
String objectKey = extractObjectKey(filePath);
|
||||
byte[] content = objectStorageService.download(bucketName, objectKey);
|
||||
String contentStr = new String(content, StandardCharsets.UTF_8);
|
||||
|
||||
|
||||
return new FileContentResponse(filePath, contentStr, content.length);
|
||||
} catch (BusinessException e) {
|
||||
throw e;
|
||||
@@ -270,4 +365,5 @@ public class AnnotationResultArchiveService {
|
||||
throw new BusinessException(ResultCode.ERROR, "加载文件内容失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -116,7 +116,24 @@ public class AnnotationResultService {
|
||||
AnnotationResultDetailResponse.QaContentDto qaContentDto = new AnnotationResultDetailResponse.QaContentDto(
|
||||
qaContent.records().stream()
|
||||
.map(r -> new AnnotationResultDetailResponse.QaRecordDto(
|
||||
r.id(), r.question(), r.answer(), r.requiresReview()))
|
||||
r.id(),
|
||||
r.batchId(),
|
||||
r.question(),
|
||||
r.answer(),
|
||||
r.requiresReview(),
|
||||
r.sourceSegments() != null ? new AnnotationResultDetailResponse.SourceSegmentsDto(
|
||||
r.sourceSegments().segment(),
|
||||
r.sourceSegments().chunkIndex(),
|
||||
r.sourceSegments().chunkTitle(),
|
||||
r.sourceSegments().chunkContent()) : null,
|
||||
r.questionCategory(),
|
||||
r.scores() != null ? new AnnotationResultDetailResponse.ScoresDto(
|
||||
r.scores().similarity(),
|
||||
r.scores().confidence1(),
|
||||
r.scores().confidence2(),
|
||||
r.scores().hallucination(),
|
||||
r.scores().trust()) : null,
|
||||
r.reviewComment()))
|
||||
.toList()
|
||||
);
|
||||
|
||||
@@ -127,7 +144,14 @@ public class AnnotationResultService {
|
||||
diffContent.records().stream()
|
||||
.map(r -> new AnnotationResultDetailResponse.DiffRecordDto(
|
||||
r.qaId(), r.question(), r.extractAnswer(),
|
||||
r.verifyAnswer(), r.diffReason(), r.mergedAnswer()))
|
||||
r.verifyAnswer(), r.diffReason(), r.mergedAnswer(),
|
||||
r.questionCategory(),
|
||||
r.scores() != null ? new AnnotationResultDetailResponse.ScoresDto(
|
||||
r.scores().similarity(),
|
||||
r.scores().confidence1(),
|
||||
r.scores().confidence2(),
|
||||
r.scores().hallucination(),
|
||||
r.scores().trust()) : null))
|
||||
.toList()
|
||||
);
|
||||
}
|
||||
@@ -145,8 +169,6 @@ public class AnnotationResultService {
|
||||
result.getDiffSummaryFilePath(),
|
||||
qaContentDto,
|
||||
diffContentDto,
|
||||
result.getReviewComment(),
|
||||
result.getReviewedAt(),
|
||||
result.getCreatedAt()
|
||||
);
|
||||
}
|
||||
@@ -173,9 +195,23 @@ public class AnnotationResultService {
|
||||
List<AnnotationResultCompareResponse.QaRecord> qaRecords = qaContent.records().stream()
|
||||
.map(qa -> new AnnotationResultCompareResponse.QaRecord(
|
||||
qa.id(),
|
||||
qa.batchId(),
|
||||
qa.question(),
|
||||
qa.answer(),
|
||||
qa.requiresReview()
|
||||
qa.requiresReview(),
|
||||
qa.sourceSegments() != null ? new AnnotationResultCompareResponse.SourceSegments(
|
||||
qa.sourceSegments().segment(),
|
||||
qa.sourceSegments().chunkIndex(),
|
||||
qa.sourceSegments().chunkTitle(),
|
||||
qa.sourceSegments().chunkContent()) : null,
|
||||
qa.questionCategory(),
|
||||
qa.scores() != null ? new AnnotationResultCompareResponse.Scores(
|
||||
qa.scores().similarity(),
|
||||
qa.scores().confidence1(),
|
||||
qa.scores().confidence2(),
|
||||
qa.scores().hallucination(),
|
||||
qa.scores().trust()) : null,
|
||||
qa.reviewComment()
|
||||
)).toList();
|
||||
|
||||
// 转换差异记录
|
||||
@@ -187,7 +223,14 @@ public class AnnotationResultService {
|
||||
diff.extractAnswer(),
|
||||
diff.verifyAnswer(),
|
||||
diff.diffReason(),
|
||||
diff.mergedAnswer()
|
||||
diff.mergedAnswer(),
|
||||
diff.questionCategory(),
|
||||
diff.scores() != null ? new AnnotationResultCompareResponse.Scores(
|
||||
diff.scores().similarity(),
|
||||
diff.scores().confidence1(),
|
||||
diff.scores().confidence2(),
|
||||
diff.scores().hallucination(),
|
||||
diff.scores().trust()) : null
|
||||
)).toList() : List.of();
|
||||
|
||||
return new AnnotationResultCompareResponse(
|
||||
@@ -220,16 +263,22 @@ public class AnnotationResultService {
|
||||
// 读取当前 qa.json
|
||||
QaContent qaContent = loadQaContent(result);
|
||||
|
||||
// 更新 qa.json 的 answer 字段
|
||||
// 更新 qa.json 的 answer 字段和 reviewComment
|
||||
List<QaContent.QaRecord> updatedQaRecords = qaContent.records().stream()
|
||||
.map(record -> {
|
||||
String mergedAnswer = request.mergedAnswers().get(record.id());
|
||||
if (mergedAnswer != null) {
|
||||
String reviewComment = request.reviewComments() != null ? request.reviewComments().get(record.id()) : null;
|
||||
if (mergedAnswer != null || reviewComment != null) {
|
||||
return new QaContent.QaRecord(
|
||||
record.id(),
|
||||
record.batchId(),
|
||||
record.question(),
|
||||
mergedAnswer,
|
||||
false
|
||||
mergedAnswer != null ? mergedAnswer : record.answer(),
|
||||
false,
|
||||
record.sourceSegments(),
|
||||
record.questionCategory(),
|
||||
record.scores(),
|
||||
reviewComment != null ? reviewComment : record.reviewComment()
|
||||
);
|
||||
}
|
||||
return record;
|
||||
@@ -247,13 +296,20 @@ public class AnnotationResultService {
|
||||
);
|
||||
saveQaContent(result, updatedQaContent);
|
||||
|
||||
// 更新数据库记录
|
||||
result.setIsDeleted(Boolean.TRUE);
|
||||
result.setReviewerId(currentUser.userId());
|
||||
result.setReviewComment(request.reviewComment());
|
||||
result.setReviewedAt(LocalDateTime.now());
|
||||
// 用单条 SQL 原子完成人工审核归档,避免状态部分更新后再次被自动归档扫描到。
|
||||
int updated = annotationResultMapper.markReviewedAndArchived(
|
||||
result.getId(),
|
||||
currentUser.companyId(),
|
||||
currentUser.userId());
|
||||
|
||||
if (updated == 0) {
|
||||
// 记录已被其他进程归档
|
||||
throw new BusinessException(ResultCode.CONFLICT, "记录已被归档");
|
||||
}
|
||||
|
||||
result.setRequiresManualReview(false);
|
||||
annotationResultMapper.updateById(result);
|
||||
result.setIsDeleted(true);
|
||||
result.setReviewerId(currentUser.userId());
|
||||
|
||||
// 归档到历史表(人工审核后归档)
|
||||
archiveToHistory(result, currentUser, "审核通过后归档", false);
|
||||
@@ -281,8 +337,6 @@ public class AnnotationResultService {
|
||||
result.getIsDeleted(),
|
||||
result.getQaContentFilePath(),
|
||||
result.getDiffSummaryFilePath(),
|
||||
result.getReviewComment(),
|
||||
result.getReviewedAt(),
|
||||
result.getCreatedAt()
|
||||
);
|
||||
}
|
||||
@@ -392,17 +446,15 @@ public class AnnotationResultService {
|
||||
|
||||
// 根据归档类型设置审核人信息
|
||||
if (isAutoArchive) {
|
||||
// 自动归档:reviewer_id为NULL,name和comment为"auto"
|
||||
// 自动归档:reviewer_id为NULL,name为"auto"
|
||||
historyBuilder
|
||||
.reviewerId(null)
|
||||
.reviewerName("auto")
|
||||
.reviewerComment("auto");
|
||||
.reviewerName("auto");
|
||||
} else {
|
||||
// 人工审核后归档:使用审核人信息
|
||||
historyBuilder
|
||||
.reviewerId(result.getReviewerId())
|
||||
.reviewerName(currentUser.realName())
|
||||
.reviewerComment(result.getReviewComment());
|
||||
.reviewerId(currentUser.userId())
|
||||
.reviewerName(currentUser.realName());
|
||||
}
|
||||
|
||||
annotationResultHistoryMapper.insert(historyBuilder.build());
|
||||
@@ -436,7 +488,16 @@ public class AnnotationResultService {
|
||||
List<QaRecord> records,
|
||||
Metadata metadata
|
||||
) {
|
||||
private record QaRecord(String id, String question, String answer, Boolean requiresReview) {
|
||||
private record QaRecord(String id, Long batchId, String question, String answer,
|
||||
Boolean requiresReview, SourceSegments sourceSegments,
|
||||
String questionCategory, Scores scores, String reviewComment) {
|
||||
}
|
||||
|
||||
private record SourceSegments(String segment, Integer chunkIndex, String chunkTitle, String chunkContent) {
|
||||
}
|
||||
|
||||
private record Scores(Double similarity, Double confidence1, Double confidence2,
|
||||
Double hallucination, Double trust) {
|
||||
}
|
||||
|
||||
private record Metadata(String createdAt, String updatedAt) {
|
||||
@@ -451,10 +512,15 @@ public class AnnotationResultService {
|
||||
Metadata metadata
|
||||
) {
|
||||
private record DiffRecord(String qaId, String question, String extractAnswer,
|
||||
String verifyAnswer, String diffReason, String mergedAnswer) {
|
||||
String verifyAnswer, String diffReason, String mergedAnswer,
|
||||
String questionCategory, Scores scores) {
|
||||
}
|
||||
|
||||
private record Scores(Double similarity, Double confidence1, Double confidence2,
|
||||
Double hallucination, Double trust) {
|
||||
}
|
||||
|
||||
private record Metadata(String createdAt) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ import com.labelsys.backend.dto.response.AnnotationTaskResponse;
|
||||
import com.labelsys.backend.entity.AnnotationTask;
|
||||
import com.labelsys.backend.entity.AnnotationTaskResource;
|
||||
import com.labelsys.backend.entity.SourceResource;
|
||||
import com.labelsys.backend.enums.IndustryType;
|
||||
import com.labelsys.backend.enums.TaskStatus;
|
||||
import com.labelsys.backend.enums.TaskType;
|
||||
import com.labelsys.backend.mapper.AnnotationTaskMapper;
|
||||
@@ -53,7 +52,6 @@ public class AnnotationTaskService {
|
||||
.creatorId(currentUser.userId())
|
||||
.creatorRole(currentUser.role())
|
||||
.taskName(request.taskName())
|
||||
.industryType(defaultIndustryType(request.industryType()))
|
||||
.taskType(defaultTaskType(request.taskType()))
|
||||
.taskStatus(TaskStatus.PENDING.name())
|
||||
.isDeleted(false)
|
||||
@@ -97,10 +95,6 @@ public class AnnotationTaskService {
|
||||
resources = loadAndValidateResources(currentUser, request.resourceIds());
|
||||
}
|
||||
|
||||
if (request.industryType() != null) {
|
||||
task.setIndustryType(request.industryType());
|
||||
}
|
||||
|
||||
if (request.taskType() != null) {
|
||||
task.setTaskType(request.taskType());
|
||||
}
|
||||
@@ -238,7 +232,6 @@ public class AnnotationTaskService {
|
||||
return new AnnotationTaskResponse(
|
||||
task.getId(),
|
||||
task.getTaskName(),
|
||||
task.getIndustryType(),
|
||||
task.getTaskType(),
|
||||
task.getTaskStatus(),
|
||||
resourceIds,
|
||||
@@ -264,10 +257,6 @@ public class AnnotationTaskService {
|
||||
}
|
||||
}
|
||||
|
||||
private IndustryType defaultIndustryType(IndustryType industryType) {
|
||||
return industryType != null ? industryType : IndustryType.TRANSPORT;
|
||||
}
|
||||
|
||||
private TaskType defaultTaskType(TaskType taskType) {
|
||||
return taskType != null ? taskType : TaskType.EXTRACT_QA;
|
||||
}
|
||||
|
||||
@@ -13,16 +13,14 @@
|
||||
<result column="requires_manual_review" property="requiresManualReview"/>
|
||||
<result column="is_deleted" property="isDeleted"/>
|
||||
<result column="reviewer_id" property="reviewerId"/>
|
||||
<result column="review_comment" property="reviewComment"/>
|
||||
<result column="reviewed_at" property="reviewedAt"/>
|
||||
<result column="created_at" property="createdAt"/>
|
||||
<result column="updated_at" property="updatedAt"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="AnnotationResultColumns">
|
||||
id, company_id, creator_id, creator_role, task_id, resource_id, qa_content_file_path,
|
||||
diff_summary_file_path, requires_manual_review, is_deleted, reviewer_id, review_comment,
|
||||
reviewed_at, created_at, updated_at
|
||||
diff_summary_file_path, requires_manual_review, is_deleted, reviewer_id,
|
||||
created_at, updated_at
|
||||
</sql>
|
||||
|
||||
<select id="findActiveByIdAndCompanyId" resultMap="AnnotationResultResultMap">
|
||||
@@ -37,12 +35,19 @@
|
||||
<update id="markArchived">
|
||||
update annotation_result
|
||||
set is_deleted = true,
|
||||
reviewer_id = #{reviewerId},
|
||||
review_comment = #{reviewComment},
|
||||
reviewed_at = #{reviewedAt},
|
||||
updated_at = #{reviewedAt}
|
||||
reviewer_id = #{reviewerId}
|
||||
where id = #{id}
|
||||
and company_id = #{companyId}
|
||||
and is_deleted = false
|
||||
</update>
|
||||
</mapper>
|
||||
|
||||
<update id="markReviewedAndArchived">
|
||||
update annotation_result
|
||||
set is_deleted = true,
|
||||
requires_manual_review = false,
|
||||
reviewer_id = #{reviewerId}
|
||||
where id = #{id}
|
||||
and company_id = #{companyId}
|
||||
and is_deleted = false
|
||||
</update>
|
||||
</mapper>
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
<result column="creator_id" property="creatorId"/>
|
||||
<result column="creator_role" property="creatorRole"/>
|
||||
<result column="task_name" property="taskName"/>
|
||||
<result column="industry_type" property="industryType"/>
|
||||
<result column="task_type" property="taskType"/>
|
||||
<result column="task_status" property="taskStatus"/>
|
||||
<result column="is_deleted" property="isDeleted"/>
|
||||
@@ -19,7 +18,7 @@
|
||||
</resultMap>
|
||||
|
||||
<sql id="AnnotationTaskColumns">
|
||||
id, company_id, creator_id, creator_role, task_name, industry_type, task_type,
|
||||
id, company_id, creator_id, creator_role, task_name, task_type,
|
||||
task_status, is_deleted, started_at, finished_at, error_message, created_at, updated_at
|
||||
</sql>
|
||||
|
||||
|
||||
@@ -66,12 +66,12 @@ INSERT INTO source_resource (
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
INSERT INTO annotation_task (
|
||||
id, company_id, creator_id, creator_role, task_name, industry_type, task_type,
|
||||
id, company_id, creator_id, creator_role, task_name, task_type,
|
||||
task_status, is_deleted, started_at, finished_at, error_message
|
||||
) VALUES
|
||||
(701, 2, 4, 'EMPLOYEE', '多资源问答抽取任务', 'ELECTRICITY', 'EXTRACT_QA',
|
||||
(701, 2, 4, 'EMPLOYEE', '多资源问答抽取任务', 'EXTRACT_QA',
|
||||
'PENDING', FALSE, NULL, NULL, NULL),
|
||||
(702, 2, 4, 'EMPLOYEE', '图片问答抽取任务', 'TRANSPORT', 'EXTRACT_QA',
|
||||
(702, 2, 4, 'EMPLOYEE', '图片问答抽取任务', 'EXTRACT_QA',
|
||||
'COMPLETED', FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL)
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
@@ -86,25 +86,25 @@ ON CONFLICT DO NOTHING;
|
||||
INSERT INTO annotation_result (
|
||||
id, company_id, creator_id, creator_role, task_id, task_name, resource_id, resource_name,
|
||||
qa_content_file_path, diff_summary_file_path,
|
||||
requires_manual_review, is_deleted, reviewer_id, review_comment, reviewed_at
|
||||
requires_manual_review, is_deleted, reviewer_id
|
||||
) VALUES
|
||||
(801, 2, 3, 'EMPLOYEE', 701, '多资源问答抽取任务', 601, '设备巡检规范.txt',
|
||||
'annotation-artifacts/qa/qa1.json',
|
||||
'annotation-artifacts/diff/diff1.json',
|
||||
TRUE, FALSE, NULL, NULL, NULL),
|
||||
TRUE, FALSE, NULL),
|
||||
(802, 2, 3, 'EMPLOYEE', 702, '图片问答抽取任务', 602, '控制柜照片.jpg',
|
||||
'annotation-artifacts/qa/qa2.json',
|
||||
'annotation-artifacts/diff/diff2.json',
|
||||
FALSE, FALSE, 5, '结果可通过。', CURRENT_TIMESTAMP)
|
||||
FALSE, FALSE, 5)
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
INSERT INTO annotation_result_history (
|
||||
id, company_id, creator_id, creator_role, source_result_id, task_id, task_name, resource_id, resource_name,
|
||||
qa_content_file_path, reviewer_id, reviewer_name, reviewer_comment, archive_reason, archived_by, archived_at
|
||||
qa_content_file_path, reviewer_id, reviewer_name, archive_reason, archived_by, archived_at
|
||||
) VALUES
|
||||
(901, 2, 3, 'EMPLOYEE', 802, 702, '图片问答抽取任务', 602, '控制柜照片.jpg',
|
||||
'annotation-results/2/qa/802.json',
|
||||
5, '甲公司审核员', '结果可通过。', '审核通过后归档', 5, CURRENT_TIMESTAMP)
|
||||
5, '甲公司审核员', '审核通过后归档', 5, CURRENT_TIMESTAMP)
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
INSERT INTO image_bbox_annotation (
|
||||
|
||||
@@ -199,7 +199,6 @@ CREATE TABLE IF NOT EXISTS annotation_task
|
||||
creator_id BIGINT NOT NULL,
|
||||
creator_role VARCHAR(32) NOT NULL DEFAULT 'EMPLOYEE',
|
||||
task_name VARCHAR(255) NOT NULL,
|
||||
industry_type VARCHAR(32) NOT NULL DEFAULT 'GENERAL',
|
||||
task_type VARCHAR(32) NOT NULL DEFAULT 'EXTRACT_QA',
|
||||
task_status VARCHAR(32) NOT NULL DEFAULT 'PENDING',
|
||||
is_deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
@@ -218,7 +217,6 @@ COMMENT ON COLUMN annotation_task.company_id IS '所属公司ID。';
|
||||
COMMENT ON COLUMN annotation_task.creator_id IS '任务创建人用户ID。';
|
||||
COMMENT ON COLUMN annotation_task.creator_role IS '任务创建人数据权限角色,默认 EMPLOYEE。';
|
||||
COMMENT ON COLUMN annotation_task.task_name IS '任务名称。';
|
||||
COMMENT ON COLUMN annotation_task.industry_type IS '行业类型简写,默认 transport,可选值按业务扩展。';
|
||||
COMMENT ON COLUMN annotation_task.task_type IS '任务类型,默认 EXTRACT_QA。';
|
||||
COMMENT ON COLUMN annotation_task.task_status IS '任务状态,默认 PENDING,可选 RUNNING、COMPLETED、FAILED。';
|
||||
COMMENT ON COLUMN annotation_task.is_deleted IS '任务软删除标记,默认 FALSE。';
|
||||
@@ -263,8 +261,6 @@ CREATE TABLE IF NOT EXISTS annotation_result
|
||||
requires_manual_review BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
is_deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
reviewer_id BIGINT,
|
||||
review_comment TEXT,
|
||||
reviewed_at TIMESTAMP,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT fk_annotation_result_company FOREIGN KEY (company_id) REFERENCES sys_company (id),
|
||||
@@ -286,8 +282,6 @@ COMMENT ON COLUMN annotation_result.diff_summary_file_path IS '差异摘要文
|
||||
COMMENT ON COLUMN annotation_result.requires_manual_review IS '是否需要人工审核,默认 FALSE。当diff_summary_file_path不为空时为TRUE。';
|
||||
COMMENT ON COLUMN annotation_result.is_deleted IS '软删除标记,默认 FALSE。';
|
||||
COMMENT ON COLUMN annotation_result.reviewer_id IS '审核人用户ID。';
|
||||
COMMENT ON COLUMN annotation_result.review_comment IS '审核意见。';
|
||||
COMMENT ON COLUMN annotation_result.reviewed_at IS '审核时间。';
|
||||
COMMENT ON COLUMN annotation_result.created_at IS '创建时间。';
|
||||
COMMENT ON COLUMN annotation_result.updated_at IS '更新时间。';
|
||||
COMMENT ON COLUMN annotation_result.task_name IS '任务名称(冗余字段)。';
|
||||
@@ -307,7 +301,6 @@ CREATE TABLE IF NOT EXISTS annotation_result_history
|
||||
qa_content_file_path VARCHAR(512) NOT NULL,
|
||||
reviewer_id BIGINT,
|
||||
reviewer_name VARCHAR(128),
|
||||
reviewer_comment TEXT,
|
||||
archive_reason VARCHAR(256),
|
||||
archived_by BIGINT,
|
||||
archived_at TIMESTAMP,
|
||||
@@ -336,7 +329,6 @@ COMMENT ON COLUMN annotation_result_history.archived_at IS '归档时间。';
|
||||
COMMENT ON COLUMN annotation_result_history.created_at IS '创建时间。';
|
||||
COMMENT ON COLUMN annotation_result_history.reviewer_id IS '审核人用户ID。自动归档时为NULL。';
|
||||
COMMENT ON COLUMN annotation_result_history.reviewer_name IS '审核人姓名。自动归档时为"auto"。';
|
||||
COMMENT ON COLUMN annotation_result_history.reviewer_comment IS '审核意见。自动归档时为"auto"。';
|
||||
COMMENT ON COLUMN annotation_result_history.task_name IS '任务名称(冗余字段)。';
|
||||
COMMENT ON COLUMN annotation_result_history.resource_name IS '资源名称(冗余字段)。';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user