Files
ALL-teach_sys/frontend_环保/课程可试看功能完整指南.md
KQL 38350dca36 更新12个教务系统并优化项目大小
主要更新:
- 更新所有12个产业的教务系统数据和功能
- 删除所有 node_modules 文件夹(节省3.7GB)
- 删除所有 .yoyo 缓存文件夹(节省1.2GB)
- 删除所有 dist 构建文件(节省55MB)

项目优化:
- 项目大小从 8.1GB 减少到 3.2GB(节省60%空间)
- 保留完整的源代码和配置文件
- .gitignore 已配置,防止再次提交大文件

启动脚本:
- start-industry.sh/bat/ps1 脚本会自动检测并安装依赖
- 首次启动时自动运行 npm install
- 支持单个或批量启动产业系统

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-17 14:36:25 +08:00

807 lines
23 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 课程可试看功能完整指南
**文档版本**: v2.0
**最后更新**: 2025-10-14
**适用项目**: 环保产业教务系统前端
---
## 📋 目录
1. [功能概述](#功能概述)
2. [iframe嵌入升级历史](#iframe嵌入升级历史)
3. [快速开始](#快速开始)
4. [详细配置步骤](#详细配置步骤)
5. [完整示例](#完整示例)
6. [技术实现说明](#技术实现说明)
7. [常见问题](#常见问题)
8. [验证清单](#验证清单)
---
## 功能概述
### 什么是"可试看"功能?
- 允许特定课程显示"可试看"标签
- 点击课程后通过**iframe嵌入**展示课程内容(**不是新建页面跳转**
- 非可试看课程显示锁定状态
- 可试看课程会自动排在课程列表最前面
### ⚡ 重要说明iframe嵌入功能已升级
**本项目已升级为iframe嵌入方式完全复用了文旅项目的实现**
#### 原始实现(已废弃)
- ❌ 点击可试看课程后打开**新的浏览器窗口**(使用 `window.open`
- ❌ 用户离开教务系统页面
- ❌ 需要手动切换标签页返回
- ❌ 用户体验不连贯
#### 当前实现(已升级)
- ✅ 点击可试看课程后在**当前页面内通过iframe嵌入**显示
- ✅ 用户始终停留在教务系统内
- ✅ 有专门的返回按钮或全屏功能
- ✅ 与文旅项目完全一致的交互体验
#### 当前功能特性
**课程直播间**
- 点击可试看课程后课程内容会在视频播放区域通过iframe嵌入显示
- 支持全屏功能(右上角有全屏按钮)
- iframe自动缩放zoom: 0.5
- 非可试看课程显示模糊背景+锁定图标
- **不再打开新窗口**
**课程作业页面**
- 点击"已完成"按钮后作业页面会全屏通过iframe嵌入显示
- 顶部有"返回课后作业"按钮
- 显示课程标题
- iframe自动缩放zoom: 0.8
- **不再打开新窗口**
### 您只需要做什么?
**只需修改一个文件**`src/data/mockData.js`
**配置两个字段**
- `canPreview`: 设置为 `true`
- `previewUrl`: 设置iframe要显示的URL
**其余功能iframe嵌入、全屏、返回按钮等已全部自动实现**
---
## iframe嵌入升级历史
### 升级信息
**升级日期**2025-10-14
**升级目的**将原始的新窗口跳转方式改为iframe嵌入提升用户体验
**参考项目**:文旅产业教务系统
### 原始版本的问题
**课程直播间**
```javascript
// 原始代码(已移除)
window.open(course.previewUrl, '_blank');
```
**课程作业**
```javascript
// 原始代码(已移除)
setShowIframe(true); // 使用固定URL
// 硬编码标题和URL
```
**存在的问题**
- ❌ 打开新的浏览器窗口
- ❌ 用户离开教务系统页面
- ❌ 需要手动切换标签页
- ❌ 用户体验割裂
### 当前版本的改进
**改进的文件**
1. `src/components/CoursesVideoPlayer/index.jsx` - 课程直播间iframe嵌入
2. `src/pages/HomeworkPage/index.jsx` - 课程作业动态iframe
3. `src/components/CourseList/index.jsx` - 移除window.open代码
**新增功能**
- ✅ 完整的Fullscreen API支持课程直播间
- ✅ 跨浏览器兼容Chrome、Firefox、Safari、Edge
- ✅ 动态iframe数据管理课程作业
- ✅ 可试看课程自动排序
- ✅ 与文旅项目完全一致的交互体验
### 升级效果对比
| 功能 | 原始版本 | 当前版本 |
|------|---------|---------|
| **课程直播间** | | |
| 展示方式 | window.open新窗口 | iframe嵌入 |
| 全屏功能 | ❌ 无 | ✅ 右上角全屏按钮 |
| 缩放适配 | ❌ 无 | ✅ zoom: 0.5全屏1.0 |
| 浏览器兼容 | ❌ 不完善 | ✅ 全浏览器支持 |
| **课程作业** | | |
| URL来源 | 硬编码 | 动态获取 |
| 课程标题 | 固定文本 | 动态显示 |
| 支持课程数 | 1个 | 无限 |
| 状态管理 | boolean | 数据对象 |
| **用户体验** | | |
| 页面跳转 | ✅ 打开新窗口 | ❌ 无跳转 |
| 用户留存 | ❌ 离开系统 | ✅ 停留系统内 |
| 交互流畅度 | ⭐⭐ | ⭐⭐⭐⭐⭐ |
---
## 快速开始
### 配置位置速查
只需修改 **一个文件**`src/data/mockData.js`
**位置1: 课程直播间约第680行**
```javascript
// 搜索这段注释找到位置
// 为"水质样品的采样与保存"课程添加试看标签和链接
```
**位置2: 课程作业约第5325行**
```javascript
// 搜索这段注释找到位置
// 为水质样品的采样与保存课程添加可试看标记
```
### 配置模板
#### 课程直播间配置
```javascript
// 为"您的课程名称"添加试看标签和链接
if (event.title === "课程名称" && unitName === "单元名称") {
courseObj.canPreview = true;
courseObj.previewUrl = "课程iframe嵌入URL";
}
```
#### 课程作业配置
```javascript
// 为"您的课程名称"作业添加可试看标记
if (course.courseName === "课程名称" && unit.unitName === "单元名称") {
homeworkItem.canPreview = true;
homeworkItem.previewUrl = "作业iframe嵌入URL";
}
```
### 配置参数说明
| 字段 | 类型 | 说明 | 示例 |
|------|------|------|------|
| `event.title` / `course.courseName` | string | 课程名称(必须完全匹配) | `"水质样品的采样与保存"` |
| `unitName` / `unit.unitName` | string | 单元名称(必须完全匹配) | `"检验检测实用取样方法"` |
| `canPreview` | boolean | 是否可试看(固定值) | `true` |
| `previewUrl` | string | 预览URLiframe地址 | `"https://example.com/course"` |
### ⚠️ 重要注意事项
1. **课程名称和单元名称必须完全匹配**
- 包括中英文标点符号、空格等
- 大小写必须一致
- 如果名称不匹配,可试看功能不会生效
2. **URL必须支持iframe嵌入**
- 某些网站设置了X-Frame-Options禁止iframe嵌入
- 确保URL可以在浏览器中正常访问
3. **课程作业的URL通常与课程直播间的URL不同**
- 课程直播间课程内容的URL
- 课程作业作业页面的URL
---
## 详细配置步骤
### 步骤1: 找到课程名称和单元名称
#### 方法1查看页面显示
直接在课程列表中查看显示的课程名称和单元名称
#### 方法2使用浏览器控制台
```javascript
// 在浏览器控制台执行
console.log(mockData.courseLiveData.vertical);
console.log(mockData.homework);
```
#### 方法3在代码中搜索
`src/data/mockData.js` 中搜索课程相关的关键词
### 步骤2: 配置课程直播间
`src/data/mockData.js` 文件中找到 `generateVerticalCourseLiveList` 函数。
找到这个位置大约在第680行左右
```javascript
// 为"水质样品的采样与保存"课程添加试看标签和链接
if (event.title === "水质样品的采样与保存" && unitName === "检验检测实用取样方法") {
courseObj.canPreview = true;
courseObj.previewUrl = "https://du9uay.github.io/environment-education-web/";
}
```
在上述代码**之后**,添加新的判断条件:
```javascript
// 为"您的课程名称"添加试看标签和链接
if (event.title === "您的课程名称" && unitName === "单元名称") {
courseObj.canPreview = true;
courseObj.previewUrl = "您的iframe嵌入URL";
}
```
### 步骤3: 配置课程作业
`src/data/mockData.js` 文件中,搜索这段注释:
```javascript
// 为水质样品的采样与保存课程添加可试看标记
```
找到这个位置大约在第5325行左右
```javascript
// 为水质样品的采样与保存课程添加可试看标记
if (course.courseName === "水质样品的采样与保存" && unit.unitName === "检验检测实用取样方法") {
homeworkItem.canPreview = true;
homeworkItem.previewUrl = "https://du9uay.github.io/environment-education-web/#/course-test";
}
```
在上述代码**之后**,添加新的判断条件:
```javascript
// 为"您的课程名称"作业添加可试看标记
if (course.courseName === "您的课程名称" && unit.unitName === "单元名称") {
homeworkItem.canPreview = true;
homeworkItem.previewUrl = "您的作业iframe嵌入URL";
}
```
### 步骤4: 保存并验证
1. 保存 `mockData.js` 文件
2. 刷新浏览器页面Vite会自动热更新
3. 使用验证清单检查功能是否正常
---
## 完整示例
### 示例1为"环境监测技术"课程添加可试看功能
假设要添加的课程信息:
- 课程名称:`环境监测技术`
- 单元名称:`环境监测基础`
- 课程直播URL`https://example.com/course/monitor`
- 作业页面URL`https://example.com/homework/monitor`
#### 配置课程直播间
`src/data/mockData.js` 的约第680行位置添加
```javascript
// 为"水质样品的采样与保存"课程添加试看标签和链接
if (event.title === "水质样品的采样与保存" && unitName === "检验检测实用取样方法") {
courseObj.canPreview = true;
courseObj.previewUrl = "https://du9uay.github.io/environment-education-web/";
}
// 为"环境监测技术"课程添加试看标签和链接
if (event.title === "环境监测技术" && unitName === "环境监测基础") {
courseObj.canPreview = true;
courseObj.previewUrl = "https://example.com/course/monitor";
}
```
#### 配置课程作业
`src/data/mockData.js` 的约第5325行位置添加
```javascript
// 为水质样品的采样与保存课程添加可试看标记
if (course.courseName === "水质样品的采样与保存" && unit.unitName === "检验检测实用取样方法") {
homeworkItem.canPreview = true;
homeworkItem.previewUrl = "https://du9uay.github.io/environment-education-web/#/course-test";
}
// 为"环境监测技术"课程作业添加可试看标记
if (course.courseName === "环境监测技术" && unit.unitName === "环境监测基础") {
homeworkItem.canPreview = true;
homeworkItem.previewUrl = "https://example.com/homework/monitor";
}
```
#### 验证配置
1. 保存文件
2. 刷新浏览器
3. 检查:
- ✅ 课程列表中"环境监测技术"显示在最前面
- ✅ 课程右侧显示"可试看"蓝色标签
- ✅ 点击课程后在视频区域显示iframe不打开新窗口
- ✅ 课程作业页面也显示"可试看"标签
- ✅ 点击作业后全屏显示iframe不打开新窗口
### 示例2批量添加多个可试看课程
如果要为多个课程添加可试看功能,只需要重复添加判断条件:
```javascript
// 课程直播间 - 批量添加
if (event.title === "水质样品的采样与保存" && unitName === "检验检测实用取样方法") {
courseObj.canPreview = true;
courseObj.previewUrl = "https://du9uay.github.io/environment-education-web/";
}
if (event.title === "环境监测技术" && unitName === "环境监测基础") {
courseObj.canPreview = true;
courseObj.previewUrl = "https://example.com/course/monitor";
}
if (event.title === "大气污染控制" && unitName === "污染控制技术") {
courseObj.canPreview = true;
courseObj.previewUrl = "https://example.com/course/air";
}
```
```javascript
// 课程作业 - 批量添加
if (course.courseName === "水质样品的采样与保存" && unit.unitName === "检验检测实用取样方法") {
homeworkItem.canPreview = true;
homeworkItem.previewUrl = "https://du9uay.github.io/environment-education-web/#/course-test";
}
if (course.courseName === "环境监测技术" && unit.unitName === "环境监测基础") {
homeworkItem.canPreview = true;
homeworkItem.previewUrl = "https://example.com/homework/monitor";
}
if (course.courseName === "大气污染控制" && unit.unitName === "污染控制技术") {
homeworkItem.canPreview = true;
homeworkItem.previewUrl = "https://example.com/homework/air";
}
```
---
## 技术实现说明
### iframe嵌入与新窗口跳转的区别
#### 新窗口跳转(原始方式 - 已废弃)
```javascript
// 原始代码(已移除)
window.open(url, '_blank');
```
**表现**
- 点击课程后打开新的浏览器标签页
- 用户离开当前教务系统页面
- 需要手动切换标签页返回
- 用户体验不连贯
#### iframe嵌入当前实现
```javascript
// 当前实现
<iframe src={url} />
```
**表现**
- 点击课程后在当前页面内显示课程内容
- 用户始终停留在教务系统内
- 有明确的返回按钮或关闭方式
- 用户体验流畅连贯
### 实现细节
#### 1. 课程直播间iframe嵌入
**实现位置**`src/components/CoursesVideoPlayer/index.jsx`
**核心代码**
```jsx
// 状态管理
const [isFullscreen, setIsFullscreen] = useState(false);
const iframeContainerRef = useRef(null);
// 全屏处理
const handleFullscreen = () => {
const container = iframeContainerRef.current;
if (!container) return;
if (!isFullscreen) {
// 进入全屏 - 支持多浏览器
if (container.requestFullscreen) {
container.requestFullscreen();
} else if (container.webkitRequestFullscreen) {
container.webkitRequestFullscreen();
}
// ... 其他浏览器前缀
} else {
// 退出全屏
if (document.exitFullscreen) {
document.exitFullscreen();
}
// ... 其他浏览器前缀
}
};
// 渲染逻辑
{selectedCourse.canPreview && selectedCourse.previewUrl ? (
<div ref={iframeContainerRef}>
<iframe
src={selectedCourse.previewUrl}
style={{
width: '100%',
height: '100%',
zoom: isFullscreen ? 1 : 0.5
}}
allowFullScreen
/>
<button onClick={handleFullscreen}>
{isFullscreen ? '退出全屏' : '全屏'}
</button>
</div>
) : (
<Locked /> // 锁定状态
)}
```
**功能特点**
- ✅ 自动检测 `canPreview``previewUrl`
- ✅ 在视频区域嵌入iframe
- ✅ 支持全屏使用Fullscreen API
- ✅ 跨浏览器兼容
- ✅ 自动缩放适配zoom: 0.5全屏时1.0
- ✅ 右上角全屏按钮带SVG图标
#### 2. 课程作业页面iframe嵌入
**实现位置**`src/pages/HomeworkPage/index.jsx`
**核心代码**
```jsx
// 状态管理
const [showIframe, setShowIframe] = useState(false);
const [iframeData, setIframeData] = useState(null);
// 点击处理
const handleClickBtn = (sectionId, item) => {
if (sectionId === 2 && (item.isShowCase || item.canPreview)) {
setIframeData({
url: item.previewUrl || "默认URL",
title: item.name
});
setShowIframe(true);
}
};
// 渲染逻辑
if (showIframe && iframeData) {
return (
<div className="homework-page-iframe-wrapper">
<div className="homework-page-iframe-header">
<button onClick={() => {
setShowIframe(false);
setIframeData(null);
}}>
<IconArrowLeft />
返回课后作业
</button>
<span>{iframeData.title}</span>
</div>
<iframe
src={iframeData.url}
style={{ zoom: 0.8 }}
/>
</div>
);
}
```
**功能特点**
- ✅ 自动检测 `canPreview``isShowCase`
- ✅ 全屏显示iframe
- ✅ 动态课程标题和URL
- ✅ 返回按钮(自动清理状态)
- ✅ 自动缩放zoom: 0.8
#### 3. 课程自动排序
**实现位置**`src/pages/HomeworkPage/index.jsx` - `getFilteredCourses` 函数
**核心代码**
```javascript
// 将可试看的课程排在最前面
const previewCourses = allCourses.filter(course => course.canPreview || course.isShowCase);
const otherCourses = allCourses.filter(course => !course.canPreview && !course.isShowCase);
return [...previewCourses, ...otherCourses];
```
**效果**
- ✅ 可试看课程自动排在最前面
- ✅ 无论"全部"还是"特定单元"视图都生效
- ✅ 提升用户体验
### 自动实现的功能
以下功能**无需手动配置**,系统已自动实现:
1. ✅ 可试看课程自动排在最前面
2. ✅ "可试看"标签自动显示
3.**iframe嵌入功能课程直播间和作业页面**
4.**全屏功能(课程直播间有全屏按钮)**
5.**返回按钮和导航功能(作业页面)**
6. ✅ 锁定状态自动判断
7. ✅ 按钮状态自动切换(蓝色/灰色)
### 您只需要做的事情
**只需在 `mockData.js` 中配置两处:**
1. 课程直播间:添加 `canPreview``previewUrl`
2. 课程作业:添加 `canPreview``previewUrl`
**系统会自动:**
- 在视频区域嵌入iframe而不是打开新窗口
- 在作业页面全屏嵌入iframe而不是打开新窗口
- 添加全屏按钮和返回按钮
- 处理所有交互逻辑
**就这么简单!** 🎉
---
## 常见问题
### Q1: 为什么添加了配置但没有显示"可试看"标签?
**可能原因:**
1. **课程名称不匹配**
- 检查 `event.title``course.courseName` 是否与数据中的课程名称完全一致
- 注意中英文标点符号、空格等
2. **单元名称不匹配**
- 检查 `unitName``unit.unitName` 是否与数据中的单元名称完全一致
3. **代码位置错误**
- 确保代码添加在正确的函数内部
- 课程直播间:`generateVerticalCourseLiveList` 函数内
- 课程作业:在生成 `homeworkItem` 的循环内
**解决方法:**
在浏览器控制台查看课程数据,确认实际的课程名称和单元名称:
```javascript
// 在浏览器控制台执行
console.log(mockData.courseLiveData.vertical);
console.log(mockData.homework);
```
### Q2: iframe显示空白或无法加载
**可能原因:**
1. **URL不支持iframe嵌入**
- 某些网站设置了X-Frame-Options禁止iframe嵌入
2. **URL地址错误**
- 检查URL是否可以直接在浏览器中访问
3. **跨域问题**
- 确保目标网站允许跨域访问
**解决方法:**
1. 先在浏览器中直接访问URL确认页面可以正常打开
2. 使用浏览器开发者工具的Network标签检查是否有加载错误
3. 查看Console是否有跨域相关的错误信息
### Q3: 点击课程后显示锁定状态而非iframe
**可能原因:**
`canPreview` 字段没有正确设置为 `true`
**解决方法:**
1. 检查配置代码中的 `canPreview` 是否拼写正确
2. 确认 `if` 条件判断确实被执行(添加 `console.log` 调试)
```javascript
if (event.title === "您的课程名称" && unitName === "单元名称") {
console.log("匹配到可试看课程:", event.title); // 添加调试日志
courseObj.canPreview = true;
courseObj.previewUrl = "您的URL";
}
```
### Q4: 可试看课程没有排在最前面
**可能原因:**
页面缓存或数据未刷新
**解决方法:**
1. 硬刷新浏览器Cmd+Shift+R 或 Ctrl+Shift+R
2. 清除浏览器缓存后重新加载
3. 检查开发服务器是否正常运行
### Q5: 配置后会打开新窗口吗?
**不会!**
本项目已完全移除 `window.open` 代码所有可试看课程都通过iframe嵌入显示。
### Q6: 如何验证iframe嵌入是否生效
**验证方法:**
1. 打开课程直播间或作业页面
2. 点击可试看课程
3. 检查浏览器地址栏URL是否改变
**结果判断**
-**URL没有改变** = iframe嵌入成功正确
-**URL改变或打开新标签页** = 配置有误(需要检查)
### Q7: 修改后需要重启服务器吗?
**不需要!**
- Vite开发服务器支持热更新
- 保存 `mockData.js` 后,页面会自动刷新
- 如果没有自动刷新,手动刷新浏览器即可
### Q8: 如何快速找到课程名称和单元名称?
**方法1查看页面显示**
直接在课程列表中查看显示的课程名称和单元名称
**方法2在代码中搜索**
`src/data/mockData.js` 中搜索课程相关的关键词
**方法3使用浏览器控制台**
```javascript
// 查看所有垂直课程数据
console.log(mockData.courseLiveData.vertical);
// 查看所有作业数据
console.log(mockData.homework);
```
---
## 验证清单
配置完成后,使用此清单验证功能:
### 课程直播间页面(/live
- [ ] 可试看课程显示在课程列表最前面
- [ ] 课程右侧显示"可试看"蓝色标签
- [ ] 点击可试看课程后视频区域显示iframe内容**不是新窗口**
- [ ] iframe右上角有全屏按钮
- [ ] 点击全屏按钮可以正常全屏显示
- [ ] iframe内容可以正常交互
- [ ] 非可试看课程显示锁定状态(模糊背景+锁图标)
- [ ] 浏览器地址栏URL未改变
### 课程作业页面(/homework
- [ ] 可试看课程作业显示在列表最前面
- [ ] 课程作业卡片显示"可试看"标签
- [ ] "已完成"按钮是蓝色(非灰色)
- [ ] 点击"已完成"按钮后全屏显示iframe**不是新窗口**
- [ ] 顶部显示"返回课后作业"按钮和课程标题
- [ ] 点击返回按钮可以正常返回列表
- [ ] iframe内容正常显示zoom: 0.8
- [ ] 浏览器地址栏URL未改变
---
## 快速参考卡片
### 配置位置
| 位置 | 文件 | 行号 | 搜索关键词 |
|------|------|------|-----------|
| 课程直播间 | `src/data/mockData.js` | 约680行 | `为"水质样品的采样与保存"课程添加试看标签` |
| 课程作业 | `src/data/mockData.js` | 约5325行 | `为水质样品的采样与保存课程添加可试看标记` |
### 配置模板
```javascript
// 课程直播间
if (event.title === "课程名称" && unitName === "单元名称") {
courseObj.canPreview = true;
courseObj.previewUrl = "URL";
}
// 课程作业
if (course.courseName === "课程名称" && unit.unitName === "单元名称") {
homeworkItem.canPreview = true;
homeworkItem.previewUrl = "URL";
}
```
### 常见错误
| 问题 | 原因 | 解决方法 |
|------|------|----------|
| 没有显示标签 | 名称不匹配 | 检查课程/单元名称是否完全一致 |
| iframe空白 | URL不支持嵌入 | 换一个支持iframe的URL |
| 显示锁定状态 | canPreview未生效 | 检查if条件是否匹配 |
| 打开新窗口 | 配置错误 | 不会出现已移除window.open |
---
## 项目信息
**项目名称**:环保产业教务系统前端
**项目路径**`/Users/apple/Documents/cursor/教务系统/frontend_环保`
**开发服务器**http://localhost:5161
**相关页面**
- 课程直播间http://localhost:5161/live
- 课程作业http://localhost:5161/homework
---
## 总结
### 核心要点
1. ✅ iframe嵌入功能已完全实现2025-10-14升级
2. ✅ 原始版本使用window.open已废弃
3. ✅ 当前版本完全复用文旅项目实现
4. ✅ 您只需配置 `canPreview``previewUrl`
5. ✅ 不需要修改任何组件代码
6. ✅ 不会打开新窗口,始终在当前页面显示
7. ✅ 支持全屏、返回按钮等所有交互功能
### 配置三步走
1. **找到课程名称和单元名称**
2. **在mockData.js的两个位置添加配置**
3. **保存文件并验证效果**
### 自动实现的功能
- iframe嵌入课程直播间和作业页面
- 全屏功能(课程直播间)
- 返回按钮(作业页面)
- 可试看课程自动排序
- "可试看"标签显示
- 锁定状态判断
- 按钮状态切换
**配置简单,功能强大!** 🎉
---
**文档结束**