package course import ( "context" v1 "likedream-goframe/internal/api/v1" "likedream-goframe/internal/application/smartedu/model" "likedream-goframe/internal/application/smartedu/sc" db2 "likedream-goframe/internal/common/db" errors2 "likedream-goframe/internal/common/errors" "likedream-goframe/internal/ent" "likedream-goframe/internal/ent/courseentity" "likedream-goframe/internal/ent/sysuser" "likedream-goframe/internal/framework/logger" "likedream-goframe/internal/utils" "go.uber.org/zap" ) type SmartEduSCServiceV1 struct { } // List 获取四川智慧教育刷课列表 func (s SmartEduSCServiceV1) List(ctx context.Context, req *v1.SmartEduSCListReq) *utils.Response[[]*ent.CourseEntity] { user := utils.GetUserInfoFromCtx(ctx) query := db2.Global.CourseEntity.Query(). Where( courseentity.HasSysUserWith(sysuser.ID(user.ID)), courseentity.TypeEQ(courseentity.TypeSmarteduSc), ). Order(ent.Desc(courseentity.FieldCreateTime)) if req.Username != "" { query.Where(courseentity.UsernameContains(req.Username)) } if req.Status != "" { query.Where(courseentity.StatusEQ(courseentity.Status(req.Status))) } total := query.CountX(ctx) var data []*ent.CourseEntity if total > 0 { query.Limit(req.Size).Offset((req.Page - 1) * req.Size) data = query.AllX(ctx) for _, item := range data { item.Password = "" } } return utils.SuccessWithTotal[[]*ent.CourseEntity](data, total) } // QueryCourses 查询四川智慧教育课程列表 func (s SmartEduSCServiceV1) QueryCourses(ctx context.Context, req *v1.SmartEduSCQueryCourseReq) *utils.Response[[]model.Course] { login := sc.NewLogin(req.Username, req.Password) ticket := login.Login(ctx) token := login.OOSLogin(ctx, ticket) client := login.GetClient() courseService := sc.NewCourse(token, client) courses := courseService.GetCourseList(ctx) return utils.SuccessWithData[[]model.Course](courses) } // AddCourse 添加四川智慧教育刷课任务 func (s SmartEduSCServiceV1) AddCourse(ctx context.Context, req *v1.SmartEduSCAddCourseReq) *utils.Response[any] { user := utils.GetUserInfoFromCtx(ctx) // 检查是否已存在相同任务 exists := db2.Global.CourseEntity.Query(). Where( courseentity.HasSysUserWith(sysuser.ID(user.ID)), courseentity.Username(req.Username), courseentity.CourseID(req.CourseID), courseentity.TypeEQ(courseentity.TypeSmarteduSc), ). ExistX(ctx) if exists { utils.OkOrPanic(errors2.NewBusinessError(400, "该课程已存在刷课任务")) } // 登录验证并获取课程信息 login := sc.NewLogin(req.Username, req.Password) ticket := login.Login(ctx) token := login.OOSLogin(ctx, ticket) client := login.GetClient() courseService := sc.NewCourse(token, client) courseList := courseService.GetCourseList(ctx) // 验证课程是否存在 var targetCourse *model.Course for _, c := range courseList { if c.Id == req.CourseID { targetCourse = &c break } } if targetCourse == nil { utils.OkOrPanic(errors2.NewBusinessError(400, "未找到该课程")) } // 创建数据库记录 entity := db2.Global.CourseEntity.Create(). SetUserID(user.ID). SetUsername(req.Username). SetPassword(req.Password). SetType(courseentity.TypeSmarteduSc). SetCourseName(req.CourseName). SetCourseID(req.CourseID). SetNeed(courseentity.NeedTask). SetViolence(courseentity.ViolenceYes). SetNillableDesc(&req.Desc). SetStatus(courseentity.StatusDoing). SetTaskCount(0). SetSuccessCount(0). SaveX(ctx) // 开启协程执行秒刷 go s.executeStudy(context.Background(), entity.ID, req.Username, req.Password, req.CourseID) return utils.SuccessWithMsg("任务已提交,正在刷课中") } // executeStudy 执行刷课(协程中运行) func (s SmartEduSCServiceV1) executeStudy(ctx context.Context, entityID int64, username, password, courseID string) { defer func() { if r := recover(); r != nil { logger.Logger.Error("刷课执行异常", zap.Any("error", r), zap.Int64("entityID", entityID)) db2.Global.CourseEntity.UpdateOneID(entityID). SetStatus(courseentity.StatusFail). SaveX(ctx) } }() login := sc.NewLogin(username, password) ticket := login.Login(ctx) token := login.OOSLogin(ctx, ticket) client := login.GetClient() courseService := sc.NewCourse(token, client) courseList := courseService.GetCourseList(ctx) var targetCourse *model.Course for _, c := range courseList { if c.Id == courseID { targetCourse = &c break } } if targetCourse == nil { logger.Logger.Error("未找到课程", zap.String("courseID", courseID)) db2.Global.CourseEntity.UpdateOneID(entityID). SetStatus(courseentity.StatusFail). SaveX(ctx) return } chapterList := courseService.GetChapterList(ctx, courseID) taskCount := 0 successCount := 0 for _, ch := range chapterList { taskCount += len(ch.SubSection) } db2.Global.CourseEntity.UpdateOneID(entityID). SetTaskCount(taskCount). SaveX(ctx) for _, ch := range chapterList { for _, sec := range ch.SubSection { courseService.Study(ctx, *targetCourse, ch, sec) successCount++ db2.Global.CourseEntity.UpdateOneID(entityID). SetSuccessCount(successCount). SaveX(ctx) } } db2.Global.CourseEntity.UpdateOneID(entityID). SetStatus(courseentity.StatusDone). SaveX(ctx) logger.Logger.Info("刷课完成", zap.String("username", username), zap.String("courseID", courseID), zap.Int("taskCount", taskCount), zap.Int("successCount", successCount)) } // DeleteCourse 删除四川智慧教育刷课任务 func (s SmartEduSCServiceV1) DeleteCourse(ctx context.Context, req *v1.SmartEduSCDeleteReq) *utils.Response[any] { user := utils.GetUserInfoFromCtx(ctx) course := db2.Global.CourseEntity.Query(). Where( courseentity.ID(req.ID), courseentity.HasSysUserWith(sysuser.ID(user.ID)), courseentity.TypeEQ(courseentity.TypeSmarteduSc), ). OnlyX(ctx) if course == nil { utils.OkOrPanic(errors2.NewBusinessError(400, "任务不存在或无权限操作")) } db2.Global.CourseEntity.DeleteOne(course).ExecX(ctx) return utils.SuccessWithMsg("删除成功") } func NewSmartEduSCServiceV1() *SmartEduSCServiceV1 { return &SmartEduSCServiceV1{} }