From 8e37a3d33388be1485b144788656760f8ef4bd3d Mon Sep 17 00:00:00 2001 From: hy001 Date: Thu, 21 May 2026 16:19:53 +0800 Subject: [PATCH] =?UTF-8?q?CP=E5=85=B3=E7=B3=BB=E5=86=B7=E9=9D=99=E6=9C=9F?= =?UTF-8?q?=E8=A7=A3=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CpRelationshipRestController.java | 9 +- .../command/user/DismissCpApplyCmdExe.java | 67 ++++++--- .../query/UserCpPairUserProfileQryExe.java | 29 ++-- .../cp/CleanExpiredDismissingCpTask.java | 2 +- .../relation/UserCpRelationServiceImpl.java | 9 +- .../user/DismissCpApplyCmdExeTest.java | 135 ++++++++++++++++++ .../user/relation/cp/CpDismissApplyCO.java | 45 ++++++ .../user/relation/UserCpRelationService.java | 3 +- .../user/user/CpRelationshipService.java | 21 +-- .../user/impl/CpRelationshipServiceImpl.java | 68 +++++---- .../src/test/java/CpLocalFlowSmokeTest.java | 15 +- 11 files changed, 315 insertions(+), 88 deletions(-) create mode 100644 rc-service/rc-service-other/other-application/src/test/java/com/red/circle/other/app/command/user/DismissCpApplyCmdExeTest.java create mode 100644 rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/user/relation/cp/CpDismissApplyCO.java diff --git a/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/user/relation/CpRelationshipRestController.java b/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/user/relation/CpRelationshipRestController.java index 649e168d..36dd4765 100644 --- a/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/user/relation/CpRelationshipRestController.java +++ b/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/user/relation/CpRelationshipRestController.java @@ -3,6 +3,7 @@ package com.red.circle.other.adapter.app.user.relation; import com.red.circle.common.business.dto.cmd.AppExtCommand; import com.red.circle.framework.web.controller.BaseController; import com.red.circle.other.app.command.user.LoveLetterQueryCmdExe; +import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpDismissApplyCO; import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpPairUserProfileCO; import com.red.circle.other.domain.model.cp.loveletter.LoveLetterDetailCO; import com.red.circle.other.domain.model.cp.loveletter.LoveLetterWallCO; @@ -90,10 +91,10 @@ public class CpRelationshipRestController extends BaseController { * @eo.method get * @eo.request-type formdata */ - @GetMapping("/dismiss-apply") - public void dismiss(@Validated CpApplyDismissCmd cmd) { - userCpRelationService.dismissApply(cmd); - } + @GetMapping("/dismiss-apply") + public CpDismissApplyCO dismiss(@Validated CpApplyDismissCmd cmd) { + return userCpRelationService.dismissApply(cmd); + } /** * 获取用户cp申请ID. diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/user/DismissCpApplyCmdExe.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/user/DismissCpApplyCmdExe.java index 87908ae0..cfd30df1 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/user/DismissCpApplyCmdExe.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/user/DismissCpApplyCmdExe.java @@ -6,8 +6,8 @@ import com.red.circle.external.inner.model.cmd.message.notice.official.NoticeExt import com.red.circle.external.inner.model.enums.message.OfficialNoticeTypeEnum; import com.red.circle.framework.core.asserts.ResponseAssert; import com.red.circle.framework.core.response.CommonErrorCode; +import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpDismissApplyCO; import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyDismissCmd; -import com.red.circle.other.app.service.user.user.UserProfileService; import com.red.circle.other.domain.gateway.user.UserProfileGateway; import com.red.circle.other.domain.model.user.UserProfile; import com.red.circle.other.infra.common.user.UserGiftBackpackCommon; @@ -25,7 +25,6 @@ import com.red.circle.tool.core.collection.MapBuilder; import com.red.circle.tool.core.date.TimestampUtils; import java.util.Arrays; -import java.util.List; import java.util.Objects; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; @@ -37,7 +36,9 @@ import org.springframework.stereotype.Component; */ @Component @RequiredArgsConstructor -public class DismissCpApplyCmdExe { +public class DismissCpApplyCmdExe { + + private static final long DISMISS_DURATION_MS = 0L; private final CpValueService cpValueService; private final CpApplyService cpApplyService; @@ -51,45 +52,40 @@ public class DismissCpApplyCmdExe { private final UserProfileGateway userProfileGateway; private final CpRelationshipCacheService cpRelationshipCacheService; - public void execute(CpApplyDismissCmd cmd) { + public CpDismissApplyCO execute(CpApplyDismissCmd cmd) { String relationType = parseRelationType(cmd.getRelationType()); var cpRelationship = cpRelationshipService.getByUserId( cmd.requiredReqUserId(), cmd.getCpUserId(), relationType); if (Objects.isNull(cpRelationship)) { - return; + CpRelationship dismissingCp = cpRelationshipService.getDismissingCp( + cmd.requiredReqUserId(), cmd.getCpUserId(), relationType); + if (Objects.nonNull(dismissingCp)) { + cleanCpData(dismissingCp, relationType); + } + return buildDismissedResult(cmd.getCpUserId(), relationType, TimestampUtils.now().getTime()); } // 更新申请状态为解散 cpApplyService.dismiss(cmd.requiredReqUserId(), relationType); - // 更新CP关系为分手中,不删除数据 + // 解除冷静期为0,先标记解除再立即清理关系数据 cpRelationshipService.updateToDismissing(cmd.requiredReqUserId(), cmd.getCpUserId(), relationType); - cpRelationshipCacheService.remove(Arrays.asList(cmd.requiredReqUserId(), cmd.getCpUserId())); - sendDismissNotice(cmd, relationType); - - // 以下数据不删除,7天后由定时任务清理 - // weekCpValueCountService.removeThisWeek(...) - // cpValueService.deleteById(...) - // userGiftBackpackCommon.removeUserCpGift(...) - // userCpValueCacheService.remove(...) - // cpCabinAchieveService.deleteByCpValId(...) - // cpBlessRecordService.deleteByCpValId(...) - - } - - private String getSendApplyUserId(CpApplyDismissCmd cmd) { - return cmd.requiredReqUserId().toString(); - } + Long dismissEndTime = TimestampUtils.now().getTime() + DISMISS_DURATION_MS; + cleanCpData(cpRelationship, relationType); + return buildDismissedResult(cmd.getCpUserId(), relationType, dismissEndTime); + + } + private void sendDismissNotice(CpApplyDismissCmd cmd, String relationType) { UserProfile userProfile = userProfileGateway.getByUserId(cmd.requiredReqUserId()); if (Objects.isNull(userProfile)) { return; } - long dismissEndTime = TimestampUtils.now().getTime() + (7 * 24 * 60 * 60 * 1000L); + long dismissEndTime = TimestampUtils.now().getTime() + DISMISS_DURATION_MS; officialNoticeClient.send(NoticeExtTemplateTypeCmd.builder() .toAccount(cmd.getCpUserId()) .noticeType(OfficialNoticeTypeEnum.CP_DISMISS) @@ -107,6 +103,31 @@ public class DismissCpApplyCmdExe { .build()); } + private void cleanCpData(CpRelationship relationship, String relationType) { + cpRelationshipService.deleteByUserPair(relationship.getUserId(), relationship.getCpUserId(), + relationType); + weekCpValueCountService.removeThisWeek(relationship.getUserId(), relationship.getCpUserId()); + weekCpValueCountService.removeThisSeason(relationship.getUserId(), relationship.getCpUserId()); + cpValueService.deleteById(relationship.getCpValId()); + userGiftBackpackCommon.removeUserCpGift( + Sets.newHashSet(relationship.getUserId(), relationship.getCpUserId())); + userCpValueCacheService.remove(relationship.getUserId(), relationship.getCpUserId()); + cpCabinAchieveService.deleteByCpValId(relationship.getCpValId()); + cpBlessRecordService.deleteByCpValId(relationship.getCpValId()); + cpRelationshipCacheService.remove( + Arrays.asList(relationship.getUserId(), relationship.getCpUserId())); + } + + private CpDismissApplyCO buildDismissedResult(Long cpUserId, String relationType, + Long dismissEndTime) { + return new CpDismissApplyCO() + .setCpUserId(cpUserId) + .setRelationType(relationType) + .setStatus("NONE") + .setDismissEndTime(dismissEndTime) + .setDismissRemainSeconds(0L); + } + private String parseRelationType(String relationType) { try { return CpRelationshipType.normalize(relationType); diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/user/query/UserCpPairUserProfileQryExe.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/user/query/UserCpPairUserProfileQryExe.java index f22452fc..b1346882 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/user/query/UserCpPairUserProfileQryExe.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/user/query/UserCpPairUserProfileQryExe.java @@ -1,7 +1,6 @@ package com.red.circle.other.app.command.user.query; import com.red.circle.framework.core.asserts.ResponseAssert; -import com.red.circle.mq.business.model.event.task.TaskApprovalEvent; import com.red.circle.mq.rocket.business.producer.TaskMqMessage; import com.red.circle.other.infra.database.rds.service.user.user.CpValueService; import com.red.circle.tool.core.date.DateUtils; @@ -22,9 +21,9 @@ import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.Objects; +import java.util.stream.Stream; -import com.red.circle.tool.core.date.LocalDateTimeUtils; -import lombok.RequiredArgsConstructor; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; /** @@ -36,7 +35,7 @@ import org.springframework.stereotype.Component; @RequiredArgsConstructor public class UserCpPairUserProfileQryExe { - private static final long DISMISS_DURATION_MS = 7 * 24 * 60 * 60 * 1000L; + private static final long DISMISS_DURATION_MS = 0L; private final CpRelationshipService cpRelationshipService; private final UserProfileGateway userProfileGateway; @@ -50,14 +49,15 @@ public class UserCpPairUserProfileQryExe { UserProfile meUser = userProfileGateway.getByUserId(cmd.requiredReqUserId()); ResponseAssert.notNull(UserErrorCode.USER_INFO_NOT_FOUND, meUser); - List cpRelationshipList = cpRelationshipService.getByUserId( - cmd.requiredReqUserId(), relationType); - List dismissing = cpRelationshipService.getDismissingByUserId( - cmd.requiredReqUserId(), relationType); - cpRelationshipList.addAll(dismissing); - if (cpRelationshipList.isEmpty()) { - return Collections.emptyList(); - } + List cpRelationshipList = Stream.concat( + cpRelationshipService.getByUserId(cmd.requiredReqUserId(), relationType).stream(), + cpRelationshipService.getDismissingByUserId(cmd.requiredReqUserId(), relationType) + .stream() + .filter(UserCpPairUserProfileQryExe::isDismissingVisible)) + .toList(); + if (cpRelationshipList.isEmpty()) { + return Collections.emptyList(); + } return cpRelationshipList.stream() .map(cpRelationship -> new CpPairUserProfileCO() @@ -98,6 +98,11 @@ public class UserCpPairUserProfileQryExe { return cpRelationship.getDismissTime() + DISMISS_DURATION_MS; } + private static boolean isDismissingVisible(CpRelationship cpRelationship) { + Long dismissEndTime = dismissEndTime(cpRelationship); + return Objects.nonNull(dismissEndTime) && dismissEndTime > System.currentTimeMillis(); + } + private static Long dismissRemainSeconds(CpRelationship cpRelationship) { Long dismissEndTime = dismissEndTime(cpRelationship); if (Objects.isNull(dismissEndTime)) { diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/scheduler/cp/CleanExpiredDismissingCpTask.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/scheduler/cp/CleanExpiredDismissingCpTask.java index 9ad98184..98095ab6 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/scheduler/cp/CleanExpiredDismissingCpTask.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/scheduler/cp/CleanExpiredDismissingCpTask.java @@ -21,7 +21,7 @@ import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; /** - * 清理7天前分手中的CP数据. + * 清理已到期的解除关系数据. * * @author AI Assistant */ diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/user/relation/UserCpRelationServiceImpl.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/user/relation/UserCpRelationServiceImpl.java index ab2f5347..0c128d6e 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/user/relation/UserCpRelationServiceImpl.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/user/relation/UserCpRelationServiceImpl.java @@ -11,7 +11,8 @@ import com.red.circle.other.app.command.user.query.CpApplyIdQryExe; import com.red.circle.other.app.command.user.query.UserCpPairUserProfileQryExe; import com.red.circle.other.app.command.user.query.UserCpRelationQryExe; import com.red.circle.other.app.command.user.query.UserCpRelationQueryV4Exe; -import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpCabinUserProfileCO; +import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpCabinUserProfileCO; +import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpDismissApplyCO; import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpPairUserProfileCO; import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpUserProfileCO; import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyIdQueryCmd; @@ -77,9 +78,9 @@ public class UserCpRelationServiceImpl implements UserCpRelationService { } @Override - public void dismissApply(CpApplyDismissCmd cmd) { - dismissCpApplyCmdExe.execute(cmd); - } + public CpDismissApplyCO dismissApply(CpApplyDismissCmd cmd) { + return dismissCpApplyCmdExe.execute(cmd); + } @Override public String getCpApplyId(CpApplyIdQueryCmd cmd) { diff --git a/rc-service/rc-service-other/other-application/src/test/java/com/red/circle/other/app/command/user/DismissCpApplyCmdExeTest.java b/rc-service/rc-service-other/other-application/src/test/java/com/red/circle/other/app/command/user/DismissCpApplyCmdExeTest.java new file mode 100644 index 00000000..c0c75ded --- /dev/null +++ b/rc-service/rc-service-other/other-application/src/test/java/com/red/circle/other/app/command/user/DismissCpApplyCmdExeTest.java @@ -0,0 +1,135 @@ +package com.red.circle.other.app.command.user; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.red.circle.external.inner.endpoint.message.OfficialNoticeClient; +import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpDismissApplyCO; +import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyDismissCmd; +import com.red.circle.other.domain.gateway.user.UserProfileGateway; +import com.red.circle.other.domain.model.user.UserProfile; +import com.red.circle.other.infra.common.user.UserGiftBackpackCommon; +import com.red.circle.other.infra.database.cache.service.cp.CpRelationshipCacheService; +import com.red.circle.other.infra.database.cache.service.user.UserCpValueCacheService; +import com.red.circle.other.infra.database.mongo.service.user.count.WeekCpValueCountService; +import com.red.circle.other.infra.database.rds.entity.user.user.CpRelationship; +import com.red.circle.other.infra.database.rds.service.user.user.CpApplyService; +import com.red.circle.other.infra.database.rds.service.user.user.CpBlessRecordService; +import com.red.circle.other.infra.database.rds.service.user.user.CpCabinAchieveService; +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.CpRelationshipStatus; +import java.util.Arrays; +import org.junit.jupiter.api.Test; + +class DismissCpApplyCmdExeTest { + + @Test + void dismissShouldCleanRelationshipImmediatelyWhenCooldownIsZero() { + Fixture fixture = new Fixture(); + when(fixture.cpRelationshipService.getByUserId(1001L, 2001L, "CP")) + .thenReturn(relationship()); + + CpApplyDismissCmd cmd = new CpApplyDismissCmd() + .setCpUserId(2001L) + .setRelationType("CP"); + cmd.setReqUserId(1001L); + + CpDismissApplyCO result = fixture.exe.execute(cmd); + + assertEquals("NONE", result.getStatus()); + assertEquals("CP", result.getRelationType()); + assertEquals(2001L, result.getCpUserId()); + assertEquals(0L, result.getDismissRemainSeconds()); + assertNotNull(result.getDismissEndTime()); + + verify(fixture.cpApplyService).dismiss(1001L, "CP"); + verify(fixture.cpRelationshipService).updateToDismissing(1001L, 2001L, "CP"); + verify(fixture.cpRelationshipService).deleteByUserPair(1001L, 2001L, "CP"); + verify(fixture.weekCpValueCountService).removeThisWeek(1001L, 2001L); + verify(fixture.weekCpValueCountService).removeThisSeason(1001L, 2001L); + verify(fixture.cpValueService).deleteById(3001L); + verify(fixture.userCpValueCacheService).remove(1001L, 2001L); + verify(fixture.cpCabinAchieveService).deleteByCpValId(3001L); + verify(fixture.cpBlessRecordService).deleteByCpValId(3001L); + verify(fixture.cpRelationshipCacheService).remove(Arrays.asList(1001L, 2001L)); + } + + @Test + void dismissShouldCleanExistingDismissingRelationship() { + Fixture fixture = new Fixture(); + CpRelationship relationship = relationship().setStatus(CpRelationshipStatus.DISMISSING.name()); + when(fixture.cpRelationshipService.getDismissingCp(1001L, 2001L, "CP")) + .thenReturn(relationship); + + CpApplyDismissCmd cmd = new CpApplyDismissCmd() + .setCpUserId(2001L) + .setRelationType("CP"); + cmd.setReqUserId(1001L); + + CpDismissApplyCO result = fixture.exe.execute(cmd); + + assertEquals("NONE", result.getStatus()); + assertEquals(0L, result.getDismissRemainSeconds()); + verify(fixture.cpRelationshipService).deleteByUserPair(1001L, 2001L, "CP"); + } + + private static CpRelationship relationship() { + return new CpRelationship() + .setUserId(1001L) + .setCpUserId(2001L) + .setCpValId(3001L) + .setRelationType("CP") + .setStatus(CpRelationshipStatus.NORMAL.name()); + } + + private static UserProfile userProfile() { + UserProfile userProfile = new UserProfile(); + userProfile.setId(1001L); + userProfile.setAccount("1001"); + userProfile.setUserNickname("user-1001"); + userProfile.setUserAvatar("avatar"); + userProfile.setCountryCode("SA"); + userProfile.setCountryName("Saudi Arabia"); + return userProfile; + } + + private static class Fixture { + + private final CpValueService cpValueService = mock(CpValueService.class); + private final CpApplyService cpApplyService = mock(CpApplyService.class); + private final CpRelationshipService cpRelationshipService = mock(CpRelationshipService.class); + private final UserCpValueCacheService userCpValueCacheService = mock( + UserCpValueCacheService.class); + private final WeekCpValueCountService weekCpValueCountService = mock( + WeekCpValueCountService.class); + private final CpBlessRecordService cpBlessRecordService = mock(CpBlessRecordService.class); + private final CpCabinAchieveService cpCabinAchieveService = mock(CpCabinAchieveService.class); + private final CpRelationshipCacheService cpRelationshipCacheService = mock( + CpRelationshipCacheService.class); + private final DismissCpApplyCmdExe exe; + + private Fixture() { + OfficialNoticeClient officialNoticeClient = mock(OfficialNoticeClient.class); + UserGiftBackpackCommon userGiftBackpackCommon = mock(UserGiftBackpackCommon.class); + UserProfileGateway userProfileGateway = mock(UserProfileGateway.class); + when(userProfileGateway.getByUserId(1001L)).thenReturn(userProfile()); + + exe = new DismissCpApplyCmdExe( + cpValueService, + cpApplyService, + officialNoticeClient, + cpRelationshipService, + userGiftBackpackCommon, + weekCpValueCountService, + userCpValueCacheService, + cpBlessRecordService, + cpCabinAchieveService, + userProfileGateway, + cpRelationshipCacheService); + } + } +} diff --git a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/user/relation/cp/CpDismissApplyCO.java b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/user/relation/cp/CpDismissApplyCO.java new file mode 100644 index 00000000..17a9b266 --- /dev/null +++ b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/user/relation/cp/CpDismissApplyCO.java @@ -0,0 +1,45 @@ +package com.red.circle.other.app.dto.clientobject.user.relation.cp; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import com.red.circle.framework.dto.ClientObject; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * CP relationship dismiss result. + */ +@Data +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = true) +public class CpDismissApplyCO extends ClientObject { + + /** + * Target user id. + */ + @JsonSerialize(using = ToStringSerializer.class) + private Long cpUserId; + + /** + * Relationship type: CP/BROTHER/SISTERS. + */ + private String relationType; + + /** + * Relationship status: DISMISSING/NONE. + */ + private String status; + + /** + * Dismiss cooling-off end timestamp. + */ + @JsonSerialize(using = ToStringSerializer.class) + private Long dismissEndTime; + + /** + * Remaining cooling-off seconds. + */ + private Long dismissRemainSeconds; + +} diff --git a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/user/relation/UserCpRelationService.java b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/user/relation/UserCpRelationService.java index fd2d7453..0dde3576 100644 --- a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/user/relation/UserCpRelationService.java +++ b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/user/relation/UserCpRelationService.java @@ -3,6 +3,7 @@ package com.red.circle.other.app.service.user.relation; import com.red.circle.common.business.dto.cmd.UserIdCmd; import com.red.circle.common.business.dto.cmd.UserIdCommonCmd; import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpCabinUserProfileCO; +import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpDismissApplyCO; import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpPairUserProfileCO; import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpUserProfileCO; import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyIdQueryCmd; @@ -29,7 +30,7 @@ public interface UserCpRelationService { void processApply(ProcessApplyCmd cmd); - void dismissApply(CpApplyDismissCmd cmd); + CpDismissApplyCO dismissApply(CpApplyDismissCmd cmd); String getCpApplyId(CpApplyIdQueryCmd cmd); diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/user/user/CpRelationshipService.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/user/user/CpRelationshipService.java index c1385a0a..a32aecc9 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/user/user/CpRelationshipService.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/user/user/CpRelationshipService.java @@ -161,9 +161,14 @@ public interface CpRelationshipService extends BaseService { * 更新指定类型关系为分手中. */ void updateToDismissing(Long userId, Long cpUserId, String relationType); - - /** - * 复合CP(更新为正常状态). + + /** + * 删除双方指定类型关系. + */ + boolean deleteByUserPair(Long userId, Long cpUserId, String relationType); + + /** + * 复合CP(更新为正常状态). * * @param userId 用户id * @param cpUserId cp用户id @@ -175,11 +180,9 @@ public interface CpRelationshipService extends BaseService { */ void reconcile(Long userId, Long cpUserId, String relationType); - /** - * 获取7天前分手中的CP关系列表. - * - * @return CP关系列表 - */ - List listExpiredDismissingCp(); + /** + * 获取已到期的解除中关系列表. + */ + List listExpiredDismissingCp(); } diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/user/user/impl/CpRelationshipServiceImpl.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/user/user/impl/CpRelationshipServiceImpl.java index 9c67e217..3e92125d 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/user/user/impl/CpRelationshipServiceImpl.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/service/user/user/impl/CpRelationshipServiceImpl.java @@ -1,8 +1,9 @@ package com.red.circle.other.infra.database.rds.service.user.user.impl; -import com.red.circle.framework.mybatis.constant.PageConstant; -import com.red.circle.framework.mybatis.entity.TimestampBaseEntity; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.red.circle.framework.mybatis.constant.PageConstant; +import com.red.circle.framework.mybatis.entity.TimestampBaseEntity; import com.red.circle.framework.mybatis.service.impl.BaseServiceImpl; import com.red.circle.tool.core.collection.CollectionUtils; import com.red.circle.tool.core.date.LocalDateUtils; @@ -29,10 +30,12 @@ import org.springframework.stereotype.Service; */ @Service @RequiredArgsConstructor -public class CpRelationshipServiceImpl extends - BaseServiceImpl implements CpRelationshipService { - - private final CpRelationshipDAO cpRelationshipDAO; +public class CpRelationshipServiceImpl extends + BaseServiceImpl implements CpRelationshipService { + + private static final long DISMISS_DURATION_MS = 0L; + + private final CpRelationshipDAO cpRelationshipDAO; @Override public List listLatestCp(String sysOrigin, Integer size) { @@ -85,6 +88,7 @@ public class CpRelationshipServiceImpl extends public List getCpUserId(Long userId) { return query().select(CpRelationship::getCpUserId, TimestampBaseEntity::getCreateTime) .eq(CpRelationship::getUserId, userId) + .eq(CpRelationship::getStatus, CpRelationshipStatus.NORMAL.name()) .eq(CpRelationship::getRelationType, CpRelationshipType.CP.name()) .list() .stream() @@ -129,12 +133,14 @@ public class CpRelationshipServiceImpl extends } @Override - public Long getCpValByUserId(Long userId) { - return Optional.ofNullable(query() - .select(CpRelationship::getCpValId) - .eq(CpRelationship::getUserId, userId) - .last(PageConstant.LIMIT_ONE) - .getOne() + public Long getCpValByUserId(Long userId) { + return Optional.ofNullable(query() + .select(CpRelationship::getCpValId) + .eq(CpRelationship::getUserId, userId) + .eq(CpRelationship::getStatus, CpRelationshipStatus.NORMAL.name()) + .eq(CpRelationship::getRelationType, CpRelationshipType.CP.name()) + .last(PageConstant.LIMIT_ONE) + .getOne() ).map(CpRelationship::getCpValId).orElse(null); } @@ -175,6 +181,7 @@ public class CpRelationshipServiceImpl extends @Override public CpRelationship getByUserIdOrCpUserId(Long userId, String relationType) { return Optional.ofNullable(query() + .eq(CpRelationship::getStatus, CpRelationshipStatus.NORMAL.name()) .eq(Objects.nonNull(relationType), CpRelationship::getRelationType, Objects.nonNull(relationType) ? CpRelationshipType.normalize(relationType) : null) .and(where -> where.eq(CpRelationship::getUserId, userId) @@ -203,10 +210,7 @@ public class CpRelationshipServiceImpl extends @Override public int countCp(Long userId) { - return Math.toIntExact(query() - .eq(CpRelationship::getUserId, userId) - .eq(CpRelationship::getStatus, CpRelationshipStatus.NORMAL.name()) - .count()); + return countCp(userId, CpRelationshipType.CP.name()); } @Override @@ -255,9 +259,21 @@ public class CpRelationshipServiceImpl extends .nested(w -> w.eq(CpRelationship::getUserId, cpUserId).eq(CpRelationship::getCpUserId, userId)) ) .eq(CpRelationship::getStatus, CpRelationshipStatus.NORMAL.name()) - .execute(); - } - + .execute(); + } + + @Override + public boolean deleteByUserPair(Long userId, Long cpUserId, String relationType) { + return remove(new LambdaQueryWrapper() + .eq(CpRelationship::getRelationType, CpRelationshipType.normalize(relationType)) + .and(where -> where + .nested(w -> w.eq(CpRelationship::getUserId, userId) + .eq(CpRelationship::getCpUserId, cpUserId)) + .or() + .nested(w -> w.eq(CpRelationship::getUserId, cpUserId) + .eq(CpRelationship::getCpUserId, userId)))); + } + @Override public void reconcile(Long userId, Long cpUserId) { reconcile(userId, cpUserId, CpRelationshipType.CP.name()); @@ -280,12 +296,12 @@ public class CpRelationshipServiceImpl extends } @Override - public List listExpiredDismissingCp() { - Long sevenDaysAgo = LocalDateUtils.nowTimestamp().getTime() - (7 * 24 * 60 * 60 * 1000L) ; - return query() - .eq(CpRelationship::getStatus, CpRelationshipStatus.DISMISSING.name()) - .le(CpRelationship::getDismissTime, sevenDaysAgo) - .list(); - } + public List listExpiredDismissingCp() { + Long expiredAt = LocalDateUtils.nowTimestamp().getTime() - DISMISS_DURATION_MS; + return query() + .eq(CpRelationship::getStatus, CpRelationshipStatus.DISMISSING.name()) + .le(CpRelationship::getDismissTime, expiredAt) + .list(); + } } diff --git a/rc-service/rc-service-other/other-start/src/test/java/CpLocalFlowSmokeTest.java b/rc-service/rc-service-other/other-start/src/test/java/CpLocalFlowSmokeTest.java index a1d9e6f4..b0138a5e 100644 --- a/rc-service/rc-service-other/other-start/src/test/java/CpLocalFlowSmokeTest.java +++ b/rc-service/rc-service-other/other-start/src/test/java/CpLocalFlowSmokeTest.java @@ -13,6 +13,7 @@ import com.red.circle.other.app.command.user.ProcessCpApplyCmd; import com.red.circle.other.app.command.user.SendCpApplyCmdExe; import com.red.circle.other.app.command.user.query.UserCpPairUserProfileQryExe; import com.red.circle.other.app.command.user.query.UserCpCabinQueryExe; +import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpDismissApplyCO; import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpPairUserProfileCO; import com.red.circle.other.app.dto.clientobject.user.user.UserCpCabinCO; import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyDismissCmd; @@ -262,15 +263,13 @@ public class CpLocalFlowSmokeTest { .setRelationType("CP"); dismissCmd.setReqUserId(pair.sendUserId); dismissCmd.setReqSysOrigin(REQ_SYS_ORIGIN); - dismissCpApplyCmdExe.execute(dismissCmd); + CpDismissApplyCO dismissResult = dismissCpApplyCmdExe.execute(dismissCmd); + assertEquals("NONE", dismissResult.getStatus()); + assertEquals(Long.valueOf(0L), dismissResult.getDismissRemainSeconds()); - CpPairUserProfileCO dismissing = findPairView(pair.sendUserId, pair.acceptUserId, "CP"); - assertNotNull("CP pair after dismiss", dismissing); - assertEquals("DISMISSING", dismissing.getStatus()); - assertNotNull("dismissEndTime", dismissing.getDismissEndTime()); - assertNotNull("dismissRemainSeconds", dismissing.getDismissRemainSeconds()); - assertTrue("dismissRemainSeconds should be positive", - dismissing.getDismissRemainSeconds() > 0); + assertNull("CP relationship after dismiss", + cpRelationshipService.getByUserId(pair.sendUserId, pair.acceptUserId, "CP")); + assertNull("CP pair view after dismiss", findPairView(pair.sendUserId, pair.acceptUserId, "CP")); } private void assertCpCabinEmptyState(Long queryUserId, Long reqUserId, String relationType) {