CP
This commit is contained in:
parent
c02050274b
commit
3f59e5b653
@ -46,9 +46,14 @@ public class GiveGiftConfig implements Serializable {
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 礼物tab.
|
||||
*/
|
||||
private String giftTab;
|
||||
|
||||
}
|
||||
/**
|
||||
* 礼物tab.
|
||||
*/
|
||||
private String giftTab;
|
||||
|
||||
/**
|
||||
* CP礼物关系类型:CP/BROTHER/SISTERS.
|
||||
*/
|
||||
private String cpRelationType;
|
||||
|
||||
}
|
||||
|
||||
@ -91,15 +91,20 @@ public class GiftConfigDTO implements Serializable {
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 礼物tab.
|
||||
*/
|
||||
private String giftTab;
|
||||
|
||||
/**
|
||||
* 0.未删除 1.已删除.
|
||||
*/
|
||||
private Boolean del;
|
||||
/**
|
||||
* 礼物tab.
|
||||
*/
|
||||
private String giftTab;
|
||||
|
||||
/**
|
||||
* CP礼物关系类型:CP/BROTHER/SISTERS.
|
||||
*/
|
||||
private String cpRelationType;
|
||||
|
||||
/**
|
||||
* 0.未删除 1.已删除.
|
||||
*/
|
||||
private Boolean del;
|
||||
|
||||
/**
|
||||
* 幸运礼物规格ID.
|
||||
|
||||
@ -86,15 +86,20 @@ public class SysGiftConfigCO implements Serializable {
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 礼物tab.
|
||||
*/
|
||||
private String giftTab;
|
||||
|
||||
/**
|
||||
* 0.未删除 1.已删除.
|
||||
*/
|
||||
private Boolean del;
|
||||
/**
|
||||
* 礼物tab.
|
||||
*/
|
||||
private String giftTab;
|
||||
|
||||
/**
|
||||
* CP礼物关系类型:CP/BROTHER/SISTERS.
|
||||
*/
|
||||
private String cpRelationType;
|
||||
|
||||
/**
|
||||
* 0.未删除 1.已删除.
|
||||
*/
|
||||
private Boolean del;
|
||||
|
||||
/**
|
||||
* 幸运礼物规格ID.
|
||||
|
||||
@ -37,9 +37,12 @@ import org.springframework.stereotype.Component;
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class ProcessCpApplyCmd {
|
||||
|
||||
private final CpApplyService cpApplyService;
|
||||
public class ProcessCpApplyCmd {
|
||||
|
||||
private static final int CP_MAX_COUNT = 1;
|
||||
private static final int FRIEND_MAX_COUNT = 3;
|
||||
|
||||
private final CpApplyService cpApplyService;
|
||||
private final CpValueService cpValueService;
|
||||
private final ImMessageClient imMessageClient;
|
||||
private final WalletGoldClient walletGoldClient;
|
||||
@ -73,12 +76,12 @@ public class ProcessCpApplyCmd {
|
||||
cpRelationshipService.existsCp(cpApply.getSendApplyUserId(), cpApply.getAcceptApplyUserId(),
|
||||
relationType));
|
||||
|
||||
// 检查CP数量限制(最多4个)
|
||||
int senderCpCount = cpRelationshipService.countCp(cpApply.getSendApplyUserId());
|
||||
int receiverCpCount = cpRelationshipService.countCp(cpApply.getAcceptApplyUserId());
|
||||
ResponseAssert.isFalse(UserRelationErrorCode.CP_LIMIT_EXCEEDED, senderCpCount >= 4);
|
||||
ResponseAssert.isFalse(UserRelationErrorCode.CP_LIMIT_EXCEEDED, receiverCpCount >= 4);
|
||||
}
|
||||
int maxCount = relationMaxCount(relationType);
|
||||
ResponseAssert.isFalse(UserRelationErrorCode.CP_LIMIT_EXCEEDED,
|
||||
cpRelationshipService.countCp(cpApply.getSendApplyUserId(), relationType) >= maxCount);
|
||||
ResponseAssert.isFalse(UserRelationErrorCode.CP_LIMIT_EXCEEDED,
|
||||
cpRelationshipService.countCp(cpApply.getAcceptApplyUserId(), relationType) >= maxCount);
|
||||
}
|
||||
|
||||
// 操作失败
|
||||
ResponseAssert.isTrue(CommonErrorCode.OPERATING_FAILURE,
|
||||
@ -89,8 +92,6 @@ public class ProcessCpApplyCmd {
|
||||
return;
|
||||
}
|
||||
|
||||
refuseStatusWait(cmd, cpApply, relationType);
|
||||
|
||||
if (isReconcile) {
|
||||
// 复合:更新状态为NORMAL
|
||||
cpRelationshipService.reconcile(cpApply.getSendApplyUserId(), cpApply.getAcceptApplyUserId(),
|
||||
@ -100,19 +101,32 @@ public class ProcessCpApplyCmd {
|
||||
cpRelationshipService
|
||||
.addCp(cpApply.getSendApplyUserId(), cpApply.getAcceptApplyUserId(), createCpValue(),
|
||||
cmd.requireReqSysOrigin(), relationType);
|
||||
}
|
||||
|
||||
cpRelationshipCacheService.remove(Arrays.asList(cpApply.getSendApplyUserId(), cpApply.getAcceptApplyUserId()));
|
||||
}
|
||||
|
||||
private void refuseStatusWait(ProcessApplyCmd cmd, CpApply cpApply, String relationType) {
|
||||
}
|
||||
|
||||
refuseStatusWaitIfLimitReached(cmd, cpApply, relationType);
|
||||
|
||||
cpRelationshipCacheService.remove(Arrays.asList(cpApply.getSendApplyUserId(), cpApply.getAcceptApplyUserId()));
|
||||
}
|
||||
|
||||
private void refuseStatusWaitIfLimitReached(ProcessApplyCmd cmd, CpApply cpApply,
|
||||
String relationType) {
|
||||
if (cpRelationshipService.countCp(cpApply.getAcceptApplyUserId(), relationType)
|
||||
< relationMaxCount(relationType)) {
|
||||
return;
|
||||
}
|
||||
cpApplyService.refuseStatusWait(cmd.requiredReqUserId(), relationType);
|
||||
userMqMessageService.cpApplyDelayed(
|
||||
new CpApplyEvent()
|
||||
userMqMessageService.cpApplyDelayed(
|
||||
new CpApplyEvent()
|
||||
.setId(cpApply.getId())
|
||||
.setSysOrigin(SysOriginPlatformEnum.valueOf(cmd.requireReqSysOrigin())),
|
||||
TimestampUtils.nowPlusMinutes(1));
|
||||
}
|
||||
TimestampUtils.nowPlusMinutes(1));
|
||||
}
|
||||
|
||||
private int relationMaxCount(String relationType) {
|
||||
return Objects.equals(CpRelationshipType.CP, CpRelationshipType.of(relationType))
|
||||
? CP_MAX_COUNT
|
||||
: FRIEND_MAX_COUNT;
|
||||
}
|
||||
|
||||
private void returnGoldCoins(ProcessApplyCmd cmd, CpApply cpApply) {
|
||||
if (Objects.isNull(cpApply.getApplyConsumeGold())
|
||||
|
||||
@ -46,8 +46,11 @@ import org.springframework.stereotype.Component;
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class SendCpApplyCmdExe {
|
||||
|
||||
private final CpApplyService cpApplyService;
|
||||
|
||||
private static final int CP_MAX_COUNT = 1;
|
||||
private static final int FRIEND_MAX_COUNT = 3;
|
||||
|
||||
private final CpApplyService cpApplyService;
|
||||
private final OfficialNoticeClient officialNoticeClient;
|
||||
private final WalletGoldClient walletGoldClient;
|
||||
private final UserMqMessageService userMqMessageService;
|
||||
@ -63,12 +66,18 @@ public class SendCpApplyCmdExe {
|
||||
}
|
||||
|
||||
public boolean autoCreateFromCpGift(Long sendUserId, Long acceptUserId, String sysOrigin) {
|
||||
return autoCreateFromCpGift(sendUserId, acceptUserId, sysOrigin, CpRelationshipType.CP.name());
|
||||
}
|
||||
|
||||
public boolean autoCreateFromCpGift(Long sendUserId, Long acceptUserId, String sysOrigin,
|
||||
String relationTypeValue) {
|
||||
try {
|
||||
process(sendUserId, acceptUserId, sysOrigin, CpRelationshipType.CP.name(), false);
|
||||
process(sendUserId, acceptUserId, sysOrigin, relationTypeValue, false);
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
log.info("[CP] skip auto create cp apply from gift, sendUserId={}, acceptUserId={}, reason={}",
|
||||
sendUserId, acceptUserId, ex.getMessage());
|
||||
log.info(
|
||||
"[CP] skip auto create cp apply from gift, sendUserId={}, acceptUserId={}, relationType={}, reason={}",
|
||||
sendUserId, acceptUserId, relationTypeValue, ex.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -101,16 +110,12 @@ public class SendCpApplyCmdExe {
|
||||
cpRelationshipService
|
||||
.existsCp(sendUserId, acceptUserId, relationType.name()));
|
||||
|
||||
// 检查CP数量限制(最多4个)
|
||||
int senderCpCount = cpRelationshipService.countCp(sendUserId);
|
||||
int receiverCpCount = cpRelationshipService.countCp(acceptUserId);
|
||||
ResponseAssert.isFalse(UserRelationErrorCode.CP_LIMIT_EXCEEDED, senderCpCount >= 4);
|
||||
ResponseAssert.isFalse(UserRelationErrorCode.CP_LIMIT_EXCEEDED, receiverCpCount >= 4);
|
||||
validateRelationLimit(sendUserId, acceptUserId, relationType);
|
||||
}
|
||||
|
||||
// 您已发送申请
|
||||
ResponseAssert.isFalse(UserRelationErrorCode.YOU_HAVE_SENT_AN_APPLICATION,
|
||||
cpApplyService.existsNotProcessSendApply(sendUserId, relationType.name()));
|
||||
cpApplyService.exists(acceptUserId, sendUserId, relationType.name()));
|
||||
|
||||
// 对方已向你发送申请
|
||||
ResponseAssert.isFalse(UserRelationErrorCode.OTHER_SIDE_ALREADY_APPLIED,
|
||||
@ -166,6 +171,19 @@ public class SendCpApplyCmdExe {
|
||||
TimestampUtils.nowPlusDays(1));
|
||||
}
|
||||
|
||||
private void validateRelationLimit(Long sendUserId, Long acceptUserId,
|
||||
CpRelationshipType relationType) {
|
||||
int maxCount = relationMaxCount(relationType);
|
||||
ResponseAssert.isFalse(UserRelationErrorCode.CP_LIMIT_EXCEEDED,
|
||||
cpRelationshipService.countCp(sendUserId, relationType.name()) >= maxCount);
|
||||
ResponseAssert.isFalse(UserRelationErrorCode.CP_LIMIT_EXCEEDED,
|
||||
cpRelationshipService.countCp(acceptUserId, relationType.name()) >= maxCount);
|
||||
}
|
||||
|
||||
private int relationMaxCount(CpRelationshipType relationType) {
|
||||
return Objects.equals(relationType, CpRelationshipType.CP) ? CP_MAX_COUNT : FRIEND_MAX_COUNT;
|
||||
}
|
||||
|
||||
private CpRelationshipType parseRelationType(String relationTypeValue) {
|
||||
try {
|
||||
return CpRelationshipType.of(relationTypeValue);
|
||||
@ -177,12 +195,10 @@ public class SendCpApplyCmdExe {
|
||||
|
||||
private void validateRelationTypeGender(CpRelationshipType relationType, UserProfileDTO userProfile,
|
||||
UserProfileDTO acceptUserProfile) {
|
||||
if (Objects.equals(relationType, CpRelationshipType.CP)) {
|
||||
ResponseAssert.isFalse(UserRelationErrorCode.UNAVAILABLE_SAME_GENDER,
|
||||
Objects.equals(userProfile.getUserSex(), acceptUserProfile.getUserSex()));
|
||||
if (!Objects.equals(relationType, CpRelationshipType.CP)) {
|
||||
return;
|
||||
}
|
||||
ResponseAssert.isTrue(UserRelationErrorCode.RELATION_TYPE_GENDER_NOT_MATCH,
|
||||
ResponseAssert.isTrue(UserRelationErrorCode.UNAVAILABLE_SAME_GENDER,
|
||||
relationType.genderMatched(userProfile.getUserSex(), acceptUserProfile.getUserSex()));
|
||||
}
|
||||
|
||||
|
||||
@ -81,11 +81,12 @@ public interface GiftAppConvertor {
|
||||
return new GiveGiftConfig()
|
||||
.setId(giftConfig.getId())
|
||||
.setGiftCandy(giftConfig.getGiftCandy())
|
||||
.setGiftIntegral(giftConfig.getGiftIntegral())
|
||||
.setSpecial(giftConfig.getSpecial())
|
||||
.setType(giftConfig.getType())
|
||||
.setGiftTab(giftConfig.getGiftTab());
|
||||
}
|
||||
.setGiftIntegral(giftConfig.getGiftIntegral())
|
||||
.setSpecial(giftConfig.getSpecial())
|
||||
.setType(giftConfig.getType())
|
||||
.setGiftTab(giftConfig.getGiftTab())
|
||||
.setCpRelationType(giftConfig.getCpRelationType());
|
||||
}
|
||||
|
||||
default GiveAwayGiftBatchEvent toBackpackGift(GiveAwayGiftBackpackCmd cmd,
|
||||
GiftConfigDTO giftConfig, Long trackId) {
|
||||
|
||||
@ -807,12 +807,13 @@ public class GiveGiftsListener implements MessageListener {
|
||||
|
||||
GiveGiftConfig giftConfig = event.getGiftConfig();
|
||||
|
||||
return new GiftValue()
|
||||
.setCurrencyType(giftConfig.getType())
|
||||
.setGiftType(getGiftType(event, giftConfig))
|
||||
.setUnitPrice(giftConfig.getGiftCandy())
|
||||
.setQuantity(event.getQuantity())
|
||||
.setUserSize(event.acceptUserSize())
|
||||
return new GiftValue()
|
||||
.setCurrencyType(giftConfig.getType())
|
||||
.setGiftType(getGiftType(event, giftConfig))
|
||||
.setCpRelationType(giftConfig.getCpRelationType())
|
||||
.setUnitPrice(giftConfig.getGiftCandy())
|
||||
.setQuantity(event.getQuantity())
|
||||
.setUserSize(event.acceptUserSize())
|
||||
.setActualAmount(event.countConsumAmountTotal())
|
||||
.setGiftValue(event.checkGiftTypeEqGold() ?
|
||||
event.countSingleGiftGolds()
|
||||
|
||||
@ -57,9 +57,9 @@ import com.red.circle.other.infra.database.rds.entity.live.RoomMember;
|
||||
import com.red.circle.other.infra.database.rds.entity.user.user.ConfessionChance;
|
||||
import com.red.circle.other.infra.database.rds.entity.user.user.CpBlessRecord;
|
||||
import com.red.circle.other.infra.database.rds.entity.user.user.CpRelationship;
|
||||
import com.red.circle.other.infra.database.rds.entity.user.user.CpValue;
|
||||
import com.red.circle.other.infra.database.rds.entity.user.user.FriendshipCard;
|
||||
import com.red.circle.other.infra.database.rds.service.dynamic.DynamicContentService;
|
||||
import com.red.circle.other.infra.database.rds.entity.user.user.CpValue;
|
||||
import com.red.circle.other.infra.database.rds.entity.user.user.FriendshipCard;
|
||||
import com.red.circle.other.infra.database.rds.service.dynamic.DynamicContentService;
|
||||
import com.red.circle.other.infra.database.rds.service.dynamic.DynamicGiftService;
|
||||
import com.red.circle.other.infra.database.rds.service.dynamic.DynamicMessageService;
|
||||
import com.red.circle.other.infra.database.rds.service.game.GameRoomPkIntegralRecordService;
|
||||
@ -70,9 +70,10 @@ import com.red.circle.other.infra.database.rds.service.user.user.ConfessionChanc
|
||||
import com.red.circle.other.infra.database.rds.service.user.user.ConsumptionLevelService;
|
||||
import com.red.circle.other.infra.database.rds.service.user.user.CpBlessRecordService;
|
||||
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.database.rds.service.user.user.FriendshipCardService;
|
||||
import com.red.circle.other.inner.enums.config.EnumConfigKey;
|
||||
import com.red.circle.other.infra.database.rds.service.user.user.CpValueService;
|
||||
import com.red.circle.other.infra.database.rds.service.user.user.FriendshipCardService;
|
||||
import com.red.circle.other.infra.enums.user.user.CpRelationshipType;
|
||||
import com.red.circle.other.inner.enums.config.EnumConfigKey;
|
||||
import com.red.circle.other.inner.enums.game.GamePkTypeEnum;
|
||||
import com.red.circle.other.inner.enums.material.GiftCurrencyType;
|
||||
import com.red.circle.other.inner.enums.material.GiftSpecialEnum;
|
||||
@ -378,12 +379,15 @@ public class GiftCountStrategy implements GiftStrategy {
|
||||
if (CollectionUtils.isEmpty(runningWater.getAcceptUsers())) {
|
||||
return;
|
||||
}
|
||||
String relationType = CpRelationshipType.normalize(
|
||||
runningWater.getGiftValue().getCpRelationType());
|
||||
runningWater.getAcceptUsers().forEach(accept -> {
|
||||
if (Objects.equals(runningWater.getUserId(), accept.getAcceptUserId())) {
|
||||
return;
|
||||
}
|
||||
sendCpApplyCmdExe.autoCreateFromCpGift(
|
||||
runningWater.getUserId(), accept.getAcceptUserId(), runningWater.getSysOrigin());
|
||||
runningWater.getUserId(), accept.getAcceptUserId(), runningWater.getSysOrigin(),
|
||||
relationType);
|
||||
});
|
||||
} catch (Exception ex) {
|
||||
log.warn("[CP] skip auto create cp apply from gift, runningWaterId={}, giftId={}, sendUserId={}, reason={}",
|
||||
|
||||
@ -0,0 +1,110 @@
|
||||
package com.red.circle.other.app.command.user;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
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.external.inner.model.cmd.message.notice.official.NoticeExtTemplateTypeCmd;
|
||||
import com.red.circle.framework.dto.ResultResponse;
|
||||
import com.red.circle.mq.rocket.business.producer.UserMqMessageService;
|
||||
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
|
||||
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
|
||||
import com.red.circle.other.domain.gateway.user.ability.UserRegionGateway;
|
||||
import com.red.circle.other.domain.model.user.UserProfile;
|
||||
import com.red.circle.other.infra.database.cache.service.other.EnumConfigCacheService;
|
||||
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.database.rds.service.user.user.CpRelationshipService;
|
||||
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
|
||||
import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
class SendCpApplyCmdExeTest {
|
||||
|
||||
@Test
|
||||
void autoCreateFromCpGiftShouldNotRestrictBrotherAndSistersGender() {
|
||||
Fixture fixture = new Fixture(1, 0);
|
||||
|
||||
assertTrue(fixture.exe.autoCreateFromCpGift(1001L, 2001L, "LIKEI", "BROTHER"));
|
||||
assertEquals("BROTHER", fixture.savedApply().getRelationType());
|
||||
|
||||
fixture = new Fixture(0, 1);
|
||||
|
||||
assertTrue(fixture.exe.autoCreateFromCpGift(1001L, 2001L, "LIKEI", "SISTERS"));
|
||||
assertEquals("SISTERS", fixture.savedApply().getRelationType());
|
||||
}
|
||||
|
||||
@Test
|
||||
void autoCreateFromCpGiftShouldSkipSameGenderCp() {
|
||||
Fixture fixture = new Fixture(1, 1);
|
||||
|
||||
assertFalse(fixture.exe.autoCreateFromCpGift(1001L, 2001L, "LIKEI", "CP"));
|
||||
verify(fixture.cpApplyService, never()).save(any(CpApply.class));
|
||||
}
|
||||
|
||||
private static class Fixture {
|
||||
|
||||
private final CpApplyService cpApplyService = mock(CpApplyService.class);
|
||||
private final SendCpApplyCmdExe exe;
|
||||
|
||||
private Fixture(Integer sendSex, Integer acceptSex) {
|
||||
OfficialNoticeClient officialNoticeClient = mock(OfficialNoticeClient.class);
|
||||
WalletGoldClient walletGoldClient = mock(WalletGoldClient.class);
|
||||
UserMqMessageService userMqMessageService = mock(UserMqMessageService.class);
|
||||
CpRelationshipService cpRelationshipService = mock(CpRelationshipService.class);
|
||||
EnumConfigCacheService enumConfigCacheService = mock(EnumConfigCacheService.class);
|
||||
UserProfileGateway userProfileGateway = mock(UserProfileGateway.class);
|
||||
UserProfileAppConvertor userProfileAppConvertor = mock(UserProfileAppConvertor.class);
|
||||
UserRegionGateway userRegionGateway = mock(UserRegionGateway.class);
|
||||
|
||||
UserProfile sendProfile = new UserProfile();
|
||||
UserProfile acceptProfile = new UserProfile();
|
||||
UserProfileDTO sendProfileDTO = profile(1001L, sendSex);
|
||||
UserProfileDTO acceptProfileDTO = profile(2001L, acceptSex);
|
||||
|
||||
when(userRegionGateway.checkEqRegion(1001L, 2001L)).thenReturn(true);
|
||||
when(userProfileGateway.getByUserId(1001L)).thenReturn(sendProfile);
|
||||
when(userProfileGateway.getByUserId(2001L)).thenReturn(acceptProfile);
|
||||
when(userProfileAppConvertor.toUserProfileDTO(sendProfile)).thenReturn(sendProfileDTO);
|
||||
when(userProfileAppConvertor.toUserProfileDTO(acceptProfile)).thenReturn(acceptProfileDTO);
|
||||
when(officialNoticeClient.send(any(NoticeExtTemplateTypeCmd.class)))
|
||||
.thenReturn(ResultResponse.success());
|
||||
|
||||
exe = new SendCpApplyCmdExe(
|
||||
cpApplyService,
|
||||
officialNoticeClient,
|
||||
walletGoldClient,
|
||||
userMqMessageService,
|
||||
cpRelationshipService,
|
||||
enumConfigCacheService,
|
||||
userProfileGateway,
|
||||
userProfileAppConvertor,
|
||||
userRegionGateway
|
||||
);
|
||||
}
|
||||
|
||||
private CpApply savedApply() {
|
||||
ArgumentCaptor<CpApply> captor = ArgumentCaptor.forClass(CpApply.class);
|
||||
verify(cpApplyService).save(captor.capture());
|
||||
return captor.getValue();
|
||||
}
|
||||
|
||||
private static UserProfileDTO profile(Long userId, Integer sex) {
|
||||
UserProfileDTO userProfile = new UserProfileDTO();
|
||||
userProfile.setId(userId);
|
||||
userProfile.setUserSex(sex);
|
||||
userProfile.setAccount(userId.toString());
|
||||
userProfile.setUserNickname("user-" + userId);
|
||||
userProfile.setCountryCode("SA");
|
||||
userProfile.setCountryName("Saudi Arabia");
|
||||
return userProfile;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -63,15 +63,20 @@ public class GiftConfigCO extends ClientObject {
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 礼物tab.
|
||||
*/
|
||||
private String giftTab;
|
||||
|
||||
/**
|
||||
* 规格ID.
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
/**
|
||||
* 礼物tab.
|
||||
*/
|
||||
private String giftTab;
|
||||
|
||||
/**
|
||||
* CP礼物关系类型:CP/BROTHER/SISTERS.
|
||||
*/
|
||||
private String cpRelationType;
|
||||
|
||||
/**
|
||||
* 规格ID.
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long standardId;
|
||||
|
||||
/**
|
||||
|
||||
@ -27,15 +27,20 @@ public class GiftValue implements Serializable {
|
||||
*/
|
||||
private String currencyType;
|
||||
|
||||
/**
|
||||
* 礼物类型.
|
||||
*/
|
||||
private String giftType;
|
||||
|
||||
/**
|
||||
* 礼物单价.
|
||||
*/
|
||||
private BigDecimal unitPrice;
|
||||
/**
|
||||
* 礼物类型.
|
||||
*/
|
||||
private String giftType;
|
||||
|
||||
/**
|
||||
* CP礼物关系类型:CP/BROTHER/SISTERS.
|
||||
*/
|
||||
private String cpRelationType;
|
||||
|
||||
/**
|
||||
* 礼物单价.
|
||||
*/
|
||||
private BigDecimal unitPrice;
|
||||
|
||||
/**
|
||||
* 发送礼物数量.
|
||||
|
||||
@ -106,17 +106,23 @@ public class GiftConfig extends TimestampBaseEntity implements Serializable {
|
||||
@TableField("type")
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 礼物tab.
|
||||
*/
|
||||
@TableField("gift_tab")
|
||||
private String giftTab;
|
||||
|
||||
/**
|
||||
* 0.未删除 1.已删除.
|
||||
*/
|
||||
@TableField("is_del")
|
||||
private Boolean del;
|
||||
/**
|
||||
* 礼物tab.
|
||||
*/
|
||||
@TableField("gift_tab")
|
||||
private String giftTab;
|
||||
|
||||
/**
|
||||
* CP礼物关系类型:CP/BROTHER/SISTERS.
|
||||
*/
|
||||
@TableField("cp_relation_type")
|
||||
private String cpRelationType;
|
||||
|
||||
/**
|
||||
* 0.未删除 1.已删除.
|
||||
*/
|
||||
@TableField("is_del")
|
||||
private Boolean del;
|
||||
|
||||
/**
|
||||
* 幸运礼物规格ID.
|
||||
|
||||
@ -5,12 +5,13 @@ import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
|
||||
import com.red.circle.framework.dto.PageResult;
|
||||
import com.red.circle.framework.mybatis.constant.PageConstant;
|
||||
import com.red.circle.framework.mybatis.service.impl.BaseServiceImpl;
|
||||
import com.red.circle.other.infra.database.rds.dao.gift.GiftConfigDAO;
|
||||
import com.red.circle.other.infra.database.rds.entity.gift.GiftConfig;
|
||||
import com.red.circle.other.infra.database.rds.service.gift.GiftConfigService;
|
||||
import com.red.circle.other.inner.enums.material.GiftCurrencyType;
|
||||
import com.red.circle.other.inner.enums.material.GiftSpecialEnum;
|
||||
import com.red.circle.other.inner.enums.material.GiftTabEnum;
|
||||
import com.red.circle.other.infra.database.rds.dao.gift.GiftConfigDAO;
|
||||
import com.red.circle.other.infra.database.rds.entity.gift.GiftConfig;
|
||||
import com.red.circle.other.infra.database.rds.service.gift.GiftConfigService;
|
||||
import com.red.circle.other.infra.enums.user.user.CpRelationshipType;
|
||||
import com.red.circle.other.inner.enums.material.GiftCurrencyType;
|
||||
import com.red.circle.other.inner.enums.material.GiftSpecialEnum;
|
||||
import com.red.circle.other.inner.enums.material.GiftTabEnum;
|
||||
import com.red.circle.other.inner.model.cmd.sys.GiftQryCmd;
|
||||
import com.red.circle.tool.core.collection.CollectionUtils;
|
||||
import com.red.circle.tool.core.num.NumUtils;
|
||||
@ -223,20 +224,29 @@ public class GiftConfigServiceImpl extends BaseServiceImpl<GiftConfigDAO, GiftCo
|
||||
.set(GiftConfig::getSpecial, giftConfig.getSpecial())
|
||||
.set(GiftConfig::getRegions, giftConfig.getRegions())
|
||||
.set(GiftConfig::getType, giftConfig.getType())
|
||||
.set(GiftConfig::getSort, giftConfig.getSort())
|
||||
.set(GiftConfig::getGiftTab, giftConfig.getGiftTab())
|
||||
.set(GiftConfig::getStandardId, giftConfig.getStandardId())
|
||||
.set(GiftConfig::getExpiredTime, giftConfig.getExpiredTime())
|
||||
.set(GiftConfig::getExplanationGift,
|
||||
.set(GiftConfig::getSort, giftConfig.getSort())
|
||||
.set(GiftConfig::getGiftTab, giftConfig.getGiftTab())
|
||||
.set(GiftConfig::getCpRelationType, normalizeCpRelationType(giftConfig))
|
||||
.set(GiftConfig::getStandardId, giftConfig.getStandardId())
|
||||
.set(GiftConfig::getExpiredTime, giftConfig.getExpiredTime())
|
||||
.set(GiftConfig::getExplanationGift,
|
||||
Objects.nonNull(giftConfig.getExplanationGift()) ? giftConfig.getExplanationGift()
|
||||
: Boolean.FALSE)
|
||||
.set(GiftConfig::getUserId, giftConfig.getUserId())
|
||||
.eq(GiftConfig::getId, giftConfig.getId())
|
||||
.last(PageConstant.LIMIT_ONE)
|
||||
.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
.execute();
|
||||
}
|
||||
|
||||
private String normalizeCpRelationType(GiftConfig giftConfig) {
|
||||
if (Objects.isNull(giftConfig)
|
||||
|| !Objects.equals(giftConfig.getGiftTab(), GiftTabEnum.CP.name())) {
|
||||
return null;
|
||||
}
|
||||
return CpRelationshipType.normalize(giftConfig.getCpRelationType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean switchDelStatus(Long id, Boolean status) {
|
||||
return update().set(GiftConfig::getDel, status)
|
||||
.eq(GiftConfig::getId, id)
|
||||
|
||||
@ -123,16 +123,21 @@ public interface CpRelationshipService extends BaseService<CpRelationship> {
|
||||
*/
|
||||
CpRelationship getByUserIdOrCpUserId(Long userId, String relationType);
|
||||
|
||||
/**
|
||||
* 获取用户正常CP数量.
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @return CP数量
|
||||
*/
|
||||
int countCp(Long userId);
|
||||
|
||||
/**
|
||||
* 获取分手中的CP关系.
|
||||
/**
|
||||
* 获取用户正常CP数量.
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @return CP数量
|
||||
*/
|
||||
int countCp(Long userId);
|
||||
|
||||
/**
|
||||
* 获取用户指定类型正常关系数量.
|
||||
*/
|
||||
int countCp(Long userId, String relationType);
|
||||
|
||||
/**
|
||||
* 获取分手中的CP关系.
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @param cpUserId cp用户id
|
||||
|
||||
@ -201,13 +201,23 @@ public class CpRelationshipServiceImpl extends
|
||||
return cpUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countCp(Long userId) {
|
||||
return Math.toIntExact(query()
|
||||
.eq(CpRelationship::getUserId, userId)
|
||||
.count());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countCp(Long userId) {
|
||||
return Math.toIntExact(query()
|
||||
.eq(CpRelationship::getUserId, userId)
|
||||
.eq(CpRelationship::getStatus, CpRelationshipStatus.NORMAL.name())
|
||||
.count());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countCp(Long userId, String relationType) {
|
||||
return Math.toIntExact(query()
|
||||
.eq(CpRelationship::getUserId, userId)
|
||||
.eq(CpRelationship::getStatus, CpRelationshipStatus.NORMAL.name())
|
||||
.eq(CpRelationship::getRelationType, CpRelationshipType.normalize(relationType))
|
||||
.count());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CpRelationship getDismissingCp(Long userId, Long cpUserId) {
|
||||
return getDismissingCp(userId, cpUserId, CpRelationshipType.CP.name());
|
||||
|
||||
@ -15,18 +15,15 @@ public enum CpRelationshipType {
|
||||
CP,
|
||||
|
||||
/**
|
||||
* Brothers, requires both users to be male.
|
||||
* Brothers.
|
||||
*/
|
||||
BROTHER,
|
||||
|
||||
/**
|
||||
* Sisters, requires both users to be female.
|
||||
* Sisters.
|
||||
*/
|
||||
SISTERS;
|
||||
|
||||
private static final int FEMALE = 0;
|
||||
private static final int MALE = 1;
|
||||
|
||||
public static CpRelationshipType of(String value) {
|
||||
if (StringUtils.isBlank(value)) {
|
||||
return CP;
|
||||
@ -48,8 +45,7 @@ public enum CpRelationshipType {
|
||||
public boolean genderMatched(Integer sendUserSex, Integer acceptUserSex) {
|
||||
return switch (this) {
|
||||
case CP -> !Objects.equals(sendUserSex, acceptUserSex);
|
||||
case BROTHER -> Objects.equals(sendUserSex, MALE) && Objects.equals(acceptUserSex, MALE);
|
||||
case SISTERS -> Objects.equals(sendUserSex, FEMALE) && Objects.equals(acceptUserSex, FEMALE);
|
||||
case BROTHER, SISTERS -> true;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
package com.red.circle.other.infra.enums.user.user;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class CpRelationshipTypeTest {
|
||||
|
||||
@Test
|
||||
void cpRequiresDifferentGender() {
|
||||
assertTrue(CpRelationshipType.CP.genderMatched(1, 0));
|
||||
assertTrue(CpRelationshipType.CP.genderMatched(0, 1));
|
||||
assertFalse(CpRelationshipType.CP.genderMatched(1, 1));
|
||||
assertFalse(CpRelationshipType.CP.genderMatched(0, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void brotherAndSistersDoNotRestrictGender() {
|
||||
assertTrue(CpRelationshipType.BROTHER.genderMatched(1, 1));
|
||||
assertTrue(CpRelationshipType.BROTHER.genderMatched(1, 0));
|
||||
assertTrue(CpRelationshipType.BROTHER.genderMatched(0, 1));
|
||||
assertTrue(CpRelationshipType.BROTHER.genderMatched(0, 0));
|
||||
|
||||
assertTrue(CpRelationshipType.SISTERS.genderMatched(1, 1));
|
||||
assertTrue(CpRelationshipType.SISTERS.genderMatched(1, 0));
|
||||
assertTrue(CpRelationshipType.SISTERS.genderMatched(0, 1));
|
||||
assertTrue(CpRelationshipType.SISTERS.genderMatched(0, 0));
|
||||
}
|
||||
}
|
||||
@ -6,10 +6,12 @@ import com.red.circle.other.app.inner.convertor.material.GiftInnerConvertor;
|
||||
import com.red.circle.other.app.inner.service.material.gift.GiftConfigClientService;
|
||||
import com.red.circle.other.infra.database.cache.service.other.GameLuckyGiftCacheService;
|
||||
import com.red.circle.other.infra.database.cache.service.other.GiftCacheService;
|
||||
import com.red.circle.other.infra.database.rds.entity.gift.GiftConfig;
|
||||
import com.red.circle.other.infra.database.rds.service.gift.GiftConfigService;
|
||||
import com.red.circle.other.infra.database.rds.service.gift.GiftWallService;
|
||||
import com.red.circle.other.inner.model.cmd.sys.GiftQryCmd;
|
||||
import com.red.circle.other.infra.database.rds.entity.gift.GiftConfig;
|
||||
import com.red.circle.other.infra.database.rds.service.gift.GiftConfigService;
|
||||
import com.red.circle.other.infra.database.rds.service.gift.GiftWallService;
|
||||
import com.red.circle.other.infra.enums.user.user.CpRelationshipType;
|
||||
import com.red.circle.other.inner.enums.material.GiftTabEnum;
|
||||
import com.red.circle.other.inner.model.cmd.sys.GiftQryCmd;
|
||||
import com.red.circle.other.inner.model.dto.gift.UserGiftWallDTO;
|
||||
import com.red.circle.other.inner.model.dto.material.GiftConfigDTO;
|
||||
import java.sql.Timestamp;
|
||||
@ -65,10 +67,11 @@ public class GiftConfigClientServiceImpl implements GiftConfigClientService {
|
||||
return pageResult.convert(giftInnerConvertor::toGiftConfigDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateGift(GiftConfigDTO giftConfigDTO) {
|
||||
return giftConfigService.updateGift(giftInnerConvertor.toGiftConfig(giftConfigDTO));
|
||||
}
|
||||
@Override
|
||||
public Boolean updateGift(GiftConfigDTO giftConfigDTO) {
|
||||
return giftConfigService.updateGift(
|
||||
normalizeCpRelationType(giftInnerConvertor.toGiftConfig(giftConfigDTO)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGiftCache() {
|
||||
@ -80,10 +83,20 @@ public class GiftConfigClientServiceImpl implements GiftConfigClientService {
|
||||
gameLuckyGiftCacheService.removeRemainingInventory(id, standardId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean saveGift(GiftConfigDTO giftConfig) {
|
||||
return giftConfigService.save(giftInnerConvertor.toGiftConfig(giftConfig));
|
||||
}
|
||||
@Override
|
||||
public Boolean saveGift(GiftConfigDTO giftConfig) {
|
||||
return giftConfigService.save(normalizeCpRelationType(giftInnerConvertor.toGiftConfig(giftConfig)));
|
||||
}
|
||||
|
||||
private GiftConfig normalizeCpRelationType(GiftConfig giftConfig) {
|
||||
if (Objects.isNull(giftConfig)) {
|
||||
return null;
|
||||
}
|
||||
if (!Objects.equals(giftConfig.getGiftTab(), GiftTabEnum.CP.name())) {
|
||||
return giftConfig.setCpRelationType(null);
|
||||
}
|
||||
return giftConfig.setCpRelationType(CpRelationshipType.normalize(giftConfig.getCpRelationType()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean switchDelStatus(Long id, Boolean status) {
|
||||
|
||||
@ -367,24 +367,23 @@ public class TeamManualSalaryPaymentClientServiceImpl implements
|
||||
|
||||
List<TeamSalaryPayment> cyclePayments = listCyclePayments(salaryPaymentMap,
|
||||
target.getUserId(), billBelong);
|
||||
PaymentSummary paymentSummary = summarizePayments(cyclePayments);
|
||||
PaymentSummary receivedPaymentSummary = summarizeReceivedPayments(
|
||||
new ArrayList<>(salaryPaymentMap.values()), target.getUserId());
|
||||
BigDecimal expectedMemberSalary = salaryValue(billTarget.getMemberSalary());
|
||||
BigDecimal expectedAgentSalary = salaryValue(billTarget.getOwnSalary());
|
||||
BigDecimal expectedSalary = expectedTotalSalary(billTarget);
|
||||
BigDecimal payableSalary = expectedSalary.subtract(paymentSummary.getTotalIssuedSalary())
|
||||
BigDecimal payableSalary = expectedSalary.subtract(receivedPaymentSummary.getTotalIssuedSalary())
|
||||
.setScale(2, RoundingMode.DOWN);
|
||||
BigDecimal payableMemberSalary = expectedMemberSalary
|
||||
.subtract(paymentSummary.getMemberIssuedSalary())
|
||||
.subtract(receivedPaymentSummary.getMemberIssuedSalary())
|
||||
.setScale(2, RoundingMode.DOWN);
|
||||
BigDecimal payableAgentSalary = expectedAgentSalary
|
||||
.subtract(paymentSummary.getAgentIssuedSalary())
|
||||
.subtract(receivedPaymentSummary.getAgentIssuedSalary())
|
||||
.setScale(2, RoundingMode.DOWN);
|
||||
boolean currentLevelSettled = areCurrentRolesSettled(cyclePayments, target.getUserId(), region,
|
||||
billTarget, payableSalary);
|
||||
List<PolicyPayment> policyPayments = buildSettlementPayments(policyManager, billTarget,
|
||||
cyclePayments, target.getUserId(), region, paymentSummary, payableSalary,
|
||||
cyclePayments, target.getUserId(), region, receivedPaymentSummary, payableSalary,
|
||||
currentLevelSettled);
|
||||
|
||||
TeamManualSalaryPaymentDTO dto = new TeamManualSalaryPaymentDTO()
|
||||
|
||||
@ -151,10 +151,10 @@ public class CpLocalFlowSmokeTest {
|
||||
UserPair cpPair = findPair(candidates, 1, 0, "CP");
|
||||
runCpGiftApplyBlessDismissFlow(cpPair);
|
||||
|
||||
UserPair brotherPair = findPair(candidates, 1, 1, "BROTHER");
|
||||
UserPair brotherPair = findPair(candidates, 1, 0, "BROTHER");
|
||||
runNoChargeApplyAndAgreeFlow(brotherPair, "BROTHER");
|
||||
|
||||
UserPair sistersPair = findPair(candidates, 0, 0, "SISTERS");
|
||||
UserPair sistersPair = findPair(candidates, 0, 1, "SISTERS");
|
||||
runNoChargeApplyAndAgreeFlow(sistersPair, "SISTERS");
|
||||
}
|
||||
|
||||
@ -197,6 +197,36 @@ public class CpLocalFlowSmokeTest {
|
||||
cpApplyService.getId(sameGenderPair.acceptUserId, sameGenderPair.sendUserId, "CP"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cpGiftAutoApplyUsesGiftRelationType() {
|
||||
List<BaseInfo> candidates = baseInfoService.query()
|
||||
.select(BaseInfo::getId, BaseInfo::getUserSex, BaseInfo::getOriginSys,
|
||||
BaseInfo::getCountryCode)
|
||||
.eq(BaseInfo::getOriginSys, SYS_ORIGIN)
|
||||
.in(BaseInfo::getUserSex, Arrays.asList(0, 1))
|
||||
.orderByDesc(BaseInfo::getId)
|
||||
.last("LIMIT 500")
|
||||
.list();
|
||||
assertFalse("local LIKEI candidates should not be empty", candidates.isEmpty());
|
||||
|
||||
assertGiftAutoApplyRelationType(findPair(candidates, 1, 0, "BROTHER"), "BROTHER");
|
||||
assertGiftAutoApplyRelationType(findPair(candidates, 0, 1, "SISTERS"), "SISTERS");
|
||||
}
|
||||
|
||||
private void assertGiftAutoApplyRelationType(UserPair pair, String relationType) {
|
||||
boolean created = sendCpApplyCmdExe.autoCreateFromCpGift(pair.sendUserId,
|
||||
pair.acceptUserId, SYS_ORIGIN, relationType);
|
||||
assertTrue(relationType + " gift should auto create apply", created);
|
||||
|
||||
Long applyId = cpApplyService.getId(pair.acceptUserId, pair.sendUserId, relationType);
|
||||
assertNotNull(relationType + " auto apply id", applyId);
|
||||
createdApplyIds.add(applyId);
|
||||
|
||||
CpApply apply = cpApplyService.getById(applyId);
|
||||
assertEquals(relationType, apply.getRelationType());
|
||||
assertEquals(0, BigDecimal.ZERO.compareTo(apply.getApplyConsumeGold()));
|
||||
}
|
||||
|
||||
private void runCpGiftApplyBlessDismissFlow(UserPair pair) throws Exception {
|
||||
boolean created = sendCpApplyCmdExe.autoCreateFromCpGift(pair.sendUserId, pair.acceptUserId,
|
||||
SYS_ORIGIN);
|
||||
@ -394,14 +424,14 @@ public class CpLocalFlowSmokeTest {
|
||||
String relationType) {
|
||||
for (BaseInfo send : candidates) {
|
||||
if (!Objects.equals(send.getUserSex(), sendSex) || hasWaitApply(send.getId(), relationType)
|
||||
|| cpRelationshipService.countCp(send.getId()) >= 4) {
|
||||
|| cpRelationshipService.countCp(send.getId(), relationType) >= relationMaxCount(relationType)) {
|
||||
continue;
|
||||
}
|
||||
for (BaseInfo accept : candidates) {
|
||||
if (Objects.equals(send.getId(), accept.getId())
|
||||
|| !Objects.equals(accept.getUserSex(), acceptSex)
|
||||
|| hasReceivedWaitApply(accept.getId(), relationType)
|
||||
|| cpRelationshipService.countCp(accept.getId()) >= 4
|
||||
|| cpRelationshipService.countCp(accept.getId(), relationType) >= relationMaxCount(relationType)
|
||||
|| cpRelationshipService.existsCp(send.getId(), accept.getId(), relationType)) {
|
||||
continue;
|
||||
}
|
||||
@ -417,6 +447,10 @@ public class CpLocalFlowSmokeTest {
|
||||
return cpApplyService.existsNotProcessSendApply(sendUserId, relationType);
|
||||
}
|
||||
|
||||
private int relationMaxCount(String relationType) {
|
||||
return Objects.equals("CP", relationType) ? 1 : 3;
|
||||
}
|
||||
|
||||
private boolean hasReceivedWaitApply(Long acceptUserId, String relationType) {
|
||||
return cpApplyService.query()
|
||||
.eq(CpApply::getAcceptApplyUserId, acceptUserId)
|
||||
|
||||
7
sql/20260521_sys_gift_config_cp_relation_type.sql
Normal file
7
sql/20260521_sys_gift_config_cp_relation_type.sql
Normal file
@ -0,0 +1,7 @@
|
||||
ALTER TABLE `sys_gift_config`
|
||||
ADD COLUMN `cp_relation_type` varchar(32) DEFAULT NULL COMMENT 'CP礼物关系类型:CP/BROTHER/SISTERS' AFTER `gift_tab`;
|
||||
|
||||
UPDATE `sys_gift_config`
|
||||
SET `cp_relation_type` = 'CP'
|
||||
WHERE `gift_tab` = 'CP'
|
||||
AND (`cp_relation_type` IS NULL OR `cp_relation_type` = '');
|
||||
Loading…
x
Reference in New Issue
Block a user