Files
RGKT/rg-09112127/js/apiService.js

558 lines
16 KiB
JavaScript
Raw Normal View History

2025-10-10 19:35:04 +08:00
/**
* 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的加法/交互11+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();