diff --git a/README.md b/README.md
index 73a0338..3c775f6 100644
--- a/README.md
+++ b/README.md
@@ -24,6 +24,8 @@ npm run dev
```bash
VITE_API_PROXY_TARGET=http://127.0.0.1:8080 npm run dev
+
+VITE_API_PROXY_TARGET=https://hao858.com/ npm run dev
```
## 构建
diff --git a/src/App.tsx b/src/App.tsx
index 4126ba1..226c064 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -10,7 +10,6 @@ import ConfigProvider from "antd/es/config-provider";
import Empty from "antd/es/empty";
import Input from "antd/es/input";
import Pagination from "antd/es/pagination";
-import Select from "antd/es/select";
import Spin from "antd/es/spin";
import Tag from "antd/es/tag";
import Tooltip from "antd/es/tooltip";
@@ -53,25 +52,36 @@ const initialOptions: ListingPublishOptions = {
rank_options: [],
insurance_options: [],
level_options: [],
+ region_options: [],
skin_groups: [],
};
-const fallbackLevels = ["4级", "5级", "6级", "7级"];
-const fallbackInsurance = ["1*2", "2*2", "2*3", "3*3"];
-const fallbackLogins = ["QQ", "微信", "Steam", "不限"];
-const fallbackRanks = ["青铜", "白银", "黄金", "铂金", "钻石", "黑鹰", "巅峰"];
-const fallbackSkins = ["信条", "坠星者", "处刑者", "影锋", "暗星", "电锯", "蚀金玫瑰", "维什戴尔"];
+/** 数值区间预设(主站 HomeFilters 同款,非 publish_options) */
+interface RangeOption {
+ label: string;
+ min: string;
+ max: string;
+}
-const coinRanges = [
+const coinRanges: RangeOption[] = [
{ label: "15-50", min: "15", max: "50" },
{ label: "50-100", min: "50", max: "100" },
{ label: "100-150", min: "100", max: "150" },
{ label: "150-200", min: "150", max: "200" },
{ label: "200-250", min: "200", max: "250" },
+ { label: "250-300", min: "250", max: "300" },
{ label: "300以上", min: "300", max: "" },
];
-const priceRanges = [
+const ratioRanges: RangeOption[] = [
+ { label: "≤30", min: "", max: "30" },
+ { label: "30-35", min: "30", max: "35" },
+ { label: "35-40", min: "35", max: "40" },
+ { label: "40-45", min: "40", max: "45" },
+ { label: "45+", min: "45", max: "" },
+];
+
+const priceRanges: RangeOption[] = [
{ label: "0-50", min: "0", max: "50" },
{ label: "50-100", min: "50", max: "100" },
{ label: "100-150", min: "100", max: "150" },
@@ -79,49 +89,85 @@ const priceRanges = [
{ label: "200以上", min: "200", max: "" },
];
+const depositRanges: RangeOption[] = [
+ { label: "50-100", min: "50", max: "100" },
+ { label: "100-150", min: "100", max: "150" },
+ { label: "150-200", min: "150", max: "200" },
+ { label: "200以上", min: "200", max: "" },
+];
+
+const totalRanges: RangeOption[] = [
+ { 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" },
+ { label: "5000+", min: "5000", max: "" },
+];
+
+const fireLevelRanges: RangeOption[] = [
+ { label: "38-50", min: "38", max: "50" },
+ { label: "50-60", min: "50", max: "60" },
+];
+
const sortOptions = [
{ key: "recommended", label: "默认排序" },
{ key: "priceDesc", label: "价格排序" },
{ key: "ratioDesc", label: "比例排序" },
{ key: "coinDesc", label: "哈夫币排序" },
{ key: "ratioAsc", label: "绝密KD排序" },
- { key: "coinAsc", label: "AWM排序" },
+ { key: "awmDesc", label: "AWM子弹排序" },
{ key: "priceAsc", label: "六头排序" },
{ key: "loadDesc", label: "六甲排序" },
];
+type RangeMinKey = "minCoin" | "minRatio" | "minPrice" | "minDeposit" | "minTotal" | "minFireLevel";
+type RangeMaxKey = "maxCoin" | "maxRatio" | "maxPrice" | "maxDeposit" | "maxTotal" | "maxFireLevel";
+type ListFilterKey = "stamina" | "load" | "insurance" | "skinNames" | "loginMethods" | "ranks" | "regions";
+
interface Filters {
keyword: string;
minCoin: string;
maxCoin: string;
+ minRatio: string;
+ maxRatio: string;
minPrice: string;
maxPrice: string;
- minKd: string;
- maxKd: string;
+ minDeposit: string;
+ maxDeposit: string;
+ minTotal: string;
+ maxTotal: string;
+ minFireLevel: string;
+ maxFireLevel: string;
stamina: string[];
load: string[];
insurance: string[];
skinNames: string[];
loginMethods: string[];
ranks: string[];
- zones: string[];
+ regions: string[];
}
const emptyFilters: Filters = {
keyword: "",
minCoin: "",
maxCoin: "",
+ minRatio: "",
+ maxRatio: "",
minPrice: "",
maxPrice: "",
- minKd: "",
- maxKd: "",
+ minDeposit: "",
+ maxDeposit: "",
+ minTotal: "",
+ maxTotal: "",
+ minFireLevel: "",
+ maxFireLevel: "",
stamina: [],
load: [],
insurance: [],
skinNames: [],
loginMethods: [],
ranks: [],
- zones: [],
+ regions: [],
};
export default function App() {
@@ -141,9 +187,6 @@ export default function App() {
Input: {
controlHeight: 38,
},
- Select: {
- controlHeight: 30,
- },
},
}}
>
@@ -168,46 +211,40 @@ function Showcase() {
const [copiedCode, setCopiedCode] = useState("");
const [copiedInfoCode, setCopiedInfoCode] = useState("");
- const levelOptions = useMemo(
- () => (publishOptions.level_options.length ? publishOptions.level_options : fallbackLevels),
- [publishOptions.level_options]
+ // 枚举类筛选项全部来自 /api/mobile-home-config 的 publish_options
+ const levelOptions = publishOptions.level_options;
+ const insuranceOptions = publishOptions.insurance_options;
+ const loginOptions = publishOptions.login_method_options;
+ const rankOptions = publishOptions.rank_options;
+ const regionOptions = publishOptions.region_options;
+ /** 基础筛选:刀皮 / 红皮 */
+ const basicSkinSections = useMemo(
+ () =>
+ resolveSkinSections(publishOptions.skin_groups, [
+ { key: "melee", title: "刀皮" },
+ { key: "operatorRed", title: "红皮" },
+ ]),
+ [publishOptions.skin_groups]
);
- const insuranceOptions = useMemo(
- () => (publishOptions.insurance_options.length ? publishOptions.insurance_options : fallbackInsurance),
- [publishOptions.insurance_options]
+ /** 高级筛选:枪皮 */
+ const advancedSkinSections = useMemo(
+ () => resolveSkinSections(publishOptions.skin_groups, [{ key: "weapon", title: "枪皮" }]),
+ [publishOptions.skin_groups]
);
- const loginOptions = useMemo(
- () => (publishOptions.login_method_options.length ? publishOptions.login_method_options : fallbackLogins),
- [publishOptions.login_method_options]
- );
- const rankOptions = useMemo(
- () => (publishOptions.rank_options.length ? publishOptions.rank_options : fallbackRanks),
- [publishOptions.rank_options]
- );
- const zoneOptions = useMemo(() => publishOptions.server_options, [publishOptions.server_options]);
- const skinSections = useMemo(() => {
- const groups = publishOptions.skin_groups.filter((group) =>
- ["melee", "operatorGold", "operatorRed", "weapon"].includes(group.key)
- );
- if (groups.length) {
- return groups.map((group) => ({
- key: group.key,
- title: groupTitle(group.key, group.title),
- options: group.options,
- }));
- }
- return [{ key: "skin", title: "稀有皮肤", options: fallbackSkins }];
- }, [publishOptions.skin_groups]);
const noticeText = announcements[0]?.trim() || "";
const activeFilterCount = useMemo(() => countActiveFilters(filters), [filters]);
const appliedFilterCount = useMemo(() => countActiveFilters(appliedFilters), [appliedFilters]);
+ const advancedActiveCount = useMemo(() => countAdvancedFilters(filters), [filters]);
const displayListings = useMemo(() => {
const items = [...listings];
if (activeSort === "ratioAsc") return items.sort((a, b) => ratioValue(a) - ratioValue(b));
if (activeSort === "ratioDesc") return items.sort((a, b) => ratioValue(b) - ratioValue(a));
- if (activeSort === "coinAsc") return items.sort((a, b) => a.haf_coin_amount - b.haf_coin_amount);
+ // 与后端 awmDesc 一致:按 AW子弹数量降序(当前页兜底)
+ if (activeSort === "awmDesc") {
+ return items.sort((a, b) => getResourceQuantity(b, "awmAmmo") - getResourceQuantity(a, "awmAmmo"));
+ }
if (activeSort === "loadDesc") {
return items.sort((a, b) => getResourceQuantity(b, "armor6") - getResourceQuantity(a, "armor6"));
}
@@ -258,7 +295,7 @@ function Showcase() {
setFilters((current) => ({ ...current, [key]: value }));
}
- function toggleFilterList(key: "stamina" | "load" | "insurance" | "skinNames", value: string) {
+ function toggleFilterList(key: ListFilterKey, value: string) {
setFilters((current) => {
const nextList = current[key].includes(value) ? current[key].filter((item) => item !== value) : [...current[key], value];
return { ...current, [key]: nextList };
@@ -281,7 +318,7 @@ function Showcase() {
setAdvancedOpen(false);
}
- function selectRange(minKey: "minCoin" | "minPrice", maxKey: "maxCoin" | "maxPrice", min: string, max: string) {
+ function selectRange(minKey: RangeMinKey, maxKey: RangeMaxKey, min: string, max: string) {
setFilters((current) => {
if (current[minKey] === min && current[maxKey] === max) {
return { ...current, [minKey]: "", [maxKey]: "" };
@@ -290,6 +327,10 @@ function Showcase() {
});
}
+ function isRangeActive(minKey: RangeMinKey, maxKey: RangeMaxKey, item: RangeOption) {
+ return filters[minKey] === item.min && filters[maxKey] === item.max;
+ }
+
function setSort(sortKey: string) {
setActiveSort(sortKey);
setPage(1);
@@ -411,7 +452,7 @@ function Showcase() {
{appliedFilterCount > 0 && !filterOpen ? (
- {buildFilterSummary(appliedFilters, insuranceLabel).map((item) => (
+ {buildFilterSummary(appliedFilters).map((item) => (
{item}
@@ -420,26 +461,27 @@ function Showcase() {
) : null}
+ {/* 基础筛选:哈夫币 / 比例 / 保险 / 体力 / 负重 / 登录 / 刀皮 / 红皮 */}
filters.minCoin === item.min && filters.maxCoin === item.max}
+ active={(item) => isRangeActive("minCoin", "maxCoin", item)}
label="哈夫币"
options={coinRanges}
render={(item) => item.label}
onSelect={(item) => selectRange("minCoin", "maxCoin", item.min, item.max)}
/>
filters.minPrice === item.min && filters.maxPrice === item.max}
- label="租金"
- options={priceRanges}
+ active={(item) => isRangeActive("minRatio", "maxRatio", item)}
+ label="比例"
+ options={ratioRanges}
render={(item) => item.label}
- onSelect={(item) => selectRange("minPrice", "maxPrice", item.min, item.max)}
+ onSelect={(item) => selectRange("minRatio", "maxRatio", item.min, item.max)}
/>
filters.insurance.includes(item)}
label="保险"
options={insuranceOptions}
- render={insuranceLabel}
+ render={(item) => item}
onSelect={(item) => toggleFilterList("insurance", item)}
/>
item}
onSelect={(item) => toggleFilterList("load", item)}
/>
-
- IP地址
-
-
- 登录方式
-
-
- 段位
-
-
-
-
-
- {skinSections.map((section) => (
+
filters.loginMethods.includes(item)}
+ label="登录方式"
+ options={loginOptions}
+ render={(item) => item}
+ onSelect={(item) => toggleFilterList("loginMethods", item)}
+ />
+ {basicSkinSections.map((section) => (
filters.skinNames.includes(item)}
label={section.title}
- options={section.options.slice(0, 18)}
+ options={section.options}
render={(item) => item}
onSelect={(item) => toggleFilterList("skinNames", item)}
/>
))}
-
+
+
+
+ {/* 高级筛选:租金 / 押金 / 合计 / 等级 / 段位 / IP / 枪皮 */}
+
+
+ isRangeActive("minPrice", "maxPrice", item)}
+ label="租金"
+ options={priceRanges}
+ render={(item) => item.label}
+ onSelect={(item) => selectRange("minPrice", "maxPrice", item.min, item.max)}
+ />
+ isRangeActive("minDeposit", "maxDeposit", item)}
+ label="押金"
+ options={depositRanges}
+ render={(item) => item.label}
+ onSelect={(item) => selectRange("minDeposit", "maxDeposit", item.min, item.max)}
+ />
+ isRangeActive("minTotal", "maxTotal", item)}
+ label="合计金额"
+ options={totalRanges}
+ render={(item) => item.label}
+ onSelect={(item) => selectRange("minTotal", "maxTotal", item.min, item.max)}
+ />
+ isRangeActive("minFireLevel", "maxFireLevel", item)}
+ label="等级"
+ options={fireLevelRanges}
+ render={(item) => item.label}
+ onSelect={(item) => selectRange("minFireLevel", "maxFireLevel", item.min, item.max)}
+ />
+ filters.ranks.includes(item)}
+ label="段位"
+ options={rankOptions}
+ render={(item) => item}
+ onSelect={(item) => toggleFilterList("ranks", item)}
+ />
+ filters.regions.includes(item)}
+ label="IP地区"
+ options={regionOptions}
+ render={(item) => item}
+ onSelect={(item) => toggleFilterList("regions", item)}
+ />
+ {advancedSkinSections.map((section) => (
+ filters.skinNames.includes(item)}
+ label={section.title}
+ options={section.options}
+ render={(item) => item}
+ onSelect={(item) => toggleFilterList("skinNames", item)}
+ />
+ ))}
+
+
+
+
} onClick={() => applyFilters()}>
@@ -644,11 +682,13 @@ interface FilterRowProps
{
active: (item: T) => boolean;
render: (item: T) => string;
onSelect: (item: T) => void;
+ fullWidth?: boolean;
}
-function FilterRow({ active, label, onSelect, options, render }: FilterRowProps) {
+function FilterRow({ active, fullWidth, label, onSelect, options, render }: FilterRowProps) {
+ if (!options.length) return null;
return (
-
+
{label}
{options.map((item) => {
@@ -853,15 +893,21 @@ function buildQuery(nextPage: number, filters: Filters, sort: string): PublicLis
page_size: pageSize,
keyword: filters.keyword.trim(),
sort: backendSortKey(sort),
- zone: filters.zones.join(","),
+ region: filters.regions.join(","),
login_method: filters.loginMethods.join(","),
rank: filters.ranks.join(","),
min_coin: toNumber(filters.minCoin),
max_coin: toNumber(filters.maxCoin),
+ min_ratio: toNumber(filters.minRatio),
+ max_ratio: toNumber(filters.maxRatio),
min_price: toNumber(filters.minPrice),
max_price: toNumber(filters.maxPrice),
- min_secret_kd: toNumber(filters.minKd),
- max_secret_kd: toNumber(filters.maxKd),
+ min_deposit: toNumber(filters.minDeposit),
+ max_deposit: toNumber(filters.maxDeposit),
+ min_total: toNumber(filters.minTotal),
+ max_total: toNumber(filters.maxTotal),
+ min_fire_level: toNumber(filters.minFireLevel),
+ max_fire_level: toNumber(filters.maxFireLevel),
stamina: filters.stamina.join(","),
load: filters.load.join(","),
insurance: filters.insurance.join(","),
@@ -870,7 +916,7 @@ function buildQuery(nextPage: number, filters: Filters, sort: string): PublicLis
}
function backendSortKey(sort: string) {
- if (sort === "priceAsc" || sort === "priceDesc" || sort === "coinDesc") return sort;
+ if (sort === "priceAsc" || sort === "priceDesc" || sort === "coinDesc" || sort === "awmDesc") return sort;
return "recommended";
}
@@ -897,60 +943,100 @@ function cloneFilters(filters: Filters): Filters {
skinNames: [...filters.skinNames],
loginMethods: [...filters.loginMethods],
ranks: [...filters.ranks],
- zones: [...filters.zones],
+ regions: [...filters.regions],
};
}
-function groupTitle(key: string, title: string) {
- if (key === "melee") return "刀皮";
- if (key === "operatorGold") return "干员金皮";
- if (key === "operatorRed") return "干员红皮";
- if (key === "weapon") return "枪皮";
- return title;
+/** 从主站 publish_options.skin_groups 取对应分组,无数据则不展示 */
+function resolveSkinSections(
+ groups: ListingPublishOptions["skin_groups"],
+ defs: Array<{ key: string; title: string }>
+) {
+ return defs
+ .map((def) => {
+ const group = groups.find((item) => item.key === def.key);
+ if (!group?.options?.length) return null;
+ return {
+ key: def.key,
+ title: def.title,
+ options: group.options,
+ };
+ })
+ .filter((item): item is { key: string; title: string; options: string[] } => item !== null);
}
-function insuranceLabel(value: string) {
- const [rows, cols] = value.split("*").map((item) => Number(item));
- if (rows > 0 && cols > 0) return `${rows * cols}格`;
- return value;
+function hasRange(min: string, max: string) {
+ return Boolean(min || max);
+}
+
+function formatRangeText(min: string, max: string) {
+ if (min && max) return `${min}-${max}`;
+ if (min) return `${min}+`;
+ if (max) return `≤${max}`;
+ return "";
}
function countActiveFilters(filters: Filters) {
let count = 0;
if (filters.keyword.trim()) count += 1;
- if (filters.minCoin || filters.maxCoin) count += 1;
- if (filters.minPrice || filters.maxPrice) count += 1;
- if (filters.minKd || filters.maxKd) count += 1;
+ if (hasRange(filters.minCoin, filters.maxCoin)) count += 1;
+ if (hasRange(filters.minRatio, filters.maxRatio)) count += 1;
+ if (hasRange(filters.minPrice, filters.maxPrice)) count += 1;
+ if (hasRange(filters.minDeposit, filters.maxDeposit)) count += 1;
+ if (hasRange(filters.minTotal, filters.maxTotal)) count += 1;
+ if (hasRange(filters.minFireLevel, filters.maxFireLevel)) count += 1;
count += filters.stamina.length;
count += filters.load.length;
count += filters.insurance.length;
count += filters.skinNames.length;
count += filters.loginMethods.length;
count += filters.ranks.length;
- count += filters.zones.length;
+ count += filters.regions.length;
return count;
}
-function buildFilterSummary(filters: Filters, formatInsurance: (value: string) => string) {
+/** 高级筛选区已选项数(用于展开按钮角标) */
+function countAdvancedFilters(filters: Filters) {
+ let count = 0;
+ if (hasRange(filters.minPrice, filters.maxPrice)) count += 1;
+ if (hasRange(filters.minDeposit, filters.maxDeposit)) count += 1;
+ if (hasRange(filters.minTotal, filters.maxTotal)) count += 1;
+ if (hasRange(filters.minFireLevel, filters.maxFireLevel)) count += 1;
+ if (filters.ranks.length) count += 1;
+ if (filters.regions.length) count += 1;
+ // 枪皮无法单独区分,用 skinNames 有选中时在高级区也提示(保守计 0,避免误导)
+ return count;
+}
+
+function buildFilterSummary(filters: Filters) {
const items: string[] = [];
- if (filters.minCoin || filters.maxCoin) {
- items.push(`哈夫币 ${filters.minCoin || "0"}-${filters.maxCoin || "∞"}`);
+ if (hasRange(filters.minCoin, filters.maxCoin)) {
+ items.push(`哈夫币 ${formatRangeText(filters.minCoin, filters.maxCoin)}`);
}
- if (filters.minPrice || filters.maxPrice) {
- items.push(`租金 ${filters.minPrice || "0"}-${filters.maxPrice || "∞"}`);
+ if (hasRange(filters.minRatio, filters.maxRatio)) {
+ items.push(`比例 ${formatRangeText(filters.minRatio, filters.maxRatio)}`);
}
- for (const value of filters.insurance) items.push(`保险 ${formatInsurance(value)}`);
+ for (const value of filters.insurance) items.push(`保险 ${value}`);
for (const value of filters.stamina) items.push(`体力 ${value}`);
for (const value of filters.load) items.push(`负重 ${value}`);
- for (const value of filters.ranks) items.push(value);
for (const value of filters.loginMethods) items.push(value);
- for (const value of filters.zones) items.push(value);
- for (const value of filters.skinNames) items.push(value);
- if (filters.minKd || filters.maxKd) {
- items.push(`KD ${filters.minKd || "0"}-${filters.maxKd || "∞"}`);
+ if (hasRange(filters.minPrice, filters.maxPrice)) {
+ items.push(`租金 ${formatRangeText(filters.minPrice, filters.maxPrice)}`);
}
+ if (hasRange(filters.minDeposit, filters.maxDeposit)) {
+ items.push(`押金 ${formatRangeText(filters.minDeposit, filters.maxDeposit)}`);
+ }
+ if (hasRange(filters.minTotal, filters.maxTotal)) {
+ items.push(`合计 ${formatRangeText(filters.minTotal, filters.maxTotal)}`);
+ }
+ if (hasRange(filters.minFireLevel, filters.maxFireLevel)) {
+ items.push(`等级 ${formatRangeText(filters.minFireLevel, filters.maxFireLevel)}`);
+ }
+ for (const value of filters.ranks) items.push(value);
+ for (const value of filters.regions) items.push(value);
+ for (const value of filters.skinNames) items.push(value);
if (filters.keyword.trim()) items.push(`编号 ${filters.keyword.trim()}`);
- return items.slice(0, 6);
+ return items.slice(0, 8);
}
function getAssetText(item: Listing, key: string) {
diff --git a/src/api.ts b/src/api.ts
index 5210562..f818401 100644
--- a/src/api.ts
+++ b/src/api.ts
@@ -52,6 +52,7 @@ export interface PublicListingQuery {
keyword?: string;
sort?: string;
zone?: string;
+ region?: string;
login_method?: string;
rank?: string;
insurance?: string;
@@ -60,8 +61,16 @@ export interface PublicListingQuery {
skin_name?: string;
min_coin?: number;
max_coin?: number;
+ min_ratio?: number;
+ max_ratio?: number;
min_price?: number;
max_price?: number;
+ min_deposit?: number;
+ max_deposit?: number;
+ min_total?: number;
+ max_total?: number;
+ min_fire_level?: number;
+ max_fire_level?: number;
min_secret_kd?: number;
max_secret_kd?: number;
}
@@ -81,6 +90,7 @@ export interface ListingPublishOptions {
rank_options: string[];
insurance_options: string[];
level_options: string[];
+ region_options: string[];
skin_groups: Array<{
key: string;
title: string;
@@ -141,6 +151,7 @@ function normalizeOptions(value: unknown): ListingPublishOptions {
rank_options: normalizeStringArray(options.rank_options),
insurance_options: normalizeStringArray(options.insurance_options),
level_options: normalizeStringArray(options.level_options),
+ region_options: normalizeStringArray(options.region_options),
skin_groups: normalizeSkinGroups(options.skin_groups),
};
}
diff --git a/src/styles.css b/src/styles.css
index 9d559c8..57c216a 100644
--- a/src/styles.css
+++ b/src/styles.css
@@ -412,8 +412,11 @@ input {
gap: 12px;
}
-.filter-label,
-.range-fields > label > span {
+.filter-row-full {
+ grid-column: 1 / -1;
+}
+
+.filter-label {
min-height: 30px;
display: inline-flex;
align-items: center;
@@ -472,71 +475,27 @@ input {
transform: translateY(1px);
}
-.compact-select .ant-select {
- width: min(280px, 100%);
-}
-
-.compact-select .ant-select-selector {
- min-height: 34px !important;
- border-radius: 10px !important;
- border-color: #e6ebf2 !important;
- background: #f8fafc !important;
-}
-
-.compact-select .ant-select-focused .ant-select-selector {
- border-color: var(--brand) !important;
- box-shadow: 0 0 0 2px rgba(255, 107, 0, 0.12) !important;
-}
-
.advanced-panel {
display: none;
padding-top: 16px;
border-top: 1px dashed #e8edf3;
- margin-top: 16px;
+ margin-top: 4px;
}
.advanced-panel.open {
- display: grid;
- gap: 14px;
+ display: block;
}
-.range-fields {
- display: grid;
- grid-template-columns: repeat(2, minmax(0, 1fr));
- gap: 16px 38px;
-}
-
-.range-fields > label {
- display: grid;
- grid-template-columns: 72px minmax(0, 1fr);
- align-items: center;
- gap: 12px;
-}
-
-.range-inputs {
- min-width: 0;
- display: grid;
- grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
- align-items: center;
- gap: 8px;
-}
-
-.range-inputs em {
- color: #98a2b3;
- font-size: 12px;
- font-style: normal;
- font-weight: 700;
-}
-
-.range-inputs .ant-input {
- border-radius: 10px;
- background: #f8fafc;
+.advanced-toggle-row {
+ display: flex;
+ justify-content: center;
+ padding: 8px 0 4px;
}
.filter-footer {
justify-content: center;
- min-height: 44px;
- padding-top: 4px;
+ min-height: 0;
+ padding-top: 10px;
flex-wrap: wrap;
gap: 10px;
}
@@ -565,6 +524,22 @@ input {
font-size: 11px;
}
+.advanced-count {
+ min-width: 16px;
+ height: 16px;
+ padding: 0 5px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 999px;
+ color: #fff;
+ background: var(--brand);
+ font-size: 11px;
+ font-style: normal;
+ font-weight: 900;
+ line-height: 1;
+}
+
.result-area {
margin-top: 14px;
padding: 16px 16px 28px;
@@ -1146,8 +1121,7 @@ input {
width: calc(100% - 24px);
}
- .filter-grid,
- .range-fields {
+ .filter-grid {
grid-template-columns: 1fr;
}
@@ -1310,17 +1284,14 @@ input {
gap: 10px;
}
- .filter-row,
- .range-fields > label {
- grid-template-columns: 44px minmax(0, 1fr);
+ .filter-row {
+ grid-template-columns: 52px minmax(0, 1fr);
align-items: center;
gap: 8px;
}
.filter-label,
- .range-fields > label > span,
- .filter-row > span.filter-label,
- .compact-select > .filter-label {
+ .filter-row > span.filter-label {
min-height: 28px;
font-size: 12px;
color: #667085;
@@ -1349,12 +1320,11 @@ input {
font-size: 12px;
}
- .compact-select .ant-select {
- width: 100%;
- }
-
- .compact-select .ant-select-selector {
- min-height: 32px !important;
+ /* 全宽筛选(皮肤/地区)在移动端允许换行,避免横向滚太长 */
+ .filter-row-full .chip-list {
+ flex-wrap: wrap;
+ overflow: visible;
+ mask-image: none;
}
.advanced-panel {
@@ -1362,13 +1332,8 @@ input {
padding-top: 12px;
}
- .advanced-panel.open {
- gap: 10px;
- }
-
- .range-fields {
- grid-template-columns: 1fr;
- gap: 10px;
+ .advanced-toggle-row {
+ padding: 4px 0 0;
}
.filter-footer {
@@ -1420,10 +1385,6 @@ input {
font-size: 12px;
}
- .compact-select .ant-select {
- width: 100%;
- }
-
.sort-toolbar {
align-items: stretch;
flex-direction: column;