from rest_framework import viewsets, status, permissions from rest_framework.decorators import action from rest_framework.response import Response from django.utils import timezone from datetime import timedelta from .models import Meeting, Participant, Message from .serializers import MeetingSerializer, ParticipantSerializer, MessageSerializer from django.contrib.auth import get_user_model from django.shortcuts import get_object_or_404 import uuid User = get_user_model() class MeetingViewSet(viewsets.ModelViewSet): """会议室视图集""" queryset = Meeting.objects.all() serializer_class = MeetingSerializer permission_classes = [] # 临时开放所有权限 def get_queryset(self): return Meeting.objects.all().order_by('-created_at') def create(self, request, *args, **kwargs): """创建会议""" serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) # 使用第一个用户作为 host host = User.objects.first() meeting = serializer.save(host=host) # 设置 1 小时过期时间 meeting.expires_at = timezone.now() + timedelta(hours=1) meeting.save() # 创建主持人参会记录 Participant.objects.create( meeting=meeting, user=host, agent_type='human', nickname=host.username, is_host=True ) # 处理随行龙虾 agent_ids = request.data.get('agent_ids', []) for agent_id in agent_ids: Participant.objects.create( meeting=meeting, agent_type='openclaw', agent_id=agent_id, agent_name='Agent', agent_emoji='🤖', nickname=f'Agent {agent_id}', is_host=False ) return Response(serializer.data, status=status.HTTP_201_CREATED) @action(detail=True, methods=['post']) def join(self, request, pk=None): """加入会议(支持批量加入)""" meeting = self.get_object() # 检查会议是否过期 if meeting.expires_at and timezone.now() > meeting.expires_at: # 过期会议,清空坐席 meeting.participants.all().delete() return Response( {'error': '会议已过期,坐席已清空'}, status=status.HTTP_400_BAD_REQUEST ) if meeting.status == 'ended': return Response( {'error': '会议已结束'}, status=status.HTTP_400_BAD_REQUEST ) invite_code = request.data.get('invite_code') if invite_code != meeting.invite_code: return Response( {'error': '邀请码错误'}, status=status.HTTP_400_BAD_REQUEST ) # 获取要加入的龙虾 ID 列表 agent_ids = request.data.get('agent_ids', []) # 获取当前用户 user = User.objects.first() # 临时使用第一个用户 # 检查用户是否已加入 existing = Participant.objects.filter( meeting=meeting, user=user, left_at__isnull=True ).first() if not existing: # 用户加入会议 Participant.objects.create( meeting=meeting, user=user, agent_type='human', nickname=user.username if user else '用户', is_host=False ) # 随行龙虾加入会议 joined_agents = [] for agent_id in agent_ids: # 检查是否已存在 exists = Participant.objects.filter( meeting=meeting, agent_id=agent_id, left_at__isnull=True ).first() if not exists: participant = Participant.objects.create( meeting=meeting, agent_type='openclaw', agent_id=agent_id, agent_name='Agent', agent_emoji='🤖', nickname=f'Agent {agent_id}', is_host=False ) joined_agents.append(ParticipantSerializer(participant).data) # 返回所有参会者 participants = Participant.objects.filter( meeting=meeting, left_at__isnull=True ) return Response({ 'message': '加入成功', 'participants': ParticipantSerializer(participants, many=True).data, 'joined_agents': joined_agents }) @action(detail=True, methods=['post']) def send_message(self, request, pk=None): """发送消息""" meeting = self.get_object() # 获取或创建参会者 participant = Participant.objects.filter( meeting=meeting, left_at__isnull=True ).first() if not participant: host = meeting.host participant = Participant.objects.create( meeting=meeting, user=host, agent_type='human', nickname=host.username ) content = request.data.get('content') if not content: return Response( {'error': '消息内容不能为空'}, status=status.HTTP_400_BAD_REQUEST ) message = Message.objects.create( meeting=meeting, sender=participant, content=content, is_broadcast=request.data.get('is_broadcast', True), requires_response=request.data.get('requires_response', False) ) return Response(MessageSerializer(message).data, status=status.HTTP_201_CREATED) @action(detail=True, methods=['get']) def messages(self, request, pk=None): """获取消息""" meeting = self.get_object() last_id = request.query_params.get('last_id', 0) messages = meeting.messages.filter(id__gt=last_id).select_related('sender') serializer = MessageSerializer(messages, many=True) return Response({'messages': serializer.data}) @action(detail=True, methods=['get']) def participants(self, request, pk=None): """获取参会者列表""" meeting = self.get_object() participants = meeting.participants.filter(left_at__isnull=True) serializer = ParticipantSerializer(participants, many=True) return Response(serializer.data)