类似于美团红包的功能

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;
    }
}

猜你喜欢

转载自blog.csdn.net/u014229652/article/details/81748749