Refactor: перенос API загрузки файлов в приложение api
- Создан api/v1/communications/views.py с функцией upload_message_with_attachments - Добавлен endpoint /api/v1/communications/upload-message/ - Обновлён frontend для использования правильного API пути - Удалён дублирующий код из communications/api_views.py - Обновлён communications/urls.py (убран старый endpoint) Теперь все API эндпоинты находятся в приложении api, как и должно быть
This commit is contained in:
parent
cdd26c91fe
commit
679651bbf6
1
backend/api/v1/communications/__init__.py
Normal file
1
backend/api/v1/communications/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
# backend/api/v1/communications/__init__.py
|
||||
113
backend/api/v1/communications/views.py
Normal file
113
backend/api/v1/communications/views.py
Normal file
@ -0,0 +1,113 @@
|
||||
# backend/api/v1/communications/views.py
|
||||
"""API views для чатов и сообщений"""
|
||||
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.db import transaction
|
||||
from django.http import JsonResponse
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.views.decorators.http import require_POST
|
||||
|
||||
from communications.models import (
|
||||
Chat,
|
||||
ChatMembership,
|
||||
Message,
|
||||
MessageAttachment,
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_POST
|
||||
def upload_message_with_attachments(request):
|
||||
"""Отправка сообщения с вложениями"""
|
||||
chat_id = request.POST.get('chat_id')
|
||||
content = request.POST.get('content', '').strip()
|
||||
|
||||
if not chat_id:
|
||||
return JsonResponse(
|
||||
{'ok': False, 'error': 'chat_id required'},
|
||||
status=400
|
||||
)
|
||||
|
||||
chat = get_object_or_404(Chat, pk=chat_id)
|
||||
|
||||
# Проверка доступа к чату
|
||||
membership = ChatMembership.objects.filter(
|
||||
chat=chat,
|
||||
user=request.user,
|
||||
is_active=True,
|
||||
can_send_messages=True
|
||||
).first()
|
||||
|
||||
if not membership:
|
||||
return JsonResponse(
|
||||
{'ok': False, 'error': 'Cannot send messages to this chat'},
|
||||
status=403
|
||||
)
|
||||
|
||||
# Если нет ни текста, ни файлов
|
||||
if not content and not request.FILES:
|
||||
return JsonResponse(
|
||||
{'ok': False, 'error': 'Content or files required'},
|
||||
status=400
|
||||
)
|
||||
|
||||
with transaction.atomic():
|
||||
# Создаем сообщение
|
||||
message = Message.objects.create(
|
||||
chat=chat,
|
||||
author=request.user,
|
||||
content=content or '',
|
||||
has_attachments=bool(request.FILES)
|
||||
)
|
||||
|
||||
# Обрабатываем все загруженные файлы
|
||||
attachments = []
|
||||
for file_key in request.FILES:
|
||||
uploaded_file = request.FILES[file_key]
|
||||
|
||||
# Определение типа файла
|
||||
mime_type = uploaded_file.content_type or ''
|
||||
if mime_type.startswith('image/'):
|
||||
file_type = 'image'
|
||||
elif mime_type.startswith('video/'):
|
||||
file_type = 'video'
|
||||
elif mime_type.startswith('audio/'):
|
||||
file_type = 'audio'
|
||||
else:
|
||||
file_type = 'file'
|
||||
|
||||
attachment = MessageAttachment.objects.create(
|
||||
message=message,
|
||||
file=uploaded_file,
|
||||
file_type=file_type,
|
||||
file_name=uploaded_file.name,
|
||||
file_size=uploaded_file.size,
|
||||
mime_type=mime_type
|
||||
)
|
||||
|
||||
attachments.append({
|
||||
'id': attachment.id,
|
||||
'file_name': attachment.file_name,
|
||||
'file_type': attachment.file_type,
|
||||
'file_url': attachment.file.url,
|
||||
'file_size': attachment.file_size,
|
||||
'mime_type': attachment.mime_type
|
||||
})
|
||||
|
||||
avatar_url = None
|
||||
if hasattr(request.user, 'avatar') and request.user.avatar:
|
||||
avatar_url = request.user.avatar.url
|
||||
|
||||
return JsonResponse({
|
||||
'ok': True,
|
||||
'message_id': message.id,
|
||||
'chat_id': chat.id,
|
||||
'author': {
|
||||
'id': request.user.id,
|
||||
'full_name': request.user.get_full_name(),
|
||||
'avatar': avatar_url
|
||||
},
|
||||
'content': message.content,
|
||||
'created_at': message.created_at.isoformat(),
|
||||
'attachments': attachments
|
||||
})
|
||||
@ -10,6 +10,7 @@ from .employees.views import (DepartmentRoleViewSet, DepartmentViewSet,
|
||||
from .feed.views import CommentViewSet, PostViewSet
|
||||
from .documents.views import DocumentViewSet
|
||||
from .requests_app.views import RequestViewSet
|
||||
from .communications.views import upload_message_with_attachments
|
||||
|
||||
app_name = "v1"
|
||||
|
||||
@ -36,5 +37,10 @@ urlpatterns = [
|
||||
path("auth/register/", RegisterAPIView.as_view(), name="register"),
|
||||
path("auth/resend-email/", ResendEmailAPIView.as_view(), name="resend-email"),
|
||||
path("auth/verify-email/", VerifyEmailAPIView.as_view(), name="verify-email"),
|
||||
path(
|
||||
"communications/upload-message/",
|
||||
upload_message_with_attachments,
|
||||
name="upload_message"
|
||||
),
|
||||
path("", include(router.urls)),
|
||||
]
|
||||
|
||||
@ -306,104 +306,8 @@ def pin_message(request, message_id):
|
||||
|
||||
|
||||
# ============ ATTACHMENTS ============
|
||||
|
||||
@login_required
|
||||
@require_POST
|
||||
def upload_message_with_attachments(request):
|
||||
"""Отправка сообщения с вложениями"""
|
||||
chat_id = request.POST.get('chat_id')
|
||||
content = request.POST.get('content', '').strip()
|
||||
|
||||
if not chat_id:
|
||||
return JsonResponse(
|
||||
{'ok': False, 'error': 'chat_id required'},
|
||||
status=400
|
||||
)
|
||||
|
||||
chat = get_object_or_404(Chat, pk=chat_id)
|
||||
|
||||
# Проверка доступа к чату
|
||||
membership = ChatMembership.objects.filter(
|
||||
chat=chat,
|
||||
user=request.user,
|
||||
is_active=True,
|
||||
can_send_messages=True
|
||||
).first()
|
||||
|
||||
if not membership:
|
||||
return JsonResponse(
|
||||
{'ok': False, 'error': 'Cannot send messages to this chat'},
|
||||
status=403
|
||||
)
|
||||
|
||||
# Если нет ни текста, ни файлов
|
||||
if not content and not request.FILES:
|
||||
return JsonResponse(
|
||||
{'ok': False, 'error': 'Content or files required'},
|
||||
status=400
|
||||
)
|
||||
|
||||
with transaction.atomic():
|
||||
# Создаем сообщение
|
||||
message = Message.objects.create(
|
||||
chat=chat,
|
||||
author=request.user,
|
||||
content=content or '',
|
||||
has_attachments=bool(request.FILES)
|
||||
)
|
||||
|
||||
# Обрабатываем все загруженные файлы
|
||||
attachments = []
|
||||
for file_key in request.FILES:
|
||||
uploaded_file = request.FILES[file_key]
|
||||
|
||||
# Определение типа файла
|
||||
mime_type = uploaded_file.content_type or ''
|
||||
if mime_type.startswith('image/'):
|
||||
file_type = 'image'
|
||||
elif mime_type.startswith('video/'):
|
||||
file_type = 'video'
|
||||
elif mime_type.startswith('audio/'):
|
||||
file_type = 'audio'
|
||||
else:
|
||||
file_type = 'file'
|
||||
|
||||
attachment = MessageAttachment.objects.create(
|
||||
message=message,
|
||||
file=uploaded_file,
|
||||
file_type=file_type,
|
||||
file_name=uploaded_file.name,
|
||||
file_size=uploaded_file.size,
|
||||
mime_type=mime_type
|
||||
)
|
||||
|
||||
attachments.append({
|
||||
'id': attachment.id,
|
||||
'file_name': attachment.file_name,
|
||||
'file_type': attachment.file_type,
|
||||
'file_url': attachment.file.url,
|
||||
'file_size': attachment.file_size,
|
||||
'mime_type': attachment.mime_type
|
||||
})
|
||||
|
||||
avatar_url = None
|
||||
if hasattr(request.user, 'avatar') and request.user.avatar:
|
||||
avatar_url = request.user.avatar.url
|
||||
|
||||
return JsonResponse({
|
||||
'ok': True,
|
||||
'message_id': message.id,
|
||||
'chat_id': chat.id,
|
||||
'author': {
|
||||
'id': request.user.id,
|
||||
'full_name': request.user.get_full_name(),
|
||||
'avatar': avatar_url
|
||||
},
|
||||
'content': message.content,
|
||||
'created_at': message.created_at.isoformat(),
|
||||
'attachments': attachments
|
||||
})
|
||||
|
||||
# Примечание: endpoint для загрузки сообщений с файлами
|
||||
# перенесён в api/v1/communications/views.py
|
||||
|
||||
@login_required
|
||||
@require_POST
|
||||
|
||||
@ -69,11 +69,7 @@ urlpatterns = [
|
||||
),
|
||||
|
||||
# Attachments
|
||||
path(
|
||||
"api/upload-message/",
|
||||
api_views.upload_message_with_attachments,
|
||||
name="api_upload_message"
|
||||
),
|
||||
# Основной endpoint для загрузки сообщений с файлами находится в api/v1
|
||||
path(
|
||||
"api/attachment/upload/",
|
||||
api_views.upload_attachment,
|
||||
|
||||
@ -344,7 +344,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
formData.append('chat_id', '{{ chat.id }}');
|
||||
|
||||
try {
|
||||
const response = await fetch('/communications/api/upload-message/', {
|
||||
const response = await fetch('/api/v1/communications/upload-message/', {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user