from django.shortcuts import render from apps.utils.viewsets import CustomModelViewSet, CustomGenericViewSet from .models import Mroom, MroomBooking, MroomSlot from .serializers import MroomSerializer, MroomBookingSerializer, MroomSlotSerializer from rest_framework.decorators import action from apps.utils.mixins import CustomListModelMixin from rest_framework.exceptions import ParseError from apps.ofm.filters import MroomBookingFilterset class MroomViewSet(CustomModelViewSet): """list: 会议室 会议室 """ queryset = Mroom.objects.all() serializer_class = MroomSerializer class MroomBookingViewSet(CustomModelViewSet): """list: 会议室预订 会议室预订 """ queryset = MroomBooking.objects.all() serializer_class = MroomBookingSerializer select_related_fields = ["create_by"] filterset_class = MroomBookingFilterset def add_info_for_list(self, data): booking_ids = [d["id"] for d in data] slots = MroomSlot.objects.filter(booking__in=booking_ids).order_by("booking", "mroom", "mdate", "slot") booking_info = {} for slot in slots: booking_id = slot.booking.id if booking_id not in booking_info: booking_info[booking_id] = { "mdate": slot.mdate.strftime("%Y-%m-%d"), # 格式化日期 "mroom": slot.mroom.id, "mroom_name": slot.mroom.name, # 会议室名称 "time_ranges": [], # 存储时间段(如 ["8:00-9:00", "10:00-11:30"]) "current_slots": [], # 临时存储连续的slot(用于合并) } # 检查是否连续(当前slot是否紧接上一个slot) current_slots = booking_info[booking_id]["current_slots"] if not current_slots or slot.slot == current_slots[-1] + 1: current_slots.append(slot.slot) else: # 如果不连续,先把当前连续的slot转换成时间段 if current_slots: start_time = self._slot_to_time(current_slots[0]) end_time = self._slot_to_time(current_slots[-1] + 1) booking_info[booking_id]["time_ranges"].append(f"{start_time}-{end_time}") current_slots.clear() current_slots.append(slot.slot) # 处理最后剩余的连续slot for info in booking_info.values(): if info["current_slots"]: start_time = self._slot_to_time(info["current_slots"][0]) end_time = self._slot_to_time(info["current_slots"][-1] + 1) info["time_ranges"].append(f"{start_time}-{end_time}") info.pop("current_slots") # 清理临时数据 for item in data: item.update(booking_info.get(item["id"], {})) return data @staticmethod def _slot_to_time(slot): """将slot (0-47) 转换为 HH:MM 格式的时间字符串""" hours = slot // 2 minutes = (slot % 2) * 30 return f"{hours:02d}:{minutes:02d}" def perform_update(self, serializer): ins:MroomBooking = self.get_object() if ins.create_by != self.request.user: raise ParseError("只允许创建者修改") return super().perform_update(serializer) def perform_destroy(self, instance): if instance.create_by != self.request.user: raise ParseError("只允许创建者删除") return super().perform_destroy(instance) class MroomSlotViewSet(CustomListModelMixin, CustomGenericViewSet): """list: 会议室预订时段 会议室预订时段 """ queryset = MroomSlot.objects.all() serializer_class = MroomSlotSerializer filterset_fields = ["mroom", "mdate", "booking"]