mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-28 03:06:38 +08:00
bug处理
This commit is contained in:
@@ -89,7 +89,7 @@ func listLibrarySeriesHandler(svc *service.Container) gin.HandlerFunc {
|
||||
writeInternalOrCanceled(c, err)
|
||||
return
|
||||
}
|
||||
cards = service.SortSeriesCards(cards, sortSpec.Field, sortSpec.Order, history)
|
||||
cards = sortRemoteSeriesCards(cards, sortSpec, history)
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
size, _ := strconv.Atoi(c.DefaultQuery("page_size", "500"))
|
||||
if page < 1 {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"github.com/truewhile/MeBox/internal/service"
|
||||
)
|
||||
|
||||
// sortRemoteSeriesCards keeps the DateLastContentAdded order returned by the
|
||||
// remote Emby server when LastAddedAt is not exposed in the Series DTO.
|
||||
func sortRemoteSeriesCards(cards []service.SeriesCard, spec service.MediaSortSpec, history map[string]time.Time) []service.SeriesCard {
|
||||
if spec.Field != "updated_at" {
|
||||
return service.SortSeriesCards(cards, spec.Field, spec.Order, history)
|
||||
}
|
||||
|
||||
out := append([]service.SeriesCard(nil), cards...)
|
||||
// RemoteSeriesCards always fetches DateLastContentAdded in descending order.
|
||||
if spec.Order == "asc" {
|
||||
slices.Reverse(out)
|
||||
}
|
||||
return service.SortSeriesCards(out, spec.Field, spec.Order, history)
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/truewhile/MeBox/internal/service"
|
||||
)
|
||||
|
||||
func TestSortRemoteSeriesCardsUpdatedAtUsesRemoteOrder(t *testing.T) {
|
||||
cards := []service.SeriesCard{{Key: "newest"}, {Key: "middle"}, {Key: "oldest"}}
|
||||
|
||||
desc := sortRemoteSeriesCards(cards, service.MediaSortSpec{Field: "updated_at", Order: "desc"}, nil)
|
||||
if desc[0].Key != "newest" || desc[1].Key != "middle" || desc[2].Key != "oldest" {
|
||||
t.Fatalf("descending order = %q, %q, %q", desc[0].Key, desc[1].Key, desc[2].Key)
|
||||
}
|
||||
|
||||
asc := sortRemoteSeriesCards(cards, service.MediaSortSpec{Field: "updated_at", Order: "asc"}, nil)
|
||||
if asc[0].Key != "oldest" || asc[1].Key != "middle" || asc[2].Key != "newest" {
|
||||
t.Fatalf("ascending order = %q, %q, %q", asc[0].Key, asc[1].Key, asc[2].Key)
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,9 @@ func SortSeriesCards(cards []SeriesCard, field, order string, history map[string
|
||||
}
|
||||
sort.SliceStable(out, func(i, j int) bool {
|
||||
cmp := compareSeriesByField(out[i], out[j], spec, history)
|
||||
if cmp == 0 {
|
||||
// updated_at 表示最后一集添加日期。远程卡片可能没有该字段,此时
|
||||
// 保持调用方给定的顺序,不要用 ID 再次打乱。
|
||||
if cmp == 0 && spec.Field != "updated_at" {
|
||||
cmp = compareID(out[i].Key, out[j].Key)
|
||||
}
|
||||
return cmp < 0
|
||||
@@ -173,7 +175,7 @@ func seriesUpdatedTime(card SeriesCard) (time.Time, bool) {
|
||||
if card.LastAddedAt != nil && !card.LastAddedAt.IsZero() {
|
||||
return *card.LastAddedAt, true
|
||||
}
|
||||
return mediaUpdatedTime(card.Rep)
|
||||
return time.Time{}, false
|
||||
}
|
||||
|
||||
func seriesLastPlayed(card SeriesCard, history map[string]time.Time) (time.Time, bool) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package service
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/truewhile/MeBox/internal/model"
|
||||
)
|
||||
@@ -40,3 +41,45 @@ func TestSortSeriesCardsTitleAsc(t *testing.T) {
|
||||
t.Fatalf("series order = %q, %q", got[0].Key, got[1].Key)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSortSeriesCardsUpdatedAtDoesNotFallbackToMediaDate(t *testing.T) {
|
||||
olderMediaDate := time.Date(2023, time.January, 1, 0, 0, 0, 0, time.UTC)
|
||||
newerMediaDate := time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC)
|
||||
cards := []SeriesCard{
|
||||
{
|
||||
Key: "remote-first",
|
||||
Rep: model.Media{Base: model.Base{
|
||||
ID: "remote-first",
|
||||
CreatedAt: olderMediaDate,
|
||||
UpdatedAt: olderMediaDate,
|
||||
}},
|
||||
},
|
||||
{
|
||||
Key: "remote-second",
|
||||
Rep: model.Media{Base: model.Base{
|
||||
ID: "remote-second",
|
||||
CreatedAt: newerMediaDate,
|
||||
UpdatedAt: newerMediaDate,
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
got := SortSeriesCards(cards, "updated_at", "desc", nil)
|
||||
if got[0].Key != "remote-first" || got[1].Key != "remote-second" {
|
||||
t.Fatalf("series order = %q, %q, want remote-provided order", got[0].Key, got[1].Key)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSortSeriesCardsUpdatedAtSortsKnownLastEpisodeDates(t *testing.T) {
|
||||
older := time.Date(2024, time.January, 1, 0, 0, 0, 0, time.UTC)
|
||||
newer := time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC)
|
||||
cards := []SeriesCard{
|
||||
{Key: "older", LastAddedAt: &older},
|
||||
{Key: "newer", LastAddedAt: &newer},
|
||||
}
|
||||
|
||||
got := SortSeriesCards(cards, "updated_at", "desc", nil)
|
||||
if got[0].Key != "newer" || got[1].Key != "older" {
|
||||
t.Fatalf("series order = %q, %q", got[0].Key, got[1].Key)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,7 +460,7 @@ export function groupSeries(items: Media[] = []): SeriesCard[] {
|
||||
? compactSeriesKey(externalKey)
|
||||
: getSeriesKey(m)
|
||||
|
||||
const mAddedAt = m.created_at || m.updated_at || ''
|
||||
const mAddedAt = m.updated_at || m.created_at || ''
|
||||
const g = groups.get(key)
|
||||
if (!g) {
|
||||
groups.set(key, { key, rep: m, linkMedia: m, count: 1, last_added_at: mAddedAt })
|
||||
|
||||
@@ -114,7 +114,7 @@ export function sortMediaList(
|
||||
case 'created_at':
|
||||
return compareDates(a.created_at, b.created_at, order) || compareStrings(a.title, b.title, 'asc')
|
||||
case 'updated_at':
|
||||
return compareDates(a.created_at || a.updated_at, b.created_at || b.updated_at, order) || compareStrings(a.title, b.title, 'asc')
|
||||
return compareDates(a.updated_at || a.created_at, b.updated_at || b.created_at, order) || compareStrings(a.title, b.title, 'asc')
|
||||
case 'rating':
|
||||
case 'imdb_rating': {
|
||||
const cmp = compareNumbers(a.rating || 0, b.rating || 0, order)
|
||||
|
||||
Reference in New Issue
Block a user