diff --git a/rc-common-business/common-business-dto/src/main/java/com/red/circle/common/business/enums/DiamondOrigin.java b/rc-common-business/common-business-dto/src/main/java/com/red/circle/common/business/enums/DiamondOrigin.java index 36acf399..a4b2929c 100644 --- a/rc-common-business/common-business-dto/src/main/java/com/red/circle/common/business/enums/DiamondOrigin.java +++ b/rc-common-business/common-business-dto/src/main/java/com/red/circle/common/business/enums/DiamondOrigin.java @@ -320,7 +320,10 @@ public enum DiamondOrigin { */ DEDUCT_DIAMOND("Deduct diamonds"), - + /** + * lottery 奖励 + */ + LOTTERY_REWARD("Lottery Diamonds Rewards"), ; diff --git a/rc-common-business/common-business-dto/src/main/java/com/red/circle/common/business/enums/SendPropsOrigin.java b/rc-common-business/common-business-dto/src/main/java/com/red/circle/common/business/enums/SendPropsOrigin.java index 7a85823c..4d5a2bb2 100644 --- a/rc-common-business/common-business-dto/src/main/java/com/red/circle/common/business/enums/SendPropsOrigin.java +++ b/rc-common-business/common-business-dto/src/main/java/com/red/circle/common/business/enums/SendPropsOrigin.java @@ -254,6 +254,11 @@ public enum SendPropsOrigin { */ MEMBER_ACTIVE_TASK_REWARD("member activity Reward"), + /** + * lottery 奖励 + */ + LOTTERY_REWARD("Lottery Rewards"), + ; private final String desc; diff --git a/rc-service/lottery_system_init.sql b/rc-service/lottery_system_init.sql deleted file mode 100644 index acc3a266..00000000 --- a/rc-service/lottery_system_init.sql +++ /dev/null @@ -1,125 +0,0 @@ -# 抽奖系统数据库初始化SQL - -## 1. 抽奖活动表 -```sql -CREATE TABLE lottery_activity ( - id BIGINT PRIMARY KEY AUTO_INCREMENT, - activity_code VARCHAR(50) UNIQUE NOT NULL COMMENT '活动编码', - activity_name VARCHAR(100) NOT NULL COMMENT '活动名称', - activity_desc VARCHAR(500) COMMENT '活动描述', - start_time DATETIME NOT NULL COMMENT '开始时间', - end_time DATETIME NOT NULL COMMENT '结束时间', - status TINYINT DEFAULT 0 COMMENT '状态:0-未开始,1-进行中,2-已结束,3-已关闭', - total_stock INT DEFAULT 0 COMMENT '总奖品库存', - consumed_stock INT DEFAULT 0 COMMENT '已消耗库存', - draw_count_limit INT DEFAULT 0 COMMENT '每人抽奖次数限制(0为不限制)', - draw_count_cycle VARCHAR(20) COMMENT '次数限制周期:DAILY-每天,TOTAL-总计', - need_ticket TINYINT DEFAULT 0 COMMENT '是否需要抽奖券:0-否,1-是', - ticket_cost INT DEFAULT 1 COMMENT '每次消耗抽奖券数量', - sort_order INT DEFAULT 0 COMMENT '排序', - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - INDEX idx_status_time (status, start_time, end_time), - INDEX idx_code (activity_code) -) COMMENT '抽奖活动表'; -``` - -## 2. 奖品配置表 -```sql -CREATE TABLE lottery_prize ( - id BIGINT PRIMARY KEY AUTO_INCREMENT, - activity_id BIGINT NOT NULL COMMENT '活动ID', - prize_code VARCHAR(50) NOT NULL COMMENT '奖品编码', - prize_name VARCHAR(100) NOT NULL COMMENT '奖品名称', - prize_type TINYINT NOT NULL COMMENT '奖品类型:1-实物,2-虚拟币,3-优惠券,4-积分,5-谢谢参与', - prize_value DECIMAL(10,2) COMMENT '奖品价值/数量', - prize_image VARCHAR(200) COMMENT '奖品图片', - prize_level TINYINT COMMENT '奖品等级:1-特等奖,2-一等奖,3-二等奖...', - total_stock INT NOT NULL COMMENT '总库存', - remaining_stock INT NOT NULL COMMENT '剩余库存', - daily_stock INT DEFAULT 0 COMMENT '每日库存限制(0为不限制)', - probability DECIMAL(10,6) NOT NULL COMMENT '中奖概率(0-1之间)', - sort_order INT DEFAULT 0 COMMENT '排序(九宫格位置)', - is_display TINYINT DEFAULT 1 COMMENT '是否展示:0-否,1-是', - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - INDEX idx_activity (activity_id), - INDEX idx_code (prize_code), - UNIQUE KEY uk_activity_code (activity_id, prize_code) -) COMMENT '奖品配置表'; -``` - -## 3. 中奖记录表 -```sql -CREATE TABLE lottery_record ( - id BIGINT PRIMARY KEY AUTO_INCREMENT, - record_no VARCHAR(50) UNIQUE NOT NULL COMMENT '记录编号', - user_id BIGINT NOT NULL COMMENT '用户ID', - activity_id BIGINT NOT NULL COMMENT '活动ID', - prize_id BIGINT COMMENT '奖品ID(未中奖为NULL)', - prize_name VARCHAR(100) COMMENT '奖品名称快照', - prize_type TINYINT COMMENT '奖品类型快照', - is_win TINYINT NOT NULL COMMENT '是否中奖:0-未中奖,1-中奖', - draw_time DATETIME NOT NULL COMMENT '抽奖时间', - prize_status TINYINT DEFAULT 0 COMMENT '奖品状态:0-待发放,1-已发放,2-发放失败', - deliver_time DATETIME COMMENT '发放时间', - remark VARCHAR(500) COMMENT '备注', - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - INDEX idx_user_activity (user_id, activity_id), - INDEX idx_draw_time (draw_time), - INDEX idx_activity_win (activity_id, is_win), - INDEX idx_record_no (record_no) -) COMMENT '中奖记录表'; -``` - -## 4. 抽奖券表 -```sql -CREATE TABLE lottery_ticket ( - id BIGINT PRIMARY KEY AUTO_INCREMENT, - user_id BIGINT NOT NULL COMMENT '用户ID', - ticket_source VARCHAR(50) COMMENT '来源:SYSTEM-系统发放,ACTIVITY-活动赠送,PURCHASE-购买', - source_id VARCHAR(50) COMMENT '来源ID', - total_count INT NOT NULL COMMENT '总数量', - used_count INT DEFAULT 0 COMMENT '已使用数量', - remaining_count INT NOT NULL COMMENT '剩余数量', - expire_time DATETIME COMMENT '过期时间', - status TINYINT DEFAULT 1 COMMENT '状态:0-已失效,1-正常', - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - INDEX idx_user_status (user_id, status), - INDEX idx_expire (expire_time) -) COMMENT '抽奖券表'; -``` - -## 5. 抽奖券使用记录表 -```sql -CREATE TABLE lottery_ticket_record ( - id BIGINT PRIMARY KEY AUTO_INCREMENT, - user_id BIGINT NOT NULL COMMENT '用户ID', - ticket_id BIGINT NOT NULL COMMENT '抽奖券ID', - change_count INT NOT NULL COMMENT '变动数量(正数增加,负数减少)', - change_type TINYINT NOT NULL COMMENT '变动类型:1-发放,2-消耗,3-过期,4-退回', - lottery_record_id BIGINT COMMENT '关联的抽奖记录ID', - remark VARCHAR(200) COMMENT '备注', - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - INDEX idx_user (user_id), - INDEX idx_ticket (ticket_id), - INDEX idx_lottery_record (lottery_record_id) -) COMMENT '抽奖券使用记录表'; -``` - -## 6. 用户抽奖次数统计表 -```sql -CREATE TABLE lottery_user_count ( - id BIGINT PRIMARY KEY AUTO_INCREMENT, - user_id BIGINT NOT NULL COMMENT '用户ID', - activity_id BIGINT NOT NULL COMMENT '活动ID', - draw_date DATE NOT NULL COMMENT '统计日期', - draw_count INT DEFAULT 0 COMMENT '抽奖次数', - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - UNIQUE KEY uk_user_activity_date (user_id, activity_id, draw_date), - INDEX idx_user_activity (user_id, activity_id) -) COMMENT '用户抽奖次数统计表'; -``` diff --git a/rc-service/rc-inner-api/other-inner/other-inner-model/src/main/java/com/red/circle/other/inner/enums/sys/SysCurrencySendReasonEnum.java b/rc-service/rc-inner-api/other-inner/other-inner-model/src/main/java/com/red/circle/other/inner/enums/sys/SysCurrencySendReasonEnum.java index 710200ea..46d19465 100644 --- a/rc-service/rc-inner-api/other-inner/other-inner-model/src/main/java/com/red/circle/other/inner/enums/sys/SysCurrencySendReasonEnum.java +++ b/rc-service/rc-inner-api/other-inner/other-inner-model/src/main/java/com/red/circle/other/inner/enums/sys/SysCurrencySendReasonEnum.java @@ -14,7 +14,9 @@ public enum SysCurrencySendReasonEnum { REWARD(1, "奖励"), INTERNAL(2, "内部"), WAGE(3, "工资"), - OTHER(4, "其他"); + OTHER(4, "其他"), + LOTTERY(5, "抽奖"), + ; private final Integer type; private final String typeName; diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/LotteryDrawExe.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/LotteryDrawExe.java index ea2c8cf8..24c81964 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/LotteryDrawExe.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/LotteryDrawExe.java @@ -4,6 +4,7 @@ import com.red.circle.framework.core.asserts.ResponseAssert; import com.red.circle.other.app.dto.clientobject.activity.LotteryDrawResultCO; import com.red.circle.other.app.dto.clientobject.activity.LotteryPrizeCO; import com.red.circle.other.app.dto.cmd.activity.LotteryDrawCmd; +import com.red.circle.other.app.service.activity.LotteryPrizeGrantService; import com.red.circle.other.infra.database.rds.entity.activity.LotteryActivity; import com.red.circle.other.infra.database.rds.entity.activity.LotteryPrize; import com.red.circle.other.infra.database.rds.entity.activity.LotteryRecord; @@ -53,6 +54,7 @@ public class LotteryDrawExe { private final LotteryTicketRecordService lotteryTicketRecordService; private final LotteryUserCountService lotteryUserCountService; private final LotteryUserProgressService lotteryUserProgressService; + private final LotteryPrizeGrantService lotteryPrizeGrantService; @Transactional(rollbackFor = Exception.class) public LotteryDrawResultCO execute(LotteryDrawCmd cmd) { @@ -89,13 +91,18 @@ public class LotteryDrawExe { // 7. 保存抽奖记录 LotteryRecord record = saveDrawRecord(userId, activityId, prize, now, null, 1); - // 8. 更新用户抽奖次数 + // 8. 发放奖励 + if (prize != null) { + lotteryPrizeGrantService.grantPrize(userId, prize, record.getRecordNo()); + } + + // 9. 更新用户抽奖次数 updateUserDrawCount(userId, activityId); - // 9. 更新用户进度(累加金额和次数) + // 10. 更新用户进度(累加金额和次数) updateUserProgress(progress, prize); - // 10. 组装返回结果 + // 11. 组装返回结果 return convertToResultCO(record, prize); } diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/LotteryMultiDrawExe.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/LotteryMultiDrawExe.java index 03f0cb1f..4a98246b 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/LotteryMultiDrawExe.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/LotteryMultiDrawExe.java @@ -5,6 +5,7 @@ import com.red.circle.other.app.dto.clientobject.activity.LotteryDrawResultCO; import com.red.circle.other.app.dto.clientobject.activity.LotteryMultiDrawResultCO; import com.red.circle.other.app.dto.clientobject.activity.LotteryPrizeCO; import com.red.circle.other.app.dto.cmd.activity.LotteryMultiDrawCmd; +import com.red.circle.other.app.service.activity.LotteryPrizeGrantService; import com.red.circle.other.infra.database.rds.entity.activity.LotteryActivity; import com.red.circle.other.infra.database.rds.entity.activity.LotteryPrize; import com.red.circle.other.infra.database.rds.entity.activity.LotteryRecord; @@ -54,6 +55,7 @@ public class LotteryMultiDrawExe { private final LotteryTicketRecordService lotteryTicketRecordService; private final LotteryUserCountService lotteryUserCountService; private final LotteryUserProgressService lotteryUserProgressService; + private final LotteryPrizeGrantService lotteryPrizeGrantService; @Transactional(rollbackFor = Exception.class) public LotteryMultiDrawResultCO execute(LotteryMultiDrawCmd cmd) { @@ -113,6 +115,11 @@ public class LotteryMultiDrawExe { LotteryRecord record = saveDrawRecord(userId, activityId, prize, now, batchNo, 2); results.add(convertToResultCO(record, prize)); + // 发放奖励 + if (prize != null) { + lotteryPrizeGrantService.grantPrize(userId, prize, record.getRecordNo()); + } + // 临时更新用户进度(用于下次抽奖判断阶段) if (prize != null && prize.getPrizeValue() != null) { BigDecimal prizeValue = prize.getPrizeValue(); @@ -340,10 +347,15 @@ public class LotteryMultiDrawExe { record.setPrizeType(guaranteePrize.getPrizeType()); record.setIsWin(1); lotteryRecordService.updateSelectiveById(record); + results.set(replaceIndex, convertToResultCO(record, guaranteePrize)); + + // 发放保底奖励 + lotteryPrizeGrantService.grantPrize(userId, guaranteePrize, record.getRecordNo()); } - results.set(replaceIndex, convertToResultCO(record, guaranteePrize)); + updateUserProgress(progress, guaranteePrize); } + } private LotteryPrize getGuaranteePrize(Long activityId, Long guaranteePrizeId) { diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/activity/LotteryPrizeGrantService.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/activity/LotteryPrizeGrantService.java new file mode 100644 index 00000000..d3f3bbc7 --- /dev/null +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/activity/LotteryPrizeGrantService.java @@ -0,0 +1,22 @@ +package com.red.circle.other.app.service.activity; + +import com.red.circle.other.infra.database.rds.entity.activity.LotteryPrize; + +/** + * 抽奖奖励发放服务. + * + * @author system + * @since 2025-10-21 + */ +public interface LotteryPrizeGrantService { + + /** + * 发放奖励. + * + * @param userId 用户ID + * @param prize 奖品信息 + * @param recordNo 抽奖记录编号 + */ + void grantPrize(Long userId, LotteryPrize prize, String recordNo); + +} diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/activity/impl/LotteryPrizeGrantServiceImpl.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/activity/impl/LotteryPrizeGrantServiceImpl.java new file mode 100644 index 00000000..0fc8213e --- /dev/null +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/activity/impl/LotteryPrizeGrantServiceImpl.java @@ -0,0 +1,280 @@ +package com.red.circle.other.app.service.activity.impl; + +import com.red.circle.common.business.core.enums.ReceiptType; +import com.red.circle.common.business.core.enums.SysOriginPlatformEnum; +import com.red.circle.common.business.enums.DiamondOrigin; +import com.red.circle.common.business.enums.SendPropsOrigin; +import com.red.circle.other.app.service.activity.LotteryPrizeGrantService; +import com.red.circle.other.infra.database.rds.entity.activity.LotteryPrize; +import com.red.circle.other.inner.endpoint.material.props.BadgeBackpackClient; +import com.red.circle.other.inner.endpoint.material.props.PropsBackpackClient; +import com.red.circle.other.inner.endpoint.material.props.RoomThemeBackpackClient; +import com.red.circle.other.inner.endpoint.user.user.UserProfileClient; +import com.red.circle.other.inner.enums.material.BadgeBackpackExpireTypeEnum; +import com.red.circle.other.inner.enums.sys.SysBadgeConfigTypeEnum; +import com.red.circle.other.inner.enums.sys.SysCurrencySendReasonEnum; +import com.red.circle.other.inner.model.cmd.material.GiveBadgeCmd; +import com.red.circle.other.inner.model.cmd.material.GivePropsBackpackCmd; +import com.red.circle.other.inner.model.dto.user.UserProfileDTO; +import com.red.circle.tool.core.date.TimestampUtils; +import com.red.circle.tool.core.sequence.IdWorkerUtils; +import com.red.circle.wallet.inner.endpoint.wallet.WalletDiamondClient; +import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient; +import com.red.circle.wallet.inner.model.cmd.DiamondReceiptCmd; +import com.red.circle.wallet.inner.model.cmd.GoldReceiptCmd; +import java.math.BigDecimal; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +/** + * 抽奖奖励发放服务实现. + * + * @author system + * @since 2025-10-21 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class LotteryPrizeGrantServiceImpl implements LotteryPrizeGrantService { + + private final WalletGoldClient walletGoldClient; + private final WalletDiamondClient walletDiamondClient; + private final PropsBackpackClient propsBackpackClient; + private final BadgeBackpackClient badgeBackpackClient; + private final RoomThemeBackpackClient roomThemeBackpackClient; + private final UserProfileClient userProfileClient; + + @Override + public void grantPrize(Long userId, LotteryPrize prize, String recordNo) { + if (prize == null || prize.getPrizeValue() == null) { + log.warn("Prize is null or prizeValue is null, skip grant. userId: {}, recordNo: {}", userId, recordNo); + return; + } + + String prizeType = prize.getPrizeType(); + if (prizeType == null) { + log.warn("Prize type is null, skip grant. userId: {}, prizeId: {}", userId, prize.getId()); + return; + } + + try { + switch (prizeType) { + case "MONEY": + // 金钱类型暂不处理,由业务方自行提现 + log.info("Money prize granted, userId: {}, amount: {}, recordNo: {}", + userId, prize.getPrizeValue(), recordNo); + break; + + case "GOLD": + grantGold(userId, prize, recordNo); + break; + + case "PROPS": + grantProps(userId, prize, recordNo); + break; + + case "BADGE": + grantBadge(userId, prize, recordNo); + break; + + case "THEME": + grantTheme(userId, prize, recordNo); + break; + + case "AVATAR_FRAME": + case "RIDE": + case "CHAT_BUBBLE": + case "DATA_CARD": + grantBackpackProps(userId, prize, recordNo, prizeType); + break; + + case "THANKS": + // 谢谢参与,不发放奖励 + log.info("Thanks prize, no reward. userId: {}, recordNo: {}", userId, recordNo); + break; + + default: + log.warn("Unknown prize type: {}, userId: {}, prizeId: {}", prizeType, userId, prize.getId()); + } + } catch (Exception e) { + log.error("Grant prize failed, userId: {}, prizeId: {}, recordNo: {}", + userId, prize.getId(), recordNo, e); + } + } + + /** + * 发放金币. + */ + private void grantGold(Long userId, LotteryPrize prize, String recordNo) { + UserProfileDTO userProfile = userProfileClient.getByUserId(userId).getBody(); + if (userProfile == null) { + log.warn("User profile not found, userId: {}", userId); + return; + } + + BigDecimal amount = prize.getPrizeValue(); + walletGoldClient.changeBalance( + GoldReceiptCmd.builder() + .opsIncome() + .userId(userId) + .sysOrigin(userProfile.getOriginSys()) + .eventId(recordNo) + .origin(SysCurrencySendReasonEnum.LOTTERY.name()) + .originDescribe("抽奖奖励") + .amount(amount) + .remark("抽奖获得金币") + .build() + ); + + log.info("Gold granted, userId: {}, amount: {}, recordNo: {}", userId, amount, recordNo); + } + + /** + * 发放钻石. + */ + private void grantDiamond(Long userId, LotteryPrize prize, String recordNo) { + UserProfileDTO userProfile = userProfileClient.getByUserId(userId).getBody(); + if (userProfile == null) { + log.warn("User profile not found, userId: {}", userId); + return; + } + + Long trackId = IdWorkerUtils.getId(); + BigDecimal amount = prize.getPrizeValue(); + + walletDiamondClient.changeBalance( + new DiamondReceiptCmd() + .setConsumeId(recordNo) + .setTrackId(trackId) + .setUserId(userId) + .setSysOrigin(SysOriginPlatformEnum.valueOf(userProfile.getOriginSys())) + .setOriginUserId(userId) + .setOrigin(DiamondOrigin.LOTTERY_REWARD) + .setAmount(amount) + .setCreateTime(TimestampUtils.now()) + .setType(ReceiptType.INCOME) + ); + + log.info("Diamond granted, userId: {}, amount: {}, recordNo: {}", userId, amount, recordNo); + } + + /** + * 发放道具(通用道具). + */ + private void grantProps(Long userId, LotteryPrize prize, String recordNo) { + if (prize.getPropsId() == null) { + log.warn("Props id is null, skip grant. userId: {}, prizeId: {}", userId, prize.getId()); + return; + } + + Integer days = prize.getDays() != null ? prize.getDays() : 7; + + GivePropsBackpackCmd cmd = new GivePropsBackpackCmd() + .setAcceptUserId(userId) + .setPropsId(prize.getPropsId()) + .setType("PROPS") + .setOrigin(SendPropsOrigin.LOTTERY_REWARD.name()) + .setOriginDesc("抽奖奖励") + .setDays(days) + .setUseProps(Boolean.FALSE) + .setAllowGive(Boolean.FALSE) + .setOpUser(userId); + + propsBackpackClient.giveProps(cmd); + + // 发送通知 +// propsBackpackClient.givePropsNotify(userId, "PROPS", days, prize.getPropsId()); + + log.info("Props granted, userId: {}, propsId: {}, days: {}, recordNo: {}", + userId, prize.getPropsId(), days, recordNo); + } + + /** + * 发放背包道具(头像框、座驾、气泡、名片). + */ + private void grantBackpackProps(Long userId, LotteryPrize prize, String recordNo, String type) { + if (prize.getPropsId() == null) { + log.warn("Props id is null, skip grant. userId: {}, prizeId: {}", userId, prize.getId()); + return; + } + + Integer days = prize.getDays() != null ? prize.getDays() : 7; + + GivePropsBackpackCmd cmd = new GivePropsBackpackCmd() + .setAcceptUserId(userId) + .setPropsId(prize.getPropsId()) + .setType(type) + .setOrigin(SendPropsOrigin.LOTTERY_REWARD.name()) + .setOriginDesc("抽奖奖励") + .setDays(days) + .setUseProps(Boolean.FALSE) + .setAllowGive(Boolean.FALSE) + .setOpUser(userId); + + propsBackpackClient.giveProps(cmd); + + // 发送通知 + propsBackpackClient.givePropsNotify(userId, type, days, prize.getPropsId()); + + log.info("Backpack props granted, userId: {}, type: {}, propsId: {}, days: {}, recordNo: {}", + userId, type, prize.getPropsId(), days, recordNo); + } + + /** + * 发放徽章. + */ + private void grantBadge(Long userId, LotteryPrize prize, String recordNo) { + if (prize.getPropsId() == null) { + log.warn("Badge id is null, skip grant. userId: {}, prizeId: {}", userId, prize.getId()); + return; + } + + Integer days = prize.getDays() != null ? prize.getDays() : 7; + + // 徽章赠送天数大于1000天则为永久赠送 + BadgeBackpackExpireTypeEnum expireType = days >= 1000 + ? BadgeBackpackExpireTypeEnum.PERMANENT + : BadgeBackpackExpireTypeEnum.TEMPORARY; + + badgeBackpackClient.giveBadge(new GiveBadgeCmd() + .setAcceptUserId(userId) + .setBadgeId(prize.getPropsId()) + .setExpireType(expireType) + .setDays(days) + .setBadgeType(SysBadgeConfigTypeEnum.ACTIVITY) + ); + + // 发送通知 + propsBackpackClient.givePropsNotify(userId, "BADGE", days, prize.getPropsId()); + + log.info("Badge granted, userId: {}, badgeId: {}, days: {}, expireType: {}, recordNo: {}", + userId, prize.getPropsId(), days, expireType, recordNo); + } + + /** + * 发放主题. + */ + private void grantTheme(Long userId, LotteryPrize prize, String recordNo) { + if (prize.getPropsId() == null) { + log.warn("Theme id is null, skip grant. userId: {}, prizeId: {}", userId, prize.getId()); + return; + } + + Integer days = prize.getDays() != null ? prize.getDays() : 7; + + roomThemeBackpackClient.sendRoomTheme( + userId, + prize.getPropsId(), + days, + SendPropsOrigin.LOTTERY_REWARD + ); + + // 发送通知 +// propsBackpackClient.givePropsNotify(userId, "THEME", days, prize.getPropsId()); + + log.info("Theme granted, userId: {}, themeId: {}, days: {}, recordNo: {}", + userId, prize.getPropsId(), days, recordNo); + } + +} diff --git a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/activity/LotteryPrizeCO.java b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/activity/LotteryPrizeCO.java index 8c88df34..5648bdf4 100644 --- a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/activity/LotteryPrizeCO.java +++ b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/activity/LotteryPrizeCO.java @@ -47,6 +47,21 @@ public class LotteryPrizeCO extends ClientObject { */ private String prizeImage; + /** + * 奖品图标(用于中奖记录展示). + */ + private String prizeIcon; + + /** + * 道具ID. + */ + private Long propsId; + + /** + * 有效天数. + */ + private Integer days; + /** * 奖品等级. */ diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/entity/activity/LotteryPrize.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/entity/activity/LotteryPrize.java index 5d089325..439b8dd3 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/entity/activity/LotteryPrize.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/entity/activity/LotteryPrize.java @@ -52,7 +52,7 @@ public class LotteryPrize implements Serializable { private String prizeName; /** - * 奖品类型:1-实物,2-虚拟币,3-优惠券,4-积分,5-谢谢参与. + * 奖品类型:MONEY-金钱,GOLD-金币,DIAMOND-钻石,PROPS-道具,BADGE-徽章,THEME-主题,NOBLE_VIP-贵族VIP,THANKS-谢谢参与. */ @TableField("prize_type") private String prizeType; @@ -69,6 +69,18 @@ public class LotteryPrize implements Serializable { @TableField("prize_image") private String prizeImage; + /** + * 道具ID(当prize_type为PROPS类时使用). + */ + @TableField("props_id") + private Long propsId; + + /** + * 有效天数(道具/徽章使用). + */ + @TableField("days") + private Integer days; + /** * 奖品等级:1-特等奖,2-一等奖,3-二等奖. */