diff --git a/react-ui/src/pages/Dataset/components/AddVersionModal/index.tsx b/react-ui/src/pages/Dataset/components/AddVersionModal/index.tsx index 527cc092..9b20147a 100644 --- a/react-ui/src/pages/Dataset/components/AddVersionModal/index.tsx +++ b/react-ui/src/pages/Dataset/components/AddVersionModal/index.tsx @@ -45,7 +45,7 @@ function AddVersionModal({ // 上传请求 const createDatasetVersion = async (params: any) => { - const request = resourceConfig[resourceType].addVersionReq; + const request = resourceConfig[resourceType].addVersion; const [res] = await to(request(params)); if (res) { message.success('创建成功'); diff --git a/react-ui/src/pages/Dataset/components/CategoryItem/index.tsx b/react-ui/src/pages/Dataset/components/CategoryItem/index.tsx index 5232acfa..53a5430e 100644 --- a/react-ui/src/pages/Dataset/components/CategoryItem/index.tsx +++ b/react-ui/src/pages/Dataset/components/CategoryItem/index.tsx @@ -20,13 +20,13 @@ function CategoryItem({ resourceType, item, isSelected, onClick }: CategoryItemP {item.name} diff --git a/react-ui/src/pages/Dataset/components/ResourceIntro/index.less b/react-ui/src/pages/Dataset/components/ResourceIntro/index.less new file mode 100644 index 00000000..cff0a9e5 --- /dev/null +++ b/react-ui/src/pages/Dataset/components/ResourceIntro/index.less @@ -0,0 +1,52 @@ +.resource-intro { + height: 100%; + + &__top { + display: flex; + flex-direction: column; + justify-content: space-between; + width: 100%; + height: 110px; + margin-bottom: 10px; + padding: 25px 30px; + background-image: url(/assets/images/dataset-back.png); + background-repeat: no-repeat; + background-position: top center; + background-size: 100% 100%; + + &__name { + margin-bottom: 12px; + color: @text-color; + font-size: 20; + } + + &__tag { + margin-right: 10px; + padding: 4px 10px; + color: @primary-color; + font-size: 14px; + background: rgba(22, 100, 255, 0.1); + border-radius: 4px; + } + } + + &__bottom { + height: calc(100% - 120px); + padding: 8px 30px 20px; + background: #ffffff; + border-radius: 10px; + box-shadow: 0px 2px 12px rgba(180, 182, 191, 0.09); + } + + &__title { + margin: 30px 0 10px; + color: @text-color; + font-weight: 500; + font-size: @font-size; + } + + &__intro { + color: @text-color-secondary; + font-size: 14px; + } +} diff --git a/react-ui/src/pages/Dataset/components/ResourceIntro/index.tsx b/react-ui/src/pages/Dataset/components/ResourceIntro/index.tsx new file mode 100644 index 00000000..813abdb5 --- /dev/null +++ b/react-ui/src/pages/Dataset/components/ResourceIntro/index.tsx @@ -0,0 +1,86 @@ +import { to } from '@/utils/promise'; +import { useParams, useSearchParams } from '@umijs/max'; +import { Flex, Tabs } from 'antd'; +import { useEffect, useState } from 'react'; +import { ResourceData, ResourceType, resourceConfig } from '../../config'; +import ResourceVersion from '../ResourceVersion'; +import styles from './index.less'; + +type ResourceIntroProps = { + resourceType: ResourceType; +}; + +const ResourceIntro = ({ resourceType }: ResourceIntroProps) => { + const [info, setInfo] = useState({} as ResourceData); + const locationParams = useParams(); //新版本获取路由参数接口 + const [searchParams] = useSearchParams(); + const isPublic = searchParams.get('isPublic') === 'true'; + const resourceId = Number(locationParams.id); + const name = resourceConfig[resourceType].name; + + useEffect(() => { + getModelByDetail(); + }, []); + + // 获取详情 + const getModelByDetail = async () => { + const request = resourceConfig[resourceType].getInfo; + const [res] = await to(request(resourceId)); + if (res) { + setInfo(res.data); + } + }; + + const items = [ + { + key: '1', + label: `${name}简介`, + children: ( + <> +
简介
+
{info.description}
+ + ), + }, + { + key: '2', + label: `${name}文件/版本`, + children: ( + + ), + }, + ]; + + const infoTypePropertyName = resourceConfig[resourceType] + .infoTypePropertyName as keyof ResourceData; + const infoTagPropertyName = resourceConfig[resourceType] + .infoTagPropertyName as keyof ResourceData; + + return ( +
+
+ {info.name} + +
+ {name} id:{info.id} +
+
+ {info[infoTypePropertyName] || '--'} +
+
+ {info[infoTagPropertyName] || '--'} +
+
+
+
+ +
+
+ ); +}; +export default ResourceIntro; diff --git a/react-ui/src/pages/Dataset/components/ResourceList/index.tsx b/react-ui/src/pages/Dataset/components/ResourceList/index.tsx index 18634004..acfd9fdb 100644 --- a/react-ui/src/pages/Dataset/components/ResourceList/index.tsx +++ b/react-ui/src/pages/Dataset/components/ResourceList/index.tsx @@ -129,11 +129,8 @@ function ResourceList( activeType: dataType, activeTag: dataTag, }); - if (resourceType === ResourceType.Dataset) { - navigate(`/dataset/dataset/${record.id}?isPublic=${isPublic}`); - } else { - navigate(`/dataset/model/${record.id}?isPublic=${isPublic}`); - } + const prefix = resourceConfig[resourceType].prefix; + navigate(`/dataset/${prefix}/${record.id}?isPublic=${isPublic}`); }; // 分页切换 diff --git a/react-ui/src/pages/Dataset/components/ResourceVersion/index.less b/react-ui/src/pages/Dataset/components/ResourceVersion/index.less new file mode 100644 index 00000000..d36c5ab6 --- /dev/null +++ b/react-ui/src/pages/Dataset/components/ResourceVersion/index.less @@ -0,0 +1,4 @@ +.resource-version { + color: @text-color; + font-size: @font-size-content; +} diff --git a/react-ui/src/pages/Dataset/components/ResourceVersion/index.tsx b/react-ui/src/pages/Dataset/components/ResourceVersion/index.tsx new file mode 100644 index 00000000..08035fdf --- /dev/null +++ b/react-ui/src/pages/Dataset/components/ResourceVersion/index.tsx @@ -0,0 +1,236 @@ +import CommonTableCell from '@/components/CommonTableCell'; +import DateTableCell from '@/components/DateTableCell'; +import KFIcon from '@/components/KFIcon'; +import AddVersionModal from '@/pages/Dataset/components/AddVersionModal'; +import { ResourceType } from '@/pages/Dataset/config'; +import { downLoadZip } from '@/utils/downloadfile'; +import { openAntdModal } from '@/utils/modal'; +import { to } from '@/utils/promise'; +import { modalConfirm } from '@/utils/ui'; +import { App, Button, Flex, Select, Table } from 'antd'; +import { useEffect, useState } from 'react'; +import { ResourceFileData, resourceConfig } from '../../config'; +import styles from './index.less'; + +type ResourceVersionProps = { + resourceType: ResourceType; + resourceId: number; + resourceName: string; + isPublic: boolean; +}; +function ResourceVersion({ + resourceType, + resourceId, + resourceName, + isPublic, +}: ResourceVersionProps) { + const [versionList, setVersionList] = useState([]); + const [version, setVersion] = useState(undefined); + const [fileList, setFileList] = useState([]); + const { message } = App.useApp(); + + useEffect(() => { + getVersionList(); + }, []); + + // 获取版本列表 + const getVersionList = async () => { + const request = resourceConfig[resourceType].getVersions; + const [res] = await to(request(resourceId)); + if (res && res.data && res.data.length > 0) { + setVersionList( + res.data.map((item: string) => { + return { + label: item, + value: item, + }; + }), + ); + setVersion(res.data[0]); + getFileList(res.data[0]); + } else { + setVersion(undefined); + setFileList([]); + } + }; + + // 获取版本下的文件列表 + const getFileList = async (version: string) => { + const params = { + version, + [resourceConfig[resourceType].fileReqParamKey]: resourceId, + }; + const request = resourceConfig[resourceType].getFiles; + const [res] = await to(request(params)); + if (res) { + setFileList(res?.data?.content ?? []); + } + }; + + // 删除版本 + const deleteVersion = async () => { + const request = resourceConfig[resourceType].deleteVersion; + const params = { + [resourceConfig[resourceType].idParamKey]: resourceId, + version, + }; + const [res] = await to(request(params)); + if (res) { + getVersionList(); + message.success('删除成功'); + } + }; + + // 新建版本 + const showModal = () => { + const { close } = openAntdModal(AddVersionModal, { + resourceType: resourceType, + resourceId: resourceId, + initialName: resourceName, + onOk: () => { + getVersionList(); + close(); + }, + }); + }; + + // 处理删除 + const hanldeDelete = () => { + modalConfirm({ + title: '删除后,该版本将不可恢复', + content: '是否确认删除?', + okText: '确认', + cancelText: '取消', + + onOk: () => { + deleteVersion(); + }, + }); + }; + + // 全部导出 + const handleExport = async () => { + const url = resourceConfig[resourceType].downloadAllAction; + downLoadZip(url, { models_id: resourceId, version }); + }; + + // 单个导出 + const downloadAlone = (record: ResourceFileData) => { + const url = resourceConfig[resourceType].downloadSingleAction; + downLoadZip(`${url}/${record.id}`); + }; + + // 版本变化 + const handleChange = (value: string) => { + if (value) { + getFileList(value); + setVersion(value); + } else { + setVersion(undefined); + } + }; + + const columns = [ + { + title: '序号', + dataIndex: 'index', + key: 'index', + width: 80, + render(text: string, record: ResourceFileData, index: number) { + return {index + 1}; + }, + }, + { + title: '文件名称', + dataIndex: 'file_name', + key: 'file_name', + render: (text: string, record: ResourceFileData) => ( + downloadAlone(record)}>{text} + ), + }, + { + title: '版本号', + dataIndex: 'version', + key: 'version', + render: CommonTableCell(), + }, + { + title: '文件大小', + dataIndex: 'file_size', + key: 'file_size', + render: CommonTableCell(), + }, + { + title: '更新时间', + dataIndex: 'update_time', + key: 'update_time', + render: DateTableCell, + }, + { + title: '操作', + dataIndex: 'option', + width: '100px', + key: 'option', + render: (_: any, record: ResourceFileData) => [ + , + ], + }, + ]; + + return ( +
+ + + 版本号: + - -
-
- {!isPublic && ( - - )} - -
- -
- {wordList.length > 0 && wordList[0].description - ? '版本描述:' + wordList[0].description - : null} -
- - - - - - - ); -}; -export default Dataset; diff --git a/react-ui/src/pages/Dataset/intro.less b/react-ui/src/pages/Dataset/intro.less deleted file mode 100644 index b36af2cf..00000000 --- a/react-ui/src/pages/Dataset/intro.less +++ /dev/null @@ -1,82 +0,0 @@ -.datasetIntroTopBox { - display: flex; - flex-direction: column; - justify-content: space-between; - width: 100%; - height: 110px; - margin-bottom: 10px; - padding: 25px 30px; - background-image: url(/assets/images/dataset-back.png); - background-repeat: no-repeat; - background-position: top center; - background-size: 100% 100%; - - .smallTagBox { - display: flex; - align-items: center; - color: #1664ff; - font-size: 14px; - .tagItem { - margin-right: 20px; - padding: 4px 10px; - background: rgba(22, 100, 255, 0.1); - border-radius: 4px; - } - } -} -.dataListBox { - padding: 20px 30px; - color: #1d1d20; - font-size: 16px; - font-family: alibaba; - background: #ffffff; - border-radius: 10px; - box-shadow: 0px 2px 12px rgba(180, 182, 191, 0.09); - .dataButtonList { - display: flex; - align-items: center; - justify-content: space-between; - height: 32px; - margin: 24px 0 30px 0; - color: #575757; - font-size: 16px; - } -} -.datasetIntroCneterBox { - height: 77vh; - padding: 20px 30px; - background: #ffffff; - border-radius: 10px; - box-shadow: 0px 2px 12px rgba(180, 182, 191, 0.09); -} -.datasetIntroTitle { - margin: 37px 0 10px 0; - color: #1d1d20; - font-size: 15px; -} -.datasetIntroText { - margin-bottom: 30px; - color: #575757; - font-size: 14px; -} -.datasetBox { - background: #f9fafb; - - :global { - .ant-tabs-top > .ant-tabs-nav { - margin: 0; - } - .ant-pagination { - text-align: right; - } - } -} - -.plusButton { - margin: 0 18px 0 20px; -} - -.tipContent { - margin-top: 5px; - color: #c73131; -} diff --git a/react-ui/src/pages/Dataset/intro.tsx b/react-ui/src/pages/Dataset/intro.tsx new file mode 100644 index 00000000..6a9e14ec --- /dev/null +++ b/react-ui/src/pages/Dataset/intro.tsx @@ -0,0 +1,8 @@ +import ResourceIntro from '@/pages/Dataset/components/ResourceIntro'; +import { ResourceType } from '@/pages/Dataset/config'; + +function DatasetIntro() { + return ; +} + +export default DatasetIntro; diff --git a/react-ui/src/pages/Experiment/index.less b/react-ui/src/pages/Experiment/index.less index 0a1bed49..5b453d45 100644 --- a/react-ui/src/pages/Experiment/index.less +++ b/react-ui/src/pages/Experiment/index.less @@ -86,7 +86,7 @@ } .experimentBox { - height: calc(100% - 20px); + height: 100%; .experimentTable { height: calc(100% - 60px); :global { diff --git a/react-ui/src/pages/Model/components/ModelEvolution/index.less b/react-ui/src/pages/Model/components/ModelEvolution/index.less new file mode 100644 index 00000000..e69de29b diff --git a/react-ui/src/pages/Model/components/ModelEvolution/index.tsx b/react-ui/src/pages/Model/components/ModelEvolution/index.tsx new file mode 100644 index 00000000..e69de29b diff --git a/react-ui/src/pages/Model/intro.jsx b/react-ui/src/pages/Model/intro.jsx deleted file mode 100644 index d315743f..00000000 --- a/react-ui/src/pages/Model/intro.jsx +++ /dev/null @@ -1,262 +0,0 @@ -import KFIcon from '@/components/KFIcon'; -import AddVersionModal from '@/pages/Dataset/components/AddVersionModal'; -import { ResourceType } from '@/pages/Dataset/config'; -import { - deleteModelVersion, - getModelById, - getModelVersionIdList, - getModelVersionsById, -} from '@/services/dataset/index.js'; -import { formatDate } from '@/utils/date'; -import { downLoadZip } from '@/utils/downloadfile'; -import { openAntdModal } from '@/utils/modal'; -import { modalConfirm } from '@/utils/ui'; -import { useParams, useSearchParams } from '@umijs/max'; -import { App, Button, Input, Select, Table, Tabs } from 'antd'; -import { useEffect, useRef, useState } from 'react'; -import Styles from './intro.less'; -const { Search } = Input; -const { TabPane } = Tabs; - -const Dataset = () => { - const [formList, setFormList] = useState([]); - const [datasetDetailObj, setDatasetDetailObj] = useState({}); - const [version, setVersion] = useState(null); - const [versionList, setVersionList] = useState([]); - const locationParams = useParams(); //新版本获取路由参数接口 - const [searchParams] = useSearchParams(); - const [wordList, setWordList] = useState([]); - const { message } = App.useApp(); - const isPublic = searchParams.get('isPublic') === 'true'; - - const getModelByDetail = () => { - getModelById(locationParams.id).then((ret) => { - console.log(ret); - setDatasetDetailObj(ret.data); - }); - }; - const getModelVersionsList = () => { - getModelVersionsById(locationParams.id).then((ret) => { - console.log(ret); - if (ret && ret.data && ret.data.length > 0) { - setVersionList( - ret.data.map((item) => { - return { - label: item, - value: item, - }; - }), - ); - setVersion(ret.data[0]); - getModelVersions({ version: ret.data[0], models_id: locationParams.id }); - } else { - setVersion(null); - setWordList([]); - } - }); - }; - useEffect(() => { - getModelByDetail(); - getModelVersionsList(); - return () => {}; - }, []); - const showModal = () => { - const { close } = openAntdModal(AddVersionModal, { - resourceType: ResourceType.Model, - resourceId: locationParams.id, - initialName: datasetDetailObj.name, - onOk: () => { - getModelVersionsList(); - close(); - }, - }); - }; - - const deleteDataset = () => { - modalConfirm({ - title: '删除后,该版本将不可恢复', - content: '是否确认删除?', - okText: '确认', - cancelText: '取消', - - onOk: () => { - deleteModelVersion({ models_id: locationParams.id, version }).then((ret) => { - getModelVersionsList(); - message.success('删除成功'); - }); - }, - }); - }; - - const getModelVersions = (params) => { - getModelVersionIdList(params).then((ret) => { - setWordList(ret?.data?.content ?? []); - }); - }; - const handleExport = async () => { - const hide = message.loading('正在下载'); - hide(); - downLoadZip(`/api/mmp/models/downloadAllFiles`, { models_id: locationParams.id, version }); - }; - const downloadAlone = (e, record) => { - console.log(record); - const hide = message.loading('正在下载'); - hide(); - downLoadZip(`/api/mmp/models/download_model/${record.id}`); - }; - const handleChange = (value) => { - console.log(value); - if (value) { - getModelVersions({ version: value, models_id: locationParams.id }); - setVersion(value); - } else { - setVersion(''); - } - }; - - const columns = [ - { - title: '序号', - dataIndex: 'index', - key: 'index', - width: 80, - render(text, record, index) { - return {(pageOption.current.page - 1) * 10 + index + 1}; - }, - // render: (text, record, index) => `${((curPage-1)*10)+(index+1)}`, - }, - { - title: '文件名称', - dataIndex: 'file_name', - key: 'file_name', - render: (text, record) => downloadAlone(e, record)}>{text}, - }, - { - title: '版本号', - dataIndex: 'version', - key: 'version', - }, - { - title: '文件大小', - dataIndex: 'file_size', - key: 'file_size', - }, - { - title: '更新时间', - dataIndex: 'update_time', - key: 'update_time', - render: (text) => {formatDate(text)}, - }, - { - title: '操作', - dataIndex: 'option', - width: '100px', - key: 'option', - render: (_, record) => [ - , - ], - }, - ]; - const pageOption = useRef({ page: 1, size: 10 }); - - // 当前页面切换 - const paginationChange = async (current, size) => { - console.log('page', current, size); - pageOption.current = { - page: current, - size: size, - }; - // getList() - }; - return ( -
-
- {datasetDetailObj.name} -
-
模型 id:{datasetDetailObj.id}
-
{datasetDetailObj.model_type_name || '...'}
-
{datasetDetailObj.model_tag_name || '...'}
-
-
-
- - -
简介
-
{datasetDetailObj.description}
-
- -
-
模型列表
-
-
- 版本号: -
- - - - - - ); -}; -export default Dataset; diff --git a/react-ui/src/pages/Model/intro.less b/react-ui/src/pages/Model/intro.less deleted file mode 100644 index b40d4a2b..00000000 --- a/react-ui/src/pages/Model/intro.less +++ /dev/null @@ -1,80 +0,0 @@ -.datasetIntroTopBox { - display: flex; - flex-direction: column; - justify-content: space-between; - width: 100%; - height: 110px; - margin-bottom: 10px; - padding: 25px 30px; - background-image: url(/assets/images/dataset-back.png); - background-repeat: no-repeat; - background-position: top center; - background-size: 100% 100%; - - .smallTagBox { - display: flex; - align-items: center; - color: #1664ff; - font-size: 14px; - .tagItem { - margin-right: 20px; - padding: 4px 10px; - background: rgba(22, 100, 255, 0.1); - border-radius: 4px; - } - } -} -.dataListBox { - padding: 20px 30px; - color: #1d1d20; - font-size: 16px; - background: #ffffff; - border-radius: 10px; - box-shadow: 0px 2px 12px rgba(180, 182, 191, 0.09); - .dataButtonList { - display: flex; - align-items: center; - justify-content: space-between; - height: 32px; - margin: 24px 0 30px 0; - color: #575757; - font-size: 16px; - } -} -.datasetIntroCneterBox { - height: 77vh; - padding: 20px 30px; - background: #ffffff; - border-radius: 10px; - box-shadow: 0px 2px 12px rgba(180, 182, 191, 0.09); -} -.datasetIntroTitle { - margin: 37px 0 10px 0; - color: #1d1d20; - font-size: 15px; -} -.datasetIntroText { - margin-bottom: 30px; - color: #575757; - font-size: 14px; -} -.datasetBox { - font-family: 'Alibaba'; - background: #f9fafb; - :global { - .ant-tabs-top > .ant-tabs-nav { - margin: 0; - } - .ant-pagination { - text-align: right; - } - } -} -.plusButton { - margin: 0 18px 0 20px; -} - -.tipContent { - margin-top: 5px; - color: #c73131; -} diff --git a/react-ui/src/pages/Model/intro.tsx b/react-ui/src/pages/Model/intro.tsx new file mode 100644 index 00000000..6e62d53a --- /dev/null +++ b/react-ui/src/pages/Model/intro.tsx @@ -0,0 +1,8 @@ +import ResourceIntro from '@/pages/Dataset/components/ResourceIntro'; +import { ResourceType } from '@/pages/Dataset/config'; + +function ModelIntro() { + return ; +} + +export default ModelIntro; diff --git a/react-ui/src/pages/Pipeline/index.less b/react-ui/src/pages/Pipeline/index.less index e1808690..78b30dd4 100644 --- a/react-ui/src/pages/Pipeline/index.less +++ b/react-ui/src/pages/Pipeline/index.less @@ -13,7 +13,7 @@ } .PipelineBox { - height: calc(100% - 20px); + height: 100%; .PipelineTable { height: calc(100% - 60px); :global { diff --git a/react-ui/src/utils/downloadfile.ts b/react-ui/src/utils/downloadfile.ts index 3a185844..ee56962e 100644 --- a/react-ui/src/utils/downloadfile.ts +++ b/react-ui/src/utils/downloadfile.ts @@ -29,7 +29,7 @@ export function resolveBlob(res: any, mimeType: string) { document.body.removeChild(aLink); } -export function downLoadZip(url: string, params: any) { +export function downLoadZip(url: string, params?: any) { request(url, { method: 'GET', params,