Exemplo n.º 1
0
def get_house_detail(house_id):
    """
    获取房屋详情信息:缓存----磁盘----缓存
    1/获取参数,user_id,把用户分为两类,登陆用户/未登陆用户
    user_id = session.get('user_id','-1')
    2/校验house_id参数
    3/尝试从redis缓存中获取房屋信息
    4/校验结果,如果有数据,
    5/查询mysql数据库
    6/调用模型类的to_full_dict(),进行异常处理
    7/序列化数据
    8/存储到redis缓存中
    9/返回结果
    :return:
    """
    # 使用请求上下文对象session,从redis中获取用户身份信息,如未登陆,默认给-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).decode(encoding='utf-8')
    except Exception as e:
        current_app.logger.error(e)
        ret = None
    # 判断获取结果
    if ret:
        current_app.logger.info('hit house detail info redis')
        return '{"errno":0,"errmsg":"OK","data":{"user_id":%s,"house":%s}}' % (
            user_id, ret)
    # 查询mysql数据库
    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.DBERR, errmsg='获取房屋详情信息异常')
    # 序列化数据
    house_json = json.dumps(house_data)
    # 把房屋详情数据存入缓存中
    try:
        redis_store.setex('house_info_%s' % house_id,
                          constants.HOUSE_DETAIL_REDIS_EXPIRE_SECOND,
                          house_json)
    except Exception as e:
        current_app.logger.error(e)
    # 返回结果
    resp = '{"errno":0,"errmsg":"OK","data":{"user_id":%s,"house":%s}}' % (
        user_id, house_json)
    return resp
Exemplo n.º 2
0
def get_houses_index():
    """
    项目首页信息:缓存----磁盘----缓存
    1/尝试从redis缓存中获取房屋信息
    2/判断获取结果,如果有数据,记录访问时间,直接返回结果
    3/查询mysql数据库
    4/默认按照房屋成交量进行查询,
    houses = House.query.order_by(House.order_count.desc()).limit(5)
    5/判断查询结果
    6/定义列表,遍历查询结果,添加数据,
    7/判断是否设置主图片,如未设置主图片默认不添加
    8/序列化房屋数据
    9/存入到缓存中,
    10/返回结果
    :return:
    """
    #  尝试从redis获取房屋首页幻灯片信息
    try:
        ret = redis_store.get('home_page_data')
    except Exception as e:
        current_app.logger.error(e)
        ret = None
    # 如果有数据,记录访问缓存数据的时间,直接返回房屋信息
    if ret:
        current_app.logger.info('hit house index info redis')
        return '{"errno":0,"errmsg":"OK","data":%s}' % ret
    # 查询mysql数据库,获取房屋信息,默认按照房屋成交量进行倒叙查询
    try:
        houses = House.query.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:
        # 判断房屋主图片如未设置,默认不添加数据
        if not house.index_image_url:
            continue
        houses_list.append(house.to_basic_dict())
    # 序列化数据
    houses_json = json.dumps(houses_list)
    # 把房屋数据存入到redis缓存中
    try:
        redis_store.setex('home_page_data',
                          constants.HOME_PAGE_DATA_REDIS_EXPIRES, houses_json)
    except Exception as e:
        current_app.logger.error(e)
    # 返回结果
    resp = '{"errno":0,"errmsg":"Ok","data":%s}' % houses_json
    return resp
Exemplo n.º 3
0
def get_area_info():
    """
    获取区域信息
    首页区域信息加载----缓存数据库-----磁盘数据库----缓存数据库
    1. 尝试从redis 数据库中获取缓存的区域信息
    2. 如果获取过程发生异常,要把获取结果重新置为None值
    3. 判断获取结果,如果有数据直接返回,可留下房屋缓存数据的日志信息
    4. 查询mysql数据库,获取区域信息
    5. 校验查询结果
    6. 对查询结果进行保存,遍历查询结果,调用模型类实例方法,添加区域信息
    7. 序列化数据,转为json,存入缓存中
    8. 拼接字符串,直接返回区域信息的json数据
    :return:
    """
    # 先尝试从redis缓存中获取区域信息
    try:
        ret = redis_store.get('area_info').decode(encoding='utf-8')
    except Exception as e:
        current_app.logger.error(e)
        # 把ret重新置为None值
        ret = None
    # 判断获取结果
    if ret:
        # 记录访问redis数据库房屋区域信息的时间
        current_app.logger.info('hit area info redis')
        # 直接返回区域信息数据
        return '{"errno":0, "errmsg":"OK", "data":%s}' % ret
    # 查询mysql数据库,获取区域信息
    try:
        areas = Area.query.all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='获取区域信息失败')
    # 判断查询结果
    if not areas:
        return jsonify(errno=RET.NODATA, errmsg='无区域信息')
    # 定义列表存储查询结果
    areas_list = []
    # 遍历查询结果,调用模型类的实例方法,添加区域信息数据
    for area in areas:
        areas_list.append(area.to_dict())
    # 转为json字符串,准备存入缓存中
    areas_json = json.dumps(areas_list)
    try:
        redis_store.setex('area_info', constants.AREA_INFO_REDIS_EXPIRES,
                          areas_json)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='缓存区域信息异常')
    # 返回区域信息的json数据
    resp = '{"errno":0, "errmsg":"OK","data":%s}' % areas_json
    return resp
Exemplo n.º 4
0
def login():
    """
    登录:获取参数/检验参数/查询数据/返回结果
    1. 获取post请求的参数,grt_json()
    2. 检验参数存在
    3. 进一步获取详细的参数信息,mobile,password
    4. 对手机号格式进行检验
    5. 查询数据库,确定用户存在
    6. 检查查询结果,对密码正确性进行检验user.check_password_has(password)
    7. 缓存用户信息,session['user_id']= user.id
    8. 返回结果
    :return: 
    """
    # 获取post请求的参数
    user_data = request.get_json()
    if not user_data:
        return jsonify(errno=RET.PARAMERR, errmsg='参数错误')
    # 进一步获取详细的参数信息
    mobile = user_data.get('mobile')
    password = user_data.get('password')
    # 验证参数的完整性
    if not all([mobile, password]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数缺失')
    # 校验手机号格式
    if not re.match(r'1[3455678]\d{9}$', mobile):
        return jsonify(errno=RET.PARAMERR, errmsg='手机号格式错误')
    # 判断用户的错误次数,从redis获取错误次数 remote_addr取出ip地址信息
    user_ip = request.remote_addr
    try:
        access_count = redis_store.get("access_%s" % user_ip)
    except Exception as e:
        current_app.logger.error(e)
    else:
        # 如果错误记录超过最大次数,则直接返回
        if access_count is not None and int(access_count) >= constants.LOGIN_ERROR_MAX_NUM:
            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='查询用户信息异常')
    # 校验查询结果,校验密码,如果用户不存在或者密码错误
    if user is None or not user.check_password(password):
        # 出现错误则累加错误次数,incr
        try:
            redis_store.incr("access_%s" % user_ip)
            redis_store.expire("access_%s" % user_ip, constants.LOGIN_ERROR_FORBID_TIME)
        except Exception as e:
            current_app.logger.error(e)
        return jsonify(errno=RET.DATAERR, errmsg='用户名或密码错误')
    # 登录成功,则清除用户登录错误次数
    try:
        redis_store.delete("access_%s" % user_ip)
    except Exception as e:
        current_app.logger.error(e)
    # 缓存用户信息
    session['user_id'] = user.id
    session['name'] = user.name
    session['mobile'] = mobile
    # 返回结果
    return jsonify(errno=RET.OK, errmsg='OK', data={'user_id': user.id})
Exemplo n.º 5
0
def send_sms_code(mobile):
    """
    发送短信:获取参数/校验参数/查询数据/返回结果
    1. 获取参数,查询字符串的参数获取,mobile, text, id, request.args.get('text')
    2. 校验参数,首先校验参数存在
    3. 校验手机号,正则表达式,re.match(r'^1[]$',mobile)
    4. 校验图片验证码:获取本地存储的真实图片验证码
    5. 判断获取结果,如果图片验证码过期结束程序
    6. 删除图片验证码
    7. 比较图片验证码:统一转成小写比较图片验证码内容是否一致
    8. 生成短信码: 使用random 模块随机数
    9. 在本地保存短信验证码内容,判断用户是否已注册
    10. 调用云通讯发送信息: 使用异常进行处理
    11. 保存云通讯的发送结果,判断是否发送成功
    12. 返回前端结果

    :param modile: 
    :return: 
    """
    # 获取参数, mobile, text, id
    image_code = request.args.get('text')
    image_code_id = request.args.get('id')
    # 校验参数存在
    # any, all 方法判断所有参数全部存在
    if not all([mobile, image_code, image_code_id]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数缺失')
    # 检验手机号,使用正则模块
    if not re.match(r'1[345789]\d{9}$', mobile):
        return jsonify(errno=RET.PARAMERR, errmsg='手机号格式错误')
    # 校验图片验证码,获取本地存储的真实图片验证码
    try:
        real_image_code = redis_store.get('ImageCode_' + image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='查询图片验证码异常')
    # 判断获取结果
    if not real_image_code:
        return jsonify(errno=RET.NODATA, errmsg='图片验证码过期')
    # 图片验证码只能获取一次,无论是否获取到,都必须删除图片验证码
    try:
        redis_store.delete('ImageCode_' + 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='图片验证码错误')
    # 生成短信随机码,使用随机数模块,生成六位数
    sms_code = '%06d' % random.randint(1, 999999)
    # 保存短信验证码
    try:
        redis_store.setex('SMSCode_' + mobile,
                          constants.SMS_CODE_REDIS_EXPIRES, sms_code)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, 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='手机号已注册')

    # 发送短信,调用云通讯接口
    try:
        # 实例化对象
        ccp = sms.CCP()
        # 调用云通讯发送短信方法
        result = ccp.send_template_sms(
            mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES / 60], 1)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR, errmsg='发送短信异常')
    # 判断发送结果
    # if result ==0:
    # 表达式判断,变量写在后面
    if 0 == result:
        return jsonify(errno=RET.OK, errmsg='发送成功')
    else:
        return jsonify(errno=RET.THIRDERR, errmsg='发送失败')
Exemplo n.º 6
0
def register():
    """
    注册
    1. 获取参数,获取post请求的参数,get_json()
    2. 校验参数存在
    3. 进一步获取详细的参数信息
    4. 校验参数的完整性
    5. 校验手机号格式
    6. 校验短信验证码,获取本地存储的真实的短信验证码
    7. 判断查询结果
    8. 如果有数据,比较短信验证码
    9. 删除已经验证过的短信验证码
    10. 判断用户是否注册过
    11. 保存用户信息,User(name=mobile, mobile=mobile), user.password = password
    12. 提交数据到数据库中,需要进行回滚
    13. 缓存用户信息,user.id, name, mobile
    14. 返回结果,user.to_dict()
    
    :return: 
    """

    # 获取post 请求的参数
    user_data = request.get_json()
    # 判断数据存在
    if not user_data:
        return jsonify(errno=RET.PARAMERR, errmsg='参数错误')
    # 进一步获取详细的参数,mobile, sms_code, password
    # user_data['mobile']
    mobile = user_data.get('mobile')
    sms_code = user_data.get('sms_code')
    password = user_data.get('password')
    # 验证参数的完整性
    if not all([mobile, sms_code, password]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数缺失')
    # 验证手机号
    if not re.match(r'^1[34578]\d{9}$', mobile):
        return jsonify(errno=RET.PARAMERR, 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:
            return jsonify(errno=RET.DATAERR, errmsg='手机号已注册')

    # 校验短信验证码
    try:
        real_sms_code = redis_store.get('SMSCode_' + mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='获取短信验证码异常')

    # 判断查询结果
    if not real_sms_code:
        return jsonify(errno=RET.DATAERR, errmsg='短信验证码过期')

    # 比较短信验证码,前端的短信验证码转为str
    if real_sms_code != str(sms_code):
        return jsonify(errno=RET.DATAERR, errmsg='短信验证码错误')

    # 删除短信验证码
    try:
        redis_store.delete('SMSCode_' + mobile)
    except Exception as e:
        current_app.logger.error(e)

        # 保存用户信息, name/mobile/password
        user = User(name=mobile, mobile=mobile)
        # 调用模型类中的加密方法
        user.password = password
        # 提交数据到数据库中
        try:
            db.seesion.add(user)
            db.session.commit()
        except Exception as e:
            current_app.logger.error(e)
            # 写入数据如果发生错误,需要进行回滚
            db.session.rollback()
            return jsonify(errno=RET.DBERR, errmsg='保存用户信息异常')
        # 缓存用户信息
        session['user_id'] = user.id
        session['name'] = mobile
        session['mobile'] = mobile

        # 返回结果
        return jsonify(errno=RET.OK, errmsg='OK', data=user.to_dict())
Exemplo n.º 7
0
def register():
    """
    注册
    1. 获取参数,获取post请求的参数,get_json()
    2. 校验参数存在
    3. 进一步获取详细的参数信息
    4. 校验参数的完整性
    5. 校验手机号格式
    6. 校验短信验证码(或者图片验证码),获取本地存储的真实的短信验证码(或者图片验证码)
    7. 判断查询结果
    8. 如果有数据,比较短信验证码(或者图片验证码)
    9. 删除已经验证过的短信验证码(或者图片验证码)
    10. 判断用户是否注册过
    11. 保存用户信息,User(name=mobile, mobile=mobile), user.password = password
    12. 提交数据到数据库中,需要进行回滚
    13. 缓存用户信息,user.id, name, mobile
    14. 返回结果,user.to_dict()
    
    :return: 
    """

    # 获取post 请求的参数
    user_data = request.get_json()
    # 判断数据存在
    if not user_data:
        return jsonify(errno=RET.PARAMERR, errmsg='参数错误')
    # 进一步获取详细的参数,mobile, sms_code, password
    # user_data['mobile']
    mobile = user_data.get('mobile')
    # sms_code = user_data.get('sms_code')
    captcha_code = user_data.get('captcha_code')  # 验证码
    captcha_id = user_data.get('captcha_id')  # 验证码编号
    password = user_data.get('password')
    # 验证参数的完整性
    if not all([mobile, captcha_code, captcha_id, password]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数缺失')
    # 验证手机号
    if not re.match(r'^1[34578]\d{9}$', mobile):
        return jsonify(errno=RET.PARAMERR, 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:
            return jsonify(errno=RET.DATAERR, errmsg='手机号已注册')

    # # 校验短信验证码
    # try:
    #     real_sms_code = redis_store.get('SMSCode_' + mobile)
    # except Exception as e:
    #     current_app.logger.error(e)
    #     return jsonify(errno=RET.DBERR, errmsg='获取短信验证码异常')
    #
    # # 判断查询结果
    # if not real_sms_code:
    #     return jsonify(errno=RET.DATAERR, errmsg='短信验证码过期')
    #
    # # 比较短信验证码,前端的短信验证码转为str
    # if real_sms_code != str(sms_code):
    #     return jsonify(errno=RET.DATAERR, errmsg='短信验证码错误')

    # # 删除短信验证码
    # try:
    #     redis_store.delete('SMSCode_' + mobile)
    # except Exception as e:
    #     current_app.logger.error(e)

    # 校验图片验证码,获取本地存储的真实图片验证码
    try:
        real_image_code = redis_store.get('ImageCode_' + captcha_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='查询图片验证码异常')
    # 判断获取结果
    if not real_image_code:
        return jsonify(errno=RET.NODATA, errmsg='图片验证码过期')

    # 比较图片验证码内容是否一致
    # 注意:在redis中取出的数据是二进制,需要decode,否则匹配不成功
    if real_image_code.lower().decode(
            encoding='utf-8') != captcha_code.lower():
        return jsonify(errno=RET.DATAERR, errmsg='图片验证码错误')

    # 删除图片验证码
    try:
        redis_store.delete('ImageCode_' + captcha_id)
    except Exception as e:
        current_app.logger.error(e)

    # 保存用户信息
    user = User(name=mobile, mobile=mobile)
    # 调用模型类中的加密方法
    user.password = password
    # 提交数据到数据库中
    try:
        user.add_update()
    except Exception as e:
        current_app.logger.error(e)
        # 写入数据如果发生错误,需要进行回滚
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg='保存用户信息异常')
    # 缓存用户信息
    session['user_id'] = user.id
    session['name'] = mobile
    session['mobile'] = mobile

    # 返回结果
    return jsonify(errno=RET.OK, errmsg='OK', data=user.to_dict())
Exemplo n.º 8
0
def get_houses_list():
    """
    房屋列表页:
    获取参数/校验参数/查询数据/返回结果
    缓存----磁盘----缓存
    1/获取参数,area_id,start_date_str,end_date_str,sort_key,page
    2/参数处理,sort_key给默认值,默认按照房屋发布时间进行排序,page默认加载第一页数据
    3/判断如果有日期参数,对日期进行格式化处理,datetime模块
    4/确认用户选择的开始日期必须小于等于结束结束日期,至少预定1天
    5/对页数进行格式化,page = int(page)
    6/尝试从redis中获取房屋列表信息,每页数据里存储多条数据,需要使用hash数据类型
    ret = redis_store.hget('houses_%s_%s_%s_%s' % (area_id,start_date_str_end_date_str,sort_key))
    7/如果有数据,记录访问房屋列表数据的信息,返回结果
    8/需要查询mysql数据库,
    9/定义查询数据库的过滤条件,params_filter = []主要包括:区域信息/开始日期和结束日期
    10/根据过滤条件查询数据库,按照booking成交量/价格price-inc,price-des/房屋发布时间new;
    houses = House.query.filter(*params_filter).order_by(House.create_time.desc())
    11/对查询结果进行分页,paginate分页返回的结果,包括总页数,房屋数据
    hosues_page = houses.paginate(page,2,False) /False分页如果发生异常不报错
    houses_list = houses_page.items (分页后的房屋数据)
    total_page = houses_page.pages (分页后的总页数)
    12/遍历分页后的房屋数据,获取房屋的基本信息,需要调用模型类中的house_dict_list = to_basic_dict()方法
    13/构造响应数据:
    resp = {"errno":0,"errmsg":"OK","data":{"houses":houses_dict_list,"total_page":total_page,"current_page":page}}
    14/序列化数据,resp_json = json.dumps(resp)
    15/存入缓存中,设置redis中房屋列表数据,判断用户请求的页数小于等于总页数,即请求的页数是有数据的
    16/对多条数据往redis中存储,需要开启事务,确保数据的完整性和一致性,
    pip = redis_store.pipeline()
    pip.multi()/pip.hset(redis_key,page,resp_json)/pip.expire(redis_key,7200)/pip.execute()
    17/返回结果 return resp_json
    :return:
    """
    # 获取参数,当前接口都是可选参数
    area_id = request.args.get('aid', '')
    start_date_str = request.args.get('sd', '')
    end_date_str = request.args.get('ed', '')
    sort_key = request.args.get('sk', 'new')  # 如未传参默认new,房屋发布时间
    page = request.args.get('p', '1')  # 如未传参默认1,房屋列表页
    # 首先对日期进行格式化
    try:
        # 存储日期转换后的结果
        start_date, end_date = None, None
        # 判断如有传入开始日期
        if start_date_str:
            start_date = datetime.datetime.strptime(start_date_str, '%Y-%m-%d')
        # 判断如有传入结束日期:
        if end_date_str:
            end_date = datetime.datetime.strptime(end_date_str, '%Y-%m-%d')
        # 如果开始日期和结束日期都存在,判断开始日期小于等于结束日期,即订房的时间必须是1天
        if start_date_str and end_date_str:
            # 断言代码放入try/except中,会被捕获,
            assert start_date <= end_date
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DATAERR, errmsg='日期格式错误')
    # 对页数进行格式化
    try:
        page = int(page)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DATAERR, errmsg='页数格式错误')
    # 尝试从redis中获取房屋列表信息
    try:
        # 键里包含区域信息/开始日期/结束日期/排序条件/分页
        redis_key = 'houses_%s_%s_%s_%s_%s' % (area_id, start_date_str,
                                               end_date_str, sort_key, page)
        # 尝试获取redis缓存中的数据,指定键,属性
        # ret = redis_store.hget(redis_key, page)
        ret = redis_store.get(redis_key).decode(encoding='utf-8')
    except Exception as e:
        current_app.logger.error(e)
        ret = None
    # 判断查询结果,如有数据直接返回
    if ret:
        # 记录访问redis数据的时间
        current_app.logger.info('hit houses list info redis')
        return ret
    # 查询mysql数据库
    try:
        # 定义列表,存储查询房屋数据的过滤条件
        params_filter = []
        # 校验区域信息的存在
        if area_id:
            # a = [1,3,5,7,9]
            # b = 5
            # a.append(a == b) 添加的数据为true或false
            # 返回的结果是sqlalchemy的对象
            params_filter.append(House.area_id == area_id)
        # 对日期进行处理,决定了房屋能否预定,判断用户如果选择了开始日期和结束日期
        if start_date and end_date:
            # 查询有冲突的订单
            conflict_orders = Order.query.filter(
                Order.begin_date <= end_date,
                Order.end_date >= start_date).all()
            # 遍历有冲突的订单,获取有冲突的房屋
            conflict_houses_id = [order.house_id for order in conflict_orders]
            # 判断有冲突的房屋是否存在
            if conflict_houses_id:
                # 存入过滤参数中,进行取反操作,获取所有不冲突的房屋
                params_filter.append(House.id.notin_(conflict_houses_id))
        # 如果用户只选择了开始日期
        if start_date:
            # 查询开始日期有冲突的订单数据
            conflict_orders = Order.query.filter(
                Order.end_date >= start_date).all()
            # 遍历有冲突的订单数据
            conflict_houses_id = [order.house_id for order in conflict_orders]
            # 判断有冲突的房屋存在
            if conflict_houses_id:
                params_filter.append(House.id.notin_(conflict_houses_id))
        # 如果用户只选择了结束日期
        if end_date:
            conflict_orders = Order.query.filter(
                Order.begin_date <= end_date).all()
            conflict_houses_id = [order.house_id for order in conflict_orders]
            if conflict_houses_id:
                params_filter.append(House.id.notin_(conflict_houses_id))
        # 过滤条件已经完成,执行查询语句,获取房屋数据,进行排序查询
        # 判断排序条件,按房屋成交排序查询
        if 'booking' == sort_key:
            houses = House.query.filter(*params_filter).order_by(
                House.order_count.desc())
        # 按照房屋价格进行排序
        elif 'price-inc' == sort_key:
            houses = House.query.filter(*params_filter).order_by(
                House.price.asc())
        elif 'prcie-des' == sort_key:
            houses = House.query.filter(*params_filter).order_by(
                House.price.desc())
        # 如果用户未选择排序条件,默认按照房屋发布时间进行排序
        else:
            houses = House.query.filter(*params_filter).order_by(
                House.create_time.desc())
        # 对查询结果进行分页,page:页数,每页条目书,False分页出错,不会报错
        houses_page = houses.paginate(page, constants.HOUSE_LIST_PAGE_CAPACITY,
                                      False)
        # 存储分页后的房屋数据
        houses_list = houses_page.items
        # 存储分页后的总页数
        total_page = houses_page.pages
        # 定义列表,存储分页后的数据
        houses_dict_list = []
        # 遍历分页后的数据,调用了模型类方法,获取房屋基本数据
        for house in houses_list:
            houses_dict_list.append(house.to_basic_dict())
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='查询房屋列表信息失败')
    # 构造响应数据
    resp = {
        "errno": 0,
        "errmsg": "OK",
        "data": {
            "houses": houses_dict_list,
            "total_page": total_page,
            "current_page": page
        }
    }
    # 序列化数据
    resp_json = json.dumps(resp)
    # 判断用户请求的页数必须有数据
    if page <= total_page:
        try:
            # 构造redis_key
            redis_key = 'houses_%s_%s_%s_%s_%s' % \
                        (area_id, start_date_str, end_date_str, sort_key, page)
            redis_store.setex(redis_key,
                              constants.HOME_PAGE_DATA_REDIS_EXPIRES,
                              resp_json)
        except Exception as e:
            current_app.logger.errno(e)
        # # 使用hash数据类型,对多条数据需要统一操作,使用事务
        # pip = redis_store.pipeline()
        # try:
        #     # 开启事务
        #     pip.multe()
        #     # 设置数据
        #     pip.hset(redis_key, page, resp_json)
        #     # 设置过期时间
        #     pip.expire(redis_key, constants.HOUSE_LIST_REDIS_EXPIRES)
        #     # 执行事务
        #     pip.execute()
        # except Exception as e:
        #     print(e)
        #     current_app.logger.error(e)
    # 返回结果
    return resp_json