コード例 #1
0
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="登陆成功")
コード例 #2
0
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"}
コード例 #3
0
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"}
コード例 #4
0
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"}
コード例 #5
0
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='发送成功')
コード例 #6
0
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="注册成功")