forgeplus-react/src/forums/list/index.jsx

248 lines
10 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useEffect, useState } from "react";
import './index.scss';
import { Button, Carousel, Divider, Pagination, Tag } from "antd";
import { getForumsById, getForumSections, getForumsList } from "../api";
import { httpUrl } from "../fetch";
import { Link } from "react-router-dom";
import icon5 from '../image/icon5.png';
import icon6 from '../image/icon6.png';
import icon10 from '../image/icon10.png';
import Nodata from "../../forge/Nodata";
import { forumSectionId } from "../static";
import { rollingButton } from "../../components/button";
function List(props) {
const {mygetHelmetapi, location} = props;
const {common} = mygetHelmetapi || {};
const {forums: forumsDoMain} = common || {};
const tagNameByState = location && location.state && location.state.name;
const [forumsList, setForumsList] = useState([]);
const [forumsImgList, setForumsImgList] = useState([]);
const [hottestForumsList, setHottestForumsList] = useState([]);
// 板块信息
const [forumTag, setForumTag] = useState([]);
// 选中的板块详情
const [forumTagDetail, setForumTagDetail] = useState(undefined);
// 选中的板块对应的帖子列表
const LIMIT = 10;
const [total, setTotal] = useState(0);
const [page, setPage] = useState(1);
const [forumListByTag, setForumListByTag] = useState([]);
// 轮播的active
const [activeId, setActiveId] = useState(0);
const sortImg1 = {
0: require('../image/icon7.png'),
1: require('../image/icon8.png'),
2: require('../image/icon9.png'),
}
const sortImg2 = {
0: require('../image/icon2.png'),
1: require('../image/icon3.png'),
2: require('../image/icon4.png'),
}
useEffect(() => {
document.title = '论坛交流';
getForumsList({
page: 1,
limit: 6,
sort: 'published_at',
homepage_show: true
}).then(res => {
if (res) {
setForumsList(res.memos || []);
const imageList = res.memos.filter(item=>!!item.memo_image_info)
setForumsImgList(imageList)
setHottestForumsList(res.hottest_memos || []);
}
})
getForumSections(forumSectionId).then(res => {
if (res && res.recommend_forum_sections) {
// 获取所有子板块
const childrenTags = res.recommend_forum_sections;
// 并发请求所有板块的精华帖子
const fetchEssencePosts = async (tag) => {
try {
const essenceRes = await getForumsById(tag.id, {
page: 1,
limit: 1,
sort: 'published_at',
select_type: 'is_fine',
});
return {
...tag,
essencePosts: essenceRes?.memos || []
};
} catch (err) {
return {
...tag,
essencePosts: []
};
}
};
// 使用 Promise.all 并发处理所有请求
Promise.all(childrenTags.map(fetchEssencePosts))
.then(updatedTags => {
setForumTag(updatedTags);
if (updatedTags.length > 0) {
const tagByState = updatedTags.filter(i=>i.title.includes(tagNameByState))
setForumTagDetail(tagByState && !!tagByState.length ? tagByState[0] : updatedTags[0]);
}
})
.catch(error => {
// 降级处理
setForumTag(childrenTags);
if (childrenTags.length > 0) {
const tagByState = updatedTags.filter(i=>i.title.includes(tagNameByState))
setForumTagDetail(tagByState && !!tagByState.length ? tagByState[0] : updatedTags[0]);
}
});
}
})
}, [])
useEffect(() => {
if (forumTagDetail && forumTagDetail.id) {
const forums = forumTagDetail.essencePosts[0] || {}
getForumsById(forumTagDetail.id, {
page: page,
limit: LIMIT,
sort: 'published_at',
select_type: 'all',
hide_id: forums.id
}).then(res => {
if (res) {
setForumListByTag(res.memos || []);
setTotal(res.memos_count);
}
})
}
}, [forumTagDetail && forumTagDetail.id, page])
return (
<div className="forums-list-box">
<div className="forums-banner-box">
<div className="width1600 center">
<div className="font-60 font-bd forums-banner-title1">论坛交流·<span className="carousel-text">解锁头脑风暴</span></div>
<div className="font-18 mb35">开源动态社区前言新闻速递开启开源新视野</div>
{forumsDoMain && rollingButton({href: `${forumsDoMain}/forums/new`, name: '发布帖子', hoverName: '发布帖子', classname: "add-forums"})}
</div>
<div className="width1600 df pt70">
{forumsImgList && !!forumsImgList.length && <Carousel autoplay className='forums-list-left-Carousel' beforeChange={(_, nextId)=>{setActiveId(nextId)}}>
{forumsImgList.map((item, index)=>{
return <img src={httpUrl + item.memo_image_info.url} alt=''key={index}/>
})}
</Carousel>}
<div className="forums-list1">
{forumsList.map((item, index) => (
<div className={`font-18 forums-list-item ${activeId === index ? 'forums-list-item-active' : ''}`} key={index}>
<span className="forums-subject AlignCenter">
<Link className="task-hide" to={`/forums/${item.id}`}>{item.subject}</Link>
{index === 0 && <Tag color="#df2659" className="mr0">new</Tag>}
{item.is_original && <Tag color="#7e41f1">原创</Tag>}
</span>
</div>
))}
</div>
{/* 热门回答 */}
<div className="hot-forums-list flex1 ml20">
<div className="font-22 hot-forums-list-header">
<img src={require('../image/icon1.png')} alt="" width={24} className="mr8 mb3"/>
热门回答
</div>
<div className="forums-list2">
{hottestForumsList.slice(0,5).map((item, index) => (
<div className="font-18 forums-list-item" key={index}>
<span className="forums-subject AlignCenter">
{index < 3 ? <img src={sortImg2[index]} width={22} className="mr5"/> : <span className="ml5 mr10">{index + 1}</span>}
<Link className="task-hide" to={`/forums/${item.id}`}>{item.subject}</Link>
</span>
</div>
))}
</div>
</div>
</div>
</div>
<div className="forums-list3-box">
<div className="font-40 font-bd center mb20">精华论坛</div>
<div className="width1600 pb100">
{/* 四个板块 */}
<div className="forums-section-box df">
{forumTag.map((item, index) => {
const isSelected = forumTagDetail && forumTagDetail.id === item.id;
const forums = item.essencePosts[0] || {};
return (
<div key={index} className={`forums-section-item-box flex1 ${isSelected && 'active'}`} onClick={()=>{setForumTagDetail(item)}}>
<div className="forums-section-item">
<div className="font-20 font-bd center section-title pt8 pb5">{item.title}</div>
<div className="forums-section-item-content">
{forums.memo_image_info && <img src={httpUrl + forums.memo_image_info.url} alt="" className="memo_image_info"/>}
<div className="pl20 pr20">
<Link to={`/forums/${forums.id}`} className="AlignCenter pt10 pb10">
<div className="task-hide font-22">{forums.subject}</div>
<i className="iconfont icon-jiantou3 ml5 font-20"></i>
</Link>
<div className="pt10 pb10">
<img src={forums.image_url} alt="" className="user-img" />
{forums.username}
</div>
<div className="opacity8 clearfix pt10 pb10">
<img src={icon5} width={14} className="mb3 mr5" />
{forums.praises_count}
<img src={icon6} width={14} className="mb3 mr5 ml10" />
{forums.replies_count}
<span className="fr">{forums.published_time}</span>
</div>
</div>
</div>
</div>
</div>
)
})}
</div>
{/* 板块对应的帖子列表 */}
<div className="forums-list4-box mt30">
{forumListByTag.map((item, index) => {
const orderIndex = index+LIMIT*(page-1)
return <div className="forums-list4-item">
<div className="pr80 AlignCenter">
{orderIndex < 3 ? <img src={sortImg1[orderIndex]} width={24} className="mr10"/> : <span className="font-bd font-20 mr10">{orderIndex + 1}</span>}
<Link to={`/forums/${item.id}`} className="forums-list4-item-link font-22 task-hide">{item.subject}<i className="iconfont icon-jiantou3 ml5 font-20"></i></Link>
{item.sticky && <Tag color="#d06d3c">置顶</Tag>}
{item.is_original && <Tag color="#7e41f1">原创</Tag>}
{item.is_fine && <Tag color="#2E89FF">精华</Tag>}
</div>
<div className="opacity8 mt15">
<img src={item.image_url} alt="" className="user-img" />
{item.username}
<span className="ml10">{item.published_time}</span>
<Divider type="vertical" />
<img src={icon5} width={14} className="mb3 mr5" />
{item.praises_count}
<img src={icon6} width={14} className="mb3 mr5 ml10" />
{item.replies_count}
</div>
<span className="viewed_count">
<img src={icon10} width={11} className="mb3 mr5 viewed_count-icon" />
{item.viewed_count}
</span>
</div>
})}
{forumListByTag.length === 0 && (
<Nodata _html="暂无数据" />
)}
<Pagination pageSize={LIMIT} total={total} hideOnSinglePage={true} current={page} onChange={(page) => { setPage(page) }} className='center mt30' />
</div>
</div>
</div>
</div>
)
}
export default List;