v1.0 : 深海活动
This commit is contained in:
@@ -35,6 +35,8 @@ public class WebSecurityConfig {
|
||||
private String seekElfinEnterpriseWechatPushKey;
|
||||
// 线性奖池提醒企业微信机器人key
|
||||
private String linearylyPoolEnterpriseWechatPushKey;
|
||||
// 深海活动预警机器人key
|
||||
private String luckySeaPreWarningRobotKey;
|
||||
|
||||
public void setJwtWebKey(String jwtWebKey) {
|
||||
WebSecurityConfig.jwtWebKey = jwtWebKey;
|
||||
@@ -47,4 +49,8 @@ public class WebSecurityConfig {
|
||||
public void setRsaWebPrivateKey(String rsaWebPrivateKey) {
|
||||
WebSecurityConfig.rsaWebPrivateKey = rsaWebPrivateKey;
|
||||
}
|
||||
|
||||
public void setLuckySeaPreWarningRobotKey(String luckySeaPreWarningRobotKey) {
|
||||
this.luckySeaPreWarningRobotKey = luckySeaPreWarningRobotKey;
|
||||
}
|
||||
}
|
||||
|
@@ -1745,6 +1745,11 @@ public class Constant {
|
||||
public static final String ACT_MAGIC_SCHOOL_AWARD_CONFIG = "act_magic_school_award_config";
|
||||
|
||||
public static final String GOOGLE_PAY_LIMIT_CONFIG = "google_pay_limit_config";
|
||||
|
||||
/**
|
||||
* 深海活动预警配置
|
||||
*/
|
||||
public static final String LUCKY_SEA_PREWARNING_CONFIG = "lucky_sea_prewarning_config";
|
||||
}
|
||||
|
||||
public static class ActiveMq {
|
||||
@@ -2502,6 +2507,8 @@ public class Constant {
|
||||
|
||||
public static final String HEADWEAR_GOLD = "buss_headwear_gold"; // 购买头饰扣减金币
|
||||
|
||||
public static final String LUCKY_SEA_DRAW = "lucky_sea_draw";// 春日游园抽奖
|
||||
|
||||
}
|
||||
|
||||
public static class MonsterStatus {
|
||||
|
@@ -1106,6 +1106,7 @@ public enum RedisKey {
|
||||
LOCK_LUCKY_SEA_USER_DRAW,
|
||||
/** 深海奇缘活动当前轮正在进行抽奖的用户数 **/
|
||||
lucky_sea_curr_write_data_user_count,
|
||||
lucky_sea_run_task,
|
||||
/** 许愿集福气 **/
|
||||
activity_fortune,
|
||||
/** 许愿集福气保存数据锁 **/
|
||||
|
@@ -138,6 +138,9 @@ public enum BillObjTypeEnum {
|
||||
|
||||
SHIP_ANTICS_PACK((byte) 82, "航海冒险礼包支出", BillTypeEnum.OUT, CurrencyEnum.DIAMOND),
|
||||
|
||||
ACTIVITY_LUCKY_SEA_DRAW((byte) 83, "深海活动抽奖", BillTypeEnum.OUT, CurrencyEnum.DIAMOND),
|
||||
ACTIVITY_LUCKY_SEA_DIAMOND_IN((byte) 84, "深海活动奖励", BillTypeEnum.IN, CurrencyEnum.DIAMOND),
|
||||
|
||||
;
|
||||
BillObjTypeEnum(byte value, String desc, BillTypeEnum type, CurrencyEnum currency) {
|
||||
this.value = value;
|
||||
|
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 文 件 名: LuckySeaPreWarningConfig
|
||||
* 版 权:
|
||||
* 描 述: <描述>
|
||||
* 创建人: H1
|
||||
* 创建时间: 2021/9/22
|
||||
* 修改人:
|
||||
* 修改内容:
|
||||
* 修改时间:
|
||||
*/
|
||||
package com.accompany.business.config;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <br>类描述: 深海奇缘类活动预警配置
|
||||
* <br>功能详细描述:
|
||||
*
|
||||
* @author H1
|
||||
* @date [2021/9/22]
|
||||
*/
|
||||
@Data
|
||||
public class LuckySeaPreWarningConfig {
|
||||
/**
|
||||
* 应用名称
|
||||
*/
|
||||
private String appName;
|
||||
/**
|
||||
* 活动名称
|
||||
*/
|
||||
private String actName;
|
||||
/**
|
||||
* 金币预警
|
||||
*/
|
||||
private GoldPreWarning goldPreWarning;
|
||||
/**
|
||||
* 定时轮播
|
||||
*/
|
||||
private Broadcast broadcast;
|
||||
|
||||
/**
|
||||
* 金币预警
|
||||
*/
|
||||
@Data
|
||||
public static class GoldPreWarning {
|
||||
/**
|
||||
* 开关
|
||||
*/
|
||||
private Boolean open;
|
||||
/**
|
||||
* 监测列表
|
||||
*/
|
||||
private List<GoldPreWarningItem> itemList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 监测内容
|
||||
*/
|
||||
@Data
|
||||
public static class GoldPreWarningItem {
|
||||
/**
|
||||
* 监测轮数
|
||||
*/
|
||||
private Integer roundNum;
|
||||
/**
|
||||
* 预警比例 = out/in
|
||||
*/
|
||||
private Double warnRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 定时轮播
|
||||
*/
|
||||
@Data
|
||||
public static class Broadcast {
|
||||
/**
|
||||
* 开关
|
||||
*/
|
||||
private Boolean open;
|
||||
/**
|
||||
* 广播开启时间段
|
||||
*/
|
||||
private String openTime;
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 文 件 名: LuckySeaBroadDTO
|
||||
* 版 权:
|
||||
* 描 述: <描述>
|
||||
* 创建人: H1
|
||||
* 创建时间: 2021/9/23
|
||||
* 修改人:
|
||||
* 修改内容:
|
||||
* 修改时间:
|
||||
*/
|
||||
package com.accompany.business.dto.activity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* <br>类描述:
|
||||
* <br>功能详细描述:
|
||||
*
|
||||
* @author H1
|
||||
* @date [2021/9/23]
|
||||
*/
|
||||
@Data
|
||||
public class LuckySeaBroadCastDTO {
|
||||
private Integer goldIn;
|
||||
private Integer goldOut;
|
||||
private Integer roundNum;
|
||||
private Integer peopleNum;
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 文 件 名: LuckySeaGoldPreWarningDTO
|
||||
* 版 权:
|
||||
* 描 述: <描述>
|
||||
* 创建人: H1
|
||||
* 创建时间: 2021/9/22
|
||||
* 修改人:
|
||||
* 修改内容:
|
||||
* 修改时间:
|
||||
*/
|
||||
package com.accompany.business.dto.activity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* <br>类描述:
|
||||
* <br>功能详细描述:
|
||||
*
|
||||
* @author H1
|
||||
* @date [2021/9/22]
|
||||
*/
|
||||
@Data
|
||||
public class LuckySeaGoldPreWarningDTO {
|
||||
private Integer goldIn;
|
||||
private Integer goldOut;
|
||||
}
|
@@ -36,15 +36,19 @@ public interface LuckySeaActMapper {
|
||||
* @param startTime
|
||||
* @param endTime
|
||||
*/
|
||||
List<LuckySeaRankListVo> listDiamondRank(@Param("start") Integer start, @Param("pageSize") Integer pageSize,
|
||||
@Param("startTime") Date startTime, @Param("endTime") Date endTime);
|
||||
List<LuckySeaRankListVo> listDiamondRank(@Param("start") Integer start,
|
||||
@Param("pageSize") Integer pageSize,
|
||||
@Param("startTime") Date startTime,
|
||||
@Param("endTime") Date endTime);
|
||||
|
||||
/**
|
||||
* 获取深海奇缘活动欧皇榜
|
||||
* @return
|
||||
*/
|
||||
List<LuckySeaRankListVo> listLuckyManRank(@Param("start") Integer start, @Param("pageSize")Integer pageSize,
|
||||
@Param("startTime") Date startTime, @Param("endTime") Date endTime);
|
||||
List<LuckySeaRankListVo> listLuckyManRank(@Param("start") Integer start,
|
||||
@Param("pageSize")Integer pageSize,
|
||||
@Param("startTime") Date startTime,
|
||||
@Param("endTime") Date endTime);
|
||||
|
||||
|
||||
/**
|
||||
@@ -99,10 +103,9 @@ public interface LuckySeaActMapper {
|
||||
* 获取用户指定伦的投注情况
|
||||
* @param roundId
|
||||
* @param uid
|
||||
* @param itemType
|
||||
* @return
|
||||
*/
|
||||
List<LuckySeaActUserDrawItemVO> listUserDrawItemInfo(@Param("roundId") String roundId, @Param("uid") Long uid, @Param("itemType") Integer itemType);
|
||||
List<LuckySeaActUserDrawItemVO> listUserDrawItemInfo(@Param("roundId") String roundId, @Param("uid") Long uid );
|
||||
|
||||
/**
|
||||
* 获取用户指定轮的投注情况
|
||||
|
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 文 件 名: LuckySeaPreWarningMapper
|
||||
* 版 权:
|
||||
* 描 述: <描述>
|
||||
* 创建人: H1
|
||||
* 创建时间: 2021/9/22
|
||||
* 修改人:
|
||||
* 修改内容:
|
||||
* 修改时间:
|
||||
*/
|
||||
package com.accompany.business.mybatismapper.activity;
|
||||
|
||||
import com.accompany.business.dto.activity.LuckySeaBroadCastDTO;
|
||||
import com.accompany.business.dto.activity.LuckySeaGoldPreWarningDTO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* <br>接口描述:
|
||||
* <br>功能详细描述:
|
||||
*
|
||||
* @author H1
|
||||
* @date [2021/9/22]
|
||||
*/
|
||||
public interface LuckySeaPreWarningMapper {
|
||||
/**
|
||||
* 统计前N轮的活动in和out
|
||||
* @param roundNum 统计活动轮数
|
||||
* @return
|
||||
*/
|
||||
LuckySeaGoldPreWarningDTO getPreRoundStat(Integer roundNum);
|
||||
|
||||
/**
|
||||
* 获取轮播广播统计信息
|
||||
* @return
|
||||
* @param startTime
|
||||
* @param endTime
|
||||
*/
|
||||
LuckySeaBroadCastDTO getBroadCastStat(@Param("startTime") String startTime, @Param("endTime") String endTime);
|
||||
}
|
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* 文 件 名: LuckySeaPreWarningService
|
||||
* 版 权:
|
||||
* 描 述: <描述>
|
||||
* 创建人: H1
|
||||
* 创建时间: 2021/9/22
|
||||
* 修改人:
|
||||
* 修改内容:
|
||||
* 修改时间:
|
||||
*/
|
||||
package com.accompany.business.service;
|
||||
|
||||
import com.accompany.business.config.LuckySeaPreWarningConfig;
|
||||
import com.accompany.business.dto.activity.LuckySeaBroadCastDTO;
|
||||
import com.accompany.business.dto.activity.LuckySeaGoldPreWarningDTO;
|
||||
import com.accompany.business.mybatismapper.activity.LuckySeaPreWarningMapper;
|
||||
import com.accompany.business.service.activities.ActivitiesLuckySeaService;
|
||||
import com.accompany.business.service.activities.impl.ActivitiesLuckySeaServiceImpl;
|
||||
import com.accompany.business.service.push.EnterpriseWechatPushService;
|
||||
import com.accompany.common.config.SystemConfig;
|
||||
import com.accompany.common.config.WebSecurityConfig;
|
||||
import com.accompany.common.constant.Constant;
|
||||
import com.accompany.common.push.MarkdownMessage;
|
||||
import com.accompany.common.utils.DateTimeUtil;
|
||||
import com.accompany.common.utils.StringUtils;
|
||||
import com.accompany.core.service.SysConfService;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.joda.time.DateTime;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <br>类描述:
|
||||
* <br>功能详细描述:
|
||||
*
|
||||
* @author H1
|
||||
* @date [2021/9/22]
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class LuckySeaPreWarningService {
|
||||
|
||||
@Autowired
|
||||
private SysConfService sysConfService;
|
||||
@Autowired
|
||||
private LuckySeaPreWarningMapper luckySeaPreWarningMapper;
|
||||
@Autowired
|
||||
private WebSecurityConfig webSecurityConfig;
|
||||
@Autowired
|
||||
private ActivitiesLuckySeaService activitiesLuckySeaService;
|
||||
|
||||
@Autowired
|
||||
private EnterpriseWechatPushService enterpriseWechatPushService;
|
||||
|
||||
private static final String START_TIME_KEY = "startTime";
|
||||
private static final String END_TIME_KEY = "endTime";
|
||||
|
||||
/**
|
||||
* 金币预警
|
||||
*/
|
||||
@Async
|
||||
public void handleGoldPreWarning() {
|
||||
log.info("[handleGoldPreWarning] =========== start ===========");
|
||||
LuckySeaPreWarningConfig config = getConfig();
|
||||
if (null == config) {
|
||||
log.info("[handleGoldPreWarning] config is null");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
handleGoldPreWarning(config);
|
||||
log.info("[handleGoldPreWarning] =========== end ===========");
|
||||
} catch (Exception e) {
|
||||
log.error("[handleGoldPreWarning] error", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取预警配置
|
||||
* @return
|
||||
*/
|
||||
private LuckySeaPreWarningConfig getConfig() {
|
||||
String configVal = sysConfService.getSysConfValueById(Constant.SysConfId.LUCKY_SEA_PREWARNING_CONFIG);
|
||||
return StringUtils.isBlank(configVal) ? null : JSON.parseObject(configVal, LuckySeaPreWarningConfig.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理金币预警
|
||||
* @param config
|
||||
*/
|
||||
private void handleGoldPreWarning(LuckySeaPreWarningConfig config) {
|
||||
LuckySeaPreWarningConfig.GoldPreWarning goldPreWarning = config.getGoldPreWarning();
|
||||
if (!goldPreWarning.getOpen()) {
|
||||
log.info("[handleGoldPreWarning] 开关未开启");
|
||||
return;
|
||||
}
|
||||
List<LuckySeaPreWarningConfig.GoldPreWarningItem> itemList = goldPreWarning.getItemList();
|
||||
if (CollectionUtils.isEmpty(itemList)) {
|
||||
log.info("[handleGoldPreWarning] 未配置监测项");
|
||||
return;
|
||||
}
|
||||
for (LuckySeaPreWarningConfig.GoldPreWarningItem item : itemList) {
|
||||
LuckySeaGoldPreWarningDTO stat = luckySeaPreWarningMapper.getPreRoundStat(item.getRoundNum());
|
||||
if (stat.getGoldIn() != 0) {
|
||||
double rate = new BigDecimal(stat.getGoldOut()).divide(BigDecimal.valueOf(stat.getGoldIn()), 2, BigDecimal.ROUND_HALF_UP).doubleValue();
|
||||
log.info("[handleGoldPreWarning] 前{}轮 out{} in{} rate{}", item.getRoundNum(), stat.getGoldOut(), stat.getGoldIn(), rate);
|
||||
if (rate >= item.getWarnRate()) {
|
||||
sendGoldPreWarningEnterpriseWechatMsg(config, stat, item.getRoundNum(), rate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送金币预警企业微信消息
|
||||
* @param config
|
||||
* @param stat
|
||||
* @param roundNum
|
||||
* @param rate
|
||||
*/
|
||||
private void sendGoldPreWarningEnterpriseWechatMsg(LuckySeaPreWarningConfig config, LuckySeaGoldPreWarningDTO stat, Integer roundNum, Double rate) {
|
||||
MarkdownMessage msg = new MarkdownMessage();
|
||||
String appName = config.getAppName();
|
||||
String actName = config.getActName();
|
||||
msg.add(MarkdownMessage.getHeaderText(3, actName + "产出金币预警"));
|
||||
msg.add(MarkdownMessage.getReferenceText("["+ appName + "]" + "[" + actName + "]在前" + roundNum + "轮的产出/投入=" + "[" + rate + "],具体:"));
|
||||
msg.add(MarkdownMessage.getReferenceText("前"+ roundNum + "轮投入:" + stat.getGoldIn()));
|
||||
msg.add(MarkdownMessage.getReferenceText("前"+ roundNum + "轮产出:" + stat.getGoldOut()));
|
||||
msg.add(MarkdownMessage.getReferenceText("请判断是否需要前往后台查看"));
|
||||
String key = webSecurityConfig.getLuckySeaPreWarningRobotKey();
|
||||
enterpriseWechatPushService.pushMessageByKey(key,msg);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理信息轮播
|
||||
*/
|
||||
public void handleBroadcast() {
|
||||
log.info("[handleBroadcast] =========== start ===========");
|
||||
LuckySeaPreWarningConfig config = getConfig();
|
||||
if (null == config) {
|
||||
log.info("[handleBroadcast] config is null");
|
||||
return;
|
||||
}
|
||||
LuckySeaPreWarningConfig.Broadcast broadcast = config.getBroadcast();
|
||||
if (!broadcast.getOpen()) {
|
||||
log.info("[handleBroadcast] 开关未开启");
|
||||
return;
|
||||
}
|
||||
// 校验是否处在开启时间
|
||||
if (!checkIsOpeningTime(broadcast)) {
|
||||
log.info("[handleBroadcast] 不处于播报时间段");
|
||||
return;
|
||||
}
|
||||
Date now = new Date();
|
||||
String endTime = DateTimeUtil.convertDate(now, DateTimeUtil.DEFAULT_DATETIME_PATTERN);
|
||||
String startTime = DateTimeUtil.convertDate(DateTimeUtil.addHours(now, -1), DateTimeUtil.DEFAULT_DATETIME_PATTERN);
|
||||
LuckySeaBroadCastDTO broadCastStat = luckySeaPreWarningMapper.getBroadCastStat(startTime, endTime);
|
||||
sendBroadcastEnterpriseWechatMsg(config, broadCastStat, startTime, endTime);
|
||||
log.info("[handleBroadcast] =========== end ===========");
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否处于轮播时段
|
||||
* @param broadcast
|
||||
* @return
|
||||
*/
|
||||
private boolean checkIsOpeningTime(LuckySeaPreWarningConfig.Broadcast broadcast) {
|
||||
String timesConfig = broadcast.getOpenTime();
|
||||
if (StringUtils.isBlank(timesConfig)) {
|
||||
return false;
|
||||
}
|
||||
String[] times = timesConfig.split("-");
|
||||
Map<String, String> openTimeMap = ImmutableMap.of(START_TIME_KEY, times[0], END_TIME_KEY, times[1]);
|
||||
String startTime = openTimeMap.get(START_TIME_KEY);
|
||||
String endTime = openTimeMap.get(END_TIME_KEY);
|
||||
String[] startHourAndMinutes = startTime.split(":");
|
||||
String[] endHourAndMinutes = endTime.split(":");
|
||||
DateTime now = DateTime.now();
|
||||
DateTime startDateTime =
|
||||
now.withTime(
|
||||
Integer.valueOf(startHourAndMinutes[0]), Integer.valueOf(startHourAndMinutes[1]), 0, 0);
|
||||
DateTime endDateTime =
|
||||
now.withTime(
|
||||
Integer.valueOf(endHourAndMinutes[0]), Integer.valueOf(endHourAndMinutes[1]), 0, 0);
|
||||
// 如果结束时间小于开始时间,则结束日期往后延一天。因为存在跨天的情况
|
||||
if (endDateTime.compareTo(startDateTime) < 0) {
|
||||
if (now.getHourOfDay() > endDateTime.getHourOfDay()) {
|
||||
endDateTime = endDateTime.plusDays(1);
|
||||
} else {
|
||||
startDateTime = startDateTime.minusDays(1);
|
||||
}
|
||||
}
|
||||
return now.compareTo(startDateTime) >= 0 && now.compareTo(endDateTime) <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送定时轮播企业微信
|
||||
* @param config
|
||||
* @param broadCastStat
|
||||
* @param startTime
|
||||
* @param endTime
|
||||
*/
|
||||
private void sendBroadcastEnterpriseWechatMsg(LuckySeaPreWarningConfig config, LuckySeaBroadCastDTO broadCastStat, String startTime, String endTime) {
|
||||
MarkdownMessage msg = new MarkdownMessage();
|
||||
String appName = config.getAppName();
|
||||
String actName = config.getActName();
|
||||
msg.add(MarkdownMessage.getHeaderText(3, actName + "定时播报"));
|
||||
msg.add(MarkdownMessage.getReferenceText("["+ appName + "]" + "[" + actName + "]在" + startTime + "-" + endTime + "期间内情况如下:"));
|
||||
msg.add(MarkdownMessage.getReferenceText("参与用户数:" + broadCastStat.getPeopleNum()));
|
||||
msg.add(MarkdownMessage.getReferenceText("用户参与总值:" + broadCastStat.getGoldIn()));
|
||||
msg.add(MarkdownMessage.getReferenceText("用户产出总值:" + broadCastStat.getGoldOut()));
|
||||
msg.add(MarkdownMessage.getReferenceText("游戏执行轮数:" + broadCastStat.getRoundNum()));
|
||||
Long stock = activitiesLuckySeaService.getStock();
|
||||
String stockStr = new BigDecimal(stock).divide(new BigDecimal(ActivitiesLuckySeaServiceImpl.HANDLE_STOCK_MULTIPLE), 2, RoundingMode.HALF_DOWN).toString();
|
||||
msg.add(MarkdownMessage.getReferenceText("当前库存数:" + stockStr));
|
||||
String key = webSecurityConfig.getLuckySeaPreWarningRobotKey();
|
||||
enterpriseWechatPushService.pushMessageByKey(key,msg);
|
||||
}
|
||||
|
||||
}
|
@@ -243,7 +243,7 @@ public class YidunCallbackService extends BaseService {
|
||||
msg.setType(0);
|
||||
msg.setFrom(SystemConfig.secretaryUid);
|
||||
msg.setTo(uid);
|
||||
msg.setBody(String.format("头像审核通知\t\t%s\n你上传的头像,\n审核不通过,请重新上传。", DateTimeUtil.converDateToLocalDate(new Date())));
|
||||
msg.setBody(String.format("頭像審核通知\t\t%s\n你上傳的頭像,\n審核不通過,請重新上傳。", DateTimeUtil.converDateToLocalDate(new Date())));
|
||||
sendSysMsgService.sendMsg(msg);
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ public class YidunCallbackService extends BaseService {
|
||||
msg.setType(0);
|
||||
msg.setFrom(SystemConfig.secretaryUid);
|
||||
msg.setTo(uid);
|
||||
msg.setBody(String.format("相册审核通知\t\t%s\n你上传的相册图片,\n审核不通过,请重新上传。", DateTimeUtil.converDateToLocalDate(new Date())));
|
||||
msg.setBody(String.format("相冊審核通知\t\t%s\n你上傳的相冊圖片,\n審核不通過,請重新上傳。", DateTimeUtil.converDateToLocalDate(new Date())));
|
||||
sendSysMsgService.sendMsg(msg);
|
||||
}
|
||||
|
||||
|
@@ -10,6 +10,8 @@
|
||||
*/
|
||||
package com.accompany.business.service.activities;
|
||||
|
||||
|
||||
|
||||
import com.accompany.business.config.LuckySeaActConfig;
|
||||
import com.accompany.business.model.activity.LuckySeaActInfo;
|
||||
import com.accompany.business.model.activity.LuckySeaItem;
|
||||
@@ -49,9 +51,8 @@ public interface ActivitiesLuckySeaService {
|
||||
/**
|
||||
* 获取深海奇缘活动配置奖项列表
|
||||
* @return
|
||||
* @param itemType
|
||||
*/
|
||||
List<LuckySeaItem> listLuckySeaItem(Integer itemType);
|
||||
List<LuckySeaItem> listLuckySeaItem();
|
||||
|
||||
/**
|
||||
* 获取深海奇缘活动信息列表
|
||||
@@ -109,9 +110,8 @@ public interface ActivitiesLuckySeaService {
|
||||
/**
|
||||
* 异步更新用户抽奖记录信息
|
||||
* @param roundId
|
||||
* @param modelType
|
||||
*/
|
||||
void updateUserDrawRecordAsync(String roundId, List<LuckySeaItem> itemList, Integer modelType);
|
||||
void updateUserDrawRecordAsync(String roundId, List<LuckySeaItem> itemList);
|
||||
|
||||
/**
|
||||
* 创建新的一轮游戏
|
||||
|
@@ -16,7 +16,6 @@ import com.accompany.business.dto.LuckySeaActUserRoundStatDTO;
|
||||
import com.accompany.business.dto.LuckySeaUserDrawResultDto;
|
||||
import com.accompany.business.enums.UserActPropertyObjType;
|
||||
import com.accompany.business.model.ActivityPack;
|
||||
import com.accompany.business.model.Gift;
|
||||
import com.accompany.business.model.UserPurse;
|
||||
import com.accompany.business.model.activity.LuckySeaActInfo;
|
||||
import com.accompany.business.model.activity.LuckySeaItem;
|
||||
@@ -25,7 +24,6 @@ import com.accompany.business.model.activity.LuckySeaUserDrawResult;
|
||||
import com.accompany.business.model.user.UserActPropertyInfoV2;
|
||||
import com.accompany.business.mybatismapper.activity.LuckySeaActMapper;
|
||||
import com.accompany.business.mybatismapper.activity.LuckySeaUserDrawResultMapper;
|
||||
import com.accompany.business.param.UserBackpackParam;
|
||||
import com.accompany.business.param.activity.LuckySeaActDrawParams;
|
||||
import com.accompany.business.service.activities.*;
|
||||
import com.accompany.business.service.activities.vo.LuckySeaActUserDrawRecordVo;
|
||||
@@ -33,12 +31,10 @@ import com.accompany.business.service.activities.vo.LuckySeaActUserInfo;
|
||||
import com.accompany.business.service.activities.vo.LuckySeaRankListVo;
|
||||
import com.accompany.business.service.activities.vo.LuckySeaRankVo;
|
||||
import com.accompany.business.service.activity.ActivityPackService;
|
||||
import com.accompany.business.service.gift.GiftService;
|
||||
import com.accompany.business.service.purse.UserPurseService;
|
||||
import com.accompany.business.service.record.BillRecordService;
|
||||
import com.accompany.business.service.user.UserActPropertyInfoService;
|
||||
import com.accompany.business.service.user.UserActPropertyInfoV2Service;
|
||||
import com.accompany.business.service.user.UserBackpackService;
|
||||
import com.accompany.business.service.user.UsersService;
|
||||
import com.accompany.business.vo.activities.*;
|
||||
import com.accompany.common.constant.Constant;
|
||||
@@ -47,6 +43,7 @@ import com.accompany.common.redis.RedisKey;
|
||||
import com.accompany.common.status.BusiStatus;
|
||||
import com.accompany.common.utils.BlankUtil;
|
||||
import com.accompany.common.utils.DateTimeUtil;
|
||||
import com.accompany.common.utils.RandomUtil;
|
||||
import com.accompany.common.utils.StringUtils;
|
||||
import com.accompany.core.enumeration.BillObjTypeEnum;
|
||||
import com.accompany.core.exception.ServiceException;
|
||||
@@ -68,8 +65,8 @@ import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.accompany.core.enumeration.BillObjTypeEnum.ACTIVITY_DIAMOND;
|
||||
|
||||
/**
|
||||
* <br>类描述:
|
||||
@@ -112,10 +109,6 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
@Autowired
|
||||
private BillRecordService billRecordService;
|
||||
@Autowired
|
||||
private GiftService giftService;
|
||||
@Autowired
|
||||
private UserBackpackService userBackpackService;
|
||||
@Autowired
|
||||
private UserActPropertyInfoV2Service userActPropertyInfoV2Service;
|
||||
|
||||
/**
|
||||
@@ -144,13 +137,13 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
@Override
|
||||
public void updateUserLuckySeaActPiece(Long uid, Integer packId, Integer packNum) {
|
||||
if (null == uid) {
|
||||
throw new ServiceException("uid不能為空");
|
||||
throw new ServiceException("uid不能为空");
|
||||
}
|
||||
if (null == packId) {
|
||||
throw new ServiceException("packId不能為空");
|
||||
throw new ServiceException("packId不能为空");
|
||||
}
|
||||
if (null == packNum || packNum <= 0) {
|
||||
throw new ServiceException("購買禮包數必須大於0");
|
||||
throw new ServiceException("购买礼包数必须大于0");
|
||||
}
|
||||
log.info("updateUserLuckySeaActPiece, uid = {}, packId = {}, packNum = {}", uid, packId, packNum);
|
||||
String lock = null;
|
||||
@@ -161,10 +154,11 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
}
|
||||
ActivityPack pack = activityPackService.getPackById(packId);
|
||||
if (null == pack) {
|
||||
throw new ServiceException("購買的產品不存在");
|
||||
throw new ServiceException("购买的产品不存在");
|
||||
}
|
||||
userActPropertyInfoV2Service.updateUserPiece(uid, (long) (pack.getTicketNum() * packNum), ActivitesPackTypeEnum.LUCKY_SEA.getValue());
|
||||
log.info("updateTicketNum, num = {}",pack.getTicketNum() * packNum);
|
||||
int pieceNum = pack.getTicketNum() * packNum;
|
||||
userActPropertyInfoService.updatePiece(uid, (long)pieceNum);
|
||||
log.info("updateTicketNum, num = {}",pieceNum);
|
||||
}finally {
|
||||
jedisLockService.unlock(RedisKey.LOCK_LUCKY_SEA_UPDATE_PIECE.getKey(uid.toString()), lock);
|
||||
}
|
||||
@@ -173,7 +167,7 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
@Override
|
||||
public LuckySeaActUserInfo getUserLuckySeaActInfo(Long uid) {
|
||||
if (null == uid) {
|
||||
throw new ServiceException("uid不能為空");
|
||||
throw new ServiceException("uid不能为空");
|
||||
}
|
||||
Users user = usersService.getUsersByUid(uid);
|
||||
if (user == null) {
|
||||
@@ -182,10 +176,6 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
LuckySeaActUserInfo info = new LuckySeaActUserInfo();
|
||||
info.setAvatar(user.getAvatar());
|
||||
info.setNick(user.getNick());
|
||||
// 获取用户碎片数
|
||||
UserActPropertyInfoV2 propertyInfo = userActPropertyInfoV2Service.getUserActPropertyInfo(uid, ActivitesPackTypeEnum.LUCKY_SEA.getValue());
|
||||
|
||||
info.setPieceNum(propertyInfo != null ? propertyInfo.getPieceNum() : 0);
|
||||
// 获取用户钱包钻石数
|
||||
UserPurse userPurse = userPurseService.queryUserPurse(uid);
|
||||
info.setDiamonds(userPurse != null ? userPurse.getDiamonds() : 0);
|
||||
@@ -199,10 +189,9 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LuckySeaItem> listLuckySeaItem(Integer itemType) {
|
||||
public List<LuckySeaItem> listLuckySeaItem() {
|
||||
QueryWrapper<LuckySeaItem> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda().eq(LuckySeaItem::getStatus, Constant.status.valid)
|
||||
.eq(LuckySeaItem::getItemType, itemType.byteValue())
|
||||
.orderByAsc(LuckySeaItem::getMultiple );
|
||||
return luckySeaItemService.list(wrapper);
|
||||
}
|
||||
@@ -253,11 +242,6 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
if (actStatus.getDrawStatus().equals(Constant.LuckySeaUserStatus.WIN)) {
|
||||
result.setDrawStatus(Constant.LuckySeaUserStatus.WIN);
|
||||
result.setPrizeDiamonds(actStatus.getPrizeDiamonds());
|
||||
result.setPrizeName(actStatus.getPrizeName());
|
||||
result.setPrizePrice(actStatus.getPrizePrice());
|
||||
if (result.getPrizePrice() != null && result.getPrizePrice() != 0) {
|
||||
result.setPrizeCount(result.getPrizeDiamonds()/ result.getPrizePrice());
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
result.setDrawStatus(Constant.LuckySeaUserStatus.NOT_WIN);
|
||||
@@ -276,7 +260,7 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
@Override
|
||||
public LuckySeaRankVo listRank(Integer type, Integer page, Integer pageSize, Long uid) {
|
||||
if (null == type) {
|
||||
throw new ServiceException("榜單type不能為空");
|
||||
throw new ServiceException("榜单type不能为空");
|
||||
}
|
||||
if (null == page) {
|
||||
page = Constant.DEFAULT_PAGE;
|
||||
@@ -291,18 +275,7 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
Date beginTimeOfDay = DateTimeUtil.getBeginTimeOfDay(new Date());
|
||||
Date endTimeOfDay = DateTimeUtil.getEndTimeOfDay(new Date());
|
||||
if (type.equals(Constant.LuckySeaRankType.DIAMOND_RANK)) {
|
||||
Integer num = 0;
|
||||
List<LuckySeaRankListVo> luckySeaList = luckySeaActMapper.listDiamondRank( start, pageSize, beginTimeOfDay, endTimeOfDay);
|
||||
for(LuckySeaRankListVo luckySeaVo : luckySeaList){
|
||||
Integer giftDistanceNum = - new Double( - luckySeaVo.getNum() + num ).intValue() ;
|
||||
num = new Double(luckySeaVo.getNum()).intValue();
|
||||
if(giftDistanceNum >= 0){
|
||||
luckySeaVo.setNum(giftDistanceNum.doubleValue());
|
||||
}else{
|
||||
luckySeaVo.setNum( - giftDistanceNum.doubleValue());
|
||||
}
|
||||
rankList.add(luckySeaVo);
|
||||
}
|
||||
rankList = luckySeaActMapper.listDiamondRank(start, pageSize, beginTimeOfDay, endTimeOfDay);
|
||||
userRankInfo = luckySeaActMapper.listUserDiamondRank(uid, beginTimeOfDay, endTimeOfDay);
|
||||
} else if (type.equals(Constant.LuckySeaRankType.LUCKY_MAN_RANK)) {
|
||||
rankList = luckySeaActMapper.listLuckyManRank(start, pageSize, beginTimeOfDay, endTimeOfDay);
|
||||
@@ -320,16 +293,16 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
@Override
|
||||
public void draw(Long uid, List<LuckySeaActDrawParams> params) {
|
||||
if (null == uid) {
|
||||
throw new ServiceException("uid不能為空");
|
||||
throw new ServiceException("uid不能为空");
|
||||
}
|
||||
String lockVal = jedisLockService.lock(RedisKey.LOCK_LUCKY_SEA_USER_DRAW.getKey(uid.toString()));
|
||||
if (BlankUtil.isBlank(lockVal)) {
|
||||
log.error("深海奇缘,获取分布式锁失败,uid:{}", uid);
|
||||
log.error("春日游园,获取分布式锁失败,uid:{}", uid);
|
||||
throw new ServiceException(BusiStatus.JOIN_GAME_USER_TOO_MORE);
|
||||
}
|
||||
String roundId = null;
|
||||
try {
|
||||
Long costPieceTotal = checkDrawParam(params, uid);
|
||||
checkDrawParam(params, uid);
|
||||
LuckySeaActInfo actInfo = luckySeaActInfoService.getByCurrTime();
|
||||
if (actInfo == null) {
|
||||
log.error("选择失败,当前时段不存在活动。actInfo:" + JSON.toJSONString(actInfo));
|
||||
@@ -339,13 +312,16 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
jedisService.incrBy(RedisKey.lucky_sea_curr_write_data_user_count.getKey(roundId), 1);
|
||||
if (!actInfo.getStatus().equals(Constant.LuckySeaActStatus.CHOOSE_STAGE)) {
|
||||
log.error("选择失败,当前不处于选择阶段。actInfo:" + JSON.toJSONString(actInfo));
|
||||
throw new ServiceException("選擇失敗,當前不處於選擇階段");
|
||||
throw new ServiceException("Selection failed. It is not in the selection at present");
|
||||
}
|
||||
// TODO: 2021/1/14 待优化,这里可以优化为批量写入
|
||||
Long costGoldTotal = 0L;
|
||||
for (LuckySeaActDrawParams param : params) {
|
||||
luckySeaUserDrawRecordService.updateUserDrawRecord(uid, actInfo.getRoundId(), param.getItemId(), param.getNum());
|
||||
costGoldTotal += param.getNum();
|
||||
}
|
||||
userActPropertyInfoV2Service.updateUserPiece(uid, -costPieceTotal, ActivitesPackTypeEnum.LUCKY_SEA.getValue());
|
||||
billRecordService.insertGeneralBillRecord(uid, null, null, BillObjTypeEnum.ACTIVITY_LUCKY_SEA_DRAW,
|
||||
-Double.valueOf(costGoldTotal));
|
||||
} finally {
|
||||
jedisLockService.unlock(RedisKey.LOCK_LUCKY_SEA_USER_DRAW.getKey(uid.toString()), lockVal);
|
||||
jedisService.decrBy(RedisKey.lucky_sea_curr_write_data_user_count.getKey(roundId), 1);
|
||||
@@ -355,16 +331,14 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
@Override
|
||||
public LuckySeaActConfig getLuckySeaTimeConfig() {
|
||||
String luckySeaConfigStr = sysConfService.getSysConfValueById(Constant.SysConfId.LUCKY_SEA_TIME_CONFIG);
|
||||
String modelType = sysConfService.getDefaultSysConfValueById(Constant.SysConfId.LUCKY_SEA_MODEL, Constant.luckySeaItemType.NORMAL.toString());
|
||||
LuckySeaActConfig config = new LuckySeaActConfig();
|
||||
if (StringUtils.isBlank(luckySeaConfigStr)) {
|
||||
LuckySeaActConfig config = new LuckySeaActConfig();
|
||||
config.setChooseStageTime(DEFAULT_CHOOSE_STAGE_TIME);
|
||||
config.setWaitingDrawStageTime(DEFAULT_WAITING_DRAW_STAGE_TIME);
|
||||
config.setDrawOverStageTime(DEFAULT_DRAW_OVER_STAGE_TIME);
|
||||
return config;
|
||||
}
|
||||
config = JSON.parseObject(luckySeaConfigStr, LuckySeaActConfig.class);
|
||||
config.setModelType(Integer.valueOf(modelType));
|
||||
return config;
|
||||
return JSON.parseObject(luckySeaConfigStr, LuckySeaActConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -384,26 +358,21 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
for (LuckySeaUserDrawResult result : list) {
|
||||
LuckySeaActUserDrawRecordVo vo = new LuckySeaActUserDrawRecordVo();
|
||||
Long reward = 0L;
|
||||
Long price = 0L;
|
||||
LuckySeaActInfo actInfo = luckySeaActInfoService.getById(result.getRoundId());
|
||||
if (actInfo != null) {
|
||||
vo.setRoundId(actInfo.getRoundId());
|
||||
vo.setDrawTime(actInfo.getEndTime());
|
||||
vo.setDrawId(actInfo.getDrawId());
|
||||
vo.setItemType(result.getItemType().intValue());
|
||||
}
|
||||
List<LuckySeaUserDrawResultVo> resultVos = handleDrawResult(result.getResult());
|
||||
for (LuckySeaUserDrawResultVo resultVo : resultVos) {
|
||||
if (null != result.getDrawId() && result.getDrawId().equals(resultVo.getItemId())) {
|
||||
reward = resultVo.getCostPiece() * resultVo.getMultiple() * 10;
|
||||
price = Long.valueOf(resultVo.getMultiple() * 10);
|
||||
reward = resultVo.getCostPiece() * resultVo.getMultiple();
|
||||
}
|
||||
}
|
||||
vo.setResults(resultVos);
|
||||
vo.setDrawStatus(result.getDrawStatus());
|
||||
vo.setReward(reward);
|
||||
vo.setPrice(price);
|
||||
vo.setItemName(result.getItemName());
|
||||
results.add(vo);
|
||||
}
|
||||
}
|
||||
@@ -413,21 +382,21 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
@Override
|
||||
public Long luckySeaActDraw(List<LuckySeaItem> itemList, String roundId, LuckySeaActConfig timeConfig, Long stockInCache) throws InterruptedException {
|
||||
long beforeDraw = System.currentTimeMillis();
|
||||
log.info("深海奇缘活动, 开始开奖, currTime:{}", beforeDraw);
|
||||
log.info("春日游园活动, 开始开奖, currTime:{}", beforeDraw);
|
||||
// 开奖
|
||||
LuckySeaActInfo actInfo = luckySeaActInfoService.getById(roundId);
|
||||
log.info("深海奇缘活动, 开奖时使用的配置, itemList:{}", JSON.toJSONString(itemList));
|
||||
log.info("深海奇缘活动, 当前开奖的活动信息, actInfo:{}", JSON.toJSONString(actInfo));
|
||||
log.info("春日游园活动, 开奖时使用的配置, itemList:{}", JSON.toJSONString(itemList));
|
||||
log.info("春日游园活动, 当前开奖的活动信息, actInfo:{}", JSON.toJSONString(actInfo));
|
||||
if (actInfo == null) {
|
||||
throw new ServiceException("當前沒有進行中的活動");
|
||||
throw new ServiceException("当前没有进行中的活动");
|
||||
}
|
||||
if (!actInfo.getStatus().equals(Constant.LuckySeaActStatus.DRAWING)) {
|
||||
throw new ServiceException("活動開獎狀態異常");
|
||||
throw new ServiceException("活动开奖状态异常");
|
||||
}
|
||||
// 查询当前是否有用户正在进行写入抽奖数据
|
||||
String count = jedisService.get(RedisKey.lucky_sea_curr_write_data_user_count.getKey(roundId));
|
||||
while (StringUtils.isNotBlank(count) && Integer.valueOf(count) > 0) {
|
||||
log.info("深海奇缘活动, 当前还有{}用户正在写入抽奖数据, 轮数:{}", count, roundId);
|
||||
log.info("春日游园活动, 当前还有{}用户正在写入抽奖数据, 轮数:{}", count, roundId);
|
||||
Thread.sleep(100);
|
||||
count = jedisService.get(RedisKey.lucky_sea_curr_write_data_user_count.getKey(roundId));
|
||||
}
|
||||
@@ -438,21 +407,19 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
// 计算此轮应该抽取的门票
|
||||
BigDecimal ticketPiece = new BigDecimal(userInput).multiply(new BigDecimal(ticket))
|
||||
.setScale(5, BigDecimal.ROUND_DOWN);
|
||||
log.info("深海奇缘活动,轮次号:{}, 库存:{}, 用户扣除前投入总和:{}, 需要扣除门票:{}", actInfo.getRoundId(), stock, userInput, ticketPiece);
|
||||
log.info("春日游园活动,轮次号:{}, 库存:{}, 用户扣除前投入总和:{}, 需要扣除门票:{}", actInfo.getRoundId(), stock, userInput, ticketPiece);
|
||||
// 扣除门票之后的用户投入
|
||||
BigDecimal userInputAfterDeduct = new BigDecimal(userInput).subtract(ticketPiece).setScale(5, BigDecimal.ROUND_DOWN);
|
||||
log.info("深海奇缘活动,轮次号:{}, 用户扣除后投入总和:{}", actInfo.getRoundId(), userInputAfterDeduct);
|
||||
log.info("春日游园活动,轮次号:{}, 用户扣除后投入总和:{}", actInfo.getRoundId(), userInputAfterDeduct);
|
||||
// 扣除门票之后加入库存
|
||||
if (!userInputAfterDeduct.equals(BigDecimal.ZERO.setScale(5, BigDecimal.ROUND_DOWN))) {
|
||||
Long userInputAfterDeductInt = Long.valueOf(userInputAfterDeduct.multiply(new BigDecimal(HANDLE_STOCK_MULTIPLE)).setScale(0,BigDecimal.ROUND_DOWN).toString());
|
||||
jedisService.incrBy(RedisKey.LUCKY_SEA_ACT_STOCK.getKey(), userInputAfterDeductInt);
|
||||
}
|
||||
double stockWithUserInput = stock.add(userInputAfterDeduct)
|
||||
Long userInputAfterDeductInt = Long.valueOf(userInputAfterDeduct.multiply(new BigDecimal(HANDLE_STOCK_MULTIPLE)).setScale(0,BigDecimal.ROUND_DOWN).toString());
|
||||
stockInCache = jedisService.incrBy(RedisKey.LUCKY_SEA_ACT_STOCK.getKey(), userInputAfterDeductInt);
|
||||
double stockWithUserInput = new BigDecimal(stockInCache).divide(new BigDecimal(HANDLE_STOCK_MULTIPLE))
|
||||
.setScale(5, BigDecimal.ROUND_DOWN).doubleValue();
|
||||
log.info("深海奇缘活动,轮次号:{}, 加入用户投入之后的库存:{}", actInfo.getRoundId(), stockWithUserInput);
|
||||
log.info("春日游园活动,轮次号:{}, 加入用户投入之后的库存:{}", actInfo.getRoundId(), stockWithUserInput);
|
||||
List<LuckySeaActRoundStatVo> statList = luckySeaActMapper.listUserRoundStat(actInfo.getRoundId());
|
||||
Long drawId = handleDrawPrize(statList, itemList, stockWithUserInput);
|
||||
log.info("深海奇缘活动,轮次号:{}, 开奖结束,itemId :{}", actInfo.getRoundId(), drawId);
|
||||
log.info("春日游园活动,轮次号:{}, 开奖结束,itemId :{}", actInfo.getRoundId(), drawId);
|
||||
LuckySeaItem item = null;
|
||||
for (LuckySeaItem items : itemList) {
|
||||
if (drawId.equals(items.getId())) {
|
||||
@@ -462,14 +429,14 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
long endDraw = System.currentTimeMillis();
|
||||
log.info("深海奇缘活动, 结束开奖, currTime:{}", endDraw);
|
||||
// 获取处理此次开奖的时间
|
||||
Long drawSeconds = (endDraw - beforeDraw)/ 1000;
|
||||
log.info("深海奇缘活动, 结束开奖,处理开奖花费{}秒", drawSeconds);
|
||||
Long drawMills = endDraw - beforeDraw;
|
||||
log.info("深海奇缘活动, 结束开奖,处理开奖花费{}毫秒", drawMills);
|
||||
// 更新活动状态
|
||||
int drawTime = Math.max(timeConfig.getWaitingDrawStageTime(), drawSeconds.intValue());
|
||||
Date showResultStageStartTime = DateTimeUtil.addSeconds(actInfo.getDrawStageStartTime(), drawTime);
|
||||
int drawTime = Math.max(timeConfig.getWaitingDrawStageTime() * 1000, drawMills.intValue());
|
||||
Date showResultStageStartTime = DateTimeUtil.addMilliSecond(actInfo.getDrawStageStartTime(), drawTime);
|
||||
updateLuckyActDrawResult(roundId, drawId, item, showResultStageStartTime,ticketPiece.doubleValue());
|
||||
jedisService.del(RedisKey.lucky_sea_curr_write_data_user_count.getKey(roundId));
|
||||
return drawSeconds;
|
||||
return drawMills;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -478,48 +445,21 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
*/
|
||||
@Async
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
private void distributeDiamondAsync(String roundId) {
|
||||
log.info("深海奇缘活动, 开始分发钻石奖励, roundId:{}", roundId);
|
||||
void distributeDiamondAsync(String roundId) {
|
||||
log.info("春日游园活动, 开始分发钻石奖励, roundId:{}", roundId);
|
||||
// 获取轮次下中奖的用户列表
|
||||
QueryWrapper<LuckySeaUserDrawRecord> recordQueryWrapper = new QueryWrapper<>();
|
||||
recordQueryWrapper.lambda().eq(LuckySeaUserDrawRecord::getRoundId, roundId)
|
||||
.eq(LuckySeaUserDrawRecord::getDrawStatus, Constant.status.valid);
|
||||
List<LuckySeaUserDrawRecord> drawUserRecordList = luckySeaUserDrawRecordService.list(recordQueryWrapper);
|
||||
log.info("深海奇缘活动, 开始分发钻石奖励, 分发用户:{}", JSON.toJSONString(drawUserRecordList));
|
||||
log.info("春日游园活动, 开始分发钻石奖励, 分发用户:{}", JSON.toJSONString(drawUserRecordList));
|
||||
// 奖励用户对应钻石
|
||||
for (LuckySeaUserDrawRecord record : drawUserRecordList) {
|
||||
long diamondsNum = record.getCostPriceNum() * record.getItemMultiple() * 10;
|
||||
log.info("深海奇缘活动, 开始分发钻石奖励。 uid:{}, diamondsNum:{}", record.getUid(), diamondsNum);
|
||||
userPurseService.addDiamond(record.getUid(), Double.valueOf(diamondsNum), null, BillObjTypeEnum.ACTIVITY_DIAMOND.getDesc());
|
||||
billRecordService.insertGeneralBillRecord(record.getUid(), 0L, record.getRoundId(), ACTIVITY_DIAMOND, Double.valueOf(diamondsNum));
|
||||
log.info("深海奇缘活动, 结束分发钻石奖励。 uid:{}, diamondsNum:{}", record.getUid(), diamondsNum);
|
||||
}
|
||||
}
|
||||
|
||||
@Async
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
private void distributeGiftAsync(String roundId, Integer giftId) {
|
||||
log.info("深海奇缘活动, 开始分发礼物奖励, roundId:{}", roundId);
|
||||
// 获取轮次下中奖的用户列表
|
||||
QueryWrapper<LuckySeaUserDrawRecord> recordQueryWrapper = new QueryWrapper<>();
|
||||
recordQueryWrapper.lambda().eq(LuckySeaUserDrawRecord::getRoundId, roundId)
|
||||
.eq(LuckySeaUserDrawRecord::getDrawStatus, Constant.status.valid);
|
||||
List<LuckySeaUserDrawRecord> drawUserRecordList = luckySeaUserDrawRecordService.list(recordQueryWrapper);
|
||||
log.info("深海奇缘活动, 开始分发礼物奖励, 分发用户:{}", JSON.toJSONString(drawUserRecordList));
|
||||
// 奖励用户对应背包礼物
|
||||
for (LuckySeaUserDrawRecord record : drawUserRecordList) {
|
||||
Long giftNum = record.getCostPriceNum();
|
||||
log.info("深海奇缘活动, 开始分发礼物奖励。 uid:{},giftId:{}, giftNum:{}", record.getUid(), giftId, giftNum);
|
||||
Gift gift = giftService.getGiftByIdFromDb(giftId);
|
||||
UserBackpackParam userBackpackParam = new UserBackpackParam();
|
||||
userBackpackParam.setGiftId(giftId);
|
||||
userBackpackParam.setUid(record.getUid());
|
||||
userBackpackParam.setGiftType(gift.getGiftType());
|
||||
userBackpackParam.setGiftSeq(gift.getSeqNo());
|
||||
userBackpackParam.setCount(giftNum.intValue());
|
||||
userBackpackService.saveOrUpdateUserBackpack(userBackpackParam);
|
||||
// billRecordService.insertGeneralBillRecord(record.getUid(), 0L, record.getRoundId(), ACTIVITY_DIAMOND, Double.valueOf(giftNum));
|
||||
log.info("深海奇缘活动, 结束分发礼物奖励。 uid:{},giftId:{}, giftNum:{}", record.getUid(), giftId, giftNum);
|
||||
long diamondsNum = record.getCostPriceNum() * record.getItemMultiple();
|
||||
log.info("春日游园活动, 开始分发钻石奖励。 uid:{}, diamondsNum:{}", record.getUid(), diamondsNum);
|
||||
userPurseService.addDiamond(record.getUid(), Double.valueOf(diamondsNum), null, BillObjTypeEnum.ACTIVITY_LUCKY_SEA_DIAMOND_IN.getDesc());
|
||||
billRecordService.insertGeneralBillRecord(record.getUid(), 0L, record.getRoundId(), BillObjTypeEnum.ACTIVITY_LUCKY_SEA_DIAMOND_IN, (double) diamondsNum);
|
||||
log.info("春日游园活动, 结束分发钻石奖励。 uid:{}, diamondsNum:{}", record.getUid(), diamondsNum);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -527,12 +467,10 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
* 异步写入用户的游戏记录
|
||||
* @param roundId
|
||||
* @param itemList
|
||||
* @param itemType
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void addUserDrawResult(String roundId, List<LuckySeaItem> itemList, Byte itemType) {
|
||||
public void addUserDrawResult(String roundId, List<LuckySeaItem> itemList) {
|
||||
LuckySeaActInfo actInfo = luckySeaActInfoService.getById(roundId);
|
||||
LuckySeaItem item = luckySeaItemService.getById(actInfo.getDrawId());
|
||||
QueryWrapper<LuckySeaUserDrawRecord> recordQueryWrapper = new QueryWrapper<>();
|
||||
recordQueryWrapper.lambda().eq(LuckySeaUserDrawRecord::getRoundId, roundId).orderByAsc(LuckySeaUserDrawRecord::getUid).orderByAsc(LuckySeaUserDrawRecord::getDrawStatus);
|
||||
List<LuckySeaUserDrawRecord> drawUserRecordList = luckySeaUserDrawRecordService.list(recordQueryWrapper);
|
||||
@@ -560,8 +498,6 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
LuckySeaUserDrawResult result = new LuckySeaUserDrawResult();
|
||||
result.setUid(uid);
|
||||
result.setRoundId(actInfo.getRoundId());
|
||||
result.setItemType(itemType);
|
||||
result.setItemName(item.getName());
|
||||
result.setDrawId(actInfo.getDrawId());
|
||||
result.setResult(JSON.toJSONString(resultDtoList));
|
||||
result.setDrawStatus(userDrawStatusMap.get(uid));
|
||||
@@ -611,30 +547,22 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
/**
|
||||
* 异步更新用户抽奖记录信息
|
||||
* @param roundId
|
||||
* @param modelType
|
||||
*/
|
||||
@Async
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void updateUserDrawRecordAsync(String roundId, List<LuckySeaItem> itemList, Integer modelType) {
|
||||
public void updateUserDrawRecordAsync(String roundId, List<LuckySeaItem> itemList) {
|
||||
try {
|
||||
LuckySeaActInfo actInfo = luckySeaActInfoService.getById(roundId);
|
||||
if (null != actInfo) {
|
||||
luckySeaActMapper.batchUpdateUserDrawRecord(roundId, actInfo.getDrawId());
|
||||
}
|
||||
// 分发中奖用户的奖励
|
||||
if (Constant.luckySeaItemType.NORMAL.equals(modelType.byteValue())) {
|
||||
distributeDiamondAsync(roundId);
|
||||
} else if (Constant.luckySeaItemType.GIFT.equals(modelType.byteValue())) {
|
||||
LuckySeaItem item = luckySeaItemService.getById(actInfo.getDrawId());
|
||||
if (item != null) {
|
||||
distributeGiftAsync(roundId, item.getReferenceId());
|
||||
}
|
||||
}
|
||||
addUserDrawResult(roundId, itemList, modelType.byteValue());
|
||||
distributeDiamondAsync(roundId);
|
||||
addUserDrawResult(roundId, itemList);
|
||||
} catch (Exception e) {
|
||||
log.error("深海奇缘活动,异步更新用户参与信息时出现异常, roundId:" + roundId, e);
|
||||
throw new ServiceException("深海奇緣活動,異步更新用戶參与信息時出現異常", e);
|
||||
log.error("春日游园活动,异步更新用户参与信息时出现异常, roundId:" + roundId, e);
|
||||
throw new ServiceException("春日游园活动,异步更新用户参与信息时出现异常");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -646,7 +574,7 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
* @param ticket
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
private void updateLuckyActDrawResult(String roundId, Long drawId, LuckySeaItem item, Date showResultStageStartTime, Double ticket) {
|
||||
void updateLuckyActDrawResult(String roundId, Long drawId, LuckySeaItem item, Date showResultStageStartTime, Double ticket) {
|
||||
LuckySeaActInfo act = new LuckySeaActInfo();
|
||||
act.setRoundId(roundId);
|
||||
act.setDrawId(drawId);
|
||||
@@ -696,14 +624,13 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
|
||||
@Override
|
||||
public List<LuckySeaActUserDrawItemVO> listUserDrawItemInfo(Long uid, String roundId) {
|
||||
String modelType = sysConfService.getDefaultSysConfValueById(Constant.SysConfId.LUCKY_SEA_MODEL, Constant.luckySeaItemType.NORMAL.toString());
|
||||
List<LuckySeaActUserDrawItemVO> itemVOS = luckySeaActMapper.listUserDrawItemInfo(roundId, uid, Integer.valueOf(modelType));
|
||||
List<LuckySeaActUserDrawItemVO> itemVOS = luckySeaActMapper.listUserDrawItemInfo(roundId, uid);
|
||||
return itemVOS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void compensateUserPieceWhenGameAbnormal(String roundId, Long beforeStoke) {
|
||||
log.info("深海奇缘活动,开始处理发生异常的活动, roundId:{}, 还原库存:{}", roundId, beforeStoke/HANDLE_STOCK_MULTIPLE);
|
||||
log.info("春日游园活动,开始处理发生异常的活动, roundId:{}, 还原库存:{}", roundId, beforeStoke/HANDLE_STOCK_MULTIPLE);
|
||||
// 将库存还原为发生异常之前的库存
|
||||
jedisService.set(RedisKey.LUCKY_SEA_ACT_STOCK.getKey(), String.valueOf(beforeStoke));
|
||||
// 获取此轮参加游戏的用户投入碎片情况
|
||||
@@ -713,7 +640,7 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
userActPropertyInfoV2Service.updateUserPiece(stat.getUid(), stat.getCostPieceNum(), ActivitesPackTypeEnum.LUCKY_SEA.getValue(), UserActPropertyObjType.ACT_ABNORMAL_COMPENSATE);
|
||||
}
|
||||
}
|
||||
log.info("深海奇缘活动,结束处理发生异常的活动, roundId:{}, 处理的投入列表statList:{}", roundId, JSON.toJSONString(statList));
|
||||
log.info("春日游园活动,结束处理发生异常的活动, roundId:{}, 处理的投入列表statList:{}", roundId, JSON.toJSONString(statList));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -737,7 +664,7 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
act.setCreateTime(new Date());
|
||||
act.setUpdateTime(new Date());
|
||||
luckySeaActInfoService.save(act);
|
||||
log.info("深海奇缘活动, 创建新的一轮游戏 roundId:{}, startTime:{}", roundId, startTime);
|
||||
log.info("春日游园活动, 创建新的一轮游戏 roundId:{}, startTime:{}", roundId, startTime);
|
||||
return roundId;
|
||||
}
|
||||
|
||||
@@ -764,19 +691,22 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
}
|
||||
Long drawId = null;
|
||||
if (!CollectionUtils.isEmpty(lessThanStockItemId)) {
|
||||
log.info("深海奇缘活动, 存在小于库存的条件组, lessThanStockItemId: {}", JSON.toJSONString(lessThanStockItemId));
|
||||
Collections.shuffle(lessThanStockItemId);
|
||||
drawId = lessThanStockItemId.get(0);
|
||||
log.info("春日游园活动, 存在小于库存的条件组, lessThanStockItemId: {}", JSON.toJSONString(lessThanStockItemId));
|
||||
int randomIndex = RandomUtil.randomByRange(0, lessThanStockItemId.size());
|
||||
drawId = lessThanStockItemId.get(randomIndex);
|
||||
} else {
|
||||
// 将map进行排序,最小的放在map首位
|
||||
itemPieceMap.entrySet().stream().sorted((p1, p2) -> p2.getValue().compareTo(p1.getValue()));
|
||||
log.info("深海奇缘活动, 没有小于库存的条件组, itemPieceMap: {}", JSON.toJSONString(itemPieceMap));
|
||||
drawId = itemPieceMap.keySet().iterator().next();
|
||||
ArrayList<Map.Entry<Long, Long>> entries = new ArrayList<>(itemPieceMap.entrySet());
|
||||
entries.sort(Map.Entry.comparingByValue());
|
||||
Long minValue = entries.get(0).getValue();
|
||||
List<Long> keys = itemPieceMap.entrySet().stream().filter(o -> Objects.equals(o.getValue(), minValue)).map(Map.Entry::getKey).collect(Collectors.toList());
|
||||
log.info("春日游园活动, 没有小于库存的条件组, 满足最小用户投入的itemIdList: {}", JSON.toJSONString(keys));
|
||||
int index = RandomUtil.randomByRange(0, keys.size());
|
||||
drawId = keys.get(index);
|
||||
}
|
||||
|
||||
// 更新库存
|
||||
Long prizePiece = itemPieceMap.get(drawId);
|
||||
log.info("深海奇缘活动, drawId: {}, prizePiece: {}", drawId, prizePiece);
|
||||
log.info("春日游园活动, drawId: {}, prizePiece: {}", drawId, prizePiece);
|
||||
// 因为redis中的库存最多保留5位小数,需要转成整数之后在计算,所以prizePiece需要乘上100000
|
||||
jedisService.decrBy(RedisKey.LUCKY_SEA_ACT_STOCK.getKey(), prizePiece * HANDLE_STOCK_MULTIPLE);
|
||||
return drawId;
|
||||
@@ -798,17 +728,17 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取深海奇缘活动配置的门票
|
||||
* 获取春日游园活动配置的门票
|
||||
* @return
|
||||
*/
|
||||
private Double getLuckySeaActTicket() {
|
||||
String ticketStr = sysConfService.getSysConfValueById(Constant.SysConfId.LUCKY_SEA_TICKET);
|
||||
if (StringUtils.isBlank(ticketStr)) {
|
||||
throw new ServiceException("配置的門票為空");
|
||||
throw new ServiceException("配置的门票为空");
|
||||
}
|
||||
Double ticket = Double.valueOf(ticketStr);
|
||||
if (ticket >= 1) {
|
||||
throw new ServiceException("門票配置不能大於或等於1");
|
||||
throw new ServiceException("门票配置不能大于或等于1");
|
||||
}
|
||||
return ticket;
|
||||
}
|
||||
@@ -843,29 +773,26 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
*/
|
||||
private Long checkDrawParam(List<LuckySeaActDrawParams> params, Long uid) {
|
||||
if (CollectionUtils.isEmpty(params)) {
|
||||
throw new ServiceException("至少需要選中一項");
|
||||
throw new ServiceException("至少需要选中一项");
|
||||
}
|
||||
Long costPieceTotal = 0L;
|
||||
for (LuckySeaActDrawParams param : params) {
|
||||
if (param.getItemId() == null) {
|
||||
throw new ServiceException("itemId不能為空");
|
||||
throw new ServiceException("itemId不能为空");
|
||||
}
|
||||
if (param.getNum() <= 0) {
|
||||
throw new ServiceException("選擇數量需要大於0");
|
||||
throw new ServiceException("选择数量需要大于0");
|
||||
}
|
||||
LuckySeaItem item = luckySeaItemService.getById(param.getItemId());
|
||||
if (null == item || !item.getStatus().equals(Constant.status.valid)) {
|
||||
log.error("选择的配置不存在, itemId:" + param.getItemId());
|
||||
throw new ServiceException("選擇的配置不存在");
|
||||
throw new ServiceException("选择的配置不存在");
|
||||
}
|
||||
costPieceTotal += param.getNum();
|
||||
}
|
||||
// 检查用户碎片是否充足
|
||||
UserActPropertyInfoV2 propertyInfo = userActPropertyInfoV2Service.getUserActPropertyInfo(uid, ActivitesPackTypeEnum.LUCKY_SEA.getValue());
|
||||
|
||||
if (null == propertyInfo || propertyInfo.getPieceNum() < costPieceTotal) {
|
||||
throw new ServiceException(BusiStatus.PIECE_NOT_ENOUGH);
|
||||
}
|
||||
// 扣减用户钻石
|
||||
log.info("【春日游园活动】 uid {} 消耗钻石总数 {}", uid, costPieceTotal);
|
||||
userPurseService.subDiamond(uid, (double)costPieceTotal, Constant.BusinessType.LUCKY_SEA_DRAW);
|
||||
return costPieceTotal;
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
<mapper namespace="com.accompany.business.mybatismapper.activity.LuckySeaPreWarningMapper">
|
||||
<select id="getPreRoundStat" resultType="com.accompany.business.dto.activity.LuckySeaGoldPreWarningDTO">
|
||||
select ifnull(sum(r.cost_piece_num),0) as goldIn,
|
||||
ifnull(sum(if(r.draw_status = 1, r.cost_piece_num * r.item_multiple, 0 )), 0) as goldOut
|
||||
from
|
||||
(select round_id from lucky_sea_act_info where status = 3 order by round_id desc limit #{roundNum}) a, lucky_sea_user_draw_record r
|
||||
where a.round_id = r.round_id;
|
||||
</select>
|
||||
|
||||
<select id="getBroadCastStat" resultType="com.accompany.business.dto.activity.LuckySeaBroadCastDTO">
|
||||
select
|
||||
ifnull(sum(r.cost_piece_num),0) as goldIn,
|
||||
ifnull(sum(if(r.draw_status = 1, r.cost_piece_num * r.item_multiple, 0 )), 0) as goldOut,
|
||||
count(distinct a.round_id) roundNum,
|
||||
count(distinct r.uid) peopleNum
|
||||
from
|
||||
(select round_id from lucky_sea_act_info where status = 3
|
||||
and start_time between #{startTime} and #{endTime}) a
|
||||
left join
|
||||
lucky_sea_user_draw_record r
|
||||
on a.round_id = r.round_id
|
||||
;
|
||||
</select>
|
||||
</mapper>
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user