超算专区-开源项目首页改版+动画

This commit is contained in:
caishi 2026-05-06 17:15:59 +08:00
parent 9588e7e8c9
commit faec3b4ba5
8 changed files with 161 additions and 33 deletions

View File

@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react';
import { Modal , Table , Input , Button , Select , message , Popconfirm } from 'antd';
import { getManageProjects , getMemberProjectList , addProjects , addMemberProject , removeProject } from '../api';
const { Option } = Select;
function AddProjects({id,visible,typeList,role,onCancel,onFresh}){
function AddProjects({id,visible,typeList,needAudit,role,onCancel,onFresh}){
const [ dataSource , setDataSource ]= useState([]);
const [ searchValue , setSearchValue ] = useState(null);
const [ page ,setPage ] = useState(1);
@ -110,7 +110,7 @@ function AddProjects({id,visible,typeList,role,onCancel,onFresh}){
}
const res = response.data;
if(res && res.code === 200){
message.success("操作成功");
message.success(needAudit === 1 ? "操作成功,请等待管理员审核" : "操作成功!");
Init(page,searchValue);
onFresh();
}else{

View File

@ -10,7 +10,6 @@ function CategorySection({ category, index, zoneId, nsccTitle }) {
const cateConfig = projectCateConfig.getCateName(category.name, index);
const projects = category.homepageProjects
//
const getLayoutType = (index) => {
const layouts = [
@ -24,16 +23,15 @@ function CategorySection({ category, index, zoneId, nsccTitle }) {
return layouts[index] || 'layout-3';
};
const layoutType = getLayoutType(index);
//
const renderProjects = (showBtn,range) => {
console.log("-------------",category.name,showBtn, range && range[0]);
if (!projects || projects.length === 0) {
return <Nodata _html="暂无数据" />;
}
return projects.map((item, pIndex)=>{
console.log(category.name,pIndex,range && pIndex === range[0]);
return(
(!range || (range && pIndex >= range[0] && pIndex < range[1])) ? <div key={`${index}_${pIndex}`} className='cate-project-card'>
<div className='font-18 project-list-item-title mb20'>
@ -79,7 +77,7 @@ function CategorySection({ category, index, zoneId, nsccTitle }) {
<Fragment>
{layoutType === 'layout-1' && (
<div className="project_cate_home_part2">
<div className='project-cate-1600 df pt50'>
<div className='project-cate-1600 df pt50 needFadeUp'>
<div className="cate_parter_1_left">
{nsccTitle(category.name, 0.3, "pt30")}
<div className='font-20 mt10 mb40'>{cateConfig.description}</div>
@ -99,8 +97,8 @@ function CategorySection({ category, index, zoneId, nsccTitle }) {
{layoutType === 'layout-2' && (
<div className="project_cate_home_part3">
{nsccTitle(category.name, 0.3, "pt80 center")}
<div className='center font-20 mb50'>{cateConfig.description}</div>
<div className='project-cate-1600 df projectCateContent'>
<div className='center font-20 mb50 needFadeUp'>{cateConfig.description}</div>
<div className='project-cate-1600 df projectCateContent needFadeUp'>
<div className='project_cate_home_part3_left'>
<div className='font-16 font-bd mb20'>天文及固体地球物理研究</div>
{["天文地球物理是超算重要应用,研究宇宙及地球深部问题", "研究多尺度耦合,数据量大,向计算驱动转型", "超算助力科研模拟,支撑基础研究与灾害预警"].map((point, pIndex) => (
@ -123,7 +121,7 @@ function CategorySection({ category, index, zoneId, nsccTitle }) {
{layoutType === 'layout-3' && (
<div className="project_cate_home_part4">
{parter_title()}
<div className='project_cate_home_part4_list project-cate-1600'>
<div className='project_cate_home_part4_list project-cate-1600 needFadeUp'>
<div className="cate_project_list_box">
{renderProjects(true)}
</div>
@ -132,7 +130,7 @@ function CategorySection({ category, index, zoneId, nsccTitle }) {
)}
{ layoutType ==="layout-4" && <div className="project_cate_home_part5">
{parter_title()}
<div className='project-cate-1600 df cate_project_list_box'>
<div className='project-cate-1600 df cate_project_list_box needFadeUp'>
{renderProjects(true,[0,1])}
<div className='df newLeftMainCard'>
{renderProjects(false,[1,5])}
@ -142,7 +140,7 @@ function CategorySection({ category, index, zoneId, nsccTitle }) {
{
layoutType ==="layout-5" && <div className='project_cate_home_part6'>
{parter_title()}
<div className='project-cate-1600 df cate_project_list_box'>
<div className='project-cate-1600 df cate_project_list_box needFadeUp'>
<div className='cateSixMain'>
<div className='cateSixMainBox'><img src={main6} width={"100%"}/></div>
</div>
@ -157,9 +155,10 @@ function CategorySection({ category, index, zoneId, nsccTitle }) {
{nsccTitle(category.name, 0.3)}
<div className='font-20'>{cateConfig.description}</div>
</div>
<GlowButton href={`/zone/NSCC/projects/${category.id}?name=${category.name}`} className="NSCC_project_btn blue_image font-15">查看更多<i className='iconfont icon-arrowRight font-16 ml5'></i></GlowButton>
<a href={`/zone/NSCC/projects/${category.id}?name=${category.name}`} className="submit-project-btn">查看更多<i className='iconfont icon-arrowRight font-16 ml5'/></a>
{/* <GlowButton href={`/zone/NSCC/projects/${category.id}?name=${category.name}`} className="NSCC_project_btn blue_image font-15">查看更多<i className='iconfont icon-arrowRight font-16 ml5'></i></GlowButton> */}
</div>
<div className='project-cate-1600 df cate_project_list_box'>
<div className='project-cate-1600 df cate_project_list_box needFadeUp'>
{renderProjects(false)}
</div>
</div>

View File

@ -12,12 +12,84 @@ import GlowButton, { FlowBorderButton } from '../../../../../components/button';
import AddProjects from '../../../Component/addProjects';
function ProjectCateList(props) {
const { id, role } = props;
const { id, role , data } = props;
const [ typeList, setTypeList ] = useState(undefined);
const [ statistics, setStatistics ] = useState(undefined);
const [ loading, setLoading ] = useState(false);
const [ categoryProjects, setCategoryProjects ] = useState({});
const [ visible ,setVisible ] =useState(false);
useEffect(()=>{
if(role && typeList){
setTimeout(()=>{InitObs();InitScaleObs();},200)
setTimeout(()=>{InitContentObs();},1000)
}
},[role,typeList])
// ()
function InitScaleObs(){
const eles = document.getElementsByClassName("needScale");
const observer = new IntersectionObserver((entries) => {
const entry = entries[0];
//
let name = entries[0].target.className;
if (entry.isIntersecting) {
entries[0].target.className = name + ` fadeScale`;
}else{
entries[0].target.className = name.replaceAll(" fadeScale","");
}
}, {
threshold: 0.3 // 30%
});
if(eles && eles.length> 0){
for(var i =0;i<eles.length;i++){
observer.observe(eles[i])
}
}
}
// ()
function InitContentObs(){
const eles = document.getElementsByClassName("needFadeUp");
const observer = new IntersectionObserver((entries) => {
const entry = entries[0];
//
let name = entries[0].target.className;
if (entry.isIntersecting) {
entries[0].target.className = name + ` fadeUp`;
}else{
entries[0].target.className = name.replaceAll(" fadeUp","");
}
}, {
threshold: 0.3 // 30%
});
if(eles && eles.length> 0){
for(var i =0;i<eles.length;i++){
observer.observe(eles[i])
}
}
}
// ()
function InitObs(){
const eles = document.getElementsByClassName("project-cate-title");
const observer = new IntersectionObserver((entries) => {
const entry = entries[0];
//
let name = entries[0].target.className;
if (entry.isIntersecting) {
entries[0].target.className = name + ` fadeInChar`;
}else{
entries[0].target.className = name.replaceAll(" fadeInChar","");
}
}, {
threshold: 0.1 // 30%
});
if(eles && eles.length> 0){
for(var i =0;i<eles.length;i++){
observer.observe(eles[i])
}
}
}
const statsData = [
{ label: '开源项目', value: statistics?.projectCount || 0, suffix: '个' },
{ label: '领域分类', value: statistics?.categoryCount || 6, suffix: '个' },
@ -34,6 +106,7 @@ function ProjectCateList(props) {
let username = getUserName(props.current_user);
let remark = ` 操作系统:${platform};浏览器:${browser};`;
setZoneVisits({url, username, uuid, remark});
}, []);
//
@ -96,7 +169,7 @@ function ProjectCateList(props) {
});
}
}
const nsccTitle = (title, delay=0.1, classname)=> <div className={`project-cate-title fadeInChar ${classname}`}>
const nsccTitle = (title, delay=0.1, classname)=> <div className={`project-cate-title ${classname}`}>
{title.split("").map((char, index) => (
<span key={index} className="title-char" style={{ animationDelay: `${delay + index * 0.1}s` }}>
{char}
@ -106,12 +179,12 @@ function ProjectCateList(props) {
return (
<div className="project_cate_home project-cate-page">
<AddProjects id={id} visible={visible} typeList={typeList} onCancel={()=>setVisible(false)} role={role && role.role} onFresh={()=>{getTypeList();}}/>
<AddProjects needAudit={data && data.projectNeedAudit} id={id} visible={visible} typeList={typeList} onCancel={()=>setVisible(false)} role={role && role.role} onFresh={()=>{getTypeList();}}/>
{/* 数据统计部分 */}
<div className='project_cate_home_part1'>
{nsccTitle("数聚开源力量,实时见证开源生态的每一次进化", 0.1, "center pt80")}
<div className='project-cate-1600'>
<div className="statistics-cards">
<div className="statistics-cards needScale">
{statsData.map((stat, index) => (
<div key={index} className="stat-card" style={{ animationDelay: `${0.3 + index * 0.1}s` }}>
<div className="stat-value font-20">
@ -122,11 +195,9 @@ function ProjectCateList(props) {
</div>
))}
</div>
{role && role.role !== "None" && <div className='center pt20'>
{role && role.role !== "None" && <div className='center pt20 needFadeUp'>
<GlowButton href={`/zone/NSCC/projects/self`} className="NSCC_project_btn blue_image font-15 mr50">{role.role === "Member" ? "我的项目" : "管理项目" }<i className='iconfont icon-arrowRight font-16 ml5'></i></GlowButton>
<FlowBorderButton className='NSCC_project_btn font-15' onClick={(e)=>{
console.log("3333333333");
setVisible(true);
e.stopPropagation();
}}>添加项目<i className='iconfont icon-arrowRight font-16 ml5'></i></FlowBorderButton>

View File

@ -288,9 +288,30 @@
background-size: 100% 100%;
padding:0 60px;
height: 182px;
border-radius:15px 15px 0 0 ;
.toolCateFlex{
flex: 1;
}
.submit-project-btn {
display: inline-flex;
justify-content: center;
width: 160px;
height: 44px;
line-height: 44px;
text-align: center;
background-color: #091221;
color:#fff;
border-radius: 8px;
font-size: 15px;
text-decoration: none;
transition: all 0.3s ease;
&:hover {
.iconfont {
animation: arrow-move 1.2s ease-in-out infinite;
}
}
}
}
.cate_project_list_box{
padding:40px 50px;

View File

@ -45,16 +45,16 @@ export const projectCateConfig = {
description: "天文地球物理依托高性能计算,助力科研与灾害预警"
},
"工业设计制造": {
description: "工业设计制造是高性能计算的核心应用领域之一广泛涵盖计算流体力学CFD、计算固体力学、高频电磁仿真…"
description: "工业设计制造依托超算,赋能高端装备研发与制造业转型"
},
"新能源新材料": {
description: "新能源新材料行业以材料微观结构与宏观性能之间的关系为核心研究对象,依托高性能计算与先进算法,实现材料从…"
description: "新能源新材料借超算实现数字化研发,助力技术突破与材料国产化"
},
"生物医药健康": {
description: "生物医药健康是高性能计算与人工智能深度融合的核心应用领域之一,涵盖分子模拟、药物研发、基因数据分析、蛋白质结构预测…"
description: "生物医药融合超算与 AI助力药物研发与精准医疗保障全民健康"
},
"工具": {
description: "工具类软件是高性能计算生态的核心基石,广泛涵盖编译器、并行编程框架、数学与科学计算核心库、性能分析与调优工具…"
description: "工具软件是超算生态核心,夯实算力底座,支撑高效研发应用"
}
},

View File

@ -16,27 +16,30 @@ function SelfList(props){
const [ list , setList ] = useState(undefined);
const [ page , setPage ] = useState(1);
const [ total , setTotal ] = useState(0);
const [ needAudit ,setNeedAudit ] = useState(true);
const [ visible ,setVisible ] = useState(false);
const [ deleId , setDeleId] = useState(undefined);
const pathname = props.location.pathname;
const { deptId} = props.match.params;
const { id , temp , data , role } = props;
const { sectionCmsTitle, sectionResourceTitle , sectionProjectTitle } = data||{};
const { sectionCmsTitle, sectionResourceTitle , sectionProjectTitle , docNeedAudit , resourceNeedAudit , projectNeedAudit } = data||{};
const limit = 15;
useEffect(()=>{
if(pathname){
if(pathname && data){
if(pathname.indexOf("/source/self")>-1){
setSource("source");
setNeedAudit(resourceNeedAudit === 1);
}else if(pathname.indexOf("/news/self")>-1){
setSource("news");
setNeedAudit(docNeedAudit === 1);
}else{
setSource("projects");
setNeedAudit(projectNeedAudit === 1);
}
}
},[pathname])
},[pathname,data])
useEffect(()=>{
if(id && role){
@ -192,10 +195,10 @@ function SelfList(props){
<Breadcrumb.Item><Link className="primaryColor" to={pathname.replace("/self","")}>{ source==="source"?sectionResourceTitle:source==="news"?sectionCmsTitle:sectionProjectTitle }</Link></Breadcrumb.Item>
<Breadcrumb.Item>我的{source==="source"?"资源":source==="news"?"资讯":"项目"}</Breadcrumb.Item>
</Breadcrumb>
<ul className="selfMenu">
<ul className={`selfMenu ${!needAudit ?"onlyFirst" :""}`}>
<li onClick={()=>setStatus(1)} className={status===1?"active":""}>已发布</li>
<li onClick={()=>setStatus(0)} className={status===0?"active":""}>待审核</li>
<li onClick={()=>setStatus(2)} className={status===2?"active":""}>未通过</li>
{ needAudit && <li onClick={()=>setStatus(0)} className={status===0?"active":""}>待审核</li> }
{ needAudit && <li onClick={()=>setStatus(2)} className={status===2?"active":""}>未通过</li>}
</ul>
<Spin spinning={isSpin}>
<div style={{backgroundColor:"#fff",borderRadius:"4px"}}>
@ -224,7 +227,7 @@ function SelfList(props){
<span>
<span>{i.domainName || i.dirName}</span>
{(i.domainName || i.dirName) && <span className="ml10 mr15">|</span> }
<span><i className="iconfont icon-a-31shijian mr5 font-15"></i>{i.timeAgo || moment(i.createTime).format("YYYY/MM/DD")}</span>
<span><i className="iconfont icon-a-31shijian mr5 font-15"></i>{source==="projects" ? "更新于":"创建于"}{i.timeAgo || moment(i.createTime).format("YYYY/MM/DD")}</span>
</span>
<span className="s-info-right">
{source!=="projects" && <a href={`/zone/${deptId}/${source}/${i.id}/edit`} style={{color:"#466aff"}}><i className="iconfont icon-a-bianji12 mr5 font-14"></i>编辑</a> }

View File

@ -15,7 +15,7 @@ function beforeFetch(actionUrl){
service.interceptors.request.use(request => {
let deptId = sessionStorage.getItem('deptId');
// request.headers.Authorization = 'c2361e926a027ef8f6beeca3bc03daf905b5685e'
// request.headers.Authorization = 'baf748d0570754d3126d1a3fc29b9c456becf93f'
if (deptId) {
// 用于权限区分
request.headers['Dept-Id'] = deptId

View File

@ -1956,6 +1956,15 @@
display: flex;
border-radius: 4px;
box-shadow:0px 0px 10px rgba(61, 85, 183, 0.1);
&.onlyFirst{
background-color: unset;
box-shadow: unset;
justify-content: center;
>li{
border-radius: 0px!important;
max-width: 180px;
}
}
li{
flex: 1;
border-right: 1px solid rgba(141, 149, 172, 0.17);
@ -2290,6 +2299,21 @@
animation: fadeInCharZone 0.5s ease-out forwards;
}
}
.needFadeUp{
opacity: 0;
}
.fadeUp{
opacity: 0;
animation-delay: .2s;
animation: fadeUpZone 0.8s ease-out forwards;
}
.needScale{
transform: scale(.8);
transition: 1s;
}
.fadeScale{
transform: scale(1);
}
@keyframes moveArrow {
0% {
@ -2321,4 +2345,14 @@
opacity: 1;
filter: blur(0);
}
}
@keyframes fadeUpZone {
from {
opacity: 0;
transform: translateY(50px);
}
to {
opacity: 1;
transform: translateY(0px);
}
}