🐛 学习通完善
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
package schedule
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/gob"
|
||||
"likedream-goframe/internal/application/xuexitong"
|
||||
"likedream-goframe/internal/common/db"
|
||||
errors2 "likedream-goframe/internal/common/errors"
|
||||
"likedream-goframe/internal/ent"
|
||||
"likedream-goframe/internal/ent/courseentity"
|
||||
"likedream-goframe/internal/framework/errors"
|
||||
"likedream-goframe/internal/utils"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/hibiken/asynq"
|
||||
"github.com/samber/oops"
|
||||
)
|
||||
|
||||
type XuexitongTaskHandler struct{}
|
||||
|
||||
func (h *XuexitongTaskHandler) ProcessTask(ctx context.Context, task *asynq.Task) (err error) {
|
||||
defer utils.Pass(&err)
|
||||
|
||||
// 解码payload
|
||||
var taskPayload XuexitongTaskPayload
|
||||
|
||||
e := gob.NewDecoder(bytes.NewReader(task.Payload())).Decode(&taskPayload)
|
||||
utils.OkOrPanic(e, oops.WithContext(ctx).With("payload", task.Payload(), "type", task.Type()).In("XuexitongTask.DecodePayload").Wrap)
|
||||
|
||||
// 查询课程信息
|
||||
targetCourse, e := db.Global.CourseEntity.Query().Where(courseentity.ID(taskPayload.CourseID)).First(ctx)
|
||||
if ent.IsNotFound(e) {
|
||||
utils.OkOrPanic(oops.WithContext(ctx).With("course_id", taskPayload.CourseID).In("XuexitongTask.ProcessTask").Wrap(e))
|
||||
}
|
||||
utils.OkOrPanic(e, oops.WithContext(ctx).With("course_id", taskPayload.CourseID).In("XuexitongTask.ProcessTask").Wrap)
|
||||
|
||||
// 检查是否暂停
|
||||
if targetCourse.Status == courseentity.StatusPause {
|
||||
g.Log().Debugf(ctx, "课程ID %d 已暂停,跳过执行", targetCourse.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 检查时间限制(非暴力模式)
|
||||
if targetCourse.Violence == courseentity.ViolenceNo {
|
||||
currentTime := time.Now()
|
||||
currentHour := currentTime.Hour()
|
||||
currentMinute := currentTime.Minute()
|
||||
|
||||
// 只在 8:30-17:30 之间执行
|
||||
startTime := 8*60 + 30 // 8:30
|
||||
endTime := 17*60 + 30 // 17:30
|
||||
currentMinutes := currentHour*60 + currentMinute
|
||||
|
||||
if currentMinutes < startTime || currentMinutes >= endTime {
|
||||
g.Log().Debugf(ctx, "课程ID %d 非暴力模式,当前时间 %02d:%02d 不在执行时间范围内(8:30-17:30),跳过执行",
|
||||
targetCourse.ID, currentHour, currentMinute)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// 更新状态为执行中
|
||||
db.Global.CourseEntity.UpdateOneID(taskPayload.CourseID).SetStatus(courseentity.StatusDoing).ExecX(ctx)
|
||||
|
||||
defer utils.HandleError(func(err error) {
|
||||
// 执行失败更新状态
|
||||
e := db.Global.CourseEntity.UpdateOneID(taskPayload.CourseID).SetStatus(courseentity.StatusFail).Exec(ctx)
|
||||
utils.LogError(ctx, "设置课程状态失败", oops.With("course_id", taskPayload.CourseID).Wrap(e))
|
||||
|
||||
var errorMessage string
|
||||
if e1, ok := utils.Of[*errors.BusinessError](err); ok {
|
||||
errorMessage = e1.Message()
|
||||
} else if e1, ok := utils.Of[*errors2.BusinessError](err); ok {
|
||||
errorMessage = e1.Message
|
||||
} else {
|
||||
errorMessage = "未知的错误导致任务执行失败: " + err.Error()
|
||||
}
|
||||
|
||||
g.Log().Errorf(ctx, "学习通刷课失败 - 课程: %s, 错误: %s", targetCourse.CourseName, errorMessage)
|
||||
panic(err)
|
||||
})
|
||||
|
||||
// 创建学习通登录客户端
|
||||
loginClient := xuexitong.NewXuexitongLogin(ctx)
|
||||
|
||||
// 登录学习通
|
||||
err = loginClient.Login(ctx, targetCourse.Username, targetCourse.Password, 3)
|
||||
if err != nil {
|
||||
utils.OkOrPanic(errors.NewBusinessErrorWithDetail(400, "登录失败,请检查账号密码", err))
|
||||
}
|
||||
|
||||
// 获取客户端
|
||||
client := loginClient.GetClient()
|
||||
|
||||
// 创建课程服务
|
||||
courseService := xuexitong.NewXuexitongCourse(client)
|
||||
|
||||
// 执行刷课
|
||||
err = courseService.AutoStudyByCourseID(ctx, targetCourse.CourseID)
|
||||
if err != nil {
|
||||
utils.OkOrPanic(errors.NewBusinessErrorWithDetail(503, "刷课失败", err))
|
||||
}
|
||||
|
||||
// 刷课完成后,统计任务情况
|
||||
g.Log().Infof(ctx, "刷课完成,正在统计任务情况...")
|
||||
|
||||
// 获取章节列表
|
||||
chapters := courseService.PullCourseChapterList(ctx, targetCourse.CourseID)
|
||||
|
||||
// 统计总任务数(累加所有章节的JobCount)
|
||||
totalTasks := 0
|
||||
for _, chapter := range chapters {
|
||||
totalTasks += chapter.JobCount
|
||||
}
|
||||
|
||||
g.Log().Infof(ctx, "课程 %s 统计完成: 总任务点 %d", targetCourse.CourseName, totalTasks)
|
||||
|
||||
// 更新数据库(暂时不统计完成数,只统计总数)
|
||||
db.Global.CourseEntity.UpdateOneID(taskPayload.CourseID).
|
||||
SetStatus(courseentity.StatusDone).
|
||||
SetTaskCount(totalTasks).
|
||||
ExecX(ctx)
|
||||
|
||||
g.Log().Infof(ctx, "学习通刷课完成 - 课程: %s", targetCourse.CourseName)
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user