1、对于未参加过活动,且已经成功接过单的用户(老用户),在首页弹窗显示红包活动
2、进入活动后先自己拆红包
3、会在3-10元之间随机开出一个金额,显示在红包金额中
4、查看活动规则做弹窗显示
5、可对红包金额进行提取,将红包里的钱提到用户的平台现金账户中。
6、页面下方显示拆红包记录和红包提取记录,数据默认10条,下拉加载一次。
暂无记录显示方式
7、点击分享效果
8、好友收到分享访问后的落地页效果,点击“开”提示绑定手机注册。
注册成功后返回开红包成功的界面
9、用户点“开红包”进入我的红包页面,效果同步骤2及以后
10、用户点宝贝,到新人专区页。
PS:所有的用户名默认都显示昵称,无昵称的才显示手机号加密码
活动规则:
1、用户第一次自己开红包金额3-10元之间浮动,3-5元50%,5.01-6.00元40%,6.01-8元8%,8-10元2%
2、好友帮忙拆红包,金额在0.5-5元之间浮动,0.5-1元50%,1.01-2.00元40%,2.01-3元8%,3-5元2%
3、红包金额累计,当用户提取一次,消耗累计金额一次。
4、红包必须先提取到用户平台账户中,提取次数不限,再由平台账户申请提现。
5、平台账户提现需要另限制,必须成功完成过一单的用户才可以提现。
6、后台需要对每一次提取进行记账,分类为:一起拆红包_拿手红包提取。
7、用户账单中要显示出提取记录
8、开红包仅对未注册过的手机号有效,老用户无法开红包。老用户点击链接后进入自己的活动界面,做一个浮动提示:您已注册过白拿拿,无法再帮好友拆红包。
、
系统设计:
1、
@PostMapping("/openRedEnvelope")
@ApiOperation("拆红包动作")
public ControllerResult openRedEnvelope(@RequestParam @ApiParam("红包金额流入的用户ID") Long redUserId,
@RequestParam @ApiParam("进行拆红包动作的用户ID") Long openUserId) {
try {
ControllerResult controllerResult = distributedLock.lock(LockKeyUtils.getTradLockKeyUid(redUserId), () -> {
ControllerResult cs = judgeIfCanOpenRedEnvelope(redUserId, openUserId);
if (!cs.getStatus()) {
return cs;
}
return distributedLock.lock(LockKeyUtils.getTradLockKeyUid(openUserId), () -> {
return redEnvelopeService.openRedEnvelope(redUserId, openUserId);
});
});
return controllerResult;
} catch (Exception e) {
e.printStackTrace();
return ControllerResult.build(false, "error", e.getMessage());
}
}
2、红包怎么算?
@Override
public long getEnvelopeMe(Long redUserId) {
long reward = 0L;
List<OpenRedEnvelope> openRedEnvelopes = findByRedUserIdAndOpenUserId(redUserId, redUserId);
if (openRedEnvelopes != null && openRedEnvelopes.size() > 0) {
//不是第一次
reward = LotteryUtil.getRandomInt(5, 10);
} else {
//第一次
reward = LotteryUtil.getRandomInt(0, 100);
}
// return lotteryUtilMe.getReward(rMe);
return reward;
}
@Override
public long getEnvelopeFriend() {
return lotteryUtilFriend.getReward(rFri);
}
概率的实现:
package com.zhibi.xiuba.utils.envelope;
import com.zhibi.xiuba.domain.envelope.Envelope;
import com.zhibi.xiuba.domain.envelope.EnvelopeProbability;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* Created by QinHe on 2018/3/28.
*/
public class LotteryUtil {
private List<EnvelopeProbability> lotteryList; //概率连续集合
private double maxElement = 0d; //这里只需要最大值,最小值默认为0.0
/**
* 构造抽奖集合
*/
public LotteryUtil(List<Envelope> list) {
this.lotteryList = new ArrayList<>();
if (list != null && list.size() > 0) {
double minElement = 0d;
for (Envelope envelope : list) {
minElement = maxElement;
maxElement = maxElement + envelope.getRate();
EnvelopeProbability envelopeProbability = new EnvelopeProbability(envelope.getMinFen(), envelope.getMaxFen(), minElement, maxElement, envelope.getRewardType());
lotteryList.add(envelopeProbability);
}
} else {
throw new IllegalArgumentException("抽奖集合不能为空!");
}
}
/**
* 进行抽奖操作
* 返回:奖品的概率list集合中的下标
*/
public long getReward(Random r) {
double d = r.nextDouble() * maxElement; //生成0-1间的随机数
while (d == 0d) {
d = r.nextDouble() * maxElement; //防止生成0.0
}
for (EnvelopeProbability envelopeProbability : lotteryList) {
if (envelopeProbability.isContainKey(d)) {
return getRandomInt(envelopeProbability.getMinFen(), envelopeProbability.getMaxFen());
}
}
throw new IllegalArgumentException("概率集合设置不合理!");
}
public double getMaxElement() {
return maxElement;
}
/**
* 生成一个 begin 到 end 的整数
*/
public static int getRandomInt(int begin, int end) {
if (end < begin) {
return 0;
} else if (end == begin) {
return begin;
}
Random random = new Random();
return random.nextInt(end - begin + 1) + begin;
}
}