1 Commits

Author SHA1 Message Date
a2c5711d43 feat: 样本标签增加枚举标签
All checks were successful
Auto Deploy / build-and-deploy (push) Successful in 36s
2026-03-05 17:03:12 +08:00
5 changed files with 197 additions and 153 deletions

View File

@@ -112,7 +112,7 @@ export const layout: RunTimeLayoutConfig = ({
waterMarkProps: { waterMarkProps: {
content: initialState?.currentUser?.user.nickname, content: initialState?.currentUser?.user.nickname,
}, },
footerRender: () => <Footer />, // footerRender: () => <Footer />,
onPageChange: () => { onPageChange: () => {
const { location } = history; const { location } = history;
// 如果没有登录,重定向到 login // 如果没有登录,重定向到 login

View File

@@ -20,21 +20,49 @@ export const baseTenantColumns: ProColumns<AiSampleRespVO>[] = [
ellipsis: true, ellipsis: true,
}, },
{ {
title: '文件格式', title: '枚举标签',
width: 100, dataIndex: 'enumTags',
dataIndex: 'sampleMineType', width: 120,
ellipsis: true,
render: (_, record) => {
return (
record.enumTags?.map((tag) => {
return (
<>
{tag.enumValue}:<Tag key={tag.id}>{tag.tagName}</Tag>
</>
);
}) || '-'
);
},
}, },
{ {
title: '标签', title: '个性标签',
dataIndex: 'tags', dataIndex: 'tags',
width: 200, width: 200,
hideInSearch: true, hideInSearch: true,
render: (_, record) => { render: (_, record) => {
return record.tags?.map((tag) => { return record.tags?.map((tag) => {
return <Tag key={tag.id}>{tag.tagName}</Tag>; return (
<Tag key={tag.id} style={{ marginBottom: 5, marginTop: 5 }}>
{tag.tagName}
</Tag>
);
}); });
}, },
}, },
{
title: '关联模型',
width: 100,
dataIndex: 'relatedModels',
},
{
title: '文件格式',
width: 100,
dataIndex: 'sampleMineType',
},
{ {
title: '注释', title: '注释',
width: 100, width: 100,

View File

@@ -1,5 +1,6 @@
import { ProForm, ProFormGroup, ProFormText } from '@ant-design/pro-components'; import { ProForm, ProFormGroup, ProFormText } from '@ant-design/pro-components';
import { Button, message, Space, Tag } from 'antd'; import { Button, Empty, Input, message, Space, Tag } from 'antd';
import FormItem from 'antd/es/form/FormItem';
import type { RowSelectionType } from 'antd/es/table/interface'; import type { RowSelectionType } from 'antd/es/table/interface';
import type { FormInstance } from 'antd/lib'; import type { FormInstance } from 'antd/lib';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
@@ -13,6 +14,7 @@ import React, {
import GroupTagModal from '@/components/GroupTag/GroupTagModal'; import GroupTagModal from '@/components/GroupTag/GroupTagModal';
import type { TagItem } from '@/components/GroupTag/types'; import type { TagItem } from '@/components/GroupTag/types';
import type { FileItem } from '@/components/RenameRule'; import type { FileItem } from '@/components/RenameRule';
import TagEditor from '@/components/TagEditor';
import { import {
createSampleTag, createSampleTag,
createSampleTagGroup, createSampleTagGroup,
@@ -177,28 +179,50 @@ const SampleTagDetail = <T extends Record<string, any>>(
<> <>
{data!.length > 0 ? ( {data!.length > 0 ? (
<> <>
<ProForm name="validate_other" formRef={formRef} submitter={false}> <div className="sample-tag-detail">
{type === 'radio' && ( <ProForm name="validate_other" formRef={formRef} submitter={false}>
<ProFormGroup title="预览">
{data?.[0].sampleFilePath && (
<audio
controls
preload="true"
crossOrigin="anonymous"
style={{ marginBottom: 24 }}
>
<source src={data[0].sampleFilePath} />
<track kind="captions" />
</audio>
)}
</ProFormGroup>
)}
<ProFormGroup title="基本信息">
{type === 'radio' && ( {type === 'radio' && (
<ProFormGroup title="预览">
{data?.[0].sampleFilePath && (
<audio
controls
preload="true"
crossOrigin="anonymous"
style={{ marginBottom: 24 }}
>
<source src={data[0].sampleFilePath} />
<track kind="captions" />
</audio>
)}
</ProFormGroup>
)}
<ProFormGroup title="基本信息">
{type === 'radio' && (
<ProFormText
width="md"
name="sampleName"
placeholder="请输入样本名称"
fieldProps={{
onBlur: async (e) => {
if (e.target.value) {
const newData =
data?.map((sample) => {
return {
id: sample.id,
sampleName: e.target.value,
};
}) || [];
await updateSamples(newData);
props?.onRefresh?.();
message.success('更新样本名称成功');
}
},
}}
rules={[{ required: true, message: '样本名称不能为空' }]}
/>
)}
<ProFormText <ProFormText
width="md" width="md"
name="sampleName"
placeholder="请输入样本名称"
fieldProps={{ fieldProps={{
onBlur: async (e) => { onBlur: async (e) => {
if (e.target.value) { if (e.target.value) {
@@ -206,136 +230,96 @@ const SampleTagDetail = <T extends Record<string, any>>(
data?.map((sample) => { data?.map((sample) => {
return { return {
id: sample.id, id: sample.id,
sampleName: e.target.value, remark: e.target.value,
}; };
}) || []; }) || [];
await updateSamples(newData); await updateSamples(newData);
props?.onRefresh?.(); props?.onRefresh?.();
message.success('更新样本名称成功'); message.success('更新注释成功');
} }
}, },
}} }}
rules={[{ required: true, message: '样本名称不能为空' }]} name="remark"
placeholder="请输入注释"
/> />
)} </ProFormGroup>
<ProFormText <ProFormGroup title="枚举标签" block></ProFormGroup>
width="md" <ProForm.Item name="tag1" label="物种">
fieldProps={{ <TagEditor maxCount={1} />
onBlur: async (e) => { </ProForm.Item>
if (e.target.value) { <ProForm.Item name="tag2" label="情绪">
const newData = <TagEditor maxCount={1} />
data?.map((sample) => { </ProForm.Item>
return { <ProFormGroup title="个性标签">
id: sample.id, {/* <Form.Item name="tag"> */}
remark: e.target.value, {forMap(value.tags || [])}
}; </ProFormGroup>
}) || []; <Button
await updateSamples(newData); type="dashed"
props?.onRefresh?.(); block
message.success('更新注释成功'); style={{ marginBottom: 24 }}
} onClick={handleAddTag}
}, >
}}
name="remark" </Button>
placeholder="请输入注释" <ProFormGroup title="文本信息" block></ProFormGroup>
/> <Space size={10} style={{ width: '100%', marginBottom: 12 }}>
</ProFormGroup> <span>: </span>
<span>
{dayjs(value.createTime).format('YYYY-MM-DD HH:mm:ss')}
</span>
</Space>
<Space size={10} style={{ width: '100%', marginBottom: 12 }}>
<span></span>
<span>
{dayjs(value.updateTime).format('YYYY-MM-DD HH:mm:ss')}
</span>
</Space>
<Space size={10} style={{ width: '100%', marginBottom: 12 }}>
<span>: </span>
<span>{value.sampleSize}</span>
</Space>
<Space size={10} style={{ width: '100%', marginBottom: 12 }}>
<span>: </span>
<span>{value.sampleMineType}</span>
</Space>
</ProForm>
<GroupTagModal
visible={modalVisible}
onCancel={() => setModalVisible(false)}
onChange={onListAddTag}
editable={false}
value={value?.tags}
request={{
groupsApi: {
get: getSampleTagGroup,
create: createSampleTagGroup,
delete: deleteSampleTagGroup,
update: updateSampleTagGroup,
},
tagsApi: {
get: getSampleTagPage,
create: createSampleTag,
delete: deleteSampleTag,
update: updateSampleTag,
},
}}
title="管理技术标签"
width={800}
height={500}
/>
</div>
<ProFormGroup title="标签">
{/* <Form.Item name="tag"> */}
{forMap(value.tags || [])}
</ProFormGroup>
<Button
type="dashed"
block
style={{ marginBottom: 24 }}
onClick={handleAddTag}
>
</Button>
<ProFormGroup title="文本信息" block></ProFormGroup>
<Space size={10} style={{ width: '100%', marginBottom: 12 }}>
<span>: </span>
<span>
{dayjs(value.createTime).format('YYYY-MM-DD HH:mm:ss')}
</span>
</Space>
<Space size={10} style={{ width: '100%', marginBottom: 12 }}>
<span></span>
<span>
{dayjs(value.updateTime).format('YYYY-MM-DD HH:mm:ss')}
</span>
</Space>
<Space size={10} style={{ width: '100%', marginBottom: 12 }}>
<span>: </span>
<span>{value.sampleSize}</span>
</Space>
<Space size={10} style={{ width: '100%', marginBottom: 12 }}>
<span>: </span>
<span>{value.sampleMineType}</span>
</Space>
{type === 'checkbox' && (
<>
<ProFormGroup title="其他"></ProFormGroup>
<Button
block
style={{ marginBottom: 24 }}
onClick={handleTagManager}
>
</Button>
<Button
block
style={{ marginBottom: 24 }}
onClick={handleDownloadAll}
>
</Button>
<Button
block
color="danger"
style={{ marginBottom: 24 }}
onClick={handleDeleteAll}
>
</Button>
</>
)}
</ProForm>
<GroupTagModal
visible={modalVisible}
onCancel={() => setModalVisible(false)}
onChange={onListAddTag}
editable={false}
value={value?.tags}
request={{
groupsApi: {
get: getSampleTagGroup,
create: createSampleTagGroup,
delete: deleteSampleTagGroup,
update: updateSampleTagGroup,
},
tagsApi: {
get: getSampleTagPage,
create: createSampleTag,
delete: deleteSampleTag,
update: updateSampleTag,
},
}}
title="管理技术标签"
width={800}
height={500}
/>
<TagManager <TagManager
visible={tagManagerVisible} visible={tagManagerVisible}
files={tagNames} files={tagNames}
onOk={onRename} onOk={onRename}
onCancel={() => setTagManagerVisible(false)} onCancel={() => setTagManagerVisible(false)}
></TagManager> ></TagManager>
{type === 'radio' && ( {type === 'radio' ? (
<Space <Space
style={{ width: '100%', justifyContent: 'center', padding: 12 }} style={{ width: '100%', justifyContent: 'center', padding: 12 }}
className="tag-manager-btns"
> >
<Button color="danger" onClick={onDownload}> <Button color="danger" onClick={onDownload}>
@@ -344,10 +328,31 @@ const SampleTagDetail = <T extends Record<string, any>>(
</Button> </Button>
</Space> </Space>
) : (
<Space
style={{
width: '100%',
justifyContent: 'center',
padding: 12,
flexWrap: 'wrap',
flexDirection: 'column',
}}
className="tag-manager-btns"
>
<Button block onClick={handleTagManager}>
</Button>
<Button block onClick={handleDownloadAll}>
</Button>
<Button block color="danger" onClick={handleDeleteAll}>
</Button>
</Space>
)} )}
</> </>
) : ( ) : (
'暂无数据-请选择样本' <Empty description="未选择样本" />
)} )}
</> </>
); );

View File

@@ -1,28 +1,38 @@
.tag-content { .tag-content {
background: #fff; background: #fff;
width: 100%; width: 100%;
overflow: auto; height: calc(100vh - 90px);
display: flex;
overflow: hidden;
:global { :global {
.left { .left {
padding-right: 385px; background: #fff;
overflow: auto;
flex: 1;
} }
.uploader-card {
padding-right: 400px;
}
.detail { .detail {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
border-left: 1px solid #e8e8e8; border-left: 1px solid #e8e8e8;
border-top: 1px solid #e8e8e8; width: 360px;
width: 400px;
padding: 16px;
top: 74px;
height: calc(100vh - 80px); height: calc(100vh - 80px);
overflow: auto; overflow-y: auto;
background: #fff; background: #fff;
position: fixed; overflow-x: hidden;
right: 0; position: relative;
.ant-pro-form-group-title {
margin-bottom: 20px;
}
.sample-tag-detail {
padding: 16px;
}
.tag-manager-btns {
position: sticky;
bottom: 10px;
background: #fff;
box-shadow: 0 0 10px #e8e8e8;
align-items: center;
}
form { form {
flex: 1; flex: 1;
} }

View File

@@ -87,6 +87,7 @@ export interface AiSampleRespVO {
*/ */
sampleTime?: string; sampleTime?: string;
tags?: { tagName?: string; id?: number }[]; tags?: { tagName?: string; id?: number }[];
enumTags?: { tagName?: string; id?: number; enumValue?: string }[];
} }
export interface SampleReqVo extends PageParam { export interface SampleReqVo extends PageParam {