新年抽奖活动游戏和充值接入抽奖券

This commit is contained in:
tianfeng 2025-12-30 14:24:52 +08:00
parent 27fe96a76e
commit ca0d6ad49d
5 changed files with 314 additions and 1 deletions

View File

@ -1,28 +1,113 @@
package com.red.circle.other.adapter.app.activity;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.order.inner.model.enums.MonthlyRechargeType;
import com.red.circle.other.app.dto.cmd.SpinsTaskProgressUpdateCmd;
import com.red.circle.other.app.service.SpinsUserTaskProgressService;
import com.red.circle.other.app.util.DateTimeAsiaRiyadhUtils;
import com.red.circle.other.infra.database.rds.service.activity.UserActivityRechargeService;
import com.red.circle.other.inner.endpoint.activity.api.UserActivityRechargeClientApi;
import com.red.circle.tool.core.text.StringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;
/**
* 用户活动充值服务实现
*/
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping(UserActivityRechargeClientApi.API_PREFIX)
public class UserActivityRechargeClientController implements UserActivityRechargeClientApi {
private final UserActivityRechargeService userActivityRechargeService;
private final SpinsUserTaskProgressService spinsUserTaskProgressService;
private final RedisService redisService;
@Override
public ResultResponse<Void> recordRecharge(Long userId, BigDecimal amount, String type) {
userActivityRechargeService.recordRecharge(userId, amount, MonthlyRechargeType.valueOf(type));
handleRechargeTask(userId, amount);
return ResultResponse.success();
}
/**
* 处理充值任务送券
*/
private void handleRechargeTask(Long userId, BigDecimal amount) {
try {
BigDecimal totalAmount = incrementDailyRechargeAmount(userId, amount);
log.info("Spins充值任务, userId={}, amount={}, totalAmount={}", userId, amount, totalAmount);
if (totalAmount.compareTo(BigDecimal.ONE) >= 0) {
spinsUserTaskProgressService.updateTaskProgress(
new SpinsTaskProgressUpdateCmd()
.setUserId(userId)
.setTaskCode("SPINS_RECHARGE_1")
.setProgressValue(1)
);
}
if (totalAmount.compareTo(BigDecimal.TEN) >= 0) {
spinsUserTaskProgressService.updateTaskProgress(
new SpinsTaskProgressUpdateCmd()
.setUserId(userId)
.setTaskCode("SPINS_RECHARGE_10")
.setProgressValue(1)
);
}
if (totalAmount.compareTo(new BigDecimal("50")) >= 0) {
spinsUserTaskProgressService.updateTaskProgress(
new SpinsTaskProgressUpdateCmd()
.setUserId(userId)
.setTaskCode("SPINS_RECHARGE_50")
.setProgressValue(1)
);
}
if (totalAmount.compareTo(new BigDecimal("100")) >= 0) {
spinsUserTaskProgressService.updateTaskProgress(
new SpinsTaskProgressUpdateCmd()
.setUserId(userId)
.setTaskCode("SPINS_RECHARGE_100")
.setProgressValue(1)
);
}
log.info("Spins充值任务处理成功, userId={}, totalAmount={}", userId, totalAmount);
} catch (Exception e) {
log.error("处理Spins充值任务失败, userId={}, amount={}", userId, amount, e);
}
}
/**
* 增加用户每日累计充值金额
* @param userId 用户ID
* @param amount 充值金额
* @return 当前累计充值金额
*/
private BigDecimal incrementDailyRechargeAmount(Long userId, BigDecimal amount) {
String redisKey = "spins:daily:recharge:amount:" + userId;
String amountStr = redisService.getString(redisKey);
if (StringUtils.isBlank(amountStr)) {
long expireSeconds = DateTimeAsiaRiyadhUtils.getSecondsUntilMidnight();
redisService.setString(redisKey, amount.toString(), expireSeconds, TimeUnit.SECONDS);
return amount;
} else {
BigDecimal currentAmount = new BigDecimal(amountStr);
BigDecimal newAmount = currentAmount.add(amount);
long expireSeconds = DateTimeAsiaRiyadhUtils.getSecondsUntilMidnight();
redisService.setString(redisKey, newAmount.toString(), expireSeconds, TimeUnit.SECONDS);
return newAmount;
}
}
}

View File

@ -14,6 +14,7 @@ import com.red.circle.component.game.hkys.response.UpdateUserCoinResponse;
import com.red.circle.component.game.hotgame.response.HotGameCoin;
import com.red.circle.component.game.hotgame.response.HotGameErrorEnum;
import com.red.circle.component.game.hotgame.response.HotGameResponse;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.external.inner.endpoint.message.ImGroupClient;
import com.red.circle.external.inner.model.cmd.message.BroadcastGroupMsgBodyCmd;
import com.red.circle.external.inner.model.enums.message.GroupMessageTypeEnum;
@ -26,9 +27,12 @@ import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.cmd.activity.RankingDataUpdateCmd;
import com.red.circle.other.app.dto.cmd.game.GameLxwlUpdateBalanceCmd;
import com.red.circle.other.app.dto.cmd.game.GameLxwlUserInfoCmd;
import com.red.circle.other.app.dto.cmd.SpinsTaskProgressUpdateCmd;
import com.red.circle.other.app.enums.violation.GameOriginEnum;
import com.red.circle.other.app.enums.violation.ViolationTypeEnum;
import com.red.circle.other.app.service.activity.RankingActivityService;
import com.red.circle.other.app.service.SpinsUserTaskProgressService;
import com.red.circle.other.app.util.DateTimeAsiaRiyadhUtils;
import com.red.circle.other.app.util.OfficialNoticeUtils;
import com.red.circle.other.domain.game.GameRankingIncrementCmd;
import com.red.circle.other.domain.gateway.game.GameRankingGateway;
@ -52,6 +56,7 @@ import com.red.circle.tool.crypto.SecurityUtils;
import java.math.BigDecimal;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -85,6 +90,8 @@ public class GameHkysRestController {
private final GameRankingGateway gameRankingGateway;
private final GameListCacheService gameListCacheService;
private final RankingActivityService rankingActivityService;
private final SpinsUserTaskProgressService spinsUserTaskProgressService;
private final RedisService redisService;
@IgnoreResultResponse
@PostMapping("/getUserInfo")
@ -175,12 +182,18 @@ public class GameHkysRestController {
}
}
// type = 1 是支出 type = 2 是收入
//游戏参与打榜活动
incGameRankingActivity(cmd);
//累计游戏排行榜
incGameRankingRecord(cmd, gameListConfig);
//处理游戏消费任务
handleGameSpendTask(userId, cmd.getType(), cmd.getCoin());
return new HkysResponse<JSONObject>()
.setErrorCode(HyksErrorEnum.SUCCESS.getErrorCode())
.setData(jsonObject);
@ -220,6 +233,71 @@ public class GameHkysRestController {
}
}
/**
* 处理游戏消费任务
*/
private void handleGameSpendTask(Long userId, Integer type, Long amount) {
try {
if (type != 1 || amount <= 0) {
return;
}
// 累计每日游戏消费金额
String redisKey = "spins:daily:game:spend:" + userId;
String totalStr = redisService.getString(redisKey);
long totalSpend;
if (StringUtils.isBlank(totalStr)) {
totalSpend = amount;
long expireSeconds = DateTimeAsiaRiyadhUtils.getSecondsUntilMidnight();
redisService.setString(redisKey, String.valueOf(totalSpend), expireSeconds, TimeUnit.SECONDS);
} else {
long currentTotal = Long.parseLong(totalStr);
// 如果已经超过50000不再处理
if (currentTotal >= 50000) {
log.info("Spins游戏消费任务已达上限, userId={}, totalSpend={}", userId, currentTotal);
return;
}
totalSpend = currentTotal + amount;
long expireSeconds = DateTimeAsiaRiyadhUtils.getSecondsUntilMidnight();
redisService.setString(redisKey, String.valueOf(totalSpend), expireSeconds, TimeUnit.SECONDS);
}
log.info("Spins游戏消费任务, userId={}, spendAmount={}, totalSpend={}", userId, amount, totalSpend);
if (totalSpend >= 5000) {
spinsUserTaskProgressService.updateTaskProgress(
new SpinsTaskProgressUpdateCmd()
.setUserId(userId)
.setTaskCode("SPINS_SPEND_5000")
.setProgressValue(1)
);
}
if (totalSpend >= 10000) {
spinsUserTaskProgressService.updateTaskProgress(
new SpinsTaskProgressUpdateCmd()
.setUserId(userId)
.setTaskCode("SPINS_SPEND_10000")
.setProgressValue(1)
);
}
if (totalSpend >= 50000) {
spinsUserTaskProgressService.updateTaskProgress(
new SpinsTaskProgressUpdateCmd()
.setUserId(userId)
.setTaskCode("SPINS_SPEND_50000")
.setProgressValue(1)
);
}
log.info("Spins游戏消费任务处理成功, userId={}, totalSpend={}", userId, totalSpend);
} catch (Exception e) {
log.error("处理Spins游戏消费任务失败, userId={}, amount={}", userId, amount, e);
}
}
@IgnoreResultResponse
@PostMapping("/orderCompensation")
public HkysResponse<JSONObject> orderCompensation(@RequestBody JSONObject object) {

View File

@ -1,5 +1,6 @@
package com.red.circle.other.app.service.game;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.red.circle.auth.inner.endpoint.AuthClient;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.component.game.baishun.GameBaishunService;
@ -24,10 +25,13 @@ import com.red.circle.framework.core.security.UserCredential;
import com.red.circle.mq.business.model.event.task.TaskApprovalEvent;
import com.red.circle.mq.rocket.business.producer.TaskMqMessage;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.cmd.SpinsTaskProgressUpdateCmd;
import com.red.circle.other.app.dto.cmd.activity.RankingDataUpdateCmd;
import com.red.circle.other.app.enums.violation.GameOriginEnum;
import com.red.circle.other.app.service.SpinsUserTaskProgressService;
import com.red.circle.other.app.service.activity.RankingActivityService;
import com.red.circle.other.app.service.task.TaskService;
import com.red.circle.other.app.util.DateTimeAsiaRiyadhUtils;
import com.red.circle.other.app.util.OfficialNoticeUtils;
import com.red.circle.other.domain.game.GameRankingIncrementCmd;
import com.red.circle.other.domain.gateway.game.GameRankingGateway;
@ -84,6 +88,7 @@ public class GameBaishunServiceImpl implements GameBaishunService {
private final GameRankingGateway gameRankingGateway;
private final GameListCacheService gameListCacheService;
private final TaskService taskService;
private final SpinsUserTaskProgressService spinsUserTaskProgressService;
@Value("${red-circle.game-rank.gameid}")
private String gameId;
@ -202,6 +207,8 @@ public class GameBaishunServiceImpl implements GameBaishunService {
sysOrigin,
() -> gameListConfigService.getByGameId(request.getGameId(), GameOriginEnum.BAISHUN.name(), sysOrigin)
);
// request.getCurrencyDiff() > 0 是收入 request.getCurrencyDiff() < 0 是支出
if (Objects.nonNull(gameListConfig)) {
sendBroadcast(request, gameListConfig);
@ -210,6 +217,9 @@ public class GameBaishunServiceImpl implements GameBaishunService {
//累计游戏排行榜
incGameRankingRecord(request, gameListConfig);
//处理游戏消费任务
handleGameSpendTask(userId, request.getCurrencyDiff());
}
log.warn("{} 发送游戏获奖通知--金币数量{}", GoldOrigin.BAISHUN_GAME.name(), request.getCurrencyDiff());
@ -293,6 +303,71 @@ public class GameBaishunServiceImpl implements GameBaishunService {
}
}
/**
* 处理游戏消费任务
*/
private void handleGameSpendTask(Long userId, Long amount) {
try {
if (amount >= 0) {
return;
}
long spendAmount = Math.abs(amount);
// 累计每日游戏消费金额
String redisKey = "spins:daily:game:spend:" + userId;
String totalStr = redisService.getString(redisKey);
long totalSpend;
if (StringUtils.isBlank(totalStr)) {
totalSpend = spendAmount;
long expireSeconds = DateTimeAsiaRiyadhUtils.getSecondsUntilMidnight();
redisService.setString(redisKey, String.valueOf(totalSpend), expireSeconds, TimeUnit.SECONDS);
} else {
long currentTotal = Long.parseLong(totalStr);
// 如果已经超过50000不再处理
if (currentTotal >= 50000) {
log.info("Spins游戏消费任务已达上限, userId={}, totalSpend={}", userId, currentTotal);
return;
}
totalSpend = currentTotal + spendAmount;
long expireSeconds = DateTimeAsiaRiyadhUtils.getSecondsUntilMidnight();
redisService.setString(redisKey, String.valueOf(totalSpend), expireSeconds, TimeUnit.SECONDS);
}
if (totalSpend >= 5000) {
spinsUserTaskProgressService.updateTaskProgress(
new SpinsTaskProgressUpdateCmd()
.setUserId(userId)
.setTaskCode("SPINS_SPEND_5000")
.setProgressValue(1)
);
}
if (totalSpend >= 10000) {
spinsUserTaskProgressService.updateTaskProgress(
new SpinsTaskProgressUpdateCmd()
.setUserId(userId)
.setTaskCode("SPINS_SPEND_10000")
.setProgressValue(1)
);
}
if (totalSpend >= 50000) {
spinsUserTaskProgressService.updateTaskProgress(
new SpinsTaskProgressUpdateCmd()
.setUserId(userId)
.setTaskCode("SPINS_SPEND_50000")
.setProgressValue(1)
);
}
log.info("Spins游戏消费任务处理成功, userId={}, totalSpend={}", userId, totalSpend);
} catch (Exception e) {
log.error("处理Spins游戏消费任务失败, userId={}, amount={}", userId, amount, e);
}
}
private GoldReceiptCmd createReceipt(BaishunChangeCurrencyRequest param) {
UserCredential userCredential = UserCredential.parseToken(param.getToken());
return createGoldReceiptCmdBuilder(param.getCurrencyDiff())

View File

@ -23,10 +23,13 @@ import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.clientobject.game.HotGameUpdateRequest;
import com.red.circle.other.app.dto.cmd.activity.RankingDataUpdateCmd;
import com.red.circle.other.app.dto.cmd.game.GameLxwlUpdateBalanceCmd;
import com.red.circle.other.app.dto.cmd.SpinsTaskProgressUpdateCmd;
import com.red.circle.other.app.enums.violation.GameOriginEnum;
import com.red.circle.other.app.service.activity.RankingActivityService;
import com.red.circle.other.app.service.game.override.domain.HotGameUserProfile;
import com.red.circle.other.app.service.game.override.service.HotGameService;
import com.red.circle.other.app.service.SpinsUserTaskProgressService;
import com.red.circle.other.app.util.DateTimeAsiaRiyadhUtils;
import com.red.circle.other.app.util.OfficialNoticeUtils;
import com.red.circle.other.domain.game.GameRankingIncrementCmd;
import com.red.circle.other.domain.gateway.game.GameRankingGateway;
@ -92,6 +95,7 @@ public class HotGameServiceImpl implements HotGameService {
private final GameRankingGateway gameRankingGateway;
private final GameListCacheService gameListCacheService;
private final RankingActivityService rankingActivityService;
private final SpinsUserTaskProgressService spinsUserTaskProgressService;
@Value("${red-circle.game-rank.gameid}")
private String gameId;
@Value("${red-circle.game-rank.endTime}")
@ -225,6 +229,8 @@ public class HotGameServiceImpl implements HotGameService {
sysOrigin,
() -> gameListConfigService.getByGameId(param.getGameId(), GameOriginEnum.HOTGAME.name(), sysOrigin)
);
// type = 1 支出 type = 2 收入
sendBroadcast(param, gameListConfig);
//累计游戏排行榜
incGameRankingRecord(param, gameListConfig);
@ -234,6 +240,9 @@ public class HotGameServiceImpl implements HotGameService {
//FruitParty
incGameRankingTmpActivity(param);
//处理游戏消费任务
handleGameSpendTask(userId, param.getType(), param.getCoin());
return new HotGameResponse<HotGameCoin>()
.setData(new HotGameCoin()
.setBalanceCoin(res.getBalance().getDollarAmount().longValue())
@ -367,4 +376,69 @@ public class HotGameServiceImpl implements HotGameService {
.build();
}
/**
* 处理游戏消费任务
*/
private void handleGameSpendTask(Long userId, Integer type, Long amount) {
try {
if (type != 1 || amount <= 0) {
return;
}
// 累计每日游戏消费金额
String redisKey = "spins:daily:game:spend:" + userId;
String totalStr = redisService.getString(redisKey);
long totalSpend;
if (StringUtils.isBlank(totalStr)) {
totalSpend = amount;
long expireSeconds = DateTimeAsiaRiyadhUtils.getSecondsUntilMidnight();
redisService.setString(redisKey, String.valueOf(totalSpend), expireSeconds, TimeUnit.SECONDS);
} else {
long currentTotal = Long.parseLong(totalStr);
// 如果已经超过50000不再处理
if (currentTotal >= 50000) {
log.info("Spins游戏消费任务已达上限, userId={}, totalSpend={}", userId, currentTotal);
return;
}
totalSpend = currentTotal + amount;
long expireSeconds = DateTimeAsiaRiyadhUtils.getSecondsUntilMidnight();
redisService.setString(redisKey, String.valueOf(totalSpend), expireSeconds, TimeUnit.SECONDS);
}
log.info("Spins游戏消费任务, userId={}, spendAmount={}, totalSpend={}", userId, amount, totalSpend);
if (totalSpend >= 5000) {
spinsUserTaskProgressService.updateTaskProgress(
new SpinsTaskProgressUpdateCmd()
.setUserId(userId)
.setTaskCode("SPINS_SPEND_5000")
.setProgressValue(1)
);
}
if (totalSpend >= 10000) {
spinsUserTaskProgressService.updateTaskProgress(
new SpinsTaskProgressUpdateCmd()
.setUserId(userId)
.setTaskCode("SPINS_SPEND_10000")
.setProgressValue(1)
);
}
if (totalSpend >= 50000) {
spinsUserTaskProgressService.updateTaskProgress(
new SpinsTaskProgressUpdateCmd()
.setUserId(userId)
.setTaskCode("SPINS_SPEND_50000")
.setProgressValue(1)
);
}
log.info("Spins游戏消费任务处理成功, userId={}, totalSpend={}", userId, totalSpend);
} catch (Exception e) {
log.error("处理Spins游戏消费任务失败, userId={}, amount={}", userId, amount, e);
}
}
}

View File

@ -3,6 +3,7 @@ package com.red.circle.other.infra.database.rds.service.activity.impl;
import com.red.circle.order.inner.model.enums.MonthlyRechargeType;
import com.red.circle.other.infra.database.rds.dao.activity.UserActivityRechargeDAO;
import com.red.circle.other.infra.database.rds.service.activity.UserActivityRechargeService;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@ -27,7 +28,7 @@ public class UserActivityRechargeServiceImpl implements UserActivityRechargeServ
@Override
public void recordRecharge(Long userId, BigDecimal amount, MonthlyRechargeType type) {
LocalDate today = LocalDate.now();
LocalDate today = ZonedDateTimeAsiaRiyadhUtils.now().toLocalDate();
String rechargeDate = today.toString();
int result = userActivityRechargeDAO.incrAmount(