diff --git a/react-ui/src/pages/Home/components/CodeConfig/index.less b/react-ui/src/pages/Home/components/CodeConfig/index.less new file mode 100644 index 00000000..73435c0b --- /dev/null +++ b/react-ui/src/pages/Home/components/CodeConfig/index.less @@ -0,0 +1,68 @@ +.dataset { + position: relative; + display: flex; + flex-direction: column; + align-items: center; + padding: 0 16.25rem 3.125rem; + .backgroundFullImage(url(@/assets/img/home/model-bg.png)); + + &__item { + position: relative; + width: 27.875rem; + padding: 1.875rem 1.25rem; + color: #8284a4; + font-size: 0.8125rem; + background-color: transparent; + border-radius: 11px; + cursor: pointer; + .backgroundFullImage(url(@/assets/img/home/dataset-item-bg.png)); + + &:hover { + .backgroundFullImage(url(@/assets/img/home/dataset-item-bg-hover.png)); + } + + &__user-avatar { + flex: none; + width: 2.75rem; + height: 2.75rem; + margin-right: 1rem; + } + + &__title { + flex: 1; + color: #020814; + font-size: 1rem; + .singleLine(); + } + + &:hover &__title { + color: @primary-color; + } + + &__arrow { + display: none; + flex: none; + width: 1.5625rem; + margin-left: 0.75rem; + } + + &:hover &__arrow { + display: block; + } + + &__desc { + height: 2.75rem; + margin-bottom: 0.875rem; + font-size: 0.875rem; + line-height: 1.375rem; + .multiLine(2); + } + + &__user-divider { + height: 0.625rem; + margin-right: 0.75rem; + margin-left: 0.75rem; + background-color: #8284a4; + } + } +} diff --git a/react-ui/src/pages/Home/components/CodeConfig/index.tsx b/react-ui/src/pages/Home/components/CodeConfig/index.tsx new file mode 100644 index 00000000..9b755683 --- /dev/null +++ b/react-ui/src/pages/Home/components/CodeConfig/index.tsx @@ -0,0 +1,77 @@ +import { CodeConfigData } from '@/components/CodeSelectorModal'; +import { getPublicCodeConfigsReq } from '@/services/home'; +import { getGitUrl } from '@/utils'; +import { formatDate } from '@/utils/date'; +import { to } from '@/utils/promise'; +import { useNavigate } from '@umijs/max'; +import { Divider, Flex } from 'antd'; +import { useEffect, useState } from 'react'; +import BlockTitle from '../BlockTitle'; +import styles from './index.less'; + +function CodeConfig() { + const navigate = useNavigate(); + const [codeCofigs, setCodeConfigs] = useState([]); + + useEffect(() => { + const getPublicCodeConfigs = async () => { + const [res] = await to(getPublicCodeConfigsReq()); + if (res && res.data) { + const { content = [] } = res.data; + setCodeConfigs(content.slice(0, 6)); + } + }; + + getPublicCodeConfigs(); + }, []); + + return ( +
+ navigate('/dataset/codeConfig')} + > + + {codeCofigs.map((item) => { + return ( + { + const url = getGitUrl(item.git_url, item.git_branch); + window.open(url, '_blank'); + }} + > + +
+ +
{item.code_repo_name}
+ +
+
{item.git_url}
+ +
{item.create_by}
+ +
{formatDate(item.create_time)}
+
+
+
+
+ ); + })} +
+
+ ); +} + +export default CodeConfig; diff --git a/react-ui/src/pages/Home/components/Dataset/index.less b/react-ui/src/pages/Home/components/Dataset/index.less index d3d82861..1467aa50 100644 --- a/react-ui/src/pages/Home/components/Dataset/index.less +++ b/react-ui/src/pages/Home/components/Dataset/index.less @@ -3,15 +3,12 @@ display: flex; flex-direction: column; align-items: center; - padding: 0 16.25rem 3.125rem; - background-image: url(@/assets/img/home/model-bg.png); - background-repeat: no-repeat; - background-position: top 6.375rem left 0; - background-size: 100% 100%; + padding: 0 16.25rem 9.125rem; + .backgroundFullImage(url(@/assets/img/home/model-bg.png)); &__item { position: relative; - width: 42.75rem; + width: 27.875rem; padding: 1.875rem 1.25rem; color: #8284a4; font-size: 0.8125rem; diff --git a/react-ui/src/pages/Home/components/Dataset/index.tsx b/react-ui/src/pages/Home/components/Dataset/index.tsx index b2004bd2..fedb4049 100644 --- a/react-ui/src/pages/Home/components/Dataset/index.tsx +++ b/react-ui/src/pages/Home/components/Dataset/index.tsx @@ -1,55 +1,28 @@ +import { DatasetData } from '@/pages/Dataset/config'; +import { getPublicDatasetsReq } from '@/services/home'; +import { to } from '@/utils/promise'; import { useNavigate } from '@umijs/max'; import { Divider, Flex } from 'antd'; +import { useEffect, useState } from 'react'; import BlockTitle from '../BlockTitle'; import styles from './index.less'; -const datasetData = [ - { - id: 1, - title: '材料大数据与机器学习', - desc: '在材料科学与人工智能交叉融合的当下', - user: '陈绮贞', - date: '18小时前更新', - }, - { - id: 2, - title: '材料大数据与机器学习', - desc: '在材料科学与人工智能交叉融合的当下,机器学习技术正逐步成为材料研究的重要工具。', - user: '陈绮贞', - date: '18小时前更新', - }, - { - id: 3, - title: '材料大数据与机器学习材料大数据与机器学习材料大数据与机器学习', - desc: '在材料科学与人工智能交叉融合的当下,机器学习技术正逐步成为材料研究的重要工具。在材料科学与人工智能交叉融合的当下,机器学习技术正逐步成为材料研究的重要工具在材料科学与人工智能交叉融合的当下,机器学习技术正逐步成为材料研究的重要工具', - user: '陈绮贞', - date: '18小时前更新', - }, - { - id: 4, - title: '材料大数据与机器学习', - desc: '在材料科学与人工智能交叉融合的当下,机器学习技术正逐步成为材料研究的重要工具。本课程为2025年新', - user: '陈绮贞', - date: '18小时前更新', - }, - { - id: 5, - title: '材料大数据与机器学习', - desc: '在材料科学与人工智能交叉融合的当下,机器学习技术正逐步成为材料研究的重要工具。本课程为2025年新', - user: '陈绮贞', - date: '18小时前更新', - }, - { - id: 6, - title: '材料大数据与机器学习', - desc: '在材料科学与人工智能交叉融合的当下,机器学习技术正逐步成为材料研究的重要工具。本课程为2025年新', - user: '陈绮贞', - date: '18小时前更新', - }, -]; - function DatasetBlock() { const navigate = useNavigate(); + const [datasetData, setDatasetData] = useState([]); + + useEffect(() => { + const getPublicDatasets = async () => { + const [res] = await to(getPublicDatasetsReq()); + if (res && res.data) { + const { content = [] } = res.data; + setDatasetData(content.slice(0, 6)); + } + }; + + getPublicDatasets(); + }, []); + return (
{datasetData.map((item) => { return ( - + { + navigate( + `/dataset/dataset/info/${item.id}?name=${item.name}&owner=${item.owner}&identifier=${item.identifier}&is_public=${item.is_public}`, + ); + }} + >
-
{item.title}
+
{item.name}
-
{item.desc}
+
{item.description}
-
{item.user}
+
{item.create_by}
-
{item.date}
+
{item.time_ago}更新
diff --git a/react-ui/src/pages/Home/components/Intro/index.less b/react-ui/src/pages/Home/components/Intro/index.less index 53144be9..6efeec56 100644 --- a/react-ui/src/pages/Home/components/Intro/index.less +++ b/react-ui/src/pages/Home/components/Intro/index.less @@ -4,7 +4,7 @@ display: flex; flex-direction: column; align-items: center; - padding-top: 8.375rem; + padding-top: 5.625rem; background-image: url(@/assets/img/home/header-bg.png); background-repeat: no-repeat; background-position: left top; diff --git a/react-ui/src/pages/Home/components/Mirror/index.less b/react-ui/src/pages/Home/components/Mirror/index.less new file mode 100644 index 00000000..7683af78 --- /dev/null +++ b/react-ui/src/pages/Home/components/Mirror/index.less @@ -0,0 +1,67 @@ +.model { + position: relative; + display: flex; + flex-direction: column; + align-items: center; + padding: 0 16.25rem 9.125rem; + .backgroundFullImage(url(@/assets/img/home/model-bg.png)); + + &__item { + position: relative; + width: 27.875rem; + padding: 1.875rem 1.25rem; + color: #8284a4; + font-size: 0.8125rem; + background-color: transparent; + border-radius: 11px; + box-shadow: 0rem 0.0625rem 0.75rem rgba(33, 73, 212, 0.09); + cursor: pointer; + .backgroundFullImage(url(@/assets/img/home/model-item-bg.png)); + + &:hover { + color: white; + .backgroundFullImage(url(@/assets/img/home/model-item-bg-hover.png)); + } + + &:nth-child(3n + 2) { + top: -3.75rem; + } + + &__user-avatar { + flex: none; + width: 2.75rem; + height: 2.75rem; + margin-right: 0.875rem; + } + + &__title { + margin-bottom: 0.625rem; + color: #020814; + font-size: 1rem; + .singleLine(); + } + + &:hover &__title { + color: white; + } + + &__desc { + height: 2.75rem; + margin-bottom: 0.875rem; + font-size: 0.875rem; + line-height: 1.375rem; + .multiLine(2); + } + + &__user-divider { + height: 0.625rem; + margin-right: 0.75rem; + margin-left: 0.75rem; + background-color: #8284a4; + } + + &:hover &__user-divider { + background-color: white; + } + } +} diff --git a/react-ui/src/pages/Home/components/Mirror/index.tsx b/react-ui/src/pages/Home/components/Mirror/index.tsx new file mode 100644 index 00000000..cb933c55 --- /dev/null +++ b/react-ui/src/pages/Home/components/Mirror/index.tsx @@ -0,0 +1,69 @@ +import { MirrorData } from '@/pages/Mirror/List'; +import { getPublicImagesReq } from '@/services/home'; +import { formatDate } from '@/utils/date'; +import { to } from '@/utils/promise'; +import { useNavigate } from '@umijs/max'; +import { Divider, Flex } from 'antd'; +import { useEffect, useState } from 'react'; +import BlockTitle from '../BlockTitle'; +import styles from './index.less'; + +function MirrorBlock() { + const navigate = useNavigate(); + const [mirrorData, setMirrirData] = useState([]); + + useEffect(() => { + const getPublicImages = async () => { + const [res] = await to(getPublicImagesReq()); + if (res && res.data) { + const { content = [] } = res.data; + setMirrirData(content.slice(0, 6)); + } + }; + + getPublicImages(); + }, []); + + return ( +
+ navigate('/dataset/mirror')} + > + + {mirrorData.map((item) => { + return ( + { + navigate(`/dataset/mirror/info/${item.id}`); + }} + > + +
+
{item.name}
+
{item.description}
+ +
{item.create_by}
+ +
{formatDate(item.create_time)}
+
+
+
+
+ ); + })} +
+
+ ); +} + +export default MirrorBlock; diff --git a/react-ui/src/pages/Home/components/Model/index.tsx b/react-ui/src/pages/Home/components/Model/index.tsx index 556da2be..07380dbc 100644 --- a/react-ui/src/pages/Home/components/Model/index.tsx +++ b/react-ui/src/pages/Home/components/Model/index.tsx @@ -1,55 +1,28 @@ +import { ModelData } from '@/pages/Dataset/config'; +import { getPublicModelsReq } from '@/services/home'; +import { to } from '@/utils/promise'; import { useNavigate } from '@umijs/max'; import { Divider, Flex } from 'antd'; +import { useEffect, useState } from 'react'; import BlockTitle from '../BlockTitle'; import styles from './index.less'; -const modelData = [ - { - id: 1, - title: '材料大数据与机器学习', - desc: '在材料科学与人工智能交叉融合的当下', - user: '陈绮贞', - date: '18小时前更新', - }, - { - id: 2, - title: '材料大数据与机器学习', - desc: '在材料科学与人工智能交叉融合的当下,机器学习技术正逐步成为材料研究的重要工具。', - user: '陈绮贞', - date: '18小时前更新', - }, - { - id: 3, - title: '材料大数据与机器学习材料大数据与机器学习材料大数据与机器学习', - desc: '在材料科学与人工智能交叉融合的当下,机器学习技术正逐步成为材料研究的重要工具。在材料科学与人工智能交叉融合的当下,机器学习技术正逐步成为材料研究的重要工具在材料科学与人工智能交叉融合的当下,机器学习技术正逐步成为材料研究的重要工具', - user: '陈绮贞', - date: '18小时前更新', - }, - { - id: 4, - title: '材料大数据与机器学习', - desc: '在材料科学与人工智能交叉融合的当下,机器学习技术正逐步成为材料研究的重要工具。本课程为2025年新', - user: '陈绮贞', - date: '18小时前更新', - }, - { - id: 5, - title: '材料大数据与机器学习', - desc: '在材料科学与人工智能交叉融合的当下,机器学习技术正逐步成为材料研究的重要工具。本课程为2025年新', - user: '陈绮贞', - date: '18小时前更新', - }, - { - id: 6, - title: '材料大数据与机器学习', - desc: '在材料科学与人工智能交叉融合的当下,机器学习技术正逐步成为材料研究的重要工具。本课程为2025年新', - user: '陈绮贞', - date: '18小时前更新', - }, -]; - function ModelBlock() { const navigate = useNavigate(); + const [modelData, setModelData] = useState([]); + + useEffect(() => { + const getPublicModels = async () => { + const [res] = await to(getPublicModelsReq()); + if (res && res.data) { + const { content = [] } = res.data; + setModelData(content.slice(0, 6)); + } + }; + + getPublicModels(); + }, []); + return (
{modelData.map((item) => { return ( - + { + navigate( + `/dataset/model/info/${item.id}?name=${item.name}&owner=${item.owner}&identifier=${item.identifier}&is_public=${item.is_public}`, + ); + }} + >
-
{item.title}
-
{item.desc}
+
{item.name}
+
{item.description}
-
{item.user}
+
{item.create_by}
-
{item.date}
+
{item.time_ago}更新
diff --git a/react-ui/src/pages/Home/components/Service/index.less b/react-ui/src/pages/Home/components/Service/index.less index 5c28cb0b..62ea8fa9 100644 --- a/react-ui/src/pages/Home/components/Service/index.less +++ b/react-ui/src/pages/Home/components/Service/index.less @@ -31,9 +31,6 @@ &__image { width: 100%; height: 100%; - background-repeat: no-repeat; - background-position: top left; - background-size: 100% 100%; transform: scale(1); transition: transform 0.3s linear; } diff --git a/react-ui/src/pages/Home/components/Service/index.tsx b/react-ui/src/pages/Home/components/Service/index.tsx index 4b97e48c..de70e411 100644 --- a/react-ui/src/pages/Home/components/Service/index.tsx +++ b/react-ui/src/pages/Home/components/Service/index.tsx @@ -3,7 +3,8 @@ import ServiceImg2 from '@/assets/img/home/service2.png'; import ServiceImg3 from '@/assets/img/home/service3.png'; import ServiceImg4 from '@/assets/img/home/service4.png'; import { type ServiceData } from '@/pages/ModelDeployment/types'; -import { getAssetPublicCountReq } from '@/services/home'; +import { getPublicServicesReq } from '@/services/home'; +import { formatDate } from '@/utils/date'; import { to } from '@/utils/promise'; import { useNavigate } from '@umijs/max'; import { Flex } from 'antd'; @@ -11,73 +12,21 @@ import { useEffect, useState } from 'react'; import BlockTitle from '../BlockTitle'; import styles from './index.less'; -const serviceData1 = [ - { - id: 1, - img: ServiceImg1, - title: 'MD是研究原子间相互作用的基本工具', - user: '陈绮贞', - date: '18小时前更新', - }, - { - id: 2, - img: ServiceImg2, - title: 'MD是研究原子间相互作用的基本工具 原子间相互作用势函数 通常基于力场或者量子', - user: '陈绮贞', - date: '18小时前更新', - }, - { - id: 3, - img: ServiceImg3, - title: 'MD是研究原子间相互作用的基本工具 原子间相互作用势函数 通常基于力场或者量子', - user: '陈绮贞', - date: '18小时前更新', - }, - { - id: 4, - img: ServiceImg4, - title: - 'MD是研究原子间相互作用的基本工具 原子间相互作用势函数 通常基于力场或者量子 通常基于力场或者量子 通常基于力场或者量子', - user: '陈绮贞', - date: '18小时前更新', - }, -]; - function ServiceBlock() { const navigate = useNavigate(); const [serviceData, setServiceData] = useState([]); + const images = [ServiceImg1, ServiceImg2, ServiceImg3, ServiceImg4]; + useEffect(() => { - const getAssetPublicCount = async () => { - const [res] = await to(getAssetPublicCountReq()); + const getPublicServices = async () => { + const [res] = await to(getPublicServicesReq()); if (res && res.data) { - const { dataset, image, model, codeConfig, service } = res.data; - const items = [ - { - title: '数据集', - value: dataset, - }, - { - title: '模型', - value: model, - }, - { - title: '镜像', - value: image, - }, - { - title: '代码配置', - value: codeConfig, - }, - { - title: '服务', - value: service, - }, - ]; - //setServiceData(items); + const { content = [] } = res.data; + setServiceData(content.slice(0, 4)); } }; - getAssetPublicCount(); + getPublicServices(); }, []); return (
@@ -87,26 +36,30 @@ function ServiceBlock() { onClick={() => navigate('/dataset/modelDeployment')} > - {serviceData1.map((item) => { + {serviceData.map((item, index) => { return ( -
+
navigate(`/dataset/modelDeployment/serviceInfo/${item.id}`)} + >
-
{item.title}
+
{item.service_name}
-
{item.user}
+
{item.create_by}
-
{item.date}
+
{formatDate(item.create_time)}
); diff --git a/react-ui/src/pages/Home/components/Statistics/index.tsx b/react-ui/src/pages/Home/components/Statistics/index.tsx index 490a1e2a..953dde78 100644 --- a/react-ui/src/pages/Home/components/Statistics/index.tsx +++ b/react-ui/src/pages/Home/components/Statistics/index.tsx @@ -9,9 +9,35 @@ import { useEffect, useState } from 'react'; import styles from './index.less'; function StatisticsBlock() { - const [assetCounts, setAssetCounts] = useState<{ title: string; value: number; icon: string }[]>( - [], - ); + const [assetCounts, setAssetCounts] = useState< + { title: string; value: number | undefined; icon: string }[] + >([ + { + title: '数据集', + value: undefined, + icon: DatasetIcon, + }, + { + title: '模型', + value: undefined, + icon: ModelIcon, + }, + { + title: '镜像', + value: undefined, + icon: ImageIcon, + }, + { + title: '代码配置', + value: undefined, + icon: CodeIcon, + }, + { + title: '服务', + value: undefined, + icon: ServiceIcon, + }, + ]); useEffect(() => { const getAssetPublicCount = async () => { const [res] = await to(getAssetPublicCountReq()); @@ -58,7 +84,7 @@ function StatisticsBlock() {
-
{item.value}
+
{item.value ?? '--'}
{item.title}
diff --git a/react-ui/src/pages/Home/index.tsx b/react-ui/src/pages/Home/index.tsx index 22aa13fc..c275024a 100644 --- a/react-ui/src/pages/Home/index.tsx +++ b/react-ui/src/pages/Home/index.tsx @@ -1,5 +1,7 @@ +import CodeConfig from './components/CodeConfig'; import DatasetBlock from './components/Dataset'; import IntroBlock from './components/Intro'; +import MirrorBlock from './components/Mirror'; import ModelBlock from './components/Model'; import ServiceBlock from './components/Service'; import styles from './index.less'; @@ -16,6 +18,18 @@ function Home() { className={styles['home__separator']} > + + + +
); } diff --git a/react-ui/src/pages/Mirror/List/index.tsx b/react-ui/src/pages/Mirror/List/index.tsx index 0671261b..09127603 100644 --- a/react-ui/src/pages/Mirror/List/index.tsx +++ b/react-ui/src/pages/Mirror/List/index.tsx @@ -47,6 +47,7 @@ export type MirrorData = { name: string; description: string; create_time: string; + create_by: string; }; function MirrorList() { diff --git a/react-ui/src/pages/ModelDeployment/types.ts b/react-ui/src/pages/ModelDeployment/types.ts index fe06b84b..3423ce01 100644 --- a/react-ui/src/pages/ModelDeployment/types.ts +++ b/react-ui/src/pages/ModelDeployment/types.ts @@ -8,7 +8,7 @@ export type ServiceData = { service_type_name: string; // 服务类型中文 description: string; // 描述 version_count: number; // 版本数量 - created_by: string; + create_by: string; create_time: string; update_by: string; update_time: string; diff --git a/react-ui/src/services/home/index.ts b/react-ui/src/services/home/index.ts index 57875d00..fb790aa5 100644 --- a/react-ui/src/services/home/index.ts +++ b/react-ui/src/services/home/index.ts @@ -15,3 +15,53 @@ export function getAssetPublicCountReq() { }, }); } + +// 获取公开服务 +export function getPublicServicesReq() { + return request('/api/mmp/workspace/getPublicServices', { + method: 'GET', + headers: { + isToken: false, + }, + }); +} + +// 获取公开模型 +export function getPublicModelsReq() { + return request('/api/mmp/workspace/getPublicModels', { + method: 'GET', + headers: { + isToken: false, + }, + }); +} + +// 获取公开数据集 +export function getPublicDatasetsReq() { + return request('/api/mmp/workspace/getPublicDatasets', { + method: 'GET', + headers: { + isToken: false, + }, + }); +} + +// 获取代码配置 +export function getPublicCodeConfigsReq() { + return request('/api/mmp/workspace/getPublicCodeConfigs', { + method: 'GET', + headers: { + isToken: false, + }, + }); +} + +// 获取公开镜像 +export function getPublicImagesReq() { + return request('/api/mmp/workspace/getPublicImages', { + method: 'GET', + headers: { + isToken: false, + }, + }); +}