10 KiB
10 KiB
Улучшения модала создания чатов
Что добавлено
1. Новые типы чатов
- Чат отдела (
department) - автоматически включает всех сотрудников отдела - Глобальный чат (
global) - для всей компании
2. Новые поля
Аватар чата
- Загрузка изображения (JPG/PNG/GIF, до 5 МБ)
- Предпросмотр перед загрузкой
- Автоматическое сжатие до 512x512px (до 500KB)
- Удаление старых файлов при замене
Выбор отдела
- Для типа "Чат отдела"
- Dropdown со всеми отделами
- Автодобавление всех сотрудников отдела
Включить всех сотрудников
- Для типов:
announcement,global,channel - Автодобавление всех активных сотрудников компании
- Ограниченная отправка для
channelиannouncement
Основной чат
- Для типов:
global,department - Только 1 основной глобальный чат
- Только 1 основной чат на отдел
- Валидация на уровне API
3. Улучшенный UI
Типы чатов с подсказками
Личный: приватный чат с 1 сотрудником
Группа: чат с несколькими участниками
Отдел: автоматически включает всех сотрудников отдела
Канал: для объявлений с ограниченной отправкой
Объявления: односторонняя рассылка
Глобальный: общий чат компании (может быть только 1 основной)
Динамическое переключение полей
- Private: только выбор участника
- Group: название + описание + аватар + участники
- Department: название + описание + аватар + отдел + "основной"
- Global: название + описание + аватар + "включить всех" + "основной"
- Channel/Announcement: название + описание + аватар + "включить всех"
4. API изменения
FormData support
// Теперь поддерживает загрузку файлов
const formData = new FormData();
formData.append('type', 'group');
formData.append('name', 'Команда разработки');
formData.append('avatar', file);
formData.append('participant_ids', [1, 2, 3]);
Новые параметры API
avatar(file) - файл аватараdepartment_id(int) - ID отдела дляtype=departmentinclude_all_employees(bool) - включить всех сотрудниковis_main(bool) - сделать основным чатом
Валидация
- ✅ Проверка типа чата
- ✅ Обязательное название (кроме private)
- ✅ Обязательный отдел для
department - ✅ Уникальность основного глобального чата
- ✅ Уникальность основного чата отдела
5. Автоматическое сжатие аватаров
Signal compress_and_cleanup_chat_avatar
@receiver(pre_save, sender='communications.Chat')
def compress_and_cleanup_chat_avatar(sender, instance, **kwargs):
# 1. Сжимает новый аватар до 512x512px (макс 500KB)
# 2. Удаляет старый файл при замене
# 3. Использует LANCZOS для высокого качества
Параметры сжатия
- Размер: 512x512px (оптимально для отображения)
- Формат: JPEG (универсальный)
- Качество: 50-85 (бинарный поиск оптимального)
- Максимум: 500KB
6. Автодобавление участников
Для include_all_employees=True
# Добавляются все активные сотрудники
all_employees = Employee.objects.filter(is_active=True)
# Права зависят от типа чата:
# - channel/announcement: can_send_messages=False
# - остальные: can_send_messages=True
Для type=department
# Добавляются сотрудники отдела
dept_employees = EmployeeDepartment.objects.filter(
department=department,
is_active=True
)
# Все получают can_send_messages=True
Примеры использования
Создать групповой чат с аватаром
const formData = new FormData();
formData.append('type', 'group');
formData.append('name', 'DevOps Team');
formData.append('description', 'Обсуждение инфраструктуры');
formData.append('avatar', avatarFile);
formData.append('participant_ids', 5);
formData.append('participant_ids', 12);
formData.append('participant_ids', 23);
fetch('/communications/api/chat/create/', {
method: 'POST',
headers: { 'X-CSRFToken': csrftoken },
body: formData
});
Создать основной чат отдела
const formData = new FormData();
formData.append('type', 'department');
formData.append('name', 'Отдел разработки');
formData.append('department_id', 3);
formData.append('is_main', 'true');
fetch('/communications/api/chat/create/', {
method: 'POST',
headers: { 'X-CSRFToken': csrftoken },
body: formData
});
Создать канал с аватаром для всех
const formData = new FormData();
formData.append('type', 'channel');
formData.append('name', 'Новости компании');
formData.append('description', 'Официальные объявления');
formData.append('avatar', avatarFile);
formData.append('include_all_employees', 'true');
fetch('/communications/api/chat/create/', {
method: 'POST',
headers: { 'X-CSRFToken': csrftoken },
body: formData
});
Технические детали
Структура модели Chat
class Chat(models.Model):
type = CharField(choices=[...])
name = CharField(max_length=255)
description = TextField()
avatar = ImageField(upload_to='chat_avatars/%Y/%m/') # NEW
created_by = ForeignKey(Employee)
department = ForeignKey(Department) # NEW
include_all_employees = BooleanField(default=False) # NEW
is_main = BooleanField(default=False) # NEW
participants = ManyToManyField(Employee)
created_at = DateTimeField(auto_now_add=True)
Constraints
# Только 1 основной глобальный чат
UniqueConstraint(
fields=["type"],
condition=Q(is_main=True, type="global"),
name="unique_main_global_chat"
)
# Только 1 основной чат на отдел
UniqueConstraint(
fields=["type", "department"],
condition=Q(is_main=True, type="department"),
name="unique_main_department_chat"
)
Путь хранения аватаров
media/
chat_avatars/
2024/
11/
chat_avatar_abc123.jpg (сжато до 512x512, <500KB)
Совместимость
Backward compatibility
- ✅ Старые чаты без аватаров работают как прежде
- ✅ API поддерживает JSON (legacy) и FormData (новый)
- ✅ Все новые поля опциональные (кроме валидируемых случаев)
Frontend
- Модал: Bootstrap 5
- Preview: FileReader API
- Validation: Client-side + Server-side
- CSRF: Из cookie или hidden input
Производительность
Оптимизации
- ✅ Сжатие аватаров на лету (JPEG quality 50-85)
- ✅ Удаление старых файлов (нет дубликатов)
- ✅ Batch добавление участников (без N+1 queries)
- ✅
select_related('employee')для отделов
Размеры файлов
- До: 8.3 MB PNG, 800+ KB JPEG
- После: <500 KB JPEG, 512x512px
- Экономия: ~90-95% места на диске
Тестирование
Проверить создание чатов
- Личный чат с 1 участником ✅
- Групповой чат с аватаром ✅
- Чат отдела с автодобавлением ✅
- Глобальный основной чат (только 1) ✅
- Канал для всех с ограниченной отправкой ✅
Проверить сжатие
- Загрузить PNG 5MB → сжато до <500KB JPEG ✅
- Заменить аватар → старый файл удален ✅
- Проверить preview в модале ✅
Проверить валидацию
- Попытка создать 2 основных глобальных чата → ошибка ✅
- Чат отдела без выбора отдела → ошибка ✅
- Файл >5MB → отклонен на клиенте ✅
Changelog
v1.0 (30 ноября 2024)
- ✅ Добавлены поля: avatar, department, include_all_employees, is_main
- ✅ Реализовано автосжатие аватаров (512x512, <500KB)
- ✅ Добавлены типы: department, global
- ✅ Динамические поля в модале
- ✅ API поддержка FormData + файлов
- ✅ Валидация основных чатов
- ✅ Автодобавление участников по правилам
- ✅ Signal для сжатия и cleanup
TODO
- Crop аватара перед загрузкой (client-side)
- Batch upload нескольких аватаров
- История изменений аватара чата
- Права на изменение аватара (только owner/admin)
- Предпросмотр аватара в списке чатов
- Поиск чатов по названию в модале