增加校验
This commit is contained in:
parent
0260498bd3
commit
c2e28b5cb3
@ -4,6 +4,7 @@ import com.red.circle.common.business.dto.cmd.AppExtCommand;
|
|||||||
import com.red.circle.framework.web.controller.BaseController;
|
import com.red.circle.framework.web.controller.BaseController;
|
||||||
import com.red.circle.other.app.command.user.LoveLetterQueryCmdExe;
|
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.CpDismissApplyCO;
|
||||||
|
import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpGiftRelationCheckCO;
|
||||||
import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpPairUserProfileCO;
|
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.LoveLetterDetailCO;
|
||||||
import com.red.circle.other.domain.model.cp.loveletter.LoveLetterWallCO;
|
import com.red.circle.other.domain.model.cp.loveletter.LoveLetterWallCO;
|
||||||
@ -11,6 +12,7 @@ import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyIdQueryCmd;
|
|||||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyCmd;
|
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyCmd;
|
||||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyDismissCmd;
|
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyDismissCmd;
|
||||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyStatusQueryCmd;
|
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyStatusQueryCmd;
|
||||||
|
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpGiftRelationCheckCmd;
|
||||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpRelationshipQueryCmd;
|
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpRelationshipQueryCmd;
|
||||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.ProcessApplyCmd;
|
import com.red.circle.other.app.dto.cmd.user.relation.cp.ProcessApplyCmd;
|
||||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.loveletter.SendLoveLetterCmd;
|
import com.red.circle.other.app.dto.cmd.user.relation.cp.loveletter.SendLoveLetterCmd;
|
||||||
@ -123,6 +125,19 @@ public class CpRelationshipRestController extends BaseController {
|
|||||||
return userCpRelationService.getCpApplyStatus(cmd);
|
return userCpRelationService.getCpApplyStatus(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CP礼物关系名额校验.
|
||||||
|
*
|
||||||
|
* @eo.name CP礼物关系名额校验.
|
||||||
|
* @eo.url /gift-relation/check
|
||||||
|
* @eo.method get
|
||||||
|
* @eo.request-type formdata
|
||||||
|
*/
|
||||||
|
@GetMapping("/gift-relation/check")
|
||||||
|
public CpGiftRelationCheckCO checkGiftRelation(@Validated CpGiftRelationCheckCmd cmd) {
|
||||||
|
return userCpRelationService.checkGiftRelation(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送CP告白信封.
|
* 发送CP告白信封.
|
||||||
*
|
*
|
||||||
|
|||||||
@ -42,9 +42,6 @@ import org.springframework.stereotype.Component;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class SendCpApplyCmdExe {
|
public class SendCpApplyCmdExe {
|
||||||
|
|
||||||
private static final int CP_MAX_COUNT = 1;
|
|
||||||
private static final int FRIEND_MAX_COUNT = 3;
|
|
||||||
|
|
||||||
private final CpApplyService cpApplyService;
|
private final CpApplyService cpApplyService;
|
||||||
private final ImMessageClient imMessageClient;
|
private final ImMessageClient imMessageClient;
|
||||||
private final WalletGoldClient walletGoldClient;
|
private final WalletGoldClient walletGoldClient;
|
||||||
@ -207,7 +204,7 @@ public class SendCpApplyCmdExe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int relationMaxCount(CpRelationshipType relationType) {
|
private int relationMaxCount(CpRelationshipType relationType) {
|
||||||
return Objects.equals(relationType, CpRelationshipType.CP) ? CP_MAX_COUNT : FRIEND_MAX_COUNT;
|
return relationType.maxCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
private CpRelationshipType parseRelationType(String relationTypeValue) {
|
private CpRelationshipType parseRelationType(String relationTypeValue) {
|
||||||
|
|||||||
@ -0,0 +1,81 @@
|
|||||||
|
package com.red.circle.other.app.command.user.query;
|
||||||
|
|
||||||
|
import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpGiftRelationCheckCO;
|
||||||
|
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpGiftRelationCheckCmd;
|
||||||
|
import com.red.circle.other.infra.database.rds.service.user.user.CpRelationshipService;
|
||||||
|
import com.red.circle.other.infra.enums.user.user.CpRelationshipType;
|
||||||
|
import java.util.Objects;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a relationship gift can trigger a relationship apply.
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class CpGiftRelationCheckQryExe {
|
||||||
|
|
||||||
|
private static final String OK_MSG = "OK";
|
||||||
|
private static final String USER_FULL_MSG = "Your relationships are full.";
|
||||||
|
private static final String ACCEPT_USER_FULL_MSG = "The other party's relationships are full.";
|
||||||
|
private static final String RELATION_TYPE_NOT_SUPPORTED_MSG = "relationType is not supported.";
|
||||||
|
|
||||||
|
private final CpRelationshipService cpRelationshipService;
|
||||||
|
|
||||||
|
public CpGiftRelationCheckCO execute(CpGiftRelationCheckCmd cmd) {
|
||||||
|
Long userId = cmd.requiredReqUserId();
|
||||||
|
Long acceptUserId = cmd.getAcceptUserId();
|
||||||
|
CpRelationshipType relationType = parseRelationType(cmd.getRelationType());
|
||||||
|
if (Objects.isNull(relationType)) {
|
||||||
|
return new CpGiftRelationCheckCO()
|
||||||
|
.setStatus(false)
|
||||||
|
.setMsg(RELATION_TYPE_NOT_SUPPORTED_MSG)
|
||||||
|
.setRelationType(cmd.getRelationType())
|
||||||
|
.setUserId(userId)
|
||||||
|
.setAcceptUserId(acceptUserId);
|
||||||
|
}
|
||||||
|
int maxCount = relationType.maxCount();
|
||||||
|
int userCount = cpRelationshipService.countCp(userId, relationType.name());
|
||||||
|
int acceptUserCount = cpRelationshipService.countCp(acceptUserId, relationType.name());
|
||||||
|
boolean userFull = userCount >= maxCount;
|
||||||
|
boolean acceptUserFull = acceptUserCount >= maxCount;
|
||||||
|
boolean skipApplyCheck = Objects.equals(userId, acceptUserId)
|
||||||
|
|| cpRelationshipService.existsRelationship(userId, acceptUserId)
|
||||||
|
|| Objects.nonNull(cpRelationshipService.getDismissingCp(userId, acceptUserId,
|
||||||
|
relationType.name()));
|
||||||
|
boolean canContinue = skipApplyCheck || (!userFull && !acceptUserFull);
|
||||||
|
|
||||||
|
return new CpGiftRelationCheckCO()
|
||||||
|
.setStatus(canContinue)
|
||||||
|
.setMsg(message(canContinue, userFull, acceptUserFull))
|
||||||
|
.setRelationType(relationType.name())
|
||||||
|
.setUserId(userId)
|
||||||
|
.setAcceptUserId(acceptUserId)
|
||||||
|
.setUserRelationCount(userCount)
|
||||||
|
.setAcceptUserRelationCount(acceptUserCount)
|
||||||
|
.setMaxRelationCount(maxCount)
|
||||||
|
.setUserRelationFull(userFull)
|
||||||
|
.setAcceptUserRelationFull(acceptUserFull);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String message(boolean canContinue, boolean userFull, boolean acceptUserFull) {
|
||||||
|
if (canContinue) {
|
||||||
|
return OK_MSG;
|
||||||
|
}
|
||||||
|
if (userFull) {
|
||||||
|
return USER_FULL_MSG;
|
||||||
|
}
|
||||||
|
if (acceptUserFull) {
|
||||||
|
return ACCEPT_USER_FULL_MSG;
|
||||||
|
}
|
||||||
|
return OK_MSG;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CpRelationshipType parseRelationType(String relationTypeValue) {
|
||||||
|
try {
|
||||||
|
return CpRelationshipType.of(relationTypeValue);
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,15 +9,18 @@ import com.red.circle.other.app.command.user.SendCpApplyCmdExe;
|
|||||||
import com.red.circle.other.app.command.user.SendLoveLetterCmdExe;
|
import com.red.circle.other.app.command.user.SendLoveLetterCmdExe;
|
||||||
import com.red.circle.other.app.command.user.query.CpApplyIdQryExe;
|
import com.red.circle.other.app.command.user.query.CpApplyIdQryExe;
|
||||||
import com.red.circle.other.app.command.user.query.CpApplyStatusQryExe;
|
import com.red.circle.other.app.command.user.query.CpApplyStatusQryExe;
|
||||||
|
import com.red.circle.other.app.command.user.query.CpGiftRelationCheckQryExe;
|
||||||
import com.red.circle.other.app.command.user.query.UserCpPairUserProfileQryExe;
|
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.UserCpRelationQryExe;
|
||||||
import com.red.circle.other.app.command.user.query.UserCpRelationQueryV4Exe;
|
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.CpDismissApplyCO;
|
||||||
|
import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpGiftRelationCheckCO;
|
||||||
import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpPairUserProfileCO;
|
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.clientobject.user.relation.cp.CpUserProfileCO;
|
||||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyIdQueryCmd;
|
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyIdQueryCmd;
|
||||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyStatusQueryCmd;
|
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyStatusQueryCmd;
|
||||||
|
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpGiftRelationCheckCmd;
|
||||||
import com.red.circle.other.domain.model.cp.loveletter.LoveLetterDetailCO;
|
import com.red.circle.other.domain.model.cp.loveletter.LoveLetterDetailCO;
|
||||||
import com.red.circle.other.domain.model.cp.loveletter.LoveLetterWallCO;
|
import com.red.circle.other.domain.model.cp.loveletter.LoveLetterWallCO;
|
||||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyCmd;
|
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyCmd;
|
||||||
@ -43,6 +46,7 @@ public class UserCpRelationServiceImpl implements UserCpRelationService {
|
|||||||
|
|
||||||
private final CpApplyIdQryExe cpApplyIdQryExe;
|
private final CpApplyIdQryExe cpApplyIdQryExe;
|
||||||
private final CpApplyStatusQryExe cpApplyStatusQryExe;
|
private final CpApplyStatusQryExe cpApplyStatusQryExe;
|
||||||
|
private final CpGiftRelationCheckQryExe cpGiftRelationCheckQryExe;
|
||||||
private final SendCpApplyCmdExe sendCpApplyCmdExe;
|
private final SendCpApplyCmdExe sendCpApplyCmdExe;
|
||||||
private final ProcessCpApplyCmd processCpApplyCmd;
|
private final ProcessCpApplyCmd processCpApplyCmd;
|
||||||
private final DismissCpApplyCmdExe dismissCpApplyCmdExe;
|
private final DismissCpApplyCmdExe dismissCpApplyCmdExe;
|
||||||
@ -95,6 +99,11 @@ public class UserCpRelationServiceImpl implements UserCpRelationService {
|
|||||||
return cpApplyStatusQryExe.execute(cmd);
|
return cpApplyStatusQryExe.execute(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CpGiftRelationCheckCO checkGiftRelation(CpGiftRelationCheckCmd cmd) {
|
||||||
|
return cpGiftRelationCheckQryExe.execute(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CpCabinUserProfileCO getCpUserV4(UserIdCommonCmd cmd) {
|
public CpCabinUserProfileCO getCpUserV4(UserIdCommonCmd cmd) {
|
||||||
return userCpRelationQueryV4Exe.execute(cmd);
|
return userCpRelationQueryV4Exe.execute(cmd);
|
||||||
|
|||||||
@ -0,0 +1,119 @@
|
|||||||
|
package com.red.circle.other.app.command.user.query;
|
||||||
|
|
||||||
|
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.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpGiftRelationCheckCO;
|
||||||
|
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpGiftRelationCheckCmd;
|
||||||
|
import com.red.circle.other.infra.database.rds.entity.user.user.CpRelationship;
|
||||||
|
import com.red.circle.other.infra.database.rds.service.user.user.CpRelationshipService;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class CpGiftRelationCheckQryExeTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldReturnOkWhenBothUsersHaveAvailableCpSlot() {
|
||||||
|
CpRelationshipService cpRelationshipService = mock(CpRelationshipService.class);
|
||||||
|
CpGiftRelationCheckQryExe exe = new CpGiftRelationCheckQryExe(cpRelationshipService);
|
||||||
|
|
||||||
|
CpGiftRelationCheckCO result = exe.execute(cmd(1001L, 2001L, "CP"));
|
||||||
|
|
||||||
|
assertTrue(result.getStatus());
|
||||||
|
assertEquals("OK", result.getMsg());
|
||||||
|
assertEquals("CP", result.getRelationType());
|
||||||
|
assertEquals(0, result.getUserRelationCount());
|
||||||
|
assertEquals(0, result.getAcceptUserRelationCount());
|
||||||
|
assertEquals(1, result.getMaxRelationCount());
|
||||||
|
assertFalse(result.getUserRelationFull());
|
||||||
|
assertFalse(result.getAcceptUserRelationFull());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldReturnFalseWhenSenderRelationshipIsFull() {
|
||||||
|
CpRelationshipService cpRelationshipService = mock(CpRelationshipService.class);
|
||||||
|
when(cpRelationshipService.countCp(1001L, "CP")).thenReturn(1);
|
||||||
|
CpGiftRelationCheckQryExe exe = new CpGiftRelationCheckQryExe(cpRelationshipService);
|
||||||
|
|
||||||
|
CpGiftRelationCheckCO result = exe.execute(cmd(1001L, 2001L, "CP"));
|
||||||
|
|
||||||
|
assertFalse(result.getStatus());
|
||||||
|
assertEquals("Your relationships are full.", result.getMsg());
|
||||||
|
assertEquals(1, result.getUserRelationCount());
|
||||||
|
assertEquals(0, result.getAcceptUserRelationCount());
|
||||||
|
assertTrue(result.getUserRelationFull());
|
||||||
|
assertFalse(result.getAcceptUserRelationFull());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldReturnFalseWhenReceiverRelationshipIsFull() {
|
||||||
|
CpRelationshipService cpRelationshipService = mock(CpRelationshipService.class);
|
||||||
|
when(cpRelationshipService.countCp(1001L, "BROTHER")).thenReturn(2);
|
||||||
|
when(cpRelationshipService.countCp(2001L, "BROTHER")).thenReturn(3);
|
||||||
|
CpGiftRelationCheckQryExe exe = new CpGiftRelationCheckQryExe(cpRelationshipService);
|
||||||
|
|
||||||
|
CpGiftRelationCheckCO result = exe.execute(cmd(1001L, 2001L, "BROTHER"));
|
||||||
|
|
||||||
|
assertFalse(result.getStatus());
|
||||||
|
assertEquals("The other party's relationships are full.", result.getMsg());
|
||||||
|
assertEquals(2, result.getUserRelationCount());
|
||||||
|
assertEquals(3, result.getAcceptUserRelationCount());
|
||||||
|
assertEquals(3, result.getMaxRelationCount());
|
||||||
|
assertFalse(result.getUserRelationFull());
|
||||||
|
assertTrue(result.getAcceptUserRelationFull());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldNotBlockGiftWhenUsersAlreadyHaveRelationship() {
|
||||||
|
CpRelationshipService cpRelationshipService = mock(CpRelationshipService.class);
|
||||||
|
when(cpRelationshipService.countCp(1001L, "CP")).thenReturn(1);
|
||||||
|
when(cpRelationshipService.countCp(2001L, "CP")).thenReturn(1);
|
||||||
|
when(cpRelationshipService.existsRelationship(1001L, 2001L)).thenReturn(true);
|
||||||
|
CpGiftRelationCheckQryExe exe = new CpGiftRelationCheckQryExe(cpRelationshipService);
|
||||||
|
|
||||||
|
CpGiftRelationCheckCO result = exe.execute(cmd(1001L, 2001L, "CP"));
|
||||||
|
|
||||||
|
assertTrue(result.getStatus());
|
||||||
|
assertEquals("OK", result.getMsg());
|
||||||
|
assertTrue(result.getUserRelationFull());
|
||||||
|
assertTrue(result.getAcceptUserRelationFull());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldNotBlockGiftWhenRelationIsDismissing() {
|
||||||
|
CpRelationshipService cpRelationshipService = mock(CpRelationshipService.class);
|
||||||
|
when(cpRelationshipService.countCp(1001L, "SISTERS")).thenReturn(3);
|
||||||
|
when(cpRelationshipService.countCp(2001L, "SISTERS")).thenReturn(3);
|
||||||
|
when(cpRelationshipService.getDismissingCp(1001L, 2001L, "SISTERS"))
|
||||||
|
.thenReturn(new CpRelationship());
|
||||||
|
CpGiftRelationCheckQryExe exe = new CpGiftRelationCheckQryExe(cpRelationshipService);
|
||||||
|
|
||||||
|
CpGiftRelationCheckCO result = exe.execute(cmd(1001L, 2001L, "SISTERS"));
|
||||||
|
|
||||||
|
assertTrue(result.getStatus());
|
||||||
|
assertEquals("OK", result.getMsg());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldReturnFalseForUnsupportedRelationTypeWithoutThrowing() {
|
||||||
|
CpRelationshipService cpRelationshipService = mock(CpRelationshipService.class);
|
||||||
|
CpGiftRelationCheckQryExe exe = new CpGiftRelationCheckQryExe(cpRelationshipService);
|
||||||
|
|
||||||
|
CpGiftRelationCheckCO result = exe.execute(cmd(1001L, 2001L, "FRIEND"));
|
||||||
|
|
||||||
|
assertFalse(result.getStatus());
|
||||||
|
assertEquals("relationType is not supported.", result.getMsg());
|
||||||
|
assertEquals("FRIEND", result.getRelationType());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CpGiftRelationCheckCmd cmd(Long reqUserId, Long acceptUserId,
|
||||||
|
String relationType) {
|
||||||
|
CpGiftRelationCheckCmd cmd = new CpGiftRelationCheckCmd();
|
||||||
|
cmd.setReqUserId(reqUserId);
|
||||||
|
cmd.setAcceptUserId(acceptUserId);
|
||||||
|
cmd.setRelationType(relationType);
|
||||||
|
return cmd;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,69 @@
|
|||||||
|
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 gift relationship limit check result.
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class CpGiftRelationCheckCO extends ClientObject {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether app can continue sending the relationship gift.
|
||||||
|
*/
|
||||||
|
private Boolean status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* App display message.
|
||||||
|
*/
|
||||||
|
private String msg;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Relationship type: CP/BROTHER/SISTERS.
|
||||||
|
*/
|
||||||
|
private String relationType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gift sender user id.
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gift receiver user id.
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long acceptUserId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sender current normal relationship count for relationType.
|
||||||
|
*/
|
||||||
|
private Integer userRelationCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receiver current normal relationship count for relationType.
|
||||||
|
*/
|
||||||
|
private Integer acceptUserRelationCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Max count for relationType: CP=1, BROTHER/SISTERS=3.
|
||||||
|
*/
|
||||||
|
private Integer maxRelationCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether sender reached maxRelationCount.
|
||||||
|
*/
|
||||||
|
private Boolean userRelationFull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether receiver reached maxRelationCount.
|
||||||
|
*/
|
||||||
|
private Boolean acceptUserRelationFull;
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
package com.red.circle.other.app.dto.cmd.user.relation.cp;
|
||||||
|
|
||||||
|
import com.red.circle.common.business.dto.cmd.AppExtCommand;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CP gift relationship limit check.
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class CpGiftRelationCheckCmd extends AppExtCommand {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gift receiver user id.
|
||||||
|
*
|
||||||
|
* @eo.required
|
||||||
|
*/
|
||||||
|
@NotNull(message = "acceptUserId required.")
|
||||||
|
private Long acceptUserId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Relationship type carried by the CP gift: CP/BROTHER/SISTERS, default CP.
|
||||||
|
*/
|
||||||
|
private String relationType;
|
||||||
|
}
|
||||||
@ -4,12 +4,14 @@ import com.red.circle.common.business.dto.cmd.UserIdCmd;
|
|||||||
import com.red.circle.common.business.dto.cmd.UserIdCommonCmd;
|
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.CpCabinUserProfileCO;
|
||||||
import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpDismissApplyCO;
|
import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpDismissApplyCO;
|
||||||
|
import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpGiftRelationCheckCO;
|
||||||
import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpPairUserProfileCO;
|
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.clientobject.user.relation.cp.CpUserProfileCO;
|
||||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyIdQueryCmd;
|
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyIdQueryCmd;
|
||||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyCmd;
|
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyCmd;
|
||||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyDismissCmd;
|
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyDismissCmd;
|
||||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyStatusQueryCmd;
|
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyStatusQueryCmd;
|
||||||
|
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpGiftRelationCheckCmd;
|
||||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpRelationshipQueryCmd;
|
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpRelationshipQueryCmd;
|
||||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.ProcessApplyCmd;
|
import com.red.circle.other.app.dto.cmd.user.relation.cp.ProcessApplyCmd;
|
||||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.loveletter.SendLoveLetterCmd;
|
import com.red.circle.other.app.dto.cmd.user.relation.cp.loveletter.SendLoveLetterCmd;
|
||||||
@ -37,6 +39,8 @@ public interface UserCpRelationService {
|
|||||||
|
|
||||||
String getCpApplyStatus(CpApplyStatusQueryCmd cmd);
|
String getCpApplyStatus(CpApplyStatusQueryCmd cmd);
|
||||||
|
|
||||||
|
CpGiftRelationCheckCO checkGiftRelation(CpGiftRelationCheckCmd cmd);
|
||||||
|
|
||||||
CpCabinUserProfileCO getCpUserV4(UserIdCommonCmd cmd);
|
CpCabinUserProfileCO getCpUserV4(UserIdCommonCmd cmd);
|
||||||
|
|
||||||
void sendLoveLetter(SendLoveLetterCmd cmd);
|
void sendLoveLetter(SendLoveLetterCmd cmd);
|
||||||
|
|||||||
@ -56,4 +56,11 @@ public enum CpRelationshipType {
|
|||||||
case SISTERS -> "sisters";
|
case SISTERS -> "sisters";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int maxCount() {
|
||||||
|
return switch (this) {
|
||||||
|
case CP -> 1;
|
||||||
|
case BROTHER, SISTERS -> 3;
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,14 +1,45 @@
|
|||||||
package com.red.circle.other.app.inner.service.team.impl;
|
package com.red.circle.other.app.inner.service.team.impl;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyLong;
|
||||||
|
import static org.mockito.ArgumentMatchers.anySet;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
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.component.redis.service.RedisService;
|
||||||
|
import com.red.circle.framework.dto.ResultResponse;
|
||||||
import com.red.circle.other.infra.database.mongo.dto.team.TeamBillMemberTarget;
|
import com.red.circle.other.infra.database.mongo.dto.team.TeamBillMemberTarget;
|
||||||
|
import com.red.circle.other.infra.database.mongo.dto.team.TeamPolicy;
|
||||||
import com.red.circle.other.infra.database.mongo.dto.team.TeamSalaryPaymentDetails;
|
import com.red.circle.other.infra.database.mongo.dto.team.TeamSalaryPaymentDetails;
|
||||||
|
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamMember;
|
||||||
|
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamMemberTarget;
|
||||||
|
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamPolicyManager;
|
||||||
|
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamProfile;
|
||||||
|
import com.red.circle.other.infra.database.mongo.service.team.TeamBillCycleUtils;
|
||||||
|
import com.red.circle.other.infra.database.mongo.service.team.team.TeamMemberService;
|
||||||
|
import com.red.circle.other.infra.database.mongo.service.team.team.TeamMemberTargetService;
|
||||||
|
import com.red.circle.other.infra.database.mongo.service.team.team.TeamPolicyManagerService;
|
||||||
|
import com.red.circle.other.infra.database.mongo.service.team.team.TeamProfileService;
|
||||||
|
import com.red.circle.other.infra.database.mongo.service.team.team.TeamSalaryPaymentService;
|
||||||
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamSalaryPayment;
|
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamSalaryPayment;
|
||||||
|
import com.red.circle.other.inner.enums.team.TeamMemberTargetIndex;
|
||||||
|
import com.red.circle.other.inner.model.cmd.team.TeamManualSalaryPaymentCmd;
|
||||||
|
import com.red.circle.other.inner.model.dto.agency.agency.TeamManualSalaryPaymentResultDTO;
|
||||||
|
import com.red.circle.wallet.inner.endpoint.bank.UserBankBalanceClient;
|
||||||
|
import com.red.circle.wallet.inner.endpoint.bank.UserBankRunningWaterClient;
|
||||||
|
import com.red.circle.wallet.inner.model.dto.BankBalanceDTO;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.springframework.test.util.ReflectionTestUtils;
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
class TeamManualSalaryPaymentClientServiceImplTest {
|
class TeamManualSalaryPaymentClientServiceImplTest {
|
||||||
@ -79,6 +110,111 @@ class TeamManualSalaryPaymentClientServiceImplTest {
|
|||||||
"salary"));
|
"salary"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void payShouldReturnTopUpDetailsWhenCurrentLevelRecordExistsButSalaryIsInsufficient() {
|
||||||
|
RedisService redisService = mock(RedisService.class);
|
||||||
|
TeamMemberService teamMemberService = mock(TeamMemberService.class);
|
||||||
|
TeamProfileService teamProfileService = mock(TeamProfileService.class);
|
||||||
|
UserBankBalanceClient userBankBalanceClient = mock(UserBankBalanceClient.class);
|
||||||
|
TeamMemberTargetService teamMemberTargetService = mock(TeamMemberTargetService.class);
|
||||||
|
TeamSalaryPaymentService teamSalaryPaymentService = mock(TeamSalaryPaymentService.class);
|
||||||
|
TeamPolicyManagerService teamPolicyManagerService = mock(TeamPolicyManagerService.class);
|
||||||
|
UserBankRunningWaterClient userBankRunningWaterClient = mock(UserBankRunningWaterClient.class);
|
||||||
|
TeamManualSalaryPaymentClientServiceImpl service = new TeamManualSalaryPaymentClientServiceImpl(
|
||||||
|
redisService, teamMemberService, teamProfileService, userBankBalanceClient,
|
||||||
|
teamMemberTargetService, teamSalaryPaymentService, teamPolicyManagerService,
|
||||||
|
userBankRunningWaterClient);
|
||||||
|
|
||||||
|
String sysOrigin = "LIKEI";
|
||||||
|
String countryCode = "PH";
|
||||||
|
String region = "2046067717605224449";
|
||||||
|
Long userId = 2054591808909930498L;
|
||||||
|
Long teamId = 2054614353419759617L;
|
||||||
|
Integer billBelong = TeamBillCycleUtils.getCalcBillBelong();
|
||||||
|
String paymentId = userId + "_" + billBelong;
|
||||||
|
TeamMemberTarget target = new TeamMemberTarget()
|
||||||
|
.setId("target-id")
|
||||||
|
.setTimeId(2056024761217118210L)
|
||||||
|
.setSysOrigin(sysOrigin)
|
||||||
|
.setRegion(region)
|
||||||
|
.setCountryCode(countryCode)
|
||||||
|
.setTeamId(teamId)
|
||||||
|
.setUserId(userId)
|
||||||
|
.setBillBelong(billBelong)
|
||||||
|
.setDailyTargets(List.of(new TeamMemberTargetIndex()
|
||||||
|
.setOwnOnlineTime(717L)
|
||||||
|
.setAcceptGiftValue(15151819L)));
|
||||||
|
TeamSalaryPayment existingPayment = new TeamSalaryPayment()
|
||||||
|
.setId(paymentId)
|
||||||
|
.setUserId(userId)
|
||||||
|
.setDateNumber(billBelong)
|
||||||
|
.setSalarySendDetails(List.of(
|
||||||
|
new TeamSalaryPaymentDetails()
|
||||||
|
.setTeamMemberId(userId)
|
||||||
|
.setTeamOwnId(userId)
|
||||||
|
.setTeamRegionId(region)
|
||||||
|
.setPolicyLevel(6)
|
||||||
|
.setAnchor(Boolean.TRUE)
|
||||||
|
.setSalary(new BigDecimal("22.00"))
|
||||||
|
.setRecycled(Boolean.FALSE),
|
||||||
|
new TeamSalaryPaymentDetails()
|
||||||
|
.setTeamMemberId(userId)
|
||||||
|
.setTeamOwnId(userId)
|
||||||
|
.setTeamRegionId(region)
|
||||||
|
.setPolicyLevel(6)
|
||||||
|
.setAnchor(Boolean.FALSE)
|
||||||
|
.setSalary(new BigDecimal("9.50"))
|
||||||
|
.setRecycled(Boolean.FALSE)));
|
||||||
|
TeamPolicyManager policyManager = new TeamPolicyManager()
|
||||||
|
.setSysOrigin(sysOrigin)
|
||||||
|
.setRegion(region)
|
||||||
|
.setCountryCode(countryCode)
|
||||||
|
.setPolicy(List.of(new TeamPolicy()
|
||||||
|
.setLevel(6)
|
||||||
|
.setTarget(8810000L)
|
||||||
|
.setOnlineTime(10L)
|
||||||
|
.setEffectiveDay(0)
|
||||||
|
.setMemberSalary(new BigDecimal("35.00"))
|
||||||
|
.setOwnSalary(new BigDecimal("8.75"))
|
||||||
|
.setTotalSalary(new BigDecimal("43.75"))));
|
||||||
|
|
||||||
|
when(redisService.lock(anyString(), anyLong())).thenReturn(true);
|
||||||
|
when(teamMemberTargetService.listManualSalaryTargets(eq(sysOrigin), eq(countryCode), anySet(),
|
||||||
|
eq(billBelong))).thenReturn(List.of(target));
|
||||||
|
when(teamMemberService.mapByMemberIds(anySet())).thenReturn(Map.of(userId,
|
||||||
|
new TeamMember().setMemberId(userId).setTeamId(teamId)));
|
||||||
|
when(teamProfileService.mapProfileByIds(anySet())).thenReturn(Map.of(teamId,
|
||||||
|
new TeamProfile().setId(teamId).setOwnUserId(userId).setRegion(region)));
|
||||||
|
when(teamSalaryPaymentService.listByPaymentOrRecipientUserIdsAndDateNumbers(eq(sysOrigin),
|
||||||
|
anySet(), anySet())).thenReturn(List.of(existingPayment));
|
||||||
|
when(teamPolicyManagerService.getReleaseByRegionAndType(sysOrigin, region, null, countryCode))
|
||||||
|
.thenReturn(policyManager);
|
||||||
|
when(teamSalaryPaymentService.createIfAbsent(userId, billBelong, sysOrigin))
|
||||||
|
.thenReturn(new TeamSalaryPayment().setId(paymentId));
|
||||||
|
when(userBankBalanceClient.getBalance(userId))
|
||||||
|
.thenReturn(ResultResponse.success(BankBalanceDTO.of(0L)))
|
||||||
|
.thenReturn(ResultResponse.success(BankBalanceDTO.of(1225L)));
|
||||||
|
when(userBankBalanceClient.incr(any())).thenReturn(ResultResponse.success(Boolean.TRUE));
|
||||||
|
when(userBankRunningWaterClient.add(any())).thenReturn(ResultResponse.success());
|
||||||
|
when(teamSalaryPaymentService.mapPolicy(paymentId)).thenReturn(new HashMap<>());
|
||||||
|
|
||||||
|
List<TeamManualSalaryPaymentResultDTO> results = service.pay(new TeamManualSalaryPaymentCmd()
|
||||||
|
.setSysOrigin(sysOrigin)
|
||||||
|
.setCountryCode(countryCode)
|
||||||
|
.setUserIds(List.of(userId)));
|
||||||
|
|
||||||
|
assertEquals(1, results.size());
|
||||||
|
assertEquals(userId, results.get(0).getUserId());
|
||||||
|
assertEquals(new BigDecimal("12.25"), results.get(0).getIssuedSalary());
|
||||||
|
ArgumentCaptor<TeamSalaryPaymentDetails> detailsCaptor =
|
||||||
|
ArgumentCaptor.forClass(TeamSalaryPaymentDetails.class);
|
||||||
|
verify(teamSalaryPaymentService).paymentSalary(eq(paymentId), detailsCaptor.capture());
|
||||||
|
assertEquals(new BigDecimal("12.25"), detailsCaptor.getValue().getSalary());
|
||||||
|
assertEquals(Boolean.TRUE, detailsCaptor.getValue().getAnchor());
|
||||||
|
verify(teamSalaryPaymentService, never()).checkRepeatPayment(anyString(), anyLong(),
|
||||||
|
anyString(), any(), any());
|
||||||
|
}
|
||||||
|
|
||||||
private Object paymentSummary(BigDecimal totalIssuedSalary, BigDecimal memberIssuedSalary,
|
private Object paymentSummary(BigDecimal totalIssuedSalary, BigDecimal memberIssuedSalary,
|
||||||
BigDecimal agentIssuedSalary) throws Exception {
|
BigDecimal agentIssuedSalary) throws Exception {
|
||||||
Class<?> summaryClass = Class.forName(
|
Class<?> summaryClass = Class.forName(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user