最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
当前位置: 首页 - 科技 - 知识百科 - 正文

使用.NET Core实现饿了吗拆红包功能

来源:懂视网 责编:小采 时间:2020-11-27 14:43:06
文档

使用.NET Core实现饿了吗拆红包功能

使用.NET Core实现饿了吗拆红包功能:需求说明 以前很讨厌点外卖的我,最近中午经常点外卖,因为确实很方便,提前点好餐,算准时间,就可以在下班的时候吃上饭,然后省下的那些时间就可以在中午的时候多休息一下了。 点餐结束后,会有一个好友分享红包功能,虽说这个红包不能提现,但却可以抵扣点
推荐度:
导读使用.NET Core实现饿了吗拆红包功能:需求说明 以前很讨厌点外卖的我,最近中午经常点外卖,因为确实很方便,提前点好餐,算准时间,就可以在下班的时候吃上饭,然后省下的那些时间就可以在中午的时候多休息一下了。 点餐结束后,会有一个好友分享红包功能,虽说这个红包不能提现,但却可以抵扣点

需求说明

以前很讨厌点外卖的我,最近中午经常点外卖,因为确实很方便,提前点好餐,算准时间,就可以在下班的时候吃上饭,然后省下的那些时间就可以在中午的时候多休息一下了。

点餐结束后,会有一个好友分享红包功能,虽说这个红包不能提现,但却可以抵扣点餐费用,对于经常点餐的人来说,直接用于抵扣现金确实是很大的诱惑,在点餐之后所获得的那个红包,必须要分享出去才能拆。

那么如果自己也想实现以下抢红包功能,需要说明的是,本文所描述的红包功能更多的关注与随机红包的生成,至于高并发、数据一致性等问题,本文暂未涉及,以下是本文所讨论的两个技术点:

不同的消费金额获取的红包总额不同,消费金额越大,红包总额就越大,红包总数也就越多;假设有一天,有一种需求是,需要保证参与抢红包的人获得的红包金额在平均数附近波动,也就是尽量的服从正态分布;

功能实现

本文描述的场景,所涉及到的金额以分为单位,目的是为了更好的处理随机数。总体的示意图如下:

消费后红包的初始化

需求重点,用户分享出去的红包总额跟消费总额成正比,可以分拆的子红包个数也与消费总额成正比。

比如:

10-20元的消费金额,可以分享的单个红包金额为10元,可以供5个人抢20-40元的消费金额,可以分享的单个红包金额为20元,可以供8个人抢40-60元的消费金额,可以分享的单个红包金额为30元,可以供10个人抢60-100元的消费金额,可以分享的单个红包金额为40元,可以供10个人抢100元以上的消费金额,可以分享的单个红包金额为50元,可以供10个人抢

那么我们设计出来一个实体,用于表示红包信息,以方便的配置及调整红包规则

public class RedPacketsInfo
{
/// <summary>
/// 最大消费金额
/// </summary>
public int MaxAmount { get; set; }
/// <summary>
 /// 最小消费金额
 /// </summary>
 public int MinAmount { get; set; }
 /// <summary>
 /// 红包金额
 /// </summary>
 public int TotalAmount { get; set; }
 /// <summary>
 /// 红包可被分割的数量
 /// </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
 }
 };
}

接下来我们就可以通过消费金额获取相应的红包信息了。

随机红包的生成时机及处理

随机红包的生成可以在抢之前生成也可以在抢的过程中确定,一般而言,很多时候红包会在抢的过程中动态的实际分配,不过在本文中,红包在用户分享成功后会预先生成,主要原因是为了更好地处理处理数据,以使得数据能够服从正态分布。

以下是其流程图,其中有一段逻辑是回调功能,可能会有圈友会问,如何保证有回调以及回调是成功的,这个地方有很多种处理,比如MQ、任务调度等,此处也不做讨论

那么我们需要设计一个新的实体,以表示分享出去的红包及其生成的随机红包:

public class SharedRedPacket
{
 /// <summary>
 /// 分享人UserId
 /// </summary>
 public int SenderUserId { get; set; }
 /// <summary>
 /// 分享时间
 /// </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>
 /// 抢到时间
 /// </summary>
 public DateTime RobbedTime { get; set; }
}

在实现过程中,根据用户消费金额获取相应红包,然后通过随机数,生成n-1个原始的随机数据,最后一个数据用总和减去n-1个数据的和获取到

//红包随机拆分
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);

然后通过设置好系数,以处理数据达到服从正太分布的目的:

//正太分布处理
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;
}

经过第二次处理后,得到的数据与原始数据有偏差,那么我们通过等比例方式再次处理,以确保拆分后的红包总额等于红包原始总额:

//生成最终的红包数据
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)
});

测试

测试效果图如下:

部分代码如下,

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("-------------------------------------------------------");
 }

总结

以上所述是小编给大家介绍的使用.NET Core实现饿了吗拆红包功能,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文档

使用.NET Core实现饿了吗拆红包功能

使用.NET Core实现饿了吗拆红包功能:需求说明 以前很讨厌点外卖的我,最近中午经常点外卖,因为确实很方便,提前点好餐,算准时间,就可以在下班的时候吃上饭,然后省下的那些时间就可以在中午的时候多休息一下了。 点餐结束后,会有一个好友分享红包功能,虽说这个红包不能提现,但却可以抵扣点
推荐度:
标签: 红包 使用 饿了么
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top