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().Where(u => u.UserName == loginRequest.UserName && u.Pwd == pwd).ToOne(); if (user == null) throw new BusinessException("用户名或密码错误"); #region 签发token var claims = new List() { 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 GetUserList() { var userList = fsql.Select().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(); return userList; } #region 用户资产 /// /// 单向资产变更 /// /// /// /// /// /// /// private void OneWayAssetChange(long operationUserId, decimal changeAmount, long changeUserId, Enums.CapitalChangeType capitalChangeType, string remark) { var changeUser = fsql.Select(changeUserId).ToOne().Map(); 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("交易所总余额小于减持资金,不能提现"); } 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(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().ToList().Map>(); 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(fromUser.Id).Set(u => u.CostAmount, fromUser.CostAmount) .Set(u => u.Profit, fromUser.Profit) .Set(u => u.WithdrawAmount + fundsTransferRequest.ChangeAmount) .ExecuteAffrows(); fsql.Update(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() .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) .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() // .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) // .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, // SpotOrderId = p.SpotOrderId, // Symbol = r.Symbol, // UserId = p.UserId, // UserName = u.UserName, // UserProfit = p.UserProfit // }); // return new UserAccountProfitLossRecordListResponse() // { // List = list, // RecordCount = recordCount // }; //} #endregion } }