7cbc712dc4
Если на сайте конкурента короткий локальный номер без кода города И на странице нет ни одного полного номера, движок берёт код по региону конкурента. Основной путь прежний — код со страницы; региональный код лишь запасной. - RegionAreaCode: субъект РФ → телефонный код адм. центра, только уверенные 3-значные коды миллионников, ключ по имени из RussianRegions, неизвестный → null - RealCompetitorAgent резолвит regionCode и пробрасывает в CandidateBuilder→HtmlPhoneScanner - ограничение задокументировано: код центра, не выдумываем при отсутствии в карте - тесты карты и сквозной достройки; бэкенд автоподбора 130/130 НЕ на проде, воркстри avtopodbor. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
60 lines
3.8 KiB
PHP
60 lines
3.8 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace App\Support;
|
||
|
||
use App\Services\Autopodbor\Agent\Extract\HtmlPhoneScanner;
|
||
|
||
/**
|
||
* Запасной телефонный код города по коду субъекта РФ (1..89, см. {@see RussianRegions}).
|
||
*
|
||
* Назначение: достройка коротких локальных номеров на сайте конкурента, КОГДА на странице
|
||
* нет ни одного полного номера, по которому код можно вычислить (основной путь —
|
||
* «код со страницы» в {@see HtmlPhoneScanner}; этот
|
||
* справочник — лишь запасной).
|
||
*
|
||
* ВАЖНО — ограничение по точности (решение владельца «по столице региона»):
|
||
* • Берём телефонный код АДМИНИСТРАТИВНОГО ЦЕНТРА субъекта. Для конкурента из НЕ-столичного
|
||
* города региона код может отличаться (Норильск 3919 ≠ Красноярск 391) — поэтому достройка
|
||
* «по региону» срабатывает только при отсутствии кода на самой странице.
|
||
* • Внесены ТОЛЬКО уверенные 3-значные коды (достраивают 7-значный локальный номер). Регионы
|
||
* без однозначного 3-значного кода центра НЕ внесены → forSubject() вернёт null, и движок
|
||
* не выдумывает код (короткий номер уйдёт в «требует проверки»). Карта расширяема.
|
||
*
|
||
* Ключ — каноничное имя субъекта из RussianRegions::CODE_TO_NAME (а не номер строки),
|
||
* чтобы исключить ошибку индекса при сопоставлении кода и города.
|
||
*/
|
||
final class RegionAreaCode
|
||
{
|
||
/** @var array<string, string> каноничное имя субъекта => 3-значный код адм. центра */
|
||
private const AREA_BY_NAME = [
|
||
'Москва' => '495',
|
||
'Санкт-Петербург' => '812',
|
||
'Красноярский край' => '391', // Красноярск
|
||
'Новосибирская область' => '383', // Новосибирск
|
||
'Свердловская область' => '343', // Екатеринбург
|
||
'Республика Татарстан' => '843', // Казань
|
||
'Нижегородская область' => '831', // Нижний Новгород
|
||
'Самарская область' => '846', // Самара
|
||
'Ростовская область' => '863', // Ростов-на-Дону
|
||
'Воронежская область' => '473', // Воронеж
|
||
'Пермский край' => '342', // Пермь
|
||
'Приморский край' => '423', // Владивосток
|
||
'Республика Башкортостан' => '347', // Уфа
|
||
'Челябинская область' => '351', // Челябинск
|
||
'Краснодарский край' => '861', // Краснодар
|
||
];
|
||
|
||
/** 3-значный телефонный код центра субъекта или null, если уверенного кода нет. */
|
||
public static function forSubject(int $subjectCode): ?string
|
||
{
|
||
$name = RussianRegions::CODE_TO_NAME[$subjectCode] ?? null;
|
||
if ($name === null) {
|
||
return null;
|
||
}
|
||
|
||
return self::AREA_BY_NAME[$name] ?? null;
|
||
}
|
||
}
|