232 lines
6.3 KiB
Go
232 lines
6.3 KiB
Go
package xuexitong
|
||
|
||
import (
|
||
"context"
|
||
"encoding/json"
|
||
"likedream-goframe/internal/application/xuexitong/entity"
|
||
errors2 "likedream-goframe/internal/common/errors"
|
||
"likedream-goframe/internal/framework/logger"
|
||
"net/url"
|
||
"strconv"
|
||
"time"
|
||
|
||
"github.com/avast/retry-go/v4"
|
||
"go.uber.org/zap"
|
||
)
|
||
|
||
// attachmentDetectDocument 从附件设置中检测并填充文档信息
|
||
func (c *XuexitongCourse) attachmentDetectDocument(attachment *entity.AttachmentSetting, p *entity.ChapterPoint) {
|
||
for _, att := range attachment.Attachments {
|
||
typeStr := ""
|
||
// 进行不同方案的类型值获取
|
||
if t, ok := att["type"].(string); ok {
|
||
typeStr = t
|
||
} else if property, ok := att["property"].(map[string]interface{}); ok {
|
||
if module, ok := property["module"].(string); ok {
|
||
typeStr = module
|
||
}
|
||
}
|
||
|
||
property, ok := att["property"].(map[string]interface{})
|
||
if !ok {
|
||
continue
|
||
}
|
||
|
||
// 如果未给出文档类型,先进行文档解析尝试
|
||
if typeStr == "" {
|
||
if name, ok := property["name"].(string); ok {
|
||
p.Title = name
|
||
}
|
||
if jid, ok := property["jobid"].(string); ok {
|
||
p.JobID = jid
|
||
}
|
||
if jtoken, ok := att["jtoken"].(string); ok {
|
||
p.Jtoken = jtoken
|
||
}
|
||
if isJob, ok := att["job"].(bool); ok {
|
||
p.IsJob = isJob
|
||
} else {
|
||
p.IsJob = false
|
||
}
|
||
if bookname, ok := property["bookname"].(string); ok {
|
||
p.Title = bookname
|
||
}
|
||
// 过滤匹配
|
||
objectid, _ := property["objectid"].(string)
|
||
jobid, _ := property["jobid"].(string)
|
||
if (p.ObjectID != "" && objectid == p.ObjectID) || (jobid != "" && p.JobID == jobid) {
|
||
break
|
||
}
|
||
} else if typeStr == "insertbook" || typeStr == "read" {
|
||
if jtoken, ok := att["jtoken"].(string); ok {
|
||
p.Jtoken = jtoken
|
||
}
|
||
if isJob, ok := att["job"].(bool); ok {
|
||
p.IsJob = isJob
|
||
} else {
|
||
p.IsJob = false
|
||
}
|
||
if bookname, ok := property["bookname"].(string); ok {
|
||
p.Title = bookname
|
||
}
|
||
if typeStr == "insertbook" {
|
||
p.DocumentType = "insertbook"
|
||
} else {
|
||
p.DocumentType = "read"
|
||
}
|
||
|
||
// 过滤匹配
|
||
objectid, _ := property["objectid"].(string)
|
||
jobid, _ := property["jobid"].(string)
|
||
if (p.ObjectID != "" && objectid == p.ObjectID) || (jobid != "" && p.JobID == jobid) {
|
||
break
|
||
}
|
||
} else if typeStr == "document" || typeStr == "insertdoc" {
|
||
if isJob, ok := att["job"].(bool); ok {
|
||
p.IsJob = isJob
|
||
}
|
||
objectid, _ := property["objectid"].(string)
|
||
if objectid == p.ObjectID {
|
||
if name, ok := property["name"].(string); ok {
|
||
p.Title = name
|
||
}
|
||
if jid, ok := property["jobid"].(string); ok {
|
||
p.JobID = jid
|
||
}
|
||
if jtoken, ok := att["jtoken"].(string); ok {
|
||
p.Jtoken = jtoken
|
||
}
|
||
p.DocumentType = "document"
|
||
break
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// DocumentDtoReadingReport 提交文档阅读完成
|
||
func (c *XuexitongCourse) DocumentDtoReadingReport(ctx context.Context, p *entity.PointDocumentDto) (string, error) {
|
||
params := url.Values{}
|
||
params.Add("jobid", p.JobID)
|
||
params.Add("knowledgeid", strconv.Itoa(p.KnowledgeID))
|
||
params.Add("courseid", p.CourseID)
|
||
params.Add("clazzid", p.ClassID)
|
||
params.Add("jtoken", p.Jtoken)
|
||
params.Add("_dc", strconv.FormatInt(time.Now().UnixMilli(), 10))
|
||
|
||
apiUrl := ApiDocumentReport
|
||
if p.Cpi == "insertbook" {
|
||
apiUrl = ApiDocumentBook
|
||
}
|
||
|
||
var body string
|
||
err := retry.Do(func() error {
|
||
resp, err := c.client.R().SetHeaders(map[string]string{
|
||
"User-Agent": GetUA("mobile"),
|
||
}).Get(apiUrl + "?" + params.Encode())
|
||
if err != nil {
|
||
return err
|
||
}
|
||
if resp.StatusCode() != 200 {
|
||
return errors2.NewBusinessError(resp.StatusCode(), "提交文档阅读失败")
|
||
}
|
||
body = resp.String()
|
||
return nil
|
||
}, retry.Attempts(3), retry.Delay(2*time.Second))
|
||
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
|
||
return body, nil
|
||
}
|
||
|
||
// AutoReadDocumentByPoint 自动阅读文档(使用统一的 ChapterPoint)
|
||
func (c *XuexitongCourse) AutoReadDocumentByPoint(ctx context.Context, course entity.XueXiTCourse, p *entity.ChapterPoint) error {
|
||
// 获取附件信息填充 Jtoken、IsJob 等参数
|
||
attachment, _, err := c.PageMobileChapterCard(ctx, course, p.KnowledgeID, p.CardIndex)
|
||
if err != nil {
|
||
logger.Logger.Error("获取章节卡片失败", zap.String("title", p.Title), zap.Error(err))
|
||
return err
|
||
}
|
||
|
||
if attachment != nil {
|
||
c.attachmentDetectDocument(attachment, p)
|
||
}
|
||
|
||
logger.Logger.Debug("文档参数",
|
||
zap.String("jobID", p.JobID),
|
||
zap.String("objectID", p.ObjectID),
|
||
zap.String("jtoken", p.Jtoken),
|
||
zap.Bool("isJob", p.IsJob),
|
||
zap.String("documentType", p.DocumentType))
|
||
|
||
if !p.IsJob {
|
||
logger.Logger.Info("文档不是任务点,跳过", zap.String("jobID", p.JobID), zap.String("title", p.Title))
|
||
return nil
|
||
}
|
||
|
||
logger.Logger.Info("开始刷文档",
|
||
zap.String("jobID", p.JobID),
|
||
zap.String("title", p.Title))
|
||
|
||
report, err := c.DocumentDtoReadingReportByPoint(ctx, p)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
var result map[string]interface{}
|
||
if err := json.Unmarshal([]byte(report), &result); err == nil {
|
||
if status, ok := result["status"].(bool); ok && status {
|
||
logger.Logger.Info("文档刷课完成", zap.String("jobID", p.JobID), zap.String("title", p.Title))
|
||
c.onTaskComplete()
|
||
return nil
|
||
}
|
||
if msg, ok := result["msg"].(string); ok {
|
||
logger.Logger.Warn("文档无法正常学习", zap.String("msg", msg))
|
||
}
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// DocumentDtoReadingReportByPoint 提交文档阅读完成(使用统一的 ChapterPoint)
|
||
func (c *XuexitongCourse) DocumentDtoReadingReportByPoint(ctx context.Context, p *entity.ChapterPoint) (string, error) {
|
||
formParams := map[string]string{
|
||
"jobid": p.JobID,
|
||
"knowledgeid": strconv.Itoa(p.KnowledgeID),
|
||
"courseid": p.CourseID,
|
||
"clazzid": p.ClassID,
|
||
"jtoken": p.Jtoken,
|
||
"_dc": strconv.FormatInt(time.Now().UnixMilli(), 10),
|
||
}
|
||
|
||
apiUrl := ApiDocumentReport
|
||
if p.DocumentType == "insertbook" {
|
||
apiUrl = ApiDocumentBook
|
||
} else if p.DocumentType == "read" {
|
||
apiUrl = ApiDocumentReadV2
|
||
}
|
||
// read 类型使用 document 接口
|
||
|
||
var body string
|
||
err := retry.Do(func() error {
|
||
resp, err := c.client.R().SetHeaders(map[string]string{
|
||
"User-Agent": GetUA("mobile"),
|
||
}).SetQueryParams(formParams).Get(apiUrl)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
if resp.StatusCode() != 200 {
|
||
return errors2.NewBusinessError(resp.StatusCode(), "提交文档阅读失败")
|
||
}
|
||
body = resp.String()
|
||
return nil
|
||
}, retry.Attempts(3), retry.Delay(2*time.Second))
|
||
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
|
||
return body, nil
|
||
}
|