新增 transfer gold 接口
This commit is contained in:
parent
6b78840f5e
commit
324b8dc2d5
@ -619,6 +619,11 @@ public enum GoldOrigin {
|
|||||||
*/
|
*/
|
||||||
BANK_GOLD_COIN_EXCHANGE("[Bank]Gold coin exchange"),
|
BANK_GOLD_COIN_EXCHANGE("[Bank]Gold coin exchange"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转账金币.
|
||||||
|
*/
|
||||||
|
BANK_GOLD_COIN_TRANSFER("[Bank]Gold coin transfer"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 幸运礼物.
|
* 幸运礼物.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -15,6 +15,11 @@ public enum UserBankWaterEvent {
|
|||||||
*/
|
*/
|
||||||
TRANSFER("Transfer"),
|
TRANSFER("Transfer"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转账金币.
|
||||||
|
*/
|
||||||
|
TRANSFER_GOLD("Transfer"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接收转账.
|
* 接收转账.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -123,6 +123,20 @@ public class BankRestController extends BaseController {
|
|||||||
return userBankService.transfer(cmd);
|
return userBankService.transfer(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转账到金币.
|
||||||
|
*
|
||||||
|
* @eo.name 转账到金币.
|
||||||
|
* @eo.url /transferGold
|
||||||
|
* @eo.method post
|
||||||
|
* @eo.request-type json
|
||||||
|
*/
|
||||||
|
@PostMapping("/transferGold")
|
||||||
|
public UserBankWithdrawResultCO transferGold(
|
||||||
|
@RequestBody @Validated UserBankWithdrawTransferCmd cmd) {
|
||||||
|
return userBankService.transferGold(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 钻石转账.
|
* 钻石转账.
|
||||||
*
|
*
|
||||||
|
|||||||
@ -0,0 +1,195 @@
|
|||||||
|
package com.red.circle.wallet.app.command.bank;
|
||||||
|
|
||||||
|
import com.red.circle.common.business.core.enums.OpUserType;
|
||||||
|
import com.red.circle.common.business.core.enums.ReceiptType;
|
||||||
|
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
|
||||||
|
import com.red.circle.component.redis.service.RedisService;
|
||||||
|
import com.red.circle.framework.core.asserts.ResponseAssert;
|
||||||
|
import com.red.circle.framework.core.response.CommonErrorCode;
|
||||||
|
import com.red.circle.framework.core.response.ResponseErrorCode;
|
||||||
|
import com.red.circle.order.inner.endpoint.UserFreightRechargeRecordClient;
|
||||||
|
import com.red.circle.order.inner.endpoint.UserRechargeCountClient;
|
||||||
|
import com.red.circle.other.inner.endpoint.team.target.TeamMemberClient;
|
||||||
|
import com.red.circle.other.inner.endpoint.team.target.UserBillDiamondBalanceClient;
|
||||||
|
import com.red.circle.other.inner.endpoint.user.region.UserRegionClient;
|
||||||
|
import com.red.circle.other.inner.endpoint.user.user.UserSvipClient;
|
||||||
|
import com.red.circle.other.inner.model.dto.user.SysExchangeGoldTipDTO;
|
||||||
|
import com.red.circle.tool.core.date.TimestampUtils;
|
||||||
|
import com.red.circle.tool.core.num.ArithmeticUtils;
|
||||||
|
import com.red.circle.tool.core.sequence.IdWorkerUtils;
|
||||||
|
import com.red.circle.tool.core.tuple.PennyAmount;
|
||||||
|
import com.red.circle.wallet.app.dto.clientobject.UserBankWithdrawResultCO;
|
||||||
|
import com.red.circle.wallet.app.dto.cmd.UserBankExchangeGoldCmd;
|
||||||
|
import com.red.circle.wallet.app.dto.cmd.UserBankWithdrawTransferCmd;
|
||||||
|
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;
|
||||||
|
import com.red.circle.wallet.infra.database.mongo.entity.bank.UserBankRunningWater;
|
||||||
|
import com.red.circle.wallet.infra.database.mongo.service.bank.UserBankBalanceService;
|
||||||
|
import com.red.circle.wallet.infra.database.mongo.service.bank.UserBankRunningWaterService;
|
||||||
|
import com.red.circle.wallet.infra.database.mongo.service.bank.UserBankWithdrawGoldApplyService;
|
||||||
|
import com.red.circle.wallet.infra.database.rds.entity.freight.FreightBalanceRunningWater;
|
||||||
|
import com.red.circle.wallet.infra.database.rds.service.auth.PayAuthService;
|
||||||
|
import com.red.circle.wallet.infra.database.rds.service.diamond.SalaryDiamondBalanceService;
|
||||||
|
import com.red.circle.wallet.infra.database.rds.service.diamond.SalaryDiamondRunningWaterService;
|
||||||
|
import com.red.circle.wallet.infra.database.rds.service.freight.FreightBalanceRunningWaterService;
|
||||||
|
import com.red.circle.wallet.infra.database.rds.service.freight.FreightBalanceService;
|
||||||
|
import com.red.circle.wallet.inner.error.WalletErrorCode;
|
||||||
|
import com.red.circle.wallet.inner.model.dto.BankBalanceDTO;
|
||||||
|
import com.red.circle.wallet.inner.model.enums.FreightBalanceOrigin;
|
||||||
|
import com.red.circle.wallet.inner.model.enums.GoldOrigin;
|
||||||
|
import com.red.circle.wallet.inner.model.enums.UserBankWaterEvent;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户银行转账到金币命令执行器
|
||||||
|
*
|
||||||
|
* @author system
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class UserBankTransferGoldCmdExe {
|
||||||
|
|
||||||
|
private final RedisService redisService;
|
||||||
|
private final UserBankBalanceService userBankBalanceService;
|
||||||
|
private final UserBankRunningWaterService userBankRunningWaterService;
|
||||||
|
private final WalletGoldGateway walletGoldGateway;
|
||||||
|
private final FreightBalanceService freightBalanceService;
|
||||||
|
private final UserRegionClient userRegionClient;
|
||||||
|
private final FreightBalanceRunningWaterService freightBalanceRunningWaterService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行转账到金币操作
|
||||||
|
*
|
||||||
|
* @param cmd 转账命令
|
||||||
|
* @return 转账结果
|
||||||
|
*/
|
||||||
|
public UserBankWithdrawResultCO execute(UserBankWithdrawTransferCmd cmd) {
|
||||||
|
ResponseAssert.isTrue(ResponseErrorCode.REQUEST_PARAMETER_ERROR,
|
||||||
|
ArithmeticUtils.gtZero(cmd.getAmount()));
|
||||||
|
|
||||||
|
// 上锁
|
||||||
|
String key = "UBWTransferGold:" + cmd.requiredReqUserId();
|
||||||
|
ResponseAssert.isTrue(CommonErrorCode.REQUEST_LIMITING, redisService.lock(key, 60));
|
||||||
|
|
||||||
|
BigDecimal balance = userBankBalanceService.getBalance(cmd.requiredReqUserId())
|
||||||
|
.getAccurateBalance();
|
||||||
|
|
||||||
|
ResponseAssert.isTrue(WalletErrorCode.INSUFFICIENT_BALANCE,
|
||||||
|
ArithmeticUtils.gte(balance, cmd.getAmount()));
|
||||||
|
|
||||||
|
// 扣钱
|
||||||
|
BankBalanceDTO decrUserBankBalanceDTO = userBankBalanceService.decr(cmd.requiredReqUserId(),
|
||||||
|
PennyAmount.ofDollar(cmd.getAmount()));
|
||||||
|
ResponseAssert.notNull(WalletErrorCode.INSUFFICIENT_BALANCE, decrUserBankBalanceDTO);
|
||||||
|
|
||||||
|
Long bankRunWaterId = IdWorkerUtils.getId();
|
||||||
|
|
||||||
|
// 银行卡流水
|
||||||
|
userBankRunningWaterService.add(
|
||||||
|
new UserBankRunningWater()
|
||||||
|
.setId(bankRunWaterId)
|
||||||
|
.setUserId(cmd.requiredReqUserId())
|
||||||
|
.setSysOrigin(cmd.requireReqSysOrigin())
|
||||||
|
.setType(ReceiptType.EXPENDITURE.getType())
|
||||||
|
.setAmount(cmd.getAmount())
|
||||||
|
.setEvent(UserBankWaterEvent.TRANSFER_GOLD.name())
|
||||||
|
.setEventDescribe(UserBankWaterEvent.TRANSFER_GOLD.getDescribe())
|
||||||
|
.setRemark("Withdrawal transfer")
|
||||||
|
.setTrackId(Objects.toString(cmd.getAcceptUserId()))
|
||||||
|
.setBalance(decrUserBankBalanceDTO.getAccurateBalance())
|
||||||
|
.setCreateTime(TimestampUtils.now())
|
||||||
|
.setUpdateTime(TimestampUtils.now())
|
||||||
|
.setCreateUser(cmd.getReqUserId())
|
||||||
|
.setCreateUserOrigin(OpUserType.APP.getType())
|
||||||
|
);
|
||||||
|
|
||||||
|
boolean freight = freightBalanceService.existsBalance(cmd.getAcceptUserId());
|
||||||
|
|
||||||
|
// 获得区域兑换比例金币比例
|
||||||
|
Double goldRatio = getExchangeGoldRatio(cmd);
|
||||||
|
BigDecimal goldQuantity = BigDecimal.valueOf(goldRatio).multiply(cmd.getAmount()).setScale(0, RoundingMode.DOWN);
|
||||||
|
// 发送金额
|
||||||
|
sendGold(cmd, freight, goldQuantity, bankRunWaterId, "转账金币");
|
||||||
|
|
||||||
|
redisService.unlock(key);
|
||||||
|
return new UserBankWithdrawResultCO()
|
||||||
|
.setBankBalance(decrUserBankBalanceDTO.getAccurateBalance())
|
||||||
|
.setWithdrawAmount(Objects.toString(cmd.getAmount()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendGold(UserBankWithdrawTransferCmd cmd, boolean freight, BigDecimal goldQuantity,
|
||||||
|
Long bankRunWaterId, String remark) {
|
||||||
|
if (freight) {
|
||||||
|
// 货运代理入账
|
||||||
|
ResponseAssert.isTrue(CommonErrorCode.OPERATING_FAILURE,
|
||||||
|
freightBalanceService
|
||||||
|
.incrCandyBalance(SysOriginPlatformEnum.valueOf(cmd.getReqSysOrigin().getOrigin()),
|
||||||
|
cmd.getAcceptUserId(), goldQuantity));
|
||||||
|
|
||||||
|
// 插入流水
|
||||||
|
BigDecimal freightBalance = freightBalanceService.getAvailableBalance(cmd.getAcceptUserId());
|
||||||
|
freightBalanceRunningWaterService.save(new FreightBalanceRunningWater()
|
||||||
|
.setSysOrigin(cmd.getReqSysOrigin().getOrigin())
|
||||||
|
.setUserId(cmd.getReqUserId())
|
||||||
|
.setAcceptUserId(cmd.getAcceptUserId())
|
||||||
|
.setType(ReceiptType.INCOME.getType())
|
||||||
|
.setQuantity(goldQuantity)
|
||||||
|
.setUsdQuantity(cmd.getAmount())
|
||||||
|
.setBalance(freightBalance)
|
||||||
|
.setOrigin(FreightBalanceOrigin.PURCHASE.name())
|
||||||
|
.setRemark(remark)
|
||||||
|
.withCreateUser(cmd.getReqUserId()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 金币入账
|
||||||
|
walletGoldGateway.changeBalance(new WalletReceipt()
|
||||||
|
.setReqTraceId(cmd.getReqTraceId())
|
||||||
|
.setReceiptType(ReceiptType.INCOME)
|
||||||
|
.setUserId(cmd.getAcceptUserId())
|
||||||
|
.setSysOrigin(cmd.getReqSysOrigin().getOrigin())
|
||||||
|
.setEventType(Objects.toString(GoldOrigin.BANK_GOLD_COIN_TRANSFER))
|
||||||
|
.setEventDesc(GoldOrigin.BANK_GOLD_COIN_TRANSFER.getDesc())
|
||||||
|
.setEventId(Objects.toString(bankRunWaterId))
|
||||||
|
.setAmount(PennyAmount.ofDollar(goldQuantity.longValue()))
|
||||||
|
.setOpUserType(OpUserType.APP)
|
||||||
|
.setCreateTime(cmd.getReqTime())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得1$兑换多少金币比例, 基于区域+用户输入的美元.
|
||||||
|
*
|
||||||
|
* @return 1美元可获得的金币数量.
|
||||||
|
*/
|
||||||
|
private Double getExchangeGoldRatio(UserBankWithdrawTransferCmd cmd) {
|
||||||
|
|
||||||
|
boolean freight = freightBalanceService.existsBalance(cmd.getReqUserId());
|
||||||
|
|
||||||
|
List<SysExchangeGoldTipDTO> exchangeGolds = ResponseAssert.requiredSuccess(
|
||||||
|
userRegionClient.listRegionExchangeGoldTip(cmd.getReqUserId(), freight));
|
||||||
|
ResponseAssert.notEmpty(CommonErrorCode.CONFIGURATION_ERROR, exchangeGolds);
|
||||||
|
|
||||||
|
exchangeGolds = exchangeGolds.stream().filter(gold ->
|
||||||
|
cmd.getAmount().compareTo(BigDecimal.valueOf(gold.getStart())) >= 0 &&
|
||||||
|
cmd.getAmount().compareTo(BigDecimal.valueOf(gold.getEnd())) <= 0)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
ResponseAssert.notEmpty(CommonErrorCode.CONFIGURATION_ERROR, exchangeGolds);
|
||||||
|
|
||||||
|
SysExchangeGoldTipDTO exchangeGold = exchangeGolds.get(0);
|
||||||
|
ResponseAssert.notNull(CommonErrorCode.CONFIGURATION_ERROR, exchangeGold);
|
||||||
|
ResponseAssert.isFalse(CommonErrorCode.CONFIGURATION_ERROR,
|
||||||
|
Objects.isNull(exchangeGold.getValue()) || exchangeGold.getValue() <= 0);
|
||||||
|
|
||||||
|
return exchangeGold.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -48,6 +48,7 @@ public class UserBankServiceImpl implements UserBankService {
|
|||||||
private final UserBankCheckWithdrawQryExe userBankCheckWithdrawQueryExe;
|
private final UserBankCheckWithdrawQryExe userBankCheckWithdrawQueryExe;
|
||||||
private final UserBankExchangeGoldTipQryExe userBankExchangeGoldTipQryExe;
|
private final UserBankExchangeGoldTipQryExe userBankExchangeGoldTipQryExe;
|
||||||
private final UserBankWithdrawTransferCmdExe userBankWithdrawTransferCmdExe;
|
private final UserBankWithdrawTransferCmdExe userBankWithdrawTransferCmdExe;
|
||||||
|
private final UserBankTransferGoldCmdExe userBankTransferGoldCmdExe;
|
||||||
private final UserBankDiamondWithdrawTransferCmdExe userBankDiamondWithdrawTransferCmdExe;
|
private final UserBankDiamondWithdrawTransferCmdExe userBankDiamondWithdrawTransferCmdExe;
|
||||||
private final UserBankSearchUserProfileQryExe userBankSearchUserProfileQryExe;
|
private final UserBankSearchUserProfileQryExe userBankSearchUserProfileQryExe;
|
||||||
private final UserBankCheckExchangeGoldQryExe userBankCheckExchangeGoldQryExe;
|
private final UserBankCheckExchangeGoldQryExe userBankCheckExchangeGoldQryExe;
|
||||||
@ -83,6 +84,11 @@ public class UserBankServiceImpl implements UserBankService {
|
|||||||
return userBankWithdrawTransferCmdExe.execute(cmd);
|
return userBankWithdrawTransferCmdExe.execute(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserBankWithdrawResultCO transferGold(UserBankWithdrawTransferCmd cmd) {
|
||||||
|
return userBankTransferGoldCmdExe.execute(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserBankWithdrawResultCO diamondTransfer(UserBankWithdrawTransferCmd cmd) {
|
public UserBankWithdrawResultCO diamondTransfer(UserBankWithdrawTransferCmd cmd) {
|
||||||
return userBankDiamondWithdrawTransferCmdExe.execute(cmd);
|
return userBankDiamondWithdrawTransferCmdExe.execute(cmd);
|
||||||
|
|||||||
@ -54,6 +54,11 @@ public interface UserBankService {
|
|||||||
*/
|
*/
|
||||||
UserBankWithdrawResultCO transfer(UserBankWithdrawTransferCmd cmd);
|
UserBankWithdrawResultCO transfer(UserBankWithdrawTransferCmd cmd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转账到金币.
|
||||||
|
*/
|
||||||
|
UserBankWithdrawResultCO transferGold(UserBankWithdrawTransferCmd cmd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 钻石转账.
|
* 钻石转账.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user