diff --git a/frontend/src/features/listings/composables/__tests__/useFilterOptions.spec.ts b/frontend/src/features/listings/composables/__tests__/useFilterOptions.spec.ts
index 51dcc30..57cbeb2 100644
--- a/frontend/src/features/listings/composables/__tests__/useFilterOptions.spec.ts
+++ b/frontend/src/features/listings/composables/__tests__/useFilterOptions.spec.ts
@@ -2,10 +2,12 @@ import { describe, it, expect } from 'vitest'
import {
awmRangeOptions,
depositRangeOptions,
+ defaultRangePresets,
isRangeSelected,
moneyRangeOptions,
rangeLabel,
ratioRangeOptions,
+ secretKdRangeOptions,
} from '@/features/listings/composables/useFilterOptions'
describe('useFilterOptions', () => {
@@ -65,4 +67,32 @@ describe('useFilterOptions', () => {
max: undefined,
})
})
+
+ it('应该包含绝密KD预设选项', () => {
+ expect(secretKdRangeOptions.map(option => option.label)).toEqual([
+ '全部',
+ '1-2',
+ '2-3',
+ '3-5',
+ '5以上',
+ ])
+ })
+
+ it('defaultRangePresets 应该为移动端提供统一的日消耗与绝密KD档位', () => {
+ expect(defaultRangePresets.dailyLoss).toEqual([
+ { label: '≤10', min: '', 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: '' },
+ ])
+ expect(defaultRangePresets.secretKd).toEqual([
+ { label: '1-2', min: '1', max: '2' },
+ { label: '2-3', min: '2', max: '3' },
+ { label: '3-5', min: '3', max: '5' },
+ { label: '5以上', min: '5', max: '' },
+ ])
+ expect(defaultRangePresets.price.length).toBeGreaterThan(0)
+ expect(defaultRangePresets.coin.length).toBeGreaterThan(0)
+ })
})
diff --git a/frontend/src/features/listings/composables/__tests__/useHomeFilters.spec.ts b/frontend/src/features/listings/composables/__tests__/useHomeFilters.spec.ts
index 107ccc6..8c24642 100644
--- a/frontend/src/features/listings/composables/__tests__/useHomeFilters.spec.ts
+++ b/frontend/src/features/listings/composables/__tests__/useHomeFilters.spec.ts
@@ -1,5 +1,9 @@
import { describe, it, expect } from 'vitest'
-import { useHomeFilters } from '@/features/listings/composables/useHomeFilters'
+import {
+ useHomeFilters,
+ mobileFiltersToHomeFilters,
+} from '@/features/listings/composables/useHomeFilters'
+import { buildListingQueryFromFilters } from '@/features/listings/composables/useListingQuery'
import { ref } from 'vue'
import { emptyListingPublishOptions } from '@/features/listings/api/listingOptions'
@@ -90,4 +94,110 @@ describe('useHomeFilters', () => {
expect(filters.minCoin).toBe(100)
expect(filters.maxCoin).toBe(500)
})
+
+ it('应该支持绝密KD与日消耗并正确统计高级筛选数量', () => {
+ const publishOptions = ref(emptyListingPublishOptions)
+ const listings = ref([])
+
+ const { filters, advancedActiveCount, setDailyLossRange, setSecretKdRange, resetFilters } =
+ useHomeFilters(publishOptions, listings)
+
+ expect(advancedActiveCount.value).toBe(0)
+
+ setDailyLossRange(10, 20)
+ expect(filters.minDailyLoss).toBe(10)
+ expect(filters.maxDailyLoss).toBe(20)
+ expect(advancedActiveCount.value).toBe(1)
+
+ setSecretKdRange(2, 3)
+ expect(filters.minSecretKd).toBe(2)
+ expect(filters.maxSecretKd).toBe(3)
+ expect(advancedActiveCount.value).toBe(2)
+
+ resetFilters()
+ expect(filters.minDailyLoss).toBeUndefined()
+ expect(filters.maxDailyLoss).toBeUndefined()
+ expect(filters.minSecretKd).toBeUndefined()
+ expect(filters.maxSecretKd).toBeUndefined()
+ expect(advancedActiveCount.value).toBe(0)
+ })
+
+ describe('mobileFiltersToHomeFilters & buildListingQueryFromFilters', () => {
+ it('应该正确转换移动端结构为统一 HomeFilters 并生成对齐的查询参数', () => {
+ const selectedFilters = {
+ server: ['微信区'],
+ region: ['北京', '上海'],
+ login: ['账密'],
+ rank: ['大师'],
+ insurance: ['3*3'],
+ melee: ['小刀'],
+ }
+ const rangeFilters = {
+ price: { min: '50', max: '100' },
+ coin: { min: '100', max: '300' },
+ dailyLoss: { min: '10', max: '20' },
+ secretKd: { min: '2', max: '3' },
+ resource_awmAmmo: { min: '50', max: '100' },
+ resource_testItem: { min: '1', max: '5' },
+ }
+
+ const homeFilters = mobileFiltersToHomeFilters(selectedFilters, rangeFilters, '搜索关键字', [
+ 'melee',
+ ])
+
+ expect(homeFilters.keyword).toBe('搜索关键字')
+ expect(homeFilters.server).toBe('微信区')
+ expect(homeFilters.region).toEqual(['北京', '上海'])
+ expect(homeFilters.loginMethod).toEqual(['账密'])
+ expect(homeFilters.rank).toEqual(['大师'])
+ expect(homeFilters.insurance).toEqual(['3*3'])
+ expect(homeFilters.skinGroups).toEqual(['melee'])
+ expect(homeFilters.skinNames).toEqual(['小刀'])
+ expect(homeFilters.minPrice).toBe(50)
+ expect(homeFilters.maxPrice).toBe(100)
+ expect(homeFilters.minCoin).toBe(100)
+ expect(homeFilters.maxCoin).toBe(300)
+ expect(homeFilters.minDailyLoss).toBe(10)
+ expect(homeFilters.maxDailyLoss).toBe(20)
+ expect(homeFilters.minSecretKd).toBe(2)
+ expect(homeFilters.maxSecretKd).toBe(3)
+ expect(homeFilters.minAwmAmmo).toBe(50)
+ expect(homeFilters.maxAwmAmmo).toBe(100)
+ expect(homeFilters.resources).toEqual({ testItem: { min: 1, max: 5 } })
+
+ const query = buildListingQueryFromFilters(homeFilters, {
+ page: 1,
+ pageSize: 10,
+ sort: 'recommended',
+ zone: 'all',
+ })
+
+ expect(query).toMatchObject({
+ page: 1,
+ page_size: 10,
+ keyword: '搜索关键字',
+ sort: 'recommended',
+ zone: 'all',
+ server: '微信区',
+ region: '北京,上海',
+ login_method: '账密',
+ rank: '大师',
+ insurance: '3*3',
+ skin_group: 'melee',
+ skin_name: '小刀',
+ min_price: 50,
+ max_price: 100,
+ min_coin: 100,
+ max_coin: 300,
+ min_daily_loss: 10,
+ max_daily_loss: 20,
+ min_secret_kd: 2,
+ max_secret_kd: 3,
+ resource_awmAmmo_min: 50,
+ resource_awmAmmo_max: 100,
+ resource_testItem_min: 1,
+ resource_testItem_max: 5,
+ })
+ })
+ })
})
diff --git a/frontend/src/features/listings/composables/useFilterOptions.ts b/frontend/src/features/listings/composables/useFilterOptions.ts
index 3a2a51c..b1d6e90 100644
--- a/frontend/src/features/listings/composables/useFilterOptions.ts
+++ b/frontend/src/features/listings/composables/useFilterOptions.ts
@@ -71,6 +71,44 @@ export const dailyLossRangeOptions = [
{ label: '40以上', min: 40, max: undefined },
]
+export const secretKdRangeOptions = [
+ { label: '全部', min: undefined, max: undefined },
+ { label: '1-2', min: 1, max: 2 },
+ { label: '2-3', min: 2, max: 3 },
+ { label: '3-5', min: 3, max: 5 },
+ { label: '5以上', min: 5, max: undefined },
+]
+
+export interface RangePresetOption {
+ label: string
+ min: string
+ max: string
+}
+
+export function toRangePresets(
+ options: Array<{ label: string; min?: number; max?: number }>
+): RangePresetOption[] {
+ return options
+ .filter(option => option.label !== '全部')
+ .map(option => ({
+ label: option.label,
+ min: option.min === undefined ? '' : String(option.min),
+ max: option.max === undefined ? '' : String(option.max),
+ }))
+}
+
+export const defaultRangePresets: Record
= {
+ price: toRangePresets(moneyRangeOptions),
+ coin: toRangePresets(coinRangeOptions),
+ ratio: toRangePresets(ratioRangeOptions),
+ deposit: toRangePresets(depositRangeOptions),
+ total: toRangePresets(totalRangeOptions),
+ fireLevel: toRangePresets(fireLevelRangeOptions),
+ dailyLoss: toRangePresets(dailyLossRangeOptions),
+ secretKd: toRangePresets(secretKdRangeOptions),
+ resource_awmAmmo: toRangePresets(awmRangeOptions),
+}
+
export function rangeLabel(min: number | undefined, max: number | undefined, fallback: string) {
if (min !== undefined && max !== undefined) return `${min}-${max}`
if (min !== undefined) return `${min}+`
diff --git a/frontend/src/features/listings/composables/useHomeFilters.ts b/frontend/src/features/listings/composables/useHomeFilters.ts
index 270e0f8..7d0061b 100644
--- a/frontend/src/features/listings/composables/useHomeFilters.ts
+++ b/frontend/src/features/listings/composables/useHomeFilters.ts
@@ -55,6 +55,13 @@ export interface HomeFilters {
/** 日消耗(M/天)区间 */
minDailyLoss: number | undefined
maxDailyLoss: number | undefined
+ /** 绝密KD区间 */
+ minSecretKd?: number | undefined
+ maxSecretKd?: number | undefined
+ /** 皮肤分类列表 */
+ skinGroups?: string[] | undefined
+ /** 动态资源区间 */
+ resources?: Record | undefined
/** AWM 子弹数量区间 */
minAwmAmmo: number | undefined
maxAwmAmmo: number | undefined
@@ -66,6 +73,107 @@ export interface SkinFilterGroup {
options: string[]
}
+function parseOptionalNumber(value: string | undefined): number | undefined {
+ if (!value || value.trim() === '') return undefined
+ const num = Number(value.trim())
+ return Number.isFinite(num) ? num : undefined
+}
+
+/** 将移动端筛选抽屉的 (selectedFilters, rangeFilters) 映射为统一的 HomeFilters 模型 */
+export function mobileFiltersToHomeFilters(
+ selectedFilters: Record,
+ rangeFilters: Record,
+ keyword = '',
+ knownSkinGroupKeys: string[] = []
+): HomeFilters {
+ const isSkinGroup = (key: string) =>
+ knownSkinGroupKeys.includes(key) || key === 'melee' || key === 'operatorRed' || key === 'weapon'
+
+ const skinGroups: string[] = []
+ const skinNames: string[] = []
+ let server = ''
+ const region: string[] = []
+ const loginMethod: string[] = []
+ const rank: string[] = []
+ const insurance: string[] = []
+ const stamina: string[] = []
+ const load: string[] = []
+
+ for (const [key, values] of Object.entries(selectedFilters)) {
+ const validValues = values.map(v => v.trim()).filter(Boolean)
+ if (!validValues.length) continue
+
+ if (key === 'server') {
+ server = validValues.join(',')
+ } else if (key === 'region') {
+ region.push(...validValues)
+ } else if (key === 'login') {
+ loginMethod.push(...validValues)
+ } else if (key === 'rank') {
+ rank.push(...validValues)
+ } else if (key === 'insurance') {
+ insurance.push(...validValues)
+ } else if (key === 'stamina') {
+ stamina.push(...validValues)
+ } else if (key === 'load') {
+ load.push(...validValues)
+ } else if (isSkinGroup(key)) {
+ skinGroups.push(key)
+ skinNames.push(...validValues)
+ }
+ }
+
+ const resources: Record = {}
+ let minAwmAmmo: number | undefined
+ let maxAwmAmmo: number | undefined
+
+ for (const [key, range] of Object.entries(rangeFilters)) {
+ if (key.startsWith('resource_')) {
+ const resKey = key.replace('resource_', '')
+ const min = parseOptionalNumber(range.min)
+ const max = parseOptionalNumber(range.max)
+ if (resKey === 'awmAmmo') {
+ minAwmAmmo = min
+ maxAwmAmmo = max
+ } else if (min !== undefined || max !== undefined) {
+ resources[resKey] = { min, max }
+ }
+ }
+ }
+
+ return {
+ keyword,
+ server,
+ region,
+ loginMethod,
+ rank,
+ insurance,
+ stamina,
+ load,
+ skinNames,
+ skinGroups: skinGroups.length ? skinGroups : undefined,
+ resources: Object.keys(resources).length ? resources : undefined,
+ minCoin: parseOptionalNumber(rangeFilters.coin?.min),
+ maxCoin: parseOptionalNumber(rangeFilters.coin?.max),
+ minRatio: parseOptionalNumber(rangeFilters.ratio?.min),
+ maxRatio: parseOptionalNumber(rangeFilters.ratio?.max),
+ minPrice: parseOptionalNumber(rangeFilters.price?.min),
+ maxPrice: parseOptionalNumber(rangeFilters.price?.max),
+ minDeposit: parseOptionalNumber(rangeFilters.deposit?.min),
+ maxDeposit: parseOptionalNumber(rangeFilters.deposit?.max),
+ minTotal: parseOptionalNumber(rangeFilters.total?.min),
+ maxTotal: parseOptionalNumber(rangeFilters.total?.max),
+ minFireLevel: parseOptionalNumber(rangeFilters.fireLevel?.min),
+ maxFireLevel: parseOptionalNumber(rangeFilters.fireLevel?.max),
+ minDailyLoss: parseOptionalNumber(rangeFilters.dailyLoss?.min),
+ maxDailyLoss: parseOptionalNumber(rangeFilters.dailyLoss?.max),
+ minSecretKd: parseOptionalNumber(rangeFilters.secretKd?.min),
+ maxSecretKd: parseOptionalNumber(rangeFilters.secretKd?.max),
+ minAwmAmmo,
+ maxAwmAmmo,
+ }
+}
+
export function useHomeFilters(
publishOptions: Ref,
listings: Ref
@@ -94,6 +202,8 @@ export function useHomeFilters(
maxFireLevel: undefined,
minDailyLoss: undefined,
maxDailyLoss: undefined,
+ minSecretKd: undefined,
+ maxSecretKd: undefined,
minAwmAmmo: undefined,
maxAwmAmmo: undefined,
})
@@ -159,6 +269,7 @@ export function useHomeFilters(
if (filters.minTotal !== undefined || filters.maxTotal !== undefined) count += 1
if (filters.minFireLevel !== undefined || filters.maxFireLevel !== undefined) count += 1
if (filters.minDailyLoss !== undefined || filters.maxDailyLoss !== undefined) count += 1
+ if (filters.minSecretKd !== undefined || filters.maxSecretKd !== undefined) count += 1
return count
})
@@ -190,6 +301,8 @@ export function useHomeFilters(
filters.maxFireLevel = undefined
filters.minDailyLoss = undefined
filters.maxDailyLoss = undefined
+ filters.minSecretKd = undefined
+ filters.maxSecretKd = undefined
filters.minAwmAmmo = undefined
filters.maxAwmAmmo = undefined
}
@@ -249,6 +362,11 @@ export function useHomeFilters(
filters.maxDailyLoss = max
}
+ function setSecretKdRange(min: number | undefined, max: number | undefined) {
+ filters.minSecretKd = min
+ filters.maxSecretKd = max
+ }
+
function setAwmAmmoRange(min: number | undefined, max: number | undefined) {
filters.minAwmAmmo = min
filters.maxAwmAmmo = max
@@ -302,6 +420,7 @@ export function useHomeFilters(
setTotalRange,
setFireLevelRange,
setDailyLossRange,
+ setSecretKdRange,
setAwmAmmoRange,
toggleRange,
setFilterPopover,
diff --git a/frontend/src/features/listings/composables/useListingQuery.ts b/frontend/src/features/listings/composables/useListingQuery.ts
index 5424116..c530511 100644
--- a/frontend/src/features/listings/composables/useListingQuery.ts
+++ b/frontend/src/features/listings/composables/useListingQuery.ts
@@ -4,6 +4,65 @@ import type { HomeFilters } from './useHomeFilters'
const homePageSize = 12
+function joinCSV(values: string[] | undefined) {
+ if (!values?.length) return undefined
+ return values.filter(Boolean).join(',') || undefined
+}
+
+export function buildListingQueryFromFilters(
+ filters: HomeFilters,
+ options: {
+ page: number
+ pageSize: number
+ sort?: string
+ zone?: string
+ }
+): PublicListingQuery {
+ const query: PublicListingQuery = {
+ page: options.page,
+ page_size: options.pageSize,
+ keyword: filters.keyword?.trim() || undefined,
+ sort: options.sort,
+ zone: options.zone,
+ server: filters.server || undefined,
+ region: joinCSV(filters.region),
+ login_method: joinCSV(filters.loginMethod),
+ rank: joinCSV(filters.rank),
+ insurance: joinCSV(filters.insurance),
+ stamina: joinCSV(filters.stamina),
+ load: joinCSV(filters.load),
+ skin_group: joinCSV(filters.skinGroups),
+ skin_name: joinCSV(filters.skinNames),
+ min_coin: filters.minCoin,
+ max_coin: filters.maxCoin,
+ min_ratio: filters.minRatio,
+ max_ratio: filters.maxRatio,
+ min_price: filters.minPrice,
+ max_price: filters.maxPrice,
+ min_deposit: filters.minDeposit,
+ max_deposit: filters.maxDeposit,
+ min_total: filters.minTotal,
+ max_total: filters.maxTotal,
+ min_fire_level: filters.minFireLevel,
+ max_fire_level: filters.maxFireLevel,
+ min_daily_loss: filters.minDailyLoss,
+ max_daily_loss: filters.maxDailyLoss,
+ min_secret_kd: filters.minSecretKd,
+ max_secret_kd: filters.maxSecretKd,
+ resource_awmAmmo_min: filters.minAwmAmmo,
+ resource_awmAmmo_max: filters.maxAwmAmmo,
+ }
+
+ if (filters.resources) {
+ for (const [key, range] of Object.entries(filters.resources)) {
+ if (range.min !== undefined) query[`resource_${key}_min`] = range.min
+ if (range.max !== undefined) query[`resource_${key}_max`] = range.max
+ }
+ }
+
+ return query
+}
+
export function useListingQuery(
filters: HomeFilters,
sortBy: Ref,
@@ -18,43 +77,13 @@ export function useListingQuery(
const hasMoreListings = ref(true)
let listingRequestSeq = 0
- function joinCSV(values: string[]) {
- return values.filter(Boolean).join(',') || undefined
- }
-
function buildListingQuery(page: number): PublicListingQuery {
- return {
+ return buildListingQueryFromFilters(filters, {
page,
- page_size: homePageSize,
- keyword: filters.keyword.trim(),
+ pageSize: homePageSize,
sort: sortBy.value,
zone: activeZone.value,
- server: filters.server,
- region: joinCSV(filters.region),
- login_method: joinCSV(filters.loginMethod),
- rank: joinCSV(filters.rank),
- insurance: joinCSV(filters.insurance),
- stamina: joinCSV(filters.stamina),
- load: joinCSV(filters.load),
- // 多选皮肤名;后端 skin_name CSV 为 AND 匹配(账号需包含所有选中皮肤)
- skin_name: joinCSV(filters.skinNames),
- min_coin: filters.minCoin,
- max_coin: filters.maxCoin,
- min_ratio: filters.minRatio,
- max_ratio: filters.maxRatio,
- min_price: filters.minPrice,
- max_price: filters.maxPrice,
- min_deposit: filters.minDeposit,
- max_deposit: filters.maxDeposit,
- min_total: filters.minTotal,
- max_total: filters.maxTotal,
- min_fire_level: filters.minFireLevel,
- max_fire_level: filters.maxFireLevel,
- min_daily_loss: filters.minDailyLoss,
- max_daily_loss: filters.maxDailyLoss,
- resource_awmAmmo_min: filters.minAwmAmmo,
- resource_awmAmmo_max: filters.maxAwmAmmo,
- }
+ })
}
function listingQuerySignature() {
diff --git a/frontend/src/features/listings/views/MobileHomeView.vue b/frontend/src/features/listings/views/MobileHomeView.vue
index b23c8ce..f9c8430 100644
--- a/frontend/src/features/listings/views/MobileHomeView.vue
+++ b/frontend/src/features/listings/views/MobileHomeView.vue
@@ -40,7 +40,9 @@ import {
storeHomeQuery,
type HomeQueryValue,
} from '@/features/listings/composables/useHomeFilterQuery'
-import { depositRangeOptions } from '@/features/listings/composables/useFilterOptions'
+import { defaultRangePresets } from '@/features/listings/composables/useFilterOptions'
+import { mobileFiltersToHomeFilters } from '@/features/listings/composables/useHomeFilters'
+import { buildListingQueryFromFilters } from '@/features/listings/composables/useListingQuery'
import {
getListingChips,
getListingDisplayPrice,
@@ -139,51 +141,8 @@ const zoneOptions = [
{ key: 'highCoin', label: '高币', hint: '100M以上' },
]
-/** 押金档位直接复用首页高级筛选项,保证移动端与桌面端完全一致 */
-const depositPresets = depositRangeOptions
- .filter(option => option.label !== '全部')
- .map(option => ({
- label: option.label,
- min: option.min === undefined ? '' : String(option.min),
- max: option.max === undefined ? '' : String(option.max),
- }))
-
-const rangePresets: Record> = {
- price: [
- { label: '50-100', min: '50', max: '100' },
- { label: '100-200', min: '100', max: '200' },
- { label: '200以上', min: '200', max: '' },
- ],
- coin: [
- { label: '0-100', min: '0', max: '100' },
- { label: '100-300', min: '100', max: '300' },
- { label: '300-500', min: '300', max: '500' },
- { label: '500以上', min: '500', max: '' },
- ],
- ratio: [
- { label: '30-40', min: '30', max: '40' },
- { label: '40以上', min: '40', max: '' },
- ],
- deposit: depositPresets,
- total: [
- { label: '0-500', min: '0', max: '500' },
- { label: '500-1000', min: '500', max: '1000' },
- { label: '1000-2000', min: '1000', max: '2000' },
- { label: '2000-5000', min: '2000', max: '5000' },
- ],
- fireLevel: [
- { label: '38-50', min: '38', max: '50' },
- { label: '50-60', min: '50', max: '60' },
- { label: '60-70', min: '60', max: '70' },
- { label: '70以上', min: '70', max: '' },
- ],
- resource_awmAmmo: [
- { label: '20-50', min: '20', max: '50' },
- { label: '50-100', min: '50', max: '100' },
- { label: '100-200', min: '100', max: '200' },
- { label: '200以上', min: '200', max: '' },
- ],
-}
+/** 统一使用领域层导出的预设区间,保证与桌面端完全一致 */
+const rangePresets = defaultRangePresets
const activeSortLabel = computed(
() => sortOptions.find(option => option.key === activeSort.value)?.label || '综合排序'
@@ -279,6 +238,14 @@ const filterSections = computed(() => [
minPlaceholder: '最低',
maxPlaceholder: '最高',
},
+ {
+ key: 'dailyLoss',
+ title: '日消耗',
+ type: 'range',
+ unit: 'M/天',
+ minPlaceholder: '最低',
+ maxPlaceholder: '最高',
+ },
{
key: 'fireLevel',
title: '等级',
@@ -602,65 +569,18 @@ function clearFilters() {
}
function buildListingQuery(page: number): PublicListingQuery {
- const query: PublicListingQuery = {
+ const homeFilters = mobileFiltersToHomeFilters(
+ selectedFilters.value,
+ rangeFilters.value,
+ searchValue.value,
+ publishOptions.value.skin_groups.map(group => group.key)
+ )
+ return buildListingQueryFromFilters(homeFilters, {
page,
- page_size: mobilePageSize,
- keyword: searchValue.value.trim(),
+ pageSize: mobilePageSize,
sort: activeSort.value,
zone: activeZone.value,
- }
- const skinGroups: string[] = []
- const skinNames: string[] = []
- for (const [key, values] of Object.entries(selectedFilters.value)) {
- const value = values.filter(Boolean).join(',')
- if (!value) continue
- if (key === 'server') query.server = value
- else if (key === 'region') query.region = value
- else if (key === 'login') query.login_method = value
- else if (key === 'insurance') query.insurance = value
- else if (key === 'stamina') query.stamina = value
- else if (key === 'load') query.load = value
- else if (key === 'rank') query.rank = value
- else if (isSkinGroupKey(key)) {
- skinGroups.push(key)
- skinNames.push(...values)
- }
- }
- if (skinGroups.length) query.skin_group = skinGroups.join(',')
- if (skinNames.length) query.skin_name = skinNames.join(',')
-
- for (const [key, range] of Object.entries(rangeFilters.value)) {
- if (!range.min && !range.max) continue
- const min = parseOptionalNumber(range.min)
- const max = parseOptionalNumber(range.max)
- if (key === 'price') {
- query.min_price = min
- query.max_price = max
- } else if (key === 'coin') {
- query.min_coin = min
- query.max_coin = max
- } else if (key === 'ratio') {
- query.min_ratio = min
- query.max_ratio = max
- } else if (key === 'secretKd') {
- query.min_secret_kd = min
- query.max_secret_kd = max
- } else if (key === 'deposit') {
- query.min_deposit = min
- query.max_deposit = max
- } else if (key === 'total') {
- query.min_total = min
- query.max_total = max
- } else if (key === 'fireLevel') {
- query.min_fire_level = min
- query.max_fire_level = max
- } else if (key.startsWith('resource_')) {
- const resourceKey = key.replace('resource_', '')
- query[`resource_${resourceKey}_min`] = min
- query[`resource_${resourceKey}_max`] = max
- }
- }
- return query
+ })
}
function filterQuerySignature() {
@@ -672,12 +592,6 @@ function filterQuerySignature() {
})
}
-function parseOptionalNumber(value: string) {
- if (value === '') return undefined
- const number = Number(value)
- return Number.isFinite(number) ? number : undefined
-}
-
function applyRouteQueryToMobileState() {
const storedQuery = readStoredHomeQuery(mobileHomeFilterStorageKey)
const query = hasHomeQueryValues(route.query, mobileHomeFilterQueryKeys)
@@ -776,10 +690,6 @@ function scrollToTop() {
homeCache.saveScrollTop(0)
}
-function isSkinGroupKey(key: string) {
- return publishOptions.value.skin_groups.some(group => group.key === key)
-}
-
function parseQuantityUnit(price: string) {
const unit = price.split('/')[1]?.trim()
return unit || undefined