v1.0 : 深海活动

This commit is contained in:
fbc
2022-10-11 18:31:12 +08:00
parent 97768c0b8b
commit 61fb414535
15 changed files with 605 additions and 197 deletions

View File

@@ -12,11 +12,14 @@ package com.accompany.scheduler.task.activity;
import com.accompany.business.config.LuckySeaActConfig;
import com.accompany.business.model.activity.LuckySeaItem;
import com.accompany.business.service.LuckySeaPreWarningService;
import com.accompany.business.service.activities.ActivitiesLuckySeaService;
import com.accompany.business.vo.activities.LuckySeaActInfoVo;
import com.accompany.common.constant.Constant;
import com.accompany.common.redis.RedisKey;
import com.accompany.common.utils.StringUtils;
import com.accompany.core.service.SysConfService;
import com.accompany.core.util.StringUtils;
import com.accompany.core.service.common.JedisLockService;
import com.accompany.scheduler.base.BaseTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -44,6 +47,10 @@ public class LuckySeaActTask extends BaseTask {
private ActivitiesLuckySeaService activitiesLuckySeaService;
@Autowired
private SysConfService sysConfService;
@Autowired
private JedisLockService jedisLockService;
@Autowired
private LuckySeaPreWarningService luckySeaPreWarningService;
@PostConstruct
public void handleLuckySeaAct() {
@@ -59,22 +66,28 @@ public class LuckySeaActTask extends BaseTask {
public void runTask() {
while (true) {
// 活动开关是否开着
Boolean actSwitch = Optional.ofNullable(
Boolean actSwitch = Optional.of(
Boolean.parseBoolean(sysConfService.getSysConfValueById(Constant.SysConfId.LUCKY_SEA_SWITCH))).orElse(false);
log.info("深海奇缘活动, 开关状态: {}", actSwitch);
log.info("春日游园活动, 开关状态: {}", actSwitch);
if (actSwitch) {
String modelType = sysConfService.getDefaultSysConfValueById(Constant.SysConfId.LUCKY_SEA_MODEL, Constant.luckySeaItemType.NORMAL.toString());
log.info("深海奇缘活动, 当前模式: {}", modelType);
String roundId = null;
Date nextRoundStartTime = null;
Long stock = activitiesLuckySeaService.getStock();
// 获取游戏的配置
List<LuckySeaItem> itemList = activitiesLuckySeaService.listLuckySeaItem();
LuckySeaActConfig timeConfig = activitiesLuckySeaService.getLuckySeaTimeConfig();
int totalTime = timeConfig.getWaitingDrawStageTime() + timeConfig.getChooseStageTime() + timeConfig.getDrawOverStageTime();
// 加锁,确保创建与开奖是单线程执行
String lockVal = jedisLockService.lock(RedisKey.lucky_sea_run_task.getKey(), 10 * 1000, totalTime * 1000);
if (StringUtils.isBlank(lockVal)) {
log.info("春日游园活动, 获取锁失败");
break;
}
long drawMills = 0L;
try {
boolean needCreateNewAct = true;
boolean needWaitUserDraw = true;
LuckySeaActConfig timeConfig = activitiesLuckySeaService.getLuckySeaTimeConfig();
Integer waitUserDrawTime = timeConfig.getChooseStageTime();
// 获取游戏的配置
List<LuckySeaItem> itemList = activitiesLuckySeaService.listLuckySeaItem(Integer.valueOf(modelType));
// 处理异常活动
LuckySeaActInfoVo lastLuckySeaActInfo = activitiesLuckySeaService.getNewestLuckySeaActInfo(null);
if (null != lastLuckySeaActInfo && StringUtils.isNotBlank(lastLuckySeaActInfo.getRoundId())) {
@@ -82,19 +95,19 @@ public class LuckySeaActTask extends BaseTask {
needCreateNewAct = false;
roundId = lastLuckySeaActInfo.getRoundId();
Long intervalSecond = (System.currentTimeMillis() - lastLuckySeaActInfo.getStartTime().getTime()) / 1000;
log.info("深海奇缘活动, 上一轮投注时间发生异常的活动到现在的间隔时间{}秒, roundId:{}", intervalSecond, roundId);
log.info("春日游园活动, 上一轮投注时间发生异常的活动到现在的间隔时间{}秒, roundId:{}", intervalSecond, roundId);
if (intervalSecond <= timeConfig.getChooseStageTime()) {
waitUserDrawTime = timeConfig.getChooseStageTime() - intervalSecond.intValue();
log.info("深海奇缘活动, 上一轮投注时间发生异常的活动留给用户的下注时间{}秒", waitUserDrawTime);
log.info("春日游园活动, 上一轮投注时间发生异常的活动留给用户的下注时间{}秒", waitUserDrawTime);
} else {
log.info("深海奇缘活动, 上一轮投注时间发生异常的活动直接进行开奖, roundId:{}", roundId);
log.info("春日游园活动, 上一轮投注时间发生异常的活动直接进行开奖, roundId:{}", roundId);
needWaitUserDraw = false;
}
} else if (lastLuckySeaActInfo.getStatus().equals(Constant.LuckySeaActStatus.DRAWING)) {
needCreateNewAct = false;
needWaitUserDraw = false;
roundId = lastLuckySeaActInfo.getRoundId();
log.info("深海奇缘活动, 上一轮投注时间发生异常的活动直接进行开奖, roundId:{}", roundId);
log.info("春日游园活动, 上一轮投注时间发生异常的活动直接进行开奖, roundId:{}", roundId);
}
}
// 创建新的一轮游戏
@@ -103,38 +116,50 @@ public class LuckySeaActTask extends BaseTask {
}
// 等待用户投碎片
if (needWaitUserDraw) {
log.info("深海奇缘活动, 开始等待用户投入碎片, currTime: {}", System.currentTimeMillis());
log.info("春日游园活动, 开始等待用户投入碎片, currTime: {}", System.currentTimeMillis());
Thread.sleep(waitUserDrawTime * 1000);
log.info("深海奇缘活动, 结束等待用户投入碎片, currTime: {}", System.currentTimeMillis());
log.info("春日游园活动, 结束等待用户投入碎片, currTime: {}", System.currentTimeMillis());
}
activitiesLuckySeaService.updateLuckyActStatus(roundId, Constant.LuckySeaActStatus.DRAWING);
// 开奖
Long drawSeconds = activitiesLuckySeaService.luckySeaActDraw(itemList, roundId, timeConfig, stock);
// 异步更新用户抽奖记录
activitiesLuckySeaService.updateUserDrawRecordAsync(roundId, itemList, Integer.valueOf(modelType));
// 等待开奖动画与页面渲染开奖结果时间
long sleepSeconds = timeConfig.getDrawOverStageTime() + timeConfig.getWaitingDrawStageTime() - drawSeconds;
log.info("深海奇缘活动, 等待开奖动画与页面渲染开奖结果时间{}秒", sleepSeconds);
Thread.sleep(sleepSeconds * 1000);
log.info("深海奇缘活动此轮结束, roundId:{}", roundId);
// 异步更新活动endTime
nextRoundStartTime = new Date();
activitiesLuckySeaService.endLuckyAct(roundId, nextRoundStartTime);
drawMills = activitiesLuckySeaService.luckySeaActDraw(itemList, roundId, timeConfig, stock);
} catch (Exception e) {
// 更新活动状态, 此轮游戏标识为异常,不开始下一轮游戏
log.error("深海奇缘活动出现异常, roundId: " + roundId, e);
log.error("春日游园活动开奖时出现异常, roundId: " + roundId, e);
activitiesLuckySeaService.updateLuckyActStatus(roundId, Constant.LuckySeaActStatus.GAME_ABNORMAL);
activitiesLuckySeaService.compensateUserPieceWhenGameAbnormal(roundId, stock);
break;
} finally {
jedisLockService.unlock(RedisKey.lucky_sea_run_task.getKey(), lockVal);
}
try {
// 异步更新用户抽奖记录
activitiesLuckySeaService.updateUserDrawRecordAsync(roundId, itemList);
// 等待开奖动画与页面渲染开奖结果时间
long sleepMills = (timeConfig.getDrawOverStageTime() + timeConfig.getWaitingDrawStageTime()) * 1000
- drawMills;
if (sleepMills > 0) {
log.info("春日游园活动, 等待开奖动画与页面渲染开奖结果时间{}毫秒", sleepMills);
Thread.sleep(sleepMills);
}
log.info("春日游园活动此轮结束, roundId:{}", roundId);
// 异步更新活动endTime
nextRoundStartTime = new Date();
activitiesLuckySeaService.endLuckyAct(roundId, nextRoundStartTime);
// 进行预警数据统计
luckySeaPreWarningService.handleGoldPreWarning();
} catch (Exception e) {
// 更新活动状态
log.error("春日游园活动更新用户抽奖记录与分发奖励时出现异常, roundId: " + roundId, e);
activitiesLuckySeaService.updateLuckyActStatus(roundId, Constant.LuckySeaActStatus.SUCCESS_DRAW_UPDATE_DATA_FAIL);
}
} else {
try {
log.info("深海奇缘活动, 开关未开启,线程进入休眠: {}", actSwitch);
log.info("春日游园活动, 开关未开启,线程进入休眠: {}", actSwitch);
Thread.sleep(60 * 1000);
continue;
} catch (Exception e){
log.error("深海奇缘活动线程休眠时出现异常", e);
break;
log.error("春日游园活动线程休眠时出现异常", e);
}
}
}