添加邀请

This commit is contained in:
hy001 2026-04-27 19:19:06 +08:00
parent 05fb11d4e7
commit e5594dd692
6 changed files with 212 additions and 36 deletions

View File

@ -2,3 +2,11 @@ spring:
data:
redis:
database: 0
invite:
campaign:
go:
enabled: ${INVITE_CAMPAIGN_GO_ENABLED:true}
base-url: ${INVITE_CAMPAIGN_GO_URL:}
internal-token: ${GAME_INTERNAL_CALLBACK_SECRET:}
timeout-millis: ${INVITE_CAMPAIGN_GO_TIMEOUT_MILLIS:10000}

View File

@ -238,11 +238,12 @@ public class TeamLeaderBDServiceImpl implements TeamLeaderBDService {
bd.setUpdateUser(param.getUpdateUser());
bdTeamInfoClient.updateSelectiveById(bd);
} else {
bdTeamInfoClient.add(new BdTeamInfoCmd()
.setSysOrigin(bdLead.getSysOrigin())
.setCreateUser(bdLead.getCreateUser())
.setRegion(bdLead.getRegionId())
.setUserId(param.getUserId())
bdTeamInfoClient.add(new BdTeamInfoCmd()
.setId(IdWorkerUtils.getId())
.setSysOrigin(bdLead.getSysOrigin())
.setCreateUser(bdLead.getCreateUser())
.setRegion(bdLead.getRegionId())
.setUserId(param.getUserId())
.setBdLeadUserId(param.getBdLeadUserId()));
}

View File

@ -27,8 +27,9 @@ import com.red.circle.tool.core.num.ArithmeticUtils;
import com.red.circle.tool.core.tuple.PennyAmount;
import com.red.circle.other.inner.asserts.user.UserErrorCode;
import com.red.circle.other.inner.endpoint.user.user.UserSvipClient;
import com.red.circle.wallet.app.dto.cmd.FreightDealerToUserShipCmd;
import com.red.circle.wallet.domain.gateway.FreightShipGateway;
import com.red.circle.wallet.app.dto.cmd.FreightDealerToUserShipCmd;
import com.red.circle.wallet.app.common.invite.InviteCampaignGoClient;
import com.red.circle.wallet.domain.gateway.FreightShipGateway;
import com.red.circle.wallet.domain.gateway.WalletGoldGateway;
import com.red.circle.wallet.domain.wallet.WalletReceipt;
import com.red.circle.wallet.infra.database.cache.service.UserPayAuthCacheService;
@ -79,9 +80,10 @@ public class DealerToUserShipCmdExe {
private final CumulativeRechargeClient cumulativeRechargeClient;
private final FreightBalanceRunningWaterService freightBalanceRunningWaterService;
private final PropsActivityClient propsActivityClient;
private final UserOneTimeTaskClient userOneTimeTaskClient;
private final UserProfileClient userProfileClient;
private final InviteUserClient inviteUserClient;
private final UserOneTimeTaskClient userOneTimeTaskClient;
private final UserProfileClient userProfileClient;
private final InviteUserClient inviteUserClient;
private final InviteCampaignGoClient inviteCampaignGoClient;
public BigDecimal execute(FreightDealerToUserShipCmd cmd) {
controlSwitch.execute(cmd.requireReqSysOriginChildEnum());
@ -165,11 +167,12 @@ public class DealerToUserShipCmdExe {
);
}
// 累计充值
incrRechargeQuantity(cmd);
//累计今日充值每日累计充值抽奖活动
cumulativeRechargeClient.incrTodayRechargeScore(cmd.getAcceptUserId(),
// 累计充值
incrRechargeQuantity(cmd);
notifyInviteCampaignRecharge(cmd, runningWater);
//累计今日充值每日累计充值抽奖活动
cumulativeRechargeClient.incrTodayRechargeScore(cmd.getAcceptUserId(),
getGoldToSUD(cmd).doubleValue());
// 余额如果等于0则回收货运代理徽章
@ -245,10 +248,27 @@ public class DealerToUserShipCmdExe {
userProfileClient.removeCacheAll(userId);
}*/
}
}
private void incrRechargeQuantity(FreightDealerToUserShipCmd cmd) {
}
private void notifyInviteCampaignRecharge(FreightDealerToUserShipCmd cmd,
FreightBalanceRunningWater runningWater) {
try {
inviteCampaignGoClient.notifyRechargeSuccess(
new InviteCampaignGoClient.RechargeSuccessRequest()
.setOrderId("seller-agent:" + runningWater.getId())
.setUserId(cmd.getAcceptUserId())
.setRechargeCoins(InviteCampaignGoClient.toRechargeCoins(cmd.getQuantity()))
.setPayTime(System.currentTimeMillis())
.setSysOrigin(cmd.getReqSysOrigin().getOrigin())
);
} catch (Exception e) {
log.error("Invite campaign recharge notify failed. channel=SELLER_AGENT, userId={}, orderId={}",
cmd.getAcceptUserId(), runningWater.getId(), e);
}
}
private void incrRechargeQuantity(FreightDealerToUserShipCmd cmd) {
userRechargeCountClient.count(cmd.getAcceptUserId(),
getGoldToSUD(cmd),
MonthlyRechargeType.SELLER_AGENT

View File

@ -31,9 +31,10 @@ import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.tool.core.date.LocalDateTimeUtils;
import com.red.circle.tool.core.json.JacksonUtils;
import com.red.circle.tool.core.num.ArithmeticUtils;
import com.red.circle.tool.core.tuple.PennyAmount;
import com.red.circle.other.inner.asserts.user.UserErrorCode;
import com.red.circle.wallet.app.dto.cmd.FreightShipSendCmd;
import com.red.circle.tool.core.tuple.PennyAmount;
import com.red.circle.other.inner.asserts.user.UserErrorCode;
import com.red.circle.wallet.app.common.invite.InviteCampaignGoClient;
import com.red.circle.wallet.app.dto.cmd.FreightShipSendCmd;
import com.red.circle.wallet.app.dto.cmd.SalaryWithdrawCmd;
import com.red.circle.wallet.domain.gateway.FreightShipGateway;
import com.red.circle.wallet.domain.gateway.WalletGoldGateway;
@ -88,10 +89,11 @@ public class SendFreightShipCmdExe {
private final TaskMqMessage taskMqMessage;
private final UserLevelClient userLevelClient;
private final PropsActivityClient propsActivityClient;
private final UserOneTimeTaskClient userOneTimeTaskClient;
private final InviteUserClient inviteUserClient;
private final UserRegionClient userRegionClient;
private final OfficialNoticeClient officialNoticeClient;
private final UserOneTimeTaskClient userOneTimeTaskClient;
private final InviteUserClient inviteUserClient;
private final InviteCampaignGoClient inviteCampaignGoClient;
private final UserRegionClient userRegionClient;
private final OfficialNoticeClient officialNoticeClient;
public BigDecimal execute(FreightShipSendCmd cmd) {
@ -183,12 +185,13 @@ public class SendFreightShipCmdExe {
log.error("send freight balance failed: {}", e.getMessage());
}
// 累计充值
incrRechargeQuantity(cmd);
//累计今日充值每日累计充值抽奖活动
cumulativeRechargeClient.incrTodayRechargeScore(cmd.getAcceptUserId(),getGoldToSUD(cmd).doubleValue());
// 累计充值
incrRechargeQuantity(cmd);
notifyInviteCampaignRecharge(cmd, runningWater);
//累计今日充值每日累计充值抽奖活动
cumulativeRechargeClient.incrTodayRechargeScore(cmd.getAcceptUserId(),getGoldToSUD(cmd).doubleValue());
completedFirstCharge(cmd.getAcceptUserId(), cmd.getReqSysOrigin().getOrigin());
}
@ -274,10 +277,27 @@ public class SendFreightShipCmdExe {
}*/
}
}
}
private void incrRechargeQuantity(FreightShipSendCmd cmd) {
}
private void notifyInviteCampaignRecharge(FreightShipSendCmd cmd,
FreightBalanceRunningWater runningWater) {
try {
inviteCampaignGoClient.notifyRechargeSuccess(
new InviteCampaignGoClient.RechargeSuccessRequest()
.setOrderId("shipping-agent:" + runningWater.getId())
.setUserId(cmd.getAcceptUserId())
.setRechargeCoins(InviteCampaignGoClient.toRechargeCoins(cmd.getQuantity()))
.setPayTime(System.currentTimeMillis())
.setSysOrigin(cmd.getReqSysOrigin().getOrigin())
);
} catch (Exception e) {
log.error("Invite campaign recharge notify failed. channel=SHIPPING_AGENT, userId={}, orderId={}",
cmd.getAcceptUserId(), runningWater.getId(), e);
}
}
private void incrRechargeQuantity(FreightShipSendCmd cmd) {
userRechargeCountClient.count(cmd.getAcceptUserId(),
getGoldToSUD(cmd),
MonthlyRechargeType.SHIPPING_AGENT

View File

@ -0,0 +1,106 @@
package com.red.circle.wallet.app.common.invite;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.red.circle.wallet.infra.config.InviteCampaignGoConfig;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.Objects;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@RequiredArgsConstructor
public class InviteCampaignGoClient {
private static final String RECHARGE_SUCCESS_PATH = "/internal/invite-campaign/recharge-success";
private final InviteCampaignGoConfig inviteCampaignGoConfig;
public void notifyRechargeSuccess(RechargeSuccessRequest request) {
if (!inviteCampaignGoConfig.isEnabled()) {
return;
}
String baseUrl = Objects.toString(inviteCampaignGoConfig.getBaseUrl(), "").trim();
if (baseUrl.isEmpty()) {
log.warn("Invite campaign go baseUrl is blank, skip recharge notify. userId={}, orderId={}",
request.getUserId(), request.getOrderId());
return;
}
int timeoutMillis = Objects.requireNonNullElse(inviteCampaignGoConfig.getTimeoutMillis(), 10000);
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(URI.create(trimRightSlash(baseUrl) + RECHARGE_SUCCESS_PATH))
.timeout(Duration.ofMillis(timeoutMillis))
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.header("X-Internal-Token", Objects.toString(inviteCampaignGoConfig.getInternalToken(), ""))
.POST(HttpRequest.BodyPublishers.ofString(JSON.toJSONString(request)))
.build();
HttpResponse<String> response;
try {
response = HttpClient.newBuilder()
.connectTimeout(Duration.ofMillis(timeoutMillis))
.build()
.send(httpRequest, HttpResponse.BodyHandlers.ofString());
} catch (IOException e) {
throw new IllegalStateException("Invite campaign go request failed", e);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IllegalStateException("Invite campaign go request interrupted", e);
}
String responseBody = response.body();
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new IllegalStateException("Invite campaign go http error, status=" + response.statusCode()
+ ", body=" + responseBody);
}
if (responseBody == null || responseBody.trim().isEmpty()) {
throw new IllegalStateException("Invite campaign go response is empty");
}
JSONObject root = JSON.parseObject(responseBody);
if (root == null) {
throw new IllegalStateException("Invite campaign go response is invalid");
}
if (root.containsKey("status") && !root.getBooleanValue("status")) {
throw new IllegalStateException("Invite campaign go business error: " + root.getString("message"));
}
}
private String trimRightSlash(String value) {
while (value.endsWith("/")) {
value = value.substring(0, value.length() - 1);
}
return value;
}
public static long toRechargeCoins(BigDecimal quantity) {
if (quantity == null) {
return 0L;
}
return quantity.setScale(0, RoundingMode.DOWN).longValue();
}
@Data
@Accessors(chain = true)
public static class RechargeSuccessRequest {
private String orderId;
private Long userId;
private Long rechargeCoins;
private Long payTime;
private String sysOrigin;
}
}

View File

@ -0,0 +1,21 @@
package com.red.circle.wallet.infra.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
@Data
@Component
@RefreshScope
@ConfigurationProperties(prefix = "invite.campaign.go")
public class InviteCampaignGoConfig {
private boolean enabled = true;
private String baseUrl;
private String internalToken;
private Integer timeoutMillis = 10000;
}