From ca0d6ad49d3231d7d379826ccc7275e3d939b3c3 Mon Sep 17 00:00:00 2001 From: tianfeng <769204422@qq.com> Date: Tue, 30 Dec 2025 14:24:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=B9=B4=E6=8A=BD=E5=A5=96=E6=B4=BB?= =?UTF-8?q?=E5=8A=A8=E6=B8=B8=E6=88=8F=E5=92=8C=E5=85=85=E5=80=BC=E6=8E=A5?= =?UTF-8?q?=E5=85=A5=E6=8A=BD=E5=A5=96=E5=88=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UserActivityRechargeClientController.java | 85 +++++++++++++++++++ .../game/party3rd/GameHkysRestController.java | 78 +++++++++++++++++ .../service/game/GameBaishunServiceImpl.java | 75 ++++++++++++++++ .../app/service/game/HotGameServiceImpl.java | 74 ++++++++++++++++ .../impl/UserActivityRechargeServiceImpl.java | 3 +- 5 files changed, 314 insertions(+), 1 deletion(-) diff --git a/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/activity/UserActivityRechargeClientController.java b/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/activity/UserActivityRechargeClientController.java index 0d931c5c..bc971ab9 100644 --- a/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/activity/UserActivityRechargeClientController.java +++ b/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/activity/UserActivityRechargeClientController.java @@ -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 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; + } + } } diff --git a/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/game/party3rd/GameHkysRestController.java b/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/game/party3rd/GameHkysRestController.java index b46d4a54..7e360201 100644 --- a/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/game/party3rd/GameHkysRestController.java +++ b/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/game/party3rd/GameHkysRestController.java @@ -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() .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 orderCompensation(@RequestBody JSONObject object) { diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/game/GameBaishunServiceImpl.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/game/GameBaishunServiceImpl.java index 7eee4fa0..1ebf424e 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/game/GameBaishunServiceImpl.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/game/GameBaishunServiceImpl.java @@ -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()) diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/game/HotGameServiceImpl.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/game/HotGameServiceImpl.java index ece075ec..a04359e4 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/game/HotGameServiceImpl.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/game/HotGameServiceImpl.java @@ -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() .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); + } + } + } diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/activity/impl/UserActivityRechargeServiceImpl.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/activity/impl/UserActivityRechargeServiceImpl.java index 56d46cd9..24edcaff 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/activity/impl/UserActivityRechargeServiceImpl.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/activity/impl/UserActivityRechargeServiceImpl.java @@ -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(