Поставщик не нашёл этот VIN в своей базе (код {v.code}, «{v.msg}»).
{v.local ? (
{v.local.generic
? Почему: префикс {v.local.wmi} — машина собрана не в Китае (VIN китайских заводов начинаются на L). Какой это завод, у нас пока не записано.
: Почему: префикс {v.local.wmi} — это {v.local.brands}, сборка «{v.local.plant}».} Китайские каталоги знают VIN китайских заводов,
а у машин местной сборки свой код завода — такие VIN в их базе отсутствуют. {v.local.note}
) : (
Префикс {vin.slice(0, 3)} в нашем списке местных сборок не значится. Возможные причины: марка не
покрыта поставщиком, ошибка в VIN, или это местная сборка, которой ещё нет в списке (Вадим может добавить её в админке → Префиксы).
)}
Ответ сохранён — повторный ввод не спишет квоту. Другой VIN
в базе поставщика: {v.brand} {v.sys}
{v.alias ? " — внутреннее китайское название той же машины" : " — русское название модели не задано (админка → Модели)"}
VIN размер колёс не определяет. {v.rims.map((r) => `${r.rim}: ${r.tyres.join(", ")}`).join(" · ")}
По VIN поставщик отдаёт {v.trims.length} комплектаций за {v.years.join(", ")} гг. — до одной не сужает.
{rim && rimMatchVinYear.length === 1 && <> Для {v.vin_year} года и {rim} подходит одна — выберите её.>}
{rim && rimMatchVinYear.length > 1 && <> Для {v.vin_year} года и {rim} подходят {rimMatchVinYear.length}: для тормозов разницы обычно нет, для салона и электрики может понадобиться уточнение.>}
{!selected && {rim ? "Выберите комплектацию" : "Сначала размер колёс, потом комплектация"}}
);
}
// ------------------------------------------------------------ 3. подбор
const BADGE = {
exact: { cls: "exact", text: "НОМЕР ЭТОЙ МАШИНЫ", hint: "API явно подтвердил номер для этой комплектации (containFlag = 0)" },
analog: { cls: "analog", text: "АНАЛОГ ПО ПОЗИЦИИ — ПРОВЕРЬТЕ", hint: "Номер этой машине не принадлежит: система подставила деталь той же позиции (containFlag = 1). Перед заказом сверьте." },
unknown: { cls: "unknown", text: "ПРИВЯЗКА НЕ УКАЗАНА", hint: "API не сообщил, родной ли это номер для комплектации (поле containFlag пустое). Точность не гарантирована." },
};
function mergeParts(parts) {
// одинаковый номер с одинаковым примечанием склеиваем (API шлёт дубли с заменой и без)
const m = new Map();
for (const p of parts) {
const k = `${p.key}|${p.partNumber}|${p.comment || ""}`;
if (!m.has(k)) { m.set(k, { ...p, substitutes: p.substitute ? [p.substitute] : [], refs: p.ref ? [p.ref] : [] }); continue; }
const x = m.get(k);
if (p.substitute && !x.substitutes.includes(p.substitute)) x.substitutes.push(p.substitute);
if (p.ref && !x.refs.includes(p.ref)) x.refs.push(p.ref);
if (x.badge !== p.badge) x.badge = x.badge === "analog" || p.badge === "analog" ? "analog" : "unknown";
}
// группы: один ключ + одно название, разные номера → варианты
const groups = new Map();
for (const p of m.values()) {
const g = `${p.key}|${p.stdPartName}`;
if (!groups.has(g)) groups.set(g, []);
groups.get(g).push(p);
}
return [...groups.values()];
}
function PartBody({ p, compact }) {
return (
<>
{/* Поиск поставщика нечёткий: оригинал рядом с переводом, чтобы было видно, если вернулось не то */}
Поставщик ищет только по-китайски: русское слово переводится по словарю. Можно ввести номер детали или китайское слово.
{err &&
{err}
}
{res && res.mode === "no_dict" && (
Слова «{res.q}» нет в словаре — поставщику искать нечего. {res.suggestions.length > 0 ? "Возможно, вы имели в виду:" : "Добавить слово может Вадим в админке → Словарь."}
{res.suggestions.length > 0 && (
{res.suggestions.map((s) => (
))}
)}
)}
{res && res.mode !== "no_dict" && (
<>
{res.mode === "oe" ? "Поиск по номеру" : res.mode === "zh" ? "Поиск по-китайски" : `Запрос к поставщику: ${res.keys.join(", ")}`}найдено {res.parts.length}номер этой машиныаналог по позиции — проверьтепривязка не указана
{res.parts.length === 0 && (
Поставщик ничего не нашёл.
{res.per_key.map((k) => `${k.key}: ${k.code === "402" ? "нет результата" : k.code}`).join(" · ")}
{res.mode === "oe" && " · Номер отсутствует в базе поставщика или не относится к этой комплектации."}
)}
{/* «Варианты» — только развилка по дате сборки. Одинаковое stdPartName у разных деталей
(передний и задний сайлентблок рычага) — это разные детали, а не выбор. */}
{groups.map((list) => list.length > 1 && list.some((p) => p.date_split)
?
: list.map((p) => ))}
>
)}
);
}
// ------------------------------------------------------------ 4. схема
function Scheme({ vin, route, setCtx, lastSearch }) {
const { mjsid, image, prefix, focus, rim } = route.q;
const [s, setS] = useState(null), [err, setErr] = useState(""), [full, setFull] = useState(false);
useEffect(() => {
setS(null); setErr("");
api(`/api/scheme?${new URLSearchParams({ image, prefix: prefix || "", vin, mjsid })}`).then(setS).catch((x) => setErr(x.message));
}, [image]);
useEffect(() => { setCtx("Схема узла"); }, []);
useEffect(() => {
const f = (e) => { if (e.key === "Escape") setFull(false); };
if (full) { addEventListener("keydown", f); return () => removeEventListener("keydown", f); }
}, [full]);
// пока getPartByImage отвечает 403 — список из результатов поиска с той же схемой
const fromSearch = useMemo(() => {
if (!lastSearch || lastSearch.vin !== vin) return [];
const seen = new Set();
return lastSearch.res.parts.filter((p) => p.image === image && !seen.has(p.partNumber + p.ref) && seen.add(p.partNumber + p.ref));
}, [lastSearch, image]);
const list = s && s.parts_status === "ok" ? s.parts : fromSearch;
const back = `#/vin/${vin}/parts?mjsid=${mjsid}${rim ? `&rim=${rim}` : ""}`;
return (
{s.width && `${s.width}×${s.height}`} · нажмите, чтобы открыть во весь экранв работе Точки на схеме
Схема сохранена у нас — ссылки поставщика временные. Кликабельных позиций пока нет: метод деталей схемы отвечает ошибкой ({s.parts_code || "нет ответа"}), вопрос у поставщика. Номера позиций — в списке справа.
Детали на схеме
{s.parts_status !== "ok" && (
Полный список деталей узла поставщик пока не отдаёт. Показаны найденные поиском детали с этой схемы.
Прогоняет все китайские ключи словаря по одной машине и отмечает, сколько деталей нашёл каждый. Квоту не тратит (поиск бесплатный), идёт несколько минут.