Files
2025-11-17 14:09:17 +08:00

468 lines
14 KiB
Dart

import '../models/test_models.dart';
import '../data/test_static_data.dart';
import '../../../core/models/api_response.dart';
/// 综合测试服务类
class TestService {
// 单例模式
static final TestService _instance = TestService._internal();
factory TestService() => _instance;
TestService._internal();
/// 获取所有测试模板
Future<ApiResponse<List<TestTemplate>>> getTestTemplates() async {
try {
// 模拟网络延迟
await Future.delayed(const Duration(milliseconds: 500));
final templates = TestStaticData.getAllTemplates();
return ApiResponse.success(
data: templates,
message: '获取测试模板成功',
);
} catch (e) {
return ApiResponse.error(
message: '获取测试模板失败: ${e.toString()}',
);
}
}
/// 根据类型获取测试模板
Future<ApiResponse<List<TestTemplate>>> getTestTemplatesByType(
TestType type,
) async {
try {
await Future.delayed(const Duration(milliseconds: 300));
final templates = TestStaticData.getTemplatesByType(type);
return ApiResponse.success(
data: templates,
message: '获取${_getTestTypeName(type)}模板成功',
);
} catch (e) {
return ApiResponse.error(
message: '获取测试模板失败: ${e.toString()}',
);
}
}
/// 根据ID获取测试模板
Future<ApiResponse<TestTemplate>> getTestTemplateById(String id) async {
try {
await Future.delayed(const Duration(milliseconds: 200));
final template = TestStaticData.getTemplateById(id);
if (template == null) {
return ApiResponse.error(message: '测试模板不存在');
}
return ApiResponse.success(
data: template,
message: '获取测试模板成功',
);
} catch (e) {
return ApiResponse.error(
message: '获取测试模板失败: ${e.toString()}',
);
}
}
/// 创建测试会话
Future<ApiResponse<TestSession>> createTestSession({
required String templateId,
required String userId,
}) async {
try {
await Future.delayed(const Duration(milliseconds: 800));
final session = TestStaticData.createTestSession(
templateId: templateId,
userId: userId,
);
return ApiResponse.success(
data: session,
message: '创建测试会话成功',
);
} catch (e) {
return ApiResponse.error(
message: '创建测试会话失败: ${e.toString()}',
);
}
}
/// 开始测试
Future<ApiResponse<TestSession>> startTest(String sessionId) async {
try {
await Future.delayed(const Duration(milliseconds: 300));
// 模拟开始测试,实际应用中会更新数据库中的会话状态
// 这里返回一个模拟的已开始的会话
return ApiResponse.success(
data: TestSession(
id: sessionId,
templateId: 'template_quick',
userId: 'user_001',
status: TestStatus.inProgress,
questions: TestStaticData.getQuestionsByIds(['vocab_001', 'grammar_001']),
answers: [],
currentQuestionIndex: 0,
startTime: DateTime.now(),
timeRemaining: 900, // 15分钟
),
message: '测试已开始',
);
} catch (e) {
return ApiResponse.error(
message: '开始测试失败: ${e.toString()}',
);
}
}
/// 提交答案
Future<ApiResponse<TestSession>> submitAnswer({
required String sessionId,
required UserAnswer answer,
}) async {
try {
await Future.delayed(const Duration(milliseconds: 400));
// 模拟提交答案并返回更新后的会话
return ApiResponse.success(
data: TestSession(
id: sessionId,
templateId: 'template_quick',
userId: 'user_001',
status: TestStatus.inProgress,
questions: TestStaticData.getQuestionsByIds(['vocab_001', 'grammar_001']),
answers: [answer],
currentQuestionIndex: 1,
startTime: DateTime.now().subtract(const Duration(minutes: 5)),
timeRemaining: 600, // 剩余10分钟
),
message: '答案提交成功',
);
} catch (e) {
return ApiResponse.error(
message: '提交答案失败: ${e.toString()}',
);
}
}
/// 暂停测试
Future<ApiResponse<TestSession>> pauseTest(String sessionId) async {
try {
await Future.delayed(const Duration(milliseconds: 200));
return ApiResponse.success(
data: TestSession(
id: sessionId,
templateId: 'template_quick',
userId: 'user_001',
status: TestStatus.paused,
questions: TestStaticData.getQuestionsByIds(['vocab_001', 'grammar_001']),
answers: [],
currentQuestionIndex: 0,
startTime: DateTime.now().subtract(const Duration(minutes: 5)),
timeRemaining: 600,
),
message: '测试已暂停',
);
} catch (e) {
return ApiResponse.error(
message: '暂停测试失败: ${e.toString()}',
);
}
}
/// 恢复测试
Future<ApiResponse<TestSession>> resumeTest(String sessionId) async {
try {
await Future.delayed(const Duration(milliseconds: 200));
return ApiResponse.success(
data: TestSession(
id: sessionId,
templateId: 'template_quick',
userId: 'user_001',
status: TestStatus.inProgress,
questions: TestStaticData.getQuestionsByIds(['vocab_001', 'grammar_001']),
answers: [],
currentQuestionIndex: 0,
startTime: DateTime.now().subtract(const Duration(minutes: 5)),
timeRemaining: 600,
),
message: '测试已恢复',
);
} catch (e) {
return ApiResponse.error(
message: '恢复测试失败: ${e.toString()}',
);
}
}
/// 完成测试
Future<ApiResponse<TestResult>> completeTest({
required String sessionId,
required List<UserAnswer> answers,
}) async {
try {
await Future.delayed(const Duration(milliseconds: 1000));
// 模拟计算测试结果
final result = _calculateTestResult(sessionId, answers);
// 保存结果到静态数据
TestStaticData.addTestResult(result);
return ApiResponse.success(
data: result,
message: '测试完成,结果已保存',
);
} catch (e) {
return ApiResponse.error(
message: '完成测试失败: ${e.toString()}',
);
}
}
/// 获取用户测试历史
Future<ApiResponse<List<TestResult>>> getUserTestHistory(
String userId, {
int page = 1,
int limit = 10,
}) async {
try {
await Future.delayed(const Duration(milliseconds: 600));
final allResults = TestStaticData.getUserResults(userId);
final startIndex = (page - 1) * limit;
final endIndex = startIndex + limit;
final results = allResults.length > startIndex
? allResults.sublist(
startIndex,
endIndex > allResults.length ? allResults.length : endIndex,
)
: <TestResult>[];
return ApiResponse.success(
data: results,
message: '获取测试历史成功',
);
} catch (e) {
return ApiResponse.error(
message: '获取测试历史失败: ${e.toString()}',
);
}
}
/// 获取最近的测试结果
Future<ApiResponse<List<TestResult>>> getRecentTestResults(
String userId, {
int limit = 5,
}) async {
try {
await Future.delayed(const Duration(milliseconds: 400));
final results = TestStaticData.getRecentResults(userId, limit: limit);
return ApiResponse.success(
data: results,
message: '获取最近测试结果成功',
);
} catch (e) {
return ApiResponse.error(
message: '获取最近测试结果失败: ${e.toString()}',
);
}
}
/// 获取测试结果详情
Future<ApiResponse<TestResult>> getTestResultById(String resultId) async {
try {
await Future.delayed(const Duration(milliseconds: 300));
final result = TestStaticData.getResultById(resultId);
if (result == null) {
return ApiResponse.error(message: '测试结果不存在');
}
return ApiResponse.success(
data: result,
message: '获取测试结果成功',
);
} catch (e) {
return ApiResponse.error(
message: '获取测试结果失败: ${e.toString()}',
);
}
}
/// 获取用户技能统计
Future<ApiResponse<Map<SkillType, double>>> getUserSkillStatistics(
String userId,
) async {
try {
await Future.delayed(const Duration(milliseconds: 500));
final statistics = TestStaticData.getSkillStatistics(userId);
return ApiResponse.success(
data: statistics,
message: '获取技能统计成功',
);
} catch (e) {
return ApiResponse.error(
message: '获取技能统计失败: ${e.toString()}',
);
}
}
/// 获取题目统计
Future<ApiResponse<Map<String, dynamic>>> getQuestionStatistics() async {
try {
await Future.delayed(const Duration(milliseconds: 300));
final difficultyStats = TestStaticData.getDifficultyStatistics();
final skillStats = TestStaticData.getSkillDistributionStatistics();
return ApiResponse.success(
data: {
'difficultyDistribution': difficultyStats,
'skillDistribution': skillStats,
'totalQuestions': TestStaticData.getAllQuestions().length,
},
message: '获取题目统计成功',
);
} catch (e) {
return ApiResponse.error(
message: '获取题目统计失败: ${e.toString()}',
);
}
}
/// 删除测试结果
Future<ApiResponse<bool>> deleteTestResult(String resultId) async {
try {
await Future.delayed(const Duration(milliseconds: 300));
final success = TestStaticData.deleteTestResult(resultId);
if (success) {
return ApiResponse.success(
data: true,
message: '删除测试结果成功',
);
} else {
return ApiResponse.error(message: '测试结果不存在');
}
} catch (e) {
return ApiResponse.error(
message: '删除测试结果失败: ${e.toString()}',
);
}
}
/// 获取测试类型名称
String _getTestTypeName(TestType type) {
switch (type) {
case TestType.quick:
return '快速测试';
case TestType.standard:
return '标准测试';
case TestType.full:
return '完整测试';
case TestType.mock:
return '模拟考试';
case TestType.vocabulary:
return '词汇专项';
case TestType.grammar:
return '语法专项';
case TestType.reading:
return '阅读专项';
case TestType.listening:
return '听力专项';
case TestType.speaking:
return '口语专项';
case TestType.writing:
return '写作专项';
}
}
/// 计算测试结果(模拟)
TestResult _calculateTestResult(String sessionId, List<UserAnswer> answers) {
// 这里是一个简化的计算逻辑,实际应用中会更复杂
final totalQuestions = answers.length;
final correctAnswers = (totalQuestions * 0.8).round(); // 模拟80%正确率
final totalScore = correctAnswers;
final maxScore = totalQuestions;
final percentage = (totalScore / maxScore) * 100;
return TestResult(
id: 'result_${DateTime.now().millisecondsSinceEpoch}',
testId: 'template_quick',
userId: 'user_001',
testType: TestType.quick,
totalScore: totalScore,
maxScore: maxScore,
percentage: percentage,
overallLevel: _calculateOverallLevel(percentage),
skillScores: _calculateSkillScores(answers),
answers: answers,
startTime: DateTime.now().subtract(const Duration(minutes: 15)),
endTime: DateTime.now(),
duration: 900,
feedback: _generateFeedback(percentage),
recommendations: {
'nextLevel': 'intermediate',
'focusAreas': ['grammar', 'vocabulary'],
'suggestedStudyTime': 45,
},
);
}
/// 计算整体水平
DifficultyLevel _calculateOverallLevel(double percentage) {
if (percentage >= 90) return DifficultyLevel.advanced;
if (percentage >= 80) return DifficultyLevel.upperIntermediate;
if (percentage >= 70) return DifficultyLevel.intermediate;
if (percentage >= 60) return DifficultyLevel.elementary;
return DifficultyLevel.beginner;
}
/// 计算技能得分
List<SkillScore> _calculateSkillScores(List<UserAnswer> answers) {
// 简化的技能得分计算
return [
SkillScore(
skillType: SkillType.vocabulary,
score: 4,
maxScore: 5,
percentage: 80.0,
level: DifficultyLevel.elementary,
feedback: '词汇掌握良好',
),
SkillScore(
skillType: SkillType.grammar,
score: 3,
maxScore: 4,
percentage: 75.0,
level: DifficultyLevel.elementary,
feedback: '语法基础扎实',
),
];
}
/// 生成反馈
String _generateFeedback(double percentage) {
if (percentage >= 90) {
return '优秀!您的英语水平很高,继续保持。';
} else if (percentage >= 80) {
return '良好!您的英语基础扎实,可以尝试更高难度的内容。';
} else if (percentage >= 70) {
return '不错!您的英语水平中等,建议加强薄弱环节的练习。';
} else if (percentage >= 60) {
return '及格!您的英语基础还需要加强,建议多练习基础知识。';
} else {
return '需要努力!建议从基础开始,系统性地学习英语。';
}
}
}