feat(game): 添加 PGT 游戏平台支持

- 新增 PGT 游戏平台的 API接口和实现类
- 添加 PGT 游戏平台的会员账户生成逻辑
- 实现 PGT 游戏平台的余额查询、转账等功能
- 添加 PGT 游戏平台的错误响应和数据模型类
main-meitian
shi 2025-04-03 16:27:48 +08:00
parent 8ffe94204c
commit e020b73282
18 changed files with 1163 additions and 24 deletions

View File

@ -13,7 +13,8 @@ public enum GamePlatforms {
DG("DG", "DG"),
MeiTian("MeiTian","美天棋牌"),
AE("AE", "AE"),
KM("KM", "KM")
KM("KM", "KM"),
PGT("PGT", "PGT"),
;
private final String code;

View File

@ -9,7 +9,6 @@ import java.util.concurrent.ThreadLocalRandom;
public class NumberUtils {
/**
*
*
@ -68,17 +67,13 @@ public class NumberUtils {
Random random = new Random();
StringBuilder sb = new StringBuilder();
// 每位字符可以是字母A-Z, a-z或数字0-9
for (int i = 0; i <size ; i++) {
int choice = random.nextInt(3);
// 每位字符可以是大写字母A-Z或数字0-9
for (int i = 0; i < size; i++) {
int choice = random.nextInt(2);
if (choice == 0) {
// 随机字母(大写或小写)
// 随机大写字母
char letter = (char) ('A' + random.nextInt(26));
sb.append(letter);
} else if (choice == 1) {
// 随机小写字母
char letter = (char) ('a' + random.nextInt(26));
sb.append(letter);
} else {
// 随机数字
sb.append(random.nextInt(10));
@ -88,4 +83,5 @@ public class NumberUtils {
return sb.toString();
}
}

View File

@ -104,7 +104,7 @@ public class ApiMemberController extends BaseController {
ApiException.notNull(gameSecretKey, ErrorCode.CURRENCY_NOT_EXIST.getCode());
String gameAccount = StringUtils.addSuffix(memberService.getMemberGameAccount(memberCreateApiRequest.getPlatformCode()), tenantSecretKey.getTenantSn());
String gameAccount =memberService.getMemberGameAccount(memberCreateApiRequest.getPlatformCode(), tenantSecretKey.getTenantSn());
// 获取用户信息

View File

@ -2,13 +2,10 @@ package com.ff.game.api.km.client;
import com.dtflys.forest.annotation.*;
import com.ff.game.api.dg.dto.DGBetRecordResponseDTO;
import com.ff.game.api.dg.dto.DGResponse;
import com.ff.game.api.dg.dto.DGUserListResponseDTO;
import com.ff.game.api.km.address.MyKMAddressSource;
import com.ff.game.api.km.dto.*;
import com.ff.game.api.km.success.MyKMSuccessCondition;
import com.ff.game.api.xk.dto.XKBetRecordResponseDTO;
import com.ff.game.api.success.MySuccessCondition;
import java.util.Map;
@ -19,7 +16,7 @@ import java.util.Map;
* @date 2025/02/10
*/
@Address(source = MyKMAddressSource.class)
@Success(condition = MyKMSuccessCondition.class)
@Success(condition = MySuccessCondition.class)
public interface KMClient {
/**
*

View File

@ -0,0 +1,30 @@
package com.ff.game.api.pgt.address;
import com.dtflys.forest.callback.AddressSource;
import com.dtflys.forest.http.ForestAddress;
import com.dtflys.forest.http.ForestRequest;
import com.ff.base.constant.Constants;
import com.ff.base.system.service.ISysConfigService;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* pt
*
* @author shi
* @date 2025/02/10
*/
@Component
public class MyPGTAddressSource implements AddressSource {
@Resource
private ISysConfigService configService;
@Override
public ForestAddress getAddress(ForestRequest request) {
return new ForestAddress("https","test.ambsuperapi.com", 443,"");
}
}

View File

@ -0,0 +1,132 @@
package com.ff.game.api.pgt.client;
import com.dtflys.forest.annotation.*;
import com.ff.game.api.dg.dto.DGResponse;
import com.ff.game.api.jili.dto.JILIKickMemberAllDTO;
import com.ff.game.api.jili.dto.JILIKickMemberDTO;
import com.ff.game.api.ng.dto.ApiExchangeTransferStatusResponseDTO;
import com.ff.game.api.ng.dto.ApiNGResponseDTO;
import com.ff.game.api.pgt.address.MyPGTAddressSource;
import com.ff.game.api.pgt.dto.*;
import com.ff.game.api.success.MySuccessCondition;
import com.ff.game.api.xk.dto.XKKickMemberAllDTO;
import java.util.Map;
/**
* pt
*
* @author shi
* @date 2025/02/10
*/
@Address(source = MyPGTAddressSource.class)
@Success(condition = MySuccessCondition.class)
public interface PGTClient {
/**
*
*
* @param parameters
* @param headerMap
* @return {@link String }
*/
@Post("/member")
PGTCreateMemberResponse createMember(@JSONBody Map<String, Object> parameters, @Header Map<String, String> headerMap);
/**
*
*
* @param parameters
* @return {@link PGTBalanceResponse }
*/
@Get("/balance?${parameters}")
PGTBalanceResponse getMemberInfo(@Var("parameters") String parameters, @Header Map<String, String> headerMap);
/**
* JD.
*
* @param parameters
* @return {@link PGXPlayerStatusResponse }
*/
@Get("/isPlayerIngame.ashx?${parameters}")
PGXPlayerStatusResponse getMemberPlayInfo(@Var("parameters") String parameters);
/**
*
*
* @param parameters
* @return {@link PGXGameLoginResponse }
*/
@Post("/launchGames.aspx?${parameters}")
PGXGameLoginResponse loginWithoutRedirect(@Var("parameters") String parameters);
/**
* id
*
* @param parameters
* @return {@link PGXErrorResponse }
*/
@Post(url = "/makeTransfer.aspx?{parameters}")
PGXErrorResponse exchangeTransferByAgentId(@Var("parameters") String parameters);
/**
*
*
* @return {@link DGResponse }
*/
@Post(url = "markbyjson.aspx")
DGResponse markReport(@JSONBody Map<String, Object> params);
/**
*
*
* @param parameters
* @return {@link ApiNGResponseDTO }<{@link ApiExchangeTransferStatusResponseDTO }>
*/
@Post(url = "/checkTransaction.ashx?{parameters}")
PGXExchangeTransferStatusResponse exchangeTransferStatus(@Var("parameters") String parameters);
/**
*
*
* @return {@link PGXBetHistoryResponse }
*/
@Get(url = "/fetchbykey.aspx?{parameters}")
PGXBetHistoryResponse getBetRecordByTime(@Var("parameters") String parameters);
@Get(url = "h/fetchArchieve.aspx?{parameters}")
PGXBetHistoryResponse getBetRecordByHistoryTime(@Var("parameters") String parameters);
/**
*
*
* @param parameters
* @return {@link JILIKickMemberDTO }
*/
@Post("/kickPlayerFromProduct.ashx?{parameters}")
PGXErrorResponse kickMember(@Var("parameters") String parameters);
/**
*
*
* @param params
* @return {@link JILIKickMemberAllDTO }
*/
@Get("/kickMemberAll")
XKKickMemberAllDTO kickMemberAll(@JSONBody Map<String, Object> params);
}

View File

@ -0,0 +1,62 @@
package com.ff.game.api.pgt.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* PG
*
* @author shi
* @date 2025/04/03
*/
@Data
public class PGTBalanceResponse {
/**
*
*/
@JsonProperty("reqId")
private String reqId;
/**
* 0
*/
@JsonProperty("code")
private int code;
/**
*
*/
@JsonProperty("message")
private String message;
/**
*
*/
@JsonProperty("data")
private BalanceData data;
@Data
public static class BalanceData {
/**
*
*/
@JsonProperty("username")
private String username;
/**
* productId
*/
@JsonProperty("balance")
private BigDecimal balance;
/**
*
*/
@JsonProperty("status")
private String status;
}
}

View File

@ -0,0 +1,60 @@
package com.ff.game.api.pgt.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
* pgtcreate
*
* @author shi
* @date 2025/04/03
*/
@Data
public class PGTCreateMemberResponse {
/**
*
*/
@JsonProperty("reqId")
private String reqId;
/**
* 0
*/
@JsonProperty("code")
private int code;
/**
*
*/
@JsonProperty("message")
private String message;
/**
*
*/
@JsonProperty("data")
private ResponseData data;
@Data
public static class ResponseData {
/**
*
*/
@JsonProperty("username")
private String username;
/**
*
*/
@JsonProperty("currency")
private String currency;
/**
*
*/
@JsonProperty("status")
private String status;
}
}

View File

@ -0,0 +1,148 @@
package com.ff.game.api.pgt.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
*
*
* @author shi
* @date 2025/03/28
*/
@Data
public class PGXBetHistoryResponse {
/**
*
*/
@JsonProperty("errCode")
private Integer errCode;
/**
* JSON (String)
*/
@JsonProperty("result")
private String result;
/**
* (String)
*/
@JsonProperty("errMsg")
private String errMsg;
/**
* AIO
*/
@Data
public class Result {
/**
* AIO () (Long)
*/
@JsonProperty("id")
private Long id;
/**
* (Long)
*/
@JsonProperty("ref_no")
private Long refNo;
/**
* (String)
*/
@JsonProperty("site")
private String site;
/**
* (String)
*/
@JsonProperty("product")
private String product;
/**
* (String)
*/
@JsonProperty("member")
private String member;
/**
* (String)
*/
@JsonProperty("game_id")
private String gameId;
/**
* () GMT/UTC +0
*/
@JsonProperty("start_time")
private Date startTime;
/**
* (String) GMT/UTC +0
*/
@JsonProperty("end_time")
private Date endTime;
/**
* (String) GMT/UTC +0
*/
@JsonProperty("match_time")
private String matchTime;
/**
* (String)
*/
@JsonProperty("bet_detail")
private String betDetail;
/**
* (Double)
*/
@JsonProperty("turnover")
private BigDecimal turnover;
/**
* (Double)
*/
@JsonProperty("bet")
private BigDecimal bet;
/**
* (Double)
*/
@JsonProperty("payout")
private BigDecimal payout;
/**
* (Double)
*/
@JsonProperty("commission")
private BigDecimal commission;
/**
* (Double)
*/
@JsonProperty("p_share")
private BigDecimal pShare;
/**
* (Double)
*/
@JsonProperty("p_win")
private BigDecimal pWin;
/**
* (Int)
* 1 (valid bet record )
* 0 (running/ongoing match )
* -1 (invalid bet record e.g. voided , canceled )
*/
@JsonProperty("status")
private int status;
}
}

View File

@ -0,0 +1,26 @@
package com.ff.game.api.pgt.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
*
*
* @author shi
* @date 2025/03/27
*/
@Data
public class PGXErrorResponse {
/** 错误码 */
@JsonProperty("errCode")
private Integer errCode;
/** 内部参考代码 (字符串类型) */
@JsonProperty("innerCode")
private String innerCode;
/** 错误信息 (字符串类型) */
@JsonProperty("errMsg")
private String errMsg;
}

View File

@ -0,0 +1,67 @@
package com.ff.game.api.pgt.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
* pgxexchange
*
* @author shi
* @date 2025/03/28
*/
@Data
public class PGXExchangeTransferStatusResponse {
/** 错误码 */
@JsonProperty("errCode")
private Integer errCode;
/** 错误信息 (字符串类型) */
@JsonProperty("errMsg")
private String errMsg;
/** GSC生成的转账ID (String类型) */
@JsonProperty("trans_id")
private String transId;
/** 交易时间GMT+0 (String类型) */
@JsonProperty("trans_time")
private String transTime;
/** 玩家姓名 (String类型) */
@JsonProperty("username")
private String username;
/** 交易类型 (String类型)0为存款1为取款 */
@JsonProperty("type")
private String type;
/** 提供商 (String类型) */
@JsonProperty("provider")
private String provider;
/** 交易金额 (double类型) */
@JsonProperty("amount")
private double amount;
/** 运营商的参考ID (String类型) */
@JsonProperty("ref_id")
private String refId;
/** (String)SUCCESS
PROCESSING
FAILED */
@JsonProperty("status")
private String status;
/** GSC操作员代码 (String类型) */
@JsonProperty("operator")
private String operator;
/** 交易备注 (String类型) */
@JsonProperty("remark")
private String remark;
}

View File

@ -0,0 +1,30 @@
package com.ff.game.api.pgt.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
*
*/
@Data
public class PGXGameLoginResponse {
/**
* (String)
*/
@JsonProperty("errCode")
private Integer errCode;
/**
* (String)
*/
@JsonProperty("gameUrl")
private String gameUrl;
/**
* (String)
*/
@JsonProperty("errMsg")
private String errMsg;
}

View File

@ -0,0 +1,26 @@
package com.ff.game.api.pgt.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
*
*/
@Data
public class PGXMemberResponse {
/** 错误码 */
@JsonProperty("errCode")
private Integer errCode;
/** 账户余额 (小数类型) */
@JsonProperty("balance")
private BigDecimal balance;
/** 错误信息 (字符串类型) */
@JsonProperty("errMsg")
private String errMsg;
}

View File

@ -0,0 +1,26 @@
package com.ff.game.api.pgt.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
*
*
* @author shi
* @date 2025/03/28
*/
@Data
public class PGXPlayerStatusResponse {
/** 错误码 (字符串类型) */
@JsonProperty("errCode")
private Integer errCode;
/** 玩家是否在游戏中 (字符串类型) "true" 表示在游戏中,"false" 表示不在游戏中 */
@JsonProperty("result")
private Boolean result;
/** 错误信息 (字符串类型) */
@JsonProperty("errMsg")
private String errMsg;
}

View File

@ -0,0 +1,534 @@
package com.ff.game.api.pgt.impl;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSON;
import com.ff.base.constant.CacheConstants;
import com.ff.base.constant.Constants;
import com.ff.base.core.redis.RedisCache;
import com.ff.base.enums.*;
import com.ff.base.exception.base.ApiException;
import com.ff.base.exception.base.BaseException;
import com.ff.base.system.service.ISysConfigService;
import com.ff.base.utils.JsonUtil;
import com.ff.base.utils.sign.Base64;
import com.ff.config.KeyConfig;
import com.ff.game.api.IGamesService;
import com.ff.game.api.pgt.client.PGTClient;
import com.ff.game.api.pgt.dto.*;
import com.ff.game.api.request.*;
import com.ff.game.domain.*;
import com.ff.game.dto.GameSecretKeyCurrencyDTO;
import com.ff.game.service.*;
import com.ff.member.domain.Member;
import com.ff.member.service.IMemberService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.Base64Utils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* pg
*
* @author shi
* @date 2025/03/27
*/
@Service("PGTService")
@Slf4j
public class GamesPGTServiceImpl implements IGamesService {
@Resource
private ISysConfigService configService;
@Resource
private RedisCache redisCache;
@Resource
private IGameExchangeMoneyService gameExchangeMoneyService;
@Resource
private IGamePlatformService gamePlatformService;
@Resource
private IGameService gameService;
@Resource
private IMemberService memberService;
@Resource
private IGameFreeRecordService gameFreeRecordService;
@Resource
private IGameSecretKeyService gameSecretKeyService;
@Resource
private IGameSecretKeyCurrencyService gameSecretKeyCurrencyService;
@Resource
private PGTClient pgtClient;
@Resource
private KeyConfig keyConfig;
@Resource
private IGameBettingDetailsService gameBettingDetailsService;
@Resource
private IGameNameService gameNameService;
/**
*
*
* @param errorCode
* @return {@link Boolean }
*/
private Boolean getIsSuccess(Integer errorCode) {
return 0 == errorCode;
}
/**
*
*
* @return {@link String }
*/
private Map<String, String> getKey( GamesBaseRequestDTO gamesBaseRequestDTO) {
Map<String, String> headerMap=new LinkedHashMap<>();
String auth = gamesBaseRequestDTO.getAgentId() + ":" + gamesBaseRequestDTO.getAgentKey();
String encodedAuth = Base64Utils.encodeToString(auth.getBytes());
headerMap.put("Authorization","Basic "+encodedAuth);
return headerMap;
}
/**
*
*
* @param createMemberRequestDTO dto
* @return {@link Boolean }
*/
@Override
public Boolean createMember(CreateMemberRequestDTO createMemberRequestDTO) {
log.info("GamesPGTServiceImpl [createMember] 请求参数 {}", createMemberRequestDTO);
Map<String, String> headerMap = this.getKey(createMemberRequestDTO);
Map<String, Object> params = new LinkedHashMap<>();
params.put("username", createMemberRequestDTO.getAccount());
params.put("productId","PGSOFT");
PGTCreateMemberResponse member = pgtClient.createMember(params, headerMap);
if (this.getIsSuccess(member.getCode())) {
return Boolean.TRUE;
}
//判断是否获取成功
return Boolean.FALSE;
}
/**
*
*
* @param memberInfoRequestDTO dto
* @return {@link MemberInfoResponseDTO }
*/
@Override
public MemberInfoResponseDTO getMemberInfo(MemberInfoRequestDTO memberInfoRequestDTO) {
log.info("GamesPGTServiceImpl [getMemberInfo] 请求参数 {}", memberInfoRequestDTO);
Map<String, Object> params = new LinkedHashMap<>();
params.put("username", memberInfoRequestDTO.getAccounts());
params.put("productId", "PGSOFT");
Map<String, String> headerMap = this.getKey(memberInfoRequestDTO);
PGTBalanceResponse memberInfo = pgtClient.getMemberInfo(JsonUtil.mapToQueryString(params),headerMap);
//判断是否获取成功
if (this.getIsSuccess(memberInfo.getCode())) {
MemberInfoResponseDTO memberInfoResponseDTO = MemberInfoResponseDTO.builder()
.status(GameMemberStatus.UNKNOWN.getCode())
.balance(memberInfo.getData().getBalance())
.account(memberInfoRequestDTO.getAccounts())
.build();
return memberInfoResponseDTO;
} else {
throw new BaseException(memberInfo.getMessage());
}
}
/**
*
*
* @param gamesLogin
* @return {@link String }
*/
@Override
public String loginWithoutRedirect(GamesLogin gamesLogin) {
log.info("GamesPGXServiceImpl [loginWithoutRedirect] 请求参数 {}", gamesLogin);
GameSecretKey gameSecretKey = gameSecretKeyService.selectGameSecretKeyByCode(gamesLogin.getAgentId());
Map<String, Object> params = new LinkedHashMap<>();
params.put("operatorcode", gamesLogin.getAgentId());
params.put("password", gameSecretKey.getPassword());
params.put("providercode", gameSecretKey.getProviderCode());
params.put("type", gamesLogin.getGameType());
params.put("username", gamesLogin.getAccount());
Map<String, String> key = this.getKey(gamesLogin);
params.put("gameid", gamesLogin.getGameId());
params.put("lang", gamesLogin.getLang());
params.put("html5", 1);
params.put("signature", key);
PGXGameLoginResponse PGXGameLoginResponse = pgtClient.loginWithoutRedirect(JsonUtil.mapToQueryString(params));
//判断是否获取成功
if (this.getIsSuccess(PGXGameLoginResponse.getErrCode())) {
return PGXGameLoginResponse.getGameUrl();
} else {
throw new BaseException(PGXGameLoginResponse.getErrMsg());
}
}
/**
*
*
* @param gamesBaseRequestDTO dto
* @return {@link String }
*/
@Transactional
@Override
public String getGameList(GamesBaseRequestDTO gamesBaseRequestDTO) {
return CacheConstants.PGX_GAMES;
}
/**
* id
*
* @param exchangeTransferMoneyRequestDTO moeny dto
* @return {@link Long }
*/
@Override
@Transactional
public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) {
log.info("GamesPGXServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO);
GameSecretKeyCurrency currencyDTO = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
.platformCode(GamePlatforms.PGX.getInfo())
.code(exchangeTransferMoneyRequestDTO.getAgentId())
.currency(exchangeTransferMoneyRequestDTO.getCurrency())
.build());
Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount());
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), "订单号重复");
GameSecretKey gameSecretKey = gameSecretKeyService.selectGameSecretKeyByCode(exchangeTransferMoneyRequestDTO.getAgentId());
//获取下一个自增id
GameExchangeMoney exchangeMoney = GameExchangeMoney
.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.quota(exchangeTransferMoneyRequestDTO.getQuota())
.balance(exchangeTransferMoneyRequestDTO.getAmount())
.exchangeType(exchangeTransferMoneyRequestDTO.getTransferType())
.currencyCode(currencyDTO.getSystemCurrency())
.memberId(member.getId())
.transactionId(transactionId)
.platformCode(GamePlatforms.PGX.getInfo())
.build();
exchangeMoney.setCreateBy(Constants.SYSTEM);
//获取余额
String type = TransferType.ALL.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType()) ? PGXTransferType.WITHDRAW.getCode() : PGXTransferType.DEPOSIT.getCode();
BigDecimal amount = exchangeTransferMoneyRequestDTO.getAmount();
BigDecimal amountBefore = BigDecimal.ZERO;
// 获取第三方钱包余额
MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder()
.accounts(exchangeTransferMoneyRequestDTO.getAccount())
.agentId(exchangeTransferMoneyRequestDTO.getAgentId())
.agentKey(exchangeTransferMoneyRequestDTO.getAgentKey())
.build();
//判断是不是提出
if (TransferType.ALL.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType())) {
amountBefore = this.getMemberInfo(gamesBaseRequestDTO).getBalance();
amount = amountBefore;
}
Map<String, Object> paramsMap = new LinkedHashMap<>();
paramsMap.put("amount", amount);
paramsMap.put("operatorcode", exchangeTransferMoneyRequestDTO.getAgentId());
paramsMap.put("password", gameSecretKey.getPassword());
paramsMap.put("providercode", gameSecretKey.getProviderCode());
paramsMap.put("referenceid", transactionId);
paramsMap.put("type", type);
paramsMap.put("username", exchangeTransferMoneyRequestDTO.getAccount());
PGXErrorResponse errorResponse = pgtClient.exchangeTransferByAgentId(JsonUtil.mapToQueryString(paramsMap));
if (this.getIsSuccess(errorResponse.getErrCode())) {
//更新数据
exchangeMoney.setBalance(amount);
exchangeMoney.setCoinBefore(amountBefore);
//转后的余额
BigDecimal coinAfter = this.getMemberInfo(gamesBaseRequestDTO).getBalance();
exchangeMoney.setCoinAfter(coinAfter);
exchangeMoney.setCurrencyBefore(exchangeMoney.getCoinBefore());
exchangeMoney.setCurrencyAfter(exchangeMoney.getCoinAfter());
exchangeMoney.setStatus(StatusType.IN_PROGRESS.getValue());
gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
//确认状态
ExchangeTransferStatusRequestDTO exchangeTransferStatusRequestDTO = new ExchangeTransferStatusRequestDTO();
exchangeTransferStatusRequestDTO.setAccount(member.getGameAccount());
exchangeTransferStatusRequestDTO.setOrderId(exchangeMoney.getTransactionId());
exchangeTransferStatusRequestDTO.setAgentId(gameSecretKey.getCode());
exchangeTransferStatusRequestDTO.setAgentKey(gameSecretKey.getKey());
this.exchangeTransferStatus(exchangeTransferStatusRequestDTO);
} else {
log.error("GamesFCServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误代码{}", errorResponse.getErrCode());
throw new ApiException(ErrorCode.BALANCE_TRANSFER_FAILED.getCode());
}
return exchangeMoney.getId();
}
/**
*
*
* @param exchangeTransferMoneyRequestDTO dto
* @return {@link Boolean }
*/
@Override
public Boolean exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO) {
log.info("GamesPGXServiceImpl [exchangeTransferStatus] 请求参数 {}", exchangeTransferMoneyRequestDTO);
Map<String, Object> paramsMap = new LinkedHashMap<>();
paramsMap.put("operatorcode", exchangeTransferMoneyRequestDTO.getAgentId());
paramsMap.put("referenceid", exchangeTransferMoneyRequestDTO.getOrderId());
PGXExchangeTransferStatusResponse exchangeTransferStatusResponse = pgtClient.exchangeTransferStatus(JsonUtil.mapToQueryString(paramsMap));
if (this.getIsSuccess(exchangeTransferStatusResponse.getErrCode())) {
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
GameExchangeMoney.builder()
.platformCode(GamePlatforms.PGX.getInfo())
.transactionId(exchangeTransferMoneyRequestDTO.getOrderId())
.build()
);
for (GameExchangeMoney exchangeMoney : gameExchangeMonies) {
//更新数据
exchangeMoney.setStatus(PGXTransactionStatus.findValueByCode(exchangeTransferStatusResponse.getStatus()));
gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney);
}
return Boolean.TRUE;
} else {
log.error("GamesPGXServiceImpl [exchangeTransferStatus]错误代码{},错误信息{}", exchangeTransferStatusResponse.getErrCode(), exchangeTransferStatusResponse.getErrMsg());
return Boolean.FALSE;
}
}
/**
*
*
* @param betRecordByTimeDTO dto
* @return {@link List }<{@link GameBettingDetails }>
*/
@Override
public Boolean getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) {
//请求参数
log.info("GamesPGXServiceImpl [getBetRecordByTime] 请求参数 {}", betRecordByTimeDTO);
Map<String, Object> paramsMap = new LinkedHashMap<>();
paramsMap.put("operatorcode", betRecordByTimeDTO.getAgentId());
paramsMap.put("versionkey", 0);
PGXBetHistoryResponse betRecordByTime = pgtClient.getBetRecordByTime(JsonUtil.mapToQueryString(paramsMap));
if (this.getIsSuccess(betRecordByTime.getErrCode())) {
List<PGXBetHistoryResponse.Result> results = JSON.parseArray(betRecordByTime.getResult(), PGXBetHistoryResponse.Result.class);
this.batchInsert(results, betRecordByTimeDTO);
return Boolean.TRUE;
} else {
log.error("GamesPGXServiceImpl [getBetRecordByTime] 获取投注记录失败,错误代码{},错误信息{}", betRecordByTime.getErrCode(), betRecordByTime.getErrMsg());
throw new BaseException(betRecordByTime.getErrMsg());
}
}
/**
*
*
* @param betRecordByTimeDTO dto
* @return {@link Boolean }
*/
@Override
public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO betRecordByTimeDTO) {
//请求参数
log.info("GamesPGXServiceImpl [getBetRecordByHistoryTime] 请求参数 {}", betRecordByTimeDTO);
Map<String, Object> paramsMap = new LinkedHashMap<>();
paramsMap.put("operatorcode", betRecordByTimeDTO.getAgentId());
paramsMap.put("versionkey", 0);
PGXBetHistoryResponse betRecordByTime = pgtClient.getBetRecordByHistoryTime(JsonUtil.mapToQueryString(paramsMap));
if (this.getIsSuccess(betRecordByTime.getErrCode())) {
List<PGXBetHistoryResponse.Result> results = JSON.parseArray(betRecordByTime.getResult(), PGXBetHistoryResponse.Result.class);
this.batchInsert(results, betRecordByTimeDTO);
return Boolean.TRUE;
} else {
log.error("GamesPGXServiceImpl [getBetRecordByHistoryTime] 获取投注记录失败,错误代码{},错误信息{}", betRecordByTime.getErrCode(), betRecordByTime.getErrMsg());
throw new BaseException(betRecordByTime.getErrMsg());
}
}
/**
*
*
* @param createFreeSpinRequest
* @return {@link Boolean }
*/
@Override
public Boolean createFreeSpin(CreateFreeSpinRequestDTO createFreeSpinRequest) {
throw new ApiException(ErrorCode.PLATFORM_NOT_METHODS.getCode());
}
/**
*
*
* @param getGameDetailRequestDTO dto
* @return {@link GetGameDetailResponseDTO }
*/
@Override
public GetGameDetailResponseDTO getGameDetail(GetGameDetailRequestDTO getGameDetailRequestDTO) {
throw new ApiException(ErrorCode.PLATFORM_NOT_METHODS.getCode());
}
/**
*
*
* @param kickMemberRequestDTO dto
* @return {@link Boolean }
*/
@Override
public Boolean kickMember(KickMemberRequestDTO kickMemberRequestDTO) {
throw new ApiException(ErrorCode.PLATFORM_NOT_METHODS.getCode());
}
/**
*
*
* @param kickMemberAllDTO dto
* @return {@link Boolean }
*/
@Override
public Boolean kickMemberAll(KickMemberAllDTO kickMemberAllDTO) {
throw new ApiException(ErrorCode.PLATFORM_NOT_METHODS.getCode());
}
/**
* 使
*
* @param getFreeSpinDashflowRequestDTO dashflowdto
* @return {@link List }<{@link GameFreeRecord }>
*/
@Override
public List<GameFreeRecord> getFreeSpinDashflow(GetFreeSpinDashflowRequestDTO getFreeSpinDashflowRequestDTO) {
throw new ApiException(ErrorCode.PLATFORM_NOT_METHODS.getCode());
}
/**
*
*
* @param cancelFreeSpinRequestDTO
* @return {@link Boolean }
*/
@Override
public Boolean cancelFreeSpin(CancelFreeSpinRequestDTO cancelFreeSpinRequestDTO) {
throw new ApiException(ErrorCode.PLATFORM_NOT_METHODS.getCode());
}
/**
*
*
* @param gameDemoLoginRequestDTO dto
* @return {@link GameDemoLoginResponseDTO }
*/
@Override
public GameDemoLoginResponseDTO gameDemoLogin(GameDemoLoginRequestDTO gameDemoLoginRequestDTO) {
throw new ApiException(ErrorCode.PLATFORM_NOT_METHODS.getCode());
}
/**
*
*
* @param dataBean bean
*/
private void batchInsert(List<PGXBetHistoryResponse.Result> dataBean, GamesBaseRequestDTO gamesBaseRequestDTO) {
List<GameBettingDetails> gameBettingDetails = new ArrayList<>();
List<String> wagersIds = new ArrayList<>();
//数据转化
for (PGXBetHistoryResponse.Result bean : dataBean) {
GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder().agentId(gamesBaseRequestDTO.getAgentId()).data(bean).build());
if (!ObjectUtils.isEmpty(bettingDetails)) {
bettingDetails.setId(IdUtil.getSnowflakeNextId());
gameBettingDetails.add(bettingDetails);
}
wagersIds.add(String.valueOf(bean.getId()));
}
if (!CollectionUtils.isEmpty(gameBettingDetails)) {
//查询重复数据id
List<String> removeWagersIds = gameBettingDetailsService.selectGameBettingDetailsByWagersId(wagersIds,GamePlatforms.PGX.getInfo());
//用steam流清除list中与wagersIds集合相同的数据
gameBettingDetails = gameBettingDetails.stream()
.filter(detail -> !removeWagersIds.contains(detail.getWagersId()))
.collect(Collectors.toList());
if (!CollectionUtils.isEmpty(gameBettingDetails)) {
gameBettingDetailsService.batchInsert(gameBettingDetails);
}
}
}
/**
*
*
* @param gamesDataBuildDTO
* @return {@link GameBettingDetails }
*/
@Override
public GameBettingDetails dataBuild(GamesDataBuildDTO gamesDataBuildDTO) {
//转化类
return new GameBettingDetails();
}
}

View File

@ -1,4 +1,4 @@
package com.ff.game.api.km.success;
package com.ff.game.api.success;
import com.dtflys.forest.callback.SuccessWhen;
@ -11,7 +11,7 @@ import com.dtflys.forest.http.ForestResponse;
* @author shi
* @date 2025/04/02
*/
public class MyKMSuccessCondition implements SuccessWhen {
public class MySuccessCondition implements SuccessWhen {
/**
*

View File

@ -30,9 +30,11 @@ public interface IMemberService
/**
*
*
* @param platformCode
* @param tenantSn sn
* @return {@link String }
*/
String getMemberGameAccount(String platformCode);
String getMemberGameAccount(String platformCode,String tenantSn);
/**
*

View File

@ -53,19 +53,21 @@ public class MemberServiceImpl implements IMemberService {
* @return {@link String }
*/
@Override
public synchronized String getMemberGameAccount(String platformCode) {
public synchronized String getMemberGameAccount(String platformCode,String tenantSn) {
String gameAccount = null;
if (GamePlatforms.DG.getInfo().equals(platformCode) || GamePlatforms.KM.getInfo().equals(platformCode)) {
tenantSn=tenantSn.toUpperCase();
do {
gameAccount = RandomGeneratorUtils.generateRandomAccountUpper();
gameAccount = RandomGeneratorUtils.generateRandomAccountUpper()+tenantSn;
} while (!ObjectUtils.isEmpty(memberMapper.selectMemberByGameAccount(gameAccount)));
} else if (GamePlatforms.PG.getInfo().equals(platformCode) || GamePlatforms.PGX.getInfo().equals(platformCode)) {
} else if (GamePlatforms.PG.getInfo().equals(platformCode) || GamePlatforms.PGX.getInfo().equals(platformCode) || GamePlatforms.PGT.getInfo().equals(platformCode)) {
tenantSn=tenantSn.toLowerCase();
do {
gameAccount = RandomGeneratorUtils.generateRandomAccountLower();
gameAccount = RandomGeneratorUtils.generateRandomAccountLower()+tenantSn;
} while (!ObjectUtils.isEmpty(memberMapper.selectMemberByGameAccount(gameAccount)));
} else {
do {
gameAccount = RandomGeneratorUtils.generateRandomAccount();
gameAccount = RandomGeneratorUtils.generateRandomAccount()+tenantSn;
} while (!ObjectUtils.isEmpty(memberMapper.selectMemberByGameAccount(gameAccount)));
}