zoukankan      html  css  js  c++  java
  • 抽奖功能实现

    1. 需求分析

    抽奖可以获得积分,礼券,小样,正品等

    若库存为0,则用户不能在抽中此奖

    每个奖项的中奖概率

    每天抽奖次数的限制

    每次抽奖是否需要消耗积分的限制

    有没有批量抽奖功能

    2.表结构设计

    会员表,积分表,是以前就有的,本次新增抽奖功能,需要新增一下的表:

    首先要有库存表,暂且定义为BPRIZE

    其次要记录用户抽中的奖项,暂且定义为HPRIZE

          

    3. 后台代码实现

    Controller 

    @RestController
    @RequestMapping(value = "draw")
    public class DrawController extends BaseController {
    
        @Autowired
        DrawService drawService;
    
        @Autowired
        CouponService couponService;
    
        @Autowired
        SocialProviderService socialProviderService;
    
        @ApiOperation(value = "抽奖历史记录", notes = "抽奖历史记录")
        @GetMapping(value = "history", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
        private ResponseBean prizeHistory(@RequestParam("userId") String userId,
                                          @RequestParam("social") String social, @RequestParam("page") int page, @RequestParam("size") int size) {
    
            ResponseBean responseBean = new ResponseBean();
            List<HPrizerecord> hPrizerecords = drawService.getPrizeHistory(userId, social, page, size);
            responseBean.setData(hPrizerecords);
            return responseBean;
        }
    
        @ApiOperation(value = "抽奖榜单", notes = "抽奖榜单")
        @GetMapping(value = "billboard", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
        private ResponseBean billboard(@RequestParam("topN") int topN, @RequestParam("levelList") String levelList, @RequestParam("social") String social) {
            ResponseBean responseBean = new ResponseBean();
    
            // 查找SopId
            SSocialProvider socialProvider = socialProviderService.findSocialProvider(social);
    
            // 格式化等级 (str-> list(int))
            List<Integer> level = Arrays.stream(levelList.split(",")).map(a -> {
                return Integer.parseInt(a);
            }).collect(Collectors.toList());
    
            // 查询
            JSONArray billboard = drawService.getBillboard(topN, level, socialProvider.getSopId());
            responseBean.setData(billboard);
            return responseBean;
        }
    
    
        @ApiOperation(value = "抽奖", notes = "抽奖")
        @PostMapping(produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
        private ResponseBean<BPrize> draw(@RequestParam("userId") String userId,
                                          @RequestParam("social") String social) throws Exception {
    
            ResponseBean responseBean = new ResponseBean();
            BPrize bPrize = drawService.draw(userId, social, super.getSid());
            responseBean.setData(bPrize);
    
            return responseBean;
        }
    }
    

     

    具体实现

    @Service
    public class DrawServiceImpl implements DrawService {
    
    
        @Autowired
        HPrizerecordMapper hPrizerecordMapper;
    
        @Autowired
        SaveDrawRecord saveDrawRecord;
    
    
        @Autowired
        SocialService socialService;
    
        @Autowired
        SocialProviderService socialProviderService;
    
        @Autowired
        BCustomerService bCustomerService;
    
        @Autowired
        BPrizeService bPrizeService;
    
        @Autowired
        PEService peService;
    
    
        @Autowired
        CustomerService customerService;
    
        @Autowired
        SendMemberInfoToEcrmMqTask sendMemberInfoToEcrmMqTask;
    
        @Value("${sys.name}")
        private String sysName;
    
        int freeCount=2;
    
        int dalyMaxDrawCount=5;
    
    
        @Value("${cc.draw.pe.code}")
        String luckyDrawPeEventCode;
    
        @Value("${cc.draw.max.probability}")
        int maxProbability;
        static  Random rand = new Random();
    
        @Value("#{'${cc.draw.actual.prizeLevel}'.split(',')}")
        private  List<Integer>  actualPrizeLevel;
    
    
        @Override
        public List<HPrizerecord> getPrizeHistory(String userId, String social, int page, int size) {
            int cstId = socialService.findCstIdBySocialAndSocialId(userId, social);
    
            if (size == 0 ){
                size = 10;
            }
            if (page<=0){
                page = 1;
            }
    
            return  hPrizerecordMapper.getPrizeHistory(cstId, page, size);
        }
    
    
        @Override
        public BPrize draw(String userId, String social, String sid) throws Exception {
            int cstId = socialService.findCstIdBySocialAndSocialId(userId, social);
    
    
            // 今天一共抽了几次奖
            int todayCount = getDrawCountToday(cstId);
    
            // 如果超过最大次数,直接返回, 不进行抽奖
            if (todayCount >= dalyMaxDrawCount){
                throw new DrawCountLimitException();
            }
    
            // 超过规定的一个次数就要开始扣积分
            if (todayCount >= freeCount) {
                // 扣减积分, 如果扣减失败, 会抛出异常,这边不用管
                peService.sendEvent(cstId, sysName, luckyDrawPeEventCode);
                sendMemberInfoToEcrmMqTask.syncMemberInfoToECRM(cstId, luckyDrawPeEventCode);
            }
    
            boolean drawEnd = false;
            BPrize bPrize = null;
    
            while (!drawEnd) {
                int x = rand.nextInt(maxProbability);
                bPrize = bPrizeService.getPrize(x);
    
                // 如果抽中的是实物奖品
                if (bPrize!=null && actualPrizeLevel.indexOf(bPrize.getPrizeLevel())>=0){
                    // 判断当日是否有中过实物奖品
                    boolean isWinningTheActualPrizeFlag =  isWinningTheActualPrize(cstId);
                    // 如果isWinningTheActualPrizeFlag 为false , 抽奖成功
                    if (!isWinningTheActualPrizeFlag) {
                        drawEnd = true;
                    }
                }
    
                if (bPrize != null) {
                    drawEnd = true;
                }
            }
    
            // 如果礼品里面配置了PEcode 调用PE积分调整
            String peCode = bPrize.getPointCode();
            if (StringUtils.isNotBlank(peCode)) {
                peService.sendEvent(cstId, sysName, peCode);
                sendMemberInfoToEcrmMqTask.syncMemberInfoToECRM(cstId, luckyDrawPeEventCode);
            }
    
            // 记录到抽奖历史
            saveDrawRecord.savePrizerecordHistory(cstId, bPrize, sid);
            return bPrize;
        }
    
        private boolean isWinningTheActualPrize(int cstId) {
    
            // 查询今天是否中过实物奖项
            List<HPrizerecord> hPrizerecords = hPrizerecordMapper.getWinningTheActualPrizeToday(cstId,actualPrizeLevel);
            if (null != hPrizerecords ||!hPrizerecords.isEmpty() || hPrizerecords.size()>0) {
                return true;
            }
    
            return false;
        }
    
        @Override
        public JSONArray getBillboard(int topN, List<Integer> levelList, Integer sopId) {
    
    
            List<Map> records = hPrizerecordMapper.selectBillboard(topN, levelList, sopId);
    
            return (JSONArray) JSONArray.toJSON(records);
        }
    
        private int getDrawCountToday(int cstId) {
            return hPrizerecordMapper.getDrawCountToday(cstId);
        }
    
    
    }
    

      

     

    4. 前端UI实现

  • 相关阅读:
    Net 下安装、调试的常见问题与错误
    解决在网页框架中,页面的样式表失效的方法
    C#.NET Show Text Info
    C#.NET 部署应用程序之ClickOnce
    VS2005 数据库间转移数据(SSIS)
    C#.NET ClickOnce
    SQL2005 还原备份数据
    C#.NET TreeView.cs
    C#.NET SetComboBox Class
    C#.NET GetLocalMachineInfo.cs
  • 原文地址:https://www.cnblogs.com/qianjinyan/p/11384470.html
Copyright © 2011-2022 走看看