feat(api): 重构游戏余额兑换逻辑

- 新增 GameBalanceExchange DTO 用于封装游戏余额兑换参数
- 在 ITenantGameQuotaService 中添加 gameBalanceExchange 方法处理兑换逻辑
- 优化了额度类型的处理,使用新的 QuotaType 枚举
- 调整了 TenantGameQuota 和 Tenant
main-p
shi 2025-02-21 14:39:21 +08:00
parent 0c9a1ac2b1
commit 9ee0e34d16
21 changed files with 589 additions and 187 deletions

View File

@ -59,7 +59,6 @@ public class HeaderCheckAspect {
TenantSecretKey tenantSecretKey = tenantSecretKeyService.selectTenantSecretKeyByTenantKey(key); TenantSecretKey tenantSecretKey = tenantSecretKeyService.selectTenantSecretKeyByTenantKey(key);
Assert.isTrue(!tenantSecretKey.getAgentType(), "当前用户不是租户");
Assert.notNull(tenantSecretKey, "key不存在"); Assert.notNull(tenantSecretKey, "key不存在");
Assert.isTrue(tenantSecretKey.getTenantStatus(), "当前租户已停用"); Assert.isTrue(tenantSecretKey.getTenantStatus(), "当前租户已停用");

View File

@ -5,7 +5,7 @@ import com.ff.annotation.CheckHeader;
import com.ff.api.response.TenantInfoResponse; import com.ff.api.response.TenantInfoResponse;
import com.ff.base.core.controller.BaseController; import com.ff.base.core.controller.BaseController;
import com.ff.base.core.domain.AjaxResult; import com.ff.base.core.domain.AjaxResult;
import com.ff.base.enums.TenantQuotaType; import com.ff.base.enums.QuotaType;
import com.ff.base.utils.bean.BeanUtils; import com.ff.base.utils.bean.BeanUtils;
import com.ff.common.domain.TenantGameQuota; import com.ff.common.domain.TenantGameQuota;
import com.ff.common.domain.TenantSecretKey; import com.ff.common.domain.TenantSecretKey;
@ -44,7 +44,7 @@ public class ApiAgentController extends BaseController {
@PostMapping("/create/tenant") @PostMapping("/create/tenant")
public AjaxResult info() { public AjaxResult info() {
TenantSecretKey tenantSecretKey = keyConfig.get(); TenantSecretKey tenantSecretKey = keyConfig.get();
TenantGameQuota tenantGameQuota = tenantGameQuotaService.selectTenantGameQuotaByTenantKey(tenantSecretKey.getTenantKey(), TenantQuotaType.BALANCE.getCode()); TenantGameQuota tenantGameQuota = tenantGameQuotaService.selectTenantGameQuotaByTenantKey(tenantSecretKey.getTenantKey(), QuotaType.BALANCE.getCode());
TenantInfoResponse tenantInfoResponse= new TenantInfoResponse(); TenantInfoResponse tenantInfoResponse= new TenantInfoResponse();
BeanUtils.copyProperties(tenantGameQuota,tenantInfoResponse); BeanUtils.copyProperties(tenantGameQuota,tenantInfoResponse);
return AjaxResult.success(tenantInfoResponse); return AjaxResult.success(tenantInfoResponse);

View File

@ -1,9 +1,7 @@
package com.ff.api.controller; package com.ff.api.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.NumberUtil;
import com.dtflys.forest.annotation.Post;
import com.ff.annotation.CheckHeader; import com.ff.annotation.CheckHeader;
import com.ff.api.request.*; import com.ff.api.request.*;
import com.ff.api.response.*; import com.ff.api.response.*;
@ -11,16 +9,16 @@ import com.ff.base.constant.Constants;
import com.ff.base.core.controller.BaseController; import com.ff.base.core.controller.BaseController;
import com.ff.base.core.domain.AjaxResult; import com.ff.base.core.domain.AjaxResult;
import com.ff.base.core.page.TableDataInfo; import com.ff.base.core.page.TableDataInfo;
import com.ff.base.enums.ErrorCode; import com.ff.base.enums.*;
import com.ff.base.enums.OperationType;
import com.ff.base.enums.TransferType;
import com.ff.base.exception.base.ApiException; import com.ff.base.exception.base.ApiException;
import com.ff.base.exception.base.BaseException; import com.ff.base.exception.base.BaseException;
import com.ff.base.utils.QuotaUtils;
import com.ff.base.utils.StringUtils; import com.ff.base.utils.StringUtils;
import com.ff.base.utils.bean.BeanUtils; import com.ff.base.utils.bean.BeanUtils;
import com.ff.common.domain.TenantGameQuotaFlow; import com.ff.common.domain.TenantGameQuotaFlow;
import com.ff.common.domain.TenantSecretKey; import com.ff.common.domain.TenantSecretKey;
import com.ff.common.dto.BalanceChangesDTO; import com.ff.common.dto.BalanceChangesDTO;
import com.ff.common.dto.GameBalanceExchange;
import com.ff.common.service.ITenantGameQuotaFlowService; import com.ff.common.service.ITenantGameQuotaFlowService;
import com.ff.common.service.ITenantGameQuotaService; import com.ff.common.service.ITenantGameQuotaService;
import com.ff.config.KeyConfig; import com.ff.config.KeyConfig;
@ -47,9 +45,7 @@ import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -183,63 +179,33 @@ public class ApiGameController extends BaseController {
IGamesService iGamesService = gamesService.get(gameExchangeBalanceRequest.getPlatformCode() + Constants.SERVICE); IGamesService iGamesService = gamesService.get(gameExchangeBalanceRequest.getPlatformCode() + Constants.SERVICE);
ApiException.notNull(iGamesService, ErrorCode.PLATFORM_NOT_EXIST.getCode());
TenantSecretKey tenantSecretKey = keyConfig.get(); TenantSecretKey tenantSecretKey = keyConfig.get();
GameSecretKey gameSecretKey = gameSecretKeyService.findSecretKeyByPlatformAndSystemCode(gameExchangeBalanceRequest.getPlatformCode(), gameExchangeBalanceRequest.getCurrencyCode()); GameSecretKey gameSecretKey = gameSecretKeyService.findSecretKeyByPlatformAndSystemCode(gameExchangeBalanceRequest.getPlatformCode(), gameExchangeBalanceRequest.getCurrencyCode());
ApiException.notNull(gameSecretKey, ErrorCode.CURRENCY_NOT_EXIST.getCode()); ApiException.notNull(gameSecretKey, ErrorCode.CURRENCY_NOT_EXIST.getCode());
BigDecimal quota = tenantGameQuotaService.gameBalanceExchange(GameBalanceExchange.builder()
.platformCode(gameExchangeBalanceRequest.getPlatformCode())
.currencyCode(gameExchangeBalanceRequest.getCurrencyCode())
.transferType(gameExchangeBalanceRequest.getTransferType())
.amount(gameExchangeBalanceRequest.getAmount())
.account(gameExchangeBalanceRequest.getAccount())
.tenantKey(tenantSecretKey.getTenantKey())
.build());
// 获取用户信息
Member member = memberService.selectMemberByGameAccount(StringUtils.addSuffix(gameExchangeBalanceRequest.getAccount(), gameExchangeBalanceRequest.getCurrencyCode() + tenantSecretKey.getTenantSn())); Member member = memberService.selectMemberByGameAccount(StringUtils.addSuffix(gameExchangeBalanceRequest.getAccount(), gameExchangeBalanceRequest.getCurrencyCode() + tenantSecretKey.getTenantSn()));
ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode());
//操作租户额度
boolean isOut = gameExchangeBalanceRequest.getTransferType() == 1;
BigDecimal balanceRequestAmount = gameExchangeBalanceRequest.getAmount();
//如果是增加不可以超过对应的额度
if (isOut) {
//获取第三方钱包余额
MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder()
.accounts(member.getGameAccount())
.agentId(gameSecretKey.getCode())
.agentKey(gameSecretKey.getKey())
.build();
balanceRequestAmount = iGamesService.getMemberInfo(gamesBaseRequestDTO).getBalance();
//转入金额
BigDecimal balanceInto = tenantGameQuotaFlowService.getBalanceByMemberId(TenantGameQuotaFlow.builder()
.isOut(Boolean.TRUE)
.tenantKey(tenantSecretKey.getTenantKey())
.memberId(member.getId())
.build());
//转出金额
BigDecimal balanceOut = tenantGameQuotaFlowService.getBalanceByMemberId(TenantGameQuotaFlow.builder()
.isOut(Boolean.FALSE)
.tenantKey(tenantSecretKey.getTenantKey())
.memberId(member.getId())
.build());
//如果转入金额+本次转入金额 大于转出额度则取差值
if (NumberUtil.add(balanceInto, balanceRequestAmount).compareTo(balanceOut) > 0) {
balanceRequestAmount = NumberUtil.sub(balanceOut, balanceInto);
}
}
//租户余额操作
tenantGameQuotaService.balanceChanges(BalanceChangesDTO.builder()
.isOut(isOut)
.tenantKey(tenantSecretKey.getTenantKey())
.balance(balanceRequestAmount)
.memberId(member.getId())
.operationType(OperationType.API_BALANCE.getCode())
.remark(OperationType.API_BALANCE.getDescription())
.build());
//操作第三方额度接口
ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO = ExchangeTransferMoneyRequestDTO.builder() ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO = ExchangeTransferMoneyRequestDTO.builder()
.agentId(gameSecretKey.getCode()) .agentId(gameSecretKey.getCode())
.agentKey(gameSecretKey.getKey()) .agentKey(gameSecretKey.getKey())
.account(member.getGameAccount()) .account(member.getGameAccount())
.tenantKey(tenantSecretKey.getTenantKey()) .tenantKey(tenantSecretKey.getTenantKey())
.quota(balanceRequestAmount) .quota(quota)
.amount(gameExchangeBalanceRequest.getAmount()) .amount(gameExchangeBalanceRequest.getAmount())
.transferType(gameExchangeBalanceRequest.getTransferType()) .transferType(gameExchangeBalanceRequest.getTransferType())
.build(); .build();
@ -311,9 +277,9 @@ public class ApiGameController extends BaseController {
params.put("endTime", gameCreateFreeSpinRequest.getEndTime()); params.put("endTime", gameCreateFreeSpinRequest.getEndTime());
List<GameBettingDetails> bettingDetails = gameBettingDetailsService.selectGameBettingDetailsList(gameBettingDetails); List<GameBettingDetails> bettingDetails = gameBettingDetailsService.selectGameBettingDetailsList(gameBettingDetails);
TableDataInfo dataTable = getDataTable(bettingDetails); TableDataInfo dataTable = getDataTable(bettingDetails);
List<GameBettingDetailsResponse> result=new ArrayList<>(); List<GameBettingDetailsResponse> result = new ArrayList<>();
for (GameBettingDetails row : (List<GameBettingDetails>) dataTable.getRows()) { for (GameBettingDetails row : (List<GameBettingDetails>) dataTable.getRows()) {
GameBettingDetailsResponse gameBettingDetailsResponse=new GameBettingDetailsResponse(); GameBettingDetailsResponse gameBettingDetailsResponse = new GameBettingDetailsResponse();
BeanUtils.copyProperties(row, gameBettingDetailsResponse); BeanUtils.copyProperties(row, gameBettingDetailsResponse);
Member member = memberService.selectMemberById(row.getMemberId()); Member member = memberService.selectMemberById(row.getMemberId());
gameBettingDetailsResponse.setAccount(member.getMemberAccount()); gameBettingDetailsResponse.setAccount(member.getMemberAccount());
@ -335,7 +301,6 @@ public class ApiGameController extends BaseController {
public AjaxResult getDetail(@Validated @RequestBody GameGetDetailRequest gameGetDetailRequest) { public AjaxResult getDetail(@Validated @RequestBody GameGetDetailRequest gameGetDetailRequest) {
GameSecretKey gameSecretKey = gameSecretKeyService.findSecretKeyByPlatformAndSystemCode(gameGetDetailRequest.getPlatformCode(), gameGetDetailRequest.getCurrencyCode()); GameSecretKey gameSecretKey = gameSecretKeyService.findSecretKeyByPlatformAndSystemCode(gameGetDetailRequest.getPlatformCode(), gameGetDetailRequest.getCurrencyCode());
ApiException.notNull(gameSecretKey, ErrorCode.CURRENCY_NOT_EXIST.getCode()); ApiException.notNull(gameSecretKey, ErrorCode.CURRENCY_NOT_EXIST.getCode());
@ -425,9 +390,9 @@ public class ApiGameController extends BaseController {
params.put("endTime", gameGetFreeSpinDashflowRequest.getEndTime()); params.put("endTime", gameGetFreeSpinDashflowRequest.getEndTime());
List<GameFreeRecord> gameFreeRecords = gameFreeRecordService.selectGameFreeRecordList(gameFreeRecord); List<GameFreeRecord> gameFreeRecords = gameFreeRecordService.selectGameFreeRecordList(gameFreeRecord);
TableDataInfo dataTable = getDataTable(gameFreeRecords); TableDataInfo dataTable = getDataTable(gameFreeRecords);
List<GameFreeRecordResponse> result=new ArrayList<>(); List<GameFreeRecordResponse> result = new ArrayList<>();
for (GameFreeRecord row : (List<GameFreeRecord>) dataTable.getRows()) { for (GameFreeRecord row : (List<GameFreeRecord>) dataTable.getRows()) {
GameFreeRecordResponse gameFreeRecordResponse=new GameFreeRecordResponse(); GameFreeRecordResponse gameFreeRecordResponse = new GameFreeRecordResponse();
BeanUtils.copyProperties(row, gameFreeRecordResponse); BeanUtils.copyProperties(row, gameFreeRecordResponse);
Member member = memberService.selectMemberById(row.getMemberId()); Member member = memberService.selectMemberById(row.getMemberId());
gameFreeRecordResponse.setMemberAccount(member.getMemberAccount()); gameFreeRecordResponse.setMemberAccount(member.getMemberAccount());
@ -525,34 +490,15 @@ public class ApiGameController extends BaseController {
balanceMap.put(gameExchangeMoney.getPlatformCode(), gameExchangeMoney.getBalance()); balanceMap.put(gameExchangeMoney.getPlatformCode(), gameExchangeMoney.getBalance());
BigDecimal balance = gameExchangeMoney.getBalance(); BigDecimal balance = gameExchangeMoney.getBalance();
balanceAll = NumberUtil.add(balanceAll, balance); balanceAll = NumberUtil.add(balanceAll, balance);
//转入金额
BigDecimal balanceInto = tenantGameQuotaFlowService.getBalanceByMemberId(TenantGameQuotaFlow.builder()
.isOut(Boolean.TRUE)
.tenantKey(tenantSecretKey.getTenantKey())
.memberId(member.getId())
.build());
//转出金额
BigDecimal balanceOut = tenantGameQuotaFlowService.getBalanceByMemberId(TenantGameQuotaFlow.builder()
.isOut(Boolean.FALSE)
.tenantKey(tenantSecretKey.getTenantKey())
.memberId(member.getId())
.build());
//如果转入金额+本次转入金额 大于转出额度则取差值
if (NumberUtil.add(balanceInto, balance).compareTo(NumberUtil.add(balanceOut, BigDecimal.ZERO)) > 0) {
balance = NumberUtil.sub(balanceOut, balanceInto);
}
//更新租户额度
gameExchangeMoney.setQuota(balance);
gameExchangeMoneyService.updateGameExchangeMoney(gameExchangeMoney);
//余额扣除 //操作租户额度
tenantGameQuotaService.balanceChanges(BalanceChangesDTO.builder() tenantGameQuotaService.gameBalanceExchange(GameBalanceExchange.builder()
.isOut(Boolean.TRUE) .platformCode(gameExchangeMoney.getPlatformCode())
.currencyCode(gameExchangeMoney.getCurrencyCode())
.transferType(TransferType.ALL.getCode())
.amount(gameExchangeMoney.getBalance())
.account(member.getMemberAccount())
.tenantKey(tenantSecretKey.getTenantKey()) .tenantKey(tenantSecretKey.getTenantKey())
.balance(balance)
.memberId(member.getId())
.operationType(OperationType.API_BALANCE.getCode())
.remark(OperationType.API_BALANCE.getDescription())
.build()); .build());
} }

View File

@ -1,56 +1,22 @@
package com.ff.api.controller; package com.ff.api.controller;
import cn.hutool.core.util.NumberUtil;
import com.ff.annotation.CheckHeader; import com.ff.annotation.CheckHeader;
import com.ff.api.request.*;
import com.ff.api.response.GameExchangeBalanceResponse;
import com.ff.api.response.TenantInfoResponse; import com.ff.api.response.TenantInfoResponse;
import com.ff.base.constant.Constants;
import com.ff.base.core.controller.BaseController; import com.ff.base.core.controller.BaseController;
import com.ff.base.core.domain.AjaxResult; import com.ff.base.core.domain.AjaxResult;
import com.ff.base.core.page.TableDataInfo; import com.ff.base.enums.QuotaType;
import com.ff.base.enums.OperationType;
import com.ff.base.enums.TenantQuotaType;
import com.ff.base.enums.TransferType;
import com.ff.base.exception.base.BaseException;
import com.ff.base.utils.StringUtils;
import com.ff.base.utils.bean.BeanUtils; import com.ff.base.utils.bean.BeanUtils;
import com.ff.common.domain.TenantGameQuota; import com.ff.common.domain.TenantGameQuota;
import com.ff.common.domain.TenantGameQuotaFlow;
import com.ff.common.domain.TenantSecretKey; import com.ff.common.domain.TenantSecretKey;
import com.ff.common.dto.BalanceChangesDTO;
import com.ff.common.service.ITenantGameQuotaFlowService;
import com.ff.common.service.ITenantGameQuotaService; import com.ff.common.service.ITenantGameQuotaService;
import com.ff.config.KeyConfig; import com.ff.config.KeyConfig;
import com.ff.game.api.IGamesService;
import com.ff.game.api.request.*;
import com.ff.game.domain.*;
import com.ff.game.service.*;
import com.ff.member.domain.Member;
import com.ff.member.service.IMemberService;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
/** /**
* api * api
@ -78,7 +44,7 @@ public class ApiTenantController extends BaseController {
@PostMapping("/info") @PostMapping("/info")
public AjaxResult info() { public AjaxResult info() {
TenantSecretKey tenantSecretKey = keyConfig.get(); TenantSecretKey tenantSecretKey = keyConfig.get();
TenantGameQuota tenantGameQuota = tenantGameQuotaService.selectTenantGameQuotaByTenantKey(tenantSecretKey.getTenantKey(), TenantQuotaType.BALANCE.getCode()); TenantGameQuota tenantGameQuota = tenantGameQuotaService.selectTenantGameQuotaByTenantKey(tenantSecretKey.getTenantKey(), QuotaType.BALANCE.getCode());
TenantInfoResponse tenantInfoResponse= new TenantInfoResponse(); TenantInfoResponse tenantInfoResponse= new TenantInfoResponse();
BeanUtils.copyProperties(tenantGameQuota,tenantInfoResponse); BeanUtils.copyProperties(tenantGameQuota,tenantInfoResponse);
return AjaxResult.success(tenantInfoResponse); return AjaxResult.success(tenantInfoResponse);

View File

@ -0,0 +1,40 @@
package com.ff.common.domain;
import com.ff.base.annotation.Excel;
import com.ff.base.core.domain.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* ff_tenant_agent
*
* @author shi
* @date 2025-02-20
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class TenantAgent extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键id */
private Long id;
/** 账号 */
@Excel(name = "账号")
private String account;
/** 密码 */
@Excel(name = "密码")
private String password;
/** 代理状态 1正常 0停用 */
@Excel(name = "代理状态 1正常 0停用")
private Boolean agentStatus;
}

View File

@ -12,7 +12,7 @@ import lombok.NoArgsConstructor;
* ff_tenant_game_quota * ff_tenant_game_quota
* *
* @author shi * @author shi
* @date 2025-02-14 * @date 2025-02-20
*/ */
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@ -33,9 +33,9 @@ public class TenantGameQuota extends BaseEntity
@Excel(name = "游戏额度") @Excel(name = "游戏额度")
private BigDecimal balance; private BigDecimal balance;
/** 额度类型 TenantQuotaType 枚举 */ /** 额度类型 TenantQuotaType 枚举或者平台_币种或者平台_币种_FALSE 假额度 */
@Excel(name = "额度类型 TenantQuotaType 枚举") @Excel(name = "额度类型 TenantQuotaType 枚举或者平台_币种或者平台_币种_FALSE 假额度")
private Integer quotaType; private String quotaType;
/** 版本号 */ /** 版本号 */
@Excel(name = "版本号") @Excel(name = "版本号")

View File

@ -12,7 +12,7 @@ import lombok.NoArgsConstructor;
* ff_tenant_game_quota_flow * ff_tenant_game_quota_flow
* *
* @author shi * @author shi
* @date 2025-02-12 * @date 2025-02-20
*/ */
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@ -29,6 +29,10 @@ public class TenantGameQuotaFlow extends BaseEntity
@Excel(name = "租户key") @Excel(name = "租户key")
private String tenantKey; private String tenantKey;
/** 额度类型 */
@Excel(name = "额度类型")
private String quotaType;
/** 用户账号id */ /** 用户账号id */
@Excel(name = "用户账号id") @Excel(name = "用户账号id")
private Long memberId; private Long memberId;

View File

@ -1,5 +1,6 @@
package com.ff.common.domain; package com.ff.common.domain;
import java.math.BigDecimal;
import com.ff.base.annotation.Excel; import com.ff.base.annotation.Excel;
import com.ff.base.core.domain.BaseEntity; import com.ff.base.core.domain.BaseEntity;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@ -11,7 +12,7 @@ import lombok.NoArgsConstructor;
* ff_tenant_secret_key * ff_tenant_secret_key
* *
* @author shi * @author shi
* @date 2025-02-14 * @date 2025-02-20
*/ */
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@ -24,20 +25,22 @@ public class TenantSecretKey extends BaseEntity
/** 主键id */ /** 主键id */
private Long id; private Long id;
/** /** 账号 */
* false @Excel(name = "账号")
*/ private String account;
private Boolean agentType;
/** /** 密码 */
* id @Excel(name = "密码")
*/ private String password;
private Long agentId;
/** 租户key */ /** 租户key */
@Excel(name = "租户key") @Excel(name = "租户key")
private String tenantKey; private String tenantKey;
/** 代理id */
@Excel(name = "代理id")
private Long agentId;
/** 商户后缀 */ /** 商户后缀 */
@Excel(name = "商户后缀") @Excel(name = "商户后缀")
private String tenantSn; private String tenantSn;
@ -47,11 +50,24 @@ public class TenantSecretKey extends BaseEntity
private String tenantSecret; private String tenantSecret;
/** 租户状态 1正常 0停用 */ /** 租户状态 1正常 0停用 */
@Excel(name = "租户状态 1正常 0停用")
private Boolean tenantStatus; private Boolean tenantStatus;
/** 额度类型 TenantQuotaType 枚举 */
@Excel(name = "额度类型 TenantQuotaType 枚举")
private Integer quotaType;
/** 买分比例 */
@Excel(name = "买分比例")
private BigDecimal scoreRatio;
/** 租户类型 TenantType 枚举 */ /** 租户类型 TenantType 枚举 */
@Excel(name = "租户类型 TenantType 枚举") @Excel(name = "租户类型 TenantType 枚举")
private Integer tenantType; private Integer tenantType;
/** 透支比例 */
@Excel(name = "透支比例")
private BigDecimal depositRatio;
} }

View File

@ -26,6 +26,10 @@ public class BalanceChangesDTO implements Serializable {
/** 充值类型 false 扣除 true 充值 */ /** 充值类型 false 扣除 true 充值 */
private Boolean isOut; private Boolean isOut;
/**
*
*/
private String quotaType;
/** 租户key */ /** 租户key */
private String tenantKey; private String tenantKey;

View File

@ -0,0 +1,57 @@
package com.ff.common.dto;
import io.swagger.models.auth.In;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
import java.math.BigDecimal;
/**
*
*
* @author shi
* @date 2025/02/21
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class GameBalanceExchange implements Serializable {
private final static long serialVersionUID = 3452954102791311247L;
/**
*
*/
private String platformCode;
/**
*
*/
private String currencyCode;
/**
* TransferType
*/
private Integer transferType;
/**
*
*/
private BigDecimal amount;
/**
*
*/
private String account;
/** 租户key */
private String tenantKey;
}

View File

@ -27,7 +27,7 @@ public interface TenantGameQuotaMapper {
* @param tenantKey * @param tenantKey
* @return * @return
*/ */
TenantGameQuota selectTenantGameQuotaByTenantKey(@Param("tenantKey") String tenantKey,@Param("quotaType") Integer quotaType); TenantGameQuota selectTenantGameQuotaByTenantKey(@Param("tenantKey") String tenantKey,@Param("quotaType") String quotaType);
/** /**
* *

View File

@ -1,8 +1,10 @@
package com.ff.common.service; package com.ff.common.service;
import java.math.BigDecimal;
import java.util.List; import java.util.List;
import com.ff.common.domain.TenantGameQuota; import com.ff.common.domain.TenantGameQuota;
import com.ff.common.dto.BalanceChangesDTO; import com.ff.common.dto.BalanceChangesDTO;
import com.ff.common.dto.GameBalanceExchange;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
/** /**
@ -69,6 +71,13 @@ public interface ITenantGameQuotaService
*/ */
Boolean balanceChanges(BalanceChangesDTO balanceChangesDTO); Boolean balanceChanges(BalanceChangesDTO balanceChangesDTO);
/**
*
*
* @param gameBalanceExchange
* @return {@link BigDecimal }
*/
BigDecimal gameBalanceExchange(GameBalanceExchange gameBalanceExchange);
/** /**
* *
@ -76,5 +85,5 @@ public interface ITenantGameQuotaService
* @param tenantKey * @param tenantKey
* @return * @return
*/ */
TenantGameQuota selectTenantGameQuotaByTenantKey(String tenantKey, Integer quotaType); TenantGameQuota selectTenantGameQuotaByTenantKey(String tenantKey, String quotaType);
} }

View File

@ -2,20 +2,27 @@ package com.ff.common.service.impl;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List; import java.util.List;
import java.util.Map;
import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.NumberUtil;
import com.ff.base.constant.Constants; import com.ff.base.constant.Constants;
import com.ff.base.enums.TenantQuotaType; import com.ff.base.enums.*;
import com.ff.base.enums.TenantType; import com.ff.base.exception.base.ApiException;
import com.ff.base.utils.DateUtils; import com.ff.base.utils.DateUtils;
import com.ff.base.utils.MessageUtils; import com.ff.base.utils.QuotaUtils;
import com.ff.base.utils.SecurityUtils; import com.ff.base.utils.StringUtils;
import com.ff.common.domain.TenantGameQuotaFlow; import com.ff.common.domain.TenantGameQuotaFlow;
import com.ff.common.domain.TenantSecretKey; import com.ff.common.domain.TenantSecretKey;
import com.ff.common.dto.BalanceChangesDTO; import com.ff.common.dto.BalanceChangesDTO;
import com.ff.common.mapper.TenantGameQuotaFlowMapper; import com.ff.common.dto.GameBalanceExchange;
import com.ff.common.service.ITenantGameQuotaFlowService; import com.ff.common.service.ITenantGameQuotaFlowService;
import com.ff.common.service.ITenantSecretKeyService; import com.ff.common.service.ITenantSecretKeyService;
import com.ff.game.api.IGamesService;
import com.ff.game.api.request.MemberInfoRequestDTO;
import com.ff.game.domain.GameSecretKey;
import com.ff.game.service.IGameSecretKeyService;
import com.ff.member.domain.Member;
import com.ff.member.service.IMemberService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.ff.common.mapper.TenantGameQuotaMapper; import com.ff.common.mapper.TenantGameQuotaMapper;
@ -44,6 +51,18 @@ public class TenantGameQuotaServiceImpl implements ITenantGameQuotaService {
@Resource @Resource
private ITenantSecretKeyService tenantSecretKeyService; private ITenantSecretKeyService tenantSecretKeyService;
@Resource
private IMemberService memberService;
@Resource
private IGameSecretKeyService gameSecretKeyService;
@Autowired
private Map<String, IGamesService> gamesService;
/** /**
* *
* *
@ -120,10 +139,8 @@ public class TenantGameQuotaServiceImpl implements ITenantGameQuotaService {
*/ */
@Override @Override
public Boolean balanceChanges(BalanceChangesDTO balanceChangesDTO) { public Boolean balanceChanges(BalanceChangesDTO balanceChangesDTO) {
TenantGameQuota tenantGameQuota = tenantGameQuotaMapper.selectTenantGameQuotaByTenantKey(balanceChangesDTO.getTenantKey(), TenantQuotaType.BALANCE.getCode());
Assert.isTrue(!ObjectUtils.isEmpty(tenantGameQuota), "租户余额额度不足");
TenantGameQuota tenantGameQuota = this.selectTenantGameQuotaByTenantKey(balanceChangesDTO.getTenantKey(), balanceChangesDTO.getQuotaType());
BigDecimal balanceBefore = tenantGameQuota.getBalance(); BigDecimal balanceBefore = tenantGameQuota.getBalance();
BigDecimal balance = balanceChangesDTO.getBalance(); BigDecimal balance = balanceChangesDTO.getBalance();
if (BigDecimal.ZERO.compareTo(balance) >= 0) { if (BigDecimal.ZERO.compareTo(balance) >= 0) {
@ -139,8 +156,7 @@ public class TenantGameQuotaServiceImpl implements ITenantGameQuotaService {
//判断剩余额度是否大于0 //判断剩余额度是否大于0
TenantSecretKey tenantSecretKey = tenantSecretKeyService.selectTenantSecretKeyByTenantKey(balanceChangesDTO.getTenantKey()); TenantSecretKey tenantSecretKey = tenantSecretKeyService.selectTenantSecretKeyByTenantKey(balanceChangesDTO.getTenantKey());
if (TenantType.DEPOSIT.getCode().equals(tenantSecretKey.getTenantType())) { if (TenantType.DEPOSIT.getCode().equals(tenantSecretKey.getTenantType())) {
TenantGameQuota depositQuota = tenantGameQuotaMapper.selectTenantGameQuotaByTenantKey(balanceChangesDTO.getTenantKey(), TenantQuotaType.DEPOSIT.getCode()); TenantGameQuota depositQuota = tenantGameQuotaMapper.selectTenantGameQuotaByTenantKey(balanceChangesDTO.getTenantKey(), QuotaUtils.getReputationQuota(balanceChangesDTO.getQuotaType()));
//判断剩余额度是否大于0 //判断剩余额度是否大于0
Assert.isTrue(balanceAfter.compareTo(depositQuota.getBalance().negate()) >= 0, "余额额度不足"); Assert.isTrue(balanceAfter.compareTo(depositQuota.getBalance().negate()) >= 0, "余额额度不足");
} else { } else {
@ -153,13 +169,14 @@ public class TenantGameQuotaServiceImpl implements ITenantGameQuotaService {
Boolean changedBalanceResult = tenantGameQuotaMapper.changeBalance(TenantGameQuota.builder() Boolean changedBalanceResult = tenantGameQuotaMapper.changeBalance(TenantGameQuota.builder()
.tenantKey(balanceChangesDTO.getTenantKey()) .tenantKey(balanceChangesDTO.getTenantKey())
.balance(balanceAfter) .balance(balanceAfter)
.quotaType(TenantQuotaType.BALANCE.getCode()) .quotaType(balanceChangesDTO.getQuotaType())
.version(tenantGameQuota.getVersion()) .version(tenantGameQuota.getVersion())
.build()); .build());
Assert.isTrue(changedBalanceResult, "租户游戏额度操作失败"); Assert.isTrue(changedBalanceResult, "租户游戏额度操作失败");
//插入流水 //插入流水
TenantGameQuotaFlow tenantGameQuotaFlow = TenantGameQuotaFlow.builder() TenantGameQuotaFlow tenantGameQuotaFlow = TenantGameQuotaFlow.builder()
.quotaType(balanceChangesDTO.getQuotaType())
.tenantKey(balanceChangesDTO.getTenantKey()) .tenantKey(balanceChangesDTO.getTenantKey())
.isOut(balanceChangesDTO.getIsOut()) .isOut(balanceChangesDTO.getIsOut())
.balanceAfter(balanceAfter) .balanceAfter(balanceAfter)
@ -175,6 +192,148 @@ public class TenantGameQuotaServiceImpl implements ITenantGameQuotaService {
return changedBalanceResult; return changedBalanceResult;
} }
/**
*
*
* @param gameBalanceExchange
* @return {@link BigDecimal }
*/
@Override
public BigDecimal gameBalanceExchange(GameBalanceExchange gameBalanceExchange) {
// 获取平台接口密钥
GameSecretKey gameSecretKey = gameSecretKeyService.findSecretKeyByPlatformAndSystemCode(gameBalanceExchange.getPlatformCode(), gameBalanceExchange.getCurrencyCode());
// 检查平台密钥是否存在,否则抛出异常
ApiException.notNull(gameSecretKey, ErrorCode.CURRENCY_NOT_EXIST.getCode());
// 获取租户信息
TenantSecretKey tenantSecretKey = tenantSecretKeyService.selectTenantSecretKeyByTenantKey(gameBalanceExchange.getTenantKey());
// 获取用户信息
Member member = memberService.selectMemberByGameAccount(StringUtils.addSuffix(gameBalanceExchange.getAccount(), gameBalanceExchange.getCurrencyCode() + tenantSecretKey.getTenantSn()));
// 检查用户是否存在,否则抛出异常
ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode());
// 根据平台代码获取平台接口
IGamesService iGamesService = gamesService.get(gameBalanceExchange.getPlatformCode() + Constants.SERVICE);
// 初始化额度类型为余额
String quotaType = QuotaType.BALANCE.getCode();
// 根据租户额度类型调整额度类型
if (TenantQuotaType.SINGLE.getCode().equals(tenantSecretKey.getQuotaType())) {
quotaType = QuotaUtils.getPlatformQuota(gameBalanceExchange.getPlatformCode(), gameBalanceExchange.getCurrencyCode());
}
// 判断操作类型(出账/入账)
boolean isOut = gameBalanceExchange.getTransferType().equals(TransferType.ALL.getCode());
// 初始化操作金额
BigDecimal balanceRequestAmount = gameBalanceExchange.getAmount();
// 如果是出账操作
if (isOut) {
// 获取第三方钱包余额
MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder()
.accounts(member.getGameAccount())
.agentId(gameSecretKey.getCode())
.agentKey(gameSecretKey.getKey())
.build();
balanceRequestAmount = iGamesService.getMemberInfo(gamesBaseRequestDTO).getBalance();
// 计算累计转入和转出金额
BigDecimal balanceInto = tenantGameQuotaFlowService.getBalanceByMemberId(TenantGameQuotaFlow.builder()
.isOut(Boolean.TRUE)
.quotaType(quotaType)
.tenantKey(gameBalanceExchange.getTenantKey())
.memberId(member.getId())
.build());
BigDecimal balanceOut = tenantGameQuotaFlowService.getBalanceByMemberId(TenantGameQuotaFlow.builder()
.isOut(Boolean.FALSE)
.quotaType(quotaType)
.tenantKey(gameBalanceExchange.getTenantKey())
.memberId(member.getId())
.build());
// 初始化平台额度
BigDecimal platformBalance = BigDecimal.ZERO;
// 确保转入金额不超过转出额度
if (NumberUtil.add(balanceInto, balanceRequestAmount).compareTo(balanceOut) > 0) {
BigDecimal difference = NumberUtil.sub(balanceOut, balanceInto);
platformBalance = NumberUtil.sub(balanceRequestAmount, difference);
balanceRequestAmount = difference;
}
// 如果有平台额度变化,进行余额调整
if (platformBalance.compareTo(BigDecimal.ZERO) > 0) {
this.balanceChanges(BalanceChangesDTO.builder()
.isOut(Boolean.TRUE)
.tenantKey(gameBalanceExchange.getTenantKey())
.balance(platformBalance)
.memberId(member.getId())
.operationType(OperationType.API_BALANCE.getCode())
.remark(OperationType.API_BALANCE.getDescription())
.quotaType(QuotaUtils.getFalseTenantQuota(gameBalanceExchange.getPlatformCode(), gameBalanceExchange.getCurrencyCode()))
.build());
}
// 进行租户余额调整
this.balanceChanges(BalanceChangesDTO.builder()
.isOut(isOut)
.tenantKey(gameBalanceExchange.getTenantKey())
.balance(balanceRequestAmount)
.memberId(member.getId())
.operationType(OperationType.API_BALANCE.getCode())
.quotaType(quotaType)
.remark(OperationType.API_BALANCE.getDescription())
.build());
} else {
// 如果是扣账操作,首先处理假额度
String falseTenantQuotaType = QuotaUtils.getFalseTenantQuota(gameBalanceExchange.getPlatformCode(), gameBalanceExchange.getCurrencyCode());
TenantGameQuota falseTenantQuota = selectTenantGameQuotaByTenantKey(tenantSecretKey.getTenantKey(), falseTenantQuotaType);
if (falseTenantQuota.getBalance().compareTo(BigDecimal.ZERO) > 0) {
BigDecimal amountToDeduct = gameBalanceExchange.getAmount();
BigDecimal falseQuotaBalance = falseTenantQuota.getBalance();
if (falseQuotaBalance.compareTo(amountToDeduct) >= 0) {
// 假额度足够扣除本次所需金额
this.balanceChanges(BalanceChangesDTO.builder()
.isOut(Boolean.FALSE)
.tenantKey(tenantSecretKey.getTenantKey())
.balance(amountToDeduct)
.memberId(member.getId())
.operationType(OperationType.API_BALANCE.getCode())
.quotaType(falseTenantQuotaType)
.remark(OperationType.API_BALANCE.getDescription())
.build());
balanceRequestAmount = BigDecimal.ZERO;
} else {
// 假额度不足以扣除本次所需金额,扣除全部假额度
balanceRequestAmount = amountToDeduct.subtract(falseQuotaBalance);
this.balanceChanges(BalanceChangesDTO.builder()
.isOut(Boolean.FALSE)
.tenantKey(tenantSecretKey.getTenantKey())
.balance(falseQuotaBalance)
.memberId(member.getId())
.operationType(OperationType.API_BALANCE.getCode())
.quotaType(falseTenantQuotaType)
.remark(OperationType.API_BALANCE.getDescription())
.build());
}
}
// 处理剩余的入账金额
if (balanceRequestAmount.compareTo(BigDecimal.ZERO) > 0) {
this.balanceChanges(BalanceChangesDTO.builder()
.isOut(Boolean.FALSE)
.tenantKey(tenantSecretKey.getTenantKey())
.balance(balanceRequestAmount)
.memberId(member.getId())
.operationType(OperationType.API_BALANCE.getCode())
.quotaType(quotaType)
.remark(OperationType.API_BALANCE.getDescription())
.build());
}
}
return balanceRequestAmount;
}
/** /**
* *
* *
@ -183,7 +342,19 @@ public class TenantGameQuotaServiceImpl implements ITenantGameQuotaService {
* @return {@link TenantGameQuota } * @return {@link TenantGameQuota }
*/ */
@Override @Override
public TenantGameQuota selectTenantGameQuotaByTenantKey(String tenantKey, Integer quotaType) { public TenantGameQuota selectTenantGameQuotaByTenantKey(String tenantKey, String quotaType) {
return tenantGameQuotaMapper.selectTenantGameQuotaByTenantKey(tenantKey, quotaType); TenantGameQuota tenantGameQuota = tenantGameQuotaMapper.selectTenantGameQuotaByTenantKey(tenantKey, quotaType);
//如果当前钱包不存在
if (ObjectUtils.isEmpty(tenantGameQuota)) {
tenantGameQuota = TenantGameQuota.builder()
.tenantKey(tenantKey)
.balance(BigDecimal.ZERO)
.quotaType(quotaType)
.version(0)
.build();
tenantGameQuotaMapper.insertTenantGameQuota(tenantGameQuota);
}
return tenantGameQuota;
} }
} }

View File

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ff.common.mapper.TenantAgentMapper">
<resultMap type="TenantAgent" id="TenantAgentResult">
<result property="id" column="id" />
<result property="account" column="account" />
<result property="password" column="password" />
<result property="agentStatus" column="agent_status" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectTenantAgentVo">
select id, account, password, agent_status, create_by, create_time, update_by, update_time from ff_tenant_agent
</sql>
<select id="selectTenantAgentList" parameterType="TenantAgent" resultMap="TenantAgentResult">
<include refid="selectTenantAgentVo"/>
<where>
<if test="account != null and account != ''"> and account = #{account}</if>
<if test="password != null and password != ''"> and password = #{password}</if>
<if test="agentStatus != null "> and agent_status = #{agentStatus}</if>
</where>
</select>
<select id="selectTenantAgentById" parameterType="Long" resultMap="TenantAgentResult">
<include refid="selectTenantAgentVo"/>
where id = #{id}
</select>
<insert id="insertTenantAgent" parameterType="TenantAgent" useGeneratedKeys="true" keyProperty="id">
insert into ff_tenant_agent
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="account != null">account,</if>
<if test="password != null">password,</if>
<if test="agentStatus != null">agent_status,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="account != null">#{account},</if>
<if test="password != null">#{password},</if>
<if test="agentStatus != null">#{agentStatus},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
</trim>
</insert>
<update id="updateTenantAgent" parameterType="TenantAgent">
update ff_tenant_agent
<trim prefix="SET" suffixOverrides=",">
<if test="account != null">account = #{account},</if>
<if test="password != null">password = #{password},</if>
<if test="agentStatus != null">agent_status = #{agentStatus},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteTenantAgentById" parameterType="Long">
delete from ff_tenant_agent where id = #{id}
</delete>
<delete id="deleteTenantAgentByIds" parameterType="String">
delete from ff_tenant_agent where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

View File

@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper <!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ff.common.mapper.TenantGameQuotaFlowMapper"> <mapper namespace="com.ff.common.mapper.TenantGameQuotaFlowMapper">
<resultMap type="TenantGameQuotaFlow" id="TenantGameQuotaFlowResult"> <resultMap type="TenantGameQuotaFlow" id="TenantGameQuotaFlowResult">
<result property="id" column="id" /> <result property="id" column="id" />
<result property="tenantKey" column="tenant_key" /> <result property="tenantKey" column="tenant_key" />
<result property="quotaType" column="quota_type" />
<result property="memberId" column="member_id" /> <result property="memberId" column="member_id" />
<result property="isOut" column="is_out" /> <result property="isOut" column="is_out" />
<result property="operationType" column="operation_type" /> <result property="operationType" column="operation_type" />
@ -21,13 +22,14 @@
</resultMap> </resultMap>
<sql id="selectTenantGameQuotaFlowVo"> <sql id="selectTenantGameQuotaFlowVo">
select id, tenant_key, member_id, is_out, operation_type, balance_before, balance, balance_after, remark, create_by, create_time, update_by, update_time from ff_tenant_game_quota_flow select id, tenant_key, quota_type, member_id, is_out, operation_type, balance_before, balance, balance_after, remark, create_by, create_time, update_by, update_time from ff_tenant_game_quota_flow
</sql> </sql>
<select id="selectTenantGameQuotaFlowList" parameterType="TenantGameQuotaFlow" resultMap="TenantGameQuotaFlowResult"> <select id="selectTenantGameQuotaFlowList" parameterType="TenantGameQuotaFlow" resultMap="TenantGameQuotaFlowResult">
<include refid="selectTenantGameQuotaFlowVo"/> <include refid="selectTenantGameQuotaFlowVo"/>
<where> <where>
<if test="tenantKey != null and tenantKey != ''"> and tenant_key = #{tenantKey}</if> <if test="tenantKey != null and tenantKey != ''"> and tenant_key = #{tenantKey}</if>
<if test="quotaType != null and quotaType != ''"> and quota_type = #{quotaType}</if>
<if test="memberId != null "> and member_id = #{memberId}</if> <if test="memberId != null "> and member_id = #{memberId}</if>
<if test="isOut != null "> and is_out = #{isOut}</if> <if test="isOut != null "> and is_out = #{isOut}</if>
<if test="operationType != null "> and operation_type = #{operationType}</if> <if test="operationType != null "> and operation_type = #{operationType}</if>
@ -46,6 +48,7 @@
insert into ff_tenant_game_quota_flow insert into ff_tenant_game_quota_flow
<trim prefix="(" suffix=")" suffixOverrides=","> <trim prefix="(" suffix=")" suffixOverrides=",">
<if test="tenantKey != null and tenantKey != ''">tenant_key,</if> <if test="tenantKey != null and tenantKey != ''">tenant_key,</if>
<if test="quotaType != null">quota_type,</if>
<if test="memberId != null">member_id,</if> <if test="memberId != null">member_id,</if>
<if test="isOut != null">is_out,</if> <if test="isOut != null">is_out,</if>
<if test="operationType != null">operation_type,</if> <if test="operationType != null">operation_type,</if>
@ -60,6 +63,7 @@
</trim> </trim>
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="tenantKey != null and tenantKey != ''">#{tenantKey},</if> <if test="tenantKey != null and tenantKey != ''">#{tenantKey},</if>
<if test="quotaType != null">#{quotaType},</if>
<if test="memberId != null">#{memberId},</if> <if test="memberId != null">#{memberId},</if>
<if test="isOut != null">#{isOut},</if> <if test="isOut != null">#{isOut},</if>
<if test="operationType != null">#{operationType},</if> <if test="operationType != null">#{operationType},</if>
@ -78,6 +82,7 @@
update ff_tenant_game_quota_flow update ff_tenant_game_quota_flow
<trim prefix="SET" suffixOverrides=","> <trim prefix="SET" suffixOverrides=",">
<if test="tenantKey != null and tenantKey != ''">tenant_key = #{tenantKey},</if> <if test="tenantKey != null and tenantKey != ''">tenant_key = #{tenantKey},</if>
<if test="quotaType != null">quota_type = #{quotaType},</if>
<if test="memberId != null">member_id = #{memberId},</if> <if test="memberId != null">member_id = #{memberId},</if>
<if test="isOut != null">is_out = #{isOut},</if> <if test="isOut != null">is_out = #{isOut},</if>
<if test="operationType != null">operation_type = #{operationType},</if> <if test="operationType != null">operation_type = #{operationType},</if>
@ -108,6 +113,7 @@
select ifnull(sum(balance),0) from ff_tenant_game_quota_flow select ifnull(sum(balance),0) from ff_tenant_game_quota_flow
<where> <where>
<if test="tenantKey != null and tenantKey != ''"> and tenant_key = #{tenantKey}</if> <if test="tenantKey != null and tenantKey != ''"> and tenant_key = #{tenantKey}</if>
<if test="quotaType != null and quotaType != ''"> and quota_type = #{quotaType}</if>
<if test="memberId != null "> and member_id = #{memberId}</if> <if test="memberId != null "> and member_id = #{memberId}</if>
<if test="isOut != null "> and is_out = #{isOut}</if> <if test="isOut != null "> and is_out = #{isOut}</if>
<if test="operationType != null "> and operation_type = #{operationType}</if> <if test="operationType != null "> and operation_type = #{operationType}</if>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper <!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ff.common.mapper.TenantGameQuotaMapper"> <mapper namespace="com.ff.common.mapper.TenantGameQuotaMapper">
<resultMap type="TenantGameQuota" id="TenantGameQuotaResult"> <resultMap type="TenantGameQuota" id="TenantGameQuotaResult">
@ -30,7 +30,7 @@
<where> <where>
<if test="tenantKey != null and tenantKey != ''"> and tenant_key = #{tenantKey}</if> <if test="tenantKey != null and tenantKey != ''"> and tenant_key = #{tenantKey}</if>
<if test="balance != null "> and balance = #{balance}</if> <if test="balance != null "> and balance = #{balance}</if>
<if test="quotaType != null "> and quota_type = #{quotaType}</if> <if test="quotaType != null and quotaType != ''"> and quota_type = #{quotaType}</if>
<if test="version != null "> and version = #{version}</if> <if test="version != null "> and version = #{version}</if>
</where> </where>
</select> </select>

View File

@ -1,18 +1,22 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper <!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ff.common.mapper.TenantSecretKeyMapper"> <mapper namespace="com.ff.common.mapper.TenantSecretKeyMapper">
<resultMap type="TenantSecretKey" id="TenantSecretKeyResult"> <resultMap type="TenantSecretKey" id="TenantSecretKeyResult">
<result property="id" column="id" /> <result property="id" column="id" />
<result property="agentId" column="agent_id" /> <result property="account" column="account" />
<result property="agentType" column="agent_type" /> <result property="password" column="password" />
<result property="tenantKey" column="tenant_key" /> <result property="tenantKey" column="tenant_key" />
<result property="agentId" column="agent_id" />
<result property="tenantSn" column="tenant_sn" /> <result property="tenantSn" column="tenant_sn" />
<result property="tenantSecret" column="tenant_secret" /> <result property="tenantSecret" column="tenant_secret" />
<result property="tenantStatus" column="tenant_status" /> <result property="tenantStatus" column="tenant_status" />
<result property="quotaType" column="quota_type" />
<result property="scoreRatio" column="score_ratio" />
<result property="tenantType" column="tenant_type" /> <result property="tenantType" column="tenant_type" />
<result property="depositRatio" column="deposit_ratio" />
<result property="createBy" column="create_by" /> <result property="createBy" column="create_by" />
<result property="createTime" column="create_time" /> <result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" /> <result property="updateBy" column="update_by" />
@ -20,19 +24,23 @@
</resultMap> </resultMap>
<sql id="selectTenantSecretKeyVo"> <sql id="selectTenantSecretKeyVo">
select id,agent_id, agent_type, tenant_key, tenant_sn, tenant_secret, tenant_status, tenant_type, create_by, create_time, update_by, update_time from ff_tenant_secret_key select id, account, password, tenant_key, agent_id, tenant_sn, tenant_secret, tenant_status, quota_type, score_ratio, tenant_type, deposit_ratio, create_by, create_time, update_by, update_time from ff_tenant_secret_key
</sql> </sql>
<select id="selectTenantSecretKeyList" parameterType="TenantSecretKey" resultMap="TenantSecretKeyResult"> <select id="selectTenantSecretKeyList" parameterType="TenantSecretKey" resultMap="TenantSecretKeyResult">
<include refid="selectTenantSecretKeyVo"/> <include refid="selectTenantSecretKeyVo"/>
<where> <where>
<if test="account != null and account != ''"> and account = #{account}</if>
<if test="password != null and password != ''"> and password = #{password}</if>
<if test="tenantKey != null and tenantKey != ''"> and tenant_key = #{tenantKey}</if> <if test="tenantKey != null and tenantKey != ''"> and tenant_key = #{tenantKey}</if>
<if test="agentType != null "> and agent_type = #{agentType}</if>
<if test="agentId != null "> and agent_id = #{agentId}</if> <if test="agentId != null "> and agent_id = #{agentId}</if>
<if test="tenantSn != null and tenantSn != ''"> and tenant_sn = #{tenantSn}</if> <if test="tenantSn != null and tenantSn != ''"> and tenant_sn = #{tenantSn}</if>
<if test="tenantSecret != null and tenantSecret != ''"> and tenant_secret = #{tenantSecret}</if> <if test="tenantSecret != null and tenantSecret != ''"> and tenant_secret = #{tenantSecret}</if>
<if test="tenantStatus != null "> and tenant_status = #{tenantStatus}</if> <if test="tenantStatus != null "> and tenant_status = #{tenantStatus}</if>
<if test="quotaType != null "> and quota_type = #{quotaType}</if>
<if test="scoreRatio != null "> and score_ratio = #{scoreRatio}</if>
<if test="tenantType != null "> and tenant_type = #{tenantType}</if> <if test="tenantType != null "> and tenant_type = #{tenantType}</if>
<if test="depositRatio != null "> and deposit_ratio = #{depositRatio}</if>
</where> </where>
</select> </select>
@ -49,26 +57,34 @@
<insert id="insertTenantSecretKey" parameterType="TenantSecretKey" useGeneratedKeys="true" keyProperty="id"> <insert id="insertTenantSecretKey" parameterType="TenantSecretKey" useGeneratedKeys="true" keyProperty="id">
insert into ff_tenant_secret_key insert into ff_tenant_secret_key
<trim prefix="(" suffix=")" suffixOverrides=","> <trim prefix="(" suffix=")" suffixOverrides=",">
<if test="account != null">account,</if>
<if test="password != null">password,</if>
<if test="tenantKey != null and tenantKey != ''">tenant_key,</if> <if test="tenantKey != null and tenantKey != ''">tenant_key,</if>
<if test="agentType != null ">agent_type,</if> <if test="agentId != null">agent_id,</if>
<if test="agentId != null ">agent_id,</if>
<if test="tenantSn != null">tenant_sn,</if> <if test="tenantSn != null">tenant_sn,</if>
<if test="tenantSecret != null and tenantSecret != ''">tenant_secret,</if> <if test="tenantSecret != null and tenantSecret != ''">tenant_secret,</if>
<if test="tenantStatus != null">tenant_status,</if> <if test="tenantStatus != null">tenant_status,</if>
<if test="quotaType != null">quota_type,</if>
<if test="scoreRatio != null">score_ratio,</if>
<if test="tenantType != null">tenant_type,</if> <if test="tenantType != null">tenant_type,</if>
<if test="depositRatio != null">deposit_ratio,</if>
<if test="createBy != null">create_by,</if> <if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if> <if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if> <if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if> <if test="updateTime != null">update_time,</if>
</trim> </trim>
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="account != null">#{account},</if>
<if test="password != null">#{password},</if>
<if test="tenantKey != null and tenantKey != ''">#{tenantKey},</if> <if test="tenantKey != null and tenantKey != ''">#{tenantKey},</if>
<if test="agentType != null ">#{agentType},</if> <if test="agentId != null">#{agentId},</if>
<if test="agentId != null ">#{agentId},</if>
<if test="tenantSn != null">#{tenantSn},</if> <if test="tenantSn != null">#{tenantSn},</if>
<if test="tenantSecret != null and tenantSecret != ''">#{tenantSecret},</if> <if test="tenantSecret != null and tenantSecret != ''">#{tenantSecret},</if>
<if test="tenantStatus != null">#{tenantStatus},</if> <if test="tenantStatus != null">#{tenantStatus},</if>
<if test="quotaType != null">#{quotaType},</if>
<if test="scoreRatio != null">#{scoreRatio},</if>
<if test="tenantType != null">#{tenantType},</if> <if test="tenantType != null">#{tenantType},</if>
<if test="depositRatio != null">#{depositRatio},</if>
<if test="createBy != null">#{createBy},</if> <if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if> <if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if> <if test="updateBy != null">#{updateBy},</if>
@ -79,13 +95,17 @@
<update id="updateTenantSecretKey" parameterType="TenantSecretKey"> <update id="updateTenantSecretKey" parameterType="TenantSecretKey">
update ff_tenant_secret_key update ff_tenant_secret_key
<trim prefix="SET" suffixOverrides=","> <trim prefix="SET" suffixOverrides=",">
<if test="account != null">account = #{account},</if>
<if test="password != null">password = #{password},</if>
<if test="tenantKey != null and tenantKey != ''">tenant_key = #{tenantKey},</if> <if test="tenantKey != null and tenantKey != ''">tenant_key = #{tenantKey},</if>
<if test="agentType != null ">agent_type = #{agentType},</if> <if test="agentId != null">agent_id = #{agentId},</if>
<if test="agentId != null ">agent_id = #{agentId},</if>
<if test="tenantSn != null">tenant_sn = #{tenantSn},</if> <if test="tenantSn != null">tenant_sn = #{tenantSn},</if>
<if test="tenantSecret != null and tenantSecret != ''">tenant_secret = #{tenantSecret},</if> <if test="tenantSecret != null and tenantSecret != ''">tenant_secret = #{tenantSecret},</if>
<if test="tenantStatus != null">tenant_status = #{tenantStatus},</if> <if test="tenantStatus != null">tenant_status = #{tenantStatus},</if>
<if test="quotaType != null">quota_type = #{quotaType},</if>
<if test="scoreRatio != null">score_ratio = #{scoreRatio},</if>
<if test="tenantType != null">tenant_type = #{tenantType},</if> <if test="tenantType != null">tenant_type = #{tenantType},</if>
<if test="depositRatio != null">deposit_ratio = #{depositRatio},</if>
<if test="createBy != null">create_by = #{createBy},</if> <if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if> <if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if> <if test="updateBy != null">update_by = #{updateBy},</if>

View File

@ -234,5 +234,10 @@ public class Constants {
*/ */
public static final String KEY = "key"; public static final String KEY = "key";
/**
*
*/
public static final String FALSE = "FALSE";
} }

View File

@ -0,0 +1,30 @@
package com.ff.base.enums;
/**
*
*
* @author shi
* @date 2025/02/14
*/
public enum QuotaType {
BALANCE("BALANCE", "余额"),
DEPOSIT("DEPOSIT", "押金"),
REPUTATION("REPUTATION", "信誉额度")
;
private final String code;
private final String info;
QuotaType(String code, String info) {
this.code = code;
this.info = info;
}
public String getCode() {
return code;
}
public String getInfo() {
return info;
}
}

View File

@ -7,8 +7,8 @@ package com.ff.base.enums;
* @date 2025/02/14 * @date 2025/02/14
*/ */
public enum TenantQuotaType { public enum TenantQuotaType {
BALANCE(1, "余额"), ALL(1, "通用额度"),
DEPOSIT(2, "押金"); SINGLE(2, "单一额度");
private final Integer code; private final Integer code;
private final String info; private final String info;

View File

@ -0,0 +1,47 @@
package com.ff.base.utils;
import com.ff.base.constant.Constants;
import com.ff.base.enums.QuotaType;
/**
*
*
* @author shi
* @date 2025/02/21
*/
public class QuotaUtils {
/**
*
*
* @param platformCode
* @param currencyCode
* @return {@link String }
*/
public static String getPlatformQuota(String platformCode, String currencyCode){
return platformCode + "_" + currencyCode;
}
/**
*
*
* @param tenantKey
* @param currencyCode
* @return {@link String }
*/
public static String getFalseTenantQuota(String tenantKey, String currencyCode){
return tenantKey + "_" + currencyCode+ "_"+ Constants.FALSE;
}
/**
*
*
* @param quotaType
* @return {@link String }
*/
public static String getReputationQuota(String quotaType){
return quotaType + "_" + QuotaType.REPUTATION.getCode();
}
}