258 lines
7.0 KiB
TypeScript
Raw Normal View History

2025-07-22 14:39:45 +08:00
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
2025-07-28 09:51:21 +08:00
import { CourseApi } from '@/api/modules/course'
2025-07-22 14:39:45 +08:00
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 interface Lesson {
id: number
courseId: number
title: string
description: string
videoUrl?: string
duration: string
order: number
isCompleted?: boolean
isFree?: boolean
}
export const useCourseStore = defineStore('course', () => {
// 状态
const courses = ref<Course[]>([])
const currentCourse = ref<Course | null>(null)
const lessons = ref<Lesson[]>([])
const enrolledCourses = ref<Course[]>([])
const isLoading = ref(false)
const searchQuery = ref('')
const selectedCategory = ref('')
const selectedLevel = ref('')
// 计算属性
const filteredCourses = computed(() => {
let filtered = courses.value
if (searchQuery.value) {
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())
)
}
if (selectedCategory.value) {
filtered = filtered.filter(course => course.category === selectedCategory.value)
}
if (selectedLevel.value) {
filtered = filtered.filter(course => course.level === selectedLevel.value)
}
return filtered
})
const categories = computed(() => {
const cats = courses.value.map(course => course.category)
return [...new Set(cats)]
})
// 方法
const fetchCourses = async () => {
isLoading.value = true
try {
2025-07-28 09:51:21 +08:00
console.log('尝试从API获取课程数据...')
const response = await CourseApi.getCourses()
console.log('API响应:', response)
courses.value = response.data.list
} catch (error) {
console.error('API调用失败使用模拟数据:', error)
// 如果API调用失败使用模拟数据作为后备
2025-07-22 14:39:45 +08:00
const mockCourses: Course[] = [
{
id: 1,
title: 'Vue.js 3 完整教程',
description: '从零开始学习Vue.js 3包括Composition API、TypeScript集成等现代开发技术',
instructor: '李老师',
instructorAvatar: 'https://via.placeholder.com/50',
thumbnail: 'https://via.placeholder.com/300x200',
price: 299,
originalPrice: 399,
rating: 4.8,
studentsCount: 1234,
duration: '12小时',
level: 'intermediate',
category: '前端开发',
tags: ['Vue.js', 'JavaScript', 'TypeScript'],
createdAt: '2024-01-01',
updatedAt: '2024-01-15'
},
{
id: 2,
title: 'React 18 实战开发',
description: '掌握React 18的新特性包括并发渲染、Suspense等高级功能',
instructor: '王老师',
instructorAvatar: 'https://via.placeholder.com/50',
thumbnail: 'https://via.placeholder.com/300x200',
price: 399,
rating: 4.9,
studentsCount: 2156,
duration: '15小时',
level: 'advanced',
category: '前端开发',
tags: ['React', 'JavaScript', 'Hooks'],
createdAt: '2024-01-05',
updatedAt: '2024-01-20'
},
{
id: 3,
title: 'Node.js 后端开发',
description: '学习Node.js后端开发包括Express、数据库操作、API设计等',
instructor: '张老师',
instructorAvatar: 'https://via.placeholder.com/50',
thumbnail: 'https://via.placeholder.com/300x200',
price: 349,
rating: 4.7,
studentsCount: 987,
duration: '18小时',
level: 'intermediate',
category: '后端开发',
tags: ['Node.js', 'Express', 'MongoDB'],
createdAt: '2024-01-10',
updatedAt: '2024-01-25'
}
]
courses.value = mockCourses
} finally {
isLoading.value = false
}
}
const fetchCourseById = async (id: number) => {
isLoading.value = true
try {
2025-07-28 09:51:21 +08:00
const response = await CourseApi.getCourseById(id)
currentCourse.value = response.data
} catch (error) {
console.error('Failed to fetch course:', error)
// 如果API调用失败从本地数据中查找
2025-07-22 14:39:45 +08:00
const course = courses.value.find(c => c.id === id)
if (course) {
currentCourse.value = course
}
} finally {
isLoading.value = false
}
}
const fetchLessons = async (courseId: number) => {
isLoading.value = true
try {
// 模拟API调用
await new Promise(resolve => setTimeout(resolve, 500))
// 模拟课程章节数据
const mockLessons: Lesson[] = [
{
id: 1,
courseId,
title: '课程介绍',
description: '了解课程内容和学习目标',
duration: '10分钟',
order: 1,
isFree: true
},
{
id: 2,
courseId,
title: '环境搭建',
description: '配置开发环境和工具',
duration: '20分钟',
order: 2,
isFree: true
},
{
id: 3,
courseId,
title: '基础语法',
description: '学习基础语法和概念',
duration: '45分钟',
order: 3
}
]
lessons.value = mockLessons
} catch (error) {
console.error('Failed to fetch lessons:', error)
} finally {
isLoading.value = false
}
}
const enrollCourse = async (courseId: number) => {
isLoading.value = true
try {
// 模拟API调用
await new Promise(resolve => setTimeout(resolve, 1000))
const course = courses.value.find(c => c.id === courseId)
if (course) {
course.isEnrolled = true
course.progress = 0
enrolledCourses.value.push(course)
}
return { success: true, message: '报名成功' }
} catch (error) {
return { success: false, message: '报名失败' }
} finally {
isLoading.value = false
}
}
const updateProgress = async (courseId: number, progress: number) => {
const course = enrolledCourses.value.find(c => c.id === courseId)
if (course) {
course.progress = progress
}
}
return {
// 状态
courses,
currentCourse,
lessons,
enrolledCourses,
isLoading,
searchQuery,
selectedCategory,
selectedLevel,
// 计算属性
filteredCourses,
categories,
// 方法
fetchCourses,
fetchCourseById,
fetchLessons,
enrollCourse,
updateProgress
}
})