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

This commit is contained in:
Eeeros 2026-03-19 16:38:33 +08:00
commit b6e5600b86
1 changed files with 74 additions and 36 deletions

View File

@ -6,40 +6,16 @@ import right from '../img/schedule/right.webp'
import { timelineDir, ruleList } from '../info'
import { getDocDetail, getDocList } from '../api'
import { history } from 'umi'
import { Base64 } from 'js-base64'
function Schedule(props) {
const [selectedRule, setSelectedRule] = useState(ruleList[1].id)
const [ ruleInfo, setRuleInfo ] = useState({
headImg: icon,
name: '2026年第八届CCF开源创新大赛赛事规则',
summary: '原生编程挑战赛,是由阿里云主办,云原生应用平台承办的云原生知名品牌赛事。 自 2015 年开始,大赛已经成功举办了十届,共吸引了超过 91000 支队伍,覆盖 10 余个国家和地区。今年大赛主题全新升级为”全栈观测,智赢未来”,将深度探索全栈可观测技术在 AIOps 智能运…',
id: 1
})
const [ruleInfoList, setRuleInfoList] = useState({})
const [periodList, setPeriodList] = useState([])
const scheduleList = [
{ id: 1, periodId: 1, date: '3月20日', content: '我是此日期的具体赛事安排占一行我是此日期的具体赛事安排占一行', status: '报名招募期' },
{ id: 2, periodId: 1, date: '3月28日', content: '我是此日期的具体赛事安排占一行我是此日期的具体赛事安排占一行我是此日期的具体赛事安排占一行我是此日期的具体赛事安排占一行我是此日期的具体赛事安排占一行我是此日期的具体赛事安排占一行', status: '报名招募期' },
{ id: 3, periodId: 1, date: '3月28日', content: '我是此日期的具体赛事安排占一行我是此日期的具体赛事安排占一行我是此日期的具体赛事安排占一行', status: '报名招募期' },
{ id: 4, periodId: 1, date: '3月28日', content: '我是此日期的具体赛事安排占一行我是此日期的具体赛事安排占一行', status: '报名招募期' },
{ id: 5, periodId: 1, date: '3月28日', content: '我是此日期的具体赛事安排占一行我是此日期的具体赛事安排占一行', status: '报名招募期' },
{ id: 6, periodId: 2, date: '5月20日', content: '我是此日期的具体赛事安排占一行我是此日期的', status: '报名招募期' },
{ id: 7, periodId: 2, date: '5月20日', content: '我是此日期的具体赛事安排占一行我是此日期的', status: '报名招募期' },
{ id: 8, periodId: 2, date: '5月20日', content: '我是此日期的具体赛事安排占一行我是此日期的', status: '报名招募期' },
{ id: 9, periodId: 3, date: '7月20日', content: '行是此日期的具体赛事安排占一行', status: '报名招募期' },
{ id: 10, periodId: 4, date: '7月20日', content: '行是此日期的具体赛事安排占一行', status: '报名招募期' },
{ id: 11, periodId: 4, date: '7月20日', content: '行是此日期的具体赛事安排占一行', status: '报名招募期' },
{ id: 12, periodId: 4, date: '7月20日', content: '行是此日期的具体赛事安排占一行', status: '报名招募期' },
{ id: 13, periodId: 4, date: '7月20日', content: '行是此日期的具体赛事安排占一行', status: '报名招募期' },
{ id: 14, periodId: 4, date: '7月20日', content: '行是此日期的具体赛事安排占一行', status: '报名招募期' },
{ id: 15, periodId: 4, date: '7月20日', content: '行是此日期的具体赛事安排占一行', status: '报名招募期' },
{ id: 16, periodId: 4, date: '7月20日', content: '行是此日期的具体赛事安排占一行', status: '报名招募期' }
]
const [scheduleList, setScheduleList] = useState([])
const [selectedPeriod, setSelectedPeriod] = useState(1)
const scheduleRefs = useRef({})
@ -67,7 +43,67 @@ function Schedule(props) {
const getList = () => {
if (timelineDir) {
getDocList(timelineDir).then(res => {
setPeriodList(res.rows);
//
const sortedRows = res.rows.reverse();
setPeriodList(sortedRows);
// getDocDetail
const scheduleData = [];
let processedCount = 0;
sortedRows.forEach((period, periodIndex) => {
getDocDetail(period.id).then(detailRes => {
if (detailRes.data && detailRes.data.content) {
// Base64content
const decodedContent = Base64.decode(detailRes.data.content);
// 使DOMParserHTML
const parser = new DOMParser();
const doc = parser.parseFromString(decodedContent, 'text/html');
const paragraphs = doc.querySelectorAll('p');
let scheduleId = scheduleData.length + 1;
paragraphs.forEach((p) => {
const text = p.textContent.trim();
if (text) {
//
const parts = text.split(/\s+/);
if (parts.length > 0) {
const date = parts[0];
const content = parts.slice(1).join(' ');
//
scheduleData.push({
id: scheduleId++,
periodId: period.id,
date: date,
content: content,
status: period.summary || '进行中'
});
}
}
});
}
processedCount++;
// scheduleList
if (processedCount === sortedRows.length) {
// scheduleList
setScheduleList(scheduleData);
}
}).catch(err => {
console.error(`获取文章详情失败 (ID: ${period.id}):`, err);
processedCount++;
if (processedCount === sortedRows.length) {
setScheduleList(scheduleData);
}
});
});
}).catch(err => {
console.error('获取文档列表失败:', err);
});
@ -93,16 +129,18 @@ function Schedule(props) {
}
// 200px
const firstScheduleOfPeriod = scheduleList.find(schedule => schedule.periodId === periodId)
if (firstScheduleOfPeriod && scheduleRefs.current[firstScheduleOfPeriod.id]) {
const element = scheduleRefs.current[firstScheduleOfPeriod.id]
const container = element.parentElement
const offsetTop = element.getBoundingClientRect().top - container.getBoundingClientRect().top
if (scheduleList && scheduleList.length > 0) {
const firstScheduleOfPeriod = scheduleList.find(schedule => schedule.periodId === periodId)
if (firstScheduleOfPeriod && scheduleRefs.current[firstScheduleOfPeriod.id]) {
const element = scheduleRefs.current[firstScheduleOfPeriod.id]
const container = element.parentElement
const offsetTop = element.getBoundingClientRect().top - container.getBoundingClientRect().top
container.scrollTo({
top: offsetTop + container.scrollTop,
behavior: 'smooth'
})
container.scrollTo({
top: offsetTop + container.scrollTop,
behavior: 'smooth'
})
}
}
}