新增发IM C2c
This commit is contained in:
parent
a0461ce68c
commit
dca9f12cb5
@ -1,8 +1,12 @@
|
||||
package com.red.circle.external.inner.endpoint.message.api;
|
||||
|
||||
import com.red.circle.framework.dto.ResultResponse;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import com.red.circle.framework.dto.ResultResponse;
|
||||
import com.red.circle.external.inner.model.cmd.message.CustomC2cMsgBodyCmd;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
/**
|
||||
* im 消息服务.
|
||||
@ -24,9 +28,15 @@ public interface ImMessageClientApi {
|
||||
/**
|
||||
* 发送文本消息.
|
||||
*/
|
||||
@GetMapping("/sendMessageText/long")
|
||||
ResultResponse<Void> sendMessageText(@RequestParam("fromAccount") Long fromAccount,
|
||||
@RequestParam("toAccount") Long toAccount,
|
||||
@RequestParam("text") String text);
|
||||
|
||||
}
|
||||
@GetMapping("/sendMessageText/long")
|
||||
ResultResponse<Void> sendMessageText(@RequestParam("fromAccount") Long fromAccount,
|
||||
@RequestParam("toAccount") Long toAccount,
|
||||
@RequestParam("text") String text);
|
||||
|
||||
/**
|
||||
* 发送 C2C 自定义消息.
|
||||
*/
|
||||
@PostMapping("/sendCustomMessage")
|
||||
ResultResponse<Void> sendCustomMessage(@RequestBody @Valid CustomC2cMsgBodyCmd cmd);
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,82 @@
|
||||
package com.red.circle.external.inner.model.cmd.message;
|
||||
|
||||
import com.red.circle.framework.dto.Command;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.io.Serial;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* C2C custom IM message.
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class CustomC2cMsgBodyCmd extends Command {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@NotBlank(message = "fromAccount required.")
|
||||
private String fromAccount;
|
||||
|
||||
@NotBlank(message = "toAccount required.")
|
||||
private String toAccount;
|
||||
|
||||
@NotBlank(message = "desc required.")
|
||||
private String desc;
|
||||
|
||||
@NotNull(message = "data required.")
|
||||
private Object data;
|
||||
|
||||
public static CustomC2cMsgBodyBuilder builder() {
|
||||
return new CustomC2cMsgBodyBuilder();
|
||||
}
|
||||
|
||||
public static class CustomC2cMsgBodyBuilder {
|
||||
|
||||
private String fromAccount;
|
||||
private String toAccount;
|
||||
private String desc;
|
||||
private Object data;
|
||||
|
||||
public CustomC2cMsgBodyBuilder fromAccount(String fromAccount) {
|
||||
this.fromAccount = fromAccount;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomC2cMsgBodyBuilder fromAccount(Long fromAccount) {
|
||||
this.fromAccount = String.valueOf(fromAccount);
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomC2cMsgBodyBuilder toAccount(String toAccount) {
|
||||
this.toAccount = toAccount;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomC2cMsgBodyBuilder toAccount(Long toAccount) {
|
||||
this.toAccount = String.valueOf(toAccount);
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomC2cMsgBodyBuilder desc(String desc) {
|
||||
this.desc = desc;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomC2cMsgBodyBuilder data(Object data) {
|
||||
this.data = data;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomC2cMsgBodyCmd build() {
|
||||
CustomC2cMsgBodyCmd cmd = new CustomC2cMsgBodyCmd();
|
||||
cmd.setFromAccount(this.fromAccount);
|
||||
cmd.setToAccount(this.toAccount);
|
||||
cmd.setDesc(this.desc);
|
||||
cmd.setData(this.data);
|
||||
return cmd;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,9 @@
|
||||
package com.red.circle.external.inner.endpoint.message;
|
||||
|
||||
import com.red.circle.external.inner.endpoint.message.api.ImMessageClientApi;
|
||||
import com.red.circle.external.inner.service.message.ImMessageClientService;
|
||||
import com.red.circle.framework.dto.ResultResponse;
|
||||
import com.red.circle.external.inner.endpoint.message.api.ImMessageClientApi;
|
||||
import com.red.circle.external.inner.model.cmd.message.CustomC2cMsgBodyCmd;
|
||||
import com.red.circle.external.inner.service.message.ImMessageClientService;
|
||||
import com.red.circle.framework.dto.ResultResponse;
|
||||
import com.red.circle.tool.core.parse.DataTypeUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.MediaType;
|
||||
@ -30,10 +31,16 @@ public class ImMessageClientEndpoint implements ImMessageClientApi {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultResponse<Void> sendMessageText(Long fromAccount, Long toAccount, String text) {
|
||||
imMessageClientService.sendMessageText(DataTypeUtils.toString(fromAccount),
|
||||
DataTypeUtils.toString(toAccount), text);
|
||||
return ResultResponse.success();
|
||||
}
|
||||
|
||||
}
|
||||
public ResultResponse<Void> sendMessageText(Long fromAccount, Long toAccount, String text) {
|
||||
imMessageClientService.sendMessageText(DataTypeUtils.toString(fromAccount),
|
||||
DataTypeUtils.toString(toAccount), text);
|
||||
return ResultResponse.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultResponse<Void> sendCustomMessage(CustomC2cMsgBodyCmd cmd) {
|
||||
imMessageClientService.sendCustomMessage(cmd);
|
||||
return ResultResponse.success();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
package com.red.circle.external.inner.service.message;
|
||||
|
||||
/**
|
||||
* im 消息服务.
|
||||
package com.red.circle.external.inner.service.message;
|
||||
|
||||
import com.red.circle.external.inner.model.cmd.message.CustomC2cMsgBodyCmd;
|
||||
|
||||
/**
|
||||
* im 消息服务.
|
||||
*
|
||||
* @author pengliang on 2023/7/12
|
||||
*/
|
||||
@ -9,7 +11,12 @@ public interface ImMessageClientService {
|
||||
|
||||
/**
|
||||
* 发送文本消息.
|
||||
*/
|
||||
void sendMessageText(String fromAccount, String toAccount, String text);
|
||||
|
||||
}
|
||||
*/
|
||||
void sendMessageText(String fromAccount, String toAccount, String text);
|
||||
|
||||
/**
|
||||
* 发送 C2C 自定义消息.
|
||||
*/
|
||||
void sendCustomMessage(CustomC2cMsgBodyCmd cmd);
|
||||
|
||||
}
|
||||
|
||||
@ -1,10 +1,16 @@
|
||||
package com.red.circle.external.inner.service.message.impl;
|
||||
|
||||
import com.red.circle.component.instant.msg.tencet.service.endpoint.api.im.account.ImMessageManagerService;
|
||||
import com.red.circle.external.inner.service.message.ImMessageClientService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.red.circle.component.instant.msg.tencet.service.endpoint.api.im.account.ImMessageManagerService;
|
||||
import com.red.circle.component.instant.msg.tencet.service.param.ImMessageParam;
|
||||
import com.red.circle.component.instant.msg.tencet.service.param.MessageBody;
|
||||
import com.red.circle.component.instant.msg.tencet.service.param.OfflinePushInfo;
|
||||
import com.red.circle.external.inner.model.cmd.message.CustomC2cMsgBodyCmd;
|
||||
import com.red.circle.external.inner.service.message.ImMessageClientService;
|
||||
import com.red.circle.tool.core.num.NumUtils;
|
||||
import com.red.circle.tool.core.parse.DataTypeUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* im 消息服务.
|
||||
@ -19,8 +25,22 @@ public class ImMessageClientServiceImpl implements ImMessageClientService {
|
||||
private final ImMessageManagerService imMessageManagerService;
|
||||
|
||||
@Override
|
||||
public void sendMessageText(String fromAccount, String toAccount, String text) {
|
||||
imMessageManagerService.sendMessageText(fromAccount, toAccount, text).subscribe();
|
||||
}
|
||||
|
||||
}
|
||||
public void sendMessageText(String fromAccount, String toAccount, String text) {
|
||||
imMessageManagerService.sendMessageText(fromAccount, toAccount, text).subscribe();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendCustomMessage(CustomC2cMsgBodyCmd cmd) {
|
||||
ImMessageParam param = ImMessageParam.builder()
|
||||
.fromAccount(cmd.getFromAccount())
|
||||
.toAccount(cmd.getToAccount())
|
||||
.offlinePushInfo(OfflinePushInfo.builder()
|
||||
.pushFlag(0)
|
||||
.build())
|
||||
.msgRandom(DataTypeUtils.toInteger(NumUtils.getRandomNumberString(9)))
|
||||
.build()
|
||||
.addMsgBody(MessageBody.customBody(cmd.getDesc(), cmd.getData()));
|
||||
imMessageManagerService.sendMessage(param).subscribe();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -186,10 +186,11 @@ public class BlessingsGiftGiveCmdExe {
|
||||
giftConfig.setId(giftConfigCache.getId());
|
||||
giftConfig.setGiftCandy(giftConfigCache.getGiftCandy());
|
||||
giftConfig.setGiftIntegral(giftConfigCache.getGiftIntegral());
|
||||
giftConfig.setSpecial(giftConfigCache.getSpecial());
|
||||
giftConfig.setType(giftConfigCache.getType());
|
||||
giftConfig.setGiftTab(giftConfigCache.getGiftTab());
|
||||
return giftConfig;
|
||||
}
|
||||
|
||||
}
|
||||
giftConfig.setSpecial(giftConfigCache.getSpecial());
|
||||
giftConfig.setType(giftConfigCache.getType());
|
||||
giftConfig.setGiftTab(giftConfigCache.getGiftTab());
|
||||
giftConfig.setCpRelationType(giftConfigCache.getCpRelationType());
|
||||
return giftConfig;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
package com.red.circle.other.app.command.user;
|
||||
|
||||
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
|
||||
import com.red.circle.external.inner.endpoint.message.OfficialNoticeClient;
|
||||
import com.red.circle.external.inner.model.cmd.message.notice.official.NoticeExtTemplateTypeCmd;
|
||||
import com.red.circle.external.inner.model.enums.message.OfficialNoticeTypeEnum;
|
||||
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
|
||||
import com.red.circle.external.inner.endpoint.message.ImMessageClient;
|
||||
import com.red.circle.external.inner.model.cmd.message.CustomC2cMsgBodyCmd;
|
||||
import com.red.circle.framework.core.asserts.ResponseAssert;
|
||||
import com.red.circle.framework.core.response.CommonErrorCode;
|
||||
import com.red.circle.mq.business.model.event.user.CpApplyEvent;
|
||||
@ -20,16 +19,18 @@ import com.red.circle.other.infra.database.rds.service.user.user.CpApplyService;
|
||||
import com.red.circle.other.infra.database.rds.service.user.user.CpRelationshipService;
|
||||
import com.red.circle.other.infra.enums.user.user.CpApplyStatus;
|
||||
import com.red.circle.other.infra.enums.user.user.CpRelationshipType;
|
||||
import com.red.circle.other.inner.asserts.user.UserRelationErrorCode;
|
||||
import com.red.circle.other.inner.enums.config.EnumConfigKey;
|
||||
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
|
||||
import com.red.circle.tool.core.date.TimestampUtils;
|
||||
import com.red.circle.other.inner.asserts.user.UserRelationErrorCode;
|
||||
import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient;
|
||||
import com.red.circle.tool.core.json.JacksonUtils;
|
||||
import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient;
|
||||
import com.red.circle.wallet.inner.model.cmd.GoldReceiptCmd;
|
||||
import com.red.circle.wallet.inner.model.dto.WalletReceiptResDTO;
|
||||
import com.red.circle.wallet.inner.model.enums.GoldOrigin;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@ -47,12 +48,13 @@ import org.springframework.stereotype.Component;
|
||||
@Slf4j
|
||||
public class SendCpApplyCmdExe {
|
||||
|
||||
private static final String CP_BUILD_NOTICE_TYPE = "CP_BUILD";
|
||||
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 ImMessageClient imMessageClient;
|
||||
private final WalletGoldClient walletGoldClient;
|
||||
private final UserMqMessageService userMqMessageService;
|
||||
private final CpRelationshipService cpRelationshipService;
|
||||
private final EnumConfigCacheService enumConfigCacheService;
|
||||
@ -69,10 +71,22 @@ public class SendCpApplyCmdExe {
|
||||
return autoCreateFromCpGift(sendUserId, acceptUserId, sysOrigin, CpRelationshipType.CP.name());
|
||||
}
|
||||
|
||||
public boolean autoCreateFromCpGift(Long sendUserId, Long acceptUserId, String sysOrigin,
|
||||
BigDecimal applyConsumeGold) {
|
||||
return autoCreateFromCpGift(sendUserId, acceptUserId, sysOrigin, CpRelationshipType.CP.name(),
|
||||
applyConsumeGold);
|
||||
}
|
||||
|
||||
public boolean autoCreateFromCpGift(Long sendUserId, Long acceptUserId, String sysOrigin,
|
||||
String relationTypeValue) {
|
||||
return autoCreateFromCpGift(sendUserId, acceptUserId, sysOrigin, relationTypeValue,
|
||||
BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public boolean autoCreateFromCpGift(Long sendUserId, Long acceptUserId, String sysOrigin,
|
||||
String relationTypeValue, BigDecimal applyConsumeGold) {
|
||||
try {
|
||||
process(sendUserId, acceptUserId, sysOrigin, relationTypeValue, false);
|
||||
process(sendUserId, acceptUserId, sysOrigin, relationTypeValue, false, applyConsumeGold);
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
log.info(
|
||||
@ -84,6 +98,11 @@ public class SendCpApplyCmdExe {
|
||||
|
||||
private void process(Long sendUserId, Long acceptUserId, String sysOrigin, String relationTypeValue,
|
||||
boolean chargeGold) {
|
||||
process(sendUserId, acceptUserId, sysOrigin, relationTypeValue, chargeGold, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
private void process(Long sendUserId, Long acceptUserId, String sysOrigin, String relationTypeValue,
|
||||
boolean chargeGold, BigDecimal giftApplyConsumeGold) {
|
||||
CpRelationshipType relationType = parseRelationType(relationTypeValue);
|
||||
|
||||
// 不可用操作自己
|
||||
@ -121,7 +140,7 @@ public class SendCpApplyCmdExe {
|
||||
ResponseAssert.isFalse(UserRelationErrorCode.OTHER_SIDE_ALREADY_APPLIED,
|
||||
cpApplyService.exists(sendUserId, acceptUserId, relationType.name()));
|
||||
|
||||
BigDecimal applyConsumeGold = BigDecimal.ZERO;
|
||||
BigDecimal applyConsumeGold = normalizeApplyConsumeGold(giftApplyConsumeGold);
|
||||
if (chargeGold) {
|
||||
WalletReceiptResDTO receipt = ResponseAssert.requiredSuccess(
|
||||
walletGoldClient.changeBalance(GoldReceiptCmd.builder()
|
||||
@ -153,16 +172,8 @@ public class SendCpApplyCmdExe {
|
||||
|
||||
cpApplyService.save(cpApply);
|
||||
|
||||
Map<Object, Object> map = OfficialNoticeUtils.buildUserProfile(userProfile);
|
||||
map.put("applyType", isReconcile ? "RECONCILE" : "APPLY");
|
||||
map.put("relationType", relationType.name());
|
||||
officialNoticeClient.send(NoticeExtTemplateTypeCmd.builder()
|
||||
.toAccount(acceptUserId)
|
||||
.noticeType(OfficialNoticeTypeEnum.CP_BUILD)
|
||||
.templateParam(map)
|
||||
.expand(cpApply.getId())
|
||||
.build()
|
||||
);
|
||||
sendCpBuildIm(sendUserId, acceptUserId, cpApply.getId(), userProfile, isReconcile,
|
||||
relationType, applyText);
|
||||
|
||||
userMqMessageService.cpApplyDelayed(
|
||||
new CpApplyEvent()
|
||||
@ -171,6 +182,39 @@ public class SendCpApplyCmdExe {
|
||||
TimestampUtils.nowPlusDays(1));
|
||||
}
|
||||
|
||||
private void sendCpBuildIm(Long sendUserId, Long acceptUserId, Long applyId,
|
||||
UserProfileDTO userProfile, boolean isReconcile, CpRelationshipType relationType,
|
||||
String title) {
|
||||
Map<String, Object> content = new LinkedHashMap<>();
|
||||
OfficialNoticeUtils.buildUserProfile(userProfile)
|
||||
.forEach((key, value) -> content.put(String.valueOf(key), value));
|
||||
content.put("applyType", isReconcile ? "RECONCILE" : "APPLY");
|
||||
content.put("relationType", relationType.name());
|
||||
|
||||
Map<String, Object> payload = new LinkedHashMap<>();
|
||||
payload.put("noticeType", CP_BUILD_NOTICE_TYPE);
|
||||
payload.put("type", CP_BUILD_NOTICE_TYPE);
|
||||
payload.put("title", title);
|
||||
payload.put("content", JacksonUtils.toJson(content));
|
||||
payload.put("expand", applyId);
|
||||
payload.put("applyId", applyId);
|
||||
payload.put("relationType", relationType.name());
|
||||
|
||||
imMessageClient.sendCustomMessage(CustomC2cMsgBodyCmd.builder()
|
||||
.fromAccount(sendUserId)
|
||||
.toAccount(acceptUserId)
|
||||
.desc(CP_BUILD_NOTICE_TYPE)
|
||||
.data(payload)
|
||||
.build());
|
||||
}
|
||||
|
||||
private BigDecimal normalizeApplyConsumeGold(BigDecimal applyConsumeGold) {
|
||||
if (Objects.isNull(applyConsumeGold) || applyConsumeGold.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
return applyConsumeGold;
|
||||
}
|
||||
|
||||
private void validateRelationLimit(Long sendUserId, Long acceptUserId,
|
||||
CpRelationshipType relationType) {
|
||||
int maxCount = relationMaxCount(relationType);
|
||||
|
||||
@ -379,15 +379,15 @@ public class GiftCountStrategy implements GiftStrategy {
|
||||
if (CollectionUtils.isEmpty(runningWater.getAcceptUsers())) {
|
||||
return;
|
||||
}
|
||||
String relationType = CpRelationshipType.normalize(
|
||||
runningWater.getGiftValue().getCpRelationType());
|
||||
String relationType = resolveCpGiftRelationType(runningWater);
|
||||
BigDecimal applyConsumeGold = cpGiftApplyConsumeGold(runningWater.getGiftValue());
|
||||
runningWater.getAcceptUsers().forEach(accept -> {
|
||||
if (Objects.equals(runningWater.getUserId(), accept.getAcceptUserId())) {
|
||||
return;
|
||||
}
|
||||
sendCpApplyCmdExe.autoCreateFromCpGift(
|
||||
runningWater.getUserId(), accept.getAcceptUserId(), runningWater.getSysOrigin(),
|
||||
relationType);
|
||||
relationType, applyConsumeGold);
|
||||
});
|
||||
} catch (Exception ex) {
|
||||
log.warn("[CP] skip auto create cp apply from gift, runningWaterId={}, giftId={}, sendUserId={}, reason={}",
|
||||
@ -398,6 +398,44 @@ public class GiftCountStrategy implements GiftStrategy {
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveCpGiftRelationType(GiftGiveRunningWater runningWater) {
|
||||
String relationType = Objects.nonNull(runningWater.getGiftValue())
|
||||
? runningWater.getGiftValue().getCpRelationType()
|
||||
: null;
|
||||
if (StringUtils.isNotBlank(relationType)) {
|
||||
return CpRelationshipType.normalize(relationType);
|
||||
}
|
||||
String configuredRelationType = cpRelationTypeFromGiftConfig(runningWater);
|
||||
return CpRelationshipType.normalize(configuredRelationType);
|
||||
}
|
||||
|
||||
private String cpRelationTypeFromGiftConfig(GiftGiveRunningWater runningWater) {
|
||||
if (Objects.isNull(runningWater) || Objects.isNull(runningWater.getGiftId())) {
|
||||
log.warn("[CP] cp gift relation type missing and giftId missing, fallback CP. runningWaterId={}",
|
||||
Objects.nonNull(runningWater) ? runningWater.getId() : null);
|
||||
return CpRelationshipType.CP.name();
|
||||
}
|
||||
GiftConfigDTO giftConfig = cacheGiftConfigManagerService.getById(runningWater.getGiftId());
|
||||
if (Objects.nonNull(giftConfig) && StringUtils.isNotBlank(giftConfig.getCpRelationType())) {
|
||||
return giftConfig.getCpRelationType();
|
||||
}
|
||||
log.warn("[CP] cp gift relation type missing from running water and config, fallback CP. runningWaterId={}, giftId={}",
|
||||
runningWater.getId(), runningWater.getGiftId());
|
||||
return CpRelationshipType.CP.name();
|
||||
}
|
||||
|
||||
private BigDecimal cpGiftApplyConsumeGold(GiftValue giftValue) {
|
||||
if (Objects.isNull(giftValue) || !GiftCurrencyType.GOLD.eq(giftValue.getCurrencyType())
|
||||
|| Objects.equals(giftValue.getBag(), Boolean.TRUE)) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
BigDecimal giftGold = giftValue.getGiftValue();
|
||||
if (Objects.isNull(giftGold) || giftGold.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
return giftGold;
|
||||
}
|
||||
|
||||
private void sendCpBlessNotice(GiftGiveRunningWater runningWater, CpRelationship cpRelationship,
|
||||
GiftConfigDTO giftConfig) {
|
||||
UserProfile userProfile = userProfileRepository.getByUserId(runningWater.getUserId());
|
||||
|
||||
@ -0,0 +1,100 @@
|
||||
package com.red.circle.other.app.command.user;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
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.ImMessageClient;
|
||||
import com.red.circle.framework.core.dto.ReqSysOrigin;
|
||||
import com.red.circle.mq.rocket.business.producer.UserMqMessageService;
|
||||
import com.red.circle.other.app.common.cp.CpRelationBroadcastMqClient;
|
||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.ProcessApplyCmd;
|
||||
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
|
||||
import com.red.circle.other.infra.database.cache.service.cp.CpRelationshipCacheService;
|
||||
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.infra.database.rds.service.user.user.CpValueService;
|
||||
import com.red.circle.other.infra.enums.user.user.CpApplyStatus;
|
||||
import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class ProcessCpApplyCmdTest {
|
||||
|
||||
@Test
|
||||
void agreeBrotherApplyShouldCreateBrotherRelationship() {
|
||||
Fixture fixture = new Fixture("BROTHER");
|
||||
|
||||
fixture.exe.execute(processCmd());
|
||||
|
||||
verify(fixture.cpRelationshipService).addCp(eq(1001L), eq(2001L),
|
||||
nullable(Long.class), eq("LIKEI"), eq("BROTHER"));
|
||||
verify(fixture.cpRelationBroadcastMqClient).publish("LIKEI", 3001L, 1001L, 2001L,
|
||||
"BROTHER");
|
||||
}
|
||||
|
||||
@Test
|
||||
void agreeSistersApplyShouldCreateSistersRelationship() {
|
||||
Fixture fixture = new Fixture("SISTERS");
|
||||
|
||||
fixture.exe.execute(processCmd());
|
||||
|
||||
verify(fixture.cpRelationshipService).addCp(eq(1001L), eq(2001L),
|
||||
nullable(Long.class), eq("LIKEI"), eq("SISTERS"));
|
||||
verify(fixture.cpRelationBroadcastMqClient).publish("LIKEI", 3001L, 1001L, 2001L,
|
||||
"SISTERS");
|
||||
}
|
||||
|
||||
private static ProcessApplyCmd processCmd() {
|
||||
ProcessApplyCmd cmd = new ProcessApplyCmd()
|
||||
.setApplyId(3001L)
|
||||
.setAgree(Boolean.TRUE);
|
||||
cmd.setReqUserId(2001L);
|
||||
cmd.setReqSysOrigin(ReqSysOrigin.of("LIKEI", "LIKEI"));
|
||||
return cmd;
|
||||
}
|
||||
|
||||
private static CpApply apply(String relationType) {
|
||||
return new CpApply()
|
||||
.setId(3001L)
|
||||
.setSendApplyUserId(1001L)
|
||||
.setAcceptApplyUserId(2001L)
|
||||
.setRelationType(relationType)
|
||||
.setStatus(CpApplyStatus.WAIT.name());
|
||||
}
|
||||
|
||||
private static class Fixture {
|
||||
|
||||
private final CpApplyService cpApplyService = mock(CpApplyService.class);
|
||||
private final CpRelationshipService cpRelationshipService = mock(CpRelationshipService.class);
|
||||
private final CpRelationBroadcastMqClient cpRelationBroadcastMqClient = mock(
|
||||
CpRelationBroadcastMqClient.class);
|
||||
private final ProcessCpApplyCmd exe;
|
||||
|
||||
private Fixture(String relationType) {
|
||||
CpValueService cpValueService = mock(CpValueService.class);
|
||||
ImMessageClient imMessageClient = mock(ImMessageClient.class);
|
||||
WalletGoldClient walletGoldClient = mock(WalletGoldClient.class);
|
||||
UserMqMessageService userMqMessageService = mock(UserMqMessageService.class);
|
||||
UserProfileGateway userProfileGateway = mock(UserProfileGateway.class);
|
||||
CpRelationshipCacheService cpRelationshipCacheService = mock(
|
||||
CpRelationshipCacheService.class);
|
||||
|
||||
when(cpApplyService.getById(3001L)).thenReturn(apply(relationType));
|
||||
when(cpApplyService.changeStatusById(3001L, CpApplyStatus.AGREE)).thenReturn(true);
|
||||
|
||||
exe = new ProcessCpApplyCmd(
|
||||
cpApplyService,
|
||||
cpValueService,
|
||||
imMessageClient,
|
||||
walletGoldClient,
|
||||
userMqMessageService,
|
||||
cpRelationshipService,
|
||||
userProfileGateway,
|
||||
cpRelationshipCacheService,
|
||||
cpRelationBroadcastMqClient);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,13 +4,14 @@ 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.times;
|
||||
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.external.inner.endpoint.message.ImMessageClient;
|
||||
import com.red.circle.external.inner.model.cmd.message.CustomC2cMsgBodyCmd;
|
||||
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;
|
||||
@ -23,6 +24,8 @@ 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 java.util.List;
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
@ -49,13 +52,48 @@ class SendCpApplyCmdExeTest {
|
||||
verify(fixture.cpApplyService, never()).save(any(CpApply.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void autoCreateFromCpGiftShouldCreateIndependentAppliesForDifferentRelationTypes() {
|
||||
Fixture fixture = new Fixture(1, 0);
|
||||
|
||||
assertTrue(fixture.exe.autoCreateFromCpGift(1001L, 2001L, "LIKEI", "CP"));
|
||||
assertTrue(fixture.exe.autoCreateFromCpGift(1001L, 2001L, "LIKEI", "BROTHER"));
|
||||
assertTrue(fixture.exe.autoCreateFromCpGift(1001L, 2001L, "LIKEI", "SISTERS"));
|
||||
|
||||
List<CpApply> applies = fixture.savedApplies(3);
|
||||
assertEquals("CP", applies.get(0).getRelationType());
|
||||
assertEquals("BROTHER", applies.get(1).getRelationType());
|
||||
assertEquals("SISTERS", applies.get(2).getRelationType());
|
||||
|
||||
List<CustomC2cMsgBodyCmd> messages = fixture.sentCustomMessages(3);
|
||||
assertEquals("1001", messages.get(0).getFromAccount());
|
||||
assertEquals("2001", messages.get(0).getToAccount());
|
||||
assertCpBuildMessage(messages.get(0), "CP", 3001L);
|
||||
assertCpBuildMessage(messages.get(1), "BROTHER", 3002L);
|
||||
assertCpBuildMessage(messages.get(2), "SISTERS", 3003L);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static void assertCpBuildMessage(CustomC2cMsgBodyCmd message, String relationType,
|
||||
Long applyId) {
|
||||
assertEquals("CP_BUILD", message.getDesc());
|
||||
Map<String, Object> data = (Map<String, Object>) message.getData();
|
||||
assertEquals("CP_BUILD", data.get("noticeType"));
|
||||
assertEquals("CP_BUILD", data.get("type"));
|
||||
assertEquals(applyId, data.get("expand"));
|
||||
assertEquals(applyId, data.get("applyId"));
|
||||
assertEquals(relationType, data.get("relationType"));
|
||||
assertTrue(data.get("content").toString().contains("\"relationType\":\"" + relationType + "\""));
|
||||
}
|
||||
|
||||
private static class Fixture {
|
||||
|
||||
private final CpApplyService cpApplyService = mock(CpApplyService.class);
|
||||
private final ImMessageClient imMessageClient = mock(ImMessageClient.class);
|
||||
private final SendCpApplyCmdExe exe;
|
||||
private long nextApplyId = 3001L;
|
||||
|
||||
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);
|
||||
@ -65,7 +103,9 @@ class SendCpApplyCmdExeTest {
|
||||
UserRegionGateway userRegionGateway = mock(UserRegionGateway.class);
|
||||
|
||||
UserProfile sendProfile = new UserProfile();
|
||||
sendProfile.setId(1001L);
|
||||
UserProfile acceptProfile = new UserProfile();
|
||||
acceptProfile.setId(2001L);
|
||||
UserProfileDTO sendProfileDTO = profile(1001L, sendSex);
|
||||
UserProfileDTO acceptProfileDTO = profile(2001L, acceptSex);
|
||||
|
||||
@ -74,12 +114,17 @@ class SendCpApplyCmdExeTest {
|
||||
when(userProfileGateway.getByUserId(2001L)).thenReturn(acceptProfile);
|
||||
when(userProfileAppConvertor.toUserProfileDTO(sendProfile)).thenReturn(sendProfileDTO);
|
||||
when(userProfileAppConvertor.toUserProfileDTO(acceptProfile)).thenReturn(acceptProfileDTO);
|
||||
when(officialNoticeClient.send(any(NoticeExtTemplateTypeCmd.class)))
|
||||
when(imMessageClient.sendCustomMessage(any(CustomC2cMsgBodyCmd.class)))
|
||||
.thenReturn(ResultResponse.success());
|
||||
when(cpApplyService.save(any(CpApply.class))).thenAnswer(invocation -> {
|
||||
CpApply apply = invocation.getArgument(0);
|
||||
apply.setId(nextApplyId++);
|
||||
return true;
|
||||
});
|
||||
|
||||
exe = new SendCpApplyCmdExe(
|
||||
cpApplyService,
|
||||
officialNoticeClient,
|
||||
imMessageClient,
|
||||
walletGoldClient,
|
||||
userMqMessageService,
|
||||
cpRelationshipService,
|
||||
@ -91,9 +136,19 @@ class SendCpApplyCmdExeTest {
|
||||
}
|
||||
|
||||
private CpApply savedApply() {
|
||||
return savedApplies(1).get(0);
|
||||
}
|
||||
|
||||
private List<CpApply> savedApplies(int count) {
|
||||
ArgumentCaptor<CpApply> captor = ArgumentCaptor.forClass(CpApply.class);
|
||||
verify(cpApplyService).save(captor.capture());
|
||||
return captor.getValue();
|
||||
verify(cpApplyService, times(count)).save(captor.capture());
|
||||
return captor.getAllValues();
|
||||
}
|
||||
|
||||
private List<CustomC2cMsgBodyCmd> sentCustomMessages(int count) {
|
||||
ArgumentCaptor<CustomC2cMsgBodyCmd> captor = ArgumentCaptor.forClass(CustomC2cMsgBodyCmd.class);
|
||||
verify(imMessageClient, times(count)).sendCustomMessage(captor.capture());
|
||||
return captor.getAllValues();
|
||||
}
|
||||
|
||||
private static UserProfileDTO profile(Long userId, Integer sex) {
|
||||
|
||||
@ -215,8 +215,9 @@ public class CpLocalFlowSmokeTest {
|
||||
}
|
||||
|
||||
private void assertGiftAutoApplyRelationType(UserPair pair, String relationType) {
|
||||
BigDecimal giftConsumeGold = BigDecimal.valueOf(66);
|
||||
boolean created = sendCpApplyCmdExe.autoCreateFromCpGift(pair.sendUserId,
|
||||
pair.acceptUserId, SYS_ORIGIN, relationType);
|
||||
pair.acceptUserId, SYS_ORIGIN, relationType, giftConsumeGold);
|
||||
assertTrue(relationType + " gift should auto create apply", created);
|
||||
|
||||
Long applyId = cpApplyService.getId(pair.acceptUserId, pair.sendUserId, relationType);
|
||||
@ -225,12 +226,21 @@ public class CpLocalFlowSmokeTest {
|
||||
|
||||
CpApply apply = cpApplyService.getById(applyId);
|
||||
assertEquals(relationType, apply.getRelationType());
|
||||
assertEquals(0, BigDecimal.ZERO.compareTo(apply.getApplyConsumeGold()));
|
||||
assertEquals(0, giftConsumeGold.compareTo(apply.getApplyConsumeGold()));
|
||||
|
||||
agree(applyId, pair.acceptUserId);
|
||||
CpRelationship relationship = cpRelationshipService.getByUserId(pair.sendUserId,
|
||||
pair.acceptUserId, relationType);
|
||||
assertNotNull(relationType + " relationship after gift auto apply agree", relationship);
|
||||
assertEquals(relationType, relationship.getRelationType());
|
||||
createdPairs.add(new RelationPair(pair.sendUserId, pair.acceptUserId, relationType));
|
||||
createdCpValIds.add(relationship.getCpValId());
|
||||
}
|
||||
|
||||
private void runCpGiftApplyBlessDismissFlow(UserPair pair) throws Exception {
|
||||
BigDecimal giftConsumeGold = BigDecimal.valueOf(88);
|
||||
boolean created = sendCpApplyCmdExe.autoCreateFromCpGift(pair.sendUserId, pair.acceptUserId,
|
||||
SYS_ORIGIN);
|
||||
SYS_ORIGIN, giftConsumeGold);
|
||||
Long pendingApplyId = cpApplyService.getId(pair.acceptUserId, pair.sendUserId, "CP");
|
||||
if (pendingApplyId != null && !createdApplyIds.contains(pendingApplyId)) {
|
||||
createdApplyIds.add(pendingApplyId);
|
||||
@ -243,7 +253,7 @@ public class CpLocalFlowSmokeTest {
|
||||
|
||||
CpApply apply = cpApplyService.getById(applyId);
|
||||
assertEquals("CP", apply.getRelationType());
|
||||
assertEquals(0, BigDecimal.ZERO.compareTo(apply.getApplyConsumeGold()));
|
||||
assertEquals(0, giftConsumeGold.compareTo(apply.getApplyConsumeGold()));
|
||||
|
||||
agree(applyId, pair.acceptUserId);
|
||||
CpRelationship relationship = cpRelationshipService.getByUserId(pair.sendUserId,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user