Files
RGKT/rg-09112127/js/apiService.js
2025-10-10 19:35:04 +08:00

558 lines
16 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 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();