123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- package com.qs.mp.quartz.task;
- import com.alibaba.fastjson.JSONArray;
- import com.alibaba.fastjson.JSONObject;
- import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
- import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
- import com.qs.mp.admin.domain.Ticket;
- import com.qs.mp.admin.domain.TicketAwards;
- import com.qs.mp.admin.domain.TicketBox;
- import com.qs.mp.admin.service.ITicketAwardsService;
- import com.qs.mp.admin.service.ITicketBoxService;
- import com.qs.mp.admin.service.ITicketService;
- import com.qs.mp.common.annotation.Log;
- import com.qs.mp.common.core.domain.AjaxResult;
- import com.qs.mp.common.enums.TicketTypeEnum;
- import com.qs.mp.common.enums.UserTicketOrderStatusEnum;
- import com.qs.mp.common.utils.DateUtils;
- import com.qs.mp.common.utils.LogUtil;
- import com.qs.mp.common.utils.RSAUtil;
- import com.qs.mp.user.domain.UserTicketOrder;
- import com.qs.mp.user.service.IUserTicketOrderService;
- import java.math.BigDecimal;
- import java.math.RoundingMode;
- import java.util.ArrayList;
- import java.util.Comparator;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.TreeMap;
- import java.util.stream.Collectors;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Component;
- import org.springframework.util.Assert;
- /**
- * 检查票组出奖率
- * @author zhongcp
- * @Date 2022/3/17
- */
- @Component("ticketBoxTask")
- public class TicketBoxTask {
- protected final Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName());
- @Autowired
- private ITicketService ticketService;
- @Autowired
- private ITicketAwardsService ticketAwardsService;
- @Autowired
- private ITicketBoxService ticketBoxService;
- private final int PAGE_SIZE = 100;
- /**
- * 检查票组中奖分布任务
- */
- public void checkPrize(String boxId) {
- LogUtil.info(logger, "...票组奖品分布检测任务开始...");
- TicketBox ticketBox = ticketBoxService.getById(boxId);
- List<TicketAwards> ticketAwardsList = ticketAwardsService.list(new LambdaQueryWrapper<TicketAwards>().eq(TicketAwards::getBoxId, boxId));
- Map<String, TicketAwards> ticketAwardsMap = new HashMap<>();
- for (TicketAwards ticketAward : ticketAwardsList) {
- ticketAwardsMap.put(ticketAward.getName(), ticketAward);
- }
- List<Ticket> listAll = new ArrayList<Ticket>();
- // 首先查询要导出的数据总数
- LambdaQueryWrapper<Ticket> queryWrapper = new LambdaQueryWrapper<Ticket>();
- queryWrapper.eq(Ticket::getBoxId, boxId);
- int totalSize = ticketService.count(queryWrapper);
- if (totalSize == 0) {
- LogUtil.info(logger, "票组票数为0,boxId:{0}", boxId);
- }
- if(totalSize > PAGE_SIZE) {
- int totalPage = totalSize%PAGE_SIZE == 0 ? totalSize/PAGE_SIZE : totalSize/PAGE_SIZE+1;
- for (int i = 0; i < totalPage; i++) {
- LambdaQueryWrapper<Ticket> pageQueryWrapper = new LambdaQueryWrapper<Ticket>();
- pageQueryWrapper.select(Ticket::getSerialNo, Ticket::getDrawNum, Ticket::getCipherLuckyNum, Ticket::getPkgId);
- pageQueryWrapper.eq(Ticket::getBoxId, boxId);
- pageQueryWrapper.last("limit "+ (i*PAGE_SIZE) +", " + PAGE_SIZE);
- List<Ticket> list = ticketService.list(pageQueryWrapper);
- if(null != list && list.size() > 0 ) {
- listAll.addAll(list);
- }
- }
- }else {
- listAll = ticketService.list(queryWrapper);
- }
- HashMap<String, HashMap<String, Integer>> pkgAwardsMap = new HashMap<>();
- if(null != listAll && listAll.size() > 0 ) {
- listAll.sort(Comparator.comparing(Ticket::getSerialNo));
- for (Ticket ticket : listAll) {
- JSONArray jsonArray = JSONArray.parseArray(ticket.getDrawNum());
- for (int i = 0; i < jsonArray.size(); i++) {
- JSONObject jo = jsonArray.getJSONObject(i);
- String luckyNum = RSAUtil.decrypt(ticket.getCipherLuckyNum());
- // LogUtil.info(logger, "num:{0},luckyNum:{1}", new Object[]{jo.get("num"), luckyNum});
- if (jo.get("num") == Integer.valueOf(luckyNum)) {
- HashMap<String, Integer> awardsMap = pkgAwardsMap.get(ticket.getPkgId());
- if (awardsMap == null) {
- awardsMap = new HashMap<>();
- pkgAwardsMap.put(ticket.getPkgId(), awardsMap);
- }
- Integer awardsNum = awardsMap.get(jo.getString("name"));
- if (null == awardsNum) {
- awardsNum = 0;
- }
- awardsNum += 1;
- awardsMap.put(jo.getString("name"), awardsNum);
- }
- }
- }
- }
- LogUtil.info(logger, "票包奖品分布:{0}", JSONObject.toJSONString(pkgAwardsMap));
- // 奖级累计中奖数量
- Map<String, Integer> totalAwardsMap = new HashMap<>();
- for (String key : pkgAwardsMap.keySet()) {
- HashMap<String, Integer> awardsMap = pkgAwardsMap.get(key);
- int sumAwardsNum = 0;
- for (String subKey : awardsMap.keySet()) {
- sumAwardsNum += awardsMap.get(subKey);
- Integer totalAwardsNum = totalAwardsMap.get(subKey);
- if (totalAwardsNum == null) {
- totalAwardsNum = 0;
- }
- totalAwardsNum += awardsMap.get(subKey);
- totalAwardsMap.put(subKey, totalAwardsNum);
- }
- Assert.isTrue(sumAwardsNum == ticketBox.getPkgUnit(), "票包的中奖数和票包张数不匹配。总中奖数:" + sumAwardsNum + ",票包张数:" + ticketBox.getPkgUnit());
- // 检查票包每个奖项的中奖率是否和整体票组中奖率一致
- for (String subKey : awardsMap.keySet()) {
- BigDecimal hitRate = new BigDecimal(awardsMap.get(subKey) * 100).divide(new BigDecimal(sumAwardsNum), 4, RoundingMode.DOWN);
- // 误差率
- BigDecimal misRate = ticketAwardsMap.get(subKey).getHitRate().subtract(hitRate).divide(hitRate, 2, RoundingMode.HALF_UP);
- if (misRate.abs().compareTo(new BigDecimal(0.01)) > 0) {
- LogUtil.error(logger, "中奖率与整个票组的中奖率误差大于0.01,pkgId:{0},票包奖项:{1},数量:{2},票包中奖率:{3},票组中奖率:{4}",
- new Object[]{key, subKey, awardsMap.get(subKey), hitRate, ticketAwardsMap.get(subKey).getHitRate()});
- }
- }
- Map<String, Integer> treeMap = new TreeMap<>((str1, str2) -> str1.compareTo(str2));
- treeMap.putAll(awardsMap);
- LogUtil.info(logger, "票包{0}奖级分布情况:{1}", new Object[]{key, treeMap});
- }
- // 排序
- Map<String, Integer> resultMap = new TreeMap<>((str1, str2) -> str1.compareTo(str2));
- resultMap.putAll(totalAwardsMap);
- for (String key : resultMap.keySet()) {
- int realNum = resultMap.get(key);
- LogUtil.info(logger, "奖级{0}数量为{1}", new Object[]{key, realNum});
- if(realNum != ticketAwardsMap.get(key).getQuantity()) {
- LogUtil.error(logger, "实际中奖数(" + realNum + ")和票组中奖数(" + ticketAwardsMap.get(key).getQuantity() + ")不等" );
- }
- }
- LogUtil.info(logger, "...票组奖品分布检测任务结束...");
- }
- }
|