From 922d59591de6546cdccd96ffce9ae2b3757feb25 Mon Sep 17 00:00:00 2001 From: shi Date: Tue, 1 Apr 2025 16:13:44 +0800 Subject: [PATCH] =?UTF-8?q?feat(game):=20=E6=8E=A5=E5=85=A5=20AE=E6=B8=B8?= =?UTF-8?q?=E6=88=8F=E5=B9=B3=E5=8F=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 AE 游戏平台的下注记录获取功能 - 实现 AE平台的余额转换状态查询接口 - 添加 AE 平台的玩家登出接口 - 重构原有 XK 平台的相关代码,改为支持 AE 平台 --- .../com/ff/base/constant/CacheConstants.java | 8 + .../java/com/ff/base/utils/DateUtils.java | 24 ++ .../com/ff/game/api/ae/client/AEClient.java | 43 +++- .../game/api/ae/dto/AEBetRecordResponse.java | 186 ++++++++++++++ .../dto/AEExchangeTransferStatusResponse.java | 54 +++++ .../game/api/ae/dto/AELogoutUserResponse.java | 33 +++ .../api/ae/dto/XKBetRecordResponseDTO.java | 54 ----- .../api/ae/dto/XKCreateMemberResponseDTO.java | 32 --- .../ae/dto/XKExchangeMoneyResponseDTO.java | 46 ---- .../game/api/ae/dto/XKKickMemberAllDTO.java | 27 --- .../ff/game/api/ae/dto/XKKickMemberDTO.java | 13 - .../XKLoginWithoutRedirectResponseDTO.java | 29 --- .../ff/game/api/ae/dto/XKMemberInfoDTO.java | 49 ---- .../game/api/ae/impl/GamesAEServiceImpl.java | 228 +++++++++++------- .../ExchangeTransferStatusRequestDTO.java | 5 +- .../ff/game/domain/GameBettingDetails.java | 6 + .../java/com/ff/quartz/task/GameTask.java | 1 + 17 files changed, 496 insertions(+), 342 deletions(-) create mode 100644 ff-game/src/main/java/com/ff/game/api/ae/dto/AEBetRecordResponse.java create mode 100644 ff-game/src/main/java/com/ff/game/api/ae/dto/AEExchangeTransferStatusResponse.java create mode 100644 ff-game/src/main/java/com/ff/game/api/ae/dto/AELogoutUserResponse.java delete mode 100644 ff-game/src/main/java/com/ff/game/api/ae/dto/XKBetRecordResponseDTO.java delete mode 100644 ff-game/src/main/java/com/ff/game/api/ae/dto/XKCreateMemberResponseDTO.java delete mode 100644 ff-game/src/main/java/com/ff/game/api/ae/dto/XKExchangeMoneyResponseDTO.java delete mode 100644 ff-game/src/main/java/com/ff/game/api/ae/dto/XKKickMemberAllDTO.java delete mode 100644 ff-game/src/main/java/com/ff/game/api/ae/dto/XKKickMemberDTO.java delete mode 100644 ff-game/src/main/java/com/ff/game/api/ae/dto/XKLoginWithoutRedirectResponseDTO.java delete mode 100644 ff-game/src/main/java/com/ff/game/api/ae/dto/XKMemberInfoDTO.java diff --git a/ff-base/src/main/java/com/ff/base/constant/CacheConstants.java b/ff-base/src/main/java/com/ff/base/constant/CacheConstants.java index 676af5f..b922b43 100644 --- a/ff-base/src/main/java/com/ff/base/constant/CacheConstants.java +++ b/ff-base/src/main/java/com/ff/base/constant/CacheConstants.java @@ -83,5 +83,13 @@ public class CacheConstants */ public static final String PG_GAMES_BET_CURRENCY= "pg_games:bet:currency"; + /** + * ae时间从 + */ + public static final String AE_TIME_FROM= "ae:time:from"; } + + + + diff --git a/ff-base/src/main/java/com/ff/base/utils/DateUtils.java b/ff-base/src/main/java/com/ff/base/utils/DateUtils.java index 49e7441..36043d1 100644 --- a/ff-base/src/main/java/com/ff/base/utils/DateUtils.java +++ b/ff-base/src/main/java/com/ff/base/utils/DateUtils.java @@ -38,6 +38,8 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils { public static String DAY_END_TIME = "23:59:59"; + public static final String ISO_8601_FORMAT= "yyyy-MM-dd'T'HH:mm:ss"; + /** * 获取当前Date型日期 * @@ -202,6 +204,28 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils { return zdt.format(formatter); } + /** + * 将时间戳转换为指定格式的时间字符串 + * + * @param timestamp 时间戳(毫秒) + * @param format 目标时间格式,例如:yyyy-MM-dd'T'HH:mm:ssXXX + * @param timeZone 时区,例如:GMT+8,UTC等 + * @return 格式化后的时间字符串 + */ + public static String convertTimestampToFormattedDate(long timestamp, String format, String timeZone) { + // 创建日期格式化对象 + SimpleDateFormat sdf = new SimpleDateFormat(format); + + // 设置时区为GMT+8 + sdf.setTimeZone(TimeZone.getTimeZone(timeZone)); + + // 转换为 Date 对象 + Date date = new Date(timestamp); + + // 返回格式化后的时间字符串 + return sdf.format(date); + } + /** * 将毫秒时间戳转换为指定时区的时间,并按指定格式输出 * diff --git a/ff-game/src/main/java/com/ff/game/api/ae/client/AEClient.java b/ff-game/src/main/java/com/ff/game/api/ae/client/AEClient.java index e87950c..032cc08 100644 --- a/ff-game/src/main/java/com/ff/game/api/ae/client/AEClient.java +++ b/ff-game/src/main/java/com/ff/game/api/ae/client/AEClient.java @@ -4,6 +4,8 @@ import com.dtflys.forest.annotation.*; import com.ff.game.api.ae.address.MyAEAddressSource; import com.ff.game.api.ae.dto.*; import com.ff.game.api.jili.dto.*; +import com.ff.game.api.xk.dto.XKKickMemberAllDTO; +import com.ff.game.api.xk.dto.XKKickMemberDTO; import java.util.Map; @@ -69,24 +71,53 @@ public interface AEClient { }) AETransactionResponse withdraw(@Body Map params); + + /** + * 汇兑转移状态 + * + * @param params 参数 + * @return {@link AEExchangeTransferStatusResponse } + */ + @Post(url ="/wallet/checkTransferOperation", + headers = { + "Content-type: application/x-www-form-urlencoded" + }) + AEExchangeTransferStatusResponse exchangeTransferStatus(@Body Map params); + /** * 按时间获取投注记录 * * @param params 参数 - * @return {@link XKBetRecordResponseDTO } + * @return {@link AEBetRecordResponse } */ - @Post(url = "/getGameRecordByTime") - XKBetRecordResponseDTO getBetRecordByTime(@JSONBody Map params); - + @Post(url ="https://tttfetch.apihub55.com/fetch/gzip/getTransactionByUpdateDate", + headers = { + "Content-type: application/x-www-form-urlencoded" + }) + AEBetRecordResponse getBetRecordByTime(@Body Map params); + /** + * 按时间获取投注历史记录 + * + * @param params 参数 + * @return {@link AEBetRecordResponse } + */ + @Post(url ="https://tttfetch.apihub55.com/fetch/gzip/getTransactionByTxTime", + headers = { + "Content-type: application/x-www-form-urlencoded" + }) + AEBetRecordResponse getBetHistoryRecordByTime(@Body Map params); /** * 踢出队员 * * @param params 参数 * @return {@link JILIKickMemberDTO } */ - @Post("/kickMember") - XKKickMemberDTO kickMember(@JSONBody Map params); + @Post(url ="/wallet/logout", + headers = { + "Content-type: application/x-www-form-urlencoded" + }) + XKKickMemberDTO kickMember(@Body Map params); /** * 踢出所有队员 diff --git a/ff-game/src/main/java/com/ff/game/api/ae/dto/AEBetRecordResponse.java b/ff-game/src/main/java/com/ff/game/api/ae/dto/AEBetRecordResponse.java new file mode 100644 index 0000000..a288b22 --- /dev/null +++ b/ff-game/src/main/java/com/ff/game/api/ae/dto/AEBetRecordResponse.java @@ -0,0 +1,186 @@ +package com.ff.game.api.ae.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +/** + * aebet记录响应 + * + * @author shi + * @date 2025/04/01 + */ +@Data +public class AEBetRecordResponse { + + /** + * 状态代码 + */ + @JsonProperty("status") + private Integer status; + + /** + * 描述信息 (String类型) + * "Success" - 请求成功 + * 其他 - 错误信息 + */ + private String desc; + /** + * 交易记录 + */ + @JsonProperty("transactions") + private List transactions; + + @Data + public static class Transaction { + + /** + * 游戏类型 + */ + @JsonProperty("gameType") + private String gameType; + + /** + * 返还金额(包含下注金额) + */ + @JsonProperty("winAmount") + private BigDecimal winAmount; + + /** + * 交易时间 + */ + @JsonProperty("txTime") + private Date txTime; + + /** + * 结算状态 + */ + @JsonProperty("settleStatus") + private Integer settleStatus; + + /** + * 游戏信息 + */ + @JsonProperty("gameInfo") + private String gameInfo; + + /** + * 真实返还金额 + */ + @JsonProperty("realWinAmount") + private BigDecimal realWinAmount; + + /** + * 更新时间 + */ + @JsonProperty("updateTime") + private String updateTime; + + /** + * 真实下注金额 + */ + @JsonProperty("realBetAmount") + private BigDecimal realBetAmount; + + /** + * 用户ID + */ + @JsonProperty("userId") + private String userId; + + /** + * 下注类型 + */ + @JsonProperty("betType") + private String betType; + + /** + * 平台名称 + */ + @JsonProperty("platform") + private String platform; + + /** + * 交易状态 + */ + @JsonProperty("txStatus") + private Integer txStatus; + + /** + * 下注金额 + */ + @JsonProperty("betAmount") + private BigDecimal betAmount; + + /** + * 游戏名称 + */ + @JsonProperty("gameName") + private String gameName; + + /** + * 平台注单号 + */ + @JsonProperty("platformTxId") + private String platformTxId; + + /** + * 下注时间 + */ + @JsonProperty("betTime") + private Date betTime; + + /** + * 平台游戏代码 + */ + @JsonProperty("gameCode") + private String gameCode; + + /** + * 玩家货币代码 + */ + @JsonProperty("currency") + private String currency; + + /** + * 累积奖金的获胜金额 + */ + @JsonProperty("jackpotWinAmount") + private BigDecimal jackpotWinAmount; + + /** + * 累积奖金贡献金额 + */ + @JsonProperty("jackpotBetAmount") + private BigDecimal jackpotBetAmount; + + /** + * 平台有效投注 + */ + @JsonProperty("turnover") + private BigDecimal turnover; + + /** + * 游戏商的回合识别码 + */ + @JsonProperty("roundId") + private String roundId; + + + + /** + * 子注单号 + */ + @JsonProperty("refPlatformTxId") + private String refPlatformTxId; + + /** + * 是否为特殊收费游戏 + */ + @JsonProperty("isPremium") + private Boolean isPremium; + } +} diff --git a/ff-game/src/main/java/com/ff/game/api/ae/dto/AEExchangeTransferStatusResponse.java b/ff-game/src/main/java/com/ff/game/api/ae/dto/AEExchangeTransferStatusResponse.java new file mode 100644 index 0000000..c2d064e --- /dev/null +++ b/ff-game/src/main/java/com/ff/game/api/ae/dto/AEExchangeTransferStatusResponse.java @@ -0,0 +1,54 @@ +package com.ff.game.api.ae.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + + +/** + * aeexchange传输状态响应 + * + * @author shi + * @date 2025/04/01 + */ +@Data +public class AEExchangeTransferStatusResponse { + + /** + * 响应状态 + */ + @JsonProperty("status") + private String status; + + /** + * 情境 1:响应 status = 0000 & txStatus = 1 表示存款/提款成功 + * 情境 2:响应 status = 0000 & txStatus = 0 表示存款/提款失败 + * 情境 3:响应 status = 0000 & txStatus = 2 表示存款/提款处理中,可 3 秒后调用 checkTransferOperation API 确认回覆直到 txStatus = 0 或 1 的回覆 + * 情境 4:响应 status = 1017 表示交易不存在 + */ + @JsonProperty("txStatus") + private String txStatus; + + /** + * 当前余额 + */ + @JsonProperty("balance") + private double balance; + + /** + * 转账金额 + */ + @JsonProperty("transferAmount") + private double transferAmount; + + /** + * 转账类型(如:DEPOSIT 或 WITHDRAW) + */ + @JsonProperty("transferType") + private String transferType; + + /** + * 交易代码 + */ + @JsonProperty("txCode") + private String txCode; +} diff --git a/ff-game/src/main/java/com/ff/game/api/ae/dto/AELogoutUserResponse.java b/ff-game/src/main/java/com/ff/game/api/ae/dto/AELogoutUserResponse.java new file mode 100644 index 0000000..7451bce --- /dev/null +++ b/ff-game/src/main/java/com/ff/game/api/ae/dto/AELogoutUserResponse.java @@ -0,0 +1,33 @@ +package com.ff.game.api.ae.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +/** + * 注销用户响应 + * + * @author shi + * @date 2025/04/01 + */ +@Data +public class AELogoutUserResponse { + /** + * 状态代码 + */ + @JsonProperty("status") + private String status; + + /** + * 已注销的用户列表 + */ + @JsonProperty("logoutUsers") + private List logoutUsers; + + /** + * 用户数量 + */ + @JsonProperty("count") + private Integer count; +} diff --git a/ff-game/src/main/java/com/ff/game/api/ae/dto/XKBetRecordResponseDTO.java b/ff-game/src/main/java/com/ff/game/api/ae/dto/XKBetRecordResponseDTO.java deleted file mode 100644 index a4c3540..0000000 --- a/ff-game/src/main/java/com/ff/game/api/ae/dto/XKBetRecordResponseDTO.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.ff.game.api.ae.dto; - -import io.jsonwebtoken.lang.Collections; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; - -@NoArgsConstructor -@Data -public class XKBetRecordResponseDTO { - - private Integer code; - private String msg; - private DataBean data; - - @NoArgsConstructor - @Data - public static class DataBean { - private Integer currentPage; - private Integer totalPages; - private Integer pageLimit; - private Integer totalNumber; - private List result; - - public List getResult() { - if (Collections.isEmpty(result)) { - return new ArrayList<>(); - } - return result; - } - - @NoArgsConstructor - @Data - public static class ResultBean { - private String account; - private Long wagersId; - private String gameId; - private Long wagersTime; - private BigDecimal betAmount; - private Long payoffTime; - private BigDecimal payoffAmount; - private Integer status; - private Long settlementTime; - private Integer gameCategoryId; - private Integer type; - private String agentId; - private BigDecimal turnover; - private Long roundIndex; - } - } -} diff --git a/ff-game/src/main/java/com/ff/game/api/ae/dto/XKCreateMemberResponseDTO.java b/ff-game/src/main/java/com/ff/game/api/ae/dto/XKCreateMemberResponseDTO.java deleted file mode 100644 index 01578a0..0000000 --- a/ff-game/src/main/java/com/ff/game/api/ae/dto/XKCreateMemberResponseDTO.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.ff.game.api.ae.dto; - - -import com.ff.game.api.request.GamesBaseRequestDTO; -import lombok.Data; -import lombok.NoArgsConstructor; - - -/** - * 创建成员响应dto - * - * @author shi - * @date 2024/10/22 - */ -@NoArgsConstructor -@Data -public class XKCreateMemberResponseDTO extends GamesBaseRequestDTO { - - - /** - * 代码 - */ - private int code; - /** - * 数据 - */ - private String data; - /** - * msg - */ - private String msg; -} diff --git a/ff-game/src/main/java/com/ff/game/api/ae/dto/XKExchangeMoneyResponseDTO.java b/ff-game/src/main/java/com/ff/game/api/ae/dto/XKExchangeMoneyResponseDTO.java deleted file mode 100644 index be8a729..0000000 --- a/ff-game/src/main/java/com/ff/game/api/ae/dto/XKExchangeMoneyResponseDTO.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.ff.game.api.ae.dto; - -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.math.BigDecimal; - -@NoArgsConstructor -@Data -public class XKExchangeMoneyResponseDTO { - - private int code; - private String msg; - private DataBean data; - - @NoArgsConstructor - @Data - public static class DataBean { - /** - * 交易序号,额度转移纪录唯一值, 长度上限 50 - */ - private String transactionId; - /** - * 转账前金额(游戏币) - */ - private BigDecimal coinBefore; - /** - * 转账后金额(游戏币) - */ - private BigDecimal coinAfter; - /** - * 转账前金额(指定货币) - */ - private BigDecimal currencyBefore; - /** - * 转账后金额(指定货币) - */ - private BigDecimal currencyAfter; - /** - * 状态: - * 1: 成功 - * 2: 失败 - */ - private Integer status; - } -} diff --git a/ff-game/src/main/java/com/ff/game/api/ae/dto/XKKickMemberAllDTO.java b/ff-game/src/main/java/com/ff/game/api/ae/dto/XKKickMemberAllDTO.java deleted file mode 100644 index ea17acc..0000000 --- a/ff-game/src/main/java/com/ff/game/api/ae/dto/XKKickMemberAllDTO.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.ff.game.api.ae.dto; - -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * xkkick会员全部dto - * - * @author shi - * @date 2024/11/13 - */ -@Data -@NoArgsConstructor -public class XKKickMemberAllDTO { - /** - * 代码 - */ - private int code; - /** - * 数据 - */ - private String data; - /** - * msg - */ - private String msg; -} diff --git a/ff-game/src/main/java/com/ff/game/api/ae/dto/XKKickMemberDTO.java b/ff-game/src/main/java/com/ff/game/api/ae/dto/XKKickMemberDTO.java deleted file mode 100644 index ac5ea42..0000000 --- a/ff-game/src/main/java/com/ff/game/api/ae/dto/XKKickMemberDTO.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.ff.game.api.ae.dto; - -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@Data -public class XKKickMemberDTO { - - private int code; - private String msg; - private Object data; -} diff --git a/ff-game/src/main/java/com/ff/game/api/ae/dto/XKLoginWithoutRedirectResponseDTO.java b/ff-game/src/main/java/com/ff/game/api/ae/dto/XKLoginWithoutRedirectResponseDTO.java deleted file mode 100644 index e622416..0000000 --- a/ff-game/src/main/java/com/ff/game/api/ae/dto/XKLoginWithoutRedirectResponseDTO.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.ff.game.api.ae.dto; - -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * 登录时不重定向响应dto - * - * @author shi - * @date 2024/10/22 - */ -@NoArgsConstructor -@Data -public class XKLoginWithoutRedirectResponseDTO { - - - /** - * 代码 - */ - private int code; - /** - * 数据 - */ - private String data; - /** - * msg - */ - private String msg; -} diff --git a/ff-game/src/main/java/com/ff/game/api/ae/dto/XKMemberInfoDTO.java b/ff-game/src/main/java/com/ff/game/api/ae/dto/XKMemberInfoDTO.java deleted file mode 100644 index ae6a3bb..0000000 --- a/ff-game/src/main/java/com/ff/game/api/ae/dto/XKMemberInfoDTO.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.ff.game.api.ae.dto; - -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.math.BigDecimal; -import java.util.List; - -/** - * 会员信息dto - * - * @author shi - * @date 2024/10/30 - */ -@NoArgsConstructor -@Data -public class XKMemberInfoDTO { - - - /** - * 代码 - */ - private Integer code; - /** - * msg - */ - private String msg; - /** - * 数据 - */ - private List data; - - @NoArgsConstructor - @Data - public static class DataBean { - /** - * 账户 - */ - private String account; - /** - * 平衡 - */ - private BigDecimal balance; - /** - * 地位 - */ - private Integer status; - } -} diff --git a/ff-game/src/main/java/com/ff/game/api/ae/impl/GamesAEServiceImpl.java b/ff-game/src/main/java/com/ff/game/api/ae/impl/GamesAEServiceImpl.java index 7003447..2c66655 100644 --- a/ff-game/src/main/java/com/ff/game/api/ae/impl/GamesAEServiceImpl.java +++ b/ff-game/src/main/java/com/ff/game/api/ae/impl/GamesAEServiceImpl.java @@ -11,13 +11,21 @@ import com.ff.base.exception.base.BaseException; import com.ff.base.system.service.ISysConfigService; import com.ff.base.utils.DateUtils; import com.ff.base.utils.JsonUtil; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.TenantUtils; import com.ff.base.utils.uuid.IdUtils; +import com.ff.common.dto.GameBalanceExchange; +import com.ff.common.service.ITenantGameQuotaFlowService; +import com.ff.common.service.ITenantGameQuotaService; import com.ff.config.KeyConfig; import com.ff.game.api.IGamesService; import com.ff.game.api.ae.client.AEClient; import com.ff.game.api.ae.dto.*; +import com.ff.game.api.ng.dto.ApiExchangeTransferStatusResponseDTO; +import com.ff.game.api.ng.dto.ApiNGResponseDTO; import com.ff.game.api.request.*; import com.ff.game.api.xk.dto.XKGamesDTO; +import com.ff.game.api.xk.dto.XKKickMemberDTO; import com.ff.game.domain.*; import com.ff.game.dto.GameSecretKeyCurrencyDTO; import com.ff.game.service.*; @@ -63,7 +71,8 @@ public class GamesAEServiceImpl implements IGamesService { @Resource private IGameService gameService; - + @Resource + private ITenantGameQuotaService tenantGameQuotaService; @Resource private IMemberService memberService; @@ -308,10 +317,15 @@ public class GamesAEServiceImpl implements IGamesService { deposit = AEClient.withdraw(params); } } finally { - + BigDecimal coinBefore; + if (TransferType.GAMES.getCode().equals(exchangeTransferMoneyRequestDTO.getTransferType())) { + coinBefore = NumberUtil.sub(deposit.getCurrentBalance(), deposit.getAmount()); + } else { + coinBefore = NumberUtil.add(deposit.getCurrentBalance(), deposit.getAmount()); + } //更新数据 exchangeMoney.setBalance(deposit.getAmount()); - exchangeMoney.setCoinBefore(NumberUtil.sub(deposit.getCurrentBalance(), deposit.getAmount())); + exchangeMoney.setCoinBefore(coinBefore); exchangeMoney.setCoinAfter(deposit.getCurrentBalance()); exchangeMoney.setCurrencyBefore(exchangeMoney.getCoinBefore()); exchangeMoney.setCurrencyAfter(exchangeMoney.getCoinAfter()); @@ -338,6 +352,39 @@ public class GamesAEServiceImpl implements IGamesService { @Override public Boolean exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO) { log.info("GamesAEServiceImpl [exchangeTransferStatus] 请求参数 {}", exchangeTransferMoneyRequestDTO); + + Map paramsMap = this.getKey(exchangeTransferMoneyRequestDTO); + paramsMap.put("txCode", exchangeTransferMoneyRequestDTO.getOrderId()); + + AEExchangeTransferStatusResponse exchangeTransferStatusResponse = AEClient.exchangeTransferStatus(paramsMap); + Integer status = StatusType.IN_PROGRESS.getValue(); + if ("0000".equals(exchangeTransferStatusResponse.getStatus()) && "1".equals(exchangeTransferStatusResponse.getTxStatus())) { + status = StatusType.SUCCESS.getValue(); + } else if ("0000".equals(exchangeTransferStatusResponse.getStatus()) && "0".equals(exchangeTransferStatusResponse.getTxStatus())) { + status = StatusType.FAILURE.getValue(); + } else if ("1017".equals(exchangeTransferStatusResponse.getStatus())) { + status = StatusType.FAILURE.getValue(); + } + GameExchangeMoney exchangeMoney = gameExchangeMoneyService.selectGameExchangeMoneyById(exchangeTransferMoneyRequestDTO.getGameExchangeMoneyId()); + + //如果失败扣除租户之前被扣额度 + if (status.equals(StatusType.FAILURE.getValue())) { + Member member = memberService.selectMemberById(exchangeMoney.getMemberId()); + tenantGameQuotaService.gameBalanceExchange(GameBalanceExchange.builder() + .platformCode(exchangeMoney.getPlatformCode()) + .sourceId(exchangeMoney.getOrderId()) + .currencyCode(exchangeMoney.getCurrencyCode()) + .transferType(TransferType.ALL.getCode()) + .amount(exchangeMoney.getBalance()) + .account(member.getMemberAccount()) + .tenantKey(exchangeMoney.getTenantKey()) + .build()); + } + exchangeMoney.setStatus(status); + exchangeMoney.setUpdateBy(Constants.SYSTEM); + gameExchangeMoneyService.updateGameExchangeMoney(exchangeMoney); + + return Boolean.TRUE; } @@ -350,50 +397,29 @@ public class GamesAEServiceImpl implements IGamesService { */ @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); - Map key = this.getKey(betRecordByTimeDTO); - params.put("key", key); - XKBetRecordResponseDTO xkBetRecordResponseDTO = AEClient.getBetRecordByTime(params); + log.info("GamesAEServiceImpl [getBetRecordByTime] 请求参数 {}", betRecordByTimeDTO); + Map params = this.getKey(betRecordByTimeDTO); + + String timeFrom = redisCache.getCacheObject(CacheConstants.AE_TIME_FROM); + if (StringUtils.isEmpty(timeFrom)){ + timeFrom = DateUtils.convertTimestampToFormattedDate(betRecordByTimeDTO.getEndTime(), DateUtils.ISO_8601_FORMAT, "GMT+8")+"+08:00"; + } + + + params.put("timeFrom", timeFrom); + params.put("platform", "SEXYBCRT"); + params.put("delayTime",10000); + AEBetRecordResponse aeBetRecordResponse = AEClient.getBetRecordByTime(params); //判断是否获取成功 - if (this.getIsSuccess(xkBetRecordResponseDTO.getCode())) { + if (this.getIsSuccess(aeBetRecordResponse.getStatus())) { //数据组装 - 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); - params.put("key", key); - xkBetRecordResponseDTO = AEClient.getBetRecordByTime(params); - this.batchInsert(xkBetRecordResponseDTO); - } - - + this.batchInsert(aeBetRecordResponse); return Boolean.TRUE; } else { - log.error("GamesXKServiceImpl [getBetRecordByTime] 获取投注记录失败,错误代码{},错误信息{}", xkBetRecordResponseDTO.getCode(), xkBetRecordResponseDTO.getMsg()); - throw new BaseException(xkBetRecordResponseDTO.getMsg()); + log.error("GamesAEServiceImpl [getBetRecordByTime] 获取投注记录失败,错误代码{},错误信息{}", aeBetRecordResponse.getStatus(), aeBetRecordResponse.getDesc()); + throw new BaseException(aeBetRecordResponse.getDesc()); } } @@ -406,7 +432,28 @@ public class GamesAEServiceImpl implements IGamesService { */ @Override public Boolean getBetRecordByHistoryTime(BetRecordByTimeDTO betRecordByTimeDTO) { - return null; + log.info("GamesAEServiceImpl [getBetRecordByHistoryTime] 请求参数 {}", betRecordByTimeDTO); + Map params = this.getKey(betRecordByTimeDTO); + + long startTimeLong = DateUtils.addOrSubtractMinutes(betRecordByTimeDTO.getStartTime(), -40); + String startTime = DateUtils.convertTimestampToFormattedDate(startTimeLong, DateUtils.ISO_8601_FORMAT, "GMT+8")+"+08:00"; + String endTime = DateUtils.convertTimestampToFormattedDate(betRecordByTimeDTO.getEndTime(), DateUtils.ISO_8601_FORMAT, "GMT+8")+"+08:00"; + + + params.put("startTime", startTime); + params.put("endTime", endTime); + params.put("platform","SEXYBCRT"); + AEBetRecordResponse aeBetRecordResponse = AEClient.getBetHistoryRecordByTime(params); + + //判断是否获取成功 + if (this.getIsSuccess(aeBetRecordResponse.getStatus())) { + //数据组装 + this.batchInsert(aeBetRecordResponse); + return Boolean.TRUE; + } else { + log.error("GamesAEServiceImpl [getBetRecordByHistoryTime] 获取投注记录失败,错误代码{},错误信息{}", aeBetRecordResponse.getStatus(), aeBetRecordResponse.getDesc()); + throw new BaseException(aeBetRecordResponse.getDesc()); + } } /** @@ -439,14 +486,9 @@ public class GamesAEServiceImpl implements IGamesService { */ @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); - Map key = this.getKey(kickMemberRequestDTO); - params.put("key", key); + log.info("GamesAEServiceImpl [kickMember] 请求参数 {}", kickMemberRequestDTO); + Map params = this.getKey(kickMemberRequestDTO); + params.put("userIds", kickMemberRequestDTO.getAccount()); XKKickMemberDTO xkKickMemberDTO = AEClient.kickMember(params); //判断是否获取成功 if (this.getIsSuccess(xkKickMemberDTO.getCode())) { @@ -493,25 +535,28 @@ public class GamesAEServiceImpl implements IGamesService { /** * 批量插入 * - * @param xkBetRecordResponseDTO xk下注记录响应dto + * @param aeBetRecordResponse ae下注记录响应dto */ - private void batchInsert(XKBetRecordResponseDTO xkBetRecordResponseDTO) { + private void batchInsert(AEBetRecordResponse aeBetRecordResponse) { List gameBettingDetails = new ArrayList<>(); List wagersIds = new ArrayList<>(); //数据组装 - XKBetRecordResponseDTO.DataBean dataBean = xkBetRecordResponseDTO.getData(); + List dataBean = aeBetRecordResponse.getTransactions(); + + String timeFrom=null ; //数据转化 - for (XKBetRecordResponseDTO.DataBean.ResultBean bean : dataBean.getResult()) { + for (AEBetRecordResponse.Transaction bean : dataBean) { GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder().data(bean).build()); if (!ObjectUtils.isEmpty(bettingDetails)) { bettingDetails.setId(IdUtil.getSnowflakeNextId()); gameBettingDetails.add(bettingDetails); } - wagersIds.add(String.valueOf(bean.getWagersId())); + wagersIds.add(bean.getPlatform() + bean.getPlatformTxId()); + timeFrom=bean.getUpdateTime(); } if (!CollectionUtils.isEmpty(gameBettingDetails)) { //查询重复数据id - List removeWagersIds = gameBettingDetailsService.selectGameBettingDetailsByWagersId(wagersIds,GamePlatforms.AE.getInfo()); + List removeWagersIds = gameBettingDetailsService.selectGameBettingDetailsByWagersId(wagersIds, GamePlatforms.AE.getInfo()); //用steam流清除list中与wagersIds集合相同的数据 gameBettingDetails = gameBettingDetails.stream() .filter(detail -> !removeWagersIds.contains(detail.getWagersId())) @@ -520,7 +565,10 @@ public class GamesAEServiceImpl implements IGamesService { gameBettingDetailsService.batchInsert(gameBettingDetails); } } - + if (StringUtils.isEmpty(timeFrom)){ + timeFrom = DateUtils.convertTimestampToFormattedDate(DateUtils.getNowDate(), DateUtils.ISO_8601_FORMAT, "UTC+8")+"+08:00"; + } + redisCache.setCacheObject(CacheConstants.AE_TIME_FROM, timeFrom); } /** @@ -532,51 +580,61 @@ public class GamesAEServiceImpl implements IGamesService { @Override public GameBettingDetails dataBuild(GamesDataBuildDTO gamesDataBuildDTO) { //转化类 - XKBetRecordResponseDTO.DataBean.ResultBean resultBean = (XKBetRecordResponseDTO.DataBean.ResultBean) gamesDataBuildDTO.getData(); + AEBetRecordResponse.Transaction resultBean = (AEBetRecordResponse.Transaction) gamesDataBuildDTO.getData(); GameSecretKeyCurrency currencyDTO = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder() - .platformCode(GamePlatforms.XK.getInfo()) - .code(resultBean.getAgentId()) + .platformCode(GamePlatforms.AE.getInfo()) + .currency(resultBean.getCurrency()) .build()); - Member member = memberService.selectMemberByGameAccount(resultBean.getAccount()); + Member member = memberService.selectMemberByGameAccount(resultBean.getUserId()); 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(); + + // 判断输赢 + Integer gameStatus = GameStatus.FLAT.getCode(); + BigDecimal payoffAmount=BigDecimal.ZERO; + if (resultBean.getRealWinAmount().compareTo(resultBean.getRealBetAmount()) > 0) { + gameStatus = GameStatus.WIN.getCode(); + payoffAmount=resultBean.getRealWinAmount().subtract(resultBean.getRealBetAmount()); + } else if (resultBean.getRealWinAmount().compareTo(resultBean.getRealBetAmount()) < 0) { + gameStatus = GameStatus.FAIL.getCode(); + payoffAmount=resultBean.getRealWinAmount().subtract(resultBean.getRealBetAmount()).abs(); } + + //结算状态 + int settlementStatus=SettlementStatusEnum.REVOKED.getCode(); + if (resultBean.getTxStatus() == 1){ + settlementStatus=SettlementStatusEnum.COMPLETED.getCode(); + } + //数据构造 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(String.valueOf(resultBean.getWagersId())) - .wagersTime(resultBean.getWagersTime()) - .betAmount(resultBean.getBetAmount().abs()) - .payoffTime(resultBean.getPayoffTime()) + .gameCode(resultBean.getGameCode()) + .gameType(PlatformType.GAME_HALL.getCode()) + .platformCode(GamePlatforms.AE.getCode()) + .gameId(GAME_ID) + .gameName(resultBean.getGameName()) + .gameStatus(gameStatus) + .gameStatusType(resultBean.getSettleStatus()) + .gameCurrencyCode(resultBean.getCurrency()) + .account(resultBean.getUserId()) + .wagersId(resultBean.getPlatform()+resultBean.getPlatformTxId()) + .wagersTime(resultBean.getBetTime().getTime()) + .betAmount(resultBean.getRealBetAmount()) + .payoffTime(resultBean.getTxTime().getTime()) .payoffAmount(payoffAmount) - .settlementTime(resultBean.getSettlementTime()) + .betContent(resultBean.getGameInfo()) + .settlementTime(resultBean.getTxTime().getTime()) .turnover(resultBean.getTurnover()) - .orderNo(String.valueOf(resultBean.getRoundIndex())) - .settlementStatus(SettlementStatusEnum.COMPLETED.getCode()) + .orderNo(String.valueOf(resultBean.getRoundId())) + .settlementStatus(settlementStatus) .build(); gameBettingDetails.setCreateBy(Constants.SYSTEM); gameBettingDetails.setCreateTime(DateUtils.getNowDate()); diff --git a/ff-game/src/main/java/com/ff/game/api/request/ExchangeTransferStatusRequestDTO.java b/ff-game/src/main/java/com/ff/game/api/request/ExchangeTransferStatusRequestDTO.java index 353c3fd..8739091 100644 --- a/ff-game/src/main/java/com/ff/game/api/request/ExchangeTransferStatusRequestDTO.java +++ b/ff-game/src/main/java/com/ff/game/api/request/ExchangeTransferStatusRequestDTO.java @@ -29,5 +29,8 @@ public class ExchangeTransferStatusRequestDTO extends GamesBaseRequestDTO { */ private String orderId; - + /** + * 游戏兑换货币id + */ + private Long gameExchangeMoneyId; } diff --git a/ff-game/src/main/java/com/ff/game/domain/GameBettingDetails.java b/ff-game/src/main/java/com/ff/game/domain/GameBettingDetails.java index 04eb913..06791d1 100644 --- a/ff-game/src/main/java/com/ff/game/domain/GameBettingDetails.java +++ b/ff-game/src/main/java/com/ff/game/domain/GameBettingDetails.java @@ -82,6 +82,12 @@ public class GameBettingDetails extends BaseEntity 28 旋转奖金 DG (1:注单,2:红包小费) + AE + 正常状况: + 预设:0 + 结果更改过状况: + Resettle / Unsettle / Voidsettle / Unvoidsettle: 1 + Voidbet: -1 */ @Excel(name = "注单类型") diff --git a/ff-game/src/main/java/com/ff/quartz/task/GameTask.java b/ff-game/src/main/java/com/ff/quartz/task/GameTask.java index 6675502..fe43fbe 100644 --- a/ff-game/src/main/java/com/ff/quartz/task/GameTask.java +++ b/ff-game/src/main/java/com/ff/quartz/task/GameTask.java @@ -271,6 +271,7 @@ public class GameTask { exchangeTransferStatusRequestDTO.setOrderId(exchangeMoney.getTransactionId()); exchangeTransferStatusRequestDTO.setAgentId(gameSecretKey.getCode()); exchangeTransferStatusRequestDTO.setAgentKey(gameSecretKey.getKey()); + exchangeTransferStatusRequestDTO.setGameExchangeMoneyId(exchangeMoney.getId()); gamesService.get(exchangeMoney.getPlatformCode() + Constants.SERVICE).exchangeTransferStatus(exchangeTransferStatusRequestDTO); } catch (Exception e) { log.error("查询 更新交易记录失败,错误信息 {}", e);