/** * API服务类 - 与后端交互 */ class ApiService { constructor() { this.baseUrl = 'http://localhost:8080/api'; this.currentUser = null; } /** * 设置当前用户 */ setCurrentUser(user) { this.currentUser = user; localStorage.setItem('currentUser', JSON.stringify(user)); } /** * 获取当前用户 */ getCurrentUser() { if (!this.currentUser) { const userStr = localStorage.getItem('currentUser'); if (userStr) { this.currentUser = JSON.parse(userStr); } } return this.currentUser; } /** * 清除当前用户 */ clearCurrentUser() { this.currentUser = null; localStorage.removeItem('currentUser'); } /** * 通用请求方法 */ async request(url, options = {}) { const defaultOptions = { headers: { 'Content-Type': 'application/json', }, }; const finalOptions = { ...defaultOptions, ...options }; try { const response = await fetch(`${this.baseUrl}${url}`, finalOptions); const data = await response.json(); if (data.code === 200) { return data; } else { throw new Error(data.message || '请求失败'); } } catch (error) { console.error('API请求错误:', error); throw error; } } /** * GET请求 */ async get(url) { return this.request(url, { method: 'GET' }); } /** * POST请求 */ async post(url, data) { return this.request(url, { method: 'POST', body: JSON.stringify(data), }); } /** * PUT请求 */ async put(url, data) { return this.request(url, { method: 'PUT', body: JSON.stringify(data), }); } /** * DELETE请求 */ async delete(url) { return this.request(url, { method: 'DELETE' }); } // ========== 用户相关API ========== /** * 用户登录 */ async login(username, password) { const result = await this.post('/users/login', { username, password }); if (result.data) { this.setCurrentUser(result.data); } return result; } /** * 获取所有用户 */ async getUsers() { return this.get('/users'); } /** * 创建用户 */ async createUser(userData) { return this.post('/users', userData); } // ========== 课程相关API ========== /** * 获取所有课程 */ async getCourses() { return this.get('/courses'); } /** * 根据课程ID获取课程 */ async getCourseByCourseId(courseId) { return this.get(`/courses/courseId/${courseId}`); } /** * 根据分类获取课程 */ async getCoursesByCategory(categoryId) { return this.get(`/courses/category/${categoryId}`); } /** * 根据年级和学期获取课程 */ async getCoursesByGradeAndSemester(gradeLevel, semester) { return this.get(`/courses/grade/${gradeLevel}/semester/${semester}`); } // ========== 游戏相关API ========== /** * 获取所有游戏 */ async getGames() { return this.get('/games'); } /** * 根据课程ID获取游戏 */ async getGamesByCourseId(courseId) { return this.get(`/games/course/${courseId}`); } /** * 根据分类获取游戏 */ async getGamesByCategory(categoryId) { return this.get(`/games/category/${categoryId}`); } // ========== 数据同步API ========== /** * 获取完整数据结构 */ async getCompleteData() { return this.get('/data/complete'); } /** * 获取课程完整数据 */ async getCourseCompleteData(courseId) { return this.get(`/data/course/${courseId}/complete`); } // ========== 记录相关API ========== /** * 记录用户访问 */ async recordAccess(courseId, gameId, accessType, durationSeconds = 0) { const user = this.getCurrentUser(); if (!user) { console.warn('用户未登录,无法记录访问'); return { success: false, message: '用户未登录' }; } const data = { userId: user.id, courseId: courseId ? parseInt(courseId) : null, gameId: gameId ? parseInt(gameId) : null, accessType: accessType, durationSeconds: parseInt(durationSeconds) || 0 }; try { const result = await this.post('/records/access', data); return result; } catch (error) { console.error('记录访问失败:', error); return { success: false, message: error.message }; } } /** * 记录游戏结果 */ async recordGameResult(gameId, gameResult, score = 0, playTimeSeconds = 0, attemptsCount = 1, gameData = null) { const user = this.getCurrentUser(); if (!user) { console.warn('用户未登录,无法记录游戏结果'); return { success: false, message: '用户未登录' }; } const data = { userId: user.id, gameId: gameId ? parseInt(gameId) : null, gameResult: gameResult, score: parseInt(score) || 0, playTimeSeconds: parseInt(playTimeSeconds) || 0, attemptsCount: parseInt(attemptsCount) || 1, gameData: gameData }; try { const result = await this.post('/records/game', data); return result; } catch (error) { console.error('记录游戏结果失败:', error); return { success: false, message: error.message }; } } // ========== 统计相关API ========== /** * 获取用户学习统计 */ async getUserStats(userId) { return this.get(`/stats/user/${userId}`); } /** * 获取课程访问统计 */ async getCourseStats(courseId) { return this.get(`/stats/course/${courseId}`); } /** * 获取游戏统计 */ async getGameStats(gameId) { return this.get(`/stats/game/${gameId}`); } /** * 获取用户游戏统计 */ async getUserGameStats(userId, gameId) { return this.get(`/stats/user/${userId}/game/${gameId}`); } // ========== 数据分析相关API ========== /** * 获取学生统计数据 */ async getStudentStats(studentId, days = 30, categoryId = null) { let url = `/analytics/student/${studentId}/stats?days=${days}`; if (categoryId) { url += `&categoryId=${categoryId}`; } return this.get(url); } /** * 获取学生课程进度 */ async getStudentCourseProgress(studentId, days = 30, categoryId = null) { let url = `/analytics/student/${studentId}/courses?days=${days}`; if (categoryId) { url += `&categoryId=${categoryId}`; } return this.get(url); } /** * 获取学生游戏统计 */ async getStudentGameStats(studentId, days = 30, categoryId = null) { let url = `/analytics/student/${studentId}/games?days=${days}`; if (categoryId) { url += `&categoryId=${categoryId}`; } return this.get(url); } /** * 获取学生最近活动 */ async getStudentRecentActivities(studentId, limit = 10) { return this.get(`/analytics/student/${studentId}/activities?limit=${limit}`); } /** * 获取AI视频推荐 */ async getAIRecommendations(studentId, gameStats, courseStats) { try { // 构建推荐请求数据 const recommendationData = { studentId: studentId, gameStats: gameStats, courseStats: courseStats, timestamp: new Date().toISOString() }; // 调用AI推荐API const response = await this.post('/analytics/ai/recommendations', recommendationData); return response; } catch (error) { console.error('获取AI推荐失败:', error); // 返回模拟推荐数据 return this.getMockRecommendations(gameStats, courseStats); } } /** * 获取模拟推荐数据(当AI服务不可用时) */ getMockRecommendations(gameStats, courseStats) { const recommendations = []; // 基于游戏统计生成推荐 if (gameStats && gameStats.games) { gameStats.games.forEach(game => { if (game.accuracy < 70) { recommendations.push({ id: `rec_${game.gameId}_${Date.now()}`, type: 'video', title: `${game.gameTitle} - 基础讲解视频`, reason: `根据您的答题情况,在${game.gameTitle}中正确率为${game.accuracy}%,建议观看相关基础讲解视频来提升理解。`, tags: ['基础讲解', '数学概念', '提升理解'], videoUrl: this.getVideoUrlByGameName(game.gameTitle, 'basic'), priority: 'high' }); } }); } // 基于课程统计生成推荐 if (courseStats && courseStats.courses) { courseStats.courses.forEach(course => { if (course.progress < 50) { recommendations.push({ id: `rec_course_${course.id}_${Date.now()}`, type: 'course', title: `${course.name} - 深入学习`, reason: `您在${course.name}课程中的学习进度为${course.progress}%,建议继续深入学习相关概念。`, tags: ['深入学习', '课程内容', '巩固知识'], videoUrl: this.getVideoUrlByCourseName(course.name), priority: 'medium' }); } }); } // 如果没有特定推荐,提供通用推荐 if (recommendations.length === 0) { recommendations.push({ id: `rec_general_${Date.now()}`, type: 'general', title: '数学基础巩固视频', reason: '基于您的学习情况,建议观看数学基础概念视频来巩固知识。', tags: ['数学基础', '概念理解', '知识巩固'], videoUrl: 'video/数学-2下-视频--认识数字/认识数字课.mp4', priority: 'low' }); } return { success: true, data: { recommendations: recommendations.slice(0, 5), // 最多返回5个推荐 generatedAt: new Date().toISOString(), source: 'mock' } }; } /** * 根据游戏名称获取对应的视频URL */ getVideoUrlByGameName(gameName, type) { // 根据游戏名称匹配对应的视频文件 if (gameName.includes('数字') || gameName.includes('识数')) { return 'video/数学-2下-视频--认识数字/认识数字课.mp4'; } else if (gameName.includes('比大小') || gameName.includes('大小')) { return 'video/生活-比大小/比大小.mp4'; } else if (gameName.includes('加法') || gameName.includes('计算')) { if (type === 'basic') { return 'video/数学-2下-视频--饮品(和是4的加法)/教学片段.mp4'; } else { return 'video/数学-2下-视频--饮品(和是4的加法)/交互1(1+3).mp4'; } } else if (gameName.includes('时钟') || gameName.includes('时间')) { return 'video/数学-2下-视频--认识时钟/认识时钟.mp4'; } else if (gameName.includes('情绪') || gameName.includes('情感')) { return 'video/生活-什么是情绪/happy.mp4'; } else if (gameName.includes('垃圾') || gameName.includes('环保')) { return 'video/生活-捡垃圾/捡垃圾.mp4'; } // 默认返回数字认识视频 return 'video/数学-2下-视频--认识数字/认识数字课.mp4'; } /** * 根据课程名称获取对应的视频URL */ getVideoUrlByCourseName(courseName) { // 根据课程名称匹配对应的视频文件 if (courseName.includes('数学') || courseName.includes('数字')) { return 'video/数学-2下-视频--认识数字/认识数字课.mp4'; } else if (courseName.includes('语文') || courseName.includes('语言')) { return 'video/生活-什么是情绪/happy.mp4'; } else if (courseName.includes('生活') || courseName.includes('常识')) { return 'video/生活-捡垃圾/捡垃圾.mp4'; } else if (courseName.includes('时间') || courseName.includes('时钟')) { return 'video/数学-2下-视频--认识时钟/认识时钟.mp4'; } else if (courseName.includes('加法') || courseName.includes('计算')) { return 'video/数学-2下-视频--饮品(和是4的加法)/教学片段.mp4'; } // 默认返回数字认识视频 return 'video/数学-2下-视频--认识数字/认识数字课.mp4'; } /** * 获取班级整体统计 */ async getClassOverview(classId, days = 30) { return this.get(`/analytics/class/${classId}/overview?days=${days}`); } /** * 获取课程学习统计 */ async getCourseStats(courseId, days = 30) { return this.get(`/analytics/course/${courseId}/stats?days=${days}`); } /** * 获取游戏统计 */ async getGameStats(gameId, days = 30) { return this.get(`/analytics/game/${gameId}/stats?days=${days}`); } /** * 导出学生数据报告 */ async exportStudentReport(studentId, days = 30) { return this.get(`/analytics/student/${studentId}/export?days=${days}`); } // ==================== AI游戏生成器相关方法 ==================== /** * 生成AI个性化游戏 */ async generateAIGame(studentId, subject, gameType, difficulty, questionCount) { try { const response = await this.post('/api/ai/game/generate', { studentId: studentId, subject: subject, gameType: gameType, difficulty: difficulty, questionCount: questionCount }); return response; } catch (error) { console.error('生成AI游戏失败:', error); throw error; } } /** * 获取学生游戏统计 */ async getStudentGameStats(studentId) { try { const response = await this.get(`/api/ai/game/stats/${studentId}`); return response; } catch (error) { console.error('获取游戏统计失败:', error); throw error; } } /** * 更新游戏结果 */ async updateGameResult(studentId, gameId, correct, total, timeSpent, hintsUsed) { try { const response = await this.post('/api/ai/game/result', { studentId: studentId, gameId: gameId, correct: correct, total: total, timeSpent: timeSpent, hintsUsed: hintsUsed }); return response; } catch (error) { console.error('更新游戏结果失败:', error); throw error; } } /** * 获取推荐难度 */ async getRecommendedDifficulty(studentId) { try { const response = await this.get(`/api/ai/game/difficulty/${studentId}`); return response; } catch (error) { console.error('获取推荐难度失败:', error); throw error; } } } // 创建全局API服务实例 window.apiService = new ApiService();