Study/server/service/learning/user_learning.go

203 lines
6.7 KiB
Go

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
}
}
}