fix(annotation): 解决空标注结果的状态处理问题

- 在构建标注快照时增加空标注检查,避免空对象被处理
- 修改状态判断逻辑,当标注为空且当前状态为 NO_ANNOTATION 或 NOT_APPLICABLE 时保持原状态
- 移除冗余的 hasExistingAnnotation 变量检查
- 确保空标注情况下状态流转的正确性,防止误标为已标注状态
This commit is contained in:
2026-01-31 16:57:38 +08:00
parent f6788756d3
commit 5d8d25ca8c

View File

@@ -192,6 +192,7 @@ const stableStringify = (value: unknown) => {
const buildAnnotationSnapshot = (annotation?: Record<string, unknown>) => { const buildAnnotationSnapshot = (annotation?: Record<string, unknown>) => {
if (!annotation) return ""; if (!annotation) return "";
if (isAnnotationResultEmpty(annotation)) return "";
const cleaned: Record<string, unknown> = { ...annotation }; const cleaned: Record<string, unknown> = { ...annotation };
delete cleaned.updated_at; delete cleaned.updated_at;
delete cleaned.updatedAt; delete cleaned.updatedAt;
@@ -717,11 +718,13 @@ export default function LabelStudioTextEditor() {
const annotationRecord = annotation as Record<string, unknown>; const annotationRecord = annotation as Record<string, unknown>;
const currentTask = tasks.find((item) => item.fileId === String(fileId)); const currentTask = tasks.find((item) => item.fileId === String(fileId));
const currentStatus = currentTask?.annotationStatus; const currentStatus = currentTask?.annotationStatus;
const hasExistingAnnotation = !!currentTask?.hasAnnotation;
let resolvedStatus: AnnotationResultStatus; let resolvedStatus: AnnotationResultStatus;
if (isAnnotationResultEmpty(annotationRecord)) { if (isAnnotationResultEmpty(annotationRecord)) {
if (currentStatus === AnnotationResultStatus.ANNOTATED || (hasExistingAnnotation && !currentStatus)) { if (
resolvedStatus = AnnotationResultStatus.ANNOTATED; currentStatus === AnnotationResultStatus.NO_ANNOTATION ||
currentStatus === AnnotationResultStatus.NOT_APPLICABLE
) {
resolvedStatus = currentStatus;
} else { } else {
const selectedStatus = await confirmEmptyAnnotationStatus(); const selectedStatus = await confirmEmptyAnnotationStatus();
if (!selectedStatus) return false; if (!selectedStatus) return false;
@@ -1033,6 +1036,15 @@ export default function LabelStudioTextEditor() {
[segmentTreeData] [segmentTreeData]
); );
const inProgressSegmentedCount = useMemo(() => {
if (tasks.length === 0) return 0;
return tasks.reduce((count, item) => {
const summary = resolveSegmentSummary(item);
if (!summary) return count;
return summary.done < summary.total ? count + 1 : count;
}, 0);
}, [tasks]);
const handleSegmentSelect = useCallback((keys: Array<string | number>) => { const handleSegmentSelect = useCallback((keys: Array<string | number>) => {
const [first] = keys; const [first] = keys;
if (first === undefined || first === null) return; if (first === undefined || first === null) return;
@@ -1214,8 +1226,13 @@ export default function LabelStudioTextEditor() {
className="border-r border-gray-200 bg-gray-50 flex flex-col transition-all duration-200 min-h-0" className="border-r border-gray-200 bg-gray-50 flex flex-col transition-all duration-200 min-h-0"
style={{ width: sidebarCollapsed ? 0 : 240, overflow: "hidden" }} style={{ width: sidebarCollapsed ? 0 : 240, overflow: "hidden" }}
> >
<div className="px-3 py-2 border-b border-gray-200 bg-white font-medium text-sm"> <div className="px-3 py-2 border-b border-gray-200 bg-white font-medium text-sm flex items-center justify-between gap-2">
<span></span>
{segmented && (
<Tag color="orange" style={{ margin: 0 }}>
{inProgressSegmentedCount}
</Tag>
)}
</div> </div>
<div className="flex-1 min-h-0 overflow-auto"> <div className="flex-1 min-h-0 overflow-auto">
<List <List