add index and optimize the booking status

This commit is contained in:
David 2019-05-26 14:15:21 +08:00
parent 9601530a85
commit b91010cfbc
4 changed files with 89 additions and 41 deletions

View File

@ -0,0 +1,17 @@
# Generated by Django 2.2.1 on 2019-05-26 13:43
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('booking', '0002_auto_20190524_2040'),
]
operations = [
migrations.AlterIndexTogether(
name='booking',
index_together={('room', 'date')},
),
]

View File

@ -75,6 +75,7 @@ class Booking(models.Model):
blank=True, null=True)
class Meta:
index_together = ['room', 'date']
verbose_name = '预约'
verbose_name_plural = verbose_name

View File

@ -6,40 +6,47 @@ from . import models
@app.task
def createBooking(booking):
b = models.Booking.objects.get(id=booking['id'])
date = datetime.datetime.strptime(booking['date'], '%Y-%m-%d').date()
pre_booking_interval_day = models.Setting.objects.get(id=1).pre_booking_interval_day
today = datetime.datetime.now()
max_date = today.date() + datetime.timedelta(days=pre_booking_interval_day)
if date < today.date():
b = models.Booking.objects.get(id=booking['id'])
try:
date = datetime.datetime.strptime(booking['date'], '%Y-%m-%d').date()
pre_booking_interval_day = models.Setting.objects.get(id=1).pre_booking_interval_day
max_date = today.date() + datetime.timedelta(days=pre_booking_interval_day)
if date < today.date():
b.status = 'FAILED'
b.cancel_reason = f'预约日期超过限制,最早可预约至{date.strftime("%Y-%m-%d")}'
b.cancel_datetime = today.strftime('%Y-%m-%d %H:%M:%S')
b.save()
return
if date > max_date:
b.status = 'FAILED'
b.cancel_reason = f'预约日期超过限制,最晚可预约至{max_date.strftime("%Y-%m-%d")}'
b.cancel_datetime = today.strftime('%Y-%m-%d %H:%M:%S')
b.save()
return
isDuplicate = False
start_time = datetime.datetime.strptime(booking['start_time'], '%H:%M:%S').time()
end_time = datetime.datetime.strptime(booking['end_time'], '%H:%M:%S').time()
for seat in booking['seats']:
booking_list = models.Booking.objects.filter(room=booking['room'],
date=booking['date'],
status='SUCCESS',
seats__id=seat)
for item in booking_list:
if ((start_time >= item.start_time and start_time <= item.end_time)
or (end_time >= item.start_time and end_time <= item.end_time)
or (start_time <= item.start_time and end_time >= item.end_time)):
isDuplicate = True
if isDuplicate:
b.status = 'FAILED'
b.cancel_reason = '预约冲突。'
b.cancel_datetime = today.strftime('%Y-%m-%d %H:%M:%S')
else:
b.status = 'SUCCESS'
b.save()
except Exception as e:
b.status = 'FAILED'
b.cancel_reason = f'预约日期超过限制,最早可预约至{date.strftime("%Y-%m-%d")}'
b.cancel_reason = f'服务器错误,请联管理员\n{e}'
b.cancel_datetime = today.strftime('%Y-%m-%d %H:%M:%S')
b.save()
return
if date > max_date:
b.status = 'FAILED'
b.cancel_reason = f'预约日期超过限制,最晚可预约至{max_date.strftime("%Y-%m-%d")}'
b.cancel_datetime = today.strftime('%Y-%m-%d %H:%M:%S')
b.save()
return
isDuplicate = False
start_time = datetime.datetime.strptime(booking['start_time'], '%H:%M:%S').time()
end_time = datetime.datetime.strptime(booking['end_time'], '%H:%M:%S').time()
for seat in booking['seats']:
booking_list = models.Booking.objects.filter(room=booking['room'],
date=booking['date'],
status='SUCCESS',
seats__id=seat)
for item in booking_list:
if ((start_time >= item.start_time and start_time <= item.end_time)
or (end_time >= item.start_time and end_time <= item.end_time)
or (start_time <= item.start_time and end_time >= item.end_time)):
isDuplicate = True
if isDuplicate:
b.status = 'FAILED'
b.cancel_reason = '预约冲突。'
b.cancel_datetime = today.strftime('%Y-%m-%d %H:%M:%S')
else:
b.status = 'SUCCESS'
b.save()

View File

@ -234,17 +234,21 @@ class RoomBookingStatusDetail(generics.GenericAPIView):
"""
获得指定房间的预约信息
"""
queryset = QuerySet()
serializer_class = (serializers.RoomSerializer)
permission_classes = (permissions.IsAuthenticated,)
def get(self, request, pk):
setting = models.Setting.objects.get(id=1)
try:
date = datetime.datetime.strptime(request.query_params.get('date'), '%Y-%m-%d').date()
start_time = request.query_params.get('start_time')
end_time = request.query_params.get('end_time')
start_time = datetime.datetime.strptime(start_time, '%H:%M:%S').time() if start_time else setting.start_time
end_time = datetime.datetime.strptime(end_time, '%H:%M:%S').time() if end_time else setting.end_time
except Exception as e:
raise ValidationError(e)
room = get_object_or_404(models.Room, id=pk)
setting = models.Setting.objects.get(id=1)
record = self.get_queryset()
count_total = 0
booked_count_total = 0
seat_list = []
@ -252,9 +256,9 @@ class RoomBookingStatusDetail(generics.GenericAPIView):
# 初始化数组
step = datetime.timedelta(minutes=setting.booking_interval)
booking_status_list = []
start_datetime = datetime.datetime.combine(date, setting.start_time)
start_datetime = datetime.datetime.combine(date, start_time)
end_datetime = start_datetime + step
while end_datetime <= datetime.datetime.combine(date, setting.end_time):
while end_datetime <= datetime.datetime.combine(date, end_time):
booking_status_list.append({
'start_time': start_datetime.strftime('%H:%M:%S'),
'end_time': end_datetime.strftime('%H:%M:%S'),
@ -264,17 +268,32 @@ class RoomBookingStatusDetail(generics.GenericAPIView):
start_datetime = end_datetime
end_datetime += step
# 检查预约记录
for booking in models.Booking.objects.filter(date=date, room=room, seats__id=seat.id, status='SUCCESS'):
s_datetime = datetime.datetime.combine(date, booking.start_time)
e_datetime = datetime.datetime.combine(date, booking.end_time)
start_datetime = datetime.datetime.combine(date, start_time)
end_datetime = datetime.datetime.combine(date, end_time)
is_booked = False
for booking in record.select_related('user').filter(seats__id=seat.id):
is_booked = True
s_datetime = max(start_datetime, datetime.datetime.combine(date, booking.start_time))
e_datetime = min(end_datetime, datetime.datetime.combine(date, booking.end_time))
s = int((s_datetime - start_datetime) / step)
e = int((e_datetime - start_datetime) / step)
booked_count_total += e - s
for i in range(s, e):
booking_status_list[i]['booking'] = serializers.BookingSerializer(booking).data
booking_status_list[i]['booking'] = {
'id': booking.id,
'start_time': booking.start_time,
'end_time': booking.end_time,
'arrive_time': booking.arrive_time,
'leave_time': booking.leave_time,
'user': {
'id': booking.user.id,
'username': booking.user.username
}
}
seat_list.append({
'id': seat.id,
'name': seat.name,
'is_booked': is_booked,
'booking_status_list': booking_status_list
})
return Response({
@ -284,3 +303,7 @@ class RoomBookingStatusDetail(generics.GenericAPIView):
'booked_count_total': booked_count_total,
'seat_list': seat_list
})
def get_queryset(self):
date = datetime.datetime.strptime(self.request.query_params.get('date'), '%Y-%m-%d').date()
return models.Booking.objects.filter(date=date, room=self.kwargs['pk'], status='SUCCESS')