From 61ebcb15aa9948ec36cc70dba39a23cf79554609 Mon Sep 17 00:00:00 2001 From: shi Date: Tue, 25 Mar 2025 10:00:42 +0800 Subject: [PATCH] =?UTF-8?q?feat(game):=20=E6=B7=BB=E5=8A=A0=20SA=20?= =?UTF-8?q?=E6=B8=B8=E6=88=8F=E5=B9=B3=E5=8F=B0=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 SA游戏平台的 API 接口和实现类 - 添加 DESEncryptUtils 工具类用于加密解密 - 在 Constants 中添加 SA_API_BASE_URL 常量 - 新增 MySAAddressSource 类用于获取 SA 游戏平台的地址 - 在 pom.xml 中添加 Jackson XML 数据格式支持依赖 --- .../java/com/ff/base/constant/Constants.java | 7 + .../com/ff/base/utils/DESEncryptUtils.java | 48 ++ ff-game/pom.xml | 5 + .../api/sa/address/MySAAddressSource.java | 31 + .../com/ff/game/api/sa/client/SAClient.java | 96 +++ .../api/sa/dto/SARegUserInfoResponse.java | 46 ++ .../game/api/sa/impl/GamesSAServiceImpl.java | 607 ++++++++++++++++++ 7 files changed, 840 insertions(+) create mode 100644 ff-base/src/main/java/com/ff/base/utils/DESEncryptUtils.java create mode 100644 ff-game/src/main/java/com/ff/game/api/sa/address/MySAAddressSource.java create mode 100644 ff-game/src/main/java/com/ff/game/api/sa/client/SAClient.java create mode 100644 ff-game/src/main/java/com/ff/game/api/sa/dto/SARegUserInfoResponse.java create mode 100644 ff-game/src/main/java/com/ff/game/api/sa/impl/GamesSAServiceImpl.java diff --git a/ff-base/src/main/java/com/ff/base/constant/Constants.java b/ff-base/src/main/java/com/ff/base/constant/Constants.java index a41b811..2b86c23 100644 --- a/ff-base/src/main/java/com/ff/base/constant/Constants.java +++ b/ff-base/src/main/java/com/ff/base/constant/Constants.java @@ -197,6 +197,13 @@ public class Constants { * xk 接口请求前缀 */ public static final String XK_API_BASE_URL = "xk.api.base.url"; + + + /** + * sa-api基本url + */ + public static final String SA_API_BASE_URL = "sa.api.base.url"; + /** * 服务 */ diff --git a/ff-base/src/main/java/com/ff/base/utils/DESEncryptUtils.java b/ff-base/src/main/java/com/ff/base/utils/DESEncryptUtils.java new file mode 100644 index 0000000..a359ebb --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/utils/DESEncryptUtils.java @@ -0,0 +1,48 @@ +package com.ff.base.utils; + +import com.ff.base.exception.base.BaseException; +import lombok.Data; + +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; +import java.util.Base64; + + +/** + * 解密有用 + * + * @author shi + * @date 2025/03/24 + */ +public class DESEncryptUtils { + + /** + * 给…解密 + * + * @param inString 字符串中 + * @param secretKey 密钥 + * @return {@link String } + * @throws Exception 例外 + */ + public static String DESEncrypt(String inString, String secretKey) { + try { + // 使用相同的密钥进行加密 + SecretKeySpec key = new SecretKeySpec(secretKey.getBytes(StandardCharsets.US_ASCII), "DES"); + + // 使用DES加密算法 + Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); + cipher.init(Cipher.ENCRYPT_MODE, key); + + // 加密输入字符串 + byte[] encrypted = cipher.doFinal(inString.getBytes(StandardCharsets.UTF_8)); + + // 返回Base64编码的密文 + return Base64.getEncoder().encodeToString(encrypted); + } catch (Exception e) { + throw new BaseException("加密失败"); + } + + } + +} diff --git a/ff-game/pom.xml b/ff-game/pom.xml index ee0cfce..5d435ed 100644 --- a/ff-game/pom.xml +++ b/ff-game/pom.xml @@ -23,6 +23,11 @@ spring-boot-devtools true + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + org.springframework diff --git a/ff-game/src/main/java/com/ff/game/api/sa/address/MySAAddressSource.java b/ff-game/src/main/java/com/ff/game/api/sa/address/MySAAddressSource.java new file mode 100644 index 0000000..5ee8a89 --- /dev/null +++ b/ff-game/src/main/java/com/ff/game/api/sa/address/MySAAddressSource.java @@ -0,0 +1,31 @@ +package com.ff.game.api.sa.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; + + +/** + * 我jili address来源 + * + * @author shi + * @date 2025/02/10 + */ +@Component +public class MySAAddressSource implements AddressSource { + + @Resource + private ISysConfigService configService; + + + @Override + public ForestAddress getAddress(ForestRequest request) { + String apiBaseUrl = configService.selectConfigByKey(Constants.SA_API_BASE_URL); + return new ForestAddress("https",apiBaseUrl, 443,"api"); + } +} \ No newline at end of file diff --git a/ff-game/src/main/java/com/ff/game/api/sa/client/SAClient.java b/ff-game/src/main/java/com/ff/game/api/sa/client/SAClient.java new file mode 100644 index 0000000..a652356 --- /dev/null +++ b/ff-game/src/main/java/com/ff/game/api/sa/client/SAClient.java @@ -0,0 +1,96 @@ +package com.ff.game.api.sa.client; + +import com.dtflys.forest.annotation.*; +import com.ff.game.api.jili.dto.*; +import com.ff.game.api.sa.address.MySAAddressSource; +import com.ff.game.api.sa.dto.SARegUserInfoResponse; +import com.ff.game.api.xk.dto.*; + +import java.util.Map; + +/** + * xk 请求 + * + * @author shi + * @date 2025/02/10 + */ +@Address(source = MySAAddressSource.class) +public interface SAClient { + /** + * 创建成员 + * + * @param parameters 参数 + * @return {@link String } + */ + @Post( url ="/api.aspx/RegUserInfo?${parameters}", + headers = { + "Content-type: application/x-www-form-urlencoded" + }) + SARegUserInfoResponse createMember(@Var("parameters") String parameters); + + /** + * 获取会员信息 + * + * @param params 参数 + * @return {@link XKMemberInfoDTO } + */ + @Post("/getMemberInfo") + XKMemberInfoDTO getMemberInfo(@JSONBody Map params); + + /** + * 无重定向登录 + * + * @param params 参数 + * @return {@link JILILoginWithoutRedirectResponseDTO } + */ + @Post("/loginWithoutRedirect") + XKLoginWithoutRedirectResponseDTO loginWithoutRedirect(@JSONBody Map params); + + /** + * 获取游戏列表 + * + * @param params 参数 + * @return {@link JILIGamesDTO } + */ + @Post("/getGameList") + XKGamesDTO getGameList(@JSONBody Map params); + + /** + * 按代理id进行交换转账 + * + * @param params 参数 + * @return {@link JILIExchangeMoneyResponseDTO } + */ + @Post(url = "/exchangeTransferByAgentId") + XKExchangeMoneyResponseDTO exchangeTransferByAgentId( @JSONBody Map params); + + /** + * 按时间获取投注记录 + * + * @param params 参数 + * @return {@link XKBetRecordResponseDTO } + */ + @Post(url = "/getGameRecordByTime") + XKBetRecordResponseDTO getBetRecordByTime( @JSONBody Map params); + + + /** + * 踢出队员 + * + * @param params 参数 + * @return {@link JILIKickMemberDTO } + */ + @Post("/kickMember") + XKKickMemberDTO kickMember(@JSONBody Map params); + + /** + * 踢出所有队员 + * + * @param params 参数 + * @return {@link JILIKickMemberAllDTO } + */ + @Get("/kickMemberAll") + XKKickMemberAllDTO kickMemberAll(@JSONBody Map params); + + +} diff --git a/ff-game/src/main/java/com/ff/game/api/sa/dto/SARegUserInfoResponse.java b/ff-game/src/main/java/com/ff/game/api/sa/dto/SARegUserInfoResponse.java new file mode 100644 index 0000000..1356d5a --- /dev/null +++ b/ff-game/src/main/java/com/ff/game/api/sa/dto/SARegUserInfoResponse.java @@ -0,0 +1,46 @@ +package com.ff.game.api.sa.dto; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + + +/** + * + * sa 创建用户返回类 + * @author shi + * @date 2025/03/25 + */ +@XmlRootElement(name = "RegUserInfoResponse") +public class SARegUserInfoResponse { + + private String errorMsgId; + private String errorMsg; + private String username; + + @XmlElement(name = "ErrorMsgId") + public String getErrorMsgId() { + return errorMsgId; + } + + public void setErrorMsgId(String errorMsgId) { + this.errorMsgId = errorMsgId; + } + + @XmlElement(name = "ErrorMsg") + public String getErrorMsg() { + return errorMsg; + } + + public void setErrorMsg(String errorMsg) { + this.errorMsg = errorMsg; + } + + @XmlElement(name = "Username") + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } +} \ No newline at end of file diff --git a/ff-game/src/main/java/com/ff/game/api/sa/impl/GamesSAServiceImpl.java b/ff-game/src/main/java/com/ff/game/api/sa/impl/GamesSAServiceImpl.java new file mode 100644 index 0000000..d337f90 --- /dev/null +++ b/ff-game/src/main/java/com/ff/game/api/sa/impl/GamesSAServiceImpl.java @@ -0,0 +1,607 @@ +package com.ff.game.api.sa.impl; + +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.NumberUtil; +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.DESEncryptUtils; +import com.ff.base.utils.DateUtils; +import com.ff.base.utils.JsonUtil; +import com.ff.base.utils.sign.Md5Utils; +import com.ff.base.utils.uuid.IdUtils; +import com.ff.config.KeyConfig; +import com.ff.game.api.IGamesService; +import com.ff.game.api.request.*; +import com.ff.game.api.sa.client.SAClient; +import com.ff.game.api.sa.dto.SARegUserInfoResponse; +import com.ff.game.api.xk.dto.*; +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.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + + +/** + * SA 游戏 impl + * + * @author shi + * @date 2024/11/12 + */ +@Service("SAService") +@Slf4j +public class GamesSAServiceImpl 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 SAClient SAClient; + + + @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; + } + + + /** + * 获取密钥 + * + * @param gamesBaseRequestDTO 游戏请求dto + * @return {@link String } + */ + private String getKey(GamesBaseRequestDTO gamesBaseRequestDTO,String method) { + String dateTimeNow = DateUtils.dateTimeNow(); + String query="method="+method+"&Key="+gamesBaseRequestDTO.getAgentKey()+"&Time="+dateTimeNow+"&"+gamesBaseRequestDTO.getQuery(); + String q = DESEncryptUtils.DESEncrypt(query, "g9G16nTs"); + String s=Md5Utils.md5New(query+gamesBaseRequestDTO.getAgentId()+dateTimeNow+gamesBaseRequestDTO.getAgentKey()); + return "q="+q+"&s="+s; + } + + + + /** + * 创建成员 + * + * @param createMemberRequestDTO 创建成员请求dto + * @return {@link Boolean } + */ + @Override + public Boolean createMember(CreateMemberRequestDTO createMemberRequestDTO) { + log.info("GamesXKServiceImpl [createMember] 请求参数 {}", createMemberRequestDTO); + + Map params = new LinkedHashMap<>(); + params.put("Username", createMemberRequestDTO.getAccount()); + params.put("CurrencyType", createMemberRequestDTO.getCurrency()); + String query = JsonUtil.mapToQueryString(params); + createMemberRequestDTO.setQuery(query); + String key = this.getKey(createMemberRequestDTO,"RegUserInfo"); + SARegUserInfoResponse saRegUserInfoResponse = SAClient.createMember(key); + String errorCode = saRegUserInfoResponse.getErrorMsgId(); + //判断是否获取成功 + return Boolean.FALSE; + } + + + /** + * 获取会员信息 + * + * @param memberInfoRequestDTO 会员信息请求dto + * @return {@link MemberInfoResponseDTO } + */ + @Override + public MemberInfoResponseDTO getMemberInfo(MemberInfoRequestDTO memberInfoRequestDTO) { + log.info("GamesXKServiceImpl [getMemberInfo] 请求参数 {}", memberInfoRequestDTO); + Map params = new LinkedHashMap<>(); + params.put("accounts", memberInfoRequestDTO.getAccounts()); + params.put("agentId", memberInfoRequestDTO.getAgentId()); + String query = JsonUtil.mapToQueryString(params); + memberInfoRequestDTO.setQuery(query); + String key = this.getKey(memberInfoRequestDTO,null); + params.put("key", key); + XKMemberInfoDTO xkMemberInfoDTO = SAClient.getMemberInfo(params); + //判断是否获取成功 + if (this.getIsSuccess(xkMemberInfoDTO.getCode())) { + List memberInfoResponseDTOS = new ArrayList<>(); + xkMemberInfoDTO.getData().forEach(e -> { + memberInfoResponseDTOS.add(MemberInfoResponseDTO.builder() + .status(e.getStatus()) + .balance(e.getBalance()) + .account(e.getAccount()) + .build()); + }); + return memberInfoResponseDTOS.get(0); + } else { + throw new BaseException(xkMemberInfoDTO.getMsg()); + } + } + + /** + * 无重定向登录 + * + * @param gamesLogin 游戏登录 + * @return {@link String } + */ + @Override + public String loginWithoutRedirect(GamesLogin gamesLogin) { + log.info("GamesXKServiceImpl [loginWithoutRedirect] 请求参数 {}", gamesLogin); + + Map params = new LinkedHashMap<>(); + params.put("account", gamesLogin.getAccount()); + params.put("gameId", Integer.valueOf(gamesLogin.getGameId())); + params.put("lang", gamesLogin.getLang()); + params.put("agentId", gamesLogin.getAgentId()); + String query = JsonUtil.mapToQueryString(params); + gamesLogin.setQuery(query); + String key = this.getKey(gamesLogin,null); + params.put("key", key); + params.put("disableFullScreen", gamesLogin.getDisableFullScreen()); + params.put("homeUrl", gamesLogin.getHomeUrl()); + params.put("platform", gamesLogin.getPlatform()); + XKLoginWithoutRedirectResponseDTO xkLoginWithoutRedirectResponseDTO = SAClient.loginWithoutRedirect(params); + //判断是否获取成功 + if (this.getIsSuccess(xkLoginWithoutRedirectResponseDTO.getCode())) { + return xkLoginWithoutRedirectResponseDTO.getData(); + } else { + throw new BaseException(xkLoginWithoutRedirectResponseDTO.getMsg()); + } + } + + + /** + * 获取游戏列表 + * + * @param gamesBaseRequestDTO 游戏请求dto + * @return {@link String } + */ + @Transactional + @Override + public String getGameList(GamesBaseRequestDTO gamesBaseRequestDTO) { + + List gamesDatas = redisCache.getCacheList(CacheConstants.XK_GAMES); + if (!CollectionUtils.isEmpty(gamesDatas)) { + return CacheConstants.XK_GAMES; + } + + + Map params = new LinkedHashMap<>(); + params.put("agentId", gamesBaseRequestDTO.getAgentId()); + String query = JsonUtil.mapToQueryString(params); + gamesBaseRequestDTO.setQuery(query); + String key = this.getKey(gamesBaseRequestDTO,null); + params.put("key", key); + + XKGamesDTO xkGamesDTO = SAClient.getGameList(params); + //判断是否获取成功 + if (this.getIsSuccess(xkGamesDTO.getCode())) { + + for (XKGamesDTO.DataBean gamesDataDTO : xkGamesDTO.getData()) { + GamePlatform gamePlatform = GamePlatform.builder() + .platformType(XKGameType.findSystemByCode(gamesDataDTO.getGameCategoryId())) + .platformCode(GamePlatforms.XK.getCode()) + .build(); + List gamePlatforms = gamePlatformService.selectGamePlatformList(gamePlatform); + //没有此平台就新增一个平台 + if (CollectionUtils.isEmpty(gamePlatforms)) { + gamePlatform.setPlatformName(GamePlatforms.XK.getInfo() + XKGameType.findInfoByCode(gamesDataDTO.getGameCategoryId())); + gamePlatform.setSortNo(gamePlatformService.selectMaxSortNo() + 1); + gamePlatform.setCreateBy(Constants.SYSTEM); + gamePlatformService.insertGamePlatform(gamePlatform); + } else { + gamePlatform = gamePlatforms.get(0); + } + Game game = Game.builder() + .platformId(gamePlatform.getId()) + .gameCode(String.valueOf(gamesDataDTO.getGameId())) + .build(); + List games = gameService.selectGameList(game); + //不存在这个游戏 + if (CollectionUtils.isEmpty(games)) { + game.setGameSourceType(gamesDataDTO.getGameCategoryId()); + game.setFreespin(gamesDataDTO.isFreeSpin()); + game.setSortNo(gameService.selectMaxSortNoByPlatformId(gamePlatform.getId()) + 1); + game.setGameName(gamesDataDTO.getName()); + game.setCreateBy(Constants.SYSTEM); + gameService.insertGame(game); + } else { + game = games.get(0); + } + gamesDataDTO.setSystemGameId(game.getId()); + List gameNames = gameNameService.selectGameNameList(GameName.builder().gameId(game.getId()).gameName(game.getGameName()).build()); + if (CollectionUtils.isEmpty(gameNames)){ + gameNameService.insertGameName(GameName.builder() + .gameId(game.getId()) + .gameName(game.getGameName()) + .langCode("zh-CN") + .createBy(Constants.SYSTEM) + .build()); + } + + } + + redisCache.deleteObject(CacheConstants.XK_GAMES); + redisCache.setCacheList(CacheConstants.XK_GAMES, xkGamesDTO.getData()); + redisCache.expire(CacheConstants.XK_GAMES, 5L, TimeUnit.HOURS); + } else { + throw new BaseException(xkGamesDTO.getMsg()); + + } + + return CacheConstants.XK_GAMES; + } + + /** + * 按代理id进行交换转账 + * + * @param exchangeTransferMoneyRequestDTO 外汇转账moeny dto + * @return {@link Long } + */ + @Override + @Transactional + public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO 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 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(currencyDTO.getSystemCurrency()) + .memberId(member.getId()) + .transactionId(transactionId) + .platformCode(GamePlatforms.XK.getCode()) + .build(); + exchangeMoney.setCreateBy(Constants.SYSTEM); + //接口限制限制50字符 + exchangeMoney.setTransactionId(GamePlatforms.XK.getCode() + IdUtils.simpleUUID()); + Map params = new LinkedHashMap<>(); + params.put("account", exchangeTransferMoneyRequestDTO.getAccount()); + params.put("transactionId", exchangeMoney.getTransactionId()); + params.put("amount", exchangeTransferMoneyRequestDTO.getAmount().stripTrailingZeros().toString()); + params.put("transferType", exchangeTransferMoneyRequestDTO.getTransferType()); + params.put("agentId", exchangeTransferMoneyRequestDTO.getAgentId()); + String query = JsonUtil.mapToQueryString(params); + exchangeTransferMoneyRequestDTO.setQuery(query); + String key = this.getKey(exchangeTransferMoneyRequestDTO,null); + params.put("key", key); + XKExchangeMoneyResponseDTO exchangeMoneyResponse = SAClient.exchangeTransferByAgentId(params); + //判断是否转移成功 + if (this.getIsSuccess(exchangeMoneyResponse.getCode())) { + XKExchangeMoneyResponseDTO.DataBean exchangeMoneyResponseData = exchangeMoneyResponse.getData(); + ApiException.isTrue(!StatusType.FAILURE.getValue().equals(exchangeMoneyResponseData.getStatus()), ErrorCode.BALANCE_TRANSFER_FAILED.getCode()); + + //更新数据 + exchangeMoney.setBalance(NumberUtil.sub(exchangeMoneyResponseData.getCurrencyAfter(), exchangeMoneyResponseData.getCurrencyBefore()).abs()); + exchangeMoney.setCoinBefore(exchangeMoneyResponseData.getCoinBefore()); + exchangeMoney.setCoinAfter(exchangeMoneyResponseData.getCoinAfter()); + exchangeMoney.setCurrencyBefore(exchangeMoneyResponseData.getCurrencyBefore()); + exchangeMoney.setCurrencyAfter(exchangeMoneyResponseData.getCurrencyAfter()); + exchangeMoney.setStatus(exchangeMoneyResponseData.getStatus()); + gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney); + } else { + log.error("GamesXKServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误代码{},错误信息{}", exchangeMoneyResponse.getCode(), exchangeMoneyResponse.getMsg()); + throw new BaseException(exchangeMoneyResponse.getMsg()); + } + + return exchangeMoney.getId(); + } + + /** + * 汇兑转移状态 + * + * @param exchangeTransferMoneyRequestDTO 兑换转账请求dto + * @return {@link Boolean } + */ + @Override + public Boolean exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO) { + return Boolean.TRUE; + } + + + /** + * 按时间获取投注记录 + * + * @param betRecordByTimeDTO 按时间dto投注记录 + * @return {@link List }<{@link GameBettingDetails }> + */ + @Override + public Boolean getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) { + List gameBettingDetails = new ArrayList<>(); + //请求参数 + log.info("GamesXKServiceImpl [getBetRecordByTime] 请求参数 {}", betRecordByTimeDTO); + Map 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,null); + params.put("key", key); + XKBetRecordResponseDTO xkBetRecordResponseDTO = SAClient.getBetRecordByTime(params); + + //判断是否获取成功 + if (this.getIsSuccess(xkBetRecordResponseDTO.getCode())) { + //数据组装 + XKBetRecordResponseDTO.DataBean dataBean = xkBetRecordResponseDTO.getData(); + this.batchInsert(xkBetRecordResponseDTO); + + //获取下一页数据 + 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,null); + params.put("key", key); + xkBetRecordResponseDTO = SAClient.getBetRecordByTime(params); + this.batchInsert(xkBetRecordResponseDTO); + } + + + return Boolean.TRUE; + } else { + log.error("GamesXKServiceImpl [getBetRecordByTime] 获取投注记录失败,错误代码{},错误信息{}", xkBetRecordResponseDTO.getCode(), xkBetRecordResponseDTO.getMsg()); + throw new BaseException(xkBetRecordResponseDTO.getMsg()); + } + + } + + /** + * 赠送免费局数 + * + * @param createFreeSpinRequest 创建自由旋转请求 + * @return {@link Boolean } + */ + @Override + public Boolean createFreeSpin(CreateFreeSpinRequestDTO createFreeSpinRequest) { + throw new BaseException("当前平台不支持"); + } + + /** + * 获取游戏详细信息 + * + * @param getGameDetailRequestDTO 获取游戏详细信息请求dto + * @return {@link GetGameDetailResponseDTO } + */ + @Override + public GetGameDetailResponseDTO getGameDetail(GetGameDetailRequestDTO getGameDetailRequestDTO) { + throw new BaseException("当前平台不支持"); + } + + /** + * 强制会员从游戏注销 + * + * @param kickMemberRequestDTO 踢会员请求dto + * @return {@link Boolean } + */ + @Override + public Boolean kickMember(KickMemberRequestDTO kickMemberRequestDTO) { + log.info("GamesXKServiceImpl [kickMember] 请求参数 {}", kickMemberRequestDTO); + Map params = new LinkedHashMap<>(); + params.put("account", kickMemberRequestDTO.getAccount()); + params.put("agentId", kickMemberRequestDTO.getAgentId()); + String query = JsonUtil.mapToQueryString(params); + kickMemberRequestDTO.setQuery(query); + String key = this.getKey(kickMemberRequestDTO,null); + params.put("key", key); + XKKickMemberDTO xkKickMemberDTO = SAClient.kickMember(params); + //判断是否获取成功 + if (this.getIsSuccess(xkKickMemberDTO.getCode())) { + return Boolean.TRUE; + } else { + throw new BaseException(xkKickMemberDTO.getMsg()); + } + } + + /** + * 踢成员全部 + * + * @param kickMemberAllDTO 踢成员全部dto + * @return {@link Boolean } + */ + @Override + public Boolean kickMemberAll(KickMemberAllDTO kickMemberAllDTO) { + throw new BaseException("当前平台不支持"); + } + + /** + * 免费游戏玩家使用的纪录 + * + * @param getFreeSpinDashflowRequestDTO 获取自由旋转dashflow请求dto + * @return {@link List }<{@link GameFreeRecord }> + */ + @Override + public List getFreeSpinDashflow(GetFreeSpinDashflowRequestDTO getFreeSpinDashflowRequestDTO) { + throw new BaseException("当前平台不支持"); + } + + /** + * 取消赠送免费局数 + * + * @param cancelFreeSpinRequestDTO 取消免费旋转请求 + * @return {@link Boolean } + */ + @Override + public Boolean cancelFreeSpin(CancelFreeSpinRequestDTO cancelFreeSpinRequestDTO) { + throw new BaseException("当前平台不支持"); + } + + + /** + * 批量插入 + * + * @param xkBetRecordResponseDTO xk下注记录响应dto + */ + private void batchInsert(XKBetRecordResponseDTO xkBetRecordResponseDTO) { + List gameBettingDetails = new ArrayList<>(); + List wagersIds = new ArrayList<>(); + //数据组装 + XKBetRecordResponseDTO.DataBean dataBean = xkBetRecordResponseDTO.getData(); + //数据转化 + for (XKBetRecordResponseDTO.DataBean.ResultBean bean : dataBean.getResult()) { + GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder().data(bean).build()); + if (!ObjectUtils.isEmpty(bettingDetails)) { + bettingDetails.setId(IdUtil.getSnowflakeNextId()); + gameBettingDetails.add(bettingDetails); + } + wagersIds.add(bean.getWagersId()); + } + if (!CollectionUtils.isEmpty(gameBettingDetails)) { + //查询重复数据id + List removeWagersIds = gameBettingDetailsService.selectGameBettingDetailsByWagersId(wagersIds); + //用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) { + //转化类 + XKBetRecordResponseDTO.DataBean.ResultBean resultBean = (XKBetRecordResponseDTO.DataBean.ResultBean) gamesDataBuildDTO.getData(); + + GameSecretKeyCurrency currencyDTO = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder() + .platformCode(GamePlatforms.XK.getInfo()) + .code(resultBean.getAgentId()) + .build()); + + Member member = memberService.selectMemberByGameAccount(resultBean.getAccount()); + if (ObjectUtils.isEmpty(member)) { + return null; + } + List gamesDatas = redisCache.getCacheList(CacheConstants.XK_GAMES); + Map dataDTOMap = gamesDatas.stream().collect(Collectors.toMap(XKGamesDTO.DataBean::getGameId, e -> e)); + XKGamesDTO.DataBean gamesDataDTO = dataDTOMap.get(resultBean.getGameId()); + BigDecimal payoffAmount = BigDecimal.ZERO; + + if (GameStatus.WIN.getCode().equals(resultBean.getStatus())) { + payoffAmount = NumberUtil.sub(resultBean.getPayoffAmount(), resultBean.getTurnover()); + } else if (GameStatus.FAIL.getCode().equals(resultBean.getStatus())) { + payoffAmount = NumberUtil.sub(resultBean.getPayoffAmount(), resultBean.getTurnover()).negate(); + } + //数据构造 + GameBettingDetails gameBettingDetails = GameBettingDetails.builder() + .tenantKey(member.getTenantKey()) + //保存我们的币种id + .currencyCode(currencyDTO.getSystemCurrency()) + .memberId(member.getId()) + .gameCode(resultBean.getGameId()) + .gameType(XKGameType.findSystemByCode(resultBean.getGameCategoryId())) + .platformCode(GamePlatforms.XK.getCode()) + .gameId(gamesDataDTO.getSystemGameId()) + .gameName(gamesDataDTO.getName()) + .gameStatus(resultBean.getStatus()) + .gameStatusType(resultBean.getType()) + .gameCurrencyCode(resultBean.getAgentId()) + .account(String.valueOf(resultBean.getAccount())) + .wagersId(resultBean.getWagersId()) + .wagersTime(resultBean.getWagersTime()) + .betAmount(resultBean.getBetAmount().abs()) + .payoffTime(resultBean.getPayoffTime()) + .payoffAmount(payoffAmount) + .settlementTime(resultBean.getSettlementTime()) + .turnover(resultBean.getTurnover()) + .orderNo(String.valueOf(resultBean.getRoundIndex())) + .settlementStatus(SettlementStatusEnum.COMPLETED.getCode()) + .build(); + gameBettingDetails.setCreateBy(Constants.SYSTEM); + gameBettingDetails.setCreateTime(DateUtils.getNowDate()); + return gameBettingDetails; + } +}