Files
teach_sys_Demo/src/components/CourseList/index.jsx

177 lines
5.6 KiB
React
Raw Normal View History

import { useState, useEffect } from "react";
import { Collapse, Timeline, Spin } from "@arco-design/web-react";
import { getCourseLiveList } from "@/services/courseLive";
import "./index.css";
const TimelineItem = Timeline.Item;
const CollapseItem = Collapse.Item;
const CourseList = ({ className = "", onCourseClick }) => {
const [courseLiveList, setCourseLiveList] = useState([]);
const [loading, setLoading] = useState(false);
const [selectedCourseId, setSelectedCourseId] = useState(null);
useEffect(() => {
fetchCourseList();
}, []);
const fetchCourseList = async () => {
setLoading(true);
try {
const res = await getCourseLiveList();
if (res.success) {
const courseList = res.data || [];
setCourseLiveList(courseList);
// 设置默认选中今天的课程(如果有)
const todayStr = new Date().toISOString().split('T')[0];
let foundTodayCourse = false;
for (const unit of courseList) {
const todayCourse = unit.courses.find(c => c.date === todayStr);
if (todayCourse) {
setSelectedCourseId(todayCourse.courseId);
// 触发课程选择事件
if (onCourseClick) {
onCourseClick({
...todayCourse,
unitName: unit.unitName
});
}
foundTodayCourse = true;
break;
}
}
// 如果没有今天的课程选中第一个current或upcoming的课程
if (!foundTodayCourse) {
for (const unit of courseList) {
const activeCourse = unit.courses.find(c => c.current || c.upcoming);
if (activeCourse) {
setSelectedCourseId(activeCourse.courseId);
if (onCourseClick) {
onCourseClick({
...activeCourse,
unitName: unit.unitName
});
}
break;
}
}
}
}
} catch (error) {
console.error("获取课程列表失败:", error);
} finally {
setLoading(false);
}
};
// 判断课程状态
const getCourseStatus = (course) => {
if (course.completed) return "finish";
if (course.current) return "active";
// 判断未来课程的具体状态
if (course.upcoming) {
const courseDate = new Date(course.date);
const today = new Date();
// 重置时间部分只比较日期
courseDate.setHours(0, 0, 0, 0);
today.setHours(0, 0, 0, 0);
const timeDiff = courseDate - today;
const daysDiff = Math.floor(timeDiff / (24 * 60 * 60 * 1000));
// 未来7天内的课程显示为"即将开始"
if (daysDiff > 0 && daysDiff <= 7) {
return "coming";
}
// 7天后的课程显示为"未开始"
return "not-started";
}
// 默认状态
return "pending";
};
// 获取图标类型
const getDotIcon = (course) => {
if (course.completed) return <div className="time-line-dot-icon" />;
if (course.current) return <div className="time-line-clock-icon" />;
return <div className="time-line-lock-icon" />;
};
if (loading) {
return (
<div className={`${className} course-list-wrapper`}>
<p className="course-list-title">课程列表</p>
<div className="course-list-content">
<Spin />
</div>
</div>
);
}
return (
<div className={`${className} course-list-wrapper`}>
<p className="course-list-title">课程列表</p>
<div className="course-list-content">
<Collapse
lazyload
className="course-list"
bordered={false}
expandIconPosition="right"
defaultActiveKey={["1"]}
>
{courseLiveList.map((unit, index) => (
<CollapseItem
key={unit.unitId}
header={unit.unitName}
name={String(index + 1)}
className="course-list-item"
>
<Timeline>
{unit.courses.map((course) => (
<TimelineItem
key={course.courseId}
dot={getDotIcon(course)}
lineType="dashed"
>
<div
className={`time-line-item ${getCourseStatus(course)} ${selectedCourseId === course.courseId ? 'selected' : ''}`}
onClick={() => {
setSelectedCourseId(course.courseId);
onCourseClick && onCourseClick({ ...course, unitName: unit.unitName });
}}
style={{ cursor: 'pointer' }}
>
<p style={{
overflow: 'visible',
textOverflow: 'unset',
whiteSpace: 'normal',
wordBreak: 'break-word',
WebkitLineClamp: 'unset',
WebkitBoxOrient: 'unset',
display: 'block',
maxWidth: 'calc(100% - 70px)'
}}>{course.courseName}</p>
<div className="time-line-item-info">
<span>{course.teacherName}</span>
<span>{course.date}</span>
</div>
</div>
</TimelineItem>
))}
</Timeline>
</CollapseItem>
))}
</Collapse>
</div>
</div>
);
};
export default CourseList;