数据库去掉industrytype,适配QA新结构,解决自动和手动归档产生两次记录问题

This commit is contained in:
wh
2026-05-10 16:40:24 +08:00
parent 9425ff3a1e
commit 84ac2fe5c7
12 changed files with 35 additions and 45 deletions

View File

@@ -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) {
}

View File

@@ -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) {
}

View File

@@ -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,

View File

@@ -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")

View File

@@ -12,4 +12,8 @@ public interface AnnotationResultMapper extends BaseMapper<AnnotationResult> {
int markArchived(@Param("id") Long id,
@Param("companyId") Long companyId,
@Param("reviewerId") Long reviewerId);
int markReviewedAndArchived(@Param("id") Long id,
@Param("companyId") Long companyId,
@Param("reviewerId") Long reviewerId);
}

View File

@@ -211,8 +211,13 @@ public class AnnotationResultArchiveService {
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())
@@ -229,18 +234,11 @@ public class AnnotationResultArchiveService {
.archiveReason(archiveReason)
.archivedBy(reviewerId)
.archivedAt(archivedAt)
.createdAt(archivedAt)
.reviewerId(null)
.reviewerName("auto")
.build();
annotationResultHistoryMapper.insert(history);
int updated = annotationResultMapper.markArchived(
result.getId(),
result.getCompanyId(),
reviewerId);
if (updated == 0) {
return null;
}
return new MergeReviewResultResponse(result.getId(), history.getId(), archiveReason, archivedAt);
}

View File

@@ -296,8 +296,8 @@ public class AnnotationResultService {
);
saveQaContent(result, updatedQaContent);
// 更新数据库记录(使用 markArchived 保证幂等性,防止并发重复归档)
int updated = annotationResultMapper.markArchived(
// 用单条 SQL 原子完成人工审核归档,避免状态部分更新后再次被自动归档扫描到。
int updated = annotationResultMapper.markReviewedAndArchived(
result.getId(),
currentUser.companyId(),
currentUser.userId());
@@ -307,9 +307,9 @@ public class AnnotationResultService {
throw new BusinessException(ResultCode.CONFLICT, "记录已被归档");
}
// 更新 requires_manual_review 字段
result.setRequiresManualReview(false);
annotationResultMapper.updateById(result);
result.setIsDeleted(true);
result.setReviewerId(currentUser.userId());
// 归档到历史表(人工审核后归档)
archiveToHistory(result, currentUser, "审核通过后归档", false);
@@ -453,7 +453,7 @@ public class AnnotationResultService {
} else {
// 人工审核后归档:使用审核人信息
historyBuilder
.reviewerId(result.getReviewerId())
.reviewerId(currentUser.userId())
.reviewerName(currentUser.realName());
}

View File

@@ -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;
}

View File

@@ -40,4 +40,14 @@
and company_id = #{companyId}
and is_deleted = false
</update>
<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>

View File

@@ -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>

View File

@@ -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;

View File

@@ -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。';