Add g and kg catalog filters

This commit is contained in:
Jacky Ser
2026-08-11 09:41:44 +08:00
parent 7b9a56b7fe
commit 9078f19194
2 changed files with 78 additions and 2 deletions

View File

@@ -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<string, ProductScale & { count: number }>()).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<CatalogProduct | null>(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}</button>
))}
</div>
<div className="catalog-scale-filter">
<label>
<span> g / kg </span>
<select
value={catalogScale}
onChange={(event) => {
setCatalogScale(event.target.value);
setCatalogLimit(24);
}}
>
<option value="all"> g / kg </option>
<optgroup label="克重系列g / 克)">
{GRAM_SCALE_OPTIONS.map((option) => (
<option key={option.key} value={option.key}>{option.label}{option.count}</option>
))}
</optgroup>
<optgroup label="千克扭矩等级kg / 千克)">
{KILOGRAM_SCALE_OPTIONS.map((option) => (
<option key={option.key} value={option.key}>{option.label}{option.count}</option>
))}
</optgroup>
<option value="unmarked"> g/kg{UNMARKED_SCALE_COUNT}</option>
</select>
</label>
<p><strong></strong>g/kg/Kg通常表示舵机扭矩等级</p>
</div>
<p className="catalog-result-count">
<strong>{filteredCatalog.length}</strong>
</p>
@@ -936,7 +1005,7 @@ export default function Home() {
<div className="catalog-empty">
<strong></strong>
<p></p>
<button type="button" onClick={() => { setCatalogQuery(""); setCatalogCategory("全部产品"); }}>
<button type="button" onClick={() => { setCatalogQuery(""); setCatalogCategory("全部产品"); setCatalogScale("all"); }}>
</button>
</div>