diff --git a/react-ui/package.json b/react-ui/package.json index 1534f112..ac2bc997 100644 --- a/react-ui/package.json +++ b/react-ui/package.json @@ -57,6 +57,7 @@ "@ant-design/pro-components": "^2.4.4", "@ant-design/use-emotion-css": "1.0.4", "@antv/g6": "^4.8.24", + "@antv/hierarchy": "^0.6.12", "@umijs/route-utils": "^4.0.1", "antd": "^5.4.4", "classnames": "^2.3.2", diff --git a/react-ui/src/app.tsx b/react-ui/src/app.tsx index 7d928861..3b468859 100644 --- a/react-ui/src/app.tsx +++ b/react-ui/src/app.tsx @@ -21,6 +21,7 @@ import './styles/menu.less'; export { requestConfig as request } from './requestConfig'; // const isDev = process.env.NODE_ENV === 'development'; import { menuItemRender } from '@/utils/menuRender'; +import { gotoLoginPage } from './utils/ui'; /** * @see https://umijs.org/zh-CN/plugins/plugin-initial-state * */ @@ -45,7 +46,7 @@ export async function getInitialState(): Promise<{ } as API.CurrentUser; } catch (error) { console.log(error); - history.push(PageEnum.LOGIN); + gotoLoginPage(); } return undefined; }; @@ -97,7 +98,7 @@ export const layout: RuntimeConfig['layout'] = ({ initialState }) => { const { location } = history; // 如果没有登录,重定向到 login if (!initialState?.currentUser && location.pathname !== PageEnum.LOGIN) { - history.push(PageEnum.LOGIN); + gotoLoginPage(); } }, layoutBgImgList: [ diff --git a/react-ui/src/hooks/index.ts b/react-ui/src/hooks/index.ts index 1d56a24d..b34d5156 100644 --- a/react-ui/src/hooks/index.ts +++ b/react-ui/src/hooks/index.ts @@ -1,7 +1,7 @@ /* * @Author: 赵伟 * @Date: 2024-04-15 10:01:29 - * @Description: + * @Description: 自定义 hooks */ import { FormInstance } from 'antd'; import { debounce } from 'lodash'; @@ -126,3 +126,28 @@ export const useResetFormOnCloseModal = (form: FormInstance, open: boolean) => { } }, [form, prevOpen, open]); }; + +/** + * Executes the effect function when the specified condition is true. + * + * @param effect - The effect function to execute. + * @param deps - The dependencies for the effect. + * @param when - The condition to trigger the effect. + */ +export const useEffectWhen = (effect: () => void, deps: React.DependencyList, when: boolean) => { + const requestFns = useRef<(() => void)[]>([]); + useEffect(() => { + if (when) { + effect(); + } else { + requestFns.current.splice(0, 1, effect); + } + }, deps); + + useEffect(() => { + if (when) { + const fn = requestFns.current.pop(); + fn?.(); + } + }, [when]); +}; diff --git a/react-ui/src/pages/Dataset/components/ResourceIntro/index.less b/react-ui/src/pages/Dataset/components/ResourceIntro/index.less index cff0a9e5..3c4fcae4 100644 --- a/react-ui/src/pages/Dataset/components/ResourceIntro/index.less +++ b/react-ui/src/pages/Dataset/components/ResourceIntro/index.less @@ -2,13 +2,10 @@ height: 100%; &__top { - display: flex; - flex-direction: column; - justify-content: space-between; width: 100%; height: 110px; margin-bottom: 10px; - padding: 25px 30px; + padding: 20px 30px 0; background-image: url(/assets/images/dataset-back.png); background-repeat: no-repeat; background-position: top center; @@ -17,7 +14,7 @@ &__name { margin-bottom: 12px; color: @text-color; - font-size: 20; + font-size: 20px; } &__tag { @@ -36,6 +33,22 @@ background: #ffffff; border-radius: 10px; box-shadow: 0px 2px 12px rgba(180, 182, 191, 0.09); + + :global { + .ant-tabs { + height: 100%; + .ant-tabs-content-holder { + height: 100%; + .ant-tabs-content { + height: 100%; + .ant-tabs-tabpane { + height: 100%; + overflow-y: auto; + } + } + } + } + } } &__title { diff --git a/react-ui/src/pages/Dataset/components/ResourceIntro/index.tsx b/react-ui/src/pages/Dataset/components/ResourceIntro/index.tsx index 813abdb5..c057a64a 100644 --- a/react-ui/src/pages/Dataset/components/ResourceIntro/index.tsx +++ b/react-ui/src/pages/Dataset/components/ResourceIntro/index.tsx @@ -1,3 +1,4 @@ +import ModelEvolution from '@/pages/Model/components/ModelEvolution'; import { to } from '@/utils/promise'; import { useParams, useSearchParams } from '@umijs/max'; import { Flex, Tabs } from 'antd'; @@ -10,16 +11,27 @@ type ResourceIntroProps = { resourceType: ResourceType; }; +enum TabKeys { + Introduction = '1', + Version = '2', + Evolution = '3', +} + const ResourceIntro = ({ resourceType }: ResourceIntroProps) => { const [info, setInfo] = useState({} as ResourceData); - const locationParams = useParams(); //新版本获取路由参数接口 + const locationParams = useParams(); const [searchParams] = useSearchParams(); - const isPublic = searchParams.get('isPublic') === 'true'; + const defaultTab = searchParams.get('tab') || '1'; + let versionParam = searchParams.get('version'); + const [versionList, setVersionList] = useState([]); + const [version, setVersion] = useState(undefined); + const [activeTab, setActiveTab] = useState(defaultTab); const resourceId = Number(locationParams.id); - const name = resourceConfig[resourceType].name; + const typeName = resourceConfig[resourceType].name; // 数据集/模型 useEffect(() => { getModelByDetail(); + getVersionList(); }, []); // 获取详情 @@ -31,10 +43,39 @@ const ResourceIntro = ({ resourceType }: ResourceIntroProps) => { } }; + // 获取版本列表 + 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, + }; + }), + ); + if (versionParam) { + setVersion(versionParam); + versionParam = null; + } else { + setVersion(res.data[0]); + } + } else { + setVersion(undefined); + } + }; + + // 版本变化 + const handleVersionChange = (value: string) => { + setVersion(value); + }; + const items = [ { - key: '1', - label: `${name}简介`, + key: TabKeys.Introduction, + label: `${typeName}简介`, children: ( <>
简介
@@ -43,19 +84,41 @@ const ResourceIntro = ({ resourceType }: ResourceIntroProps) => { ), }, { - key: '2', - label: `${name}文件/版本`, + key: TabKeys.Version, + label: `${typeName}文件/版本`, children: ( ), }, ]; + if (resourceType === ResourceType.Model) { + items.push({ + key: TabKeys.Evolution, + label: `模型演化`, + children: ( + + ), + }); + } + const infoTypePropertyName = resourceConfig[resourceType] .infoTypePropertyName as keyof ResourceData; const infoTagPropertyName = resourceConfig[resourceType] @@ -64,21 +127,25 @@ const ResourceIntro = ({ resourceType }: ResourceIntroProps) => { return (
- {info.name} +
{info.name}
- {name} id:{info.id} -
-
- {info[infoTypePropertyName] || '--'} -
-
- {info[infoTagPropertyName] || '--'} + {typeName} id:{info.id}
+ {info[infoTypePropertyName] && ( +
+ {info[infoTypePropertyName] || '--'} +
+ )} + {info[infoTagPropertyName] && ( +
+ {info[infoTagPropertyName] || '--'} +
+ )}
- + setActiveTab(key)}>
); diff --git a/react-ui/src/pages/Dataset/components/ResourceList/index.tsx b/react-ui/src/pages/Dataset/components/ResourceList/index.tsx index acfd9fdb..830a9e1c 100644 --- a/react-ui/src/pages/Dataset/components/ResourceList/index.tsx +++ b/react-ui/src/pages/Dataset/components/ResourceList/index.tsx @@ -130,7 +130,7 @@ function ResourceList( activeTag: dataTag, }); const prefix = resourceConfig[resourceType].prefix; - navigate(`/dataset/${prefix}/${record.id}?isPublic=${isPublic}`); + navigate(`/dataset/${prefix}/${record.id}`); }; // 分页切换 diff --git a/react-ui/src/pages/Dataset/components/ResourceVersion/index.tsx b/react-ui/src/pages/Dataset/components/ResourceVersion/index.tsx index 08035fdf..7871f5ef 100644 --- a/react-ui/src/pages/Dataset/components/ResourceVersion/index.tsx +++ b/react-ui/src/pages/Dataset/components/ResourceVersion/index.tsx @@ -1,15 +1,20 @@ import CommonTableCell from '@/components/CommonTableCell'; import DateTableCell from '@/components/DateTableCell'; import KFIcon from '@/components/KFIcon'; +import { useEffectWhen } from '@/hooks'; import AddVersionModal from '@/pages/Dataset/components/AddVersionModal'; -import { ResourceType } from '@/pages/Dataset/config'; +import { + ResourceFileData, + ResourceType, + ResourceVersionData, + resourceConfig, +} 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 { useState } from 'react'; import styles from './index.less'; type ResourceVersionProps = { @@ -17,42 +22,38 @@ type ResourceVersionProps = { resourceId: number; resourceName: string; isPublic: boolean; + versionList: ResourceVersionData[]; + version?: string; + isActive: boolean; + getVersionList: () => void; + onVersionChange: (version: string) => void; }; function ResourceVersion({ resourceType, resourceId, resourceName, isPublic, + versionList, + version, + isActive, + getVersionList, + onVersionChange, }: 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([]); - } - }; + // 获取版本文件列表 + useEffectWhen( + () => { + if (version) { + getFileList(version); + } else { + setFileList([]); + } + }, + [resourceId, version], + isActive, + ); // 获取版本下的文件列表 const getFileList = async (version: string) => { @@ -120,16 +121,6 @@ function ResourceVersion({ downLoadZip(`${url}/${record.id}`); }; - // 版本变化 - const handleChange = (value: string) => { - if (value) { - getFileList(value); - setVersion(value); - } else { - setVersion(undefined); - } - }; - const columns = [ { title: '序号', @@ -194,8 +185,7 @@ function ResourceVersion({ placeholder="请选择版本号" style={{ width: '160px', marginRight: '20px' }} value={version} - allowClear - onChange={handleChange} + onChange={onVersionChange} options={versionList} /> )}