Улучшен поиск клиента по телефону

Исправления:
- Поиск по телефону теперь работает независимо от формата ввода (иконки, пробелы, +/-)
- Добавлена поддержка поиска по цифрам телефона (например, введение '291234' найдет +375291234567)
- Оптимизирована задержка AJAX запроса (300ms вместо 250ms)
- Добавлена обработка ошибок AJAX с логированием
- Улучшена обработка пустых результатов

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-10 22:24:36 +03:00
parent 74ece6dd66
commit 000b791702
2 changed files with 42 additions and 11 deletions

View File

@@ -148,12 +148,31 @@ def api_search_customers(request):
# Пытаемся нормализовать номер телефона для поиска # Пытаемся нормализовать номер телефона для поиска
phone_normalized = normalize_query_phone(query) phone_normalized = normalize_query_phone(query)
# Для поиска по телефону: извлекаем только цифры и ищем по ним
# Это позволит найти клиента независимо от формата ввода
query_digits = ''.join(c for c in query if c.isdigit())
# Ищем по имени, email или телефону # Ищем по имени, email или телефону
customers = Customer.objects.filter( # Используем Q-объекты для OR условий
Q(name__icontains=query) | q_objects = Q(name__icontains=query) | Q(email__icontains=query)
Q(email__icontains=query) |
Q(phone__icontains=phone_normalized) # Для телефона ищем по нормализованному номеру и по цифрам
).order_by('name')[:20] # Ограничиваем 20 результатами if phone_normalized:
q_objects |= Q(phone__icontains=phone_normalized)
if query_digits:
# Ищем клиентов, чьи телефоны содержат введенные цифры
customers_by_phone = Customer.objects.filter(phone__isnull=False)
matching_by_digits = []
for customer in customers_by_phone:
customer_digits = ''.join(c for c in str(customer.phone) if c.isdigit())
if query_digits in customer_digits:
matching_by_digits.append(customer.pk)
if matching_by_digits:
q_objects |= Q(pk__in=matching_by_digits)
customers = Customer.objects.filter(q_objects).distinct().order_by('name')[:20]
results = [] results = []

View File

@@ -406,29 +406,41 @@ document.addEventListener('DOMContentLoaded', function() {
language: 'ru', language: 'ru',
placeholder: 'Начните вводить имя, телефон или email', placeholder: 'Начните вводить имя, телефон или email',
minimumInputLength: 1, minimumInputLength: 1,
allowClear: true,
ajax: { ajax: {
url: '{% url "customers:api-search-customers" %}', url: '{% url "customers:api-search-customers" %}',
dataType: 'json', dataType: 'json',
delay: 250, delay: 300,
quietMillis: 250,
data: function(params) { data: function(params) {
return { return {
q: params.term, q: params.term || '',
page: params.page || 1 page: params.page || 1
}; };
}, },
processResults: function(data) { processResults: function(data) {
return { return {
results: data.results, results: data.results || [],
pagination: { pagination: {
more: data.pagination.more more: data.pagination ? data.pagination.more : false
} }
}; };
}, },
cache: true cache: true,
error: function() {
console.log('Ошибка при поиске клиента');
}
}, },
templateResult: formatCustomerOption, templateResult: formatCustomerOption,
templateSelection: formatCustomerSelection, templateSelection: formatCustomerSelection,
escapeMarkup: function(markup) { return markup; } escapeMarkup: function(markup) { return markup; },
matcher: function(params, data) {
// Позволяем все результаты, фильтрация на сервере
if ($.trim(params.term) === '') {
return null;
}
return data;
}
}); });
// Форматирование опции в списке // Форматирование опции в списке