furry/chat/views.py

397 lines
12 KiB
Python

"""
Chat Views für Admin-Interface und Chat-Management
"""
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required, user_passes_test
from django.contrib import messages
from django.http import JsonResponse
from django.utils import timezone
from django.db.models import Q, Count
from django.core.paginator import Paginator
from .models import ChatRoom, ChatMessage, UserOnlineStatus, QuickResponse, ChatAnalytics
from .forms import QuickResponseForm
import json
def is_admin(user):
"""Prüfen ob User Admin ist"""
return user.is_staff or user.is_superuser
@login_required
def chat_dashboard(request):
"""Admin Chat Dashboard"""
if not is_admin(request.user):
messages.error(request, 'Zugriff verweigert.')
return redirect('home')
# Chat-Statistiken
total_rooms = ChatRoom.objects.count()
active_rooms = ChatRoom.objects.filter(status='active').count()
waiting_rooms = ChatRoom.objects.filter(status='waiting').count()
today_messages = ChatMessage.objects.filter(
created_at__date=timezone.now().date()
).count()
# Online Admins
online_admins = UserOnlineStatus.objects.filter(
is_online=True,
user__is_staff=True
).count()
# Letzte Chat-Räume
recent_rooms = ChatRoom.objects.select_related('customer', 'admin').order_by('-last_message_at')[:10]
# Quick Responses
quick_responses = QuickResponse.objects.filter(is_active=True).order_by('category', 'title')
context = {
'total_rooms': total_rooms,
'active_rooms': active_rooms,
'waiting_rooms': waiting_rooms,
'today_messages': today_messages,
'online_admins': online_admins,
'recent_rooms': recent_rooms,
'quick_responses': quick_responses,
}
return render(request, 'chat/dashboard.html', context)
@login_required
def chat_room_list(request):
"""Liste aller Chat-Räume"""
if not is_admin(request.user):
messages.error(request, 'Zugriff verweigert.')
return redirect('home')
# Filter
status_filter = request.GET.get('status', '')
search_query = request.GET.get('search', '')
rooms = ChatRoom.objects.select_related('customer', 'admin').order_by('-last_message_at')
if status_filter:
rooms = rooms.filter(status=status_filter)
if search_query:
rooms = rooms.filter(
Q(customer__username__icontains=search_query) |
Q(subject__icontains=search_query)
)
# Pagination
paginator = Paginator(rooms, 20)
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
context = {
'page_obj': page_obj,
'status_filter': status_filter,
'search_query': search_query,
'status_choices': ChatRoom.ROOM_STATUS_CHOICES,
}
return render(request, 'chat/room_list.html', context)
@login_required
def chat_room_detail(request, room_id):
"""Chat-Raum Detail-Ansicht"""
if not is_admin(request.user):
messages.error(request, 'Zugriff verweigert.')
return redirect('home')
room = get_object_or_404(ChatRoom, id=room_id)
# Admin dem Raum zuweisen wenn noch nicht zugewiesen
if not room.admin and room.status == 'waiting':
room.admin = request.user
room.status = 'active'
room.save()
# System-Nachricht
ChatMessage.objects.create(
room=room,
sender=request.user,
content=f"{request.user.username} ist dem Chat beigetreten",
message_type='system',
is_system_message=True
)
# Nachrichten laden
messages = room.messages.select_related('sender').order_by('created_at')
# Quick Responses
quick_responses = QuickResponse.objects.filter(is_active=True).order_by('category', 'title')
context = {
'room': room,
'messages': messages,
'quick_responses': quick_responses,
}
return render(request, 'chat/room_detail.html', context)
@login_required
def chat_room_assign(request, room_id):
"""Chat-Raum einem Admin zuweisen"""
if not is_admin(request.user):
return JsonResponse({'error': 'Zugriff verweigert'}, status=403)
room = get_object_or_404(ChatRoom, id=room_id)
if request.method == 'POST':
admin_id = request.POST.get('admin_id')
if admin_id:
try:
admin = User.objects.get(id=admin_id, is_staff=True)
room.admin = admin
room.status = 'active'
room.save()
# System-Nachricht
ChatMessage.objects.create(
room=room,
sender=request.user,
content=f"Chat wurde {admin.username} zugewiesen",
message_type='system',
is_system_message=True
)
return JsonResponse({'success': True})
except User.DoesNotExist:
return JsonResponse({'error': 'Admin nicht gefunden'}, status=400)
return JsonResponse({'error': 'Ungültige Anfrage'}, status=400)
@login_required
def chat_room_close(request, room_id):
"""Chat-Raum schließen"""
if not is_admin(request.user):
return JsonResponse({'error': 'Zugriff verweigert'}, status=403)
room = get_object_or_404(ChatRoom, id=room_id)
if request.method == 'POST':
room.status = 'closed'
room.save()
# System-Nachricht
ChatMessage.objects.create(
room=room,
sender=request.user,
content="Chat wurde geschlossen",
message_type='system',
is_system_message=True
)
return JsonResponse({'success': True})
return JsonResponse({'error': 'Ungültige Anfrage'}, status=400)
@login_required
def quick_response_list(request):
"""Quick Response Verwaltung"""
if not is_admin(request.user):
messages.error(request, 'Zugriff verweigert.')
return redirect('home')
responses = QuickResponse.objects.all().order_by('category', 'title')
if request.method == 'POST':
form = QuickResponseForm(request.POST)
if form.is_valid():
response = form.save(commit=False)
response.created_by = request.user
response.save()
messages.success(request, 'Quick Response erstellt.')
return redirect('chat:quick_response_list')
else:
form = QuickResponseForm()
context = {
'responses': responses,
'form': form,
}
return render(request, 'chat/quick_response_list.html', context)
@login_required
def quick_response_edit(request, response_id):
"""Quick Response bearbeiten"""
if not is_admin(request.user):
messages.error(request, 'Zugriff verweigert.')
return redirect('home')
response = get_object_or_404(QuickResponse, id=response_id)
if request.method == 'POST':
form = QuickResponseForm(request.POST, instance=response)
if form.is_valid():
form.save()
messages.success(request, 'Quick Response aktualisiert.')
return redirect('chat:quick_response_list')
else:
form = QuickResponseForm(instance=response)
context = {
'response': response,
'form': form,
}
return render(request, 'chat/quick_response_edit.html', context)
@login_required
def quick_response_delete(request, response_id):
"""Quick Response löschen"""
if not is_admin(request.user):
return JsonResponse({'error': 'Zugriff verweigert'}, status=403)
response = get_object_or_404(QuickResponse, id=response_id)
if request.method == 'POST':
response.delete()
return JsonResponse({'success': True})
return JsonResponse({'error': 'Ungültige Anfrage'}, status=400)
@login_required
def chat_analytics(request):
"""Chat Analytics Dashboard"""
if not is_admin(request.user):
messages.error(request, 'Zugriff verweigert.')
return redirect('home')
# Analytics für heute
today_analytics = ChatAnalytics.get_or_create_today()
# Wöchentliche Statistiken
from datetime import timedelta
week_ago = timezone.now().date() - timedelta(days=7)
weekly_stats = {
'total_messages': ChatMessage.objects.filter(
created_at__date__gte=week_ago
).count(),
'total_rooms': ChatRoom.objects.filter(
created_at__date__gte=week_ago
).count(),
'avg_response_time': 120, # Placeholder - würde aus echten Daten berechnet
'customer_satisfaction': 4.2, # Placeholder
}
# Top Quick Responses
top_responses = QuickResponse.objects.filter(
use_count__gt=0
).order_by('-use_count')[:5]
# Online Status
online_users = UserOnlineStatus.objects.filter(is_online=True)
context = {
'today_analytics': today_analytics,
'weekly_stats': weekly_stats,
'top_responses': top_responses,
'online_users': online_users,
}
return render(request, 'chat/analytics.html', context)
# API Views für AJAX
@login_required
def chat_messages_api(request, room_id):
"""API für Chat-Nachrichten"""
if not is_admin(request.user):
return JsonResponse({'error': 'Zugriff verweigert'}, status=403)
room = get_object_or_404(ChatRoom, id=room_id)
messages = room.messages.select_related('sender').order_by('created_at')
message_list = []
for msg in messages:
message_list.append({
'id': str(msg.id),
'sender': msg.sender.username,
'sender_id': msg.sender.id,
'content': msg.content,
'message_type': msg.message_type,
'file_url': msg.file.url if msg.file else None,
'image_url': msg.image.url if msg.image else None,
'created_at': msg.created_at.isoformat(),
'is_system': msg.is_system_message,
'read_at': msg.read_at.isoformat() if msg.read_at else None,
})
return JsonResponse({'messages': message_list})
@login_required
def chat_send_message_api(request, room_id):
"""API für Nachrichten senden"""
if not is_admin(request.user):
return JsonResponse({'error': 'Zugriff verweigert'}, status=403)
room = get_object_or_404(ChatRoom, id=room_id)
if request.method == 'POST':
try:
data = json.loads(request.body)
content = data.get('content', '').strip()
message_type = data.get('message_type', 'text')
if not content and message_type == 'text':
return JsonResponse({'error': 'Nachricht darf nicht leer sein'}, status=400)
message = ChatMessage.objects.create(
room=room,
sender=request.user,
content=content,
message_type=message_type,
)
return JsonResponse({
'success': True,
'message_id': str(message.id)
})
except json.JSONDecodeError:
return JsonResponse({'error': 'Ungültiges JSON'}, status=400)
return JsonResponse({'error': 'Ungültige Anfrage'}, status=400)
@login_required
def chat_mark_read_api(request, room_id):
"""API für Nachrichten als gelesen markieren"""
if not is_admin(request.user):
return JsonResponse({'error': 'Zugriff verweigert'}, status=403)
room = get_object_or_404(ChatRoom, id=room_id)
room.mark_messages_as_read(request.user)
return JsonResponse({'success': True})
@login_required
def quick_response_use_api(request, response_id):
"""API für Quick Response verwenden"""
if not is_admin(request.user):
return JsonResponse({'error': 'Zugriff verweigert'}, status=403)
response = get_object_or_404(QuickResponse, id=response_id)
response.increment_use_count()
return JsonResponse({
'success': True,
'content': response.content
})