From 9078f19194301d24659d4342afd524d384e82a4b Mon Sep 17 00:00:00 2001 From: Jacky Ser Date: Tue, 11 Aug 2026 09:41:44 +0800 Subject: [PATCH] Add g and kg catalog filters --- app/globals.css | 7 +++++ app/page.tsx | 73 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/app/globals.css b/app/globals.css index bb62def..74ae0e5 100644 --- a/app/globals.css +++ b/app/globals.css @@ -313,6 +313,12 @@ select:focus, input:focus, textarea:focus { border-color: var(--blue); box-shado } .category-pills button.active { border-color: var(--blue); color: white; background: var(--blue); } .category-pills button.feature-filter:not(.active) { border-color: #f1bf92; color: #a75a19; background: #fff9f3; } +.catalog-scale-filter { display: grid; grid-template-columns: minmax(240px, 330px) 1fr; align-items: end; gap: 14px; margin-top: 13px; padding-top: 13px; border-top: 1px solid #e7ebf1; } +.catalog-scale-filter label { display: grid; gap: 6px; } +.catalog-scale-filter label > span { color: #68758a; font-size: 10px; font-weight: 700; } +.catalog-scale-filter select { width: 100%; height: 42px; padding: 0 12px; } +.catalog-scale-filter p { margin: 0 0 4px; color: #8792a3; font-size: 9px; line-height: 1.55; } +.catalog-scale-filter p strong { color: #657187; } .catalog-result-count { margin: 11px 2px 0; color: #8792a3; font-size: 10px; } .catalog-result-count strong { color: var(--blue); font-size: 12px; } .catalog-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; } @@ -496,6 +502,7 @@ footer > span { color: #9aa4b2; font-size: 10px; } .catalog-summary { grid-template-columns: repeat(2, 1fr); } .catalog-summary button:last-child { grid-column: 1 / -1; } .catalog-toolbar { top: 64px; } + .catalog-scale-filter { grid-template-columns: 1fr; align-items: stretch; } .catalog-grid { grid-template-columns: 1fr; gap: 15px; } .catalog-image-button { height: 280px; } .catalog-card-body { padding: 15px; } diff --git a/app/page.tsx b/app/page.tsx index 0fa4cdd..1aa474b 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -94,6 +94,46 @@ function getCategoryCount(category: string) { return category === SILENT_SERVO_CATEGORY ? SILENT_SERVO_COUNT : CATALOG_COUNTS[category]; } +type ProductScale = { + key: string; + label: string; + unit: "g" | "kg"; + value: number; +}; + +function getProductScale(product: CatalogProduct): ProductScale | null { + const kilogramMatch = product.name.match(/(\d+(?:\.\d+)?)\s*(?:kg|千克)/i); + if (kilogramMatch) { + const value = Number(kilogramMatch[1]); + return { key: `kg:${value}`, label: `${value}kg`, unit: "kg", value }; + } + + const gramMatch = product.name.match(/(\d+(?:\.\d+)?)\s*(?:g|克)/i); + if (gramMatch) { + const value = Number(gramMatch[1]); + return { key: `g:${value}`, label: `${value}g`, unit: "g", value }; + } + + return null; +} + +const PRODUCT_SCALE_OPTIONS = [...CATALOG_PRODUCTS.reduce((options, product) => { + const scale = getProductScale(product); + if (!scale) return options; + const current = options.get(scale.key); + options.set(scale.key, { ...scale, count: (current?.count ?? 0) + 1 }); + return options; +}, new Map()).values()].sort( + (a, b) => (a.unit === b.unit ? a.value - b.value : a.unit === "g" ? -1 : 1), +); + +const GRAM_SCALE_OPTIONS = PRODUCT_SCALE_OPTIONS.filter((option) => option.unit === "g"); +const KILOGRAM_SCALE_OPTIONS = PRODUCT_SCALE_OPTIONS.filter((option) => option.unit === "kg"); +const UNMARKED_SCALE_COUNT = CATALOG_PRODUCTS.length - PRODUCT_SCALE_OPTIONS.reduce( + (total, option) => total + option.count, + 0, +); + function inferWeight(product: CatalogProduct) { const listedWeight = parseNumbers(product.specs["重量"])[0]; if (Number.isFinite(listedWeight)) return listedWeight; @@ -280,6 +320,7 @@ export default function Home() { const [leadId, setLeadId] = useState(""); const [catalogQuery, setCatalogQuery] = useState(""); const [catalogCategory, setCatalogCategory] = useState("全部产品"); + const [catalogScale, setCatalogScale] = useState("all"); const [catalogLimit, setCatalogLimit] = useState(24); const [selectedCatalogProduct, setSelectedCatalogProduct] = useState(null); @@ -290,6 +331,8 @@ export default function Home() { const filteredCatalog = useMemo(() => { const query = catalogQuery.trim().toLowerCase(); return CATALOG_PRODUCTS.filter((product) => { + const productScale = getProductScale(product)?.key ?? "unmarked"; + if (catalogScale !== "all" && productScale !== catalogScale) return false; const matchesCategory = catalogCategory === "全部产品" || product.category === catalogCategory || @@ -307,7 +350,7 @@ export default function Home() { .toLowerCase(); return haystack.includes(query); }); - }, [catalogCategory, catalogQuery]); + }, [catalogCategory, catalogQuery, catalogScale]); const visibleCatalog = filteredCatalog.slice(0, catalogLimit); const needsEngineer = !top?.coreCompatible || @@ -894,6 +937,32 @@ export default function Home() { >{category === SILENT_SERVO_CATEGORY ? `${category} · ${SILENT_SERVO_COUNT}` : category} ))} +
+ +

说明:g/克表示产品克重系列;kg/Kg通常表示舵机扭矩等级,并非产品自身重量。

+

找到 {filteredCatalog.length} 个型号

@@ -936,7 +1005,7 @@ export default function Home() {
没有找到匹配型号

可以尝试减少关键词,或切换到“全部产品”。

-