溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

使用.NET Core怎么實(shí)現(xiàn)餓了嗎拆紅包功能

發(fā)布時(shí)間:2021-05-27 16:55:32 來源:億速云 閱讀:110 作者:Leah 欄目:開發(fā)技術(shù)

這篇文章給大家介紹使用.NET Core怎么實(shí)現(xiàn)餓了嗎拆紅包功能,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

功能實(shí)現(xiàn)

本文描述的場(chǎng)景,所涉及到的金額以分為單位,目的是為了更好的處理隨機(jī)數(shù)??傮w的示意圖如下:

使用.NET Core怎么實(shí)現(xiàn)餓了嗎拆紅包功能

消費(fèi)后紅包的初始化

需求重點(diǎn),用戶分享出去的紅包總額跟消費(fèi)總額成正比,可以分拆的子紅包個(gè)數(shù)也與消費(fèi)總額成正比。

比如:

10-20元的消費(fèi)金額,可以分享的單個(gè)紅包金額為10元,可以供5個(gè)人搶20-40元的消費(fèi)金額,可以分享的單個(gè)紅包金額為20元,可以供8個(gè)人搶40-60元的消費(fèi)金額,可以分享的單個(gè)紅包金額為30元,可以供10個(gè)人搶60-100元的消費(fèi)金額,可以分享的單個(gè)紅包金額為40元,可以供10個(gè)人搶100元以上的消費(fèi)金額,可以分享的單個(gè)紅包金額為50元,可以供10個(gè)人搶

那么我們?cè)O(shè)計(jì)出來一個(gè)實(shí)體,用于表示紅包信息,以方便的配置及調(diào)整紅包規(guī)則

public class RedPacketsInfo
{
/// <summary>
/// 最大消費(fèi)金額
/// </summary>
public int MaxAmount { get; set; }
/// <summary>
 /// 最小消費(fèi)金額
  /// </summary>
  public int MinAmount { get; set; }
  /// <summary>
  /// 紅包金額
  /// </summary>
  public int TotalAmount { get; set; }
  /// <summary>
  /// 紅包可被分割的數(shù)量
  /// </summary>
  public int RedPacketQuantity { get; set; }
}

紅包初始化信息

private static List<RedPacketsInfo> GetRedPackets()
{
  return new List<RedPacketsInfo>()
  {
    new RedPacketsInfo
    {
      MinAmount = 1000,
      MaxAmount = 2000,
      RedPacketQuantity = 5,
      TotalAmount=1000
    },
    new RedPacketsInfo
    {
      MinAmount = 2000,
      MaxAmount = 3000,
      RedPacketQuantity = 5,
      TotalAmount=1000
    },
    new RedPacketsInfo
    {
      MinAmount = 4000,
      MaxAmount = 6000,
      RedPacketQuantity = 5,
      TotalAmount=1000
    },
    new RedPacketsInfo
    {
      MinAmount = 6000,
      MaxAmount = 8000,
      RedPacketQuantity = 5,
      TotalAmount=1000
    },
    new RedPacketsInfo
    {
      MinAmount = 10000,
      MaxAmount = int.MaxValue,
      RedPacketQuantity = 5,
      TotalAmount=1000
    }
  };
}

接下來我們就可以通過消費(fèi)金額獲取相應(yīng)的紅包信息了。

隨機(jī)紅包的生成時(shí)機(jī)及處理

隨機(jī)紅包的生成可以在搶之前生成也可以在搶的過程中確定,一般而言,很多時(shí)候紅包會(huì)在搶的過程中動(dòng)態(tài)的實(shí)際分配,不過在本文中,紅包在用戶分享成功后會(huì)預(yù)先生成,主要原因是為了更好地處理處理數(shù)據(jù),以使得數(shù)據(jù)能夠服從正態(tài)分布。

以下是其流程圖,其中有一段邏輯是回調(diào)功能,可能會(huì)有圈友會(huì)問,如何保證有回調(diào)以及回調(diào)是成功的,這個(gè)地方有很多種處理,比如MQ、任務(wù)調(diào)度等,此處也不做討論

使用.NET Core怎么實(shí)現(xiàn)餓了嗎拆紅包功能

那么我們需要設(shè)計(jì)一個(gè)新的實(shí)體,以表示分享出去的紅包及其生成的隨機(jī)紅包:

public class SharedRedPacket
{
  /// <summary>
  /// 分享人UserId
  /// </summary>
  public int SenderUserId { get; set; }
  /// <summary>
  /// 分享時(shí)間
  /// </summary>
  public DateTime SendTime { get; set; }
  public List<RobbedRedPacket> RobbedRedPackets { get; set; }
}
public class RobbedRedPacket
{
  /// <summary>
  /// 搶到紅包的人的UserId
  /// </summary>
  public int UserId { get; set; }
  /// <summary>
  /// 搶到的紅包金額
  /// </summary>
  public int Amount { get; set; }
  /// <summary>
  /// 搶到時(shí)間
  /// </summary>
  public DateTime RobbedTime { get; set; }
}

在實(shí)現(xiàn)過程中,根據(jù)用戶消費(fèi)金額獲取相應(yīng)紅包,然后通過隨機(jī)數(shù),生成n-1個(gè)原始的隨機(jī)數(shù)據(jù),最后一個(gè)數(shù)據(jù)用總和減去n-1個(gè)數(shù)據(jù)的和獲取到

//紅包隨機(jī)拆分
Random ran = new Random();
List<double> randoms = new List<double>(redPacketsList.Count);
for (int i = 0; i < redPacketsInfo.RedPacketQuantity - 1; i++)
{
  int max = (totalAmount - (redPacketsInfo.RedPacketQuantity - i)) * 1;
  int result = ran.Next(1, max);
  randoms.Add(result);
  totalAmount -= result;
}
randoms.Add(totalAmount);

然后通過設(shè)置好系數(shù),以處理數(shù)據(jù)達(dá)到服從正太分布的目的:

//正太分布處理
for (int i = 0; i < redPacketsInfo.RedPacketQuantity; i++)
{
  double a = Math.Sqrt(Math.Abs(2 * Math.Log(randoms[i], Math.E)));
  double b = Math.Cos(2 * Math.PI * randoms[i]);
  randoms[i] = a * b * 0.3 + 1;
}

經(jīng)過第二次處理后,得到的數(shù)據(jù)與原始數(shù)據(jù)有偏差,那么我們通過等比例方式再次處理,以確保拆分后的紅包總額等于紅包原始總額:

//生成最終的紅包數(shù)據(jù)
double d = originalTotal / randoms.Sum();
SharedRedPacket sharedRedPacket = new SharedRedPacket();
sharedRedPacket.RobbedRedPackets = new List<RobbedRedPacket>(redPacketsList.Count);
for (int i = 0; i < redPacketsInfo.RedPacketQuantity - 1; i++)
{
  sharedRedPacket.RobbedRedPackets.Add(new RobbedRedPacket
  {
    Amount = (int)Math.Round(randoms[i] * d, 0)
  });
}
sharedRedPacket.RobbedRedPackets.Add(new RobbedRedPacket
{
  Amount = originalTotal - sharedRedPacket.RobbedRedPackets.Sum(p => p.Amount)
});

測(cè)試

測(cè)試效果圖如下:

使用.NET Core怎么實(shí)現(xiàn)餓了嗎拆紅包功能

部分代碼如下,

Console.WriteLine("是否分享輸入Y分享成功,輸入N退出");
 string result = Console.ReadLine();
 if (result == "Y")
 {
   var leftRedPacket = sharedRedPacket.RobbedRedPackets.Where(p => p.UserId <= 0).ToList();
   var robbedRedPacket = leftRedPacket[new Random().Next(1, leftRedPacket.Count + 1)];
   Console.WriteLine("搶到的到紅包金額是:" + robbedRedPacket.Amount);
   Console.WriteLine("-------------------------------------------------------");
 }

關(guān)于使用.NET Core怎么實(shí)現(xiàn)餓了嗎拆紅包功能就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI