feat(quota): 添加真实余额变动功能并实现日用额度结算- 新增 BalanceRealChangesDTO 类用于真实余额变动
- 在 ITenantGameQuotaService 中添加 balanceRealChanges 方法 - 在 TenantGameQuotaServiceImpl 中实现 balanceRealChanges 方法 - 在 ITenantGameQuotaFlowService 中添加 getBalanceByTenantKey 方法 - 在 TenantGameQuotaFlowMapper 中添加 getBalanceByTenantKey 方法的 SQL - 在 TenantQuotaTask 中实现更新租户实际配额的逻辑- 在 OperationType 枚举中添加 REAL_BALANCE_SETTLEMENT 类型main-p
parent
7df30a21e1
commit
365da941c9
|
@ -0,0 +1,52 @@
|
|||
package com.ff.common.dto;
|
||||
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 余额更改为
|
||||
*
|
||||
* @author shi
|
||||
* @date 2025/02/12
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class BalanceRealChangesDTO implements Serializable {
|
||||
private static final long serialVersionUID = -4864053711644163092L;
|
||||
|
||||
/** 充值类型 false 扣除 true 充值 */
|
||||
private Boolean isOut;
|
||||
|
||||
|
||||
/** 租户key */
|
||||
private String tenantKey;
|
||||
|
||||
/** 游戏额度 */
|
||||
private BigDecimal balance;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
|
||||
|
||||
|
||||
/** 操作类型 OperationType枚举 */
|
||||
private Integer operationType;
|
||||
|
||||
/**
|
||||
* 汇率 传值计算
|
||||
*/
|
||||
private BigDecimal actualBalance;
|
||||
|
||||
/** 币种代码 */
|
||||
private String currencyCode;
|
||||
|
||||
}
|
|
@ -3,6 +3,7 @@ package com.ff.common.mapper;
|
|||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import com.ff.common.domain.TenantGameQuotaFlow;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* 租户游戏额度流水Mapper接口
|
||||
|
@ -68,4 +69,15 @@ public interface TenantGameQuotaFlowMapper
|
|||
* @return {@link BigDecimal }
|
||||
*/
|
||||
BigDecimal getExchangeMoneyByMemberId(TenantGameQuotaFlow tenantGameQuotaFlow);
|
||||
|
||||
|
||||
/**
|
||||
* 通过租户密钥获取余额
|
||||
*
|
||||
* @param tenantGameQuotaFlow 租户游戏配额流
|
||||
* @return {@link List }<{@link TenantGameQuotaFlow }>
|
||||
*/
|
||||
List<TenantGameQuotaFlow> getBalanceByTenantKey(TenantGameQuotaFlow tenantGameQuotaFlow);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -67,4 +67,13 @@ public interface ITenantGameQuotaFlowService
|
|||
* @return {@link BigDecimal }
|
||||
*/
|
||||
BigDecimal getExchangeMoneyByMemberId(TenantGameQuotaFlow tenantGameQuotaFlow);
|
||||
|
||||
|
||||
/**
|
||||
* 通过租户密钥获取余额
|
||||
*
|
||||
* @param tenantGameQuotaFlow 租户游戏配额流
|
||||
* @return {@link List }<{@link TenantGameQuotaFlow }>
|
||||
*/
|
||||
List<TenantGameQuotaFlow> getBalanceByTenantKey(TenantGameQuotaFlow tenantGameQuotaFlow);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.math.BigDecimal;
|
|||
import java.util.List;
|
||||
import com.ff.common.domain.TenantGameQuota;
|
||||
import com.ff.common.dto.BalanceChangesDTO;
|
||||
import com.ff.common.dto.BalanceRealChangesDTO;
|
||||
import com.ff.common.dto.GameBalanceExchange;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
|
@ -73,6 +74,15 @@ public interface ITenantGameQuotaService
|
|||
*/
|
||||
Boolean balanceChanges(BalanceChangesDTO balanceChangesDTO);
|
||||
|
||||
|
||||
/**
|
||||
* 真实余额变化
|
||||
*
|
||||
* @param balanceRealChangesDTO 余额更改为
|
||||
* @return {@link Boolean }
|
||||
*/
|
||||
Boolean balanceRealChanges(BalanceRealChangesDTO balanceRealChangesDTO);
|
||||
|
||||
/**
|
||||
* 游戏余额兑换
|
||||
*
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.ff.common.service.impl;
|
|||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import com.ff.base.utils.DateUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
@ -16,8 +17,7 @@ import com.ff.common.service.ITenantGameQuotaFlowService;
|
|||
* @date 2025-02-12
|
||||
*/
|
||||
@Service
|
||||
public class TenantGameQuotaFlowServiceImpl implements ITenantGameQuotaFlowService
|
||||
{
|
||||
public class TenantGameQuotaFlowServiceImpl implements ITenantGameQuotaFlowService {
|
||||
@Autowired
|
||||
private TenantGameQuotaFlowMapper tenantGameQuotaFlowMapper;
|
||||
|
||||
|
@ -28,8 +28,7 @@ public class TenantGameQuotaFlowServiceImpl implements ITenantGameQuotaFlowServi
|
|||
* @return 租户游戏额度流水
|
||||
*/
|
||||
@Override
|
||||
public TenantGameQuotaFlow selectTenantGameQuotaFlowById(Long id)
|
||||
{
|
||||
public TenantGameQuotaFlow selectTenantGameQuotaFlowById(Long id) {
|
||||
return tenantGameQuotaFlowMapper.selectTenantGameQuotaFlowById(id);
|
||||
}
|
||||
|
||||
|
@ -40,8 +39,7 @@ public class TenantGameQuotaFlowServiceImpl implements ITenantGameQuotaFlowServi
|
|||
* @return 租户游戏额度流水
|
||||
*/
|
||||
@Override
|
||||
public List<TenantGameQuotaFlow> selectTenantGameQuotaFlowList(TenantGameQuotaFlow tenantGameQuotaFlow)
|
||||
{
|
||||
public List<TenantGameQuotaFlow> selectTenantGameQuotaFlowList(TenantGameQuotaFlow tenantGameQuotaFlow) {
|
||||
return tenantGameQuotaFlowMapper.selectTenantGameQuotaFlowList(tenantGameQuotaFlow);
|
||||
}
|
||||
|
||||
|
@ -52,8 +50,7 @@ public class TenantGameQuotaFlowServiceImpl implements ITenantGameQuotaFlowServi
|
|||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int insertTenantGameQuotaFlow(TenantGameQuotaFlow tenantGameQuotaFlow)
|
||||
{
|
||||
public int insertTenantGameQuotaFlow(TenantGameQuotaFlow tenantGameQuotaFlow) {
|
||||
tenantGameQuotaFlow.setCreateTime(DateUtils.getNowDate());
|
||||
return tenantGameQuotaFlowMapper.insertTenantGameQuotaFlow(tenantGameQuotaFlow);
|
||||
}
|
||||
|
@ -65,8 +62,7 @@ public class TenantGameQuotaFlowServiceImpl implements ITenantGameQuotaFlowServi
|
|||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updateTenantGameQuotaFlow(TenantGameQuotaFlow tenantGameQuotaFlow)
|
||||
{
|
||||
public int updateTenantGameQuotaFlow(TenantGameQuotaFlow tenantGameQuotaFlow) {
|
||||
tenantGameQuotaFlow.setUpdateTime(DateUtils.getNowDate());
|
||||
return tenantGameQuotaFlowMapper.updateTenantGameQuotaFlow(tenantGameQuotaFlow);
|
||||
}
|
||||
|
@ -78,8 +74,7 @@ public class TenantGameQuotaFlowServiceImpl implements ITenantGameQuotaFlowServi
|
|||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteTenantGameQuotaFlowByIds(Long[] ids)
|
||||
{
|
||||
public int deleteTenantGameQuotaFlowByIds(Long[] ids) {
|
||||
return tenantGameQuotaFlowMapper.deleteTenantGameQuotaFlowByIds(ids);
|
||||
}
|
||||
|
||||
|
@ -90,8 +85,7 @@ public class TenantGameQuotaFlowServiceImpl implements ITenantGameQuotaFlowServi
|
|||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteTenantGameQuotaFlowById(Long id)
|
||||
{
|
||||
public int deleteTenantGameQuotaFlowById(Long id) {
|
||||
return tenantGameQuotaFlowMapper.deleteTenantGameQuotaFlowById(id);
|
||||
}
|
||||
|
||||
|
@ -105,4 +99,16 @@ public class TenantGameQuotaFlowServiceImpl implements ITenantGameQuotaFlowServi
|
|||
public BigDecimal getExchangeMoneyByMemberId(TenantGameQuotaFlow tenantGameQuotaFlow) {
|
||||
return tenantGameQuotaFlowMapper.getExchangeMoneyByMemberId(tenantGameQuotaFlow);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过租户密钥获取余额
|
||||
*
|
||||
* @param tenantGameQuotaFlow 租户游戏配额流
|
||||
* @return {@link List }<{@link TenantGameQuotaFlow }>
|
||||
*/
|
||||
@Override
|
||||
public List<TenantGameQuotaFlow> getBalanceByTenantKey(TenantGameQuotaFlow tenantGameQuotaFlow) {
|
||||
return tenantGameQuotaFlowMapper.getBalanceByTenantKey(tenantGameQuotaFlow);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import com.ff.common.domain.TenantGameQuotaFlow;
|
|||
import com.ff.common.domain.TenantQuotaExchange;
|
||||
import com.ff.common.domain.TenantSecretKey;
|
||||
import com.ff.common.dto.BalanceChangesDTO;
|
||||
import com.ff.common.dto.BalanceRealChangesDTO;
|
||||
import com.ff.common.dto.GameBalanceExchange;
|
||||
import com.ff.common.service.ITenantGameQuotaFlowService;
|
||||
import com.ff.common.service.ITenantQuotaExchangeService;
|
||||
|
@ -212,6 +213,60 @@ public class TenantGameQuotaServiceImpl implements ITenantGameQuotaService {
|
|||
return changedBalanceResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 真实余额变化
|
||||
*
|
||||
* @param balanceRealChangesDTO 余额更改为
|
||||
* @return {@link Boolean }
|
||||
*/
|
||||
@Override
|
||||
public Boolean balanceRealChanges(BalanceRealChangesDTO balanceRealChangesDTO) {
|
||||
TenantGameQuota tenantGameQuota = this.selectTenantGameQuotaByTenantKey(balanceRealChangesDTO.getTenantKey(),QuotaType.REAL_BALANCE.getCode());
|
||||
BigDecimal balanceBefore = tenantGameQuota.getBalance();
|
||||
BigDecimal balance = balanceRealChangesDTO.getBalance();
|
||||
//如果有汇率 则需要计算真实扣除额度
|
||||
if (!ObjectUtils.isEmpty(balanceRealChangesDTO.getActualBalance())) {
|
||||
balance = NumberUtil.div(balance, balanceRealChangesDTO.getActualBalance(), 2, RoundingMode.FLOOR);
|
||||
}
|
||||
|
||||
if (BigDecimal.ZERO.compareTo(balance) >= 0) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
BigDecimal balanceAfter;
|
||||
//判断是充值还是扣除
|
||||
if (balanceRealChangesDTO.getIsOut()) {
|
||||
balanceAfter = NumberUtil.add(balanceBefore, balance);
|
||||
} else {
|
||||
balanceAfter = NumberUtil.sub(balanceBefore, balance);
|
||||
}
|
||||
//修改余额
|
||||
Boolean changedBalanceResult = tenantGameQuotaMapper.changeBalance(TenantGameQuota.builder()
|
||||
.tenantKey(balanceRealChangesDTO.getTenantKey())
|
||||
.balance(balanceAfter)
|
||||
.quotaType(QuotaType.REAL_BALANCE.getCode())
|
||||
.version(tenantGameQuota.getVersion())
|
||||
.build());
|
||||
|
||||
//插入流水
|
||||
TenantGameQuotaFlow tenantGameQuotaFlow = TenantGameQuotaFlow.builder()
|
||||
.quotaType(QuotaType.REAL_BALANCE.getCode())
|
||||
.tenantKey(balanceRealChangesDTO.getTenantKey())
|
||||
.isOut(balanceRealChangesDTO.getIsOut())
|
||||
.currencyCode(balanceRealChangesDTO.getCurrencyCode())
|
||||
.balanceAfter(balanceAfter)
|
||||
.exchangeRatio(balanceRealChangesDTO.getActualBalance())
|
||||
.exchangeMoney(balanceRealChangesDTO.getBalance())
|
||||
.balance(balance)
|
||||
.balanceBefore(balanceBefore)
|
||||
.operationType(balanceRealChangesDTO.getOperationType())
|
||||
.build();
|
||||
tenantGameQuotaFlow.setRemark(balanceRealChangesDTO.getRemark());
|
||||
tenantGameQuotaFlow.setCreateTime(DateUtils.getNowDate());
|
||||
tenantGameQuotaFlow.setCreateBy(Constants.SYSTEM);
|
||||
tenantGameQuotaFlowService.insertTenantGameQuotaFlow(tenantGameQuotaFlow);
|
||||
return changedBalanceResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 游戏余额兑换
|
||||
*
|
||||
|
|
|
@ -1,13 +1,28 @@
|
|||
package com.ff.quartz.task;
|
||||
|
||||
|
||||
import com.ff.base.constant.Constants;
|
||||
import com.ff.base.enums.OperationType;
|
||||
import com.ff.base.enums.QuotaType;
|
||||
import com.ff.base.utils.DateUtils;
|
||||
import com.ff.common.domain.TenantGameQuota;
|
||||
import com.ff.common.domain.TenantGameQuotaFlow;
|
||||
import com.ff.common.domain.TenantQuotaExchange;
|
||||
import com.ff.common.domain.TenantSecretKey;
|
||||
import com.ff.common.dto.BalanceChangesDTO;
|
||||
import com.ff.common.dto.BalanceRealChangesDTO;
|
||||
import com.ff.common.service.ITenantGameQuotaFlowService;
|
||||
import com.ff.common.service.ITenantGameQuotaService;
|
||||
import com.ff.common.service.ITenantQuotaExchangeService;
|
||||
import com.ff.common.service.ITenantSecretKeyService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 租户配额任务
|
||||
|
@ -22,12 +37,54 @@ public class TenantQuotaTask {
|
|||
@Resource
|
||||
private ITenantGameQuotaService tenantGameQuotaService;
|
||||
|
||||
@Resource
|
||||
private ITenantGameQuotaFlowService tenantGameQuotaFlowService;
|
||||
|
||||
@Resource
|
||||
private ITenantSecretKeyService tenantSecretKeyService;
|
||||
|
||||
@Resource
|
||||
private ITenantQuotaExchangeService tenantQuotaExchangeService;
|
||||
|
||||
/**
|
||||
* 更新租户实际配额
|
||||
*/
|
||||
// public void updateTenantRealQuota() {
|
||||
// List<TenantGameQuota> tenantGameQuotas = tenantGameQuotaService.selectTenantGameQuotaList(TenantGameQuota.builder()
|
||||
// .quotaType(TenantGameQuota.TenantQuotaType.TENANT_REAL_QUOTA.getCode())
|
||||
// .build());
|
||||
// }
|
||||
public void updateTenantRealQuota() {
|
||||
Long yesterdayStart = DateUtils.getYesterdayStart();
|
||||
Long yesterdayEnd = DateUtils.getYesterdayEnd();
|
||||
TenantGameQuotaFlow gameQuotaFlow = TenantGameQuotaFlow.builder()
|
||||
.quotaType(QuotaType.BALANCE.getCode())
|
||||
.operationType(OperationType.API_BALANCE.getCode())
|
||||
.build();
|
||||
Map<String, Object> params = gameQuotaFlow.getParams();
|
||||
params.put("beginTime", yesterdayStart);
|
||||
params.put("endTime", yesterdayEnd);
|
||||
List<TenantGameQuotaFlow> balanceByTenantKey = tenantGameQuotaFlowService.getBalanceByTenantKey(gameQuotaFlow);
|
||||
for (TenantGameQuotaFlow tenantGameQuotaFlow : balanceByTenantKey) {
|
||||
BigDecimal balance = tenantGameQuotaFlow.getExchangeMoney();
|
||||
Boolean isOut = Boolean.TRUE;
|
||||
// 添加判断逻辑
|
||||
if (balance.compareTo(BigDecimal.ZERO) < 0) {
|
||||
balance = balance.abs();
|
||||
isOut = Boolean.FALSE;
|
||||
}
|
||||
TenantQuotaExchange tenantQuotaExchange = tenantQuotaExchangeService.getTenantQuotaExchange(Constants.USDT, tenantGameQuotaFlow.getCurrencyCode());
|
||||
//更新额度
|
||||
BalanceRealChangesDTO realChangesDTO = BalanceRealChangesDTO.builder()
|
||||
.isOut(isOut)
|
||||
.tenantKey(tenantGameQuotaFlow.getTenantKey())
|
||||
.balance(balance)
|
||||
.remark(OperationType.REAL_BALANCE_SETTLEMENT.getDescription())
|
||||
.operationType(OperationType.REAL_BALANCE_SETTLEMENT.getCode())
|
||||
.currencyCode(tenantGameQuotaFlow.getCurrencyCode())
|
||||
.actualBalance(tenantQuotaExchange.getActualBalance())
|
||||
.build();
|
||||
Boolean result = tenantGameQuotaService.balanceRealChanges(realChangesDTO);
|
||||
//如果没成功重新跑
|
||||
while (!result) {
|
||||
result = tenantGameQuotaService.balanceRealChanges(realChangesDTO);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -145,4 +145,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
group by member_id
|
||||
</select>
|
||||
|
||||
<select id="getBalanceByTenantKey" resultMap="TenantGameQuotaFlowResult">
|
||||
select tenant_key, sum(if(is_out,exchange_money,0))-sum(if(!is_out,exchange_money,0)) as exchange_money,currency_code
|
||||
from ff_tenant_game_quota_flow
|
||||
where create_time between #{params.beginTime} and #{params.endTime}
|
||||
and quota_type =#{quotaType} and operation_type = #{operationType}
|
||||
group by tenant_key,currency_code
|
||||
</select>
|
||||
|
||||
</mapper>
|
|
@ -10,7 +10,9 @@ import lombok.Getter;
|
|||
*/
|
||||
@Getter
|
||||
public enum OperationType {
|
||||
API_BALANCE(1, "租户游玩操作余额");
|
||||
API_BALANCE(1, "租户游玩操作余额"),
|
||||
REAL_BALANCE_SETTLEMENT(2, "日用额度结算")
|
||||
;
|
||||
|
||||
private final Integer code;
|
||||
private final String description;
|
||||
|
|
Loading…
Reference in New Issue