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 22dc42ce..e19809a1 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 @@ -224,6 +224,11 @@ public enum SendPropsOrigin { */ OFFICIAL_GIFT("Official gift"), + /** + * 系统操作 + */ + SYSTEM_OPERATION("System Operation"), + /** * 活动奖励. */ diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/listener/BadgeOperateListener.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/listener/BadgeOperateListener.java index 8bbe5fd3..34e4a34a 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/listener/BadgeOperateListener.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/listener/BadgeOperateListener.java @@ -1,5 +1,6 @@ package com.red.circle.other.app.listener; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Sets; import com.red.circle.component.mq.MessageEventProcess; 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.ConsumerMessage; 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.rocket.business.streams.BadgeOperateSink; 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.service.badge.BadgeBackpackService; import com.red.circle.other.infra.database.rds.service.badge.BadgeConfigService; - -import java.util.Collections; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - +import com.red.circle.other.inner.endpoint.material.props.PropsBackpackClient; 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.tool.core.collection.CollectionUtils; 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.extern.slf4j.Slf4j; import org.jetbrains.annotations.NotNull; @@ -40,13 +45,25 @@ import org.jetbrains.annotations.NotNull; @RequiredArgsConstructor public class BadgeOperateListener implements MessageListener { + /** 徽章key -> 头像框道具id 映射. */ + private static final Map BADGE_AVATAR_FRAME_MAP = ImmutableMap.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 BadgeBackpackService badgeBackpackService; private final MessageEventProcess messageEventProcess; private final UserRunProfileService userRunProfileService; private final UserBadgeCommon userBadgeCommon; - private final UserProfileGateway userProfileGateway; - private final DistributedLockUtil distributedLockUtil; + private final UserProfileGateway userProfileGateway; + private final DistributedLockUtil distributedLockUtil; + private final PropsBackpackClient propsBackpackClient; @Override public Action consume(ConsumerMessage message) { @@ -75,8 +92,7 @@ public class BadgeOperateListener implements MessageListener { } Long finalBadgeId = badgeId; - - // 如果传了badgeId则使用badgeId,否则通过badgeKey查询 + if (finalBadgeId == null) { if (badgeKey == null) { log.warn("徽章操作事件缺少badgeKey和badgeId, userId: {}", userId); @@ -90,11 +106,10 @@ public class BadgeOperateListener implements MessageListener { finalBadgeId = badgeConfig.getId(); } - // 根据操作类型执行对应逻辑 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)) { - handleRemoveBadge(userId, finalBadgeId); + handleRemoveBadge(userId, finalBadgeId, badgeKey); } else { log.warn("未知的操作类型, operationType: {}", operationType); } @@ -103,9 +118,9 @@ 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; - + distributedLockUtil.executeWithLock(lockKey, () -> { BadgeBackpack existBadge = badgeBackpackService.query() .eq(BadgeBackpack::getUserId, userId) @@ -127,8 +142,8 @@ public class BadgeOperateListener implements MessageListener { badgeBackpackService.save(buildSaveUserBadgeBackpack(badgeId, userId, days)); } - // 刷新用户佩戴的勋章 refreshUserWearBadges(userId); + giveAvatarFrameIfMapped(badgeKey, userId, days); return null; }); @@ -137,9 +152,9 @@ public class BadgeOperateListener implements MessageListener { @NotNull private Set getUseBadgeIdSet(Long userId) { List ownBadgeList = badgeBackpackService.query() - .eq(BadgeBackpack::getUserId, userId) - .eq(BadgeBackpack::getUseProps, Boolean.TRUE) - .list(); + .eq(BadgeBackpack::getUserId, userId) + .eq(BadgeBackpack::getUseProps, Boolean.TRUE) + .list(); if (CollectionUtils.isEmpty(ownBadgeList)) { 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; distributedLockUtil.executeWithLock(lockKey, () -> { badgeBackpackService.deleteBadges(userId, Sets.newHashSet(badgeId)); - // 刷新用户佩戴的勋章 refreshUserWearBadges(userId); + giveAvatarFrameIfMapped(badgeKey, userId, -999L); 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) { Set badgeIdSet = getUseBadgeIdSet(userId); UserProfile userProfile = userProfileGateway.getByUserId(userId); @@ -171,8 +214,8 @@ public class BadgeOperateListener implements MessageListener { List useBadgeDTOList = userBadgeCommon.listUseBadge(userId, userProfile.getSysOriginChild(), badgeIdSet); userRunProfileService.updateUserWearBadgesOverlay( - userId, - CollectionUtils.isNotEmpty(useBadgeDTOList) ? useBadgeDTOList : Collections.emptyList() + userId, + CollectionUtils.isNotEmpty(useBadgeDTOList) ? useBadgeDTOList : Collections.emptyList() ); }