diff --git a/public/images/Featured_resources/全部图片1.png b/public/images/Featured_resources/全部图片1.png new file mode 100644 index 0000000..d56e265 Binary files /dev/null and b/public/images/Featured_resources/全部图片1.png differ diff --git a/public/images/Featured_resources/全部图片2.png b/public/images/Featured_resources/全部图片2.png new file mode 100644 index 0000000..c5283cf Binary files /dev/null and b/public/images/Featured_resources/全部图片2.png differ diff --git a/public/images/Featured_resources/全部图片3.png b/public/images/Featured_resources/全部图片3.png new file mode 100644 index 0000000..91472f0 Binary files /dev/null and b/public/images/Featured_resources/全部图片3.png differ diff --git a/public/images/Featured_resources/全部图片4.png b/public/images/Featured_resources/全部图片4.png new file mode 100644 index 0000000..1513b42 Binary files /dev/null and b/public/images/Featured_resources/全部图片4.png differ diff --git a/public/images/Featured_resources/全部图片5.png b/public/images/Featured_resources/全部图片5.png new file mode 100644 index 0000000..9a04a90 Binary files /dev/null and b/public/images/Featured_resources/全部图片5.png differ diff --git a/public/images/Featured_resources/全部图片6.png b/public/images/Featured_resources/全部图片6.png new file mode 100644 index 0000000..6095487 Binary files /dev/null and b/public/images/Featured_resources/全部图片6.png differ diff --git a/public/images/Featured_resources/全部图片7.png b/public/images/Featured_resources/全部图片7.png new file mode 100644 index 0000000..477e604 Binary files /dev/null and b/public/images/Featured_resources/全部图片7.png differ diff --git a/public/images/Featured_resources/全部图片8.png b/public/images/Featured_resources/全部图片8.png new file mode 100644 index 0000000..9ea8498 Binary files /dev/null and b/public/images/Featured_resources/全部图片8.png differ diff --git a/public/images/Featured_resources/全部视频1.png b/public/images/Featured_resources/全部视频1.png new file mode 100644 index 0000000..d1ba28a Binary files /dev/null and b/public/images/Featured_resources/全部视频1.png differ diff --git a/public/images/Featured_resources/全部视频2.png b/public/images/Featured_resources/全部视频2.png new file mode 100644 index 0000000..4941ebc Binary files /dev/null and b/public/images/Featured_resources/全部视频2.png differ diff --git a/public/images/Featured_resources/全部视频3.png b/public/images/Featured_resources/全部视频3.png new file mode 100644 index 0000000..cb64db9 Binary files /dev/null and b/public/images/Featured_resources/全部视频3.png differ diff --git a/public/images/Featured_resources/全部视频4.png b/public/images/Featured_resources/全部视频4.png new file mode 100644 index 0000000..fac7d2d Binary files /dev/null and b/public/images/Featured_resources/全部视频4.png differ diff --git a/public/images/Featured_resources/全部视频5.png b/public/images/Featured_resources/全部视频5.png new file mode 100644 index 0000000..7410ade Binary files /dev/null and b/public/images/Featured_resources/全部视频5.png differ diff --git a/public/images/Featured_resources/全部视频6.png b/public/images/Featured_resources/全部视频6.png new file mode 100644 index 0000000..2f49aff Binary files /dev/null and b/public/images/Featured_resources/全部视频6.png differ diff --git a/public/images/Featured_resources/全部视频7.png b/public/images/Featured_resources/全部视频7.png new file mode 100644 index 0000000..2cedbd2 Binary files /dev/null and b/public/images/Featured_resources/全部视频7.png differ diff --git a/public/images/Featured_resources/全部视频8.png b/public/images/Featured_resources/全部视频8.png new file mode 100644 index 0000000..8121303 Binary files /dev/null and b/public/images/Featured_resources/全部视频8.png differ diff --git a/public/images/Featured_resources/精品视频3.png b/public/images/Featured_resources/精品视频3.png new file mode 100644 index 0000000..4f233c4 Binary files /dev/null and b/public/images/Featured_resources/精品视频3.png differ diff --git a/public/images/Featured_resources/精选视频1.png b/public/images/Featured_resources/精选视频1.png new file mode 100644 index 0000000..3725927 Binary files /dev/null and b/public/images/Featured_resources/精选视频1.png differ diff --git a/public/images/Featured_resources/精选视频2.png b/public/images/Featured_resources/精选视频2.png new file mode 100644 index 0000000..406a054 Binary files /dev/null and b/public/images/Featured_resources/精选视频2.png differ diff --git a/public/images/Featured_resources/精选资源轮播.png b/public/images/Featured_resources/精选资源轮播.png new file mode 100644 index 0000000..6a0328a Binary files /dev/null and b/public/images/Featured_resources/精选资源轮播.png differ diff --git a/public/images/Teachers/师资力量1.png b/public/images/Teachers/师资力量1.png new file mode 100644 index 0000000..218e2b4 Binary files /dev/null and b/public/images/Teachers/师资力量1.png differ diff --git a/public/images/Teachers/师资力量2.png b/public/images/Teachers/师资力量2.png new file mode 100644 index 0000000..f522e13 Binary files /dev/null and b/public/images/Teachers/师资力量2.png differ diff --git a/public/images/Teachers/师资力量3.png b/public/images/Teachers/师资力量3.png new file mode 100644 index 0000000..a2f2fc8 Binary files /dev/null and b/public/images/Teachers/师资力量3.png differ diff --git a/public/images/Teachers/师资力量4.png b/public/images/Teachers/师资力量4.png new file mode 100644 index 0000000..7d3ff51 Binary files /dev/null and b/public/images/Teachers/师资力量4.png differ diff --git a/public/images/Teachers/师资力量5.png b/public/images/Teachers/师资力量5.png new file mode 100644 index 0000000..2a710a8 Binary files /dev/null and b/public/images/Teachers/师资力量5.png differ diff --git a/public/images/Teachers/师资力量6.png b/public/images/Teachers/师资力量6.png new file mode 100644 index 0000000..c7c5520 Binary files /dev/null and b/public/images/Teachers/师资力量6.png differ diff --git a/public/images/Teachers/师资力量7.png b/public/images/Teachers/师资力量7.png new file mode 100644 index 0000000..2bbbfaf Binary files /dev/null and b/public/images/Teachers/师资力量7.png differ diff --git a/public/images/Teachers/师资力量8.png b/public/images/Teachers/师资力量8.png new file mode 100644 index 0000000..7c10830 Binary files /dev/null and b/public/images/Teachers/师资力量8.png differ diff --git a/public/images/Teachers/师资力量切图-轮播区.png b/public/images/Teachers/师资力量切图-轮播区.png new file mode 100644 index 0000000..3211f4d Binary files /dev/null and b/public/images/Teachers/师资力量切图-轮播区.png differ diff --git a/public/images/activity/活动切图-轮播区.png b/public/images/activity/活动切图-轮播区.png new file mode 100644 index 0000000..e75053c Binary files /dev/null and b/public/images/activity/活动切图-轮播区.png differ diff --git a/public/images/activity/活动图1.png b/public/images/activity/活动图1.png new file mode 100644 index 0000000..91bf39f Binary files /dev/null and b/public/images/activity/活动图1.png differ diff --git a/public/images/activity/活动图2.png b/public/images/activity/活动图2.png new file mode 100644 index 0000000..b3227d7 Binary files /dev/null and b/public/images/activity/活动图2.png differ diff --git a/public/images/activity/活动图3.png b/public/images/activity/活动图3.png new file mode 100644 index 0000000..26e834f Binary files /dev/null and b/public/images/activity/活动图3.png differ diff --git a/src/api/examples/usage.ts b/src/api/examples/usage.ts index 889cdaf..d74cda2 100644 --- a/src/api/examples/usage.ts +++ b/src/api/examples/usage.ts @@ -73,13 +73,13 @@ export const getCoursesExample = async () => { const response = await CourseApi.getCourses({ page: 1, pageSize: 20, - category: '前端开发', - level: 'intermediate', - sortBy: 'rating' + categoryId: 1, + difficulty: 1, + sortBy: 'createdAt' }) if (response.code === 200) { - const { list, total, page, pageSize } = response.data + const { list, total } = response.data console.log('课程列表:', list) console.log('总数:', total) return response.data @@ -98,7 +98,7 @@ export const searchCoursesExample = async () => { level: 'intermediate', price: 'paid', rating: 4, - sortBy: 'rating', + sortBy: 'newest', page: 1, pageSize: 10 }) diff --git a/src/api/modules/auth.ts b/src/api/modules/auth.ts index 9d3abda..8a54e77 100644 --- a/src/api/modules/auth.ts +++ b/src/api/modules/auth.ts @@ -33,6 +33,7 @@ export class AuthApi { nickname: '用户', avatar: '', role: 'student', + status: 'active', createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() }, diff --git a/src/api/modules/course.ts b/src/api/modules/course.ts index 2063067..df09693 100644 --- a/src/api/modules/course.ts +++ b/src/api/modules/course.ts @@ -13,7 +13,6 @@ import type { BackendCourseSection, BackendCourseSectionListResponse, Quiz, - QuizQuestion, LearningProgress, SearchRequest, Instructor, @@ -30,12 +29,23 @@ export class CourseApi { /** * 格式化时间戳为ISO字符串 */ - private static formatTimestamp(timestamp: number | null | undefined): string { - if (!timestamp || timestamp <= 0) { + private static formatTimestamp(timestamp: number | string | null | undefined): string { + if (!timestamp) { return new Date().toISOString() } try { + // 如果是字符串,尝试解析 + if (typeof timestamp === 'string') { + const date = new Date(timestamp) + return isNaN(date.getTime()) ? new Date().toISOString() : date.toISOString() + } + + // 如果是数字时间戳 + if (timestamp <= 0) { + return new Date().toISOString() + } + // 如果时间戳是秒级的,转换为毫秒级 const ms = timestamp < 10000000000 ? timestamp * 1000 : timestamp const date = new Date(ms) @@ -181,8 +191,8 @@ export class CourseApi { content: response.data.outline, // 使用 outline 作为课程内容 thumbnail: response.data.cover, coverImage: response.data.cover, - price: parseFloat(response.data.price), - originalPrice: parseFloat(response.data.price), + price: parseFloat(response.data.price || '0'), + originalPrice: parseFloat(response.data.price || '0'), currency: 'CNY', rating: 4.5, ratingCount: 0, @@ -214,8 +224,8 @@ export class CourseApi { certifications: [] }, status: 'published' as const, - createdAt: this.formatTimestamp(response.data.createdAt), - updatedAt: this.formatTimestamp(response.data.updatedAt), + createdAt: this.formatTimestamp(response.data.createdTime), + updatedAt: this.formatTimestamp(response.data.updatedTime), publishedAt: response.data.startTime } diff --git a/src/api/modules/order.ts b/src/api/modules/order.ts index b9ed0d8..ea9a6d9 100644 --- a/src/api/modules/order.ts +++ b/src/api/modules/order.ts @@ -4,7 +4,7 @@ import type { ApiResponse, PaginationResponse, Order, - OrderItem, + } from '../types' /** diff --git a/src/api/modules/upload.ts b/src/api/modules/upload.ts index b7f6f02..7c99cda 100644 --- a/src/api/modules/upload.ts +++ b/src/api/modules/upload.ts @@ -53,7 +53,7 @@ export class UploadApi { headers: { 'Content-Type': 'multipart/form-data', }, - onUploadProgress: (progressEvent) => { + onUploadProgress: (progressEvent: any) => { if (onProgress && progressEvent.total) { const progress = Math.round( (progressEvent.loaded * 100) / progressEvent.total @@ -90,7 +90,7 @@ export class UploadApi { headers: { 'Content-Type': 'multipart/form-data', }, - onUploadProgress: (progressEvent) => { + onUploadProgress: (progressEvent: any) => { if (onProgress && progressEvent.total) { const progress = Math.round( (progressEvent.loaded * 100) / progressEvent.total @@ -130,7 +130,7 @@ export class UploadApi { headers: { 'Content-Type': 'multipart/form-data', }, - onUploadProgress: (progressEvent) => { + onUploadProgress: (progressEvent: any) => { if (onProgress && progressEvent.total) { const progress = Math.round( (progressEvent.loaded * 100) / progressEvent.total @@ -155,7 +155,7 @@ export class UploadApi { error?: string }>>> { const formData = new FormData() - files.forEach((file, index) => { + files.forEach((file) => { formData.append(`files`, file) }) @@ -163,7 +163,7 @@ export class UploadApi { headers: { 'Content-Type': 'multipart/form-data', }, - onUploadProgress: (progressEvent) => { + onUploadProgress: (progressEvent: any) => { if (onProgress && progressEvent.total) { const progress = Math.round( (progressEvent.loaded * 100) / progressEvent.total @@ -255,7 +255,7 @@ export class UploadApi { headers: { 'Content-Type': 'multipart/form-data', }, - onUploadProgress: (progressEvent) => { + onUploadProgress: (progressEvent: any) => { if (onProgress && progressEvent.total) { const progress = Math.round( (progressEvent.loaded * 100) / progressEvent.total @@ -291,7 +291,7 @@ export class UploadApi { headers: { 'Content-Type': 'multipart/form-data', }, - onUploadProgress: (progressEvent) => { + onUploadProgress: (progressEvent: any) => { if (onProgress && progressEvent.total) { const progress = Math.round( (progressEvent.loaded * 100) / progressEvent.total diff --git a/src/api/request.ts b/src/api/request.ts index 092f478..181c4ff 100644 --- a/src/api/request.ts +++ b/src/api/request.ts @@ -1,7 +1,7 @@ // HTTP 请求封装文件 -import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios' +import axios, { AxiosInstance, InternalAxiosRequestConfig, AxiosRequestConfig, AxiosResponse } from 'axios' import { useUserStore } from '@/stores/user' -import router from '@/router' +// import router from '@/router' import type { ApiResponse } from './types' // 消息提示函数 - 使用window.alert作为fallback,实际项目中应该使用UI库的消息组件 @@ -27,21 +27,15 @@ const request: AxiosInstance = axios.create({ // 请求拦截器 request.interceptors.request.use( - (config: AxiosRequestConfig) => { + (config: InternalAxiosRequestConfig) => { // 添加认证token const userStore = useUserStore() if (userStore.token) { - config.headers = { - ...config.headers, - Authorization: `Bearer ${userStore.token}`, - } + config.headers.Authorization = `Bearer ${userStore.token}` } // 添加请求时间戳 - config.headers = { - ...config.headers, - 'X-Request-Time': Date.now().toString(), - } + config.headers['X-Request-Time'] = Date.now().toString() // 开发环境下打印请求信息 if (import.meta.env.DEV) { @@ -77,7 +71,7 @@ request.interceptors.response.use( // 检查业务状态码 if (data.code === 200 || data.code === 0) { - return data + return response } // 处理业务错误 diff --git a/src/api/types.ts b/src/api/types.ts index 6d2f56d..05628d9 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -23,6 +23,7 @@ export interface User { username: string email: string phone?: string + nickname?: string avatar?: string role: 'student' | 'teacher' | 'admin' status: 'active' | 'inactive' | 'banned' diff --git a/src/components/VideoPlayer.vue b/src/components/VideoPlayer.vue index e72bf69..6e4f335 100644 --- a/src/components/VideoPlayer.vue +++ b/src/components/VideoPlayer.vue @@ -57,7 +57,7 @@ -
+
@@ -336,7 +336,7 @@ const loadVideo = () => { loading.value = false }) - hls.on(Hls.Events.ERROR, (event, data) => { + hls.on(Hls.Events.ERROR, (_event, data) => { console.error('HLS error:', data) if (data.fatal) { error.value = true diff --git a/src/stores/course.ts b/src/stores/course.ts index ce2871d..11580ff 100644 --- a/src/stores/course.ts +++ b/src/stores/course.ts @@ -1,27 +1,9 @@ import { defineStore } from 'pinia' import { ref, computed } from 'vue' import { CourseApi } from '@/api/modules/course' +import type { Course as ApiCourse } from '@/api/types' -export interface Course { - id: number - title: string - description: string - instructor: string - instructorAvatar?: string - thumbnail: string - price: number - originalPrice?: number - rating: number - studentsCount: number - duration: string - level: 'beginner' | 'intermediate' | 'advanced' - category: string - tags: string[] - createdAt: string - updatedAt: string - isEnrolled?: boolean - progress?: number -} +export type Course = ApiCourse export interface Lesson { id: number @@ -54,12 +36,12 @@ export const useCourseStore = defineStore('course', () => { filtered = filtered.filter(course => course.title.toLowerCase().includes(searchQuery.value.toLowerCase()) || course.description.toLowerCase().includes(searchQuery.value.toLowerCase()) || - course.instructor.toLowerCase().includes(searchQuery.value.toLowerCase()) + course.instructor.name.toLowerCase().includes(searchQuery.value.toLowerCase()) ) } if (selectedCategory.value) { - filtered = filtered.filter(course => course.category === selectedCategory.value) + filtered = filtered.filter(course => course.category.name === selectedCategory.value) } if (selectedLevel.value) { @@ -90,53 +72,136 @@ export const useCourseStore = defineStore('course', () => { id: 1, title: 'Vue.js 3 完整教程', description: '从零开始学习Vue.js 3,包括Composition API、TypeScript集成等现代开发技术', - instructor: '李老师', - instructorAvatar: 'https://via.placeholder.com/50', + content: '详细的Vue.js 3课程内容', + instructor: { + id: 1, + name: '李老师', + title: '前端开发专家', + bio: '资深前端开发工程师', + avatar: 'https://via.placeholder.com/50', + rating: 4.8, + studentsCount: 1234, + coursesCount: 5, + experience: '5年前端开发经验', + education: ['计算机科学学士'], + certifications: ['Vue.js认证'] + }, thumbnail: 'https://via.placeholder.com/300x200', + coverImage: 'https://via.placeholder.com/300x200', price: 299, originalPrice: 399, + currency: 'CNY', rating: 4.8, + ratingCount: 100, studentsCount: 1234, duration: '12小时', level: 'intermediate', - category: '前端开发', + category: { + id: 1, + name: '前端开发', + slug: 'frontend', + description: '前端开发相关课程' + }, tags: ['Vue.js', 'JavaScript', 'TypeScript'], + totalLessons: 20, + language: 'zh-CN', + skills: ['Vue.js', 'TypeScript', 'Composition API'], + requirements: ['JavaScript基础', 'HTML/CSS基础'], + objectives: ['掌握Vue.js 3核心概念', '学会使用Composition API', '理解TypeScript集成'], + status: 'published', createdAt: '2024-01-01', - updatedAt: '2024-01-15' + updatedAt: '2024-01-15', + publishedAt: '2024-01-01' }, { id: 2, title: 'React 18 实战开发', description: '掌握React 18的新特性,包括并发渲染、Suspense等高级功能', - instructor: '王老师', - instructorAvatar: 'https://via.placeholder.com/50', + content: '详细的React 18课程内容', + instructor: { + id: 2, + name: '王老师', + title: 'React专家', + bio: '资深React开发工程师', + avatar: 'https://via.placeholder.com/50', + rating: 4.9, + studentsCount: 2156, + coursesCount: 8, + experience: '6年React开发经验', + education: ['软件工程硕士'], + certifications: ['React认证'] + }, thumbnail: 'https://via.placeholder.com/300x200', + coverImage: 'https://via.placeholder.com/300x200', price: 399, + originalPrice: 499, + currency: 'CNY', rating: 4.9, + ratingCount: 200, studentsCount: 2156, duration: '15小时', level: 'advanced', - category: '前端开发', + category: { + id: 1, + name: '前端开发', + slug: 'frontend', + description: '前端开发相关课程' + }, tags: ['React', 'JavaScript', 'Hooks'], + totalLessons: 25, + language: 'zh-CN', + skills: ['React 18', 'Hooks', '并发渲染'], + requirements: ['JavaScript基础', 'React基础'], + objectives: ['掌握React 18新特性', '学会并发渲染', '理解Suspense'], + status: 'published', createdAt: '2024-01-05', - updatedAt: '2024-01-20' + updatedAt: '2024-01-20', + publishedAt: '2024-01-05' }, { id: 3, title: 'Node.js 后端开发', description: '学习Node.js后端开发,包括Express、数据库操作、API设计等', - instructor: '张老师', - instructorAvatar: 'https://via.placeholder.com/50', + content: '详细的Node.js课程内容', + instructor: { + id: 3, + name: '张老师', + title: 'Node.js专家', + bio: '资深后端开发工程师', + avatar: 'https://via.placeholder.com/50', + rating: 4.7, + studentsCount: 987, + coursesCount: 6, + experience: '7年后端开发经验', + education: ['计算机科学硕士'], + certifications: ['Node.js认证'] + }, thumbnail: 'https://via.placeholder.com/300x200', + coverImage: 'https://via.placeholder.com/300x200', price: 349, + originalPrice: 449, + currency: 'CNY', rating: 4.7, + ratingCount: 150, studentsCount: 987, duration: '18小时', level: 'intermediate', - category: '后端开发', + category: { + id: 2, + name: '后端开发', + slug: 'backend', + description: '后端开发相关课程' + }, tags: ['Node.js', 'Express', 'MongoDB'], + totalLessons: 30, + language: 'zh-CN', + skills: ['Node.js', 'Express', 'MongoDB', 'API设计'], + requirements: ['JavaScript基础', '编程基础'], + objectives: ['掌握Node.js后端开发', '学会Express框架', '理解数据库操作'], + status: 'published', createdAt: '2024-01-10', - updatedAt: '2024-01-25' + updatedAt: '2024-01-25', + publishedAt: '2024-01-10' } ] courses.value = mockCourses diff --git a/src/stores/user.ts b/src/stores/user.ts index d4a6217..75d725a 100644 --- a/src/stores/user.ts +++ b/src/stores/user.ts @@ -18,12 +18,12 @@ export const useUserStore = defineStore('user', () => { const isAdmin = computed(() => user.value?.role === 'admin') // 方法 - 简化版本,主要用于状态管理 - const login = async (credentials: { email: string; password: string }) => { + const login = async (_credentials: { email: string; password: string }) => { // 这个方法现在主要用于兼容性,实际登录逻辑在组件中处理 return { success: true, message: '请使用登录模态框进行登录' } } - const register = async (userData: any) => { + const register = async (_userData: any) => { // 这个方法现在主要用于兼容性,实际注册逻辑在组件中处理 return { success: true, message: '请使用注册模态框进行注册' } } diff --git a/src/views/Activities.vue b/src/views/Activities.vue index 1badecc..8a578d3 100644 --- a/src/views/Activities.vue +++ b/src/views/Activities.vue @@ -42,49 +42,47 @@ class="activity-card" >
-
-
2025
-
{{ activity.title }}
-
{{ activity.subtitle }}
+
+ 活动图片
- +
- -
- - - {{ tag }} - + +
+ 进行中
- - -
-
- {{ activity.courseTitle }} + + +

{{ activity.courseTitle }}

+ + +

{{ activity.subtitle }}

+ + +
+
+ 活动时间: + {{ activity.schedule.replace('开课时间:', '') }}
-
- {{ activity.schedule }} +
+ 活动类型: + 激励类活动
-
- {{ activity.duration }} -
-
- {{ activity.students }} -
-
- {{ activity.price }} +
+ 已报名: + {{ activity.students.replace('已报名:', '') }}
- +
@@ -103,7 +101,7 @@ import { ref, computed, onMounted } from 'vue' const loading = ref(true) // 横幅图片路径 - 您可以在这里设置图片路径 -const bannerImageSrc = ref('') +const bannerImageSrc = ref('/images/activity/活动切图-轮播区.png') // 检查是否有横幅图片 const hasBannerImage = computed(() => bannerImageSrc.value.trim() !== '') @@ -114,7 +112,6 @@ const activities = ref([ id: 1, title: '计算机二级', subtitle: 'C语言讲练综合班', - tags: ['系统备考', '考点详解', '题考刷题'], courseTitle: '计算机二级C语言程序设计证书', schedule: '开课时间:2025.07.26-2025.09.28', duration: '适合年级:高校本科生', @@ -125,7 +122,6 @@ const activities = ref([ id: 2, title: '计算机二级', subtitle: 'C语言讲练综合班', - tags: ['系统备考', '考点详解', '题考刷题'], courseTitle: '计算机二级C语言程序设计证书', schedule: '开课时间:2025.07.26-2025.09.28', duration: '适合年级:高校本科生', @@ -136,7 +132,6 @@ const activities = ref([ id: 3, title: '计算机二级', subtitle: 'C语言讲练综合班', - tags: ['系统备考', '考点详解', '题考刷题'], courseTitle: '计算机二级C语言程序设计证书', schedule: '开课时间:2025.07.26-2025.09.28', duration: '适合年级:高校本科生', @@ -147,7 +142,6 @@ const activities = ref([ id: 4, title: '计算机二级', subtitle: 'C语言讲练综合班', - tags: ['系统备考', '考点详解', '题考刷题'], courseTitle: '计算机二级C语言程序设计证书', schedule: '开课时间:2025.07.26-2025.09.28', duration: '适合年级:高校本科生', @@ -158,7 +152,6 @@ const activities = ref([ id: 5, title: '计算机二级', subtitle: 'C语言讲练综合班', - tags: ['系统备考', '考点详解', '题考刷题'], courseTitle: '计算机二级C语言程序设计证书', schedule: '开课时间:2025.07.26-2025.09.28', duration: '适合年级:高校本科生', @@ -169,7 +162,6 @@ const activities = ref([ id: 6, title: '计算机二级', subtitle: 'C语言讲练综合班', - tags: ['系统备考', '考点详解', '题考刷题'], courseTitle: '计算机二级C语言程序设计证书', schedule: '开课时间:2025.07.26-2025.09.28', duration: '适合年级:高校本科生', @@ -186,9 +178,9 @@ const viewDetail = (id: number) => { } // 设置横幅图片的方法(供后续使用) -const setBannerImage = (imagePath: string) => { - bannerImageSrc.value = imagePath -} +// const setBannerImage = (imagePath: string) => { +// bannerImageSrc.value = imagePath +// } // 模拟数据加载 onMounted(() => { @@ -318,51 +310,44 @@ onMounted(() => { /* 卡片头部 */ .card-header { position: relative; - height: 120px; + height: 180px; overflow: hidden; + border-radius: 12px 12px 0 0; } -.card-background { +.card-image { width: 100%; height: 100%; - background: linear-gradient(135deg, #4ECDC4 0%, #44A08D 100%); + position: relative; +} + +.activity-image { + width: 100%; + height: 100%; + object-fit: cover; + object-position: center; + display: block; +} + +.card-overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.3); padding: 20px; display: flex; flex-direction: column; justify-content: center; - position: relative; -} - -.card-background::before { - content: ''; - position: absolute; - top: 0; - right: 0; - width: 80px; - height: 80px; - background: rgba(255, 255, 255, 0.1); - border-radius: 50%; - transform: translate(30px, -30px); -} - -.card-background::after { - content: ''; - position: absolute; - bottom: 0; - left: 0; - width: 60px; - height: 60px; - background: rgba(255, 255, 255, 0.08); - border-radius: 50%; - transform: translate(-20px, 20px); } .year-badge { position: absolute; top: 15px; left: 20px; - background: rgba(255, 255, 255, 0.9); - color: #44A08D; + background: #9ACD32; + color: #333; padding: 4px 8px; border-radius: 4px; font-size: 12px; @@ -385,64 +370,62 @@ onMounted(() => { z-index: 1; } + + /* 卡片主体 */ .card-body { padding: 20px; } -.feature-tags { - display: flex; - gap: 8px; - margin-bottom: 16px; - flex-wrap: wrap; +/* 状态标签 */ +.status-badge { + margin-bottom: 12px; } -.feature-tag { - display: flex; - align-items: center; - gap: 4px; - background: #FFF2E6; - color: #FF6B35; - padding: 4px 8px; - border-radius: 4px; +.status-text { + display: inline-block; + background: #FF6B35; + color: white; + padding: 4px 12px; + border-radius: 12px; font-size: 12px; font-weight: 500; } -.tag-icon { - font-size: 10px; - font-style: normal; -} - -.course-info { - margin-bottom: 20px; -} - -.info-row { - margin-bottom: 8px; - font-size: 13px; - color: #666; +/* 课程标题 */ +.course-main-title { + font-size: 16px; + font-weight: 600; + color: #333; + margin: 0 0 8px 0; line-height: 1.4; } -.info-row:first-child { - margin-bottom: 12px; -} - -.info-label { - font-weight: 600; - color: #333; +/* 课程副标题 */ +.course-subtitle-text { font-size: 14px; -} - -.info-text { - color: #666; -} - -.price { color: #FF6B35; - font-weight: 600; - font-size: 14px; + margin: 0 0 16px 0; + line-height: 1.4; +} + +/* 课程详细信息 */ +.course-details { + margin-bottom: 20px; +} + +.detail-item { + margin-bottom: 8px; + font-size: 13px; + line-height: 1.4; +} + +.detail-label { + color: #999; +} + +.detail-value { + color: #666; } /* 卡片底部 */ @@ -452,9 +435,9 @@ onMounted(() => { .detail-btn { width: 100%; - padding: 10px 20px; - background: #4A90E2; - color: white; + padding: 12px 20px; + background: #f5f5f5; + color: #666; border: none; border-radius: 6px; font-size: 14px; @@ -464,7 +447,8 @@ onMounted(() => { } .detail-btn:hover { - background: #357ABD; + background: #4A90E2; + color: white; transform: translateY(-1px); } @@ -573,6 +557,10 @@ onMounted(() => { .placeholder-text { font-size: 20px; } + + .card-header { + height: 160px; + } } @media (max-width: 768px) { @@ -604,6 +592,10 @@ onMounted(() => { .container { padding: 0 16px; } + + .card-header { + height: 140px; + } } @media (max-width: 480px) { diff --git a/src/views/CourseDetail.vue b/src/views/CourseDetail.vue index 07c45b2..aa07fa8 100644 --- a/src/views/CourseDetail.vue +++ b/src/views/CourseDetail.vue @@ -87,6 +87,7 @@ :size="60" />
+
{{ course.instructor.name }}
{{ course.instructor.title }}
@@ -258,7 +259,7 @@
-
+
{{ getLessonTypeText(section) }} @@ -458,17 +459,17 @@ const generateChapterGroups = () => { } // 获取章节标题 -const getChapterTitle = (chapterIndex: number): string => { - const titles = [ - '课前准备', - '程序设计基础知识', - '程序的控制结构', - '大话吉模型介绍', - 'DeepSeek实际应用', - 'DeepSeek实际应用' - ] - return titles[chapterIndex - 1] || '课程内容' -} +// const getChapterTitle = (chapterIndex: number): string => { +// const titles = [ +// '课前准备', +// '程序设计基础知识', +// '程序的控制结构', +// '大话吉模型介绍', +// 'DeepSeek实际应用', +// 'DeepSeek实际应用' +// ] +// return titles[chapterIndex - 1] || '课程内容' +// } // 预览模态框相关数据 const previewModalVisible = ref(false) @@ -585,13 +586,13 @@ const toggleChapter = (chapterIndex: number) => { } // 格式化时长 -const formatDuration = (sortOrder: number): string => { - // 根据章节序号模拟时长 - const baseDuration = 5 + (sortOrder * 3) // 基础5分钟 + 序号*3分钟 - const minutes = baseDuration % 60 - const seconds = (sortOrder * 17) % 60 // 模拟秒数 - return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}` -} +// const formatDuration = (sortOrder: number): string => { +// // 根据章节序号模拟时长 +// const baseDuration = 5 + (sortOrder * 3) // 基础5分钟 + 序号*3分钟 +// const minutes = baseDuration % 60 +// const seconds = (sortOrder * 17) % 60 // 模拟秒数 +// return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}` +// } // 获取课时类型样式类 const getLessonTypeClass = (section: CourseSection): string => { @@ -696,18 +697,18 @@ const navigateToEnrolledArea = (videoUrl: string, sectionName: string) => { } // 更新视频播放器(备用方案) -const updateVideoPlayer = (videoUrl: string, sectionName: string) => { - console.log('更新视频播放器:', { videoUrl, sectionName }) +// const updateVideoPlayer = (videoUrl: string, sectionName: string) => { +// console.log('更新视频播放器:', { videoUrl, sectionName }) - // 如果在同一页面内更新视频播放器 - // 可以通过事件总线或状态管理来实现 +// // 如果在同一页面内更新视频播放器 +// // 可以通过事件总线或状态管理来实现 - // 这里先显示确认信息 - const confirmed = confirm(`即将播放视频: ${sectionName}\n是否继续?`) - if (confirmed) { - navigateToEnrolledArea(videoUrl, sectionName) - } -} +// // 这里先显示确认信息 +// const confirmed = confirm(`即将播放视频: ${sectionName}\n是否继续?`) +// if (confirmed) { +// navigateToEnrolledArea(videoUrl, sectionName) +// } +// } // 预览章节(非视频内容) const previewSection = (section: CourseSection) => { diff --git a/src/views/CourseStudy.vue b/src/views/CourseStudy.vue index b2c7137..4f915a9 100644 --- a/src/views/CourseStudy.vue +++ b/src/views/CourseStudy.vue @@ -597,21 +597,46 @@ const setDefaultCourseInfo = () => { id: courseId.value, title: 'C语言程序设计', description: '

本课程将带你从零开始学习C语言程序设计,掌握编程基础知识。

', - category: '信息技术', - instructor: '教师', - duration: 3600, + content: '详细的C语言课程内容', + category: { + id: 3, + name: '信息技术', + slug: 'it', + description: '信息技术相关课程' + }, + instructor: { + id: 4, + name: '教师', + title: 'C语言专家', + bio: '资深C语言开发工程师', + avatar: '', + rating: 4.5, + studentsCount: 1000, + coursesCount: 3, + experience: '10年C语言教学经验', + education: ['计算机科学博士'], + certifications: ['C语言认证'] + }, + thumbnail: '', + coverImage: '', + duration: '60小时', level: 'beginner', price: 0, originalPrice: 0, + currency: 'CNY', rating: 4.5, + ratingCount: 100, studentsCount: 1000, - lessonsCount: 20, - thumbnail: '', + totalLessons: 20, + language: 'zh-CN', + skills: ['C语言', '程序设计', '算法'], + requirements: ['计算机基础'], + objectives: ['掌握C语言语法', '学会程序设计', '理解算法思维'], tags: ['编程', 'C语言'], - createdAt: Date.now(), - updatedAt: Date.now(), - isEnrolled: true, - progress: 0 + status: 'published', + createdAt: '2024-01-01', + updatedAt: '2024-01-01', + publishedAt: '2024-01-01' } } } @@ -633,7 +658,7 @@ const onVideoEnded = () => { } } -const onVideoTimeUpdate = (time: number) => { +const onVideoTimeUpdate = (_time: number) => { // 记录学习时长 totalStudyTime.value += 1 } @@ -764,7 +789,7 @@ const replyToComment = (commentId: number) => { const likeReply = (commentId: number, replyId: number) => { const comment = comments.value.find(c => c.id === commentId) if (comment && comment.replies) { - const reply = comment.replies.find(r => r.id === replyId) + const reply = comment.replies.find((r: any) => r.id === replyId) if (reply) { if (reply.liked) { reply.likes = (reply.likes || 0) - 1 diff --git a/src/views/Faculty.vue b/src/views/Faculty.vue index 5c0d277..147be40 100644 --- a/src/views/Faculty.vue +++ b/src/views/Faculty.vue @@ -45,8 +45,12 @@ >
- -
+ +
@@ -57,11 +61,9 @@

{{ teacher.name }}

-

{{ teacher.title }}

+

{{ teacher.position }}

{{ teacher.description }}

-
- {{ tag }} -
+
{{ teacher.specialty }}
@@ -94,13 +96,13 @@ import { ref, computed } from 'vue' // 横幅图片相关 -const bannerImageSrc = ref('') +const bannerImageSrc = ref('/images/Teachers/师资力量切图-轮播区.png') const hasBannerImage = computed(() => bannerImageSrc.value.trim() !== '') // 设置横幅图片的方法(供后续使用) -const setBannerImage = (imagePath: string) => { - bannerImageSrc.value = imagePath -} +// const setBannerImage = (imagePath: string) => { +// bannerImageSrc.value = imagePath +// } // 筛选标签数据 const filterTabs = ref([ @@ -121,59 +123,67 @@ const teachers = ref([ { id: 1, name: '黄天羽', - title: '注册国际人才测评师资格认证', - description: '注册国际企业学习设计师 认证', - tags: ['主讲', '资深人才测评师'], - featured: true + position: '北京理工大学计算机学院教授', + description: '北京市高等学校育年教学名师,博导', + specialty: '主讲 - 软件工程基础训练', + featured: true, + avatar: '/images/Teachers/师资力量1.png' }, { id: 2, name: '蓝天', - title: '北京理工大学MBA企业文化专家顾问', + position: '北京理工大学MBA企业文化专家顾问', description: '多家知名上市企业高管', - tags: ['主讲', 'MBA企业文化专家'] + specialty: '主讲 - MBA企业文化专家', + avatar: '/images/Teachers/师资力量2.png' }, { id: 3, name: '万精云', - title: '中国人事科学', + position: '中国人事科学研究院研究员', description: '中国科学院博士', - tags: ['主讲', '人事专家'] + specialty: '主讲 - 人事管理专家', + avatar: '/images/Teachers/师资力量3.png' }, { id: 4, name: '张庆勋', - title: '北京大学博士', - description: '内蒙古财经大学', - tags: ['主讲', '金牌讲师'] + position: '北京大学博士', + description: '内蒙古财经大学教授', + specialty: '主讲 - 金融学专家', + avatar: '/images/Teachers/师资力量4.png' }, { id: 5, name: '程毅', - title: '中国科技大学博士研究生', - description: '', - tags: ['主讲', '科技专家'] + position: '中国科技大学博士研究生导师', + description: '计算机科学与技术专业带头人', + specialty: '主讲 - 计算机科学专家', + avatar: '/images/Teachers/师资力量5.png' }, { id: 6, name: '王德华', - title: '数字经济与金融研究中心专家', + position: '数字经济与金融研究中心专家', description: '多家知名上市企业高级管理顾问', - tags: ['主讲', '数字经济专家'] + specialty: '主讲 - 数字经济专家', + avatar: '/images/Teachers/师资力量6.png' }, { id: 7, name: '马前程', - title: '清华大学管理学院', + position: '清华大学管理学院教授', description: '多家一线互联网企业高级管理顾问', - tags: ['主讲', '清华大学管理专家'] + specialty: '主讲 - 企业管理专家', + avatar: '/images/Teachers/师资力量7.png' }, { id: 8, name: '陈宇', - title: '知名上市企业高级管理顾问专家', + position: '知名上市企业高级管理顾问专家', description: '多家一线互联网企业高级管理顾问', - tags: ['主讲', '企业管理专家'] + specialty: '主讲 - 企业战略专家', + avatar: '/images/Teachers/师资力量8.png' } ]) @@ -246,18 +256,15 @@ const goToPage = (page: number) => { .banner-image-container { width: 100%; - height: 400px; + height: auto; position: relative; - display: flex; - align-items: center; - justify-content: center; } .banner-image { width: 100%; - height: 100%; + height: auto; + display: block; object-fit: cover; - object-position: center; } .banner-placeholder { @@ -364,6 +371,7 @@ const goToPage = (page: number) => { box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); transition: all 0.3s; cursor: pointer; + aspect-ratio: 3/4; } .faculty-card:hover { @@ -373,7 +381,7 @@ const goToPage = (page: number) => { .card-header { position: relative; - height: 200px; + height: 70%; background: #f5f5f5; display: flex; align-items: center; @@ -386,26 +394,18 @@ const goToPage = (page: number) => { height: 100%; } -.avatar-placeholder { +.teacher-avatar { width: 100%; height: 100%; - background: linear-gradient(135deg, #e0e0e0 0%, #f0f0f0 100%); - display: flex; - align-items: center; - justify-content: center; -} - -.avatar-placeholder::after { - content: '头像占位'; - color: #999; - font-size: 14px; + object-fit: cover; + object-position: center; } .featured-badge { position: absolute; - top: 12px; - left: 12px; - background: #FF6B35; + top: 8px; + left: 8px; + background: #E53E3E; color: white; padding: 4px 8px; border-radius: 4px; @@ -415,59 +415,60 @@ const goToPage = (page: number) => { .card-arrow { position: absolute; - top: 50%; + bottom: 16px; right: 16px; - transform: translateY(-50%); - color: #4A90E2; - background: white; - width: 32px; - height: 32px; + color: white; + background: #4A90E2; + width: 36px; + height: 36px; border-radius: 50%; display: flex; align-items: center; justify-content: center; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + box-shadow: 0 2px 8px rgba(74, 144, 226, 0.3); + transition: all 0.3s; +} + +.card-arrow:hover { + background: #357ABD; + transform: scale(1.1); } .card-content { - padding: 20px; + padding: 16px; + height: 30%; + display: flex; + flex-direction: column; + justify-content: flex-start; + text-align: left; } .teacher-name { - font-size: 18px; + font-size: 16px; font-weight: 600; color: #333; - margin: 0 0 8px 0; + margin: 0 0 6px 0; + line-height: 1.2; } -.teacher-title { - font-size: 14px; +.teacher-position { + font-size: 12px; color: #666; - margin: 0 0 8px 0; - line-height: 1.4; + margin: 0 0 4px 0; + line-height: 1.3; } .teacher-description { - font-size: 13px; - color: #999; - margin: 0 0 12px 0; - line-height: 1.4; - min-height: 18px; -} - -.teacher-tags { - display: flex; - gap: 6px; - flex-wrap: wrap; -} - -.tag { - background: #f0f8ff; - color: #4A90E2; - padding: 2px 8px; - border-radius: 12px; font-size: 12px; - border: 1px solid #e6f3ff; + color: #666; + margin: 0 0 6px 0; + line-height: 1.3; +} + +.teacher-specialty { + font-size: 11px; + color: #999; + line-height: 1.3; } /* 分页组件 */ @@ -528,10 +529,6 @@ const goToPage = (page: number) => { } @media (max-width: 1024px) { - .banner-image-container { - height: 350px; - } - .placeholder-icon { font-size: 40px; } @@ -557,10 +554,6 @@ const goToPage = (page: number) => { font-size: 13px; } - .banner-image-container { - height: 300px; - } - .placeholder-icon { font-size: 36px; } @@ -587,10 +580,6 @@ const goToPage = (page: number) => { padding: 20px 0 40px; } - .banner-image-container { - height: 250px; - } - .placeholder-icon { font-size: 32px; } diff --git a/src/views/Home.vue b/src/views/Home.vue index 512f100..3181b08 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -230,7 +230,7 @@ import RegisterModal from '@/components/auth/RegisterModal.vue' const { t, locale } = useI18n() const router = useRouter() const courseStore = useCourseStore() -const { loginModalVisible, registerModalVisible, enrollCourse, handleAuthSuccess } = useAuth() +const { loginModalVisible, registerModalVisible, handleAuthSuccess } = useAuth() // 轮播图根据语言动态切换 const bannerImage = computed(() => { diff --git a/src/views/Resources.vue b/src/views/Resources.vue index 63d3305..c7e1c0f 100644 --- a/src/views/Resources.vue +++ b/src/views/Resources.vue @@ -1,23 +1,13 @@