dramaling-vocab-learning/backend/DramaLing.Api/Services/Domain/Learning/IFlashcardService.cs

116 lines
4.3 KiB
C#

using DramaLing.Api.Models.Entities;
using DramaLing.Api.Models.DTOs;
namespace DramaLing.Api.Services.Domain.Learning;
/// <summary>
/// 詞卡服務介面,封裝詞卡相關的業務邏輯
/// </summary>
public interface IFlashcardService
{
// 基本 CRUD 操作
Task<FlashcardDto> CreateFlashcardAsync(CreateFlashcardRequest request);
Task<FlashcardDto?> GetFlashcardAsync(Guid flashcardId, Guid userId);
Task<FlashcardDto> UpdateFlashcardAsync(Guid flashcardId, UpdateFlashcardRequest request);
Task<bool> DeleteFlashcardAsync(Guid flashcardId, Guid userId);
// 查詢操作
Task<IEnumerable<FlashcardDto>> GetUserFlashcardsAsync(Guid userId, FlashcardQueryOptions? options = null);
Task<IEnumerable<FlashcardDto>> GetDueFlashcardsAsync(Guid userId, int limit = 20);
Task<IEnumerable<FlashcardDto>> GetFlashcardsByDifficultyAsync(Guid userId, string difficultyLevel);
Task<IEnumerable<FlashcardDto>> SearchFlashcardsAsync(Guid userId, string searchTerm);
// 學習相關操作
Task<StudyRecommendations> GetStudyRecommendationsAsync(Guid userId);
Task<bool> UpdateMasteryLevelAsync(Guid flashcardId, int masteryLevel, Guid userId);
Task<bool> MarkAsReviewedAsync(Guid flashcardId, StudyResult result, Guid userId);
// 批次操作
Task<IEnumerable<FlashcardDto>> CreateFlashcardsFromAnalysisAsync(SentenceAnalysisData analysis, Guid userId);
Task<bool> BulkUpdateMasteryAsync(IEnumerable<Guid> flashcardIds, int masteryLevel, Guid userId);
// 統計功能
Task<FlashcardStats> GetFlashcardStatsAsync(Guid userId);
Task<LearningProgress> GetLearningProgressAsync(Guid userId);
}
/// <summary>
/// 詞卡查詢選項
/// </summary>
public class FlashcardQueryOptions
{
public int? Limit { get; set; }
public int? Offset { get; set; }
public string? SortBy { get; set; } = "CreatedAt";
public bool SortDescending { get; set; } = true;
public bool? IsFavorite { get; set; }
public bool? IsArchived { get; set; }
public string? DifficultyLevel { get; set; }
public Guid? CardSetId { get; set; }
}
/// <summary>
/// 學習推薦
/// </summary>
public class StudyRecommendations
{
public IEnumerable<FlashcardDto> DueCards { get; set; } = new List<FlashcardDto>();
public IEnumerable<FlashcardDto> NewCards { get; set; } = new List<FlashcardDto>();
public IEnumerable<FlashcardDto> ReviewCards { get; set; } = new List<FlashcardDto>();
public IEnumerable<FlashcardDto> ChallengingCards { get; set; } = new List<FlashcardDto>();
public int RecommendedStudyTimeMinutes { get; set; }
public string RecommendationReason { get; set; } = string.Empty;
}
/// <summary>
/// 學習結果
/// </summary>
public class StudyResult
{
public int QualityRating { get; set; } // 1-5 SM2 算法評分
public int ResponseTimeMs { get; set; }
public bool IsCorrect { get; set; }
public string? UserAnswer { get; set; }
public DateTime StudiedAt { get; set; } = DateTime.UtcNow;
}
/// <summary>
/// 詞卡統計
/// </summary>
public class FlashcardStats
{
public int TotalCards { get; set; }
public int MasteredCards { get; set; }
public int DueCards { get; set; }
public int NewCards { get; set; }
public double MasteryRate => TotalCards > 0 ? (double)MasteredCards / TotalCards : 0;
public Dictionary<string, int> DifficultyDistribution { get; set; } = new();
public TimeSpan AverageStudyTime { get; set; }
}
/// <summary>
/// 學習進度
/// </summary>
public class LearningProgress
{
public int ConsecutiveDays { get; set; }
public int TotalStudyDays { get; set; }
public int WordsLearned { get; set; }
public int WordsMastered { get; set; }
public string CurrentLevel { get; set; } = "A2";
public double ProgressToNextLevel { get; set; }
public DateTime LastStudyDate { get; set; }
public IEnumerable<DailyProgress> RecentProgress { get; set; } = new List<DailyProgress>();
}
/// <summary>
/// 每日進度
/// </summary>
public class DailyProgress
{
public DateOnly Date { get; set; }
public int CardsStudied { get; set; }
public int CorrectAnswers { get; set; }
public TimeSpan StudyTime { get; set; }
public double AccuracyRate => CardsStudied > 0 ? (double)CorrectAnswers / CardsStudied : 0;
}