接入币安,新增币安订单查询功能
This commit is contained in:
parent
f686b95e30
commit
2f54f9a29b
@ -0,0 +1,15 @@
|
||||
package com.red.circle.external.inner.endpoint.binance;
|
||||
|
||||
import com.red.circle.external.inner.endpoint.binance.api.BinanceClientApi;
|
||||
import com.red.circle.external.inner.endpoint.censor.api.CensorImageClientApi;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
|
||||
/**
|
||||
* 图片安全鉴定.
|
||||
*
|
||||
* @author pengliang on 2023/10/17
|
||||
*/
|
||||
@FeignClient(name = "binanceClient", url = "${feign.external.url}" +
|
||||
CensorImageClientApi.API_PREFIX)
|
||||
public interface BinanceClient extends BinanceClientApi {
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package com.red.circle.external.inner.endpoint.binance.api;
|
||||
|
||||
import com.red.circle.framework.dto.ResultResponse;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* 图片安全鉴定.
|
||||
*
|
||||
* @author pengliang on 2023/10/17
|
||||
*/
|
||||
public interface BinanceClientApi {
|
||||
|
||||
String API_PREFIX = "/binance/client";
|
||||
|
||||
/**
|
||||
* 鉴定.
|
||||
*
|
||||
* @param txId 被鉴定的图片url
|
||||
*/
|
||||
@GetMapping("/deposit/history")
|
||||
ResultResponse<String> depositHistory(@RequestParam("txId") String txId);
|
||||
|
||||
@GetMapping("/transactions")
|
||||
ResultResponse<String> transactions(@RequestParam("orderId") String orderId)
|
||||
throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException;
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
package com.red.circle.other.inner.enums.freight;
|
||||
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
/**
|
||||
* 币商政策.
|
||||
*
|
||||
* @author pengliang on 2019/10/24 14:35
|
||||
*/
|
||||
public enum FreightPolicyEnum {
|
||||
|
||||
G(0, 10000),
|
||||
|
||||
F(100, 11300),
|
||||
|
||||
E(300, 11400),
|
||||
|
||||
D(500, 11500),
|
||||
|
||||
C(1000, 11600),
|
||||
|
||||
B(2000, 12000),
|
||||
|
||||
A(3000, 12200),
|
||||
|
||||
S(5000, 12500);
|
||||
|
||||
|
||||
private final Integer price;
|
||||
|
||||
private final Integer ratio;
|
||||
|
||||
FreightPolicyEnum(Integer price, Integer ratio) {
|
||||
this.price = price;
|
||||
this.ratio = ratio;
|
||||
}
|
||||
|
||||
public static BigDecimal earnPoints(BigDecimal amount) {
|
||||
FreightPolicyEnum[] values = FreightPolicyEnum.values();
|
||||
for (int i = values.length - 1; i >= 0; i--) {
|
||||
FreightPolicyEnum value = values[i];
|
||||
if (value.price.compareTo(amount.intValue()) <= 0) {
|
||||
return amount.multiply(new BigDecimal(value.ratio)).setScale(0, RoundingMode.FLOOR);
|
||||
}
|
||||
}
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(FreightPolicyEnum.earnPoints(new BigDecimal(12)));
|
||||
}
|
||||
}
|
||||
@ -51,6 +51,30 @@
|
||||
<artifactId>component-push</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.github.binance</groupId>
|
||||
<artifactId>binance-pay</artifactId>
|
||||
<version>2.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.github.binance</groupId>
|
||||
<artifactId>binance-wallet</artifactId>
|
||||
<version>1.1.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>4.12.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>logging-interceptor</artifactId>
|
||||
<version>4.12.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<parent>
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
package com.red.circle.external.infra.props;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author pengliang on 2023/9/21
|
||||
*/
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
@Component
|
||||
@ConfigurationProperties(BinanceProperties.PREFIX)
|
||||
public class BinanceProperties {
|
||||
|
||||
public final static String PREFIX = "red-circle.binance";
|
||||
|
||||
String url;
|
||||
String apiKey;
|
||||
String secretKey;
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
package com.red.circle.external.inner.endpoint.binance;
|
||||
|
||||
import com.red.circle.external.inner.endpoint.binance.api.BinanceClientApi;
|
||||
import com.red.circle.external.inner.endpoint.censor.api.CensorImageClientApi;
|
||||
import com.red.circle.external.inner.service.binance.BinanceClientService;
|
||||
import com.red.circle.framework.dto.ResultResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* 图片安全鉴定.
|
||||
*
|
||||
* @author pengliang on 2023/10/17
|
||||
*/
|
||||
@Validated
|
||||
@RestController
|
||||
@RequestMapping(value = CensorImageClientApi.API_PREFIX, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@RequiredArgsConstructor
|
||||
public class BinanceClientEndpoint implements BinanceClientApi {
|
||||
|
||||
private final BinanceClientService binanceClientService;
|
||||
|
||||
@Override
|
||||
public ResultResponse<String> depositHistory(String txId) {
|
||||
return ResultResponse.success(binanceClientService.depositHistory(txId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultResponse<String> transactions(String orderId)
|
||||
throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
|
||||
return ResultResponse.success(binanceClientService.transactions(orderId));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package com.red.circle.external.inner.service.binance;
|
||||
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* minimax 相关服务.
|
||||
*
|
||||
* @author pengliang on 2021/3/25
|
||||
*/
|
||||
public interface BinanceClientService {
|
||||
|
||||
String depositHistory(String txId);
|
||||
|
||||
String transactions(String orderId)
|
||||
throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException;
|
||||
}
|
||||
@ -0,0 +1,191 @@
|
||||
package com.red.circle.external.inner.service.binance.impl;
|
||||
|
||||
import com.binance.connector.client.common.ApiClient;
|
||||
import com.binance.connector.client.common.ApiResponse;
|
||||
import com.binance.connector.client.common.auth.BinanceAuthenticationFactory;
|
||||
import com.binance.connector.client.common.configuration.ClientConfiguration;
|
||||
import com.binance.connector.client.common.configuration.SignatureConfiguration;
|
||||
import com.binance.connector.client.wallet.rest.api.CapitalApi;
|
||||
import com.binance.connector.client.wallet.rest.model.DepositHistoryResponse;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.red.circle.external.infra.props.BinanceProperties;
|
||||
import com.red.circle.external.inner.service.binance.BinanceClientService;
|
||||
import com.red.circle.tool.core.collection.CollectionUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* minimax 实现.
|
||||
*
|
||||
* @author pengliang on 2023/7/12
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class BinanceClientServiceImpl implements BinanceClientService {
|
||||
|
||||
private final BinanceProperties binanceProperties;
|
||||
|
||||
|
||||
@Override
|
||||
public String depositHistory(String txId) {
|
||||
if (StringUtils.isBlank(txId)) {
|
||||
return "";
|
||||
}
|
||||
ClientConfiguration clientConfiguration = new ClientConfiguration();
|
||||
clientConfiguration.setUrl(binanceProperties.getUrl());
|
||||
SignatureConfiguration signatureConfiguration = new SignatureConfiguration();
|
||||
signatureConfiguration.setApiKey(binanceProperties.getApiKey());
|
||||
signatureConfiguration.setSecretKey(binanceProperties.getSecretKey());
|
||||
clientConfiguration.setSignatureConfiguration(signatureConfiguration);
|
||||
ApiClient apiClient = new ApiClient(clientConfiguration, new BinanceAuthenticationFactory());
|
||||
CapitalApi api = new CapitalApi(apiClient);
|
||||
// 获取当前时间戳(毫秒级)
|
||||
long currentTimeStamp = System.currentTimeMillis();
|
||||
|
||||
// 计算24小时前的时间戳(毫秒级)
|
||||
long twentyFourHoursInMillis = 24 * 60 * 60 * 1000L;
|
||||
long twentyFourHoursAgoTimeStamp = currentTimeStamp - twentyFourHoursInMillis;
|
||||
|
||||
ApiResponse<DepositHistoryResponse> depositHistoryResponseApiResponse =
|
||||
api.depositHistory(true, "USDT", 1L, twentyFourHoursAgoTimeStamp, currentTimeStamp, 0L, 1000L, 5000L, txId);
|
||||
try {
|
||||
return depositHistoryResponseApiResponse.getData().get(0).getAmount();
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String transactions(String orderId)
|
||||
throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException {
|
||||
long currentTimeStamp = System.currentTimeMillis();
|
||||
|
||||
long twentyFourHoursInMillis = 24 * 60 * 60 * 1000L;
|
||||
long twentyFourHoursAgoTimeStamp = currentTimeStamp - twentyFourHoursInMillis;
|
||||
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("timestamp", String.valueOf(System.currentTimeMillis()));
|
||||
params.put("recvWindow", "5000");
|
||||
params.put("startTime", String.valueOf(twentyFourHoursAgoTimeStamp));
|
||||
params.put("endTime", String.valueOf(currentTimeStamp));
|
||||
|
||||
List<String> sortedKeys = new ArrayList<>(params.keySet());
|
||||
Collections.sort(sortedKeys);
|
||||
StringBuilder queryString = new StringBuilder();
|
||||
for (String key : sortedKeys) {
|
||||
if (!queryString.isEmpty()) {
|
||||
queryString.append("&");
|
||||
}
|
||||
queryString.append(java.net.URLEncoder.encode(key, "UTF-8"))
|
||||
.append("=")
|
||||
.append(java.net.URLEncoder.encode(params.get(key), "UTF-8"));
|
||||
}
|
||||
|
||||
Mac hmacSha256 = Mac.getInstance("HmacSHA256");
|
||||
SecretKeySpec secretKey = new SecretKeySpec(binanceProperties.getSecretKey().getBytes("UTF-8"), "HmacSHA256");
|
||||
hmacSha256.init(secretKey);
|
||||
byte[] signatureBytes = hmacSha256.doFinal(queryString.toString().getBytes("UTF-8"));
|
||||
String signature = Hex.encodeHexString(signatureBytes);
|
||||
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
String finalUrl = binanceProperties.getUrl() + "/sapi/v1/pay/transactions" + "?" + queryString + "&signature=" + signature;
|
||||
Request request = new Request.Builder()
|
||||
.url(finalUrl)
|
||||
.addHeader("X-MBX-APIKEY", binanceProperties.getApiKey())
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute()) {
|
||||
assert response.body() != null;
|
||||
String string = response.body().string();
|
||||
Map<String, String> map = parseOrderIdAndAmount(string);
|
||||
return CollectionUtils.isEmpty(map) ? "" : map.get(orderId);
|
||||
} catch (IOException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, String> parseOrderIdAndAmount(String responseBody) {
|
||||
Map<String, String> orderMap = new HashMap<>();
|
||||
|
||||
try {
|
||||
// 创建ObjectMapper实例
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
// 解析JSON
|
||||
JsonNode rootNode = objectMapper.readTree(responseBody);
|
||||
|
||||
// 获取data数组
|
||||
JsonNode dataNode = rootNode.get("data");
|
||||
|
||||
// 检查data是否存在且是数组
|
||||
if (dataNode != null && dataNode.isArray()) {
|
||||
// 遍历数组中的每个元素
|
||||
for (JsonNode node : dataNode) {
|
||||
// 提取orderId
|
||||
JsonNode orderIdNode = node.get("orderId");
|
||||
// 提取amount
|
||||
JsonNode amountNode = node.get("amount");
|
||||
|
||||
// 只有当两个字段都存在且为字符串类型时才添加到Map
|
||||
if (orderIdNode != null && orderIdNode.isTextual() &&
|
||||
amountNode != null && amountNode.isTextual()) {
|
||||
orderMap.put(orderIdNode.asText(), amountNode.asText());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return orderMap;
|
||||
}
|
||||
return orderMap;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
ClientConfiguration clientConfiguration = new ClientConfiguration();
|
||||
clientConfiguration.setUrl("https://api.binance.com");
|
||||
SignatureConfiguration signatureConfiguration = new SignatureConfiguration();
|
||||
signatureConfiguration.setApiKey("币安的Key");
|
||||
signatureConfiguration.setSecretKey("币安的密钥");
|
||||
clientConfiguration.setSignatureConfiguration(signatureConfiguration);
|
||||
|
||||
ApiClient apiClient = new ApiClient(clientConfiguration, new BinanceAuthenticationFactory());
|
||||
|
||||
CapitalApi api = new CapitalApi(apiClient);
|
||||
|
||||
// 获取当前时间戳(毫秒级)
|
||||
long currentTimeStamp = System.currentTimeMillis();
|
||||
|
||||
// 计算24小时前的时间戳(毫秒级)
|
||||
long twentyFourHoursInMillis = 24 * 60 * 60 * 1000L;
|
||||
long twentyFourHoursAgoTimeStamp = currentTimeStamp - twentyFourHoursInMillis;
|
||||
|
||||
|
||||
System.out.println("currentTimeStamp: " + currentTimeStamp);
|
||||
System.out.println("twentyFourHoursAgoTimeStamp: " + twentyFourHoursAgoTimeStamp);
|
||||
|
||||
ApiResponse<DepositHistoryResponse> depositHistoryResponseApiResponse =
|
||||
api.depositHistory(true, "USDT", 1L, twentyFourHoursAgoTimeStamp, currentTimeStamp, 0L, 1000L, 5000L, "");
|
||||
|
||||
System.out.println(depositHistoryResponseApiResponse.getStatusCode());
|
||||
System.out.println(depositHistoryResponseApiResponse.getData().get(0).getAmount());
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,205 @@
|
||||
package com.red.circle.other.app.command.user;
|
||||
|
||||
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
|
||||
import com.red.circle.component.redis.service.RedisService;
|
||||
import com.red.circle.external.inner.endpoint.binance.BinanceClient;
|
||||
import com.red.circle.framework.core.asserts.ResponseAssert;
|
||||
import com.red.circle.framework.core.response.CommonErrorCode;
|
||||
import com.red.circle.order.inner.endpoint.UserFreightRechargeRecordClient;
|
||||
import com.red.circle.other.app.dto.cmd.user.user.FreightRechargeCmd;
|
||||
import com.red.circle.other.app.scheduler.MyAmazingBot;
|
||||
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
|
||||
import com.red.circle.other.domain.model.user.UserProfile;
|
||||
import com.red.circle.other.inner.asserts.ImErrorCode;
|
||||
import com.red.circle.other.inner.asserts.user.UserErrorCode;
|
||||
import com.red.circle.other.inner.endpoint.material.props.BadgeBackpackClient;
|
||||
import com.red.circle.other.inner.endpoint.material.props.BadgeSourceClient;
|
||||
import com.red.circle.other.inner.enums.freight.FreightPolicyEnum;
|
||||
import com.red.circle.tool.core.num.ArithmeticUtils;
|
||||
import com.red.circle.wallet.inner.endpoint.freight.FreightGoldClient;
|
||||
import com.red.circle.wallet.inner.error.FreightErrorCode;
|
||||
import com.red.circle.wallet.inner.model.cmd.AddFreightBalanceRunningWaterCmd;
|
||||
import com.red.circle.wallet.inner.model.cmd.FreightAgentReviewCmd;
|
||||
import com.red.circle.wallet.inner.model.dto.UserFreightBalanceDTO;
|
||||
import com.red.circle.wallet.inner.model.enums.FreightBalanceOrigin;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author longli on 2024/3/22
|
||||
*/
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class FreightRechargeCmdExe {
|
||||
|
||||
private final BadgeBackpackClient badgeBackpackClient;
|
||||
private final RedisService redisService;
|
||||
private final UserProfileGateway userProfileGateway;
|
||||
private final BinanceClient binanceClient;
|
||||
private final FreightGoldClient freightGoldClient;
|
||||
private final UserFreightRechargeRecordClient userFreightRechargeRecordClient;
|
||||
private final BadgeSourceClient badgeSourceClient;
|
||||
|
||||
public void recharge(FreightRechargeCmd cmd) {
|
||||
UserProfile userProfile = userProfileGateway.getByUserId(cmd.getReqUserId());
|
||||
ResponseAssert.notNull(ImErrorCode.NOT_FOUND_USER_INFO, userProfile);
|
||||
ResponseAssert.isTrue(UserErrorCode.USER_INFO_NOT_FOUND,
|
||||
Objects.equals(userProfile.getOriginSys(), cmd.requireReqSysOrigin()));
|
||||
|
||||
ResponseAssert.isFalse(FreightErrorCode.THE_GOLD_COINS_HAVE_ARRIVED, freightGoldClient.existsRecord(cmd.getTxId()).getBody());
|
||||
|
||||
String lockKey = "back_send_freight_ship:" + cmd.getTxId();
|
||||
try {
|
||||
// 操作冲突
|
||||
ResponseAssert.isTrue(CommonErrorCode.OPERATION_CONFLICT, redisService.lock(lockKey, 60));
|
||||
|
||||
String dollar = "";
|
||||
if (cmd.getTxId().length() == 18) {
|
||||
dollar = binanceClient.transactions(cmd.getTxId()).getBody();
|
||||
} else {
|
||||
dollar = binanceClient.depositHistory(cmd.getTxId()).getBody();
|
||||
}
|
||||
ResponseAssert.isTrue(FreightErrorCode.INCORRECT_ORDER_NUMBER, StringUtils.isNotBlank(dollar));
|
||||
|
||||
BigDecimal bigDecimal = new BigDecimal(dollar);
|
||||
|
||||
BigDecimal earnPoints = FreightPolicyEnum.earnPoints(bigDecimal);
|
||||
|
||||
BigDecimal rechargeRatio = freightGoldClient.rechargeRatio(cmd.getReqUserId()).getBody();
|
||||
if (rechargeRatio.compareTo(BigDecimal.ZERO) > 0) {
|
||||
earnPoints = bigDecimal.multiply(rechargeRatio).setScale(0, RoundingMode.FLOOR);
|
||||
}
|
||||
|
||||
// 操作失败
|
||||
ResponseAssert.isTrue(CommonErrorCode.OPERATING_FAILURE,
|
||||
incrCandyBalance(cmd.requireReqSysOrigin(), cmd.getReqUserId(), earnPoints));
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append("Hooka 币商充值").append("\n")
|
||||
.append("用户ID:").append(userProfile.getAccount()).append("\n")
|
||||
.append("充值金额: ").append(bigDecimal).append("\n")
|
||||
.append("自动到账金币: ").append(earnPoints).append("\n")
|
||||
.append("订单号: ").append(cmd.getTxId());
|
||||
sendTelegram(stringBuilder);
|
||||
|
||||
// 插入流水
|
||||
if (ArithmeticUtils.gte(earnPoints, BigDecimal.ONE)) {
|
||||
|
||||
BigDecimal balance = getAvailableBalance(cmd.getReqUserId());
|
||||
|
||||
freightGoldClient.addRunningWater(new AddFreightBalanceRunningWaterCmd()
|
||||
|
||||
.setSysOrigin(cmd.requireReqSysOrigin())
|
||||
.setUserId(cmd.getReqUserId())
|
||||
.setAcceptUserId(cmd.getReqUserId())
|
||||
.setType(0)
|
||||
.setQuantity(earnPoints)
|
||||
.setUsdQuantity(BigDecimal.ZERO)
|
||||
.setBalance(balance)
|
||||
.setRechargeType("USDT-进货")
|
||||
.setAmount(bigDecimal)
|
||||
.setOrigin(FreightBalanceOrigin.PURCHASE.name())
|
||||
.setRemark(cmd.getTxId())
|
||||
.setCreateUser(cmd.getReqUserId())
|
||||
.setUpdateUser(cmd.getReqUserId()));
|
||||
|
||||
// 记录充值金额: 货运代理充值500以上则发送货运代理徽章
|
||||
BigDecimal amount = userFreightRechargeRecordClient.inrNowMonthAmount(cmd.getReqUserId(),
|
||||
ArithmeticUtils.lteZero(bigDecimal) ? BigDecimal.ZERO : bigDecimal)
|
||||
.getBody();
|
||||
sendFreightShipBadge(cmd.getReqUserId(), amount);
|
||||
}
|
||||
} catch (UnsupportedEncodingException | NoSuchAlgorithmException | InvalidKeyException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
redisService.unlock(lockKey);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void sendTelegram(StringBuilder stringBuilder) {
|
||||
//机器人来咯
|
||||
MyAmazingBot myAmazingBot = new MyAmazingBot();
|
||||
myAmazingBot.sendMsg("机器人群组", stringBuilder.toString());
|
||||
}
|
||||
|
||||
private BigDecimal getAvailableBalance(Long userId) {
|
||||
return Optional.ofNullable(
|
||||
ResponseAssert.requiredSuccess(freightGoldClient.getFreightBalance(userId)))
|
||||
.map(balance -> balance.getEarnPoints()
|
||||
.subtract(balance.getConsumptionPoints())
|
||||
.setScale(2, RoundingMode.DOWN))
|
||||
.orElse(BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 余额如果大于1250则发送货运代理徽章.
|
||||
*
|
||||
* @param userId 代理用户id.
|
||||
* @param balance 代理余额.
|
||||
*/
|
||||
public void sendFreightShipBadge(Long userId, BigDecimal balance) {
|
||||
|
||||
if (Objects.isNull(balance)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Long freightBadgeId = getFreightBadgeId();
|
||||
if (Objects.isNull(freightBadgeId)) {
|
||||
return;
|
||||
}
|
||||
if (balance.compareTo(BigDecimal.valueOf(500)) < 0) {
|
||||
return;
|
||||
}
|
||||
badgeBackpackClient.giveBadgePermanent(freightBadgeId, userId);
|
||||
|
||||
}
|
||||
|
||||
private boolean incrCandyBalance(String sysOrigin, Long userId,
|
||||
BigDecimal quantity) {
|
||||
UserFreightBalanceDTO freightBalance = freightGoldClient.getFreightBalance(userId)
|
||||
.getBody();
|
||||
|
||||
if (Objects.isNull(freightBalance)) {
|
||||
|
||||
ResponseAssert.isFalse(
|
||||
UserErrorCode.USER_IS_SELLER, ResponseAssert.requiredSuccess(
|
||||
freightGoldClient.existsSeller(userId)));
|
||||
|
||||
//获得货运代理徽章
|
||||
Long badgeId = getFreightBadgeId();
|
||||
if (Objects.nonNull(badgeId) && quantity.compareTo(BigDecimal.valueOf(1250)) >= 0) {
|
||||
//发送货运代理徽章
|
||||
badgeBackpackClient.giveBadgePermanent(badgeId, userId);
|
||||
}
|
||||
|
||||
// 增加新开货运代理审查记录
|
||||
freightGoldClient.addFreightAgentReview(new FreightAgentReviewCmd()
|
||||
.setSysOrigin(sysOrigin)
|
||||
.setUserId(userId)
|
||||
);
|
||||
|
||||
}
|
||||
if (Objects.equals(Boolean.TRUE, ResponseAssert.requiredSuccess(
|
||||
freightGoldClient.incrCandyBalance(SysOriginPlatformEnum.valueOf(sysOrigin), userId,
|
||||
quantity)))) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
private Long getFreightBadgeId() {
|
||||
return badgeSourceClient.getFreightBadgeId().getBody();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.red.circle.other.app.dto.cmd.user.user;
|
||||
|
||||
import com.red.circle.common.business.dto.cmd.AppExtCommand;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 填写邀请用户.
|
||||
* </p>
|
||||
*
|
||||
* @author pengshigang
|
||||
* @since 2023-12-20
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class FreightRechargeCmd extends AppExtCommand {
|
||||
|
||||
@NotBlank(message = "txId required.")
|
||||
private String txId;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user