package learning import ( "context" "time" "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/flipped-aurora/gin-vue-admin/server/model/learning" learningReq "github.com/flipped-aurora/gin-vue-admin/server/model/learning/request" ) type UserLearningService struct{} // CreateUserLearning 创建用户学习记录 func (userLearningService *UserLearningService) CreateUserLearning(ctx context.Context, userLearning *learning.UserLearning) (err error) { // 检查是否已存在该用户对该课程的学习记录 var existingRecord learning.UserLearning err = global.GVA_DB.WithContext(ctx).Where("user_id = ? AND course_id = ?", userLearning.UserId, userLearning.CourseId).First(&existingRecord).Error if err == nil { // 如果已存在,更新记录 return userLearningService.UpdateUserLearning(ctx, *userLearning) } // 设置默认值 if userLearning.LastStudyAt.IsZero() { userLearning.LastStudyAt = time.Now() } if userLearning.Status == "" { userLearning.Status = "learning" } err = global.GVA_DB.WithContext(ctx).Create(userLearning).Error return err } // DeleteUserLearning 删除用户学习记录 func (userLearningService *UserLearningService) DeleteUserLearning(ctx context.Context, ID string) (err error) { err = global.GVA_DB.WithContext(ctx).Delete(&learning.UserLearning{}, ID).Error return err } // DeleteUserLearningByIds 批量删除用户学习记录 func (userLearningService *UserLearningService) DeleteUserLearningByIds(ctx context.Context, IDs []string) (err error) { err = global.GVA_DB.WithContext(ctx).Delete(&[]learning.UserLearning{}, "id in ?", IDs).Error return err } // UpdateUserLearning 更新用户学习记录 func (userLearningService *UserLearningService) UpdateUserLearning(ctx context.Context, userLearning learning.UserLearning) (err error) { // 更新最后学习时间 userLearning.LastStudyAt = time.Now() // 如果进度达到100%,设置完成状态和完成时间 if userLearning.Progress >= 100 && userLearning.Status != "completed" { userLearning.Status = "completed" userLearning.CompletedAt = time.Now() } err = global.GVA_DB.WithContext(ctx).Model(&learning.UserLearning{}).Where("id = ?", userLearning.ID).Updates(&userLearning).Error return err } // GetUserLearning 根据ID获取用户学习记录 func (userLearningService *UserLearningService) GetUserLearning(ctx context.Context, ID string) (userLearning learning.UserLearning, err error) { err = global.GVA_DB.WithContext(ctx).Where("id = ?", ID).First(&userLearning).Error if err != nil { return } // 手动查询关联信息 userLearningService.loadAssociations(ctx, &userLearning) return } // GetUserLearningInfoList 分页获取用户学习记录列表 func (userLearningService *UserLearningService) GetUserLearningInfoList(ctx context.Context, info learningReq.UserLearningSearch) (list []learning.UserLearning, total int64, err error) { limit := info.PageSize offset := info.PageSize * (info.Page - 1) // 创建db db := global.GVA_DB.WithContext(ctx).Model(&learning.UserLearning{}) var userLearnings []learning.UserLearning // 如果有条件搜索 下方会自动创建搜索语句 if info.StartCreatedAt != nil && info.EndCreatedAt != nil { db = db.Where("created_at BETWEEN ? AND ?", info.StartCreatedAt, info.EndCreatedAt) } if info.UserId != 0 { db = db.Where("user_id = ?", info.UserId) } if info.CourseId != 0 { db = db.Where("course_id = ?", info.CourseId) } if info.Status != "" { db = db.Where("status = ?", info.Status) } err = db.Count(&total).Error if err != nil { return } if limit != 0 { db = db.Limit(limit).Offset(offset) } err = db.Order("last_study_at desc").Find(&userLearnings).Error if err != nil { return userLearnings, total, err } // 批量加载关联信息 for i := range userLearnings { userLearningService.loadAssociations(ctx, &userLearnings[i]) } return userLearnings, total, err } // GetUserProgress 获取用户学习进度 func (userLearningService *UserLearningService) GetUserProgress(ctx context.Context, userId uint, courseId uint) (progress []learning.UserLearning, err error) { db := global.GVA_DB.WithContext(ctx).Where("user_id = ?", userId) if courseId != 0 { db = db.Where("course_id = ?", courseId) } err = db.Find(&progress).Error // 批量加载关联信息 for i := range progress { userLearningService.loadAssociations(ctx, &progress[i]) } return } // GetLearningStatistics 获取用户学习统计 func (userLearningService *UserLearningService) GetLearningStatistics(ctx context.Context, userId uint) (stats learningReq.LearningStatistics, err error) { // 总课程数 var totalCourses int64 err = global.GVA_DB.WithContext(ctx).Model(&learning.UserLearning{}).Where("user_id = ?", userId).Count(&totalCourses).Error if err != nil { return } stats.TotalCourses = int(totalCourses) // 已完成课程数 var completedCourses int64 err = global.GVA_DB.WithContext(ctx).Model(&learning.UserLearning{}).Where("user_id = ? AND status = ?", userId, "completed").Count(&completedCourses).Error if err != nil { return } stats.CompletedCourses = int(completedCourses) // 学习中课程数 var inProgressCourses int64 err = global.GVA_DB.WithContext(ctx).Model(&learning.UserLearning{}).Where("user_id = ? AND status = ?", userId, "learning").Count(&inProgressCourses).Error if err != nil { return } stats.InProgressCourses = int(inProgressCourses) // 总学习时长和平均分数 var result struct { TotalStudyTime int AverageScore int } err = global.GVA_DB.WithContext(ctx).Model(&learning.UserLearning{}). Select("SUM(study_time) as total_study_time, AVG(score) as average_score"). Where("user_id = ?", userId). Scan(&result).Error if err != nil { return } stats.TotalStudyTime = result.TotalStudyTime stats.AverageScore = result.AverageScore return } // loadAssociations 加载关联信息 func (userLearningService *UserLearningService) loadAssociations(ctx context.Context, userLearning *learning.UserLearning) { // 加载课程信息 if userLearning.CourseId != 0 { var course learning.Course if err := global.GVA_DB.WithContext(ctx).Where("id = ?", userLearning.CourseId).First(&course).Error; err == nil { userLearning.Course = course } } // 加载章节信息 if userLearning.ChapterId != 0 { var chapter learning.Chapter if err := global.GVA_DB.WithContext(ctx).Where("id = ?", userLearning.ChapterId).First(&chapter).Error; err == nil { userLearning.Chapter = chapter } } // 加载知识点信息 if userLearning.KnowledgePointId != 0 { var knowledgePoint learning.KnowledgePoint if err := global.GVA_DB.WithContext(ctx).Where("id = ?", userLearning.KnowledgePointId).First(&knowledgePoint).Error; err == nil { userLearning.KnowledgePoint = knowledgePoint } } }