修复边界

This commit is contained in:
hy001 2026-05-23 14:02:23 +08:00
parent 3588d0aeee
commit fa6b9be148
8 changed files with 270 additions and 157 deletions

View File

@ -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<Long> 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<CpApply> 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<CpApply> autoRefuseWaitAppliesAfterAgree(CpApply cpApply, String relationType) {
Map<Long, CpApply> 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<CpApply> refuseWaitAppliesIfLimitReached(CpApply cpApply, Long userId,
String relationType) {
if (cpRelationshipService.countCp(userId, relationType) < relationMaxCount(relationType)) {
return List.of();
}
List<CpApply> 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<Long, CpApply> applyMap, List<CpApply> 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);

View File

@ -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<Long, CpApply> 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<Long, CpApply> applyMap, List<CpApply> 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) {

View File

@ -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<CpApplyEvent> 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<CustomC2cMsgBodyCmd> 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<CustomC2cMsgBodyCmd> 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<CustomC2cMsgBodyCmd> 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<CustomC2cMsgBodyCmd> 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<String, Object> data = (Map<String, Object>) 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<CustomC2cMsgBodyCmd> captor = ArgumentCaptor.forClass(
CustomC2cMsgBodyCmd.class);
@ -188,6 +297,13 @@ class ProcessCpApplyCmdTest {
return captor.getValue();
}
private List<CustomC2cMsgBodyCmd> sentCustomMessages(int count) {
ArgumentCaptor<CustomC2cMsgBodyCmd> 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);

View File

@ -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")) {

View File

@ -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<CustomC2cMsgBodyCmd> messages = captor.getAllValues();
assertExpiredMessage(messages.get(0), "1001", "2001");
assertExpiredMessage(messages.get(1), "2001", "1001");
verify(cpApplyService).changeStatusById(3001L, CpApplyStatus.EXPIRE);
}
@SuppressWarnings("unchecked")

View File

@ -95,6 +95,17 @@ public interface CpApplyService extends BaseService<CpApply> {
*/
List<Long> refuseOtherWaitBetweenUsers(Long excludeApplyId, Long userId, Long cpUserId);
/**
* 拒绝两个用户之间除指定申请外的其他等待申请并返回被拒绝的申请记录.
*/
List<CpApply> refuseOtherWaitAppliesBetweenUsers(Long excludeApplyId, Long userId, Long cpUserId);
/**
* 拒绝指定用户所有同类型等待申请并返回被拒绝的申请记录.
*/
List<CpApply> refuseWaitAppliesByUserAndRelation(Long excludeApplyId, Long userId,
String relationType);
/**
* 获取两个用户之间已拒绝的申请.
*/

View File

@ -119,8 +119,17 @@ public class CpApplyServiceImpl extends BaseServiceImpl<CpApplyDAO, CpApply> imp
@Override
public List<Long> refuseOtherWaitBetweenUsers(Long excludeApplyId, Long userId, Long cpUserId) {
List<Long> applyIds = query()
.select(CpApply::getId)
return refuseOtherWaitAppliesBetweenUsers(excludeApplyId, userId, cpUserId)
.stream()
.map(CpApply::getId)
.filter(Objects::nonNull)
.toList();
}
@Override
public List<CpApply> refuseOtherWaitAppliesBetweenUsers(Long excludeApplyId, Long userId,
Long cpUserId) {
List<CpApply> 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<CpApplyDAO, CpApply> imp
.or()
.nested(w -> w.eq(CpApply::getSendApplyUserId, cpUserId)
.eq(CpApply::getAcceptApplyUserId, userId)))
.list()
.stream()
.list();
List<Long> 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<CpApply> refuseWaitAppliesByUserAndRelation(Long excludeApplyId, Long userId,
String relationType) {
List<CpApply> 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<Long> 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

View File

@ -22,19 +22,24 @@ public enum CpApplyStatus {
*/
DISMISS,
/**
* 拒绝.
*/
REFUSE,
/**
* 退款.
*/
REIMBURSE,
/**
* 分手中.
*/
/**
* 拒绝.
*/
REFUSE,
/**
* 退款.
*/
REIMBURSE,
/**
* 已过期.
*/
EXPIRE,
/**
* 分手中.
*/
DISMISSING
}