feat(game): 添加美天棋牌平台支持

- 新增美天棋牌相关的常量、API接口和数据模型
- 实现美天棋牌的会员创建、余额查询、登录、转账等功能
- 添加美天棋牌的游戏数据和记录查询接口
main-KM
liaoyong 2025-04-01 11:38:30 +08:00
parent 5f9af0e041
commit e632c378a2
17 changed files with 1659 additions and 10 deletions

View File

@ -5,8 +5,7 @@ package com.ff.base.constant;
*
* @author ff
*/
public class CacheConstants
{
public class CacheConstants {
/**
* redis key
*/
@ -45,43 +44,48 @@ public class CacheConstants
/**
* jili
*/
public static final String JILI_GAMES= "jili_games:";
public static final String JILI_GAMES = "jili_games:";
/**
* xk
*/
public static final String XK_GAMES= "xk_games:";
public static final String XK_GAMES = "xk_games:";
/**
* pgx
*/
public static final String PGX_GAMES= "pgx_games:";
public static final String PGX_GAMES = "pgx_games:";
/**
* pg
*/
public static final String PG_GAMES= "pg_games:";
public static final String PG_GAMES = "pg_games:";
/**
* fc
*/
public static final String FC_GAMES= "fc_games:";
public static final String FC_GAMES = "fc_games:";
/**
* sa
*/
public static final String SA_GAMES= "sa_games:";
public static final String SA_GAMES = "sa_games:";
/**
* dg
*/
public static final String DG_GAMES= "dg_games:";
public static final String DG_GAMES = "dg_games:";
/**
* pg
*/
public static final String PG_GAMES_BET_CURRENCY= "pg_games:bet:currency";
public static final String PG_GAMES_BET_CURRENCY = "pg_games:bet:currency";
/**
*
*/
public static final String MeiTian_GAMES = "meitian_games:";
}

View File

@ -219,6 +219,11 @@ public class Constants {
*/
public static final String SA_API_BASE_URL = "sa.api.base.url";
/**
*
*/
public static final String MEITIAN_API_BASE_URL = "meitian.api.base.url";
/**
*
*/

View File

@ -11,6 +11,8 @@ public enum GamePlatforms {
FC("FC", "FC"),
SA("SA", "SA"),
DG("DG", "DG"),
MeiTIan("MeiTIan","美天棋牌")
,
;
private final String code;

View File

@ -0,0 +1,53 @@
package com.ff.base.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Optional;
import java.util.stream.Stream;
/**
* @author cengy
*/
@Getter
@AllArgsConstructor
public enum MeiTianGameType {
ELECTRON(4, 1, "电子"),
CHESS(2, 2, "棋牌"),
GAME_HALL(0, 3, "游戏大厅"),
CATCH_FISH(3, 4, "捕鱼")
//bai_ren(1, 5,"白人")
,
;
private final Integer code;
private final Integer systemCode;
private final String info;
/**
*
*
* @param code
* @return {@link String }
*/
public static Integer findSystemByCode(Integer code) {
Optional<Integer> system = Stream.of(MeiTianGameType.values())
.filter(gameType -> gameType.getCode().equals(code))
.map(MeiTianGameType::getSystemCode)
.findFirst();
return system.orElse(null);
}
/**
*
*
* @param code
* @return {@link String }
*/
public static String findInfoByCode(Integer code) {
Optional<String> system = Stream.of(MeiTianGameType.values())
.filter(gameType -> gameType.getCode().equals(code))
.map(MeiTianGameType::getInfo)
.findFirst();
return system.orElse(null);
}
}

View File

@ -0,0 +1,29 @@
package com.ff.game.api.meitian.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;
/**
* @author shi
* @date 2025/02/10
*/
@Component
public class MeiTianAddressSource implements AddressSource {
@Resource
private ISysConfigService configService;
@Override
public ForestAddress getAddress(ForestRequest request) {
String apiBaseUrl = configService.selectConfigByKey(Constants.MEITIAN_API_BASE_URL);
return new ForestAddress("https", apiBaseUrl, 443, "services");
}
}

View File

@ -0,0 +1,147 @@
package com.ff.game.api.meitian.client;
import com.dtflys.forest.annotation.Address;
import com.dtflys.forest.annotation.Body;
import com.dtflys.forest.annotation.Post;
import com.dtflys.forest.annotation.Var;
import com.ff.game.api.meitian.address.MeiTianAddressSource;
import com.ff.game.api.meitian.dto.*;
/**
* jili
*
* @author shi
* @date 2025/02/10
*/
@Address(source = MeiTianAddressSource.class)
public interface MeiTianClient {
/**
*
*
* @param playerName
* @param merchantId
* @param pwd
* @return {@link MeiTianCreateMemberResponseDTO}
*/
@Post("/dg/player/playerCreate2/{playerName}/{merchantId}/{pwd}/{code}/{data}")
MeiTianCreateMemberResponseDTO createMember(
@Var("playerName") String playerName,
@Var("merchantId") String merchantId,
@Var("pwd") String pwd,
@Var("code") String code,
@Var("data") String data);
/**
*
*
* @param playerName
* @param merchantId
* @return {@link MeiTianMemberInfoDTO}
*/
@Post("/dg/player/getPlayerBalance/{playerName}/{merchantId}")
MeiTianMemberInfoDTO getMemberInfo(
@Var("playerName") String playerName,
@Var("merchantId") String merchantId);
/**
*
*
* @param merchantId id
* @param playerName
* @return {@link MeiTianLoginResultDTO }
*/
@Post("/dg/player/playerPlatformUrl/{merchantId}/{playerName}/{pwd}/{code}/{data}")
MeiTianLoginResultDTO loginWithoutRedirect(
@Var("merchantId") String merchantId,
@Var("playerName") String playerName,
@Var("pwd") String pwd,
@Var("code") String code,
@Var("data") String data
);
/**
*
*
* @param merchantId
* @param playerName
* @param coins
* @param extTransId
* @param code
* @param data
* @return {@link MeiTianExchangeMoneyResponseDTO}
*/
@Post("/dg/player/deposit2/{merchantId}/{playerName}/{coins}/{extTransId}/{code}/{data}")
MeiTianExchangeMoneyResponseDTO transferIn(
@Var("merchantId") String merchantId,
@Var("playerName") String playerName,
@Var("coins") String coins,
@Var("extTransId") String extTransId,
@Var("code") String code,
@Var("data") String data
);
/**
*
*
* @param merchantId
* @param playerName
* @param coins
* @param extTransId
* @param code
* @param data
* @return {@link MeiTianExchangeMoneyResponseDTO}
*/
@Post("/dg/player/withdraw2/{merchantId}/{playerName}/{coins}/{extTransId}/{code}/{data}")
MeiTianExchangeMoneyResponseDTO transferOut(
@Var("merchantId") String merchantId,
@Var("playerName") String playerName,
@Var("coins") String coins,
@Var("extTransId") String extTransId,
@Var("code") String code,
@Var("data") String data
);
/**
*
*
* @param parameters
* @param agentId id
* @return {@link JILIBetRecordResponseDTO }
*/
@Post(url = "/GetBetRecordByTime?${parameters}")
JILIBetRecordResponseDTO getBetRecordByTime(
@Var("parameters") String parameters,
@Body("AgentId") String agentId);
/**
*
*
* @param merchantId
* @param playerName
* @return {@link MeiTianLogoutDTO }
*/
@Post("/dg/player/logOutGame/{merchantId}/{playerName}")
MeiTianLogoutDTO kickMember(
@Var("merchantId") String merchantId,
@Var("playerName") String playerName
);
/**
*
*
* @param merchantId
* @param code
* @param data
* @return {@link MeiTianGameRecordDetailDTO}
*/
@Post("dg/player/playCheckUrl/{merchantId}/{code}/{data}")
MeiTianGameRecordDetailDTO getGameDetail(
@Var("merchantId") String merchantId,
@Var("code") String code,
@Var("data") String data
);
}

View File

@ -0,0 +1,89 @@
package com.ff.game.api.meitian.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
/**
* JiLi
*
* @author shi
* @date 2024/10/21
*/
@NoArgsConstructor
@Data
public class JILIBetRecordDataResponseDTO {
/**
*
*/
@JsonProperty("Account")
private String account;
/**
* id
*/
@JsonProperty("WagersId")
private String wagersId;
/**
* id
*/
@JsonProperty("GameId")
private String gameId;
/**
*
*/
@JsonProperty("WagersTime")
private Long wagersTime;
/**
*
*/
@JsonProperty("BetAmount")
private BigDecimal betAmount;
/**
*
*/
@JsonProperty("PayoffTime")
private Long payoffTime;
/**
*
*/
@JsonProperty("PayoffAmount")
private BigDecimal payoffAmount;
/**
* 1: 2: 3:
*/
@JsonProperty("Status")
private int status;
/**
*
*/
@JsonProperty("SettlementTime")
private Long settlementTime;
/**
* id
*/
@JsonProperty("GameCategoryId")
private int gameCategoryId;
/**
*
*/
@JsonProperty("Type")
private int type;
/**
* id
*/
@JsonProperty("AgentId")
private String agentId;
/**
*
*/
@JsonProperty("Turnover")
private BigDecimal turnover;
/**
*
*/
@JsonProperty("RoundIndex")
private long roundIndex;
}

View File

@ -0,0 +1,62 @@
package com.ff.game.api.meitian.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* JiLi
*
* @author shi
* @date 2024/10/21
*/
@NoArgsConstructor
@Data
public class JILIBetRecordResponseDTO {
@JsonProperty("ErrorCode")
private int errorCode;
@JsonProperty("Message")
private String message;
@JsonProperty("Data")
private DataBean data;
@NoArgsConstructor
@Data
public static class DataBean {
@JsonProperty("Result")
private List<JILIBetRecordDataResponseDTO> result;
@JsonProperty("Pagination")
private PaginationBean pagination;
@NoArgsConstructor
@Data
public static class PaginationBean {
/**
*
*/
@JsonProperty("CurrentPage")
private int currentPage;
/**
*
*/
@JsonProperty("TotalPages")
private int totalPages;
/**
*
*/
@JsonProperty("PageLimit")
private int pageLimit;
/**
*
*/
@JsonProperty("TotalNumber")
private int totalNumber;
}
}
}

View File

@ -0,0 +1,46 @@
package com.ff.game.api.meitian.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
/**
* dto
*
* @author shi
* @date 2024/10/22
*/
@Data
public class MeiTianCreateMemberResponseDTO {
/**
*
*/
@JsonProperty("resultCode")
private int resultCode;
@Getter
@AllArgsConstructor
public enum CreateMemberResultCode {
/**
*
*/
CreateException(0, "创建异常"),
CreateSuccess(1, "创建成功"),
MerchantNotExist(2, "商户不存在"),
MerchantInvalid(3, "商户无效"),
AlreadyRegistered(5, "商户用户已注册"),
IpLimit(15, "IP被限制"),
DecryptError(21, "解密错误"),
OptionalParameterError(32, "可选参数错误"),
Maintenance(40, "维护模式"),
;
private int code;
private String message;
}
}

View File

@ -0,0 +1,118 @@
package com.ff.game.api.meitian.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import java.math.BigDecimal;
/**
* jiliexchange
*
* @author shi
* @date 2024/10/22
*/
@Data
public class MeiTianExchangeMoneyResponseDTO {
/**
*
*/
@JsonProperty("resultCode")
private int errorCode;
/**
* , 50
*/
@JsonProperty("transId")
private String transactionId;
/**
*
*/
@JsonProperty("currency")
private String currency;
/**
*
*/
@JsonProperty("curBalance")
private BigDecimal balance;
/**
* () GMT+8
*/
@JsonProperty("timezone")
private String timezone;
/**
* 2018-08-08 12:23:44
*/
@JsonProperty("date")
private String date;
@Getter
@AllArgsConstructor
public enum TransferIn {
// 提现异常
WITHDRAW_ERROR(0, "充值异常"),
// 提现成功
WITHDRAW_SUCCESS(1, "充值成功"),
MERCHANT_NOT_EXIST(2, "商户不存在"),
MERCHANT_INVALID(3, "商户无效"),
MERCHANT_USER_NOT_EXIST(4, "商户用户不存在"),
MERCHANT_USER_SYSTEM_DISABLED(6, "商户用户系统禁用"),
MERCHANT_USER_GOLD_BALANCE_INSUFFICIENT(9, "商户用户金币余额不足"),
GAME_NOT_SETTLED(12, "游戏未结算"),
IP_LIMIT(15, "IP被限制"),
DECRYPT_ERROR(21, "解密错误"),
OPTIONAL_PARAMETER_ERROR(32, "可选参数错误"),
EXIST_UNPROCESSED_ORDER(36, "存在未处理订单"),
MAINTENANCE(40, "维护模式"),
Unknown(-1, "未知");;
private int code;
private String message;
public static TransferIn get(int code) {
for (TransferIn resultMessage : TransferIn.values()) {
if (resultMessage.code == code) {
return resultMessage;
}
}
return Unknown;
}
}
@Getter
@AllArgsConstructor
public enum TransferOut {
WITHDRAW_ERROR(0, "提现异常"),
WITHDRAW_SUCCESS(1, "提现成功"),
MERCHANT_NOT_EXIST(2, "商户不存在"),
MERCHANT_INVALID(3, "商户无效"),
MERCHANT_USER_NOT_EXIST(4, "商户用户不存在"),
MERCHANT_USER_SYSTEM_DISABLED(6, "商户用户系统禁用"),
MERCHANT_USER_GOLD_BALANCE_INSUFFICIENT(9, "商户用户金币余额不足"),
GAME_NOT_SETTLED(12, "游戏未结算"),
IP_LIMIT(15, "IP被限制"),
DECRYPT_ERROR(21, "解密错误"),
OPTIONAL_PARAMETER_ERROR(32, "可选参数错误"),
EXIST_UNPROCESSED_ORDER(36, "存在未处理订单"),
MAINTENANCE(40, "维护模式"),
Unknown(-1, "未知");;
private int code;
private String message;
public static TransferOut get(int code) {
for (TransferOut resultMessage : TransferOut.values()) {
if (resultMessage.code == code) {
return resultMessage;
}
}
return Unknown;
}
}
}

View File

@ -0,0 +1,31 @@
package com.ff.game.api.meitian.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* jiligamesdto
*
* @author shi
* @date 2024/10/22
*/
@NoArgsConstructor
@Data
@Builder
@AllArgsConstructor
public class MeiTianGameDataDTO {
/**
*id
*/
private Long systemGameId;
private String gameId;
private String cnName;
private String enName;
private Integer gameCategoryId;
}

View File

@ -0,0 +1,51 @@
package com.ff.game.api.meitian.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
/**
* dto
*
* @author shi
* @date 2024/11/12
*/
@NoArgsConstructor
@Data
public class MeiTianGameRecordDetailDTO {
@JsonProperty("resultCode")
private int errorCode;
private String url;
private String currency;
@Getter
@AllArgsConstructor
public enum ResultMessage {
QueryException(0, "查询异常"),
QuerySuccess(1, "查询成功"),
MerchantNotExist(2, "商户不存在"),
MerchantInvalid(3, "商户无效"),
IPLimited(15, "IP被限制"),
DecryptError(21, "解密错误"),
OptionalParameterError(32, "可选参数错误"),
MaintenanceMode(40, "维护模式"),
Unknown(-1, "未知错误"),
;
private int code;
private String message;
}
public static ResultMessage get(int code) {
for (ResultMessage resultMessage : ResultMessage.values()) {
if (resultMessage.getCode() == code) {
return resultMessage;
}
}
return ResultMessage.Unknown;
}
}

View File

@ -0,0 +1,171 @@
package com.ff.game.api.meitian.dto;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
*
*
* @author shi
* @date 2024/10/22
*/
@NoArgsConstructor
@Data
public class MeiTianGamesDTO {
// 捕鱼3棋牌2街机4百人1全部0或不传
private List<MeiTianGameDataDTO> data;
{
data = new java.util.ArrayList<>();
// 捕鱼游戏数据列表
String[][] buyu = {
{"PTG0056", "3D捕鱼", "3D Fishing", "3"},
{"PTG0011", "李逵劈鱼", "Fishing Kui Lee", "3"},
{"PTG0045", "金蟾捕鱼", "Golden Toad", "3"},
{"PTG0100", "海王2", "Ocean King 2", "3"},
{"PTG0094", "疯狂捕鱼", "Crazy Fishing", "3"},
{"PTG0004", "捕鱼来了", "Fishing Joy", "3"},
{"PTG0104", "疯狂魔鬼城", "Trick or Treat", "3"},
{"PTG0125", "水果炸翻天", "Fruits Carnival", "3"},
};
addGames(buyu, data);
// 棋牌游戏数据列表
String[][] qipai = {
{"PTG0042", "五人牛牛", "Beat Bullfight", "2"},
{"PTG0022", "通比牛牛", "Mutual Bullfight", "2"},
{"PTG0013", "二人牛牛", "Versus Niu-Niu", "2"},
{"PTG0039", "十三水", "Winning Thirteen", "2"},
{"PTG0062", "炸金花", "Fraud Jinhua", "2"},
{"PTG0037", "德州扑克", "Texas Hold'em", "2"},
{"PTG0006", "欢乐斗地主", "Fight the Landlord", "2"},
{"PTG0023", "黑杰克", "Black Jack", "2"},
{"PTG0017", "二人梭哈", "Show Hand", "2"},
{"PTG0080", "抢庄牌九", "Pai Gow", "2"},
{"PTG0082", "三公", "3-card poker", "2"},
{"PTG0061", "明牌牛牛", "Spread Bullfight", "2"},
{"PTG0084", "土豪百家乐", "Rich Baccarat", "2"},
{"PTG0085", "推筒子", "versus 2-8 bar", "2"},
{"PTG0086", "二人雀神", "Versus Mahjong", "2"},
{"PTG0093", "血流成河", "Rivers of Blood", "2"},
{"PTG0110", "看牌牛牛", "Royal Bull-fight", "2"},
{"PTG0121", "越式13张", "TIEN LEN", "2"},
{"PTG0127", "UNO", "UNO", "2"},
{"PTG0122", "Dummy", "Dummy", "2"},
{"PTG0123", "九鸡", "Jiu-Ji", "2"}, // 未分类
{"PTG0124", "博丁", "Bo-Ding", "2"}, // 未分类
{"PTG0126", "牌肯", "Card Ken", "2"},
{"PTG0133", "泰式十三支", "Thai 13 Cards", "2"},
{"PTG0134", "泰九牌", "Gao Gae Thai", "2"},
{"PTG0136", "Dummy Speto", "Dummy Speto", "2"},
{"PTG0137", "Gao Gae Sam Bai Thod", "Gao Gae Sam Bai Thod", "2"},
{"PTG0138", "Slave Card", "Slave Card", "2"}
};
addGames(qipai, data);
// 百人场游戏数据列表
String[][] bairenchang = {
{"PTG0058", "红黑大战", "King's Queen", "1"},
{"PTG0044", "百人牛牛", "Hundred Niu-Niu", "1"},
{"PTG0059", "百家乐", "Baccarat", "1"},
{"PTG0008", "豪车漂移", "Drift Car Racing", "-1"}, // 未分类
{"PTG0041", "龙虎斗", "The Chinese Boxer", "1"},
{"PTG0007", "飞禽走兽", "Fowls and Beasts", "-1"}, // 未分类
{"PTG0036", "五星宏辉", "Five Star Stud", "1"},
{"PTG0064", "金鲨银鲨", "Golden Shark", "1"},
{"PTG0020", "西游争霸", "Journey to the West", "1"},
{"PTG0018", "港式赛马", "Horse Racing", "-1"}, // 未分类
{"PTG0070", "二八杠", "2-8 Bar", "-1"}, // 未分类
{"PTG0081", "骰宝", "Sic bo", "1"},
{"PTG0067", "森林舞会", "Forest Party", "-1"}, // 未分类
{"PTG0091", "鱼虾蟹", "Crab and Shrimp", "1"},
{"PTG0092", "红包扫雷", "Minesweeping", "-1"}, // 未分类
{"PTG0089", "动物跑跑跑", "Animal Running", "-1"}, // 未分类
{"PTG0116", "越式鱼虾蟹", "Vietnamese Fish-Prawn-Crab", "-1"}, // 未分类
{"PTG0102", "正版抢车位", "GA Car Parking", "-1"}, // 未分类
{"PTG0120", "番摊", "FAN TAN", "1"},
{"PTG2008", "西游争霸战无不胜", "Monkey King2 PLUS", "-1"}, // 未分类
{"PTG0135", "泰式鱼虾蟹", "Thai Fish Prawn Crab", "-1"} // 未分类
};
addGames(bairenchang, data);
// 街机游戏数据列表
String[][] dianzi = {
{"PTG0060", "超级大亨", "Super Tycoon", "4"},
{"PTG0069", "ATT金皇冠", "ATT Gold Crown", "4"},
{"PTG0001", "水果机", "Super Frootz", "4"},
{"PTG0010", "水浒传", "The Water Margin", "4"},
{"PTG0066", "大满贯水果机", "Grand Slam Frootz", "4"},
{"PTG0068", "泰山闯天关2", "Tarzan Adventure 2", "4"},
{"PTG0083", "财神到", "Mammon", "4"},
{"PTG0079", "不倒翁", "Happy tumbler", "4"},
{"PTG0087", "醉西游", "Monkey King", "4"},
{"PTG0090", "延禧攻略", "Story of Yanxi Palace", "4"},
{"PTG0095", "连环夺宝", "Linking Jewels", "4"},
{"PTG0098", "三只小猪", "Three Little Pigs", "4"},
{"PTG0097", "招财猫", "Fortune Cat", "4"},
{"PTG0099", "欲望魅影", "Sexy Succubus", "4"},
{"PTG0096", "绝地求生", "Playerunknown's Battlegrounds", "4"},
{"PTG0101", "埃及艳后", "Cleopatra's treasures", "4"},
{"PTG0103", "年年有鱼", "Lucky boy", "4"},
{"PTG0105", "天空之神", "God of Sky", "4"},
{"PTG0107", "阿拉丁神灯", "PLUS ALADDIN'S GOLD", "4"},
{"PTG0109", "武媚娘传奇", "Empress Wu Zetian", "4"},
{"PTG0106", "亿万富翁", "Billionaire", "4"},
{"PTG0115", "萝卜跳一跳", "Jump Hot", "4"},
{"PTG0117", "宫心计", "Beyond The Realm Of Conscience", "4"},
{"PTG2001", "恭喜发财", "Good Fortune", "4"},
{"PTG2002", "新潘金莲", "Pan Jinlian", "4"},
{"PTG2003", "宫本武藏", "Miyamoto Musashi", "4"},
{"PTG2004", "武则天", "Empress of the Great Tang", "4"},
{"PTG2005", "发发发", "Fa Fa Fa", "4"},
{"PTG2007", "赏金船长", "Captain's Bounty", "4"},
{"PTG2009", "爱尔兰精灵", "Leprechaun Riches", "4"},
{"PTG2010", "水浒传豪华版", "Water Margin DELUXE", "4"},
{"PTG2011", "金钱豹水果机", "Golden Jaguar", "4"},
{"PTG0118", "疯狂猴子", "Crazy Monkey", "4"},
{"PTG2015", "金刚", "King Kong", "4"},
{"PTG2016", "福星献舞", "Dancing FU", "4"},
{"PTG2017", "野蛮世界", "HUGA", "4"},
{"PTG2018", "上海甜心", "Shanghai Honey", "4"},
{"PTG2019", "美洲野牛", "Buffalo Gold", "4"},
{"PTG2020", "白蛇传", "The Legend of White Snake", "4"},
{"PTG2021", "笑弥勒", "Happys Prosperous", "4"},
{"PTG2013", "招财推币机", "Fortune Coindozer", "4"},
{"PTG2025", "东海之王", "Dragon Of The Eastern Ocean", "4"},
{"PTG2028", "中国龙", "Dragon World", "4"},
{"PTG2023", "秦皇传说", "Legend of Emperor Qin", "4"},
{"PTG2026", "辣椒多多", "More Chilli", "4"},
{"PTG2029", "财神驾到", "CHOY SUN DOA", "4"},
{"PTG2030", "招财猫2", "Fortune Cat 2", "4"},
{"PTG2031", "黄金城魅影", "Gold City Treasure Hunt", "4"},
{"PTG2032", "亡灵宝藏", "WILD BANDITO", "4"},
{"PTG2033", "麒麟献宝", "WAYS OF THE QILIN", "4"},
{"PTG2034", "天将神兵", "Heavenly Warriors", "4"}
};
addGames(dianzi, data);
}
public void addGames(String[][] gameData, List<MeiTianGameDataDTO> dataList) {
// 添加数据到 List
for (String[] game : gameData) {
String gameId = game[0];
String cnName = game[1];
String enName = game[2];
Integer categoryId = Integer.valueOf(game[3]);
dataList.add(MeiTianGameDataDTO.builder().gameId(gameId)
.cnName(cnName)
.enName(enName)
.gameCategoryId(categoryId)
.build());
}
}
}

View File

@ -0,0 +1,52 @@
package com.ff.game.api.meitian.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
/**
* dto
*
* @author shi
* @date 2024/10/22
*/
@NoArgsConstructor
@Data
public class MeiTianLoginResultDTO {
@JsonProperty("resultCode")
private int errorCode;
@JsonProperty("url")
private String url;
@Getter
@AllArgsConstructor
public enum ResultMessage {
LoginException(0, "登录异常"),
LoginSuccess(1, "登录成功"),
MerchantNotExist(2, "商户不存在"),
MerchantInvalid(3, "商户无效"),
MerchantUserNotExist(4, "商户用户不存在"),
MerchantUserSystemDisabled(6, "商户用户系统禁用"),
PasswordError(7, "密码错误"),
IPLimited(15, "IP被限制"),
DecryptError(21, "解密错误"),
MerchantUserLoginDisabled(22, "商户用户登录禁用"),
OptionalParameterError(32, "可选参数错误"),
MaintenanceMode(40, "维护模式"),
Unknown(-1, "未知错误");
private int code;
private String message;
}
public static ResultMessage get(int errorCode) {
for (ResultMessage resultMessage : ResultMessage.values()) {
if (resultMessage.getCode() == errorCode) {
return resultMessage;
}
}
return ResultMessage.Unknown;
}
}

View File

@ -0,0 +1,43 @@
package com.ff.game.api.meitian.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@Data
public class MeiTianLogoutDTO {
@JsonProperty("resultCode")
private int errorCode;
@Getter
@AllArgsConstructor
public enum ResultMessage {
QueryException(0, "查询异常"),
QuerySuccess(1, "查询成功"),
MerchantNotExist(2, "商户不存在"),
MerchantInvalid(3, "商户无效"),
MerchantUserNotExist(4, "商户用户不存在"),
MerchantUserSystemDisabled(6, "商户用户系统禁用"),
MerchantUserGameOnline(12, "商户用户游戏在线"),
IPLimited(15, "IP被限制"),
MaintenanceMode(40, "维护模式"),
Unknown(-1, "未知错误")
,;
private int code;
private String message;
}
public static ResultMessage get(int errorCode) {
for (ResultMessage resultMessage : ResultMessage.values()) {
if (resultMessage.code == errorCode) {
return resultMessage;
}
}
return ResultMessage.Unknown;
}
}

View File

@ -0,0 +1,69 @@
package com.ff.game.api.meitian.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
/**
* dto
*
* @author shi
* @date 2024/10/30
*/
@NoArgsConstructor
@Data
public class MeiTianMemberInfoDTO {
/**
*
*/
@JsonProperty("resultCode")
private int errorCode;
/**
*
*/
@JsonProperty("coinBalance")
private BigDecimal balance;
@JsonProperty("status")
private Integer status;
@JsonProperty("currency")
private String currency;
@Getter
@AllArgsConstructor
public enum ResultMessage {
Excep(0,"查询异常"),
Success(1,"查询成功"),
// 商户不存在
MerchantNotExist(2,"商户不存在"),
// 商户无效
MerchantInvalid(3,"商户无效"),
// 商户用户不存在
AccountNotExist(4,"商户用户不存在"),
// IP被限制
IpLimit(15,"IP被限制"),
// 维护模式
Maintenance(40,"维护模式"),
Unknown(-1, "未知")
,;
private int code;
private String message;
public static ResultMessage getResultMessage(int code) {
for (ResultMessage resultMessage : ResultMessage.values()) {
if (resultMessage.code == code) {
return resultMessage;
}
}
return Unknown;
}
}
}

View File

@ -0,0 +1,677 @@
package com.ff.game.api.meitian.impl;
import cn.hutool.core.codec.Base64;
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.sign.Md5Utils;
import com.ff.base.utils.uuid.IdUtils;
import com.ff.game.api.IGamesService;
import com.ff.game.api.meitian.client.MeiTianClient;
import com.ff.game.api.meitian.dto.*;
import com.ff.game.api.request.*;
import com.ff.game.domain.*;
import com.ff.game.dto.GameSecretKeyCurrencyDTO;
import com.ff.game.service.*;
import com.ff.member.domain.Member;
import com.ff.member.service.IMemberService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
*
*
* @author shi
* @date 2024/10/21
*/
@Service("MeiTianService")
@Slf4j
public class MeiTianGameServiceImpl 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 IGameSecretKeyService gameSecretKeyService;
@Resource
private MeiTianClient meiTianClient;
@Resource
private IGameBettingDetailsService gameBettingDetailsService;
@Resource
private IGameSecretKeyCurrencyService gameSecretKeyCurrencyService;
@Resource
private IGameNameService gameNameService;
/**
*
*
* @param errorCode
* @return {@link Boolean }
*/
private Boolean isSuccess(Integer errorCode) {
return 1 == errorCode;
}
/**
*
*
* @param createMemberRequestDTO dto
* @return {@link Boolean }
*/
@Override
public Boolean createMember(CreateMemberRequestDTO createMemberRequestDTO) {
GameSecretKey gameSecretKey = gameSecretKeyService.selectGameSecretKeyByCode(createMemberRequestDTO.getAgentId());
String playerName = createMemberRequestDTO.getAccount();
String merchantId = createMemberRequestDTO.getAgentId();
String md5Password = Md5Utils.md5New(gameSecretKey.getPassword());
Map<String, String> rawMap = new LinkedHashMap<>();
rawMap.put("nickname", createMemberRequestDTO.getAccount());
rawMap.put("playerLevel", "0");
String rawData = JSON.toJSONString(rawMap);
String data = null;
try {
data = Base64.encode(rawData.getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
log.error("[MeiTian] encode rawData failure", e);
throw new ApiException(ErrorCode.ERROR.getCode());
}
String md5Code = Md5Utils.md5New(gameSecretKey.getKey() + rawData);//MD5(key+rawData);
MeiTianCreateMemberResponseDTO createMemberResponseDTO =
meiTianClient.createMember(
playerName,
merchantId,
md5Password,
md5Code,
data);
int errorCode = createMemberResponseDTO.getResultCode();
log.info("[MeiTian]创建会员失败返回结果:{}", errorCode);
if (1 == errorCode) {
return Boolean.TRUE;
}
if (5 == errorCode) {
throw new ApiException(ErrorCode.GAME_ACCOUNT_CREATION_FAILED.getCode());
}
//判断是否获取成功
return Boolean.FALSE;
}
/**
*
*
* @param memberInfoRequestDTO dto
* @return {@link MemberInfoResponseDTO }
*/
@Override
public MemberInfoResponseDTO getMemberInfo(MemberInfoRequestDTO memberInfoRequestDTO) {
String playerName = memberInfoRequestDTO.getAccounts();
String merchantId = memberInfoRequestDTO.getAgentId();
MeiTianMemberInfoDTO memberInfoDTO = meiTianClient.getMemberInfo(playerName, merchantId);
//判断是否获取成功
if (this.isSuccess(memberInfoDTO.getErrorCode())) {
return MemberInfoResponseDTO.builder()
.status(GameMemberStatus.UNKNOWN.getCode())
.balance(memberInfoDTO.getBalance())
.account(playerName)
.build();
} else {
throw new BaseException(MeiTianMemberInfoDTO.ResultMessage.getResultMessage(memberInfoDTO.getErrorCode()).getMessage());
}
}
/**
*
*
* @param gamesLogin
* @return {@link String }
*/
@Override
public String loginWithoutRedirect(GamesLogin gamesLogin) {
GameSecretKey gameSecretKey = gameSecretKeyService.selectGameSecretKeyByCode(gamesLogin.getAgentId());
String merchantId = gamesLogin.getAgentId();
String playerName = gamesLogin.getAccount();
String md5Password = Md5Utils.md5New(gameSecretKey.getPassword());
Map<String, String> rawMap = new LinkedHashMap<>();
rawMap.put("gameHall ", gamesLogin.getGameType());
/*rawMap.put("gameCode", gamesLogin.getGameId());
rawMap.put("lang", gamesLogin.getLang());
rawMap.put("roomID", "0");*/
String rawData = JSON.toJSONString(rawMap);
String data = null;
try {
data = Base64.encode(rawData.getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
log.error("[MeiTian] encode rawData failure", e);
throw new ApiException(ErrorCode.ERROR.getCode());
}
String code = Md5Utils.md5New(gameSecretKey.getKey() + rawData);
MeiTianLoginResultDTO loginWithoutRedirectResponseDTO =
meiTianClient.loginWithoutRedirect(
merchantId,
playerName,
md5Password,
code,
data
);
//判断是否获取成功
if (this.isSuccess(loginWithoutRedirectResponseDTO.getErrorCode())) {
return loginWithoutRedirectResponseDTO.getUrl();
} else {
throw new BaseException(MeiTianLoginResultDTO.get(loginWithoutRedirectResponseDTO.getErrorCode()).getMessage());
}
}
/**
*
*
* @param gamesBaseRequestDTO dto
* @return {@link String }
*/
@Transactional
@Override
public String getGameList(GamesBaseRequestDTO gamesBaseRequestDTO) {
List<MeiTianGameDataDTO> gamesDatas = redisCache.getCacheList(CacheConstants.MeiTian_GAMES);
if (!CollectionUtils.isEmpty(gamesDatas)) {
return CacheConstants.MeiTian_GAMES;
}
MeiTianGamesDTO gameList = new MeiTianGamesDTO();
for (MeiTianGameDataDTO gamesDataDTO : gameList.getData()) {
GamePlatform gamePlatform = GamePlatform.builder()
.platformType(MeiTianGameType.findSystemByCode(gamesDataDTO.getGameCategoryId()))
.platformCode(GamePlatforms.MeiTIan.getCode())
.build();
List<GamePlatform> gamePlatforms = gamePlatformService.selectGamePlatformList(gamePlatform);
//没有此平台就新增一个平台
if (CollectionUtils.isEmpty(gamePlatforms)) {
gamePlatform.setPlatformName(GamePlatforms.MeiTIan.getInfo() + MeiTianGameType.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<Game> games = gameService.selectGameList(game);
//不存在这个游戏
if (CollectionUtils.isEmpty(games)) {
game.setGameSourceType(String.valueOf(gamesDataDTO.getGameCategoryId()));
game.setFreespin(false);
game.setSortNo(gameService.selectMaxSortNoByPlatformId(gamePlatform.getId()) + 1);
game.setGameName(gamesDataDTO.getCnName());
game.setCreateBy(Constants.SYSTEM);
gameService.insertGame(game);
} else {
game = games.get(0);
}
gamesDataDTO.setSystemGameId(game.getId());
List<GameName> 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());
//
gameNameService.insertGameName(GameName.builder()
.gameId(game.getId())
.gameName(gamesDataDTO.getEnName())
.langCode("en-US")
.createBy(Constants.SYSTEM)
.build());
}
}
redisCache.deleteObject(CacheConstants.MeiTian_GAMES);
redisCache.setCacheList(CacheConstants.MeiTian_GAMES, gameList.getData());
redisCache.expire(CacheConstants.MeiTian_GAMES, 5L, TimeUnit.HOURS);
return CacheConstants.MeiTian_GAMES;
}
/**
* id
*
* @param exchangeTransferMoneyRequestDTO moeny dto
* @return {@link Long }
*/
@Override
@Transactional
public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) {
GameSecretKeyCurrencyDTO gameSecretKey = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
.code(exchangeTransferMoneyRequestDTO.getAgentId())
.currency(exchangeTransferMoneyRequestDTO.getCurrency()).build());
Member member = memberService.selectMemberByGameAccount(exchangeTransferMoneyRequestDTO.getAccount());
String transactionId = GamePlatforms.MeiTIan.getCode() + IdUtils.simpleUUID();
List<GameExchangeMoney> gameExchangeMonies = gameExchangeMoneyService.selectGameExchangeMoneyList(
GameExchangeMoney.builder()
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.build()
);
Assert.isTrue(CollectionUtils.isEmpty(gameExchangeMonies), "订单号重复");
//获取下一个自增id
GameExchangeMoney exchangeMoney = GameExchangeMoney
.builder()
.orderId(exchangeTransferMoneyRequestDTO.getOrderId())
.tenantKey(exchangeTransferMoneyRequestDTO.getTenantKey())
.quota(exchangeTransferMoneyRequestDTO.getQuota())
.balance(exchangeTransferMoneyRequestDTO.getAmount())
.exchangeType(exchangeTransferMoneyRequestDTO.getTransferType())
.currencyCode(gameSecretKey.getSystemCurrency())
.memberId(member.getId())
.transactionId(transactionId)
.platformCode(GamePlatforms.MeiTIan.getCode())
.build();
exchangeMoney.setCreateBy(Constants.SYSTEM);
//接口限制限制50字符
exchangeMoney.setTransactionId(transactionId);
String key = gameSecretKey.getKey();
String merchantId = exchangeTransferMoneyRequestDTO.getAgentId();
String playerName = exchangeTransferMoneyRequestDTO.getAccount();
String coins = exchangeTransferMoneyRequestDTO.getAmount().setScale(4, RoundingMode.DOWN).toString();
Map<String, String> rawMap = new LinkedHashMap<>();
rawMap.put("merchantId", merchantId);
rawMap.put("playerName", playerName);
rawMap.put("extTransId", transactionId);
rawMap.put("coins", coins);
String rawData = JSON.toJSONString(rawMap);
String data = null;
try {
data = Base64.encode(rawData.getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
log.error("[MeiTian] base64 rawData failure", e);
throw new ApiException(ErrorCode.BALANCE_TRANSFER_FAILED.getCode());
}
String md5Code = Md5Utils.md5New(key + rawData);
// 转入到游戏商 type == 2
if (exchangeTransferMoneyRequestDTO.getTransferType().equals(TransferType.GAMES.getCode())) {
MeiTianExchangeMoneyResponseDTO exchangeMoneyResponse = meiTianClient
.transferIn(
merchantId,
playerName,
coins,
transactionId,
md5Code,
data
);
//判断是否转移成功
if (this.isSuccess(exchangeMoneyResponse.getErrorCode())) {
//更新数据
exchangeMoney.setBalance(exchangeMoneyResponse.getBalance());
BigDecimal transAmount = exchangeTransferMoneyRequestDTO.getAmount();
exchangeMoney.setCoinBefore(exchangeMoneyResponse.getBalance().subtract(transAmount));
exchangeMoney.setCoinAfter(exchangeMoneyResponse.getBalance());
exchangeMoney.setCurrencyBefore(exchangeMoneyResponse.getBalance().subtract(transAmount));
exchangeMoney.setCurrencyAfter(exchangeMoneyResponse.getBalance());
exchangeMoney.setStatus(1); // SUCCESS
gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
} else {
throw new BaseException(MeiTianExchangeMoneyResponseDTO.TransferIn.get(exchangeMoneyResponse.getErrorCode()).getMessage());
}
} else {
MeiTianExchangeMoneyResponseDTO exchangeMoneyResponse = meiTianClient
.transferOut(
merchantId,
playerName,
coins,
transactionId,
md5Code,
data
);
//判断是否转移成功
if (this.isSuccess(exchangeMoneyResponse.getErrorCode())) {
//更新数据
exchangeMoney.setBalance(exchangeMoneyResponse.getBalance());
BigDecimal transAmount = exchangeTransferMoneyRequestDTO.getAmount();
exchangeMoney.setCoinBefore(exchangeMoneyResponse.getBalance().add(transAmount));
exchangeMoney.setCoinAfter(exchangeMoneyResponse.getBalance());
exchangeMoney.setCurrencyBefore(exchangeMoneyResponse.getBalance().add(transAmount));
exchangeMoney.setCurrencyAfter(exchangeMoneyResponse.getBalance());
exchangeMoney.setStatus(1); // SUCCESS
gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney);
} else {
throw new BaseException(MeiTianExchangeMoneyResponseDTO.TransferOut.get(exchangeMoneyResponse.getErrorCode()).getMessage());
}
}
return exchangeMoney.getId();
}
/**
*
*
* @param exchangeTransferMoneyRequestDTO dto
* @return {@link Boolean }
*/
@Override
public Boolean exchangeTransferStatus(ExchangeTransferStatusRequestDTO exchangeTransferMoneyRequestDTO) {
return Boolean.TRUE;
}
/**
*
*
* @param betRecordByTimeDTO dto
* @return {@link Boolean }
*/
@Override
public Boolean getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) {
/*//获取key
JILIBetRecordResponseDTO betRecordJILIResponse = meiTianClient.getBetRecordByTime(query + "&Key=" + key, betRecordByTimeDTO.getAgentId());
//判断是否获取成功
if (this.isSuccess(betRecordJILIResponse.getErrorCode())) {
//数据插入
this.batchInsert(betRecordJILIResponse);
JILIBetRecordResponseDTO.DataBean dataBean = betRecordJILIResponse.getData();
//获取下一页数据
while (dataBean.getPagination().getCurrentPage() != dataBean.getPagination().getTotalPages() && dataBean.getPagination().getTotalPages() > 0) {
betRecordByTimeDTO.setPage(dataBean.getPagination().getCurrentPage() + 1);
//请求参数
query = "StartTime=" + startTime + "&EndTime=" + endTime + "&Page=" + betRecordByTimeDTO.getPage() + "&PageLimit=" + betRecordByTimeDTO.getPageLimit() + "&AgentId=" + betRecordByTimeDTO.getAgentId();
log.info("GamesJILIServiceImpl [getBetRecordByTime] 请求参数 {}", query);
betRecordByTimeDTO.setQuery(query);
key = this.getKey(betRecordByTimeDTO);
betRecordJILIResponse = meiTianClient.getBetRecordByTime(query + "&Key=" + key, betRecordByTimeDTO.getAgentId());
dataBean = betRecordJILIResponse.getData();
if (this.isSuccess(betRecordJILIResponse.getErrorCode())) {
//数据插入
this.batchInsert(betRecordJILIResponse);
} else {
log.error("GameBettingDataJILIServiceImpl [getBetRecordByTime] 获取投注记录失败,错误代码{},错误信息{}", betRecordJILIResponse.getErrorCode(), betRecordJILIResponse.getMessage());
}
}
} else {
return Boolean.FALSE;
}*/
return Boolean.TRUE;
}
/**
*
*
* @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 BaseException("暂不支持免费局数");
}
/**
*
*
* @param getGameDetailRequestDTO dto
* @return {@link GetGameDetailResponseDTO }
*/
@Override
public GetGameDetailResponseDTO getGameDetail(GetGameDetailRequestDTO getGameDetailRequestDTO) {
GameSecretKey gameSecretKey = gameSecretKeyService.selectGameSecretKeyByCode(getGameDetailRequestDTO.getAgentId());
String key = gameSecretKey.getKey();
String merchantId = getGameDetailRequestDTO.getAgentId();
Map<String, String> rawMap = new LinkedHashMap<>();
rawMap.put("rowID", getGameDetailRequestDTO.getWagersId());
rawMap.put("lang", getGameDetailRequestDTO.getLang());
String rawData = JSON.toJSONString(rawMap);
String data = null;
try {
data = Base64.encode(rawData.getBytes("UTF-8"));
} catch (Exception e) {
log.error("[MeiTian] encode rawData failure", e);
throw new ApiException(ErrorCode.ERROR.getCode());
}
String code = Md5Utils.md5New(data + key);
MeiTianGameRecordDetailDTO responseDTO = meiTianClient.getGameDetail(merchantId, code, data);
//判断是否获取成功
if (this.isSuccess(responseDTO.getErrorCode())) {
GetGameDetailResponseDTO getGameDetailResponseDTO = new GetGameDetailResponseDTO();
getGameDetailResponseDTO.setUrl(responseDTO.getUrl());
return getGameDetailResponseDTO;
} else {
throw new BaseException(MeiTianGameRecordDetailDTO.get(responseDTO.getErrorCode()).getMessage());
}
}
/**
*
*
* @param kickMemberRequestDTO dto
* @return {@link Boolean }
*/
@Override
public Boolean kickMember(KickMemberRequestDTO kickMemberRequestDTO) {
String merchantId = kickMemberRequestDTO.getAgentId();
String playerName = kickMemberRequestDTO.getAccount();
MeiTianLogoutDTO jiliKickMemberDTO = meiTianClient.kickMember(
merchantId,
playerName);
//判断是否获取成功
if (this.isSuccess(jiliKickMemberDTO.getErrorCode())) {
return Boolean.TRUE;
} else {
throw new BaseException(MeiTianLogoutDTO.get(jiliKickMemberDTO.getErrorCode()).getMessage());
}
}
/**
*
*
* @param kickMemberAllDTO dto
* @return {@link Boolean }
*/
@Override
public Boolean kickMemberAll(KickMemberAllDTO kickMemberAllDTO) {
throw new ApiException(ErrorCode.PLATFORM_NOT_METHODS.getCode());
}
/**
* 使
*
* @param getFreeSpinDashflowRequestDTO dashflowdto
* @return {@link List }<{@link GameFreeRecord }>
*/
@Override
public List<GameFreeRecord> getFreeSpinDashflow(GetFreeSpinDashflowRequestDTO getFreeSpinDashflowRequestDTO) {
throw new ApiException(ErrorCode.PLATFORM_NOT_METHODS.getCode());
}
/**
*
*
* @param cancelFreeSpinRequestDTO
* @return {@link Boolean }
*/
@Override
public Boolean cancelFreeSpin(CancelFreeSpinRequestDTO cancelFreeSpinRequestDTO) {
throw new ApiException(ErrorCode.PLATFORM_NOT_METHODS.getCode());
}
/**
*
*
* @param betRecordJILIResponse jiliresponse
* @return {@link Integer }
*/
private void batchInsert(JILIBetRecordResponseDTO betRecordJILIResponse) {
List<GameBettingDetails> gameBettingDetails = new ArrayList<>();
List<String> wagersIds = new ArrayList<>();
//数据组装
JILIBetRecordResponseDTO.DataBean dataBean = betRecordJILIResponse.getData();
//数据转化
for (JILIBetRecordDataResponseDTO jiliBetRecordDataResponseDTO : dataBean.getResult()) {
GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder().data(jiliBetRecordDataResponseDTO).build());
if (!ObjectUtils.isEmpty(bettingDetails)) {
bettingDetails.setId(IdUtil.getSnowflakeNextId());
gameBettingDetails.add(bettingDetails);
}
wagersIds.add(jiliBetRecordDataResponseDTO.getWagersId());
}
if (!CollectionUtils.isEmpty(gameBettingDetails)) {
//查询重复数据id
List<String> 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) {
//转化类
JILIBetRecordDataResponseDTO jiliBetRecordDataResponseDTO = (JILIBetRecordDataResponseDTO) gamesDataBuildDTO.getData();
GameSecretKeyCurrencyDTO gameSecretKey = gameSecretKeyCurrencyService.findByGameSecretKeyCurrencyDTO(GameSecretKeyCurrencyDTO.builder()
.code(jiliBetRecordDataResponseDTO.getAgentId())
.platformCode(GamePlatforms.MeiTIan.getInfo()).build());
Member member = memberService.selectMemberByGameAccount(jiliBetRecordDataResponseDTO.getAccount());
if (ObjectUtils.isEmpty(member)) {
return null;
}
List<MeiTianGameDataDTO> gamesDatas = redisCache.getCacheList(CacheConstants.JILI_GAMES);
Map<String, MeiTianGameDataDTO> dataDTOMap = gamesDatas.stream().collect(Collectors.toMap(MeiTianGameDataDTO::getGameId, e -> e));
MeiTianGameDataDTO gamesDataDTO = dataDTOMap.get(jiliBetRecordDataResponseDTO.getGameId());
BigDecimal payoffAmount = BigDecimal.ZERO;
if (GameStatus.WIN.getCode().equals(jiliBetRecordDataResponseDTO.getStatus())) {
payoffAmount = NumberUtil.sub(jiliBetRecordDataResponseDTO.getPayoffAmount(), jiliBetRecordDataResponseDTO.getTurnover());
} else if (GameStatus.FAIL.getCode().equals(jiliBetRecordDataResponseDTO.getStatus())) {
payoffAmount = NumberUtil.sub(jiliBetRecordDataResponseDTO.getPayoffAmount(), jiliBetRecordDataResponseDTO.getTurnover()).negate();
}
//数据构造
GameBettingDetails gameBettingDetails = GameBettingDetails.builder()
.tenantKey(member.getTenantKey())
//保存我们的币种id
.currencyCode(gameSecretKey.getSystemCurrency())
.memberId(member.getId())
.gameCode(jiliBetRecordDataResponseDTO.getGameId())
.gameType(JILIGameType.findSystemByCode(jiliBetRecordDataResponseDTO.getGameCategoryId()))
.platformCode(GamePlatforms.MeiTIan.getCode())
.gameId(gamesDataDTO.getSystemGameId())
.gameName(gamesDataDTO.getCnName())
.gameStatus(jiliBetRecordDataResponseDTO.getStatus())
.gameStatusType(jiliBetRecordDataResponseDTO.getType())
.gameCurrencyCode(jiliBetRecordDataResponseDTO.getAgentId())
.account(String.valueOf(jiliBetRecordDataResponseDTO.getAccount()))
.wagersId(jiliBetRecordDataResponseDTO.getWagersId())
.wagersTime(jiliBetRecordDataResponseDTO.getWagersTime())
.betAmount(jiliBetRecordDataResponseDTO.getBetAmount().abs())
.payoffTime(jiliBetRecordDataResponseDTO.getPayoffTime())
.payoffAmount(payoffAmount)
.settlementTime(jiliBetRecordDataResponseDTO.getSettlementTime())
.turnover(jiliBetRecordDataResponseDTO.getTurnover())
.orderNo(String.valueOf(jiliBetRecordDataResponseDTO.getRoundIndex()))
.settlementStatus(SettlementStatusEnum.COMPLETED.getCode())
.build();
gameBettingDetails.setCreateBy(Constants.SYSTEM);
gameBettingDetails.setCreateTime(DateUtils.getNowDate());
return gameBettingDetails;
}
}