feat(listing): 公共筛选新增日消耗区间(高级筛选)

This commit is contained in:
yml2213
2026-08-15 13:32:01 +08:00
parent 096121a8cd
commit 51c3f2767f
11 changed files with 65 additions and 0 deletions
+2
View File
@@ -146,6 +146,8 @@ type PublicListQuery struct {
MaxTotal *float64 MaxTotal *float64
MinFireLevel *float64 MinFireLevel *float64
MaxFireLevel *float64 MaxFireLevel *float64
MinDailyLoss *float64
MaxDailyLoss *float64
MinSecretKD *float64 MinSecretKD *float64
MaxSecretKD *float64 MaxSecretKD *float64
ResourceRanges map[string]NumberRange ResourceRanges map[string]NumberRange
@@ -114,6 +114,8 @@ func parsePublicListQuery(c *gin.Context) PublicListQuery {
MaxTotal: parseOptionalFloat(c.Query("max_total")), MaxTotal: parseOptionalFloat(c.Query("max_total")),
MinFireLevel: parseOptionalFloat(c.Query("min_fire_level")), MinFireLevel: parseOptionalFloat(c.Query("min_fire_level")),
MaxFireLevel: parseOptionalFloat(c.Query("max_fire_level")), MaxFireLevel: parseOptionalFloat(c.Query("max_fire_level")),
MinDailyLoss: parseOptionalFloat(c.Query("min_daily_loss")),
MaxDailyLoss: parseOptionalFloat(c.Query("max_daily_loss")),
MinSecretKD: parseOptionalFloat(c.Query("min_secret_kd")), MinSecretKD: parseOptionalFloat(c.Query("min_secret_kd")),
MaxSecretKD: parseOptionalFloat(c.Query("max_secret_kd")), MaxSecretKD: parseOptionalFloat(c.Query("max_secret_kd")),
ResourceRanges: parseResourceRanges(c), ResourceRanges: parseResourceRanges(c),
@@ -78,6 +78,9 @@ func matchesPublicQuery(item ListingDTO, query PublicListQuery) bool {
if !numberInRange(readSummaryNumber(item.AssetSummary["fire_level"]), NumberRange{Min: query.MinFireLevel, Max: query.MaxFireLevel}) { if !numberInRange(readSummaryNumber(item.AssetSummary["fire_level"]), NumberRange{Min: query.MinFireLevel, Max: query.MaxFireLevel}) {
return false return false
} }
if !numberInRange(readSummaryNumber(item.AssetSummary["daily_loss_m"]), NumberRange{Min: query.MinDailyLoss, Max: query.MaxDailyLoss}) {
return false
}
if !numberInRange(readSummaryNumber(item.AssetSummary["secret_kd"]), NumberRange{Min: query.MinSecretKD, Max: query.MaxSecretKD}) { if !numberInRange(readSummaryNumber(item.AssetSummary["secret_kd"]), NumberRange{Min: query.MinSecretKD, Max: query.MaxSecretKD}) {
return false return false
} }
@@ -130,6 +130,9 @@ func canListPublicWithSQL(query PublicListQuery) bool {
if query.MinFireLevel != nil || query.MaxFireLevel != nil || query.MinSecretKD != nil || query.MaxSecretKD != nil { if query.MinFireLevel != nil || query.MaxFireLevel != nil || query.MinSecretKD != nil || query.MaxSecretKD != nil {
return false return false
} }
if query.MinDailyLoss != nil || query.MaxDailyLoss != nil {
return false
}
switch query.Sort { switch query.Sort {
case "", "published", "recommended", "comprehensive", "priceAsc", "priceDesc", "coinDesc": case "", "published", "recommended", "comprehensive", "priceAsc", "priceDesc", "coinDesc":
return true return true
@@ -76,6 +76,8 @@ export interface PublicListingQuery {
max_total?: number max_total?: number
min_fire_level?: number min_fire_level?: number
max_fire_level?: number max_fire_level?: number
min_daily_loss?: number
max_daily_loss?: number
min_secret_kd?: number min_secret_kd?: number
max_secret_kd?: number max_secret_kd?: number
[key: `resource_${string}_min`]: number | undefined [key: `resource_${string}_min`]: number | undefined
@@ -10,6 +10,7 @@ import {
depositRangeOptions, depositRangeOptions,
totalRangeOptions, totalRangeOptions,
fireLevelRangeOptions, fireLevelRangeOptions,
dailyLossRangeOptions,
isRangeSelected, isRangeSelected,
} from '@/features/listings/composables/useFilterOptions' } from '@/features/listings/composables/useFilterOptions'
import type { ListingPublishOptions } from '@/features/listings/api/listingOptions' import type { ListingPublishOptions } from '@/features/listings/api/listingOptions'
@@ -69,6 +70,7 @@ function toggleRange(
| 'minDeposit' | 'minDeposit'
| 'minTotal' | 'minTotal'
| 'minFireLevel' | 'minFireLevel'
| 'minDailyLoss'
| 'minAwmAmmo', | 'minAwmAmmo',
maxKey: maxKey:
| 'maxCoin' | 'maxCoin'
@@ -77,6 +79,7 @@ function toggleRange(
| 'maxDeposit' | 'maxDeposit'
| 'maxTotal' | 'maxTotal'
| 'maxFireLevel' | 'maxFireLevel'
| 'maxDailyLoss'
| 'maxAwmAmmo', | 'maxAwmAmmo',
option: RangeOption option: RangeOption
) { ) {
@@ -97,6 +100,7 @@ function isRangeActive(
| 'minDeposit' | 'minDeposit'
| 'minTotal' | 'minTotal'
| 'minFireLevel' | 'minFireLevel'
| 'minDailyLoss'
| 'minAwmAmmo', | 'minAwmAmmo',
maxKey: maxKey:
| 'maxCoin' | 'maxCoin'
@@ -105,6 +109,7 @@ function isRangeActive(
| 'maxDeposit' | 'maxDeposit'
| 'maxTotal' | 'maxTotal'
| 'maxFireLevel' | 'maxFireLevel'
| 'maxDailyLoss'
| 'maxAwmAmmo', | 'maxAwmAmmo',
option: RangeOption option: RangeOption
) { ) {
@@ -355,6 +360,22 @@ const redSkinGroup = computed(() =>
</div> </div>
</div> </div>
<div class="filter-field">
<label>日消耗</label>
<div class="pill-row">
<button
v-for="item in dailyLossRangeOptions.filter(o => o.label !== '全部')"
:key="`daily-${item.label}`"
type="button"
class="pill-chip"
:class="{ active: isRangeActive('minDailyLoss', 'maxDailyLoss', item) }"
@click="toggleRange('minDailyLoss', 'maxDailyLoss', item)"
>
{{ item.label }}
</button>
</div>
</div>
<div class="filter-field"> <div class="filter-field">
<label>段位</label> <label>段位</label>
<div class="pill-row"> <div class="pill-row">
@@ -62,6 +62,16 @@ export const fireLevelRangeOptions = [
{ label: '50-60', min: 50, max: 60 }, { label: '50-60', min: 50, max: 60 },
] ]
/** 日消耗(M/天):发布档位为 10/20/30/40/50 */
export const dailyLossRangeOptions = [
{ label: '全部', min: undefined, max: undefined },
{ label: '≤10', min: undefined, max: 10 },
{ label: '10-20', min: 10, max: 20 },
{ label: '20-30', min: 20, max: 30 },
{ label: '30-40', min: 30, max: 40 },
{ label: '40以上', min: 40, max: undefined },
]
export function rangeLabel(min: number | undefined, max: number | undefined, fallback: string) { export function rangeLabel(min: number | undefined, max: number | undefined, fallback: string) {
if (min !== undefined && max !== undefined) return `${min}-${max}` if (min !== undefined && max !== undefined) return `${min}-${max}`
if (min !== undefined) return `${min}+` if (min !== undefined) return `${min}+`
@@ -26,6 +26,8 @@ export const desktopHomeFilterQueryKeys = [
'max_total', 'max_total',
'min_fire_level', 'min_fire_level',
'max_fire_level', 'max_fire_level',
'min_daily_loss',
'max_daily_loss',
'resource_awmAmmo_min', 'resource_awmAmmo_min',
'resource_awmAmmo_max', 'resource_awmAmmo_max',
] as const ] as const
@@ -52,6 +52,9 @@ export interface HomeFilters {
maxTotal: number | undefined maxTotal: number | undefined
minFireLevel: number | undefined minFireLevel: number | undefined
maxFireLevel: number | undefined maxFireLevel: number | undefined
/** 日消耗(M/天)区间 */
minDailyLoss: number | undefined
maxDailyLoss: number | undefined
/** AWM 子弹数量区间 */ /** AWM 子弹数量区间 */
minAwmAmmo: number | undefined minAwmAmmo: number | undefined
maxAwmAmmo: number | undefined maxAwmAmmo: number | undefined
@@ -89,6 +92,8 @@ export function useHomeFilters(
maxTotal: undefined, maxTotal: undefined,
minFireLevel: undefined, minFireLevel: undefined,
maxFireLevel: undefined, maxFireLevel: undefined,
minDailyLoss: undefined,
maxDailyLoss: undefined,
minAwmAmmo: undefined, minAwmAmmo: undefined,
maxAwmAmmo: undefined, maxAwmAmmo: undefined,
}) })
@@ -153,6 +158,7 @@ export function useHomeFilters(
if (filters.minDeposit !== undefined || filters.maxDeposit !== undefined) count += 1 if (filters.minDeposit !== undefined || filters.maxDeposit !== undefined) count += 1
if (filters.minTotal !== undefined || filters.maxTotal !== undefined) count += 1 if (filters.minTotal !== undefined || filters.maxTotal !== undefined) count += 1
if (filters.minFireLevel !== undefined || filters.maxFireLevel !== undefined) count += 1 if (filters.minFireLevel !== undefined || filters.maxFireLevel !== undefined) count += 1
if (filters.minDailyLoss !== undefined || filters.maxDailyLoss !== undefined) count += 1
return count return count
}) })
@@ -182,6 +188,8 @@ export function useHomeFilters(
filters.maxTotal = undefined filters.maxTotal = undefined
filters.minFireLevel = undefined filters.minFireLevel = undefined
filters.maxFireLevel = undefined filters.maxFireLevel = undefined
filters.minDailyLoss = undefined
filters.maxDailyLoss = undefined
filters.minAwmAmmo = undefined filters.minAwmAmmo = undefined
filters.maxAwmAmmo = undefined filters.maxAwmAmmo = undefined
} }
@@ -236,6 +244,11 @@ export function useHomeFilters(
filters.maxFireLevel = max filters.maxFireLevel = max
} }
function setDailyLossRange(min: number | undefined, max: number | undefined) {
filters.minDailyLoss = min
filters.maxDailyLoss = max
}
function setAwmAmmoRange(min: number | undefined, max: number | undefined) { function setAwmAmmoRange(min: number | undefined, max: number | undefined) {
filters.minAwmAmmo = min filters.minAwmAmmo = min
filters.maxAwmAmmo = max filters.maxAwmAmmo = max
@@ -288,6 +301,7 @@ export function useHomeFilters(
setDepositRange, setDepositRange,
setTotalRange, setTotalRange,
setFireLevelRange, setFireLevelRange,
setDailyLossRange,
setAwmAmmoRange, setAwmAmmoRange,
toggleRange, toggleRange,
setFilterPopover, setFilterPopover,
@@ -50,6 +50,8 @@ export function useListingQuery(
max_total: filters.maxTotal, max_total: filters.maxTotal,
min_fire_level: filters.minFireLevel, min_fire_level: filters.minFireLevel,
max_fire_level: filters.maxFireLevel, max_fire_level: filters.maxFireLevel,
min_daily_loss: filters.minDailyLoss,
max_daily_loss: filters.maxDailyLoss,
resource_awmAmmo_min: filters.minAwmAmmo, resource_awmAmmo_min: filters.minAwmAmmo,
resource_awmAmmo_max: filters.maxAwmAmmo, resource_awmAmmo_max: filters.maxAwmAmmo,
} }
@@ -216,6 +216,8 @@ function applyRouteQueryToHomeState() {
filters.maxTotal = readQueryNumber(query, 'max_total') filters.maxTotal = readQueryNumber(query, 'max_total')
filters.minFireLevel = readQueryNumber(query, 'min_fire_level') filters.minFireLevel = readQueryNumber(query, 'min_fire_level')
filters.maxFireLevel = readQueryNumber(query, 'max_fire_level') filters.maxFireLevel = readQueryNumber(query, 'max_fire_level')
filters.minDailyLoss = readQueryNumber(query, 'min_daily_loss')
filters.maxDailyLoss = readQueryNumber(query, 'max_daily_loss')
filters.minAwmAmmo = readQueryNumber(query, 'resource_awmAmmo_min') filters.minAwmAmmo = readQueryNumber(query, 'resource_awmAmmo_min')
filters.maxAwmAmmo = readQueryNumber(query, 'resource_awmAmmo_max') filters.maxAwmAmmo = readQueryNumber(query, 'resource_awmAmmo_max')
// 无 sort 参数即综合推荐(默认) // 无 sort 参数即综合推荐(默认)
@@ -268,6 +270,8 @@ function buildDesktopHomeQueryValues(): Record<string, HomeQueryValue> {
max_total: filters.maxTotal, max_total: filters.maxTotal,
min_fire_level: filters.minFireLevel, min_fire_level: filters.minFireLevel,
max_fire_level: filters.maxFireLevel, max_fire_level: filters.maxFireLevel,
min_daily_loss: filters.minDailyLoss,
max_daily_loss: filters.maxDailyLoss,
resource_awmAmmo_min: filters.minAwmAmmo, resource_awmAmmo_min: filters.minAwmAmmo,
resource_awmAmmo_max: filters.maxAwmAmmo, resource_awmAmmo_max: filters.maxAwmAmmo,
} }