def sms_code(mobile): """获取短信验证码""" # 接收数据 image_code = request.args.get('image_code') image_code_id = request.args.get('image_code_id') # 校验数据 # 验证码数据是否存在 if not all([image_code, image_code_id]): return jsonify(errcode=RET.DATAERR, errmsg='验证码信息不全') try: redis_code = redis_store.get('image_code_%s' % image_code_id) redis_store.delete('image_code_%s' % image_code_id) except Exception as e: current_app.logger.error(e) return jsonify(errcode=RET.DBERR, errmag='数据库信息错误') if redis_code is None: return jsonify(errcode=RET.NODATA, errmsg='验证码过期') elif image_code.lower() != redis_code.lower(): return jsonify(errcode=RET.DATAERR, errmag='验证码错误') # 业务逻辑处理 # 查询用户手机是否存在 try: if User.query.filter_by(mobile=mobile).first(): return jsonify(errcode=RET.DATAEXIST, errmsg='手机号已被注册') except Exception as e: current_app.logger.error(e) # 短信验证码 sms_codes = '%06d' % random.randint(0, 999999) # 将短信验证码存入redis try: if redis_store.get('mobile_%s' % mobile) is None: redis_store.setex('sms_code_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_codes) redis_store.setex('mobile_%s' % mobile, constants.SMS_SEND_TIME, 1) else: return jsonify(errcode=RET.DATAEXIST, errmsg='请求过于频繁,稍后再尝试') except Exception as e: current_app.logger.error(e) return jsonify(errcode=RET.DBERR, errmag='数据库信息错误') # 发送信息 try: # 发送短信 sms_sender = CCP() resp = sms_sender.sendTemplateSMS(mobile, [sms_codes, 5], 1) except Exception as e: current_app.logger.error(e) return jsonify(errcode=RET.THIRDERR, errmsg='第三方系统错误') # 返回 if resp: return jsonify(errcode=RET.OK, errmsg='发送成功') else: return jsonify(errcode=RET.THIRDERR, errmsg='第三方系统错误')
def get_sms_code(mobile): """获取短信""" image_code = request.args.get("image_code") image_code_id = request.args.get("image_code_id") if not all([image_code, image_code_id]): return jsonify(errno=RET.PARAMERR, errmsg="参数不完整") # 取出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(errno=RET.DBERR, errmsg="redis error") if real_image_code is None: return jsonify(errno=RET.NODATA, errmsg="code older") # remove verification code try: redis_store.delete("image_code_%s" % 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="code error") # 判断是否发送过 try: send_flag = redis_store.get("send_sms_%s" % mobile) except Exception as e: current_app.logger.error(e) else: if send_flag is not None: return jsonify(errno=RET.REQERR, errmsg="time not achieve") # 判断手机号是否存在 try: user = User.query.filter_by(mobile=mobile).firs() except Exception as e: current_app.logger.error(e) else: if user is not None: return jsonify(errno=RET.DATAEXIST, errmsg="mobile exist") # 生成短信验证码 sms_code = "%06d" % random.randint(0, 999999) try: redis_store.setex("sms_code_%s" % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code) # redis_store.setex("send_sms_%s" % mobile, constants.SEND_SMS_CODE_INTERVAL, 1) except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR, errmsg="save sms code error") # 发送短信西 try: # ccp = CCP() # result = ccp.send_template_sms(mobile, [sms_code, int(constants.SMS_CODE_REDIS_EXPIRES / 60)], 1) send_sms.delay( mobile, [sms_code, int(constants.SMS_CODE_REDIS_EXPIRES / 60)], 1) except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.THIRDERR, errmsg="send error") return jsonify(errno=RET.OK, errmsg="ok")
def get_sms_code(mobile): """ 发送手机验证码 :param mobile: :return: """ image_code = request.args.get("image_code") image_code_id = request.args.get("image_code_id") if not all([image_code, image_code_id]): return jsonify(errno=RET.PARAMERR, errmsg="参数不完整") try: redis_image_code = redis_store.get("image_code_%s" % image_code_id) redis_store.delete("image_code_%s" % image_code_id) except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR, errmsg="数据库异常") if redis_image_code is None: return jsonify(errno=RET.NODATA, errmsg="验证码过期") if redis_image_code.lower() != image_code.lower(): return jsonify(errno=RET.DATAERR, errmsg="验证码错误") try: # 判断在60秒内用户有没有发送过验证码,如果有表示用户请求频繁,拒绝处理 send_flg = redis_store.get("send_sms_code_%s" % mobile) except Exception as e: current_app.logger.error(e) else: if send_flg is not None: # 60秒内发送过验证码 return jsonify(errno=RET.REQERR, errmsg="请求过于平凡,请60秒后再试") # 生成手机验证码信息 sms_code = "%06d" % random.randint(0, 999999) try: redis_store.setex("sms_code_%s" % mobile, constants.SMS_CODE_REDIS_EXPIRES, 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(errno=RET.DBERR, errmsg="保存验证码异常") try: ccp = CCP() result = ccp.send_template_sms(mobile, [sms_code, int(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: return jsonify(errno=RET.OK, errmsg="发送成功") else: return jsonify(errno=RET.THIRDERR, errmsg="发送失败")
def get_area_info(): '''获取城区信息''' try: resp_json = redis_store.get("area_info") except Exception as e: current_app.logger.error(e) else: if resp_json is not None: resp_json = resp_json.decode() 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(errno=RET.DBERR, errmsg="数据库异常") area_dict_li = [] for area in area_li: area_dict_li.append(area.to_dict()) resp_dict = dict(errno=RET.OK, errmsg="ok", data=area_dict_li) resp_json = json.dumps(resp_dict) try: redis_store.setex("area_info", constants.AREA_INFO_REDIS_CACHE_EXPIRES, resp_json) except Exception as e: current_app.logger.error() return resp_json, 200, {"Content-Type": "application/json"}
def get_area_info(): """获取城区信息""" # 先从redis中取数据,如果没有,再去mysql中取数据 try: resp_json = redis_store.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, 200, {"Content-Type": "application/json"} try: area_li = Area.query.all() except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR, errmsg="mysql数据库错误") area_dict = [] for area in area_li: area_dict.append(area.to_dict()) resp_dict = dict(errno=RET.OK, errmsg="OK", data=area_dict) 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 get_area_info(): '''获取城区信息''' # 尝试从redis中获取缓存 try: resp_json = redis_store.get('area_info').decode() except Exception as e: current_app.logger.error(e) else: if resp_json: print('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(errno=RET.DBERR, errmsg="数据库异常") # 组织数据 area_dict_li = list() for area in area_li: area_dict_li.append(area.to_dict()) # 将数据保存到redis中,作为缓存使用,将响应结果直接转换为json字符串 resp_dict = dict(errno=RET.OK, errmsg="获取成功", data=area_dict_li) resp_json = json.dumps(resp_dict) try: redis_store.setex('area_info', constants.AREA_INFO_REDIS_EXPIRE, resp_json) except Exception as e: current_app.logger.error(e) return resp_json, 200, {"Content-Type": "application/json"}
def get_area_info(): # 一. 逻辑处理 ''' 1. 读取redis中的缓存数据 2. 没有缓存, 去查询数据库 3. 为了将来读取方便, 在存入redis的时候, 将数据转为JSON字典 4. 将查询的数据, 存储到redis中 ''' # 1. 读取redis中的缓存数据 try: areas_json = redis_store.get('area_info') except Exception as e: logging.error(e) # 这里不需要返回错误信息, 因为没有会直接查询数据库 # 为了避免异常的事情发生, 如果执行失败, 就把数据设置为None areas_json = None # 2. 没有缓存, 去查询数据库 if areas_json is None: # 查询区域信息 areas_list = Area.query.all() # 3. 数据转JSON areas = [] # for area in areas_list: # # 调用模型的转字典方法, 不断拼接成一个areas # areas.append(area.to_dict()) # # # 将areas转换成JSON, 方便将来保存redis, 方便返回数据 # # # json.dumps 将list类型转换成了str # areas_dict = {'areas': areas} # areas_json = json.dumps(areas_dict) # 调用模型的转字典方法, 不断拼接成一个areas areas_dict = {'areas': [area.to_dict() for area in areas_list]} # 将字典类型转换成了str areas_json = json.dumps(areas_dict) # 4. 保存redis中 try: redis_store.setex('area_info', constants.AREA_INFO_REDIS_EXPIRES, areas_json) except Exception as e: logging.error(e) # 这里如果出错, 可以不用返回错误信息. 因此如果redis没有保存, 那么下一次会直接访问Mysql读取数据, 再次保存 # 二. 返回数据 # 1. 希望返回的数据, data里是一个字典 # return jsonify(errno=RET.DBERR, errmsg='查询城区信息成功', data=areas) # 2. json.dumps --> jsonify --> 连续转换, 第二次会将第一次的结果当做一个字符串的value进行二次转换 # return jsonify(errno=RET.DBERR, errmsg='查询城区信息成功', data={'areas': areas_json}) # 3. a. 因为前面已经转换过了. 这里不需要二次转换. b.JSON格式消耗性能, 返回原生字典会比较快 # return '{"errno": 0, "errmsg": "查询城区信息成功", "data":%s}' % areas_json, 200, \ # {"Content-Type": "application/json"} return '{"errno": 0, "errmsg": "查询城区信息成功", "data":%s}' % areas_json '''
def get_areas_info(): """获取城区信息""" #从redis中获取缓存 try: area_dict = redis_store.get("area_info") except Exception as e: current_app.logger.reeor(e) else: if area_dict is not None: current_app.logger.info("hit redis area_info") # 有缓存 返回数据 return jsonify(errno=RET.OK, errmsg="OK", data=area_dict) #无缓存,查询数据库 try: area_li = Area.query.all() print(area_li) except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR, errmsg="数据库查询失败") # 拼装城区数据 aera_dict_li = [] for area in area_li: aera_dict_li.append(area.to_dict()) #设置缓存到redis try: redis_store.setex("area_info", constants.AREA_INFO_REDIS_CACHE_EXPIRES, aera_dict_li) except Exception as e: current_app.logger.error(e) #返回数据 return jsonify(errno=RET.OK, errmsg="OK", data=aera_dict_li)
def login(): """ 用户登录 传递参数: 手机号 密码 格式: json :return: """ # 接收参数 req_dict = request.get_json() mobile = req_dict.get("mobile") password = req_dict.get("password") # 校验参数 # 判断参数是否完整 if not all([mobile, password]): return jsonify(errnum=RET.PARAMERR, errmsg=u"参数不完整") # 判断手机格式是否正确 if not re.match(r"1[345678]\d{9}", mobile): return jsonify(errnum=RET.PARAMERR, errms=u"手机格式不正确") # 输入错误5次, 封ip10分钟 # 查询ip user_ip = request.remote_addr try: access_num = redis_store.get("access_num_%s" % user_ip) except Exception as e: current_app.logger.error(e) else: if access_num is not None and int(access_num) >= LOGIN_ERROR_MAX_TIMES: return jsonify(errnum=RET.REQERR, errmsg=u"请求次数过多, 请稍后再试") # 根据手机号查询数据库, 判断有没该用户 try: user = User.query.filter_by(mobile=mobile).first() except Exception as e: current_app.logger.error(e) return jsonify(errnu=RET.DBERR, errmsg=u"获取用户信息失败") # 判断是否有该用户并且进行密码比对 if user is None or not user.check_password(password): # 记录登录次数, 并且设置有效期 try: redis_store.incr("access_num_%s" % user_ip) redis_store.expire("access_num_%s" % user_ip, LOGIN_ERROR_FORBID_TIME) except Exception as e: current_app.logger.error(e) return jsonify(errnum=RET.ROLEERR, errmsg=u"没有该用户") # 业务处理 # 保存用户登录状态到session中 session["name"] = user.name session["mobile"] = user.mobile session["user_id"] = user.id # 返回应答 return jsonify(errnum=RET.OK, errmsg=u"登录成功")
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('hide redis area_info') return resp_json, 200, {"Contant-Type": 'application/json'} # 查新数据库 try: area_li = 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_li: 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_EXPIRE, resp_json) except Exception as e: current_app.logger.error(e) return resp_json, 200, {"Contant-Type": 'application/json'}
def get_area_info(): """获取城区信息""" # 先从redis中尝试获取城区信息 try: areas_json = redis_store.get("area_info") except Exception as e: current_app.logger.error(e) areas_json = None if areas_json is None: # 查询数据库获取城区信息 try: areas_list = Area.query.all() except Exception as e: current_app.logger.error(e) return jsonify(error_code=RET.DBERR, errmsg="查询城区信息异常") # 遍历列表,处理每一个对象,转换一下对象的属性名 areas = [] for area in areas_list: areas.append(area.to_dict()) # 将数据转换为json areas_json = json.dumps(areas) # 将数据在redis中保存一份缓存 try: redis_store.setex("area_info", constants.AREA_INFO_REDIS_EXPIRES, areas_json) except Exception as e: current_app.logger.error(e) return '{"error_code": 0, "errmsg": "查询城区信息成功", "data": {"areas": %s}}' % areas_json, 200, \ {"Content-Type": "application/json"}
def get_areas(): """查询全部区域 由于区域访问频繁,但是更新不频繁,所以可以放入redis缓存 """ try: rsp_json = redis_store.get('area_info') except Exception as e: current_app.logger.error(e) else: if rsp_json is not None: current_app.logger.info('hit area into redis') return rsp_json, 200, {'Content-Type': 'application/json'} try: areas = Area.query.all() except Exception as e: current_app.logger.err(e) return jsonify(errno=RET.DBERR, errmsg='数据库查询异常') areas_list = [] for area in areas: areas_list.append(area.to_dict()) # 将数据转换成json字符串 rsp_dict = dict(errno=RET.OK, errmsg='OK', data=areas_list) rsp_json = json.dumps(rsp_dict) try: redis_store.setex('area_info', constants.AREA_INFO_REDIS_CACHE_EXPIRES, rsp_json) except Exception as e: current_app.logger.error(e) return rsp_json, 200, {'Content-Type': 'application/json'}
def get_area_info(): # 先尝试从redis中读取缓存数据 try: areas_json = redis_store.get('area_info') except Exception as e: current_app.logger.error(e) areas_json = None # 查询数据库,获取城区信息 if areas_json is None: try: areas_list = Area.query.all() except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR, errmsg='查询城区信息异常') areas = [] for area in areas_list: areas.append(area.to_dict()) areas_json = json.dumps(areas) try: redis_store.setex("area_info", constants.AREA_INFO_REDIS_EXPIRES, areas_json) except Exception as e: current_app.logger.error(e) else: current_app.logger.info('hit redis cache area info') return '{"errno": 0, "errmsg": "查询城区信息成功", "data":{"areas": %s}}' % areas_json, 200, \ {"Content-Type": "application/json"}
def get_areas(): """提供城区信息 1.查询所有的城区信息 2.构造响应数据 3.响应结果 """ # 查询缓存数据,如果有缓存数据,就使用缓存数据,反之,就查询,并缓存新查询的数据 try: area_dict_list = redis_store.get('Areas') if area_dict_list: return jsonify(errno=RET.OK, errmsg='OK', data=eval(area_dict_list)) except Exception as e: current_app.logger.error(e) # 1.查询所有的城区信息 areas == [Area,Area,Area,...] try: areas = Area.query.all() except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR, errmsg='查询城区信息失败') # 2.构造响应数据 area_dict_list = [] for area in areas: area_dict_list.append(area.to_dict()) # 缓存城区信息到redis : 没有缓存成功也没有影响,因为前爱你会判断和查询 try: redis_store.set('Areas', area_dict_list, constants.AREA_INFO_REDIS_EXPIRES) except Exception as e: current_app.logger.error(e) # 3.响应结果 return jsonify(errno=RET.OK, errmsg='OK', data=area_dict_list)
def get_area_info(): """ 获取城区信息,查询数据库获取信息 请求参数 :无 :return: 正常json包含城区信息 异常json对象 """ # 获取缓存中的 数据 try: resp_json = redis_store.get("resp_json") 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, {"Context-Type": "application/json"} # 查询数据库 try: areas = Area.query.all() except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR, errmsg="数据库异常") area_li = [] for area in areas: area_li.append(area.to_dict()) # 将数据转换成json字符串 resp = dict(errno=RET.OK, errmsg="数据获取成功", data=area_li) resp_json = json.dumps(resp) # 保存到redis数据库中 try: redis_store.setex("resp_json", constants.AREA_CACHE_TIME, resp_json) except Exception as e: current_app.logger.error(e) return resp_json, 200, {"Context-Type": "application/json"}
def get_areas(): # 将城区显示存储为redis缓存 try: areas_list = redis_store.get('Areas') if areas_list: return jsonify(errno=RET.OK, errmsg=u'城区数据查询成功', data=eval({'areas_list': areas_list})) except Exception as e: current_app.logger.error(e) # 1.查找出所以城区信息 try: # 获取所有相关的城区数据对象 areas = Area.query.all() # 这是 一个模型对象集合列表 except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR, errmsg=u'城区数据查询失败') # 2.封装响应数据 areas_list = [] # 这个列表就是作为响应数据的装有城区数据对象的列表数据 for area in areas: #在所有城区数据信息对象遍历出每个城区的数据对象,再调用封装好的显示信息函数 areas_list.append(area.to_dict()) try: # 将数据缓存在redis redis_store.set('Areas', areas_list, constants.AREA_INFO_REDIS_EXPIRES) except Exception as e: current_app.logger.error(e) # 3.响应 return jsonify(errno=RET.OK, errmsg=u'城区数据查询成功', data={'areas_list': areas_list})
def get_areas(): # 查询缓存 try: ret_json = redis_store.get('area_info') except Exception as e: current_app.logger.error(e) else: if ret_json is not None: current_app.logger.info('hit redis cache: area_info') return ret_json, 200, {'Content-Type': 'application/json'} # 查询数据库, 获取城区信息 try: area_li = Area.query.all() except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR, errmsg=u'数据库错误') # 将对象转化为字典 area_dict_li = [] for area in area_li: area_dict_li.append(area.to_dict()) # 转化为json ret_dict = dict(errno=RET.OK, errmsg='OK', data=area_dict_li) ret_json = json.dumps(ret_dict) # 存储到缓存 try: redis_store.setex('area_info', constants.AREA_INFO_REDIS_CACHE_EXPIRE, ret_json) except Exception as e: current_app.logger.error(e) return ret_json, 200, {'Content-Type': 'application/json'}
def get_house_detail(house_id): try: redis_house_detail = redis_store.get("house_detail:%s" % house_id) except: current_app.logger.error(e) # return jsonify(errno=RET.DBERR,errmsg="获取缓存异常") if redis_house_detail: return jsonify(errno=RET.OK, errmsg="获取成功", data={"house": json.loads(redis_house_detail)}) 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: redis_store.set( "house_detail:%s" % house_id, json.dump(house.to_full_dict(), constants.HOUSE_DETAIL_REDIS_EXPIRE_SECOND)) except Exception as e: current_app.logger.error(e) # return jsonify(errno=RET.DBERR,errmsg="缓存异常") return jsonify(errno=RET.OK, errmsg="获取成功", data={"house": house.to_full_dict()})
def get_area_info(): """获取城区信息""" # 从redis中读取数据 try: resp_json = redis_store.get('area_info') except Exception as e: pass else: if resp_json is not None: return resp_json, 200, { 'Content-Type': 'application/json;charset=UTF-8' } # 查询数据库,读取城区信息 try: # 获取所有的城区信息 area_li = Area.query.all() except Exception as e: return jsonify(errno=RET.DBERR, errmsg='数据库异常') # 因为要传入前端以json格式,只有dict能转换成json,所以将对象转换成字典 area_dict_li = [] for area in area_li: d = {"aid": area.id, "aname": area.name} area_dict_li.append(d) # 将数据转换成json格式 resp_dict = dict(errno=RET.OK, data=area_dict_li) resp_json = json.dumps(resp_dict) redis_store.setex('area_info', AREA_TIME, resp_json) return resp_json, 200, {'Content-Type': 'application/json;charset=UTF-8'}
def get_sms_code(): json_data = request.data dict_data = json.loads(json_data) mobile = dict_data.get("mobile") image_code = dict_data.get("image_code") image_code_id = dict_data.get("image_code_id") if not all([mobile, image_code, image_code_id]): return jsonify(errno=RET.PARAMERR, errmsg="参数不完整") if not re.match(r"1[34578]\d{9}", mobile): return jsonify(errno=RET.DATAERR, errmsg="手机号格式不正确") try: redis_image_code = redis_store.get("image_code:%s" % image_code_id) except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DATAERR, errmsg="图片验证码获取失败") try: redis_store.delete("imge_code:%s" % image_code_id) except Exception as e: current_app.logger.error(e) if image_code != redis_image_code: return jsonify(errno=RET.DATAERR, errmsg="图片验证码填写错误") sms_code = "%06d" % random.randint(0, 999999) current_app.logger.debug("短信验证码是:%s" % sms_code) try: redis_store.set("sms_code:%s" % mobile, sms_code, constants.SMS_CODE_REDIS_EXPIRES) except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR, errmsg="短信验证码保存失败") return jsonify(errno=RET.OK, errmsg="发送成功")
def get_house_index(): """获取首页房屋信息""" # 从缓存中获取首页房屋信息 try: json_dict = redis_store.get("index_house") except Exception as e: current_app.logger.error(e) if json_dict: return json_dict, 200, {"Content-Type": "application/json"} try: houses = House.query.order_by(House.order_count.desc()).limit( constants.INDEX_MAX_AMOUNT) except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR, errmsg="数据库异常") house_list = [] for house in houses: if not house.index_image_url: continue house_list.append(house.to_basic_dict()) house_dict = dict(errno=RET.OK, errmsg="获取数据成功", data=house_list) json_dict = json.dumps(house_dict) # 将首页信息保存到缓存中 try: redis_store.setex("index_house", constants.INDEX_HOUSE_SAVE_TIME, json_dict) except Exception as e: current_app.looger.error(e) return json_dict, 200, {"Content-Type": "application/json"}
def login(): ''' 登录 :return: ''' # 接收数据 (手机号, 密码) req_dict = request.get_json() mobile = req_dict.get("mobile") password = req_dict.get("password") # 校验数据 if not all([mobile, password]): return jsonify(error=RET.PARAMERR, errmsg="参数不完整") # 判断手机号是否符合 if not re.match(r"1[34578]\d{9}", mobile): return jsonify(error=RET.PARAMERR, errmsg="手机格式错误") # 限制登录错误次数 redis "access_nums_ip": "次数" user_ip = request.remote_addr # 用户ip try: access_nums = redis_store.get("access_nums_%s" % user_ip) except Exception as e: current_app.logger.error(e) else: if access_nums is not None and int( access_nums) >= current_app.config.get( "LOGIN_ERROR_MAX_TIMES"): return jsonify(error=RET.REQERR, errmsg="超过登录限制次数") # 手机号是否存在 try: user = User.query.filter_by(mobile=mobile).first() except Exception as e: current_app.logger.error(e) return jsonify(error=RET.DBERR, errmsg="数据库查询错误") else: # 判断密码是否正确 if user is None or user.check_password_hash(password) is False: # 记录错误次数 try: # incr(name, amount=1) 默认自动+1, 如果为空,则初始化为0 redis_store.incr("access_nums_%s" % user_ip) # 设置限制时间 redis_store.expire( "access_nums_%s" % user_ip, current_app.config.get("LOGIN_ERROR_FORBID_TIME")) except Exception as e: current_app.logger.error(e) return jsonify(error=RET.DATAERR, errmsg="用户名或密码错误") # 保存登录状态session session["name"] = user.name session["mobile"] = user.mobile session["user_id"] = user.id # reutnr OK return jsonify(error=RET.OK, errmsg="登录成功")
def get_area_info(): """城区信息""" # 查询数据库,读取城区信息 try: resp_json_str = redis_store.get("area_info") except Exception as e: current_app.logger.error(e) else: if resp_json_str is not None: current_app.logger.info("hit redis area") return resp_json_str, 200, {"Content-Type": "application/json"} try: area_li = 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_li: area_dict_li.append(area.to_dict()) resp_dict = dict(errno=RET.OK, errmsg="OK", data=area_dict_li) resp_json_str = json.dumps(resp_dict) try: redis_store.setex("area_info", constants.AREA_INFO_REDIS_CACHE_EXPIRES, resp_json_str) except Exception as e: current_app.logger.error(e) return resp_json_str, 200, {"Content-Type": "application/json"}
def get_areas_info(): try: areas_info = redis_store.get('areas_info') except Exception as e: current_app.logger.error(e) else: if areas_info: current_app.logger.info('hit redis areas_info') return areas_info, 200, {"Content-Type": "application/json"} try: areas = Area.query.all() except Exception as e: return jsonify(errno=RET.DBERR, errmsg='数据库异常') area_list = [] for area in areas: area_list.append({ 'aid': area.id, 'aname': area.name, }) resp_dict = dict(errno=RET.OK, errmsg="OK", data=area_list) resp_json = json.dumps(resp_dict) try: redis_store.setex("areas_info", constants.AREA_INFO_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("从redis中读取成功") return resp_json,200,{"Content-Type": "application/json"} #从数据库查询城区信息 all_area_list=[] try: all_area=Area.query.all() except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR,errmsg="数据库查询异常") for area in all_area: #将对象转换为字典 all_area_list.append(area.to_dict()) #将数据转换为json resp_dict=dict(errno=RET.OK,errmsg="OK",data=all_area_list) resp_json=json.dumps(resp_dict) #将数据保存到redis当中 try: redis_store.setex("area_info",Const.AREA_INFO_REDIS_CACHE_EXPIRES,resp_json) except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR,errmsg="城区信息缓存失败") return resp_json,200,{"Content-Type":"application/json"}
def login(): """ 用户注册 参数:手机号 密码 格式:json :return: """ # 获取参数 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="参数不完整") # 手机号的格式 if not re.match(r"1[345678]\d{9}", mobile): return jsonify(errno=RET.PARAMERR, errmsg="手机号格式错误") # 判断错误次数是否超过限制,如果超过限制,则限制后续操作时间 # redis记录:"acess_num_"请求的IP: 次数 user_ip = request.remote_addr # 用户的IP地址 try: access_nums = redis_store.get("access_nums_%s" % 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="获取用户信息失败") # 用数据库的密码与用户填写的密码进行对比验证 if user is None or not user.check_password(password): # 如果验证失败,记录错误次数,反回信息 try: redis_store.incr("access_nums_%s" % user_ip) redis_store.expire("access_nums_%s" % user_ip, constants.LOGIN_ERROR_FORBID_TIME) 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 # 登录成功删除redis登录错误次数记录 redis_store.delete("access_nums_%s" % user_ip) return jsonify(errno=RET.OK, errmsg="登录成功")
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: # 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(errno=RET.DBERR, errmsg="数据库异常") area_dict_li = [] # 将对象转换为字典 for area in area_li: 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 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="参数不完整") #判断手机号码的格式是否正确 if not re.match(r"1[34578]\d{9}", mobile): return jsonify(errno=RET.PARAMERR, errmsg="手机号码格式不正确") # 判断用户的登录次数防止用户暴力破解密码 #从redis 中获取错误次数 user_ip = request.remote_addr try: access_counts = redis_store.get("access_%s" % user_ip) except Exception as e: current_app.logger.error(e) else: #如果有错误次数纪录,并且超过最大次数,直接返回 if access_counts is not None and int( access_counts) >= 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.DATAERR, errmsg="用户信息查询失败") if user is None or not user.check_password(password): #出现错误,开始累加错误次数 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.LOGINERR, errmsg="用户名或者密码错误") #登陆成功,设置session #清除用户的登录错误次数 try: redis_store.delete("access_%s" % user_ip) except Exception as e: current_app.logger.error(e) #保存用户的登录状态 session["user_id"] = user.id session["user_name"] = user.name session["mobile"] = user.mobile return jsonify(errno=RET.OK, errmsg="用户登录成功")
def get_areas(): """ 获取城区的接口,这个接口的数据会经常请求,并且变化不大,可以缓存起来 """ 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('缓存中获取') return resp_json, 200, {'Content-Type': 'application/json'} try: areas = Area.query.all() except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR, errmsg="数据库操作失败") a_dict_lis = [] for area in areas: a_dict_lis.append(area.to_dict()) # 将返回的数据转成json字符串, dict() 构建一个字典 resp_dict = dict(errno=RET.OK, errmsg="获取城区成功", data=a_dict_lis) 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) print('从数据库中获取') return resp_json, 200, {'Content-Type': 'application/json'}
def get_houses_index(): """ 项目首页幻灯片 缓存----磁盘----缓存 1/尝试查询redis数据库,获取项目首页信息 2/判断查询结果 3/如果有数据,留下访问的记录,直接返回 4/查询mysql数据库 5/默认采取房屋成交次数最高的五套房屋 houses = House.query.order_by(House.order_count.desc()).limit(5) 6/判断查询结果 7/定义容器存储查询结果 8/遍历查询结果,判断房屋是否有主图片,如未设置默认不添加 9/调用模型类中方法house.to_basic_dict() 10/把房屋数据转成json字符串 11/存入redis缓存中 12/返回结果 :return: """ # 尝试从redis中获取后人幻灯片信息 try: ret = redis_store.get("home_page_data") except Exception as e: current_app.logger.error(e) ret = None # 判断获取结果 if ret: # 留下访问redis数据库的记录 current_app.logger.info("hit redis houses index info") return '{"errno":0,"errmsg":"OK","data":%s}' % ret # 未获取,查询mysql数据库 try: # 默认按房屋成交次数排序,使用limit分页5条房屋数据 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(erno=RET.NODATA, errmsg="无房屋数据") # 定义容器 houses_list = [] for house in houses: # 如果房屋为设置主图片,默认不添加 if not house.index_image_url: continue houses_list.append(house.to_basic_dict()) # 把房屋数据转换成json 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
def login(): # 获取参数 resp_json = request.get_json() mobile = resp_json.get('mobile') password = resp_json.get('password') # 参数校验 # 1 数据完整性 if not all([mobile, password]): return jsonify(errno=RET.PARAMERR, errmsg='数据不完整') # 2 手机号格式 if not re.match(r"1[345678]\d{9}", mobile): return jsonify(errno=RET.PARAMERR, errmsg='手机号格式不正确') # 业务处理 # 用户ip user_ip = request.remote_addr try: real_count = redis_store.get('access_' + user_ip) except Exception as e: logging.error(e) return jsonify(errno=RET.DBERR, errmsg='查询Redis失败') # Redis存储错误次数 不大于5次 if real_count and int(real_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: logging.error(e) return jsonify(errno=RET.DBERR, errmsg='用户查询失败') # 用户是否存在或者密码是否正确 if user is None or not user.check_password(password): # 错误一次加一 设置过期时间 try: redis_store.incr('access_' + user_ip) redis_store.expire('access_' + user_ip, constants.LOGIN_ERROR_FORBID_TIME) except Exception as e: logging.error(e) return jsonify(errno=RET.DBERR, errmsg='Redis操作失败') return jsonify(errno=RET.LOGINERR, errmsg='用户名或密码输入错误') # 如果输入正确 错误次数清零 try: redis_store.delete('access_' + user_ip) except Exception as e: logging.error(e) return jsonify(errno=RET.DBERR, errmsg='删除Redis数据失败') # 保存登录状态 try: session['id'] = user.id session['name'] = user.mobile session['mobile'] = user.mobile except Exception as e: logging.error(e) return jsonify(errno=RET.DBERR, errmsg='用户登录失败') # 返回数据 return jsonify(errno=RET.OK, errmsg='用户登录成功')
def get_house_detail(house_id): """获取房屋详情""" # 前端在房屋详情页面展示时,如果浏览页面的用户不是该屋的房东,则展示预定按钮,否则不展示 # 所以需要后端返回登录用户的id # 尝试获取用户登录的信息,若登录,则返回给前端登录用户的id,否则返回user_id = -1 user_id = session.get("user_id", "-1") # 校验参数 if not house_id: return jsonify(error_code=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 '{"error_code": 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(error_code=RET.DBERR, errmsg="查询数据失败") if not house: return jsonify(error_code=RET.NODATA, errmsg="房屋不存在") # 将房屋对象数据转换为字典 try: house_data = house.to_full_dict() except Exception as e: current_app.logger.error(e) return jsonify(error_code=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) resp = '{"error_code":0, "errmsg":"ok", "data":{"user_id": %s, "house": %s}}' % (user_id, json_house), \ 200, {"Content-Type": "application/json"} return resp
def get_house_index(): """获取主页幻灯片展示的房屋基本信息""" # 尝试从缓存中获取 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") # 因为redis中保存的是json字符串,所以值直接进行字符串拼接返回 return '{"error_code": 0, "errmsg": "ok", "data": %s}' % ret, 200, {"Content-Type": "application/json"} else: try: # 查询数据库,返回房屋订单数目最多的5条数据 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(error_code=RET.DBERR, errmsg="查询数据失败") if not houses: return jsonify(error_code=RET.NODATA, errmsg="查询无数据") houses_list = [] 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) try: redis_store.setex("home_page_data", constants.HOME_PAGE_DATA_REDIS_EXPIRES, json_houses) except Exception as e: current_app.logger.error(e) return '{"error_code": 0, "errmsg": "ok", "data": %s}' % json_houses, 200, {"Content-Type": "application/json"}
def register(): """用户注册""" # 接收参数,手机号 短信验证码 密码 req_dict = request.get_json() mobile = req_dict.get("mobile") sms_code = req_dict.get("sms_code") password = req_dict.get("password") # 校验参数 if not all([mobile, sms_code, password]): resp = { "error_code": RET.PARAMERR, "errmsg": "参数不完整" } return jsonify(resp) if not re.match(r"1[34578]\d{9}", mobile): resp = { "error_code": RET.DATAERR, "errmsg": "手机号格式错误" } return jsonify(resp) # 业务处理 # 获取真实的短信验证码 try: real_sms_code = redis_store.get("sms_code_%s" % mobile) except Exception as e: current_app.logger.error(e) resp = { "error_code": RET.DBERR, "errmsg": "查询短信验证码错误" } return jsonify(resp) # 判断短信验证码是否过期 if real_sms_code is None: resp = { "error_code": RET.NODATA, "errmsg": "短信验证码已过期" } return jsonify(resp) # 判断用户输入的短信验证码是否正确 if real_sms_code != sms_code: resp = { "error_code": RET.DATAERR, "errmsg": "短信验证码错误" } return jsonify(resp) # 删除短信验证码 try: redis_store.delete("sms_code_%s" % mobile) except Exception as e: current_app.logger.error(e) # 判断手机号是否已经注册 # try: # user = User.query.filter_by(mobile=mobile).first() # except Exception as e: # current_app.logger.error(e) # resp = { # "error_code": RET.DBERR, # "errmsg": "数据库异常" # } # return jsonify(resp) # # if user is not None: # resp = { # "error_code": RET.DATAEXIST, # "errmsg": "手机号已经注册" # } # return jsonify(resp) # 保存用户的数据到数据库中 user = User(name=mobile, mobile=mobile) # 对于password属性的设置,会调用属性方法 user.password = password try: db.session.add(user) db.session.commit() except Exception as e: current_app.logger.error(e) resp = { "error_code": RET.DATAEXIST, "errmsg": "手机号已经注册" } return jsonify(resp) # 记录用户的登录状态 session["user_id"] = user.id session["username"] = mobile session["mobile"] = mobile # 返回响应 resp = { "error_code": RET.OK, "errmsg": "注册成功" } return jsonify(resp)
def send_sms_code(mobile): """ 1/获取参数,mobile,text,id,request.args.get('text') 2/校验参数的完整性 3/校验手机号,正则表达式校验手机号格式 4/校验图片验证码,操作redis数据库,获取本地存储的真实图片验证码 5/校验获取结果,判断真实的图片验证码是否存在 6/删除redis中的图片验证码 7/比较图片验证码是否一致 8/生成短信验证码,'%06d' % random.randint(1,999999)生成随机数 9/在本地存储短信验证码,存redis中 10/判断手机号是否已注册 11调用云通讯接口,发送短信,send_template_sms(mobile,sms_coce,time,tempID) 12/保存发送结果,判断发送是否成功 13/返回结果 :param mobile: :return: """ # 获取参数 image_code = request.args.get('text') image_code_id = request.args.get('id') # 校验参数的完整性 if not all([mobile, image_code_id, image_code]): return jsonify(errno=RET.PARAMERR, errmsg='参数不完整') # 校验手机号码的格式 if not re.match(r'1[3456789]\d{9}', mobile): return jsonify(errno=RET.PARAMERR, errmsg='手机号码格式不正确') # 校验图片验证码,从redis中获取 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.PARAMERR, errmsg='图片验证码错误') # 开始准备发送短信验证码 sms_code = '%06d'% random.randint(1, 999999) # 把验证码保存到redis中 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.DATAEXIS,errmsg='用户已经存在') # 调用云通讯接口发送短信 try: cpp = sms.CCP() # 发送短信的模板方法会有返回值,0 表示发送成功 result = cpp.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 0 == result: return jsonify(errno=RET.OK, errmsg='发送成功') else: return jsonify(errno=RET.THIRDERR, errmsg='发送失败')
def login(): """登录""" # 获取参数, 用户名 密码 req_dict = request.get_json() mobile = req_dict.get("mobile") password = req_dict.get("password") # 校验参数 if not all([mobile, password]): resp = { "error_code": RET.PARAMERR, "errmsg": "参数不完整" } return jsonify(resp) if not re.match(r"1[34578]\d{9}", mobile): resp = { "error_code": RET.PARAMERR, "errmsg": "手机号格式错误" } return jsonify(resp) # 判断用户的错误次数 # 从redis中获取错误次数 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(error_code=RET.REQERR, errmsg="登录过于频繁") # 业务处理 try: user = User.query.filter_by(mobile=mobile).first() except Exception as e: current_app.logger.error(e) resp = { "error_code": RET.DBERR, "errmsg": "查询用户信息失败" } return jsonify(resp) if user is not None and user.check_password(password): # 清除用户的登录错误此时 try: redis_store.delete("access_%s" % user_ip) except Exception as e: current_app.logger.error(e) # 记录用户的登录状态 session["user_id"] = user.id session["username"] = user.name session["mobile"] = mobile resp = { "error_code": RET.OK, "errmsg": "登录成功" } return jsonify(resp) else: 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) resp = { "error_code": RET.LOGINERR, "errmsg": "用户名或密码错误" } return jsonify(resp)
def send_sms_code(mobile): """发送短信验证码""" # 获取参数 image_code_id = request.args.get("image_code_id") image_code = request.args.get("image_code") # 校验参数 if not all([image_code_id, image_code]): resp = { "error_code": RET.PARAMERR, "errmsg": "参数不完整" } return jsonify(resp) # 业务处理 # 取出真实的图片验证码 try: real_image_code = redis_store.get("image_code_%s" % image_code_id) except Exception as e: current_app.logger.error(e) resp = { "error_code": RET.DBERR, "errmsg": "获取图片验证码失败" } return jsonify(resp) # 判断验证码的有效期 if real_image_code is None: resp = { "error_code": RET.NODATA, "errmsg": "图片验证码过期" } return jsonify(resp) # 删除redis中的图片验证码,防止用户多次尝试同一个图片验证码 try: redis_store.delete("image_code_%s" % image_code_id) except Exception as e: current_app.logger.error(e) # 判断用户填写的验证码与真实验证码 if real_image_code.lower() != image_code.lower(): # 表示用户填写错误 resp = { "error_code": RET.DATAERR, "errmsg": "图片验证码有误" } return jsonify(resp) # 判断用户手机号是否注册过 try: user = User.query.filter_by(mobile=mobile).first() except Exception as e: current_app.logger.error(e) else: if user is not None: resp = { "error_code": RET.DATAEXIST, "errmsg": "手机号已注册过" } return jsonify(resp) # 创建短信验证码 sms_code = "%06d" % random.randint(0, 999999) # 保存短信验证码 try: redis_store.setex("sms_code_%s" % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code) except Exception as e: current_app.logger.error(e) resp = { "error_code": RET.DBERR, "errmsg": "保存短信验证码异常" } return jsonify(resp) # 发送验证码短信 # 通过celery发送 # task_sms.send_template_sms.delay(mobile, [sms_code, str(constants.SMS_CODE_REDIS_EXPIRES/60)], 1) # result返回异步结果对象, 通过对象能够获取最终执行结果 result = tasks.send_template_sms.delay(mobile, [sms_code, str(constants.SMS_CODE_REDIS_EXPIRES/60)], 1) # 通过get方法能返回执行结果 # get()默认是阻塞的, 会等到worker执行完成有了结果的时候才返回 # get()通过timeout超时时间,可以在超过超时时间后立即返回 ret = result.get() print ret return jsonify(error_code=RET.OK, errmsg="ok")
def register(): # 获取参数 resp_json = request.get_json() mobile = resp_json.get('mobile') sms_code = resp_json.get('sms_code') password = resp_json.get('password') # 参数校验 # 1 数据完整性 if not all([mobile, sms_code, password]): return jsonify(errno=RET.PARAMERR, errmsg='数据不完整') # 2 手机号格式 if not re.match(r"1[345678]\d{9}", mobile): return jsonify(errno=RET.PARAMERR, errmsg='手机号格式不正确') # 业务处理 # Redis中取出短信验证码 try: real_sms_code = redis_store.get('sms_code_' + mobile) except Exception as e: logging.error(e) return jsonify(errno=RET.DBERR, errmsg='获取Redis数据错误') # 短信验证码是否失效 if not real_sms_code: return jsonify(errno=RET.DATAERR, errmsg='短信验证码过期或不存在') # 对比短信验证码是否一致 if real_sms_code != sms_code: return jsonify(errno=RET.PARAMERR, errmsg='短信验证码输入错误,请重新输入') # 删除短信Redis--》可以修改后重新输入 try: redis_store.delete('sms_code_' + mobile) except Exception as e: logging.error(e) return jsonify(errno=RET.DBERR, errmsg='删除Redis数据错误') # 查询用户是否存在 try: user = User.query.filter_by(mobile=mobile).first() except Exception as e: logging.error(e) return jsonify(errno=RET.DBERR, errmsg='用户表查询失败') if user: return jsonify(errno=RET.DATAEXIST, errmsg='该用户已注册,请去登录') # 将用户信息保存到数据库中 user = User(name=mobile, mobile=mobile) # 密码需要加密 user.password = password try: db.session.add(user) db.session.commit() except Exception as e: logging.error(e) db.session.rollback() return jsonify(errno=RET.DBERR, errmsg='添加用户失败') # 保存用户登录状态并跳转到登录页 try: session['id'] = user.id session['name'] = user.mobile session['mobile'] = user.mobile except Exception as e: logging.error(e) return jsonify(errno=RET.DBERR, errmsg='session存储错误') # 返回数据 return jsonify(errno=RET.OK, errmsg='用户注册成功')
def get_sms_codes(mobile): # 获取参数 code = request.args.get('code') codeId = request.args.get('codeId') # 参数校验 if not all([code, codeId]): resp = { 'errno': RET.DATAERR, 'errmsg': '数据不完整' } return jsonify(resp) # 业务处理 # 2 获取图片验证码 image_code_id = 'image_code_' + codeId try: new_code = redis_store.get(image_code_id) except Exception as e: logging.error(e) resp = { 'errno': RET.DBERR, 'errmsg': '获取图片验证码失败' } return jsonify(resp) # 图片验证码是否有效 if new_code is None: resp_dict = { 'errno': RET.NODATA, 'errmsg': '图片验证码过期/失效' } return jsonify(resp_dict) # 删除原来的验证码 try: redis_store.delete(image_code_id) except Exception as e: logging.error(e) resp = { 'errno': RET.DBERR, 'errmsg': '删除图片验证码失败' } return jsonify(resp) # 3 对比是否一致 if new_code.lower() != code.lower(): # 不一致 resp = { 'errno': RET.PARAMERR, 'errmsg': '图片二维码填写错误,请点击刷新后重新输入' } return jsonify(resp) # 1 用户名是否存在 try: user = User.query.filter_by(mobile=mobile).first() except Exception as e: logging.error(e) resp = { 'errno': RET.DBERR, 'errmsg': '查找用户信息失败' } return jsonify(resp) if user: # 用户存在 resp = { 'errno': RET.DATAEXIST, 'errmsg': '该用户已存在' } return jsonify(resp) # 创建6位验证码 sms_code = '%06d' % random.randint(0, 999999) # 将短信验证码存储到Redis中 点击注册时进行对比 try: redis_store.setex('sms_code_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRE, sms_code) except Exception as e: logging.error(e) resp = { 'errno': RET.DBERR, 'errmsg': '保存短信验证码失败' } return jsonify(resp) # 发送验证码 ccp = CCP() status_code = ccp.send_template_sms('18204681825', [sms_code, constants.SMS_CODE_TIME_EXPIRE], 1) # 返回数据 if status_code == '000000': resp = { 'errno': RET.OK, 'errmsg': '发送短信验证码成功' } return jsonify(resp) else: resp = { 'errno': RET.THIRDERR, 'errmsg': '发送短信验证码失败' } return jsonify(resp)
def register(): """ 注册 1/获取参数,使用user_data = request.get_json() 2/校验参数的存在 3/进一步获取详细的参数信息,mobile,smscode,password 4/校验参数的完整性 5/进一步校验详细的参数信息,mobile 6/校验短信验证码,获取本地存储的短信验证码 7/判断短信验证码是否过期 8/比较短信验证码是否正确 9/删除短信验证码 10/判断用户是否已注册 11/保存用户信息, user = User(mobile=mobile,name=mobile) user.password = password 12/缓存用户信息:flask_session扩展包的作用:指定用户的缓存信息存放位置,加密签名,指定有效期; 我们需要使用请求上下文对象session来从redis中获取或设置用户信息; session.get('user_id') session[user_id] = user_id 13/返回结果 :return: """ # 获取参数 user_data = request.get_json() # 判断获取结果 if not user_data: return jsonify(errno=RET.PARAMERR, errmsg='参数缺失') # 进一步获取详细的参数信息 mobile = user_data.get('mobile') smscode = user_data.get('sms_code') password = user_data.get('password') # 校验参数的完整性 if not all([mobile, smscode, password]): return jsonify(errno=RET.PARAMERR, errmsg='参数不完整') # 校验手机号格式是否符合要求 if not re.match(r'1[3456789]\d{9}$', mobile): return jsonify(errno=RET.PARAMERR, errmsg='手机号格式错误') # 校验短信验证码,从redis中获取真实的短信验证码 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.NODATA, errmsg='短信验证码过期') # 比较短信验证码 if real_sms_code != str(smscode): return jsonify(errno=RET.DATAERR, errmsg='短信验证码错误') # 删除短信验证码 try: redis_store.delete('SMSCode_' + mobile) except Exception as e: current_app.logger.error(e) # 判断用户是否已注册 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(mobile=mobile, name=mobile) # 对密码存储,这里调用了模型类generate_password_hash方法,对密码进行加密存储 user.password = password # 提交数据到数据库中 try: db.session.add(user) db.session.commit() except Exception as e: current_app.logger.error(e) # 存入数据如果发生异常,需要进行回滚 db.session.rollback() return jsonify(errno=RET.DBERR, errmsg='保存用户信息失败') # 缓存用户的信息,使用请求上下文对象session session['user_id'] = user.id session['name'] = mobile session['mobile'] = mobile # 返回结果,data 为附属消息 return jsonify(errno=RET.OK, errmsg='OK', data=user.to_dict())