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

260 lines
11 KiB
JavaScript

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";
import { HoverUnderline } from "../../components/title";
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'),
}
function init(updatedTags){
const tagByState = updatedTags.filter(i=>i.title.includes(tagNameByState))
setForumTagDetail(tagByState && !!tagByState.length ? tagByState[0] : updatedTags[0]);
tagByState && !!tagByState.length && window.scrollTo({
top: 850,
behavior: 'smooth'
})
}
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) {
init(updatedTags)
}
})
.catch(error => {
// 降级处理
setForumTag(childrenTags);
if (childrenTags.length > 0) {
init(childrenTags)
}
});
}
})
}, [])
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 mb10"><span>论坛交流·</span><span className="carousel-text"></span><span className="carousel-text"></span></div>
<div className="font-18 mb35 forums-banner-title2">需求反馈 技术交流 创意分享</div>
{forumsDoMain && rollingButton({href: `${forumsDoMain}/forums/new`, name: '发布帖子', hoverName: '发布帖子', classname: "add-forums"})}
</div>
<div className="width1600 df pt50 forums-hot-list">
{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" id="forums-list3-id">
{/* 四个板块 */}
<div className="forums-section-box df">
{forumTag.map((item, index) => {
const isSelected = forumTagDetail && forumTagDetail.id === item.id;
const forums = item.essencePosts && 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-22 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-20">{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 task-hide">
<HoverUnderline classname="font-22 task-hide">
{item.subject}
</HoverUnderline>
</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='edu-txt-right mt30' />
</div>
</div>
</div>
</div>
)
}
export default List;