class SMSVerificationCodeResource(Resource): """ 获取短信验证码 """ error_message = 'Too many requests.' decorators = [ lmt.limit(constants.LIMIT_SMS_VERIFICATION_CODE_BY_MOBILE, key_func=lambda: request.view_args['mobile'], error_message=error_message), lmt.limit(constants.LIMIT_SMS_VERIFICATION_CODE_BY_IP, key_func=get_remote_address, error_message=error_message) ] def get(self, mobile): # 生成验证码 code = '{:0>6d}'.format(random.randint(0, 999999)) # 保存到redis中 current_app.redis_master.setex('app:code:{}'.format(mobile), constants.SMS_VERIFICATION_CODE_EXPIRES, code) # 使用celery异步任务 发送短信 send_verification_code.delay(mobile, code) return {'mobile': mobile}
class GenerateCodeView(Resource): error_message = 'Too many requests.' decorators = [ lmt.limit(constants.LIMIT_SMS_VERIFICATION_CODE_BY_IP, key_func=get_remote_address, error_message=error_message) ] @generate_code.expect(image_code_model) def get(self): """生成图片验证码""" parser_data = reqparse.RequestParser() parser_data.add_argument('uuid', type=str, required=True) args = parser_data.parse_args() # 生成图片验证码 data = captcha.generate_captcha() text = data[1] image = data[2] # 保存图片验证码 current_app.redis_cli.setex('img_{}'.format(args.uuid), constants.IMAGES_VERIFICATION_CODE_EXPIRES, text) # 响应图片验证码 # base_image = base64.b64encode(image).decode() # return {'data': base_image} resp = Response(image, mimetype="image/jpeg") return resp
class UserDrawTaskView(Resource): method_decorators = [ verify_required, login_required # , withdrawal ] error_message = 'Too many requests.' decorators = [ lmt.limit(constants.LIMIT_SMS_VERIFICATION_CODE_BY_IP, key_func=get_remote_address, error_message=error_message) ] @user_draw_tasks.expect(draw_tasks_model) def get(self): """用户接任务""" parser = reqparse.RequestParser() parser.add_argument('task_id', type=int, required=True, location='args') args = parser.parse_args() task_status = current_app.redis_cli.sismember( 'cancel_tasks_:{}'.format(args.task_id), g.user_id) if task_status is True: return {'error': '此任务用户已取消过, 24小时内不能在领取'}, HttpStatus.OK.value complete_task = current_app.redis_cli.sismember( 'complete_tasks_:{}'.format(args.task_id), g.user_id) if complete_task is True: return {'error': '此任务用户已领取'}, HttpStatus.OK.value else: now_time = datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S") sql = f"INSERT INTO {ET_TASK_ORDERS} (task_id,member_id,status,add_time) VALUE ('{args.task_id}','{g.user_id}',1,'{now_time}')" res = MysqlWrite().write(sql) if res == 1: # 更新任务剩余数量 r = MysqlWrite().write( f"UPDATE {TASKS_TABLE} SET count_tasks=count_tasks + 1 WHERE ID='{args.task_id}'" ) # redis操作 rc = current_app.redis_cli # 删除用户任务缓存 rc.delete('user_tasks_:{}'.format(g.user_id)) # 删除任务缓存 rc.delete('tasks_info') # 删除用户任务的缓存 rc.delete('user_tasks_:{}'.format(g.user_id)) rc.sadd('complete_tasks_:{}'.format(args.task_id), g.user_id) # 向已领取任务redis中添加数据 rc.sadd('fetch_tasks_:{}'.format(args.task_id), g.user_id) # 删除任务详情缓存 rc.delete("tasks_detail_:{}".format(args.task_id)) # 删除用户任务总列表数据 rc.delete(f"tasks_info_{g.user_id}") return {'data': '添加任务完成'}, HttpStatus.OK.value else: return {'error': '任务获取失败,请重试'}, HttpStatus.OK.value
class UpdateView(Resource): # 接口限流 error_message = 'Too many requests.' decorators = [ lmt.limit(constants.LIMIT_SMS_VERIFICATION_CODE_BY_IP, key_func=get_remote_address, error_message=error_message) ] def post(self): """更新版本""" parser = reqparse.RequestParser() parser.add_argument('app_version', type=str, required=True, location='json') args = parser.parse_args() up = MysqlWrite().write( f"UPDATE {MEMBERS_TABLE} SET app_version='{args.app_version}' WHERE ID='{g.user_id}'" ) return HttpStatus.OK.value def get(self): """返回当前app版本号""" up = MysqlSearch().get_more( f"SELECT version,down_url,update_time,up_logs FROM {ET_APPS_PUB_HISTORY}" ) if up[-1]: app_version = dict() for i in up: app_version['app版本号'] = i['version'], app_version['app下载url'] = i['down_url'], app_version['更新日期'] = i['update_time'].strftime( "%Y-%m-%d-%H-%M-%S") app_version['更新日志'] = i['up_logs'] if app_version: return {'data': app_version}, HttpStatus.OK.value
class UserDrawTaskView(Resource): method_decorators = [ verify_required, login_required # , withdrawal ] error_message = 'Too many requests.' decorators = [ lmt.limit(constants.LIMIT_SMS_VERIFICATION_CODE_BY_IP, key_func=get_remote_address, error_message=error_message) ] @user_draw_tasks.expect(draw_tasks_model) def post(self): """用户接任务""" parser = reqparse.RequestParser() parser.add_argument('task_id', type=int, required=True, location='json') parser.add_argument('app_safe_info', type=dict, required=True, location='json') args = parser.parse_args() # 要json数据入库,接收的类型必须是dict然后转str,不然会一直报错.可能需要flask的json, new_data = json.dumps(args.app_safe_info).replace("'", '"') # 判断此任务是否还有剩余数量 # 判断用户是否已经提现成功 tx = MysqlSearch().get_one(f"SELECT verify FROM {ET_MEMBER_WITHDRAWAL} WHERE member_id='{g.user_id}' and verify=2") current_app.logger.error(tx) if tx is None: return {"error": "请进行新手提现成功再领取任务"} sy = MysqlSearch().get_one(f"SELECT tasks_counts,count_tasks,check_router FROM {TASKS_TABLE} WHERE id='{args.task_id}'") if sy['tasks_counts'] == sy['count_tasks']: return {'error_code': 4003, 'msg': '此任务无法领取.数量不足'} task_status = current_app.redis_cli.sismember('cancel_tasks_{}'.format(g.user_id), args.task_id) if task_status is True: return {'error': '此任务用户已取消过, 24小时内不能在领取'},HttpStatus.OK.value complete_task = current_app.redis_cli.sismember('complete_tasks_{}'.format(g.user_id), args.task_id) if complete_task is True: return {'error': '此任务用户已领取'}, HttpStatus.OK.value else: now_time = datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S") # todo 'http://' + '47.113.91.65:5007' 添加到config配置项 current_app.logger.error(sy['check_router']) safe_token = global_config.getRaw('Invite_link', 'EWM_LINK') + f'?td={args.task_id}&fromu={g.user_id}&ref={sy["check_router"]}' current_app.logger.error(safe_token) sql = f"INSERT INTO {ET_TASK_ORDERS} (task_id,member_id,status,add_time,app_safe_info,safe_token) VALUE ('{args.task_id}','{g.user_id}',1,'{now_time}','{new_data}','{safe_token}')" res = MysqlWrite().write(sql) if res == 1: # 更新任务剩余数量 r = MysqlWrite().write(f"UPDATE {TASKS_TABLE} SET count_tasks=count_tasks + 1 WHERE ID='{args.task_id}'") # redis操作 rc = current_app.redis_cli # 删除用户任务缓存 rc.delete('user_tasks_:{}'.format(g.user_id)) # 删除任务缓存 rc.delete('tasks_info') # 删除用户任务的缓存 rc.delete('user_tasks_:{}'.format(g.user_id)) rc.sadd('complete_tasks_:{}'.format(args.task_id),g.user_id) # 向已领取任务redis中添加数据 rc.sadd('fetch_tasks_:{}'.format(args.task_id), g.user_id) # 删除任务详情缓存 rc.delete("tasks_detail_:{}".format(args.task_id)) # 删除用户任务总列表数据 rc.delete(f"tasks_info_{g.user_id}") return {'data': '添加任务完成'}, HttpStatus.OK.value else: return {'error': '任务获取失败,请重试'}, HttpStatus.OK.value
class UserCarryMoneyView(Resource): error_message = 'Too many requests.' decorators = [ lmt.limit(constants.LIMIT_SMS_VERIFICATION_CODE_BY_IP, key_func=get_remote_address, error_message=error_message) ] method_decorators = [verify_required] # method_decorators = { # 'get': [login_required], # 'post': [verify_required] # } @user_carry.expect(user_carry_model) def get(self): # 取出drp_config表里面的withdrawal_condition字段组装数据返回 sql_charge = f"SELECT handling_fee,daily_withdrawal,min_money,withdrawal_condition FROM {ET_DRP_CONFIG}" res = MysqlSearch().get_more(sql_charge) # 查询当前用户余额 y = MysqlSearch().get_one( f"SELECT balance FROM {MEMBERS_TABLE} WHERE ID='{g.user_id}'") user_carry_money = dict() if res: charge = res[-1] user_carry_money = json.loads(charge['withdrawal_condition']) user_carry_money['手续费'] = charge['handling_fee'] user_carry_money['最小提现金额'] = charge['min_money'] user_carry_money['可提现次数'] = charge['daily_withdrawal'] if y['balance'] is None: user_carry_money['钱包余额'] = 0 else: user_carry_money['钱包余额'] = y['balance'] / 100 # 查询当前用户邀请的人数 son_member = MysqlSearch().get_more( f"SELECT member_id FROM {ET_MEMBER_RELATIONS} WHERE parent_id='{g.user_id}'" ) if son_member is not None: member_count = 80 for son in son_member: if son['member_id'] != g.user_id: member_count += 1 user_carry_money['邀请人数'] = member_count return {'data': user_carry_money}, HttpStatus.OK.value @user_carry_post.expect(user_carry_post_model) def post(self): """提交提现数据""" parser = reqparse.RequestParser() parser.add_argument('amount', type=str, required=True, location='json') args = parser.parse_args() args.amount = float(args.amount) # 查询当前用户余额 #todo 以后增加手续费计算出正常金额对比提现条件是否相等 y = MysqlSearch().get_one( f"SELECT balance,alipayid FROM {MEMBERS_TABLE} WHERE ID='{g.user_id}'" ) if y['balance'] is None or args.amount > (y['balance'] / 100) or y['alipayid'] == '': return { 'error': f"余额不足,剩余余额{y['balance']}/支付宝未绑定" }, HttpStatus.OK.value # 查询最小提现金额和当天最多提现次数 sql = f"SELECT daily_withdrawal,handling_fee,withdrawal_condition FROM {ET_DRP_CONFIG}" res = MysqlSearch().get_more(sql)[-1] # 查询是否已经提现过1元 if args.amount == 1: try: sm = current_app.redis_cli.sismember('carry_money_1', g.user_id) if sm is True: return {'error': '用户已提现过1元,无法再次提现1元'}, HttpStatus.OK.value except TypeError as e: current_app.logger.error(f"TypeError{e}") # 查询当前用户邀请的人数 son_member = MysqlSearch().get_more( f"SELECT member_id FROM {ET_MEMBER_RELATIONS} WHERE parent_id='{g.user_id}'" ) if son_member is not None: member_count = 0 for son in son_member: if son['member_id'] != g.user_id: member_count += 1 # 对比当前提现条件 # todo conditions要从数据库取出判断. # 从数据库取出提现条件 allow_money = [] prentice_count = [] with_data = json.loads(res['withdrawal_condition']) for q in with_data.values(): for i, e in enumerate(q): if 'allow_money' in e: allow_money.append(e['allow_money']) continue for k in with_data.values(): for c, x in enumerate(k): if 'prentice_count' in x: prentice_count.append(x['prentice_count']) continue for k, v in enumerate(zip(allow_money, prentice_count)): current_app.logger.info(f"Exception1 : { args.amount }") current_app.logger.info(f"Exception2 : { v[0] }") current_app.logger.info(f"Exception3 : { v[1] }") current_app.logger.info(f"Exception4 : { member_count }") # 输入金额== 条件金额 用户总金额 >= if args.amount == v[0] and member_count >= v[1]: # 查询当前用户当天提现次数 c_list = MysqlSearch().get_more( f"SELECT member_id,start_time FROM {ET_MEMBER_WITHDRAWAL} WHERE member_id='{g.user_id}'" ) if c_list: now_time = datetime.now().strftime("%Y-%m-%d") count = 0 for c in c_list: if c['start_time'].strftime( "%Y-%m-%d") == now_time: count += 1 # 判断当前用户当天是否超过提现次数 if count > int(res['daily_withdrawal']): return {'error': '已超过当天提现次数'}, HttpStatus.OK.value current_app.logger.info(f"res : { res }") if res: # 提现最小金额限制暂时取消使用 # new_res = res # min_money = new_res['min_money'] / 100 # if args.amount < min_money: new_res = res min_money = 0 if args.amount < min_money: return { 'error': '提现金额过小最小提现金额为:{}'.format(min_money) }, HttpStatus.BAD_REQUEST.value else: res1 = None # 查询手续费.当前提现金额减去手续费入库 try: if res['handling_fee'] != '0': handling_fee = float( res['handling_fee']) / 100 elif res['handling_fee'] != 0: handling_fee = float( res['handling_fee']) / 100 else: handling_fee = 0 user_handling = args.amount * handling_fee new_amounts = args.amount - user_handling res1 = MysqlWrite().write( f"INSERT INTO {ET_MEMBER_WITHDRAWAL} (pay_status,amounts,member_id) VALUE (1, {new_amounts}, {g.user_id})" ) except Exception as e: current_app.logger.info(f"Exception try : {e}") if res1 == 1: # 乐观锁解决修改用户余额 l = MysqlSearch().get_one( f"SELECT balance,balance_version FROM {MEMBERS_TABLE} WHERE id='{g.user_id}'" ) ye = l['balance'] - args.amount * 100 version_time = time.time() try: u = MysqlWrite().write( f"UPDATE {MEMBERS_TABLE} SET balance='{ye}',balance_version='{version_time}' WHERE balance_version='{l['balance_version']}' and id='{g.user_id}'" ) except Exception: return { 'error': '请稍后重试' }, HttpStatus.OK.value rc = current_app.redis_cli # 增加redis set 保存已提现过1元的用户 if args.amount == 1: rc.sadd('carry_money_1', g.user_id) rc.delete('user_center:{}'.format(g.user_id)) rc.delete('user_withdraw_recode:{}'.format( g.user_id)) a_data = { '手续费': user_handling, '提现金额': new_amounts } return { 'data': a_data, 1: '提现成功!' }, HttpStatus.OK.value continue return {'error': '提现金额/邀请人数不符合条件'}, HttpStatus.OK.value