feat: 实现公共课单元背景图片切换和项目库功能
- 为公共课直播间添加单元背景图片切换功能 - 支持终生学习系统、企业高管公开课、营销能力课的背景图片 - 点击不同单元课程时左侧直播间背景自动切换 - 添加我的项目库功能,展示25个完成项目 - 项目库采用灰色禁用样式,hover显示权限提示 - 优化李奇导师头像显示效果和容器背景色匹配 - 修复展会课程跳转链接 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -124,18 +124,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 李奇导师头像特殊调整 - 居中显示 */
|
/* 李奇导师头像特殊调整 - 放大并居中显示 */
|
||||||
.teacher-avatar.teacher-liqi {
|
.teacher-avatar.teacher-liqi {
|
||||||
overflow: hidden !important;
|
overflow: hidden !important;
|
||||||
|
background-color: rgb(190, 196, 202) !important;
|
||||||
img {
|
img {
|
||||||
width: 140% !important;
|
width: 260% !important;
|
||||||
height: 140% !important;
|
height: 260% !important;
|
||||||
object-fit: cover !important;
|
object-fit: cover !important;
|
||||||
object-position: center 35% !important;
|
object-position: center 30% !important;
|
||||||
position: absolute !important;
|
position: absolute !important;
|
||||||
top: 55% !important;
|
top: -25% !important;
|
||||||
left: 50% !important;
|
left: -20% !important;
|
||||||
transform: translate(-50%, -50%) !important;
|
transform: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ export default ({ className = "", isLock = false, selectedCourse, teacherData, u
|
|||||||
"郭建辉": "#E0D9D3", // 米灰色
|
"郭建辉": "#E0D9D3", // 米灰色
|
||||||
"赵志强": "#E3E2E0", // 浅灰色
|
"赵志强": "#E3E2E0", // 浅灰色
|
||||||
"孙应战": "#FFFFFF", // 白色
|
"孙应战": "#FFFFFF", // 白色
|
||||||
"魏立慧": "#DCD8D4" // 灰褐色
|
"魏立慧": "#DCD8D4", // 灰褐色
|
||||||
|
"李奇": "#E8E8E8" // 浅灰色 - 匹配头像背景
|
||||||
};
|
};
|
||||||
return backgrounds[name] || "#E3E2E0";
|
return backgrounds[name] || "#E3E2E0";
|
||||||
};
|
};
|
||||||
@@ -101,7 +102,13 @@ export default ({ className = "", isLock = false, selectedCourse, teacherData, u
|
|||||||
/* 选中课程时显示模糊的海报图和锁定状态 */
|
/* 选中课程时显示模糊的海报图和锁定状态 */
|
||||||
<div style={{ position: 'relative', width: '100%', height: '100%' }}>
|
<div style={{ position: 'relative', width: '100%', height: '100%' }}>
|
||||||
<img
|
<img
|
||||||
src={unitPosters?.[unitName] || unitPosters?.["终生学习系统课"]}
|
src={(() => {
|
||||||
|
const posterUrl = selectedCourse?.unitPoster || unitPosters?.[unitName] || unitPosters?.["终生学习系统课"];
|
||||||
|
console.log('CoursesVideoPlayer 背景图片URL:', posterUrl);
|
||||||
|
console.log('selectedCourse.unitPoster:', selectedCourse?.unitPoster);
|
||||||
|
console.log('unitName:', unitName);
|
||||||
|
return posterUrl;
|
||||||
|
})()}
|
||||||
alt={unitName}
|
alt={unitName}
|
||||||
style={{
|
style={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
|
|||||||
@@ -58,7 +58,32 @@
|
|||||||
|
|
||||||
.course-list-item .arco-collapse-item-header {
|
.course-list-item .arco-collapse-item-header {
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background-color: #f2f3f5;
|
background-color: rgba(242, 243, 245, 0.9);
|
||||||
|
color: #1d2129;
|
||||||
|
font-weight: 600;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 为带有背景图的单元项添加特殊样式 */
|
||||||
|
.course-list-item[style*="background-image"] .arco-collapse-item-header {
|
||||||
|
background-color: rgba(255, 255, 255, 0.9);
|
||||||
|
backdrop-filter: blur(4px);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.course-list-item[style*="background-image"] .arco-collapse-item-header::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: inherit;
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
opacity: 0.3;
|
||||||
|
z-index: -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.course-list-item .arco-timeline-item {
|
.course-list-item .arco-timeline-item {
|
||||||
@@ -67,7 +92,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.course-list-item .arco-collapse-item-content-expanded {
|
.course-list-item .arco-collapse-item-content-expanded {
|
||||||
background-color: #fff;
|
background-color: rgba(255, 255, 255, 0.95);
|
||||||
|
backdrop-filter: blur(2px);
|
||||||
|
border-radius: 0 0 8px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 为带有背景图的单元项内容区域添加特殊样式 */
|
||||||
|
.course-list-item[style*="background-image"] .arco-collapse-item-content-expanded {
|
||||||
|
background-color: rgba(255, 255, 255, 0.9);
|
||||||
|
backdrop-filter: blur(4px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.course-list-item .arco-collapse-item-content-box {
|
.course-list-item .arco-collapse-item-content-box {
|
||||||
|
|||||||
@@ -3,6 +3,13 @@ import { Collapse, Timeline, Spin } from "@arco-design/web-react";
|
|||||||
import { getPublicCourseLiveList } from "@/services/courseLive";
|
import { getPublicCourseLiveList } from "@/services/courseLive";
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
|
|
||||||
|
// 公共课单元海报数据
|
||||||
|
const unitPosters = {
|
||||||
|
"终生学习系统": "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/public_bg/recuW7gMz6sRee.jpg", // AI课 -> sRee
|
||||||
|
"企业高管公开课": "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/public_bg/recuW7gMz6CiPN.jpg", // 公共课 -> CiPN
|
||||||
|
"营销能力课": "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/public_bg/recuW7gMz6zwRv.jpg" // 营销课 -> zwRv
|
||||||
|
};
|
||||||
|
|
||||||
const TimelineItem = Timeline.Item;
|
const TimelineItem = Timeline.Item;
|
||||||
const CollapseItem = Collapse.Item;
|
const CollapseItem = Collapse.Item;
|
||||||
|
|
||||||
@@ -106,7 +113,15 @@ const PublicCourseList = ({ className = "", onCourseClick }) => {
|
|||||||
className={`time-line-item ${getCourseStatus(course)} ${selectedCourseId === course.courseId ? 'selected' : ''}`}
|
className={`time-line-item ${getCourseStatus(course)} ${selectedCourseId === course.courseId ? 'selected' : ''}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSelectedCourseId(course.courseId);
|
setSelectedCourseId(course.courseId);
|
||||||
onCourseClick && onCourseClick({ ...course, unitName: unit.unitName });
|
// 调试日志
|
||||||
|
console.log('点击课程单元:', unit.unitName);
|
||||||
|
console.log('匹配的海报URL:', unitPosters[unit.unitName]);
|
||||||
|
|
||||||
|
onCourseClick && onCourseClick({
|
||||||
|
...course,
|
||||||
|
unitName: unit.unitName,
|
||||||
|
unitPoster: unitPosters[unit.unitName] || unitPosters["终生学习系统"] || "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/public_bg/recuW7gMz6sRee.jpg"
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
style={{ cursor: 'pointer' }}
|
style={{ cursor: 'pointer' }}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -173,5 +173,35 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.my-project-item {
|
||||||
|
background-color: #f7f8fa !important;
|
||||||
|
border-color: #e5e6eb !important;
|
||||||
|
cursor: default !important;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: #e5e6eb !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
transform: none !important;
|
||||||
|
background-color: #f7f8fa !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-library-item-title {
|
||||||
|
color: #86909c !important;
|
||||||
|
border-color: #c9cdd4 !important;
|
||||||
|
background-color: #f7f8fa !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
> div {
|
||||||
|
> p {
|
||||||
|
color: #86909c !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disabled-detail {
|
||||||
|
color: #c9cdd4 !important;
|
||||||
|
cursor: default !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,114 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
import { Tooltip } from "@arco-design/web-react";
|
||||||
import toast from "@/components/Toast";
|
import toast from "@/components/Toast";
|
||||||
import InfiniteScroll from "@/components/InfiniteScroll";
|
import InfiniteScroll from "@/components/InfiniteScroll";
|
||||||
import ProjectCasesModal from "./components/ProjectCasesModal";
|
import ProjectCasesModal from "./components/ProjectCasesModal";
|
||||||
import { getProjectsList, getProjectsdetail } from "@/services/projectLibrary";
|
import { getProjectsList, getProjectsdetail } from "@/services/projectLibrary";
|
||||||
|
// 我的项目库数据
|
||||||
|
const myProjectsData = [
|
||||||
|
{
|
||||||
|
unitName: "商业活动策略设计与创意策划",
|
||||||
|
projects: [
|
||||||
|
"校园特色摆摊创意策划与出摊运营项目",
|
||||||
|
"社区水果店节日促销创意方案设计与落地执行项目"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
unitName: "商业活动全程策划执行与运营优化",
|
||||||
|
projects: [
|
||||||
|
"社区便利店促销活动策划落地项目",
|
||||||
|
"校园二手物品交易活动策划执行与运营项目"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
unitName: "商业空间与文创产品设计",
|
||||||
|
projects: [
|
||||||
|
"街边小型咖啡馆主题空间布置与配套文创周边设计项目",
|
||||||
|
"社区书店文创体验区空间规划项目"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
unitName: "短视频与自媒体运营",
|
||||||
|
projects: [
|
||||||
|
"本地某餐厅生活服务新媒体账号运营项目",
|
||||||
|
"某猫咖宠物日常类短视频账号运营实操项目"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
unitName: "漫展与二次元活动策划与执行",
|
||||||
|
projects: [
|
||||||
|
"南京 Comic Festival 周边展区活动统筹项目",
|
||||||
|
"盐城 ICGC 动漫嘉年华品牌互动区运营项目"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
unitName: "户外音乐节主题策划与流程统筹",
|
||||||
|
projects: [
|
||||||
|
"青春旋律校园户外音乐节活动策划与实施项目",
|
||||||
|
"环湖露天音乐节活动策划与组织项目"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
unitName: "城市 IP 赛事活动整合与策划",
|
||||||
|
projects: [
|
||||||
|
"2025 城市电竞对抗赛整体策划与落地项目",
|
||||||
|
"城市龙舟赛活动统筹与文化主题策划项目",
|
||||||
|
"成都跑酷&街舞跨界赛事活动策划与组织项目"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
unitName: "消费电子展品牌策划与执行",
|
||||||
|
projects: [
|
||||||
|
"智能穿戴设备消费电子展展区策划与执行项目",
|
||||||
|
"智能生活类消费电子展策划项目"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
unitName: "品牌招商展全案策划与招商运营",
|
||||||
|
projects: [
|
||||||
|
"苏州文旅文创产业品牌招商展策划与落地运营项目",
|
||||||
|
"南京青年创客品牌招商展策划项目"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
unitName: "商业街区打卡空间视觉呈现",
|
||||||
|
projects: [
|
||||||
|
"南京老门东历史街区创意打卡点策划项目",
|
||||||
|
"苏州观前街沉浸式商业打卡体验空间设计项目",
|
||||||
|
"无锡拈花湾文旅商业街区夜景灯光打卡点策划项目"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
unitName: "文旅衍生文创产品设计",
|
||||||
|
projects: [
|
||||||
|
"南京云锦纹样衍生丝巾与服饰配件设计项目",
|
||||||
|
"苏州园林拙政园窗棂纹样衍生文创书签与文具设计项目"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
|
|
||||||
|
|
||||||
const PAGE_SIZE = 10;
|
const PAGE_SIZE = 10;
|
||||||
|
|
||||||
const ProjectLibrary = () => {
|
const ProjectLibrary = () => {
|
||||||
|
// 处理我的项目数据
|
||||||
|
const processMyProjects = () => {
|
||||||
|
const projects = [];
|
||||||
|
myProjectsData.forEach(unit => {
|
||||||
|
unit.projects.forEach(projectName => {
|
||||||
|
projects.push({
|
||||||
|
id: `my-${projects.length + 1}`,
|
||||||
|
unitName: unit.unitName,
|
||||||
|
name: projectName,
|
||||||
|
isMyProject: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return projects;
|
||||||
|
};
|
||||||
|
|
||||||
|
const myProjects = processMyProjects();
|
||||||
const [modalData, setModalData] = useState(undefined);
|
const [modalData, setModalData] = useState(undefined);
|
||||||
const [projectList, setProjectList] = useState([]);
|
const [projectList, setProjectList] = useState([]);
|
||||||
const [projectCasesModalVisible, setProjectCasesModalVisible] =
|
const [projectCasesModalVisible, setProjectCasesModalVisible] =
|
||||||
@@ -19,6 +119,11 @@ const ProjectLibrary = () => {
|
|||||||
|
|
||||||
|
|
||||||
const handleProjectClick = async (item) => {
|
const handleProjectClick = async (item) => {
|
||||||
|
// 如果是我的项目,不允许点击
|
||||||
|
if (item?.isMyProject) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (item?.id) {
|
if (item?.id) {
|
||||||
const res = await getProjectsdetail(item.id);
|
const res = await getProjectsdetail(item.id);
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
@@ -84,8 +189,22 @@ const ProjectLibrary = () => {
|
|||||||
{/* 我的项目库板块 */}
|
{/* 我的项目库板块 */}
|
||||||
<div className="project-library-wrapper my-project-library">
|
<div className="project-library-wrapper my-project-library">
|
||||||
<p className="project-library-title">我完成的项目库</p>
|
<p className="project-library-title">我完成的项目库</p>
|
||||||
<div className="project-library-empty">
|
<div className="project-library-list">
|
||||||
<p>暂无项目</p>
|
{myProjects.map((item) => (
|
||||||
|
<Tooltip
|
||||||
|
key={item.id}
|
||||||
|
content="非学员及导师无查看权限"
|
||||||
|
position="top"
|
||||||
|
>
|
||||||
|
<li className="project-library-item my-project-item">
|
||||||
|
<p className="project-library-item-title">{item.unitName}</p>
|
||||||
|
<div>
|
||||||
|
<p>{item.name}</p>
|
||||||
|
<span className="disabled-detail">详情 ></span>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</Tooltip>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user