203 lines
6.7 KiB
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
|
|
}
|
|
}
|
|
}
|