private static decimal GetRandomMoney(RedPocket redPackage, decimal min, int n) { // RemainCount 剩余的红包数量 // Balance 剩余的钱 if (redPackage.RemainCount <= 0) { return(0); } if (redPackage.RemainCount == 1) { redPackage.RemainCount--; return(Math.Round(redPackage.Balance * n) / n); } var r = new Random(); var max = redPackage.Balance / redPackage.RemainCount * 2; var money = (decimal)r.NextDouble() * max; money = money <= min ? min : money; money = Math.Floor(money * n) / n; redPackage.RemainCount--; redPackage.Balance -= money; return(money); }
public long Insert(RedPocket model) { using (var con = WriteConnection()) { return(con.ExecuteScalar <long>(@"INSERT INTO RedPockets(AccountId,CryptoCode,Amount,Balance,Count,RemainCount,Message,Timestamp,PassCode,Status,ExpirationDate,CryptoId,OrderNo,FiatAmount) VALUES(@AccountId,@CryptoCode,@Amount,@Balance,@Count,@RemainCount,@Message,@Timestamp,@PassCode,@Status,@ExpirationDate,@CryptoId,@OrderNo,@FiatAmount); SELECT SCOPE_IDENTITY()", model)); } }
public RedPocket Push(UserAccount userAccount, Guid accountId, int cryptoId, decimal amount, int count, string userPIN, string pin, string message = "") { if (userAccount.L1VerifyStatus != Entities.Enums.VerifyStatus.Certified) { throw new CommonException(ReasonCode.NOT_VERIFY_LV1, Resources.EMNeedLV1Verfied); } if (amount <= 0 || cryptoId <= 0) { throw new CommonException(Argument_Error, MessageResources.InvalidDataFormat); } if (count <= 0) { throw new CommonException(Argument_Error, MessageResources.InvalidDataFormat); } if (count > MaxCount) { throw new CommonException(Argument_Error, string.Format(MessageResources.RedPocket_MaxCount, MaxCount)); } if (!string.IsNullOrWhiteSpace(message) && message.Length > 46) { throw new CommonException(Argument_Error, MessageResources.RedPocket_MaxMessage); } SecurityVerify.Verify(new PinVerifier(), SystemPlatform.FiiiPay, accountId.ToString(), userPIN, pin); var cryptoDAC = new CryptocurrencyDAC(); var priceDAC = new PriceInfoDAC(); var crypto = cryptoDAC.GetById(cryptoId); if (crypto == null) { throw new SystemErrorException(); } if (!crypto.Status.HasFlag(Foundation.Entities.Enum.CryptoStatus.RedPocket) || crypto.Enable == 0) { throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, MessageResources.CurrencyForbidden); } var min = crypto.DecimalPlace == 8 ? 0.00000001M : crypto.DecimalPlace == 6 ? 0.000001M : 0.00000001M; var minAmount = count * min; if (amount < minAmount) { throw new CommonException(Push_MinAmount, string.Format(MessageResources.RedPocket_MinAmount, minAmount, crypto.Code)); } var price = priceDAC.GetPriceByName("USD", crypto.Code); var max = crypto.DecimalPlace == 8 ? 999999999.999999999M : crypto.DecimalPlace == 6 ? 999999999.999999M : 999999999.999999999M; var maxAmount = Math.Round(MaxAmount / price, crypto.DecimalPlace); if (count > 1) { maxAmount = Math.Round(MaxAmount * count / price, crypto.DecimalPlace); } if (amount >= max || Math.Round(amount, crypto.DecimalPlace) > maxAmount) { throw new CommonException(Argument_Error, string.Format(MessageResources.RedPocket_MaxAmount, maxAmount, crypto.Code)); } var userWalletDAC = new UserWalletDAC(); var redPocketDAC = new RedPocketDAC(); var userWalletStatementDAC = new UserWalletStatementDAC(); var userTransactionDAC = new UserTransactionDAC(); var wallet = userWalletDAC.GetByAccountId(accountId, cryptoId); if (wallet == null || wallet.Balance < amount) { throw new CommonException(ReasonCode.INSUFFICIENT_BALANCE, MessageResources.InsufficientBalance); } var fiatAmount = price * amount; using (var scope = new TransactionScope()) { try { var redPocket = new RedPocket { AccountId = accountId, Status = RedPocketStatus.Actived, PassCode = GeneralPassCode(), CryptoCode = crypto.Code, Amount = amount, Balance = amount, Count = count, RemainCount = count, Message = message, Timestamp = DateTime.UtcNow, ExpirationDate = DateTime.UtcNow.AddMinutes(_expried), CryptoId = cryptoId, OrderNo = IdentityHelper.OrderNo(), FiatAmount = fiatAmount <= 0 ? 0M : Math.Round(fiatAmount, 8) }; var redPocketId = redPocketDAC.Insert(redPocket); userTransactionDAC.Insert(new UserTransaction { Id = Guid.NewGuid(), AccountId = accountId, CryptoId = redPocket.CryptoId, CryptoCode = redPocket.CryptoCode, Type = UserTransactionType.PushRedPocket, DetailId = redPocketId.ToString(), Status = (byte)redPocket.Status, Timestamp = redPocket.Timestamp, Amount = redPocket.Amount, OrderNo = redPocket.OrderNo }); userWalletDAC.Decrease(wallet.Id, amount); userWalletStatementDAC.Insert(new UserWalletStatement { WalletId = wallet.Id, Balance = wallet.Balance - amount, Amount = 0 - amount, FrozenAmount = 0, FrozenBalance = wallet.FrozenBalance, Action = "Push Red Pocket", Timestamp = DateTime.UtcNow }); QueueHelper.DelaySender.Send("FiiiPay_RedPocket", redPocketId); scope.Complete(); return(redPocket); } catch (Exception ex) { _log.Error(ex); throw new SystemErrorException(); } } }