Beispiel #1
0
def get_image_code():
    """
    获取图片验证码
    1.接收请求,获取UUID和上一个uuid
    2.判断数据库保存的uuid是否等于last_uuid等于删除,
    3.生成图片验证码
    4.保存新的uuid,对应的图片文本信息
    :return: josnify 验证码图片
    """
    # 1.接收请求,获取UUID,last_uuid
    uuid=request.args.get('uuid')
    last_uuid=request.args.get('last_uuid')
    if not uuid:
        #缺省参数报403异常
        abort(403)
    # 2.生成图片验证码 名字,文字信息,图片信息
    name, text, image = captcha.generate_captcha()
    current_app.logger.debug('图片验证码信息:'+text)
    # 4.删除上次生成的验证码图片
    try:
        if last_uuid:
            redis_conn.delete('ImageCode:'+last_uuid)
        # 3.保存UUID对应的验证码文字信息,设置时长
        redis_conn.set('ImageCode:' + uuid, text,constants.IMAGE_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.debug(e)
        return jsonify(re_code=RET.DBERR,msg='保存图片验证码失败')
    response=make_response(image)
    response.headers['Content-Type']='image/jpg'
    return response
Beispiel #2
0
def image_code(image_code_id):
    """ 获取图片验证码

    Args:
        image_code_id:   图片验证码编号
    Retruns:
        正常情况(验证码图片)  错误情况(错误信息)

    """
    # 1. 业务逻辑处理
    if not image_code_id:
        return jsonify(errcode=RET.NODATA, errmsg='缺少数据')

    # 2. 生成验证码图片
    name, text, image_data = captcha.generate_captcha()
    # print(text)

    # 将验证码真实值与编号保存到redis中, 使用字符串数据存储单条记录: 'image_code_编号': '验证码真实值'
    try:
        redis_conn.set('image_code_{}'.format(image_code_id),
                       text,
                       ex=current_app.config.get('IMAGE_CODE_REDIS_EXPIRE'))
    except Exception as e:
        # 记录日志
        current_app.logger.error(e)
        return jsonify(errcode=RET.DBERR, errmsg='保存图片验证码失败')

    # 3. 返回图片
    resp = make_response(image_data)
    resp.headers['Content-Type'] = 'image/jpg'
    return resp
Beispiel #3
0
def get_areas():
    """获取城区信息:
    1.查询出所有城区信息
    2.响应数据
    """
    # 1.查询所有城区信息
    try:
        resp_json = redis_conn.get("area_info")
    except Exception as e:
        current_app.logger.error(e)
    else:
        if resp_json:
            current_app.logger.info("hit redis area_info")
            return resp_json.decode(), 200, {"Content-Type": "application/json"}

    try:
        areas = Area.query.all()
    except Exception as e:
        current_app.logger.debug(e)
        return jsonify(re_code=RET.DBERR, msg='查询城区信息失败')

    if not areas:
        return jsonify(re_code=RET.NODATA, msg='暂无城区')

    areas = [area.to_dict() for area in areas]

    resp_dict = dict(re_code=RET.OK, msg='查询城区成功', areas=areas)
    resp_json = json.dumps(resp_dict)

    try:
        redis_conn.set("area_info", resp_json, constants.AREA_INFO_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)

    return resp_json, 200, {"Content-Type": "application/json"}
Beispiel #4
0
def get_hosue_details():
    """ 获取房屋详情信息 """
    # 接收路径参数
    house_id = request.args.get('house_id')
    if not house_id:
        return jsonify(errcode=RET.PARAMERR, errmsg="缺少必须参数, 请检查路径是否正确")

    # 尝试获取访问者的id, 如果获取为空, 将使用默认值'-1'替代
    call_user_id = session.get('user_id', '-1')

    # 尝试从redis中读取缓存数据
    try:
        json_house = redis_conn.get('house_info_{}'.format(house_id))
    except Exception as e:
        current_app.logger.error(e)
    else:
        if json_house is not None:
            return '{{"errcode": "0", "errmsg": "OK", "data": {0}, "call_user_id": {1}}}'.format(json_house.decode(), call_user_id), \
                200, {"Content-Type": "application/json"}

    # 查询数据库
    try:
        house = House.query.filter_by(id=house_id).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errcode=RET.DBERR, errmsg="数据库异常")

    if house is None:
        return jsonify(errcode=RET.NODATA, errmsg="没有查询到数据")

    try:
        # 先将数据转换为字典, 这是在模型中封装的方法
        house_data_dict = house.to_full_dict()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errcode=RET.SERVERERR, errmsg="数据提取失败, 请联系管理员")
    else:
        # 将数据存放到redis中
        json_house = json.dumps(house_data_dict)

    # 获取设置的redis过期时间, 配置文件中
    redis_expires = current_app.config.get('HOME_PAGE_DATA_REDIS_EXPIRES')
    try:
        redis_conn.set('house_info_{}'.format(house_id),
                       json_house,
                       ex=redis_expires)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errcode=RET.DBERR, errmsg="设置缓存异常")

    # return jsonify(errcode=RET.OK, errmsg="OK", data=house.to_full_dict())
    return '{{"errcode": "0", "errmsg": "OK", "data": {0},  "call_user_id": {1}}}'.format(
        json_house, call_user_id), 200, {
            "Content-Type": "application/json"
        }
Beispiel #5
0
def get_house_index():
    """ 获取主页幻灯片 """
    # 设置首页获取首页的幻灯片数量
    HOME_PAGE_MAX_IMAGE = 5
    # 尝试从缓存中读取
    try:
        json_houses = redis_conn.get('home_page_data')
    except Exception as e:
        current_app.logger.error(e)

    if json_houses is not None:
        return '{{"errcode": "0", "errmsg": "OK", "data": {}}}'.format(
            json_houses.decode()), 200, {
                "Content-Type": "application/json"
            }
    else:
        # 查询数据库
        try:
            houses = House.query.order_by(
                House.order_count.desc()).limit(HOME_PAGE_MAX_IMAGE).all()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errcode=RET.DBERR, errmsg="查询数据库失败")

        if not houses:
            return jsonify(errcode=RET.NODATA, errmsg="抱歉, 暂时没有查到数据")

        houses_list = []
        # 遍历house表的查询集
        for house in houses:
            # 如果房屋未设置主图片, 则跳过
            if not house.index_image_url:
                continue
            houses_list.append(house.to_basic_dict())

        # 将数据转换为json, 并保存到redis缓存中, 字符串类型
        json_houses = json.dumps(houses_list)
        # 获取redis缓存时间
        home_page_data_redis_expires = current_app.config.get(
            'HOME_PAGE_DATA_REDIS_EXPIRES')
        try:
            redis_conn.set('home_page_data',
                           json_houses,
                           ex=home_page_data_redis_expires)
        except Exception as e:
            current_app.logger.error(e)

        return '{{"errcode": "0", "errmsg": "OK", "data": {}}}'.format(
            json_houses), 200, {
                "Content-Type": "application/json"
            }
Beispiel #6
0
def get_area_info():
    """ 获取城区信息 """
    # 尝试从redis中读取数据, 如果读取成功则使用缓存返回给前端, 否则从数据库获取
    try:
        resp_json = redis_conn.get('area_info')
    except Exception as e:
        current_app.logger.error(e)
    else:
        if resp_json is not None:
            # 代表redis中已经具有缓存数据
            current_app.logger.info('hit redis area_info')  # 表示拿到了数据, 记录日志
            return resp_json, 200, {'Content-Type': 'application/json'}

    # 查询数据库读取城区信息
    try:
        area_li = Area.query.all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errcode=RET.DBERR, errmsg="数据库异常")

    area_dict_li = []
    # 将对象转为字典
    for area in area_li:
        # 得到每行数据的字段, to_dict是在model里封装的方法
        area_dict_li.append(area.to_dict())

    # 将返回的数据转换为json字符串
    resp_dict = dict(errcode=RET.OK, errmsg='ok', data=area_dict_li)
    resp_json = json.dumps(resp_dict)

    # 将数据保存到redis中
    try:
        # 注意这里一定要设置有效期, 否则哪怕数据库的记录更新了, 返回给前端的也是历史记录的缓存
        redis_conn.set(
            'area_info',
            resp_json,
            ex=current_app.config.get('AREA_INFO_REDIS_CACHE_EXPIRES'))
    except Exception as e:
        current_app.logger.error(e)

    return resp_json, 200, {'Content-Type': 'application/json'}
Beispiel #7
0
def house_detail(house_id):
    """房屋详情页面:
    1.获取url栏中的house_id
    2.根据house_id获取house详细信息
    3.判断用户是否登录,
    4.响应结果
    """
    # 1.获取url栏中的house_id
    # 2.根据house_id获取house详细信息
    try:
        resp_json = redis_conn.get("house_info_{}".format(house_id))
    except Exception as e:
        current_app.logger.error(e)
    else:
        if resp_json:
            current_app.logger.info("hit redis house_info_{}".format(house_id))
            return resp_json.decode(), 200, {"Content-Type": "application/json"}
    try:
        house = House.query.get(house_id)
    except Exception as e:
        current_app.logger.debug(e)
        return jsonify(re_code=RET.DBERR, msg='查询房屋信息失败')

    if not house:
        return jsonify(re_code=RET.NODATA, msg='房屋不存在')
    house = house.to_full_dict()
    # 3. 获取user_id : 当用户登录后访问detail.html,就会有user_id,反之,没有user_id
    login_user_id = session.get('user_id', -1)

    resp_dict = dict(re_code=RET.OK, msg='查询成功', data={'house': house, 'login_user_id': login_user_id})
    resp_json = json.dumps(resp_dict)

    try:
        redis_conn.set("house_info_{}".format(house_id), resp_json, constants.AREA_INFO_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)

    # 4.响应结果
    return resp_json, 200, {"Content-Type": "application/json"}
Beispiel #8
0
def get_sms_code(mobile):
    """ 获取短信验证码
    Args:
        mobile: 注册人的手机号

    URL Param:
        image_code_id: 图片验证码id
        image_code   : 图片验证码

    Retruns:
        正常情况: 发送成功的json信息
        错误情况: 异常的json信息

    """
    # 1. 业务逻辑处理
    # 获取短信验证码的过期时间
    sms_code_redis_expire = current_app.config.get('SMS_CODE_REDIS_EXPIRE')
    if sms_code_redis_expire % 60 != 0:
        return jsonify(errcode=RET.PARAMERR, errmsg='短信验证码过期时间不合法, 需为60的整除数')

    # 效验参数是否缺失
    image_code_id = request.args.get('image_code_id')
    image_code = request.args.get('image_code')
    if not all([mobile, image_code_id, image_code]):
        return jsonify(errcode=RET.PARAMERR, errmsg='参数不全')

    # 效验手机号是否合法
    res = re.match(r"^1[3456789]\d{9}$", mobile)
    if res is None:
        return jsonify(errcode=RET.DATAERR, errmsg='非法数据, 不是合法的手机号')

    # 效验图片验证码是否正确, 从redis中取出真实的验证码, 与用户输入的值对比
    try:
        real_image_code = redis_conn.get('image_code_{}'.format(image_code_id))
    except Exception as e:
        # 记录错误日志
        current_app.logger.error(e)
        return jsonify(errcode=RET.DBERR, errmsg='读取Redis数据库异常')

    # 判断图片验证码是否过期
    if real_image_code is None:
        return jsonify(errcode=RET.NODATA, errmsg='图片验证码已失效, 请点击更换重试')

    # 对比验证码
    if real_image_code.decode().lower() != image_code.lower():
        # 表示用户填写错误
        return jsonify(errcode=RET.DATAERR, errmsg='图片验证码错误')

    # 删除已经使用的验证码, 防止对同一个验证码进行多次验证
    try:
        redis_conn.delete('image_code_{}'.format(image_code_id))
    except Exception as e:
        # 记录错误日志, 这里只是一个逻辑操作, 不要提前返回
        current_app.logger.error(e)

    # 判断用户在短时间内是否发送过验证码, 如60s内, 如果有发送记录, 则在规定时间内不允许发送第二次
    try:
        send_sign = redis_conn.get('send_sms_code_{}'.format(mobile))
    except Exception as e:
        # 记录错误日志
        current_app.logger.error(e)
    else:
        if send_sign is not None:
            # 表示用于在短时间内有发送短信的记录, RET.REQERR = "4201"
            return jsonify(errcode=RET.REQERR, errmsg='请求次数受限, 请于60秒后发送')

    # 判断手机号是否已存在, 如果不存在, 则生成短信验证码, 发送短信
    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        # 记录错误日志, 这里不能return终止, 因为可能会出现用户信息正确, 但数据库异常的情况, 此时应该让用户继续注册
        current_app.logger.error(e)
    else:
        if user is not None:
            # 表示手机号已存在
            return jsonify(errcode=RET.DATAEXIST, errmsg='该手机号已经注册')

    # 设置短信验证码, 并保存在redis中
    sms_code = '{0:0>6}'.format(random.randint(0, 999999))
    try:
        # 在redis保存字符串数据
        redis_conn.set('sms_code_{}'.format(mobile),
                       sms_code,
                       ex=sms_code_redis_expire)
        # 保存发送短信的手机号记录, 防止用户在短时间内(如60s)执行重复发送短信的操作
        redis_conn.set('send_sms_code_{}'.format(mobile),
                       'yes',
                       ex=current_app.config.get('SEND_SMS_CODE_INTERVAL'))
    except Exception as e:
        # 记录错误日志
        current_app.logger.error(e)
        return jsonify(errcode=RET.DBERR, errmsg='短信验证码保存异常')

    # 保存短信验证码到redis中: 手机号(key): 验证码(value) 字符串类型
    # ccp = CCP()
    # result = ccp.sendTemplateSMS(mobile, [sms_code, str(sms_code_redis_expire / 60)], '1')
    # if result == 0:
    #     # 发送成功
    #     return jsonify(errcode=RET.OK, errmsg='短信发送成功')
    # else:
    #     return jsonify(errcode=RET.THIRDERR, errmsg='短信发送失败, 第三方错误')

    # 使用celery进行异步请求, 发送短信
    send_sms.delay(mobile, [sms_code, str(sms_code_redis_expire / 60)], '1')

    # 因为selery是异步操作的, 它的执行不会对这里产生阻塞, 所以我们设想, 只要发送了, 就代表成功了
    return jsonify(errcode=RET.OK, errmsg='短信发送成功')
Beispiel #9
0
def send_sms_code():
    """发送手机短信息验证码:
    1.接收参数,手机号,图片验证码,uuid
    2.校验数据
    3.判断图片验证码是否正确,如果正确
    4.发送短信验证码
    """
    # 1.接收参数,手机号,图片验证码,uuid
    json_str=request.data
    json_dict=json.loads(json_str)
    phone_num=json_dict.get('phone_num')
    image_code_client=json_dict.get('image_code')
    uuid=json_dict.get('uuid')
    # 2.校验数据
    if not all([phone_num,image_code_client,uuid]):
        return jsonify(re_code=RET.PARAMERR,msg='参数缺少')

    # 校验手机号是否正确
    if not re.match(r'^0\d{2,3}\d{7,8}$|^1[358]\d{9}$|^147\d{8}$',phone_num):
        return jsonify(re_code=RET.PARAMERR,msg='手机号不正确')

    #判断用户是否已注册
    try:
        user=User.query.filter(User.phone_num == phone_num).first()
    except Exception as e:
        current_app.logger.debug(e)
        return jsonify(re_code=RET.DBERR,msg='查询数据库错误')
    #用户存在,提示该账户已被注册
    if user:
        return jsonify(re_code=RET.DATAEXIST,msg='该用户已被注册')
    # 3.判断图片验证码是否正确,如果正确
    try:
        # 从Redis取出值图片验证码
        image_code_server=redis_conn.get('ImageCode:'+uuid)
    except Exception as e:
        current_app.logger.debug(e)
        return jsonify(re_code=RET.DBERR,msg='获取服务器图片验证码失败')

    #判断为验证码空或者过期
    if not image_code_server:
        return jsonify(re_code=RET.NODATA,msg='验证码已过期')

    #校验和前端传的验证码是否相等
    if image_code_server.lower()!=image_code_client.lower():
        return jsonify(re_code=RET.DATAERR,msg='验证码输入有误')

    # 4.生成验证码
    sms_code='%06d' % random.randint(0,99999)
    current_app.logger.debug('短信验证码为:'+sms_code)
    # 5.发送短信验证码            验证码         过期时间:容联的时间单位为:分   短信模板1
    # result = CCP().send_sms('15770633066',[sms_code,constants.SMS_CODE_REDIS_EXPIRES/60],'1')
    # if result != 1:
    #     # 短信发送失败
    #     return jsonify(re_code=RET.THIRDERR,msg='发送短信验证码失败')
    # 6.发送成功,验证码存储到Redis
    try:
        redis_conn.set('PhoneCode:'+phone_num,sms_code,constants.SMS_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.debug(e)
        return jsonify(re_code=RET.DBERR,msg='存储短信验证码失败')
    #响应结果
    return jsonify(re_code=RET.OK,msg='验证码发送成功')
Beispiel #10
0
def send_sms_code():
    """发送手机短信息验证码:
    1.接收参数,手机号,图片验证码,uuid
    2.校验数据
    3.判断图片验证码是否正确,如果正确
    4.发送短信验证码
    """
    # 接收参数,手机号,图片验证码,uuid
    json_str = request.data
    json_dict = json.loads(json_str)
    phone_num = json_dict.get('phone_num')
    image_code_client = json_dict.get('image_code')
    uuid = json_dict.get('uuid')
    # 校验数据
    if not all([phone_num, image_code_client, uuid]):
        return jsonify(re_code=RET.PARAMERR, msg='参数缺少')

    # 校验手机号是否正确
    if not re.match(
            r'^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\d{8}$',
            phone_num):
        return jsonify(re_code=RET.PARAMERR, msg='手机号不正确')

    # 判断用户是否已注册
    try:
        user = User.query.filter(User.phone_num == phone_num).first()
    except Exception as e:
        current_app.logger.debug(e)
        return jsonify(re_code=RET.DBERR, msg='查询数据库错误')

    # 用户存在,提示该账户已被注册
    if user:
        return jsonify(re_code=RET.DATAEXIST, msg='该用户已被注册')

    # 判断图片验证码是否正确,如果正确
    try:
        # 从Redis取出值图片验证码
        image_code_server = redis_conn.get('ImageCode:' + uuid)
    except Exception as e:
        current_app.logger.debug(e)
        return jsonify(re_code=RET.DBERR, msg='获取服务器图片验证码失败')

    # 判断为验证码空或者过期
    if not image_code_server:
        return jsonify(re_code=RET.NODATA, msg='验证码已过期')

    # 校验和前端传的验证码是否相等
    if image_code_server.decode().lower() != image_code_client.lower():
        return jsonify(re_code=RET.DATAERR, msg='验证码输入有误')

    # 4.生成验证码
    sms_code = '%06d' % random.randint(0, 99999)
    current_app.logger.debug('短信验证码为:' + sms_code)
    # 5.发送短信验证码            验证码
    # 后台设置
    # 同一个手机号同一个验证码模板,每30秒只能获取1条
    # 同一个手机号验证码类内容,每小时最多能获取3条
    # 同一个手机号验证码类内容,24小时内最多能获取到10条
    # result = SendSMS().send_sms(phone_num, sms_code)
    # if not result:
    #     # 短信发送失败
    #     return jsonify(re_code=RET.THIRDERR, msg='发送短信验证码失败')
    # 6.发送成功,验证码存储到Redis
    try:
        redis_conn.set('PhoneCode:' + phone_num, sms_code,
                       constants.SMS_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.debug(e)
        return jsonify(re_code=RET.DBERR, msg='存储短信验证码失败')
    # 响应结果
    return jsonify(re_code=RET.OK, msg='验证码发送成功')