diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/listener/user/OnlineStatusUploadListener.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/listener/user/OnlineStatusUploadListener.java index f72cadc5..cf4e097d 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/listener/user/OnlineStatusUploadListener.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/listener/user/OnlineStatusUploadListener.java @@ -26,11 +26,11 @@ import com.red.circle.tool.core.date.DateUtils; import com.red.circle.tool.core.date.TimestampUtils; import com.red.circle.tool.core.parse.DataTypeUtils; import com.red.circle.tool.core.sequence.IdWorkerUtils; -import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient; -import java.sql.Timestamp; -import java.util.Objects; -import java.util.Optional; -import lombok.RequiredArgsConstructor; +import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient; +import java.sql.Timestamp; +import java.util.Objects; +import java.util.Optional; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -108,21 +108,59 @@ public class OnlineStatusUploadListener implements MessageListener { } ); - } - - private void countActiveUser(UserProfile userProfile) { - long account = Objects.hash(userProfile.getAccount()); - if (userProfileGateway.checkTeamMember(userProfile.getId())) { - countUserActiveIndexService.countAnchorActiveUser(account); - countUserActiveIndexService.countAnchorActiveUser(userProfile.getOriginSys(), account); - return; - } - - countUserActiveIndexService.countOrdinaryActiveUser(account); - countUserActiveIndexService.countOrdinaryActiveUser(userProfile.getOriginSys(), account); - } - - private void addOnlineUser(UserOnlineStatusEvent event, UserProfile userProfile) { + } + + private void countActiveUser(UserProfile userProfile) { + Long bitmapOffset = resolveActiveUserBitmapOffset(userProfile); + if (Objects.isNull(bitmapOffset) || bitmapOffset <= 0) { + log.warn("[在线状态]跳过活跃bitmap统计, userId={}, account={}, actualAccount={}", + userProfile.getId(), + userProfile.getAccount(), + userProfile.getActualAccount()); + return; + } + if (userProfileGateway.checkTeamMember(userProfile.getId())) { + countUserActiveIndexService.countAnchorActiveUser(bitmapOffset); + countUserActiveIndexService.countAnchorActiveUser(userProfile.getOriginSys(), bitmapOffset); + return; + } + + countUserActiveIndexService.countOrdinaryActiveUser(bitmapOffset); + countUserActiveIndexService.countOrdinaryActiveUser(userProfile.getOriginSys(), bitmapOffset); + } + + static Long resolveActiveUserBitmapOffset(UserProfile userProfile) { + if (Objects.isNull(userProfile)) { + return null; + } + Long offset = parsePositiveLong(userProfile.getAccount()); + if (Objects.nonNull(offset)) { + return offset; + } + + offset = parsePositiveLong(userProfile.getActualAccount()); + if (Objects.nonNull(offset)) { + return offset; + } + + return Optional.ofNullable(userProfile.getId()) + .filter(id -> id > 0) + .orElse(null); + } + + private static Long parsePositiveLong(String value) { + if (StringUtils.isBlank(value)) { + return null; + } + try { + long parsed = Long.parseLong(value.trim()); + return parsed > 0 ? parsed : null; + } catch (NumberFormatException ignore) { + return null; + } + } + + private void addOnlineUser(UserOnlineStatusEvent event, UserProfile userProfile) { if (StringUtils.isBlank(event.getSessionId())) { return; } diff --git a/rc-service/rc-service-other/other-application/src/test/java/com/red/circle/other/app/listener/user/OnlineStatusUploadListenerTest.java b/rc-service/rc-service-other/other-application/src/test/java/com/red/circle/other/app/listener/user/OnlineStatusUploadListenerTest.java new file mode 100644 index 00000000..ea2e5b4b --- /dev/null +++ b/rc-service/rc-service-other/other-application/src/test/java/com/red/circle/other/app/listener/user/OnlineStatusUploadListenerTest.java @@ -0,0 +1,52 @@ +package com.red.circle.other.app.listener.user; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import com.red.circle.other.domain.model.user.OwnSpecialId; +import com.red.circle.other.domain.model.user.UserProfile; +import com.red.circle.tool.core.date.TimestampUtils; +import org.junit.jupiter.api.Test; + +class OnlineStatusUploadListenerTest { + + @Test + void resolveActiveUserBitmapOffset_shouldUseNumericAccount() { + UserProfile profile = new UserProfile(); + profile.setId(9988L); + profile.setAccount("123456"); + + assertEquals(123456L, OnlineStatusUploadListener.resolveActiveUserBitmapOffset(profile)); + } + + @Test + void resolveActiveUserBitmapOffset_shouldFallbackToNumericSpecialAccount() { + UserProfile profile = new UserProfile(); + profile.setId(9988L); + profile.setAccount("abc"); + OwnSpecialId ownSpecialId = new OwnSpecialId(); + ownSpecialId.setAccount("654321"); + ownSpecialId.setExpiredTime(TimestampUtils.nowPlusDays(1)); + profile.setOwnSpecialId(ownSpecialId); + + assertEquals(654321L, OnlineStatusUploadListener.resolveActiveUserBitmapOffset(profile)); + } + + @Test + void resolveActiveUserBitmapOffset_shouldFallbackToUserIdWhenAccountIsNotNumeric() { + UserProfile profile = new UserProfile(); + profile.setId(9988L); + profile.setAccount("abc"); + + assertEquals(9988L, OnlineStatusUploadListener.resolveActiveUserBitmapOffset(profile)); + } + + @Test + void resolveActiveUserBitmapOffset_shouldReturnNullWhenNoPositiveCandidateExists() { + UserProfile profile = new UserProfile(); + profile.setId(0L); + profile.setAccount("abc"); + + assertNull(OnlineStatusUploadListener.resolveActiveUserBitmapOffset(profile)); + } +}