feat: подбор типового отраслевого объекта с фильтром по сфере
- detect_sphere(): автоопределение сферы по ключевым словам названия/ назначения/описания объекта (здравоохранение, наука, транспорт, связь, энергетика, банки, ТЭК, атомная, ОПК, ракетно-космическая, горная, металлургия, химия) - suggest_typical_object_program: фильтр по сфере в приоритете — 1) сфера из комбобокса, 2) сфера объекта (isys.sphere), 3) автодетект, 4) иначе все сферы. ОПК-объекту НЕ подбираются объекты из здравоохранения и других сфер - если в своей сфере совпадений нет — возвращается пусто, оператор выбирает сферу вручную
This commit is contained in:
+58
-2
@@ -456,9 +456,24 @@ def suggest_typical_object_program(isys, limit=10, sphere=None):
|
|||||||
if not obj_words:
|
if not obj_words:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
# Фильтр по сфере (важно: не подбирать ОПК-объекту сферу из здравоохранения):
|
||||||
|
# 1) сфера, переданная явно (выбрана в комбобоксе);
|
||||||
|
# 2) сфера, уже заполненная у объекта (isys.sphere);
|
||||||
|
# 3) автодетект по названию/назначению/описанию;
|
||||||
|
# 4) иначе — все сферы (подбор без фильтра).
|
||||||
|
used_sphere = sphere
|
||||||
|
if not used_sphere:
|
||||||
|
used_sphere = (getattr(isys, 'sphere', '') or '').strip() or None
|
||||||
|
if not used_sphere:
|
||||||
|
used_sphere = detect_sphere(isys)
|
||||||
|
|
||||||
cands = _load_all_typical()
|
cands = _load_all_typical()
|
||||||
if sphere:
|
if used_sphere:
|
||||||
cands = [c for c in cands if c['sphere'] == sphere]
|
cands = [c for c in cands if c['sphere'] == used_sphere]
|
||||||
|
if not cands:
|
||||||
|
# Сфера определена, но объектов нет — не расширяем на другие сферы,
|
||||||
|
# возвращаем пусто (оператор выберет сферу вручную)
|
||||||
|
return []
|
||||||
|
|
||||||
weights = _idf_weights(cands)
|
weights = _idf_weights(cands)
|
||||||
|
|
||||||
@@ -474,3 +489,44 @@ def suggest_typical_object_program(isys, limit=10, sphere=None):
|
|||||||
|
|
||||||
scored.sort(key=lambda x: (-x['score'], x['name']))
|
scored.sort(key=lambda x: (-x['score'], x['name']))
|
||||||
return scored[:limit]
|
return scored[:limit]
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# Автоопределение сферы деятельности объекта по ключевым словам
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
SPHERE_KEYWORDS = [
|
||||||
|
('Здравоохранение', ['медицин', 'здрав', 'поликлиник', 'больниц', 'лечеб', 'клиник', 'фармацевт', 'аптек', 'пациент', 'врач', 'диагностик', 'лабораторн', 'медпомощ']),
|
||||||
|
('Наука', ['научн', 'исследован', 'разработк', 'лаборатор', 'академи', 'институт', 'ниокр', 'наука']),
|
||||||
|
('Транспорт', ['транспорт', 'перевоз', 'автомобил', 'железнодорожн', 'авиа', 'морск', 'речн', 'метрополитен', 'вокзал', 'логистик', 'движени']),
|
||||||
|
('Связь', ['связ', 'телекоммуникац', 'оператор связи', 'интернет-провайдер', 'передач данных', 'сети связи', 'телефон']),
|
||||||
|
('Энергетика', ['энерг', 'электро', 'теплоснабж', 'электроснабж', 'генерац', 'подстанц', 'котельн', 'энергосистем']),
|
||||||
|
('Государственная регистрация прав', ['регистрац', 'кадастр', 'недвижим', 'реестр']),
|
||||||
|
('Банковская сфера и финансовый рынок', ['банк', 'финанс', 'кредит', 'платеж', 'расчет', 'страхов', 'клирин', 'депозитар', 'пенсионн', 'фондов']),
|
||||||
|
('Топливно-энергетический комплекс', ['нефт', 'газ', 'топлив', 'трубопровод', 'месторожден', 'переработк', 'уголь', 'нефте']),
|
||||||
|
('Атомная энергетика', ['атомн', 'ядерн', 'радиацион', 'аэс', 'реактор', 'атом']),
|
||||||
|
('Оборонная промышленность', ['оборон', 'военн', 'вооружен', 'оружи', 'оборонно', 'опк', 'госзаказ', 'госконтракт', 'боеприпас', 'ввт', 'минобороны']),
|
||||||
|
('Ракетно-космическая промышленность', ['ракет', 'космическ', 'спутник', 'космодром', 'орбит', 'космос', 'пуск']),
|
||||||
|
('Горнодобывающая промышленность', ['горн', 'добыч', 'шахт', 'рудник', 'карьер', 'месторожден']),
|
||||||
|
('Металлургическая промышленность', ['металлург', 'прокат', 'стал', 'чугун', 'цветн', 'сплав']),
|
||||||
|
('Химическая промышленность', ['химическ', 'хим', 'нефтехим', 'взрывчат', 'кислот', 'реактив', 'удобрен']),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def detect_sphere(isys):
|
||||||
|
"""Определяет сферу деятельности объекта КИИ по названию/назначению/описанию.
|
||||||
|
|
||||||
|
Возвращает название сферы или None, если определить не удалось.
|
||||||
|
"""
|
||||||
|
text = ' '.join([
|
||||||
|
getattr(isys, 'name', '') or '',
|
||||||
|
getattr(isys, 'purpose', '') or '',
|
||||||
|
getattr(isys, 'description', '') or '',
|
||||||
|
]).lower()
|
||||||
|
best = None
|
||||||
|
best_score = 0
|
||||||
|
for sphere, keywords in SPHERE_KEYWORDS:
|
||||||
|
score = sum(1 for kw in keywords if kw in text)
|
||||||
|
if score > best_score:
|
||||||
|
best = sphere
|
||||||
|
best_score = score
|
||||||
|
return best if best_score > 0 else None
|
||||||
|
|||||||
Reference in New Issue
Block a user