feat: 完善课程列表和直播纪要功能

- 使用CSV数据更新课程列表,支持多单元和课程状态显示
- 添加"即将开始"状态判断逻辑(今天或明天的课程)
- 删除直播纪要的"直播中"图标
- 修复时间轴排序,确保从早到晚显示
- 修复项目案例详情内容左对齐样式
- 修复组件语法错误和重复代码问题

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
KQL
2025-08-27 10:39:38 +08:00
parent a78e2c2414
commit ed5b65ea41
9 changed files with 283 additions and 46 deletions

View File

@@ -30,7 +30,10 @@
"mcp__serena__get_symbols_overview",
"mcp__serena__create_text_file",
"Bash(git remote add:*)",
"Bash(git add:*)"
"Bash(git add:*)",
"Bash(git remote remove:*)",
"Bash(git commit:*)",
"Bash(git push:*)"
],
"deny": [],
"ask": []

View File

@@ -83,6 +83,14 @@
background-image: url("@/assets/images/Common/time_line_clock_icon.png");
background-size: 100% 100%;
}
.time-line-lock-icon {
width: 12px;
height: 12px;
background-image: url("@/assets/images/Common/time_line_lock_icon.png");
background-size: 100% 100%;
opacity: 0.5;
}
.time-line-item {
width: 248px;
height: 74px;
@@ -148,6 +156,19 @@
background-size: 100% 100%;
}
}
.pending {
opacity: 0.6;
cursor: not-allowed;
> p {
color: #86909c;
}
.time-line-item-info {
color: #86909c;
}
}
.coming {
&::before {
content: "即将开始";

View File

@@ -1,10 +1,74 @@
import { Collapse, Timeline } from "@arco-design/web-react";
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 = "" }) => {
const [courseLiveList, setCourseLiveList] = useState([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
fetchCourseList();
}, []);
const fetchCourseList = async () => {
setLoading(true);
try {
const res = await getCourseLiveList();
if (res.success) {
setCourseLiveList(res.data || []);
}
} catch (error) {
console.error("获取课程列表失败:", error);
} finally {
setLoading(false);
}
};
// 判断课程状态
const getCourseStatus = (course) => {
if (course.completed) return "finish";
if (course.current) return "active";
// 判断是否为即将开始(今天或明天的课程)
const courseDate = new Date(course.date);
const today = new Date();
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
// 重置时间部分只比较日期
courseDate.setHours(0, 0, 0, 0);
today.setHours(0, 0, 0, 0);
tomorrow.setHours(0, 0, 0, 0);
if (courseDate.getTime() === today.getTime() || courseDate.getTime() === tomorrow.getTime()) {
return "coming";
}
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>
@@ -14,39 +78,34 @@ const CourseList = ({ className = "" }) => {
className="course-list"
bordered={false}
expandIconPosition="right"
defaultActiveKey={["1"]}
>
<CollapseItem
header="课程单元1"
name="1"
className="course-list-item"
>
<Timeline>
<TimelineItem
dot={<div className="time-line-dot-icon" />}
lineType="dashed"
>
<div className="time-line-item finish">
<p>终生学习系统</p>
<div className="time-line-item-info">
<span>张老师</span>
<span>2023-01-01</span>
</div>
</div>
</TimelineItem>
<TimelineItem
dot={<div className="time-line-clock-icon" />}
lineType="dashed"
>
<div className="time-line-item active">
<p>终生学习系统</p>
<div className="time-line-item-info">
<span>张老师</span>
<span>2023-01-01</span>
</div>
</div>
</TimelineItem>
</Timeline>
</CollapseItem>
{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)}`}>
<p>{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>

View File

@@ -35,16 +35,7 @@
background-size: 100% 100%;
}
&::after {
content: "";
position: absolute;
right: 0;
bottom: 10px;
width: 62px;
height: 20px;
background-image: url("@/assets/images/CoursesVideoPlayer/living_icon.png");
background-size: 100% 100%;
}
}
.live-summary-list {
width: 100%;

View File

@@ -10,8 +10,15 @@ const LiveSummary = ({ className = "", showBtn = false, isLiving = true }) => {
navigate("/job-strategy-detail");
};
// 根据type分组keyPoints
const groupedPoints = jobStrategyNotes.keyPoints.reduce((acc, point) => {
// 按时间排序keyPoints(从早到晚)
const sortedPoints = [...jobStrategyNotes.keyPoints].sort((a, b) => {
const timeA = a.time.split(':').map(Number);
const timeB = b.time.split(':').map(Number);
return (timeA[0] * 60 + timeA[1]) - (timeB[0] * 60 + timeB[1]);
});
// 根据type分组排序后的keyPoints
const groupedPoints = sortedPoints.reduce((acc, point) => {
const typeMap = {
strategy: "策略建议",
advice: "专家建议",

View File

@@ -4517,4 +4517,118 @@ mockData.profileOverview = {
},
};
// 课程直播间的课程列表数据
mockData.courseLiveList = [
{
unitId: "unit1",
unitName: "岗位体系认知",
courses: [
{ courseId: "c1-1", courseName: "教育体系认知", teacherName: "李老师", date: "2025-08-20", completed: true, current: false },
{ courseId: "c1-2", courseName: "现代文旅类企业的管理体系", teacherName: "王老师", date: "2025-08-21", completed: true, current: false },
{ courseId: "c1-3", courseName: "专科生的职业规划", teacherName: "张老师", date: "2025-08-22", completed: true, current: false }
]
},
{
unitId: "unit2",
unitName: "产业认知课",
courses: [
{ courseId: "c2-1", courseName: "文旅产业认知课", teacherName: "陈老师", date: "2025-08-23", completed: true, current: false },
{ courseId: "c2-2", courseName: "行业详解:旅游行业", teacherName: "赵老师", date: "2025-08-24", completed: true, current: false },
{ courseId: "c2-3", courseName: "行业详解:酒店与民宿行业", teacherName: "刘老师", date: "2025-08-25", completed: true, current: false },
{ courseId: "c2-4", courseName: "行业详解:活动与会展行业", teacherName: "周老师", date: "2025-08-26", completed: true, current: false },
{ courseId: "c2-5", courseName: "行业详解:文化服务行业", teacherName: "吴老师", date: "2025-08-27", completed: false, current: true }
]
},
{
unitId: "unit3",
unitName: "旅游产业全景与文旅基础知识",
courses: [
{ courseId: "c3-1", courseName: "现代文旅产业生态图谱", teacherName: "郑老师", date: "2025-08-28", completed: false, current: false },
{ courseId: "c3-2", courseName: "文旅政策法规与风险管理", teacherName: "王老师", date: "2025-08-29", completed: false, current: false },
{ courseId: "c3-3", courseName: "旅游产品与旅游资源", teacherName: "李老师", date: "2025-08-30", completed: false, current: false },
{ courseId: "c3-4", courseName: "游客行为心理学基础", teacherName: "张老师", date: "2025-08-31", completed: false, current: false },
{ courseId: "c3-5", courseName: "可持续旅游发展", teacherName: "陈老师", date: "2025-09-01", completed: false, current: false },
{ courseId: "c3-6", courseName: "单元小结", teacherName: "赵老师", date: "2025-09-02", completed: false, current: false }
]
},
{
unitId: "unit4",
unitName: "文旅服务:形象、沟通与体验的融合艺术",
courses: [
{ courseId: "c4-1", courseName: "文旅场景职业形象IP塑造", teacherName: "刘老师", date: "2025-09-03", completed: false, current: false },
{ courseId: "c4-2", courseName: "情境化服务体验设计", teacherName: "周老师", date: "2025-09-04", completed: false, current: false },
{ courseId: "c4-3", courseName: "政务商务接待专项礼仪", teacherName: "吴老师", date: "2025-09-05", completed: false, current: false },
{ courseId: "c4-4", courseName: "文旅服务中的非语言表达", teacherName: "郑老师", date: "2025-09-06", completed: false, current: false },
{ courseId: "c4-5", courseName: "服务沟通技巧与表达训练", teacherName: "王老师", date: "2025-09-07", completed: false, current: false },
{ courseId: "c4-6", courseName: "多元文化下的服务表达差异", teacherName: "李老师", date: "2025-09-08", completed: false, current: false },
{ courseId: "c4-7", courseName: "单元小结", teacherName: "张老师", date: "2025-09-09", completed: false, current: false }
]
},
{
unitId: "unit5",
unitName: "文旅与供应链基础",
courses: [
{ courseId: "c5-1", courseName: "供应链管理的内容", teacherName: "陈老师", date: "2025-09-10", completed: false, current: false },
{ courseId: "c5-2", courseName: "文旅资源调度", teacherName: "赵老师", date: "2025-09-11", completed: false, current: false },
{ courseId: "c5-3", courseName: "文旅产品全生命周期管理", teacherName: "刘老师", date: "2025-09-12", completed: false, current: false },
{ courseId: "c5-4", courseName: "文旅商品供应链", teacherName: "周老师", date: "2025-09-13", completed: false, current: false },
{ courseId: "c5-5", courseName: "住宿业资源协同", teacherName: "吴老师", date: "2025-09-14", completed: false, current: false },
{ courseId: "c5-6", courseName: "小型文旅项目的供应链角色模拟", teacherName: "郑老师", date: "2025-09-15", completed: false, current: false },
{ courseId: "c5-7", courseName: "文旅项目供应链特征", teacherName: "王老师", date: "2025-09-16", completed: false, current: false },
{ courseId: "c5-8", courseName: "文旅供应链中的B2B与B2C模式", teacherName: "李老师", date: "2025-09-17", completed: false, current: false },
{ courseId: "c5-9", courseName: "单元小结", teacherName: "张老师", date: "2025-09-18", completed: false, current: false }
]
},
{
unitId: "unit6",
unitName: "商业设计基础",
courses: [
{ courseId: "c6-1", courseName: "现代设计行业的发展现状", teacherName: "陈老师", date: "2025-09-19", completed: false, current: false },
{ courseId: "c6-2", courseName: "设计基础", teacherName: "赵老师", date: "2025-09-20", completed: false, current: false },
{ courseId: "c6-3", courseName: "字体设计与中文字体情绪表达", teacherName: "刘老师", date: "2025-09-21", completed: false, current: false },
{ courseId: "c6-4", courseName: "商业平面色彩搭配", teacherName: "周老师", date: "2025-09-22", completed: false, current: false },
{ courseId: "c6-5", courseName: "平面设计构图", teacherName: "吴老师", date: "2025-09-23", completed: false, current: false },
{ courseId: "c6-6", courseName: "图像编辑工具Photoshop", teacherName: "郑老师", date: "2025-09-24", completed: false, current: false },
{ courseId: "c6-7", courseName: "矢量与标志设计Illustrator", teacherName: "王老师", date: "2025-09-25", completed: false, current: false },
{ courseId: "c6-8", courseName: "快速设计工具使用Canva", teacherName: "李老师", date: "2025-09-26", completed: false, current: false },
{ courseId: "c6-9", courseName: "移动端视觉原型设计Figma", teacherName: "张老师", date: "2025-09-27", completed: false, current: false },
{ courseId: "c6-10", courseName: "视频剪辑入门:剪映", teacherName: "陈老师", date: "2025-09-28", completed: false, current: false },
{ courseId: "c6-11", courseName: "单元小结", teacherName: "赵老师", date: "2025-09-29", completed: false, current: false }
]
},
{
unitId: "unit7",
unitName: "AIGC人工智能生成内容",
courses: [
{ courseId: "c7-1", courseName: "AIGC发展简史与基本逻辑", teacherName: "刘老师", date: "2025-09-30", completed: false, current: false },
{ courseId: "c7-2", courseName: "AIGC的基本概念与各领域的应用", teacherName: "周老师", date: "2025-10-01", completed: false, current: false },
{ courseId: "c7-3", courseName: "AIGC语言模型chatgpt的灵活应用", teacherName: "吴老师", date: "2025-10-02", completed: false, current: false },
{ courseId: "c7-4", courseName: "AIGC生成内容的版权问题与合规使用", teacherName: "郑老师", date: "2025-10-03", completed: false, current: false },
{ courseId: "c7-5", courseName: "AIGC图像生成模型Stable Diffusion AI摄影和平面设计", teacherName: "王老师", date: "2025-10-04", completed: false, current: false },
{ courseId: "c7-6", courseName: "AIGC图像生成模型Stable Diffusion的应用操作", teacherName: "李老师", date: "2025-10-05", completed: false, current: false },
{ courseId: "c7-7", courseName: "AIGC视频应用音视频生成与AI自动剪辑", teacherName: "张老师", date: "2025-10-06", completed: false, current: false },
{ courseId: "c7-8", courseName: "AI词曲创作suno", teacherName: "陈老师", date: "2025-10-07", completed: false, current: false },
{ courseId: "c7-9", courseName: "单元小结", teacherName: "赵老师", date: "2025-10-08", completed: false, current: false }
]
},
{
unitId: "unit8",
unitName: "全栈新媒体运营赋能文旅营销",
courses: [
{ courseId: "c8-1", courseName: "新媒体应用传播学", teacherName: "刘老师", date: "2025-10-09", completed: false, current: false },
{ courseId: "c8-2", courseName: "新媒体故事结构入门", teacherName: "周老师", date: "2025-10-10", completed: false, current: false },
{ courseId: "c8-3", courseName: "新媒体产品策划", teacherName: "吴老师", date: "2025-10-11", completed: false, current: false },
{ courseId: "c8-4", courseName: "平台账号经营与内容赛道", teacherName: "郑老师", date: "2025-10-12", completed: false, current: false },
{ courseId: "c8-5", courseName: "各平台变现方式与具体方法", teacherName: "王老师", date: "2025-10-13", completed: false, current: false },
{ courseId: "c8-6", courseName: "内容运营:短视频的制作工具", teacherName: "李老师", date: "2025-10-14", completed: false, current: false },
{ courseId: "c8-7", courseName: "内容运营:短视频制作内容对标", teacherName: "张老师", date: "2025-10-15", completed: false, current: false },
{ courseId: "c8-8", courseName: "直播运营:直播间的搭建", teacherName: "陈老师", date: "2025-10-16", completed: false, current: false },
{ courseId: "c8-9", courseName: "品牌运营当地文化IP数字化传播", teacherName: "赵老师", date: "2025-10-17", completed: false, current: false },
{ courseId: "c8-10", courseName: "品牌运营:跨界营销创新", teacherName: "刘老师", date: "2025-10-18", completed: false, current: false },
{ courseId: "c8-11", courseName: "私域运营:私域流量池的运营", teacherName: "周老师", date: "2025-10-19", completed: false, current: false },
{ courseId: "c8-12", courseName: "单元小结", teacherName: "吴老师", date: "2025-10-20", completed: false, current: false }
]
}
];
// 模拟数据加载完成

View File

@@ -275,6 +275,7 @@
color: #1d2129;
font-size: 14px;
line-height: 1.6;
text-align: left;
h1, h2, h3, h4, h5, h6 {
color: #1d2129;
@@ -293,6 +294,7 @@
p {
margin: 8px 0;
line-height: 1.6;
text-align: left;
}
ul, ol {
@@ -303,6 +305,7 @@
li {
margin: 4px 0;
line-height: 1.6;
text-align: left;
}
ul li {

View File

@@ -0,0 +1,39 @@
import { mockData } from "@/data/mockData";
// 获取课程直播列表
export async function getCourseLiveList() {
// 模拟异步请求
return Promise.resolve({
success: true,
data: mockData.courseLiveList || [],
});
}
// 获取课程详情
export async function getCourseDetail(courseId) {
// 模拟异步请求
const allCourses = [];
mockData.courseLiveList?.forEach(unit => {
allCourses.push(...unit.courses);
});
const course = allCourses.find(c => c.courseId === courseId);
return Promise.resolve({
success: true,
data: course || null,
});
}
// 更新课程进度
export async function updateCourseProgress(courseId, progress) {
// 模拟异步请求
return Promise.resolve({
success: true,
data: {
courseId,
progress,
message: "进度更新成功",
},
});
}