You've already forked DataMate
feat(annotation): 添加文本数据集段落切片功能
- 在前端组件中新增 segmentationEnabled 字段控制切片开关 - 为文本数据集添加段落切片配置选项,默认启用切片功能 - 在后端接口中新增 segmentation_enabled 参数传递给标注项目 - 实现切片逻辑控制,支持文本数据的自动段落分割 - 添加数据集类型判断,仅文本数据集支持切片配置 - 更新标注任务创建和编辑表单中的切片相关字段处理
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { Button, Input, Select, Form, message, Radio } from "antd";
|
||||
import type { RadioChangeEvent } from "antd";
|
||||
import TextArea from "antd/es/input/TextArea";
|
||||
import { DatabaseOutlined } from "@ant-design/icons";
|
||||
import { Link, useNavigate } from "react-router";
|
||||
import { ArrowLeft } from "lucide-react";
|
||||
import { queryDatasetsUsingGet } from "../../DataManagement/dataset.api";
|
||||
import { mapDataset } from "@/pages/DataManagement/dataset.const";
|
||||
import type { Dataset } from "@/pages/DataManagement/dataset.model";
|
||||
import { DatasetType, type Dataset } from "@/pages/DataManagement/dataset.model";
|
||||
import {
|
||||
createAnnotationTaskUsingPost,
|
||||
queryAnnotationTemplatesUsingGet,
|
||||
@@ -14,20 +15,33 @@ import {
|
||||
import type { AnnotationTemplate } from "../annotation.model";
|
||||
import TemplateConfigurationTreeEditor from "../components/TemplateConfigurationTreeEditor";
|
||||
|
||||
const DEFAULT_SEGMENTATION_ENABLED = true;
|
||||
const SEGMENTATION_OPTIONS = [
|
||||
{ label: "需要切片段", value: true },
|
||||
{ label: "不需要切片段", value: false },
|
||||
];
|
||||
|
||||
export default function AnnotationTaskCreate() {
|
||||
const navigate = useNavigate();
|
||||
const [form] = Form.useForm();
|
||||
const [datasets, setDatasets] = useState<Dataset[]>([]);
|
||||
const [templates, setTemplates] = useState<AnnotationTemplate[]>([]);
|
||||
const [selectedDatasetId, setSelectedDatasetId] = useState<string | null>(null);
|
||||
const [labelConfig, setLabelConfig] = useState("");
|
||||
const [configMode, setConfigMode] = useState<"template" | "custom">("template");
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
|
||||
const selectedDataset = useMemo(
|
||||
() => datasets.find((dataset) => dataset.id === selectedDatasetId),
|
||||
[datasets, selectedDatasetId]
|
||||
);
|
||||
const isTextDataset = selectedDataset?.datasetType === DatasetType.TEXT;
|
||||
|
||||
const fetchDatasets = async () => {
|
||||
try {
|
||||
const { data } = await queryDatasetsUsingGet({ page: 0, pageSize: 1000 });
|
||||
const list = data?.content || [];
|
||||
setDatasets(list.map((item: any) => mapDataset(item)) || []);
|
||||
setDatasets(list.map((item) => mapDataset(item)) || []);
|
||||
} catch (error) {
|
||||
console.error("加载数据集失败:", error);
|
||||
message.error("加载数据集失败");
|
||||
@@ -62,7 +76,7 @@ export default function AnnotationTaskCreate() {
|
||||
setLabelConfig(selectedTemplate?.labelConfig || "");
|
||||
};
|
||||
|
||||
const handleConfigModeChange = (e: any) => {
|
||||
const handleConfigModeChange = (e: RadioChangeEvent) => {
|
||||
const mode = e.target.value;
|
||||
setConfigMode(mode);
|
||||
if (mode === "custom") {
|
||||
@@ -79,20 +93,26 @@ export default function AnnotationTaskCreate() {
|
||||
}
|
||||
|
||||
setSubmitting(true);
|
||||
await createAnnotationTaskUsingPost({
|
||||
const requestData: Record<string, unknown> = {
|
||||
name: values.name,
|
||||
description: values.description,
|
||||
datasetId: values.datasetId,
|
||||
templateId: configMode === "template" ? values.templateId : undefined,
|
||||
labelConfig: labelConfig.trim(),
|
||||
});
|
||||
};
|
||||
if (isTextDataset) {
|
||||
requestData.segmentationEnabled =
|
||||
values.segmentationEnabled ?? DEFAULT_SEGMENTATION_ENABLED;
|
||||
}
|
||||
await createAnnotationTaskUsingPost(requestData);
|
||||
message.success("标注任务创建成功");
|
||||
navigate("/data/annotation");
|
||||
} catch (error: any) {
|
||||
if (error?.errorFields) {
|
||||
} catch (error: unknown) {
|
||||
const err = error as { errorFields?: unknown; message?: string; data?: { message?: string } };
|
||||
if (err?.errorFields) {
|
||||
message.error("请完善必填信息");
|
||||
} else {
|
||||
const msg = error?.message || error?.data?.message || "创建失败,请稍后重试";
|
||||
const msg = err?.message || err?.data?.message || "创建失败,请稍后重试";
|
||||
message.error(msg);
|
||||
console.error(error);
|
||||
}
|
||||
@@ -149,6 +169,40 @@ export default function AnnotationTaskCreate() {
|
||||
),
|
||||
value: dataset.id,
|
||||
}))}
|
||||
onChange={(value) => {
|
||||
setSelectedDatasetId(value);
|
||||
const dataset = datasets.find((item) => item.id === value);
|
||||
if (dataset?.datasetType === DatasetType.TEXT) {
|
||||
const currentValue = form.getFieldValue("segmentationEnabled");
|
||||
if (currentValue === undefined) {
|
||||
form.setFieldsValue({
|
||||
segmentationEnabled: DEFAULT_SEGMENTATION_ENABLED,
|
||||
});
|
||||
}
|
||||
} else if (dataset) {
|
||||
form.setFieldsValue({ segmentationEnabled: false });
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label="段落切片"
|
||||
name="segmentationEnabled"
|
||||
initialValue={DEFAULT_SEGMENTATION_ENABLED}
|
||||
extra={
|
||||
!selectedDatasetId
|
||||
? "请选择数据集后配置"
|
||||
: isTextDataset
|
||||
? "仅文本数据集可配置该项"
|
||||
: "非文本数据集不支持切片段"
|
||||
}
|
||||
>
|
||||
<Radio.Group
|
||||
options={SEGMENTATION_OPTIONS}
|
||||
optionType="button"
|
||||
buttonStyle="solid"
|
||||
disabled={!isTextDataset}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user