You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
298 lines
14 KiB
298 lines
14 KiB
using Binance.TradeRobot.Business.Extensions;
|
|
using Binance.TradeRobot.Common.DI;
|
|
using Binance.TradeRobot.Common.Extensions;
|
|
using Binance.TradeRobot.Model.Base;
|
|
using Binance.TradeRobot.Model.Db;
|
|
using Binance.TradeRobot.Model.Dto;
|
|
using Microsoft.Extensions.Caching.Memory;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IdentityModel.Tokens.Jwt;
|
|
using System.Linq;
|
|
using System.Security.Claims;
|
|
using System.Text;
|
|
using Yitter.IdGenerator;
|
|
|
|
namespace Binance.TradeRobot.Business
|
|
{
|
|
[BatchRegistration(ServiceLifetime.Singleton, RegistrationType.Self)]
|
|
public class UserBusiness : BaseBusiness
|
|
{
|
|
private IConfiguration configuration;
|
|
|
|
public UserBusiness(IFreeSql fsql, NLogManager logManager, IIdGenerator idGenerator, IConfiguration configuration, IMemoryCache memoryCache) : base(fsql, logManager, idGenerator, memoryCache)
|
|
{
|
|
this.configuration = configuration;
|
|
}
|
|
|
|
public LoginResponse Login(LoginRequest loginRequest)
|
|
{
|
|
var pwd = loginRequest.Pwd.ToMD5();
|
|
var user = fsql.Select<User>().Where(u => u.UserName == loginRequest.UserName && u.Pwd == pwd).ToOne();
|
|
if (user == null)
|
|
throw new BusinessException("用户名或密码错误");
|
|
|
|
#region 签发token
|
|
var claims = new List<Claim>()
|
|
{
|
|
new Claim("Id",user.Id.ToString()),
|
|
new Claim("UserName",user.UserName),
|
|
};
|
|
|
|
var jwtSecret = configuration.GetSection("JwtConfig:Secret").Value;
|
|
var jwtIssuer = configuration.GetSection("JwtConfig:Issuer").Value;
|
|
var jwtAudience = configuration.GetSection("JwtConfig:Audience").Value;
|
|
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSecret));
|
|
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
|
|
var jwtToken = new JwtSecurityToken(jwtIssuer, jwtAudience, claims, expires: DateTime.Now.AddDays(30), signingCredentials: credentials);
|
|
var token = new JwtSecurityTokenHandler().WriteToken(jwtToken);
|
|
#endregion
|
|
return new LoginResponse()
|
|
{
|
|
Id = user.Id,
|
|
UserName = user.UserName,
|
|
Token = token
|
|
};
|
|
}
|
|
|
|
public IList<UserResponse> GetUserList(bool multiplyBy100 = true)
|
|
{
|
|
var userList = fsql.Select<User>().ToList(u => new UserResponse()
|
|
{
|
|
Id = u.Id,
|
|
CostAmount = u.CostAmount,
|
|
CreateTime = u.CreateTime,
|
|
Profit = u.Profit,
|
|
UpdateTime = u.UpdateTime,
|
|
UserName = u.UserName,
|
|
WithdrawAmount = u.WithdrawAmount
|
|
});
|
|
userList.CalculateRatio(multiplyBy100);
|
|
return userList;
|
|
}
|
|
|
|
#region 用户资产
|
|
|
|
/// <summary>
|
|
/// 单向资产变更
|
|
/// </summary>
|
|
/// <param name="operationUserId"></param>
|
|
/// <param name="changeAmount"></param>
|
|
/// <param name="changeUserId"></param>
|
|
/// <param name="capitalChangeType"></param>
|
|
/// <param name="remark"></param>
|
|
/// <exception cref="BusinessException"></exception>
|
|
private void OneWayAssetChange(long operationUserId, decimal changeAmount, long changeUserId, Enums.CapitalChangeType capitalChangeType, string remark)
|
|
{
|
|
var changeUser = fsql.Select<User>(changeUserId).ToOne().Map<UserResponse>();
|
|
if (changeUser == null)
|
|
throw new BusinessException("资金变更用户不存在");
|
|
|
|
if (capitalChangeType == Enums.CapitalChangeType.Reduce)
|
|
{
|
|
if (changeUser.TotalAssets < changeAmount)
|
|
throw new BusinessException("用户资产小于减持资金,不能提现");
|
|
|
|
//获取交易所账户总额(usdt)
|
|
//var apiKeyList = stockExchangeAccountBusiness.GetAPIKeyList(null);
|
|
//var totalBalance = apiKeyList.Sum(k => k.Balance);
|
|
//if (totalBalance < changeAmount)
|
|
// throw new BusinessException("交易所总余额小于减持资金,不能提现");
|
|
}
|
|
changeUser.ChangeAmount(capitalChangeType, changeAmount, true);
|
|
//if (capitalChangeType == Enums.CapitalChangeType.Add)
|
|
//{
|
|
// changeUser.CostAmount += changeAmount;
|
|
//}
|
|
//else if (capitalChangeType == Enums.CapitalChangeType.Reduce)
|
|
//{
|
|
// if (changeUser.Profit > 0)
|
|
// {
|
|
// if (changeUser.Profit >= changeAmount)
|
|
// changeUser.Profit -= changeAmount; //收益足够提现,只扣收益
|
|
// else
|
|
// {
|
|
// var lessChangeAmount = changeAmount; //收益不足提现,先扣收益,不足部分再扣本金
|
|
// lessChangeAmount -= changeUser.Profit;
|
|
// changeUser.Profit = 0;
|
|
// changeUser.CostAmount -= lessChangeAmount;
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// changeUser.CostAmount -= changeAmount;
|
|
// }
|
|
//}
|
|
|
|
fsql.Transaction(() =>
|
|
{
|
|
fsql.Update<User>(changeUser.Id).Set(u => u.CostAmount, changeUser.CostAmount)
|
|
.Set(u => u.Profit, changeUser.Profit)
|
|
.SetIf(capitalChangeType == Enums.CapitalChangeType.Reduce, u => u.WithdrawAmount + changeAmount)
|
|
.ExecuteAffrows();
|
|
|
|
fsql.Insert(new UserAccountFundChangeRecord()
|
|
{
|
|
Id = idGenerator.NewLong(),
|
|
ChangeAmount = changeAmount,
|
|
UserId = changeUserId,
|
|
OperationType = capitalChangeType,
|
|
OperationUserId = operationUserId,
|
|
Remark = remark,
|
|
Direction = capitalChangeType == Enums.CapitalChangeType.Add ? Enums.FundDirection.In : Enums.FundDirection.Out
|
|
}).ExecuteAffrows();
|
|
});
|
|
}
|
|
|
|
public void AddFunds(long operationUserId, FundsChangeRequest fundsChangeRequest)
|
|
{
|
|
if (fundsChangeRequest.ChangeAmount <= 0)
|
|
throw new BusinessException("无效金额");
|
|
OneWayAssetChange(operationUserId, fundsChangeRequest.ChangeAmount, fundsChangeRequest.UserId, Enums.CapitalChangeType.Add, fundsChangeRequest.Remark);
|
|
}
|
|
|
|
public void ReduceFunds(long operationUserId, FundsChangeRequest fundsChangeRequest)
|
|
{
|
|
if (fundsChangeRequest.ChangeAmount <= 0)
|
|
throw new BusinessException("无效金额");
|
|
OneWayAssetChange(operationUserId, fundsChangeRequest.ChangeAmount, fundsChangeRequest.UserId, Enums.CapitalChangeType.Reduce, fundsChangeRequest.Remark);
|
|
}
|
|
|
|
public void TransferFunds(long operationUserId, FundsTransferRequest fundsTransferRequest)
|
|
{
|
|
if (fundsTransferRequest.ChangeAmount <= 0)
|
|
throw new BusinessException("无效金额");
|
|
|
|
var userList = fsql.Select<User>().ToList().Map<IList<UserResponse>>();
|
|
var fromUser = userList.FirstOrDefault(u => u.Id == fundsTransferRequest.FromUserId);
|
|
if (fromUser == null)
|
|
throw new BusinessException("资金变更用户不存在");
|
|
var toUser = userList.FirstOrDefault(u => u.Id == fundsTransferRequest.ToUserId);
|
|
if (toUser == null)
|
|
throw new BusinessException("资金变更用户不存在");
|
|
|
|
if (fromUser.TotalAssets < fundsTransferRequest.ChangeAmount)
|
|
throw new BusinessException("用户资产小于转移资金,不能转移");
|
|
|
|
if (fromUser.Profit > 0)
|
|
{
|
|
if (fromUser.Profit >= fundsTransferRequest.ChangeAmount)
|
|
fromUser.Profit -= fundsTransferRequest.ChangeAmount; //收益足够提现,只扣收益
|
|
else
|
|
{
|
|
var lessChangeAmount = fundsTransferRequest.ChangeAmount; //收益不足提现,先扣收益,不足部分再扣本金
|
|
lessChangeAmount -= fromUser.Profit;
|
|
fromUser.Profit = 0;
|
|
fromUser.CostAmount -= lessChangeAmount;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fromUser.CostAmount -= fundsTransferRequest.ChangeAmount;
|
|
}
|
|
|
|
fsql.Transaction(() =>
|
|
{
|
|
fsql.Update<User>(fromUser.Id).Set(u => u.CostAmount, fromUser.CostAmount)
|
|
.Set(u => u.Profit, fromUser.Profit)
|
|
.Set(u => u.WithdrawAmount + fundsTransferRequest.ChangeAmount)
|
|
.ExecuteAffrows();
|
|
|
|
fsql.Update<User>(toUser.Id).Set(u => u.CostAmount + fundsTransferRequest.ChangeAmount)
|
|
.ExecuteAffrows();
|
|
|
|
fsql.Insert(new UserAccountFundChangeRecord()
|
|
{
|
|
Id = idGenerator.NewLong(),
|
|
ChangeAmount = fundsTransferRequest.ChangeAmount,
|
|
UserId = fundsTransferRequest.FromUserId,
|
|
OperationType = Enums.CapitalChangeType.Transfer,
|
|
OperationUserId = operationUserId,
|
|
Remark = fundsTransferRequest.Remark,
|
|
Direction = Enums.FundDirection.Out,
|
|
ToUserId = fundsTransferRequest.ToUserId
|
|
}).ExecuteAffrows();
|
|
|
|
fsql.Insert(new UserAccountFundChangeRecord()
|
|
{
|
|
Id = idGenerator.NewLong(),
|
|
ChangeAmount = fundsTransferRequest.ChangeAmount,
|
|
UserId = fundsTransferRequest.ToUserId,
|
|
OperationType = Enums.CapitalChangeType.Transfer,
|
|
OperationUserId = operationUserId,
|
|
Remark = fundsTransferRequest.Remark,
|
|
Direction = Enums.FundDirection.In,
|
|
ToUserId = fundsTransferRequest.FromUserId
|
|
}).ExecuteAffrows();
|
|
});
|
|
}
|
|
|
|
public UserAccountChangeRecordListResponse GetUserAccountFundChangeRecordList(QueryUserAccountRequest queryUserAccountRequest)
|
|
{
|
|
var list = fsql.Select<UserAccountFundChangeRecord, User, User, User>()
|
|
.InnerJoin((ucr, u, ou, tu) => ucr.UserId == u.Id)
|
|
.InnerJoin((ucr, u, ou, tu) => ucr.OperationUserId == ou.Id)
|
|
.LeftJoin((ucr, u, ou, tu) => ucr.ToUserId == tu.Id)
|
|
.Where((ucr, u, ou, tu) => ucr.UserId == queryUserAccountRequest.UserId)
|
|
.OrderByDescending((ucr, u, ou, tu) => ucr.CreateTime)
|
|
.Count(out var recordCount)
|
|
.Page(queryUserAccountRequest.PageIndex, queryUserAccountRequest.PageSize)
|
|
.ToList((ucr, u, ou, tu) => new UserAccountFundChangeRecordResponse()
|
|
{
|
|
Id = ucr.Id,
|
|
ChangeAmount = ucr.ChangeAmount,
|
|
CreateTime = ucr.CreateTime,
|
|
OperationType = ucr.OperationType,
|
|
OperationUserId = ucr.OperationUserId,
|
|
OperationUserName = ou.UserName,
|
|
UserId = ucr.UserId,
|
|
UserName = u.UserName,
|
|
Remark = ucr.Remark,
|
|
Direction = ucr.Direction,
|
|
ToUserId = tu.Id,
|
|
ToUserName = tu.UserName
|
|
});
|
|
return new UserAccountChangeRecordListResponse()
|
|
{
|
|
List = list,
|
|
RecordCount = recordCount
|
|
};
|
|
}
|
|
|
|
public UserAccountProfitLossRecordListResponse GetUserAccountProfitLossRecordList(QueryUserAccountRequest queryUserAccountRequest)
|
|
{
|
|
var list = fsql.Select<Model.Db.UserAccountProfitLossRecord, Model.Db.User, Model.Db.Robot>()
|
|
.WithLock(SqlServerLock.NoLock)
|
|
.InnerJoin((p, u, r) => p.UserId == u.Id)
|
|
.InnerJoin((p, u, r) => p.RobotId == r.Id)
|
|
.Where((p, u, r) => p.UserId == queryUserAccountRequest.UserId)
|
|
.OrderByDescending((p, u, r) => p.CreateTime)
|
|
.Count(out var recordCount)
|
|
.Page(queryUserAccountRequest.PageIndex, queryUserAccountRequest.PageSize)
|
|
.ToList((p, u, r) => new UserAccountProfitLossRecordResponse()
|
|
{
|
|
Id = p.Id,
|
|
ChangeAmount = p.ChangeAmount,
|
|
CreateTime = p.CreateTime,
|
|
DividendRatio = p.DividendRatio,
|
|
OrderProfit = p.OrderProfit,
|
|
RobotId = p.RobotId,
|
|
OrderId = p.OrderId,
|
|
Symbol = r.Symbol,
|
|
UserId = p.UserId,
|
|
UserName = u.UserName,
|
|
UserProfit = p.UserProfit
|
|
});
|
|
return new UserAccountProfitLossRecordListResponse()
|
|
{
|
|
List = list,
|
|
RecordCount = recordCount
|
|
};
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|
|
|