添加商品管理资产皮肤筛选
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
package listing
|
||||
|
||||
func hasAdminAssetFilters(query AdminListQuery) bool {
|
||||
return len(query.Insurance) > 0 ||
|
||||
len(query.Stamina) > 0 ||
|
||||
len(query.Load) > 0 ||
|
||||
len(query.SkinGroup) > 0 ||
|
||||
len(query.SkinName) > 0
|
||||
}
|
||||
|
||||
func filterAdminListings(items []ListingDTO, query AdminListQuery) []ListingDTO {
|
||||
if !hasAdminAssetFilters(query) {
|
||||
return items
|
||||
}
|
||||
filtered := make([]ListingDTO, 0, len(items))
|
||||
for _, item := range items {
|
||||
if !matchesAdminAssetQuery(item, query) {
|
||||
continue
|
||||
}
|
||||
filtered = append(filtered, item)
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
func matchesAdminAssetQuery(item ListingDTO, query AdminListQuery) bool {
|
||||
if !matchesAny(query.Insurance, readAssetString(item.AssetSummary, "season_insurance")) {
|
||||
return false
|
||||
}
|
||||
if !matchesAny(query.Stamina, readAssetString(item.AssetSummary, "stamina_level")) {
|
||||
return false
|
||||
}
|
||||
if !matchesAny(query.Load, readAssetString(item.AssetSummary, "load_level")) {
|
||||
return false
|
||||
}
|
||||
if len(query.SkinName) > 0 {
|
||||
if len(query.SkinGroup) > 0 {
|
||||
return skinGroupsContainAny(item.AssetSummary, query.SkinGroup, query.SkinName)
|
||||
}
|
||||
return intersects(query.SkinName, skinNamesFromSummary(item.AssetSummary))
|
||||
}
|
||||
if len(query.SkinGroup) > 0 {
|
||||
return skinGroupsHaveAny(item.AssetSummary, query.SkinGroup)
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package listing
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestFilterAdminListingsByAssetLevels(t *testing.T) {
|
||||
items := []ListingDTO{
|
||||
{
|
||||
ID: 1,
|
||||
AssetSummary: map[string]any{
|
||||
"season_insurance": "3*3",
|
||||
"stamina_level": "7级",
|
||||
"load_level": "7级",
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
AssetSummary: map[string]any{
|
||||
"season_insurance": "2*3",
|
||||
"stamina_level": "7级",
|
||||
"load_level": "6级",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
filtered := filterAdminListings(items, AdminListQuery{
|
||||
Insurance: []string{"3*3"},
|
||||
Stamina: []string{"7级"},
|
||||
Load: []string{"7级"},
|
||||
})
|
||||
|
||||
if len(filtered) != 1 || filtered[0].ID != 1 {
|
||||
t.Fatalf("expected only listing 1 in 9/7/7 asset filter, got %#v", filtered)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterAdminListingsBySkinGroupAndName(t *testing.T) {
|
||||
items := []ListingDTO{
|
||||
{
|
||||
ID: 1,
|
||||
AssetSummary: map[string]any{
|
||||
"skin_groups": map[string]any{
|
||||
"operatorRed": []any{"凌霄成卫"},
|
||||
"weapon": []any{"K416命运"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
AssetSummary: map[string]any{
|
||||
"skin_groups": map[string]any{
|
||||
"operatorGold": []any{"露娜-金牌射手"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
filtered := filterAdminListings(items, AdminListQuery{
|
||||
SkinGroup: []string{"operatorRed"},
|
||||
SkinName: []string{"凌霄成卫"},
|
||||
})
|
||||
|
||||
if len(filtered) != 1 || filtered[0].ID != 1 {
|
||||
t.Fatalf("expected only listing 1 by red skin name, got %#v", filtered)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterAdminListingsBySkinGroupOnly(t *testing.T) {
|
||||
items := []ListingDTO{
|
||||
{
|
||||
ID: 1,
|
||||
AssetSummary: map[string]any{
|
||||
"skin_groups": map[string]any{
|
||||
"operatorRed": []any{"凌霄成卫"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
AssetSummary: map[string]any{
|
||||
"skin_groups": map[string]any{
|
||||
"operatorGold": []any{"露娜-金牌射手"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
filtered := filterAdminListings(items, AdminListQuery{
|
||||
SkinGroup: []string{"operatorGold"},
|
||||
})
|
||||
|
||||
if len(filtered) != 1 || filtered[0].ID != 2 {
|
||||
t.Fatalf("expected only listing 2 by gold skin group, got %#v", filtered)
|
||||
}
|
||||
}
|
||||
@@ -76,6 +76,11 @@ type AdminListQuery struct {
|
||||
Keyword string
|
||||
Status string
|
||||
ReviewStatus string
|
||||
Insurance []string
|
||||
Stamina []string
|
||||
Load []string
|
||||
SkinGroup []string
|
||||
SkinName []string
|
||||
Limit int
|
||||
Page int
|
||||
PageSize int
|
||||
|
||||
@@ -74,6 +74,11 @@ func parseAdminListQuery(c *gin.Context) (AdminListQuery, bool) {
|
||||
query.Keyword = strings.TrimSpace(c.Query("keyword"))
|
||||
query.Status = c.Query("status")
|
||||
query.ReviewStatus = c.Query("review_status")
|
||||
query.Insurance = parseCSVQuery(c.Query("insurance"))
|
||||
query.Stamina = parseCSVQuery(c.Query("stamina"))
|
||||
query.Load = parseCSVQuery(c.Query("load"))
|
||||
query.SkinGroup = parseCSVQuery(c.Query("skin_group"))
|
||||
query.SkinName = parseCSVQuery(firstNonEmpty(c.Query("skin_name"), c.Query("skin")))
|
||||
return query, true
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,37 @@ func (r *Repository) ListAdmin(ctx context.Context, query AdminListQuery) (*Admi
|
||||
pageSize = 100
|
||||
}
|
||||
|
||||
if hasAdminAssetFilters(query) {
|
||||
var rows []listingRow
|
||||
err := r.applyAdminListFilters(r.baseQuery(ctx), query).
|
||||
Order("l.id DESC").
|
||||
Scan(&rows).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items := filterAdminListings(rowsToDTO(rows), query)
|
||||
total := int64(len(items))
|
||||
start := (page - 1) * pageSize
|
||||
if start < 0 {
|
||||
start = 0
|
||||
}
|
||||
if start >= len(items) {
|
||||
items = []ListingDTO{}
|
||||
} else {
|
||||
end := start + pageSize
|
||||
if end > len(items) {
|
||||
end = len(items)
|
||||
}
|
||||
items = items[start:end]
|
||||
}
|
||||
return &AdminListResult{
|
||||
Items: items,
|
||||
Total: total,
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
}, nil
|
||||
}
|
||||
|
||||
countDB := r.applyAdminListFilters(r.db.WithContext(ctx).Table("rental_listings AS l"), query)
|
||||
var total int64
|
||||
if err := countDB.Count(&total).Error; err != nil {
|
||||
|
||||
Reference in New Issue
Block a user