97 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Python
		
	
	
	
| 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"] |