diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/user/ProcessCpApplyCmd.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/user/ProcessCpApplyCmd.java index e15e6bf3..82e1c7f5 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/user/ProcessCpApplyCmd.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/user/ProcessCpApplyCmd.java @@ -1,11 +1,8 @@ package com.red.circle.other.app.command.user; -import com.red.circle.common.business.core.enums.SysOriginPlatformEnum; -import com.red.circle.external.inner.endpoint.message.ImMessageClient; -import com.red.circle.framework.core.asserts.ResponseAssert; -import com.red.circle.framework.core.response.CommonErrorCode; -import com.red.circle.mq.business.model.event.user.CpApplyEvent; -import com.red.circle.mq.rocket.business.producer.UserMqMessageService; +import com.red.circle.external.inner.endpoint.message.ImMessageClient; +import com.red.circle.framework.core.asserts.ResponseAssert; +import com.red.circle.framework.core.response.CommonErrorCode; import com.red.circle.other.app.common.cp.CpRelationC2cNoticeUtils; import com.red.circle.other.app.common.cp.CpRelationBroadcastMqClient; import com.red.circle.other.app.dto.cmd.user.relation.cp.ProcessApplyCmd; @@ -20,14 +17,12 @@ import com.red.circle.other.infra.database.rds.service.user.user.CpRelationshipS import com.red.circle.other.infra.database.rds.service.user.user.CpValueService; import com.red.circle.other.infra.enums.user.user.CpApplyStatus; import com.red.circle.other.infra.enums.user.user.CpRelationshipType; -import com.red.circle.tool.core.date.TimestampUtils; -import com.red.circle.other.inner.asserts.user.UserRelationErrorCode; -import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient; -import com.red.circle.wallet.inner.model.cmd.GoldReceiptCmd; -import com.red.circle.wallet.inner.model.enums.GoldOrigin; +import com.red.circle.other.inner.asserts.user.UserRelationErrorCode; import java.math.BigDecimal; import java.util.Arrays; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -47,10 +42,8 @@ public class ProcessCpApplyCmd { private static final int FRIEND_MAX_COUNT = 3; private final CpApplyService cpApplyService; - private final CpValueService cpValueService; - private final ImMessageClient imMessageClient; - private final WalletGoldClient walletGoldClient; - private final UserMqMessageService userMqMessageService; + private final CpValueService cpValueService; + private final ImMessageClient imMessageClient; private final CpRelationshipService cpRelationshipService; private final UserProfileGateway userProfileGateway; private final CpRelationshipCacheService cpRelationshipCacheService; @@ -98,7 +91,6 @@ public class ProcessCpApplyCmd { cpApplyService.changeStatusById(cmd.getApplyId(), getStatus(cmd))); if (!agree) { - returnGoldCoins(cmd, cpApply); sendProcessNotice(cpApply, false); return; } @@ -114,12 +106,7 @@ public class ProcessCpApplyCmd { cmd.requireReqSysOrigin(), relationType); } - List refusedApplyIds = cpApplyService.refuseOtherWaitBetweenUsers(cpApply.getId(), - cpApply.getSendApplyUserId(), cpApply.getAcceptApplyUserId()); - boolean refusedByLimit = refuseStatusWaitIfLimitReached(cmd, cpApply, relationType); - if (!refusedApplyIds.isEmpty() || refusedByLimit) { - scheduleReimburse(cmd, cpApply.getId()); - } + sendAutoRejectedNotices(autoRefuseWaitAppliesAfterAgree(cpApply, relationType)); cpRelationshipCacheService.remove(Arrays.asList(cpApply.getSendApplyUserId(), cpApply.getAcceptApplyUserId())); cpRelationBroadcastMqClient.publish(cmd.requireReqSysOrigin(), cpApply.getId(), @@ -145,22 +132,45 @@ public class ProcessCpApplyCmd { } } - private boolean refuseStatusWaitIfLimitReached(ProcessApplyCmd cmd, CpApply cpApply, - String relationType) { - if (cpRelationshipService.countCp(cpApply.getAcceptApplyUserId(), relationType) - < relationMaxCount(relationType)) { - return false; + private void sendAutoRejectedNotices(List refusedApplies) { + if (Objects.isNull(refusedApplies) || refusedApplies.isEmpty()) { + return; } - cpApplyService.refuseStatusWait(cmd.requiredReqUserId(), relationType); - return true; + refusedApplies.forEach(apply -> sendProcessNotice(apply, false)); } - private void scheduleReimburse(ProcessApplyCmd cmd, Long applyId) { - userMqMessageService.cpApplyDelayed( - new CpApplyEvent() - .setId(applyId) - .setSysOrigin(SysOriginPlatformEnum.valueOf(cmd.requireReqSysOrigin())), - TimestampUtils.nowPlusMinutes(1)); + private List autoRefuseWaitAppliesAfterAgree(CpApply cpApply, String relationType) { + Map refusedApplyMap = new LinkedHashMap<>(); + addRefusedApplies(refusedApplyMap, + cpApplyService.refuseOtherWaitAppliesBetweenUsers(cpApply.getId(), + cpApply.getSendApplyUserId(), cpApply.getAcceptApplyUserId())); + addRefusedApplies(refusedApplyMap, + refuseWaitAppliesIfLimitReached(cpApply, cpApply.getSendApplyUserId(), relationType)); + addRefusedApplies(refusedApplyMap, + refuseWaitAppliesIfLimitReached(cpApply, cpApply.getAcceptApplyUserId(), relationType)); + return List.copyOf(refusedApplyMap.values()); + } + + private List refuseWaitAppliesIfLimitReached(CpApply cpApply, Long userId, + String relationType) { + if (cpRelationshipService.countCp(userId, relationType) < relationMaxCount(relationType)) { + return List.of(); + } + List refusedApplies = cpApplyService.refuseWaitAppliesByUserAndRelation( + cpApply.getId(), userId, relationType); + log.info("[CP] auto refused wait applies after relation limit reached, userId={}, relationType={}, applyIds={}", + userId, relationType, refusedApplies.stream().map(CpApply::getId).toList()); + return refusedApplies; + } + + private void addRefusedApplies(Map applyMap, List applies) { + if (Objects.isNull(applies) || applies.isEmpty()) { + return; + } + applies.stream() + .filter(Objects::nonNull) + .filter(apply -> Objects.nonNull(apply.getId())) + .forEach(apply -> applyMap.putIfAbsent(apply.getId(), apply)); } private int relationMaxCount(String relationType) { @@ -169,24 +179,7 @@ public class ProcessCpApplyCmd { : FRIEND_MAX_COUNT; } - private void returnGoldCoins(ProcessApplyCmd cmd, CpApply cpApply) { - if (Objects.isNull(cpApply.getApplyConsumeGold()) - || cpApply.getApplyConsumeGold().compareTo(BigDecimal.ZERO) <= 0) { - cpApplyService.changeStatusById(cmd.getApplyId(), CpApplyStatus.REIMBURSE); - return; - } - walletGoldClient.changeBalance(GoldReceiptCmd.builder() - .appIncome() - .userId(cpApply.getSendApplyUserId()) - .eventId(cpApply.getId()) - .sysOrigin(cmd.requireReqSysOrigin()) - .origin(GoldOrigin.CP_BUILD) - .amount(cpApply.getApplyConsumeGold()) - .build()); - cpApplyService.changeStatusById(cmd.getApplyId(), CpApplyStatus.REIMBURSE); - } - - private Long createCpValue() { + private Long createCpValue() { CpValue cpValue = new CpValue() .setCpVal(BigDecimal.ZERO); cpValueService.save(cpValue); diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/listener/user/CpApplyListener.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/listener/user/CpApplyListener.java index 7f8b7add..5de85c44 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/listener/user/CpApplyListener.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/listener/user/CpApplyListener.java @@ -12,17 +12,10 @@ import com.red.circle.mq.rocket.business.streams.CpApplySink; import com.red.circle.other.app.common.cp.CpRelationC2cNoticeUtils; import com.red.circle.other.domain.gateway.user.UserProfileGateway; import com.red.circle.other.domain.model.user.UserProfile; -import com.red.circle.tool.core.collection.CollectionUtils; import com.red.circle.tool.core.json.JacksonUtils; import com.red.circle.other.infra.database.rds.entity.user.user.CpApply; -import com.red.circle.other.infra.database.rds.service.user.user.CpApplyService; -import com.red.circle.other.infra.enums.user.user.CpApplyStatus; -import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient; -import com.red.circle.wallet.inner.model.cmd.GoldReceiptCmd; -import com.red.circle.wallet.inner.model.enums.GoldOrigin; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import com.red.circle.other.infra.database.rds.service.user.user.CpApplyService; +import com.red.circle.other.infra.enums.user.user.CpApplyStatus; import java.util.Objects; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -40,7 +33,6 @@ public class CpApplyListener implements MessageListener { private final CpApplyService cpApplyService; private final ImMessageClient imMessageClient; private final UserProfileGateway userProfileGateway; - private final WalletGoldClient walletGoldClient; private final MessageEventProcess messageEventProcess; @Override @@ -61,58 +53,16 @@ public class CpApplyListener implements MessageListener { return; } - // 同意检测那些被拒绝都 - if (Objects.equals(cpApply.getStatus(), CpApplyStatus.AGREE.name())) { - checkReimburse(eventBody, cpApply); - return; - } - // 等待超时 if (Objects.equals(cpApply.getStatus(), CpApplyStatus.WAIT.name())) { - reimburse(eventBody, cpApply, true); + expire(cpApply); } }); } - - private void checkReimburse(CpApplyEvent param, CpApply cpApply) { - Map applyMap = new LinkedHashMap<>(); - addReimburseApplies(applyMap, cpApplyService.listRefuse(cpApply.getAcceptApplyUserId())); - addReimburseApplies(applyMap, cpApplyService.listRefuseBetweenUsers(cpApply.getSendApplyUserId(), - cpApply.getAcceptApplyUserId())); - if (applyMap.isEmpty()) { - return; - } - applyMap.values().forEach(apply -> reimburse(param, apply, false)); - } - private void addReimburseApplies(Map applyMap, List cpApplies) { - if (CollectionUtils.isEmpty(cpApplies)) { - return; - } - cpApplies.stream() - .filter(Objects::nonNull) - .filter(apply -> Objects.nonNull(apply.getId())) - .forEach(apply -> applyMap.putIfAbsent(apply.getId(), apply)); - } - - private void reimburse(CpApplyEvent param, CpApply cpApply, boolean expired) { - if (expired) { - sendExpiredNotice(cpApply); - } - if (Objects.isNull(cpApply.getApplyConsumeGold()) - || cpApply.getApplyConsumeGold().signum() <= 0) { - cpApplyService.changeStatusById(cpApply.getId(), CpApplyStatus.REIMBURSE); - return; - } - walletGoldClient.changeBalance(GoldReceiptCmd.builder() - .appIncome() - .userId(cpApply.getSendApplyUserId()) - .eventId(cpApply.getId()) - .sysOrigin(param.getSysOrigin()) - .origin(GoldOrigin.CP_BUILD) - .amount(cpApply.getApplyConsumeGold()) - .build()); - cpApplyService.changeStatusById(cpApply.getId(), CpApplyStatus.REIMBURSE); + private void expire(CpApply cpApply) { + sendExpiredNotice(cpApply); + cpApplyService.changeStatusById(cpApply.getId(), CpApplyStatus.EXPIRE); } private void sendExpiredNotice(CpApply cpApply) { diff --git a/rc-service/rc-service-other/other-application/src/test/java/com/red/circle/other/app/command/user/ProcessCpApplyCmdTest.java b/rc-service/rc-service-other/other-application/src/test/java/com/red/circle/other/app/command/user/ProcessCpApplyCmdTest.java index f76cf722..4a3676c0 100644 --- a/rc-service/rc-service-other/other-application/src/test/java/com/red/circle/other/app/command/user/ProcessCpApplyCmdTest.java +++ b/rc-service/rc-service-other/other-application/src/test/java/com/red/circle/other/app/command/user/ProcessCpApplyCmdTest.java @@ -12,8 +12,6 @@ import com.red.circle.external.inner.endpoint.message.ImMessageClient; import com.red.circle.external.inner.model.cmd.message.CustomC2cMsgBodyCmd; import com.red.circle.framework.core.dto.ReqSysOrigin; import com.red.circle.framework.dto.ResultResponse; -import com.red.circle.mq.business.model.event.user.CpApplyEvent; -import com.red.circle.mq.rocket.business.producer.UserMqMessageService; import com.red.circle.other.app.common.cp.CpRelationBroadcastMqClient; import com.red.circle.other.app.dto.cmd.user.relation.cp.ProcessApplyCmd; import com.red.circle.other.domain.gateway.user.UserProfileGateway; @@ -24,8 +22,6 @@ import com.red.circle.other.infra.database.rds.service.user.user.CpApplyService; import com.red.circle.other.infra.database.rds.service.user.user.CpRelationshipService; import com.red.circle.other.infra.database.rds.service.user.user.CpValueService; import com.red.circle.other.infra.enums.user.user.CpApplyStatus; -import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient; -import java.sql.Timestamp; import java.util.List; import java.util.Map; import org.junit.jupiter.api.Assertions; @@ -91,16 +87,108 @@ class ProcessCpApplyCmdTest { @Test void agreeApplyShouldRejectOtherWaitAppliesBetweenSameUsers() { Fixture fixture = new Fixture("CP"); - when(fixture.cpApplyService.refuseOtherWaitBetweenUsers(3001L, 1001L, 2001L)) - .thenReturn(List.of(3002L, 3003L)); + when(fixture.cpApplyService.refuseOtherWaitAppliesBetweenUsers(3001L, 1001L, 2001L)) + .thenReturn(List.of(apply(3002L, "BROTHER"), apply(3003L, "SISTERS"))); fixture.exe.execute(processCmd(true)); - verify(fixture.cpApplyService).refuseOtherWaitBetweenUsers(3001L, 1001L, 2001L); - ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(CpApplyEvent.class); - verify(fixture.userMqMessageService).cpApplyDelayed(eventCaptor.capture(), - any(Timestamp.class)); - Assertions.assertEquals(3001L, eventCaptor.getValue().getId()); + verify(fixture.cpApplyService).refuseOtherWaitAppliesBetweenUsers(3001L, 1001L, 2001L); + List messages = fixture.sentCustomMessages(3); + assertProcessMessage(messages.get(0), "RELATION_REJECTED", "REJECTED", false, "BROTHER", + 3002L); + assertProcessMessage(messages.get(1), "RELATION_REJECTED", "REJECTED", false, "SISTERS", + 3003L); + assertProcessMessage(messages.get(2), "RELATION_ESTABLISHED", "ACCEPTED", true, "CP", + 3001L); + } + + @Test + void agreeCpApplyShouldRejectPairOtherRelationAppliesAndSenderOtherCpApplies() { + Fixture fixture = new Fixture("CP"); + fixture.mockProfile(4001L); + fixture.mockProfile(4002L); + when(fixture.cpRelationshipService.countCp(1001L, "CP")).thenReturn(0, 1); + when(fixture.cpRelationshipService.countCp(2001L, "CP")).thenReturn(0, 1); + when(fixture.cpApplyService.refuseOtherWaitAppliesBetweenUsers(3001L, 1001L, 2001L)) + .thenReturn(List.of(apply(3002L, "BROTHER"), apply(3003L, "SISTERS"))); + when(fixture.cpApplyService.refuseWaitAppliesByUserAndRelation(3001L, 1001L, "CP")) + .thenReturn(List.of( + apply(3004L, 1001L, 4001L, "CP"), + apply(3005L, 1001L, 4002L, "CP"))); + + fixture.exe.execute(processCmd(true)); + + List messages = fixture.sentCustomMessages(5); + assertProcessMessage(messages.get(0), "RELATION_REJECTED", "REJECTED", false, "BROTHER", + 3002L); + assertProcessMessage(messages.get(1), "RELATION_REJECTED", "REJECTED", false, "SISTERS", + 3003L); + assertProcessMessage(messages.get(2), "RELATION_REJECTED", "REJECTED", false, "CP", + 3004L, "4001", "1001"); + assertProcessMessage(messages.get(3), "RELATION_REJECTED", "REJECTED", false, "CP", + 3005L, "4002", "1001"); + assertProcessMessage(messages.get(4), "RELATION_ESTABLISHED", "ACCEPTED", true, "CP", + 3001L); + } + + @Test + void agreeCpApplyShouldRejectSenderOtherCpAppliesWhenCpLimitReached() { + Fixture fixture = new Fixture("CP"); + fixture.mockProfile(4001L); + fixture.mockProfile(4002L); + when(fixture.cpRelationshipService.countCp(1001L, "CP")).thenReturn(0, 1); + when(fixture.cpRelationshipService.countCp(2001L, "CP")).thenReturn(0, 1); + when(fixture.cpApplyService.refuseWaitAppliesByUserAndRelation(3001L, 1001L, "CP")) + .thenReturn(List.of( + apply(3002L, 1001L, 4001L, "CP"), + apply(3003L, 1001L, 4002L, "CP"))); + + fixture.exe.execute(processCmd(true)); + + List messages = fixture.sentCustomMessages(3); + assertProcessMessage(messages.get(0), "RELATION_REJECTED", "REJECTED", false, "CP", + 3002L, "4001", "1001"); + assertProcessMessage(messages.get(1), "RELATION_REJECTED", "REJECTED", false, "CP", + 3003L, "4002", "1001"); + assertProcessMessage(messages.get(2), "RELATION_ESTABLISHED", "ACCEPTED", true, "CP", + 3001L); + } + + @Test + void agreeBrotherApplyShouldNotRejectOtherBrotherAppliesBeforeLimitReached() { + Fixture fixture = new Fixture("BROTHER"); + when(fixture.cpRelationshipService.countCp(1001L, "BROTHER")).thenReturn(1, 2); + when(fixture.cpRelationshipService.countCp(2001L, "BROTHER")).thenReturn(0, 1); + + fixture.exe.execute(processCmd(true)); + + verify(fixture.cpApplyService, never()).refuseWaitAppliesByUserAndRelation( + any(Long.class), eq(1001L), eq("BROTHER")); + assertProcessMessage(fixture.sentCustomMessage(), "RELATION_ESTABLISHED", "ACCEPTED", + true, "BROTHER"); + } + + @Test + void agreeBrotherApplyShouldRejectSenderOtherBrotherAppliesWhenLimitReached() { + Fixture fixture = new Fixture("BROTHER"); + fixture.mockProfile(4001L); + fixture.mockProfile(4002L); + when(fixture.cpRelationshipService.countCp(1001L, "BROTHER")).thenReturn(2, 3); + when(fixture.cpRelationshipService.countCp(2001L, "BROTHER")).thenReturn(0, 1); + when(fixture.cpApplyService.refuseWaitAppliesByUserAndRelation(3001L, 1001L, "BROTHER")) + .thenReturn(List.of( + apply(3002L, 1001L, 4001L, "BROTHER"), + apply(3003L, 1001L, 4002L, "BROTHER"))); + + fixture.exe.execute(processCmd(true)); + + List messages = fixture.sentCustomMessages(3); + assertProcessMessage(messages.get(0), "RELATION_REJECTED", "REJECTED", false, "BROTHER", + 3002L, "4001", "1001"); + assertProcessMessage(messages.get(1), "RELATION_REJECTED", "REJECTED", false, "BROTHER", + 3003L, "4002", "1001"); + assertProcessMessage(messages.get(2), "RELATION_ESTABLISHED", "ACCEPTED", true, "BROTHER", + 3001L); } private static ProcessApplyCmd processCmd(boolean agree) { @@ -113,10 +201,19 @@ class ProcessCpApplyCmdTest { } private static CpApply apply(String relationType) { + return apply(3001L, relationType); + } + + private static CpApply apply(Long applyId, String relationType) { + return apply(applyId, 1001L, 2001L, relationType); + } + + private static CpApply apply(Long applyId, Long sendUserId, Long acceptUserId, + String relationType) { return new CpApply() - .setId(3001L) - .setSendApplyUserId(1001L) - .setAcceptApplyUserId(2001L) + .setId(applyId) + .setSendApplyUserId(sendUserId) + .setAcceptApplyUserId(acceptUserId) .setRelationType(relationType) .setStatus(CpApplyStatus.WAIT.name()); } @@ -124,8 +221,21 @@ class ProcessCpApplyCmdTest { @SuppressWarnings("unchecked") private static void assertProcessMessage(CustomC2cMsgBodyCmd message, String action, String status, Boolean agree, String relationType) { - Assertions.assertEquals("2001", message.getFromAccount()); - Assertions.assertEquals("1001", message.getToAccount()); + assertProcessMessage(message, action, status, agree, relationType, 3001L); + } + + @SuppressWarnings("unchecked") + private static void assertProcessMessage(CustomC2cMsgBodyCmd message, String action, + String status, Boolean agree, String relationType, Long applyId) { + assertProcessMessage(message, action, status, agree, relationType, applyId, "2001", "1001"); + } + + @SuppressWarnings("unchecked") + private static void assertProcessMessage(CustomC2cMsgBodyCmd message, String action, + String status, Boolean agree, String relationType, Long applyId, String fromAccount, + String toAccount) { + Assertions.assertEquals(fromAccount, message.getFromAccount()); + Assertions.assertEquals(toAccount, message.getToAccount()); Assertions.assertEquals("CP_BUILD", message.getDesc()); Map data = (Map) message.getData(); Assertions.assertEquals("CP_BUILD", data.get("noticeType")); @@ -135,7 +245,7 @@ class ProcessCpApplyCmdTest { Assertions.assertEquals(status, data.get("result")); Assertions.assertEquals(status, data.get("state")); Assertions.assertEquals(agree, data.get("agree")); - Assertions.assertEquals(3001L, data.get("applyId")); + Assertions.assertEquals(applyId, data.get("applyId")); Assertions.assertEquals(relationType, data.get("relationType")); Assertions.assertTrue(data.get("content").toString() .contains("\"relationType\":\"" + relationType + "\"")); @@ -148,21 +258,18 @@ class ProcessCpApplyCmdTest { private final CpRelationBroadcastMqClient cpRelationBroadcastMqClient = mock( CpRelationBroadcastMqClient.class); private final ImMessageClient imMessageClient = mock(ImMessageClient.class); - private final UserMqMessageService userMqMessageService = mock(UserMqMessageService.class); + private final UserProfileGateway userProfileGateway = mock(UserProfileGateway.class); private final ProcessCpApplyCmd exe; private Fixture(String relationType) { CpValueService cpValueService = mock(CpValueService.class); - WalletGoldClient walletGoldClient = mock(WalletGoldClient.class); - UserProfileGateway userProfileGateway = mock(UserProfileGateway.class); CpRelationshipCacheService cpRelationshipCacheService = mock( CpRelationshipCacheService.class); when(cpApplyService.getById(3001L)).thenReturn(apply(relationType)); when(cpApplyService.changeStatusById(3001L, CpApplyStatus.AGREE)).thenReturn(true); when(cpApplyService.changeStatusById(3001L, CpApplyStatus.REFUSE)).thenReturn(true); - when(cpApplyService.changeStatusById(3001L, CpApplyStatus.REIMBURSE)).thenReturn(true); - when(cpApplyService.refuseOtherWaitBetweenUsers(3001L, 1001L, 2001L)) + when(cpApplyService.refuseOtherWaitAppliesBetweenUsers(3001L, 1001L, 2001L)) .thenReturn(List.of()); when(userProfileGateway.getByUserId(1001L)).thenReturn(profile(1001L)); when(userProfileGateway.getByUserId(2001L)).thenReturn(profile(2001L)); @@ -173,14 +280,16 @@ class ProcessCpApplyCmdTest { cpApplyService, cpValueService, imMessageClient, - walletGoldClient, - userMqMessageService, cpRelationshipService, userProfileGateway, cpRelationshipCacheService, cpRelationBroadcastMqClient); } + private void mockProfile(Long userId) { + when(userProfileGateway.getByUserId(userId)).thenReturn(profile(userId)); + } + private CustomC2cMsgBodyCmd sentCustomMessage() { ArgumentCaptor captor = ArgumentCaptor.forClass( CustomC2cMsgBodyCmd.class); @@ -188,6 +297,13 @@ class ProcessCpApplyCmdTest { return captor.getValue(); } + private List sentCustomMessages(int count) { + ArgumentCaptor captor = ArgumentCaptor.forClass( + CustomC2cMsgBodyCmd.class); + verify(imMessageClient, org.mockito.Mockito.times(count)).sendCustomMessage(captor.capture()); + return captor.getAllValues(); + } + private static UserProfile profile(Long userId) { UserProfile userProfile = new UserProfile(); userProfile.setId(userId); diff --git a/rc-service/rc-service-other/other-application/src/test/java/com/red/circle/other/app/command/user/query/UserCpRightsConfigQueryExeTest.java b/rc-service/rc-service-other/other-application/src/test/java/com/red/circle/other/app/command/user/query/UserCpRightsConfigQueryExeTest.java index e01ceea9..f5164efa 100644 --- a/rc-service/rc-service-other/other-application/src/test/java/com/red/circle/other/app/command/user/query/UserCpRightsConfigQueryExeTest.java +++ b/rc-service/rc-service-other/other-application/src/test/java/com/red/circle/other/app/command/user/query/UserCpRightsConfigQueryExeTest.java @@ -8,6 +8,7 @@ import static org.mockito.Mockito.when; import com.red.circle.framework.core.dto.ReqSysOrigin; import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpRightsConfigCO; import com.red.circle.other.app.dto.cmd.user.relation.cp.CpRightsConfigQueryCmd; +import com.red.circle.other.infra.database.cache.service.other.EnumConfigCacheService; import com.red.circle.other.infra.database.rds.entity.user.user.CpCabinConfig; import com.red.circle.other.infra.database.rds.entity.user.user.CpRelationship; import com.red.circle.other.infra.database.rds.entity.user.user.CpValue; @@ -54,8 +55,9 @@ class UserCpRightsConfigQueryExeTest { private final CpCabinConfigService cpCabinConfigService = mock(CpCabinConfigService.class); private final CpRelationshipService cpRelationshipService = mock(CpRelationshipService.class); private final CpValueService cpValueService = mock(CpValueService.class); + private final EnumConfigCacheService enumConfigCacheService = mock(EnumConfigCacheService.class); private final UserCpRightsConfigQueryExe exe = new UserCpRightsConfigQueryExe( - cpCabinConfigService, cpRelationshipService, cpValueService); + cpCabinConfigService, cpRelationshipService, cpValueService, enumConfigCacheService); private Fixture() { for (String relationType : List.of("CP", "BROTHER", "SISTERS")) { diff --git a/rc-service/rc-service-other/other-application/src/test/java/com/red/circle/other/app/listener/user/CpApplyListenerTest.java b/rc-service/rc-service-other/other-application/src/test/java/com/red/circle/other/app/listener/user/CpApplyListenerTest.java index d9bd2ff1..9a57aea3 100644 --- a/rc-service/rc-service-other/other-application/src/test/java/com/red/circle/other/app/listener/user/CpApplyListenerTest.java +++ b/rc-service/rc-service-other/other-application/src/test/java/com/red/circle/other/app/listener/user/CpApplyListenerTest.java @@ -22,7 +22,6 @@ import com.red.circle.other.domain.model.user.UserProfile; import com.red.circle.other.infra.database.rds.entity.user.user.CpApply; import com.red.circle.other.infra.database.rds.service.user.user.CpApplyService; import com.red.circle.other.infra.enums.user.user.CpApplyStatus; -import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient; import java.util.List; import java.util.Map; import java.util.function.Consumer; @@ -36,7 +35,6 @@ class CpApplyListenerTest { CpApplyService cpApplyService = mock(CpApplyService.class); ImMessageClient imMessageClient = mock(ImMessageClient.class); UserProfileGateway userProfileGateway = mock(UserProfileGateway.class); - WalletGoldClient walletGoldClient = mock(WalletGoldClient.class); MessageEventProcess messageEventProcess = mock(MessageEventProcess.class); CpApply apply = new CpApply() .setId(3001L) @@ -46,7 +44,7 @@ class CpApplyListenerTest { .setStatus(CpApplyStatus.WAIT.name()); when(cpApplyService.getById(3001L)).thenReturn(apply); - when(cpApplyService.changeStatusById(3001L, CpApplyStatus.REIMBURSE)).thenReturn(true); + when(cpApplyService.changeStatusById(3001L, CpApplyStatus.EXPIRE)).thenReturn(true); when(userProfileGateway.getByUserId(1001L)).thenReturn(profile(1001L)); when(userProfileGateway.getByUserId(2001L)).thenReturn(profile(2001L)); when(imMessageClient.sendCustomMessage(any(CustomC2cMsgBodyCmd.class))) @@ -62,7 +60,7 @@ class CpApplyListenerTest { }); CpApplyListener listener = new CpApplyListener(cpApplyService, imMessageClient, - userProfileGateway, walletGoldClient, messageEventProcess); + userProfileGateway, messageEventProcess); assertEquals(Action.SUCCESS, listener.consume(new ConsumerMessage())); @@ -72,6 +70,7 @@ class CpApplyListenerTest { List messages = captor.getAllValues(); assertExpiredMessage(messages.get(0), "1001", "2001"); assertExpiredMessage(messages.get(1), "2001", "1001"); + verify(cpApplyService).changeStatusById(3001L, CpApplyStatus.EXPIRE); } @SuppressWarnings("unchecked") diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/user/user/CpApplyService.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/user/user/CpApplyService.java index 0f894c84..332648cc 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/user/user/CpApplyService.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/user/user/CpApplyService.java @@ -95,6 +95,17 @@ public interface CpApplyService extends BaseService { */ List refuseOtherWaitBetweenUsers(Long excludeApplyId, Long userId, Long cpUserId); + /** + * 拒绝两个用户之间除指定申请外的其他等待申请,并返回被拒绝的申请记录. + */ + List refuseOtherWaitAppliesBetweenUsers(Long excludeApplyId, Long userId, Long cpUserId); + + /** + * 拒绝指定用户所有同类型等待申请,并返回被拒绝的申请记录. + */ + List refuseWaitAppliesByUserAndRelation(Long excludeApplyId, Long userId, + String relationType); + /** * 获取两个用户之间已拒绝的申请. */ diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/user/user/impl/CpApplyServiceImpl.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/user/user/impl/CpApplyServiceImpl.java index ea5e1dbf..e7a88513 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/user/user/impl/CpApplyServiceImpl.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/user/user/impl/CpApplyServiceImpl.java @@ -119,8 +119,17 @@ public class CpApplyServiceImpl extends BaseServiceImpl imp @Override public List refuseOtherWaitBetweenUsers(Long excludeApplyId, Long userId, Long cpUserId) { - List applyIds = query() - .select(CpApply::getId) + return refuseOtherWaitAppliesBetweenUsers(excludeApplyId, userId, cpUserId) + .stream() + .map(CpApply::getId) + .filter(Objects::nonNull) + .toList(); + } + + @Override + public List refuseOtherWaitAppliesBetweenUsers(Long excludeApplyId, Long userId, + Long cpUserId) { + List applies = query() .eq(CpApply::getStatus, CpApplyStatus.WAIT) .ne(Objects.nonNull(excludeApplyId), CpApply::getId, excludeApplyId) .and(where -> where @@ -129,20 +138,48 @@ public class CpApplyServiceImpl extends BaseServiceImpl imp .or() .nested(w -> w.eq(CpApply::getSendApplyUserId, cpUserId) .eq(CpApply::getAcceptApplyUserId, userId))) - .list() - .stream() + .list(); + List applyIds = applies.stream() .map(CpApply::getId) .filter(Objects::nonNull) .toList(); if (applyIds.isEmpty()) { - return applyIds; + return applies; } update() .set(CpApply::getStatus, CpApplyStatus.REFUSE) .set(CpApply::getUpdateTime, LocalDateTime.now()) .in(CpApply::getId, applyIds) .execute(); - return applyIds; + applies.forEach(apply -> apply.setStatus(CpApplyStatus.REFUSE.name())); + return applies; + } + + @Override + public List refuseWaitAppliesByUserAndRelation(Long excludeApplyId, Long userId, + String relationType) { + List applies = query() + .eq(CpApply::getStatus, CpApplyStatus.WAIT) + .eq(CpApply::getRelationType, CpRelationshipType.normalize(relationType)) + .ne(Objects.nonNull(excludeApplyId), CpApply::getId, excludeApplyId) + .and(where -> where.eq(CpApply::getSendApplyUserId, userId) + .or() + .eq(CpApply::getAcceptApplyUserId, userId)) + .list(); + List applyIds = applies.stream() + .map(CpApply::getId) + .filter(Objects::nonNull) + .toList(); + if (applyIds.isEmpty()) { + return applies; + } + update() + .set(CpApply::getStatus, CpApplyStatus.REFUSE) + .set(CpApply::getUpdateTime, LocalDateTime.now()) + .in(CpApply::getId, applyIds) + .execute(); + applies.forEach(apply -> apply.setStatus(CpApplyStatus.REFUSE.name())); + return applies; } @Override diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/enums/user/user/CpApplyStatus.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/enums/user/user/CpApplyStatus.java index b749addd..155e1da5 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/enums/user/user/CpApplyStatus.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/enums/user/user/CpApplyStatus.java @@ -22,19 +22,24 @@ public enum CpApplyStatus { */ DISMISS, - /** - * 拒绝. - */ - REFUSE, - - /** - * 退款. - */ - REIMBURSE, - - /** - * 分手中. - */ + /** + * 拒绝. + */ + REFUSE, + + /** + * 退款. + */ + REIMBURSE, + + /** + * 已过期. + */ + EXPIRE, + + /** + * 分手中. + */ DISMISSING }