完善
BIN
public/banners/banner8.png
Normal file
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1011 B After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 812 B After Width: | Height: | Size: 908 B |
Before Width: | Height: | Size: 944 B After Width: | Height: | Size: 1.4 KiB |
BIN
public/images/Help-center/course-active.png
Normal file
After Width: | Height: | Size: 844 B |
BIN
public/images/Help-center/disposition.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 182 KiB After Width: | Height: | Size: 224 KiB |
BIN
public/images/advertising/advertising3.png
Normal file
After Width: | Height: | Size: 175 KiB |
BIN
public/images/advertising/advertising4.png
Normal file
After Width: | Height: | Size: 368 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 273 KiB |
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 236 KiB |
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 260 KiB |
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 394 KiB |
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 359 KiB |
69
src/App.vue
@ -81,56 +81,9 @@ body {
|
||||
width: 100%;
|
||||
max-width: 1420px;
|
||||
margin: 0 auto;
|
||||
padding: 0 20px;
|
||||
/* padding: 0 20px; */
|
||||
}
|
||||
|
||||
/* 响应式断点 */
|
||||
@media (max-width: 1200px) {
|
||||
.container {
|
||||
max-width: 1140px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 992px) {
|
||||
.container {
|
||||
max-width: 960px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.container {
|
||||
max-width: 720px;
|
||||
padding: 0 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.container {
|
||||
max-width: 540px;
|
||||
padding: 0 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.container {
|
||||
padding: 0 8px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 缩放兼容性 - 确保在所有缩放级别下都能正常显示 */
|
||||
@media screen and (min-resolution: 2dppx) {
|
||||
body {
|
||||
zoom: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-resolution: 1dppx) {
|
||||
body {
|
||||
zoom: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 工具类 */
|
||||
.text-center {
|
||||
@ -157,24 +110,4 @@ body {
|
||||
.d-block {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.d-md-none {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.d-md-block {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.d-sm-none {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.d-sm-block {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
BIN
src/assets/fonts/AlimamaShuHeiTi-Bold.ttf
Normal file
BIN
src/assets/fonts/DouyinSansBold.otf
Normal file
BIN
src/assets/fonts/优设标题黑.ttf
Normal file
BIN
src/assets/fonts/庞门正道标题体3.0.ttf
Normal file
BIN
src/assets/fonts/文道潮黑.ttf
Normal file
@ -7,6 +7,12 @@ import router from './router'
|
||||
import i18n from './i18n'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
|
||||
import '@/assets/fonts/优设标题黑.ttf'
|
||||
import '@/assets/fonts/AlimamaShuHeiTi-Bold.ttf'
|
||||
import '@/assets/fonts/文道潮黑.ttf'
|
||||
import '@/assets/fonts/庞门正道标题体3.0.ttf'
|
||||
import '@/assets/fonts/DouyinSansBold.otf'
|
||||
|
||||
// Naive UI
|
||||
import {
|
||||
create,
|
||||
|
@ -295,21 +295,17 @@ onMounted(() => {
|
||||
|
||||
.activity-card {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.activity-card:hover {
|
||||
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.15);
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
/* 卡片头部 */
|
||||
.card-header {
|
||||
position: relative;
|
||||
height: 180px;
|
||||
height: 298px;
|
||||
overflow: hidden;
|
||||
border-radius: 12px 12px 0 0;
|
||||
}
|
||||
|
@ -110,7 +110,7 @@
|
||||
分类:<span class="category-link">{{ course.category?.name || '信息技术' }}</span>
|
||||
</span>
|
||||
<div class="meta-right">
|
||||
<button class="btn-notes">
|
||||
<button class="btn-notes" @click="handleNotesClick">
|
||||
<i class="icon-note"></i>
|
||||
记笔记
|
||||
</button>
|
||||
@ -134,7 +134,7 @@
|
||||
<div class="course-description">
|
||||
<p>{{ course.description ||
|
||||
'本课程深度聚焦问题,让每一位教师了解并学习使用DeepSeek,结合办公自动化职业岗位标准,以实际工作任务为引导,强调课程内容的易用性和岗位要求的匹配性。课程内容与全国计算机等级考试、"1+X"WPS办公应用职业技能等级证书,技能大赛紧密结合,课程设置紧密对应实际全面共享,可为职业工作人员、在校学生、创行教师提供服务与学习支持。'
|
||||
}}</p>
|
||||
}}</p>
|
||||
</div>
|
||||
|
||||
<!-- 讲师信息 -->
|
||||
@ -281,7 +281,7 @@
|
||||
</div>
|
||||
<div class="lesson-info">
|
||||
<span class="lesson-title" :class="{ 'disabled': !isUserEnrolled }">{{ section.name
|
||||
}}</span>
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="lesson-meta">
|
||||
<span v-if="isVideoLesson(section)" class="lesson-duration"
|
||||
@ -487,6 +487,21 @@ const enrollmentLoading = ref(false) // 报名加载状态
|
||||
// 报名状态
|
||||
const RegistrationStatus = ref(false)
|
||||
|
||||
// 处理记笔记点击事件
|
||||
const handleNotesClick = () => {
|
||||
if (isUserEnrolled.value) {
|
||||
// 已报名,执行记笔记逻辑
|
||||
console.log('开始记笔记')
|
||||
// 这里可以添加打开笔记模态框的逻辑
|
||||
} else if (userStore.isLoggedIn) {
|
||||
// 已登录但未报名,提示去报名
|
||||
enrollConfirmVisible.value = true
|
||||
} else {
|
||||
// 未登录,显示登录模态框
|
||||
showLoginModal()
|
||||
}
|
||||
}
|
||||
|
||||
// 计算用户是否已报名
|
||||
const isUserEnrolled = computed(() => {
|
||||
// 必须同时满足:用户已登录 AND 已报名该课程
|
||||
@ -523,41 +538,64 @@ const generateMockSections = (): CourseSection[] => {
|
||||
{ id: 5, lessonId: courseId.value, name: '第一课 程序设计入门', outline: 'https://example.com/video4.m3u8', parentId: 0, sort: 5, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: true, duration: '00:52:22' },
|
||||
{ id: 6, lessonId: courseId.value, name: '操作PPT', outline: 'https://example.com/ppt2.ppt', parentId: 0, sort: 6, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: undefined },
|
||||
{ id: 7, lessonId: courseId.value, name: '第二课 循环结构', outline: 'https://example.com/video5.m3u8', parentId: 0, sort: 7, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: true, duration: '01:03:56' },
|
||||
{ id: 8, lessonId: courseId.value, name: '函数&循环', outline: '', parentId: 0, sort: 8, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: undefined },
|
||||
{ id: 9, lessonId: courseId.value, name: '练习题目', outline: '', parentId: 0, sort: 9, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: undefined },
|
||||
{ id: 8, lessonId: courseId.value, name: '函数&循环', outline: 'https://example.com/video5.m3u8', parentId: 0, sort: 8, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: undefined },
|
||||
{ id: 9, lessonId: courseId.value, name: '第三课 条件结构', outline: 'https://example.com/video6.m3u8', parentId: 0, sort: 9, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: '00:45:30' },
|
||||
|
||||
// 第三章 - 程序的控制结构 (6个)
|
||||
{ id: 10, lessonId: courseId.value, name: '条件语句详解', outline: 'https://example.com/video6.m3u8', parentId: 0, sort: 10, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: '00:45:30' },
|
||||
{ id: 11, lessonId: courseId.value, name: '循环语句应用', outline: 'https://example.com/video7.m3u8', parentId: 0, sort: 11, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: '00:38:15' },
|
||||
{ id: 12, lessonId: courseId.value, name: '控制结构参考资料', outline: 'https://example.com/ppt3.ppt', parentId: 0, sort: 12, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: undefined },
|
||||
{ id: 13, lessonId: courseId.value, name: '条件判断练习', outline: '', parentId: 0, sort: 13, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: undefined },
|
||||
{ id: 14, lessonId: courseId.value, name: '循环结构作业', outline: '', parentId: 0, sort: 14, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: undefined },
|
||||
{ id: 15, lessonId: courseId.value, name: '控制结构测试', outline: '', parentId: 0, sort: 15, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: undefined },
|
||||
// 第三章 - 实战项目 (6个)
|
||||
{ id: 10, lessonId: courseId.value, name: '项目一:计算器开发', outline: 'https://example.com/video7.m3u8', parentId: 0, sort: 10, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: '01:20:15' },
|
||||
{ id: 11, lessonId: courseId.value, name: '项目源码下载', outline: 'https://example.com/source1.zip', parentId: 0, sort: 11, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: undefined },
|
||||
{ id: 12, lessonId: courseId.value, name: '项目二:数据管理系统', outline: 'https://example.com/video8.m3u8', parentId: 0, sort: 12, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: '01:45:20' },
|
||||
{ id: 13, lessonId: courseId.value, name: '作业:完成个人项目', outline: '', parentId: 0, sort: 13, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: undefined },
|
||||
{ id: 14, lessonId: courseId.value, name: '项目三:Web应用开发', outline: 'https://example.com/video9.m3u8', parentId: 0, sort: 14, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: '02:10:45' },
|
||||
{ id: 15, lessonId: courseId.value, name: '期末考试', outline: '', parentId: 0, sort: 15, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: undefined },
|
||||
|
||||
// 第四章 - 大语言模型介绍 (5个)
|
||||
{ id: 16, lessonId: courseId.value, name: 'AI发展历程', outline: 'https://example.com/video8.m3u8', parentId: 0, sort: 16, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: '01:12:45' },
|
||||
{ id: 17, lessonId: courseId.value, name: '大语言模型原理', outline: 'https://example.com/video9.m3u8', parentId: 0, sort: 17, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: '00:58:20' },
|
||||
{ id: 18, lessonId: courseId.value, name: 'AI模型对比资料', outline: 'https://example.com/ppt4.ppt', parentId: 0, sort: 18, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: undefined },
|
||||
{ id: 19, lessonId: courseId.value, name: 'AI应用场景分析', outline: '', parentId: 0, sort: 19, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: undefined },
|
||||
{ id: 20, lessonId: courseId.value, name: '大语言模型考试', outline: '', parentId: 0, sort: 20, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: undefined },
|
||||
// 第四章 - 高级应用 (4个)
|
||||
{ id: 16, lessonId: courseId.value, name: '高级特性介绍', outline: 'https://example.com/video10.m3u8', parentId: 0, sort: 16, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: '00:55:30' },
|
||||
{ id: 17, lessonId: courseId.value, name: '性能优化技巧', outline: 'https://example.com/video11.m3u8', parentId: 0, sort: 17, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: '01:15:20' },
|
||||
{ id: 18, lessonId: courseId.value, name: '部署与发布', outline: 'https://example.com/video12.m3u8', parentId: 0, sort: 18, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: '00:40:15' },
|
||||
{ id: 19, lessonId: courseId.value, name: '课程总结', outline: 'https://example.com/video13.m3u8', parentId: 0, sort: 19, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: '00:30:10' },
|
||||
|
||||
// 第五章 - DeepSeek实际应用 (6个)
|
||||
{ id: 21, lessonId: courseId.value, name: 'DeepSeek平台介绍', outline: 'https://example.com/video10.m3u8', parentId: 0, sort: 21, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: '00:42:10' },
|
||||
{ id: 22, lessonId: courseId.value, name: 'API接口使用', outline: 'https://example.com/video11.m3u8', parentId: 0, sort: 22, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: '00:55:35' },
|
||||
{ id: 23, lessonId: courseId.value, name: '实战项目演示', outline: 'https://example.com/video12.m3u8', parentId: 0, sort: 23, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: '01:25:18' },
|
||||
{ id: 24, lessonId: courseId.value, name: 'DeepSeek开发文档', outline: 'https://example.com/ppt5.ppt', parentId: 0, sort: 24, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: undefined },
|
||||
{ id: 25, lessonId: courseId.value, name: '项目实战作业', outline: '', parentId: 0, sort: 25, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: undefined },
|
||||
{ id: 26, lessonId: courseId.value, name: 'DeepSeek应用考试', outline: '', parentId: 0, sort: 26, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: undefined },
|
||||
// 第五章 - 拓展学习 (3个)
|
||||
{ id: 20, lessonId: courseId.value, name: '行业发展趋势', outline: 'https://example.com/video14.m3u8', parentId: 0, sort: 20, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: '00:35:45' },
|
||||
{ id: 21, lessonId: courseId.value, name: '学习资源推荐', outline: 'https://example.com/resources.pdf', parentId: 0, sort: 21, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: undefined },
|
||||
{ id: 22, lessonId: courseId.value, name: '结业证书申请', outline: '', parentId: 0, sort: 22, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: undefined },
|
||||
|
||||
// 第六章 - 综合项目实战 (5个)
|
||||
{ id: 27, lessonId: courseId.value, name: '项目需求分析', outline: 'https://example.com/video13.m3u8', parentId: 0, sort: 27, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: '00:35:45' },
|
||||
{ id: 28, lessonId: courseId.value, name: '系统架构设计', outline: 'https://example.com/video14.m3u8', parentId: 0, sort: 28, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: '00:48:22' },
|
||||
{ id: 29, lessonId: courseId.value, name: '项目开发指南', outline: 'https://example.com/ppt6.ppt', parentId: 0, sort: 29, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: undefined },
|
||||
{ id: 30, lessonId: courseId.value, name: '综合项目作业', outline: '', parentId: 0, sort: 30, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: undefined },
|
||||
{ id: 31, lessonId: courseId.value, name: '期末综合考试', outline: '', parentId: 0, sort: 31, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: undefined }
|
||||
// 第六章 - 答疑与交流 (2个)
|
||||
{ id: 23, lessonId: courseId.value, name: '常见问题解答', outline: 'https://example.com/video15.m3u8', parentId: 0, sort: 23, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: '00:25:30' },
|
||||
{ id: 24, lessonId: courseId.value, name: '在线答疑直播', outline: 'https://example.com/live1.m3u8', parentId: 0, sort: 24, level: 1, revision: 1, createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null, completed: false, duration: '01:30:00' }
|
||||
]
|
||||
}
|
||||
|
||||
// 将章节按章分组
|
||||
const groupSectionsByChapter = (sections: CourseSection[]) => {
|
||||
const chapterTitles = [
|
||||
'课前准备',
|
||||
'程序设计基础知识',
|
||||
'实战项目',
|
||||
'高级应用',
|
||||
'拓展学习',
|
||||
'答疑与交流'
|
||||
]
|
||||
|
||||
const groups: ChapterGroup[] = []
|
||||
let sectionsPerChapter = [4, 5, 6, 4, 3, 2] // 每章的课程数量
|
||||
let sectionIndex = 0
|
||||
|
||||
for (let i = 0; i < chapterTitles.length; i++) {
|
||||
const chapterSections = sections.slice(sectionIndex, sectionIndex + sectionsPerChapter[i])
|
||||
if (chapterSections.length > 0) {
|
||||
groups.push({
|
||||
title: `第${i+1}章 ${chapterTitles[i]}`,
|
||||
sections: chapterSections,
|
||||
expanded: i === 0 // 默认展开第一章
|
||||
})
|
||||
}
|
||||
sectionIndex += sectionsPerChapter[i]
|
||||
}
|
||||
|
||||
return groups
|
||||
}
|
||||
|
||||
// 根据章节数据生成分组
|
||||
const generateChapterGroups = () => {
|
||||
// 确保有章节数据
|
||||
@ -569,47 +607,12 @@ const generateChapterGroups = () => {
|
||||
console.log('开始生成章节分组,原始数据:', courseSections.value)
|
||||
console.log('章节数据数量:', courseSections.value.length)
|
||||
|
||||
// 手动创建章节分组,符合图片中的结构
|
||||
const groups: ChapterGroup[] = [
|
||||
{
|
||||
title: '第一章 课前准备',
|
||||
sections: courseSections.value.slice(0, 4), // 前4个项目
|
||||
expanded: true
|
||||
},
|
||||
{
|
||||
title: '第二章 程序设计基础知识',
|
||||
sections: courseSections.value.slice(4, 9), // 5个项目
|
||||
expanded: true
|
||||
},
|
||||
{
|
||||
title: '第三章 程序的控制结构',
|
||||
sections: courseSections.value.slice(9, 15), // 6个项目
|
||||
expanded: false
|
||||
},
|
||||
{
|
||||
title: '第四章 大语言模型介绍',
|
||||
sections: courseSections.value.slice(15, 20), // 5个项目
|
||||
expanded: false
|
||||
},
|
||||
{
|
||||
title: '第五章 DeepSeek实际应用',
|
||||
sections: courseSections.value.slice(20, 26), // 6个项目
|
||||
expanded: false
|
||||
},
|
||||
{
|
||||
title: '第六章 综合项目实战',
|
||||
sections: courseSections.value.slice(26, 31), // 5个项目
|
||||
expanded: false
|
||||
}
|
||||
]
|
||||
|
||||
console.log('生成的章节分组:', groups)
|
||||
console.log('第一章节数:', groups[0].sections.length)
|
||||
console.log('第二章节数:', groups[1].sections.length)
|
||||
groupedSections.value = groups
|
||||
// 使用统一的分组函数
|
||||
groupedSections.value = groupSectionsByChapter(courseSections.value)
|
||||
console.log('生成的章节分组:', groupedSections.value)
|
||||
}
|
||||
|
||||
// 获取章节标题
|
||||
// 获取章节标题(已弃用,使用groupSectionsByChapter替代)
|
||||
// const getChapterTitle = (chapterIndex: number): string => {
|
||||
// const titles = [
|
||||
// '课前准备',
|
||||
@ -775,56 +778,50 @@ const loadCourseSections = async () => {
|
||||
sectionsLoading.value = true
|
||||
sectionsError.value = ''
|
||||
|
||||
console.log('开始加载课程章节,课程ID:', courseId.value)
|
||||
console.log('调用API: CourseApi.getCourseSections')
|
||||
|
||||
console.log('调用API获取课程章节...')
|
||||
const response = await CourseApi.getCourseSections(courseId.value)
|
||||
console.log('章节API响应:', response)
|
||||
console.log('响应状态码:', response.code)
|
||||
console.log('响应数据:', response.data)
|
||||
|
||||
if (response.code === 0 || response.code === 200) {
|
||||
courseSections.value = response.data.list || []
|
||||
console.log('章节数据设置成功,数量:', courseSections.value.length)
|
||||
console.log('章节详细数据:', courseSections.value)
|
||||
|
||||
// 如果API返回的数据为空,使用模拟数据
|
||||
if (courseSections.value.length === 0) {
|
||||
console.log('API返回数据为空,使用模拟数据')
|
||||
courseSections.value = generateMockSections()
|
||||
if (response.data && Array.isArray(response.data)) {
|
||||
courseSections.value = response.data
|
||||
groupedSections.value = groupSectionsByChapter(response.data)
|
||||
console.log('章节数据设置成功:', courseSections.value)
|
||||
console.log('分组数据:', groupedSections.value)
|
||||
} else {
|
||||
console.log('API返回的章节数据为空,使用模拟数据')
|
||||
loadMockData()
|
||||
}
|
||||
|
||||
// 生成章节分组
|
||||
generateChapterGroups()
|
||||
} else {
|
||||
console.log('API调用失败,使用模拟数据')
|
||||
courseSections.value = generateMockSections()
|
||||
generateChapterGroups()
|
||||
sectionsError.value = '' // 清除错误,因为我们有模拟数据
|
||||
console.log('API返回错误,使用模拟数据')
|
||||
loadMockData()
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('加载课程章节失败:', err)
|
||||
console.log('网络错误,使用模拟数据')
|
||||
courseSections.value = generateMockSections()
|
||||
generateChapterGroups()
|
||||
sectionsError.value = '' // 清除错误,因为我们有模拟数据
|
||||
console.log('API调用失败,使用模拟数据')
|
||||
loadMockData()
|
||||
} finally {
|
||||
sectionsLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 强制加载模拟数据
|
||||
// const loadMockData = () => {
|
||||
// console.log('强制加载模拟数据')
|
||||
// courseSections.value = generateMockSections()
|
||||
// generateChapterGroups()
|
||||
// sectionsError.value = ''
|
||||
// console.log('模拟数据加载完成,章节数量:', courseSections.value.length)
|
||||
// console.log('分组数量:', groupedSections.value.length)
|
||||
// }
|
||||
// 加载模拟数据
|
||||
const loadMockData = () => {
|
||||
console.log('加载模拟章节数据')
|
||||
const mockSections = generateMockSections()
|
||||
courseSections.value = mockSections
|
||||
groupedSections.value = groupSectionsByChapter(mockSections)
|
||||
|
||||
// 计算学习进度
|
||||
const completed = mockSections.filter(section => section.completed).length
|
||||
completedLessons.value = completed
|
||||
progress.value = Math.round((completed / mockSections.length) * 100)
|
||||
}
|
||||
|
||||
// 切换章节展开/折叠
|
||||
const toggleChapter = (chapterIndex: number) => {
|
||||
console.log('点击切换章节,章节索引:', chapterIndex)
|
||||
|
||||
if (groupedSections.value[chapterIndex]) {
|
||||
groupedSections.value[chapterIndex].expanded = !groupedSections.value[chapterIndex].expanded
|
||||
}
|
||||
|
@ -717,6 +717,7 @@ const loadMockData = () => {
|
||||
|
||||
// 切换章节展开/收起
|
||||
const toggleChapter = (chapterIndex: number) => {
|
||||
console.log('切换章节展开/收起:', chapterIndex)
|
||||
groupedSections.value[chapterIndex].expanded = !groupedSections.value[chapterIndex].expanded
|
||||
}
|
||||
|
||||
|
@ -57,21 +57,30 @@
|
||||
@click="selectMajor('个人成长')">个人成长</span>
|
||||
<span class="filter-tag" :class="{ active: selectedMajor === '教学案例' }"
|
||||
@click="selectMajor('教学案例')">教学案例</span>
|
||||
<span class="filter-tag" :class="{ active: selectedMajor === '班级管理' }"
|
||||
@click="selectMajor('班级管理')">班级管理</span>
|
||||
<span class="filter-tag" :class="{ active: selectedMajor === '通识技能' }"
|
||||
@click="selectMajor('通识技能')">通识技能</span>
|
||||
<span class="filter-tag" :class="{ active: selectedMajor === '信息素养' }"
|
||||
@click="selectMajor('信息素养')">信息素养</span>
|
||||
<span class="filter-tag" :class="{ active: selectedMajor === '师风师德' }"
|
||||
@click="selectMajor('师风师德')">师风师德</span>
|
||||
<span class="filter-tag" :class="{ active: selectedMajor === '专题教育' }"
|
||||
@click="selectMajor('专题教育')">专题教育</span>
|
||||
<span class="filter-tag" :class="{ active: selectedMajor === '综合实践' }"
|
||||
@click="selectMajor('综合实践')">综合实践</span>
|
||||
<span class="filter-tag" :class="{ active: selectedMajor === '个人成长' }"
|
||||
@click="selectMajor('个人成长')">个人成长</span>
|
||||
|
||||
<span class="filter-tag" :class="{ active: selectedMajor === '教育技术' }"
|
||||
@click="selectMajor('教育技术')">教育技术</span>
|
||||
<span class="filter-tag" :class="{ active: selectedMajor === '心理健康' }"
|
||||
@click="selectMajor('心理健康')">心理健康</span>
|
||||
<span class="filter-tag" :class="{ active: selectedMajor === '家校沟通' }"
|
||||
@click="selectMajor('家校沟通')">家校沟通</span>
|
||||
<span class="filter-tag" :class="{ active: selectedMajor === '课程设计' }"
|
||||
@click="selectMajor('课程设计')">课程设计</span>
|
||||
<span class="filter-tag" :class="{ active: selectedMajor === '教育政策' }"
|
||||
@click="selectMajor('教育政策')">教育政策</span>
|
||||
<span class="filter-tag" :class="{ active: selectedMajor === '教学评估' }"
|
||||
@click="selectMajor('教学评估')">教学评估</span>
|
||||
<span class="filter-tag" :class="{ active: selectedMajor === '创新教育' }"
|
||||
@click="selectMajor('创新教育')">创新教育</span>
|
||||
<span class="filter-tag" :class="{ active: selectedMajor === 'STEAM教育' }"
|
||||
@click="selectMajor('STEAM教育')">STEAM教育</span>
|
||||
<span class="filter-tag" :class="{ active: selectedMajor === '教育心理学' }"
|
||||
@click="selectMajor('教育心理学')">教育心理学</span>
|
||||
<span class="filter-tag" :class="{ active: selectedMajor === '差异化教学' }"
|
||||
@click="selectMajor('差异化教学')">差异化教学</span>
|
||||
<span class="filter-tag" :class="{ active: selectedMajor === '教育领导力' }"
|
||||
@click="selectMajor('教育领导力')">教育领导力</span>
|
||||
<span class="filter-tag" :class="{ active: selectedMajor === '在线教学' }"
|
||||
@click="selectMajor('在线教学')">在线教学</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -109,9 +118,9 @@
|
||||
|
||||
<!-- 排序标签 -->
|
||||
<div class="sort-tabs">
|
||||
<span class="sort-tab">最新</span>
|
||||
<span class="sort-tab">最热</span>
|
||||
<span class="sort-tab active">推荐</span>
|
||||
<span class="sort-tab" :class="{ active: selectedSort === '最新' }" @click="selectSort('最新')">最新</span>
|
||||
<span class="sort-tab" :class="{ active: selectedSort === '最热' }" @click="selectSort('最热')">最热</span>
|
||||
<span class="sort-tab" :class="{ active: selectedSort === '推荐' }" @click="selectSort('推荐')">推荐</span>
|
||||
</div>
|
||||
|
||||
<!-- 加载状态 -->
|
||||
@ -215,6 +224,9 @@ const itemsPerPage = 20
|
||||
const totalItems = computed(() => total.value)
|
||||
const totalPages = computed(() => Math.ceil(totalItems.value / itemsPerPage))
|
||||
|
||||
// 排序相关状态
|
||||
const selectedSort = ref('推荐')
|
||||
|
||||
// 控制广告显示状态
|
||||
const showAdvertisement = ref(true)
|
||||
|
||||
@ -264,6 +276,13 @@ const visiblePages = computed(() => {
|
||||
return pages
|
||||
})
|
||||
|
||||
// 排序切换函数
|
||||
const selectSort = (sort: string) => {
|
||||
selectedSort.value = sort
|
||||
currentPage.value = 1 // 重置到第一页
|
||||
loadCourses()
|
||||
}
|
||||
|
||||
// 加载课程数据(使用模拟数据)
|
||||
const loadCourses = async () => {
|
||||
try {
|
||||
@ -289,6 +308,21 @@ const loadCourses = async () => {
|
||||
})
|
||||
}
|
||||
|
||||
// 排序逻辑
|
||||
switch (selectedSort.value) {
|
||||
case '最新':
|
||||
filteredCourses.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())
|
||||
break
|
||||
case '最热':
|
||||
filteredCourses.sort((a, b) => b.studentCount - a.studentCount)
|
||||
break
|
||||
case '推荐':
|
||||
default:
|
||||
// 推荐排序可以根据评分和学生数综合排序
|
||||
filteredCourses.sort((a, b) => (b.rating * 0.7 + b.studentCount * 0.3) - (a.rating * 0.7 + a.studentCount * 0.3))
|
||||
break
|
||||
}
|
||||
|
||||
// 按专业筛选
|
||||
if (selectedMajor.value !== '全部') {
|
||||
filteredCourses = filteredCourses.filter(course =>
|
||||
|
@ -137,7 +137,6 @@ const toggleCourseInfo = (teacherId: number) => {
|
||||
|
||||
// 筛选标签数据
|
||||
const filterTabs = ref([
|
||||
{ id: 'field', name: '课长领域' },
|
||||
{ id: 'all', name: '全部' },
|
||||
{ id: 'chinese-promotion', name: '汉语国际推广' },
|
||||
{ id: 'chinese-language', name: '汉语言' },
|
||||
@ -403,17 +402,18 @@ const goToPage = (page: number) => {
|
||||
/* 筛选标签栏 */
|
||||
.filter-tabs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0;
|
||||
margin-bottom: 40px;
|
||||
padding-bottom: 30px;
|
||||
background: transparent;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
padding: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.filter-tab {
|
||||
margin-right: 25px;
|
||||
margin-bottom: 30px;
|
||||
/* margin-bottom: 30px; */
|
||||
padding: 7px 10px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
@ -428,7 +428,7 @@ const goToPage = (page: number) => {
|
||||
}
|
||||
|
||||
.filter-tabs div {
|
||||
padding: 7px 10px;
|
||||
padding: 7px 10px 7px 0;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
@ -14,24 +14,24 @@
|
||||
<div class="divider_2"></div>
|
||||
</div>
|
||||
|
||||
<div class="box_3 active">
|
||||
<div class="box_3" :class="{ active: activeTab === 0 }" @click="handleTabChange(0)">
|
||||
<div class="image-text_2 justify-between">
|
||||
<img class="thumbnail_8" referrerpolicy="no-referrer"
|
||||
src="/images/Help-center/SketchPngd9dfa413c705d7d7838aa04a1af69011abc78cfe7a9d0d31b5bfca3ed5a4c990.png" />
|
||||
:src="activeTab === 0 ? '/images/Help-center/SketchPngd9dfa413c705d7d7838aa04a1af69011abc78cfe7a9d0d31b5bfca3ed5a4c990.png' : '/images/Help-center/disposition.png'" />
|
||||
<span class="text-group_2">账号问题</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box_3">
|
||||
<div class="box_3" :class="{ active: activeTab === 1 }" @click="handleTabChange(1)">
|
||||
<div class="image-text_2 justify-between">
|
||||
<img class="thumbnail_8" referrerpolicy="no-referrer"
|
||||
src="/images/Help-center/SketchPng8c77f6b5914ca8b5148cb9e177fb5d7ad7b15bbad1eb5506086428c4b5243169.png" />
|
||||
:src="activeTab === 1 ? '/images/Help-center/Gc_24_line-Authentication(1).png@2x.png' : '/images/Help-center/SketchPng8c77f6b5914ca8b5148cb9e177fb5d7ad7b15bbad1eb5506086428c4b5243169.png'" />
|
||||
<span class="text-group_2">认证证书</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box_3">
|
||||
<div class="box_3" :class="{ active: activeTab === 2 }" @click="handleTabChange(2)">
|
||||
<div class="image-text_2 justify-between">
|
||||
<img class="thumbnail_8" referrerpolicy="no-referrer"
|
||||
src="/images/Help-center/SketchPng9eac41c079f953a4c9dd6e8ea78ccfedb8a08687a399dfa96c25967f42408792.png" />
|
||||
:src="activeTab === 2 ? '/images/Help-center/course-active.png' : '/images/Help-center/SketchPng9eac41c079f953a4c9dd6e8ea78ccfedb8a08687a399dfa96c25967f42408792.png'" />
|
||||
<span class="text-group_2">课程问题</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -39,17 +39,44 @@
|
||||
|
||||
<div class="group_2 justify-between">
|
||||
<div class="block_1 flex-col">
|
||||
<span class="text_4">帐号问题</span>
|
||||
<span class="text_4" v-if="activeTab === 0">帐号问题</span>
|
||||
<span class="text_4" v-else-if="activeTab === 1">认证证书</span>
|
||||
<span class="text_4" v-else>课程问题</span>
|
||||
<!-- 分割线 -->
|
||||
<div class="divider_1"></div>
|
||||
<div class="section_1 justify-between">
|
||||
<img class="thumbnail_1" referrerpolicy="no-referrer"
|
||||
src="/images/Help-center/SketchPngcebb162be4c752de66c89f16a525f570b179222941fc1ebd59ee37257e634009.png" />
|
||||
<span class="text_5">1.如何在线上注册账号?</span>
|
||||
|
||||
<div v-if="activeTab === 0">
|
||||
<div class="section_1 justify-between">
|
||||
<img class="thumbnail_1" referrerpolicy="no-referrer"
|
||||
src="/images/Help-center/SketchPngcebb162be4c752de66c89f16a525f570b179222941fc1ebd59ee37257e634009.png" />
|
||||
<span class="text_5">1.如何在线上注册账号?</span>
|
||||
</div>
|
||||
<span class="text_6">
|
||||
浏览器登录www.xuetangx.com,打开网页后点击右上角登录按钮进行账号注册;您也可以在微信小程序和app的登录界面进行注册。
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div v-else-if="activeTab === 1">
|
||||
<div class="section_1 justify-between">
|
||||
<img class="thumbnail_1" referrerpolicy="no-referrer"
|
||||
src="/images/Help-center/SketchPngcebb162be4c752de66c89f16a525f570b179222941fc1ebd59ee37257e634009.png" />
|
||||
<span class="text_5">1.如何获取课程认证证书?</span>
|
||||
</div>
|
||||
<span class="text_6">
|
||||
完成课程所有学习内容并通过考核后,可在课程详情页面申请认证证书。认证证书通常在3-5个工作日内审核发放。
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<div class="section_1 justify-between">
|
||||
<img class="thumbnail_1" referrerpolicy="no-referrer"
|
||||
src="/images/Help-center/SketchPngcebb162be4c752de66c89f16a525f570b179222941fc1ebd59ee37257e634009.png" />
|
||||
<span class="text_5">1.如何购买课程?</span>
|
||||
</div>
|
||||
<span class="text_6">
|
||||
浏览课程详情页面,点击"立即购买"按钮,按照提示完成支付流程即可。支持微信、支付宝等多种支付方式。
|
||||
</span>
|
||||
</div>
|
||||
<span class="text_6">
|
||||
浏览器登录www.xuetangx.com,打开网页后点击右上角登录按钮进行账号注册;您也可以在微信小程序和app的登录界面进行注册。
|
||||
</span>
|
||||
<div class="section_1 justify-between">
|
||||
<img class="thumbnail_1" referrerpolicy="no-referrer"
|
||||
src="/images/Help-center/SketchPngcebb162be4c752de66c89f16a525f570b179222941fc1ebd59ee37257e634009.png" />
|
||||
@ -117,7 +144,15 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
|
||||
// 当前选中的tab索引
|
||||
const activeTab = ref(0);
|
||||
|
||||
// tab切换处理函数
|
||||
const handleTabChange = (index: number) => {
|
||||
activeTab.value = index;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@ -209,7 +244,7 @@
|
||||
width: 72px;
|
||||
height: 21px;
|
||||
overflow-wrap: break-word;
|
||||
color: rgba(2, 136, 209, 1);
|
||||
color: rgba(153, 153, 153, 1);
|
||||
font-size: 18px;
|
||||
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
|
||||
font-weight: normal;
|
||||
@ -218,6 +253,9 @@
|
||||
line-height: 21px;
|
||||
}
|
||||
|
||||
.box_3.active .text-group_2 {
|
||||
color: #0288D1;
|
||||
}
|
||||
.image-text_3 {
|
||||
width: 98px;
|
||||
height: 23px;
|
||||
|
@ -136,8 +136,11 @@
|
||||
<section class="advertisement-section" v-if="showAdvertisement">
|
||||
<div class="container">
|
||||
<div class="ad-container">
|
||||
<button class="close-btn" @click="closeAdvertisement">关闭</button>
|
||||
<img src="/images/advertising/advertising1.png" alt="广告图片" class="ad-image" />
|
||||
<!-- <button class="close-btn" @click="closeAdvertisement">关闭</button> -->
|
||||
<img src="/images/advertising/advertising3.png" alt="广告图片" class="ad-image" />
|
||||
<div class="ad-container-text">
|
||||
2025AI算法挑战活动大赛
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@ -236,16 +239,6 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 广告 -->
|
||||
<section class="advertisement-section" v-if="showAdvertisement">
|
||||
<div class="container">
|
||||
<div class="ad-container">
|
||||
<button class="close-btn" @click="closeAdvertisement">关闭</button>
|
||||
<img src="/images/advertising/advertising1.png" alt="广告图片" class="ad-image" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ai智能体验 -->
|
||||
<section class="ai-smart-experience">
|
||||
<div class="container">
|
||||
@ -290,6 +283,27 @@
|
||||
</div>
|
||||
</section> -->
|
||||
|
||||
|
||||
<!-- 广告 -->
|
||||
<section class="advertisement-section" v-if="showAdvertisement">
|
||||
<div class="container">
|
||||
<div class="ad-container">
|
||||
<button class="close-btn" @click="closeAdvertisement">关闭</button>
|
||||
<img src="/images/advertising/advertising4.png" alt="广告图片" class="ad-image" />
|
||||
<div class="ad-container-title1">
|
||||
<h3>数据分析高阶集训营</h3>
|
||||
<div class="ad-box">
|
||||
<div class="ad-line"></div>
|
||||
<span>DATA ANALYSIS BOOT CAMP</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ad-container-title2">
|
||||
以数据为剑 破解难题之锁
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 精选评论 -->
|
||||
<section class="featured-reviews">
|
||||
<div class="container">
|
||||
@ -736,6 +750,39 @@ onMounted(async () => {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 引入字体 */
|
||||
@font-face {
|
||||
font-family: 'TheTitleIsBlack';
|
||||
src: url('@/assets/fonts/优设标题黑.ttf') format('truetype');
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'AlimamaShuHeiTiBold';
|
||||
src: url('@/assets/fonts/AlimamaShuHeiTi-Bold.ttf') format('truetype');
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'WendaoIsTide';
|
||||
src: url('@/assets/fonts/文道潮黑.ttf') format('truetype');
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'PangMenIsRight';
|
||||
src: url('@/assets/fonts/庞门正道标题体3.0.ttf') format('truetype');
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'DouyinSansBold';
|
||||
src: url('@/assets/fonts/DouyinSansBold.otf') format('truetype');
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.home {
|
||||
width: 100%;
|
||||
background: #f8f9fa;
|
||||
@ -1107,6 +1154,64 @@ onMounted(async () => {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ad-container-text {
|
||||
position: absolute;
|
||||
color: #3BA4EB;
|
||||
top: 48%;
|
||||
transform: translateY(-50%);
|
||||
left: 24%;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.ad-container-title1 {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
left: 15%;
|
||||
}
|
||||
|
||||
.ad-container-title1 span {
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
color: #53789B;
|
||||
}
|
||||
|
||||
.ad-container-title1 h3 {
|
||||
padding: 0;
|
||||
margin-bottom: -8px;
|
||||
font-family: 'DouyinSansBold';
|
||||
color: #021B50;
|
||||
font-size: 26px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.ad-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.ad-line {
|
||||
width: 32px;
|
||||
height: 3px;
|
||||
background: linear-gradient(to right, #5479F7, #60D9E9);
|
||||
}
|
||||
|
||||
.ad-container-title2 {
|
||||
position: absolute;
|
||||
top: 65%;
|
||||
right: 29%;
|
||||
transform: translateY(-50%);
|
||||
width: 204px;
|
||||
height: 26px;
|
||||
color: #fff;
|
||||
background: linear-gradient(to right, #1D46F3, #60D9E9);
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.ad-image {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
@ -1158,6 +1263,7 @@ onMounted(async () => {
|
||||
.stat-item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
padding: 0;
|
||||
@ -1199,13 +1305,13 @@ onMounted(async () => {
|
||||
|
||||
|
||||
.stat-content {
|
||||
text-align: right;
|
||||
flex: 1;
|
||||
text-align: left;
|
||||
/* flex: 1; */
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
/* font-weight: 700; */
|
||||
color: #292C2E;
|
||||
margin-bottom: 6px;
|
||||
line-height: 1.1;
|
||||
@ -1220,6 +1326,7 @@ onMounted(async () => {
|
||||
word-wrap: break-word;
|
||||
word-break: break-word;
|
||||
hyphens: auto;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.special-content {
|
||||
@ -1287,6 +1394,8 @@ onMounted(async () => {
|
||||
}
|
||||
|
||||
.section-title-text {
|
||||
/* 字体 */
|
||||
font-family: 'AlimamaShuHeiTiBold';
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
font-size: 30px;
|
||||
@ -1819,7 +1928,7 @@ onMounted(async () => {
|
||||
}
|
||||
|
||||
.path-image {
|
||||
width: 448px;
|
||||
width: 100%;
|
||||
height: 195px;
|
||||
border-radius: 8px;
|
||||
object-fit: cover;
|
||||
|
@ -139,7 +139,7 @@
|
||||
src="https://lanhu-oss-2537-2.lanhuapp.com/SketchPng23376f42e0d0f21014efca4f1a7ee3c5efa70f6e1419d0d3e6c4a680191c7ef5" />
|
||||
<span class="text_21">{{ course.duration || '12小时43分钟' }}</span>
|
||||
<img class="thumbnail_8" referrerpolicy="no-referrer"
|
||||
:src="course.status === 'learning' ? 'https://lanhu-oss-2537-2.lanhuapp.com/SketchPng51c1f99cd7b1c15c6efdc0480d16ff2681be4bef17a9dedfcaac33f2976fbd81' : 'https://lanhu-oss-2537-2.lanhuapp.com/SketchPng317a0d8f3287bb788c48059c8181479ad5eba8557ef1c09215d9a1c962d0db67'" />
|
||||
:src="course.status === 'learning' ? 'https://lanhu-oss-2537-2.lanhuapp.com/SketchPng317a0d8f3287bb788c48059c8181479ad5eba8557ef1c09215d9a1c962d0db67' : 'https://lanhu-oss-2537-2.lanhuapp.com/SketchPng317a0d8f3287bb788c48059c8181479ad5eba8557ef1c09215d9a1c962d0db67'" />
|
||||
<span class="text_22">已看{{ course.watchedTime || '10小时20分钟' }}</span>
|
||||
<div class="text-wrapper_2 flex-col" @click="goToCourse(course.id)">
|
||||
<span class="text_23">{{ course.status === 'learning' ? '去学习' : '去复习' }}</span>
|
||||
@ -927,7 +927,7 @@ const { t, locale } = useI18n()
|
||||
|
||||
// 轮播图根据语言动态切换
|
||||
const bannerImage = computed(() => {
|
||||
return locale.value === 'zh' ? '/banners/banner1.png' : '/banners/banner1-en.png'
|
||||
return locale.value === 'zh' ? '/banners/banner8.png' : '/banners/banner1-en.png'
|
||||
})
|
||||
|
||||
const bannerAlt = computed(() => {
|
||||
@ -5217,7 +5217,7 @@ border-bottom: 1.5px solid #E6E6E6;
|
||||
|
||||
.activity-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 1.04vw;
|
||||
/* 20px转换为vw */
|
||||
margin-top: 1.04vh;
|
||||
@ -5535,9 +5535,9 @@ border-bottom: 1.5px solid #E6E6E6;
|
||||
color: white;
|
||||
font-size: 0.63vw;
|
||||
/* 12px转换为vw */
|
||||
padding: 0.1vh 0.31vw;
|
||||
padding: 2px 2px;
|
||||
/* 2px 6px转换 */
|
||||
border-radius: 0.52vw;
|
||||
border-radius: 50%;
|
||||
/* 10px转换为vw */
|
||||
min-width: 1.04vw;
|
||||
/* 20px转换为vw */
|
||||
|
@ -300,7 +300,7 @@ const allImages = ref([
|
||||
|
||||
.container {
|
||||
margin: 0 auto;
|
||||
padding: 0 20px;
|
||||
/* padding: 0 20px; */
|
||||
}
|
||||
|
||||
.section-title {
|
||||
@ -466,6 +466,8 @@ const allImages = ref([
|
||||
|
||||
/* 全部视频区域 */
|
||||
.all-videos {
|
||||
margin-left: -130px;
|
||||
width: 100vw;
|
||||
padding: 40px 0;
|
||||
background-color: #fff;
|
||||
margin-bottom: 80px;
|
||||
@ -486,11 +488,7 @@ const allImages = ref([
|
||||
overflow: hidden;
|
||||
transition: all 0.3s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.video-card:hover {
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.video-card .card-image {
|
||||
|
@ -503,11 +503,7 @@ onMounted(() => {
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
cursor: pointer;
|
||||
min-height: 350px;
|
||||
}
|
||||
|
||||
.course-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.course-image {
|
||||
|