def longterm_wk(self, request, queryset, week_num): if not request.user.is_superuser: return self.message_user(request=request, message='操作失败,没有权限,请联系老师!', level=messages.WARNING) if len(queryset) != 1: return self.message_user(request=request, message='每次仅允许将一条预约长线化!', level=messages.WARNING) for appoint in queryset: # print(appoint) try: with transaction.atomic(): stuid_list = [stu.Sid for stu in appoint.students.all()] for i in range(week_num): # 调用函数完成预约 feedback = addAppoint({ 'Rid': appoint.Room.Rid, 'students': stuid_list, 'non_yp_num': appoint.Anon_yp_num, 'Astart': appoint.Astart + (i + 1) * timedelta(days=7), 'Afinish': appoint.Afinish + (i + 1) * timedelta(days=7), 'Sid': appoint.major_student.Sid, 'Ausage': appoint.Ausage, 'announcement': appoint.Aannouncement, 'new_require': # 长线预约,不需要每一个都添加信息, 直接统一添加 0 }) if feedback.status_code != 200: # 成功预约 warning = eval( feedback.content.decode( 'unicode-escape'))['statusInfo']['message'] print(warning) raise Exception(warning) ''' newappoint = Appoint( Room=appoint.Room, Astart=appoint.Astart + (i+1) * timedelta(days=7), Afinish=appoint.Afinish + \ (i+1) * timedelta(days=7), Ausage=appoint.Ausage, Aannouncement=appoint.Aannouncement, major_student=appoint.major_student, Anon_yp_num=appoint.Anon_yp_num, Ayp_num=appoint.Ayp_num ) newappoint.save() for tempstudent in appoint.students.all(): print(tempstudent) newappoint.students.add(tempstudent) newappoint.save() ''' except Exception as e: operation_writer( global_info.system_log, "学生" + str(appoint.major_student) + "出现添加长线化预约失败的问题:" + str(e), "admin.longterm", "Problem") return self.message_user(request=request, message=str(e), level=messages.WARNING) # 到这里, 长线化预约发起成功 scheduler.add_job( send_wechat_message, args=[ stuid_list, # stuid_list appoint.Astart, # start_time appoint.Room, # room "longterm", # message_type appoint.major_student.Sname, # major_student appoint.Ausage, # usage appoint.Aannouncement, len(stuid_list) + appoint.Anon_yp_num, week_num, # reason, 这里用作表示持续周数 #appoint.major_student.Scredit, ], id=f'{appoint.Aid}_new_wechat', next_run_time=datetime.now() + timedelta(seconds=5)) # 2s足够了 operation_writer( appoint.major_student.Sid, "发起" + str(week_num) + "周的长线化预约, 原始预约号" + str(appoint.Aid), "admin.longterm", "OK") return self.message_user(request, '长线化成功!')
def check_out(request): # 预约表单提交 if not identity_check(request): return redirect(direct_to_login(request)) temp_time = datetime.now() warn_code = 0 try: if request.method == "GET": Rid = request.GET.get('Rid') weekday = request.GET.get('weekday') startid = request.GET.get('startid') endid = request.GET.get('endid') else: Rid = request.POST.get('Rid') weekday = request.POST.get('weekday') startid = request.POST.get('startid') endid = request.POST.get('endid') # 防止恶意篡改参数 assert weekday in wklist assert int(startid) >= 0 assert int(endid) >= 0 assert int(endid) >= int(startid) appoint_params = { 'Rid': Rid, 'weekday': weekday, 'startid': int(startid), 'endid': int(endid) } room_object = Room.objects.filter(Rid=Rid)[0] dayrange_list = web_func.get_dayrange() for day in dayrange_list: if day['weekday'] == appoint_params['weekday']: # get day appoint_params['date'] = day['date'] appoint_params['starttime'], valid = web_func.get_hour_time( room_object, appoint_params['startid']) assert valid is True appoint_params['endtime'], valid = web_func.get_hour_time( room_object, appoint_params['endid'] + 1) assert valid is True appoint_params['year'] = day['year'] appoint_params['month'] = day['month'] appoint_params['day'] = day['day'] # 最小人数下限控制 appoint_params['Rmin'] = room_object.Rmin if datetime.now().strftime("%a") == appoint_params['weekday']: appoint_params['Rmin'] = min(global_info.today_min, room_object.Rmin) appoint_params['Sid'] = request.session['Sid'] appoint_params['Sname'] = Student.objects.get( Sid=appoint_params['Sid']).Sname Stu_all = Student.objects.all() except: return redirect(reverse('Appointment:index')) if request.method == "GET": js_stu_list = web_func.get_student_chosen_list(request) return render(request, "Appointment/checkout.html", locals()) elif request.method == 'POST': # 提交预约信息 contents = dict(request.POST) for key in contents.keys(): if key != "students": contents[key] = contents[key][0] if key in {'year', 'month', 'day'}: contents[key] = int(contents[key]) # 处理外院人数 if contents['non_yp_num'] == "": contents['non_yp_num'] = 0 else: try: contents['non_yp_num'] = int(contents['non_yp_num']) assert contents['non_yp_num'] >= 0 except: warn_code = 1 warning = "外院人数有误,请按要求输入!" # return render(request, "Appointment/checkout.html", locals()) # 处理用途未填写 if contents['Ausage'] == "": warn_code = 1 warning = "请输入房间用途!" # return render(request, "Appointment/checkout.html", locals()) # 处理单人预约 if "students" not in contents.keys(): contents['students'] = [contents['Sid']] else: contents['students'].append(contents['Sid']) contents['Astart'] = datetime(contents['year'], contents['month'], contents['day'], int(contents['starttime'].split(":")[0]), int(contents['starttime'].split(":")[1]), 0) contents['Afinish'] = datetime(contents['year'], contents['month'], contents['day'], int(contents['endtime'].split(":")[0]), int(contents['endtime'].split(":")[1]), 0) if warn_code != 1: # 增加contents内容,这里添加的预约需要所有提醒,所以contents['new_require'] = 1 contents['new_require'] = 1 response = scheduler_func.addAppoint( contents) # 否则没必要执行 并且有warn_code&message if response.status_code == 200: # 成功预约 urls = reverse( "Appointment:admin_index" ) + "?warn_code=2&warning=预约" + room_object.Rtitle + "成功!" return redirect(urls) else: add_dict = eval( response.content.decode('unicode-escape'))['statusInfo'] warn_code = 1 warning = add_dict['message'] # 到这里说明预约失败 补充一些已有信息,避免重复填写 js_stu_list = web_func.get_student_chosen_list(request) # selected_stu_list = Stu_all.filter( # Sid__in=contents['students']).exclude(Sid=contents['Sid']) selected_stu_list = [ w for w in js_stu_list if w['id'] in contents['students'] ] no_clause = True return render(request, 'Appointment/checkout.html', locals())
def door_check(request): # 先以Sid Rid作为参数,看之后怎么改 # --------- 基本信息 --------- # Sid, Rid = request.GET.get("Sid", None), request.GET.get("Rid", None) student, room, now_time, min15 = None, None, datetime.now(), timedelta( minutes=15) try: student = Student.objects.get(Sid=Sid) all_Rid = [room.Rid for room in Room.objects.all()] Rid = doortoroom(Rid) if Rid[:4] in all_Rid: # 表示增加了一个未知的A\B号 Rid = Rid[:4] room = Room.objects.get(Rid=Rid) except: user = student or None # TODO: 设置默认刷卡记录者 cardcheckinfo_writer(user, room, False, False, f"学号{Sid}或房间号{Rid}错误") return JsonResponse({"code": 1, "openDoor": "false"}, status=400) # --------- 直接进入 --------- # if room.Rstatus == Room.Status.FORBIDDEN: # 禁止使用的房间 cardcheckinfo_writer(student, room, False, False, f"刷卡拒绝:禁止使用") return JsonResponse({"code": 1, "openDoor": "false"}, status=400) if room.Rstatus == Room.Status.SUSPENDED: # 自习室 if room.RIsAllNight == Room.IsAllNight.Yes: # 通宵自习室 cardcheckinfo_writer(student, room, True, True, f"刷卡开门:通宵自习室") return JsonResponse({"code": 0, "openDoor": "true"}, status=200) else: # 不是通宵自习室 # 考虑到次晨的情况,判断一天内的时段 now = timedelta(hours=now_time.hour, minutes=now_time.minute) start = timedelta(hours=room.Rstart.hour, minutes=room.Rstart.minute) finish = timedelta(hours=room.Rfinish.hour, minutes=room.Rfinish.minute) if (now >= min(start, finish) and now <= max(start, finish)) ^ (start > finish): # 在开放时间内 cardcheckinfo_writer(student, room, True, True, f"刷卡开门:自习室") return JsonResponse({ "code": 0, "openDoor": "true" }, status=200) else: # 不在开放时间内 cardcheckinfo_writer(student, room, False, False, f"刷卡拒绝:自习室不开放") return JsonResponse({"code": 1, "openDoor": "false"}, status=400) # --------- 预约进入 --------- # # 获取房间的预约 room_appoint = Appoint.objects.not_canceled().filter( # 只选取接下来15分钟进行的预约 Astart__lte=now_time + min15, Afinish__gte=now_time, Room_id=Rid) # --- modify by dyh: 更改规则 --- # # --- modify by lhw: 临时预约 --- # if len(room_appoint) != 0: # 当前有预约 if len(room_appoint.filter(students__in=[student])) == 0: # 不是自己的预约 cardcheckinfo_writer(student, room, False, False, f"刷卡拒绝:该房间有别人的预约,或者距离别人的下一条预约开始不到15min!") return JsonResponse({"code": 1, "openDoor": "false"}, status=400) else: # 自己的预约 cardcheckinfo_writer(student, room, True, True, f"刷卡开门:预约进入") return JsonResponse({"code": 0, "openDoor": "true"}, status=200) else: # 当前无预约 if check_temp_appoint(room) == False: # 房间不可以临时预约 cardcheckinfo_writer(student, room, False, False, f"刷卡拒绝:该房间不可临时预约") return JsonResponse({"code": 1, "openDoor": "false"}, status=400) else: # 该房间可以用于临时预约 # 注意,由于制度上不允许跨天预约,这里的逻辑也不支持跨日预约(比如从晚上23:00约到明天1:00)。 start = datetime(now_time.year, now_time.month, now_time.day, now_time.hour, now_time.minute, 0) # 需要剥离秒级以下的数据,否则admin-index无法正确渲染 timeid = web_func.get_time_id(room, time(start.hour, start.minute)) # 房间未开放 if timeid < 0: message = f"该时段房间未开放!别熬夜了,回去睡觉!" cardcheckinfo_writer(student, room, False, False, f"刷卡拒绝:临时预约失败({message})") send_wechat_message([Sid], start, room, "temp_appointment_fail", student, "临时预约", "", 1, message) return JsonResponse({ "code": 1, "openDoor": "false" }, status=400) finish, valid = web_func.get_hour_time(room, timeid + 1) finish = datetime(now_time.year, now_time.month, now_time.day, int(finish.split(':')[0]), int(finish.split(':')[1]), 0) # 检查时间是否合法 # 合法条件:为避免冲突,临时预约时长必须超过15分钟;预约时在房间可用时段 # OBSELETE: 时间合法(暂时将间隔定为5min) if valid: contents = { 'Rid': Rid, 'students': [Sid], 'Sid': Sid, 'Astart': start, 'Afinish': finish, 'non_yp_num': 0, 'Ausage': "临时预约", 'announcement': "", 'Atemp_flag': True } response = scheduler_func.addAppoint(contents) if response.status_code == 200: # 临时预约成功 cardcheckinfo_writer(student, room, True, True, f"刷卡开门:临时预约") return JsonResponse({ "code": 0, "openDoor": "true" }, status=200) else: # 无法预约(比如没信用分了) message = json.loads( response.content.decode())["statusInfo"]["message"] cardcheckinfo_writer(student, room, False, False, f"刷卡拒绝:临时预约失败({message})") send_wechat_message([Sid], start, room, "temp_appointment_fail", student, "临时预约", "", 1, message) return JsonResponse({ "code": 1, "openDoor": "false" }, status=400) else: # 预约时间不合法 message = f"预约时间不合法,请不要恶意篡改数据!" cardcheckinfo_writer(student, room, False, False, f"刷卡拒绝:临时预约失败({message})") send_wechat_message([Sid], start, room, "temp_appointment_fail", student, "临时预约", "", 1, message) return JsonResponse({ "code": 1, "openDoor": "false" }, status=400)