def get(self): account_key = g.account_key parse = reqparse.RequestParser() now = int(time.time()) parse.add_argument('limit', type=int, required=False, default=10) parse.add_argument('offset', type=int, required=False, default=0) parse.add_argument('from', type=int, required=False, default=0) parse.add_argument('end', type=int, required=False, default=now) parse.add_argument('coin_name', type=str, required=False) parse.add_argument('status', type=int, required=False) parse.add_argument('type', type=int, required=False) args = parse.parse_args() limit = args.get('limit') offset = args.get('offset') from_ts = args.get('from') end_ts = args.get('end') coin_name = args.get('coin_name') status = args.get('status') mining_type = args.get('type') if mining_type in [IncomeTypeMining, IncomeTYpeMiningEcol]: mining_type = [mining_type] else: mining_type = [IncomeTypeMining, IncomeTYpeMiningEcol] from_dt = datetime.fromtimestamp(from_ts) end_dt = datetime.fromtimestamp(end_ts) kwargs = {"account_key": account_key} if not coin_name: coin_name = BHD_COIN_NAME if coin_name == BHD_COIN_NAME: model = IncomeRecord elif coin_name == LHD_NAME: model = LHDIncomeRecord elif coin_name == DISK_NAME: model = DISKIncomeRecord elif coin_name == HDD_NAME: model = HDDIncomeRecord elif coin_name == NEWBI_NAME: model = NBIncomeRecord else: return make_resp(400, False, message="请求币种错误") infos = model.query.filter_by(**kwargs).filter( model.type.in_(mining_type)).filter( and_(model.create_time > from_dt, model.create_time < end_dt)).order_by( model.create_time.desc()).limit(limit).offset( offset).all() total_records = model.query.filter_by(**kwargs).filter( model.type.in_(mining_type)).count() records = [info.to_dict() for info in infos] client = get_rpc(coin_name) latest_height = client.get_latest_block_number() return make_resp(records=records, total_records=total_records, latest_height=latest_height)
def get(self, transaction_type): if transaction_type not in transaction_type: return make_resp(404, message="查询列表内容不存在") account_key = g.account_key model = self.transaction_types.get(transaction_type) parse = reqparse.RequestParser() now = int(time.time()) parse.add_argument('limit', type=int, required=False, default=10) parse.add_argument('offset', type=int, required=False, default=0) parse.add_argument('from', type=int, required=False, default=0) parse.add_argument('end', type=int, required=False, default=now) parse.add_argument('coin_name', type=str, required=False) parse.add_argument('status', type=int, required=False) args = parse.parse_args() limit = args.get('limit') offset = args.get('offset') from_ts = args.get('from') end_ts = args.get('end') coin_name = args.get('coin_name') status = args.get('status') from_dt = datetime.fromtimestamp(from_ts) end_dt = datetime.fromtimestamp(end_ts) kwargs = {"account_key": account_key} if not coin_name: coin_name = BHD_COIN_NAME if coin_name: # and transaction_type != "transfer" kwargs['coin_name'] = coin_name if status: kwargs['status'] = status if "block_earnings" == transaction_type: # 只展示用户挖矿收益 kwargs['type'] = IncomeTypeMining if 'coop_income' == transaction_type: kwargs['type'] = IncomeTYpeCoopReward if 'ecol_block_earnings' == transaction_type: kwargs['type'] = IncomeTYpeMiningEcol infos = model.query.filter_by(**kwargs).filter( and_(model.create_time > from_dt, model.create_time < end_dt)).order_by( model.create_time.desc()).limit(limit).offset( offset).all() total_records = model.query.filter_by(**kwargs).count() records = [info.to_dict() for info in infos] if transaction_type in [ 'block_earnings', 'coop_income', 'coop_income' ]: client = get_rpc(coin_name) latest_height = client.get_latest_block_number() return make_resp(records=records, total_records=total_records, latest_height=latest_height) return make_resp(records=records, total_records=total_records)
def get(self): """ 用户合作订单信息 :return: """ account_key = g.account_key parse = reqparse.RequestParser() now = int(time.time()) parse.add_argument('coin_name', type=str, required=False) parse.add_argument('limit', type=int, required=False, default=10) parse.add_argument('offset', type=int, required=False, default=0) parse.add_argument('from', type=int, required=False, default=0) parse.add_argument('end', type=int, required=False, default=now) args = parse.parse_args() coin_name = args.get('coin_name') or BHD_COIN_NAME limit = args.get('limit') offset = args.get('offset') from_ts = args.get('from') end_ts = args.get('end') from_dt = datetime.fromtimestamp(from_ts) end_dt = datetime.fromtimestamp(end_ts) coin_name = coin_name.lower() kwargs = {"account_key": account_key} if coin_name == LHD_NAME: model = LHDTeamWorkRecordActivity else: model = TeamWorkRecordActivity teamworkorders = model.query.filter_by(**kwargs).filter( and_( model.create_time > from_dt, model.create_time < end_dt)).limit(limit).offset(offset).all() total_records = model.query.filter_by(**kwargs).count() records = [teamworkorder.to_dict() for teamworkorder in teamworkorders] return make_resp(records=records, total_records=total_records)
def get(self): account_key = g.account_key parse = reqparse.RequestParser() now = int(time.time()) ten_days = now - 864000 parse.add_argument('limit', type=int, required=False, default=10) parse.add_argument('offset', type=int, required=False, default=0) parse.add_argument('from', type=int, required=False, default=ten_days) parse.add_argument('end', type=int, required=False, default=now) parse.add_argument('coin_name', type=str, required=False) parse.add_argument('status', type=int, required=False) args = parse.parse_args() limit = args.get('limit') offset = args.get('offset') from_ts = args.get('from') end_ts = args.get('end') from_dt = datetime.fromtimestamp(from_ts) end_dt = datetime.fromtimestamp(end_ts) kwargs = {"account_key": account_key} infos = ActivityReward.query.filter_by(**kwargs).filter( and_(ActivityReward.create_time > from_dt, ActivityReward.create_time < end_dt)).filter( ActivityReward.amount > 0).order_by( ActivityReward.create_time.desc()).limit( limit).offset(offset).all() total_records = ActivityReward.query.filter_by(**kwargs).filter( ActivityReward.amount > 0).count() records = [info.to_dict() for info in infos] return make_resp(records=records, total_records=total_records)
def put(self): """ 站内用户资产划转 :return: """ parse = reqparse.RequestParser() parse.add_argument('coin_name', type=str, required=True, trim=True) parse.add_argument('amount', type=str, required=True) parse.add_argument('to_account', type=str, required=True, trim=True) args = parse.parse_args() coin_name = args.get('coin_name') account_key = g.account_key amount = Decimal(str(args.get('amount'))) to_account = args.get('to_account') api_logger.info( "transfer api, to:%s, amount:%s, account_key:%s, coin_name:%s" % (to_account, amount, account_key, coin_name)) try: user_asset_sender = UserAsset.query.filter_by( account_key=account_key, coin_name=coin_name).with_for_update(read=True).first() user_asset_receiver = UserAsset.query.filter_by( account_key=to_account, coin_name=coin_name).with_for_update(read=True).first() if not user_asset_sender or not user_asset_receiver: api_logger.error("withdrawal,user not found %s" % account_key) return make_resp(404, False, message="用户资产错误") if user_asset_sender.available_asset < amount or user_asset_sender.total_asset < amount: return make_resp(400, False, message="余额不足") user_asset_sender.available_asset -= amount user_asset_sender.total_asset -= amount user_asset_receiver.available += amount user_asset_receiver.total_asset += amount db.session.commit() except Exception as e: api_logger.error("transfer, error %s" % str(e)) db.session.rollback() return make_resp(500, False, message="提现申请提交失败") api_logger.info("transfer api, succeed") return make_resp(200, True)
def handle_error(self, error): msg = "API_ERROR>>>url:%s, method:[%s], data:%s" % ( request.url, request.method, request.form) from models import db db.session.rollback() api_logger.error(msg) api_logger.error(format_exc()) return make_resp(500, False, message="error")
def get(self): """ 生成用户钱包地址 :return: """ parse = reqparse.RequestParser() parse.add_argument('coin_name', type=str, required=True, trim=True) args = parse.parse_args() account_key = g.account_key coin_name = args.get('coin_name').lower() api_logger.info("generate address, account_key:%s, coin_name:%s" % (account_key, coin_name)) # 检查是否已有地址 bhd_address = PoolAddress.query.filter_by(account_key=account_key, coin_name=coin_name).first() if bhd_address: return make_resp(**bhd_address.to_dict()) # 从节点获取地址 client = get_rpc(coin_name) try: format_address = "" if coin_name != NEWBI_NAME: address, priv_key = client.generate_address(g.user.id) else: priv_key = os.urandom(32).hex() address, format_address = client.generate_address(priv_key) # 插入数据库 bhd_address = PoolAddress(account_key, address, priv_key, coin_name, format_address) db.session.add(bhd_address) db.session.commit() api_logger.info( "wallet address api, insert into wallet_address %s" % bhd_address.to_dict()) except Exception as e: db.session.rollback() api_logger.error("generate address %s " % e) return make_resp(400, False, message="生成地址失败") return make_resp(**bhd_address.to_dict())
def wrapper(*args, **kwargs): token = request.headers.get("token") if token is None: return make_resp(401, False, message="token not found") try: auth_dict = jwt.decode(token, JWT_SECRET, audience='pool') except Exception as e: api_logger.error("auth failed %s" % str(e)) return make_resp(401, False, message="用户登陆过期,请重新登录") account_key = auth_dict.get("accountKey") userid = auth_dict.get("userid") user = User.query.filter_by(account_key=account_key).first() if not user or user.account_key != account_key: return make_resp(401, False, message="account key not found") g.account_key = account_key g.user = user g.token = token return f(*args, **kwargs)
def put(self): """ 撤销转账 :return: """ parse = reqparse.RequestParser() parse.add_argument('id', type=int, required=True) parse.add_argument('coin_name', type=str) args = parse.parse_args() account_key = g.account_key id = args.get('id') coin_name = args.get('coin_name') or BHD_COIN_NAME withdrawal = WithdrawalTransaction.query.filter_by( id=id, account_key=account_key).first() if not withdrawal: api_logger.warning("account_key:%s, apply revocation:%s" % withdrawal.to_dict()) return make_resp(406, False, message="撤销订单不存在") if withdrawal.status != WITHDRAWAL_APPLY: api_logger.warning("account_key:%s, apply revocation:%s" % (account_key, withdrawal.to_dict())) return make_resp(400, False, message="订单状态不可撤销") try: user_asset = UserAsset.query.filter_by( account_key=account_key, coin_name=coin_name).with_for_update(read=True).first() user_asset.frozen_asset -= withdrawal.amount user_asset.available_asset += withdrawal.amount withdrawal.status = WITHDRAWAL_UNDO db.session.commit() api_logger.info("account_key:%s, revoke:%s " % (account_key, id)) return make_resp(200) except Exception as e: api_logger.error("account_key:%s, 撤销转账失败:%s " % (account_key, e)) withdrawal.status = WITHDRAWAL_FAILED db.session.rollback() return make_resp(400, False, message="撤销订单失败")
def get(self): parse = reqparse.RequestParser() parse.add_argument('code_type', type=str, required=False, trim=True, default='withdrawal') args = parse.parse_args() code_type = args.get('code_type').lower() account_key = g.account_key pass_code = randint(0, 999999) key = "%s:seccode:%s" % (code_type, account_key) redis_auth.set(key, pass_code, ex=5 * 60) from schedule.task_email import email_sender_task email_sender_task.delay(g.user.email, pass_code, g.token) return make_resp(200, True)
def get(self): account_key = g.account_key parse = reqparse.RequestParser() now = int(time.time()) parse.add_argument('limit', type=int, required=False, default=10) parse.add_argument('offset', type=int, required=False, default=0) parse.add_argument('from', type=int, required=False, default=0) parse.add_argument('end', type=int, required=False, default=now) parse.add_argument('type', type=list, required=False) args = parse.parse_args() limit = args.get('limit') offset = args.get('offset') from_ts = args.get('from') end_ts = args.get('end') billing_types = args.get('type') if not billing_types: billing_types = [str(ACTIVITY_REWORD), str(COOP_FINE)] billing_types = [ int(billing_type) for billing_type in billing_types if billing_type.isalnum() ] from_dt = datetime.fromtimestamp(from_ts) end_dt = datetime.fromtimestamp(end_ts) infos = Billings.query.filter_by(account_key=account_key, ).filter( Billings.type.in_(billing_types), ).filter( and_(Billings.create_time > from_dt, Billings.create_time < end_dt)).order_by( Billings.create_time.desc()).limit(limit).offset( offset).all() total_records = Billings.query.filter_by( account_key=account_key, ).filter( Billings.type.in_(billing_types), ).count() records = [info.to_dict() for info in infos] return make_resp(records=records, total_records=total_records)
def get(self): account_key = g.account_key parse = reqparse.RequestParser() now = int(time.time()) parse.add_argument('limit', type=int, required=False, default=10) parse.add_argument('offset', type=int, required=False, default=0) parse.add_argument('from', type=int, required=False, default=0) parse.add_argument('end', type=int, required=False, default=now) parse.add_argument('coin_name', type=str, required=False) parse.add_argument('status', type=int, required=False) args = parse.parse_args() limit = args.get('limit') offset = args.get('offset') from_ts = args.get('from') end_ts = args.get('end') coin_name = args.get('coin_name') status = args.get('status') from_dt = datetime.fromtimestamp(from_ts) end_dt = datetime.fromtimestamp(end_ts) kwargs = {"account_key": account_key} if not coin_name: coin_name = BHD_COIN_NAME if coin_name == BHD_COIN_NAME: model = BurstBlock query_deadline = model.deadline elif coin_name == LHD_NAME: model = LHDBurstBlock query_deadline = model.deadline elif coin_name == DISK_NAME: model = DISKBurstBlock query_deadline = model.deadline elif coin_name == HDD_NAME: model = HDDECOLBurstBlock query_deadline = model.deadline else: model = NBBurstBlock query_deadline = literal("0") if coin_name == BHD_COIN_NAME: coop_query = db.session.query( model.plotter_id, model.height, query_deadline, model.create_time.label('create_time'), literal("coop")).filter_by(account_key=account_key).filter( and_(model.create_time > from_dt, model.create_time < end_dt)) else: # coin_name == LHD_NAME: coop_query = db.session.query( model.plotter_id, model.height, query_deadline, model.create_time.label('create_time'), literal("ecol")).filter_by(account_key=account_key).filter( and_(model.create_time > from_dt, model.create_time < end_dt)) # else: # coop_query = db.session.query(model.plotter_id, model.height, # query_deadline, # model.create_time.label( # 'create_time'), # literal("ecol") # ).filter_by(account_key=account_key # ).filter( # and_(model.create_time > from_dt, # model.create_time < end_dt)) if coin_name == NEWBI_NAME: coops = coop_query.limit(limit).offset(offset).all() coops = [coop.to_dict() for coop in coops] return make_resp(records=coops, total_records=len(coops)) ecol_query = None if coin_name == BHD_COIN_NAME: ecol_query = db.session.query( EcolBurstBlock.plotter_id, EcolBurstBlock.height, EcolBurstBlock.deadline, EcolBurstBlock.create_time.label('create_time'), literal("ecol")).filter_by(account_key=account_key).filter( and_(EcolBurstBlock.create_time > from_dt, EcolBurstBlock.create_time < end_dt)) elif coin_name == LHD_NAME: ecol_query = db.session.query( LHDMainBurstBlock.plotter_id, LHDMainBurstBlock.height, LHDMainBurstBlock.deadline, LHDMainBurstBlock.create_time.label('create_time'), literal("coop")).filter_by(account_key=account_key).filter( and_(LHDMainBurstBlock.create_time > from_dt, LHDMainBurstBlock.create_time < end_dt)) all_burst = None if coin_name in [BHD_COIN_NAME, LHD_NAME]: all_burst = coop_query.union_all(ecol_query).order_by( 'create_time').all()[::-1][offset:limit] elif coin_name in [DISK_NAME, HDD_NAME]: all_burst = coop_query.order_by( 'create_time').all()[::-1][offset:limit] total_records = len(all_burst) return make_resp(records=all_burst, total_records=total_records)
def get(self): """ 按天获取收益列表 :return: """ account_key = g.account_key parse = reqparse.RequestParser() now = int(time.time()) parse.add_argument('limit', type=int, required=False, default=10) parse.add_argument('offset', type=int, required=False, default=0) parse.add_argument('from', type=int, required=False, default=0) parse.add_argument('end', type=int, required=False, default=now) parse.add_argument('coin_name', type=str, required=False) parse.add_argument('status', type=int, required=False) args = parse.parse_args() limit = args.get('limit') offset = args.get('offset') from_ts = args.get('from') end_ts = args.get('end') coin_name = args.get('coin_name') status = args.get('status') from_dt = datetime.fromtimestamp(from_ts) end_dt = datetime.fromtimestamp(end_ts) kwargs = {"account_key": account_key} if not coin_name: coin_name = BHD_COIN_NAME if coin_name == BHD_COIN_NAME: model = IncomeRecord elif coin_name == LHD_NAME: model = LHDIncomeRecord elif coin_name == DISK_NAME: model = DISKIncomeRecord elif coin_name == HDD_NAME: model = HDDIncomeRecord elif coin_name == NEWBI_NAME: model = NBIncomeRecord else: return make_resp(400, False, message="请求币种错误") # manage_money_amount = model.query.filter_by( # account_key=account_key, type=IncomeTYpemanagemoney # ).filter( # and_(model.create_time > from_dt, # model.create_time < end_dt) # ).with_entities(func.sum(model.amount)).first()[0] infos = model.query.filter_by(**kwargs).with_entities( # 查询指定的列 model.type, func.sum(model.amount), func.date(model.create_time), func.avg(model.capacity), ).filter(and_( model.create_time > from_dt, model.create_time < end_dt)).order_by( model.create_time.desc()).group_by( model.type, func.date( model.create_time)).limit(limit).offset(offset).all() total_records = model.query.filter_by(**kwargs).group_by( func.to_days(model.create_time)).count() date_incomes = {} for income_type, amount, create_time, capacity in infos: create_time = str(create_time) if create_time not in date_incomes: date_incomes[create_time] = { 'coop_income': 0, 'mining_income': 0, "manage_money_income": 0, 'capacity': 0 } day_income = date_incomes[create_time] filed_name = "coop_income" if income_type == IncomeTypeMining: filed_name = "mining_income" day_income["capacity"] = capacity elif income_type == IncomeTYpemanagemoney: filed_name = "manage_money_income" day_income[filed_name] = amount day_income["total_income"] = day_income.get("total_income", 0) + amount records = sorted(date_incomes.items(), key=lambda k: k[0], reverse=True) return make_resp(records=records, total_records=total_records)
def post(self): """ 转账 :return: """ parse = reqparse.RequestParser() parse.add_argument('coin_name', type=str, required=True, trim=True) parse.add_argument('amount', type=str, required=True) parse.add_argument('to_address', type=str, required=True, trim=True) parse.add_argument('seccode', type=str, required=True, trim=True) args = parse.parse_args() coin_name = args.get('coin_name') account_key = g.account_key amount = Decimal(str(args.get('amount'))) to_address = args.get('to_address') seccode = args.get('seccode') api_logger.info("Withdrawal api, to:%s, amount:%s, account_key:%s" % (to_address, amount, account_key)) try: user_asset = UserAsset.query.filter_by( account_key=account_key, coin_name=coin_name).with_for_update(read=True).first() if not user_asset: api_logger.error("withdrawal,user not found %s" % account_key) return make_resp(404, False, message="用户资产错误") key = "withdrawal:seccode:%s" % account_key seccode_cache = redis_auth.get(key) if seccode != seccode_cache: api_logger.error("withdrawal, seccode error") return make_resp(400, False, message="验证码错误") redis_auth.delete(key) api_logger.error( "withdrawal, user:%s, available_asset:%s, amount:%s" % (account_key, user_asset.available_asset, amount)) if user_asset.available_asset < amount or user_asset.total_asset < amount: return make_resp(400, False, message="可用余额不足") client = get_rpc(coin_name) if not client.check_address(to_address): return make_resp(400, False, message="地址错误") if user_asset.get_available_margin_amount() < amount: return make_resp(400, False, message="可提现金额不足") user_asset.available_asset -= amount user_asset.frozen_asset += amount withdrawal_transaction = WithdrawalTransaction(account_key, amount, to_address, coin_name=coin_name) db.session.add(withdrawal_transaction) db.session.commit() except Exception as e: api_logger.error("withdrawal, error %s" % str(e)) db.session.rollback() return make_resp(500, False, message="提现申请提交失败") api_logger.info( "Withdrawal api, insert into withdrawal_transaction %s" % withdrawal_transaction.to_dict()) return make_resp(200, True)
def get(self): """ 获取用户总收益 :return: """ parse = reqparse.RequestParser() parse.add_argument('coin_name', type=str, required=False) args = parse.parse_args() coin_name = args.get('coin_name') if not coin_name: coin_name = BHD_COIN_NAME if coin_name == BHD_COIN_NAME: model = IncomeRecord elif coin_name == LHD_NAME: model = LHDIncomeRecord elif coin_name == DISK_NAME: model = DISKIncomeRecord elif coin_name == HDD_NAME: model = HDDIncomeRecord elif coin_name == NEWBI_NAME: model = NBIncomeRecord else: return make_resp(400, False, message="请求币种错误") account_key = g.account_key # 合作-裸挖-挖矿总收入 mining_total_amount = model.query.filter_by( account_key=account_key).filter( model.type.in_([IncomeTypeMining, IncomeTYpeMiningEcol])).with_entities( func.sum(model.amount)).first()[0] # 昨天挖矿所得 mining_last_day = model.query.filter_by( account_key=account_key).filter( func.to_days(model.create_time) == func.to_days(func.now()) - 1).filter( model.type.in_([IncomeTypeMining, IncomeTYpeMiningEcol])).with_entities( func.sum(model.amount)).first()[0] if coin_name == NEWBI_NAME: return make_resp(mining_total_amount=mining_total_amount, mining_last_day=mining_last_day) # 合作所得总 coop_total_amount = model.query.filter_by( account_key=account_key, type=IncomeTYpeCoopReward).with_entities( func.sum(model.amount)).first()[0] # 昨日合作所得 coop_last_day = model.query.filter_by( account_key=account_key, type=IncomeTYpeCoopReward).filter( func.to_days(model.create_time) == func.to_days(func.now()) - 1).with_entities(func.sum(model.amount)).first()[0] if coin_name == LHD_NAME: return make_resp( mining_total_amount=mining_total_amount, mining_last_day=mining_last_day, coop_total_amount=coop_total_amount, coop_last_day=coop_last_day, ) # 理财收益 manage_money_amount = model.query.filter_by( account_key=account_key, type=IncomeTYpemanagemoney).with_entities( func.sum(model.amount)).first()[0] # 活动总收益 activity_rewards_total_amount = ActivityReward.query.filter_by( account_key=account_key).filter( ActivityReward.amount > 0).with_entities( func.sum(ActivityReward.amount)).first()[0] # 昨日活动收益 activity_rewards_last_day = ActivityReward.query.filter_by( account_key=account_key).filter( func.to_days( ActivityReward.create_time) == func.to_days(func.now()) - 1).filter(ActivityReward.amount > 0).with_entities( func.sum(ActivityReward.amount)).first()[0] return make_resp( mining_total_amount=mining_total_amount, mining_last_day=mining_last_day, coop_total_amount=coop_total_amount, coop_last_day=coop_last_day, activity_rewards_total_amount=activity_rewards_total_amount, activity_rewards_last_day=activity_rewards_last_day, manage_money_amount=manage_money_amount)
def get(self): account_key = g.account_key parse = reqparse.RequestParser() now = int(time.time()) parse.add_argument('limit', type=int, required=False, default=10) parse.add_argument('offset', type=int, required=False, default=0) parse.add_argument('from', type=int, required=False, default=0) parse.add_argument('end', type=int, required=False, default=now) parse.add_argument('coin_name', type=str, required=False) parse.add_argument('status', type=int, required=False) args = parse.parse_args() limit = args.get('limit') offset = args.get('offset') from_ts = args.get('from') end_ts = args.get('end') coin_name = args.get('coin_name') or BHD_COIN_NAME status = args.get('status') from_dt = datetime.fromtimestamp(from_ts) end_dt = datetime.fromtimestamp(end_ts) # 获取model model_record = TeamWorkRecordActivity model = TeamWorkActivity if coin_name == "lhd": model_record = LHDTeamWorkRecordActivity model = LHDTeamWorkActivity # 联表查询 infos = model_record.query.filter_by( account_key=account_key, type=2 # 筛选用户,筛选活动类型为理财类型 ).join( model, model_record.cooperation_id == model.id # 通过合作id字段与活动表id联表 ).with_entities( model.rate, model_record.coo_amount, model_record.income, model.deadline, model_record.create_time, model_record.end_time, model_record.status # 筛选所需列,(年化,投入金额,收益,周期,开始时间,结束时间,目前状态) ).filter( and_(model_record.create_time > from_dt, model_record.create_time < end_dt)).order_by( model_record.create_time.desc()).limit(limit).offset( offset).all() # 理财数据数量 total_records = model_record.query.filter_by( account_key=account_key, type=2).join( model, model_record.cooperation_id == model.id).with_entities( model.rate, model_record.coo_amount, model_record.income, model.deadline, model_record.create_time, model_record.end_time, model_record.status).count() records = [] for info in infos: dict_pro = {} dict_pro["rate"] = info.rate dict_pro["coo_amount"] = info.coo_amount dict_pro["income"] = info.income dict_pro["deadline"] = info.deadline dict_pro["create_time"] = info.create_time dict_pro["end_time"] = info.end_time dict_pro["status"] = info.status records.append(dict_pro) return make_resp(records=records, total_records=total_records)
def put(self): """ 用户资产划转,从抵押到余额划转,余额到抵押。 :return: """ parse = reqparse.RequestParser() parse.add_argument('amount', type=str, required=True) parse.add_argument('direction', type=bool, required=False, default=True, help="True:抵押到余额,False:余额到抵押") parse.add_argument('coin_name', type=str) args = parse.parse_args() coin_name = args.get('coin_name') or BHD_COIN_NAME amount = Decimal(args.get('amount')) # todo """ 到抵押时: 1、先从远程借贷中抵押到远程抵押 2、不够从可用中抵押到矿机抵押 到余额时: 1、先从矿机抵押划转到可用 2、不够从远程抵押减去 """ direction = args.get('direction') account_key = g.account_key api_logger.info("asset transfer, amount:%s, user:%s, direction:%s" % (amount, account_key, direction)) try: user_asset = UserAsset.query.filter_by( account_key=account_key, coin_name=coin_name).with_for_update(read=True).first() total_available_2pledge = user_asset.get_total_available_pledge_amount( ) total_available_2balance = user_asset.get_pledge_amount() if direction and total_available_2balance < amount: api_logger.error( "asset transfer, user:%s, pledge_asset:%s, amount:%s" % (account_key, user_asset.pledge_asset, amount)) return make_resp(400, False, message="pledge_asset not enough") if not direction and total_available_2pledge < amount: api_logger.error( "asset transfer, user:%s, available_asset:%s, amount:%s" % (account_key, user_asset.available_asset, amount)) return make_resp(400, False, message="available not enough") if direction: if user_asset.pledge_asset >= amount: user_asset.pledge_asset -= amount user_asset.available_asset += amount else: user_asset.remote_4pledge_asset -= ( amount - user_asset.pledge_asset) user_asset.available_asset += user_asset.pledge_asset user_asset.pledge_asset = 0 else: remote_avai2_pledge = user_asset.get_remote_avai_amount() if remote_avai2_pledge >= amount: user_asset.remote_4pledge_asset += amount else: user_asset.remote_4pledge_asset += remote_avai2_pledge del_available_asset = amount - remote_avai2_pledge user_asset.available_asset -= del_available_asset user_asset.pledge_asset += del_available_asset asset_transfer = AssetTransfer(account_key, abs(amount), direction, coin_name) db.session.add(asset_transfer) db.session.commit() except Exception as e: api_logger.error("asset transfer, error %s" % str(e)) db.session.rollback() return make_resp(500, False, message="transfer failed") api_logger.info( "asset transfer succeed, amount:%s, user:%s, direction:%s" % (amount, account_key, direction)) return make_resp(200, True)
def get(self): account_key = g.account_key parse = reqparse.RequestParser() now = int(time.time()) parse.add_argument('limit', type=int, required=False, default=10) parse.add_argument('offset', type=int, required=False, default=0) parse.add_argument('from', type=int, required=False, default=0) parse.add_argument('end', type=int, required=False, default=now) parse.add_argument('coin_name', type=str, required=False) parse.add_argument('status', type=int, required=False) args = parse.parse_args() limit = args.get('limit') offset = args.get('offset') from_ts = args.get('from') end_ts = args.get('end') coin_name = args.get('coin_name') status = args.get('status') from_dt = datetime.fromtimestamp(from_ts) end_dt = datetime.fromtimestamp(end_ts) kwargs = {"account_key": account_key} if not coin_name: coin_name = BHD_COIN_NAME if coin_name == BHD_COIN_NAME: model = DeadlineFraction elif coin_name == LHD_NAME: model = LHDDeadlineFraction elif coin_name == DISK_NAME: model = DISKDeadlineFraction elif coin_name == HDD_NAME: model = HDDECOLDeadlineFraction else: model = NBDeadlineFraction if coin_name == BHD_COIN_NAME: coop_query = db.session.query( model.height, literal("coop"), model.fraction, model.deadline, model.miner_name, model.plotter_id, model.create_time.label('create_time'), ).filter_by(account_key=account_key).filter( and_(model.create_time > from_dt, model.create_time < end_dt)) else: # coin_name == LHD_NAME: coop_query = db.session.query( model.height, literal("ecol"), model.fraction, model.deadline, model.miner_name, model.plotter_id, model.create_time.label('create_time'), ).filter_by(account_key=account_key).filter( and_(model.create_time > from_dt, model.create_time < end_dt)) # else: # coop_query = db.session.query(model.height, # literal("coop"), # model.fraction, # model.deadline, # model.miner_name, # model.plotter_id, # model.create_time.label('create_time'), # ).filter_by(account_key=account_key # ).filter( # and_(model.create_time > from_dt, # model.create_time < end_dt)) if coin_name == NEWBI_NAME: all_dls = coop_query.limit(limit).offset(offset).all() dls = [dl.to_dict() for dl in all_dls] return make_resp(records=dls, total_records=len(dls)) ecol_query = None if coin_name == BHD_COIN_NAME: ecol_query = db.session.query( DeadlineFractionEcology.height, literal("ecol"), DeadlineFractionEcology.fraction, DeadlineFractionEcology.deadline, DeadlineFractionEcology.miner_name, DeadlineFractionEcology.plotter_id, DeadlineFractionEcology.create_time.label('create_time'), ).filter_by(account_key=account_key).filter( and_(DeadlineFractionEcology.create_time > from_dt, DeadlineFractionEcology.create_time < end_dt)) elif coin_name == LHD_NAME: ecol_query = db.session.query( LHDDeadlineFractionMain.height, literal("coop"), LHDDeadlineFractionMain.fraction, LHDDeadlineFractionMain.deadline, LHDDeadlineFractionMain.miner_name, LHDDeadlineFractionMain.plotter_id, LHDDeadlineFractionMain.create_time.label('create_time'), ).filter_by(account_key=account_key).filter( and_(LHDDeadlineFractionMain.create_time > from_dt, LHDDeadlineFractionMain.create_time < end_dt)) all_dls = None if coin_name in [BHD_COIN_NAME, LHD_NAME]: all_dls = coop_query.union_all(ecol_query).order_by( 'create_time').all()[::-1][offset:limit] elif coin_name in [DISK_NAME, HDD_NAME]: all_dls = coop_query.order_by( 'create_time').all()[::-1][offset:limit] total_records = len(all_dls) return make_resp(records=all_dls, total_records=total_records)
def get(self): """ 用户资产信息获取 :return: """ account_key = g.account_key parse = reqparse.RequestParser() parse.add_argument('coin_name', type=str, required=False) args = parse.parse_args() coin_name = args.get('coin_name') or BHD_COIN_NAME user_asset = UserAsset.query.filter_by(account_key=account_key, coin_name=coin_name).first() # 如果查不到用户资产,返回404 if not user_asset: return make_resp(404, False) context = user_asset.to_dict() # 如果不是BHD或者LHD或者DISk或者HDD,直接返回资产信息json if coin_name not in (BHD_COIN_NAME, LHD_NAME, DISK_NAME, HDD_NAME): return make_resp(200, True, **context) if coin_name == BHD_COIN_NAME: keys = "miner:main:%s:*" % account_key rate = Decimal(redis_capacity.get(BHD_RATE_KEY)) elif coin_name == LHD_NAME: keys = "miner:ecol:lhd:%s:*" % account_key # ecol为主矿池算力 rate = 6 elif coin_name == DISK_NAME: keys = "miner:main:disk:%s:*" % account_key # ecol为主矿池算力 rate = 6 elif coin_name == HDD_NAME: keys = "miner:main:hdd:%s:*" % account_key rate = 6 miner_machines = redis_capacity.keys(keys) context.update({ "earning_rate": 0, "theory_pledge": 0, "pledge_rate": 0, "total_income": 0, "network_rate": rate, }) if not miner_machines: return make_resp(200, True, **context) total_capacity = 0 for machine in miner_machines: capacity_ts = redis_capacity.get(machine) capacity, ts = capacity_ts.split(":") period_validity = time() - int(ts[:-3]) if period_validity < 7200 and isinstance( capacity, str) and capacity.isdigit(): total_capacity += int(capacity) if not total_capacity: return make_resp(200, True, **context) theory_pledge = Decimal(total_capacity) / 1024 * rate pledge_rate = user_asset.get_pledge_amount() / theory_pledge if coin_name == DISK_NAME: earning_rate = DISK_NOT_MORTGAGE_YIELD_RATE else: earning_rate = NOT_MORTGAGE_YIELD_RATE if pledge_rate > 1: earning_rate = MORTGAGE_YIELD_RATE total_income = IncomeRecord.query.with_entities( func.sum(IncomeRecord.amount)).filter_by( account_key=account_key).first() if not total_income: total_income = [0] calculate_data = { "earning_rate": earning_rate, "theory_pledge": theory_pledge, "pledge_rate": pledge_rate, "total_income": total_income[0], } context.update(calculate_data) return make_resp(200, True, **context)