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 0dbb96e..676af5f 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 @@ -52,6 +52,11 @@ public class CacheConstants */ public static final String XK_GAMES= "xk_games:"; + /** + * pgx游戏 + */ + public static final String PGX_GAMES= "pgx_games:"; + /** * pg游戏 */ 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 4f76fe7..cfb844f 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 @@ -203,6 +203,10 @@ public class Constants { */ public static final String XK_API_BASE_URL = "xk.api.base.url"; + /** + * pgx-api基本url + */ + public static final String PGX_API_BASE_URL = "gpx.api.base.url"; /** * dg-api基本url diff --git a/ff-base/src/main/java/com/ff/base/enums/GPXGameType.java b/ff-base/src/main/java/com/ff/base/enums/GPXGameType.java new file mode 100644 index 0000000..c1ad300 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/GPXGameType.java @@ -0,0 +1,55 @@ +package com.ff.base.enums; + + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Optional; +import java.util.stream.Stream; + + +/** + * xkgame类型 + * + * @author shi + * @date 2024/11/13 + */ +@Getter +@AllArgsConstructor +public enum GPXGameType { + + SL("SL", 1,"电子") + + ; + + private final String code; + private final Integer systemCode; + private final String info; + /** + * 按代码查找系统 + * + * @param code 代码 + * @return {@link String } + */ + public static Integer findSystemByCode(String code) { + Optional system = Stream.of(XKGameType.values()) + .filter(gameType -> gameType.getCode().equals(code)) + .map(XKGameType::getSystemCode) + .findFirst(); + return system.orElse(null); + } + + /** + * 按代码查找信息 + * + * @param code 代码 + * @return {@link String } + */ + public static String findInfoByCode(String code) { + Optional system = Stream.of(XKGameType.values()) + .filter(gameType -> gameType.getCode().equals(code)) + .map(XKGameType::getInfo) + .findFirst(); + return system.orElse(null); + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/GamePlatforms.java b/ff-base/src/main/java/com/ff/base/enums/GamePlatforms.java index ddb0e04..6bd60a4 100644 --- a/ff-base/src/main/java/com/ff/base/enums/GamePlatforms.java +++ b/ff-base/src/main/java/com/ff/base/enums/GamePlatforms.java @@ -7,6 +7,7 @@ public enum GamePlatforms { JILI("JILI", "JILI"), XK("XK", "XK"), PG("PG", "PG"), + PGX("PGX", "PGX"), FC("FC", "FC"), SA("SA", "SA"), DG("DG", "DG"), diff --git a/ff-base/src/main/java/com/ff/base/enums/PGXBetRecordStatus.java b/ff-base/src/main/java/com/ff/base/enums/PGXBetRecordStatus.java new file mode 100644 index 0000000..1a57e04 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/PGXBetRecordStatus.java @@ -0,0 +1,40 @@ +package com.ff.base.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Optional; +import java.util.stream.Stream; + +/** + * pgxbet记录状态 + * + * @author shi + * @date 2025/03/28 + */ +@Getter +@AllArgsConstructor +public enum PGXBetRecordStatus { + VALID(1, 2,"有效注单"), + RUNNING(0,0, "赛事进行中"), + INVALID(-1,3, "无效注单 (作废, 取消)"); + + + private final Integer code; + private final Integer systemCode; + private final String description; + + /** + * 按值查找代码 + * + * @param code 代码 + * @return {@link Integer } + */ + public static Integer findSystemCodeByCode(Integer code) { + Optional system = Stream.of(PGXBetRecordStatus.values()) + .filter(transactionStatusValue -> transactionStatusValue.getCode().equals(code)) + .map(PGXBetRecordStatus::getSystemCode) + .findFirst(); + return system.orElse(null); + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/PGXTransactionStatus.java b/ff-base/src/main/java/com/ff/base/enums/PGXTransactionStatus.java new file mode 100644 index 0000000..1afa96a --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/PGXTransactionStatus.java @@ -0,0 +1,41 @@ +package com.ff.base.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Optional; +import java.util.stream.Stream; + +/** + * 转移状态 + * + * @author shi + * @date 2025/03/28 + */ +@AllArgsConstructor +@Getter +public enum PGXTransactionStatus { + SUCCESS("SUCCESS",1, "成功"), + PROCESSING("PROCESSING",0, "进行中,请稍后再确认"), + FAILED("FAILED",2, "失败"); + + // 枚举字段 + private final String code; + private final Integer value; + private final String description; + + + /** + * 按值查找代码 + * + * @param code 代码 + * @return {@link Integer } + */ + public static Integer findValueByCode(String code) { + Optional system = Stream.of(PGXTransactionStatus.values()) + .filter(transactionStatusValue -> transactionStatusValue.getCode().equals(code)) + .map(PGXTransactionStatus::getValue) + .findFirst(); + return system.orElse(null); + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/PGXTransferType.java b/ff-base/src/main/java/com/ff/base/enums/PGXTransferType.java new file mode 100644 index 0000000..6b3bbbe --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/PGXTransferType.java @@ -0,0 +1,22 @@ +package com.ff.base.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 长传输类型 + * + * @author shi + * @date 2025/03/12 + */ +@Getter +@AllArgsConstructor +public enum PGXTransferType { + WITHDRAW("1", "提出"), + DEPOSIT("0", "存入"); + + private final String code; + private final String description; + + +} diff --git a/ff-base/src/main/java/com/ff/base/utils/RandomGeneratorUtils.java b/ff-base/src/main/java/com/ff/base/utils/RandomGeneratorUtils.java index 27cb271..71ed8ba 100644 --- a/ff-base/src/main/java/com/ff/base/utils/RandomGeneratorUtils.java +++ b/ff-base/src/main/java/com/ff/base/utils/RandomGeneratorUtils.java @@ -43,9 +43,28 @@ public class RandomGeneratorUtils { if (Character.isLetter(randomChar)) { sb.append(Character.toUpperCase(randomChar)); } else { - sb.append(randomChar); // 保持数字 + sb.append(randomChar); } } return sb.toString(); } + + + + + /** + * 生成 5-8 之间的随机长度,只包含小写字母和数字 + * + * @return {@link String } + */ + public static String generateRandomAccountLower() { + int length = 5 + RANDOM.nextInt(4); + StringBuilder sb = new StringBuilder(length); + for (int i = 0; i < length; i++) { + char randomChar = CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length())); + // 保持字母小写,数字不变 + sb.append(randomChar); + } + return sb.toString(); + } } \ No newline at end of file diff --git a/ff-game/src/main/java/com/ff/game/api/dg/service/impl/GamesDGServiceImpl.java b/ff-game/src/main/java/com/ff/game/api/dg/service/impl/GamesDGServiceImpl.java index 75d6448..8c90a26 100644 --- a/ff-game/src/main/java/com/ff/game/api/dg/service/impl/GamesDGServiceImpl.java +++ b/ff-game/src/main/java/com/ff/game/api/dg/service/impl/GamesDGServiceImpl.java @@ -249,7 +249,7 @@ public class GamesDGServiceImpl implements IGamesService { game.setSortNo(gameService.selectMaxSortNoByPlatformId(gamePlatform.getId()) + 1); game.setPlatformId(gamePlatform.getId()); game.setGameCode("1"); - game.setGameSourceType(1); + game.setGameSourceType(String.valueOf(1)); game.setGameName("真人棋牌"); game.setCreateBy(Constants.SYSTEM); gameService.insertGame(game); diff --git a/ff-game/src/main/java/com/ff/game/api/fc/impl/GamesFCServiceImpl.java b/ff-game/src/main/java/com/ff/game/api/fc/impl/GamesFCServiceImpl.java index 78b0675..41b96ba 100644 --- a/ff-game/src/main/java/com/ff/game/api/fc/impl/GamesFCServiceImpl.java +++ b/ff-game/src/main/java/com/ff/game/api/fc/impl/GamesFCServiceImpl.java @@ -302,7 +302,7 @@ public class GamesFCServiceImpl implements IGamesService { List games = gameService.selectGameList(game); //不存在这个游戏 if (CollectionUtils.isEmpty(games)) { - game.setGameSourceType(PlatformType.ELECTRONIC.getCode()); + game.setGameSourceType(String.valueOf(PlatformType.ELECTRONIC.getCode())); game.setFreespin(Boolean.FALSE); game.setDemoStatus(Boolean.TRUE); game.setSortNo(gameService.selectMaxSortNoByPlatformId(gamePlatform.getId()) + 1); @@ -423,7 +423,6 @@ public class GamesFCServiceImpl implements IGamesService { if (this.getIsSuccess(transferResponseDTO.getResult())) { //更新数据 exchangeMoney.setBalance(transferResponseDTO.getPoints().abs()); - exchangeMoney.setStatus(StatusType.IN_PROGRESS.getValue()); exchangeMoney.setCoinBefore(NumberUtil.sub(transferResponseDTO.getAfterPoint(), exchangeMoney.getBalance()).abs()); exchangeMoney.setCoinAfter(transferResponseDTO.getAfterPoint()); exchangeMoney.setCurrencyBefore(exchangeMoney.getCoinBefore()); diff --git a/ff-game/src/main/java/com/ff/game/api/jili/service/impl/GamesJILIServiceImpl.java b/ff-game/src/main/java/com/ff/game/api/jili/service/impl/GamesJILIServiceImpl.java index edf1863..0b6924e 100644 --- a/ff-game/src/main/java/com/ff/game/api/jili/service/impl/GamesJILIServiceImpl.java +++ b/ff-game/src/main/java/com/ff/game/api/jili/service/impl/GamesJILIServiceImpl.java @@ -256,7 +256,7 @@ public class GamesJILIServiceImpl implements IGamesService { List games = gameService.selectGameList(game); //不存在这个游戏 if (CollectionUtils.isEmpty(games)) { - game.setGameSourceType(gamesDataDTO.getGameCategoryId()); + game.setGameSourceType(String.valueOf(gamesDataDTO.getGameCategoryId())); game.setFreespin(gamesDataDTO.isFreespin()); game.setSortNo(gameService.selectMaxSortNoByPlatformId(gamePlatform.getId()) + 1); game.setGameName(gamesDataDTO.getName().getZhCN()); diff --git a/ff-game/src/main/java/com/ff/game/api/ng/service/impl/GamesPGServiceImpl.java b/ff-game/src/main/java/com/ff/game/api/ng/service/impl/GamesPGServiceImpl.java index a966684..8b71e88 100644 --- a/ff-game/src/main/java/com/ff/game/api/ng/service/impl/GamesPGServiceImpl.java +++ b/ff-game/src/main/java/com/ff/game/api/ng/service/impl/GamesPGServiceImpl.java @@ -282,7 +282,7 @@ public class GamesPGServiceImpl implements IGamesService { List games = gameService.selectGameList(game); //不存在这个游戏 if (CollectionUtils.isEmpty(games)) { - game.setGameSourceType(apiGameInfoResponseDTO.getGameType()); + game.setGameSourceType(String.valueOf(apiGameInfoResponseDTO.getGameType())); game.setFreespin(Boolean.FALSE); game.setDemoStatus(Boolean.TRUE); game.setSortNo(gameService.selectMaxSortNoByPlatformId(gamePlatform.getId()) + 1); diff --git a/ff-game/src/main/java/com/ff/game/api/pgx/address/MyPGXAddressSource.java b/ff-game/src/main/java/com/ff/game/api/pgx/address/MyPGXAddressSource.java new file mode 100644 index 0000000..5bd6c65 --- /dev/null +++ b/ff-game/src/main/java/com/ff/game/api/pgx/address/MyPGXAddressSource.java @@ -0,0 +1,31 @@ +package com.ff.game.api.pgx.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 MyPGXAddressSource implements AddressSource { + + @Resource + private ISysConfigService configService; + + + @Override + public ForestAddress getAddress(ForestRequest request) { + String apiBaseUrl = configService.selectConfigByKey(Constants.PGX_API_BASE_URL); + return new ForestAddress("http",apiBaseUrl, 80,""); + } +} \ No newline at end of file diff --git a/ff-game/src/main/java/com/ff/game/api/pgx/client/PGXClient.java b/ff-game/src/main/java/com/ff/game/api/pgx/client/PGXClient.java new file mode 100644 index 0000000..8cb1827 --- /dev/null +++ b/ff-game/src/main/java/com/ff/game/api/pgx/client/PGXClient.java @@ -0,0 +1,132 @@ +package com.ff.game.api.pgx.client; + +import com.dtflys.forest.annotation.*; +import com.ff.game.api.dg.dto.DGResponse; +import com.ff.game.api.jili.dto.*; +import com.ff.game.api.ng.dto.ApiExchangeTransferStatusResponseDTO; +import com.ff.game.api.ng.dto.ApiNGResponseDTO; +import com.ff.game.api.pgx.address.MyPGXAddressSource; +import com.ff.game.api.pgx.dto.*; +import com.ff.game.api.xk.dto.XKBetRecordResponseDTO; +import com.ff.game.api.xk.dto.XKKickMemberAllDTO; +import com.ff.game.api.xk.dto.XKKickMemberDTO; + +import java.util.Map; + +/** + * pg 请求 + * + * @author shi + * @date 2025/02/10 + */ +@Address(source = MyPGXAddressSource.class) +public interface PGXClient { + /** + * 创建成员 + * + * @param parameters 范围 + * @return {@link String } + */ + @Get("/createMember.aspx?${parameters}") + PGXErrorResponse createMember(@Var("parameters") String parameters); + + /** + * 获取会员信息 + * + * @param parameters 范围 + * @return {@link PGXMemberResponse } + */ + @Get("/getBalance.aspx?${parameters}") + PGXMemberResponse getMemberInfo(@Var("parameters") String parameters); + + + /** + * 获取会员游戏信息 目前仅支持供应商代号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); + + /** + * 获取游戏列表 + * + * @param parameters 范围 + * @return {@link PGXGameListResponse } + */ + @Get("/getGameList.aspx?${parameters}") + PGXGameListResponse getGameList(@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 params); + + + + + /** + * 汇兑转移状态 + * + * @param parameters 范围 + * @return {@link ApiNGResponseDTO }<{@link ApiExchangeTransferStatusResponseDTO }> + */ + @Post(url = "/checkTransaction.ashx?{parameters}") + PGXExchangeTransferStatusResponse exchangeTransferStatus(@Var("parameters") String parameters); + + + + + + /** + * 按时间获取投注记录 + * + * @return {@link PGXBetHistoryResponse } + */ + @Get(url = "/fetchArchieve.aspx?{parameters}") + PGXBetHistoryResponse getBetRecordByTime(@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 params); + + +} diff --git a/ff-game/src/main/java/com/ff/game/api/pgx/dto/PGXBetHistoryResponse.java b/ff-game/src/main/java/com/ff/game/api/pgx/dto/PGXBetHistoryResponse.java new file mode 100644 index 0000000..6e43ba3 --- /dev/null +++ b/ff-game/src/main/java/com/ff/game/api/pgx/dto/PGXBetHistoryResponse.java @@ -0,0 +1,148 @@ +package com.ff.game.api.pgx.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注单号 (唯一值) (Int类型) + */ + @JsonProperty("id") + private int id; + + /** + * 供应商注单号 (Int类型) + */ + @JsonProperty("ref_no") + private int refNo; + + /** + * 供应商代号 (String类型) + */ + @JsonProperty("site") + private String site; + + /** + * 游戏类型代号 (String类型) + */ + @JsonProperty("product") + private String product; + + /** + * 玩家帐号 (String类型) + */ + @JsonProperty("member") + private String member; + + /** + * 游戏代号 (String类型) + */ + @JsonProperty("gameid") + 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; + + } +} \ No newline at end of file diff --git a/ff-game/src/main/java/com/ff/game/api/pgx/dto/PGXErrorResponse.java b/ff-game/src/main/java/com/ff/game/api/pgx/dto/PGXErrorResponse.java new file mode 100644 index 0000000..1fc0aca --- /dev/null +++ b/ff-game/src/main/java/com/ff/game/api/pgx/dto/PGXErrorResponse.java @@ -0,0 +1,26 @@ +package com.ff.game.api.pgx.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; +} diff --git a/ff-game/src/main/java/com/ff/game/api/pgx/dto/PGXExchangeTransferStatusResponse.java b/ff-game/src/main/java/com/ff/game/api/pgx/dto/PGXExchangeTransferStatusResponse.java new file mode 100644 index 0000000..e91c2a7 --- /dev/null +++ b/ff-game/src/main/java/com/ff/game/api/pgx/dto/PGXExchangeTransferStatusResponse.java @@ -0,0 +1,67 @@ +package com.ff.game.api.pgx.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; +} diff --git a/ff-game/src/main/java/com/ff/game/api/pgx/dto/PGXGameListResponse.java b/ff-game/src/main/java/com/ff/game/api/pgx/dto/PGXGameListResponse.java new file mode 100644 index 0000000..f53e146 --- /dev/null +++ b/ff-game/src/main/java/com/ff/game/api/pgx/dto/PGXGameListResponse.java @@ -0,0 +1,65 @@ +package com.ff.game.api.pgx.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * pgx游戏列表响应 + * + * @author shi + * @date 2025/03/28 + */ +@Data +public class PGXGameListResponse { + + /** 错误码 (字符串类型) */ + @JsonProperty("errCode") + private Integer errCode; + + /** 游戏列表 (包含多个游戏的详细信息) */ + @JsonProperty("gamelist") + private String gamelist; + + /** 错误信息 (字符串类型) */ + @JsonProperty("errMsg") + private String errMsg; + + /** 数据生成时间 (字符串类型) */ + @JsonProperty("generatedAt") + private Date generatedAt; + + /** + * 游戏信息类 + */ + @Data + public static class Game { + + /** 游戏ID (字符串类型) */ + @JsonProperty("gameId") + private String gameId; + + /** 游戏名称 (字符串类型) */ + @JsonProperty("gameName") + private String gameName; + + /** + * 系统游戏id + */ + private Long systemGameId; + + /** 游戏代码 (字符串类型) */ + @JsonProperty("gameCode") + private String gameCode; + + /** 游戏状态 (整数类型) */ + @JsonProperty("status") + private int status; + + /** 发布状态 (整数类型) */ + @JsonProperty("releaseStatus") + private int releaseStatus; + } +} diff --git a/ff-game/src/main/java/com/ff/game/api/pgx/dto/PGXGameLoginResponse.java b/ff-game/src/main/java/com/ff/game/api/pgx/dto/PGXGameLoginResponse.java new file mode 100644 index 0000000..db85e06 --- /dev/null +++ b/ff-game/src/main/java/com/ff/game/api/pgx/dto/PGXGameLoginResponse.java @@ -0,0 +1,30 @@ +package com.ff.game.api.pgx.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; + +} \ No newline at end of file diff --git a/ff-game/src/main/java/com/ff/game/api/pgx/dto/PGXMemberResponse.java b/ff-game/src/main/java/com/ff/game/api/pgx/dto/PGXMemberResponse.java new file mode 100644 index 0000000..0fea6fa --- /dev/null +++ b/ff-game/src/main/java/com/ff/game/api/pgx/dto/PGXMemberResponse.java @@ -0,0 +1,26 @@ +package com.ff.game.api.pgx.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; +} \ No newline at end of file diff --git a/ff-game/src/main/java/com/ff/game/api/pgx/dto/PGXPlayerStatusResponse.java b/ff-game/src/main/java/com/ff/game/api/pgx/dto/PGXPlayerStatusResponse.java new file mode 100644 index 0000000..a5698af --- /dev/null +++ b/ff-game/src/main/java/com/ff/game/api/pgx/dto/PGXPlayerStatusResponse.java @@ -0,0 +1,26 @@ +package com.ff.game.api.pgx.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; +} \ No newline at end of file diff --git a/ff-game/src/main/java/com/ff/game/api/pgx/impl/GamesPGXServiceImpl.java b/ff-game/src/main/java/com/ff/game/api/pgx/impl/GamesPGXServiceImpl.java new file mode 100644 index 0000000..37f1673 --- /dev/null +++ b/ff-game/src/main/java/com/ff/game/api/pgx/impl/GamesPGXServiceImpl.java @@ -0,0 +1,652 @@ +package com.ff.game.api.pgx.impl; + +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.NumberUtil; +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.DateUtils; +import com.ff.base.utils.JsonUtil; +import com.ff.base.utils.sign.Md5Utils; +import com.ff.config.KeyConfig; +import com.ff.game.api.IGamesService; +import com.ff.game.api.dg.dto.DGBetRecordResponseDTO; +import com.ff.game.api.ng.dto.ApiExchangeTransferStatusResponseDTO; +import com.ff.game.api.pgx.client.PGXClient; +import com.ff.game.api.pgx.dto.*; +import com.ff.game.api.request.*; +import com.ff.game.api.xk.dto.XKBetRecordResponseDTO; +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.*; +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; + + +/** + * 游戏pgxservice impl + * + * @author shi + * @date 2025/03/27 + */ +@Service("PGXService") +@Slf4j +public class GamesPGXServiceImpl 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 PGXClient PGXClient; + + + @Resource + private KeyConfig keyConfig; + + @Resource + private IGameBettingDetailsService gameBettingDetailsService; + + @Resource + private IGameNameService gameNameService; + + + /** + * 获得就是成功 + * + * @param errorCode 错误代码 + * @return {@link Boolean } + */ + private Boolean getIsSuccess(Integer errorCode) { + ApiException.isTrue(101 != errorCode, ErrorCode.GAME_ACCOUNT_CREATION_FAILED.getCode()); + + return 0 == errorCode; + } + + + /** + * 获取密钥 + * + * @return {@link String } + */ + private String getKey(Map paramsMap, GamesBaseRequestDTO gamesBaseRequestDTO) { + String result = paramsMap.values().stream() + .map(Object::toString) + .collect(Collectors.joining()); + + return Md5Utils.md5New(result + gamesBaseRequestDTO.getAgentKey()).toUpperCase(); + } + + + /** + * 创建成员 + * + * @param createMemberRequestDTO 创建成员请求dto + * @return {@link Boolean } + */ + @Override + public Boolean createMember(CreateMemberRequestDTO createMemberRequestDTO) { + log.info("GamesXKServiceImpl [createMember] 请求参数 {}", createMemberRequestDTO); + + Map params = new LinkedHashMap<>(); + params.put("operatorcode", createMemberRequestDTO.getAgentId()); + params.put("username", createMemberRequestDTO.getAccount()); + String key = this.getKey(params, createMemberRequestDTO); + params.put("signature", key); + + PGXErrorResponse pgxClientMember = PGXClient.createMember(JsonUtil.mapToQueryString(params)); + Integer errCode = pgxClientMember.getErrCode(); + if (this.getIsSuccess(errCode)) { + return Boolean.TRUE; + } + //判断是否获取成功 + return Boolean.FALSE; + } + + + /** + * 获取会员信息 + * + * @param memberInfoRequestDTO 会员信息请求dto + * @return {@link MemberInfoResponseDTO } + */ + @Override + public MemberInfoResponseDTO getMemberInfo(MemberInfoRequestDTO memberInfoRequestDTO) { + log.info("GamesPGXServiceImpl [getMemberInfo] 请求参数 {}", memberInfoRequestDTO); + GameSecretKey gameSecretKey = gameSecretKeyService.selectGameSecretKeyByCode(memberInfoRequestDTO.getAgentId()); + Map params = new LinkedHashMap<>(); + params.put("operatorcode", memberInfoRequestDTO.getAgentId()); + params.put("password", gameSecretKey.getPassword()); + params.put("providercode", gameSecretKey.getProviderCode()); + params.put("username", memberInfoRequestDTO.getAccounts()); + String key = this.getKey(params, memberInfoRequestDTO); + params.put("signature", key); + PGXMemberResponse memberInfo = PGXClient.getMemberInfo(JsonUtil.mapToQueryString(params)); + //判断是否获取成功 + if (this.getIsSuccess(memberInfo.getErrCode())) { + MemberInfoResponseDTO memberInfoResponseDTO = MemberInfoResponseDTO.builder() + .status(GameMemberStatus.UNKNOWN.getCode()) + .balance(memberInfo.getBalance()) + .account(memberInfoRequestDTO.getAccounts()) + .build(); + return memberInfoResponseDTO; + } else { + throw new BaseException(memberInfo.getErrMsg()); + } + } + + /** + * 无重定向登录 + * + * @param gamesLogin 游戏登录 + * @return {@link String } + */ + @Override + public String loginWithoutRedirect(GamesLogin gamesLogin) { + log.info("GamesPGXServiceImpl [loginWithoutRedirect] 请求参数 {}", gamesLogin); + GameSecretKey gameSecretKey = gameSecretKeyService.selectGameSecretKeyByCode(gamesLogin.getAgentId()); + Map 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()); + String key = this.getKey(params, gamesLogin); + params.put("gameid", gamesLogin.getGameId()); + params.put("lang", gamesLogin.getLang()); + params.put("html5", 1); + params.put("signature", key); + PGXGameLoginResponse PGXGameLoginResponse = PGXClient.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) { + + List gamesDatas = redisCache.getCacheList(CacheConstants.PGX_GAMES); + if (!CollectionUtils.isEmpty(gamesDatas)) { + return CacheConstants.PGX_GAMES; + } + + GameSecretKey gameSecretKey = gameSecretKeyService.selectGameSecretKeyByCode(gamesBaseRequestDTO.getAgentId()); + Map params = new LinkedHashMap<>(); + params.put("operatorcode", gamesBaseRequestDTO.getAgentId()); + params.put("providercode", gameSecretKey.getProviderCode()); + String key = this.getKey(params, gamesBaseRequestDTO); + //没有中文 + params.put("html5", 1); + params.put("signature", key); + + PGXGameListResponse gameList = PGXClient.getGameList(JsonUtil.mapToQueryString(params)); + + //判断是否获取成功 + if (this.getIsSuccess(gameList.getErrCode())) { + + List gameLists = JSON.parseArray(gameList.getGamelist(), PGXGameListResponse.Game.class); + for (PGXGameListResponse.Game gamesDataDTO : gameLists) { + GamePlatform gamePlatform = GamePlatform.builder() + .platformType(GPXGameType.SL.getSystemCode()) + .platformCode(GamePlatforms.PGX.getCode()) + .build(); + List gamePlatforms = gamePlatformService.selectGamePlatformList(gamePlatform); + //没有此平台就新增一个平台 + if (CollectionUtils.isEmpty(gamePlatforms)) { + gamePlatform.setPlatformName(GamePlatforms.PGX.getInfo() + XKGameType.findInfoByCode(GPXGameType.SL.getSystemCode())); + 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(gamesDataDTO.getGameId()) + .build(); + List games = gameService.selectGameList(game); + //不存在这个游戏 + if (CollectionUtils.isEmpty(games)) { + game.setGameSourceType(GPXGameType.SL.getCode()); + game.setFreespin(Boolean.FALSE); + game.setSortNo(gameService.selectMaxSortNoByPlatformId(gamePlatform.getId()) + 1); + game.setGameName(gamesDataDTO.getGameName()); + 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("en-US") + .createBy(Constants.SYSTEM) + .build()); + } + + + } + + redisCache.deleteObject(CacheConstants.PGX_GAMES); + redisCache.setCacheList(CacheConstants.PGX_GAMES, gameLists); + redisCache.expire(CacheConstants.PGX_GAMES, 5L, TimeUnit.HOURS); + } else { + throw new BaseException(gameList.getErrMsg()); + + } + 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.getCode()) + .code(exchangeTransferMoneyRequestDTO.getAgentId()) + .currency(exchangeTransferMoneyRequestDTO.getCurrency()) + .build()); + + Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount()); + String transactionId = gameExchangeMoneyService.getTransactionId(GamePlatforms.PGX.getCode(), 17); + List 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.getCode()) + .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 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()); + String key = this.getKey(paramsMap, exchangeTransferMoneyRequestDTO); + paramsMap.put("signature", key); + + PGXErrorResponse errorResponse = PGXClient.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 paramsMap = new LinkedHashMap<>(); + paramsMap.put("operatorcode", exchangeTransferMoneyRequestDTO.getAgentId()); + paramsMap.put("referenceid", exchangeTransferMoneyRequestDTO.getOrderId()); + String key = this.getKey(paramsMap, exchangeTransferMoneyRequestDTO); + paramsMap.put("signature", key); + + PGXExchangeTransferStatusResponse exchangeTransferStatusResponse = PGXClient.exchangeTransferStatus(JsonUtil.mapToQueryString(paramsMap)); + if (this.getIsSuccess(exchangeTransferStatusResponse.getErrCode())) { + List gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList( + GameExchangeMoney.builder() + .platformCode(GamePlatforms.PGX.getCode()) + .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 paramsMap = new LinkedHashMap<>(); + paramsMap.put("operatorcode", betRecordByTimeDTO.getAgentId()); + String key = this.getKey(paramsMap, betRecordByTimeDTO); + paramsMap.put("versionkey", 0); + paramsMap.put("signature", key); + PGXBetHistoryResponse betRecordByTime = PGXClient.getBetRecordByTime(JsonUtil.mapToQueryString(paramsMap)); + + if (this.getIsSuccess(betRecordByTime.getErrCode())) { + List 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) { + return null; + } + + /** + * 赠送免费局数 + * + * @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 获取自由旋转dashflow请求dto + * @return {@link List }<{@link GameFreeRecord }> + */ + @Override + public List 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 dataBean 数据bean + */ + private void batchInsert(List dataBean, GamesBaseRequestDTO gamesBaseRequestDTO) { + List gameBettingDetails = new ArrayList<>(); + List 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 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); + + //标记报告 + Map paramsMap = new LinkedHashMap<>(); + paramsMap.put("operatorcode", gamesBaseRequestDTO.getAgentId()); + String key = this.getKey(paramsMap, gamesBaseRequestDTO); + paramsMap.put("ticket", String.join(",", wagersIds)); + paramsMap.put("signature", key); + PGXClient.markReport(paramsMap); + } + } + + } + + /** + * 数据构建 + * + * @param gamesDataBuildDTO 数据 + * @return {@link GameBettingDetails } + */ + @Override + public GameBettingDetails dataBuild(GamesDataBuildDTO gamesDataBuildDTO) { + //转化类 + PGXBetHistoryResponse.Result resultBean = (PGXBetHistoryResponse.Result) gamesDataBuildDTO.getData(); + + GameSecretKeyCurrency currencyDTO = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder() + .platformCode(GamePlatforms.PGX.getInfo()) + .code(gamesDataBuildDTO.getAgentId()) + .build()); + + Member member = memberService.selectMemberByGameAccount(resultBean.getMember()); + if (ObjectUtils.isEmpty(member)) { + return null; + } + List gamesDatas = redisCache.getCacheList(CacheConstants.PGX_GAMES); + Map dataDTOMap = gamesDatas.stream().collect(Collectors.toMap(PGXGameListResponse.Game::getGameId, e -> e)); + PGXGameListResponse.Game gamesDataDTO = dataDTOMap.get(resultBean.getGameId()); + + + BigDecimal payoffAmount = BigDecimal.ZERO; + BigDecimal payout = resultBean.getPayout(); + //输赢状态 + Integer gameStatus = GameStatus.FLAT.getCode(); + if (payout.compareTo(resultBean.getBet()) > 0) { + payoffAmount = NumberUtil.sub(payout, resultBean.getBet()); + gameStatus = GameStatus.WIN.getCode(); + } else if (payout.compareTo(resultBean.getBet()) < 0) { + payoffAmount = NumberUtil.sub(payout, resultBean.getBet()).negate(); + gameStatus = GameStatus.FAIL.getCode(); + } + //数据构造 + GameBettingDetails gameBettingDetails = GameBettingDetails.builder() + .tenantKey(member.getTenantKey()) + //保存我们的币种id + .currencyCode(currencyDTO.getSystemCurrency()) + .memberId(member.getId()) + .gameCode(resultBean.getGameId()) + .gameType(GPXGameType.SL.getSystemCode()) + .platformCode(GamePlatforms.PGX.getCode()) + .gameId(gamesDataDTO.getSystemGameId()) + .gameName(gamesDataDTO.getGameName()) + .gameStatus(gameStatus) + .gameStatusType(1) + .betContent(resultBean.getBetDetail()) + .gameCurrencyCode(currencyDTO.getCurrency()) + .account(resultBean.getMember()) + .wagersId(String.valueOf(resultBean.getId())) + .wagersTime(resultBean.getStartTime().getTime()) + .betAmount(resultBean.getBet()) + .payoffTime(resultBean.getEndTime().getTime()) + .payoffAmount(payoffAmount) + .settlementTime(resultBean.getEndTime().getTime()) + .turnover(resultBean.getTurnover()) + .settlementStatus(PGXBetRecordStatus.findSystemCodeByCode(resultBean.getStatus())) + .build(); + gameBettingDetails.setCreateBy(Constants.SYSTEM); + gameBettingDetails.setCreateTime(DateUtils.getNowDate()); + return gameBettingDetails; + } +} diff --git a/ff-game/src/main/java/com/ff/game/api/request/GamesDataBuildDTO.java b/ff-game/src/main/java/com/ff/game/api/request/GamesDataBuildDTO.java index 7b87918..73548ee 100644 --- a/ff-game/src/main/java/com/ff/game/api/request/GamesDataBuildDTO.java +++ b/ff-game/src/main/java/com/ff/game/api/request/GamesDataBuildDTO.java @@ -34,5 +34,10 @@ public class GamesDataBuildDTO */ private String currencyCode; + /** + * 代理id + */ + private String agentId; + } diff --git a/ff-game/src/main/java/com/ff/game/api/request/GamesLogin.java b/ff-game/src/main/java/com/ff/game/api/request/GamesLogin.java index da7249c..d46d7fd 100644 --- a/ff-game/src/main/java/com/ff/game/api/request/GamesLogin.java +++ b/ff-game/src/main/java/com/ff/game/api/request/GamesLogin.java @@ -45,5 +45,5 @@ public class GamesLogin extends GamesBaseRequestDTO{ /** * 游戏类型 */ - private Integer gameType; + private String gameType; } 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 index b90a135..ac9c0d2 100644 --- 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 @@ -261,7 +261,7 @@ public class GamesSAServiceImpl implements IGamesService { game.setSortNo(gameService.selectMaxSortNoByPlatformId(gamePlatform.getId()) + 1); game.setPlatformId(gamePlatform.getId()); game.setGameCode("1"); - game.setGameSourceType(1); + game.setGameSourceType(String.valueOf(1)); game.setGameName("真人棋牌"); game.setCreateBy(Constants.SYSTEM); gameService.insertGame(game); diff --git a/ff-game/src/main/java/com/ff/game/api/xk/service/impl/GamesXKServiceImpl.java b/ff-game/src/main/java/com/ff/game/api/xk/service/impl/GamesXKServiceImpl.java index 3f8957e..82675d3 100644 --- a/ff-game/src/main/java/com/ff/game/api/xk/service/impl/GamesXKServiceImpl.java +++ b/ff-game/src/main/java/com/ff/game/api/xk/service/impl/GamesXKServiceImpl.java @@ -270,7 +270,7 @@ public class GamesXKServiceImpl implements IGamesService { List games = gameService.selectGameList(game); //不存在这个游戏 if (CollectionUtils.isEmpty(games)) { - game.setGameSourceType(gamesDataDTO.getGameCategoryId()); + game.setGameSourceType(String.valueOf(gamesDataDTO.getGameCategoryId())); game.setFreespin(gamesDataDTO.isFreeSpin()); game.setSortNo(gameService.selectMaxSortNoByPlatformId(gamePlatform.getId()) + 1); game.setGameName(gamesDataDTO.getName()); diff --git a/ff-game/src/main/java/com/ff/game/domain/Game.java b/ff-game/src/main/java/com/ff/game/domain/Game.java index c0b1e37..27b4b5f 100644 --- a/ff-game/src/main/java/com/ff/game/domain/Game.java +++ b/ff-game/src/main/java/com/ff/game/domain/Game.java @@ -48,7 +48,7 @@ public class Game extends BaseEntity /** 第三方来源分类 */ @Excel(name = "第三方来源分类") - private Integer gameSourceType; + private String gameSourceType; /** 游戏名称 */ @Excel(name = "游戏名称") diff --git a/ff-game/src/main/java/com/ff/game/domain/GameSecretKey.java b/ff-game/src/main/java/com/ff/game/domain/GameSecretKey.java index f34a0ff..d263f9b 100644 --- a/ff-game/src/main/java/com/ff/game/domain/GameSecretKey.java +++ b/ff-game/src/main/java/com/ff/game/domain/GameSecretKey.java @@ -28,6 +28,16 @@ public class GameSecretKey extends BaseEntity @Excel(name = "平台") private String platform; + /** + * 供应商号 + */ + private String providerCode; + + /** + * 供应商号密码 + */ + private String password; + /** 代码 */ @Excel(name = "代码") private String code; diff --git a/ff-game/src/main/java/com/ff/game/mapper/GameSecretKeyMapper.java b/ff-game/src/main/java/com/ff/game/mapper/GameSecretKeyMapper.java index 31daa64..eb4f84a 100644 --- a/ff-game/src/main/java/com/ff/game/mapper/GameSecretKeyMapper.java +++ b/ff-game/src/main/java/com/ff/game/mapper/GameSecretKeyMapper.java @@ -27,6 +27,17 @@ public interface GameSecretKeyMapper */ List selectGameSecretKeyList(GameSecretKey gameSecretKey); + + + /** + * 按代码选择游戏密钥 + * + * @param code 代码 + * @return {@link GameSecretKey } + */ + GameSecretKey selectGameSecretKeyByCode(String code); + + /** * 新增游戏平台密钥管理 * diff --git a/ff-game/src/main/java/com/ff/game/service/IGameSecretKeyService.java b/ff-game/src/main/java/com/ff/game/service/IGameSecretKeyService.java index 1203346..713b050 100644 --- a/ff-game/src/main/java/com/ff/game/service/IGameSecretKeyService.java +++ b/ff-game/src/main/java/com/ff/game/service/IGameSecretKeyService.java @@ -1,6 +1,8 @@ package com.ff.game.service; import java.util.List; + +import com.ff.game.domain.Game; import com.ff.game.domain.GameSecretKey; /** @@ -19,6 +21,15 @@ public interface IGameSecretKeyService */ GameSecretKey selectGameSecretKeyById(Long id); + + /** + * 按代码选择游戏密钥 + * + * @param code 代码 + * @return {@link GameSecretKey } + */ + GameSecretKey selectGameSecretKeyByCode(String code); + /** * 查询游戏平台密钥管理列表 * diff --git a/ff-game/src/main/java/com/ff/game/service/impl/GameSecretKeyServiceImpl.java b/ff-game/src/main/java/com/ff/game/service/impl/GameSecretKeyServiceImpl.java index 85350d3..2c34ac1 100644 --- a/ff-game/src/main/java/com/ff/game/service/impl/GameSecretKeyServiceImpl.java +++ b/ff-game/src/main/java/com/ff/game/service/impl/GameSecretKeyServiceImpl.java @@ -34,6 +34,17 @@ public class GameSecretKeyServiceImpl implements IGameSecretKeyService return gameSecretKeyMapper.selectGameSecretKeyById(id); } + /** + * 按代码选择游戏密钥 + * + * @param code 代码 + * @return {@link GameSecretKey } + */ + @Override + public GameSecretKey selectGameSecretKeyByCode(String code) { + return gameSecretKeyMapper.selectGameSecretKeyByCode(code); + } + /** * 查询游戏平台密钥管理列表 * diff --git a/ff-game/src/main/java/com/ff/member/service/impl/MemberServiceImpl.java b/ff-game/src/main/java/com/ff/member/service/impl/MemberServiceImpl.java index 91310dc..428270b 100644 --- a/ff-game/src/main/java/com/ff/member/service/impl/MemberServiceImpl.java +++ b/ff-game/src/main/java/com/ff/member/service/impl/MemberServiceImpl.java @@ -59,7 +59,11 @@ public class MemberServiceImpl implements IMemberService { do { gameAccount = RandomGeneratorUtils.generateRandomAccountUpper(); } while (!ObjectUtils.isEmpty(memberMapper.selectMemberByGameAccount(gameAccount))); - } else { + }else if (GamePlatforms.PG.getInfo().equals(platformCode)||GamePlatforms.PGX.getInfo().equals(platformCode)){ + do { + gameAccount = RandomGeneratorUtils.generateRandomAccountLower(); + } while (!ObjectUtils.isEmpty(memberMapper.selectMemberByGameAccount(gameAccount))); + }else { do { gameAccount = RandomGeneratorUtils.generateRandomAccount(); } while (!ObjectUtils.isEmpty(memberMapper.selectMemberByGameAccount(gameAccount))); diff --git a/ff-game/src/main/resources/mapper/game/GameSecretKeyMapper.xml b/ff-game/src/main/resources/mapper/game/GameSecretKeyMapper.xml index 7576be3..61d8240 100644 --- a/ff-game/src/main/resources/mapper/game/GameSecretKeyMapper.xml +++ b/ff-game/src/main/resources/mapper/game/GameSecretKeyMapper.xml @@ -7,6 +7,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + @@ -16,13 +18,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select id, platform, code, `key`, create_by, create_time, update_by, update_time from ff_game_secret_key + select id, platform,provider_code,password, code, `key`, create_by, create_time, update_by, update_time from ff_game_secret_key + + insert into ff_game_secret_key id, platform, + provider_code, + password, code, key, create_by, @@ -48,6 +60,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{id}, #{platform}, + #{providerCode}, + #{password}, #{code}, #{key}, #{createBy}, @@ -61,6 +75,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" update ff_game_secret_key platform = #{platform}, + provider_code = #{providerCode}, + password = #{password}, code = #{code}, key = #{key}, create_by = #{createBy},