新增查询用户时自动切换过期的VIP道具

This commit is contained in:
tianfeng 2025-11-11 16:18:31 +08:00
parent 1f7f125ade
commit 56e36531bf

View File

@ -2,8 +2,10 @@ package com.red.circle.other.infra.gateway.user;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.red.circle.other.domain.gateway.props.PropsNobleVipGateway;
import com.red.circle.other.domain.gateway.user.UserRunProfileTransportGateway;
import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.infra.common.props.PropsBackpackCommon;
import com.red.circle.other.infra.common.props.UserBadgeCommon;
import com.red.circle.other.infra.convertor.material.BadgeInfraConvertor;
import com.red.circle.other.infra.convertor.material.PropsResourcesInfraConvertor;
@ -14,6 +16,7 @@ import com.red.circle.other.infra.database.mongo.entity.user.profile.UserRunProf
import com.red.circle.other.infra.database.mongo.entity.user.profile.UserSpecialId;
import com.red.circle.other.infra.database.mongo.service.user.profile.UserRunProfileService;
import com.red.circle.other.infra.database.mongo.service.user.profile.UserSpecialIdService;
import com.red.circle.other.infra.database.rds.entity.props.PropsBackpack;
import com.red.circle.other.infra.database.rds.entity.user.user.BaseInfo;
import com.red.circle.other.infra.database.rds.service.badge.BadgeConfigService;
import com.red.circle.other.infra.database.rds.service.badge.BadgePictureConfigService;
@ -33,9 +36,12 @@ import com.red.circle.other.inner.model.dto.material.RoomThemeUserBackpackDTO;
import com.red.circle.other.inner.model.dto.material.RoomThemeUserCustomizeDTO;
import com.red.circle.other.inner.model.dto.material.UseBadgeDTO;
import com.red.circle.other.inner.model.dto.material.UsePropsDTO;
import com.red.circle.other.inner.model.dto.material.props.PropsNobleVipAbilityDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.json.JacksonUtils;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@ -63,6 +69,8 @@ public class UserRunProfileTransportGatewayImpl implements UserRunProfileTranspo
private final UserBadgeCommon userBadgeCommon;
private final BadgeConfigService badgeConfigService;
private final BadgeInfraConvertor badgeInfraConvertor;
private final PropsNobleVipGateway propsNobleVipGateway;
private final PropsBackpackCommon propsBackpackCommon;
private final PropsBackpackService propsBackpackService;
private final UserSpecialIdService userSpecialIdService;
private final UserRunProfileService userRunProfileService;
@ -308,6 +316,9 @@ public class UserRunProfileTransportGatewayImpl implements UserRunProfileTranspo
}
private Map<Long, List<UsePropsDTO>> mapUserUsePropsEntity(Set<Long> userIds) {
// 自动切换过期VIP
autoSwitchExpiredVipBatch(userIds);
return Optional.ofNullable(this.listUserUsePropsEntity(userIds))
.map(userUsePropsEntities -> userUsePropsEntities.stream()
.collect(Collectors.groupingBy(UsePropsDTO::getUserId)))
@ -338,6 +349,70 @@ public class UserRunProfileTransportGatewayImpl implements UserRunProfileTranspo
.filter(Objects::nonNull).toList();
}
/**
* 批量自动切换用户过期VIP
*/
private void autoSwitchExpiredVipBatch(Set<Long> userIds) {
if (CollectionUtils.isEmpty(userIds)) {
return;
}
for (Long userId : userIds) {
try {
autoSwitchExpiredVip(userId);
} catch (Exception e) {
log.error("批量自动切换VIP失败, userId={}", userId, e);
}
}
}
/**
* 自动切换用户过期VIP到下一个可用VIP
*/
private void autoSwitchExpiredVip(Long userId) {
if (userId == null) {
return;
}
// 1. 查询当前正在使用的VIP
PropsBackpack currentVip = propsBackpackService.getUserNotExpiredUseProps(userId, PropsCommodityType.NOBLE_VIP);
// 2. 检查当前VIP是否过期
Timestamp now = TimestampUtils.now();
if (currentVip != null && currentVip.getExpireTime().after(now)) {
// 当前VIP未过期无需切换
return;
}
// 3. 如果当前VIP已过期卸下它
if (currentVip != null) {
propsBackpackService.unloadUseProps(userId, PropsCommodityType.NOBLE_VIP);
log.info("用户VIP已过期并卸下, userId={}, propsId={}, expireTime={}",
userId, currentVip.getPropsId(), currentVip.getExpireTime());
}
// 4. 使用最高等级的可用VIP
useMaxNobleVip(userId);
}
/**
* 切换到最高等级VIP
*/
private void useMaxNobleVip(Long userId) {
PropsNobleVipAbilityDTO abilityDTO = propsNobleVipGateway.getUserMaxAbilityDTO(userId);
if (Objects.isNull(abilityDTO)) {
log.info("用户没有可用的VIP道具, userId={}", userId);
return;
}
propsBackpackCommon.switchUseProps(userId, abilityDTO.getId());
propsBackpackCommon.switchUseProps(userId, abilityDTO.getAvatarFrameId());
propsBackpackCommon.switchUseProps(userId, abilityDTO.getDataCardId());
propsBackpackCommon.switchUseProps(userId, abilityDTO.getCarId());
log.info("自动切换到最高等级VIP, userId={}, vipId={}", userId, abilityDTO.getId());
}
private UsePropsDTO mergeUserUsePropsEntity(
Map<Long, PropsResourcesDTO> propsSourceRecordMap, PropsBackpackDTO propsBackpack) {
UsePropsDTO entity = new UsePropsDTO();