def login(): """ 登陆 参数: 手机号, 密码, json :return: """ # 获取参数 resp_dict = request.get_json() mobile = resp_dict.get("mobile") password = resp_dict.get("password") # 校验参数 if not all([mobile, password]): return jsonify(errnum=RET.NODATA, errmsg="数据不完整") # 校验手机格式 if re.match(r"1[3578]\d{9}", mobile) is None: return jsonify(errnum=RET.PARAMERR, errmsg="手机格式不正确") # 业务逻辑处理 # 防止暴力测试,将手机登陆次数记录在redis中 user_ip = request.remote_addr try: # redis_store.set("access_nums_%s" % user_ip, 0) access_nums = redis_store.get("access_nums_%s" % user_ip) access_nums = int(access_nums.decode()) print(access_nums) except Exception as e: current_app.logger.error(e) else: if access_nums is not None and access_nums >= constants.LOGIN_ERROR_MAX_TIMES: return jsonify(errnum=RET.REQERR, errmsg="请求次数过多,稍后请重试") # 创建模型类对象,取出数据库中数据 try: user = User.query.filter_by(mobile=mobile).first() except Exception as e: current_app.logger.error(e) return jsonify(errnum=RET.DBERR, errmsg="数据库查询错误") # 判断用户名和密码的正确性 if user is None or user.check_password(password) is False: # 记录用户的登陆次数 try: redis_store.incr("access_nums_%s" % user_ip, amount=1) redis_store.expire("access_nums_%s" % user_ip, constants.LOGIN_ERROR_FORBID_TIME) except Exception as e: current_app.logger.error(e) return jsonify(errnum=RET.LOGINERR, errmsg="用户名或密码错误") # 保存用户登陆状态 session["name"] = user.name session['mobile'] = user.mobile session["user_id"] = user.id # 返回响应 return jsonify(errnum=RET.OK, errmsg="登陆成功")
def get_house_detail(house_id): """获取房屋详情""" # 尝试获取登陆的user_id # 登陆 就把user_id 返回给前端,用来判断登陆的是房主还是房客, # 未登录 就返回-1 user_id = session.get("user_id", "-1") # 校验参数 if house_id is None: return jsonify(errnum=RET.NODATA, errmsg="参数不存在") # 先从redis中获取数据 try: house_data = redis_store.get("house_info_%s" % house_id) except Exception as e: current_app.logger.error(e) house_data = None if house_data: current_app.logger.info("hit redis house_data") house_data = house_data.decode() return house_data, 200, {"Content-Type": "application/json"} # 查询数据库 try: house = House.query.get(house_id) except Exception as e: current_app.logger.error(e) return jsonify(errnum=RET.DBERR, errmsg="查询数据库失败") if house is None: return jsonify(errnum=RET.PARAMERR, errmsg="房屋不存在") # 将房屋对象数据转换成字典 try: house_data = house.to_full_dict() except Exception as e: current_app.logger.error(e) return jsonify(errnum=RET.DATAERR, errmsg="数据出错") house_data = dict(errnum=RET.OK, errmsg="OK", data=house_data) house_data = json.dumps(house_data) # 将数据保存到redis数据库中 try: redis_store.setex("house_info_%s" % house_id, constants.HOME_INFO_REDIS_EXPIRES, house_data) except Exception as e: current_app.logger.error(e) # resp_json = errnum=RET.OK, errmsg="OK", data={"house_list":houses_list} return house_data, 200, {"Content-Type": "application/json"}
def get_houses_index(): """获取主页信息""" # 从缓存中尝试获取信息 try: resp_json = redis_store.get("home_page_data") except Exception as e: current_app.logger.error(e) # 把resp_json设置为空,下面使用resp_json就不会显示未定义了 resp_json = None if resp_json: current_app.logger.info("hit redis home_page_data") resp_json = resp_json.decode() return resp_json, 200, {"Content-Type": "application/json"} else: # 从数据库中获取订单数排名前五的home图片 try: houses = House.query.order_by(House.order_count.desc()).limit( constants.HOME_PAGE_MAX_COUNTS) except Exception as e: current_app.logger.error(e) return jsonify(errnum=RET.DBERR, errmsg="房屋数据获取失败") if not houses: return jsonify(errnum=RET.NODATA, errmsg="数据不存在") # 用来存放房屋信息数据 houses_list = [] # 判断是否获取到数据 if houses: for house in houses: if not house.index_image_url: continue houses_list.append(house.to_basic_dict()) # 将列表数据转换成json格式 houses_list = dict(errnum=RET.OK, errmsg="OK", data=houses_list) houses_list_json = json.dumps(houses_list) # 将数据保存到redis数据库中 try: redis_store.setex("home_page_data", constants.HOME_INDEX_IMAGE_REDIS_EXPIRES, houses_list_json) except Exception as e: current_app.logger.error(e) return houses_list_json, 200, {"Content-Type": "application/json"}
def get_area(): """获取房屋地区信息""" # 查询数据库信息 try: resp_json = redis_store.get("area_info") except Exception as e: current_app.logger.error(e) else: if resp_json is not None: # 在redis中获取到地区信息 # print(type(resp_json)) current_app.logger.info("hit redis area_info") # print(resp_json) resp_json = resp_json.decode() # print("*"*20) # print(resp_json) # print(type(resp_json)) return resp_json, 200, {"Content-Type": "application/json"} try: area_list = Area.query.all() # 获取到房屋地区的对象列表 except Exception as e: current_app.logger.error(e) return jsonify(errnum=RET.DBERR, errmsg="获取房屋地区信息失败") # 数据处理 area_dict_list = [] for area in area_list: area_dict_list.append(area.to_dict()) # 处理数据 resp_dict = dict(errnum=RET.OK, errmsg="OK", data=area_dict_list) # print(resp_dict) resp_json = json.dumps(resp_dict) # print("*"*10) # print(resp_json) # 把数据存入redis数据库中 try: redis_store.setex("area_info", constants.AREA_INFO_REMACH_EXPIRES, resp_json) except Exception as e: current_app.logger.error(e) # 返回数据 return resp_json, 200, {"Content-Type": "application/json"}
def sms_code(mobile): """获取短信验证码""" # 获取参数 image_code = request.args.get("image_code") image_code_id = request.args.get("image_code_id") # 校验参数 print(image_code) # print(image_code_id) if not all([image_code, image_code_id]): # 表示参数不完整 return jsonify(errnum=RET.PARAMERR, errmsg="数据不完整") # 业务逻辑处理 # 从redis总去取出真实的image_code try: real_image_code = redis_store.get("image_code_%s" % image_code_id) except Exception as e: current_app.logger.error(e) return jsonify(errnum=RET.DBERR, errmsg='redis数据库异常') # print(real_image_code) # 判断图片验证码是否过期 if real_image_code is None: # 说明验证码过期 return jsonify(errnum=RET.NODATA, errmsg='图片验证码已失效') # 删除图片验证码 防止重复尝试输入验证码 try: redis_store.delete('image_code_%s' % image_code_id) except Exception as e: current_app.logger.error(e) # 对比用户填写的图片验证码 real_image_code = real_image_code.decode() print(real_image_code) if real_image_code.lower() != image_code.lower(): return jsonify(errnum=RET.DATAERR, errmsg='图片验证码错误') # 判断发送验证码的时间是否是正常频率 try: send_sms_code_interval = redis_store.get("send_sms_code_%s" % mobile) except Exception as e: current_app.logger.error(e) else: if send_sms_code_interval is not None: # 说明现在不能发送短信验证码 return jsonify(errnum=RET.REQERR, errmsg='短信验证码请求频率太高,稍后请重试') # 判断手机号是否存在 try: user = User.query.filter_by(mobile=mobile).first() except Exception as e: current_app.logger.error(e) else: if user is not None: # 手机号已存在 return jsonify(errnum=RET.DATAEXIST, errmsg='手机号已存在') # 不存在,生成手机验证码 sms_code = random.randint(100000, 999999) # 保存真实的短信验证码 try: redis_store.setex("sms_code_%s" % mobile, constants.SMS_CODE_EXPIRE_TIME, sms_code) # 保存用户获取验证码记录 redis_store.setex("send_sms_code_%s" % mobile, constants.SEND_SMS_CODE_INTERVAL, 1) except Exception as e: current_app.logger.error(e) return jsonify(errnum=RET.DATAERR, errmsg='短信验证码保存失败') # 发送短信 # 使用celery异步发送短信 send_sms.delay( mobile, [sms_code, int(constants.SMS_CODE_EXPIRE_TIME / 60)], 1) # 返回值 # 发送短信验证码成功 return jsonify(errnum=RET.OK, errmsg='发送成功')
def register(): """ 用户注册 参数: mobile , sms_code, password 参数类型: json :return: """ # 获取请求的json, 转换成字典 resp_dict = request.get_json() # 获取参数 mobile = resp_dict.get("mobile") sms_code = resp_dict.get("sms_code") password = resp_dict.get("password") password2 = resp_dict.get("password2") # 校验参数 if not all([mobile, sms_code, password, password2]): return jsonify(errnum=RET.PARAMERR, errmsg="参数不完整") if re.match(r"1[34578]\d{9}", mobile) is None: return jsonify(errnum=RET.PARAMERR, errmsg='手机号码错误') if password != password2: return jsonify(errnum=RET.PWDERR, errmsg="两次密码输入不一致") # 业务逻辑 # 1.从redis中取出sms_code try: real_sms_code = redis_store.get("sms_code_%s" % mobile) except Exception as e: current_app.logger.error(e) return jsonify(errnum=RET.DBERR, errmsg="读取真实短信验证码失败") # 3.判断短信验证码是否过期 if real_sms_code is None: return jsonify(errnum=RET.NODATA, errmsg="短信验证码已失效") # 4.删除短信验证码,防止重复使用 try: redis_store.delete("sms_code_%s" % mobile) except Exception as e: current_app.logger.error(e) # 3.校验短信验证码 real_sms_code = real_sms_code.decode() if sms_code != real_sms_code: return jsonify(errnum=RET.PARAMERR, errmsg="短语验证码错误") # 4.判断手机号码是否已存在 # try: # result = User.query.filter_by(mobile=mobile).first() # except Exception as e: # current_app.logger.error(e) # return jsonify(errnum=RET.DBERR, errmsg='数据库异常') # else: # if result is not None: # return jsonify(errnum=RET.DATAEXIST, errmsg="手机号已存在") # user.password_hash = generate_password_hash(password) 一般方法对密码加密 # 4.利用数据库错误来直接判断手机号码是否已存在 user = User(name=mobile, mobile=mobile) # 保存密码 user.password = password # 设置属性 # 5.把数据保存到数据库 try: db.session.add(user) db.session.commit() # 对抛出的异常进行区分,提取出数据相同造成的异常 except IntegrityError as e: db.session.rollback() current_app.logger.error(e) return jsonify(errnum=RET.DATAEXIST, errmsg="手机号已存在") except Exception as e: db.session.rollback() current_app.logger.error(e) return jsonify(errnum=RET.DBERR, errmsg="数据库异常") # 6.使用session保存用户登录状态 session["name"] = mobile session["mobile"] = mobile session["user_id"] = user.id # 7.返回响应 return jsonify(errnum=RET.OK, errmsg="注册成功")