refactor(game): 重构游戏余额转移功能

- 新增抽象步进处理类 AbstractStepProcessor 实现通用的处理和回滚逻辑- 新增具体步进处理实现类 CreateOrderServiceImpl、DeductBalanceServiceImpl 和 AddBalanceServiceImpl
-优化 ApiGameController 中的余额转移接口,采用异步处理方式- 重构 GameExchangeMoneyService 中的插入逻辑,支持更新
- 新增 GameExchangeDTO 用于游戏兑换货币的相关操作
- 更新相关枚举类和 DTO 类以支持新的业务逻辑
main-pgt
shi 2025-04-11 10:52:17 +08:00
parent 6e1afc61b0
commit f32794285a
34 changed files with 1431 additions and 407 deletions

View File

@ -30,6 +30,7 @@ public enum ErrorCode {
ACCOUNT_NOT_ONLINE(1014, "账号不在线"), ACCOUNT_NOT_ONLINE(1014, "账号不在线"),
FREQUENT_BALANCE_TRANSFER(1015, "当前游戏账号余额转移频繁"), FREQUENT_BALANCE_TRANSFER(1015, "当前游戏账号余额转移频繁"),
PLATFORM_NOT_METHODS(1016, "游戏平台不支持的方法"), PLATFORM_NOT_METHODS(1016, "游戏平台不支持的方法"),
DUPLICATE_ORDER_ID (1017, "重复的订单id"),
; ;
// 获取错误码 // 获取错误码

View File

@ -15,10 +15,20 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum GameExchangeStep { public enum GameExchangeStep {
CREATE_ORDER(1, "创建订单"), CREATE_ORDER(1, "创建订单"),
PLATFORM_TRANSACTION(2, "平台交易成功"), DEDUCT_BALANCE(2, "转入提前扣租户余额"),
PLATFORM_TRANSACTION_CONFIRM(3, "平台交易状态确认"), PLATFORM_TRANSACTION(3, "平台交易成功"),
TENANT_QUOTA_DEDUCTED(4, "租户额度扣减成功"); TENANT_QUOTA_DEDUCTED(4, "转出租户额度增加成功");
private final int code; private final Integer code;
private final String description; private final String description;
// 根据 code 获取对应的枚举
public static GameExchangeStep getByCode(int code) {
for (GameExchangeStep step : GameExchangeStep.values()) {
if (step.getCode() == code) {
return step;
}
}
return null;
}
} }

View File

@ -1,5 +1,7 @@
package com.ff.base.enums; package com.ff.base.enums;
import com.ff.base.exception.base.ApiException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -25,6 +27,20 @@ public enum GamePlatforms {
this.info = info; this.info = info;
} }
/**
*
*
* @param code
* @return {@link GamePlatforms }
*/
public static GamePlatforms getByCode(String code) {
for (GamePlatforms platform : GamePlatforms.values()) {
if (platform.getCode().equals(code)) {
return platform;
}
}
throw new ApiException(ErrorCode.PLATFORM_NOT_EXIST.getCode());
}
public static List<String> getCodes() { public static List<String> getCodes() {
List<String> result = new ArrayList<>(); List<String> result = new ArrayList<>();

View File

@ -0,0 +1,25 @@
package com.ff.base.enums;
import com.alibaba.druid.filter.AutoLoad;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
*
*
* @author shi
* @date 2025/04/09
*/
@AllArgsConstructor
@Getter
public enum TimeOutType {
GAME_EXCHANGE_MONEY("gameExchangeMoney", "游戏余额转移");
/**
*
*/
private final String code;
/**
*
*/
private final String info;
}

View File

@ -0,0 +1,21 @@
package com.ff.base.enums;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
/**
*
*
* @author shi
* @date 2025/04/09
*/
@Getter
@AllArgsConstructor
public enum TriggerType {
MANUAL(1, "用户调用手动触发"),
TIMER(2, "定时器触发");
private final int code;
private final String description;
}

View File

@ -2,11 +2,12 @@ package com.ff.base.manager;
import com.ff.base.utils.Threads; import com.ff.base.utils.Threads;
import com.ff.base.utils.spring.SpringUtils; import com.ff.base.utils.spring.SpringUtils;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.ArrayList;
import java.util.List;
import java.util.TimerTask; import java.util.TimerTask;
import java.util.concurrent.Callable; import java.util.concurrent.*;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/** /**
* *
@ -24,10 +25,33 @@ public class AsyncManager {
*/ */
private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService"); private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");
/**
* 线
*/
private List<ExecutorService> orderedExecutor = new ArrayList<>();
/**
* 线
*/
public static final int MAX_THREAD_COUNT = 16;
/**
* 线
*/
private ThreadPoolTaskExecutor taskExecutor;
/** /**
* *
*/ */
private AsyncManager() { private AsyncManager() {
for (int i = 0; i < MAX_THREAD_COUNT; i++) {
orderedExecutor.add(Executors.newSingleThreadExecutor());
}
executor = SpringUtils.getBean("scheduledExecutorService");
taskExecutor = SpringUtils.getBean("threadPoolTaskExecutor");
} }
private static AsyncManager me = new AsyncManager(); private static AsyncManager me = new AsyncManager();
@ -36,6 +60,22 @@ public class AsyncManager {
return me; return me;
} }
public void executeOrdered(String key, Runnable task) {
if (null == key || key.isEmpty()) {
taskExecutor.execute(task);
return;
}
int hash = key.hashCode();
int index = Math.abs(hash % MAX_THREAD_COUNT);
orderedExecutor.get(index).execute(task);
}
/** /**
* *
* *

View File

@ -1,6 +1,7 @@
package com.ff.api.controller; package com.ff.api.controller;
import cn.hutool.core.util.IdUtil;
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.*;
@ -8,9 +9,9 @@ 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.TransferType;
import com.ff.base.exception.base.ApiException; import com.ff.base.exception.base.ApiException;
import com.ff.base.manager.AsyncManager;
import com.ff.base.system.domain.TenantSecretKey; import com.ff.base.system.domain.TenantSecretKey;
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;
@ -19,6 +20,8 @@ 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.IGamesService;
import com.ff.game.api.exchange.StepProcessorFactory;
import com.ff.game.api.exchange.dto.GameExchangeDTO;
import com.ff.game.api.request.*; import com.ff.game.api.request.*;
import com.ff.game.domain.*; import com.ff.game.domain.*;
import com.ff.game.dto.GameBettingDetailsDTO; import com.ff.game.dto.GameBettingDetailsDTO;
@ -30,8 +33,10 @@ import lombok.Data;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -39,12 +44,14 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; 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 org.springframework.web.context.request.async.DeferredResult;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CompletableFuture;
/** /**
* api * api
@ -94,6 +101,10 @@ public class ApiGameController extends BaseController {
@Resource @Resource
private IPlatformService platformService; private IPlatformService platformService;
@Resource
private StepProcessorFactory stepProcessorFactory;
/** /**
* *
* *
@ -185,8 +196,7 @@ public class ApiGameController extends BaseController {
* @return {@link AjaxResult } * @return {@link AjaxResult }
*/ */
@PostMapping("/exchange/balance") @PostMapping("/exchange/balance")
@Transactional public DeferredResult<AjaxResult> exchangeBalance(@Validated @RequestBody GameExchangeBalanceRequest gameExchangeBalanceRequest) {
public AjaxResult exchangeBalance(@Validated @RequestBody GameExchangeBalanceRequest gameExchangeBalanceRequest) {
IGamesService iGamesService = gamesService.get(gameExchangeBalanceRequest.getPlatformCode() + Constants.SERVICE); IGamesService iGamesService = gamesService.get(gameExchangeBalanceRequest.getPlatformCode() + Constants.SERVICE);
ApiException.notNull(iGamesService, ErrorCode.PLATFORM_NOT_EXIST.getCode()); ApiException.notNull(iGamesService, ErrorCode.PLATFORM_NOT_EXIST.getCode());
@ -210,51 +220,77 @@ public class ApiGameController extends BaseController {
} }
} }
ApiException.notNull(keyInfo, ErrorCode.CURRENCY_NOT_EXIST.getCode()); ApiException.notNull(keyInfo, ErrorCode.CURRENCY_NOT_EXIST.getCode());
BigDecimal quota = BigDecimal.ZERO;
//如果是扣钱提前扣
if (TransferType.GAMES.getCode().equals(gameExchangeBalanceRequest.getTransferType())) {
quota = tenantGameQuotaService.gameBalanceExchange(GameBalanceExchange.builder()
.platformCode(gameExchangeBalanceRequest.getPlatformCode())
.sourceId(gameExchangeBalanceRequest.getOrderId())
.currencyCode(gameExchangeBalanceRequest.getCurrencyCode())
.currency(targetCurrency)
.transferType(gameExchangeBalanceRequest.getTransferType())
.amount(gameExchangeBalanceRequest.getAmount())
.account(gameExchangeBalanceRequest.getAccount())
.tenantKey(tenantSecretKey.getTenantKey())
.systemCurrency(gameExchangeBalanceRequest.getCurrencyCode())
.agentId(keyInfo.getCode())
.agentKey(keyInfo.getKey())
.build());
}
// 获取用户信息 // 获取用户信息
Member member = memberService.selectMemberByAccount(gameExchangeBalanceRequest.getAccount(), gameExchangeBalanceRequest.getCurrencyCode(), gameExchangeBalanceRequest.getPlatformCode()); Member member = memberService.selectMemberByAccount(gameExchangeBalanceRequest.getAccount(), gameExchangeBalanceRequest.getCurrencyCode(), gameExchangeBalanceRequest.getPlatformCode());
ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode()); ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode());
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
//操作第三方额度接口 GameExchangeMoney.builder()
ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO = ExchangeTransferMoneyRequestDTO.builder()
.agentId(keyInfo.getCode())
.agentKey(keyInfo.getKey())
.orderId(gameExchangeBalanceRequest.getOrderId())
.account(member.getGameAccount())
.currency(targetCurrency)
.tenantKey(tenantSecretKey.getTenantKey()) .tenantKey(tenantSecretKey.getTenantKey())
.quota(quota) .orderId(gameExchangeBalanceRequest.getOrderId())
.amount(gameExchangeBalanceRequest.getAmount()) .build()
.transferType(gameExchangeBalanceRequest.getTransferType()) );
.vendor(platform)
.keyInfo(keyInfo)
.systemCurrency(gameExchangeBalanceRequest.getCurrencyCode())
.build(); ApiException.isTrue(CollectionUtils.isEmpty(gameExchangeMonies), ErrorCode.DUPLICATE_ORDER_ID.getCode());
Long exchangeTransferId = iGamesService.exchangeTransferByAgentId(exchangeTransferMoneyRequestDTO);
GameExchangeMoney gameExchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferId);
Long gameExchangeMoneyId = IdUtil.getSnowflakeNextId();
GameExchangeDTO exchangeMoney = GameExchangeDTO.builder()
.id(gameExchangeMoneyId)
.tenantKey(tenantSecretKey.getTenantKey())
.memberId(member.getId())
.gameAccount(member.getGameAccount())
.memberAccount(member.getMemberAccount())
.exchangeType(gameExchangeBalanceRequest.getTransferType())
.currencyCode(gameExchangeBalanceRequest.getCurrencyCode())
.orderId(gameExchangeBalanceRequest.getOrderId())
.balance(gameExchangeBalanceRequest.getAmount())
.triggerType(TriggerType.MANUAL.getCode())
.platformCode(gameExchangeBalanceRequest.getPlatformCode()).build();
//转出设置转出金额为0
if (TransferType.ALL.getCode().equals(gameExchangeBalanceRequest.getTransferType())){
exchangeMoney.setBalance(BigDecimal.ZERO);
}
ExtInfo extInfo = platform.getExtInfo();
Long timeout = 5000L;
if (extInfo != null) {
timeout = extInfo.getTimeout(TimeOutType.GAME_EXCHANGE_MONEY.getCode());
}
DeferredResult<AjaxResult> output = new DeferredResult<>(timeout);
AsyncManager.me().executeOrdered(
exchangeMoney.getOrderId(),
() -> {
try {
stepProcessorFactory.getStepProcessor(GameExchangeStep.CREATE_ORDER).process(exchangeMoney);
GameExchangeMoney gameExchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(gameExchangeMoneyId);
GameExchangeBalanceResponse gameExchangeBalanceResponse = new GameExchangeBalanceResponse(); GameExchangeBalanceResponse gameExchangeBalanceResponse = new GameExchangeBalanceResponse();
BeanUtils.copyProperties(gameExchangeMoney, gameExchangeBalanceResponse); BeanUtils.copyProperties(gameExchangeMoney, gameExchangeBalanceResponse);
return AjaxResult.success(gameExchangeBalanceResponse); output.setResult(AjaxResult.success(gameExchangeBalanceResponse));
} catch (Exception e) {
log.error("ApiGameController [exchangeBalance] 余额转移失败 gameExchangeMoneyId {}", gameExchangeMoneyId,e);
stepProcessorFactory.getStepProcessor(GameExchangeStep.getByCode(exchangeMoney.getStep())).rollBack(exchangeMoney);
output.setErrorResult(AjaxResult.error(ErrorCode.BALANCE_TRANSFER_FAILED.getCode(), ErrorCode.BALANCE_TRANSFER_FAILED.getMessage()));
}
}
);
// 超时时间处理逻辑
output.onTimeout(() -> {
GameExchangeMoney gameExchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(gameExchangeMoneyId);
GameExchangeBalanceResponse gameExchangeBalanceResponse = new GameExchangeBalanceResponse();
BeanUtils.copyProperties(gameExchangeMoney, gameExchangeBalanceResponse);
output.setErrorResult(AjaxResult.success(gameExchangeBalanceResponse));
});
return output;
} }
@ -294,11 +330,6 @@ public class ApiGameController extends BaseController {
ApiException.notNull(iGamesService, ErrorCode.PLATFORM_NOT_EXIST.getCode()); ApiException.notNull(iGamesService, ErrorCode.PLATFORM_NOT_EXIST.getCode());
// TenantSecretKey tenantSecretKey = keyConfig.get();
// GameSecretKeyCurrencyDTO gameSecretKey = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
// .platformCode(gameCreateFreeSpinRequest.getPlatformCode())
// .systemCurrency(gameCreateFreeSpinRequest.getCurrencyCode()).build());
// ApiException.notNull(gameSecretKey, ErrorCode.CURRENCY_NOT_EXIST.getCode());
Platform platform = platformService.get(gameCreateFreeSpinRequest.getPlatformCode()); Platform platform = platformService.get(gameCreateFreeSpinRequest.getPlatformCode());
ApiException.notNull(platform, ErrorCode.PLATFORM_NOT_EXIST.getCode()); ApiException.notNull(platform, ErrorCode.PLATFORM_NOT_EXIST.getCode());

View File

@ -67,4 +67,9 @@ public class GameBalanceExchange extends GamesBaseRequestDTO implements Serializ
*/ */
private String sourceId; private String sourceId;
/**
*
*/
private Boolean isAll;
} }

View File

@ -152,7 +152,7 @@ public class TenantGameQuotaServiceImpl implements ITenantGameQuotaService {
BigDecimal balance = balanceChangesDTO.getBalance(); BigDecimal balance = balanceChangesDTO.getBalance();
//如果有汇率 则需要计算真实扣除额度 //如果有汇率 则需要计算真实扣除额度
if (!ObjectUtils.isEmpty(balanceChangesDTO.getActualBalance())) { if (!ObjectUtils.isEmpty(balanceChangesDTO.getActualBalance())) {
balance = NumberUtil.div(balance, balanceChangesDTO.getActualBalance(), 2, RoundingMode.FLOOR); balance = NumberUtil.div(balance, balanceChangesDTO.getActualBalance(), 5, RoundingMode.FLOOR);
} }
if (BigDecimal.ZERO.compareTo(balance) >= 0) { if (BigDecimal.ZERO.compareTo(balance) >= 0) {
@ -222,7 +222,7 @@ public class TenantGameQuotaServiceImpl implements ITenantGameQuotaService {
BigDecimal balance = balanceRealChangesDTO.getBalance(); BigDecimal balance = balanceRealChangesDTO.getBalance();
//如果有汇率 则需要计算真实扣除额度 //如果有汇率 则需要计算真实扣除额度
if (!ObjectUtils.isEmpty(balanceRealChangesDTO.getActualBalance())) { if (!ObjectUtils.isEmpty(balanceRealChangesDTO.getActualBalance())) {
balance = NumberUtil.div(balance, balanceRealChangesDTO.getActualBalance(), 2, RoundingMode.FLOOR); balance = NumberUtil.div(balance, balanceRealChangesDTO.getActualBalance(), 5, RoundingMode.FLOOR);
} }
if (BigDecimal.ZERO.compareTo(balance) >= 0) { if (BigDecimal.ZERO.compareTo(balance) >= 0) {
@ -317,6 +317,7 @@ public class TenantGameQuotaServiceImpl implements ITenantGameQuotaService {
// 如果是出账操作 // 如果是出账操作
if (isOut) { if (isOut) {
if (ObjectUtils.isEmpty(gameBalanceExchange.getIsAll())||gameBalanceExchange.getIsAll()){
// 获取第三方钱包余额 // 获取第三方钱包余额
MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder() MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder()
.accounts(member.getGameAccount()) .accounts(member.getGameAccount())
@ -325,6 +326,9 @@ public class TenantGameQuotaServiceImpl implements ITenantGameQuotaService {
.agentKey(gameBalanceExchange.getAgentKey()) .agentKey(gameBalanceExchange.getAgentKey())
.build(); .build();
balanceRequestAmount = iGamesService.getMemberInfo(gamesBaseRequestDTO).getBalance(); balanceRequestAmount = iGamesService.getMemberInfo(gamesBaseRequestDTO).getBalance();
}
balanceRequestAmount = NumberUtil.add(balanceRequestAmount, NumberUtil.mul(balanceRequestAmount, NumberUtil.div(tenantPlatform.getUseCost(), Constants.HUNDRED))); balanceRequestAmount = NumberUtil.add(balanceRequestAmount, NumberUtil.mul(balanceRequestAmount, NumberUtil.div(tenantPlatform.getUseCost(), Constants.HUNDRED)));
// 计算累计转入和转出金额 // 计算累计转入和转出金额

View File

@ -228,34 +228,8 @@ public class GamesAEServiceImpl implements IGamesService {
log.info("GamesAEServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO); log.info("GamesAEServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO);
Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount()); GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferMoneyRequestDTO.getGameExchangeId());
String transactionId = GamePlatforms.AE.getCode() + IdUtils.simpleUUID();
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
GameExchangeMoney.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.build()
);
Assert.isTrue(CollectionUtils.isEmpty(gameExchangeMonies), "订单号重复");
//获取下一个自增id
GameExchangeMoney exchangeMoney = GameExchangeMoney
.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.quota(exchangeTransferMoneyRequestDTO.getQuota())
.balance(exchangeTransferMoneyRequestDTO.getAmount())
.exchangeType(exchangeTransferMoneyRequestDTO.getTransferType())
.currencyCode(exchangeTransferMoneyRequestDTO.getSystemCurrency())
.memberId(member.getId())
.transactionId(transactionId)
.platformCode(GamePlatforms.AE.getInfo())
.build();
exchangeMoney.setCreateBy(Constants.SYSTEM);
exchangeMoney.setStatus(StatusType.IN_PROGRESS.getValue());
exchangeMoney.setStep(GameExchangeStep.CREATE_ORDER.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
Map<String, Object> params = this.getKey(exchangeTransferMoneyRequestDTO); Map<String, Object> params = this.getKey(exchangeTransferMoneyRequestDTO);
@ -264,13 +238,13 @@ public class GamesAEServiceImpl implements IGamesService {
if (TransferType.GAMES.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType())) { if (TransferType.GAMES.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType())) {
params.put("userId", exchangeTransferMoneyRequestDTO.getAccount()); params.put("userId", exchangeTransferMoneyRequestDTO.getAccount());
params.put("txCode", transactionId); params.put("txCode", exchangeTransferMoneyRequestDTO.getTransactionId());
params.put("transferAmount", exchangeTransferMoneyRequestDTO.getAmount()); params.put("transferAmount", exchangeTransferMoneyRequestDTO.getAmount());
deposit = AEClient.deposit(params); deposit = AEClient.deposit(params);
} else { } else {
params.put("userId", exchangeTransferMoneyRequestDTO.getAccount()); params.put("userId", exchangeTransferMoneyRequestDTO.getAccount());
params.put("txCode", transactionId); params.put("txCode", exchangeTransferMoneyRequestDTO.getTransactionId());
params.put("withdrawType", 1); params.put("withdrawType", 1);
deposit = AEClient.withdraw(params); deposit = AEClient.withdraw(params);
} }

View File

@ -220,39 +220,14 @@ public class GamesDGServiceImpl implements IGamesService {
log.info("GamesDGServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO); log.info("GamesDGServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO);
Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount()); GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferMoneyRequestDTO.getGameExchangeId());
String transactionId = GamePlatforms.DG.getInfo() + IdUtils.simpleUUID();
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
GameExchangeMoney.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.build()
);
Assert.isTrue(CollectionUtils.isEmpty(gameExchangeMonies), "订单号重复");
//获取下一个自增id
GameExchangeMoney exchangeMoney = GameExchangeMoney
.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.quota(exchangeTransferMoneyRequestDTO.getQuota())
.balance(exchangeTransferMoneyRequestDTO.getAmount())
.exchangeType(exchangeTransferMoneyRequestDTO.getTransferType())
.currencyCode(exchangeTransferMoneyRequestDTO.getSystemCurrency())
.memberId(member.getId())
.transactionId(transactionId)
.platformCode(GamePlatforms.DG.getInfo())
.build();
exchangeMoney.setCreateBy(Constants.SYSTEM);
exchangeMoney.setStatus(StatusType.IN_PROGRESS.getValue());
exchangeMoney.setStep(GameExchangeStep.CREATE_ORDER.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
BigDecimal amount = exchangeTransferMoneyRequestDTO.getAmount(); BigDecimal amount = exchangeTransferMoneyRequestDTO.getAmount();
if (TransferType.ALL.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType())) { if (TransferType.ALL.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType())) {
// 获取第三方钱包余额 // 获取第三方钱包余额
MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder() MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder()
.accounts(member.getGameAccount()) .accounts(exchangeTransferMoneyRequestDTO.getAccount())
.agentId(exchangeTransferMoneyRequestDTO.getAgentId()) .agentId(exchangeTransferMoneyRequestDTO.getAgentId())
.currency(exchangeTransferMoneyRequestDTO.getCurrency()) .currency(exchangeTransferMoneyRequestDTO.getCurrency())
.agentKey(exchangeTransferMoneyRequestDTO.getAgentKey()) .agentKey(exchangeTransferMoneyRequestDTO.getAgentKey())
@ -265,7 +240,7 @@ public class GamesDGServiceImpl implements IGamesService {
Map<String, Object> params = new LinkedHashMap<>(); Map<String, Object> params = new LinkedHashMap<>();
params.put("username", exchangeTransferMoneyRequestDTO.getAccount()); params.put("username", exchangeTransferMoneyRequestDTO.getAccount());
params.put("amount", amount); params.put("amount", amount);
params.put("serial", transactionId); params.put("serial", exchangeTransferMoneyRequestDTO.getTransactionId());
Map<String, Object> headerMap = this.getKey(exchangeTransferMoneyRequestDTO); Map<String, Object> headerMap = this.getKey(exchangeTransferMoneyRequestDTO);
DGTransactionResponseDTO dgTransactionResponseDTO = DGClient.exchangeTransferByAgentId(params, headerMap); DGTransactionResponseDTO dgTransactionResponseDTO = DGClient.exchangeTransferByAgentId(params, headerMap);

View File

@ -0,0 +1,118 @@
package com.ff.game.api.exchange;
import com.ff.base.enums.GameExchangeStep;
import com.ff.base.enums.GameExchangeStepStatus;
import com.ff.base.exception.base.BaseException;
import com.ff.game.api.exchange.dto.GameExchangeDTO;
import com.ff.game.domain.GameExchangeMoney;
import com.ff.game.service.IGameExchangeMoneyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
/**
*
*
* @author shi
* @date 2025/04/09
*/
@Slf4j
public abstract class AbstractStepProcessor implements StepProcessorService {
@Resource
private StepProcessorFactory stepProcessorFactory;
@Resource
private IGameExchangeMoneyService gameExchangeMoneyService;
/**
*
*
* @param gameExchangeMoney
*/
@Override
public void process(GameExchangeDTO gameExchangeMoney) {
boolean processResult = false;
try {
processResult = doProcess(gameExchangeMoney);
} catch (Exception e) {
log.error("游戏余额转移{}-步骤任务{}-执行异常", gameExchangeMoney.getId(), stepKey().getDescription(), e);
throw new BaseException("游戏余额转移"+gameExchangeMoney.getId()+"-步骤任务"+stepKey().getDescription()+"-执行异常" );
}
//更新状态
if (processResult) {
log.info("游戏余额转移{}-步骤任务{}-执行成功", gameExchangeMoney.getId(), stepKey().getDescription());
triggerNextStep(gameExchangeMoney);
}
}
/**
*
*
* @param gameExchangeMoney
*/
@Override
public void rollBack(GameExchangeDTO gameExchangeMoney){
boolean processResult = false;
try {
processResult = doRollBack(gameExchangeMoney);
} catch (Exception e) {
log.error("游戏余额转移{}-步骤任务{}-回滚异常", gameExchangeMoney.getId(), stepKey().getDescription(), e);
}
if (processResult) {
log.info("游戏余额转移{}-步骤任务{}-回滚成功", gameExchangeMoney.getId(), stepKey().getDescription());
triggerBackStep(gameExchangeMoney);
}
}
/**
* 退
*
* @param exchangeMoney
*/
private void triggerBackStep(GameExchangeDTO exchangeMoney) {
GameExchangeStep nextStep = backStepProcessor();
if (nextStep != null) {
stepProcessorFactory.getStepProcessor(nextStep).rollBack(exchangeMoney);
}
}
/**
*
*
* @param exchangeMoney
*/
private void triggerNextStep(GameExchangeDTO exchangeMoney) {
GameExchangeStep nextStep = nextStepProcessor();
if (nextStep != null) {
stepProcessorFactory.getStepProcessor(nextStep).process(exchangeMoney);
}
}
/**
*
*
* @param gameExchangeMoney
* @return boolean
* @throws Exception
*/
abstract public boolean doRollBack(GameExchangeDTO gameExchangeMoney) throws Exception;
/**
* do
*
* @param gameExchangeMoney
* @return boolean
* @throws Exception
*/
abstract public boolean doProcess(GameExchangeDTO gameExchangeMoney) throws Exception;
}

View File

@ -0,0 +1,47 @@
package com.ff.game.api.exchange;
import com.ff.base.enums.GameExchangeStep;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
*
* @author shi
* @date 2025/04/09
*/
@Component
public class StepProcessorFactory {
@Autowired
List<StepProcessorService> stepProcessors;
private Map<GameExchangeStep, StepProcessorService> processorMap;
@PostConstruct
public void init() {
Map<GameExchangeStep, StepProcessorService> map = new HashMap<>();
for (StepProcessorService stepProcessor : stepProcessors) {
map.put(stepProcessor.stepKey(), stepProcessor);
}
processorMap = Collections.unmodifiableMap(map);
}
/**
*
*
* @param stepKey
* @return {@link StepProcessorService }
*/
public StepProcessorService getStepProcessor(GameExchangeStep stepKey) {
return processorMap.get(stepKey);
}
}

View File

@ -0,0 +1,56 @@
package com.ff.game.api.exchange;
import com.ff.base.enums.GameExchangeStep;
import com.ff.game.api.exchange.dto.GameExchangeDTO;
/**
*
*
* @author shi
* @date 2025/04/09
*/
public interface StepProcessorService {
/**
*
*
* @return {@link GameExchangeStep }
*/
GameExchangeStep stepKey();
/**
*
*
* @param gameExchangeMoney
*/
void process(GameExchangeDTO gameExchangeMoney);
/**
* 退
*
* @param gameExchangeMoney
*/
void rollBack(GameExchangeDTO gameExchangeMoney);
/**
*
*
*
* @return
*/
GameExchangeStep nextStepProcessor();
/**
*
*
*
* @return {@link GameExchangeStep }
*/
GameExchangeStep backStepProcessor();
}

View File

@ -0,0 +1,32 @@
package com.ff.game.api.exchange.dto;
import com.ff.base.annotation.Excel;
import com.ff.game.domain.GameExchangeMoney;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* dto
*
* @author shi
* @date 2025/04/09
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder
public class GameExchangeDTO extends GameExchangeMoney {
/**
* 1 2
*/
private Integer triggerType;
/** 会员账号 */
private String memberAccount;
/** 游戏账号 */
private String gameAccount;
}

View File

@ -0,0 +1,170 @@
package com.ff.game.api.exchange.impl;
import com.ff.base.constant.Constants;
import com.ff.base.enums.*;
import com.ff.base.exception.base.ApiException;
import com.ff.base.utils.StringUtils;
import com.ff.common.domain.TenantGameQuotaFlow;
import com.ff.common.dto.BalanceChangesDTO;
import com.ff.common.dto.GameBalanceExchange;
import com.ff.common.service.ITenantGameQuotaFlowService;
import com.ff.common.service.ITenantGameQuotaService;
import com.ff.game.api.IGamesService;
import com.ff.game.api.exchange.AbstractStepProcessor;
import com.ff.game.api.exchange.dto.GameExchangeDTO;
import com.ff.game.api.request.ExchangeTransferMoneyRequestDTO;
import com.ff.game.api.request.ExchangeTransferStatusRequestDTO;
import com.ff.game.api.request.ExchangeTransferStatusResponseDTO;
import com.ff.game.domain.KeyInfo;
import com.ff.game.domain.Platform;
import com.ff.game.service.IGameExchangeMoneyService;
import com.ff.game.service.IPlatformService;
import com.ff.member.domain.Member;
import com.ff.member.service.IMemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
*
*
* @author shi
* @date 2025/04/09
*/
@Service
@Order(4)
public class AddBalanceServiceImpl extends AbstractStepProcessor {
@Resource
private IMemberService memberService;
@Resource
private ITenantGameQuotaService tenantGameQuotaService;
@Resource
private IGameExchangeMoneyService gameExchangeMoneyService;
@Resource
private PlatformTransactionManager transactionManager;
@Resource
private IPlatformService platformService;
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep stepKey() {
return GameExchangeStep.TENANT_QUOTA_DEDUCTED;
}
/**
* do
*
* @param gameExchangeMoney
* @return boolean
*/
@Override
public boolean doProcess(GameExchangeDTO gameExchangeMoney) {
//如果不是之前的步骤代码执行过了 或者是转入操作
if (!gameExchangeMoney.getStep().equals(GameExchangeStep.PLATFORM_TRANSACTION.getCode()) ) {
return Boolean.TRUE;
}
if (!gameExchangeMoney.getStepStatus().equals(StatusType.SUCCESS.getValue())){
return Boolean.TRUE;
}
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
Boolean result = transactionTemplate.execute(transactionStatus -> {
//不是转入操作
if (!TransferType.ALL.getCode().equals(gameExchangeMoney.getExchangeType())) {
gameExchangeMoney.setStep(GameExchangeStep.DEDUCT_BALANCE.getCode());
gameExchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
gameExchangeMoney.setStatus(StatusType.SUCCESS.getValue());
return gameExchangeMoneyService.updateGameExchangeMoney(gameExchangeMoney) > 0;
}
Platform platform = platformService.get(gameExchangeMoney.getPlatformCode());
KeyInfo keyInfo = null;
for (KeyInfo keyData : platform.getKeyInfo()) {
if (StringUtils.isNotEmpty(gameExchangeMoney.getCurrencyCode())) {
if (keyData.getCurrency().equalsIgnoreCase(gameExchangeMoney.getCurrencyCode())) {
keyInfo = keyData;
break;
}
}
}
BigDecimal decimal = tenantGameQuotaService.gameBalanceExchange(GameBalanceExchange.builder()
.platformCode(gameExchangeMoney.getPlatformCode())
.sourceId(String.valueOf(gameExchangeMoney.getId()))
.currencyCode(gameExchangeMoney.getCurrencyCode())
.currency(gameExchangeMoney.getCurrencyCode())
.transferType(gameExchangeMoney.getExchangeType())
.amount(gameExchangeMoney.getBalance())
.isAll(Boolean.FALSE)
.account(memberService.selectMemberById(gameExchangeMoney.getMemberId()).getMemberAccount())
.tenantKey(gameExchangeMoney.getTenantKey())
.systemCurrency(gameExchangeMoney.getCurrencyCode())
.agentId(keyInfo.getCode())
.agentKey(keyInfo.getKey())
.build());
gameExchangeMoney.setQuota(decimal);
gameExchangeMoney.setStep(GameExchangeStep.TENANT_QUOTA_DEDUCTED.getCode());
gameExchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
gameExchangeMoney.setStatus(StatusType.SUCCESS.getValue());
return gameExchangeMoneyService.updateGameExchangeMoney(gameExchangeMoney) > 0;
});
return Boolean.TRUE.equals(result);
}
/**
*
*
* @param gameExchangeMoney
* @return boolean
*/
@Override
public boolean doRollBack(GameExchangeDTO gameExchangeMoney) {
return Boolean.TRUE;
}
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep nextStepProcessor() {
return null;
}
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep backStepProcessor() {
{
return null;
}
}
}

View File

@ -0,0 +1,146 @@
package com.ff.game.api.exchange.impl;
import com.ff.base.constant.Constants;
import com.ff.base.enums.*;
import com.ff.base.exception.base.ApiException;
import com.ff.base.manager.AsyncManager;
import com.ff.base.utils.DateUtils;
import com.ff.base.utils.uuid.IdUtils;
import com.ff.game.api.exchange.AbstractStepProcessor;
import com.ff.game.api.exchange.StepProcessorFactory;
import com.ff.game.api.exchange.StepProcessorService;
import com.ff.game.api.exchange.dto.GameExchangeDTO;
import com.ff.game.api.request.ExchangeTransferStatusRequestDTO;
import com.ff.game.domain.GameExchangeMoney;
import com.ff.game.service.IGameExchangeMoneyService;
import com.ff.member.domain.Member;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
/**
* impl
*
* @author shi
* @date 2025/04/09
*/
@Service
@Order(1)
public class CreateOrderServiceImpl extends AbstractStepProcessor {
@Resource
private IGameExchangeMoneyService gameExchangeMoneyService;
@Resource
private StepProcessorFactory stepProcessorFactory;
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep stepKey() {
return GameExchangeStep.CREATE_ORDER;
}
/**
* do
*
* @param gameExchangeMoney
* @return boolean
*/
@Override
public boolean doProcess(GameExchangeDTO gameExchangeMoney) {
gameExchangeMoney.setTransactionId(this.getTransactionId(GamePlatforms.getByCode(gameExchangeMoney.getPlatformCode()),gameExchangeMoney.getExchangeType(),gameExchangeMoney.getGameAccount()));
gameExchangeMoney.setCreateBy(Constants.SYSTEM);
gameExchangeMoney.setStatus(StatusType.IN_PROGRESS.getValue());
gameExchangeMoney.setStep(GameExchangeStep.CREATE_ORDER.getCode());
gameExchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
return gameExchangeMoneyService.insertGameExchangeMoney(gameExchangeMoney) > 0;
}
/**
* id
*
* @return {@link String }
*/
private String getTransactionId(GamePlatforms gamePlatforms,Integer exchangeType ,String account) {
switch (gamePlatforms) {
case AE:
return GamePlatforms.AE.getCode() + IdUtils.simpleUUID();
case JILI:
return GamePlatforms.JILI.getInfo() + IdUtils.simpleUUID();
case XK:
return GamePlatforms.XK.getCode() + IdUtils.simpleUUID();
case PG:
return gameExchangeMoneyService.getTransactionId(GamePlatforms.PG.getCode(), 32);
case PGX:
return gameExchangeMoneyService.getTransactionId(GamePlatforms.PGX.getInfo(), 17);
case FC:
return gameExchangeMoneyService.getTransactionId(GamePlatforms.FC.getInfo(), 30);
case DG:
return GamePlatforms.DG.getInfo() + IdUtils.simpleUUID();
case MT:
return GamePlatforms.MT.getCode() + IdUtils.simpleUUID();
case SA:
//判断是转入还是转出
String transactionId = "OUT" + DateUtils.dateTimeNow() + account;
if (!TransferType.ALL.getCode().equals(exchangeType)) {
transactionId = "IN" + DateUtils.dateTimeNow() + account;
}
return transactionId;
case KM:
return GamePlatforms.KM.getInfo() + IdUtils.simpleUUID();
case PGT:
return gameExchangeMoneyService.getTransactionId(GamePlatforms.PGT.getInfo(), 17);
}
throw new ApiException(ErrorCode.PLATFORM_NOT_EXIST.getCode());
}
/**
*
*
* @param gameExchangeMoney
* @return boolean
*/
@Override
public boolean doRollBack(GameExchangeDTO gameExchangeMoney) {
gameExchangeMoney.setStep(GameExchangeStep.CREATE_ORDER.getCode());
gameExchangeMoney.setStepStatus(GameExchangeStepStatus.FAILURE.getCode());
gameExchangeMoney.setStatus(StatusType.FAILURE.getValue());
gameExchangeMoney.setUpdateBy(Constants.SYSTEM);
gameExchangeMoney.setUpdateTime(DateUtils.getNowDate());
return gameExchangeMoneyService.updateGameExchangeMoney(gameExchangeMoney) > 0;
}
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep nextStepProcessor() {
return GameExchangeStep.DEDUCT_BALANCE;
}
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep backStepProcessor() {
return null;
}
}

View File

@ -0,0 +1,189 @@
package com.ff.game.api.exchange.impl;
import com.ff.base.constant.Constants;
import com.ff.base.enums.*;
import com.ff.base.exception.base.ApiException;
import com.ff.base.utils.DateUtils;
import com.ff.base.utils.QuotaUtils;
import com.ff.base.utils.StringUtils;
import com.ff.base.utils.uuid.IdUtils;
import com.ff.common.domain.TenantGameQuota;
import com.ff.common.domain.TenantGameQuotaFlow;
import com.ff.common.dto.BalanceChangesDTO;
import com.ff.common.dto.GameBalanceExchange;
import com.ff.common.service.ITenantGameQuotaFlowService;
import com.ff.common.service.ITenantGameQuotaService;
import com.ff.game.api.exchange.AbstractStepProcessor;
import com.ff.game.api.exchange.StepProcessorFactory;
import com.ff.game.api.exchange.dto.GameExchangeDTO;
import com.ff.game.domain.GameExchangeMoney;
import com.ff.game.domain.KeyInfo;
import com.ff.game.domain.Platform;
import com.ff.game.service.IGameExchangeMoneyService;
import com.ff.game.service.IPlatformService;
import com.ff.member.service.IMemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
/**
* impl
*
* @author shi
* @date 2025/04/09
*/
@Service
@Order(2)
public class DeductBalanceServiceImpl extends AbstractStepProcessor {
@Resource
private IGameExchangeMoneyService gameExchangeMoneyService;
@Resource
private ITenantGameQuotaService tenantGameQuotaService;
@Resource
private IMemberService memberService;
@Resource
private IPlatformService platformService;
@Resource
private ITenantGameQuotaFlowService tenantGameQuotaFlowService;
@Autowired
private PlatformTransactionManager transactionManager;
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep stepKey() {
return GameExchangeStep.DEDUCT_BALANCE;
}
/**
* do
*
* @param gameExchangeMoney
* @return boolean
*/
@Override
public boolean doProcess(GameExchangeDTO gameExchangeMoney) {
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
Boolean result = transactionTemplate.execute(transactionStatus -> {
//如果不是之前的步骤代码执行过了
if (!gameExchangeMoney.getStep().equals(this.backStepProcessor().getCode())) {
return Boolean.TRUE;
}
//不是转入操作
if (!TransferType.GAMES.getCode().equals(gameExchangeMoney.getExchangeType())) {
gameExchangeMoney.setStep(GameExchangeStep.DEDUCT_BALANCE.getCode());
gameExchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
return gameExchangeMoneyService.updateGameExchangeMoney(gameExchangeMoney) > 0;
}
Platform platform = platformService.get(gameExchangeMoney.getPlatformCode());
KeyInfo keyInfo = null;
for (KeyInfo keyData : platform.getKeyInfo()) {
if (StringUtils.isNotEmpty(gameExchangeMoney.getCurrencyCode())) {
if (keyData.getCurrency().equalsIgnoreCase(gameExchangeMoney.getCurrencyCode())) {
keyInfo = keyData;
break;
}
}
}
BigDecimal decimal = tenantGameQuotaService.gameBalanceExchange(GameBalanceExchange.builder()
.platformCode(gameExchangeMoney.getPlatformCode())
.sourceId(String.valueOf(gameExchangeMoney.getId()))
.currencyCode(gameExchangeMoney.getCurrencyCode())
.currency(gameExchangeMoney.getCurrencyCode())
.transferType(gameExchangeMoney.getExchangeType())
.amount(gameExchangeMoney.getBalance())
.account(memberService.selectMemberById(gameExchangeMoney.getMemberId()).getMemberAccount())
.tenantKey(gameExchangeMoney.getTenantKey())
.systemCurrency(gameExchangeMoney.getCurrencyCode())
.agentId(keyInfo.getCode())
.isAll(Boolean.TRUE)
.agentKey(keyInfo.getKey())
.build());
gameExchangeMoney.setQuota(decimal);
gameExchangeMoney.setStep(GameExchangeStep.DEDUCT_BALANCE.getCode());
gameExchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
return gameExchangeMoneyService.updateGameExchangeMoney(gameExchangeMoney) > 0;
});
return Boolean.TRUE.equals(result);
}
/**
*
*
* @param gameExchangeMoney
* @return boolean
*/
@Override
public boolean doRollBack(GameExchangeDTO gameExchangeMoney) {
//如果不是之前的步骤代码执行过了 或者是转入操作
if (!gameExchangeMoney.getStep().equals(this.stepKey().getCode())) {
return Boolean.TRUE;
}
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
List<TenantGameQuotaFlow> tenantGameQuotaFlows = tenantGameQuotaFlowService.selectTenantGameQuotaFlowList(
TenantGameQuotaFlow.builder()
.sourceId(String.valueOf(gameExchangeMoney.getId()))
.isOut(Boolean.FALSE)
.build());
//取出第一个
TenantGameQuotaFlow tenantGameQuotaFlow = tenantGameQuotaFlows.get(0);
return tenantGameQuotaService.balanceChanges(BalanceChangesDTO.builder()
.isOut(Boolean.TRUE)
.platformCode(tenantGameQuotaFlow.getPlatformCode())
.currencyCode(tenantGameQuotaFlow.getCurrencyCode())
.tenantKey(tenantGameQuotaFlow.getTenantKey())
.balance(tenantGameQuotaFlow.getBalance())
.sourceId(tenantGameQuotaFlow.getSourceId())
.memberId(gameExchangeMoney.getMemberId())
.operationType(OperationType.API_BALANCE.getCode())
.remark(OperationType.API_BALANCE.getDescription())
.quotaType(tenantGameQuotaFlow.getQuotaType()).build());
}
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep nextStepProcessor() {
return GameExchangeStep.PLATFORM_TRANSACTION;
}
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep backStepProcessor() {
{
return GameExchangeStep.CREATE_ORDER;
}
}
}

View File

@ -0,0 +1,221 @@
package com.ff.game.api.exchange.impl;
import com.ff.base.constant.Constants;
import com.ff.base.enums.*;
import com.ff.base.exception.base.ApiException;
import com.ff.base.utils.StringUtils;
import com.ff.common.domain.TenantGameQuotaFlow;
import com.ff.common.dto.BalanceChangesDTO;
import com.ff.common.dto.GameBalanceExchange;
import com.ff.common.service.ITenantGameQuotaFlowService;
import com.ff.common.service.ITenantGameQuotaService;
import com.ff.game.api.IGamesService;
import com.ff.game.api.exchange.AbstractStepProcessor;
import com.ff.game.api.exchange.dto.GameExchangeDTO;
import com.ff.game.api.request.ExchangeTransferMoneyRequestDTO;
import com.ff.game.api.request.ExchangeTransferStatusRequestDTO;
import com.ff.game.api.request.ExchangeTransferStatusResponseDTO;
import com.ff.game.domain.GameExchangeMoney;
import com.ff.game.domain.KeyInfo;
import com.ff.game.domain.Platform;
import com.ff.game.service.IGameExchangeMoneyService;
import com.ff.game.service.IPlatformService;
import com.ff.member.domain.Member;
import com.ff.member.service.IMemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
*
*
* @author shi
* @date 2025/04/09
*/
@Service
@Order(3)
public class PlatformTransactionServiceImpl extends AbstractStepProcessor {
@Resource
private IGameExchangeMoneyService gameExchangeMoneyService;
@Resource
private IMemberService memberService;
@Resource
private IPlatformService platformService;
@Autowired
private Map<String, IGamesService> gamesService;
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep stepKey() {
return GameExchangeStep.PLATFORM_TRANSACTION;
}
/**
* do
*
* @param gameExchangeMoney
* @return boolean
*/
@Override
public boolean doProcess(GameExchangeDTO gameExchangeMoney) {
//如果不是之前的步骤代码执行过了
if (!gameExchangeMoney.getStep().equals(this.backStepProcessor().getCode())) {
return Boolean.TRUE;
}
Platform platform = platformService.get(gameExchangeMoney.getPlatformCode());
String targetCurrency = platform.getCurrencyInfo().get(gameExchangeMoney.getCurrencyCode());
ApiException.notNull(targetCurrency, ErrorCode.CURRENCY_NOT_EXIST.getCode());
KeyInfo keyInfo = null;
for (KeyInfo keyData : platform.getKeyInfo()) {
if (StringUtils.isNotEmpty(gameExchangeMoney.getCurrencyCode())) {
if (keyData.getCurrency().equalsIgnoreCase(gameExchangeMoney.getCurrencyCode())) {
keyInfo = keyData;
break;
}
}
}
Member member = memberService.selectMemberById(gameExchangeMoney.getMemberId());
IGamesService iGamesService = gamesService.get(gameExchangeMoney.getPlatformCode() + Constants.SERVICE);
//查询订单详情
if (TriggerType.TIMER.getCode() == gameExchangeMoney.getTriggerType()) {
ExchangeTransferStatusRequestDTO exchangeTransferStatusRequestDTO = new ExchangeTransferStatusRequestDTO();
exchangeTransferStatusRequestDTO.setAccount(member.getGameAccount());
exchangeTransferStatusRequestDTO.setCurrency(targetCurrency);
exchangeTransferStatusRequestDTO.setOrderId(gameExchangeMoney.getTransactionId());
exchangeTransferStatusRequestDTO.setAgentId(keyInfo.getCode());
exchangeTransferStatusRequestDTO.setAgentKey(keyInfo.getKey());
exchangeTransferStatusRequestDTO.setGameExchangeMoneyId(gameExchangeMoney.getId());
exchangeTransferStatusRequestDTO.setVendor(platform);
exchangeTransferStatusRequestDTO.setKeyInfo(keyInfo);
exchangeTransferStatusRequestDTO.setSystemCurrency(gameExchangeMoney.getCurrencyCode());
ExchangeTransferStatusResponseDTO statusResponseDTO = iGamesService.exchangeTransferStatus(exchangeTransferStatusRequestDTO);
//订单已成功
if (StatusType.SUCCESS.getValue().equals(statusResponseDTO.getStatusType())) {
return Boolean.TRUE;
}
}
try {
//操作第三方额度接口
ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO = ExchangeTransferMoneyRequestDTO.builder()
.agentId(keyInfo.getCode())
.agentKey(keyInfo.getKey())
.account(member.getGameAccount())
.currency(targetCurrency)
.amount(gameExchangeMoney.getBalance())
.transferType(gameExchangeMoney.getExchangeType())
.transactionId(gameExchangeMoney.getTransactionId())
.gameExchangeId(gameExchangeMoney.getId())
.vendor(platform)
.keyInfo(keyInfo)
.build();
Long id = iGamesService.exchangeTransferByAgentId(exchangeTransferMoneyRequestDTO);
}catch (Exception e){
//做二次确认调订单详情接口
this.doRollBack(gameExchangeMoney);
if (GameExchangeStepStatus.FAILURE.getCode() == gameExchangeMoney.getStepStatus()){
throw new ApiException(ErrorCode.BALANCE_TRANSFER_FAILED.getCode());
}
}
GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(gameExchangeMoney.getId());
gameExchangeMoney.setBalance(exchangeMoney.getBalance());
gameExchangeMoney.setStep(exchangeMoney.getStep());
gameExchangeMoney.setStepStatus(exchangeMoney.getStepStatus());
return gameExchangeMoneyService.updateGameExchangeMoney(gameExchangeMoney) > 0;
}
/**
*
*
* @param gameExchangeMoney
* @return boolean
*/
@Override
public boolean doRollBack(GameExchangeDTO gameExchangeMoney) {
Platform platform = platformService.get(gameExchangeMoney.getPlatformCode());
String targetCurrency = platform.getCurrencyInfo().get(gameExchangeMoney.getCurrencyCode());
ApiException.notNull(targetCurrency, ErrorCode.CURRENCY_NOT_EXIST.getCode());
KeyInfo keyInfo = null;
for (KeyInfo keyData : platform.getKeyInfo()) {
if (StringUtils.isNotEmpty(gameExchangeMoney.getCurrencyCode())) {
if (keyData.getCurrency().equalsIgnoreCase(gameExchangeMoney.getCurrencyCode())) {
keyInfo = keyData;
break;
}
}
}
Member member = memberService.selectMemberById(gameExchangeMoney.getMemberId());
IGamesService iGamesService = gamesService.get(gameExchangeMoney.getPlatformCode() + Constants.SERVICE);
ExchangeTransferStatusRequestDTO exchangeTransferStatusRequestDTO = new ExchangeTransferStatusRequestDTO();
exchangeTransferStatusRequestDTO.setAccount(member.getGameAccount());
exchangeTransferStatusRequestDTO.setCurrency(targetCurrency);
exchangeTransferStatusRequestDTO.setOrderId(gameExchangeMoney.getTransactionId());
exchangeTransferStatusRequestDTO.setAgentId(keyInfo.getCode());
exchangeTransferStatusRequestDTO.setAgentKey(keyInfo.getKey());
exchangeTransferStatusRequestDTO.setGameExchangeMoneyId(gameExchangeMoney.getId());
exchangeTransferStatusRequestDTO.setVendor(platform);
exchangeTransferStatusRequestDTO.setKeyInfo(keyInfo);
exchangeTransferStatusRequestDTO.setSystemCurrency(gameExchangeMoney.getCurrencyCode());
ExchangeTransferStatusResponseDTO statusResponseDTO = iGamesService.exchangeTransferStatus(exchangeTransferStatusRequestDTO);
//订单已成功
if (StatusType.SUCCESS.getValue().equals(statusResponseDTO.getStatusType())) {
gameExchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
gameExchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
return gameExchangeMoneyService.updateGameExchangeMoney(gameExchangeMoney) > 0;
}
gameExchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
gameExchangeMoney.setStepStatus(GameExchangeStepStatus.FAILURE.getCode());
return gameExchangeMoneyService.updateGameExchangeMoney(gameExchangeMoney) > 0;
}
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep nextStepProcessor() {
return GameExchangeStep.TENANT_QUOTA_DEDUCTED;
}
/**
*
*
* @return {@link GameExchangeStep }
*/
@Override
public GameExchangeStep backStepProcessor() {
{
return GameExchangeStep.DEDUCT_BALANCE;
}
}
}

View File

@ -313,34 +313,7 @@ public class GamesFCServiceImpl implements IGamesService {
log.info("GamesFCServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO); log.info("GamesFCServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO);
Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount()); GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferMoneyRequestDTO.getGameExchangeId());
String transactionId = gameExchangeMoneyService.getTransactionId(GamePlatforms.FC.getInfo(), 30);
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
GameExchangeMoney.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.build()
);
Assert.isTrue(CollectionUtils.isEmpty(gameExchangeMonies), "订单号重复");
//获取下一个自增id
GameExchangeMoney exchangeMoney = GameExchangeMoney
.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.quota(exchangeTransferMoneyRequestDTO.getQuota())
.balance(exchangeTransferMoneyRequestDTO.getAmount())
.exchangeType(exchangeTransferMoneyRequestDTO.getTransferType())
.currencyCode(exchangeTransferMoneyRequestDTO.getSystemCurrency())
.memberId(member.getId())
.transactionId(transactionId)
.platformCode(GamePlatforms.FC.getInfo())
.build();
exchangeMoney.setCreateBy(Constants.SYSTEM);
exchangeMoney.setStatus(StatusType.IN_PROGRESS.getValue());
exchangeMoney.setStep(GameExchangeStep.CREATE_ORDER.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
//获取余额 //获取余额
@ -352,7 +325,7 @@ public class GamesFCServiceImpl implements IGamesService {
//获取当前游戏币 //获取当前游戏币
MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder() MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder()
.accounts(member.getGameAccount()) .accounts(exchangeTransferMoneyRequestDTO.getAccount())
.agentId(exchangeTransferMoneyRequestDTO.getAgentId()) .agentId(exchangeTransferMoneyRequestDTO.getAgentId())
.agentKey(exchangeTransferMoneyRequestDTO.getAgentKey()) .agentKey(exchangeTransferMoneyRequestDTO.getAgentKey())
.currency(exchangeTransferMoneyRequestDTO.getCurrency()) .currency(exchangeTransferMoneyRequestDTO.getCurrency())
@ -366,7 +339,7 @@ public class GamesFCServiceImpl implements IGamesService {
Map<String, Object> paramsMap = new HashMap<>(); Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("MemberAccount", exchangeTransferMoneyRequestDTO.getAccount()); paramsMap.put("MemberAccount", exchangeTransferMoneyRequestDTO.getAccount());
paramsMap.put("TrsID", transactionId); paramsMap.put("TrsID", exchangeTransferMoneyRequestDTO.getTransactionId());
paramsMap.put("AllOut", type); paramsMap.put("AllOut", type);
paramsMap.put("Points", amount); paramsMap.put("Points", amount);
paramsMap.putAll(getKeyMap(paramsMap, gamesBaseRequestDTO.getAgentKey(), gamesBaseRequestDTO.getCurrency(), gamesBaseRequestDTO.getAgentId())); paramsMap.putAll(getKeyMap(paramsMap, gamesBaseRequestDTO.getAgentKey(), gamesBaseRequestDTO.getCurrency(), gamesBaseRequestDTO.getAgentId()));

View File

@ -280,35 +280,10 @@ public class GamesJILIServiceImpl implements IGamesService {
public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) { public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) {
Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount()); Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount());
String transactionId = GamePlatforms.JILI.getInfo() + IdUtils.simpleUUID(); GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferMoneyRequestDTO.getGameExchangeId());
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
GameExchangeMoney.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.build()
);
Assert.isTrue(CollectionUtils.isEmpty(gameExchangeMonies), "订单号重复");
//获取下一个自增id
GameExchangeMoney exchangeMoney = GameExchangeMoney
.builder()
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.quota(exchangeTransferMoneyRequestDTO.getQuota())
.balance(exchangeTransferMoneyRequestDTO.getAmount())
.exchangeType(exchangeTransferMoneyRequestDTO.getTransferType())
.currencyCode(exchangeTransferMoneyRequestDTO.getSystemCurrency())
.memberId(member.getId())
.transactionId(transactionId)
.platformCode(GamePlatforms.JILI.getInfo())
.build();
exchangeMoney.setCreateBy(Constants.SYSTEM);
exchangeMoney.setStatus(StatusType.IN_PROGRESS.getValue());
exchangeMoney.setStep(GameExchangeStep.CREATE_ORDER.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
String query = "Account=" + exchangeTransferMoneyRequestDTO.getAccount() String query = "Account=" + exchangeTransferMoneyRequestDTO.getAccount()

View File

@ -319,41 +319,17 @@ public class GamesKMServiceImpl implements IGamesService {
log.info("GamesKMServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO); log.info("GamesKMServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO);
Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount()); GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferMoneyRequestDTO.getGameExchangeId());
String transactionId = GamePlatforms.KM.getInfo() + IdUtils.simpleUUID();
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
GameExchangeMoney.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.build()
);
Assert.isTrue(CollectionUtils.isEmpty(gameExchangeMonies), "订单号重复");
//获取下一个自增id
GameExchangeMoney exchangeMoney = GameExchangeMoney
.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.quota(exchangeTransferMoneyRequestDTO.getQuota())
.balance(exchangeTransferMoneyRequestDTO.getAmount())
.exchangeType(exchangeTransferMoneyRequestDTO.getTransferType())
.currencyCode(exchangeTransferMoneyRequestDTO.getSystemCurrency())
.memberId(member.getId())
.transactionId(transactionId)
.platformCode(GamePlatforms.KM.getInfo())
.build();
exchangeMoney.setCreateBy(Constants.SYSTEM);
exchangeMoney.setStatus(StatusType.IN_PROGRESS.getValue());
exchangeMoney.setStep(GameExchangeStep.CREATE_ORDER.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
BigDecimal amount = exchangeTransferMoneyRequestDTO.getAmount(); BigDecimal amount = exchangeTransferMoneyRequestDTO.getAmount();
if (TransferType.ALL.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType())) { if (TransferType.ALL.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType())) {
// 获取第三方钱包余额 // 获取第三方钱包余额
MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder() MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder()
.accounts(member.getGameAccount()) .accounts(exchangeTransferMoneyRequestDTO.getAccount())
.agentId(exchangeTransferMoneyRequestDTO.getAgentId()) .agentId(exchangeTransferMoneyRequestDTO.getAgentId())
.currency(exchangeTransferMoneyRequestDTO.getCurrency()) .currency(exchangeTransferMoneyRequestDTO.getCurrency())
.agentKey(exchangeTransferMoneyRequestDTO.getAgentKey()) .agentKey(exchangeTransferMoneyRequestDTO.getAgentKey())
@ -366,7 +342,7 @@ public class GamesKMServiceImpl implements IGamesService {
params.put("userid", exchangeTransferMoneyRequestDTO.getAccount()); params.put("userid", exchangeTransferMoneyRequestDTO.getAccount());
params.put("amt", amount); params.put("amt", amount);
params.put("cur", exchangeTransferMoneyRequestDTO.getCurrency()); params.put("cur", exchangeTransferMoneyRequestDTO.getCurrency());
params.put("txid", transactionId); params.put("txid", exchangeTransferMoneyRequestDTO.getTransactionId());
Map<String, Object> headerMap = this.getKey(exchangeTransferMoneyRequestDTO); Map<String, Object> headerMap = this.getKey(exchangeTransferMoneyRequestDTO);
KMTransactionResponse kmTransactionResponse; KMTransactionResponse kmTransactionResponse;

View File

@ -267,35 +267,10 @@ public class MeiTianGameServiceImpl implements IGamesService {
public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) { public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) {
Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount()); Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount());
String transactionId = GamePlatforms.MT.getCode() + IdUtils.simpleUUID(); GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferMoneyRequestDTO.getGameExchangeId());
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
GameExchangeMoney.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.build()
);
Assert.isTrue(CollectionUtils.isEmpty(gameExchangeMonies), "订单号重复");
//获取下一个自增id
GameExchangeMoney exchangeMoney = GameExchangeMoney
.builder()
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.quota(exchangeTransferMoneyRequestDTO.getQuota())
.balance(exchangeTransferMoneyRequestDTO.getAmount())
.exchangeType(exchangeTransferMoneyRequestDTO.getTransferType())
.currencyCode(exchangeTransferMoneyRequestDTO.getSystemCurrency())
.memberId(member.getId())
.transactionId(transactionId)
.platformCode(GamePlatforms.MT.getCode())
.build();
exchangeMoney.setCreateBy(Constants.SYSTEM);
exchangeMoney.setStatus(StatusType.IN_PROGRESS.getValue());
exchangeMoney.setStep(GameExchangeStep.CREATE_ORDER.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
String key = exchangeTransferMoneyRequestDTO.getAgentKey(); String key = exchangeTransferMoneyRequestDTO.getAgentKey();
String merchantId = exchangeTransferMoneyRequestDTO.getAgentId(); String merchantId = exchangeTransferMoneyRequestDTO.getAgentId();
@ -314,7 +289,7 @@ public class MeiTianGameServiceImpl implements IGamesService {
Map<String, String> rawMap = new LinkedHashMap<>(); Map<String, String> rawMap = new LinkedHashMap<>();
rawMap.put("merchantId", merchantId); rawMap.put("merchantId", merchantId);
rawMap.put("playerName", playerName); rawMap.put("playerName", playerName);
rawMap.put("extTransId", transactionId); rawMap.put("extTransId", exchangeTransferMoneyRequestDTO.getTransactionId());
rawMap.put("coins", coins); rawMap.put("coins", coins);
String rawData = JSON.toJSONString(rawMap); String rawData = JSON.toJSONString(rawMap);
String data = null; String data = null;
@ -333,7 +308,7 @@ public class MeiTianGameServiceImpl implements IGamesService {
merchantId, merchantId,
playerName, playerName,
coins, coins,
transactionId, exchangeTransferMoneyRequestDTO.getTransactionId(),
md5Code, md5Code,
data data
); );
@ -366,7 +341,7 @@ public class MeiTianGameServiceImpl implements IGamesService {
merchantId, merchantId,
playerName, playerName,
coins, coins,
transactionId, exchangeTransferMoneyRequestDTO.getTransactionId(),
md5Code, md5Code,
data data
); );

View File

@ -285,41 +285,15 @@ public class GamesPGServiceImpl implements IGamesService {
log.info("GamesNGServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO); log.info("GamesNGServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO);
Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount()); GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferMoneyRequestDTO.getGameExchangeId());
String transactionId = gameExchangeMoneyService.getTransactionId(GamePlatforms.PG.getCode(), 32);
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
GameExchangeMoney.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.build()
);
Assert.isTrue(CollectionUtils.isEmpty(gameExchangeMonies), "订单号重复");
//获取下一个自增id
GameExchangeMoney exchangeMoney = GameExchangeMoney
.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.quota(exchangeTransferMoneyRequestDTO.getQuota())
.balance(exchangeTransferMoneyRequestDTO.getAmount())
.exchangeType(exchangeTransferMoneyRequestDTO.getTransferType())
.currencyCode(exchangeTransferMoneyRequestDTO.getSystemCurrency())
.memberId(member.getId())
.transactionId(transactionId)
.platformCode(GamePlatforms.PG.getCode())
.build();
exchangeMoney.setCreateBy(Constants.SYSTEM);
exchangeMoney.setStatus(StatusType.IN_PROGRESS.getValue());
exchangeMoney.setStep(GameExchangeStep.CREATE_ORDER.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
//获取余额 //获取余额
String type = TransferType.ALL.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType()) ? NGTransferType.TRANSFER_OUT.getValue() : NGTransferType.TRANSFER_IN.getValue(); String type = TransferType.ALL.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType()) ? NGTransferType.TRANSFER_OUT.getValue() : NGTransferType.TRANSFER_IN.getValue();
//获取当前游戏币 //获取当前游戏币
MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder() MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder()
.accounts(member.getGameAccount()) .accounts(exchangeTransferMoneyRequestDTO.getAccount())
.agentId(exchangeTransferMoneyRequestDTO.getAgentId()) .agentId(exchangeTransferMoneyRequestDTO.getAgentId())
.agentKey(exchangeTransferMoneyRequestDTO.getAgentKey()) .agentKey(exchangeTransferMoneyRequestDTO.getAgentKey())
.currency(exchangeTransferMoneyRequestDTO.getCurrency()) .currency(exchangeTransferMoneyRequestDTO.getCurrency())
@ -337,7 +311,7 @@ public class GamesPGServiceImpl implements IGamesService {
paramsMap.put("currency", exchangeTransferMoneyRequestDTO.getCurrency()); paramsMap.put("currency", exchangeTransferMoneyRequestDTO.getCurrency());
paramsMap.put("type", type); paramsMap.put("type", type);
paramsMap.put("amount", exchangeTransferMoneyRequestDTO.getAmount()); paramsMap.put("amount", exchangeTransferMoneyRequestDTO.getAmount());
paramsMap.put("orderId", transactionId); paramsMap.put("orderId", exchangeTransferMoneyRequestDTO.getTransactionId());
Map<String, String> key = this.getKey(exchangeTransferMoneyRequestDTO); Map<String, String> key = this.getKey(exchangeTransferMoneyRequestDTO);

View File

@ -268,39 +268,11 @@ public class GamesPGTServiceImpl implements IGamesService {
public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) { public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) {
log.info("GamesPGTServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO); log.info("GamesPGTServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO);
String currency = exchangeTransferMoneyRequestDTO.getCurrency();
Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount()); GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferMoneyRequestDTO.getGameExchangeId());
String transactionId = gameExchangeMoneyService.getTransactionId(GamePlatforms.PGX.getInfo(), 17);
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
GameExchangeMoney.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.build()
);
Assert.isTrue(CollectionUtils.isEmpty(gameExchangeMonies), "订单号重复");
//获取下一个自增id
GameExchangeMoney exchangeMoney = GameExchangeMoney
.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.quota(exchangeTransferMoneyRequestDTO.getQuota())
.balance(exchangeTransferMoneyRequestDTO.getAmount())
.exchangeType(exchangeTransferMoneyRequestDTO.getTransferType())
.currencyCode(currency)
.memberId(member.getId())
.transactionId(transactionId)
.platformCode(GamePlatforms.PGT.getInfo())
.build();
exchangeMoney.setCreateBy(Constants.SYSTEM);
exchangeMoney.setStatus(StatusType.IN_PROGRESS.getValue());
exchangeMoney.setStep(GameExchangeStep.CREATE_ORDER.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
BigDecimal amount = exchangeTransferMoneyRequestDTO.getAmount(); BigDecimal amount = exchangeTransferMoneyRequestDTO.getAmount();
BigDecimal amountBefore = BigDecimal.ZERO; BigDecimal amountBefore = BigDecimal.ZERO;
@ -322,7 +294,7 @@ public class GamesPGTServiceImpl implements IGamesService {
Map<String, Object> paramsMap = new LinkedHashMap<>(); Map<String, Object> paramsMap = new LinkedHashMap<>();
paramsMap.put("username", exchangeTransferMoneyRequestDTO.getAccount()); paramsMap.put("username", exchangeTransferMoneyRequestDTO.getAccount());
paramsMap.put("amount", amount.setScale(2, RoundingMode.DOWN).toString()); paramsMap.put("amount", amount.setScale(2, RoundingMode.DOWN).toString());
paramsMap.put("transactionRef", transactionId); paramsMap.put("transactionRef", exchangeTransferMoneyRequestDTO.getTransactionId());
paramsMap.put("productId", productId); paramsMap.put("productId", productId);
Map<String, String> key = this.getKey(exchangeTransferMoneyRequestDTO); Map<String, String> key = this.getKey(exchangeTransferMoneyRequestDTO);
PGTExchangeTransferResponse errorResponse; PGTExchangeTransferResponse errorResponse;

View File

@ -278,35 +278,9 @@ public class GamesPGXServiceImpl implements IGamesService {
log.info("GamesPGXServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO); log.info("GamesPGXServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO);
Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount()); GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferMoneyRequestDTO.getGameExchangeId());
String transactionId = gameExchangeMoneyService.getTransactionId(GamePlatforms.PGX.getInfo(), 17);
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
GameExchangeMoney.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.build()
);
Assert.isTrue(CollectionUtils.isEmpty(gameExchangeMonies), "订单号重复");
//获取下一个自增id
GameExchangeMoney exchangeMoney = GameExchangeMoney
.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.quota(exchangeTransferMoneyRequestDTO.getQuota())
.balance(exchangeTransferMoneyRequestDTO.getAmount())
.exchangeType(exchangeTransferMoneyRequestDTO.getTransferType())
.currencyCode(exchangeTransferMoneyRequestDTO.getSystemCurrency())
.memberId(member.getId())
.transactionId(transactionId)
.platformCode(GamePlatforms.PGX.getInfo())
.build();
exchangeMoney.setCreateBy(Constants.SYSTEM);
exchangeMoney.setStatus(StatusType.IN_PROGRESS.getValue());
exchangeMoney.setStep(GameExchangeStep.CREATE_ORDER.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
//获取余额 //获取余额
String type = TransferType.ALL.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType()) ? PGXTransferType.WITHDRAW.getCode() : PGXTransferType.DEPOSIT.getCode(); String type = TransferType.ALL.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType()) ? PGXTransferType.WITHDRAW.getCode() : PGXTransferType.DEPOSIT.getCode();
@ -339,7 +313,7 @@ public class GamesPGXServiceImpl implements IGamesService {
paramsMap.put("operatorcode", exchangeTransferMoneyRequestDTO.getAgentId()); paramsMap.put("operatorcode", exchangeTransferMoneyRequestDTO.getAgentId());
paramsMap.put("password", keyInfo.getPassword()); paramsMap.put("password", keyInfo.getPassword());
paramsMap.put("providercode", keyInfo.getProviderCode()); paramsMap.put("providercode", keyInfo.getProviderCode());
paramsMap.put("referenceid", transactionId); paramsMap.put("referenceid", exchangeTransferMoneyRequestDTO.getTransactionId());
paramsMap.put("type", type); paramsMap.put("type", type);
paramsMap.put("username", exchangeTransferMoneyRequestDTO.getAccount()); paramsMap.put("username", exchangeTransferMoneyRequestDTO.getAccount());
String key = this.getKey(paramsMap, exchangeTransferMoneyRequestDTO); String key = this.getKey(paramsMap, exchangeTransferMoneyRequestDTO);

View File

@ -27,15 +27,7 @@ public class ExchangeTransferMoneyRequestDTO extends GamesBaseRequestDTO {
*/ */
private String account; private String account;
/**
*
*/
private String tenantKey;
/**
* id
*/
private String orderId;
/** /**
* *
*/ */
@ -43,9 +35,14 @@ public class ExchangeTransferMoneyRequestDTO extends GamesBaseRequestDTO {
/** /**
* * id
*/ */
private BigDecimal quota; private Long gameExchangeId;
/**
*
*/
private String transactionId;
/** /**

View File

@ -256,45 +256,15 @@ public class GamesSAServiceImpl implements IGamesService {
public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) { public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) {
log.info("GamesSAServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO); log.info("GamesSAServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO);
Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount());
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList( GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferMoneyRequestDTO.getGameExchangeId());
GameExchangeMoney.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.build()
);
Assert.isTrue(CollectionUtils.isEmpty(gameExchangeMonies), "订单号重复");
//判断是转入还是转出
String transactionId = "OUT" + DateUtils.dateTimeNow() + exchangeTransferMoneyRequestDTO.getAccount();
if (!TransferType.ALL.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType())) {
transactionId = "IN" + DateUtils.dateTimeNow() + exchangeTransferMoneyRequestDTO.getAccount();
}
//获取下一个自增id
GameExchangeMoney exchangeMoney = GameExchangeMoney
.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.quota(exchangeTransferMoneyRequestDTO.getQuota())
.balance(exchangeTransferMoneyRequestDTO.getAmount())
.exchangeType(exchangeTransferMoneyRequestDTO.getTransferType())
.currencyCode(exchangeTransferMoneyRequestDTO.getSystemCurrency())
.memberId(member.getId())
.transactionId(transactionId)
.platformCode(GamePlatforms.SA.getInfo())
.build();
exchangeMoney.setCreateBy(Constants.SYSTEM);
exchangeMoney.setStatus(StatusType.IN_PROGRESS.getValue());
exchangeMoney.setStep(GameExchangeStep.CREATE_ORDER.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.SUCCESS.getCode());
gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
if (TransferType.ALL.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType())) { if (TransferType.ALL.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType())) {
Map<String, Object> params = new LinkedHashMap<>(); Map<String, Object> params = new LinkedHashMap<>();
params.put("Username", exchangeTransferMoneyRequestDTO.getAccount()); params.put("Username", exchangeTransferMoneyRequestDTO.getAccount());
params.put("OrderId", exchangeMoney.getTransactionId()); params.put("OrderId", exchangeTransferMoneyRequestDTO.getTransactionId());
String query = JsonUtil.mapToQueryString(params); String query = JsonUtil.mapToQueryString(params);
exchangeTransferMoneyRequestDTO.setQuery(query); exchangeTransferMoneyRequestDTO.setQuery(query);
String key = this.getKey(exchangeTransferMoneyRequestDTO, "DebitAllBalanceDV"); String key = this.getKey(exchangeTransferMoneyRequestDTO, "DebitAllBalanceDV");
@ -324,7 +294,7 @@ public class GamesSAServiceImpl implements IGamesService {
} else { } else {
Map<String, Object> params = new LinkedHashMap<>(); Map<String, Object> params = new LinkedHashMap<>();
params.put("Username", exchangeTransferMoneyRequestDTO.getAccount()); params.put("Username", exchangeTransferMoneyRequestDTO.getAccount());
params.put("OrderId", exchangeMoney.getTransactionId()); params.put("OrderId", exchangeTransferMoneyRequestDTO.getTransactionId());
params.put("CreditAmount", exchangeTransferMoneyRequestDTO.getAmount().stripTrailingZeros().toPlainString()); params.put("CreditAmount", exchangeTransferMoneyRequestDTO.getAmount().stripTrailingZeros().toPlainString());
params.put("CurrencyType", exchangeTransferMoneyRequestDTO.getCurrency()); params.put("CurrencyType", exchangeTransferMoneyRequestDTO.getCurrency());
String query = JsonUtil.mapToQueryString(params); String query = JsonUtil.mapToQueryString(params);

View File

@ -61,6 +61,16 @@ public interface XKClient {
@Post(url = "/exchangeTransferByAgentId") @Post(url = "/exchangeTransferByAgentId")
XKExchangeMoneyResponseDTO exchangeTransferByAgentId( @JSONBody Map<String, Object> params); XKExchangeMoneyResponseDTO exchangeTransferByAgentId( @JSONBody Map<String, Object> params);
/**
* id
*
* @param params
* @return {@link XKCheckTransferByTransactionIdDTO }
*/
@Post(url = "/getTransferRecordByTransactionId")
XKCheckTransferByTransactionIdDTO checkTransferByTransactionId( @JSONBody Map<String, Object> params);
/** /**
* *
* *

View File

@ -0,0 +1,76 @@
package com.ff.game.api.xk.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* xkcheckid dto
*
* @author shi
* @date 2025/04/09
*/
@Data
public class XKCheckTransferByTransactionIdDTO {
/**
*
*/
@JsonProperty("code")
private Integer code;
/**
*
*/
@JsonProperty("msg")
private String msg;
/**
*
*/
@JsonProperty("data")
private TransactionData data;
/**
*
*/
@Data
public static class TransactionData {
/**
*
*/
@JsonProperty("account")
private String account;
/**
*
*/
@JsonProperty("transactionId")
private String transactionId;
/**
*
*/
@JsonProperty("transferTime")
private Long transferTime;
/**
* Decimal(16,4)
*/
@JsonProperty("amount")
private BigDecimal amount;
/**
*
*/
@JsonProperty("transferType")
private Integer transferType;
/**
*
*/
@JsonProperty("status")
private Integer status;
}
}

View File

@ -188,7 +188,7 @@ public class GamesXKServiceImpl implements IGamesService {
params.put("key", key); params.put("key", key);
params.put("disableFullScreen", gamesLogin.getDisableFullScreen()); params.put("disableFullScreen", gamesLogin.getDisableFullScreen());
params.put("homeUrl", gamesLogin.getHomeUrl()); params.put("homeUrl", gamesLogin.getHomeUrl());
params.put("platform", gamesLogin.getVendor()); params.put("platform", gamesLogin.getPlatform());
XKLoginWithoutRedirectResponseDTO xkLoginWithoutRedirectResponseDTO = xkClient.loginWithoutRedirect(params); XKLoginWithoutRedirectResponseDTO xkLoginWithoutRedirectResponseDTO = xkClient.loginWithoutRedirect(params);
//判断是否获取成功 //判断是否获取成功
if (this.getIsSuccess(xkLoginWithoutRedirectResponseDTO.getCode())) { if (this.getIsSuccess(xkLoginWithoutRedirectResponseDTO.getCode())) {
@ -243,7 +243,7 @@ public class GamesXKServiceImpl implements IGamesService {
game.setPlatformType(platformType); game.setPlatformType(platformType);
game.setGameName(gamesDataDTO.getName()); game.setGameName(gamesDataDTO.getName());
game.setCreateBy(Constants.SYSTEM); game.setCreateBy(Constants.SYSTEM);
game.setGameId(StringUtils.addSuffix(GamePlatforms.SA.getCode(), 1)); game.setGameId(StringUtils.addSuffix(GamePlatforms.XK.getCode(), gamesDataDTO.getGameId()));
List<NameInfo> nameInfos = new ArrayList<>(); List<NameInfo> nameInfos = new ArrayList<>();
nameInfos.add(new NameInfo(gamesDataDTO.getName(), "zh-CN")); nameInfos.add(new NameInfo(gamesDataDTO.getName(), "zh-CN"));
game.setNameInfo(nameInfos); game.setNameInfo(nameInfos);
@ -276,40 +276,16 @@ public class GamesXKServiceImpl implements IGamesService {
@Transactional @Transactional
public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) { public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) {
log.info("GamesXKServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO); log.info("GamesXKServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO);
// GameSecretKeyCurrency currencyDTO = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
// .platformCode(GamePlatforms.XK.getInfo())
// .code(exchangeTransferMoneyRequestDTO.getAgentId())
// .build());
Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount());
String transactionId = GamePlatforms.XK.getCode() + IdUtils.simpleUUID();
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
GameExchangeMoney.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.build()
);
Assert.isTrue(CollectionUtils.isEmpty(gameExchangeMonies), "订单号重复");
//获取下一个自增id GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferMoneyRequestDTO.getGameExchangeId());
GameExchangeMoney exchangeMoney = GameExchangeMoney
.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.quota(exchangeTransferMoneyRequestDTO.getQuota())
.balance(exchangeTransferMoneyRequestDTO.getAmount())
.exchangeType(exchangeTransferMoneyRequestDTO.getTransferType())
.currencyCode(exchangeTransferMoneyRequestDTO.getSystemCurrency())
.memberId(member.getId())
.transactionId(transactionId)
.platformCode(GamePlatforms.XK.getCode())
.build();
exchangeMoney.setCreateBy(Constants.SYSTEM);
//接口限制限制50字符
exchangeMoney.setTransactionId(GamePlatforms.XK.getCode() + IdUtils.simpleUUID());
Map<String, Object> params = new LinkedHashMap<>(); Map<String, Object> params = new LinkedHashMap<>();
params.put("account", exchangeTransferMoneyRequestDTO.getAccount()); params.put("account", exchangeTransferMoneyRequestDTO.getAccount());
params.put("transactionId", exchangeMoney.getTransactionId()); params.put("transactionId", exchangeTransferMoneyRequestDTO.getTransactionId());
params.put("amount", exchangeTransferMoneyRequestDTO.getAmount().stripTrailingZeros().toPlainString()); params.put("amount", exchangeTransferMoneyRequestDTO.getAmount().stripTrailingZeros().toPlainString());
params.put("transferType", exchangeTransferMoneyRequestDTO.getTransferType()); params.put("transferType", exchangeTransferMoneyRequestDTO.getTransferType());
params.put("agentId", exchangeTransferMoneyRequestDTO.getAgentId()); params.put("agentId", exchangeTransferMoneyRequestDTO.getAgentId());
@ -329,9 +305,16 @@ public class GamesXKServiceImpl implements IGamesService {
exchangeMoney.setCoinAfter(exchangeMoneyResponseData.getCoinAfter()); exchangeMoney.setCoinAfter(exchangeMoneyResponseData.getCoinAfter());
exchangeMoney.setCurrencyBefore(exchangeMoneyResponseData.getCurrencyBefore()); exchangeMoney.setCurrencyBefore(exchangeMoneyResponseData.getCurrencyBefore());
exchangeMoney.setCurrencyAfter(exchangeMoneyResponseData.getCurrencyAfter()); exchangeMoney.setCurrencyAfter(exchangeMoneyResponseData.getCurrencyAfter());
exchangeMoney.setStatus(exchangeMoneyResponseData.getStatus());
gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney); exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
exchangeMoney.setStepStatus(exchangeMoneyResponseData.getStatus());
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
} else { } else {
exchangeMoney.setStep(GameExchangeStep.PLATFORM_TRANSACTION.getCode());
exchangeMoney.setStepStatus(GameExchangeStepStatus.FAILURE.getCode());
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
log.error("GamesXKServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误代码{},错误信息{}", exchangeMoneyResponse.getCode(), exchangeMoneyResponse.getMsg()); log.error("GamesXKServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误代码{},错误信息{}", exchangeMoneyResponse.getCode(), exchangeMoneyResponse.getMsg());
throw new BaseException(exchangeMoneyResponse.getMsg()); throw new BaseException(exchangeMoneyResponse.getMsg());
} }
@ -347,7 +330,27 @@ public class GamesXKServiceImpl implements IGamesService {
*/ */
@Override @Override
public ExchangeTransferStatusResponseDTO exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO) { public ExchangeTransferStatusResponseDTO exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO) {
return new ExchangeTransferStatusResponseDTO(); Map<String, Object> params = new LinkedHashMap<>();
params.put("transactionId", exchangeTransferMoneyRequestDTO.getOrderId());
params.put("agentId", exchangeTransferMoneyRequestDTO.getAgentId());
String query = JsonUtil.mapToQueryString(params);
exchangeTransferMoneyRequestDTO.setQuery(query);
String key = this.getKey(exchangeTransferMoneyRequestDTO);
params.put("key", key);
XKCheckTransferByTransactionIdDTO xkCheckTransferByTransactionIdDTO = xkClient.checkTransferByTransactionId(params);
//判断是否转移成功
if (this.getIsSuccess(xkCheckTransferByTransactionIdDTO.getCode())) {
XKCheckTransferByTransactionIdDTO.TransactionData data = xkCheckTransferByTransactionIdDTO.getData();
return ExchangeTransferStatusResponseDTO.builder()
.statusType(data.getStatus())
.balance(data.getAmount())
.build();
} else {
return ExchangeTransferStatusResponseDTO.builder()
.statusType(StatusType.FAILURE.getValue())
.build();
}
} }
@ -359,7 +362,6 @@ public class GamesXKServiceImpl implements IGamesService {
*/ */
@Override @Override
public Boolean getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) { public Boolean getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) {
// List<GameBettingDetails> gameBettingDetails = new ArrayList<>();
//请求参数 //请求参数
log.info("GamesXKServiceImpl [getBetRecordByTime] 请求参数 {}", betRecordByTimeDTO); log.info("GamesXKServiceImpl [getBetRecordByTime] 请求参数 {}", betRecordByTimeDTO);
Map<String, Object> params = new LinkedHashMap<>(); Map<String, Object> params = new LinkedHashMap<>();
@ -416,7 +418,51 @@ public class GamesXKServiceImpl implements IGamesService {
*/ */
@Override @Override
public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO betRecordByTimeDTO) { public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO betRecordByTimeDTO) {
return null; //请求参数
log.info("GamesXKServiceImpl [getBetRecordByHistoryTime] 请求参数 {}", betRecordByTimeDTO);
Map<String, Object> params = new LinkedHashMap<>();
params.put("startTime", betRecordByTimeDTO.getStartTime());
params.put("endTime", betRecordByTimeDTO.getEndTime());
params.put("page", betRecordByTimeDTO.getPage());
params.put("pageLimit", betRecordByTimeDTO.getPageLimit());
params.put("agentId", betRecordByTimeDTO.getAgentId());
String query = JsonUtil.mapToQueryString(params);
betRecordByTimeDTO.setQuery(query);
String key = this.getKey(betRecordByTimeDTO);
params.put("key", key);
XKBetRecordResponseDTO xkBetRecordResponseDTO = xkClient.getBetRecordByTime(params);
//判断是否获取成功
if (this.getIsSuccess(xkBetRecordResponseDTO.getCode())) {
//数据组装
XKBetRecordResponseDTO.DataBean dataBean = xkBetRecordResponseDTO.getData();
this.batchInsert(xkBetRecordResponseDTO, betRecordByTimeDTO);
//获取下一页数据
while (!Objects.equals(dataBean.getCurrentPage(), dataBean.getTotalPages()) && dataBean.getTotalPages() > 0) {
betRecordByTimeDTO.setPage(dataBean.getCurrentPage() + 1);
//请求参数
params = new LinkedHashMap<>();
params.put("startTime", betRecordByTimeDTO.getStartTime());
params.put("endTime", betRecordByTimeDTO.getEndTime());
params.put("page", betRecordByTimeDTO.getPage());
params.put("pageLimit", betRecordByTimeDTO.getPageLimit());
params.put("agentId", betRecordByTimeDTO.getAgentId());
query = JsonUtil.mapToQueryString(params);
betRecordByTimeDTO.setQuery(query);
key = this.getKey(betRecordByTimeDTO);
params.put("key", key);
xkBetRecordResponseDTO = xkClient.getBetRecordByTime(params);
dataBean = xkBetRecordResponseDTO.getData();
this.batchInsert(xkBetRecordResponseDTO, betRecordByTimeDTO);
}
return Boolean.TRUE;
} else {
log.error("GamesXKServiceImpl [getBetRecordByHistoryTime] 获取投注记录失败,错误代码{},错误信息{}", xkBetRecordResponseDTO.getCode(), xkBetRecordResponseDTO.getMsg());
throw new BaseException(xkBetRecordResponseDTO.getMsg());
}
} }
/** /**
@ -516,7 +562,7 @@ public class GamesXKServiceImpl implements IGamesService {
* *
* @param xkBetRecordResponseDTO xkdto * @param xkBetRecordResponseDTO xkdto
*/ */
private void batchInsert(XKBetRecordResponseDTO xkBetRecordResponseDTO, BetRecordByTimeDTO betRecordByTimeDTO) { private synchronized void batchInsert(XKBetRecordResponseDTO xkBetRecordResponseDTO, BetRecordByTimeDTO betRecordByTimeDTO) {
List<GameBettingDetails> gameBettingDetails = new ArrayList<>(); List<GameBettingDetails> gameBettingDetails = new ArrayList<>();
List<String> wagersIds = new ArrayList<>(); List<String> wagersIds = new ArrayList<>();
//数据组装 //数据组装

View File

@ -1,6 +1,7 @@
package com.ff.game.domain; package com.ff.game.domain;
import lombok.Data; import lombok.Data;
import org.springframework.util.ObjectUtils;
import java.io.Serializable; import java.io.Serializable;
import java.util.Map; import java.util.Map;
@ -13,8 +14,26 @@ public class ExtInfo implements Serializable {
// 币种信息key为其它平台的币种idvalue为我们自己的币种 // 币种信息key为其它平台的币种idvalue为我们自己的币种
private Map<String, String> currency; private Map<String, String> currency;
/**
*
*/
private Map<String, Long> timeout;
public String getOurCurrency(String currencyId) { public String getOurCurrency(String currencyId) {
return currency == null ? null : currency.get(currencyId); return currency == null ? null : currency.get(currencyId);
} }
/**
*
*
* @param key
* @return {@link Long }
*/
public Long getTimeout(String key) {
Map<String, Long> timeout = this.timeout;
if (!ObjectUtils.isEmpty(timeout) && timeout.containsKey(key)) {
return timeout.get(key);
}
return 5000L;
}
} }

View File

@ -14,6 +14,7 @@ import com.ff.game.mapper.GameExchangeMoneyMapper;
import com.ff.game.domain.GameExchangeMoney; import com.ff.game.domain.GameExchangeMoney;
import com.ff.game.service.IGameExchangeMoneyService; import com.ff.game.service.IGameExchangeMoneyService;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
/** /**
* Service * Service
@ -65,7 +66,9 @@ public class GameExchangeMoneyServiceImpl implements IGameExchangeMoneyService
@Override @Override
public int insertGameExchangeMoney(GameExchangeMoney gameExchangeMoney) public int insertGameExchangeMoney(GameExchangeMoney gameExchangeMoney)
{ {
if (ObjectUtils.isEmpty(gameExchangeMoney.getId())){
gameExchangeMoney.setId(IdUtil.getSnowflakeNextId()); gameExchangeMoney.setId(IdUtil.getSnowflakeNextId());
}
gameExchangeMoney.setCreateTime(DateUtils.getNowDate()); gameExchangeMoney.setCreateTime(DateUtils.getNowDate());
return gameExchangeMoneyMapper.insertGameExchangeMoney(gameExchangeMoney); return gameExchangeMoneyMapper.insertGameExchangeMoney(gameExchangeMoney);
} }

View File

@ -57,6 +57,9 @@
<if test="quotaType != null and quotaType != ''"> <if test="quotaType != null and quotaType != ''">
and quota_type = #{quotaType} and quota_type = #{quotaType}
</if> </if>
<if test="sourceId != null ">
and source_id = #{sourceId}
</if>
<if test="memberId != null "> <if test="memberId != null ">
and member_id = #{memberId} and member_id = #{memberId}
</if> </if>