feat(listing): 公共筛选新增日消耗区间(高级筛选)
This commit is contained in:
@@ -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,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user