新增抽奖背包道具流水

This commit is contained in:
tianfeng 2026-01-16 15:27:09 +08:00
parent 8c442abcad
commit 0117f1b5f5
10 changed files with 215 additions and 3 deletions

View File

@ -1,5 +1,6 @@
package com.red.circle.other.app.command.activity;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.framework.core.asserts.ResponseAssert;
@ -26,6 +27,7 @@ import com.red.circle.other.infra.database.rds.service.activity.LotteryDeviceRec
import com.red.circle.other.infra.database.rds.service.activity.UserActivityRechargeService;
import com.red.circle.other.infra.database.rds.entity.activity.LotteryDeviceRecord;
import com.red.circle.other.infra.database.rds.service.user.device.LatestMobileDeviceService;
import com.red.circle.other.infra.gateway.lottery.LotteryBackpackGateway;
import com.red.circle.other.infra.utils.ZonedDateTimeUtils;
import com.red.circle.other.inner.asserts.OtherErrorCode;
import com.red.circle.other.inner.asserts.lottery.LotteryErrorCode;
@ -37,6 +39,7 @@ import java.time.temporal.WeekFields;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
@ -74,6 +77,7 @@ public class LotteryDrawExe {
private final LotteryDeviceRecordService lotteryDeviceRecordService;
private final UserActivityRechargeService userActivityRechargeService;
private final WalletGoldClient walletGoldClient;
private final LotteryBackpackGateway lotteryBackpackGateway;
@Transactional(rollbackFor = Exception.class)
public LotteryDrawResultCO execute(LotteryDrawCmd cmd) {
@ -123,6 +127,11 @@ public class LotteryDrawExe {
// 10. 发放奖励
if (prize != null) {
lotteryPrizeGrantService.grantPrize(userId, prize, record.getRecordNo());
if (Objects.equals(prize.getPrizeType(), "FRAGMENTS")) {
String addBizNo = "lottery_add:" + IdWorker.getTimeId();
lotteryBackpackGateway.recordFragmentAdd(userId, prize.getPrizeValue().intValue(), "lottery", addBizNo);
}
}
// 11. 更新用户抽奖次数
@ -539,6 +548,9 @@ public class LotteryDrawExe {
records.add(ticketRecord);
remaining -= deduct;
String deductBizNo = "lottery_deduct:" + IdWorker.getIdStr();
lotteryBackpackGateway.recordTicketDeduct(userId, deduct, "lottery", deductBizNo);
}
if (!records.isEmpty()) {

View File

@ -1,5 +1,6 @@
package com.red.circle.other.app.command.activity;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.framework.core.asserts.ResponseAssert;
@ -25,6 +26,7 @@ import com.red.circle.other.infra.database.rds.service.activity.LotteryUserProgr
import com.red.circle.other.infra.database.rds.service.activity.LotteryDeviceRecordService;
import com.red.circle.other.infra.database.rds.service.activity.UserActivityRechargeService;
import com.red.circle.other.infra.database.rds.service.user.device.LatestMobileDeviceService;
import com.red.circle.other.infra.gateway.lottery.LotteryBackpackGateway;
import com.red.circle.other.infra.utils.ZonedDateTimeUtils;
import com.red.circle.other.inner.asserts.OtherErrorCode;
import com.red.circle.other.inner.asserts.lottery.LotteryErrorCode;
@ -36,6 +38,7 @@ import java.time.temporal.WeekFields;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
@ -73,6 +76,7 @@ public class LotteryMultiDrawExe {
private final LotteryDeviceRecordService lotteryDeviceRecordService;
private final UserActivityRechargeService userActivityRechargeService;
private final WalletGoldClient walletGoldClient;
private final LotteryBackpackGateway lotteryBackpackGateway;
@Transactional(rollbackFor = Exception.class)
public LotteryMultiDrawResultCO execute(LotteryMultiDrawCmd cmd) {
@ -146,6 +150,11 @@ public class LotteryMultiDrawExe {
// 发放奖励
if (prize != null) {
lotteryPrizeGrantService.grantPrize(userId, prize, record.getRecordNo());
if (Objects.equals(prize.getPrizeType(), "FRAGMENTS")) {
String addBizNo = "lottery_add:" + IdWorker.getTimeId();
lotteryBackpackGateway.recordFragmentAdd(userId, prize.getPrizeValue().intValue(), "lottery", addBizNo);
}
}
// 临时更新用户进度用于下次抽奖判断阶段
@ -512,6 +521,9 @@ public class LotteryMultiDrawExe {
ticketRecord.setRemark("连抽消耗");
records.add(ticketRecord);
remaining -= deduct;
String deductBizNo = "lottery_deduct:" + IdWorker.getTimeId();
lotteryBackpackGateway.recordTicketDeduct(userId, deduct, "lottery", deductBizNo);
}
if (!records.isEmpty()) {
lotteryTicketRecordService.saveBatch(records);

View File

@ -3,6 +3,7 @@ package com.red.circle.other.app.command.activity;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.common.business.enums.SendPropsOrigin;
import com.red.circle.framework.core.asserts.ResponseAssert;
@ -13,6 +14,7 @@ import com.red.circle.other.infra.common.activity.PropsActivitySendCommon;
import com.red.circle.other.infra.common.activity.send.SendRewardParam;
import com.red.circle.other.infra.database.mongo.entity.game.egg.GameEggStockConfig;
import com.red.circle.other.infra.database.rds.entity.game.GameUserShardsBackpack;
import com.red.circle.other.infra.gateway.lottery.LotteryBackpackGateway;
import com.red.circle.other.inner.endpoint.activity.PropsActivityClient;
import com.red.circle.other.inner.endpoint.material.props.FragmentsBackpackClient;
import com.red.circle.other.inner.endpoint.material.props.api.FragmentsBackpackClientApi;
@ -43,7 +45,7 @@ public class WeekStarExchangeExe {
private final PropsActivitySendCommon sendPropsManager;
private final PropsActivityClient propsActivityClient;
private final FragmentsBackpackClient fragmentsBackpackClient;
private final LotteryBackpackGateway lotteryBackpackGateway;
public Long execute(WeekStarExchangeCmd cmd) {
@ -89,6 +91,10 @@ public class WeekStarExchangeExe {
needFragments
);
// 记录碎片扣除
String bizNo = "exchange:" + IdWorker.getTimeId();
lotteryBackpackGateway.recordFragmentDeduct(cmd.getUserId(), needFragments, "exchange", bizNo);
// 发送奖品
sendPropsManager.sendGroup(SendRewardParam.builder()
.acceptUserId(cmd.getUserId())

View File

@ -15,6 +15,7 @@ import com.red.circle.other.infra.database.rds.entity.SignInDailyConfig;
import com.red.circle.other.infra.database.rds.entity.UserSignInRecord;
import com.red.circle.other.infra.database.rds.entity.activity.PropsActivityRewardConfig;
import com.red.circle.other.infra.database.rds.service.activity.PropsActivityRewardConfigService;
import com.red.circle.other.infra.gateway.lottery.LotteryBackpackGateway;
import com.red.circle.other.inner.asserts.OtherErrorCode;
import com.red.circle.other.inner.endpoint.activity.LotteryTicketClient;
import com.red.circle.other.inner.model.cmd.material.PrizeDescribe;
@ -46,6 +47,7 @@ public class SignCheckInExe {
private final PropsSendCommon propsSendCommon;
private final PropsActivityRewardConfigService propsActivityRewardConfigService;
private final LotteryTicketClient lotteryTicketClient;
private final LotteryBackpackGateway lotteryBackpackGateway;
private final static Long FIXED_ACTIVITY_ID = 2004471533988167125L;
@ -109,6 +111,10 @@ public class SignCheckInExe {
// 发放抽奖券
sendLotteryTickets(userId, config, record.getId());
// 记录抽奖券流水
String bizNo = "sign:" + saudiToday + ":" + userId;
lotteryBackpackGateway.recordTicketAdd(userId, config.getLotteryTicketCount(), "sign_in", bizNo);
CheckInResultCO resultCO = new CheckInResultCO();
resultCO.setSuccess(true);
resultCO.setMessage("Sign-in successful");
@ -170,7 +176,7 @@ public class SignCheckInExe {
Long ticketId = lotteryTicketClient.addTicket(
userId,
FIXED_ACTIVITY_ID,
1,
config.getLotteryTicketCount(),
"SIGN_IN",
"SIGN_IN_DAY_" + config.getDayIndex()
).getBody();

View File

@ -14,6 +14,7 @@ import com.red.circle.other.infra.database.rds.entity.SignInDailyConfig;
import com.red.circle.other.infra.database.rds.entity.UserSignInRecord;
import com.red.circle.other.infra.database.rds.entity.activity.PropsActivityRewardConfig;
import com.red.circle.other.infra.database.rds.service.activity.PropsActivityRewardConfigService;
import com.red.circle.other.infra.gateway.lottery.LotteryBackpackGateway;
import com.red.circle.other.inner.asserts.OtherErrorCode;
import com.red.circle.other.inner.endpoint.activity.LotteryTicketClient;
import com.red.circle.other.inner.model.cmd.material.PrizeDescribe;
@ -44,6 +45,7 @@ public class SupplementCheckInExe {
private final PropsSendCommon propsSendCommon;
private final PropsActivityRewardConfigService propsActivityRewardConfigService;
private final LotteryTicketClient lotteryTicketClient;
private final LotteryBackpackGateway lotteryBackpackGateway;
private final static Long FIXED_ACTIVITY_ID = 2004471533988167125L;
@ -112,6 +114,9 @@ public class SupplementCheckInExe {
// 发放抽奖券
sendLotteryTickets(userId, config, record.getId());
String bizNo = "supplement:" + saudiToday + "_" + targetDayIndex + ":" + userId;
lotteryBackpackGateway.recordTicketAdd(userId, config.getLotteryTicketCount(), "sign_in", bizNo);
CheckInResultCO resultCO = new CheckInResultCO();
resultCO.setSuccess(true);
resultCO.setMessage("Make-up successful");
@ -175,7 +180,7 @@ public class SupplementCheckInExe {
Long ticketId = lotteryTicketClient.addTicket(
userId,
FIXED_ACTIVITY_ID,
1,
config.getLotteryTicketCount(),
"SIGN_IN",
"SIGN_IN_DAY_" + config.getDayIndex()
).getBody();

View File

@ -0,0 +1,10 @@
package com.red.circle.other.infra.database.rds.dao;
import com.red.circle.framework.mybatis.dao.BaseDAO;
import com.red.circle.other.infra.database.rds.entity.LotteryBackpackLog;
/**
* 抽奖背包流水DAO
*/
public interface LotteryBackpackLogDAO extends BaseDAO<LotteryBackpackLog> {
}

View File

@ -0,0 +1,39 @@
package com.red.circle.other.infra.database.rds.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 抽奖背包流水表
*/
@Data
@TableName("lottery_backpack_log")
public class LotteryBackpackLog {
@TableId(type = IdType.AUTO)
private Long id;
private Long userId;
private String bizNo;
private String itemType;
private String itemName;
private String itemIcon;
private Integer changeType;
private Integer changeAmount;
private String source;
private String sourceId;
private LocalDateTime createdAt;
}

View File

@ -0,0 +1,29 @@
package com.red.circle.other.infra.database.rds.service.lottery;
import com.red.circle.other.infra.database.rds.dao.LotteryBackpackLogDAO;
import com.red.circle.other.infra.database.rds.entity.LotteryBackpackLog;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* 抽奖背包流水数据库服务
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class LotteryBackpackLogDatabaseService {
private final LotteryBackpackLogDAO lotteryBackpackLogDAO;
/**
* 保存流水记录
*/
public void save(LotteryBackpackLog log) {
try {
lotteryBackpackLogDAO.insert(log);
} catch (Exception e) {
}
}
}

View File

@ -0,0 +1,27 @@
package com.red.circle.other.infra.gateway.lottery;
/**
* 抽奖背包网关
*/
public interface LotteryBackpackGateway {
/**
* 记录抽奖券增加
*/
void recordTicketAdd(Long userId, Integer amount, String source, String bizNo);
/**
* 记录抽奖券扣除
*/
void recordTicketDeduct(Long userId, Integer amount, String source, String bizNo);
/**
* 记录碎片增加
*/
void recordFragmentAdd(Long userId, Integer amount, String source, String bizNo);
/**
* 记录碎片扣除
*/
void recordFragmentDeduct(Long userId, Integer amount, String source, String bizNo);
}

View File

@ -0,0 +1,66 @@
package com.red.circle.other.infra.gateway.lottery.impl;
import com.red.circle.other.infra.database.rds.entity.LotteryBackpackLog;
import com.red.circle.other.infra.database.rds.service.lottery.LotteryBackpackLogDatabaseService;
import com.red.circle.other.infra.gateway.lottery.LotteryBackpackGateway;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
/**
* 抽奖背包网关实现
*/
@Component
@RequiredArgsConstructor
public class LotteryBackpackGatewayImpl implements LotteryBackpackGateway {
private static final Long FIXED_ACTIVITY_ID = 2004471533988167125L;
private final LotteryBackpackLogDatabaseService logDatabaseService;
@Override
public void recordTicketAdd(Long userId, Integer amount, String source, String bizNo) {
LotteryBackpackLog log = buildLog(userId, "lottery_ticket", "水晶",
"https://xxx.com/crystal.png", 1, amount, source, bizNo);
logDatabaseService.save(log);
}
@Override
public void recordTicketDeduct(Long userId, Integer amount, String source, String bizNo) {
LotteryBackpackLog log = buildLog(userId, "lottery_ticket", "水晶",
"https://xxx.com/crystal.png", 2, amount, source, bizNo);
logDatabaseService.save(log);
}
@Override
public void recordFragmentAdd(Long userId, Integer amount, String source, String bizNo) {
LotteryBackpackLog log = buildLog(userId, "cp_fragment", "碎片",
"https://xxx.com/fragment.png", 1, amount, source, bizNo);
logDatabaseService.save(log);
}
@Override
public void recordFragmentDeduct(Long userId, Integer amount, String source, String bizNo) {
LotteryBackpackLog log = buildLog(userId, "cp_fragment", "碎片",
"https://xxx.com/fragment.png", 2, amount, source, bizNo);
logDatabaseService.save(log);
}
private LotteryBackpackLog buildLog(Long userId, String itemType, String itemName,
String itemIcon, Integer changeType, Integer changeAmount,
String source, String bizNo) {
LotteryBackpackLog log = new LotteryBackpackLog();
log.setUserId(userId);
log.setItemType(itemType);
log.setItemName(itemName);
log.setItemIcon(itemIcon);
log.setChangeType(changeType);
log.setChangeAmount(changeAmount);
log.setSource(source);
log.setSourceId(String.valueOf(FIXED_ACTIVITY_ID));
log.setBizNo(bizNo);
log.setCreatedAt(LocalDateTime.now());
return log;
}
}