713 lines
19 KiB
Dart
713 lines
19 KiB
Dart
/// 学习统计数据
|
|
class LearningStats {
|
|
/// 用户ID
|
|
final String userId;
|
|
|
|
/// 总学习天数
|
|
final int totalStudyDays;
|
|
|
|
/// 连续学习天数
|
|
final int currentStreak;
|
|
|
|
/// 最长连续学习天数
|
|
final int maxStreak;
|
|
|
|
/// 总学习单词数
|
|
final int totalWordsLearned;
|
|
|
|
/// 总复习单词数
|
|
final int totalWordsReviewed;
|
|
|
|
/// 总学习时间(分钟)
|
|
final int totalStudyTimeMinutes;
|
|
|
|
/// 平均每日学习单词数
|
|
final double averageDailyWords;
|
|
|
|
/// 平均每日学习时间(分钟)
|
|
final double averageDailyMinutes;
|
|
|
|
/// 学习准确率
|
|
final double accuracyRate;
|
|
|
|
/// 完成的词汇书数量
|
|
final int completedBooks;
|
|
|
|
/// 当前学习的词汇书数量
|
|
final int currentBooks;
|
|
|
|
/// 掌握的单词数
|
|
final int masteredWords;
|
|
|
|
/// 学习中的单词数
|
|
final int learningWords;
|
|
|
|
/// 需要复习的单词数
|
|
final int reviewWords;
|
|
|
|
/// 本周学习统计
|
|
final WeeklyStats weeklyStats;
|
|
|
|
/// 本月学习统计
|
|
final MonthlyStats monthlyStats;
|
|
|
|
/// 学习等级
|
|
final int level;
|
|
|
|
/// 当前等级经验值
|
|
final int currentExp;
|
|
|
|
/// 升级所需经验值
|
|
final int nextLevelExp;
|
|
|
|
/// 最后学习时间
|
|
final DateTime? lastStudyTime;
|
|
|
|
/// 创建时间
|
|
final DateTime createdAt;
|
|
|
|
/// 更新时间
|
|
final DateTime updatedAt;
|
|
|
|
/// 每日学习记录
|
|
final List<DailyStudyRecord> dailyRecords;
|
|
|
|
/// 学习成就
|
|
final List<Achievement> achievements;
|
|
|
|
/// 排行榜信息
|
|
final Leaderboard? leaderboard;
|
|
|
|
const LearningStats({
|
|
required this.userId,
|
|
required this.totalStudyDays,
|
|
required this.currentStreak,
|
|
required this.maxStreak,
|
|
required this.totalWordsLearned,
|
|
required this.totalWordsReviewed,
|
|
required this.totalStudyTimeMinutes,
|
|
required this.averageDailyWords,
|
|
required this.averageDailyMinutes,
|
|
required this.accuracyRate,
|
|
required this.completedBooks,
|
|
required this.currentBooks,
|
|
required this.masteredWords,
|
|
required this.learningWords,
|
|
required this.reviewWords,
|
|
required this.weeklyStats,
|
|
required this.monthlyStats,
|
|
required this.level,
|
|
required this.currentExp,
|
|
required this.nextLevelExp,
|
|
this.lastStudyTime,
|
|
required this.createdAt,
|
|
required this.updatedAt,
|
|
required this.dailyRecords,
|
|
required this.achievements,
|
|
this.leaderboard,
|
|
});
|
|
|
|
factory LearningStats.fromJson(Map<String, dynamic> json) {
|
|
return LearningStats(
|
|
userId: json['userId'] as String,
|
|
totalStudyDays: json['totalStudyDays'] as int,
|
|
currentStreak: json['currentStreak'] as int,
|
|
maxStreak: json['maxStreak'] as int,
|
|
totalWordsLearned: json['totalWordsLearned'] as int,
|
|
totalWordsReviewed: json['totalWordsReviewed'] as int,
|
|
totalStudyTimeMinutes: json['totalStudyTimeMinutes'] as int,
|
|
averageDailyWords: (json['averageDailyWords'] as num).toDouble(),
|
|
averageDailyMinutes: (json['averageDailyMinutes'] as num).toDouble(),
|
|
accuracyRate: (json['accuracyRate'] as num).toDouble(),
|
|
completedBooks: json['completedBooks'] as int,
|
|
currentBooks: json['currentBooks'] as int,
|
|
masteredWords: json['masteredWords'] as int,
|
|
learningWords: json['learningWords'] as int,
|
|
reviewWords: json['reviewWords'] as int,
|
|
weeklyStats: WeeklyStats.fromJson(json['weeklyStats'] as Map<String, dynamic>),
|
|
monthlyStats: MonthlyStats.fromJson(json['monthlyStats'] as Map<String, dynamic>),
|
|
level: json['level'] as int,
|
|
currentExp: json['currentExp'] as int,
|
|
nextLevelExp: json['nextLevelExp'] as int,
|
|
lastStudyTime: json['lastStudyTime'] != null
|
|
? DateTime.parse(json['lastStudyTime'] as String)
|
|
: null,
|
|
createdAt: DateTime.parse(json['createdAt'] as String),
|
|
updatedAt: DateTime.parse(json['updatedAt'] as String),
|
|
dailyRecords: (json['dailyRecords'] as List<dynamic>?)
|
|
?.map((e) => DailyStudyRecord.fromJson(e as Map<String, dynamic>))
|
|
.toList() ?? [],
|
|
achievements: (json['achievements'] as List<dynamic>?)
|
|
?.map((e) => Achievement.fromJson(e as Map<String, dynamic>))
|
|
.toList() ?? [],
|
|
leaderboard: json['leaderboard'] != null
|
|
? Leaderboard.fromJson(json['leaderboard'] as Map<String, dynamic>)
|
|
: null,
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> toJson() {
|
|
return {
|
|
'userId': userId,
|
|
'totalStudyDays': totalStudyDays,
|
|
'currentStreak': currentStreak,
|
|
'maxStreak': maxStreak,
|
|
'totalWordsLearned': totalWordsLearned,
|
|
'totalWordsReviewed': totalWordsReviewed,
|
|
'totalStudyTimeMinutes': totalStudyTimeMinutes,
|
|
'averageDailyWords': averageDailyWords,
|
|
'averageDailyMinutes': averageDailyMinutes,
|
|
'accuracyRate': accuracyRate,
|
|
'completedBooks': completedBooks,
|
|
'currentBooks': currentBooks,
|
|
'masteredWords': masteredWords,
|
|
'learningWords': learningWords,
|
|
'reviewWords': reviewWords,
|
|
'weeklyStats': weeklyStats.toJson(),
|
|
'monthlyStats': monthlyStats.toJson(),
|
|
'level': level,
|
|
'currentExp': currentExp,
|
|
'nextLevelExp': nextLevelExp,
|
|
'lastStudyTime': lastStudyTime?.toIso8601String(),
|
|
'createdAt': createdAt.toIso8601String(),
|
|
'updatedAt': updatedAt.toIso8601String(),
|
|
'dailyRecords': dailyRecords.map((e) => e.toJson()).toList(),
|
|
'achievements': achievements.map((e) => e.toJson()).toList(),
|
|
'leaderboard': leaderboard?.toJson(),
|
|
};
|
|
}
|
|
|
|
LearningStats copyWith({
|
|
String? userId,
|
|
int? totalStudyDays,
|
|
int? currentStreak,
|
|
int? maxStreak,
|
|
int? totalWordsLearned,
|
|
int? totalWordsReviewed,
|
|
int? totalStudyTimeMinutes,
|
|
double? averageDailyWords,
|
|
double? averageDailyMinutes,
|
|
double? accuracyRate,
|
|
int? completedBooks,
|
|
int? currentBooks,
|
|
int? masteredWords,
|
|
int? learningWords,
|
|
int? reviewWords,
|
|
WeeklyStats? weeklyStats,
|
|
MonthlyStats? monthlyStats,
|
|
int? level,
|
|
int? currentExp,
|
|
int? nextLevelExp,
|
|
DateTime? lastStudyTime,
|
|
DateTime? createdAt,
|
|
DateTime? updatedAt,
|
|
List<DailyStudyRecord>? dailyRecords,
|
|
List<Achievement>? achievements,
|
|
Leaderboard? leaderboard,
|
|
}) {
|
|
return LearningStats(
|
|
userId: userId ?? this.userId,
|
|
totalStudyDays: totalStudyDays ?? this.totalStudyDays,
|
|
currentStreak: currentStreak ?? this.currentStreak,
|
|
maxStreak: maxStreak ?? this.maxStreak,
|
|
totalWordsLearned: totalWordsLearned ?? this.totalWordsLearned,
|
|
totalWordsReviewed: totalWordsReviewed ?? this.totalWordsReviewed,
|
|
totalStudyTimeMinutes: totalStudyTimeMinutes ?? this.totalStudyTimeMinutes,
|
|
averageDailyWords: averageDailyWords ?? this.averageDailyWords,
|
|
averageDailyMinutes: averageDailyMinutes ?? this.averageDailyMinutes,
|
|
accuracyRate: accuracyRate ?? this.accuracyRate,
|
|
completedBooks: completedBooks ?? this.completedBooks,
|
|
currentBooks: currentBooks ?? this.currentBooks,
|
|
masteredWords: masteredWords ?? this.masteredWords,
|
|
learningWords: learningWords ?? this.learningWords,
|
|
reviewWords: reviewWords ?? this.reviewWords,
|
|
weeklyStats: weeklyStats ?? this.weeklyStats,
|
|
monthlyStats: monthlyStats ?? this.monthlyStats,
|
|
level: level ?? this.level,
|
|
currentExp: currentExp ?? this.currentExp,
|
|
nextLevelExp: nextLevelExp ?? this.nextLevelExp,
|
|
lastStudyTime: lastStudyTime ?? this.lastStudyTime,
|
|
createdAt: createdAt ?? this.createdAt,
|
|
updatedAt: updatedAt ?? this.updatedAt,
|
|
dailyRecords: dailyRecords ?? this.dailyRecords,
|
|
achievements: achievements ?? this.achievements,
|
|
leaderboard: leaderboard ?? this.leaderboard,
|
|
);
|
|
}
|
|
|
|
/// 获取学习进度百分比
|
|
double get progressPercentage {
|
|
if (nextLevelExp == 0) return 0.0;
|
|
return currentExp / nextLevelExp;
|
|
}
|
|
|
|
/// 获取总学习时间(小时)
|
|
double get totalStudyHours {
|
|
return totalStudyTimeMinutes / 60.0;
|
|
}
|
|
|
|
/// 获取平均每日学习时间(小时)
|
|
double get averageDailyHours {
|
|
return averageDailyMinutes / 60.0;
|
|
}
|
|
}
|
|
|
|
/// 周学习统计
|
|
class WeeklyStats {
|
|
/// 本周学习天数
|
|
final int studyDays;
|
|
|
|
/// 本周学习单词数
|
|
final int wordsLearned;
|
|
|
|
/// 本周复习单词数
|
|
final int wordsReviewed;
|
|
|
|
/// 本周学习时间(分钟)
|
|
final int studyTimeMinutes;
|
|
|
|
/// 本周准确率
|
|
final double accuracyRate;
|
|
|
|
/// 每日学习记录
|
|
final List<DailyStudyRecord> dailyRecords;
|
|
|
|
const WeeklyStats({
|
|
required this.studyDays,
|
|
required this.wordsLearned,
|
|
required this.wordsReviewed,
|
|
required this.studyTimeMinutes,
|
|
required this.accuracyRate,
|
|
required this.dailyRecords,
|
|
});
|
|
|
|
factory WeeklyStats.fromJson(Map<String, dynamic> json) {
|
|
return WeeklyStats(
|
|
studyDays: json['studyDays'] as int,
|
|
wordsLearned: json['wordsLearned'] as int,
|
|
wordsReviewed: json['wordsReviewed'] as int,
|
|
studyTimeMinutes: json['studyTimeMinutes'] as int,
|
|
accuracyRate: (json['accuracyRate'] as num).toDouble(),
|
|
dailyRecords: (json['dailyRecords'] as List<dynamic>?)
|
|
?.map((e) => DailyStudyRecord.fromJson(e as Map<String, dynamic>))
|
|
.toList() ?? [],
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> toJson() {
|
|
return {
|
|
'studyDays': studyDays,
|
|
'wordsLearned': wordsLearned,
|
|
'wordsReviewed': wordsReviewed,
|
|
'studyTimeMinutes': studyTimeMinutes,
|
|
'accuracyRate': accuracyRate,
|
|
'dailyRecords': dailyRecords.map((e) => e.toJson()).toList(),
|
|
};
|
|
}
|
|
|
|
/// 获取本周学习时间(小时)
|
|
double get studyHours {
|
|
return studyTimeMinutes / 60.0;
|
|
}
|
|
}
|
|
|
|
/// 月学习统计
|
|
class MonthlyStats {
|
|
/// 本月学习天数
|
|
final int studyDays;
|
|
|
|
/// 本月学习单词数
|
|
final int wordsLearned;
|
|
|
|
/// 本月复习单词数
|
|
final int wordsReviewed;
|
|
|
|
/// 本月学习时间(分钟)
|
|
final int studyTimeMinutes;
|
|
|
|
/// 本月准确率
|
|
final double accuracyRate;
|
|
|
|
/// 本月完成的词汇书数
|
|
final int completedBooks;
|
|
|
|
/// 周统计记录
|
|
final List<WeeklyStats> weeklyRecords;
|
|
|
|
const MonthlyStats({
|
|
required this.studyDays,
|
|
required this.wordsLearned,
|
|
required this.wordsReviewed,
|
|
required this.studyTimeMinutes,
|
|
required this.accuracyRate,
|
|
required this.completedBooks,
|
|
required this.weeklyRecords,
|
|
});
|
|
|
|
factory MonthlyStats.fromJson(Map<String, dynamic> json) {
|
|
return MonthlyStats(
|
|
studyDays: json['studyDays'] as int,
|
|
wordsLearned: json['wordsLearned'] as int,
|
|
wordsReviewed: json['wordsReviewed'] as int,
|
|
studyTimeMinutes: json['studyTimeMinutes'] as int,
|
|
accuracyRate: (json['accuracyRate'] as num).toDouble(),
|
|
completedBooks: json['completedBooks'] as int,
|
|
weeklyRecords: (json['weeklyRecords'] as List<dynamic>?)
|
|
?.map((e) => WeeklyStats.fromJson(e as Map<String, dynamic>))
|
|
.toList() ?? [],
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> toJson() {
|
|
return {
|
|
'studyDays': studyDays,
|
|
'wordsLearned': wordsLearned,
|
|
'wordsReviewed': wordsReviewed,
|
|
'studyTimeMinutes': studyTimeMinutes,
|
|
'accuracyRate': accuracyRate,
|
|
'completedBooks': completedBooks,
|
|
'weeklyRecords': weeklyRecords.map((e) => e.toJson()).toList(),
|
|
};
|
|
}
|
|
|
|
/// 获取本月学习时间(小时)
|
|
double get studyHours {
|
|
return studyTimeMinutes / 60.0;
|
|
}
|
|
}
|
|
|
|
/// 每日学习记录
|
|
class DailyStudyRecord {
|
|
/// 日期
|
|
final DateTime date;
|
|
|
|
/// 学习单词数
|
|
final int wordsLearned;
|
|
|
|
/// 复习单词数
|
|
final int wordsReviewed;
|
|
|
|
/// 学习时间(分钟)
|
|
final int studyTimeMinutes;
|
|
|
|
/// 准确率
|
|
final double accuracyRate;
|
|
|
|
/// 完成的测试数
|
|
final int testsCompleted;
|
|
|
|
/// 获得的经验值
|
|
final int expGained;
|
|
|
|
/// 学习的词汇书ID列表
|
|
final List<String> vocabularyBookIds;
|
|
|
|
const DailyStudyRecord({
|
|
required this.date,
|
|
required this.wordsLearned,
|
|
required this.wordsReviewed,
|
|
required this.studyTimeMinutes,
|
|
required this.accuracyRate,
|
|
required this.testsCompleted,
|
|
required this.expGained,
|
|
required this.vocabularyBookIds,
|
|
});
|
|
|
|
factory DailyStudyRecord.fromJson(Map<String, dynamic> json) {
|
|
// 支持两种命名格式:驼峰命名和蛇形命名
|
|
return DailyStudyRecord(
|
|
date: DateTime.parse(json['date'] as String),
|
|
wordsLearned: (json['wordsLearned'] ?? json['words_learned'] ?? json['new_words_learned'] ?? 0) as int,
|
|
wordsReviewed: (json['wordsReviewed'] ?? json['words_reviewed'] ?? 0) as int,
|
|
studyTimeMinutes: (json['studyTimeMinutes'] ?? json['total_study_time_seconds'] != null
|
|
? (json['total_study_time_seconds'] as int) ~/ 60
|
|
: 0) as int,
|
|
accuracyRate: ((json['accuracyRate'] ?? json['average_accuracy'] ?? 0) as num).toDouble(),
|
|
testsCompleted: (json['testsCompleted'] ?? json['session_count'] ?? 0) as int,
|
|
expGained: (json['expGained'] ?? json['experience_gained'] ?? 0) as int,
|
|
vocabularyBookIds: (json['vocabularyBookIds'] as List<dynamic>?)
|
|
?.map((e) => e as String)
|
|
.toList() ?? [],
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> toJson() {
|
|
return {
|
|
'date': date.toIso8601String(),
|
|
'wordsLearned': wordsLearned,
|
|
'wordsReviewed': wordsReviewed,
|
|
'studyTimeMinutes': studyTimeMinutes,
|
|
'accuracyRate': accuracyRate,
|
|
'testsCompleted': testsCompleted,
|
|
'expGained': expGained,
|
|
'vocabularyBookIds': vocabularyBookIds,
|
|
};
|
|
}
|
|
|
|
/// 获取学习时间(小时)
|
|
double get studyHours {
|
|
return studyTimeMinutes / 60.0;
|
|
}
|
|
}
|
|
|
|
/// 学习成就
|
|
class Achievement {
|
|
/// 成就ID
|
|
final String id;
|
|
|
|
/// 成就名称
|
|
final String name;
|
|
|
|
/// 成就描述
|
|
final String description;
|
|
|
|
/// 成就图标
|
|
final String icon;
|
|
|
|
/// 成就类型
|
|
final AchievementType type;
|
|
|
|
/// 是否已解锁
|
|
final bool isUnlocked;
|
|
|
|
/// 解锁时间
|
|
final DateTime? unlockedAt;
|
|
|
|
/// 进度值
|
|
final int progress;
|
|
|
|
/// 目标值
|
|
final int target;
|
|
|
|
/// 奖励经验值
|
|
final int rewardExp;
|
|
|
|
const Achievement({
|
|
required this.id,
|
|
required this.name,
|
|
required this.description,
|
|
required this.icon,
|
|
required this.type,
|
|
required this.isUnlocked,
|
|
this.unlockedAt,
|
|
required this.progress,
|
|
required this.target,
|
|
required this.rewardExp,
|
|
});
|
|
|
|
factory Achievement.fromJson(Map<String, dynamic> json) {
|
|
return Achievement(
|
|
id: json['id'] as String,
|
|
name: json['name'] as String,
|
|
description: json['description'] as String,
|
|
icon: json['icon'] as String,
|
|
type: AchievementType.values.firstWhere(
|
|
(e) => e.name == json['type'],
|
|
orElse: () => AchievementType.special,
|
|
),
|
|
isUnlocked: json['isUnlocked'] as bool,
|
|
unlockedAt: json['unlockedAt'] != null
|
|
? DateTime.parse(json['unlockedAt'] as String)
|
|
: null,
|
|
progress: json['progress'] as int,
|
|
target: json['target'] as int,
|
|
rewardExp: json['rewardExp'] as int,
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> toJson() {
|
|
return {
|
|
'id': id,
|
|
'name': name,
|
|
'description': description,
|
|
'icon': icon,
|
|
'type': type.name,
|
|
'isUnlocked': isUnlocked,
|
|
'unlockedAt': unlockedAt?.toIso8601String(),
|
|
'progress': progress,
|
|
'target': target,
|
|
'rewardExp': rewardExp,
|
|
};
|
|
}
|
|
|
|
/// 复制并修改部分属性
|
|
Achievement copyWith({
|
|
String? id,
|
|
String? name,
|
|
String? description,
|
|
String? icon,
|
|
AchievementType? type,
|
|
bool? isUnlocked,
|
|
DateTime? unlockedAt,
|
|
int? progress,
|
|
int? target,
|
|
int? rewardExp,
|
|
}) {
|
|
return Achievement(
|
|
id: id ?? this.id,
|
|
name: name ?? this.name,
|
|
description: description ?? this.description,
|
|
icon: icon ?? this.icon,
|
|
type: type ?? this.type,
|
|
isUnlocked: isUnlocked ?? this.isUnlocked,
|
|
unlockedAt: unlockedAt ?? this.unlockedAt,
|
|
progress: progress ?? this.progress,
|
|
target: target ?? this.target,
|
|
rewardExp: rewardExp ?? this.rewardExp,
|
|
);
|
|
}
|
|
|
|
/// 获取进度百分比
|
|
double get progressPercentage {
|
|
if (target == 0) return 0.0;
|
|
return (progress / target).clamp(0.0, 1.0);
|
|
}
|
|
}
|
|
|
|
/// 成就类型
|
|
enum AchievementType {
|
|
/// 学习天数
|
|
studyDays,
|
|
/// 学习单词数
|
|
wordsLearned,
|
|
/// 连续学习
|
|
streak,
|
|
/// 完成词汇书
|
|
booksCompleted,
|
|
/// 测试成绩
|
|
testScore,
|
|
/// 学习时间
|
|
studyTime,
|
|
/// 特殊成就
|
|
special,
|
|
}
|
|
|
|
/// 学习排行榜
|
|
class Leaderboard {
|
|
/// 排行榜类型
|
|
final LeaderboardType type;
|
|
|
|
/// 时间范围
|
|
final LeaderboardPeriod period;
|
|
|
|
/// 排行榜条目
|
|
final List<LeaderboardEntry> entries;
|
|
|
|
/// 用户排名
|
|
final int? userRank;
|
|
|
|
/// 更新时间
|
|
final DateTime updatedAt;
|
|
|
|
const Leaderboard({
|
|
required this.type,
|
|
required this.period,
|
|
required this.entries,
|
|
this.userRank,
|
|
required this.updatedAt,
|
|
});
|
|
|
|
factory Leaderboard.fromJson(Map<String, dynamic> json) {
|
|
return Leaderboard(
|
|
type: LeaderboardType.values.firstWhere(
|
|
(e) => e.name == json['type'],
|
|
orElse: () => LeaderboardType.wordsLearned,
|
|
),
|
|
period: LeaderboardPeriod.values.firstWhere(
|
|
(e) => e.name == json['period'],
|
|
orElse: () => LeaderboardPeriod.weekly,
|
|
),
|
|
entries: (json['entries'] as List<dynamic>?)
|
|
?.map((e) => LeaderboardEntry.fromJson(e as Map<String, dynamic>))
|
|
.toList() ?? [],
|
|
userRank: json['userRank'] as int?,
|
|
updatedAt: DateTime.parse(json['updatedAt'] as String),
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> toJson() {
|
|
return {
|
|
'type': type.name,
|
|
'period': period.name,
|
|
'entries': entries.map((e) => e.toJson()).toList(),
|
|
'userRank': userRank,
|
|
'updatedAt': updatedAt.toIso8601String(),
|
|
};
|
|
}
|
|
}
|
|
|
|
/// 排行榜条目
|
|
class LeaderboardEntry {
|
|
/// 排名
|
|
final int rank;
|
|
|
|
/// 用户ID
|
|
final String userId;
|
|
|
|
/// 用户名
|
|
final String username;
|
|
|
|
/// 用户头像
|
|
final String? avatar;
|
|
|
|
/// 分数
|
|
final int score;
|
|
|
|
/// 等级
|
|
final int level;
|
|
|
|
const LeaderboardEntry({
|
|
required this.rank,
|
|
required this.userId,
|
|
required this.username,
|
|
this.avatar,
|
|
required this.score,
|
|
required this.level,
|
|
});
|
|
|
|
factory LeaderboardEntry.fromJson(Map<String, dynamic> json) {
|
|
return LeaderboardEntry(
|
|
rank: json['rank'] as int,
|
|
userId: json['userId'] as String,
|
|
username: json['username'] as String,
|
|
avatar: json['avatar'] as String?,
|
|
score: json['score'] as int,
|
|
level: json['level'] as int,
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> toJson() {
|
|
return {
|
|
'rank': rank,
|
|
'userId': userId,
|
|
'username': username,
|
|
'avatar': avatar,
|
|
'score': score,
|
|
'level': level,
|
|
};
|
|
}
|
|
}
|
|
|
|
/// 排行榜类型
|
|
enum LeaderboardType {
|
|
/// 学习单词数
|
|
wordsLearned,
|
|
/// 连续学习天数
|
|
streak,
|
|
/// 学习时间
|
|
studyTime,
|
|
/// 测试分数
|
|
testScore,
|
|
}
|
|
|
|
/// 排行榜时间范围
|
|
enum LeaderboardPeriod {
|
|
/// 每日
|
|
daily,
|
|
/// 每周
|
|
weekly,
|
|
/// 每月
|
|
monthly,
|
|
/// 全部时间
|
|
allTime,
|
|
} |