From 914c0391a2251abf17e234b8a5be4e3de06428cc Mon Sep 17 00:00:00 2001 From: uname <2986773479@qq.com> Date: Thu, 5 Feb 2026 15:18:21 +0800 Subject: [PATCH 1/6] feature: Initial realization of internationalization of data annotation --- frontend/src/i18n/locales/en/common.json | 307 ++++++++ frontend/src/i18n/locales/zh/common.json | 304 ++++++++ .../Annotate/AnnotationWorkSpace.tsx | 229 ------ .../Annotate/components/AudioAnnotation.tsx | 713 ------------------ .../Annotate/components/ImageAnnotation.tsx | 617 --------------- .../Annotate/components/TextAnnotation.tsx | 457 ----------- .../Annotate/components/VideoAnnotation.tsx | 688 ----------------- .../AutoAnnotation/AutoAnnotation.tsx | 130 ++-- .../components/CreateAutoAnnotationDialog.tsx | 47 +- .../EditAutoAnnotationDatasetDialog.tsx | 21 +- .../ImportFromLabelStudioDialog.tsx | 26 +- .../DataAnnotation/Create/CreateTask.tsx | 63 +- .../components/CreateAnnotationTaskDialog.tsx | 90 ++- .../components/CreateAnnptationTaskDialog.tsx | 37 +- .../components/CustomTemplateDialog.tsx | 26 +- .../EditManualAnnotationDatasetDialog.tsx | 24 +- .../DataAnnotation/Home/DataAnnotation.tsx | 262 +++---- .../ManualImportFromLabelStudioDialog.tsx | 25 +- .../DataAnnotation/Template/TemplateList.tsx | 72 +- .../pages/DataAnnotation/annotation.const.tsx | 193 ++++- .../pages/OperatorMarket/operator.const.tsx | 1 + .../src/pages/SynthesisTask/DataSynthesis.tsx | 11 - 22 files changed, 1164 insertions(+), 3179 deletions(-) delete mode 100644 frontend/src/pages/DataAnnotation/Annotate/AnnotationWorkSpace.tsx delete mode 100644 frontend/src/pages/DataAnnotation/Annotate/components/AudioAnnotation.tsx delete mode 100644 frontend/src/pages/DataAnnotation/Annotate/components/ImageAnnotation.tsx delete mode 100644 frontend/src/pages/DataAnnotation/Annotate/components/TextAnnotation.tsx delete mode 100644 frontend/src/pages/DataAnnotation/Annotate/components/VideoAnnotation.tsx diff --git a/frontend/src/i18n/locales/en/common.json b/frontend/src/i18n/locales/en/common.json index 62bf982ce..4c23c8de4 100644 --- a/frontend/src/i18n/locales/en/common.json +++ b/frontend/src/i18n/locales/en/common.json @@ -580,6 +580,9 @@ "actions": { "createTask": "Create Task" }, + "table": { + "file": "files" + }, "placeholders": { "empty": "-" }, @@ -964,5 +967,309 @@ "score": "Score:", "scoreSuffix": " pts" } + }, + "dataAnnotation": { + "home": { + "title": "Data Annotation", + "tabs": { + "tasks": "Annotation Tasks", + "templates": "Annotation Templates" + }, + "columns": { + "taskName": "Task Name", + "type": "Type", + "taskId": "Task ID", + "dataset": "Dataset", + "model": "Model", + "confidence": "Confidence", + "targetClasses": "Target Classes", + "autoStatus": "Auto Status", + "autoProgress": "Auto Progress", + "detectedObjects": "Detected Objects", + "createdAt": "Created At", + "updatedAt": "Updated At", + "actions": "Actions" + }, + "actions": { + "annotate": "Annotate", + "edit": "Edit", + "syncToDb": "Sync to Database", + "exportResult": "Export Annotations", + "delete": "Delete", + "moreActions": "More Actions" + }, + "confirm": { + "deleteTaskTitle": "Confirm delete annotation task '{name}'?", + "deleteTaskContent1": "Deleting the annotation task will not delete the corresponding dataset.", + "deleteTaskContent2": "If you want to keep current annotation results, please sync before deleting.", + "deleteAutoTaskTitle": "Confirm delete auto annotation task '{name}'?", + "deleteAutoTaskContent": "After deleting the task, the generated annotation results will not be deleted.", + "deleteOkText": "Delete", + "deleteCancelText": "Cancel", + "syncTitle": "Confirm sync annotation task '{name}'?", + "syncContent1": "The file list in the annotation project will be consistent with the dataset, and differences will be corrected.", + "syncContent2": "Labels in the annotation project will be merged with labels in the dataset, conflicts will be based on the latest content.", + "syncOkText": "Sync", + "syncCancelText": "Cancel", + "batchSyncTitle": "Confirm sync {count} selected annotation tasks?", + "batchDeleteTitle": "Confirm delete {count} selected annotation tasks?" + }, + "messages": { + "deleteSuccess": "Mapping deleted successfully", + "deleteFailed": "Deletion failed, please try again later", + "autoTaskDeleteSuccess": "Auto annotation task deleted successfully", + "batchSyncSuccess": "Batch sync request sent", + "batchSyncFailed": "Batch sync failed, please try again later", + "batchDeleteSuccess": "Batch delete completed", + "batchDeleteFailed": "Batch delete failed, please try again later", + "syncRequestSent": "Task sync request sent", + "syncFailed": "Sync failed, please try again later", + "cannotJumpNoBase": "Cannot jump to Label Studio: Label Studio base URL not configured", + "cannotJumpNoMapping": "Cannot jump to Label Studio: No mapping bound to annotation project", + "cannotJumpError": "Cannot jump to Label Studio: Error occurred, please check configuration or console logs", + "cannotJumpAutoNoDataset": "This auto annotation task is not bound to a dataset, cannot jump to Label Studio", + "cannotJumpAutoNoProject": "No corresponding annotation project found, please create annotation project for this task or dataset first", + "autoTaskNotFound": "Corresponding auto annotation task not found", + "taskNotFound": "Corresponding annotation task not found", + "fetchAutoTasksFailed": "Failed to fetch auto annotation tasks", + "syncToDbTitle": "Confirm sync '{name}' annotations from Label Studio to database?", + "syncToDbContent1": "This operation will override current file tags and annotation information based on task data in Label Studio.", + "syncToDbContent2": "After sync, you can view latest tags and annotations in dataset file details.", + "syncToDbLoading": "Syncing annotations from Label Studio to database...", + "syncToDbSuccess": "Sync completed", + "syncToDbFailed": "Sync failed, please try again later", + "batchSyncManualOnly": "Please select manual annotation tasks for sync" + }, + "searchPlaceholder": "Search task name, description", + "autoStatusLabels": { + "pending": "Pending", + "running": "Running", + "completed": "Completed", + "failed": "Failed", + "cancelled": "Cancelled" + }, + "autoModelSizeLabels": { + "n": "YOLOv8n (Fastest)", + "s": "YOLOv8s", + "m": "YOLOv8m", + "l": "YOLOv8l (Recommended)", + "x": "YOLOv8x (Most Accurate)" + }, + "batchSync": "Batch Sync", + "batchDelete": "Batch Delete", + "createTask": "Create Annotation Task", + "manualAnnotation": "Manual Annotation", + "autoAnnotation": "Auto Annotation", + "allCategories": "All Categories", + "categoriesCount": "{count} categories", + "editDataset": "Edit Dataset", + "editTask": "Edit Task" + }, + "create": { + "title": "Create Annotation Task", + "back": "Back", + "cancel": "Cancel", + "submit": "Create Task", + "basicInfo": "Basic Information", + "form": { + "name": "Task Name", + "namePlaceholder": "Enter task name", + "nameRequired": "Please enter task name", + "nameMinLength": "Task name must be at least 3 characters (excluding leading/trailing spaces, Label Studio limit)", + "nameMaxLength": "Task name cannot exceed 100 characters", + "description": "Task Description", + "descriptionPlaceholder": "Describe the requirements and goals of the annotation task in detail", + "dataset": "Select Dataset", + "datasetRequired": "Please select dataset", + "template": "Annotation Template", + "templateRequired": "Please select annotation template", + "noTemplatesAvailable": "No templates available, please create templates first", + "selectTemplate": "Please select annotation template", + "noTemplatesFound": "No matching templates found, please create templates in 'Annotation Templates' page", + "selectDatasetAndFiles": "Select Dataset and Files", + "currentDataset": "Current dataset: {name} - Selected {count} files", + "currentDatasetImages": "Current dataset: {name} - Selected {count} image files", + "modelSize": "Model Size", + "modelSizeRequired": "Please select model size", + "confThreshold": "Confidence Threshold", + "confThresholdRequired": "Please select confidence threshold", + "targetClasses": "Target Classes", + "selectAllClasses": "Select All Classes", + "selectTargetClasses": "Select target classes" + }, + "templateCategories": { + "cv": "Computer Vision", + "nlp": "Natural Language Processing" + }, + "customTemplate": "Custom Template", + "customTemplateDesc": "Create annotation template that meets specific needs", + "selectedTemplate": "Selected Template", + "templateSelection": "Template Selection", + "manual": "Manual Annotation", + "auto": "Auto Annotation", + "ok": "Confirm", + "messages": { + "selectAtLeastOneFile": "Please select at least one file", + "selectAtLeastOneImageFile": "Please select at least one image file", + "createSuccess": "Annotation task created successfully", + "createFailed": "Failed to create annotation task, please try again", + "autoCreateSuccess": "Auto annotation task created successfully", + "autoCreateFailed": "Failed to create auto annotation task", + "datasetTypeFiltered": "Datasets have been filtered by template type, please re-select dataset and files" + } + }, + "template": { + "title": "Annotation Templates", + "create": "Create Template", + "filters": { + "category": "Classification", + "dataType": "Data Type", + "labelingType": "Labeling Type", + "builtIn": "Template Type" + }, + "columns": { + "name": "Template Name", + "description": "Description", + "dataType": "Data Type", + "labelingType": "Labeling Type", + "category": "Classification", + "builtIn": "Type", + "version": "Version", + "createdAt": "Created At", + "actions": "Actions" + }, + "messages": { + "deleteSuccess": "Template deleted successfully", + "deleteFailed": "Failed to delete template", + "deleteConfirm": "Are you sure you want to delete this template?", + "confirmDelete": "Confirm", + "cancelDelete": "Cancel" + }, + "actions": { + "viewDetail": "View Details", + "edit": "Edit", + "delete": "Delete" + }, + "searchPlaceholder": "Search template name, description" + }, + "autoAnnotation": { + "title": "Auto Annotation", + "createTask": "Create Auto Annotation Task", + "columns": { + "name": "Task Name", + "dataset": "Dataset", + "modelSize": "Model Size", + "confThreshold": "Confidence", + "targetClasses": "Target Classes", + "status": "Status", + "progress": "Progress", + "detectedObjects": "Detected Objects", + "createdAt": "Created At", + "actions": "Actions" + }, + "statusLabels": { + "pending": "Pending", + "running": "Running", + "completed": "Completed", + "failed": "Failed", + "cancelled": "Cancelled" + }, + "modelSizeLabels": { + "n": "YOLOv8n (Fastest)", + "s": "YOLOv8s", + "m": "YOLOv8m", + "l": "YOLOv8l (Recommended)", + "x": "YOLOv8x (Most Accurate)" + }, + "actions": { + "annotate": "Annotate", + "syncToDb": "Sync to Database", + "exportResult": "Export Annotations", + "editDataset": "Edit Dataset", + "delete": "Delete", + "moreActions": "More Actions" + }, + "confirm": { + "deleteTitle": "Confirm delete auto annotation task '{name}'?", + "deleteContent": "After deleting the task, the generated annotation results will not be deleted.", + "deleteOkText": "Delete", + "deleteCancelText": "Cancel" + }, + "messages": { + "deleteSuccess": "Auto annotation task deleted successfully", + "deleteFailed": "Deletion failed, please try again later" + } + }, + "annotate": { + "title": "Annotation Workspace", + "saveSuccess": "Annotation saved", + "skipSuccess": "Skipped", + "backToList": "Back to List" + }, + "dialogs": { + "editDataset": { + "title": "Edit Dataset", + "description": "Modify dataset files for this task", + "selectedCount": "Selected {count} files", + "cancel": "Cancel", + "save": "Save", + "loading": "Saving...", + "success": "Dataset updated successfully", + "failed": "Failed to update dataset, please try again later", + "fetchFilesFailed": "Failed to fetch task current dataset files" + }, + "importFromLS": { + "title": "Import from Label Studio", + "description": "Import annotation results from Label Studio to local", + "cancel": "Cancel", + "import": "Import", + "loading": "Importing...", + "success": "Import successful", + "failed": "Import failed, please try again later" + }, + "syncToDb": { + "loading": "Syncing annotations from Label Studio to database...", + "success": "Sync completed", + "fail": "Sync failed, please try again later" + } + }, + "const": { + "status": { + "active": "Active", + "processing": "Processing", + "inactive": "Inactive", + "completed": "Completed", + "skipped": "Skipped", + "pending": "Ready" + }, + "dataType": { + "text": "Text", + "image": "Image", + "audio": "Audio", + "video": "Video" + }, + "classification": { + "cv": "Computer Vision", + "nlp": "Natural Language Processing", + "audio": "Audio", + "qualityControl": "Quality Control", + "custom": "Custom" + }, + "annotationType": { + "classification": "Classification", + "objectDetection": "Object Detection", + "segmentation": "Segmentation", + "ner": "Named Entity Recognition" + }, + "templateType": { + "system": "System Built-in", + "custom": "Custom" + }, + "stats": { + "accuracy": "Accuracy", + "averageTime": "Average Time", + "reviewCount": "Pending Review" + } + } } } diff --git a/frontend/src/i18n/locales/zh/common.json b/frontend/src/i18n/locales/zh/common.json index c0b1e30da..8daee35ce 100644 --- a/frontend/src/i18n/locales/zh/common.json +++ b/frontend/src/i18n/locales/zh/common.json @@ -963,5 +963,309 @@ "score": "评分:", "scoreSuffix": "分" } + }, + "dataAnnotation": { + "home": { + "title": "数据标注", + "tabs": { + "tasks": "标注任务", + "templates": "标注模板" + }, + "columns": { + "taskName": "任务名称", + "type": "类型", + "taskId": "任务ID", + "dataset": "数据集", + "model": "模型", + "confidence": "置信度", + "targetClasses": "目标类别", + "autoStatus": "自动标注状态", + "autoProgress": "自动标注进度", + "detectedObjects": "检测对象数", + "createdAt": "创建时间", + "updatedAt": "更新时间", + "actions": "操作" + }, + "actions": { + "annotate": "标注", + "edit": "编辑", + "syncToDb": "同步到数据库", + "exportResult": "导出标注结果", + "delete": "删除", + "moreActions": "更多操作" + }, + "confirm": { + "deleteTaskTitle": "确认删除标注任务「{name}」吗?", + "deleteTaskContent1": "删除标注任务不会删除对应数据集。", + "deleteTaskContent2": "如需保留当前标注结果,请在同步后再删除。", + "deleteAutoTaskTitle": "确认删除自动标注任务「{name}」吗?", + "deleteAutoTaskContent": "删除任务后,已生成的标注结果不会被删除。", + "deleteOkText": "删除", + "deleteCancelText": "取消", + "syncTitle": "确认同步标注任务「{name}」吗?", + "syncContent1": "标注工程中文件列表将与数据集保持一致,差异项将会被修正。", + "syncContent2": "标注工程中的标签与数据集中标签将进行合并,冲突项将以最新一次内容为准。", + "syncOkText": "同步", + "syncCancelText": "取消", + "batchSyncTitle": "确认同步所选 {count} 个标注任务吗?", + "batchDeleteTitle": "确认删除所选 {count} 个标注任务吗?" + }, + "messages": { + "deleteSuccess": "映射删除成功", + "deleteFailed": "删除失败,请稍后重试", + "autoTaskDeleteSuccess": "自动标注任务删除成功", + "batchSyncSuccess": "批量同步请求已发送", + "batchSyncFailed": "批量同步失败,请稍后重试", + "batchDeleteSuccess": "批量删除已完成", + "batchDeleteFailed": "批量删除失败,请稍后重试", + "syncRequestSent": "任务同步请求已发送", + "syncFailed": "同步失败,请稍后重试", + "cannotJumpNoBase": "无法跳转到 Label Studio:未配置 Label Studio 基础 URL", + "cannotJumpNoMapping": "无法跳转到 Label Studio:该映射未绑定标注项目", + "cannotJumpError": "无法跳转到 Label Studio:发生错误,请检查配置或控制台日志", + "cannotJumpAutoNoDataset": "该自动标注任务未绑定数据集,无法跳转 Label Studio", + "cannotJumpAutoNoProject": "未找到对应的标注工程,请先为该任务或数据集创建标注项目", + "autoTaskNotFound": "未找到对应的自动标注任务", + "taskNotFound": "未找到对应的标注任务", + "fetchAutoTasksFailed": "获取自动标注任务失败", + "syncToDbTitle": "确认将「{name}」在 Label Studio 中的标注结果同步到数据库吗?", + "syncToDbContent1": "此操作会根据 Label Studio 中的任务数据覆盖当前文件标签与标注信息。", + "syncToDbContent2": "同步完成后,可在数据管理的文件详情中查看最新标签与标注。", + "syncToDbLoading": "正在从 Label Studio 同步标注到数据库...", + "syncToDbSuccess": "同步完成", + "syncToDbFailed": "同步失败,请稍后重试", + "batchSyncManualOnly": "请选择手动标注任务进行同步" + }, + "searchPlaceholder": "搜索任务名称、描述", + "autoStatusLabels": { + "pending": "等待中", + "running": "处理中", + "completed": "已完成", + "failed": "失败", + "cancelled": "已取消" + }, + "autoModelSizeLabels": { + "n": "YOLOv8n (最快)", + "s": "YOLOv8s", + "m": "YOLOv8m", + "l": "YOLOv8l (推荐)", + "x": "YOLOv8x (最精确)" + }, + "batchSync": "批量同步", + "batchDelete": "批量删除", + "createTask": "创建标注任务", + "manualAnnotation": "手动标注", + "autoAnnotation": "自动标注", + "allCategories": "全部类别", + "categoriesCount": "{count} 个类别", + "editDataset": "编辑任务数据集", + "editTask": "编辑任务" + }, + "create": { + "title": "创建标注任务", + "back": "返回", + "cancel": "取消", + "submit": "创建任务", + "basicInfo": "基本信息", + "form": { + "name": "任务名称", + "namePlaceholder": "输入任务名称", + "nameRequired": "请输入任务名称", + "nameMinLength": "任务名称至少需要 3 个字符(不含首尾空格,Label Studio 限制)", + "nameMaxLength": "任务名称不能超过100个字符", + "description": "任务描述", + "descriptionPlaceholder": "详细描述标注任务的要求和目标", + "dataset": "选择数据集", + "datasetRequired": "请选择数据集", + "template": "标注模板", + "templateRequired": "请选择标注模板", + "noTemplatesAvailable": "暂无可用模板,请先创建模板", + "selectTemplate": "请选择标注模板", + "noTemplatesFound": "暂无模板,请前往「标注模板」页面创建", + "selectDatasetAndFiles": "选择数据集和文件", + "currentDataset": "当前数据集:{name} - 已选择 {count} 个文件", + "currentDatasetImages": "当前数据集:{name} - 已选择 {count} 个图像文件", + "modelSize": "模型规模", + "modelSizeRequired": "请选择模型规模", + "confThreshold": "置信度阈值", + "confThresholdRequired": "请选择置信度阈值", + "targetClasses": "目标类别", + "selectAllClasses": "选中所有类别", + "selectTargetClasses": "选择目标类别" + }, + "templateCategories": { + "cv": "计算机视觉", + "nlp": "自然语言处理" + }, + "customTemplate": "自定义模板", + "customTemplateDesc": "创建符合特定需求的标注模板", + "selectedTemplate": "已选择模板", + "templateSelection": "模板选择", + "manual": "手动标注", + "auto": "自动标注", + "ok": "确定", + "messages": { + "selectAtLeastOneFile": "请至少选择一个文件", + "selectAtLeastOneImageFile": "请至少选择一个图像文件", + "createSuccess": "创建标注任务成功", + "createFailed": "创建失败,请稍后重试", + "autoCreateSuccess": "自动标注任务创建成功", + "autoCreateFailed": "创建自动标注任务失败", + "datasetTypeFiltered": "已根据模板类型筛选数据集,请重新选择数据集和文件" + } + }, + "template": { + "title": "标注模板", + "create": "创建模板", + "filters": { + "category": "分类", + "dataType": "数据类型", + "labelingType": "标注类型", + "builtIn": "模板类型" + }, + "columns": { + "name": "模板名称", + "description": "描述", + "dataType": "数据类型", + "labelingType": "标注类型", + "category": "分类", + "builtIn": "类型", + "version": "版本", + "createdAt": "创建时间", + "actions": "操作" + }, + "messages": { + "deleteSuccess": "模板删除成功", + "deleteFailed": "删除模板失败", + "deleteConfirm": "确定要删除这个模板吗?", + "confirmDelete": "确定", + "cancelDelete": "取消" + }, + "actions": { + "viewDetail": "查看详情", + "edit": "编辑", + "delete": "删除" + }, + "searchPlaceholder": "搜索模板名称、描述" + }, + "autoAnnotation": { + "title": "自动标注", + "createTask": "创建自动标注任务", + "columns": { + "name": "任务名称", + "dataset": "数据集", + "modelSize": "模型规模", + "confThreshold": "置信度", + "targetClasses": "目标类别", + "status": "状态", + "progress": "进度", + "detectedObjects": "检测对象数", + "createdAt": "创建时间", + "actions": "操作" + }, + "statusLabels": { + "pending": "等待中", + "running": "处理中", + "completed": "已完成", + "failed": "失败", + "cancelled": "已取消" + }, + "modelSizeLabels": { + "n": "YOLOv8n (最快)", + "s": "YOLOv8s", + "m": "YOLOv8m", + "l": "YOLOv8l (推荐)", + "x": "YOLOv8x (最精确)" + }, + "actions": { + "annotate": "标注", + "syncToDb": "同步到数据库", + "exportResult": "导出标注结果", + "editDataset": "编辑任务数据集", + "delete": "删除任务", + "moreActions": "更多操作" + }, + "confirm": { + "deleteTitle": "确认删除自动标注任务「{name}」吗?", + "deleteContent": "删除任务后,已生成的标注结果不会被删除。", + "deleteOkText": "删除", + "deleteCancelText": "取消" + }, + "messages": { + "deleteSuccess": "自动标注任务删除成功", + "deleteFailed": "删除失败,请稍后重试" + } + }, + "annotate": { + "title": "标注工作台", + "saveSuccess": "标注已保存", + "skipSuccess": "已跳过", + "backToList": "返回列表" + }, + "dialogs": { + "editDataset": { + "title": "编辑数据集", + "description": "修改该任务的数据集文件", + "selectedCount": "已选择 {count} 个文件", + "cancel": "取消", + "save": "保存", + "loading": "保存中...", + "success": "数据集更新成功", + "failed": "数据集更新失败,请稍后重试", + "fetchFilesFailed": "获取任务当前数据集文件失败" + }, + "importFromLS": { + "title": "从 Label Studio 导入", + "description": "从 Label Studio 导入标注结果到本地", + "cancel": "取消", + "import": "导入", + "loading": "导入中...", + "success": "导入成功", + "failed": "导入失败,请稍后重试" + }, + "syncToDb": { + "loading": "正在从 Label Studio 同步标注到数据库...", + "success": "同步完成", + "fail": "同步失败,请稍后重试" + } + }, + "const": { + "status": { + "active": "活跃", + "processing": "处理中", + "inactive": "未激活", + "completed": "已完成", + "skipped": "已跳过", + "pending": "待开始" + }, + "dataType": { + "text": "文本", + "image": "图片", + "audio": "音频", + "video": "视频" + }, + "classification": { + "cv": "计算机视觉", + "nlp": "自然语言处理", + "audio": "音频", + "qualityControl": "质量控制", + "custom": "自定义" + }, + "annotationType": { + "classification": "分类", + "objectDetection": "目标检测", + "segmentation": "分割", + "ner": "命名实体识别" + }, + "templateType": { + "system": "系统内置", + "custom": "自定义" + }, + "stats": { + "accuracy": "准确率", + "averageTime": "平均时长", + "reviewCount": "待复核" + } + } } } diff --git a/frontend/src/pages/DataAnnotation/Annotate/AnnotationWorkSpace.tsx b/frontend/src/pages/DataAnnotation/Annotate/AnnotationWorkSpace.tsx deleted file mode 100644 index fb5910d80..000000000 --- a/frontend/src/pages/DataAnnotation/Annotate/AnnotationWorkSpace.tsx +++ /dev/null @@ -1,229 +0,0 @@ -import { useEffect, useState } from "react"; -import { Card, message } from "antd"; -import { Button, Badge, Progress, Checkbox } from "antd"; -import { - ArrowLeft, - FileText, - ImageIcon, - Video, - Music, - Save, - SkipForward, - CheckCircle, - Eye, - Settings, -} from "lucide-react"; -import { mockTasks } from "@/mock/annotation"; -import { Outlet, useNavigate } from "react-router"; - -export default function AnnotationWorkspace() { - const navigate = useNavigate(); - const [task, setTask] = useState(mockTasks[0]); - - const [currentFileIndex, setCurrentFileIndex] = useState(0); - const [annotationProgress, setAnnotationProgress] = useState({ - completed: task.completedCount, - skipped: task.skippedCount, - total: task.totalCount, - }); - - const handleSaveAndNext = () => { - setAnnotationProgress((prev) => ({ - ...prev, - completed: prev.completed + 1, - })); - - if (currentFileIndex < task.totalCount - 1) { - setCurrentFileIndex(currentFileIndex + 1); - } - - message({ - title: "标注已保存", - description: "标注结果已保存,自动跳转到下一个", - }); - }; - - const handleSkipAndNext = () => { - setAnnotationProgress((prev) => ({ - ...prev, - skipped: prev.skipped + 1, - })); - - if (currentFileIndex < task.totalCount - 1) { - setCurrentFileIndex(currentFileIndex + 1); - } - - message({ - title: "已跳过", - description: "已跳过当前项目,自动跳转到下一个", - }); - }; - - const getDatasetTypeIcon = (type: string) => { - switch (type) { - case "text": - return ; - case "image": - return ; - case "video": - return