| @@ -22,7 +22,7 @@ export default { | |||||
| // 要代理的地址 | // 要代理的地址 | ||||
| target: 'http://172.20.32.197:31213', // 开发环境 | target: 'http://172.20.32.197:31213', // 开发环境 | ||||
| // target: 'http://172.20.32.235:31213', // 测试环境 | // target: 'http://172.20.32.235:31213', // 测试环境 | ||||
| // target: 'http://172.20.32.44:8082', | |||||
| // target: 'http://172.20.32.127:8082', | |||||
| // target: 'http://172.20.32.164:8082', | // target: 'http://172.20.32.164:8082', | ||||
| // 配置了这个可以从 http 代理到 https | // 配置了这个可以从 http 代理到 https | ||||
| // 依赖 origin 的功能可能需要这个,比如 cookie | // 依赖 origin 的功能可能需要这个,比如 cookie | ||||
| @@ -1,30 +1,8 @@ | |||||
| import { getAccessToken } from '@/access'; | |||||
| import KFIcon from '@/components/KFIcon'; | |||||
| import KFModal from '@/components/KFModal'; | import KFModal from '@/components/KFModal'; | ||||
| import { CategoryData, DataSource, ResourceType, resourceConfig } from '@/pages/Dataset/config'; | |||||
| import { CategoryData, DataSource } from '@/pages/Dataset/config'; | |||||
| import { addDataset } from '@/services/dataset/index.js'; | import { addDataset } from '@/services/dataset/index.js'; | ||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import { | |||||
| getFileListFromEvent, | |||||
| limitUploadFileType, | |||||
| removeUploadedFile, | |||||
| validateUploadFiles, | |||||
| } from '@/utils/ui'; | |||||
| import { | |||||
| Button, | |||||
| Form, | |||||
| Input, | |||||
| Radio, | |||||
| Select, | |||||
| Upload, | |||||
| UploadFile, | |||||
| message, | |||||
| type ModalProps, | |||||
| type UploadProps, | |||||
| } from 'antd'; | |||||
| import { omit } from 'lodash'; | |||||
| import { useState } from 'react'; | |||||
| import styles from './index.less'; | |||||
| import { Form, Input, Radio, Select, message, type ModalProps } from 'antd'; | |||||
| interface AddDatasetModalProps extends Omit<ModalProps, 'onOk'> { | interface AddDatasetModalProps extends Omit<ModalProps, 'onOk'> { | ||||
| typeList: CategoryData[]; | typeList: CategoryData[]; | ||||
| @@ -33,20 +11,6 @@ interface AddDatasetModalProps extends Omit<ModalProps, 'onOk'> { | |||||
| } | } | ||||
| function AddDatasetModal({ typeList, tagList, onOk, ...rest }: AddDatasetModalProps) { | function AddDatasetModal({ typeList, tagList, onOk, ...rest }: AddDatasetModalProps) { | ||||
| const [uuid] = useState(Date.now()); | |||||
| // 上传组件参数 | |||||
| const uploadProps: UploadProps = { | |||||
| action: resourceConfig[ResourceType.Dataset].uploadAction, | |||||
| headers: { | |||||
| Authorization: getAccessToken() || '', | |||||
| }, | |||||
| defaultFileList: [], | |||||
| accept: '.zip,.tgz', | |||||
| beforeUpload: limitUploadFileType('zip,tgz'), | |||||
| onRemove: removeUploadedFile, | |||||
| }; | |||||
| // 上传请求 | // 上传请求 | ||||
| const createDataset = async (params: any) => { | const createDataset = async (params: any) => { | ||||
| const [res] = await to(addDataset(params)); | const [res] = await to(addDataset(params)); | ||||
| @@ -58,22 +22,11 @@ function AddDatasetModal({ typeList, tagList, onOk, ...rest }: AddDatasetModalPr | |||||
| // 提交 | // 提交 | ||||
| const onFinish = (formData: any) => { | const onFinish = (formData: any) => { | ||||
| const fileList: UploadFile[] = formData['fileList'] ?? []; | |||||
| if (validateUploadFiles(fileList)) { | |||||
| const params = { | |||||
| ...omit(formData, ['fileList']), | |||||
| dataset_source: DataSource.Create, | |||||
| dataset_version_vos: fileList.map((item) => { | |||||
| const data = item.response?.data?.[0] ?? {}; | |||||
| return { | |||||
| file_name: data.fileName, | |||||
| file_size: data.fileSize, | |||||
| url: data.url, | |||||
| }; | |||||
| }), | |||||
| }; | |||||
| createDataset(params); | |||||
| } | |||||
| const params = { | |||||
| ...formData, | |||||
| dataset_source: DataSource.Create, | |||||
| }; | |||||
| createDataset(params); | |||||
| }; | }; | ||||
| return ( | return ( | ||||
| @@ -108,32 +61,6 @@ function AddDatasetModal({ typeList, tagList, onOk, ...rest }: AddDatasetModalPr | |||||
| > | > | ||||
| <Input placeholder="请输入数据名称" showCount allowClear maxLength={40} /> | <Input placeholder="请输入数据名称" showCount allowClear maxLength={40} /> | ||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item | |||||
| label="数据集版本" | |||||
| name="version" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: '请输入数据集版本', | |||||
| }, | |||||
| { | |||||
| pattern: /^[a-zA-Z0-9._-]+$/, | |||||
| message: '数据集版本只支持字母、数字、点(.)、下划线(_)、中横线(-)', | |||||
| }, | |||||
| { | |||||
| validator: (_rule, value) => { | |||||
| if (value === 'master') { | |||||
| return Promise.reject(`数据集版本不能为 master`); | |||||
| } else if (value === 'origin') { | |||||
| return Promise.reject(`数据集版本不能为 origin`); | |||||
| } | |||||
| return Promise.resolve(); | |||||
| }, | |||||
| }, | |||||
| ]} | |||||
| > | |||||
| <Input placeholder="请输入数据集版本" showCount allowClear maxLength={64} /> | |||||
| </Form.Item> | |||||
| <Form.Item label="数据集分类" name="data_type"> | <Form.Item label="数据集分类" name="data_type"> | ||||
| <Select | <Select | ||||
| allowClear | allowClear | ||||
| @@ -172,24 +99,6 @@ function AddDatasetModal({ typeList, tagList, onOk, ...rest }: AddDatasetModalPr | |||||
| allowClear | allowClear | ||||
| /> | /> | ||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item | |||||
| label="版本描述" | |||||
| name="version_desc" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: '请输入版本描述', | |||||
| }, | |||||
| ]} | |||||
| > | |||||
| <Input.TextArea | |||||
| placeholder="请输入版本描述" | |||||
| autoSize={{ minRows: 2, maxRows: 6 }} | |||||
| maxLength={200} | |||||
| showCount | |||||
| allowClear | |||||
| /> | |||||
| </Form.Item> | |||||
| <Form.Item | <Form.Item | ||||
| label="可见性" | label="可见性" | ||||
| name="is_public" | name="is_public" | ||||
| @@ -200,29 +109,6 @@ function AddDatasetModal({ typeList, tagList, onOk, ...rest }: AddDatasetModalPr | |||||
| <Radio value={true}>公开</Radio> | <Radio value={true}>公开</Radio> | ||||
| </Radio.Group> | </Radio.Group> | ||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item | |||||
| label="数据集文件" | |||||
| name="fileList" | |||||
| valuePropName="fileList" | |||||
| getValueFromEvent={getFileListFromEvent} | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: '请上传数据集文件', | |||||
| }, | |||||
| ]} | |||||
| > | |||||
| <Upload {...uploadProps} data={{ uuid: uuid }}> | |||||
| <Button | |||||
| className={styles['upload-button']} | |||||
| type="default" | |||||
| icon={<KFIcon type="icon-shangchuan" />} | |||||
| > | |||||
| 上传文件 | |||||
| </Button> | |||||
| <div className={styles['upload-tip']}>只允许上传 .zip 和 .tgz 格式文件</div> | |||||
| </Upload> | |||||
| </Form.Item> | |||||
| </Form> | </Form> | ||||
| </KFModal> | </KFModal> | ||||
| ); | ); | ||||
| @@ -1,25 +1,8 @@ | |||||
| import { getAccessToken } from '@/access'; | |||||
| import KFIcon from '@/components/KFIcon'; | |||||
| import KFModal from '@/components/KFModal'; | import KFModal from '@/components/KFModal'; | ||||
| import { CategoryData, DataSource, ResourceType, resourceConfig } from '@/pages/Dataset/config'; | |||||
| import { CategoryData, DataSource } from '@/pages/Dataset/config'; | |||||
| import { addModel } from '@/services/dataset/index.js'; | import { addModel } from '@/services/dataset/index.js'; | ||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import { getFileListFromEvent, removeUploadedFile, validateUploadFiles } from '@/utils/ui'; | |||||
| import { | |||||
| Button, | |||||
| Form, | |||||
| Input, | |||||
| Radio, | |||||
| Select, | |||||
| Upload, | |||||
| UploadFile, | |||||
| message, | |||||
| type ModalProps, | |||||
| type UploadProps, | |||||
| } from 'antd'; | |||||
| import { omit } from 'lodash'; | |||||
| import { useState } from 'react'; | |||||
| import styles from '../AddDatasetModal/index.less'; | |||||
| import { Form, Input, Radio, Select, message, type ModalProps } from 'antd'; | |||||
| interface AddModelModalProps extends Omit<ModalProps, 'onOk'> { | interface AddModelModalProps extends Omit<ModalProps, 'onOk'> { | ||||
| typeList: CategoryData[]; | typeList: CategoryData[]; | ||||
| @@ -28,18 +11,6 @@ interface AddModelModalProps extends Omit<ModalProps, 'onOk'> { | |||||
| } | } | ||||
| function AddModelModal({ typeList, tagList, onOk, ...rest }: AddModelModalProps) { | function AddModelModal({ typeList, tagList, onOk, ...rest }: AddModelModalProps) { | ||||
| const [uuid] = useState(Date.now()); | |||||
| // 上传组件参数 | |||||
| const uploadProps: UploadProps = { | |||||
| action: resourceConfig[ResourceType.Model].uploadAction, | |||||
| headers: { | |||||
| Authorization: getAccessToken() || '', | |||||
| }, | |||||
| defaultFileList: [], | |||||
| onRemove: removeUploadedFile, | |||||
| }; | |||||
| // 上传请求 | // 上传请求 | ||||
| const createModel = async (params: any) => { | const createModel = async (params: any) => { | ||||
| const [res] = await to(addModel(params)); | const [res] = await to(addModel(params)); | ||||
| @@ -51,22 +22,11 @@ function AddModelModal({ typeList, tagList, onOk, ...rest }: AddModelModalProps) | |||||
| // 提交 | // 提交 | ||||
| const onFinish = (formData: any) => { | const onFinish = (formData: any) => { | ||||
| const fileList: UploadFile[] = formData['fileList'] ?? []; | |||||
| if (validateUploadFiles(fileList)) { | |||||
| const params = { | |||||
| ...omit(formData, ['fileList']), | |||||
| model_source: DataSource.Create, | |||||
| model_version_vos: fileList.map((item) => { | |||||
| const data = item.response?.data?.[0] ?? {}; | |||||
| return { | |||||
| file_name: data.fileName, | |||||
| file_size: data.fileSize, | |||||
| url: data.url, | |||||
| }; | |||||
| }), | |||||
| }; | |||||
| createModel(params); | |||||
| } | |||||
| const params = { | |||||
| ...formData, | |||||
| model_source: DataSource.Create, | |||||
| }; | |||||
| createModel(params); | |||||
| }; | }; | ||||
| return ( | return ( | ||||
| @@ -99,32 +59,6 @@ function AddModelModal({ typeList, tagList, onOk, ...rest }: AddModelModalProps) | |||||
| > | > | ||||
| <Input placeholder="请输入模型名称" showCount allowClear maxLength={40} /> | <Input placeholder="请输入模型名称" showCount allowClear maxLength={40} /> | ||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item | |||||
| label="模型版本" | |||||
| name="version" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: '请输入模型版本', | |||||
| }, | |||||
| { | |||||
| pattern: /^[a-zA-Z0-9._-]+$/, | |||||
| message: '模型版本只支持字母、数字、点(.)、下划线(_)、中横线(-)', | |||||
| }, | |||||
| { | |||||
| validator: (_rule, value) => { | |||||
| if (value === 'master') { | |||||
| return Promise.reject(`模型版本不能为 master`); | |||||
| } else if (value === 'origin') { | |||||
| return Promise.reject(`模型版本不能为 origin`); | |||||
| } | |||||
| return Promise.resolve(); | |||||
| }, | |||||
| }, | |||||
| ]} | |||||
| > | |||||
| <Input placeholder="请输入模型版本" showCount allowClear maxLength={64} /> | |||||
| </Form.Item> | |||||
| <Form.Item label="模型框架" name="model_type"> | <Form.Item label="模型框架" name="model_type"> | ||||
| <Select | <Select | ||||
| allowClear | allowClear | ||||
| @@ -163,24 +97,6 @@ function AddModelModal({ typeList, tagList, onOk, ...rest }: AddModelModalProps) | |||||
| allowClear | allowClear | ||||
| /> | /> | ||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item | |||||
| label="版本描述" | |||||
| name="version_desc" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: '请输入版本描述', | |||||
| }, | |||||
| ]} | |||||
| > | |||||
| <Input.TextArea | |||||
| placeholder="请输入版本描述" | |||||
| autoSize={{ minRows: 2, maxRows: 6 }} | |||||
| maxLength={200} | |||||
| showCount | |||||
| allowClear | |||||
| /> | |||||
| </Form.Item> | |||||
| <Form.Item | <Form.Item | ||||
| label="可见性" | label="可见性" | ||||
| name="is_public" | name="is_public" | ||||
| @@ -191,28 +107,6 @@ function AddModelModal({ typeList, tagList, onOk, ...rest }: AddModelModalProps) | |||||
| <Radio value={true}>公开</Radio> | <Radio value={true}>公开</Radio> | ||||
| </Radio.Group> | </Radio.Group> | ||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item | |||||
| label="模型文件" | |||||
| name="fileList" | |||||
| valuePropName="fileList" | |||||
| getValueFromEvent={getFileListFromEvent} | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: '请上传模型文件', | |||||
| }, | |||||
| ]} | |||||
| > | |||||
| <Upload {...uploadProps} data={{ uuid: uuid }}> | |||||
| <Button | |||||
| className={styles['upload-button']} | |||||
| type="default" | |||||
| icon={<KFIcon type="icon-shangchuan" />} | |||||
| > | |||||
| 上传文件 | |||||
| </Button> | |||||
| </Upload> | |||||
| </Form.Item> | |||||
| </Form> | </Form> | ||||
| </KFModal> | </KFModal> | ||||
| ); | ); | ||||
| @@ -15,7 +15,7 @@ import { | |||||
| type UploadProps, | type UploadProps, | ||||
| } from 'antd'; | } from 'antd'; | ||||
| import { omit } from 'lodash'; | import { omit } from 'lodash'; | ||||
| import { useState } from 'react'; | |||||
| import { useEffect, useState } from 'react'; | |||||
| import styles from '../AddDatasetModal/index.less'; | import styles from '../AddDatasetModal/index.less'; | ||||
| interface AddVersionModalProps extends Omit<ModalProps, 'onOk'> { | interface AddVersionModalProps extends Omit<ModalProps, 'onOk'> { | ||||
| @@ -40,6 +40,23 @@ function AddVersionModal({ | |||||
| }: AddVersionModalProps) { | }: AddVersionModalProps) { | ||||
| const [uuid] = useState(Date.now()); | const [uuid] = useState(Date.now()); | ||||
| const config = resourceConfig[resourceType]; | const config = resourceConfig[resourceType]; | ||||
| const [form] = Form.useForm(); | |||||
| useEffect(() => { | |||||
| const getNextVersion = async () => { | |||||
| const request = config.getNextVersion; | |||||
| const params = { | |||||
| identifier, | |||||
| owner, | |||||
| }; | |||||
| const [res] = await to(request(params)); | |||||
| if (res && res.data) { | |||||
| const nextVersion = res.data; | |||||
| form.setFieldValue('version', nextVersion); | |||||
| } | |||||
| }; | |||||
| getNextVersion(); | |||||
| }, [identifier, owner, config, form]); | |||||
| // 上传组件参数 | // 上传组件参数 | ||||
| const uploadProps: UploadProps = { | const uploadProps: UploadProps = { | ||||
| @@ -109,6 +126,7 @@ function AddVersionModal({ | |||||
| }} | }} | ||||
| onFinish={onFinish} | onFinish={onFinish} | ||||
| autoComplete="off" | autoComplete="off" | ||||
| form={form} | |||||
| > | > | ||||
| <Form.Item | <Form.Item | ||||
| label={`${name}名称`} | label={`${name}名称`} | ||||
| @@ -146,7 +164,7 @@ function AddVersionModal({ | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| > | > | ||||
| <Input placeholder={`请输入${name}版本`} maxLength={64} showCount allowClear /> | |||||
| <Input placeholder={`请输入${name}版本`} maxLength={64} showCount allowClear disabled /> | |||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item | <Form.Item | ||||
| label="版本描述" | label="版本描述" | ||||
| @@ -28,8 +28,15 @@ | |||||
| border-radius: 4px; | border-radius: 4px; | ||||
| } | } | ||||
| &__desc { | |||||
| margin-bottom: 0 !important; | |||||
| color: @text-color; | |||||
| font-size: @font-size; | |||||
| } | |||||
| &__praise { | &__praise { | ||||
| display: flex; | display: flex; | ||||
| flex: none; | |||||
| align-items: center; | align-items: center; | ||||
| justify-content: center; | justify-content: center; | ||||
| width: 70px; | width: 70px; | ||||
| @@ -4,6 +4,7 @@ | |||||
| * @Description: 数据集、模型详情 | * @Description: 数据集、模型详情 | ||||
| */ | */ | ||||
| import KFEmpty, { EmptyType } from '@/components/KFEmpty'; | |||||
| import KFIcon from '@/components/KFIcon'; | import KFIcon from '@/components/KFIcon'; | ||||
| import { | import { | ||||
| ResourceData, | ResourceData, | ||||
| @@ -19,7 +20,7 @@ import { openAntdModal } from '@/utils/modal'; | |||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import { modalConfirm } from '@/utils/ui'; | import { modalConfirm } from '@/utils/ui'; | ||||
| import { useParams, useSearchParams } from '@umijs/max'; | import { useParams, useSearchParams } from '@umijs/max'; | ||||
| import { App, Button, Flex, Select, Tabs } from 'antd'; | |||||
| import { App, Button, Flex, Select, Tabs, Typography } from 'antd'; | |||||
| import classNames from 'classnames'; | import classNames from 'classnames'; | ||||
| import { useCallback, useEffect, useState } from 'react'; | import { useCallback, useEffect, useState } from 'react'; | ||||
| import AddVersionModal from '../AddVersionModal'; | import AddVersionModal from '../AddVersionModal'; | ||||
| @@ -61,21 +62,24 @@ const ResourceInfo = ({ resourceType }: ResourceInfoProps) => { | |||||
| const { message } = App.useApp(); | const { message } = App.useApp(); | ||||
| // 获取详情 | // 获取详情 | ||||
| const getResourceDetail = useCallback(async () => { | |||||
| const params = { | |||||
| id: resourceId, | |||||
| owner, | |||||
| name, | |||||
| identifier, | |||||
| version, | |||||
| is_public, | |||||
| }; | |||||
| const request = config.getInfo; | |||||
| const [res] = await to(request(params)); | |||||
| if (res && res.data) { | |||||
| setInfo(res.data); | |||||
| } | |||||
| }, [config, resourceId, owner, name, identifier, version, is_public]); | |||||
| const getResourceDetail = useCallback( | |||||
| async (version: string | undefined) => { | |||||
| const params = { | |||||
| id: resourceId, | |||||
| owner, | |||||
| name, | |||||
| identifier, | |||||
| version, | |||||
| is_public, | |||||
| }; | |||||
| const request = config.getInfo; | |||||
| const [res] = await to(request(params)); | |||||
| if (res && res.data) { | |||||
| setInfo(res.data); | |||||
| } | |||||
| }, | |||||
| [config, resourceId, owner, name, identifier, is_public], | |||||
| ); | |||||
| // 获取版本列表 | // 获取版本列表 | ||||
| const getVersionList = useCallback( | const getVersionList = useCallback( | ||||
| @@ -100,14 +104,15 @@ const ResourceInfo = ({ resourceType }: ResourceInfoProps) => { | |||||
| } | } | ||||
| } else { | } else { | ||||
| setVersion(undefined); | setVersion(undefined); | ||||
| getResourceDetail(undefined); | |||||
| } | } | ||||
| }, | }, | ||||
| [config, owner, identifier, versionParam], | |||||
| [config, owner, identifier, versionParam, getResourceDetail], | |||||
| ); | ); | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (version) { | if (version) { | ||||
| getResourceDetail(); | |||||
| getResourceDetail(version); | |||||
| } | } | ||||
| }, [version, getResourceDetail]); | }, [version, getResourceDetail]); | ||||
| @@ -116,7 +121,7 @@ const ResourceInfo = ({ resourceType }: ResourceInfoProps) => { | |||||
| }, [getVersionList]); | }, [getVersionList]); | ||||
| // 新建版本 | // 新建版本 | ||||
| const showModal = () => { | |||||
| const showAddVersionModal = () => { | |||||
| const { close } = openAntdModal(AddVersionModal, { | const { close } = openAntdModal(AddVersionModal, { | ||||
| resourceType: resourceType, | resourceType: resourceType, | ||||
| resourceId: resourceId, | resourceId: resourceId, | ||||
| @@ -278,44 +283,70 @@ const ResourceInfo = ({ resourceType }: ResourceInfoProps) => { | |||||
| <span>{info.praises_count}</span> | <span>{info.praises_count}</span> | ||||
| </div> | </div> | ||||
| </Flex> | </Flex> | ||||
| <Flex align="center"> | |||||
| <span style={{ marginRight: '10px' }}>版本号:</span> | |||||
| <Select | |||||
| placeholder="请选择版本号" | |||||
| style={{ width: '160px', marginRight: '20px' }} | |||||
| value={version} | |||||
| onChange={handleVersionChange} | |||||
| fieldNames={{ label: 'name', value: 'name' }} | |||||
| options={versionList} | |||||
| /> | |||||
| <Button type="default" onClick={showModal} icon={<KFIcon type="icon-xinjian2" />}> | |||||
| 创建新版本 | |||||
| </Button> | |||||
| <Button | |||||
| type="default" | |||||
| style={{ marginLeft: '20px' }} | |||||
| icon={<KFIcon type="icon-banbenduibi" />} | |||||
| onClick={showVersionSelector} | |||||
| > | |||||
| 版本对比 | |||||
| </Button> | |||||
| <Button | |||||
| type="default" | |||||
| style={{ marginLeft: '20px' }} | |||||
| onClick={handleDelete} | |||||
| icon={<KFIcon type="icon-shanchu" />} | |||||
| disabled={!version} | |||||
| danger | |||||
| {version ? ( | |||||
| <Flex align="center"> | |||||
| <span style={{ marginRight: '10px' }}>版本号:</span> | |||||
| <Select | |||||
| placeholder="请选择版本号" | |||||
| style={{ width: '160px', marginRight: '20px' }} | |||||
| value={version} | |||||
| onChange={handleVersionChange} | |||||
| fieldNames={{ label: 'name', value: 'name' }} | |||||
| options={versionList} | |||||
| /> | |||||
| <Button | |||||
| type="default" | |||||
| onClick={showAddVersionModal} | |||||
| icon={<KFIcon type="icon-xinjian2" />} | |||||
| > | |||||
| 创建新版本 | |||||
| </Button> | |||||
| <Button | |||||
| type="default" | |||||
| style={{ marginLeft: '20px' }} | |||||
| icon={<KFIcon type="icon-banbenduibi" />} | |||||
| onClick={showVersionSelector} | |||||
| > | |||||
| 版本对比 | |||||
| </Button> | |||||
| <Button | |||||
| type="default" | |||||
| style={{ marginLeft: '20px' }} | |||||
| onClick={handleDelete} | |||||
| icon={<KFIcon type="icon-shanchu" />} | |||||
| danger | |||||
| > | |||||
| 删除版本 | |||||
| </Button> | |||||
| </Flex> | |||||
| ) : ( | |||||
| <Typography.Paragraph | |||||
| className={styles['resource-info__top__desc']} | |||||
| ellipsis={{ tooltip: info.description }} | |||||
| > | > | ||||
| 删除版本 | |||||
| </Button> | |||||
| </Flex> | |||||
| {info.description ?? '暂无描述'} | |||||
| </Typography.Paragraph> | |||||
| )} | |||||
| </div> | </div> | ||||
| <div className={styles['resource-info__bottom']}> | <div className={styles['resource-info__bottom']}> | ||||
| <Tabs activeKey={activeTab} items={items} onChange={(key) => setActiveTab(key)}></Tabs> | |||||
| <div className={styles['resource-info__bottom__legend']}> | |||||
| {activeTab === ResourceInfoTabKeys.Evolution && <GraphLegend />} | |||||
| </div> | |||||
| {version ? ( | |||||
| <> | |||||
| <Tabs activeKey={activeTab} items={items} onChange={(key) => setActiveTab(key)}></Tabs> | |||||
| <div className={styles['resource-info__bottom__legend']}> | |||||
| {activeTab === ResourceInfoTabKeys.Evolution && <GraphLegend />} | |||||
| </div> | |||||
| </> | |||||
| ) : ( | |||||
| <KFEmpty | |||||
| style={{ height: '100%' }} | |||||
| type={EmptyType.NoData} | |||||
| title="暂无版本" | |||||
| content={`请创建${config.name}版本`} | |||||
| hasFooter={true} | |||||
| buttonTitle="创建版本" | |||||
| onButtonClick={showAddVersionModal} | |||||
| /> | |||||
| )} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| ); | ); | ||||
| @@ -11,9 +11,11 @@ import { | |||||
| deleteModelVersion, | deleteModelVersion, | ||||
| getDatasetInfo, | getDatasetInfo, | ||||
| getDatasetList, | getDatasetList, | ||||
| getDatasetNextVersionReq, | |||||
| getDatasetVersionList, | getDatasetVersionList, | ||||
| getModelInfo, | getModelInfo, | ||||
| getModelList, | getModelList, | ||||
| getModelNextVersionReq, | |||||
| getModelVersionList, | getModelVersionList, | ||||
| } from '@/services/dataset/index.js'; | } from '@/services/dataset/index.js'; | ||||
| import { limitUploadFileType } from '@/utils/ui'; | import { limitUploadFileType } from '@/utils/ui'; | ||||
| @@ -39,6 +41,7 @@ type ResourceTypeInfo = { | |||||
| deleteVersion: (params: any) => Promise<any>; // 删除版本 | deleteVersion: (params: any) => Promise<any>; // 删除版本 | ||||
| getInfo: (params: any) => Promise<any>; // 获取详情 | getInfo: (params: any) => Promise<any>; // 获取详情 | ||||
| compareVersion: (params: any) => Promise<any>; // 版本对比 | compareVersion: (params: any) => Promise<any>; // 版本对比 | ||||
| getNextVersion: (params: any) => Promise<any>; // 获取下一个版本 | |||||
| name: string; // 名称 | name: string; // 名称 | ||||
| typeParamKey: 'data_type' | 'model_type'; // 类型参数名称,获取资源列表接口使用 | typeParamKey: 'data_type' | 'model_type'; // 类型参数名称,获取资源列表接口使用 | ||||
| tagParamKey: 'data_tag' | 'model_tag'; // 标签参数名称,获取资源列表接口使用 | tagParamKey: 'data_tag' | 'model_tag'; // 标签参数名称,获取资源列表接口使用 | ||||
| @@ -68,6 +71,7 @@ export const resourceConfig: Record<ResourceType, ResourceTypeInfo> = { | |||||
| deleteVersion: deleteDatasetVersion, | deleteVersion: deleteDatasetVersion, | ||||
| getInfo: getDatasetInfo, | getInfo: getDatasetInfo, | ||||
| compareVersion: compareDatasetVersion, | compareVersion: compareDatasetVersion, | ||||
| getNextVersion: getDatasetNextVersionReq, | |||||
| name: '数据集', | name: '数据集', | ||||
| typeParamKey: 'data_type', | typeParamKey: 'data_type', | ||||
| tagParamKey: 'data_tag', | tagParamKey: 'data_tag', | ||||
| @@ -106,6 +110,7 @@ export const resourceConfig: Record<ResourceType, ResourceTypeInfo> = { | |||||
| deleteVersion: deleteModelVersion, | deleteVersion: deleteModelVersion, | ||||
| getInfo: getModelInfo, | getInfo: getModelInfo, | ||||
| compareVersion: compareModelVersion, | compareVersion: compareModelVersion, | ||||
| getNextVersion: getModelNextVersionReq, | |||||
| name: '模型', | name: '模型', | ||||
| typeParamKey: 'model_type', | typeParamKey: 'model_type', | ||||
| tagParamKey: 'model_tag', | tagParamKey: 'model_tag', | ||||
| @@ -3,12 +3,10 @@ import KFModal from '@/components/KFModal'; | |||||
| import { | import { | ||||
| DataSource, | DataSource, | ||||
| ResourceType, | ResourceType, | ||||
| ResourceVersionData, | |||||
| resourceConfig, | resourceConfig, | ||||
| type ResourceData, | type ResourceData, | ||||
| } from '@/pages/Dataset/config'; | } from '@/pages/Dataset/config'; | ||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import { InfoCircleOutlined } from '@ant-design/icons'; | |||||
| import { Form, Input, ModalProps, Select } from 'antd'; | import { Form, Input, ModalProps, Select } from 'antd'; | ||||
| import { pick } from 'lodash'; | import { pick } from 'lodash'; | ||||
| import { useEffect, useState } from 'react'; | import { useEffect, useState } from 'react'; | ||||
| @@ -44,7 +42,6 @@ function ExportModelModal({ | |||||
| }: ExportModelModalProps) { | }: ExportModelModalProps) { | ||||
| const [form] = Form.useForm(); | const [form] = Form.useForm(); | ||||
| const [resources, setResources] = useState<ResourceData[]>([]); | const [resources, setResources] = useState<ResourceData[]>([]); | ||||
| const [versions, setVersions] = useState<ResourceVersionData[]>([]); | |||||
| const config = resourceConfig[resourceType]; | const config = resourceConfig[resourceType]; | ||||
| const layout = { | const layout = { | ||||
| @@ -77,35 +74,24 @@ function ExportModelModal({ | |||||
| return undefined; | return undefined; | ||||
| }; | }; | ||||
| // 版本 tooltip | |||||
| const getTooltip = () => { | |||||
| const id = form.getFieldValue('id'); | |||||
| const resource = getSelectedResource(id); | |||||
| const name = resource?.name ?? ''; | |||||
| const versionNames = versions.map((item: ResourceVersionData) => item.name).join('、'); | |||||
| const tooltip = | |||||
| versions.length > 0 ? `${name}有以下版本:\n${versionNames}\n注意不能重复` : undefined; | |||||
| return tooltip; | |||||
| }; | |||||
| // 处理数据集、模型选择变化 | // 处理数据集、模型选择变化 | ||||
| const handleResourceChange = (id: number | undefined) => { | const handleResourceChange = (id: number | undefined) => { | ||||
| if (id) { | if (id) { | ||||
| getRecourceVersions(id); | |||||
| getRecourceNextVersion(id); | |||||
| } else { | } else { | ||||
| setVersions([]); | |||||
| form.setFieldValue('version', ''); | |||||
| } | } | ||||
| }; | }; | ||||
| // 获取数据集、模型版本列表 | |||||
| const getRecourceVersions = async (id: number) => { | |||||
| // 获取数据集、模型下一个版本 | |||||
| const getRecourceNextVersion = async (id: number) => { | |||||
| const resource = getSelectedResource(id); | const resource = getSelectedResource(id); | ||||
| if (!resource) { | if (!resource) { | ||||
| return; | return; | ||||
| } | } | ||||
| const [res] = await to(config.getVersions(pick(resource, ['identifier', 'owner']))); | |||||
| const [res] = await to(config.getNextVersion(pick(resource, ['identifier', 'owner']))); | |||||
| if (res && res.data) { | if (res && res.data) { | ||||
| setVersions(res.data); | |||||
| form.setFieldValue('version', res.data); | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -184,15 +170,6 @@ function ExportModelModal({ | |||||
| <Form.Item | <Form.Item | ||||
| label={`${config.name}版本`} | label={`${config.name}版本`} | ||||
| name="version" | name="version" | ||||
| tooltip={ | |||||
| getTooltip() | |||||
| ? { | |||||
| overlayClassName: styles['export-model-modal__tooltip'], | |||||
| title: getTooltip(), | |||||
| icon: <InfoCircleOutlined />, | |||||
| } | |||||
| : undefined | |||||
| } | |||||
| rules={[ | rules={[ | ||||
| { required: true, message: `请输入${config.name}版本` }, | { required: true, message: `请输入${config.name}版本` }, | ||||
| { | { | ||||
| @@ -205,8 +182,6 @@ function ExportModelModal({ | |||||
| return Promise.reject(`${config.name}版本不能为 master`); | return Promise.reject(`${config.name}版本不能为 master`); | ||||
| } else if (value === 'origin') { | } else if (value === 'origin') { | ||||
| return Promise.reject(`${config.name}版本不能为 origin`); | return Promise.reject(`${config.name}版本不能为 origin`); | ||||
| } else if (value && versions.map((item) => item.name).includes(value)) { | |||||
| return Promise.reject(`${config.name}版本已存在`); | |||||
| } else { | } else { | ||||
| return Promise.resolve(); | return Promise.resolve(); | ||||
| } | } | ||||
| @@ -214,7 +189,13 @@ function ExportModelModal({ | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| > | > | ||||
| <Input placeholder={`请输入${config.name}版本`} maxLength={64} showCount allowClear /> | |||||
| <Input | |||||
| placeholder={`请输入${config.name}版本`} | |||||
| maxLength={64} | |||||
| showCount | |||||
| allowClear | |||||
| disabled | |||||
| /> | |||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item | <Form.Item | ||||
| label="版本描述" | label="版本描述" | ||||
| @@ -82,6 +82,15 @@ export function compareDatasetVersion(data) { | |||||
| }); | }); | ||||
| } | } | ||||
| // 获取数据集下个版本号 | |||||
| export function getDatasetNextVersionReq(data) { | |||||
| return request(`/api/mmp/newdataset/queryNextVersion`, { | |||||
| method: 'POST', | |||||
| data, | |||||
| }); | |||||
| } | |||||
| // ----------------------------模型--------------------------------- | // ----------------------------模型--------------------------------- | ||||
| // 分页查询模型列表 | // 分页查询模型列表 | ||||
| @@ -140,6 +149,14 @@ export function deleteModelVersion(params) { | |||||
| }); | }); | ||||
| } | } | ||||
| // 获取模型下个版本号 | |||||
| export function getModelNextVersionReq(data) { | |||||
| return request(`/api/mmp/newmodel/queryNextVersion`, { | |||||
| method: 'POST', | |||||
| data, | |||||
| }); | |||||
| } | |||||
| // 获取模型依赖 | // 获取模型依赖 | ||||
| export function getModelAtlasReq(params) { | export function getModelAtlasReq(params) { | ||||
| return request(`/api/mmp/newmodel/getModelDependencyTree`, { | return request(`/api/mmp/newmodel/getModelDependencyTree`, { | ||||
| @@ -201,4 +218,5 @@ export function unpraiseResourceReq(id) { | |||||
| return request(`/api/mmp/newmodel/unpraise/${id}`, { | return request(`/api/mmp/newmodel/unpraise/${id}`, { | ||||
| method: 'DELETE', | method: 'DELETE', | ||||
| }); | }); | ||||
| } | |||||
| } | |||||