fix ccf专区首页

This commit is contained in:
谢思 2026-07-24 14:27:15 +08:00
parent 1ffbfa2ea9
commit 25fad88ec5
12 changed files with 170 additions and 40 deletions

View File

@ -5,7 +5,7 @@ import Nodata from '../../../Nodata';
import { Spin, Button, Icon } from 'antd'; import { Spin, Button, Icon } from 'antd';
import { tempConfig, tempEnum } from '../../tempInfo' import { tempConfig, tempEnum } from '../../tempInfo'
import MemberApply from '../../Component/memberApply'; import MemberApply from '../../Component/memberApply';
import { getVIPLists, getAuditStatus, applyJoin } from '../../api'; import { getVIPLists, getAuditStatus, applyJoin, getVIPTypeLists, getVIPListByTypeId } from '../../api';
import nodata from '../../img/nodata.png'; import nodata from '../../img/nodata.png';
import MemberList from '../../Component/memberList'; import MemberList from '../../Component/memberList';
import {getUniqueIdentifier,getUserName,getBrowserPlatform,getBrowserBrand} from '../../utils'; import {getUniqueIdentifier,getUserName,getBrowserPlatform,getBrowserBrand} from '../../utils';
@ -41,19 +41,117 @@ function CustomVip(props){
useEffect(()=>{ useEffect(()=>{
if(id){ if(id){
setIsSpin(true);
getLists(); getLists();
getMemberStatus(); getMemberStatus();
} }
},[id]) },[id])
function getLists(){ function getLists(){
getVIPLists(id).then(response=>{ setIsSpin(true);
if(response && response.data){ getVIPTypeLists(id).then(res=>{
setVIPLists(response.data.rows); const typeList = res.data.rows;
// memberCount
fetchMembersByTypes(typeList);
}).finally(() => {
setIsSpin(false); setIsSpin(false);
});
} }
}).catch(error=>{setIsSpin(false);})
//
function fetchMembersByTypes(typeList) {
if (!typeList || typeList.length === 0) {
return;
}
// 5
const CONCURRENCY_LIMIT = 5;
const results = new Array(typeList.length);
const totalTypes = typeList.length;
let completedCount = 0;
async function fetchSingleType(type, index) {
const typeId = type.id;
const memberCount = type.memberCount || 0;
const typeName = type.typeName || type.name;
const typeIntroduction = type.typeIntroduction || type.introduction;
let members;
if (memberCount > 500) {
members = await fetchMembersPaginatedSequential(typeId, memberCount, 500);
} else {
members = await fetchMembersOnce(typeId, memberCount);
}
results[index] = {
id: typeId,
typeName: typeName,
typeIntroduction: typeIntroduction,
zoneMemberList: members || []
};
completedCount++;
//
setVIPLists([...results.filter(Boolean)]);
}
//
async function executeInBatches() {
const promises = [];
for (let i = 0; i < typeList.length; i++) {
const type = typeList[i];
promises.push(fetchSingleType(type, i));
//
if (promises.length >= CONCURRENCY_LIMIT) {
await Promise.all(promises);
promises.length = 0;
}
}
if (promises.length > 0) {
await Promise.all(promises);
}
}
executeInBatches()
}
// memberCount > 200
async function fetchMembersPaginatedSequential(typeId, memberCount, pageSize) {
const totalPages = Math.ceil(memberCount / pageSize);
const allMembers = [];
for (let pageNum = 1; pageNum <= totalPages; pageNum++) {
try {
const response = await getVIPListByTypeId(id, {
memberTypeId: typeId,
pageNum,
pageSize
});
if (response && response.data && response.data.rows) {
allMembers.push(...response.data.rows);
}
} catch (error) {
console.error(`分页请求失败: typeId=${typeId}, pageNum=${pageNum}`, error);
}
}
return allMembers;
}
// memberCount <= 200
async function fetchMembersOnce(typeId, memberCount) {
return getVIPListByTypeId(id, {
memberTypeId: typeId,
pageNum: 1,
pageSize: memberCount
}).then(response => {
if (response && response.data && response.data.rows) {
return response.data.rows;
}
return [];
}).catch(() => {
return [];
});
} }
function getMemberStatus() { function getMemberStatus() {

View File

@ -326,9 +326,9 @@
border: 1px solid rgba(35, 93, 250, 0.13); border: 1px solid rgba(35, 93, 250, 0.13);
transition: all 0.3s ease; transition: all 0.3s ease;
// &:hover { &:hover {
// transform: translateY(-20px); transform: translateY(-20px);
// } }
} }
.ccf-vip-avatar { .ccf-vip-avatar {
@ -351,6 +351,12 @@
color: #262626; color: #262626;
margin-bottom: 12px; margin-bottom: 12px;
text-align: center; text-align: center;
em{
font-style: normal;
color: #466aff;
background: #dee4ff;
padding: 0 2px;
}
} }
.ccf-vip-tags { .ccf-vip-tags {
@ -729,7 +735,7 @@
.ccf-rule-section { .ccf-rule-section {
background-image: url('../image/ccf_bk14.png'); background-image: url('../image/ccf_bk14.png');
background-size: 100% 100%; background-size: 100% 100%;
padding-bottom: 100px; padding-bottom: 120px;
.ccf-rule-cards-container { .ccf-rule-cards-container {
position: relative; position: relative;

View File

@ -51,8 +51,8 @@ const ActivityItem = ({ id, keywords, name, summary }) => (
{moment(summary).format("YYYY")}<br /> {moment(summary).format("YYYY")}<br />
{moment(summary).format("MM/DD")} {moment(summary).format("MM/DD")}
</span> </span>
<div> <div className="flex1">
<div style={{ color: '#d8ebff' }} className="font-bd"><a href={`/zone/CCF-ODC/newdetail/${id}`}>{name}</a></div> <div style={{ color: '#d8ebff' }} className="font-bd task-hide"><a href={`/zone/CCF-ODC/newdetail/${id}`} className="task-hide">{name}</a></div>
<div style={{ color: '#d8ebffad' }}><i className="iconfont icon-weizhi font-15 mr5"></i>{keywords}</div> <div style={{ color: '#d8ebffad' }}><i className="iconfont icon-weizhi font-15 mr5"></i>{keywords}</div>
</div> </div>
</div> </div>
@ -75,7 +75,7 @@ const CCFIntro = ({ zoneInfo, sectionList, role }) => {
}, [sectionList]); }, [sectionList]);
useEffect(() => { useEffect(() => {
executiveCalendarId && getSubDocList(executiveCalendarId, { pageSize: 1000, pageNum: 1, auditStatus: 1 }).then(result => { executiveCalendarId && getSubDocList(executiveCalendarId, { pageSize: 100, pageNum: 1, auditStatus: 1 }).then(result => {
if (result && result.data.rows) { if (result && result.data.rows) {
setDocList(result.data.rows); setDocList(result.data.rows);
} }

View File

@ -12,6 +12,10 @@ function project({ id }) {
const [ typeList , setTypeList ] = useState([]); const [ typeList , setTypeList ] = useState([]);
const {communityUserCount, projectCount} = statistics || {} const {communityUserCount, projectCount} = statistics || {}
const handleLinkClick = () => {
window.scrollTo(0, 500);
};
useEffect(()=>{ useEffect(()=>{
id && getZoneStatistics(id).then(result => { id && getZoneStatistics(id).then(result => {
if (result && result.data) { if (result && result.data) {
@ -52,7 +56,7 @@ function project({ id }) {
<div className="ccf-project-blue-left"> <div className="ccf-project-blue-left">
<img src={ccf_img4} width={130} style={{margin: "0 6px 10px -10px"}}/> <img src={ccf_img4} width={130} style={{margin: "0 6px 10px -10px"}}/>
<i className="iconfont icon-a-duobianxing1 font-13 mr10"></i> <i className="iconfont icon-a-duobianxing1 font-13 mr10"></i>
<span className="font-38 font-bd mr10">{communityUserCount}+</span> <span className="font-38 font-bd mr10">{+communityUserCount > 999 ? `999+` : communityUserCount}</span>
<span className="font-15">贡献者</span> <span className="font-15">贡献者</span>
<div className="font-13">联结 CCF 会员搭建全球开源协同创新实践平台</div> <div className="font-13">联结 CCF 会员搭建全球开源协同创新实践平台</div>
<div className="ccf-project-blue-bottom-1"> <div className="ccf-project-blue-bottom-1">
@ -60,11 +64,11 @@ function project({ id }) {
<div className="df-center-between ccf-project-blue-bottom-3"> <div className="df-center-between ccf-project-blue-bottom-3">
<div className="ccf-project-blue-bottom-3-top"></div> <div className="ccf-project-blue-bottom-3-top"></div>
<div> <div>
<span className="font-38 font-bd">{typeList.length}+</span> <span className="font-38 font-bd">{typeList.length > 99 ? `99+` : typeList.length}</span>
<div className="opacity8">项目分类数</div> <div className="opacity8">项目分类数</div>
</div> </div>
<div> <div>
<span className="font-38 font-bd">{projectCount}+</span> <span className="font-38 font-bd">{+projectCount > 99 ? `99+` : projectCount}</span>
<div className="opacity8">代码库数</div> <div className="opacity8">代码库数</div>
</div> </div>
</div> </div>
@ -75,13 +79,13 @@ function project({ id }) {
<img src={icon1} width={46}/> <img src={icon1} width={46}/>
<div className="font-20 font-bd mt20 mb10">捐赠开源项目库</div> <div className="font-20 font-bd mt20 mb10">捐赠开源项目库</div>
<div className="font-15 color-5f6">覆盖AI云原生嵌入式等多领域优质开源项目开放共享</div> <div className="font-15 color-5f6">覆盖AI云原生嵌入式等多领域优质开源项目开放共享</div>
{typeId1 ? <Link to={{ pathname: `/zone/CCF-ODC/projects`, state: { id: typeId1 } }}>立即查看</Link> : <a className="unClick">暂未开放</a>} {typeId1 ? <Link to={{ pathname: `/zone/CCF-ODC/projects`, state: { id: typeId1 } }} onClick={(e) => { handleLinkClick(); }}>立即查看</Link> : <a className="unClick">暂未开放</a>}
</div> </div>
<div className="ccf_proType_2 center"> <div className="ccf_proType_2 center">
<img src={icon2} width={46}/> <img src={icon2} width={46}/>
<div className="font-20 font-bd mt20 mb10">开源学习资源库</div> <div className="font-20 font-bd mt20 mb10">开源学习资源库</div>
<div className="font-15 color-5f6">教程文档工具案例合集一站式开源学习平台</div> <div className="font-15 color-5f6">教程文档工具案例合集一站式开源学习平台</div>
{typeId2 ? <Link to={{ pathname: `/zone/CCF-ODC/projects`, state: { id: typeId2 } }}>立即查看</Link> : <a className="unClick">暂未开放</a>} {typeId2 ? <Link to={{ pathname: `/zone/CCF-ODC/projects`, state: { id: typeId2 } }} onClick={(e) => { handleLinkClick(); }}>立即查看</Link> : <a className="unClick">暂未开放</a>}
</div> </div>
</div> </div>
</div> </div>

View File

@ -79,7 +79,7 @@ const Registration = ({ sectionList, autoPlay = true }) => {
<div className="ccf-registration-left"> <div className="ccf-registration-left">
<Slider ref={sliderRef} {...carouselSettings}> <Slider ref={sliderRef} {...carouselSettings}>
{docList.map(item => { {docList.map(item => {
return <div><div className='width1600' dangerouslySetInnerHTML={{__html: Base64.decode(item.content)}}></div></div> return <div><div className='' dangerouslySetInnerHTML={{__html: Base64.decode(item.content)}}></div></div>
})} })}
</Slider> </Slider>
</div> </div>

View File

@ -45,7 +45,7 @@ function Rule({ sectionList, history }) {
}; };
}); });
// .concat(transformedCards) // .concat(transformedCards)
setRuleCards(transformedCards.concat(transformedCards).concat(transformedCards).concat(transformedCards).concat(transformedCards).concat(transformedCards)); setRuleCards(transformedCards);
} }
}) })
}, [ruleTypeId]) }, [ruleTypeId])
@ -106,10 +106,10 @@ function Rule({ sectionList, history }) {
// //
useEffect(() => { useEffect(() => {
if (!isAutoPlaying || displayCards.length <= 5) return; if (!isAutoPlaying || ruleCards.length <= 5) return;
const interval = setInterval(nextCard, autoPlayInterval); const interval = setInterval(nextCard, autoPlayInterval);
return () => clearInterval(interval); return () => clearInterval(interval);
}, [isAutoPlaying, nextCard, displayCards.length]); }, [isAutoPlaying, nextCard, ruleCards.length]);
// //
const handleMouseEnter = useCallback(() => { const handleMouseEnter = useCallback(() => {
@ -173,7 +173,7 @@ function Rule({ sectionList, history }) {
</div> </div>
{/* 导航控制 */} {/* 导航控制 */}
<div className="ccf-rule-nav"> {ruleCards && ruleCards.length > 5 && <div className="ccf-rule-nav">
<div className="ccf-rule-arrows"> <div className="ccf-rule-arrows">
<button <button
className="ccf-rule-arrow ccf-rule-arrow-left" className="ccf-rule-arrow ccf-rule-arrow-left"
@ -192,7 +192,7 @@ function Rule({ sectionList, history }) {
<i className="iconfont icon-arrowRight"></i> <i className="iconfont icon-arrowRight"></i>
</button> </button>
</div> </div>
</div> </div>}
</div> </div>
</div> </div>
</div> </div>

View File

@ -24,10 +24,11 @@ function Ccf_vip({id}) {
setVIPLists(result.data.rows.map(item=>{ setVIPLists(result.data.rows.map(item=>{
const {username, imageUrl, memberLevelName, memberTypeName} = item.extendData const {username, imageUrl, memberLevelName, memberTypeName} = item.extendData
return{ return{
name: username, name: item.title,
imageUrl: imageUrl, imageUrl: imageUrl,
memberLevel: memberLevelName, memberLevel: memberLevelName,
typeName: memberTypeName typeName: memberTypeName,
login: username
} }
})); }));
} }
@ -40,7 +41,7 @@ function Ccf_vip({id}) {
const list = response.data.rows && response.data.rows.reduce((acc, item) => { const list = response.data.rows && response.data.rows.reduce((acc, item) => {
const members = (item.zoneMemberList || []).map(member => ({ const members = (item.zoneMemberList || []).map(member => ({
...member, ...member,
typeName: item.typeName typeName: item.typeName,
})); }));
return acc.concat(members); return acc.concat(members);
}, []); }, []);
@ -76,16 +77,18 @@ function Ccf_vip({id}) {
{vipLists && vipLists.length > 0 ? ( {vipLists && vipLists.length > 0 ? (
<div className="ccf-vip-grid"> <div className="ccf-vip-grid">
{vipLists.map((member, index) => ( {vipLists.map((member, index) => (
<div className="ccf-vip-card" key={member.id}> <a href={`/${member.login}`} key={member.id}>
<div className="ccf-vip-card">
<div className="ccf-vip-avatar"> <div className="ccf-vip-avatar">
<img src={member.imageUrl} alt={member.name} /> <img src={member.imageUrl} alt={member.name} />
</div> </div>
<div className="ccf-vip-name">{member.name}</div> <div className="ccf-vip-name" dangerouslySetInnerHTML={{__html: member.name}}/>
<div className="ccf-vip-tags"> <div className="ccf-vip-tags">
<span className="ccf-vip-tag">{member.typeName}</span> <span className="ccf-vip-tag">{member.typeName}</span>
<span className="ccf-vip-tag">{member.memberLevel}</span> <span className="ccf-vip-tag">{member.memberLevel}</span>
</div> </div>
</div> </div>
</a>
))} ))}
</div> </div>
) : ( ) : (

View File

@ -1,5 +1,5 @@
import React,{ useState , useEffect, useMemo } from 'react'; import React,{ useState , useEffect, useMemo } from 'react';
import { Breadcrumb, Button, Form, Input, Select } from 'antd'; import { Breadcrumb, Button,Form, Input, Select, message } from 'antd';
import { getZoneUrl } from 'educoder'; import { getZoneUrl } from 'educoder';
import MdEditor from '../../../modules/tpm/challengesnew/tpm-md-editor'; import MdEditor from '../../../modules/tpm/challengesnew/tpm-md-editor';
import RichEditor from '../../Component/RichEditor'; import RichEditor from '../../Component/RichEditor';

View File

@ -38,7 +38,6 @@ function ProjectSource(props){
let platform = getBrowserPlatform() let platform = getBrowserPlatform()
let browser = getBrowserBrand() let browser = getBrowserBrand()
let username = getUserName(props.current_user); let username = getUserName(props.current_user);
getMemberStatus();
// if(!username) uuid = getUniqueIdentifier() // if(!username) uuid = getUniqueIdentifier()
let remark = ` 操作系统:${platform};浏览器:${browser};` let remark = ` 操作系统:${platform};浏览器:${browser};`
setZoneVisits({url,username,uuid,remark}) setZoneVisits({url,username,uuid,remark})
@ -58,6 +57,7 @@ function ProjectSource(props){
useEffect(()=>{ useEffect(()=>{
if(id){ if(id){
getTypeList(); getTypeList();
getMemberStatus();
} }
},[id]) },[id])

View File

@ -210,6 +210,22 @@ export function getVIPLists(id, params){
}) })
} }
export function getVIPListByTypeId(id, params){
return fetch({
url:`/zone/open/${id}/member/list`,
method: 'get',
params
})
}
export function getVIPTypeLists(id, params){
return fetch({
url:`/zone/open/${id}/memberType/list`,
method: 'get',
params
})
}
/**会员申请状态 */ /**会员申请状态 */
export function getAuditStatus(id){ export function getAuditStatus(id){
return fetch({ return fetch({

View File

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

View File

@ -386,9 +386,12 @@
font-size:86px; font-size:86px;
color:#ffffff; color:#ffffff;
font-family: "sanjikai"; font-family: "sanjikai";
padding-bottom: 18px;
margin-top: 90px;
} }
.sub_t{ .sub_t{
font-size: 18px; font-size: 18px;
padding-left: 10px;
} }
.bannerMenus{ .bannerMenus{
backdrop-filter:blur(44px); backdrop-filter:blur(44px);