diff --git a/react-ui/config/config.ts b/react-ui/config/config.ts index 04ab330d..653f2a54 100644 --- a/react-ui/config/config.ts +++ b/react-ui/config/config.ts @@ -127,6 +127,8 @@ export default defineConfig({ headScripts: [ // 解决首次加载时白屏的问题 { src: '/scripts/loading.js', async: true }, + { src: '/scripts/resize.js', async: true }, + // { src: '/scripts/resize-breakpoint.js', async: true }, ], // links: [ // { diff --git a/react-ui/config/proxy.ts b/react-ui/config/proxy.ts index 50acb581..20769b3c 100644 --- a/react-ui/config/proxy.ts +++ b/react-ui/config/proxy.ts @@ -20,14 +20,14 @@ export default { // localhost:8000/api/** -> https://preview.pro.ant.design/api/** '/api/': { // 要代理的地址 - // 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.44:8082', - // target: 'http://172.20.32.150:8082', + // target: 'http://172.20.32.44:8082', + // target: 'http://172.20.32.164:8082', // 配置了这个可以从 http 代理到 https // 依赖 origin 的功能可能需要这个,比如 cookie changeOrigin: true, - pathRewrite: { '^/api': '' }, + // pathRewrite: { '^/api': '' }, }, '/profile/avatar/': { target: 'http://172.20.32.235:31213', diff --git a/react-ui/config/routes.ts b/react-ui/config/routes.ts index 199769fe..1a53fe8b 100644 --- a/react-ui/config/routes.ts +++ b/react-ui/config/routes.ts @@ -13,7 +13,20 @@ export default [ { path: '/', - redirect: '/workspace', + redirect: '/home', + }, + { + name: '首页', + path: '/home', + layout: false, + routes: [ + { + name: '首页', + path: '', + key: 'home', + component: './Home/index', + }, + ], }, { name: '工作空间', diff --git a/react-ui/public/fonts/WenYiHei.ttf b/react-ui/public/fonts/WenYiHei.ttf new file mode 100644 index 00000000..5e392798 Binary files /dev/null and b/react-ui/public/fonts/WenYiHei.ttf differ diff --git a/react-ui/public/fonts/YouSheBiaoTiHei.ttf b/react-ui/public/fonts/YouSheBiaoTiHei.ttf new file mode 100644 index 00000000..3729151a Binary files /dev/null and b/react-ui/public/fonts/YouSheBiaoTiHei.ttf differ diff --git a/react-ui/public/fonts/font.css b/react-ui/public/fonts/font.css index 012b9f59..cd3d6f12 100644 --- a/react-ui/public/fonts/font.css +++ b/react-ui/public/fonts/font.css @@ -1,6 +1,6 @@ @font-face { font-family: Alibaba; - src: url('./ALIBABA-PUHUITI-MEDIUM.TTF'); + src: url('./ALIBABA-PUHUITI-REGULAR.TTF'); font-display: swap; } @@ -10,4 +10,17 @@ url('./DingTalk-JinBuTi.woff') format('woff'), /* 兼容性较好的 woff */ url('./DingTalk-JinBuTi.ttf') format('truetype'); /* ttf 作为备选 */ font-display: swap; /* 优化页面加载时的字体显示 */ +} + +@font-face { + font-family: 'WenYiHei'; + src: url('./WenYiHei.ttf'); + font-display: swap; /* 优化页面加载时的字体显示 */ +} + + +@font-face { + font-family: 'YouSheBiaoTiHei'; + src: url('./YouSheBiaoTiHei.ttf'); + font-display: swap; /* 优化页面加载时的字体显示 */ } \ No newline at end of file diff --git a/react-ui/public/scripts/resize-breakpoint.js b/react-ui/public/scripts/resize-breakpoint.js new file mode 100644 index 00000000..f2c5f45e --- /dev/null +++ b/react-ui/public/scripts/resize-breakpoint.js @@ -0,0 +1,52 @@ +(function (doc, win) { + 'use strict'; + + // 配置项 + const config = { + // 断点设置(单位:px) + // 1440 1560 1680 1800 1920 2040 2160 2280 2400 2520 + breakpoints: [ + { minWidth: 2520, fontSize: 22 }, // 21 + { minWidth: 2280, fontSize: 20 }, // 19 + { minWidth: 2040, fontSize: 18 }, // 17 + { minWidth: 1800, fontSize: 16 }, // 15 + { minWidth: 1560, fontSize: 14 }, // 13 + { minWidth: 0, fontSize: 12 }, + ], + delay: 300 // 防抖延迟(ms) + }; + + const docEl = doc.documentElement; + const resizeEvt = 'orientationchange' in win ? 'orientationchange' : 'resize'; + let resizeTimeout; + + // 计算当前宽度对应的字体大小 + function calculateFontSize() { + const clientWidth = docEl.clientWidth || win.innerWidth; + if (!clientWidth) return; + + // 从大到小匹配断点 + const targetBreakpoint = config.breakpoints.find( + bp => clientWidth >= bp.minWidth + ); + + // 设置字体大小 + docEl.style.fontSize = targetBreakpoint.fontSize + 'px'; + + // 调试输出(可选) + console.debug('[REM-Resize]', + 'Width:', clientWidth + 'px', + 'Font-Size:', targetBreakpoint.fontSize + 'px'); + } + + // 防抖处理 + function handleResize() { + clearTimeout(resizeTimeout); + resizeTimeout = setTimeout(calculateFontSize, config.delay); + } + + calculateFontSize(); + + // 初始化监听 + win.addEventListener(resizeEvt, handleResize, false); +})(document, window); \ No newline at end of file diff --git a/react-ui/public/scripts/resize.js b/react-ui/public/scripts/resize.js new file mode 100644 index 00000000..8434654d --- /dev/null +++ b/react-ui/public/scripts/resize.js @@ -0,0 +1,44 @@ +// rem-resize.js +(function (doc, win) { + 'use strict'; + + // 配置项 + const config = { + designWidth: 1920, // 设计稿宽度 + baseFontSize: 16, // 基础字体大小(设计稿下1rem = 16px) + minFontSize: 12, // 最小字体限制 + maxFontSize: 24, // 最大字体限制 + delay: 300, // 窗口变化时的延迟执行(ms) + }; + + const docEl = doc.documentElement; + const resizeEvt = 'orientationchange' in win ? 'orientationchange' : 'resize'; + let resizeTimeout; + + function calculateFontSize() { + const clientWidth = docEl.clientWidth || win.innerWidth; + if (!clientWidth) return; + + const fontSize = Math.min( + Math.max((clientWidth / config.designWidth) * config.baseFontSize, config.minFontSize), + config.maxFontSize, + ); + + docEl.style.fontSize = fontSize + 'px'; + + // 可选:调试输出 + if (win.console) { + console.debug('[REM-Resize]', 'width:', clientWidth, 'font-size:', fontSize + 'px'); + } + } + + function resizeHandler() { + clearTimeout(resizeTimeout); + resizeTimeout = setTimeout(calculateFontSize, config.delay); + } + + calculateFontSize(); + + // 初始化监听 + win.addEventListener(resizeEvt, resizeHandler, false); +})(document, window); diff --git a/react-ui/src/assets/img/home/code.png b/react-ui/src/assets/img/home/code.png new file mode 100644 index 00000000..510ed463 Binary files /dev/null and b/react-ui/src/assets/img/home/code.png differ diff --git a/react-ui/src/assets/img/home/dataset-arrow-right.png b/react-ui/src/assets/img/home/dataset-arrow-right.png new file mode 100644 index 00000000..6a4d1a35 Binary files /dev/null and b/react-ui/src/assets/img/home/dataset-arrow-right.png differ diff --git a/react-ui/src/assets/img/home/dataset-item-bg-hover.png b/react-ui/src/assets/img/home/dataset-item-bg-hover.png new file mode 100644 index 00000000..946aed2a Binary files /dev/null and b/react-ui/src/assets/img/home/dataset-item-bg-hover.png differ diff --git a/react-ui/src/assets/img/home/dataset-item-bg.png b/react-ui/src/assets/img/home/dataset-item-bg.png new file mode 100644 index 00000000..dd87e156 Binary files /dev/null and b/react-ui/src/assets/img/home/dataset-item-bg.png differ diff --git a/react-ui/src/assets/img/home/dataset.png b/react-ui/src/assets/img/home/dataset.png new file mode 100644 index 00000000..44589180 Binary files /dev/null and b/react-ui/src/assets/img/home/dataset.png differ diff --git a/react-ui/src/assets/img/home/header-bg.png b/react-ui/src/assets/img/home/header-bg.png new file mode 100644 index 00000000..d5ee7796 Binary files /dev/null and b/react-ui/src/assets/img/home/header-bg.png differ diff --git a/react-ui/src/assets/img/home/image.png b/react-ui/src/assets/img/home/image.png new file mode 100644 index 00000000..5985d29e Binary files /dev/null and b/react-ui/src/assets/img/home/image.png differ diff --git a/react-ui/src/assets/img/home/model-between-dataset.png b/react-ui/src/assets/img/home/model-between-dataset.png new file mode 100644 index 00000000..d0384a4e Binary files /dev/null and b/react-ui/src/assets/img/home/model-between-dataset.png differ diff --git a/react-ui/src/assets/img/home/model-bg.png b/react-ui/src/assets/img/home/model-bg.png new file mode 100644 index 00000000..260e4020 Binary files /dev/null and b/react-ui/src/assets/img/home/model-bg.png differ diff --git a/react-ui/src/assets/img/home/model-item-bg-hover.png b/react-ui/src/assets/img/home/model-item-bg-hover.png new file mode 100644 index 00000000..70f48227 Binary files /dev/null and b/react-ui/src/assets/img/home/model-item-bg-hover.png differ diff --git a/react-ui/src/assets/img/home/model-item-bg.png b/react-ui/src/assets/img/home/model-item-bg.png new file mode 100644 index 00000000..a1ed78db Binary files /dev/null and b/react-ui/src/assets/img/home/model-item-bg.png differ diff --git a/react-ui/src/assets/img/home/model.png b/react-ui/src/assets/img/home/model.png new file mode 100644 index 00000000..a3f0e352 Binary files /dev/null and b/react-ui/src/assets/img/home/model.png differ diff --git a/react-ui/src/assets/img/home/right-arrow-hover.png b/react-ui/src/assets/img/home/right-arrow-hover.png new file mode 100644 index 00000000..31f968fd Binary files /dev/null and b/react-ui/src/assets/img/home/right-arrow-hover.png differ diff --git a/react-ui/src/assets/img/home/right-arrow.png b/react-ui/src/assets/img/home/right-arrow.png new file mode 100644 index 00000000..d89934dd Binary files /dev/null and b/react-ui/src/assets/img/home/right-arrow.png differ diff --git a/react-ui/src/assets/img/home/service-bg.png b/react-ui/src/assets/img/home/service-bg.png new file mode 100644 index 00000000..be9bdede Binary files /dev/null and b/react-ui/src/assets/img/home/service-bg.png differ diff --git a/react-ui/src/assets/img/home/service.png b/react-ui/src/assets/img/home/service.png new file mode 100644 index 00000000..e38216b1 Binary files /dev/null and b/react-ui/src/assets/img/home/service.png differ diff --git a/react-ui/src/assets/img/home/service1.png b/react-ui/src/assets/img/home/service1.png new file mode 100644 index 00000000..9009197d Binary files /dev/null and b/react-ui/src/assets/img/home/service1.png differ diff --git a/react-ui/src/assets/img/home/service2.png b/react-ui/src/assets/img/home/service2.png new file mode 100644 index 00000000..07bc8eab Binary files /dev/null and b/react-ui/src/assets/img/home/service2.png differ diff --git a/react-ui/src/assets/img/home/service3.png b/react-ui/src/assets/img/home/service3.png new file mode 100644 index 00000000..17bce241 Binary files /dev/null and b/react-ui/src/assets/img/home/service3.png differ diff --git a/react-ui/src/assets/img/home/service4.png b/react-ui/src/assets/img/home/service4.png new file mode 100644 index 00000000..471cf98a Binary files /dev/null and b/react-ui/src/assets/img/home/service4.png differ diff --git a/react-ui/src/assets/img/home/statistics-bg.png b/react-ui/src/assets/img/home/statistics-bg.png new file mode 100644 index 00000000..858c1d11 Binary files /dev/null and b/react-ui/src/assets/img/home/statistics-bg.png differ diff --git a/react-ui/src/assets/img/home/user-avatar-big.png b/react-ui/src/assets/img/home/user-avatar-big.png new file mode 100644 index 00000000..ed548da3 Binary files /dev/null and b/react-ui/src/assets/img/home/user-avatar-big.png differ diff --git a/react-ui/src/assets/img/home/user-avatar.png b/react-ui/src/assets/img/home/user-avatar.png new file mode 100644 index 00000000..067aa252 Binary files /dev/null and b/react-ui/src/assets/img/home/user-avatar.png differ diff --git a/react-ui/src/assets/img/home/图像 638@2x.png b/react-ui/src/assets/img/home/图像 638@2x.png new file mode 100644 index 00000000..7087131a Binary files /dev/null and b/react-ui/src/assets/img/home/图像 638@2x.png differ diff --git a/react-ui/src/assets/img/home/底座.png b/react-ui/src/assets/img/home/底座.png new file mode 100644 index 00000000..cf94435b Binary files /dev/null and b/react-ui/src/assets/img/home/底座.png differ diff --git a/react-ui/src/assets/img/home/底部(2)@2x.png b/react-ui/src/assets/img/home/底部(2)@2x.png new file mode 100644 index 00000000..e6259fc7 Binary files /dev/null and b/react-ui/src/assets/img/home/底部(2)@2x.png differ diff --git a/react-ui/src/assets/img/home/更多(1)@2x.png b/react-ui/src/assets/img/home/更多(1)@2x.png new file mode 100644 index 00000000..53679a87 Binary files /dev/null and b/react-ui/src/assets/img/home/更多(1)@2x.png differ diff --git a/react-ui/src/assets/img/home/点赞icon(1)@2x.png b/react-ui/src/assets/img/home/点赞icon(1)@2x.png new file mode 100644 index 00000000..61ce455d Binary files /dev/null and b/react-ui/src/assets/img/home/点赞icon(1)@2x.png differ diff --git a/react-ui/src/assets/img/home/点赞icon(10)@2x.png b/react-ui/src/assets/img/home/点赞icon(10)@2x.png new file mode 100644 index 00000000..b0d95597 Binary files /dev/null and b/react-ui/src/assets/img/home/点赞icon(10)@2x.png differ diff --git a/react-ui/src/assets/img/home/点赞icon(11)@2x.png b/react-ui/src/assets/img/home/点赞icon(11)@2x.png new file mode 100644 index 00000000..61ce455d Binary files /dev/null and b/react-ui/src/assets/img/home/点赞icon(11)@2x.png differ diff --git a/react-ui/src/assets/img/home/点赞icon(2)@2x.png b/react-ui/src/assets/img/home/点赞icon(2)@2x.png new file mode 100644 index 00000000..b0d95597 Binary files /dev/null and b/react-ui/src/assets/img/home/点赞icon(2)@2x.png differ diff --git a/react-ui/src/assets/img/home/点赞icon(3)@2x.png b/react-ui/src/assets/img/home/点赞icon(3)@2x.png new file mode 100644 index 00000000..61ce455d Binary files /dev/null and b/react-ui/src/assets/img/home/点赞icon(3)@2x.png differ diff --git a/react-ui/src/assets/img/home/点赞icon(4)@2x.png b/react-ui/src/assets/img/home/点赞icon(4)@2x.png new file mode 100644 index 00000000..b0d95597 Binary files /dev/null and b/react-ui/src/assets/img/home/点赞icon(4)@2x.png differ diff --git a/react-ui/src/assets/img/home/点赞icon(5)@2x.png b/react-ui/src/assets/img/home/点赞icon(5)@2x.png new file mode 100644 index 00000000..db564104 Binary files /dev/null and b/react-ui/src/assets/img/home/点赞icon(5)@2x.png differ diff --git a/react-ui/src/assets/img/home/点赞icon(6)@2x.png b/react-ui/src/assets/img/home/点赞icon(6)@2x.png new file mode 100644 index 00000000..b0d95597 Binary files /dev/null and b/react-ui/src/assets/img/home/点赞icon(6)@2x.png differ diff --git a/react-ui/src/assets/img/home/点赞icon(7)@2x.png b/react-ui/src/assets/img/home/点赞icon(7)@2x.png new file mode 100644 index 00000000..61ce455d Binary files /dev/null and b/react-ui/src/assets/img/home/点赞icon(7)@2x.png differ diff --git a/react-ui/src/assets/img/home/点赞icon(8)@2x.png b/react-ui/src/assets/img/home/点赞icon(8)@2x.png new file mode 100644 index 00000000..b0d95597 Binary files /dev/null and b/react-ui/src/assets/img/home/点赞icon(8)@2x.png differ diff --git a/react-ui/src/assets/img/home/点赞icon(9)@2x.png b/react-ui/src/assets/img/home/点赞icon(9)@2x.png new file mode 100644 index 00000000..61ce455d Binary files /dev/null and b/react-ui/src/assets/img/home/点赞icon(9)@2x.png differ diff --git a/react-ui/src/assets/img/home/点赞icon@2x.png b/react-ui/src/assets/img/home/点赞icon@2x.png new file mode 100644 index 00000000..b0d95597 Binary files /dev/null and b/react-ui/src/assets/img/home/点赞icon@2x.png differ diff --git a/react-ui/src/assets/img/home/默认头像男@2x.png b/react-ui/src/assets/img/home/默认头像男@2x.png new file mode 100644 index 00000000..40488e57 Binary files /dev/null and b/react-ui/src/assets/img/home/默认头像男@2x.png differ diff --git a/react-ui/src/enums/pagesEnums.ts b/react-ui/src/enums/pagesEnums.ts index d11eb8b5..c8073a8c 100644 --- a/react-ui/src/enums/pagesEnums.ts +++ b/react-ui/src/enums/pagesEnums.ts @@ -1,4 +1,6 @@ export enum PageEnum { + Root = '/', LOGIN = '/user/login', Authorize = '/authorize', + Home = '/home', } diff --git a/react-ui/src/global.tsx b/react-ui/src/global.tsx index 2e26173b..619b33c7 100644 --- a/react-ui/src/global.tsx +++ b/react-ui/src/global.tsx @@ -19,6 +19,24 @@ const clearCache = () => { } }; +const doubleTexxt = () => { + if (process.env.NODE_ENV === 'development') { + document.body.addEventListener('click', (e) => { + const target = e.target; + if ( + e.altKey && + e.ctrlKey && + target && + target.innerText && + target.nodeType === Node.ELEMENT_NODE + ) { + const times = 2; + target.innerText = target.innerText.repeat(times); + } + }); + } +}; + // if pwa is true if (pwa) { // Notify user if offline now @@ -89,3 +107,5 @@ if (pwa) { clearCache(); } + +doubleTexxt(); diff --git a/react-ui/src/pages/Authorize/index.tsx b/react-ui/src/pages/Authorize/index.tsx index 9a035ac9..6f101b64 100644 --- a/react-ui/src/pages/Authorize/index.tsx +++ b/react-ui/src/pages/Authorize/index.tsx @@ -1,6 +1,7 @@ import { setSessionToken } from '@/access'; import { loginByOauth2Req } from '@/services/auth'; import { to } from '@/utils/promise'; +import SessionStorage from '@/utils/sessionStorage'; import { history, useModel, useSearchParams } from '@umijs/max'; import { message } from 'antd'; import { useCallback, useEffect } from 'react'; @@ -36,7 +37,9 @@ function Authorize() { setSessionToken(access_token, access_token, expires_in); message.success('登录成功!'); await fetchUserInfo(); - history.replace(redirect || '/'); + const redierctUrl = SessionStorage.getItem(SessionStorage.redirectUrl); + history.replace(redirect || redierctUrl || '/workspace'); + SessionStorage.removeItem(SessionStorage.redirectUrl); } }, [fetchUserInfo, redirect, code]); diff --git a/react-ui/src/pages/Home/components/BlockTitle/index.less b/react-ui/src/pages/Home/components/BlockTitle/index.less new file mode 100644 index 00000000..4bf9347c --- /dev/null +++ b/react-ui/src/pages/Home/components/BlockTitle/index.less @@ -0,0 +1,13 @@ +.block-title { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + + &__title { + color: #020814; + font-weight: 500; + font-size: 2.25rem; + text-align: center; + } +} diff --git a/react-ui/src/pages/Home/components/BlockTitle/index.tsx b/react-ui/src/pages/Home/components/BlockTitle/index.tsx new file mode 100644 index 00000000..cfcd3f73 --- /dev/null +++ b/react-ui/src/pages/Home/components/BlockTitle/index.tsx @@ -0,0 +1,24 @@ +import classNames from 'classnames'; +import ViewMore from '../ViewMore'; +import styles from './index.less'; + +type BlockTitleProps = { + /** 自定义类名 */ + className?: string; + /** 自定义样式 */ + style?: React.CSSProperties; + /** 标题 */ + title: string; + onClick?: () => void; +}; + +function BlockTitle({ title, onClick, className, style }: BlockTitleProps) { + return ( +
+
{title}
+ +
+ ); +} + +export default BlockTitle; diff --git a/react-ui/src/pages/Home/components/Dataset/index.less b/react-ui/src/pages/Home/components/Dataset/index.less new file mode 100644 index 00000000..d3d82861 --- /dev/null +++ b/react-ui/src/pages/Home/components/Dataset/index.less @@ -0,0 +1,71 @@ +.dataset { + position: relative; + 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%; + + &__item { + position: relative; + width: 42.75rem; + 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/Dataset/index.tsx b/react-ui/src/pages/Home/components/Dataset/index.tsx new file mode 100644 index 00000000..b2004bd2 --- /dev/null +++ b/react-ui/src/pages/Home/components/Dataset/index.tsx @@ -0,0 +1,95 @@ +import { useNavigate } from '@umijs/max'; +import { Divider, Flex } from 'antd'; +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(); + return ( +
+ navigate('/dataset/dataset')} + > + + {datasetData.map((item) => { + return ( + + +
+ +
{item.title}
+ +
+
{item.desc}
+ +
{item.user}
+ +
{item.date}
+
+
+
+
+ ); + })} +
+
+ ); +} + +export default DatasetBlock; diff --git a/react-ui/src/pages/Home/components/Intro/index.less b/react-ui/src/pages/Home/components/Intro/index.less new file mode 100644 index 00000000..53144be9 --- /dev/null +++ b/react-ui/src/pages/Home/components/Intro/index.less @@ -0,0 +1,53 @@ +.intro { + position: relative; + z-index: 10; + display: flex; + flex-direction: column; + align-items: center; + padding-top: 8.375rem; + background-image: url(@/assets/img/home/header-bg.png); + background-repeat: no-repeat; + background-position: left top; + background-size: 100% 100%; + + &__title { + margin-bottom: 1.125rem; + color: #ffffff; + font-size: 2.375rem; + font-family: WenYiHei; + } + + &__desc { + width: 54.5rem; + margin-bottom: 1.875rem; + color: #ffffff; + font-size: 1rem; + line-height: 1.75rem; + text-align: center; + } + + &__button { + margin-bottom: 4.375rem; + padding: 0.625rem 2.375rem; + color: #ffffff; + font-size: 1rem; + text-align: center; + background: linear-gradient( + 108.54deg, + #5eb4ff 3.72%, + rgba(42, 92, 255, 0.01) 49.49%, + rgba(232, 239, 255, 0.33) 98.01% + ); + border: 1px solid rgba(255, 255, 255, 0.38); + border-radius: 0.5rem; + cursor: pointer; + + &:hover { + background: linear-gradient( + 108.54deg, + rgba(183, 131, 255, 0.81) 3.72%, + rgba(119, 208, 255, 0.31) 98.01% + ); + } + } +} diff --git a/react-ui/src/pages/Home/components/Intro/index.tsx b/react-ui/src/pages/Home/components/Intro/index.tsx new file mode 100644 index 00000000..06787a58 --- /dev/null +++ b/react-ui/src/pages/Home/components/Intro/index.tsx @@ -0,0 +1,24 @@ +// import NavBar from '../NavBar'; +import { useNavigate } from '@umijs/max'; +import StatisticsBlock from '../Statistics'; +import styles from './index.less'; + +function IntroBlock() { + const navigate = useNavigate(); + return ( +
+ {/* */} +
智能材料科研平台
+
+ 智能材料科研平台是用于材料研究和开发的技术平台,它旨在提供实验数据收集、分析和可视化等功能, + 以支持材料工程师、科学家和研究人员在材料设计、性能评估和工艺优化方面的工作。 +
+
navigate('/workspace')}> + 进入首页 +
+ +
+ ); +} + +export default IntroBlock; diff --git a/react-ui/src/pages/Home/components/Model/index.less b/react-ui/src/pages/Home/components/Model/index.less new file mode 100644 index 00000000..2be9cd39 --- /dev/null +++ b/react-ui/src/pages/Home/components/Model/index.less @@ -0,0 +1,67 @@ +.model { + position: relative; + display: flex; + flex-direction: column; + align-items: center; + padding: 5.375rem 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/Model/index.tsx b/react-ui/src/pages/Home/components/Model/index.tsx new file mode 100644 index 00000000..556da2be --- /dev/null +++ b/react-ui/src/pages/Home/components/Model/index.tsx @@ -0,0 +1,89 @@ +import { useNavigate } from '@umijs/max'; +import { Divider, Flex } from 'antd'; +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(); + return ( +
+ navigate('/dataset/model')} + > + + {modelData.map((item) => { + return ( + + +
+
{item.title}
+
{item.desc}
+ +
{item.user}
+ +
{item.date}
+
+
+
+
+ ); + })} +
+
+ ); +} + +export default ModelBlock; diff --git a/react-ui/src/pages/Home/components/NavBar/index.less b/react-ui/src/pages/Home/components/NavBar/index.less new file mode 100644 index 00000000..18a08c25 --- /dev/null +++ b/react-ui/src/pages/Home/components/NavBar/index.less @@ -0,0 +1,7 @@ +.nav-bar { + display: flex; + align-items: center; + padding: 1.25rem 15.625rem; + + +} \ No newline at end of file diff --git a/react-ui/src/pages/Home/components/NavBar/index.tsx b/react-ui/src/pages/Home/components/NavBar/index.tsx new file mode 100644 index 00000000..791889fa --- /dev/null +++ b/react-ui/src/pages/Home/components/NavBar/index.tsx @@ -0,0 +1,12 @@ +import styles from './index.less'; + +function NavBar() { + return ( +
+
智能材料科研平台
+
首页
+
+ ); +} + +export default NavBar; diff --git a/react-ui/src/pages/Home/components/Service/index.less b/react-ui/src/pages/Home/components/Service/index.less new file mode 100644 index 00000000..5c28cb0b --- /dev/null +++ b/react-ui/src/pages/Home/components/Service/index.less @@ -0,0 +1,75 @@ +.service { + position: relative; + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + margin-top: -4rem; + padding: 9.625rem 16.25rem 6.25rem; + .backgroundFullImage(url(@/assets/img/home/service-bg.png)); + + &__item { + width: 21rem; + padding: 1.25rem 1.25rem 1.5625rem; + background: #ffffff; + border-radius: 1.25rem; + box-shadow: 0rem 0rem 0.75rem rgba(33, 73, 212, 0.06); + cursor: pointer; + + &:hover { + box-shadow: 0rem 0rem 0.75rem rgba(33, 73, 212, 0.12); + } + + &__image-container { + width: 18.4375rem; + height: 10.6875rem; + margin-bottom: 0.75rem; + overflow: hidden; + border-radius: 1.875rem; + } + + &__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; + } + + &:hover &__image { + transform: scale(1.1); + } + + &__title { + height: 2.625rem; + margin-bottom: 0.875rem; + color: #020814; + font-size: 0.9375rem; + .multiLine(2); + } + + &:hover &__title { + color: @primary-color; + } + + &__user-avatar { + width: 1.3125rem; + height: 1.3125rem; + margin-right: 0.5rem; + } + + &__user-name { + margin-right: 0.5rem; + color: #191919; + font-size: 0.875rem; + } + + &__date { + color: #8284a4; + font-size: 0.8125rem; + text-align: right; + } + } +} diff --git a/react-ui/src/pages/Home/components/Service/index.tsx b/react-ui/src/pages/Home/components/Service/index.tsx new file mode 100644 index 00000000..e97b4851 --- /dev/null +++ b/react-ui/src/pages/Home/components/Service/index.tsx @@ -0,0 +1,81 @@ +import ServiceImg1 from '@/assets/img/home/service1.png'; +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 { useNavigate } from '@umijs/max'; +import { Flex } from 'antd'; +import BlockTitle from '../BlockTitle'; +import styles from './index.less'; + +const serviceData = [ + { + 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(); + return ( +
+ navigate('dataset/modelDeployment')} + > + + {serviceData.map((item) => { + return ( +
+
+ +
+
{item.title}
+ + + +
{item.user}
+
+
{item.date}
+
+
+ ); + })} +
+
+ ); +} + +export default ServiceBlock; diff --git a/react-ui/src/pages/Home/components/Statistics/index.less b/react-ui/src/pages/Home/components/Statistics/index.less new file mode 100644 index 00000000..9542fb9c --- /dev/null +++ b/react-ui/src/pages/Home/components/Statistics/index.less @@ -0,0 +1,30 @@ +.statistics { + display: flex; + align-items: center; + justify-content: space-evenly; + width: 87.5rem; + height: 7.5rem; + .backgroundFullImage(url(@/assets/img/home/statistics-bg.png)); + + &__item { + display: flex; + align-items: center; + + &__icon { + width: 3rem; + height: 3rem; + margin-right: 1rem; + } + + &__count { + color: #ffffff; + font-size: 2.25rem; + font-family: YouSheBiaoTiHei; + } + + &__name { + color: #ffffff; + font-size: 0.875rem; + } + } +} diff --git a/react-ui/src/pages/Home/components/Statistics/index.tsx b/react-ui/src/pages/Home/components/Statistics/index.tsx new file mode 100644 index 00000000..5f383c09 --- /dev/null +++ b/react-ui/src/pages/Home/components/Statistics/index.tsx @@ -0,0 +1,54 @@ +import CodeIcon from '@/assets/img/home/code.png'; +import DatasetIcon from '@/assets/img/home/dataset.png'; +import ImageIcon from '@/assets/img/home/image.png'; +import ModelIcon from '@/assets/img/home/model.png'; +import ServiceIcon from '@/assets/img/home/service.png'; +import styles from './index.less'; + +const dataList = [ + { + icon: DatasetIcon, + name: '数据集', + count: 30, + }, + { + icon: ModelIcon, + name: '模型', + count: 30, + }, + { + icon: ImageIcon, + name: '镜像', + count: 30, + }, + { + icon: CodeIcon, + name: '代码', + count: 30, + }, + { + icon: ServiceIcon, + name: '服务', + count: 30, + }, +]; + +function StatisticsBlock() { + return ( +
+ {dataList.map((item) => { + return ( +
+ +
+
{item.count}
+
{item.name}
+
+
+ ); + })} +
+ ); +} + +export default StatisticsBlock; diff --git a/react-ui/src/pages/Home/components/ViewMore/index.less b/react-ui/src/pages/Home/components/ViewMore/index.less new file mode 100644 index 00000000..8ce71d6f --- /dev/null +++ b/react-ui/src/pages/Home/components/ViewMore/index.less @@ -0,0 +1,34 @@ +.view-more { + position: absolute; + right: 16.25rem; + display: flex; + align-items: center; + color: .addAlpha(#020814, 0.7) []; + font-size: 0.9375rem; + cursor: pointer; + + &:hover { + color: #020814; + } + + &__img { + display: inline; + width: 1.125rem; + height: 1.125rem; + margin-left: 0.75rem; + } + + &__hover-img { + display: none; + width: 1.5625rem; + margin-left: 0.625rem; + } + + &:hover &__img { + display: none; + } + + &:hover &__hover-img { + display: inline; + } +} diff --git a/react-ui/src/pages/Home/components/ViewMore/index.tsx b/react-ui/src/pages/Home/components/ViewMore/index.tsx new file mode 100644 index 00000000..c10d2fb2 --- /dev/null +++ b/react-ui/src/pages/Home/components/ViewMore/index.tsx @@ -0,0 +1,29 @@ +import classNames from 'classnames'; +import styles from './index.less'; + +type ViewMoreProps = { + /** 自定义类名 */ + className?: string; + /** 自定义样式 */ + style?: React.CSSProperties; + /** 自定义样式 */ + onClick?: () => void; +}; + +function ViewMore({ className, style, onClick }: ViewMoreProps) { + return ( +
+ 查看更多 + + +
+ ); +} + +export default ViewMore; diff --git a/react-ui/src/pages/Home/index.less b/react-ui/src/pages/Home/index.less new file mode 100644 index 00000000..97dcf000 --- /dev/null +++ b/react-ui/src/pages/Home/index.less @@ -0,0 +1,15 @@ +.home { + height: 100%; + overflow-y: auto; + font-family: Alibaba; + + &__separator { + position: relative; + z-index: 10; + display: block; + width: 97.5rem; + height: 8.375rem; + margin: 0 auto; + margin-top: -5.875rem; + } +} diff --git a/react-ui/src/pages/Home/index.tsx b/react-ui/src/pages/Home/index.tsx new file mode 100644 index 00000000..22aa13fc --- /dev/null +++ b/react-ui/src/pages/Home/index.tsx @@ -0,0 +1,23 @@ +import DatasetBlock from './components/Dataset'; +import IntroBlock from './components/Intro'; +import ModelBlock from './components/Model'; +import ServiceBlock from './components/Service'; +import styles from './index.less'; + +function Home() { + return ( +
+ + + + + +
+ ); +} + +export default Home; diff --git a/react-ui/src/styles/theme.less b/react-ui/src/styles/theme.less index 89b955c8..0d5f5498 100644 --- a/react-ui/src/styles/theme.less +++ b/react-ui/src/styles/theme.less @@ -51,6 +51,11 @@ @result: rgba(@red, @green, @blue, @alpha); } +// 转换为 rem +.rem(@px) { + @result: (@px / 16) * 1rem; +} + // 混合 // 单行 .singleLine() { @@ -73,7 +78,7 @@ .backgroundFullImage(@url) { background-image: @url; background-repeat: no-repeat; - background-position: top center; + background-position: top left; background-size: 100% 100%; } diff --git a/react-ui/src/utils/index.ts b/react-ui/src/utils/index.ts index 2db6af2a..568a1038 100644 --- a/react-ui/src/utils/index.ts +++ b/react-ui/src/utils/index.ts @@ -7,6 +7,9 @@ import { PageEnum } from '@/enums/pagesEnums'; import G6 from '@antv/g6'; +// 白名单,不需要登录 +const whiteList = [PageEnum.Root, PageEnum.LOGIN, PageEnum.Authorize, PageEnum.Home]; + /** * 生成 8 位随机数 * @returns 8 位随机数 @@ -295,7 +298,7 @@ export const getGitUrl = (url?: string, branch?: string): string => { * @return {boolean} true if the pathname needs to be authorized, false otherwise */ export const needAuth = (pathname: string): boolean => { - return pathname !== PageEnum.LOGIN && pathname !== PageEnum.Authorize; + return !whiteList.includes(pathname); }; /** diff --git a/react-ui/src/utils/sessionStorage.ts b/react-ui/src/utils/sessionStorage.ts index 88e48f79..9c7f71a7 100644 --- a/react-ui/src/utils/sessionStorage.ts +++ b/react-ui/src/utils/sessionStorage.ts @@ -13,6 +13,8 @@ export default class SessionStorage { static readonly aimUrlKey = 'aim-url'; /** tensorBoard url */ static readonly tensorBoardUrlKey = 'tensor-board-url'; + /** 登录之前的地址 */ + static readonly redirectUrl = 'redirect-url'; /** * 获取 SessionStorage 值 diff --git a/react-ui/src/utils/ui.tsx b/react-ui/src/utils/ui.tsx index a60c43be..3eccaef7 100644 --- a/react-ui/src/utils/ui.tsx +++ b/react-ui/src/utils/ui.tsx @@ -77,6 +77,9 @@ export const gotoLoginPage = (toHome: boolean = true) => { if (pathname !== PageEnum.LOGIN) { closeAllModals(); removeAllPageCacheState(); + if (newSearch) { + SessionStorage.setItem(newSearch, SessionStorage.redirectUrl); + } history.replace({ pathname: PageEnum.LOGIN, search: newSearch,