refactor: 重构数据集和模型新建版本

This commit is contained in:
cp3hnu 2024-05-13 10:22:38 +08:00
parent 51e9859b2b
commit e436f28c6a
13 changed files with 252 additions and 337 deletions

View File

@ -131,7 +131,7 @@ export default [
{
name: '数据集简介',
path: ':id',
component: './Dataset/datasetIntro',
component: './Dataset/intro',
},
],
},
@ -147,7 +147,7 @@ export default [
{
name: '模型简介',
path: ':id',
component: './Model/modelIntro',
component: './Model/intro',
},
],
},

View File

@ -2,6 +2,7 @@ import { useEmotionCss } from '@ant-design/use-emotion-css';
import { useModel } from '@umijs/max';
import React from 'react';
import Avatar from './AvatarDropdown';
// import { SelectLang } from '@umijs/max';
export type SiderTheme = 'light' | 'dark';

View File

@ -4,6 +4,6 @@
}
.upload-button {
height: 48px;
height: 46px;
font-size: 15px;
}

View File

@ -23,7 +23,7 @@ import { useEffect, useState } from 'react';
import { CategoryData } from '../../type';
import styles from './index.less';
interface AddDatasetModalProps extends ModalProps {
interface AddDatasetModalProps extends Omit<ModalProps, 'onOk'> {
typeList: CategoryData[];
tagList: CategoryData[];
onOk: () => void;
@ -94,15 +94,7 @@ function AddDatasetModal({ typeList, tagList, onOk, ...rest }: AddDatasetModalPr
}}
destroyOnClose
>
<Form
name="form"
layout="vertical"
initialValues={{
remember: true,
}}
onFinish={onFinish}
autoComplete="off"
>
<Form name="form" layout="vertical" onFinish={onFinish} autoComplete="off">
<Form.Item
label="数据集名称"
name="name"
@ -134,6 +126,8 @@ function AddDatasetModal({ typeList, tagList, onOk, ...rest }: AddDatasetModalPr
placeholder="请选择数据集分类"
options={typeList}
fieldNames={{ label: 'name', value: 'id' }}
optionFilterProp="name"
showSearch
/>
</Form.Item>
<Form.Item label="研究方向/应用领域" name="data_tag">
@ -142,6 +136,8 @@ function AddDatasetModal({ typeList, tagList, onOk, ...rest }: AddDatasetModalPr
placeholder="请选择研究方向/应用领域"
options={tagList}
fieldNames={{ label: 'name', value: 'id' }}
optionFilterProp="name"
showSearch
/>
</Form.Item>
<Form.Item label="集群版本" name="available_cluster">

View File

@ -18,9 +18,9 @@ import {
} from 'antd';
import { omit } from 'lodash';
import { useState } from 'react';
import styles from './index.less';
import styles from '../AddDatasetModal/index.less';
interface AddModelModalProps extends ModalProps {
interface AddModelModalProps extends Omit<ModalProps, 'onOk'> {
typeList: CategoryData[];
tagList: CategoryData[];
onOk: () => void;
@ -76,15 +76,7 @@ function AddModelModal({ typeList, tagList, onOk, ...rest }: AddModelModalProps)
form: 'form',
}}
>
<Form
name="form"
layout="vertical"
initialValues={{
remember: true,
}}
onFinish={onFinish}
autoComplete="off"
>
<Form name="form" layout="vertical" onFinish={onFinish} autoComplete="off">
<Form.Item
label="模型名称"
name="name"
@ -140,6 +132,8 @@ function AddModelModal({ typeList, tagList, onOk, ...rest }: AddModelModalProps)
placeholder="请选择模型类型"
options={typeList}
fieldNames={{ label: 'name', value: 'id' }}
optionFilterProp="name"
showSearch
/>
</Form.Item>
<Form.Item label="模型能力" name="model_tag">
@ -148,6 +142,8 @@ function AddModelModal({ typeList, tagList, onOk, ...rest }: AddModelModalProps)
placeholder="请选择模型标签"
options={tagList}
fieldNames={{ label: 'name', value: 'id' }}
optionFilterProp="name"
showSearch
/>
</Form.Item>
<Form.Item

View File

@ -0,0 +1,169 @@
import { getAccessToken } from '@/access';
import KFIcon from '@/components/KFIcon';
import KFModal from '@/components/KFModal';
import { ResourceType, resourceConfig } from '@/pages/Dataset/type';
import { to } from '@/utils/promise';
import { getFileListFromEvent, validateUploadFiles } from '@/utils/ui';
import {
Button,
Form,
Input,
Upload,
UploadFile,
message,
type ModalProps,
type UploadProps,
} from 'antd';
import { omit } from 'lodash';
import { useState } from 'react';
import styles from '../AddDatasetModal/index.less';
interface AddVersionModalProps extends Omit<ModalProps, 'onOk'> {
resourceType: ResourceType;
resourceId: number;
initialName: string;
onOk: () => void;
}
function AddVersionModal({
resourceType,
resourceId,
initialName,
onOk,
...rest
}: AddVersionModalProps) {
const [uuid] = useState(Date.now());
// 上传组件参数
const uploadProps: UploadProps = {
action: resourceConfig[resourceType].uploadAction,
headers: {
Authorization: getAccessToken() || '',
},
defaultFileList: [],
};
// 上传请求
const createDatasetVersion = async (params: any) => {
const request = resourceConfig[resourceType].addVersionReq;
const [res] = await to(request(params));
if (res) {
message.success('创建成功');
onOk?.();
}
};
// 提交
const onFinish = (formData: any) => {
const fileList: UploadFile[] = formData['fileList'] ?? [];
if (validateUploadFiles(fileList)) {
const otherParams = omit(formData, ['fileList']);
const params = fileList.map((item) => {
const data = item.response?.data?.[0] ?? {};
return {
...otherParams,
[resourceConfig[resourceType].idParamKey]: resourceId,
file_name: data.fileName,
file_size: data.fileSize,
url: data.url,
};
});
createDatasetVersion(params);
}
};
const name = resourceConfig[resourceType].name;
const accept = resourceConfig[resourceType].uploadAccept;
return (
<KFModal
{...rest}
title="创建新版本"
image={require('@/assets/img/create-experiment.png')}
width={825}
okButtonProps={{
htmlType: 'submit',
form: 'form',
}}
>
<Form
name="form"
layout="vertical"
initialValues={{
name: initialName,
}}
onFinish={onFinish}
autoComplete="off"
>
<Form.Item
label={`${name}名称`}
name="name"
rules={[
{
required: true,
message: `请输入${name}名称`,
},
]}
>
<Input disabled placeholder={`请输入${name}名称`} />
</Form.Item>
<Form.Item
label={`${name}版本`}
name="version"
rules={[
{
required: true,
message: `请输入${name}版本`,
},
]}
>
<Input placeholder={`请输入${name}版本`} maxLength={64} showCount allowClear />
</Form.Item>
<Form.Item
label="版本描述"
name="description"
rules={[
{
required: true,
message: '请输入版本描述',
},
]}
>
<Input.TextArea
placeholder="请输入版本描述"
autoSize={{ minRows: 2, maxRows: 6 }}
maxLength={256}
showCount
allowClear
/>
</Form.Item>
<Form.Item
label={`${name}文件`}
name="fileList"
valuePropName="fileList"
getValueFromEvent={getFileListFromEvent}
rules={[
{
required: true,
message: `请上传${name}文件`,
},
]}
>
<Upload {...uploadProps} data={{ uuid: uuid }} accept={accept}>
<Button
className={styles['upload-button']}
type="default"
icon={<KFIcon type="icon-shangchuan" />}
>
</Button>
{resourceType === ResourceType.Dataset && (
<div className={styles['upload-tip']}>.zip格式文件</div>
)}
</Upload>
</Form.Item>
</Form>
</KFModal>
);
}
export default AddVersionModal;

View File

@ -1,6 +1,6 @@
import KFIcon from '@/components/KFIcon';
import { CommonTabKeys } from '@/enums';
import AddModelModal from '@/pages/Model/components/AddModelModal';
import AddModelModal from '@/pages/Dataset/components/AddModelModal';
import { openAntdModal } from '@/utils/modal';
import { to } from '@/utils/promise';
import { modalConfirm } from '@/utils/ui';

View File

@ -1,56 +1,25 @@
import { getAccessToken } from '@/access';
import KFIcon from '@/components/KFIcon';
import KFModal from '@/components/KFModal';
import { ResourceType } from '@/pages/Dataset/type';
import {
addDatasetVersionDetail,
deleteDatasetVersion,
getDatasetById,
getDatasetVersionIdList,
getDatasetVersionsById,
} from '@/services/dataset/index.js';
import { downLoadZip } from '@/utils/downloadfile';
import { openAntdModal } from '@/utils/modal';
import { modalConfirm } from '@/utils/ui';
import { UploadOutlined } from '@ant-design/icons';
import { useParams, useSearchParams } from '@umijs/max';
import { Button, Form, Input, Select, Table, Tabs, Upload, message } from 'antd';
import { Button, Input, Select, Table, Tabs, message } from 'antd';
import moment from 'moment';
import { useEffect, useRef, useState } from 'react';
import Styles from './index.less';
import AddVersionModal from './components/AddVersionModal';
import Styles from './intro.less';
const { Search } = Input;
const { TabPane } = Tabs;
const Dataset = () => {
const props = {
action: '/api/mmp/dataset/upload',
// headers: {
// 'X-Requested-With': null
// },
headers: {
Authorization: getAccessToken(),
'X-Requested-With': null,
},
onChange({ file, fileList }) {
if (file.status !== 'uploading') {
console.log(file, fileList);
setFormList(
fileList.map((item) => {
return {
...form.getFieldsValue(),
dataset_id: locationParams.id,
file_name: item.response.code === 200 ? item.response.data[0].fileName : null,
file_size: item.response.code === 200 ? item.response.data[0].fileSize : null,
url: item.response.code === 200 ? item.response.data[0].url : null,
};
}),
);
}
},
defaultFileList: [],
};
const [form] = Form.useForm();
const [formList, setFormList] = useState([]);
const [dialogTitle, setDialogTitle] = useState('新建版本');
const [isModalOpen, setIsModalOpen] = useState(false);
const [datasetDetailObj, setDatasetDetailObj] = useState({});
const [version, setVersion] = useState(null);
const [versionList, setVersionList] = useState([]);
@ -58,8 +27,8 @@ const Dataset = () => {
const [searchParams] = useSearchParams();
const [wordList, setWordList] = useState([]);
const [activeTabKey, setActiveTabKey] = useState('1');
const [uuid, setUuid] = useState(Date.now());
const isPublic = searchParams.get('isPublic') === 'true';
const getDatasetByDetail = () => {
getDatasetById(locationParams.id).then((ret) => {
console.log(ret);
@ -93,21 +62,17 @@ const Dataset = () => {
return () => {};
}, []);
const showModal = () => {
form.resetFields();
form.setFieldsValue({ name: datasetDetailObj.name });
const { close } = openAntdModal(AddVersionModal, {
resourceType: ResourceType.Dataset,
resourceId: locationParams.id,
initialName: datasetDetailObj.name,
onOk: () => {
getDatasetVersionList();
close();
},
});
};
setDialogTitle('创建新版本');
setUuid(Date.now());
setIsModalOpen(true);
};
const handleCancel = () => {
setIsModalOpen(false);
};
const handleExport = async () => {
const hide = message.loading('正在下载');
hide();
downLoadZip(`/api/mmp/dataset/downloadAllFiles`, { dataset_id: locationParams.id, version });
};
const deleteDataset = () => {
modalConfirm({
title: '删除后,该数据集版本将不可恢复',
@ -120,19 +85,26 @@ const Dataset = () => {
},
});
};
const onFinish = (values) => {
addDatasetVersionDetail(formList).then((ret) => {
getDatasetVersionList();
setIsModalOpen(false);
message.success('创建成功');
});
};
//
const getDatasetVersions = (params) => {
getDatasetVersionIdList(params).then((res) => {
setWordList(res?.data?.content ?? []);
});
};
const handleExport = async () => {
const hide = message.loading('正在下载');
hide();
downLoadZip(`/api/mmp/dataset/downloadAllFiles`, { dataset_id: locationParams.id, version });
};
const downloadAlone = (e, record) => {
console.log(record);
const hide = message.loading('正在下载');
hide();
downLoadZip(`/api/mmp/dataset/download/${record.id}`);
};
const handleChange = (value) => {
console.log(value);
if (value) {
@ -142,15 +114,7 @@ const Dataset = () => {
setVersion(null);
}
};
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
};
const downloadAlone = (e, record) => {
console.log(record);
const hide = message.loading('正在下载');
hide();
downLoadZip(`/api/mmp/dataset/download/${record.id}`);
};
const columns = [
{
title: '序号',
@ -292,98 +256,6 @@ const Dataset = () => {
</TabPane>
</Tabs>
</div>
<KFModal
title={dialogTitle}
width={825}
image={require('@/assets/img/create-experiment.png')}
open={isModalOpen}
className={Styles.modal}
okButtonProps={{
htmlType: 'submit',
form: 'form',
}}
onCancel={handleCancel}
>
<Form
name="form"
form={form}
layout="vertical"
initialValues={{
remember: true,
}}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
autoComplete="off"
>
<Form.Item
label="数据集名称"
name="name"
rules={[
{
required: true,
message: '请输入数据集名称',
},
]}
>
<Input disabled placeholder="请输入数据集名称" />
</Form.Item>
<Form.Item
label="数据集版本"
name="version"
rules={[
{
required: true,
message: '请输入数据集版本',
},
]}
>
<Input placeholder="请输入数据集版本" maxLength={64} showCount allowClear />
</Form.Item>
<Form.Item
label="版本描述"
name="description"
rules={[
{
required: true,
message: '请输入版本描述',
},
]}
>
<Input.TextArea
placeholder="请输入版本描述"
autoSize={{ minRows: 2, maxRows: 6 }}
maxLength={256}
showCount
allowClear
/>
</Form.Item>
<Form.Item
label="数据集文件"
name="dataset_version_vos"
rules={[
{
required: true,
message: '请上传数据集文件',
},
]}
>
<Upload {...props} data={{ uuid: uuid }} accept=".zip,.tgz">
<Button
style={{
fontSize: '14px',
border: '1px solid',
borderColor: '#1664ff',
background: '#fff',
}}
icon={<UploadOutlined style={{ color: '#1664ff' }} />}
>
上传文件
</Button>
<div className={Styles.tipContent}>只允许上传.zip,.tgz格式文件</div>
</Upload>
</Form.Item>
</Form>
</KFModal>
</div>
);
};

View File

@ -1,6 +1,8 @@
import KFIcon from '@/components/KFIcon';
import { CommonTabKeys } from '@/enums';
import {
addDatasetVersionDetail,
addModelsVersionDetail,
deleteDataset,
deleteModel,
getDatasetList,
@ -18,9 +20,9 @@ export enum ResourceType {
}
type ResourceTypeKeys = keyof typeof ResourceType;
type ResourceTypeValues = (typeof ResourceType)[ResourceTypeKeys];
export type ResourceTypeValues = (typeof ResourceType)[ResourceTypeKeys];
export type ResourceTypeInfo = {
type ResourceTypeInfo = {
getList: (params: any) => Promise<any>;
getVersions: (params: any) => Promise<any>;
getFiles: (params: any) => Promise<any>;
@ -37,6 +39,10 @@ export type ResourceTypeInfo = {
iconPathPrefix: string; // 图标路径前缀
deleteModalTitle: string; // 删除弹框的title
addBtnTitle: string; // 新增按钮的title
addVersionReq: (params: any) => Promise<any>;
idParamKey: string;
uploadAction: string;
uploadAccept?: string;
};
export const resourceConfig: Record<ResourceTypeValues, ResourceTypeInfo> = {
@ -68,6 +74,10 @@ export const resourceConfig: Record<ResourceTypeValues, ResourceTypeInfo> = {
iconPathPrefix: 'dataset',
deleteModalTitle: '确定删除该条数据集实例吗?',
addBtnTitle: '新建数据集',
addVersionReq: addDatasetVersionDetail,
idParamKey: 'dataset_id',
uploadAction: '/api/mmp/dataset/upload',
uploadAccept: '.zip,.tgz',
},
[ResourceType.Model]: {
getList: getModelList,
@ -97,6 +107,10 @@ export const resourceConfig: Record<ResourceTypeValues, ResourceTypeInfo> = {
iconPathPrefix: 'model',
deleteModalTitle: '确定删除该条模型实例吗?',
addBtnTitle: '新建模型',
addVersionReq: addModelsVersionDetail,
idParamKey: 'models_id',
uploadAction: '/api/mmp/models/upload',
uploadAccept: undefined,
},
};

View File

@ -1,4 +0,0 @@
.upload-button {
height: 48px;
font-size: 15px;
}

View File

@ -1,65 +1,33 @@
import { getAccessToken } from '@/access';
import KFIcon from '@/components/KFIcon';
import KFModal from '@/components/KFModal';
import AddVersionModal from '@/pages/Dataset/components/AddVersionModal';
import { ResourceType } from '@/pages/Dataset/type';
import {
addModelsVersionDetail,
deleteModelVersion,
getModelById,
getModelVersionIdList,
getModelVersionsById,
} from '@/services/dataset/index.js';
import { downLoadZip } from '@/utils/downloadfile';
import { openAntdModal } from '@/utils/modal';
import { modalConfirm } from '@/utils/ui';
import { UploadOutlined } from '@ant-design/icons';
import { useParams, useSearchParams } from '@umijs/max';
import { Button, Form, Input, Select, Table, Tabs, Upload, message } from 'antd';
import { Button, Input, Select, Table, Tabs, message } from 'antd';
import moment from 'moment';
import { useEffect, useRef, useState } from 'react';
import Styles from './index.less';
import Styles from './intro.less';
const { Search } = Input;
const { TabPane } = Tabs;
const Dataset = () => {
const props = {
action: '/api/mmp/models/upload',
// headers: {
// 'X-Requested-With': null
// },
headers: {
Authorization: getAccessToken(),
'X-Requested-With': null,
},
onChange({ file, fileList }) {
if (file.status !== 'uploading') {
console.log(file, fileList);
setFormList(
fileList.map((item) => {
return {
...form.getFieldsValue(),
models_id: locationParams.id,
file_name: item.response.code === 200 ? item.response.data[0].fileName : null,
file_size: item.response.code === 200 ? item.response.data[0].fileSize : null,
url: item.response.code === 200 ? item.response.data[0].url : null,
};
}),
);
}
},
defaultFileList: [],
};
const [form] = Form.useForm();
const [formList, setFormList] = useState([]);
const [dialogTitle, setDialogTitle] = useState('新建版本');
const [isModalOpen, setIsModalOpen] = useState(false);
const [datasetDetailObj, setDatasetDetailObj] = useState({});
const [version, setVersion] = useState(null);
const [versionList, setVersionList] = useState([]);
const locationParams = useParams(); //
const [searchParams] = useSearchParams();
console.log(locationParams);
const [wordList, setWordList] = useState([]);
const [uuid, setUuid] = useState(Date.now());
const isPublic = searchParams.get('isPublic') === 'true';
const getModelByDetail = () => {
getModelById(locationParams.id).then((ret) => {
console.log(ret);
@ -92,16 +60,17 @@ const Dataset = () => {
return () => {};
}, []);
const showModal = () => {
form.resetFields();
form.setFieldsValue({ name: datasetDetailObj.name });
const { close } = openAntdModal(AddVersionModal, {
resourceType: ResourceType.Model,
resourceId: locationParams.id,
initialName: datasetDetailObj.name,
onOk: () => {
getModelVersionsList();
close();
},
});
};
setDialogTitle('创建新版本');
setUuid(Date.now());
setIsModalOpen(true);
};
const handleCancel = () => {
setIsModalOpen(false);
};
const deleteDataset = () => {
modalConfirm({
title: '删除后,该版本将不可恢复',
@ -117,13 +86,7 @@ const Dataset = () => {
},
});
};
const onFinish = () => {
addModelsVersionDetail(formList).then((ret) => {
getModelVersionsList();
setIsModalOpen(false);
message.success('创建成功');
});
};
const getModelVersions = (params) => {
getModelVersionIdList(params).then((ret) => {
setWordList(ret?.data?.content ?? []);
@ -149,9 +112,7 @@ const Dataset = () => {
setVersion('');
}
};
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
};
const columns = [
{
title: '序号',
@ -294,96 +255,6 @@ const Dataset = () => {
</TabPane>
</Tabs>
</div>
<KFModal
title={dialogTitle}
image={require('@/assets/img/create-experiment.png')}
width={825}
open={isModalOpen}
okButtonProps={{
htmlType: 'submit',
form: 'form',
}}
onCancel={handleCancel}
>
<Form
name="form"
form={form}
layout="vertical"
initialValues={{
remember: true,
}}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
autoComplete="off"
>
<Form.Item
label="模型名称"
name="name"
rules={[
{
required: true,
message: '请输入模型名称',
},
]}
>
<Input disabled placeholder="请输入模型名称" />
</Form.Item>
<Form.Item
label="模型版本"
name="version"
rules={[
{
required: true,
message: '请输入模型版本',
},
]}
>
<Input placeholder="请输入模型版本" maxLength={64} showCount allowClear />
</Form.Item>
<Form.Item
label="版本描述"
name="description"
rules={[
{
required: true,
message: '请输入版本描述',
},
]}
>
<Input.TextArea
placeholder="请输入版本描述"
autoSize={{ minRows: 2, maxRows: 6 }}
maxLength={256}
showCount
allowClear
/>
</Form.Item>
<Form.Item
label="模型文件"
name="dataset_version_vos"
rules={[
{
required: true,
message: '请上传模型文件',
},
]}
>
<Upload {...props} data={{ uuid: uuid }}>
<Button
style={{
fontSize: '14px',
border: '1px solid',
borderColor: '#1664ff',
background: '#fff',
}}
icon={<UploadOutlined style={{ color: '#1664ff' }} />}
>
上传文件
</Button>
</Upload>
</Form.Item>
</Form>
</KFModal>
</div>
);
};