徽章操作发放 会赠送和收回身份头饰

This commit is contained in:
tianfeng 2026-05-27 18:26:45 +08:00
parent aca666c781
commit 0cf4126510
2 changed files with 71 additions and 23 deletions

View File

@ -224,6 +224,11 @@ public enum SendPropsOrigin {
*/ */
OFFICIAL_GIFT("Official gift"), OFFICIAL_GIFT("Official gift"),
/**
* 系统操作
*/
SYSTEM_OPERATION("System Operation"),
/** /**
* 活动奖励. * 活动奖励.
*/ */

View File

@ -1,5 +1,6 @@
package com.red.circle.other.app.listener; package com.red.circle.other.app.listener;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.red.circle.component.mq.MessageEventProcess; import com.red.circle.component.mq.MessageEventProcess;
import com.red.circle.component.mq.MessageEventProcessDescribe; import com.red.circle.component.mq.MessageEventProcessDescribe;
@ -7,6 +8,7 @@ import com.red.circle.component.mq.config.RocketMqMessageListener;
import com.red.circle.component.mq.service.Action; import com.red.circle.component.mq.service.Action;
import com.red.circle.component.mq.service.ConsumerMessage; import com.red.circle.component.mq.service.ConsumerMessage;
import com.red.circle.component.mq.service.MessageListener; import com.red.circle.component.mq.service.MessageListener;
import com.red.circle.common.business.enums.SendPropsOrigin;
import com.red.circle.mq.business.model.event.BadgeOperateEvent; import com.red.circle.mq.business.model.event.BadgeOperateEvent;
import com.red.circle.mq.rocket.business.streams.BadgeOperateSink; import com.red.circle.mq.rocket.business.streams.BadgeOperateSink;
import com.red.circle.other.app.util.DistributedLockUtil; import com.red.circle.other.app.util.DistributedLockUtil;
@ -18,16 +20,19 @@ import com.red.circle.other.infra.database.rds.entity.badge.BadgeBackpack;
import com.red.circle.other.infra.database.rds.entity.badge.BadgeConfig; import com.red.circle.other.infra.database.rds.entity.badge.BadgeConfig;
import com.red.circle.other.infra.database.rds.service.badge.BadgeBackpackService; import com.red.circle.other.infra.database.rds.service.badge.BadgeBackpackService;
import com.red.circle.other.infra.database.rds.service.badge.BadgeConfigService; import com.red.circle.other.infra.database.rds.service.badge.BadgeConfigService;
import com.red.circle.other.inner.endpoint.material.props.PropsBackpackClient;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import com.red.circle.other.inner.enums.material.BadgeBackpackExpireTypeEnum; import com.red.circle.other.inner.enums.material.BadgeBackpackExpireTypeEnum;
import com.red.circle.other.inner.enums.material.BadgeKeyEnum;
import com.red.circle.other.inner.enums.material.ConsolePropsTypeEnum;
import com.red.circle.other.inner.model.cmd.material.GivePropsBackpackCmd;
import com.red.circle.other.inner.model.dto.material.UseBadgeDTO; import com.red.circle.other.inner.model.dto.material.UseBadgeDTO;
import com.red.circle.tool.core.collection.CollectionUtils; import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.TimestampUtils; import com.red.circle.tool.core.date.TimestampUtils;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -40,13 +45,25 @@ import org.jetbrains.annotations.NotNull;
@RequiredArgsConstructor @RequiredArgsConstructor
public class BadgeOperateListener implements MessageListener { public class BadgeOperateListener implements MessageListener {
/** 徽章key -> 头像框道具id 映射. */
private static final Map<String, Long> BADGE_AVATAR_FRAME_MAP = ImmutableMap.<String, Long>builder()
.put(BadgeKeyEnum.BD.name(), 2040075527716749314L)
.put(BadgeKeyEnum.HOST.name(), 2040075649787772929L)
.put(BadgeKeyEnum.SUPER_ADMIN.name(), 2040075765235990529L)
.put(BadgeKeyEnum.AGENCY.name(), 2040075877559451650L)
.put(BadgeKeyEnum.ADMIN.name(), 2040076072594587650L)
.put(BadgeKeyEnum.MANAGER.name(), 2040076226995306497L)
.put(BadgeKeyEnum.RECHARGE_AGENCY.name(), 2054123011514957825L)
.build();
private final BadgeConfigService badgeConfigService; private final BadgeConfigService badgeConfigService;
private final BadgeBackpackService badgeBackpackService; private final BadgeBackpackService badgeBackpackService;
private final MessageEventProcess messageEventProcess; private final MessageEventProcess messageEventProcess;
private final UserRunProfileService userRunProfileService; private final UserRunProfileService userRunProfileService;
private final UserBadgeCommon userBadgeCommon; private final UserBadgeCommon userBadgeCommon;
private final UserProfileGateway userProfileGateway; private final UserProfileGateway userProfileGateway;
private final DistributedLockUtil distributedLockUtil; private final DistributedLockUtil distributedLockUtil;
private final PropsBackpackClient propsBackpackClient;
@Override @Override
public Action consume(ConsumerMessage message) { public Action consume(ConsumerMessage message) {
@ -76,7 +93,6 @@ public class BadgeOperateListener implements MessageListener {
Long finalBadgeId = badgeId; Long finalBadgeId = badgeId;
// 如果传了badgeId则使用badgeId否则通过badgeKey查询
if (finalBadgeId == null) { if (finalBadgeId == null) {
if (badgeKey == null) { if (badgeKey == null) {
log.warn("徽章操作事件缺少badgeKey和badgeId, userId: {}", userId); log.warn("徽章操作事件缺少badgeKey和badgeId, userId: {}", userId);
@ -90,11 +106,10 @@ public class BadgeOperateListener implements MessageListener {
finalBadgeId = badgeConfig.getId(); finalBadgeId = badgeConfig.getId();
} }
// 根据操作类型执行对应逻辑
if (BadgeOperateEvent.OperationType.WEAR.name().equals(operationType)) { if (BadgeOperateEvent.OperationType.WEAR.name().equals(operationType)) {
handleWearBadge(userId, finalBadgeId, event.getDays()); handleWearBadge(userId, finalBadgeId, badgeKey, event.getDays());
} else if (BadgeOperateEvent.OperationType.REMOVE.name().equals(operationType)) { } else if (BadgeOperateEvent.OperationType.REMOVE.name().equals(operationType)) {
handleRemoveBadge(userId, finalBadgeId); handleRemoveBadge(userId, finalBadgeId, badgeKey);
} else { } else {
log.warn("未知的操作类型, operationType: {}", operationType); log.warn("未知的操作类型, operationType: {}", operationType);
} }
@ -103,7 +118,7 @@ public class BadgeOperateListener implements MessageListener {
/** /**
* 佩戴徽章. * 佩戴徽章.
*/ */
private void handleWearBadge(Long userId, Long badgeId, Long days) { private void handleWearBadge(Long userId, Long badgeId, String badgeKey, Long days) {
String lockKey = "badge:operate:wear:" + userId + ":" + badgeId; String lockKey = "badge:operate:wear:" + userId + ":" + badgeId;
distributedLockUtil.executeWithLock(lockKey, () -> { distributedLockUtil.executeWithLock(lockKey, () -> {
@ -127,8 +142,8 @@ public class BadgeOperateListener implements MessageListener {
badgeBackpackService.save(buildSaveUserBadgeBackpack(badgeId, userId, days)); badgeBackpackService.save(buildSaveUserBadgeBackpack(badgeId, userId, days));
} }
// 刷新用户佩戴的勋章
refreshUserWearBadges(userId); refreshUserWearBadges(userId);
giveAvatarFrameIfMapped(badgeKey, userId, days);
return null; return null;
}); });
@ -137,9 +152,9 @@ public class BadgeOperateListener implements MessageListener {
@NotNull @NotNull
private Set<Long> getUseBadgeIdSet(Long userId) { private Set<Long> getUseBadgeIdSet(Long userId) {
List<BadgeBackpack> ownBadgeList = badgeBackpackService.query() List<BadgeBackpack> ownBadgeList = badgeBackpackService.query()
.eq(BadgeBackpack::getUserId, userId) .eq(BadgeBackpack::getUserId, userId)
.eq(BadgeBackpack::getUseProps, Boolean.TRUE) .eq(BadgeBackpack::getUseProps, Boolean.TRUE)
.list(); .list();
if (CollectionUtils.isEmpty(ownBadgeList)) { if (CollectionUtils.isEmpty(ownBadgeList)) {
return Collections.emptySet(); return Collections.emptySet();
} }
@ -149,17 +164,45 @@ public class BadgeOperateListener implements MessageListener {
/** /**
* 移除徽章. * 移除徽章.
*/ */
private void handleRemoveBadge(Long userId, Long badgeId) { private void handleRemoveBadge(Long userId, Long badgeId, String badgeKey) {
String lockKey = "badge:operate:remove:" + userId + ":" + badgeId; String lockKey = "badge:operate:remove:" + userId + ":" + badgeId;
distributedLockUtil.executeWithLock(lockKey, () -> { distributedLockUtil.executeWithLock(lockKey, () -> {
badgeBackpackService.deleteBadges(userId, Sets.newHashSet(badgeId)); badgeBackpackService.deleteBadges(userId, Sets.newHashSet(badgeId));
// 刷新用户佩戴的勋章
refreshUserWearBadges(userId); refreshUserWearBadges(userId);
giveAvatarFrameIfMapped(badgeKey, userId, -999L);
return null; return null;
}); });
} }
/**
* 若徽章有对应头像框则联动赠送/收回.
* days > 0 为赠送-999 为收回.
*/
private void giveAvatarFrameIfMapped(String badgeKey, Long userId, Long days) {
if (badgeKey == null) {
return;
}
Long avatarFramePropsId = BADGE_AVATAR_FRAME_MAP.get(badgeKey);
if (avatarFramePropsId == null) {
return;
}
try {
propsBackpackClient.giveProps(new GivePropsBackpackCmd()
.setAcceptUserId(userId)
.setPropsId(avatarFramePropsId)
.setType(ConsolePropsTypeEnum.AVATAR_FRAME.getName())
.setOrigin(SendPropsOrigin.SYSTEM_OPERATION.name())
.setOriginDesc(SendPropsOrigin.SYSTEM_OPERATION.getDesc())
.setDays(days.intValue())
.setUseProps(Boolean.FALSE)
.setAllowGive(Boolean.FALSE)
);
} catch (Exception e) {
log.error("联动赠送头像框失败, userId: {}, badgeKey: {}, avatarFramePropsId: {}", userId, badgeKey, avatarFramePropsId, e);
}
}
private void refreshUserWearBadges(Long userId) { private void refreshUserWearBadges(Long userId) {
Set<Long> badgeIdSet = getUseBadgeIdSet(userId); Set<Long> badgeIdSet = getUseBadgeIdSet(userId);
UserProfile userProfile = userProfileGateway.getByUserId(userId); UserProfile userProfile = userProfileGateway.getByUserId(userId);
@ -171,8 +214,8 @@ public class BadgeOperateListener implements MessageListener {
List<UseBadgeDTO> useBadgeDTOList = userBadgeCommon.listUseBadge(userId, userProfile.getSysOriginChild(), badgeIdSet); List<UseBadgeDTO> useBadgeDTOList = userBadgeCommon.listUseBadge(userId, userProfile.getSysOriginChild(), badgeIdSet);
userRunProfileService.updateUserWearBadgesOverlay( userRunProfileService.updateUserWearBadgesOverlay(
userId, userId,
CollectionUtils.isNotEmpty(useBadgeDTOList) ? useBadgeDTOList : Collections.emptyList() CollectionUtils.isNotEmpty(useBadgeDTOList) ? useBadgeDTOList : Collections.emptyList()
); );
} }