Merge branch 'gitlink_ssr_head' of https://gitlink.org.cn/Gitlink/forgeplus-react into gitlink_ssr_head

This commit is contained in:
caishi 2026-06-09 09:31:50 +08:00
commit 9450275ff1
7 changed files with 353 additions and 60 deletions

View File

@ -3,7 +3,7 @@ import { Modal, Form, Input, Button, Spin, Pagination } from 'antd';
import Nodata from '../../Nodata';
import { getNewsMyList, getApplyMyList, doDocTop } from '../api';
import { getNewsMyList, getMyTopArticle, doDocTop } from '../api';
const { TextArea } = Input;
@ -45,23 +45,17 @@ function PointsDoc({ visible , onCancel , onSure , type , username , choosed , h
async function init() {
setIsSpin(true);
try{
// let result = await getApplyMyList({
// zoneId: member.zoneId,
// applyType: 'doc',
// status:1,
// pageSize:limit,
// pageNum:page
// });
// let rows = result.data && result.data.rows;
// TODO
let rows = null;
if(Array.isArray(rows) && rows.length > 0) {
setCurrentId(rows[0].applyId)
} else {
setCurrentId(null)
let res = await getMyTopArticle(member.zoneId);
if(res && res.data.code === 200){
setCurrentRow(res.data.data);
if(res.data.data) {
setCurrentId(res.data.data.docId);
} else {
setCurrentId(null);
}
await getMyNews();
}
await getMyNews();
}finally{
setIsSpin(false)
}
@ -72,10 +66,6 @@ function PointsDoc({ visible , onCancel , onSure , type , username , choosed , h
let rows = result.data && result.data.rows;
if(rows && rows.length>0){
setList(rows);
if(currentId){
const row = rows.find(item => item.applyId === currentId || item.id === currentId);
setCurrentRow(row || null);
}
}else{
setList([]);
setCurrentRow(null);
@ -124,7 +114,7 @@ function PointsDoc({ visible , onCancel , onSure , type , username , choosed , h
</div>
{currentRow && (
<div className="line dataline">
<span className="content">{currentRow.name}</span>
<span className="content">{currentRow.docName}</span>
<span className="action">
<Button type="primary" shape="round" disabled style={{backgroundColor:'rgba(70, 106, 255, 0.43)', borderColor:'rgba(70, 106, 255, 0.43)', color:'#fff'}}>已置顶</Button>
</span>

View File

@ -0,0 +1,144 @@
import React, { useEffect, useState } from 'react';
import { Modal, Form, Input, Button, Spin, Pagination } from 'antd';
import Nodata from '../../Nodata';
import { getProjectMyList, getMyTopProject, doProjectTop } from '../api';
const { TextArea } = Input;
import { getImageUrl } from 'educoder'
import '../indexUser.scss';
function PointsDoc({ visible , onCancel , onSure , type , username , choosed , history , showCompeleteDialog , member }) {
const limit = 5;
const [ page , setPage ] = useState(1);
const [ total , setTotal ] = useState(0);
const [ isSpin , setIsSpin ] = useState(true);
const [ list , setList ] = useState(undefined);
const [ currentId , setCurrentId ] = useState(null);
const [ currentRow , setCurrentRow ] = useState(null);
useEffect(()=>{
if(visible && member) {
setPage(1);
}
},[visible, member])
useEffect(()=>{
if(visible && member) {
init();
}
},[visible, member])
useEffect(()=>{
if(visible && member) {
getMyProject();
}
},[page])
async function init() {
setIsSpin(true);
try{
let res = await getMyTopProject(member.zoneId);
if(res && res.data.code === 200){
setCurrentRow(res.data.data);
if(res.data.data) {
setCurrentId(res.data.data.id);
} else {
setCurrentId(null);
}
await getMyProject();
}
}finally{
setIsSpin(false)
}
}
async function getMyProject(){
let result = await getProjectMyList({zoneId: member.zoneId, auditStatus:1, excludeId: currentId, pageSize:limit, pageNum:page});
let rows = result.data && result.data.rows;
if(rows && rows.length>0){
setList(rows);
}else{
setList([]);
setCurrentRow(null);
}
setTotal(result.data.total);
}
function onOk() {
}
async function handlePin(item) {
setIsSpin(true);
try {
let data = Object.assign({}, item, {zoneId: member.zoneId});
await doProjectTop(data);
onSure();
} finally {
setIsSpin(false);
}
}
return(
<Modal
closeIcon={<i className="iconfont icon-guanbi font-20 closeIconFont" onClick={onCancel}></i>}
className="doc_modal"
visible={visible}
title={<div className="title_box">
专区首页项目推荐
</div>}
closable={true}
width={800}
footer={
<div>
<Button onClick={onCancel}>取消</Button>
<Button className="btn_ok" style={{marginLeft:"20px"}} onClick={onOk}>确定</Button>
</div>
}
okText="确定"
cancelText="取消"
>
<div className="info">
<Spin spinning={isSpin}>
<div className="line topline">
<span className="content">新闻标题</span>
<span className="action">操作</span>
</div>
{currentRow && (
<div className="line dataline">
<span className="content">{currentRow.name}</span>
<span className="action">
<Button type="primary" shape="round" disabled style={{backgroundColor:'rgba(70, 106, 255, 0.43)', borderColor:'rgba(70, 106, 255, 0.43)', color:'#fff'}}>已置顶</Button>
</span>
</div>
)}
{list && list.map((item) => (
<div className="line dataline" key={item.id}>
<span className="content">{item.projectProperties?.name}</span>
<span className="action">
<Button type="primary" shape="round" disabled={!!currentRow} onClick={() => handlePin(item)}>置顶</Button>
</span>
</div>
))}
{ !isSpin && !currentId && (!list || !list.length) && <Nodata _html="暂无数据" />
}
</Spin>
{
total > limit &&
<div style={{padding:"20px",textAlign:"right"}}>
<Pagination showQuickJumper current={page} total={total} pageSize={limit} onChange={(p)=>{setPage(p);}}/>
</div>
}
</div>
</Modal>
)
}
export default PointsDoc;

View File

@ -1,6 +1,6 @@
import React , { useEffect, useRef, useState } from 'react';
import { Link } from 'react-router-dom';
import { getDirListById, getSubDocList } from '../../../api';
import { getDirListById, getSubDocList, getPointsDocList } from '../../../api';
import { Badge, Col, Divider, Icon, Row } from 'antd';
import '../index.scss';
import Nodata from '../../../../Nodata';
@ -60,11 +60,8 @@ function News(props) {
rows[0] && getDocById(rows[0].id, 5, (data)=>{
setDocListByFirstDir(data)
})
// 23
rows[1] && getDocById(rows[1].id, 3, (data)=>{
setDocListBySecondDir(data)
})
// rows[2] && setActiveDirId(rows[2].id)
getPointsDoc(rows[1].id);
}
})
}, [id])
@ -74,6 +71,35 @@ function News(props) {
setDocListByDir(data)
}, (data)=>{setTotal(data)})
}, [activeDirId])
async function getPointsDoc(rowId) {
let res = await
getPointsDocList(id).then(result=>{
let docList = [];
if(result && Array.isArray(result.data.data) && result.data.data.length){
docList = result.data.data.map(item => {
item.id = item.docId;
item.name = item.docName;
item.summary = item.summary;
item.zoneId = item.zoneId;
return item;
});
}
if(rowId) {
getSubDocList(rowId,{pageSize:3,pageNum:1,auditStatus:1}).then(result=>{
if(result && result.data.rows){
let rows = result.data.rows;
const existIds = new Set(docList.map(item => item.id));
const newRows = rows.filter(row => !existIds.has(row.id));
docList = [...docList, ...newRows];
}
}).finally(() => {
setDocListBySecondDir(docList);
})
}
});
}
// id
function getDocById(dirId, pageSize=10, setData, setTotal1){

View File

@ -1,6 +1,6 @@
import React, { useEffect, useRef, useState } from 'react';
import '../index.scss';
import { getProjectListByScore, getProjectsTypeLists } from '../../../api';
import { getProjectListByScore, getProjectsTypeLists, getPointsProjectList } from '../../../api';
import { Carousel, Divider, Pagination, Spin } from 'antd';
import Nodata from '../../../../Nodata';
import Slider from 'react-slick';
@ -16,6 +16,7 @@ function TypeCarousel({pageSize=4, list=[], typeId, onClick}) {
const start = i * pageSize;
const end = start + pageSize;
pages.push(list.slice(start, end));
console.log('ppp', pages)
}
return <Slider {...setting} className='mb60'>
{pages.map((page, index)=>{
@ -24,6 +25,7 @@ function TypeCarousel({pageSize=4, list=[], typeId, onClick}) {
{page.map((item, i) => {
const order = index*pageSize+i
const iconName = {
"精选项目": "icon-jingxuanxiangmu",
"并行计算框架": "icon-binghangjisuankuangjia",
"异构数据库": "icon-yigoushujuku",
"性能基准与评测": "icon-xingnengjizhunyupingce",
@ -55,6 +57,7 @@ function Project({ data, nsccTitle }) {
const [typeList, setTypeList] = useState([]);
const [typeId, setTypeId] = useState(undefined);
const [lists, setLists] = useState([]);
const [topList, setTopList] = useState([]);
const [loading, setLoading] = useState(false);
const [page, setPage] = useState(1);
const [total, setTotal] = useState(0);
@ -93,20 +96,41 @@ function Project({ data, nsccTitle }) {
}, []);
useEffect(() => {
id && getProjectsTypeLists(id, {
pageNum: 1,
pageSize: 100,
}).then(result => {
if (result) {
const rows = result.data.rows;
rows[0] && setTypeId(rows[0].id)
setTypeList(rows);
async function fetchTypeData() {
let typeList = [];
let typeId = null;
if(id) {
let res = await getPointsProjectList(id);
if(res && Array.isArray(res.data.data) && res.data.data.length){
setTopList(res.data.data);
typeList.push({id: -1, zoneId: id, name: '精选项目'});
typeId = -1;
}
getProjectsTypeLists(id, {
pageNum: 1,
pageSize: 100,
}).then(result => {
if (result) {
const rows = result.data.rows;
if(Array.isArray(rows) && rows.length) {
typeList = [...typeList, ...rows];
setTypeList(typeList);
if (typeId === null) {
setTypeId(rows[0].id);
} else {
setTypeId(typeId);
}
}
}
}).catch(() => { })
}
}).catch(() => { })
}
fetchTypeData();
}, [id])
useEffect(() => {
if (typeId) {
if (typeId && typeId !== -1) { //
setLoading(true);
getProjectListByScore(id, {
pageNum: page,
@ -168,25 +192,86 @@ function Project({ data, nsccTitle }) {
</div>
}
const topDetail = (className="online_detail", i, index, length) => {
const { extra: { } } = i || {}
return <div className={`${className} ${className === "second_detail" && index <3 && index<length-1 && 'pb30'} ${index === length && 'noBor'}`} key={i.id} onClick={() => window.open(i.projectURL)}>
<div className='clearfix'>
<span className='font-bd font-16 pointer'>{i.projectProperties && i.projectProperties.name}</span>
</div>
<div className="task-hide-2 mt5 color5d6 mb12">
{i.projectProperties.description || "暂无描述"}
</div>
<div style={{ minHeight: 46 }}>
<ul className="pd_tag_NSCC pb15 df wrap">
{i.projectProperties.language && <li className='font-13 mt5'>{i.projectProperties.language}</li>}
{
i.projectProperties && i.projectProperties.topics &&
i.projectProperties.topics.split(",").map(t => {
return (
<li className='font-13 mt5'>{t}</li>
)
})
}
</ul>
</div>
<p className='df between'>
<div className='font-15 font-bd'>
{i.projectProperties.language && (
<>
<span className='color5d6 mr5 font-14 font-n'>{i.projectProperties.language}</span>
<Divider type="vertical" style={{ margin: '0 15px' }} />
</>
)}
{i.projectProperties.timeAgo && <span className='color5d6 mr5 font-14 font-n'>更新于{i.projectProperties.timeAgo}</span>}
</div>
<div>
<span className='topitem mr10'><i className="iconfont icon-xingzhuang mr3 font-14" style={{color: '#e7d1b9'}}></i> {i.projectProperties.praisesCount}</span>
<span className='topitem'><i className="iconfont icon-yifuke_icon mr3 font-14" style={{color: '#5857cd'}}></i> fork{i.projectProperties.forkedCount}</span>
</div>
</p>
</div>
}
return <div className='project_1_bg_NSCC viewEntry' id="nscc_home4" ref={newsSectionRef}>
<div className='project_1 width1600 pt50 pb60'>
{nsccTitle(homepageProjectTitle, 0.1, "font-bd font-30 mb50 align task-hide")}
<div className='project_list_NSCC'>
<TypeCarousel pageSize={10} list={typeList} typeId={typeId} onClick={(id)=>{setTypeId(id); setPage(1)}}/>
<Spin spinning={loading}>
<div className='df gap20'>
{lists.slice(0, 3).map((i, index)=>{
return projectDetail("online_detail", i, index, 3)
})}
</div>
{lists.length > 3 && <div className='df second_detailBox mt30 wrap'>
{lists.slice(3).map((i, index)=>{
return projectDetail("second_detail", i, index, lists.slice(4).length)
})}
</div>}
<Pagination pageSize={9} total={total} hideOnSinglePage={true} current={page} onChange={(page)=>{setPage(page)}} className='center mt30'/>
{!loading && lists.length === 0 && <Nodata _html="暂无数据" />}
</Spin>
{
typeId !== -1 &&
<Spin spinning={loading}>
<div className='df gap20'>
{lists.slice(0, 3).map((i, index)=>{
return projectDetail("online_detail", i, index, 3)
})}
</div>
{lists.length > 3 && <div className='df second_detailBox mt30 wrap'>
{lists.slice(3).map((i, index)=>{
return projectDetail("second_detail", i, index, lists.slice(4).length)
})}
</div>}
<Pagination pageSize={9} total={total} hideOnSinglePage={true} current={page} onChange={(page)=>{setPage(page)}} className='center mt30'/>
{!loading && lists.length === 0 && <Nodata _html="暂无数据" />}
</Spin>
}
{
typeId === -1 &&
<Spin spinning={loading}>
<div className='df gap20'>
{topList.slice(0, 3).map((i, index)=>{
return topDetail("online_detail", i, index, 3)
})}
</div>
{lists.length > 3 && <div className='df second_detailBox mt30 wrap'>
{topList.slice(3).map((i, index)=>{
return topDetail("second_detail", i, index, lists.slice(4).length)
})}
</div>}
<Pagination pageSize={9} total={total} hideOnSinglePage={true} current={page} onChange={(page)=>{setPage(page)}} className='center mt30'/>
{!loading && lists.length === 0 && <Nodata _html="暂无数据" />}
</Spin>
}
</div>
</div>
</div>

View File

@ -984,6 +984,11 @@
padding: 22px 20px 20px 20px;
border-radius:15px;
box-shadow:0px 0px 12px rgba(33, 73, 212, 0.1);
.topitem{
background-color: rgba(0, 0, 0, 0.08);
padding: 4px 8px;
border-radius: 4px;
}
&:hover{
background-image: url('./image/projectBk2.png');
span, div{
@ -997,6 +1002,9 @@
background-color:rgba(255, 255, 255, 0.12);
border: 1px solid rgba(255, 255, 255, 0.5);
}
.topitem{
background-color: rgba(255, 255, 255, 0.12);
}
}
}
.second_detail{
@ -1190,4 +1198,5 @@
}
}
}
}
}

View File

@ -26,6 +26,7 @@ import UserEdit from '../Component/UserEdit';
import UserAward from '../Component/UserAward';
import MemberApply from '../Component/memberApply';
import PointsDoc from '../Component/pointsDoc';
import PointsProject from '../Component/pointsProject';
import ApplyAcitvity from '../Component/applyAcitvity';
import ApplyQA from '../Component/applyQA';
@ -46,11 +47,13 @@ function ZoneUser(props){
const [ applyVisible , setApplyVisible ] = useState(false);
const [ awardVisible , setAwardVisible ] = useState(false);
const [ docVisible , setDocVisible ] = useState(false);
const [ projectVisible , setProjectVisible ] = useState(false);
const [ acitvityVisible , setAcitvityVisible ] = useState(false);
const [ qaVisible , setQaVisible ] = useState(false);
const [ successVisible , setSuccessVisible ] = useState(false);
const [ timeNum, setTimeNum] = useState(3);
const [ memberAccountInfo, setMemberAccountInfo ] = useState([]);
const [msg, setMsg] = useState('');
const { id, showNotification, checkIfLogin, showLoginDialog, temp, sectionMemberTitle } = props;
@ -267,6 +270,8 @@ function ZoneUser(props){
}
} else if(item.key == 'doc') {
setDocVisible(true);
} else if(item.key == 'repo') {
setProjectVisible(true);
} else if(item.key == 'acitvity') {
setAcitvityVisible(true);
} else if(item.key == 'qa') {
@ -377,7 +382,10 @@ function ZoneUser(props){
onCancel={()=>setAwardVisible(false)}
/>
<PointsDoc visible={docVisible} member={memberInfo}
onCancel={()=>setDocVisible(false)} onSure={() => { setDocVisible(false); setSuccessVisible(true);getInfo();}}
onCancel={()=>setDocVisible(false)} onSure={() => { setDocVisible(false); setMsg('首页新闻推荐'); setSuccessVisible(true);getInfo();}}
/>
<PointsProject visible={projectVisible} member={memberInfo}
onCancel={()=>setProjectVisible(false)} onSure={() => { setProjectVisible(false); setMsg('首页项目推荐'); setSuccessVisible(true);getInfo();}}
/>
<ApplyAcitvity visible={acitvityVisible} member={memberInfo} zoneName={zoneInfo?.name}
onCancel={()=>setAcitvityVisible(false)} onSure={(msg) => { showNotification(msg); setAcitvityVisible(false); getInfo();}}
@ -397,7 +405,7 @@ function ZoneUser(props){
>
<div className="info">
<img src={SuccessImg} alt=""/>
<p>恭喜获得专区<label>首页新闻推荐</label></p>
<p>恭喜获得专区<label>{msg}</label></p>
<Button className="btn_ok" onClick={() => {setSuccessVisible(false)}}>确定({timeNum}s)</Button>
</div>
</Modal>

View File

@ -552,12 +552,19 @@ export function getProjectListByScore(id,params) {
})
}
// 专区获取我的积分申请
export function getApplyMyList(params){
// 专区获取我的置顶文章
export function getMyTopArticle(id){
return fetch({
url:`/zone/points/apply/my/list`,
url:`/zone/points/account/article/top/${id}`,
method:"get",
})
}
// 专区获取我的置顶项目
export function getMyTopProject(id){
return fetch({
url:`/zone/points/account/project/top/${id}`,
method:"get",
params
})
}
@ -680,3 +687,27 @@ export function doDocTop(data) {
});
}
export function doProjectTop(data) {
return fetch({
url: `/zone/points/account/project/top`,
method: 'post',
data
});
}
// 获取文章列表
export function getPointsDocList(id){
return fetch({
url:`/zone/zoneFront/getTopDoc/${id}`,
method: 'get',
})
}
// 获取文章列表
export function getPointsProjectList(id){
return fetch({
url:`/zone/zoneFront/getTopProject/${id}`,
method: 'get',
})
}