RuoYi/sino-act-web/src/main/java/com/ruoyi/service/DrawService.java

267 lines
13 KiB
Java

package com.ruoyi.service;
import com.ruoyi.cache.Cache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.dto.DrawActivityRequest;
import com.ruoyi.dto.DrawActivityResult;
import com.ruoyi.dto.GtPrizeConfigTemp;
import com.ruoyi.thread.DrawActivityThread;
import com.ruoyi.thread.ThreadPool;
import com.ruoyi.web.vo.Const;
import com.ruoyi.web.vo.draw.DrawResult;
import com.sinosoft.activity.domain.DrawConfig;
import com.sinosoft.activity.domain.DrawInfo;
import com.sinosoft.activity.domain.DrawPrizeInfo;
import com.sinosoft.activity.domain.DrawRule;
import com.sinosoft.activity.service.IDrawConfigService;
import com.sinosoft.activity.service.IDrawInfoService;
import com.sinosoft.activity.service.IDrawPrizeInfoService;
import com.sinosoft.activity.service.IDrawRuleService;
import com.sinosoft.activity.vo.PrizeInfo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class DrawService {
private static final Logger logger = LoggerFactory.getLogger(DrawService.class);
@Autowired
private IDrawRuleService drawRuleService;
@Autowired
private IDrawConfigService drawConfigService;
@Autowired
private IDrawPrizeInfoService drawPrizeInfoService;
@Autowired
private IDrawInfoService drawInfoService;
/**
* 抽奖实现主方法
*/
public DrawResult drawActivity(DrawActivityRequest request) {
long start = System.currentTimeMillis();
long end = 0;
long proct = 0;
String exception = "";
DrawResult drawResult = new DrawResult();
long point = System.currentTimeMillis();
logger.info("抽奖开始时间:" + request.getSerialNo() + ":" + point);
try {
// 校验体信息
String drawCode = request.getDrawCode();
if(StringUtils.isBlank(drawCode)){
return processResp(request, DrawActivityResult.EXCEPTION_000001,
DrawActivityResult.getMsg(DrawActivityResult.EXCEPTION_000001, "drawCode参数为空"));
}
long point1 = System.currentTimeMillis();
logger.info("抽奖检查点1:" + request.getSerialNo() + ":" + point1 + "与前一个检查点时间差" + (point1 - point));
// 查询活动信息
DrawInfo queryInfo = new DrawInfo();
queryInfo.setDRAWCODE(drawCode);
queryInfo.setSTATUS(Const.DRAW_STATUS_EFFECTIVE);
List<DrawInfo> drawInfos = drawInfoService.selectDrawInfoList(queryInfo);
if (drawInfos == null || drawInfos.size() == 0) {
drawResult.setRespCode("-3");
drawResult.setRespMsg("活动未开启");
return processResp(request, DrawActivityResult.EXCEPTION_000011,
DrawActivityResult.getMsg(DrawActivityResult.EXCEPTION_000011));
}
DrawInfo drawInfo = drawInfos.get(0);
Date starttime = drawInfo.getSTARTTIME();
Date endtime = drawInfo.getENDTIME();
Date currDate = new Date();
if (currDate.before(starttime) || currDate.after(endtime)) {
return processResp(request, DrawActivityResult.EXCEPTION_000011,
DrawActivityResult.getMsg(DrawActivityResult.EXCEPTION_000011));
}
long point2 = System.currentTimeMillis();
logger.info("抽奖检查点2:" + request.getSerialNo() + ":" + point2 + "与前一个检查点时间差" + (point2 - point1));
String currentDateStr = DateUtils.dateTime();
DrawInfo gtDrawInfo = null;
if ("1".equals(gtDrawInfo.getUPDATEFLAG()) || Cache.get("_" + drawCode + "_currentDateStr_") == null
|| Cache.get("_" + drawCode + "_" + currentDateStr + "_rule_") == null
|| Cache.get("_" + drawCode + "_" + currentDateStr + "_config_") == null
|| Cache.get("_" + drawCode + "_blank_") == null || Cache.get("_" + drawCode + "_blankConfig_") == null
|| Cache.get("_" + drawCode + "_" + currentDateStr + "_gtDrawConfigList_") == null
|| Cache.get("_" + drawCode + "_" + currentDateStr + "_baseNumber_") == null) {
// 刷新缓存
loadDrawRule(drawCode);
gtDrawInfo.setUPDATEFLAG("0");
drawInfoService.updateDrawInfo(gtDrawInfo);
}
long point3 = System.currentTimeMillis();
logger.info("抽奖检查点3:" + request.getSerialNo() + ":" + point3 + "与前一个检查点时间差" + (point3 - point2));
DrawRule gtDrawRule = (DrawRule) Cache.get("_" + drawCode + "_" + currentDateStr + "_rule_");
Future<DrawResult> resFuture = ThreadPool.drawActivityExecutorService.submit(new DrawActivityThread(request, gtDrawInfo, gtDrawRule, drawResult));
drawResult = resFuture.get(15 * 1000, TimeUnit.SECONDS);
end = System.currentTimeMillis();
logger.info("抽奖接口返回:" + request.getSerialNo() + "&返回时间" + end + "总时间" + (end - point));
return drawResult;
} catch (Exception e) {
drawResult = processResp(request, DrawActivityResult.EXCEPTION, DrawActivityResult.getMsg(DrawActivityResult.EXCEPTION));
logger.error("抽奖接口异常,异常原因:", e);
return drawResult;
}
}
private DrawResult processResp(DrawActivityRequest request, String resultCode, String resultInfo) {
DrawResult response = new DrawResult();
response.setRespCode(resultCode);
response.setRespMsg(resultInfo);
return response;
}
/**
* 刷新抽奖需要的缓存信息
*
* @param drawCode
* @throws Exception
*/
private void loadDrawRule(String drawCode) throws Exception {
logger.info("加载缓存:" + drawCode);
String yesterdayDateStr = DateUtils.parseDateToStr("yyyyMMdd", DateUtils.addDays(DateUtils.getNowDate(), -1));
// String yesterdayTimeStr = yesterdayDateStr + "0000000";
// Date tomorrowTime = DateUtil.toFormatDate(yesterdayTimeStr,
// "yyyyMMddHHmmss");
String currentDateStr = DateUtils.dateTime();
// long l1 = tomorrowTime.getTime();
// long l2 = new Date().getTime();
// long timeOut = l1 - l2;
long timeOut = 1000 * 60 * 60;
// 抽奖缓存日期加入缓存
Cache.remove("_" + drawCode + "_currentDateStr_");
Cache.add("_" + drawCode + "_currentDateStr_", currentDateStr);
// 抽奖规则加入缓存
DrawRule drawRuleParams = new DrawRule();
drawRuleParams.setDRAWCODE(drawCode);
DrawRule drawRule = drawRuleService.selectDrawRuleList(drawRuleParams).get(0);
cacheAdd("_" + drawCode + "_" + currentDateStr + "_rule_", drawRule, "_" + drawCode + "_" + yesterdayDateStr + "_rule_", timeOut);
// 奖项配置加入缓存
// gtDrawConfigQueryRule.addAscOrder("prizeLevel");
DrawConfig drawConfigParams = new DrawConfig();
drawConfigParams.setDRAWCODE(drawCode);
drawConfigParams.setSTATUS(Const.DRAW_CONFIG_STATUS_EFFECTIVE);
List<DrawConfig> drawConfigs = drawConfigService.selectDrawConfigList(drawConfigParams);
cacheAdd("_" + drawCode + "_" + currentDateStr + "_config_", drawConfigs, "_" + drawCode + "_" + yesterdayDateStr + "_config_", timeOut);
// 空奖奖项配置
DrawConfig drawConfigBlank = null;
// 非空奖项配置
List<DrawConfig> gtDrawConfigList = new ArrayList<>();
for (DrawConfig drawConfig : drawConfigs) {
String prizelevel = drawConfig.getPRIZELEVEL();
if (Const.PRIZE_LEVEL_BLANK.equals(prizelevel)) {
drawConfigBlank = drawConfig;
} else {
gtDrawConfigList.add(drawConfig);
}
}
if (drawConfigBlank == null) {
throw new Exception("空奖品配置错误");
}
// 非空奖奖项配置加入缓存
cacheAdd("_" + drawCode + "_" + currentDateStr + "_gtDrawConfigList_", gtDrawConfigList, "_" + drawCode + "_" + yesterdayDateStr + "_gtDrawConfigList_", timeOut);
// 空奖奖项配置加入缓存
Cache.remove("_" + drawCode + "_blankConfig_");
Cache.add("_" + drawCode + "_blankConfig_", drawConfigBlank);
//空奖奖品加入缓存
String prizeCodeBlank = drawConfigBlank.getPRIZECODE();
PrizeInfo prizeInfoParams = new PrizeInfo();
prizeInfoParams.setDRAWCODE(drawCode);
prizeInfoParams.setSTATUS(Const.STATUS_VALID);
List<DrawPrizeInfo> drawPrizeInfos = drawPrizeInfoService.selectDrawPrizeInfoByDrawCode(prizeInfoParams);
Map<String, DrawPrizeInfo> prizeMap = new HashMap<>();
for (DrawPrizeInfo prizeInfo : drawPrizeInfos) {
String prizeCode = prizeInfo.getPRIZECODE();
prizeMap.put(prizeCode, prizeInfo);
}
DrawPrizeInfo blankPrize = prizeMap.get(prizeCodeBlank);
Cache.remove("_" + drawCode + "_blank_");
Cache.add("_" + drawCode + "_blank_", blankPrize);
// 计算总权重
BigDecimal totalProbability = BigDecimal.ZERO;
// 最小概率
BigDecimal minProbability = BigDecimal.ZERO;
if (gtDrawConfigList != null && gtDrawConfigList.size() > 0) {
for (int i = 0; i < gtDrawConfigList.size(); i++) {
DrawConfig gtDrawConfig = gtDrawConfigList.get(i);
String prizeWigth = new BigDecimal(gtDrawConfig.getPROBABILITY()).divide(new BigDecimal(100)).toString();
totalProbability = totalProbability.add(new BigDecimal(prizeWigth));
String n = prizeWigth;
if (i == 0) {
minProbability = new BigDecimal(n);
} else {
if (new BigDecimal(n).compareTo(minProbability) == -1) {
minProbability = new BigDecimal(n);
}
logger.info("最小权重:" + n + "最小概率" + minProbability);
}
}
}
// 计算基数
BigDecimal bd = new BigDecimal(String.valueOf(minProbability));
logger.info("权重长度 = " + bd.scale());
BigDecimal baseNumer = new BigDecimal(Math.pow(10, bd.scale())).add(new BigDecimal(gtDrawConfigList.size()));
cacheAdd("_" + drawCode + "_" + currentDateStr + "_baseNumber_", baseNumer, "_" + drawCode + "_" + yesterdayDateStr + "_baseNumber_", timeOut);
// 计算起始区间
long tmp = 0;
if (gtDrawConfigList != null && gtDrawConfigList.size() > 0) {
for (int i = 0; i < gtDrawConfigList.size(); i++) {
DrawConfig gtDrawConfig = gtDrawConfigList.get(i);
String probability = gtDrawConfig.getPROBABILITY();
GtPrizeConfigTemp gtPrizeConfigTemp = new GtPrizeConfigTemp();
gtPrizeConfigTemp.setBaseNumer(baseNumer.longValue());
gtPrizeConfigTemp.setConfig(gtDrawConfig);
gtPrizeConfigTemp.setPrizeInfo(prizeMap.get(gtDrawConfig.getPRIZECODE()));
// 区间1从0开始
if (i == 0) {
// 区间数从1开始
long start = new BigDecimal(1).longValue();
long end = new BigDecimal(Math.floor(baseNumer.multiply(new BigDecimal(probability).divide(new BigDecimal(100))).doubleValue())).longValue();
gtPrizeConfigTemp.setStartNumer(start);
gtPrizeConfigTemp.setEndNumber(end);
gtPrizeConfigTemp.setWeightLength(end);
tmp = end;
} else {
long start = new BigDecimal(tmp).add(new BigDecimal(1)).longValue();
long end = new BigDecimal(start).add(new BigDecimal(new BigDecimal(Math.floor(baseNumer.multiply(new BigDecimal(probability).divide(new BigDecimal(100))).doubleValue())).longValue())).longValue();
gtPrizeConfigTemp.setStartNumer(start);
gtPrizeConfigTemp.setEndNumber(end);
gtPrizeConfigTemp.setWeightLength(baseNumer.multiply(new BigDecimal(probability).divide(new BigDecimal(100))).longValue());
tmp = end;
}
// 奖项开始结束区间加入缓存
cacheAdd("_cache_" + drawCode + "_" + currentDateStr + "_" + gtDrawConfig.getPRIZELEVEL() + "_", gtPrizeConfigTemp, "_cache_" + drawCode + "_" + yesterdayDateStr + "_" + gtDrawConfig.getPRIZELEVEL() + "_", timeOut);
}
}
}
/**
* HashTable缓存元素
*
* @param name
* @param value
* @param yesterdayName
* @param timeOut
*/
private void cacheAdd(String name, Object value, String yesterdayName, long timeOut) {
logger.info("缓存加入键:" + name);
if (Cache.get(name) == null) {
Cache.add(name, value, timeOut);
} else {
Cache.remove(name);
Cache.add(name, value, timeOut);
if (Cache.get(yesterdayName) != null) {
Cache.remove(yesterdayName);
}
}
}
}