83 lines
2.5 KiB
C#
83 lines
2.5 KiB
C#
namespace DramaLing.Api.Services;
|
||
|
||
/// <summary>
|
||
/// 測驗模式選擇服務介面
|
||
/// </summary>
|
||
public interface IReviewModeSelector
|
||
{
|
||
List<string> GetPlannedTests(string userCEFRLevel, string wordCEFRLevel);
|
||
string GetNextTestType(List<string> plannedTests, List<string> completedTestTypes);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 測驗模式選擇服務實現
|
||
/// </summary>
|
||
public class ReviewModeSelector : IReviewModeSelector
|
||
{
|
||
private readonly ILogger<ReviewModeSelector> _logger;
|
||
|
||
public ReviewModeSelector(ILogger<ReviewModeSelector> logger)
|
||
{
|
||
_logger = logger;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根據CEFR等級獲取預定的測驗類型列表
|
||
/// </summary>
|
||
public List<string> GetPlannedTests(string userCEFRLevel, string wordCEFRLevel)
|
||
{
|
||
var userLevel = GetCEFRLevel(userCEFRLevel);
|
||
var wordLevel = GetCEFRLevel(wordCEFRLevel);
|
||
var difficulty = wordLevel - userLevel;
|
||
|
||
_logger.LogDebug("Planning tests for user {UserCEFR} vs word {WordCEFR}, difficulty: {Difficulty}",
|
||
userCEFRLevel, wordCEFRLevel, difficulty);
|
||
|
||
if (userCEFRLevel == "A1")
|
||
{
|
||
// A1學習者:基礎保護機制
|
||
return new List<string> { "flip-memory", "vocab-choice", "vocab-listening" };
|
||
}
|
||
else if (difficulty < -10)
|
||
{
|
||
// 簡單詞彙:應用練習
|
||
return new List<string> { "sentence-fill", "sentence-reorder" };
|
||
}
|
||
else if (difficulty >= -10 && difficulty <= 10)
|
||
{
|
||
// 適中詞彙:全方位練習
|
||
return new List<string> { "sentence-fill", "sentence-reorder", "sentence-speaking" };
|
||
}
|
||
else
|
||
{
|
||
// 困難詞彙:基礎重建
|
||
return new List<string> { "flip-memory", "vocab-choice" };
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 獲取下一個測驗類型
|
||
/// </summary>
|
||
public string GetNextTestType(List<string> plannedTests, List<string> completedTestTypes)
|
||
{
|
||
var nextTest = plannedTests.FirstOrDefault(test => !completedTestTypes.Contains(test));
|
||
return nextTest ?? string.Empty;
|
||
}
|
||
|
||
/// <summary>
|
||
/// CEFR等級轉換為數值
|
||
/// </summary>
|
||
private int GetCEFRLevel(string cefrLevel)
|
||
{
|
||
return cefrLevel switch
|
||
{
|
||
"A1" => 20,
|
||
"A2" => 35,
|
||
"B1" => 50,
|
||
"B2" => 65,
|
||
"C1" => 80,
|
||
"C2" => 95,
|
||
_ => 50 // 預設B1
|
||
};
|
||
}
|
||
} |