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(bool multiplyBy100 = true) { var userList = fsql.Select().ToList().Map>(); userList.CalculateRatio(multiplyBy100); 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("用户资产小于减持资金,不能提现"); } changeUser.ChangeAmount(capitalChangeType, changeAmount, true); fsql.Transaction(() => { fsql.Update(changeUser.Id).Set(u => u.CostAmount, changeUser.CostAmount) .Set(u => u.TotalAssets, changeUser.TotalAssets) .Set(u => u.WithdrawAmount, changeUser.WithdrawAmount) .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("用户资产小于转移资金,不能转移"); fromUser.ChangeAmount(Enums.CapitalChangeType.Reduce, fundsTransferRequest.ChangeAmount, true); toUser.ChangeAmount(Enums.CapitalChangeType.Add, fundsTransferRequest.ChangeAmount, true); fsql.Transaction(() => { fsql.Update(fromUser.Id).Set(u => u.CostAmount, fromUser.CostAmount) .Set(u => u.TotalAssets, fromUser.TotalAssets) .Set(u => u.WithdrawAmount, fromUser.WithdrawAmount) .ExecuteAffrows(); fsql.Update(toUser.Id).Set(u => u.CostAmount, toUser.CostAmount) .Set(u => u.TotalAssets, toUser.TotalAssets) .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) .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() .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, CumulativeProfitAndLoss = p.CumulativeProfitAndLoss }); return new UserAccountProfitLossRecordListResponse() { List = list, RecordCount = recordCount }; } #endregion } }