主播工资提现功能完善

This commit is contained in:
tianfeng 2026-03-16 11:53:31 +08:00
parent 58af7ca107
commit 814307282e
3 changed files with 111 additions and 25 deletions

View File

@ -25,6 +25,11 @@ public enum SalaryType {
*/
ADMIN_SALARY("ADMIN_SALARY", "ADMIN工资"),
/**
* 主播工资仅新增枚举
*/
HOST_SALARY("HOST_SALARY", "主播工资"),
;

View File

@ -50,10 +50,7 @@ import com.red.circle.wallet.inner.error.BankErrorCode;
import com.red.circle.wallet.inner.error.WalletErrorCode;
import com.red.circle.wallet.inner.model.cmd.*;
import com.red.circle.wallet.inner.model.dto.*;
import com.red.circle.wallet.inner.model.enums.GoldWithdrawAcceptAccount;
import com.red.circle.wallet.inner.model.enums.UserBankWaterEvent;
import com.red.circle.wallet.inner.model.enums.WithdrawMethod;
import com.red.circle.wallet.inner.model.enums.WithdrawMoneyApprovalProcessStatus;
import com.red.circle.wallet.inner.model.enums.*;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
@ -892,16 +889,17 @@ public class UserBankBalanceBackServiceImpl implements UserBankBalanceBackServic
}
}
private void saveUserBankBalance(ApprovalMoneyApplyCmd param,
UserBankWithdrawMoneyApplyDTO apply) {
UserBankWithdrawMoneyApplyDTO apply) {
// 非驳回则不做操作.
if (!Objects
.equals(param.getApprovalStatus(), WithdrawMoneyApprovalProcessStatus.NOT_PASS.name())) {
.equals(param.getApprovalStatus(), WithdrawMoneyApprovalProcessStatus.NOT_PASS.name())) {
return;
}
// 非主播工资进 salary account账户
if (SalaryType.HOST_SALARY != SalaryType.of(apply.getAmountType())) {
SalaryWithdrawInnerCmd withdrawInnerCmd = new SalaryWithdrawInnerCmd();
withdrawInnerCmd.setUserId(apply.getSubmitUserId());
withdrawInnerCmd.setOpUserId(param.getUpdateUser());
@ -910,6 +908,33 @@ public class UserBankBalanceBackServiceImpl implements UserBankBalanceBackServic
withdrawInnerCmd.setSalaryType(apply.getAmountType());
withdrawInnerCmd.setAmount(apply.getAmount());
userSalaryAccountClient.withdrawRefund(withdrawInnerCmd);
return;
}
ResponseAssert.requiredSuccess(userBankBalanceClient.incr(
new UserBankBalanceIncrCmd()
.setUserId(apply.getSubmitUserId())
.setSysOrigin(apply.getSysOrigin())
.setAmount(PennyAmount.ofDollar(apply.getAmount())))
);
bankRunningWaterClient.add(new UserBankRunningWaterDTO()
.setId(IdWorkerUtils.getId())
.setUserId(apply.getSubmitUserId())
.setSysOrigin(apply.getSysOrigin())
.setType(0)
.setTrackId(apply.getId().toString())
.setAmount(apply.getAmount())
.setEvent(UserBankWaterEvent.WITHDRAW.name())
.setEventDescribe(UserBankWaterEvent.WITHDRAW.getDescribe())
.setRemark(param.getRemark())
.setBalance(
ResponseAssert.requiredSuccess(
userBankBalanceClient.getBalance(apply.getSubmitUserId())).getAccurateBalance())
.setCreateTime(TimestampUtils.now())
.setCreateUser(param.getUpdateUser())
.setCreateUserOrigin(1)
);
userBankCardClient.removeMonthWithdrawal(apply.getSubmitUserId());
}

View File

@ -21,6 +21,10 @@ 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.UserBankWithdrawCmd;
import com.red.circle.wallet.domain.gateway.SalaryAccountGateway;
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.inner.model.dto.BankBalanceDTO;
import com.red.circle.wallet.inner.model.enums.SalaryEvent;
import com.red.circle.wallet.domain.salary.SalaryReceipt;
import com.red.circle.wallet.domain.salary.SalaryReceiptRes;
@ -34,6 +38,7 @@ import com.red.circle.wallet.infra.database.mongo.service.bank.UserBankCardServi
import com.red.circle.wallet.infra.database.mongo.service.bank.UserBankWithdrawMoneyApplyService;
import com.red.circle.wallet.inner.error.BankErrorCode;
import com.red.circle.wallet.inner.error.WalletErrorCode;
import com.red.circle.wallet.inner.model.enums.UserBankWaterEvent;
import com.red.circle.wallet.inner.model.enums.WithdrawMethod;
import java.math.BigDecimal;
import java.math.RoundingMode;
@ -58,6 +63,8 @@ public class UserBankWithdrawCmdExe {
private final RegionAssistConfigClient regionAssistConfigClient;
private final UserBankWithdrawMoneyApplyService userBankWithdrawMoneyApplyService;
private final SalaryAccountGateway salaryAccountGateway;
private final UserBankBalanceService userBankBalanceService;
private final UserBankRunningWaterService userBankRunningWaterService;
public UserBankWithdrawResultCO execute(UserBankWithdrawCmd cmd) {
ResponseAssert.isTrue(ResponseErrorCode.REQUEST_PARAMETER_ERROR, ArithmeticUtils.gtZero(cmd.getAmount()));
@ -68,10 +75,9 @@ public class UserBankWithdrawCmdExe {
SalaryType salaryType = SalaryType.of(cmd.getSalaryType());
PennyAmount availableBalance = salaryAccountGateway.getAvailableBalance(cmd.getReqUserId(), salaryType);
BigDecimal balance = availableBalance.getDollarAmount();
BigDecimal balance = getUserBalance(cmd, salaryType);
// 3. 校验提现金额
// 3. 校验提现金额
ResponseAssert.isTrue(WalletErrorCode.INSUFFICIENT_BALANCE, ArithmeticUtils.gte(balance, cmd.getAmount()));
UserBankCard bankCard = userBankCardService.getById(cmd.getAcceptBankCardId());
@ -80,25 +86,36 @@ public class UserBankWithdrawCmdExe {
Long applyId = IdWorkerUtils.getId();
// 扣钱
SalaryReceipt receipt = new SalaryReceipt()
.setReceiptType(ReceiptType.EXPENDITURE)
.setUserId(cmd.getReqUserId())
.setAcceptUserId(cmd.getReqUserId())
.setSysOrigin(cmd.getReqSysOrigin().getOrigin())
.setSalaryType(salaryType)
.setSalaryEvent(SalaryEvent.WITHDRAW)
.setAmount(PennyAmount.ofDollar(cmd.getAmount()))
.setTrackId(String.valueOf(applyId))
.setEventDesc("提现")
.setOpUserType(OpUserType.APP)
.setOpUserId(cmd.getReqUserId());
SalaryReceiptRes salaryReceiptRes = salaryAccountGateway.changeBalance(receipt);
ResponseAssert.notNull(WalletErrorCode.INSUFFICIENT_BALANCE, salaryReceiptRes);
BigDecimal afterBalance = changeBalance(cmd, salaryType, applyId);
// 手续费
Long serviceCharge = getAssistDiamondConfig(cmd.requiredReqUserId());
BigDecimal actualAmount = getActualAmount(cmd.getAmount(), serviceCharge);
if (SalaryType.HOST_SALARY == salaryType) {
// 银行卡流水
userBankRunningWaterService.add(
new UserBankRunningWater()
.setId(IdWorkerUtils.getId())
.setUserId(cmd.requiredReqUserId())
.setSysOrigin(cmd.requireReqSysOrigin())
.setType(ReceiptType.EXPENDITURE.getType())
.setAmount(cmd.getAmount())
.setServiceCharge(serviceCharge)
.setActualAmount(actualAmount)
.setEvent(UserBankWaterEvent.WITHDRAW.name())
.setEventDescribe(UserBankWaterEvent.WITHDRAW.getDescribe())
.setRemark("Cash withdrawal")
.setTrackId(applyId.toString())
.setBalance(afterBalance)
.setCreateTime(TimestampUtils.now())
.setUpdateTime(TimestampUtils.now())
.setCreateUser(cmd.requiredReqUserId())
.setCreateUserOrigin(OpUserType.APP.getType())
);
}
// 申请详情
userBankWithdrawMoneyApplyService.add(
new UserBankWithdrawMoneyApply()
@ -130,10 +147,49 @@ public class UserBankWithdrawCmdExe {
walletBankCacheService.setMonthWithdrawal(cmd.requiredReqUserId());
redisService.unlock(key);
return new UserBankWithdrawResultCO()
.setBankBalance(salaryReceiptRes.getAvailableBalance().getDollarAmount())
.setBankBalance(afterBalance)
.setWithdrawAmount(Objects.toString(cmd.getAmount()));
}
private BigDecimal changeBalance(UserBankWithdrawCmd cmd, SalaryType salaryType, Long applyId) {
// 余额
BigDecimal balance;
if (SalaryType.HOST_SALARY == salaryType) {
BankBalanceDTO decrUserBankBalanceDTO = userBankBalanceService.decr(cmd.requiredReqUserId(), PennyAmount.ofDollar(cmd.getAmount()));
ResponseAssert.notNull(WalletErrorCode.INSUFFICIENT_BALANCE, decrUserBankBalanceDTO);
balance = decrUserBankBalanceDTO.getAccurateBalance();
} else {
SalaryReceipt receipt = new SalaryReceipt()
.setReceiptType(ReceiptType.EXPENDITURE)
.setUserId(cmd.getReqUserId())
.setAcceptUserId(cmd.getReqUserId())
.setSysOrigin(cmd.getReqSysOrigin().getOrigin())
.setSalaryType(salaryType)
.setSalaryEvent(SalaryEvent.WITHDRAW)
.setAmount(PennyAmount.ofDollar(cmd.getAmount()))
.setTrackId(String.valueOf(applyId))
.setEventDesc("提现")
.setOpUserType(OpUserType.APP)
.setOpUserId(cmd.getReqUserId());
SalaryReceiptRes salaryReceiptRes = salaryAccountGateway.changeBalance(receipt);
ResponseAssert.notNull(WalletErrorCode.INSUFFICIENT_BALANCE, salaryReceiptRes);
balance = salaryReceiptRes.getAvailableBalance().getDollarAmount();
}
return balance;
}
private BigDecimal getUserBalance(UserBankWithdrawCmd cmd, SalaryType salaryType) {
BigDecimal balance;
if (SalaryType.HOST_SALARY == salaryType) {
balance = userBankBalanceService.getBalance(cmd.requiredReqUserId()).getAccurateBalance();
} else {
balance = salaryAccountGateway.getAvailableBalance(cmd.getReqUserId(), salaryType).getDollarAmount();
}
return balance;
}
private BigDecimal getActualAmount(BigDecimal amount, Long serviceCharge) {
BigDecimal charge = new BigDecimal(serviceCharge).divide(new BigDecimal(100));
BigDecimal serviceChargeAmount = amount.multiply(charge).setScale(0, RoundingMode.CEILING);