feat: 优化 BeatLeader 和 ScoreSaber 数据查询逻辑,新增数据变更检测方法

This commit is contained in:
lixiangwuxian
2025-03-08 19:01:47 +08:00
parent fcc99efe7e
commit b0892412ce
5 changed files with 96 additions and 53 deletions

View File

@@ -2,8 +2,12 @@ package beatleader
import (
"database/sql"
"encoding/json"
"errors"
"fmt"
"io"
"log"
"net/http"
"strconv"
"time"
@@ -182,7 +186,7 @@ func (bl *blQuery) GetScore(qqId string) (reply string, err error) {
}
// 如果有新的数据,则插入
if lastDataLite.TotalPlayCount != dataLite.TotalPlayCount {
if lastDataLite.IsDiffFrom(dataLite) {
_, err = tx.NamedExec(`INSERT INTO blData (id, name, country, pp, rank, country_rank, total_score,
total_ranked_score, average_ranked_accuracy, total_play_count, ranked_play_count, replays_watched, generated_time)
VALUES (:id, :name, :country, :pp, :rank, :country_rank, :total_score,
@@ -295,23 +299,72 @@ func (bl *blQuery) GetRecentScores(count int, qqId string) ([]RecordDataLite, er
return nil, err
}
// 查询记录
var records []RecordDataLite
err = tx.Select(&records, "SELECT * FROM blRecordData WHERE bl_id = ? ORDER BY generated_time DESC LIMIT ?", blId, count)
if err != nil {
if err == sql.ErrNoRows {
return nil, errors.New("未查询到数据")
}
log.Println("查询数据出错:", err)
return nil, errors.New("查询记录失败")
}
// // 查询记录
// var records []RecordDataLite
// err = tx.Select(&records, "SELECT * FROM blRecordData WHERE bl_id = ? ORDER BY generated_time DESC LIMIT ?", blId, count)
// if err != nil {
// if err == sql.ErrNoRows {
// return nil, errors.New("未查询到数据")
// }
// log.Println("查询数据出错:", err)
// return nil, errors.New("查询记录失败")
// }
// 提交事务
err = tx.Commit()
if err != nil {
log.Print(err)
return nil, errors.New("提交事务失败")
}
// // 提交事务
// err = tx.Commit()
// if err != nil {
// log.Print(err)
// return nil, errors.New("提交事务失败")
// }
// return records, nil
//从线上获取
historyUrl := "https://api.beatleader.xyz/player/%s/scores"
fullUrl := fmt.Sprintf(historyUrl, blId)
resp, err := http.Get(fullUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var scores []ScoreData
err = json.Unmarshal(body, &scores)
if err != nil {
return nil, err
}
records := make([]RecordDataLite, 0)
for _, score := range scores {
records = append(records, RecordDataLite{
ScoreID: score.ID,
BlID: score.Player.ID,
Name: score.Player.Name,
Country: score.Player.Country,
SongName: score.Leaderboard.Song.Name,
SongSubName: score.Leaderboard.Song.SubName,
SongAuthorName: score.Leaderboard.Song.Author,
SongHash: score.Leaderboard.Song.Hash,
SongId: score.Leaderboard.Song.ID,
CoverImage: score.Leaderboard.Song.CoverImage,
DifficultyRaw: score.Leaderboard.Difficulty.DifficultyName,
PP: score.Pp,
Stars: *score.Leaderboard.Difficulty.Stars,
Weight: score.Weight,
Modifiers: score.Modifiers,
Multiplier: float64(score.ModifiedScore) / float64(score.BaseScore),
BadCuts: score.BadCuts,
Score: score.ModifiedScore,
Rank: score.Rank,
MaxScore: score.ModifiedScore,
FullCombo: score.FullCombo,
DeviceHmd: GetHMDStr(score.HMD),
DeviceControllerLeft: GetControllerStr(score.Controller),
DeviceControllerRight: GetControllerStr(score.Controller),
GeneratedTime: time.Now().Format("2006-01-02 15:04:05.999999999-07:00"),
})
}
return records, nil
}

View File

@@ -176,6 +176,7 @@ type RecordDataLite struct {
SongSubName string `json:"songSubName" db:"song_sub_name"`
SongAuthorName string `json:"songAuthorName" db:"song_author_name"`
SongHash string `json:"songHash" db:"song_hash"`
SongId string `json:"songId" db:"song_id"`
CoverImage string `json:"coverImage" db:"cover_image"`
DifficultyRaw string `json:"difficultyRaw" db:"difficulty_raw"`
Stars float64 `json:"stars" db:"stars"`
@@ -391,6 +392,15 @@ type PlayerDataLite struct {
GeneratedTime string `json:"generatedTime" db:"generated_time"`
}
func (p PlayerDataLite) IsDiffFrom(p2 PlayerDataLite) bool {
return p.TotalScore != p2.TotalScore ||
p.TotalRankedScore != p2.TotalRankedScore ||
p.AverageRankedAccuracy != p2.AverageRankedAccuracy ||
p.TotalPlayCount != p2.TotalPlayCount ||
p.RankedPlayCount != p2.RankedPlayCount ||
p.ReplaysWatched != p2.ReplaysWatched
}
func (p PlayerData) ToString() string {
formatedStr := "玩家 %s\n" +
"区域 %s\n" +