功能——云享飞web首页点击飞手课堂展示飞手列表分页

上级 3ac6d24e
import React from 'react';
import { useRouter } from 'next/router';
import styled from 'styled-components';
import { InterListType } from '@/api/interface';
import { QueryCurriculumInfoListType } from '@/api/interface/course';
// 列表类型
type DetailType = InterListType<QueryCurriculumInfoListType>[0];
// 课程类型列表
const courseAttributeList: { label: string; value: number; color: string }[] = [
{ label: '免费', value: 0, color: '#f99a0b' },
{ label: '积分', value: 1, color: '#00AD53' },
{ label: '付费', value: 2, color: '#FF4600' },
];
const CourseListItem: React.FC<{ detail: DetailType }> = ({ detail }) => {
// 路由钩子
const router = useRouter();
// 获取当前课程属性
const getCourseAttribute = () => {
return courseAttributeList.find((i) => i.value === detail?.courseAttribute);
};
// 跳转商品详情
const handleDetail = () => {
router.push(`/course/detail/${detail?.id}`).then();
};
return (
<CourseListItemWrap onClick={handleDetail}>
<div className="mb-2 h-32 w-full" style={{ height: '10.5rem' }}>
<img
className="h-full w-full object-cover"
src={
detail?.surfaceUrl
? `${detail?.surfaceUrl}?x-oss-process=image/quality,q_25`
: `${detail?.videoUrl}?x-oss-process=video/snapshot,t_1000,m_fast`
}
alt={detail?.curriculumName}
/>
</div>
<div className="course-content w-full px-2">
<div className="content-title flex w-full flex-nowrap">
<div className="title text-ellipsis">{detail?.curriculumName}</div>
<div
className="tag"
style={{ background: getCourseAttribute()?.color }}
>
{getCourseAttribute()?.label}
</div>
</div>
<div className="text-ellipsis text-xs text-gray-400">
{detail?.curriculumDesc}
</div>
{!!detail?.requireAmout && (
<div className="content-price">
<span className="label">¥</span>
<span className="num">{detail?.requireAmout}</span>
</div>
)}
{!!detail?.requireIntegral && (
<div className="content-price">
<span className="num">{detail?.requireIntegral}</span>
<span className="label">积分</span>
</div>
)}
</div>
<div className="course-footer flex justify-between">
<div className="label">课程供应商</div>
<div className="num">{(detail?.id || 1) * 333}人已学习</div>
</div>
</CourseListItemWrap>
);
};
export default CourseListItem;
// 样式
const CourseListItemWrap = styled.div`
position: relative;
box-sizing: border-box;
width: calc((100% - (0.83rem * 3)) / 4);
height: 16.9rem;
background: #ffffff;
box-shadow: 0 0.17rem 0.86rem 0 rgba(65, 65, 65, 0.08);
border-radius: 0.33rem;
margin: 0 0.83rem 0.83rem 0;
cursor: pointer;
overflow: hidden;
&:hover {
filter: brightness(0.9);
}
&:nth-child(4n) {
margin-right: 0;
}
.course-content {
.content-title {
margin-bottom: 0.25rem;
.title {
font-weight: bold;
color: #333333;
margin-right: 0.25rem;
}
.tag {
min-width: 2.25rem;
box-sizing: border-box;
font-size: 12px;
background: #f99a0b;
border-radius: 0.1rem;
text-align: center;
color: #ffffff;
padding: 0 0.25rem;
transform: scale(0.8);
}
}
.content-price {
font-weight: 500;
color: #ff3300;
.num {
font-size: 15px;
line-height: 35rpx;
margin-right: 8rpx;
}
.label {
font-size: 12px;
line-height: 28rpx;
font-weight: bold;
}
}
}
.course-footer {
position: absolute;
width: 100%;
bottom: 0.5rem;
left: 0;
box-sizing: border-box;
padding: 0 0.5rem;
color: #aaa;
}
`;
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { RightOutlined } from '@ant-design/icons'; import { RightOutlined } from '@ant-design/icons';
import { Button } from 'antd'; import { Empty, Pagination } from 'antd';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import styled from 'styled-components'; import styled from 'styled-components';
import { InterDataType } from '@/api/interface'; import { InterListType, InterReqType } from '@/api/interface';
import { SelectCurriculumClassifyType } from '@/api/interface/course'; import { QueryCurriculumInfoListType } from '@/api/interface/course';
import { CourseAPI } from '@/api/modules/course'; import { CourseAPI } from '@/api/modules/course';
import { setGlobalData } from '@/store/module/globalData'; import CourseListItem from '@/components/courseItem';
// 列表类型 // 列表类型
type ListType = Array< type ListType = InterListType<QueryCurriculumInfoListType>;
InterDataType<SelectCurriculumClassifyType>[0] & { // 请求参数类型
children: InterDataType<SelectCurriculumClassifyType>; type ReqType = InterReqType<QueryCurriculumInfoListType>;
}
>;
const HomeTabView03: React.FC = () => { const HomeTabView03: React.FC = () => {
// 导航钩子 // 导航钩子
const router = useRouter(); const router = useRouter();
// store // store
const dispatch = useDispatch(); const dispatch = useDispatch();
// 分页数据
const [pagination, setPagination] = useState({
pageNo: 1,
pageSize: 8,
totalCount: 0,
});
// 列表数据 // 列表数据
const [tabList, setTabList] = useState<ListType>([]); const [dataList, setDataList] = useState<ListType>([]);
// 获取执照培训分类
const getCategoryInfo = async () => {
const res = await CourseAPI.selectCurriculumClassify();
if (res && res.code === '200') {
setTabList(
res.result
?.filter((i) => !i.twoCourseId)
?.map((i) => {
const children = res.result?.filter(
(k) => k.oneCourseId === i.oneCourseId && k.twoCourseId,
);
return {
...i,
children,
};
}),
);
}
};
// 跳转一级分类详情
const handleMain = (i: ListType[0]) => {
dispatch(
setGlobalData({
loadingSpinnerVisible: true,
}),
);
router.push(`/course/${i?.oneCourseId}`).then();
};
// 跳转二级分类详情
const handleSecond = (i: ListType[0], n: ListType[0]['children'][0]) => {
dispatch(
setGlobalData({
loadingSpinnerVisible: true,
}),
);
router.push(`/course/${i?.oneCourseId}/${n?.twoCourseId}`).then();
};
// 跳转更多
const handleMore = async () => { const handleMore = async () => {
await router.push('/course'); await router.push('/course');
}; };
// 组件挂载 // 组件挂载
useEffect(() => { useEffect(() => {
getCategoryInfo().then(); getDataList({}).then();
}, []); }, []);
// 获取课程列表
const getDataList = async (data: ReqType) => {
const res = await CourseAPI.getCourseVideoList({
pageNo: pagination.pageNo,
pageSize: pagination.pageSize,
...data,
});
if (res && res.code === '200') {
console.log('获取商品列表 --->', res);
const { list, totalCount, pageNo, pageSize } = res.result;
setDataList(list || []);
setPagination({
...pagination,
totalCount,
pageNo,
pageSize,
});
}
};
// 翻页回调
const handlePageChange = async (pageNo: number, pageSize: number) => {
await getDataList({ pageNo, pageSize });
};
return ( return (
<HomeTabWrap04 className="animate__animated animate__fast animate__fadeIn"> <HomeTabWrap04 className="animate__animated animate__fast animate__fadeIn">
<div className="tab-title flex-between w-full"> <div className="tab-title flex-between w-full">
...@@ -81,36 +70,22 @@ const HomeTabView03: React.FC = () => { ...@@ -81,36 +70,22 @@ const HomeTabView03: React.FC = () => {
<RightOutlined className="text-primary" style={{ fontSize: 10 }} /> <RightOutlined className="text-primary" style={{ fontSize: 10 }} />
</div> </div>
</div> </div>
<Pagination
showSizeChanger={false}
onChange={handlePageChange}
defaultPageSize={pagination.pageSize}
current={pagination.pageNo}
total={pagination.totalCount}
/>
</div> </div>
<div className="tab-list"> <div className="tab-list flex-start w-full">
{tabList.map((i, j) => ( {dataList?.length ? (
<div className="tab-item align-start flex" key={j}> dataList?.map((i, j) => <CourseListItem key={j} detail={i} />)
<div className={'tab-little flex-start'}> ) : (
{!!i.classifyUrl && ( <div className="list-empty flex-center h-24 w-full">
<img src={i.classifyUrl} alt={i.name} className="title-image" /> <Empty />
)}
<Button
type={'link'}
className="title-name"
onClick={() => handleMain(i)}
>
{i.name}
</Button>
</div>
<div className="tab-list flex-start">
{i.children?.map((n, m) => (
<Button
type={'link'}
key={m}
className="list-item"
onClick={() => handleSecond(i, n)}
>
{n.name}
</Button>
))}
</div>
</div> </div>
))} )}
</div> </div>
</HomeTabWrap04> </HomeTabWrap04>
); );
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论