def draw(self): ''' 执行抽签,对所有下周可抽签场地执行。 ''' from Qinghuiyue.reservation.models import Reservation now = datetime.now() + timedelta(days=1) # 防止今天是周一 while now.weekday() != 0: now += timedelta(days=1) time = now.replace(hour=7, minute=0, second=0, microsecond=0) time_end = time + timedelta(days=6, hours=15) for status in self.Status: # 供抽签且有人参与才抽,如果没人参与的话就直接变成可先到先得 if status['code'] == 3 and status['start']>=time and status['end']<=time_end: if len(status['reservation_ids']): bingo = randint(0, len(status['reservation_ids'])) bingo_id = status['reservation_ids'].pop(bingo) reservation = Reservation.objects(id=bingo_id).first() reservation.status = 1 status['user_id'] = reservation.details['user_id'] reservation.save() for reservation_id in status['reservation_ids']: reservation = Reservation.objects(id=reservation_id).first() reservation.status = 6 reservation.save() status.pop('reservation_ids', None) status.pop('users_id',None) status['code'] = 2 else: status['code'] = 1 self.save()
def book_first_come(request): """ 先到先得预定,接受用户id和要预定的场馆和时间段 : """ book_info = json.loads(request.body) print(book_info) court = Court.objects(court_id=book_info['court_id']).first() if not court: return JsonResponse({"message": "找不到场地"}, status=400) court_status = court.Status book_info['start'] = parse(book_info['start']) book_info['end'] = parse(book_info['end']) user = User.objects(user_id=request.session.get("user_id")).first() if not user: return JsonResponse({"message": "用户不存在或登陆过期,请重新登陆"}, status=400) cache_key = str(court.court_id) + str(book_info['start']) for status in court_status: if status['start'] == book_info['start'] \ and status['end'] == book_info['end']: if status[ 'code'] == 1: # 场地状态1,先到先得还能订此时用户就是第一个到的,时间段和场地状态都符合要求,直接预定成功 if cache.get(cache_key): return JsonResponse({"message": "error"}, status=400) cache.set(cache_key, 1, 50000) status["user_id"] = user.user_id status["code"] = 2 # 2是已经定了 court.save() reservation = Reservation( type=court.enum_id, details={ "court": court.id, "user_id": user.user_id, "start": book_info["start"], "end": book_info["end"], "created": datetime.datetime.now() }, reservation_id=Stat.add_object("reservation"), status=1) reservation.save() # 应该先保存,不然会导致读取不出id user.rent_now.append(reservation.id) court.save() user.save() return JsonResponse({ "message": "ok", "reservation_id": reservation.reservation_id }) return JsonResponse({"message": "error"}, status=400)
def book_draw(request): ''' 用户抽签预定 params:user_id,court_id,start,end ''' book_info = json.loads(request.body) court = Court.objects(court_id=book_info['court_id']).first() court_status = court.Status book_info['start'] = parse(book_info['start']) book_info['end'] = parse(book_info['end']) user = User.objects(user_id=request.session.get("user_id")).first() draw_now = Reservation.objects(id__in=user.rent_now, status=5).count() if draw_now >= 3: return JsonResponse({ "message": "您最多同时参与三场抽签", "draw_now": draw_now }, status=400) for status in court_status: if status['start'] == book_info['start'] \ and status['end'] == book_info['end']: if status['code'] == 3: # 可供抽签 if user.user_id in status['users_id']: return JsonResponse({"message": "您已经预定过这个场地了"}, status=400) reservation = Reservation( type=court.enum_id, details={ "court": court.id, "user_id": user.user_id, "start": book_info["start"], "end": book_info["end"], "created": datetime.datetime.now() }, reservation_id=Stat.add_object("reservation"), status=5) # 5是等待抽签 reservation.save() # 应该先保存,不然会导致读取不出id if 'reservation_ids' not in status.keys(): status['reservation_ids'] = [] status['reservation_ids'].append(reservation.id) status['users_id'].append(user.user_id) user.rent_now.append(reservation.id) court.save() user.save() return JsonResponse({ "message": "ok", "reservation_id": reservation.reservation_id }) return JsonResponse({"message": "找不到需要预定的时间段"}, status=400)
def get_user_shares(request): ''' 获取单个用户所有拼场 :param request: :return: ''' page = int(request.GET['page']) size = int(request.GET['size']) user_id = int(request.GET['user_id']) user = User.objects(user_id=user_id).first() if not user: return JsonResponse({"message": "找不到此用户"}, status=400) shares_all = Share_notification.objects(id__in=user.invitation).order_by("-time") total = len(shares_all) if page * size > total: shares_page = shares_all else: shares_page = shares_all[(page - 1) * size:page * size] shares = [ { "user_id": share.user_id, "share_id": share.share_id, "content": share.content, "publish_date": share.time+datetime.timedelta(hours=8), "reservation": Reservation.get_reservation_info(share.reservation), "status": share.status } for share in shares_page ] return JsonResponse({"message": "ok", "total": total, "shares": shares})
def get_share_notifications(request): ''' 获取所有拼场信息,按时间排,有分页 :param request: page:int size:int ''' page = int(request.GET['page']) size = int(request.GET['size']) shares_all = Share_notification.objects().order_by("-time") total = len(shares_all) if page * size > total: shares_page = shares_all else: shares_page = shares_all[(page - 1) * size:page * size] shares = [ { "user_id": share.user_id, "share_id": share.share_id, "content": share.content, "publish_date": share.time+datetime.timedelta(hours=8), "reservation": Reservation.get_reservation_info(share.reservation), "status": share.status } for share in shares_page ] return JsonResponse({"message": "ok", "total": total, "shares": shares})
def create(cls, params): reservation = Reservation.objects( reservation_id=params['reservation_id']).first() #未付款、过期、已拼场的不符合要求 if reservation: if reservation.status != 2: return False, {"message": "场地不符合拼场要求"} if reservation.details['start'] < datetime.datetime.now(): return False, {"message": "该订单已经过期了"} if len(cls.objects(reservation=reservation.id)): return False, {"message": "该预定已经发布拼场通知"} user = User.objects(user_id=params['user_id']).first() share = cls.objects.create( user_id=user.user_id, content=params['content'], time=datetime.datetime.now(), reservation=reservation.id, status=1, share_id=Stat.add_object("share_notification")) user.invitation.append(share.id) user.save() return True, {"message": "ok", "share_id": share.share_id} else: return False, {"message": "找不到此预定"}
def pay_offline(request): ''' 线下支付 ''' params = json.loads(request.body) reservation = Reservation.objects( reservation_id=params['reservation_id']).first() # 只有存在的且为未支付的订单可以进入支付状态 if not reservation: return JsonResponse({"message": "该订单不存在"}, status=500) if reservation.status != 1: return JsonResponse({"message": "该订单不可支付"}, status=401) if reservation.details['user_id'] != request.session.get('user_id'): return JsonResponse({"message": "这不是您的订单,请确认登陆信息"}, status=403) court = Court.objects(id=reservation.details['court']).first() if not court: return JsonResponse({"message": "该场地不存在!"}, status=501) reservation.status = 2 reservation.details['paid_at'] = datetime.datetime.now() reservation.details['mode_of_pay'] = "offline" reservation.details['price'] = court.price reservation.save() return JsonResponse({"message": "ok"})
def pay_for_reservation(request): params = json.loads(request.body) reservation = Reservation.objects( reservation_id=params['reservation_id']).first() # 只有存在的且为未支付的订单可以进入支付状态 if not reservation: return JsonResponse({"message": "该订单不存在"}, status=500) if reservation.status != 1: return JsonResponse({"message": "该订单不可支付"}, status=401) if reservation.details['user_id'] != request.session.get('user_id'): return JsonResponse({"message": "这不是您的订单,请确认登陆信息"}, status=403) court = Court.objects(id=reservation.details['court']).first() if not court: return JsonResponse({"message": "该场地不存在!"}, status=501) alipay = aliPay() out_trade_no = str(reservation.reservation_id) # 商户订单号 query_params = alipay.direct_pay( subject=court.name + "支付", # 商品简单描述 这里一般是从前端传过来的数据 out_trade_no=out_trade_no, # 商户订单号 这里一般是从前端传过来的数据 total_amount=court.price, # 交易金额(单位: 元 保留俩位小数) 这里一般是从前端传过来的数据 is_phone=params['isPhone'], ) pay_url = "https://openapi.alipaydev.com/gateway.do?{}".format( query_params) response = JsonResponse({"message": "ok"}, status=200) response["Location"] = pay_url return response
def index(request): # 假的index用于在没有前端的情况下测试2 if request.method == "GET": return render(request, 'index_test_pay.html') # 对购买的数据进行加密 reservation_id = int(request.POST.get('reservation_id')) # 保留俩位小数 前端传回的数据 out_trade_no = str(reservation_id) # 商户订单号 # 订单号可以有多中生成方式,可以百度一下 reservation = Reservation.objects(reservation_id=reservation_id).first() if not reservation: return JsonResponse({"message": "该订单不存在!"}, status=500) # 1. 在数据库创建一条数据:状态(待支付) court = Court.objects(id=reservation.details['court']).first() if not court: return JsonResponse({"message": "该场地不存在!"}, status=501) # 实例化SDK里面的类AliPay alipay = aliPay() query_params = alipay.direct_pay( subject=court.name + "支付", # 商品简单描述 这里一般是从前端传过来的数据 out_trade_no=out_trade_no, # 商户订单号 这里一般是从前端传过来的数据 total_amount=court.price, # 交易金额(单位: 元 保留俩位小数) 这里一般是从前端传过来的数据 is_phone=1) # 拼接url,转到支付宝支付页面 pay_url = "https://openapi.alipaydev.com/gateway.do?{}".format( query_params) response = JsonResponse({"message": "ok"}, status=302) response["Location"] = pay_url return response
def update_order(request): """ 支付成功后,支付宝向该地址发送的POST请求(用于修改订单状态) :param request: :return: """ if request.method == 'POST': body_str = request.body.decode('utf-8') post_data = parse_qs(body_str) post_dict = {} for k, v in post_data.items(): post_dict[k] = v[0] alipay = aliPay() sign = post_dict.pop('sign', None) status = alipay.verify(post_dict, sign) if status: # 根据订单号将数据库中的数据进行更新 reservation = Reservation.objects( reservation_id=post_dict.get('out_trade_no')).first() reservation.status = 2 reservation.details['paid_at'] = datetime.now() reservation.details['trade_no_alipay'] = post_dict.get('trade_no') reservation.details['price'] = float(post_dict.get('total_amount')) reservation.details['mode_of_pay'] = "alipay" reservation.save() return HttpResponse('success') # 必须输出来告诉支付宝已经收到通知
def get_reservations(request): ''' 获取用户当前预定信息 :param request: ''' user_id = int(request.GET['user_id']) user = User.objects(user_id=user_id)[0] rent_now_id = user.rent_now rent_now = Reservation.objects( id__in=rent_now_id).order_by("-reservation_id") courts = [] for rent in rent_now: feedback = Feedback.objects(reservation_id=rent.reservation_id).first() if feedback: reviewed = feedback.feedback_id else: reviewed = 0 share = Share_notification.objects(reservation=rent.id).first() if share: shared = share.share_id else: shared = 0 try: court_name = Court.objects(id=rent.details['court'])[0].name except Exception: continue court = { "reservation_id": rent.reservation_id, "type": rent.type, "status": rent.status, "details": { "name": court_name, "start": rent.details['start'], "end": rent.details['end'], "created": rent.details['created'] + datetime.timedelta(hours=8) }, "reviewed": reviewed, "shared": shared } if rent.status == 2: court["details"]["paid_at"] = rent.details[ "paid_at"] + datetime.timedelta(hours=8) courts.append(court) return JsonResponse({"message": "ok", "courts": courts})
def cancel_reservation(request): ''' 取消订单,把订单状态改为3,并且在场馆处修改状态。 对于未付款(1)的,将对应场地状态制空,可供先到先得 对于已付款的,认为不能取消了(退款功能没有实现,可以转让) 对于未抽签(5)的,将其从队列里面删除 :param request: :return: ''' params = json.loads(request.body) reservation = Reservation.objects( reservation_id=params['reservation_id']).first() if not reservation: return JsonResponse({"message": "找不到订单"}, status=400) user = User.objects(user_id=reservation.details['user_id']).first() if user.user_id != request.session.get('user_id'): return JsonResponse({"message": "你没有取消权限!"}, status=400) court = Court.objects(id=reservation.details['court']).first() if reservation.status == 1: reservation.status = 3 reservation.save() for status in court.Status: if status['start'] == reservation.details['start'] and \ status['end'] == reservation.details['end']: status['user_id'] = -1 status['code'] = 1 break court.save() elif reservation.status == 5: reservation.status = 3 reservation.save() for status in court.Status: if status['start'] == reservation.details['start'] and \ status['end'] == reservation.details['end']: try: status['reservation_ids'].remove(reservation.id) status['users_id'].remove(user.user_id) except: return JsonResponse({"message": "您已经从抽签中退出"}, status=400) break court.save() else: return JsonResponse({"message": "当前状态不可取消预定"}, status=400) Share_notification.del_share(reservation.id) return JsonResponse({"message": "ok"})
def transfer_reservation(request): ''' 转让场地 :param request: :return: ''' # 是新建一个订单,原来的状态改为已经转移,只有已经预定成功(含未付款)才能转让 params = json.loads(request.body) reservation = Reservation.objects( reservation_id=params['reservation_id']).first() if not reservation: return JsonResponse({"message": "找不到订单"}, status=400) if reservation.status not in [1, 2]: return JsonResponse({"message": "该订单不可转让"}, status=400) if reservation.details['start'] < datetime.datetime.now(): return JsonResponse({"message": "该订单已经过期了"}, status=400) user_now = User.objects(user_id=reservation.details['user_id']).first() if user_now.user_id != request.session.get('user_id'): return JsonResponse({"message": "你没有转移权限!"}, status=400) user_new = User.objects(user_id=params['new_user_id']).first() if not user_new: return JsonResponse({"message": "找不到目标用户"}, status=400) new_reservation = Reservation.objects.create( type=reservation.type, details=reservation.details, reservation_id=Stat.add_object("reservation"), status=reservation.status) new_reservation.details['user_id'] = user_new.user_id new_reservation.save() user_new.rent_now.append(new_reservation.id) reservation.status = 4 user_new.save() user_now.save() reservation.save() Share_notification.del_share(reservation.id) # 再到court里面去修改status,可能可以抽象成函数 court = Court.objects(id=reservation.details['court']).first() for status in court.Status: if status['start'] == reservation.details['start'] and \ status['end'] == reservation.details['end']: status['user_id'] = user_new.user_id break court.save() return JsonResponse({"message": "ok"})
def create_feedback(cls, params): try: feedback = cls.objects( reservation_id=params['reservation_id']).first() if feedback: return False, "已经反馈过啦!" reservation = Reservation.objects( reservation_id=params['reservation_id']).first() feedback = cls.objects.create( user_id=params['user_id'], court=reservation.details['court'], content=params['content'], stars=params['stars'], time=datetime.datetime.now(), reply="等待管理员回复中", feedback_id=Stat.add_object("feedback"), reservation_id=params['reservation_id'], solved=False) #img_name = settings.STATIC_URL + str(feedback.feedback_id) + params['img'].name if params['img']: assert params['img'].name.endswith( ('.bmp', '.dib', '.png', '.jpg', '.jpeg', '.pbm', '.pgm', '.ppm', '.tif', '.tiff')) img_name = "static/feedback/" + str( feedback.feedback_id) + params['img'].name.split('.')[-1] feedback.img = img_name feedback.save() with open(img_name, 'wb+') as img_file: for chunk in params['img'].chunks(): img_file.write(chunk) else: feedback.img = "None" feedback.save() user = User.objects(user_id=params['user_id'])[0] user.feedback.append(feedback.id) user.save() return True, feedback.feedback_id except Exception: return False, "创建反馈失败!系统内部错误"