def get_house_detail(house_id): """获取房屋详情""" # 前端在房屋详情页面展示时,如果浏览页面的用户不是该房屋的房东,则展示预定按钮,否则不展示, # 所以需要后端返回登录用户的user_id # 尝试获取用户登录的信息,若登录,则返回给前端登录用户的user_id,否则返回user_id=-1 user_id = session.get("user_id", "-1") # 校验参数 if not house_id: return jsonify(errno=RET.PARAMERR, errmsg="参数缺失") # 先从redis缓存中获取信息 try: ret = redis_store.get("house_info_%s" % house_id) except Exception as e: current_app.logger.error(e) ret = None if ret: current_app.logger.info("hit house info redis") return '{"errno":"0", "errmsg":"OK", "data":{"user_id":%s, "house":%s}}' % (user_id, ret), \ 200, {"Content-Type": "application/json"} # 查询数据库 try: house = House.query.get(house_id) except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR, errmsg="查询数据失败") if not house: return jsonify(errno=RET.NODATA, errmsg="房屋不存在") # 将房屋对象数据转换为字典 try: house_data = house.to_full_dict() except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DATAERR, errmsg="数据出错") # 存入到redis中 json_house = json.dumps(house_data) try: redis_store.setex("house_info_%s" % house_id, constants.HOUSE_DETAIL_REDIS_EXPIRE_SECOND, json_house) except Exception as e: current_app.logger.error(e) return '{"errno":"0", "errmsg":"OK", "data":{"user_id":%s, "house":%s}}' % (user_id, json_house), \ 200, {"Content-Type": "application/json"}
def login(): """登录""" # 提取数据 req_dict = request.get_json() mobile = req_dict.get("mobile") password = req_dict.get("password") if not all([mobile, password]): return jsonify(errno=RET.PARAMERR, errmsg="参数不完整") # 判断登录次数 user_ip = request.remote_addr try: access_nums = redis_store.get("access_nums_{}".format(user_ip)) except Exception as e: current_app.logger.error(e) else: if access_nums is not None and int( access_nums) > constants.LOGIN_ERROR_MAX_TIMES: return jsonify(errno=RET.REQERR, errmsg="错误次数过多,请稍后再试") try: user = User.query.filter_by(mobile=mobile).first() except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR, errmsg="获取用户信息失败") else: if user is None or not user.check_password(password): try: redis_store.incr("access_nums_{}".format(user_ip)) redis_store.expire("access_nums_{}".format(user_ip), constants.LOGIN_ERROR_FORBID_TIMES) except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DATAERR, errmsg="用户名或密码错误") # 如果验证相同成功,保存登录状态在session中 session["name"] = user.name session["mobile"] = user.mobile session["user_id"] = user.id return jsonify(errno=RET.OK, errmsg="登录成功")
def get_house_index(): """""" # 尝试从redis读取数据 try: resp_json = redis_store.get("home_page_data") except Exception as e: current_app.logger.error(e) else: # 有数据就直接返回 if resp_json is not None: current_app.logger.info("hit redis home_page_data") return resp_json, 200, {"Content-Type": "application/json"} # 获取销量降序房屋数据 try: houses = House.query.filter(House.index_image_url != "").order_by( House.order_count.desc()).limit(constants.HOME_PAGE_MAX_HOUSES) except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR, errmsg="查询数据失败") if not houses: return jsonify(errno=RET.NODATA, errmsg="查询无数据") houses_list = [] for house in houses: houses_list.append(house.to_basic_dict()) # 将数据加入缓存 resp_dict = dict(errno=RET.OK, errmsg="OK", data=houses_list) resp_json = json.dumps(resp_dict) try: redis_store.setex("home_page_data", constants.HOME_PAGE_DATA_REDIS_EXPIRES, resp_json) except Exception as e: current_app.logger.error(e) return resp_json, 200, {"Content-Type": "application/json"}
def get_area_info(): """获取城区信息""" # 尝试从redis读取数据 try: resp_json = redis_store.get("area_info") except Exception as e: current_app.logger.error(e) else: # 有数据就直接返回 if resp_json is not None: current_app.logger.info("hit redis area_info") 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(errno=RET.DBERR, errmsg="数据库异常") # 将对象装换成字典 area_dict_li = [] for area in area_list: area_dict_li.append(area.to_dict()) # 将数据转换成json字符串 resp_dict = dict(errno=RET.OK, errmsg="OK", data=area_dict_li) resp_json = json.dumps(resp_dict) # 将数据保存到redis中 try: redis_store.setex("area_info", constants.AREA_INFO_REDIS_CACHE_EXPIRES, resp_json) except Exception as e: current_app.logger.error(e) return resp_json, 200, {"Content-Type": "application/json"}
def register(): """ 注册 :params: 手机号、短信验证码、密码、确认密码 参数格式:json """ # 提取数据 req_dict = request.get_json() mobile = req_dict.get("mobile") sms_code = req_dict.get("sms_code") password = req_dict.get("password") password2 = req_dict.get("password2") # 检验数据 if not all([mobile, sms_code, password]): return jsonify(errno=RET.PARAMERR, errmsg="参数不完整") # 判断手机号格式 if not re.match(r'1[35789]\d{9}', mobile): return jsonify(errno=RET.PARAMERR, errmsg="手机号格式错误") # 判断密码 if password != password2: return jsonify(errno=RET.PARAMERR, errmsg="两次密码不一致") # 从redis取出数据 try: real_sms_code = redis_store.get("image_code_{}".format(mobile)) except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR, errmsg="redis数据库读取短信验证码异常") # 判断过期 if real_sms_code is None: return jsonify(errno=RET.NODATA, errmsg="短信验证码失效") # 验证码对比 if real_sms_code != sms_code: return jsonify(errno=RET.DATAERR, errmsg="短信验证码错误") # 判断手机号是否已注册 # try: # user = User.query.filter_by(mobile=mobile).first() # except Exception as e: # current_app.logger.error(e) # return jsonify(errno=RET.DBERR, errmsg="数据库异常") # else: # if user is not None: # # 表示手机号已存在 # return jsonify(errno=RET.DATAEXIST, errmsg="手机号已注册") # 保存数据到数据库中 user = User(name=mobile, mobile=mobile) user.password = password try: db.session.add(user) db.session.commit() except IntegrityError as e: db.session.rollback() # 表示手机号重复 return jsonify(errno=RET.DATAEXIST, errmsg="手机号已注册") except Exception as e: db.session.rollback() current_app.logger.error(e) return jsonify(errno=RET.DBERR, errmsg="操作数据库异常") # 保存登录状态到session session["name"] = mobile session["mobile"] = mobile session["user_id"] = user.id return jsonify(errno=RET.OK, errmsg="注册成功")
def get_sms_code(mobile): """短信验证码""" # 提取参数 image_code = request.args.get("image_code") image_code_id = request.args.get("image_code_id") print(image_code) # 检验参数 if not all([image_code, image_code_id]): return jsonify(errno=RET.PARAMERR, errmsg="参数不完整") # 业务处理 # 从redis取出图片验证码数据,对比 try: real_image_code = redis_store.get( "image_code_{}".format(image_code_id)) except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR, errmsg="redis数据库异常") # 判断是否过期 if real_image_code is None: return jsonify(errno=RET.NODATA, errmsg="图片验证码失效") # 删除图片验证码,防止撞库 try: redis_store.delete("image_code_{}".format(image_code_id)) except Exception as e: current_app.logger.error(e) # 判断是否一致,忽略大小写 if real_image_code.lower() != image_code.lower(): return jsonify(errno=RET.DATAERR, errmsg="图片验证码错误") # 手机号60s验证 try: send_flag = redis_store.get("send_sms_code_{}".format(mobile)) except Exception as e: current_app.logger.error(e) else: if send_flag is not None: return jsonify(errno=RET.REQERR, errmsg="请求过于频繁,请60秒后重试") # 判断手机号是否已注册 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(errno=RET.DATAEXIST, errmsg="手机号已存在") # 生成短信验证码并保存 sms_code = "%06d" % random.randint(0, 999999) try: redis_store.setex("image_code_{}".format(mobile), SMS_CODE_REDIS_EXPIRES, sms_code) # 保存发送的手机号记录,防止用户60s多次操作 redis_store.setex("send_sms_code_{}".format(mobile), SEND_SMS_CODE_INTERVAL, 1) except Exception as e: # 记录日志 current_app.logger.error(e) return jsonify(errno=RET.DBERR, errmsg="保存短信验证码异常") # 发送短信 text = "您的短信验证码是{},有效期{}分钟".format(sms_code, SMS_CODE_REDIS_EXPIRES / 60) try: result = yunqixun.send_single_msg(mobile, text) except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.THIRDERR, errmsg="发送异常") # # 使用celery异步发送短信 # send_msg.delay(mobile, text) if result.get('code') == "0": return jsonify(errno=RET.OK, errmsg="发送成功") else: return jsonify(errno=RET.THIRDERR, errmsg="发送失败")