增加awm数量

This commit is contained in:
yml
2026-06-02 08:49:27 +08:00
parent 4509b22af7
commit a094901b72
3 changed files with 145 additions and 32 deletions
@@ -59,6 +59,7 @@ const supportLoading = ref(false);
const sortOptions = [
{ key: "comprehensive", label: "综合排序" },
{ key: "published", label: "发布时间" },
{ key: "awmDesc", label: "AWM数量" },
{ key: "priceAsc", label: "价格最低" },
{ key: "priceDesc", label: "价格最高" },
];
@@ -251,6 +252,13 @@ function sortListings(items: Listing[]) {
(a, b) => getListingDisplayPrice(b) - getListingDisplayPrice(a)
);
}
if (activeSort.value === "awmDesc") {
return sorted.sort(
(a, b) =>
getResourceQuantity(b, "awmAmmo") - getResourceQuantity(a, "awmAmmo") ||
getCoinWan(b) - getCoinWan(a)
);
}
return sorted.sort((a, b) => {
const bTime = Date.parse(b.published_at || b.created_at || "") || 0;
const aTime = Date.parse(a.published_at || a.created_at || "") || 0;
+129 -32
View File
@@ -69,6 +69,35 @@ const filters = reactive({
});
const sortBy = ref("recommended");
const activeZone = ref("all");
type FilterPopoverKey =
| "insurance"
| "stamina"
| "load"
| "region"
| "coin"
| "price"
| "deposit"
| "total"
| "skin"
| "rank"
| "fireLevel"
| "loginMethod";
type StringFilterKey =
| "insurance"
| "stamina"
| "load"
| "region"
| "rank"
| "loginMethod";
const activeFilterPopover = ref<FilterPopoverKey | "">("");
const filterPopoverBaseProps = {
placement: "bottom-start",
popperClass: "home-filter-popover",
trigger: "click",
showAfter: 0,
hideAfter: 0,
transition: "none",
} as const;
const coinRangeOptions = [
{ label: "全部区间", min: undefined, max: undefined },
@@ -189,6 +218,12 @@ const visibleListings = computed(() => {
if (sortBy.value === "coinDesc") {
return getCoinWan(b) - getCoinWan(a);
}
if (sortBy.value === "awmDesc") {
return (
getResourceQuantity(b, "awmAmmo") - getResourceQuantity(a, "awmAmmo") ||
getCoinWan(b) - getCoinWan(a)
);
}
const bTime = Date.parse(b.published_at || b.created_at || "") || 0;
const aTime = Date.parse(a.published_at || a.created_at || "") || 0;
return getCoinWan(b) - getCoinWan(a) || bTime - aTime;
@@ -293,6 +328,7 @@ function resetFilters() {
filters.maxFireLevel = undefined;
activeZone.value = "all";
sortBy.value = "recommended";
closeFilterPopover();
}
function setActiveZone(zoneKey: string) {
@@ -344,16 +380,76 @@ function setFireLevelRange(min: number | undefined, max: number | undefined) {
filters.maxFireLevel = max;
}
function setFilterPopover(key: FilterPopoverKey, visible: boolean) {
if (visible) {
activeFilterPopover.value = key;
return;
}
if (activeFilterPopover.value === key) activeFilterPopover.value = "";
}
function filterPopoverProps(key: FilterPopoverKey) {
return {
...filterPopoverBaseProps,
visible: activeFilterPopover.value === key,
"onUpdate:visible": (visible: boolean) => setFilterPopover(key, visible),
};
}
function closeFilterPopover() {
activeFilterPopover.value = "";
}
function setStringFilter(key: StringFilterKey, value: string) {
filters[key] = value;
closeFilterPopover();
}
function setCoinRangeAndClose(min: number | undefined, max: number | undefined) {
setCoinRange(min, max);
closeFilterPopover();
}
function setPriceRangeAndClose(min: number | undefined, max: number | undefined) {
setPriceRange(min, max);
closeFilterPopover();
}
function setDepositRangeAndClose(min: number | undefined, max: number | undefined) {
setDepositRange(min, max);
closeFilterPopover();
}
function setTotalRangeAndClose(min: number | undefined, max: number | undefined) {
setTotalRange(min, max);
closeFilterPopover();
}
function setFireLevelRangeAndClose(min: number | undefined, max: number | undefined) {
setFireLevelRange(min, max);
closeFilterPopover();
}
function setSkinFilter(groupKey: string, skinName = "") {
filters.skinGroup = groupKey;
filters.skinName = skinName;
}
function setSkinFilterAndClose(groupKey: string, skinName = "") {
setSkinFilter(groupKey, skinName);
closeFilterPopover();
}
function resetSkinFilter() {
filters.skinGroup = "";
filters.skinName = "";
}
function resetSkinFilterAndClose() {
resetSkinFilter();
closeFilterPopover();
}
function matchesZone(item: Listing, zoneKey: string) {
if (zoneKey === "all") return true;
if (zoneKey === "sale") return hasAcceleratedSaleRatio(item);
@@ -456,7 +552,7 @@ function timeRangeCoversHour(start: number, end: number, hour: number) {
</div>
<div class="filter-chip-row">
<el-popover placement="bottom-start" popper-class="home-filter-popover" trigger="click" :width="220">
<el-popover v-bind="filterPopoverProps('insurance')" :width="220">
<template #reference>
<button class="filter-chip" :class="{ active: filters.insurance }" type="button">
<span>{{ filters.insurance || "保险" }}</span>
@@ -464,20 +560,20 @@ function timeRangeCoversHour(start: number, end: number, hour: number) {
</button>
</template>
<div class="filter-menu">
<button type="button" :class="{ active: !filters.insurance }" @click="filters.insurance = ''">全部保险</button>
<button type="button" :class="{ active: !filters.insurance }" @click="setStringFilter('insurance', '')">全部保险</button>
<button
v-for="item in publishOptions.insurance_options"
:key="item"
type="button"
:class="{ active: filters.insurance === item }"
@click="filters.insurance = item"
@click="setStringFilter('insurance', item)"
>
{{ item }}
</button>
</div>
</el-popover>
<el-popover placement="bottom-start" popper-class="home-filter-popover" trigger="click" :width="220">
<el-popover v-bind="filterPopoverProps('stamina')" :width="220">
<template #reference>
<button class="filter-chip" :class="{ active: filters.stamina }" type="button">
<span>{{ filters.stamina || "体力" }}</span>
@@ -485,20 +581,20 @@ function timeRangeCoversHour(start: number, end: number, hour: number) {
</button>
</template>
<div class="filter-menu">
<button type="button" :class="{ active: !filters.stamina }" @click="filters.stamina = ''">全部体力</button>
<button type="button" :class="{ active: !filters.stamina }" @click="setStringFilter('stamina', '')">全部体力</button>
<button
v-for="item in publishOptions.level_options"
:key="item"
type="button"
:class="{ active: filters.stamina === item }"
@click="filters.stamina = item"
@click="setStringFilter('stamina', item)"
>
{{ item }}
</button>
</div>
</el-popover>
<el-popover placement="bottom-start" popper-class="home-filter-popover" trigger="click" :width="220">
<el-popover v-bind="filterPopoverProps('load')" :width="220">
<template #reference>
<button class="filter-chip" :class="{ active: filters.load }" type="button">
<span>{{ filters.load || "负重" }}</span>
@@ -506,20 +602,20 @@ function timeRangeCoversHour(start: number, end: number, hour: number) {
</button>
</template>
<div class="filter-menu">
<button type="button" :class="{ active: !filters.load }" @click="filters.load = ''">全部负重</button>
<button type="button" :class="{ active: !filters.load }" @click="setStringFilter('load', '')">全部负重</button>
<button
v-for="item in publishOptions.level_options"
:key="item"
type="button"
:class="{ active: filters.load === item }"
@click="filters.load = item"
@click="setStringFilter('load', item)"
>
{{ item }}
</button>
</div>
</el-popover>
<el-popover placement="bottom-start" popper-class="home-filter-popover" trigger="click" :width="240">
<el-popover v-bind="filterPopoverProps('region')" :width="240">
<template #reference>
<button class="filter-chip wide" :class="{ active: filters.region }" type="button">
<span>{{ filters.region || "地区选择" }}</span>
@@ -527,20 +623,20 @@ function timeRangeCoversHour(start: number, end: number, hour: number) {
</button>
</template>
<div class="filter-menu">
<button type="button" :class="{ active: !filters.region }" @click="filters.region = ''">全部省市</button>
<button type="button" :class="{ active: !filters.region }" @click="setStringFilter('region', '')">全部省市</button>
<button
v-for="item in regionOptions"
:key="item"
type="button"
:class="{ active: filters.region === item }"
@click="filters.region = item"
@click="setStringFilter('region', item)"
>
{{ item }}
</button>
</div>
</el-popover>
<el-popover placement="bottom-start" popper-class="home-filter-popover" trigger="click" :width="350">
<el-popover v-bind="filterPopoverProps('coin')" :width="350">
<template #reference>
<button class="filter-chip wide" :class="{ active: filters.minCoin !== undefined || filters.maxCoin !== undefined }" type="button">
<span>{{ rangeLabel(filters.minCoin, filters.maxCoin, "哈夫币(M)") }}</span>
@@ -553,7 +649,7 @@ function timeRangeCoversHour(start: number, end: number, hour: number) {
:key="item.label"
type="button"
:class="{ active: isRangeSelected(filters.minCoin, filters.maxCoin, item.min, item.max) }"
@click="setCoinRange(item.min, item.max)"
@click="setCoinRangeAndClose(item.min, item.max)"
>
{{ item.label }}
</button>
@@ -565,7 +661,7 @@ function timeRangeCoversHour(start: number, end: number, hour: number) {
</div>
</el-popover>
<el-popover placement="bottom-start" popper-class="home-filter-popover" trigger="click" :width="350">
<el-popover v-bind="filterPopoverProps('price')" :width="350">
<template #reference>
<button class="filter-chip" :class="{ active: filters.minPrice !== undefined || filters.maxPrice !== undefined }" type="button">
<span>{{ rangeLabel(filters.minPrice, filters.maxPrice, "租金") }}</span>
@@ -578,7 +674,7 @@ function timeRangeCoversHour(start: number, end: number, hour: number) {
:key="item.label"
type="button"
:class="{ active: isRangeSelected(filters.minPrice, filters.maxPrice, item.min, item.max) }"
@click="setPriceRange(item.min, item.max)"
@click="setPriceRangeAndClose(item.min, item.max)"
>
{{ item.label }}
</button>
@@ -590,7 +686,7 @@ function timeRangeCoversHour(start: number, end: number, hour: number) {
</div>
</el-popover>
<el-popover placement="bottom-start" popper-class="home-filter-popover" trigger="click" :width="350">
<el-popover v-bind="filterPopoverProps('deposit')" :width="350">
<template #reference>
<button class="filter-chip" :class="{ active: filters.minDeposit !== undefined || filters.maxDeposit !== undefined }" type="button">
<span>{{ rangeLabel(filters.minDeposit, filters.maxDeposit, "押金") }}</span>
@@ -603,7 +699,7 @@ function timeRangeCoversHour(start: number, end: number, hour: number) {
:key="item.label"
type="button"
:class="{ active: isRangeSelected(filters.minDeposit, filters.maxDeposit, item.min, item.max) }"
@click="setDepositRange(item.min, item.max)"
@click="setDepositRangeAndClose(item.min, item.max)"
>
{{ item.label }}
</button>
@@ -615,7 +711,7 @@ function timeRangeCoversHour(start: number, end: number, hour: number) {
</div>
</el-popover>
<el-popover placement="bottom-start" popper-class="home-filter-popover" trigger="click" :width="350">
<el-popover v-bind="filterPopoverProps('total')" :width="350">
<template #reference>
<button class="filter-chip wide" :class="{ active: filters.minTotal !== undefined || filters.maxTotal !== undefined }" type="button">
<span>{{ rangeLabel(filters.minTotal, filters.maxTotal, "合计金额") }}</span>
@@ -628,7 +724,7 @@ function timeRangeCoversHour(start: number, end: number, hour: number) {
:key="item.label"
type="button"
:class="{ active: isRangeSelected(filters.minTotal, filters.maxTotal, item.min, item.max) }"
@click="setTotalRange(item.min, item.max)"
@click="setTotalRangeAndClose(item.min, item.max)"
>
{{ item.label }}
</button>
@@ -640,7 +736,7 @@ function timeRangeCoversHour(start: number, end: number, hour: number) {
</div>
</el-popover>
<el-popover placement="bottom-start" popper-class="home-filter-popover" trigger="click" :width="320">
<el-popover v-bind="filterPopoverProps('skin')" :width="320">
<template #reference>
<button class="filter-chip" :class="{ active: filters.skinGroup || filters.skinName }" type="button">
<span>{{ skinChipLabel }}</span>
@@ -648,7 +744,7 @@ function timeRangeCoversHour(start: number, end: number, hour: number) {
</button>
</template>
<div class="skin-filter-menu">
<button class="skin-reset" type="button" :class="{ active: !filters.skinGroup && !filters.skinName }" @click="resetSkinFilter">
<button class="skin-reset" type="button" :class="{ active: !filters.skinGroup && !filters.skinName }" @click="resetSkinFilterAndClose">
全部皮肤
</button>
<div v-for="group in skinFilterGroups" :key="group.key" class="skin-filter-group">
@@ -657,7 +753,7 @@ function timeRangeCoversHour(start: number, end: number, hour: number) {
<button
type="button"
:class="{ active: filters.skinGroup === group.key && !filters.skinName }"
@click="setSkinFilter(group.key)"
@click="setSkinFilterAndClose(group.key)"
>
全部{{ group.title.replace('干员', '') }}
</button>
@@ -668,7 +764,7 @@ function timeRangeCoversHour(start: number, end: number, hour: number) {
:key="skin"
type="button"
:class="{ active: filters.skinGroup === group.key && filters.skinName === skin }"
@click="setSkinFilter(group.key, skin)"
@click="setSkinFilterAndClose(group.key, skin)"
>
{{ skin }}
</button>
@@ -677,7 +773,7 @@ function timeRangeCoversHour(start: number, end: number, hour: number) {
</div>
</el-popover>
<el-popover placement="bottom-start" popper-class="home-filter-popover" trigger="click" :width="220">
<el-popover v-bind="filterPopoverProps('rank')" :width="220">
<template #reference>
<button class="filter-chip" :class="{ active: filters.rank }" type="button">
<span>{{ filters.rank || "段位" }}</span>
@@ -685,20 +781,20 @@ function timeRangeCoversHour(start: number, end: number, hour: number) {
</button>
</template>
<div class="filter-menu">
<button type="button" :class="{ active: !filters.rank }" @click="filters.rank = ''">全部段位</button>
<button type="button" :class="{ active: !filters.rank }" @click="setStringFilter('rank', '')">全部段位</button>
<button
v-for="item in publishOptions.rank_options"
:key="item"
type="button"
:class="{ active: filters.rank === item }"
@click="filters.rank = item"
@click="setStringFilter('rank', item)"
>
{{ item }}
</button>
</div>
</el-popover>
<el-popover placement="bottom-start" popper-class="home-filter-popover" trigger="click" :width="350">
<el-popover v-bind="filterPopoverProps('fireLevel')" :width="350">
<template #reference>
<button class="filter-chip" :class="{ active: filters.minFireLevel !== undefined || filters.maxFireLevel !== undefined }" type="button">
<span>{{ rangeLabel(filters.minFireLevel, filters.maxFireLevel, "等级") }}</span>
@@ -711,7 +807,7 @@ function timeRangeCoversHour(start: number, end: number, hour: number) {
:key="item.label"
type="button"
:class="{ active: isRangeSelected(filters.minFireLevel, filters.maxFireLevel, item.min, item.max) }"
@click="setFireLevelRange(item.min, item.max)"
@click="setFireLevelRangeAndClose(item.min, item.max)"
>
{{ item.label }}
</button>
@@ -723,7 +819,7 @@ function timeRangeCoversHour(start: number, end: number, hour: number) {
</div>
</el-popover>
<el-popover placement="bottom-start" popper-class="home-filter-popover" trigger="click" :width="220">
<el-popover v-bind="filterPopoverProps('loginMethod')" :width="220">
<template #reference>
<button class="filter-chip wide" :class="{ active: filters.loginMethod }" type="button">
<span>{{ filters.loginMethod || "登陆方式" }}</span>
@@ -731,13 +827,13 @@ function timeRangeCoversHour(start: number, end: number, hour: number) {
</button>
</template>
<div class="filter-menu">
<button type="button" :class="{ active: !filters.loginMethod }" @click="filters.loginMethod = ''">全部方式</button>
<button type="button" :class="{ active: !filters.loginMethod }" @click="setStringFilter('loginMethod', '')">全部方式</button>
<button
v-for="item in loginMethodOptions"
:key="item"
type="button"
:class="{ active: filters.loginMethod === item }"
@click="filters.loginMethod = item"
@click="setStringFilter('loginMethod', item)"
>
{{ item }}
</button>
@@ -769,6 +865,7 @@ function timeRangeCoversHour(start: number, end: number, hour: number) {
<el-radio-group v-model="sortBy" size="small">
<el-radio-button label="recommended">综合推荐</el-radio-button>
<el-radio-button label="coinDesc">哈夫币</el-radio-button>
<el-radio-button label="awmDesc">AWM数量</el-radio-button>
<el-radio-button label="priceAsc">价格最低</el-radio-button>
<el-radio-button label="priceDesc">价格最高</el-radio-button>
</el-radio-group>
@@ -80,6 +80,7 @@ const sortBy = ref("comprehensive");
const sortOptions = [
{ key: "comprehensive", label: "综合排序" },
{ key: "published", label: "发布时间" },
{ key: "awmDesc", label: "AWM数量" },
{ key: "priceAsc", label: "价格最低" },
{ key: "priceDesc", label: "价格最高" },
];
@@ -420,6 +421,13 @@ function sortListings(items: Listing[]) {
(a, b) => getListingDisplayPrice(b) - getListingDisplayPrice(a)
);
}
if (sortBy.value === "awmDesc") {
return sorted.sort(
(a, b) =>
getResourceQuantity(b, "awmAmmo") - getResourceQuantity(a, "awmAmmo") ||
getCoinWan(b) - getCoinWan(a)
);
}
return sorted.sort((a, b) => {
const bTime = Date.parse(b.published_at || b.created_at || "") || 0;
const aTime = Date.parse(a.published_at || a.created_at || "") || 0;