package jobs import ( "encoding/json" "fmt" "gadmin/config" "gadmin/internal/gorm/model" "gadmin/internal/gorm/query" "os" "sync" "time" "github.com/sirupsen/logrus" ) var SyncChapter = new(jSyncChapter) type jSyncChapter struct { sync.Mutex } type chapterItem struct { Id int64 `json:"id"` UserId int64 `json:"user_id"` ChapterId int32 `json:"chapter_id"` Extra string `json:"extra"` EventAt int64 `json:"event_at"` ServerID int32 `json:"server_id"` // 服务器ID Difficulty int32 `json:"difficulty"` } // Run // 目前只统计100~103活动章节 func (j *jSyncChapter) Run() { logrus.Info("jSyncChapter Run.....") if os.Getenv("GIN_MODE") != "release" && os.Getenv("ADMIN_IS_LOCAL") != "1" { logrus.Warnf("测试环境禁止同步") return } j.Lock() defer j.Unlock() chapterIds := []int64{100, 101, 102, 103} var difficultys = []int32{0, 1, 2} for serverId := range config.GDBGroup { for _, chapterId := range chapterIds { if chapterId == 103 { j.syncChapter(serverId, chapterId, 0) continue } for _, difficulty := range difficultys { j.syncChapter(serverId, chapterId, difficulty) } } } } func (j *jSyncChapter) syncChapter(serverId int, chapterId int64, difficulty int32) { logrus.Infof("load SyncChapter:%v, difficulty:%v", chapterId, difficulty) lastSyncInfo, err := j.getLastId(serverId, chapterId, difficulty) if err != nil { logrus.Warnf("getLastId err . %v", err) return } var ( sql = "" chapterLst []chapterItem ) sql = fmt.Sprintf("SELECT id,user_id,chapter_id,extra,event_at,server_id,difficulty FROM `chapter_logs_%d` WHERE `id` > %d and server_id = %v and difficulty = %v", chapterId, lastSyncInfo.LastID, serverId, difficulty) + " AND `user_id` > 0 AND `event_id` = 11" // AND (JSON_CONTAINS(extra, '\"type\"') = 1) config.DB.Raw(sql).Scan(&chapterLst) if len(chapterLst) == 0 { logrus.Warnf("没有需要同步的章节信息") return } for _, chapter := range chapterLst { if err = j.saveChapter(chapter); err != nil { logrus.Warnf("saveChapter err :%+v", err) } } if err = j.setLastId(serverId, chapterId, difficulty, chapterLst[len(chapterLst)-1], lastSyncInfo.ID); err != nil { logrus.Warnf("setLastId err :%+v", err) } } func (j *jSyncChapter) saveChapter(data chapterItem) (err error) { var ( models model.Chapter q = query.Use(config.DB).Chapter suc int32 = 0 fail int32 = 0 t = time.Now() ) if j.playerPass(data.Extra) { suc = 1 } else { fail = 1 } if err = q.Where(q.PlayerID.Eq(data.UserId), q.ChapterID.Eq(data.ChapterId), q.Difficulty.Eq(data.Difficulty)).Scan(&models); err != nil { return err } if models.ID > 0 { if _, err = query.Use(config.DB).Chapter.Where(q.ID.Eq(models.ID)).UpdateSimple(q.ClearanceCount.Add(suc), q.FailCount.Add(fail), q.UpdatedAt.Value(t)); err != nil { return err } return nil } else { return query.Use(config.DB).Chapter.Create(&model.Chapter{ ServerID: data.ServerID, PlayerID: data.UserId, ChapterID: data.ChapterId, Difficulty: data.Difficulty, ClearanceCount: suc, FailCount: fail, CreatedAt: t, UpdatedAt: t, }) } } func (j *jSyncChapter) playerPass(extraInfo string) bool { type passType struct { Type int `json:"type"` //-1死亡结算;主动退出结算 1通关结算 } var passTypeTemp passType json.Unmarshal([]byte(extraInfo), &passTypeTemp) return passTypeTemp.Type == 1 } func (j *jSyncChapter) getLastId(serverId int, chapterId int64, difficulty int32) (res model.ChapterSync, err error) { var ( q = query.Use(config.DB).ChapterSync models model.ChapterSync ) if err = q.Where(q.ChapterID.Eq(chapterId), q.ServerID.Eq(int32(serverId)), q.Difficulty.Eq(difficulty)).Scan(&models); err != nil { return } return models, nil } func (j *jSyncChapter) setLastId(serverId int, chapterId int64, difficulty int32, data chapterItem, lastSyncInfoId int64) (err error) { var ( q = query.Use(config.DB).ChapterSync ) syncData := &model.ChapterSync{ ChapterID: chapterId, ServerID: int32(serverId), Difficulty: difficulty, LastID: data.Id, LastSyncTime: time.Unix(data.EventAt, 0), UpdatedAt: time.Now(), } if lastSyncInfoId != 0 { syncData.ID = lastSyncInfoId } if err = q.Where(q.ChapterID.Eq(chapterId), q.ServerID.Eq(int32(serverId)), q.Difficulty.Eq(difficulty)).Save(syncData); err != nil { return err } return }