/* 详细机型库(壳内层)— 品牌 logo 网格 → 点入品牌机型;按价格分组视图。
数据:BRANDS/DB_STATS(dbdata.jsx,_mkdb.py 从本地 db dump 生成);DBTV(data.jsx)补 6 台演示机的面板/亮点。
深链:?tool=db · &dbv=price · &b=品牌中文名 */
const dbCx = (...a) => a.filter(Boolean).join(' ');
const dbQ = (k) => new URLSearchParams(location.search).get(k);
const DBTV_DETAIL = {};
DBTV.forEach((t) => { DBTV_DETAIL[t.id] = t; });
const DB_PRICE_BUCKETS = [
{ label: '5 千内', test: (p) => p < 5000 },
{ label: '5 千 – 1 万', test: (p) => p >= 5000 && p < 10000 },
{ label: '1 – 2 万', test: (p) => p >= 10000 && p < 20000 },
{ label: '2 万以上', test: (p) => p >= 20000 },
];
function DbModelRow({ zh, m }) {
const det = DBTV_DETAIL[m.id];
const sub = [det && det.panel, m.size && `${m.size}″`, det && det.hl].filter(Boolean).join(' · ');
return (
{zh} {m.m}
{sub && {sub}}
{m.price > 0
?
¥{m.price.toLocaleString()}
:
未录价}
);
}
function DbScreen({ onBack }) {
const { useState, useRef } = React;
const [mode, setMode] = useState(dbQ('dbv') === 'price' ? 'price' : 'brand');
const b0 = BRANDS.find((b) => b.zh === dbQ('b')) || null;
const [brand, setBrand] = useState(b0);
const prev = useRef(b0);
if (brand) prev.current = brand;
const det = brand || prev.current; /* 收回滑动期间面板内容不消失 */
const sync = (fn) => { const u = new URL(location); fn(u.searchParams); history.replaceState(null, '', u); };
const pickBrand = (b) => { sync((p) => { if (b) p.set('b', b.zh); else p.delete('b'); }); setBrand(b); };
return (
{brand ? brand.zh : '机型库'}
{brand ? `共收录 ${brand.models.length} 款机型` : `在库 ${DB_STATS.inStock} 台 · ${DB_STATS.brands} 个品牌`}
{/* 面板 1:品牌网格 / 价格分组 */}
{mode === 'brand' ? (
{BRANDS.map((b) => (
))}
) : (
DB_PRICE_BUCKETS.map((bk) => {
const items = BRANDS.flatMap((b) => b.models.filter((m) => m.price > 0 && bk.test(m.price))
.map((m) => ({ ...m, zh: b.zh }))).sort((a, c) => a.price - c.price);
if (!items.length) return null;
return (
{bk.label}{items.length} 台
{items.map((m) => )}
);
})
)}
{/* 面板 2:品牌机型 */}
{det && det.models.map((m) => )}
);
}
Object.assign(window, { DbScreen });