удалени лишнего после аварии, работа за рабочий день 07.08.2026
This commit is contained in:
@@ -4,7 +4,65 @@ import requests
|
||||
import pandas as pd
|
||||
from config import OLLAMA_URL, OLLAMA_MODEL
|
||||
from core.database import get_all_rules_from_db
|
||||
from core.database import get_department_synonyms_dict, add_department_synonym_to_db
|
||||
|
||||
def resolve_department_exception_ai(dept_1c, dept_scud, exception_departments):
|
||||
"""
|
||||
Универсальный сопоставитель отделов.
|
||||
Проверяет 1С, СКУД, локальную базу синонимов SQLite и задействует ИИ для сложных случайных аббревиатур.
|
||||
"""
|
||||
if not exception_departments:
|
||||
return False
|
||||
|
||||
d_1c = str(dept_1c).strip().lower() if dept_1c else ""
|
||||
d_scud = str(dept_scud).strip().lower() if dept_scud else ""
|
||||
exc_list = [d.strip().lower() for d in exception_departments]
|
||||
|
||||
# 1. Прямая проверка: если точное имя или подстрока уже совпали в 1С или СКУД
|
||||
for exc in exc_list:
|
||||
if exc and (exc in d_1c or exc in d_scud or d_1c in exc or d_scud in exc):
|
||||
return True
|
||||
|
||||
# 2. Проверка по сохраненной Базе Знаний синонимов из SQLite
|
||||
synonyms = get_department_synonyms_dict()
|
||||
for exc in exc_list:
|
||||
# Если в БД зафиксировано: 'овк' -> 'отдел внутреннего контроля'
|
||||
full_from_db = synonyms.get(exc, "")
|
||||
if full_from_db and (full_from_db in d_1c or full_from_db in d_scud):
|
||||
return True
|
||||
|
||||
# 3. Умный ИИ-арбитраж (если отдел спорный и еще не сохранен в БД)
|
||||
if d_1c or d_scud:
|
||||
dept_to_check = d_1c if d_1c else d_scud
|
||||
prompt = f"""
|
||||
Ты — кадровый аналитик.
|
||||
Проверь, является ли отдел сотрудника "{dept_to_check}" тем же самым подразделением, что и один из отделов-исключений: {exception_departments}?
|
||||
|
||||
Примеры:
|
||||
- "Отдел внутреннего контроля" — это "ОВК" (Да)
|
||||
- "Отдел технического обеспечения" — это "ОТО" (Да)
|
||||
|
||||
Ответь СТРОГО в формате JSON:
|
||||
{{
|
||||
"is_match": true/false,
|
||||
"matched_exception": "Название из списка исключений",
|
||||
"explanation": "краткое объяснение"
|
||||
}}
|
||||
"""
|
||||
try:
|
||||
raw_res = ask_ollama(prompt, system_prompt="Отвечай только валидным JSON.")
|
||||
match = re.search(r'\{.*\}', raw_res, re.DOTALL)
|
||||
if match:
|
||||
data = json.loads(match.group(0))
|
||||
if data.get("is_match"):
|
||||
matched_exc = data.get("matched_exception", "").lower()
|
||||
# Запоминаем открытую ИИ связь в SQLite навсегда!
|
||||
add_department_synonym_to_db(matched_exc, dept_to_check)
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"[⚠️] Ошибка ИИ-арбитража отделов: {e}")
|
||||
|
||||
return False
|
||||
|
||||
def ask_ollama(prompt, system_prompt=None):
|
||||
"""
|
||||
|
||||
@@ -40,17 +40,14 @@ def review_ai_decisions(report_text, suspicious_cases):
|
||||
elif user_input_clean in ['н', 'нет', 'no', 'n', '-']:
|
||||
print(" [ℹ️] Решение отклонено оператором.")
|
||||
elif user_input:
|
||||
# Если оператор ввел действительно новое текстовое правило
|
||||
new_rule = f"Правило по {fio_target}: {user_input}"
|
||||
|
||||
add_rule_to_db(new_rule, added_by="Human_Admin")
|
||||
if save_rule:
|
||||
try:
|
||||
save_rule(new_rule)
|
||||
except Exception:
|
||||
pass
|
||||
# Если оператор обучает систему синониму отделов
|
||||
if "отдел" in user_input_clean or "овк" in user_input_clean:
|
||||
from core.database import add_department_synonym_to_db
|
||||
add_department_synonym_to_db(user_input.strip(), "отдел внутреннего контроля")
|
||||
|
||||
print(f" [✓] Новое правило записано в Базу Знаний: {new_rule}")
|
||||
new_rule = f"Правило: {user_input}"
|
||||
add_rule_to_db(new_rule, added_by="Human_Admin")
|
||||
print(f" [✓] Новое правило записано в Базу Знаний SQLite: {new_rule}")
|
||||
else:
|
||||
print(" [ℹ️] Запись пропущена.")
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import pyodbc
|
||||
from openpyxl.utils import get_column_letter
|
||||
|
||||
from config import SCUD_DIR, clean_scud_fio_light, load_exceptions
|
||||
from core.database import save_scud_to_db, has_scud_logs_for_date
|
||||
from core.database import save_scud_to_db, has_scud_logs_for_date, has_yesterday_final_snapshot
|
||||
|
||||
warnings.filterwarnings("ignore", message="pandas only supports SQLAlchemy connectable")
|
||||
|
||||
@@ -227,8 +227,8 @@ def run_export(input_date: str | None = None, save_xlsx: bool = True, debug: boo
|
||||
|
||||
# ⚡️ ПРОВЕРКА НАЛИЧИЯ ВЧЕРАШНЕГО ДНЯ В SQLITE:
|
||||
# Если это вчерашний день и его снапшот уже зафиксирован в SQLite — пропускаем тяжелый запрос к MS SQL
|
||||
if is_yesterday and has_scud_logs_for_date(processing_date_str):
|
||||
log(f"[ℹ️] Вчерашний день ({processing_date_str}) уже зафиксирован в SQLite. Пропускаем запрос к MS SQL.")
|
||||
if is_yesterday and has_yesterday_final_snapshot(processing_date_str):
|
||||
log(f"[ℹ️] Вчерашний день ({processing_date_str}) уже зафиксирован финишным снапшотом Y. Пропускаем запрос к MS SQL.")
|
||||
continue
|
||||
|
||||
if is_yesterday:
|
||||
|
||||
Reference in New Issue
Block a user