From 180a21c048469537f3b2cb4db646bf1bb987a6a3 Mon Sep 17 00:00:00 2001 From: yml2213 Date: Sat, 10 Oct 2026 17:26:28 +0800 Subject: [PATCH] =?UTF-8?q?feat(listings):=20PC=E4=B8=8E=E7=A7=BB=E5=8A=A8?= =?UTF-8?q?=E7=AB=AF=E9=A6=96=E9=A1=B5=E6=96=B0=E5=A2=9E=E6=AF=94=E4=BE=8B?= =?UTF-8?q?=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 前端选项:在 PC 首页(HomeView)与移动端首页(MobileHomeView)的排序项中,在「综合推荐」后新增「比例排序」(ratioDesc) - 后端排序:在 sortPublicListings 中实现 ratioDesc/ratio,按折算比例从高到低排序,同比例按哈夫币数量降序次级平局决胜 - 自动化验证:新增 TestSortPublicListingsByRatio 单元测试,全量运行 ./scripts/check.sh 门禁(Go测试、MySQL测试、前端lint/typecheck/build)全部通过 --- .../internal/modules/listing/public_filter.go | 14 +++++++ .../modules/listing/public_filter_test.go | 39 +++++++++++++++++++ .../src/features/listings/views/HomeView.vue | 1 + .../listings/views/MobileHomeView.vue | 1 + 4 files changed, 55 insertions(+) diff --git a/backend/internal/modules/listing/public_filter.go b/backend/internal/modules/listing/public_filter.go index 2a0647a..6e54758 100644 --- a/backend/internal/modules/listing/public_filter.go +++ b/backend/internal/modules/listing/public_filter.go @@ -103,6 +103,20 @@ func sortPublicListings(items []ListingDTO, sortKey string) { return a.PriceCent > b.PriceCent case "coinDesc": 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": aAmmo := resourceQuantity(a.AssetSummary, "awmAmmo") bAmmo := resourceQuantity(b.AssetSummary, "awmAmmo") diff --git a/backend/internal/modules/listing/public_filter_test.go b/backend/internal/modules/listing/public_filter_test.go index bf8e9bb..10ee653 100644 --- a/backend/internal/modules/listing/public_filter_test.go +++ b/backend/internal/modules/listing/public_filter_test.go @@ -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) { tests := []struct { name string diff --git a/frontend/src/features/listings/views/HomeView.vue b/frontend/src/features/listings/views/HomeView.vue index ac83f3c..511a065 100644 --- a/frontend/src/features/listings/views/HomeView.vue +++ b/frontend/src/features/listings/views/HomeView.vue @@ -72,6 +72,7 @@ const publishOptions = ref(emptyListingPublishOptions) const sortBy = ref('recommended') const sortOptions = [ { value: 'recommended', label: '综合推荐' }, + { value: 'ratioDesc', label: '比例排序' }, { value: 'coinDesc', label: '哈夫币' }, { value: 'awmDesc', label: 'AWM数量' }, { value: 'priceAsc', label: '价格最低' }, diff --git a/frontend/src/features/listings/views/MobileHomeView.vue b/frontend/src/features/listings/views/MobileHomeView.vue index bf50d99..87cc50d 100644 --- a/frontend/src/features/listings/views/MobileHomeView.vue +++ b/frontend/src/features/listings/views/MobileHomeView.vue @@ -125,6 +125,7 @@ let searchDebounceTimer: ReturnType | null = null const sortOptions = [ { key: 'recommended', label: '综合推荐' }, + { key: 'ratioDesc', label: '比例排序' }, { key: 'coinDesc', label: '哈夫币' }, { key: 'awmDesc', label: 'AWM数量' }, { key: 'priceAsc', label: '价格最低' },