feat(listings): PC与移动端首页新增比例排序
- 前端选项:在 PC 首页(HomeView)与移动端首页(MobileHomeView)的排序项中,在「综合推荐」后新增「比例排序」(ratioDesc) - 后端排序:在 sortPublicListings 中实现 ratioDesc/ratio,按折算比例从高到低排序,同比例按哈夫币数量降序次级平局决胜 - 自动化验证:新增 TestSortPublicListingsByRatio 单元测试,全量运行 ./scripts/check.sh 门禁(Go测试、MySQL测试、前端lint/typecheck/build)全部通过
This commit is contained in:
@@ -103,6 +103,20 @@ func sortPublicListings(items []ListingDTO, sortKey string) {
|
|||||||
return a.PriceCent > b.PriceCent
|
return a.PriceCent > b.PriceCent
|
||||||
case "coinDesc":
|
case "coinDesc":
|
||||||
return a.HafCoinAmount > b.HafCoinAmount
|
return a.HafCoinAmount > b.HafCoinAmount
|
||||||
|
case "ratioDesc", "ratio":
|
||||||
|
aRatio := ratioFromListing(a)
|
||||||
|
bRatio := ratioFromListing(b)
|
||||||
|
if aRatio != bRatio {
|
||||||
|
return aRatio > bRatio
|
||||||
|
}
|
||||||
|
return a.HafCoinAmount > b.HafCoinAmount
|
||||||
|
case "ratioAsc":
|
||||||
|
aRatio := ratioFromListing(a)
|
||||||
|
bRatio := ratioFromListing(b)
|
||||||
|
if aRatio != bRatio {
|
||||||
|
return aRatio < bRatio
|
||||||
|
}
|
||||||
|
return a.HafCoinAmount > b.HafCoinAmount
|
||||||
case "awmDesc":
|
case "awmDesc":
|
||||||
aAmmo := resourceQuantity(a.AssetSummary, "awmAmmo")
|
aAmmo := resourceQuantity(a.AssetSummary, "awmAmmo")
|
||||||
bAmmo := resourceQuantity(b.AssetSummary, "awmAmmo")
|
bAmmo := resourceQuantity(b.AssetSummary, "awmAmmo")
|
||||||
|
|||||||
@@ -178,6 +178,45 @@ func TestSortPublicListingsDefaultUsesShuffleKey(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSortPublicListingsByRatio(t *testing.T) {
|
||||||
|
items := []ListingDTO{
|
||||||
|
{
|
||||||
|
ID: 1,
|
||||||
|
HafCoinAmount: 50_000_000,
|
||||||
|
PriceCent: 5_000,
|
||||||
|
AssetSummary: map[string]any{"publish_ratio": 20.0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: 2,
|
||||||
|
HafCoinAmount: 50_000_000,
|
||||||
|
PriceCent: 2_500,
|
||||||
|
AssetSummary: map[string]any{"publish_ratio": 45.0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: 3,
|
||||||
|
HafCoinAmount: 80_000_000,
|
||||||
|
PriceCent: 3_000,
|
||||||
|
AssetSummary: map[string]any{"publish_ratio": 35.0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: 4,
|
||||||
|
HafCoinAmount: 100_000_000,
|
||||||
|
PriceCent: 4_000,
|
||||||
|
AssetSummary: map[string]any{"publish_ratio": 35.0},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
sortPublicListings(items, "ratioDesc")
|
||||||
|
|
||||||
|
// 预期顺序:ID=2 (45.0) > ID=4 (35.0, 100M 币更多) > ID=3 (35.0, 80M) > ID=1 (20.0)
|
||||||
|
expectedIDs := []uint64{2, 4, 3, 1}
|
||||||
|
for i, expected := range expectedIDs {
|
||||||
|
if items[i].ID != expected {
|
||||||
|
t.Fatalf("at index %d, expected listing %d, got %d (ratio=%.1f)", i, expected, items[i].ID, ratioFromListing(items[i]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestIsNightAvailableSummaryUsesEarlyMorningResponse(t *testing.T) {
|
func TestIsNightAvailableSummaryUsesEarlyMorningResponse(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ const publishOptions = ref<ListingPublishOptions>(emptyListingPublishOptions)
|
|||||||
const sortBy = ref('recommended')
|
const sortBy = ref('recommended')
|
||||||
const sortOptions = [
|
const sortOptions = [
|
||||||
{ value: 'recommended', label: '综合推荐' },
|
{ value: 'recommended', label: '综合推荐' },
|
||||||
|
{ value: 'ratioDesc', label: '比例排序' },
|
||||||
{ value: 'coinDesc', label: '哈夫币' },
|
{ value: 'coinDesc', label: '哈夫币' },
|
||||||
{ value: 'awmDesc', label: 'AWM数量' },
|
{ value: 'awmDesc', label: 'AWM数量' },
|
||||||
{ value: 'priceAsc', label: '价格最低' },
|
{ value: 'priceAsc', label: '价格最低' },
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ let searchDebounceTimer: ReturnType<typeof setTimeout> | null = null
|
|||||||
|
|
||||||
const sortOptions = [
|
const sortOptions = [
|
||||||
{ key: 'recommended', label: '综合推荐' },
|
{ key: 'recommended', label: '综合推荐' },
|
||||||
|
{ key: 'ratioDesc', label: '比例排序' },
|
||||||
{ key: 'coinDesc', label: '哈夫币' },
|
{ key: 'coinDesc', label: '哈夫币' },
|
||||||
{ key: 'awmDesc', label: 'AWM数量' },
|
{ key: 'awmDesc', label: 'AWM数量' },
|
||||||
{ key: 'priceAsc', label: '价格最低' },
|
{ key: 'priceAsc', label: '价格最低' },
|
||||||
|
|||||||
Reference in New Issue
Block a user